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 bool castLL_is_imm32(const Node* n); 426 427 %} 428 429 source %{ 430 431 bool castLL_is_imm32(const Node* n) { 432 assert(n->is_CastLL(), "must be a CastLL"); 433 const TypeLong* t = n->bottom_type()->is_long(); 434 return (t->_lo == min_jlong || Assembler::is_simm32(t->_lo)) && (t->_hi == max_jlong || Assembler::is_simm32(t->_hi)); 435 } 436 437 %} 438 439 // Register masks 440 source_hpp %{ 441 442 extern RegMask _ANY_REG_mask; 443 extern RegMask _PTR_REG_mask; 444 extern RegMask _PTR_REG_NO_RBP_mask; 445 extern RegMask _PTR_NO_RAX_REG_mask; 446 extern RegMask _PTR_NO_RAX_RBX_REG_mask; 447 extern RegMask _LONG_REG_mask; 448 extern RegMask _LONG_NO_RAX_RDX_REG_mask; 449 extern RegMask _LONG_NO_RCX_REG_mask; 450 extern RegMask _LONG_NO_RBP_R13_REG_mask; 451 extern RegMask _INT_REG_mask; 452 extern RegMask _INT_NO_RAX_RDX_REG_mask; 453 extern RegMask _INT_NO_RCX_REG_mask; 454 extern RegMask _INT_NO_RBP_R13_REG_mask; 455 extern RegMask _FLOAT_REG_mask; 456 457 extern RegMask _STACK_OR_PTR_REG_mask; 458 extern RegMask _STACK_OR_LONG_REG_mask; 459 extern RegMask _STACK_OR_INT_REG_mask; 460 461 inline const RegMask& STACK_OR_PTR_REG_mask() { return _STACK_OR_PTR_REG_mask; } 462 inline const RegMask& STACK_OR_LONG_REG_mask() { return _STACK_OR_LONG_REG_mask; } 463 inline const RegMask& STACK_OR_INT_REG_mask() { return _STACK_OR_INT_REG_mask; } 464 465 %} 466 467 source %{ 468 #define RELOC_IMM64 Assembler::imm_operand 469 #define RELOC_DISP32 Assembler::disp32_operand 470 471 #define __ masm-> 472 473 RegMask _ANY_REG_mask; 474 RegMask _PTR_REG_mask; 475 RegMask _PTR_REG_NO_RBP_mask; 476 RegMask _PTR_NO_RAX_REG_mask; 477 RegMask _PTR_NO_RAX_RBX_REG_mask; 478 RegMask _LONG_REG_mask; 479 RegMask _LONG_NO_RAX_RDX_REG_mask; 480 RegMask _LONG_NO_RCX_REG_mask; 481 RegMask _LONG_NO_RBP_R13_REG_mask; 482 RegMask _INT_REG_mask; 483 RegMask _INT_NO_RAX_RDX_REG_mask; 484 RegMask _INT_NO_RCX_REG_mask; 485 RegMask _INT_NO_RBP_R13_REG_mask; 486 RegMask _FLOAT_REG_mask; 487 RegMask _STACK_OR_PTR_REG_mask; 488 RegMask _STACK_OR_LONG_REG_mask; 489 RegMask _STACK_OR_INT_REG_mask; 490 491 static bool need_r12_heapbase() { 492 return UseCompressedOops; 493 } 494 495 void reg_mask_init() { 496 constexpr Register egprs[] = {r16, r17, r18, r19, r20, r21, r22, r23, r24, r25, r26, r27, r28, r29, r30, r31}; 497 498 // _ALL_REG_mask is generated by adlc from the all_reg register class below. 499 // We derive a number of subsets from it. 500 _ANY_REG_mask = _ALL_REG_mask; 501 502 if (PreserveFramePointer) { 503 _ANY_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg())); 504 _ANY_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg()->next())); 505 } 506 if (need_r12_heapbase()) { 507 _ANY_REG_mask.Remove(OptoReg::as_OptoReg(r12->as_VMReg())); 508 _ANY_REG_mask.Remove(OptoReg::as_OptoReg(r12->as_VMReg()->next())); 509 } 510 511 _PTR_REG_mask = _ANY_REG_mask; 512 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(rsp->as_VMReg())); 513 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(rsp->as_VMReg()->next())); 514 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(r15->as_VMReg())); 515 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(r15->as_VMReg()->next())); 516 if (!UseAPX) { 517 for (uint i = 0; i < sizeof(egprs)/sizeof(Register); i++) { 518 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(egprs[i]->as_VMReg())); 519 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(egprs[i]->as_VMReg()->next())); 520 } 521 } 522 523 _STACK_OR_PTR_REG_mask = _PTR_REG_mask; 524 _STACK_OR_PTR_REG_mask.OR(STACK_OR_STACK_SLOTS_mask()); 525 526 _PTR_REG_NO_RBP_mask = _PTR_REG_mask; 527 _PTR_REG_NO_RBP_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg())); 528 _PTR_REG_NO_RBP_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg()->next())); 529 530 _PTR_NO_RAX_REG_mask = _PTR_REG_mask; 531 _PTR_NO_RAX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg())); 532 _PTR_NO_RAX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg()->next())); 533 534 _PTR_NO_RAX_RBX_REG_mask = _PTR_NO_RAX_REG_mask; 535 _PTR_NO_RAX_RBX_REG_mask.Remove(OptoReg::as_OptoReg(rbx->as_VMReg())); 536 _PTR_NO_RAX_RBX_REG_mask.Remove(OptoReg::as_OptoReg(rbx->as_VMReg()->next())); 537 538 539 _LONG_REG_mask = _PTR_REG_mask; 540 _STACK_OR_LONG_REG_mask = _LONG_REG_mask; 541 _STACK_OR_LONG_REG_mask.OR(STACK_OR_STACK_SLOTS_mask()); 542 543 _LONG_NO_RAX_RDX_REG_mask = _LONG_REG_mask; 544 _LONG_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg())); 545 _LONG_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg()->next())); 546 _LONG_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rdx->as_VMReg())); 547 _LONG_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rdx->as_VMReg()->next())); 548 549 _LONG_NO_RCX_REG_mask = _LONG_REG_mask; 550 _LONG_NO_RCX_REG_mask.Remove(OptoReg::as_OptoReg(rcx->as_VMReg())); 551 _LONG_NO_RCX_REG_mask.Remove(OptoReg::as_OptoReg(rcx->as_VMReg()->next())); 552 553 _LONG_NO_RBP_R13_REG_mask = _LONG_REG_mask; 554 _LONG_NO_RBP_R13_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg())); 555 _LONG_NO_RBP_R13_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg()->next())); 556 _LONG_NO_RBP_R13_REG_mask.Remove(OptoReg::as_OptoReg(r13->as_VMReg())); 557 _LONG_NO_RBP_R13_REG_mask.Remove(OptoReg::as_OptoReg(r13->as_VMReg()->next())); 558 559 _INT_REG_mask = _ALL_INT_REG_mask; 560 if (!UseAPX) { 561 for (uint i = 0; i < sizeof(egprs)/sizeof(Register); i++) { 562 _INT_REG_mask.Remove(OptoReg::as_OptoReg(egprs[i]->as_VMReg())); 563 } 564 } 565 566 if (PreserveFramePointer) { 567 _INT_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg())); 568 } 569 if (need_r12_heapbase()) { 570 _INT_REG_mask.Remove(OptoReg::as_OptoReg(r12->as_VMReg())); 571 } 572 573 _STACK_OR_INT_REG_mask = _INT_REG_mask; 574 _STACK_OR_INT_REG_mask.OR(STACK_OR_STACK_SLOTS_mask()); 575 576 _INT_NO_RAX_RDX_REG_mask = _INT_REG_mask; 577 _INT_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg())); 578 _INT_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rdx->as_VMReg())); 579 580 _INT_NO_RCX_REG_mask = _INT_REG_mask; 581 _INT_NO_RCX_REG_mask.Remove(OptoReg::as_OptoReg(rcx->as_VMReg())); 582 583 _INT_NO_RBP_R13_REG_mask = _INT_REG_mask; 584 _INT_NO_RBP_R13_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg())); 585 _INT_NO_RBP_R13_REG_mask.Remove(OptoReg::as_OptoReg(r13->as_VMReg())); 586 587 // _FLOAT_REG_LEGACY_mask/_FLOAT_REG_EVEX_mask is generated by adlc 588 // from the float_reg_legacy/float_reg_evex register class. 589 _FLOAT_REG_mask = VM_Version::supports_evex() ? _FLOAT_REG_EVEX_mask : _FLOAT_REG_LEGACY_mask; 590 } 591 592 static bool generate_vzeroupper(Compile* C) { 593 return (VM_Version::supports_vzeroupper() && (C->max_vector_size() > 16 || C->clear_upper_avx() == true)) ? true: false; // Generate vzeroupper 594 } 595 596 static int clear_avx_size() { 597 return generate_vzeroupper(Compile::current()) ? 3: 0; // vzeroupper 598 } 599 600 // !!!!! Special hack to get all types of calls to specify the byte offset 601 // from the start of the call to the point where the return address 602 // will point. 603 int MachCallStaticJavaNode::ret_addr_offset() 604 { 605 int offset = 5; // 5 bytes from start of call to where return address points 606 offset += clear_avx_size(); 607 return offset; 608 } 609 610 int MachCallDynamicJavaNode::ret_addr_offset() 611 { 612 int offset = 15; // 15 bytes from start of call to where return address points 613 offset += clear_avx_size(); 614 return offset; 615 } 616 617 int MachCallRuntimeNode::ret_addr_offset() { 618 if (_entry_point == nullptr) { 619 // CallLeafNoFPInDirect 620 return 3; // callq (register) 621 } 622 int offset = 13; // movq r10,#addr; callq (r10) 623 if (this->ideal_Opcode() != Op_CallLeafVector) { 624 offset += clear_avx_size(); 625 } 626 return offset; 627 } 628 629 // 630 // Compute padding required for nodes which need alignment 631 // 632 633 // The address of the call instruction needs to be 4-byte aligned to 634 // ensure that it does not span a cache line so that it can be patched. 635 int CallStaticJavaDirectNode::compute_padding(int current_offset) const 636 { 637 current_offset += clear_avx_size(); // skip vzeroupper 638 current_offset += 1; // skip call opcode byte 639 return align_up(current_offset, alignment_required()) - current_offset; 640 } 641 642 // The address of the call instruction needs to be 4-byte aligned to 643 // ensure that it does not span a cache line so that it can be patched. 644 int CallDynamicJavaDirectNode::compute_padding(int current_offset) const 645 { 646 current_offset += clear_avx_size(); // skip vzeroupper 647 current_offset += 11; // skip movq instruction + call opcode byte 648 return align_up(current_offset, alignment_required()) - current_offset; 649 } 650 651 // This could be in MacroAssembler but it's fairly C2 specific 652 static void emit_cmpfp_fixup(MacroAssembler* masm) { 653 Label exit; 654 __ jccb(Assembler::noParity, exit); 655 __ pushf(); 656 // 657 // comiss/ucomiss instructions set ZF,PF,CF flags and 658 // zero OF,AF,SF for NaN values. 659 // Fixup flags by zeroing ZF,PF so that compare of NaN 660 // values returns 'less than' result (CF is set). 661 // Leave the rest of flags unchanged. 662 // 663 // 7 6 5 4 3 2 1 0 664 // |S|Z|r|A|r|P|r|C| (r - reserved bit) 665 // 0 0 1 0 1 0 1 1 (0x2B) 666 // 667 __ andq(Address(rsp, 0), 0xffffff2b); 668 __ popf(); 669 __ bind(exit); 670 } 671 672 static void emit_cmpfp3(MacroAssembler* masm, Register dst) { 673 Label done; 674 __ movl(dst, -1); 675 __ jcc(Assembler::parity, done); 676 __ jcc(Assembler::below, done); 677 __ setcc(Assembler::notEqual, dst); 678 __ bind(done); 679 } 680 681 // Math.min() # Math.max() 682 // -------------------------- 683 // ucomis[s/d] # 684 // ja -> b # a 685 // jp -> NaN # NaN 686 // jb -> a # b 687 // je # 688 // |-jz -> a | b # a & b 689 // | -> a # 690 static void emit_fp_min_max(MacroAssembler* masm, XMMRegister dst, 691 XMMRegister a, XMMRegister b, 692 XMMRegister xmmt, Register rt, 693 bool min, bool single) { 694 695 Label nan, zero, below, above, done; 696 697 if (single) 698 __ ucomiss(a, b); 699 else 700 __ ucomisd(a, b); 701 702 if (dst->encoding() != (min ? b : a)->encoding()) 703 __ jccb(Assembler::above, above); // CF=0 & ZF=0 704 else 705 __ jccb(Assembler::above, done); 706 707 __ jccb(Assembler::parity, nan); // PF=1 708 __ jccb(Assembler::below, below); // CF=1 709 710 // equal 711 __ vpxor(xmmt, xmmt, xmmt, Assembler::AVX_128bit); 712 if (single) { 713 __ ucomiss(a, xmmt); 714 __ jccb(Assembler::equal, zero); 715 716 __ movflt(dst, a); 717 __ jmp(done); 718 } 719 else { 720 __ ucomisd(a, xmmt); 721 __ jccb(Assembler::equal, zero); 722 723 __ movdbl(dst, a); 724 __ jmp(done); 725 } 726 727 __ bind(zero); 728 if (min) 729 __ vpor(dst, a, b, Assembler::AVX_128bit); 730 else 731 __ vpand(dst, a, b, Assembler::AVX_128bit); 732 733 __ jmp(done); 734 735 __ bind(above); 736 if (single) 737 __ movflt(dst, min ? b : a); 738 else 739 __ movdbl(dst, min ? b : a); 740 741 __ jmp(done); 742 743 __ bind(nan); 744 if (single) { 745 __ movl(rt, 0x7fc00000); // Float.NaN 746 __ movdl(dst, rt); 747 } 748 else { 749 __ mov64(rt, 0x7ff8000000000000L); // Double.NaN 750 __ movdq(dst, rt); 751 } 752 __ jmp(done); 753 754 __ bind(below); 755 if (single) 756 __ movflt(dst, min ? a : b); 757 else 758 __ movdbl(dst, min ? a : b); 759 760 __ bind(done); 761 } 762 763 //============================================================================= 764 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; 765 766 int ConstantTable::calculate_table_base_offset() const { 767 return 0; // absolute addressing, no offset 768 } 769 770 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; } 771 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 772 ShouldNotReachHere(); 773 } 774 775 void MachConstantBaseNode::emit(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const { 776 // Empty encoding 777 } 778 779 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 780 return 0; 781 } 782 783 #ifndef PRODUCT 784 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 785 st->print("# MachConstantBaseNode (empty encoding)"); 786 } 787 #endif 788 789 790 //============================================================================= 791 #ifndef PRODUCT 792 void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 793 Compile* C = ra_->C; 794 795 int framesize = C->output()->frame_size_in_bytes(); 796 int bangsize = C->output()->bang_size_in_bytes(); 797 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 798 // Remove wordSize for return addr which is already pushed. 799 framesize -= wordSize; 800 801 if (C->output()->need_stack_bang(bangsize)) { 802 framesize -= wordSize; 803 st->print("# stack bang (%d bytes)", bangsize); 804 st->print("\n\t"); 805 st->print("pushq rbp\t# Save rbp"); 806 if (PreserveFramePointer) { 807 st->print("\n\t"); 808 st->print("movq rbp, rsp\t# Save the caller's SP into rbp"); 809 } 810 if (framesize) { 811 st->print("\n\t"); 812 st->print("subq rsp, #%d\t# Create frame",framesize); 813 } 814 } else { 815 st->print("subq rsp, #%d\t# Create frame",framesize); 816 st->print("\n\t"); 817 framesize -= wordSize; 818 st->print("movq [rsp + #%d], rbp\t# Save rbp",framesize); 819 if (PreserveFramePointer) { 820 st->print("\n\t"); 821 st->print("movq rbp, rsp\t# Save the caller's SP into rbp"); 822 if (framesize > 0) { 823 st->print("\n\t"); 824 st->print("addq rbp, #%d", framesize); 825 } 826 } 827 } 828 829 if (VerifyStackAtCalls) { 830 st->print("\n\t"); 831 framesize -= wordSize; 832 st->print("movq [rsp + #%d], 0xbadb100d\t# Majik cookie for stack depth check",framesize); 833 #ifdef ASSERT 834 st->print("\n\t"); 835 st->print("# stack alignment check"); 836 #endif 837 } 838 if (C->stub_function() != nullptr) { 839 st->print("\n\t"); 840 st->print("cmpl [r15_thread + #disarmed_guard_value_offset], #disarmed_guard_value\t"); 841 st->print("\n\t"); 842 st->print("je fast_entry\t"); 843 st->print("\n\t"); 844 st->print("call #nmethod_entry_barrier_stub\t"); 845 st->print("\n\tfast_entry:"); 846 } 847 st->cr(); 848 } 849 #endif 850 851 void MachPrologNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const { 852 Compile* C = ra_->C; 853 854 __ verified_entry(C); 855 856 if (ra_->C->stub_function() == nullptr) { 857 __ entry_barrier(); 858 } 859 860 if (!Compile::current()->output()->in_scratch_emit_size()) { 861 __ bind(*_verified_entry); 862 } 863 864 C->output()->set_frame_complete(__ offset()); 865 866 if (C->has_mach_constant_base_node()) { 867 // NOTE: We set the table base offset here because users might be 868 // emitted before MachConstantBaseNode. 869 ConstantTable& constant_table = C->output()->constant_table(); 870 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset()); 871 } 872 } 873 874 int MachPrologNode::reloc() const 875 { 876 return 0; // a large enough number 877 } 878 879 //============================================================================= 880 #ifndef PRODUCT 881 void MachEpilogNode::format(PhaseRegAlloc* ra_, outputStream* st) const 882 { 883 Compile* C = ra_->C; 884 if (generate_vzeroupper(C)) { 885 st->print("vzeroupper"); 886 st->cr(); st->print("\t"); 887 } 888 889 int framesize = C->output()->frame_size_in_bytes(); 890 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 891 // Remove word for return adr already pushed 892 // and RBP 893 framesize -= 2*wordSize; 894 895 if (framesize) { 896 st->print_cr("addq rsp, %d\t# Destroy frame", framesize); 897 st->print("\t"); 898 } 899 900 st->print_cr("popq rbp"); 901 if (do_polling() && C->is_method_compilation()) { 902 st->print("\t"); 903 st->print_cr("cmpq rsp, poll_offset[r15_thread] \n\t" 904 "ja #safepoint_stub\t" 905 "# Safepoint: poll for GC"); 906 } 907 } 908 #endif 909 910 void MachEpilogNode::emit(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const 911 { 912 Compile* C = ra_->C; 913 914 if (generate_vzeroupper(C)) { 915 // Clear upper bits of YMM registers when current compiled code uses 916 // wide vectors to avoid AVX <-> SSE transition penalty during call. 917 __ vzeroupper(); 918 } 919 920 // Subtract two words to account for return address and rbp 921 int initial_framesize = C->output()->frame_size_in_bytes() - 2*wordSize; 922 __ remove_frame(initial_framesize, C->needs_stack_repair()); 923 924 if (StackReservedPages > 0 && C->has_reserved_stack_access()) { 925 __ reserved_stack_check(); 926 } 927 928 if (do_polling() && C->is_method_compilation()) { 929 Label dummy_label; 930 Label* code_stub = &dummy_label; 931 if (!C->output()->in_scratch_emit_size()) { 932 C2SafepointPollStub* stub = new (C->comp_arena()) C2SafepointPollStub(__ offset()); 933 C->output()->add_stub(stub); 934 code_stub = &stub->entry(); 935 } 936 __ relocate(relocInfo::poll_return_type); 937 __ safepoint_poll(*code_stub, true /* at_return */, true /* in_nmethod */); 938 } 939 } 940 941 int MachEpilogNode::reloc() const 942 { 943 return 2; // a large enough number 944 } 945 946 const Pipeline* MachEpilogNode::pipeline() const 947 { 948 return MachNode::pipeline_class(); 949 } 950 951 //============================================================================= 952 953 enum RC { 954 rc_bad, 955 rc_int, 956 rc_kreg, 957 rc_float, 958 rc_stack 959 }; 960 961 static enum RC rc_class(OptoReg::Name reg) 962 { 963 if( !OptoReg::is_valid(reg) ) return rc_bad; 964 965 if (OptoReg::is_stack(reg)) return rc_stack; 966 967 VMReg r = OptoReg::as_VMReg(reg); 968 969 if (r->is_Register()) return rc_int; 970 971 if (r->is_KRegister()) return rc_kreg; 972 973 assert(r->is_XMMRegister(), "must be"); 974 return rc_float; 975 } 976 977 // Next two methods are shared by 32- and 64-bit VM. They are defined in x86.ad. 978 static void vec_mov_helper(C2_MacroAssembler *masm, int src_lo, int dst_lo, 979 int src_hi, int dst_hi, uint ireg, outputStream* st); 980 981 void vec_spill_helper(C2_MacroAssembler *masm, bool is_load, 982 int stack_offset, int reg, uint ireg, outputStream* st); 983 984 static void vec_stack_to_stack_helper(C2_MacroAssembler *masm, int src_offset, 985 int dst_offset, uint ireg, outputStream* st) { 986 if (masm) { 987 switch (ireg) { 988 case Op_VecS: 989 __ movq(Address(rsp, -8), rax); 990 __ movl(rax, Address(rsp, src_offset)); 991 __ movl(Address(rsp, dst_offset), rax); 992 __ movq(rax, Address(rsp, -8)); 993 break; 994 case Op_VecD: 995 __ pushq(Address(rsp, src_offset)); 996 __ popq (Address(rsp, dst_offset)); 997 break; 998 case Op_VecX: 999 __ pushq(Address(rsp, src_offset)); 1000 __ popq (Address(rsp, dst_offset)); 1001 __ pushq(Address(rsp, src_offset+8)); 1002 __ popq (Address(rsp, dst_offset+8)); 1003 break; 1004 case Op_VecY: 1005 __ vmovdqu(Address(rsp, -32), xmm0); 1006 __ vmovdqu(xmm0, Address(rsp, src_offset)); 1007 __ vmovdqu(Address(rsp, dst_offset), xmm0); 1008 __ vmovdqu(xmm0, Address(rsp, -32)); 1009 break; 1010 case Op_VecZ: 1011 __ evmovdquq(Address(rsp, -64), xmm0, 2); 1012 __ evmovdquq(xmm0, Address(rsp, src_offset), 2); 1013 __ evmovdquq(Address(rsp, dst_offset), xmm0, 2); 1014 __ evmovdquq(xmm0, Address(rsp, -64), 2); 1015 break; 1016 default: 1017 ShouldNotReachHere(); 1018 } 1019 #ifndef PRODUCT 1020 } else { 1021 switch (ireg) { 1022 case Op_VecS: 1023 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1024 "movl rax, [rsp + #%d]\n\t" 1025 "movl [rsp + #%d], rax\n\t" 1026 "movq rax, [rsp - #8]", 1027 src_offset, dst_offset); 1028 break; 1029 case Op_VecD: 1030 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1031 "popq [rsp + #%d]", 1032 src_offset, dst_offset); 1033 break; 1034 case Op_VecX: 1035 st->print("pushq [rsp + #%d]\t# 128-bit mem-mem spill\n\t" 1036 "popq [rsp + #%d]\n\t" 1037 "pushq [rsp + #%d]\n\t" 1038 "popq [rsp + #%d]", 1039 src_offset, dst_offset, src_offset+8, dst_offset+8); 1040 break; 1041 case Op_VecY: 1042 st->print("vmovdqu [rsp - #32], xmm0\t# 256-bit mem-mem spill\n\t" 1043 "vmovdqu xmm0, [rsp + #%d]\n\t" 1044 "vmovdqu [rsp + #%d], xmm0\n\t" 1045 "vmovdqu xmm0, [rsp - #32]", 1046 src_offset, dst_offset); 1047 break; 1048 case Op_VecZ: 1049 st->print("vmovdqu [rsp - #64], xmm0\t# 512-bit mem-mem spill\n\t" 1050 "vmovdqu xmm0, [rsp + #%d]\n\t" 1051 "vmovdqu [rsp + #%d], xmm0\n\t" 1052 "vmovdqu xmm0, [rsp - #64]", 1053 src_offset, dst_offset); 1054 break; 1055 default: 1056 ShouldNotReachHere(); 1057 } 1058 #endif 1059 } 1060 } 1061 1062 uint MachSpillCopyNode::implementation(C2_MacroAssembler* masm, 1063 PhaseRegAlloc* ra_, 1064 bool do_size, 1065 outputStream* st) const { 1066 assert(masm != nullptr || st != nullptr, "sanity"); 1067 // Get registers to move 1068 OptoReg::Name src_second = ra_->get_reg_second(in(1)); 1069 OptoReg::Name src_first = ra_->get_reg_first(in(1)); 1070 OptoReg::Name dst_second = ra_->get_reg_second(this); 1071 OptoReg::Name dst_first = ra_->get_reg_first(this); 1072 1073 enum RC src_second_rc = rc_class(src_second); 1074 enum RC src_first_rc = rc_class(src_first); 1075 enum RC dst_second_rc = rc_class(dst_second); 1076 enum RC dst_first_rc = rc_class(dst_first); 1077 1078 assert(OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), 1079 "must move at least 1 register" ); 1080 1081 if (src_first == dst_first && src_second == dst_second) { 1082 // Self copy, no move 1083 return 0; 1084 } 1085 if (bottom_type()->isa_vect() != nullptr && bottom_type()->isa_vectmask() == nullptr) { 1086 uint ireg = ideal_reg(); 1087 assert((src_first_rc != rc_int && dst_first_rc != rc_int), "sanity"); 1088 assert((ireg == Op_VecS || ireg == Op_VecD || ireg == Op_VecX || ireg == Op_VecY || ireg == Op_VecZ ), "sanity"); 1089 if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) { 1090 // mem -> mem 1091 int src_offset = ra_->reg2offset(src_first); 1092 int dst_offset = ra_->reg2offset(dst_first); 1093 vec_stack_to_stack_helper(masm, src_offset, dst_offset, ireg, st); 1094 } else if (src_first_rc == rc_float && dst_first_rc == rc_float ) { 1095 vec_mov_helper(masm, src_first, dst_first, src_second, dst_second, ireg, st); 1096 } else if (src_first_rc == rc_float && dst_first_rc == rc_stack ) { 1097 int stack_offset = ra_->reg2offset(dst_first); 1098 vec_spill_helper(masm, false, stack_offset, src_first, ireg, st); 1099 } else if (src_first_rc == rc_stack && dst_first_rc == rc_float ) { 1100 int stack_offset = ra_->reg2offset(src_first); 1101 vec_spill_helper(masm, true, stack_offset, dst_first, ireg, st); 1102 } else { 1103 ShouldNotReachHere(); 1104 } 1105 return 0; 1106 } 1107 if (src_first_rc == rc_stack) { 1108 // mem -> 1109 if (dst_first_rc == rc_stack) { 1110 // mem -> mem 1111 assert(src_second != dst_first, "overlap"); 1112 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1113 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1114 // 64-bit 1115 int src_offset = ra_->reg2offset(src_first); 1116 int dst_offset = ra_->reg2offset(dst_first); 1117 if (masm) { 1118 __ pushq(Address(rsp, src_offset)); 1119 __ popq (Address(rsp, dst_offset)); 1120 #ifndef PRODUCT 1121 } else { 1122 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1123 "popq [rsp + #%d]", 1124 src_offset, dst_offset); 1125 #endif 1126 } 1127 } else { 1128 // 32-bit 1129 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1130 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1131 // No pushl/popl, so: 1132 int src_offset = ra_->reg2offset(src_first); 1133 int dst_offset = ra_->reg2offset(dst_first); 1134 if (masm) { 1135 __ movq(Address(rsp, -8), rax); 1136 __ movl(rax, Address(rsp, src_offset)); 1137 __ movl(Address(rsp, dst_offset), rax); 1138 __ movq(rax, Address(rsp, -8)); 1139 #ifndef PRODUCT 1140 } else { 1141 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1142 "movl rax, [rsp + #%d]\n\t" 1143 "movl [rsp + #%d], rax\n\t" 1144 "movq rax, [rsp - #8]", 1145 src_offset, dst_offset); 1146 #endif 1147 } 1148 } 1149 return 0; 1150 } else if (dst_first_rc == rc_int) { 1151 // mem -> gpr 1152 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1153 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1154 // 64-bit 1155 int offset = ra_->reg2offset(src_first); 1156 if (masm) { 1157 __ movq(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1158 #ifndef PRODUCT 1159 } else { 1160 st->print("movq %s, [rsp + #%d]\t# spill", 1161 Matcher::regName[dst_first], 1162 offset); 1163 #endif 1164 } 1165 } else { 1166 // 32-bit 1167 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1168 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1169 int offset = ra_->reg2offset(src_first); 1170 if (masm) { 1171 __ movl(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1172 #ifndef PRODUCT 1173 } else { 1174 st->print("movl %s, [rsp + #%d]\t# spill", 1175 Matcher::regName[dst_first], 1176 offset); 1177 #endif 1178 } 1179 } 1180 return 0; 1181 } else if (dst_first_rc == rc_float) { 1182 // mem-> xmm 1183 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1184 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1185 // 64-bit 1186 int offset = ra_->reg2offset(src_first); 1187 if (masm) { 1188 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1189 #ifndef PRODUCT 1190 } else { 1191 st->print("%s %s, [rsp + #%d]\t# spill", 1192 UseXmmLoadAndClearUpper ? "movsd " : "movlpd", 1193 Matcher::regName[dst_first], 1194 offset); 1195 #endif 1196 } 1197 } else { 1198 // 32-bit 1199 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1200 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1201 int offset = ra_->reg2offset(src_first); 1202 if (masm) { 1203 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1204 #ifndef PRODUCT 1205 } else { 1206 st->print("movss %s, [rsp + #%d]\t# spill", 1207 Matcher::regName[dst_first], 1208 offset); 1209 #endif 1210 } 1211 } 1212 return 0; 1213 } else if (dst_first_rc == rc_kreg) { 1214 // mem -> kreg 1215 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1216 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1217 // 64-bit 1218 int offset = ra_->reg2offset(src_first); 1219 if (masm) { 1220 __ kmov(as_KRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1221 #ifndef PRODUCT 1222 } else { 1223 st->print("kmovq %s, [rsp + #%d]\t# spill", 1224 Matcher::regName[dst_first], 1225 offset); 1226 #endif 1227 } 1228 } 1229 return 0; 1230 } 1231 } else if (src_first_rc == rc_int) { 1232 // gpr -> 1233 if (dst_first_rc == rc_stack) { 1234 // gpr -> mem 1235 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1236 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1237 // 64-bit 1238 int offset = ra_->reg2offset(dst_first); 1239 if (masm) { 1240 __ movq(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1241 #ifndef PRODUCT 1242 } else { 1243 st->print("movq [rsp + #%d], %s\t# spill", 1244 offset, 1245 Matcher::regName[src_first]); 1246 #endif 1247 } 1248 } else { 1249 // 32-bit 1250 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1251 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1252 int offset = ra_->reg2offset(dst_first); 1253 if (masm) { 1254 __ movl(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1255 #ifndef PRODUCT 1256 } else { 1257 st->print("movl [rsp + #%d], %s\t# spill", 1258 offset, 1259 Matcher::regName[src_first]); 1260 #endif 1261 } 1262 } 1263 return 0; 1264 } else if (dst_first_rc == rc_int) { 1265 // gpr -> gpr 1266 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1267 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1268 // 64-bit 1269 if (masm) { 1270 __ movq(as_Register(Matcher::_regEncode[dst_first]), 1271 as_Register(Matcher::_regEncode[src_first])); 1272 #ifndef PRODUCT 1273 } else { 1274 st->print("movq %s, %s\t# spill", 1275 Matcher::regName[dst_first], 1276 Matcher::regName[src_first]); 1277 #endif 1278 } 1279 return 0; 1280 } else { 1281 // 32-bit 1282 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1283 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1284 if (masm) { 1285 __ movl(as_Register(Matcher::_regEncode[dst_first]), 1286 as_Register(Matcher::_regEncode[src_first])); 1287 #ifndef PRODUCT 1288 } else { 1289 st->print("movl %s, %s\t# spill", 1290 Matcher::regName[dst_first], 1291 Matcher::regName[src_first]); 1292 #endif 1293 } 1294 return 0; 1295 } 1296 } else if (dst_first_rc == rc_float) { 1297 // gpr -> xmm 1298 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1299 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1300 // 64-bit 1301 if (masm) { 1302 __ movdq( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1303 #ifndef PRODUCT 1304 } else { 1305 st->print("movdq %s, %s\t# spill", 1306 Matcher::regName[dst_first], 1307 Matcher::regName[src_first]); 1308 #endif 1309 } 1310 } else { 1311 // 32-bit 1312 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1313 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1314 if (masm) { 1315 __ movdl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1316 #ifndef PRODUCT 1317 } else { 1318 st->print("movdl %s, %s\t# spill", 1319 Matcher::regName[dst_first], 1320 Matcher::regName[src_first]); 1321 #endif 1322 } 1323 } 1324 return 0; 1325 } else if (dst_first_rc == rc_kreg) { 1326 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1327 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1328 // 64-bit 1329 if (masm) { 1330 __ kmov(as_KRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1331 #ifndef PRODUCT 1332 } else { 1333 st->print("kmovq %s, %s\t# spill", 1334 Matcher::regName[dst_first], 1335 Matcher::regName[src_first]); 1336 #endif 1337 } 1338 } 1339 Unimplemented(); 1340 return 0; 1341 } 1342 } else if (src_first_rc == rc_float) { 1343 // xmm -> 1344 if (dst_first_rc == rc_stack) { 1345 // xmm -> mem 1346 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1347 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1348 // 64-bit 1349 int offset = ra_->reg2offset(dst_first); 1350 if (masm) { 1351 __ movdbl( Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1352 #ifndef PRODUCT 1353 } else { 1354 st->print("movsd [rsp + #%d], %s\t# spill", 1355 offset, 1356 Matcher::regName[src_first]); 1357 #endif 1358 } 1359 } else { 1360 // 32-bit 1361 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1362 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1363 int offset = ra_->reg2offset(dst_first); 1364 if (masm) { 1365 __ movflt(Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1366 #ifndef PRODUCT 1367 } else { 1368 st->print("movss [rsp + #%d], %s\t# spill", 1369 offset, 1370 Matcher::regName[src_first]); 1371 #endif 1372 } 1373 } 1374 return 0; 1375 } else if (dst_first_rc == rc_int) { 1376 // xmm -> gpr 1377 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1378 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1379 // 64-bit 1380 if (masm) { 1381 __ movdq( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1382 #ifndef PRODUCT 1383 } else { 1384 st->print("movdq %s, %s\t# spill", 1385 Matcher::regName[dst_first], 1386 Matcher::regName[src_first]); 1387 #endif 1388 } 1389 } else { 1390 // 32-bit 1391 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1392 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1393 if (masm) { 1394 __ movdl( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1395 #ifndef PRODUCT 1396 } else { 1397 st->print("movdl %s, %s\t# spill", 1398 Matcher::regName[dst_first], 1399 Matcher::regName[src_first]); 1400 #endif 1401 } 1402 } 1403 return 0; 1404 } else if (dst_first_rc == rc_float) { 1405 // xmm -> xmm 1406 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1407 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1408 // 64-bit 1409 if (masm) { 1410 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1411 #ifndef PRODUCT 1412 } else { 1413 st->print("%s %s, %s\t# spill", 1414 UseXmmRegToRegMoveAll ? "movapd" : "movsd ", 1415 Matcher::regName[dst_first], 1416 Matcher::regName[src_first]); 1417 #endif 1418 } 1419 } else { 1420 // 32-bit 1421 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1422 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1423 if (masm) { 1424 __ movflt( 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 ? "movaps" : "movss ", 1429 Matcher::regName[dst_first], 1430 Matcher::regName[src_first]); 1431 #endif 1432 } 1433 } 1434 return 0; 1435 } else if (dst_first_rc == rc_kreg) { 1436 assert(false, "Illegal spilling"); 1437 return 0; 1438 } 1439 } else if (src_first_rc == rc_kreg) { 1440 if (dst_first_rc == rc_stack) { 1441 // mem -> kreg 1442 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1443 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1444 // 64-bit 1445 int offset = ra_->reg2offset(dst_first); 1446 if (masm) { 1447 __ kmov(Address(rsp, offset), as_KRegister(Matcher::_regEncode[src_first])); 1448 #ifndef PRODUCT 1449 } else { 1450 st->print("kmovq [rsp + #%d] , %s\t# spill", 1451 offset, 1452 Matcher::regName[src_first]); 1453 #endif 1454 } 1455 } 1456 return 0; 1457 } else if (dst_first_rc == rc_int) { 1458 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1459 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1460 // 64-bit 1461 if (masm) { 1462 __ kmov(as_Register(Matcher::_regEncode[dst_first]), as_KRegister(Matcher::_regEncode[src_first])); 1463 #ifndef PRODUCT 1464 } else { 1465 st->print("kmovq %s, %s\t# spill", 1466 Matcher::regName[dst_first], 1467 Matcher::regName[src_first]); 1468 #endif 1469 } 1470 } 1471 Unimplemented(); 1472 return 0; 1473 } else if (dst_first_rc == rc_kreg) { 1474 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1475 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1476 // 64-bit 1477 if (masm) { 1478 __ kmov(as_KRegister(Matcher::_regEncode[dst_first]), as_KRegister(Matcher::_regEncode[src_first])); 1479 #ifndef PRODUCT 1480 } else { 1481 st->print("kmovq %s, %s\t# spill", 1482 Matcher::regName[dst_first], 1483 Matcher::regName[src_first]); 1484 #endif 1485 } 1486 } 1487 return 0; 1488 } else if (dst_first_rc == rc_float) { 1489 assert(false, "Illegal spill"); 1490 return 0; 1491 } 1492 } 1493 1494 assert(0," foo "); 1495 Unimplemented(); 1496 return 0; 1497 } 1498 1499 #ifndef PRODUCT 1500 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream* st) const { 1501 implementation(nullptr, ra_, false, st); 1502 } 1503 #endif 1504 1505 void MachSpillCopyNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const { 1506 implementation(masm, ra_, false, nullptr); 1507 } 1508 1509 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1510 return MachNode::size(ra_); 1511 } 1512 1513 //============================================================================= 1514 #ifndef PRODUCT 1515 void BoxLockNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1516 { 1517 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1518 int reg = ra_->get_reg_first(this); 1519 st->print("leaq %s, [rsp + #%d]\t# box lock", 1520 Matcher::regName[reg], offset); 1521 } 1522 #endif 1523 1524 void BoxLockNode::emit(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const 1525 { 1526 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1527 int reg = ra_->get_encode(this); 1528 1529 __ lea(as_Register(reg), Address(rsp, offset)); 1530 } 1531 1532 uint BoxLockNode::size(PhaseRegAlloc *ra_) const 1533 { 1534 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1535 if (ra_->get_encode(this) > 15) { 1536 return (offset < 0x80) ? 6 : 9; // REX2 1537 } else { 1538 return (offset < 0x80) ? 5 : 8; // REX 1539 } 1540 } 1541 1542 //============================================================================= 1543 #ifndef PRODUCT 1544 void MachVEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1545 { 1546 st->print_cr("MachVEPNode"); 1547 } 1548 #endif 1549 1550 void MachVEPNode::emit(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const 1551 { 1552 CodeBuffer* cbuf = masm->code(); 1553 uint insts_size = cbuf->insts_size(); 1554 if (!_verified) { 1555 __ ic_check(1); 1556 } else { 1557 // TODO 8284443 Avoid creation of temporary frame 1558 if (ra_->C->stub_function() == nullptr) { 1559 __ verified_entry(ra_->C, 0); 1560 __ entry_barrier(); 1561 int initial_framesize = ra_->C->output()->frame_size_in_bytes() - 2*wordSize; 1562 __ remove_frame(initial_framesize, false); 1563 } 1564 // Unpack inline type args passed as oop and then jump to 1565 // the verified entry point (skipping the unverified entry). 1566 int sp_inc = __ unpack_inline_args(ra_->C, _receiver_only); 1567 // Emit code for verified entry and save increment for stack repair on return 1568 __ verified_entry(ra_->C, sp_inc); 1569 if (Compile::current()->output()->in_scratch_emit_size()) { 1570 Label dummy_verified_entry; 1571 __ jmp(dummy_verified_entry); 1572 } else { 1573 __ jmp(*_verified_entry); 1574 } 1575 } 1576 /* WARNING these NOPs are critical so that verified entry point is properly 1577 4 bytes aligned for patching by NativeJump::patch_verified_entry() */ 1578 int nops_cnt = 4 - ((cbuf->insts_size() - insts_size) & 0x3); 1579 nops_cnt &= 0x3; // Do not add nops if code is aligned. 1580 if (nops_cnt > 0) { 1581 __ nop(nops_cnt); 1582 } 1583 } 1584 1585 //============================================================================= 1586 #ifndef PRODUCT 1587 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1588 { 1589 if (UseCompressedClassPointers) { 1590 st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1591 st->print_cr("\tcmpl rscratch1, [rax + CompiledICData::speculated_klass_offset()]\t # Inline cache check"); 1592 } else { 1593 st->print_cr("movq rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1594 st->print_cr("\tcmpq rscratch1, [rax + CompiledICData::speculated_klass_offset()]\t # Inline cache check"); 1595 } 1596 st->print_cr("\tjne SharedRuntime::_ic_miss_stub"); 1597 } 1598 #endif 1599 1600 void MachUEPNode::emit(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const 1601 { 1602 __ ic_check(InteriorEntryAlignment); 1603 } 1604 1605 //============================================================================= 1606 1607 bool Matcher::supports_vector_calling_convention(void) { 1608 return EnableVectorSupport; 1609 } 1610 1611 OptoRegPair Matcher::vector_return_value(uint ideal_reg) { 1612 assert(EnableVectorSupport, "sanity"); 1613 int lo = XMM0_num; 1614 int hi = XMM0b_num; 1615 if (ideal_reg == Op_VecX) hi = XMM0d_num; 1616 else if (ideal_reg == Op_VecY) hi = XMM0h_num; 1617 else if (ideal_reg == Op_VecZ) hi = XMM0p_num; 1618 return OptoRegPair(hi, lo); 1619 } 1620 1621 // Is this branch offset short enough that a short branch can be used? 1622 // 1623 // NOTE: If the platform does not provide any short branch variants, then 1624 // this method should return false for offset 0. 1625 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 1626 // The passed offset is relative to address of the branch. 1627 // On 86 a branch displacement is calculated relative to address 1628 // of a next instruction. 1629 offset -= br_size; 1630 1631 // the short version of jmpConUCF2 contains multiple branches, 1632 // making the reach slightly less 1633 if (rule == jmpConUCF2_rule) 1634 return (-126 <= offset && offset <= 125); 1635 return (-128 <= offset && offset <= 127); 1636 } 1637 1638 // Return whether or not this register is ever used as an argument. 1639 // This function is used on startup to build the trampoline stubs in 1640 // generateOptoStub. Registers not mentioned will be killed by the VM 1641 // call in the trampoline, and arguments in those registers not be 1642 // available to the callee. 1643 bool Matcher::can_be_java_arg(int reg) 1644 { 1645 return 1646 reg == RDI_num || reg == RDI_H_num || 1647 reg == RSI_num || reg == RSI_H_num || 1648 reg == RDX_num || reg == RDX_H_num || 1649 reg == RCX_num || reg == RCX_H_num || 1650 reg == R8_num || reg == R8_H_num || 1651 reg == R9_num || reg == R9_H_num || 1652 reg == R12_num || reg == R12_H_num || 1653 reg == XMM0_num || reg == XMM0b_num || 1654 reg == XMM1_num || reg == XMM1b_num || 1655 reg == XMM2_num || reg == XMM2b_num || 1656 reg == XMM3_num || reg == XMM3b_num || 1657 reg == XMM4_num || reg == XMM4b_num || 1658 reg == XMM5_num || reg == XMM5b_num || 1659 reg == XMM6_num || reg == XMM6b_num || 1660 reg == XMM7_num || reg == XMM7b_num; 1661 } 1662 1663 bool Matcher::is_spillable_arg(int reg) 1664 { 1665 return can_be_java_arg(reg); 1666 } 1667 1668 uint Matcher::int_pressure_limit() 1669 { 1670 return (INTPRESSURE == -1) ? _INT_REG_mask.Size() : INTPRESSURE; 1671 } 1672 1673 uint Matcher::float_pressure_limit() 1674 { 1675 // After experiment around with different values, the following default threshold 1676 // works best for LCM's register pressure scheduling on x64. 1677 uint dec_count = VM_Version::supports_evex() ? 4 : 2; 1678 uint default_float_pressure_threshold = _FLOAT_REG_mask.Size() - dec_count; 1679 return (FLOATPRESSURE == -1) ? default_float_pressure_threshold : FLOATPRESSURE; 1680 } 1681 1682 bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) { 1683 // In 64 bit mode a code which use multiply when 1684 // devisor is constant is faster than hardware 1685 // DIV instruction (it uses MulHiL). 1686 return false; 1687 } 1688 1689 // Register for DIVI projection of divmodI 1690 RegMask Matcher::divI_proj_mask() { 1691 return INT_RAX_REG_mask(); 1692 } 1693 1694 // Register for MODI projection of divmodI 1695 RegMask Matcher::modI_proj_mask() { 1696 return INT_RDX_REG_mask(); 1697 } 1698 1699 // Register for DIVL projection of divmodL 1700 RegMask Matcher::divL_proj_mask() { 1701 return LONG_RAX_REG_mask(); 1702 } 1703 1704 // Register for MODL projection of divmodL 1705 RegMask Matcher::modL_proj_mask() { 1706 return LONG_RDX_REG_mask(); 1707 } 1708 1709 // Register for saving SP into on method handle invokes. Not used on x86_64. 1710 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 1711 return NO_REG_mask(); 1712 } 1713 1714 %} 1715 1716 //----------ENCODING BLOCK----------------------------------------------------- 1717 // This block specifies the encoding classes used by the compiler to 1718 // output byte streams. Encoding classes are parameterized macros 1719 // used by Machine Instruction Nodes in order to generate the bit 1720 // encoding of the instruction. Operands specify their base encoding 1721 // interface with the interface keyword. There are currently 1722 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & 1723 // COND_INTER. REG_INTER causes an operand to generate a function 1724 // which returns its register number when queried. CONST_INTER causes 1725 // an operand to generate a function which returns the value of the 1726 // constant when queried. MEMORY_INTER causes an operand to generate 1727 // four functions which return the Base Register, the Index Register, 1728 // the Scale Value, and the Offset Value of the operand when queried. 1729 // COND_INTER causes an operand to generate six functions which return 1730 // the encoding code (ie - encoding bits for the instruction) 1731 // associated with each basic boolean condition for a conditional 1732 // instruction. 1733 // 1734 // Instructions specify two basic values for encoding. Again, a 1735 // function is available to check if the constant displacement is an 1736 // oop. They use the ins_encode keyword to specify their encoding 1737 // classes (which must be a sequence of enc_class names, and their 1738 // parameters, specified in the encoding block), and they use the 1739 // opcode keyword to specify, in order, their primary, secondary, and 1740 // tertiary opcode. Only the opcode sections which a particular 1741 // instruction needs for encoding need to be specified. 1742 encode %{ 1743 enc_class cdql_enc(no_rax_rdx_RegI div) 1744 %{ 1745 // Full implementation of Java idiv and irem; checks for 1746 // special case as described in JVM spec., p.243 & p.271. 1747 // 1748 // normal case special case 1749 // 1750 // input : rax: dividend min_int 1751 // reg: divisor -1 1752 // 1753 // output: rax: quotient (= rax idiv reg) min_int 1754 // rdx: remainder (= rax irem reg) 0 1755 // 1756 // Code sequnce: 1757 // 1758 // 0: 3d 00 00 00 80 cmp $0x80000000,%eax 1759 // 5: 75 07/08 jne e <normal> 1760 // 7: 33 d2 xor %edx,%edx 1761 // [div >= 8 -> offset + 1] 1762 // [REX_B] 1763 // 9: 83 f9 ff cmp $0xffffffffffffffff,$div 1764 // c: 74 03/04 je 11 <done> 1765 // 000000000000000e <normal>: 1766 // e: 99 cltd 1767 // [div >= 8 -> offset + 1] 1768 // [REX_B] 1769 // f: f7 f9 idiv $div 1770 // 0000000000000011 <done>: 1771 Label normal; 1772 Label done; 1773 1774 // cmp $0x80000000,%eax 1775 __ cmpl(as_Register(RAX_enc), 0x80000000); 1776 1777 // jne e <normal> 1778 __ jccb(Assembler::notEqual, normal); 1779 1780 // xor %edx,%edx 1781 __ xorl(as_Register(RDX_enc), as_Register(RDX_enc)); 1782 1783 // cmp $0xffffffffffffffff,%ecx 1784 __ cmpl($div$$Register, -1); 1785 1786 // je 11 <done> 1787 __ jccb(Assembler::equal, done); 1788 1789 // <normal> 1790 // cltd 1791 __ bind(normal); 1792 __ cdql(); 1793 1794 // idivl 1795 // <done> 1796 __ idivl($div$$Register); 1797 __ bind(done); 1798 %} 1799 1800 enc_class cdqq_enc(no_rax_rdx_RegL div) 1801 %{ 1802 // Full implementation of Java ldiv and lrem; checks for 1803 // special case as described in JVM spec., p.243 & p.271. 1804 // 1805 // normal case special case 1806 // 1807 // input : rax: dividend min_long 1808 // reg: divisor -1 1809 // 1810 // output: rax: quotient (= rax idiv reg) min_long 1811 // rdx: remainder (= rax irem reg) 0 1812 // 1813 // Code sequnce: 1814 // 1815 // 0: 48 ba 00 00 00 00 00 mov $0x8000000000000000,%rdx 1816 // 7: 00 00 80 1817 // a: 48 39 d0 cmp %rdx,%rax 1818 // d: 75 08 jne 17 <normal> 1819 // f: 33 d2 xor %edx,%edx 1820 // 11: 48 83 f9 ff cmp $0xffffffffffffffff,$div 1821 // 15: 74 05 je 1c <done> 1822 // 0000000000000017 <normal>: 1823 // 17: 48 99 cqto 1824 // 19: 48 f7 f9 idiv $div 1825 // 000000000000001c <done>: 1826 Label normal; 1827 Label done; 1828 1829 // mov $0x8000000000000000,%rdx 1830 __ mov64(as_Register(RDX_enc), 0x8000000000000000); 1831 1832 // cmp %rdx,%rax 1833 __ cmpq(as_Register(RAX_enc), as_Register(RDX_enc)); 1834 1835 // jne 17 <normal> 1836 __ jccb(Assembler::notEqual, normal); 1837 1838 // xor %edx,%edx 1839 __ xorl(as_Register(RDX_enc), as_Register(RDX_enc)); 1840 1841 // cmp $0xffffffffffffffff,$div 1842 __ cmpq($div$$Register, -1); 1843 1844 // je 1e <done> 1845 __ jccb(Assembler::equal, done); 1846 1847 // <normal> 1848 // cqto 1849 __ bind(normal); 1850 __ cdqq(); 1851 1852 // idivq (note: must be emitted by the user of this rule) 1853 // <done> 1854 __ idivq($div$$Register); 1855 __ bind(done); 1856 %} 1857 1858 enc_class clear_avx %{ 1859 DEBUG_ONLY(int off0 = __ offset()); 1860 if (generate_vzeroupper(Compile::current())) { 1861 // Clear upper bits of YMM registers to avoid AVX <-> SSE transition penalty 1862 // Clear upper bits of YMM registers when current compiled code uses 1863 // wide vectors to avoid AVX <-> SSE transition penalty during call. 1864 __ vzeroupper(); 1865 } 1866 DEBUG_ONLY(int off1 = __ offset()); 1867 assert(off1 - off0 == clear_avx_size(), "correct size prediction"); 1868 %} 1869 1870 enc_class Java_To_Runtime(method meth) %{ 1871 __ lea(r10, RuntimeAddress((address)$meth$$method)); 1872 __ call(r10); 1873 __ post_call_nop(); 1874 %} 1875 1876 enc_class Java_Static_Call(method meth) 1877 %{ 1878 // JAVA STATIC CALL 1879 // CALL to fixup routine. Fixup routine uses ScopeDesc info to 1880 // determine who we intended to call. 1881 if (!_method) { 1882 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, $meth$$method))); 1883 } else if (_method->intrinsic_id() == vmIntrinsicID::_ensureMaterializedForStackWalk) { 1884 // The NOP here is purely to ensure that eliding a call to 1885 // JVM_EnsureMaterializedForStackWalk doesn't change the code size. 1886 __ addr_nop_5(); 1887 __ block_comment("call JVM_EnsureMaterializedForStackWalk (elided)"); 1888 } else { 1889 int method_index = resolved_method_index(masm); 1890 RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 1891 : static_call_Relocation::spec(method_index); 1892 address mark = __ pc(); 1893 int call_offset = __ offset(); 1894 __ call(AddressLiteral(CAST_FROM_FN_PTR(address, $meth$$method), rspec)); 1895 if (CodeBuffer::supports_shared_stubs() && _method->can_be_statically_bound()) { 1896 // Calls of the same statically bound method can share 1897 // a stub to the interpreter. 1898 __ code()->shared_stub_to_interp_for(_method, call_offset); 1899 } else { 1900 // Emit stubs for static call. 1901 address stub = CompiledDirectCall::emit_to_interp_stub(masm, mark); 1902 __ clear_inst_mark(); 1903 if (stub == nullptr) { 1904 ciEnv::current()->record_failure("CodeCache is full"); 1905 return; 1906 } 1907 } 1908 } 1909 __ post_call_nop(); 1910 %} 1911 1912 enc_class Java_Dynamic_Call(method meth) %{ 1913 __ ic_call((address)$meth$$method, resolved_method_index(masm)); 1914 __ post_call_nop(); 1915 %} 1916 1917 %} 1918 1919 1920 1921 //----------FRAME-------------------------------------------------------------- 1922 // Definition of frame structure and management information. 1923 // 1924 // S T A C K L A Y O U T Allocators stack-slot number 1925 // | (to get allocators register number 1926 // G Owned by | | v add OptoReg::stack0()) 1927 // r CALLER | | 1928 // o | +--------+ pad to even-align allocators stack-slot 1929 // w V | pad0 | numbers; owned by CALLER 1930 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned 1931 // h ^ | in | 5 1932 // | | args | 4 Holes in incoming args owned by SELF 1933 // | | | | 3 1934 // | | +--------+ 1935 // V | | old out| Empty on Intel, window on Sparc 1936 // | old |preserve| Must be even aligned. 1937 // | SP-+--------+----> Matcher::_old_SP, even aligned 1938 // | | in | 3 area for Intel ret address 1939 // Owned by |preserve| Empty on Sparc. 1940 // SELF +--------+ 1941 // | | pad2 | 2 pad to align old SP 1942 // | +--------+ 1 1943 // | | locks | 0 1944 // | +--------+----> OptoReg::stack0(), even aligned 1945 // | | pad1 | 11 pad to align new SP 1946 // | +--------+ 1947 // | | | 10 1948 // | | spills | 9 spills 1949 // V | | 8 (pad0 slot for callee) 1950 // -----------+--------+----> Matcher::_out_arg_limit, unaligned 1951 // ^ | out | 7 1952 // | | args | 6 Holes in outgoing args owned by CALLEE 1953 // Owned by +--------+ 1954 // CALLEE | new out| 6 Empty on Intel, window on Sparc 1955 // | new |preserve| Must be even-aligned. 1956 // | SP-+--------+----> Matcher::_new_SP, even aligned 1957 // | | | 1958 // 1959 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 1960 // known from SELF's arguments and the Java calling convention. 1961 // Region 6-7 is determined per call site. 1962 // Note 2: If the calling convention leaves holes in the incoming argument 1963 // area, those holes are owned by SELF. Holes in the outgoing area 1964 // are owned by the CALLEE. Holes should not be necessary in the 1965 // incoming area, as the Java calling convention is completely under 1966 // the control of the AD file. Doubles can be sorted and packed to 1967 // avoid holes. Holes in the outgoing arguments may be necessary for 1968 // varargs C calling conventions. 1969 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 1970 // even aligned with pad0 as needed. 1971 // Region 6 is even aligned. Region 6-7 is NOT even aligned; 1972 // region 6-11 is even aligned; it may be padded out more so that 1973 // the region from SP to FP meets the minimum stack alignment. 1974 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 1975 // alignment. Region 11, pad1, may be dynamically extended so that 1976 // SP meets the minimum alignment. 1977 1978 frame 1979 %{ 1980 // These three registers define part of the calling convention 1981 // between compiled code and the interpreter. 1982 inline_cache_reg(RAX); // Inline Cache Register 1983 1984 // Optional: name the operand used by cisc-spilling to access 1985 // [stack_pointer + offset] 1986 cisc_spilling_operand_name(indOffset32); 1987 1988 // Number of stack slots consumed by locking an object 1989 sync_stack_slots(2); 1990 1991 // Compiled code's Frame Pointer 1992 frame_pointer(RSP); 1993 1994 // Interpreter stores its frame pointer in a register which is 1995 // stored to the stack by I2CAdaptors. 1996 // I2CAdaptors convert from interpreted java to compiled java. 1997 interpreter_frame_pointer(RBP); 1998 1999 // Stack alignment requirement 2000 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 2001 2002 // Number of outgoing stack slots killed above the out_preserve_stack_slots 2003 // for calls to C. Supports the var-args backing area for register parms. 2004 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 2005 2006 // The after-PROLOG location of the return address. Location of 2007 // return address specifies a type (REG or STACK) and a number 2008 // representing the register number (i.e. - use a register name) or 2009 // stack slot. 2010 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 2011 // Otherwise, it is above the locks and verification slot and alignment word 2012 return_addr(STACK - 2 + 2013 align_up((Compile::current()->in_preserve_stack_slots() + 2014 Compile::current()->fixed_slots()), 2015 stack_alignment_in_slots())); 2016 2017 // Location of compiled Java return values. Same as C for now. 2018 return_value 2019 %{ 2020 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 2021 "only return normal values"); 2022 2023 static const int lo[Op_RegL + 1] = { 2024 0, 2025 0, 2026 RAX_num, // Op_RegN 2027 RAX_num, // Op_RegI 2028 RAX_num, // Op_RegP 2029 XMM0_num, // Op_RegF 2030 XMM0_num, // Op_RegD 2031 RAX_num // Op_RegL 2032 }; 2033 static const int hi[Op_RegL + 1] = { 2034 0, 2035 0, 2036 OptoReg::Bad, // Op_RegN 2037 OptoReg::Bad, // Op_RegI 2038 RAX_H_num, // Op_RegP 2039 OptoReg::Bad, // Op_RegF 2040 XMM0b_num, // Op_RegD 2041 RAX_H_num // Op_RegL 2042 }; 2043 // Excluded flags and vector registers. 2044 assert(ARRAY_SIZE(hi) == _last_machine_leaf - 8, "missing type"); 2045 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 2046 %} 2047 %} 2048 2049 //----------ATTRIBUTES--------------------------------------------------------- 2050 //----------Operand Attributes------------------------------------------------- 2051 op_attrib op_cost(0); // Required cost attribute 2052 2053 //----------Instruction Attributes--------------------------------------------- 2054 ins_attrib ins_cost(100); // Required cost attribute 2055 ins_attrib ins_size(8); // Required size attribute (in bits) 2056 ins_attrib ins_short_branch(0); // Required flag: is this instruction 2057 // a non-matching short branch variant 2058 // of some long branch? 2059 ins_attrib ins_alignment(1); // Required alignment attribute (must 2060 // be a power of 2) specifies the 2061 // alignment that some part of the 2062 // instruction (not necessarily the 2063 // start) requires. If > 1, a 2064 // compute_padding() function must be 2065 // provided for the instruction 2066 2067 // Whether this node is expanded during code emission into a sequence of 2068 // instructions and the first instruction can perform an implicit null check. 2069 ins_attrib ins_is_late_expanded_null_check_candidate(false); 2070 2071 //----------OPERANDS----------------------------------------------------------- 2072 // Operand definitions must precede instruction definitions for correct parsing 2073 // in the ADLC because operands constitute user defined types which are used in 2074 // instruction definitions. 2075 2076 //----------Simple Operands---------------------------------------------------- 2077 // Immediate Operands 2078 // Integer Immediate 2079 operand immI() 2080 %{ 2081 match(ConI); 2082 2083 op_cost(10); 2084 format %{ %} 2085 interface(CONST_INTER); 2086 %} 2087 2088 // Constant for test vs zero 2089 operand immI_0() 2090 %{ 2091 predicate(n->get_int() == 0); 2092 match(ConI); 2093 2094 op_cost(0); 2095 format %{ %} 2096 interface(CONST_INTER); 2097 %} 2098 2099 // Constant for increment 2100 operand immI_1() 2101 %{ 2102 predicate(n->get_int() == 1); 2103 match(ConI); 2104 2105 op_cost(0); 2106 format %{ %} 2107 interface(CONST_INTER); 2108 %} 2109 2110 // Constant for decrement 2111 operand immI_M1() 2112 %{ 2113 predicate(n->get_int() == -1); 2114 match(ConI); 2115 2116 op_cost(0); 2117 format %{ %} 2118 interface(CONST_INTER); 2119 %} 2120 2121 operand immI_2() 2122 %{ 2123 predicate(n->get_int() == 2); 2124 match(ConI); 2125 2126 op_cost(0); 2127 format %{ %} 2128 interface(CONST_INTER); 2129 %} 2130 2131 operand immI_4() 2132 %{ 2133 predicate(n->get_int() == 4); 2134 match(ConI); 2135 2136 op_cost(0); 2137 format %{ %} 2138 interface(CONST_INTER); 2139 %} 2140 2141 operand immI_8() 2142 %{ 2143 predicate(n->get_int() == 8); 2144 match(ConI); 2145 2146 op_cost(0); 2147 format %{ %} 2148 interface(CONST_INTER); 2149 %} 2150 2151 // Valid scale values for addressing modes 2152 operand immI2() 2153 %{ 2154 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 2155 match(ConI); 2156 2157 format %{ %} 2158 interface(CONST_INTER); 2159 %} 2160 2161 operand immU7() 2162 %{ 2163 predicate((0 <= n->get_int()) && (n->get_int() <= 0x7F)); 2164 match(ConI); 2165 2166 op_cost(5); 2167 format %{ %} 2168 interface(CONST_INTER); 2169 %} 2170 2171 operand immI8() 2172 %{ 2173 predicate((-0x80 <= n->get_int()) && (n->get_int() < 0x80)); 2174 match(ConI); 2175 2176 op_cost(5); 2177 format %{ %} 2178 interface(CONST_INTER); 2179 %} 2180 2181 operand immU8() 2182 %{ 2183 predicate((0 <= n->get_int()) && (n->get_int() <= 255)); 2184 match(ConI); 2185 2186 op_cost(5); 2187 format %{ %} 2188 interface(CONST_INTER); 2189 %} 2190 2191 operand immI16() 2192 %{ 2193 predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767)); 2194 match(ConI); 2195 2196 op_cost(10); 2197 format %{ %} 2198 interface(CONST_INTER); 2199 %} 2200 2201 // Int Immediate non-negative 2202 operand immU31() 2203 %{ 2204 predicate(n->get_int() >= 0); 2205 match(ConI); 2206 2207 op_cost(0); 2208 format %{ %} 2209 interface(CONST_INTER); 2210 %} 2211 2212 // Pointer Immediate 2213 operand immP() 2214 %{ 2215 match(ConP); 2216 2217 op_cost(10); 2218 format %{ %} 2219 interface(CONST_INTER); 2220 %} 2221 2222 // Null Pointer Immediate 2223 operand immP0() 2224 %{ 2225 predicate(n->get_ptr() == 0); 2226 match(ConP); 2227 2228 op_cost(5); 2229 format %{ %} 2230 interface(CONST_INTER); 2231 %} 2232 2233 // Pointer Immediate 2234 operand immN() %{ 2235 match(ConN); 2236 2237 op_cost(10); 2238 format %{ %} 2239 interface(CONST_INTER); 2240 %} 2241 2242 operand immNKlass() %{ 2243 match(ConNKlass); 2244 2245 op_cost(10); 2246 format %{ %} 2247 interface(CONST_INTER); 2248 %} 2249 2250 // Null Pointer Immediate 2251 operand immN0() %{ 2252 predicate(n->get_narrowcon() == 0); 2253 match(ConN); 2254 2255 op_cost(5); 2256 format %{ %} 2257 interface(CONST_INTER); 2258 %} 2259 2260 operand immP31() 2261 %{ 2262 predicate(n->as_Type()->type()->reloc() == relocInfo::none 2263 && (n->get_ptr() >> 31) == 0); 2264 match(ConP); 2265 2266 op_cost(5); 2267 format %{ %} 2268 interface(CONST_INTER); 2269 %} 2270 2271 2272 // Long Immediate 2273 operand immL() 2274 %{ 2275 match(ConL); 2276 2277 op_cost(20); 2278 format %{ %} 2279 interface(CONST_INTER); 2280 %} 2281 2282 // Long Immediate 8-bit 2283 operand immL8() 2284 %{ 2285 predicate(-0x80L <= n->get_long() && n->get_long() < 0x80L); 2286 match(ConL); 2287 2288 op_cost(5); 2289 format %{ %} 2290 interface(CONST_INTER); 2291 %} 2292 2293 // Long Immediate 32-bit unsigned 2294 operand immUL32() 2295 %{ 2296 predicate(n->get_long() == (unsigned int) (n->get_long())); 2297 match(ConL); 2298 2299 op_cost(10); 2300 format %{ %} 2301 interface(CONST_INTER); 2302 %} 2303 2304 // Long Immediate 32-bit signed 2305 operand immL32() 2306 %{ 2307 predicate(n->get_long() == (int) (n->get_long())); 2308 match(ConL); 2309 2310 op_cost(15); 2311 format %{ %} 2312 interface(CONST_INTER); 2313 %} 2314 2315 operand immL_Pow2() 2316 %{ 2317 predicate(is_power_of_2((julong)n->get_long())); 2318 match(ConL); 2319 2320 op_cost(15); 2321 format %{ %} 2322 interface(CONST_INTER); 2323 %} 2324 2325 operand immL_NotPow2() 2326 %{ 2327 predicate(is_power_of_2((julong)~n->get_long())); 2328 match(ConL); 2329 2330 op_cost(15); 2331 format %{ %} 2332 interface(CONST_INTER); 2333 %} 2334 2335 // Long Immediate zero 2336 operand immL0() 2337 %{ 2338 predicate(n->get_long() == 0L); 2339 match(ConL); 2340 2341 op_cost(10); 2342 format %{ %} 2343 interface(CONST_INTER); 2344 %} 2345 2346 // Constant for increment 2347 operand immL1() 2348 %{ 2349 predicate(n->get_long() == 1); 2350 match(ConL); 2351 2352 format %{ %} 2353 interface(CONST_INTER); 2354 %} 2355 2356 // Constant for decrement 2357 operand immL_M1() 2358 %{ 2359 predicate(n->get_long() == -1); 2360 match(ConL); 2361 2362 format %{ %} 2363 interface(CONST_INTER); 2364 %} 2365 2366 // Long Immediate: low 32-bit mask 2367 operand immL_32bits() 2368 %{ 2369 predicate(n->get_long() == 0xFFFFFFFFL); 2370 match(ConL); 2371 op_cost(20); 2372 2373 format %{ %} 2374 interface(CONST_INTER); 2375 %} 2376 2377 // Int Immediate: 2^n-1, positive 2378 operand immI_Pow2M1() 2379 %{ 2380 predicate((n->get_int() > 0) 2381 && is_power_of_2((juint)n->get_int() + 1)); 2382 match(ConI); 2383 2384 op_cost(20); 2385 format %{ %} 2386 interface(CONST_INTER); 2387 %} 2388 2389 // Float Immediate zero 2390 operand immF0() 2391 %{ 2392 predicate(jint_cast(n->getf()) == 0); 2393 match(ConF); 2394 2395 op_cost(5); 2396 format %{ %} 2397 interface(CONST_INTER); 2398 %} 2399 2400 // Float Immediate 2401 operand immF() 2402 %{ 2403 match(ConF); 2404 2405 op_cost(15); 2406 format %{ %} 2407 interface(CONST_INTER); 2408 %} 2409 2410 // Half Float Immediate 2411 operand immH() 2412 %{ 2413 match(ConH); 2414 2415 op_cost(15); 2416 format %{ %} 2417 interface(CONST_INTER); 2418 %} 2419 2420 // Double Immediate zero 2421 operand immD0() 2422 %{ 2423 predicate(jlong_cast(n->getd()) == 0); 2424 match(ConD); 2425 2426 op_cost(5); 2427 format %{ %} 2428 interface(CONST_INTER); 2429 %} 2430 2431 // Double Immediate 2432 operand immD() 2433 %{ 2434 match(ConD); 2435 2436 op_cost(15); 2437 format %{ %} 2438 interface(CONST_INTER); 2439 %} 2440 2441 // Immediates for special shifts (sign extend) 2442 2443 // Constants for increment 2444 operand immI_16() 2445 %{ 2446 predicate(n->get_int() == 16); 2447 match(ConI); 2448 2449 format %{ %} 2450 interface(CONST_INTER); 2451 %} 2452 2453 operand immI_24() 2454 %{ 2455 predicate(n->get_int() == 24); 2456 match(ConI); 2457 2458 format %{ %} 2459 interface(CONST_INTER); 2460 %} 2461 2462 // Constant for byte-wide masking 2463 operand immI_255() 2464 %{ 2465 predicate(n->get_int() == 255); 2466 match(ConI); 2467 2468 format %{ %} 2469 interface(CONST_INTER); 2470 %} 2471 2472 // Constant for short-wide masking 2473 operand immI_65535() 2474 %{ 2475 predicate(n->get_int() == 65535); 2476 match(ConI); 2477 2478 format %{ %} 2479 interface(CONST_INTER); 2480 %} 2481 2482 // Constant for byte-wide masking 2483 operand immL_255() 2484 %{ 2485 predicate(n->get_long() == 255); 2486 match(ConL); 2487 2488 format %{ %} 2489 interface(CONST_INTER); 2490 %} 2491 2492 // Constant for short-wide masking 2493 operand immL_65535() 2494 %{ 2495 predicate(n->get_long() == 65535); 2496 match(ConL); 2497 2498 format %{ %} 2499 interface(CONST_INTER); 2500 %} 2501 2502 operand kReg() 2503 %{ 2504 constraint(ALLOC_IN_RC(vectmask_reg)); 2505 match(RegVectMask); 2506 format %{%} 2507 interface(REG_INTER); 2508 %} 2509 2510 // Register Operands 2511 // Integer Register 2512 operand rRegI() 2513 %{ 2514 constraint(ALLOC_IN_RC(int_reg)); 2515 match(RegI); 2516 2517 match(rax_RegI); 2518 match(rbx_RegI); 2519 match(rcx_RegI); 2520 match(rdx_RegI); 2521 match(rdi_RegI); 2522 2523 format %{ %} 2524 interface(REG_INTER); 2525 %} 2526 2527 // Special Registers 2528 operand rax_RegI() 2529 %{ 2530 constraint(ALLOC_IN_RC(int_rax_reg)); 2531 match(RegI); 2532 match(rRegI); 2533 2534 format %{ "RAX" %} 2535 interface(REG_INTER); 2536 %} 2537 2538 // Special Registers 2539 operand rbx_RegI() 2540 %{ 2541 constraint(ALLOC_IN_RC(int_rbx_reg)); 2542 match(RegI); 2543 match(rRegI); 2544 2545 format %{ "RBX" %} 2546 interface(REG_INTER); 2547 %} 2548 2549 operand rcx_RegI() 2550 %{ 2551 constraint(ALLOC_IN_RC(int_rcx_reg)); 2552 match(RegI); 2553 match(rRegI); 2554 2555 format %{ "RCX" %} 2556 interface(REG_INTER); 2557 %} 2558 2559 operand rdx_RegI() 2560 %{ 2561 constraint(ALLOC_IN_RC(int_rdx_reg)); 2562 match(RegI); 2563 match(rRegI); 2564 2565 format %{ "RDX" %} 2566 interface(REG_INTER); 2567 %} 2568 2569 operand rdi_RegI() 2570 %{ 2571 constraint(ALLOC_IN_RC(int_rdi_reg)); 2572 match(RegI); 2573 match(rRegI); 2574 2575 format %{ "RDI" %} 2576 interface(REG_INTER); 2577 %} 2578 2579 operand no_rax_rdx_RegI() 2580 %{ 2581 constraint(ALLOC_IN_RC(int_no_rax_rdx_reg)); 2582 match(RegI); 2583 match(rbx_RegI); 2584 match(rcx_RegI); 2585 match(rdi_RegI); 2586 2587 format %{ %} 2588 interface(REG_INTER); 2589 %} 2590 2591 operand no_rbp_r13_RegI() 2592 %{ 2593 constraint(ALLOC_IN_RC(int_no_rbp_r13_reg)); 2594 match(RegI); 2595 match(rRegI); 2596 match(rax_RegI); 2597 match(rbx_RegI); 2598 match(rcx_RegI); 2599 match(rdx_RegI); 2600 match(rdi_RegI); 2601 2602 format %{ %} 2603 interface(REG_INTER); 2604 %} 2605 2606 // Pointer Register 2607 operand any_RegP() 2608 %{ 2609 constraint(ALLOC_IN_RC(any_reg)); 2610 match(RegP); 2611 match(rax_RegP); 2612 match(rbx_RegP); 2613 match(rdi_RegP); 2614 match(rsi_RegP); 2615 match(rbp_RegP); 2616 match(r15_RegP); 2617 match(rRegP); 2618 2619 format %{ %} 2620 interface(REG_INTER); 2621 %} 2622 2623 operand rRegP() 2624 %{ 2625 constraint(ALLOC_IN_RC(ptr_reg)); 2626 match(RegP); 2627 match(rax_RegP); 2628 match(rbx_RegP); 2629 match(rdi_RegP); 2630 match(rsi_RegP); 2631 match(rbp_RegP); // See Q&A below about 2632 match(r15_RegP); // r15_RegP and rbp_RegP. 2633 2634 format %{ %} 2635 interface(REG_INTER); 2636 %} 2637 2638 operand rRegN() %{ 2639 constraint(ALLOC_IN_RC(int_reg)); 2640 match(RegN); 2641 2642 format %{ %} 2643 interface(REG_INTER); 2644 %} 2645 2646 // Question: Why is r15_RegP (the read-only TLS register) a match for rRegP? 2647 // Answer: Operand match rules govern the DFA as it processes instruction inputs. 2648 // It's fine for an instruction input that expects rRegP to match a r15_RegP. 2649 // The output of an instruction is controlled by the allocator, which respects 2650 // register class masks, not match rules. Unless an instruction mentions 2651 // r15_RegP or any_RegP explicitly as its output, r15 will not be considered 2652 // by the allocator as an input. 2653 // The same logic applies to rbp_RegP being a match for rRegP: If PreserveFramePointer==true, 2654 // the RBP is used as a proper frame pointer and is not included in ptr_reg. As a 2655 // result, RBP is not included in the output of the instruction either. 2656 2657 // This operand is not allowed to use RBP even if 2658 // RBP is not used to hold the frame pointer. 2659 operand no_rbp_RegP() 2660 %{ 2661 constraint(ALLOC_IN_RC(ptr_reg_no_rbp)); 2662 match(RegP); 2663 match(rbx_RegP); 2664 match(rsi_RegP); 2665 match(rdi_RegP); 2666 2667 format %{ %} 2668 interface(REG_INTER); 2669 %} 2670 2671 // Special Registers 2672 // Return a pointer value 2673 operand rax_RegP() 2674 %{ 2675 constraint(ALLOC_IN_RC(ptr_rax_reg)); 2676 match(RegP); 2677 match(rRegP); 2678 2679 format %{ %} 2680 interface(REG_INTER); 2681 %} 2682 2683 // Special Registers 2684 // Return a compressed pointer value 2685 operand rax_RegN() 2686 %{ 2687 constraint(ALLOC_IN_RC(int_rax_reg)); 2688 match(RegN); 2689 match(rRegN); 2690 2691 format %{ %} 2692 interface(REG_INTER); 2693 %} 2694 2695 // Used in AtomicAdd 2696 operand rbx_RegP() 2697 %{ 2698 constraint(ALLOC_IN_RC(ptr_rbx_reg)); 2699 match(RegP); 2700 match(rRegP); 2701 2702 format %{ %} 2703 interface(REG_INTER); 2704 %} 2705 2706 operand rsi_RegP() 2707 %{ 2708 constraint(ALLOC_IN_RC(ptr_rsi_reg)); 2709 match(RegP); 2710 match(rRegP); 2711 2712 format %{ %} 2713 interface(REG_INTER); 2714 %} 2715 2716 operand rbp_RegP() 2717 %{ 2718 constraint(ALLOC_IN_RC(ptr_rbp_reg)); 2719 match(RegP); 2720 match(rRegP); 2721 2722 format %{ %} 2723 interface(REG_INTER); 2724 %} 2725 2726 // Used in rep stosq 2727 operand rdi_RegP() 2728 %{ 2729 constraint(ALLOC_IN_RC(ptr_rdi_reg)); 2730 match(RegP); 2731 match(rRegP); 2732 2733 format %{ %} 2734 interface(REG_INTER); 2735 %} 2736 2737 operand r15_RegP() 2738 %{ 2739 constraint(ALLOC_IN_RC(ptr_r15_reg)); 2740 match(RegP); 2741 match(rRegP); 2742 2743 format %{ %} 2744 interface(REG_INTER); 2745 %} 2746 2747 operand rRegL() 2748 %{ 2749 constraint(ALLOC_IN_RC(long_reg)); 2750 match(RegL); 2751 match(rax_RegL); 2752 match(rdx_RegL); 2753 2754 format %{ %} 2755 interface(REG_INTER); 2756 %} 2757 2758 // Special Registers 2759 operand no_rax_rdx_RegL() 2760 %{ 2761 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 2762 match(RegL); 2763 match(rRegL); 2764 2765 format %{ %} 2766 interface(REG_INTER); 2767 %} 2768 2769 operand rax_RegL() 2770 %{ 2771 constraint(ALLOC_IN_RC(long_rax_reg)); 2772 match(RegL); 2773 match(rRegL); 2774 2775 format %{ "RAX" %} 2776 interface(REG_INTER); 2777 %} 2778 2779 operand rcx_RegL() 2780 %{ 2781 constraint(ALLOC_IN_RC(long_rcx_reg)); 2782 match(RegL); 2783 match(rRegL); 2784 2785 format %{ %} 2786 interface(REG_INTER); 2787 %} 2788 2789 operand rdx_RegL() 2790 %{ 2791 constraint(ALLOC_IN_RC(long_rdx_reg)); 2792 match(RegL); 2793 match(rRegL); 2794 2795 format %{ %} 2796 interface(REG_INTER); 2797 %} 2798 2799 operand r11_RegL() 2800 %{ 2801 constraint(ALLOC_IN_RC(long_r11_reg)); 2802 match(RegL); 2803 match(rRegL); 2804 2805 format %{ %} 2806 interface(REG_INTER); 2807 %} 2808 2809 operand no_rbp_r13_RegL() 2810 %{ 2811 constraint(ALLOC_IN_RC(long_no_rbp_r13_reg)); 2812 match(RegL); 2813 match(rRegL); 2814 match(rax_RegL); 2815 match(rcx_RegL); 2816 match(rdx_RegL); 2817 2818 format %{ %} 2819 interface(REG_INTER); 2820 %} 2821 2822 // Flags register, used as output of compare instructions 2823 operand rFlagsReg() 2824 %{ 2825 constraint(ALLOC_IN_RC(int_flags)); 2826 match(RegFlags); 2827 2828 format %{ "RFLAGS" %} 2829 interface(REG_INTER); 2830 %} 2831 2832 // Flags register, used as output of FLOATING POINT compare instructions 2833 operand rFlagsRegU() 2834 %{ 2835 constraint(ALLOC_IN_RC(int_flags)); 2836 match(RegFlags); 2837 2838 format %{ "RFLAGS_U" %} 2839 interface(REG_INTER); 2840 %} 2841 2842 operand rFlagsRegUCF() %{ 2843 constraint(ALLOC_IN_RC(int_flags)); 2844 match(RegFlags); 2845 predicate(false); 2846 2847 format %{ "RFLAGS_U_CF" %} 2848 interface(REG_INTER); 2849 %} 2850 2851 // Float register operands 2852 operand regF() %{ 2853 constraint(ALLOC_IN_RC(float_reg)); 2854 match(RegF); 2855 2856 format %{ %} 2857 interface(REG_INTER); 2858 %} 2859 2860 // Float register operands 2861 operand legRegF() %{ 2862 constraint(ALLOC_IN_RC(float_reg_legacy)); 2863 match(RegF); 2864 2865 format %{ %} 2866 interface(REG_INTER); 2867 %} 2868 2869 // Float register operands 2870 operand vlRegF() %{ 2871 constraint(ALLOC_IN_RC(float_reg_vl)); 2872 match(RegF); 2873 2874 format %{ %} 2875 interface(REG_INTER); 2876 %} 2877 2878 // Double register operands 2879 operand regD() %{ 2880 constraint(ALLOC_IN_RC(double_reg)); 2881 match(RegD); 2882 2883 format %{ %} 2884 interface(REG_INTER); 2885 %} 2886 2887 // Double register operands 2888 operand legRegD() %{ 2889 constraint(ALLOC_IN_RC(double_reg_legacy)); 2890 match(RegD); 2891 2892 format %{ %} 2893 interface(REG_INTER); 2894 %} 2895 2896 // Double register operands 2897 operand vlRegD() %{ 2898 constraint(ALLOC_IN_RC(double_reg_vl)); 2899 match(RegD); 2900 2901 format %{ %} 2902 interface(REG_INTER); 2903 %} 2904 2905 //----------Memory Operands---------------------------------------------------- 2906 // Direct Memory Operand 2907 // operand direct(immP addr) 2908 // %{ 2909 // match(addr); 2910 2911 // format %{ "[$addr]" %} 2912 // interface(MEMORY_INTER) %{ 2913 // base(0xFFFFFFFF); 2914 // index(0x4); 2915 // scale(0x0); 2916 // disp($addr); 2917 // %} 2918 // %} 2919 2920 // Indirect Memory Operand 2921 operand indirect(any_RegP reg) 2922 %{ 2923 constraint(ALLOC_IN_RC(ptr_reg)); 2924 match(reg); 2925 2926 format %{ "[$reg]" %} 2927 interface(MEMORY_INTER) %{ 2928 base($reg); 2929 index(0x4); 2930 scale(0x0); 2931 disp(0x0); 2932 %} 2933 %} 2934 2935 // Indirect Memory Plus Short Offset Operand 2936 operand indOffset8(any_RegP reg, immL8 off) 2937 %{ 2938 constraint(ALLOC_IN_RC(ptr_reg)); 2939 match(AddP reg off); 2940 2941 format %{ "[$reg + $off (8-bit)]" %} 2942 interface(MEMORY_INTER) %{ 2943 base($reg); 2944 index(0x4); 2945 scale(0x0); 2946 disp($off); 2947 %} 2948 %} 2949 2950 // Indirect Memory Plus Long Offset Operand 2951 operand indOffset32(any_RegP reg, immL32 off) 2952 %{ 2953 constraint(ALLOC_IN_RC(ptr_reg)); 2954 match(AddP reg off); 2955 2956 format %{ "[$reg + $off (32-bit)]" %} 2957 interface(MEMORY_INTER) %{ 2958 base($reg); 2959 index(0x4); 2960 scale(0x0); 2961 disp($off); 2962 %} 2963 %} 2964 2965 // Indirect Memory Plus Index Register Plus Offset Operand 2966 operand indIndexOffset(any_RegP reg, rRegL lreg, immL32 off) 2967 %{ 2968 constraint(ALLOC_IN_RC(ptr_reg)); 2969 match(AddP (AddP reg lreg) off); 2970 2971 op_cost(10); 2972 format %{"[$reg + $off + $lreg]" %} 2973 interface(MEMORY_INTER) %{ 2974 base($reg); 2975 index($lreg); 2976 scale(0x0); 2977 disp($off); 2978 %} 2979 %} 2980 2981 // Indirect Memory Plus Index Register Plus Offset Operand 2982 operand indIndex(any_RegP reg, rRegL lreg) 2983 %{ 2984 constraint(ALLOC_IN_RC(ptr_reg)); 2985 match(AddP reg lreg); 2986 2987 op_cost(10); 2988 format %{"[$reg + $lreg]" %} 2989 interface(MEMORY_INTER) %{ 2990 base($reg); 2991 index($lreg); 2992 scale(0x0); 2993 disp(0x0); 2994 %} 2995 %} 2996 2997 // Indirect Memory Times Scale Plus Index Register 2998 operand indIndexScale(any_RegP reg, rRegL lreg, immI2 scale) 2999 %{ 3000 constraint(ALLOC_IN_RC(ptr_reg)); 3001 match(AddP reg (LShiftL lreg scale)); 3002 3003 op_cost(10); 3004 format %{"[$reg + $lreg << $scale]" %} 3005 interface(MEMORY_INTER) %{ 3006 base($reg); 3007 index($lreg); 3008 scale($scale); 3009 disp(0x0); 3010 %} 3011 %} 3012 3013 operand indPosIndexScale(any_RegP reg, rRegI idx, immI2 scale) 3014 %{ 3015 constraint(ALLOC_IN_RC(ptr_reg)); 3016 predicate(n->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3017 match(AddP reg (LShiftL (ConvI2L idx) scale)); 3018 3019 op_cost(10); 3020 format %{"[$reg + pos $idx << $scale]" %} 3021 interface(MEMORY_INTER) %{ 3022 base($reg); 3023 index($idx); 3024 scale($scale); 3025 disp(0x0); 3026 %} 3027 %} 3028 3029 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 3030 operand indIndexScaleOffset(any_RegP reg, immL32 off, rRegL lreg, immI2 scale) 3031 %{ 3032 constraint(ALLOC_IN_RC(ptr_reg)); 3033 match(AddP (AddP reg (LShiftL lreg scale)) off); 3034 3035 op_cost(10); 3036 format %{"[$reg + $off + $lreg << $scale]" %} 3037 interface(MEMORY_INTER) %{ 3038 base($reg); 3039 index($lreg); 3040 scale($scale); 3041 disp($off); 3042 %} 3043 %} 3044 3045 // Indirect Memory Plus Positive Index Register Plus Offset Operand 3046 operand indPosIndexOffset(any_RegP reg, immL32 off, rRegI idx) 3047 %{ 3048 constraint(ALLOC_IN_RC(ptr_reg)); 3049 predicate(n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 3050 match(AddP (AddP reg (ConvI2L idx)) off); 3051 3052 op_cost(10); 3053 format %{"[$reg + $off + $idx]" %} 3054 interface(MEMORY_INTER) %{ 3055 base($reg); 3056 index($idx); 3057 scale(0x0); 3058 disp($off); 3059 %} 3060 %} 3061 3062 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 3063 operand indPosIndexScaleOffset(any_RegP reg, immL32 off, rRegI idx, immI2 scale) 3064 %{ 3065 constraint(ALLOC_IN_RC(ptr_reg)); 3066 predicate(n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3067 match(AddP (AddP reg (LShiftL (ConvI2L idx) scale)) off); 3068 3069 op_cost(10); 3070 format %{"[$reg + $off + $idx << $scale]" %} 3071 interface(MEMORY_INTER) %{ 3072 base($reg); 3073 index($idx); 3074 scale($scale); 3075 disp($off); 3076 %} 3077 %} 3078 3079 // Indirect Narrow Oop Operand 3080 operand indCompressedOop(rRegN reg) %{ 3081 predicate(UseCompressedOops && (CompressedOops::shift() == Address::times_8)); 3082 constraint(ALLOC_IN_RC(ptr_reg)); 3083 match(DecodeN reg); 3084 3085 op_cost(10); 3086 format %{"[R12 + $reg << 3] (compressed oop addressing)" %} 3087 interface(MEMORY_INTER) %{ 3088 base(0xc); // R12 3089 index($reg); 3090 scale(0x3); 3091 disp(0x0); 3092 %} 3093 %} 3094 3095 // Indirect Narrow Oop Plus Offset Operand 3096 // Note: x86 architecture doesn't support "scale * index + offset" without a base 3097 // we can't free r12 even with CompressedOops::base() == nullptr. 3098 operand indCompressedOopOffset(rRegN reg, immL32 off) %{ 3099 predicate(UseCompressedOops && (CompressedOops::shift() == Address::times_8)); 3100 constraint(ALLOC_IN_RC(ptr_reg)); 3101 match(AddP (DecodeN reg) off); 3102 3103 op_cost(10); 3104 format %{"[R12 + $reg << 3 + $off] (compressed oop addressing)" %} 3105 interface(MEMORY_INTER) %{ 3106 base(0xc); // R12 3107 index($reg); 3108 scale(0x3); 3109 disp($off); 3110 %} 3111 %} 3112 3113 // Indirect Memory Operand 3114 operand indirectNarrow(rRegN reg) 3115 %{ 3116 predicate(CompressedOops::shift() == 0); 3117 constraint(ALLOC_IN_RC(ptr_reg)); 3118 match(DecodeN reg); 3119 3120 format %{ "[$reg]" %} 3121 interface(MEMORY_INTER) %{ 3122 base($reg); 3123 index(0x4); 3124 scale(0x0); 3125 disp(0x0); 3126 %} 3127 %} 3128 3129 // Indirect Memory Plus Short Offset Operand 3130 operand indOffset8Narrow(rRegN reg, immL8 off) 3131 %{ 3132 predicate(CompressedOops::shift() == 0); 3133 constraint(ALLOC_IN_RC(ptr_reg)); 3134 match(AddP (DecodeN reg) off); 3135 3136 format %{ "[$reg + $off (8-bit)]" %} 3137 interface(MEMORY_INTER) %{ 3138 base($reg); 3139 index(0x4); 3140 scale(0x0); 3141 disp($off); 3142 %} 3143 %} 3144 3145 // Indirect Memory Plus Long Offset Operand 3146 operand indOffset32Narrow(rRegN reg, immL32 off) 3147 %{ 3148 predicate(CompressedOops::shift() == 0); 3149 constraint(ALLOC_IN_RC(ptr_reg)); 3150 match(AddP (DecodeN reg) off); 3151 3152 format %{ "[$reg + $off (32-bit)]" %} 3153 interface(MEMORY_INTER) %{ 3154 base($reg); 3155 index(0x4); 3156 scale(0x0); 3157 disp($off); 3158 %} 3159 %} 3160 3161 // Indirect Memory Plus Index Register Plus Offset Operand 3162 operand indIndexOffsetNarrow(rRegN reg, rRegL lreg, immL32 off) 3163 %{ 3164 predicate(CompressedOops::shift() == 0); 3165 constraint(ALLOC_IN_RC(ptr_reg)); 3166 match(AddP (AddP (DecodeN reg) lreg) off); 3167 3168 op_cost(10); 3169 format %{"[$reg + $off + $lreg]" %} 3170 interface(MEMORY_INTER) %{ 3171 base($reg); 3172 index($lreg); 3173 scale(0x0); 3174 disp($off); 3175 %} 3176 %} 3177 3178 // Indirect Memory Plus Index Register Plus Offset Operand 3179 operand indIndexNarrow(rRegN reg, rRegL lreg) 3180 %{ 3181 predicate(CompressedOops::shift() == 0); 3182 constraint(ALLOC_IN_RC(ptr_reg)); 3183 match(AddP (DecodeN reg) lreg); 3184 3185 op_cost(10); 3186 format %{"[$reg + $lreg]" %} 3187 interface(MEMORY_INTER) %{ 3188 base($reg); 3189 index($lreg); 3190 scale(0x0); 3191 disp(0x0); 3192 %} 3193 %} 3194 3195 // Indirect Memory Times Scale Plus Index Register 3196 operand indIndexScaleNarrow(rRegN reg, rRegL lreg, immI2 scale) 3197 %{ 3198 predicate(CompressedOops::shift() == 0); 3199 constraint(ALLOC_IN_RC(ptr_reg)); 3200 match(AddP (DecodeN reg) (LShiftL lreg scale)); 3201 3202 op_cost(10); 3203 format %{"[$reg + $lreg << $scale]" %} 3204 interface(MEMORY_INTER) %{ 3205 base($reg); 3206 index($lreg); 3207 scale($scale); 3208 disp(0x0); 3209 %} 3210 %} 3211 3212 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 3213 operand indIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegL lreg, immI2 scale) 3214 %{ 3215 predicate(CompressedOops::shift() == 0); 3216 constraint(ALLOC_IN_RC(ptr_reg)); 3217 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off); 3218 3219 op_cost(10); 3220 format %{"[$reg + $off + $lreg << $scale]" %} 3221 interface(MEMORY_INTER) %{ 3222 base($reg); 3223 index($lreg); 3224 scale($scale); 3225 disp($off); 3226 %} 3227 %} 3228 3229 // Indirect Memory Times Plus Positive Index Register Plus Offset Operand 3230 operand indPosIndexOffsetNarrow(rRegN reg, immL32 off, rRegI idx) 3231 %{ 3232 constraint(ALLOC_IN_RC(ptr_reg)); 3233 predicate(CompressedOops::shift() == 0 && n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 3234 match(AddP (AddP (DecodeN reg) (ConvI2L idx)) off); 3235 3236 op_cost(10); 3237 format %{"[$reg + $off + $idx]" %} 3238 interface(MEMORY_INTER) %{ 3239 base($reg); 3240 index($idx); 3241 scale(0x0); 3242 disp($off); 3243 %} 3244 %} 3245 3246 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 3247 operand indPosIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegI idx, immI2 scale) 3248 %{ 3249 constraint(ALLOC_IN_RC(ptr_reg)); 3250 predicate(CompressedOops::shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3251 match(AddP (AddP (DecodeN reg) (LShiftL (ConvI2L idx) scale)) off); 3252 3253 op_cost(10); 3254 format %{"[$reg + $off + $idx << $scale]" %} 3255 interface(MEMORY_INTER) %{ 3256 base($reg); 3257 index($idx); 3258 scale($scale); 3259 disp($off); 3260 %} 3261 %} 3262 3263 //----------Special Memory Operands-------------------------------------------- 3264 // Stack Slot Operand - This operand is used for loading and storing temporary 3265 // values on the stack where a match requires a value to 3266 // flow through memory. 3267 operand stackSlotP(sRegP reg) 3268 %{ 3269 constraint(ALLOC_IN_RC(stack_slots)); 3270 // No match rule because this operand is only generated in matching 3271 3272 format %{ "[$reg]" %} 3273 interface(MEMORY_INTER) %{ 3274 base(0x4); // RSP 3275 index(0x4); // No Index 3276 scale(0x0); // No Scale 3277 disp($reg); // Stack Offset 3278 %} 3279 %} 3280 3281 operand stackSlotI(sRegI reg) 3282 %{ 3283 constraint(ALLOC_IN_RC(stack_slots)); 3284 // No match rule because this operand is only generated in matching 3285 3286 format %{ "[$reg]" %} 3287 interface(MEMORY_INTER) %{ 3288 base(0x4); // RSP 3289 index(0x4); // No Index 3290 scale(0x0); // No Scale 3291 disp($reg); // Stack Offset 3292 %} 3293 %} 3294 3295 operand stackSlotF(sRegF reg) 3296 %{ 3297 constraint(ALLOC_IN_RC(stack_slots)); 3298 // No match rule because this operand is only generated in matching 3299 3300 format %{ "[$reg]" %} 3301 interface(MEMORY_INTER) %{ 3302 base(0x4); // RSP 3303 index(0x4); // No Index 3304 scale(0x0); // No Scale 3305 disp($reg); // Stack Offset 3306 %} 3307 %} 3308 3309 operand stackSlotD(sRegD reg) 3310 %{ 3311 constraint(ALLOC_IN_RC(stack_slots)); 3312 // No match rule because this operand is only generated in matching 3313 3314 format %{ "[$reg]" %} 3315 interface(MEMORY_INTER) %{ 3316 base(0x4); // RSP 3317 index(0x4); // No Index 3318 scale(0x0); // No Scale 3319 disp($reg); // Stack Offset 3320 %} 3321 %} 3322 operand stackSlotL(sRegL reg) 3323 %{ 3324 constraint(ALLOC_IN_RC(stack_slots)); 3325 // No match rule because this operand is only generated in matching 3326 3327 format %{ "[$reg]" %} 3328 interface(MEMORY_INTER) %{ 3329 base(0x4); // RSP 3330 index(0x4); // No Index 3331 scale(0x0); // No Scale 3332 disp($reg); // Stack Offset 3333 %} 3334 %} 3335 3336 //----------Conditional Branch Operands---------------------------------------- 3337 // Comparison Op - This is the operation of the comparison, and is limited to 3338 // the following set of codes: 3339 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 3340 // 3341 // Other attributes of the comparison, such as unsignedness, are specified 3342 // by the comparison instruction that sets a condition code flags register. 3343 // That result is represented by a flags operand whose subtype is appropriate 3344 // to the unsignedness (etc.) of the comparison. 3345 // 3346 // Later, the instruction which matches both the Comparison Op (a Bool) and 3347 // the flags (produced by the Cmp) specifies the coding of the comparison op 3348 // by matching a specific subtype of Bool operand below, such as cmpOpU. 3349 3350 // Comparison Code 3351 operand cmpOp() 3352 %{ 3353 match(Bool); 3354 3355 format %{ "" %} 3356 interface(COND_INTER) %{ 3357 equal(0x4, "e"); 3358 not_equal(0x5, "ne"); 3359 less(0xC, "l"); 3360 greater_equal(0xD, "ge"); 3361 less_equal(0xE, "le"); 3362 greater(0xF, "g"); 3363 overflow(0x0, "o"); 3364 no_overflow(0x1, "no"); 3365 %} 3366 %} 3367 3368 // Comparison Code, unsigned compare. Used by FP also, with 3369 // C2 (unordered) turned into GT or LT already. The other bits 3370 // C0 and C3 are turned into Carry & Zero flags. 3371 operand cmpOpU() 3372 %{ 3373 match(Bool); 3374 3375 format %{ "" %} 3376 interface(COND_INTER) %{ 3377 equal(0x4, "e"); 3378 not_equal(0x5, "ne"); 3379 less(0x2, "b"); 3380 greater_equal(0x3, "ae"); 3381 less_equal(0x6, "be"); 3382 greater(0x7, "a"); 3383 overflow(0x0, "o"); 3384 no_overflow(0x1, "no"); 3385 %} 3386 %} 3387 3388 3389 // Floating comparisons that don't require any fixup for the unordered case, 3390 // If both inputs of the comparison are the same, ZF is always set so we 3391 // don't need to use cmpOpUCF2 for eq/ne 3392 operand cmpOpUCF() %{ 3393 match(Bool); 3394 predicate(n->as_Bool()->_test._test == BoolTest::lt || 3395 n->as_Bool()->_test._test == BoolTest::ge || 3396 n->as_Bool()->_test._test == BoolTest::le || 3397 n->as_Bool()->_test._test == BoolTest::gt || 3398 n->in(1)->in(1) == n->in(1)->in(2)); 3399 format %{ "" %} 3400 interface(COND_INTER) %{ 3401 equal(0xb, "np"); 3402 not_equal(0xa, "p"); 3403 less(0x2, "b"); 3404 greater_equal(0x3, "ae"); 3405 less_equal(0x6, "be"); 3406 greater(0x7, "a"); 3407 overflow(0x0, "o"); 3408 no_overflow(0x1, "no"); 3409 %} 3410 %} 3411 3412 3413 // Floating comparisons that can be fixed up with extra conditional jumps 3414 operand cmpOpUCF2() %{ 3415 match(Bool); 3416 predicate((n->as_Bool()->_test._test == BoolTest::ne || 3417 n->as_Bool()->_test._test == BoolTest::eq) && 3418 n->in(1)->in(1) != n->in(1)->in(2)); 3419 format %{ "" %} 3420 interface(COND_INTER) %{ 3421 equal(0x4, "e"); 3422 not_equal(0x5, "ne"); 3423 less(0x2, "b"); 3424 greater_equal(0x3, "ae"); 3425 less_equal(0x6, "be"); 3426 greater(0x7, "a"); 3427 overflow(0x0, "o"); 3428 no_overflow(0x1, "no"); 3429 %} 3430 %} 3431 3432 //----------OPERAND CLASSES---------------------------------------------------- 3433 // Operand Classes are groups of operands that are used as to simplify 3434 // instruction definitions by not requiring the AD writer to specify separate 3435 // instructions for every form of operand when the instruction accepts 3436 // multiple operand types with the same basic encoding and format. The classic 3437 // case of this is memory operands. 3438 3439 opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex, 3440 indIndexScale, indPosIndexScale, indIndexScaleOffset, indPosIndexOffset, indPosIndexScaleOffset, 3441 indCompressedOop, indCompressedOopOffset, 3442 indirectNarrow, indOffset8Narrow, indOffset32Narrow, 3443 indIndexOffsetNarrow, indIndexNarrow, indIndexScaleNarrow, 3444 indIndexScaleOffsetNarrow, indPosIndexOffsetNarrow, indPosIndexScaleOffsetNarrow); 3445 3446 //----------PIPELINE----------------------------------------------------------- 3447 // Rules which define the behavior of the target architectures pipeline. 3448 pipeline %{ 3449 3450 //----------ATTRIBUTES--------------------------------------------------------- 3451 attributes %{ 3452 variable_size_instructions; // Fixed size instructions 3453 max_instructions_per_bundle = 3; // Up to 3 instructions per bundle 3454 instruction_unit_size = 1; // An instruction is 1 bytes long 3455 instruction_fetch_unit_size = 16; // The processor fetches one line 3456 instruction_fetch_units = 1; // of 16 bytes 3457 3458 // List of nop instructions 3459 nops( MachNop ); 3460 %} 3461 3462 //----------RESOURCES---------------------------------------------------------- 3463 // Resources are the functional units available to the machine 3464 3465 // Generic P2/P3 pipeline 3466 // 3 decoders, only D0 handles big operands; a "bundle" is the limit of 3467 // 3 instructions decoded per cycle. 3468 // 2 load/store ops per cycle, 1 branch, 1 FPU, 3469 // 3 ALU op, only ALU0 handles mul instructions. 3470 resources( D0, D1, D2, DECODE = D0 | D1 | D2, 3471 MS0, MS1, MS2, MEM = MS0 | MS1 | MS2, 3472 BR, FPU, 3473 ALU0, ALU1, ALU2, ALU = ALU0 | ALU1 | ALU2); 3474 3475 //----------PIPELINE DESCRIPTION----------------------------------------------- 3476 // Pipeline Description specifies the stages in the machine's pipeline 3477 3478 // Generic P2/P3 pipeline 3479 pipe_desc(S0, S1, S2, S3, S4, S5); 3480 3481 //----------PIPELINE CLASSES--------------------------------------------------- 3482 // Pipeline Classes describe the stages in which input and output are 3483 // referenced by the hardware pipeline. 3484 3485 // Naming convention: ialu or fpu 3486 // Then: _reg 3487 // Then: _reg if there is a 2nd register 3488 // Then: _long if it's a pair of instructions implementing a long 3489 // Then: _fat if it requires the big decoder 3490 // Or: _mem if it requires the big decoder and a memory unit. 3491 3492 // Integer ALU reg operation 3493 pipe_class ialu_reg(rRegI dst) 3494 %{ 3495 single_instruction; 3496 dst : S4(write); 3497 dst : S3(read); 3498 DECODE : S0; // any decoder 3499 ALU : S3; // any alu 3500 %} 3501 3502 // Long ALU reg operation 3503 pipe_class ialu_reg_long(rRegL dst) 3504 %{ 3505 instruction_count(2); 3506 dst : S4(write); 3507 dst : S3(read); 3508 DECODE : S0(2); // any 2 decoders 3509 ALU : S3(2); // both alus 3510 %} 3511 3512 // Integer ALU reg operation using big decoder 3513 pipe_class ialu_reg_fat(rRegI dst) 3514 %{ 3515 single_instruction; 3516 dst : S4(write); 3517 dst : S3(read); 3518 D0 : S0; // big decoder only 3519 ALU : S3; // any alu 3520 %} 3521 3522 // Integer ALU reg-reg operation 3523 pipe_class ialu_reg_reg(rRegI dst, rRegI src) 3524 %{ 3525 single_instruction; 3526 dst : S4(write); 3527 src : S3(read); 3528 DECODE : S0; // any decoder 3529 ALU : S3; // any alu 3530 %} 3531 3532 // Integer ALU reg-reg operation 3533 pipe_class ialu_reg_reg_fat(rRegI dst, memory src) 3534 %{ 3535 single_instruction; 3536 dst : S4(write); 3537 src : S3(read); 3538 D0 : S0; // big decoder only 3539 ALU : S3; // any alu 3540 %} 3541 3542 // Integer ALU reg-mem operation 3543 pipe_class ialu_reg_mem(rRegI dst, memory mem) 3544 %{ 3545 single_instruction; 3546 dst : S5(write); 3547 mem : S3(read); 3548 D0 : S0; // big decoder only 3549 ALU : S4; // any alu 3550 MEM : S3; // any mem 3551 %} 3552 3553 // Integer mem operation (prefetch) 3554 pipe_class ialu_mem(memory mem) 3555 %{ 3556 single_instruction; 3557 mem : S3(read); 3558 D0 : S0; // big decoder only 3559 MEM : S3; // any mem 3560 %} 3561 3562 // Integer Store to Memory 3563 pipe_class ialu_mem_reg(memory mem, rRegI src) 3564 %{ 3565 single_instruction; 3566 mem : S3(read); 3567 src : S5(read); 3568 D0 : S0; // big decoder only 3569 ALU : S4; // any alu 3570 MEM : S3; 3571 %} 3572 3573 // // Long Store to Memory 3574 // pipe_class ialu_mem_long_reg(memory mem, rRegL src) 3575 // %{ 3576 // instruction_count(2); 3577 // mem : S3(read); 3578 // src : S5(read); 3579 // D0 : S0(2); // big decoder only; twice 3580 // ALU : S4(2); // any 2 alus 3581 // MEM : S3(2); // Both mems 3582 // %} 3583 3584 // Integer Store to Memory 3585 pipe_class ialu_mem_imm(memory mem) 3586 %{ 3587 single_instruction; 3588 mem : S3(read); 3589 D0 : S0; // big decoder only 3590 ALU : S4; // any alu 3591 MEM : S3; 3592 %} 3593 3594 // Integer ALU0 reg-reg operation 3595 pipe_class ialu_reg_reg_alu0(rRegI dst, rRegI src) 3596 %{ 3597 single_instruction; 3598 dst : S4(write); 3599 src : S3(read); 3600 D0 : S0; // Big decoder only 3601 ALU0 : S3; // only alu0 3602 %} 3603 3604 // Integer ALU0 reg-mem operation 3605 pipe_class ialu_reg_mem_alu0(rRegI dst, memory mem) 3606 %{ 3607 single_instruction; 3608 dst : S5(write); 3609 mem : S3(read); 3610 D0 : S0; // big decoder only 3611 ALU0 : S4; // ALU0 only 3612 MEM : S3; // any mem 3613 %} 3614 3615 // Integer ALU reg-reg operation 3616 pipe_class ialu_cr_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2) 3617 %{ 3618 single_instruction; 3619 cr : S4(write); 3620 src1 : S3(read); 3621 src2 : S3(read); 3622 DECODE : S0; // any decoder 3623 ALU : S3; // any alu 3624 %} 3625 3626 // Integer ALU reg-imm operation 3627 pipe_class ialu_cr_reg_imm(rFlagsReg cr, rRegI src1) 3628 %{ 3629 single_instruction; 3630 cr : S4(write); 3631 src1 : S3(read); 3632 DECODE : S0; // any decoder 3633 ALU : S3; // any alu 3634 %} 3635 3636 // Integer ALU reg-mem operation 3637 pipe_class ialu_cr_reg_mem(rFlagsReg cr, rRegI src1, memory src2) 3638 %{ 3639 single_instruction; 3640 cr : S4(write); 3641 src1 : S3(read); 3642 src2 : S3(read); 3643 D0 : S0; // big decoder only 3644 ALU : S4; // any alu 3645 MEM : S3; 3646 %} 3647 3648 // Conditional move reg-reg 3649 pipe_class pipe_cmplt( rRegI p, rRegI q, rRegI y) 3650 %{ 3651 instruction_count(4); 3652 y : S4(read); 3653 q : S3(read); 3654 p : S3(read); 3655 DECODE : S0(4); // any decoder 3656 %} 3657 3658 // Conditional move reg-reg 3659 pipe_class pipe_cmov_reg( rRegI dst, rRegI src, rFlagsReg cr) 3660 %{ 3661 single_instruction; 3662 dst : S4(write); 3663 src : S3(read); 3664 cr : S3(read); 3665 DECODE : S0; // any decoder 3666 %} 3667 3668 // Conditional move reg-mem 3669 pipe_class pipe_cmov_mem( rFlagsReg cr, rRegI dst, memory src) 3670 %{ 3671 single_instruction; 3672 dst : S4(write); 3673 src : S3(read); 3674 cr : S3(read); 3675 DECODE : S0; // any decoder 3676 MEM : S3; 3677 %} 3678 3679 // Conditional move reg-reg long 3680 pipe_class pipe_cmov_reg_long( rFlagsReg cr, rRegL dst, rRegL src) 3681 %{ 3682 single_instruction; 3683 dst : S4(write); 3684 src : S3(read); 3685 cr : S3(read); 3686 DECODE : S0(2); // any 2 decoders 3687 %} 3688 3689 // Float reg-reg operation 3690 pipe_class fpu_reg(regD dst) 3691 %{ 3692 instruction_count(2); 3693 dst : S3(read); 3694 DECODE : S0(2); // any 2 decoders 3695 FPU : S3; 3696 %} 3697 3698 // Float reg-reg operation 3699 pipe_class fpu_reg_reg(regD dst, regD src) 3700 %{ 3701 instruction_count(2); 3702 dst : S4(write); 3703 src : S3(read); 3704 DECODE : S0(2); // any 2 decoders 3705 FPU : S3; 3706 %} 3707 3708 // Float reg-reg operation 3709 pipe_class fpu_reg_reg_reg(regD dst, regD src1, regD src2) 3710 %{ 3711 instruction_count(3); 3712 dst : S4(write); 3713 src1 : S3(read); 3714 src2 : S3(read); 3715 DECODE : S0(3); // any 3 decoders 3716 FPU : S3(2); 3717 %} 3718 3719 // Float reg-reg operation 3720 pipe_class fpu_reg_reg_reg_reg(regD dst, regD src1, regD src2, regD src3) 3721 %{ 3722 instruction_count(4); 3723 dst : S4(write); 3724 src1 : S3(read); 3725 src2 : S3(read); 3726 src3 : S3(read); 3727 DECODE : S0(4); // any 3 decoders 3728 FPU : S3(2); 3729 %} 3730 3731 // Float reg-reg operation 3732 pipe_class fpu_reg_mem_reg_reg(regD dst, memory src1, regD src2, regD src3) 3733 %{ 3734 instruction_count(4); 3735 dst : S4(write); 3736 src1 : S3(read); 3737 src2 : S3(read); 3738 src3 : S3(read); 3739 DECODE : S1(3); // any 3 decoders 3740 D0 : S0; // Big decoder only 3741 FPU : S3(2); 3742 MEM : S3; 3743 %} 3744 3745 // Float reg-mem operation 3746 pipe_class fpu_reg_mem(regD dst, memory mem) 3747 %{ 3748 instruction_count(2); 3749 dst : S5(write); 3750 mem : S3(read); 3751 D0 : S0; // big decoder only 3752 DECODE : S1; // any decoder for FPU POP 3753 FPU : S4; 3754 MEM : S3; // any mem 3755 %} 3756 3757 // Float reg-mem operation 3758 pipe_class fpu_reg_reg_mem(regD dst, regD src1, memory mem) 3759 %{ 3760 instruction_count(3); 3761 dst : S5(write); 3762 src1 : S3(read); 3763 mem : S3(read); 3764 D0 : S0; // big decoder only 3765 DECODE : S1(2); // any decoder for FPU POP 3766 FPU : S4; 3767 MEM : S3; // any mem 3768 %} 3769 3770 // Float mem-reg operation 3771 pipe_class fpu_mem_reg(memory mem, regD src) 3772 %{ 3773 instruction_count(2); 3774 src : S5(read); 3775 mem : S3(read); 3776 DECODE : S0; // any decoder for FPU PUSH 3777 D0 : S1; // big decoder only 3778 FPU : S4; 3779 MEM : S3; // any mem 3780 %} 3781 3782 pipe_class fpu_mem_reg_reg(memory mem, regD src1, regD src2) 3783 %{ 3784 instruction_count(3); 3785 src1 : S3(read); 3786 src2 : S3(read); 3787 mem : S3(read); 3788 DECODE : S0(2); // any decoder for FPU PUSH 3789 D0 : S1; // big decoder only 3790 FPU : S4; 3791 MEM : S3; // any mem 3792 %} 3793 3794 pipe_class fpu_mem_reg_mem(memory mem, regD src1, memory src2) 3795 %{ 3796 instruction_count(3); 3797 src1 : S3(read); 3798 src2 : S3(read); 3799 mem : S4(read); 3800 DECODE : S0; // any decoder for FPU PUSH 3801 D0 : S0(2); // big decoder only 3802 FPU : S4; 3803 MEM : S3(2); // any mem 3804 %} 3805 3806 pipe_class fpu_mem_mem(memory dst, memory src1) 3807 %{ 3808 instruction_count(2); 3809 src1 : S3(read); 3810 dst : S4(read); 3811 D0 : S0(2); // big decoder only 3812 MEM : S3(2); // any mem 3813 %} 3814 3815 pipe_class fpu_mem_mem_mem(memory dst, memory src1, memory src2) 3816 %{ 3817 instruction_count(3); 3818 src1 : S3(read); 3819 src2 : S3(read); 3820 dst : S4(read); 3821 D0 : S0(3); // big decoder only 3822 FPU : S4; 3823 MEM : S3(3); // any mem 3824 %} 3825 3826 pipe_class fpu_mem_reg_con(memory mem, regD src1) 3827 %{ 3828 instruction_count(3); 3829 src1 : S4(read); 3830 mem : S4(read); 3831 DECODE : S0; // any decoder for FPU PUSH 3832 D0 : S0(2); // big decoder only 3833 FPU : S4; 3834 MEM : S3(2); // any mem 3835 %} 3836 3837 // Float load constant 3838 pipe_class fpu_reg_con(regD dst) 3839 %{ 3840 instruction_count(2); 3841 dst : S5(write); 3842 D0 : S0; // big decoder only for the load 3843 DECODE : S1; // any decoder for FPU POP 3844 FPU : S4; 3845 MEM : S3; // any mem 3846 %} 3847 3848 // Float load constant 3849 pipe_class fpu_reg_reg_con(regD dst, regD src) 3850 %{ 3851 instruction_count(3); 3852 dst : S5(write); 3853 src : S3(read); 3854 D0 : S0; // big decoder only for the load 3855 DECODE : S1(2); // any decoder for FPU POP 3856 FPU : S4; 3857 MEM : S3; // any mem 3858 %} 3859 3860 // UnConditional branch 3861 pipe_class pipe_jmp(label labl) 3862 %{ 3863 single_instruction; 3864 BR : S3; 3865 %} 3866 3867 // Conditional branch 3868 pipe_class pipe_jcc(cmpOp cmp, rFlagsReg cr, label labl) 3869 %{ 3870 single_instruction; 3871 cr : S1(read); 3872 BR : S3; 3873 %} 3874 3875 // Allocation idiom 3876 pipe_class pipe_cmpxchg(rRegP dst, rRegP heap_ptr) 3877 %{ 3878 instruction_count(1); force_serialization; 3879 fixed_latency(6); 3880 heap_ptr : S3(read); 3881 DECODE : S0(3); 3882 D0 : S2; 3883 MEM : S3; 3884 ALU : S3(2); 3885 dst : S5(write); 3886 BR : S5; 3887 %} 3888 3889 // Generic big/slow expanded idiom 3890 pipe_class pipe_slow() 3891 %{ 3892 instruction_count(10); multiple_bundles; force_serialization; 3893 fixed_latency(100); 3894 D0 : S0(2); 3895 MEM : S3(2); 3896 %} 3897 3898 // The real do-nothing guy 3899 pipe_class empty() 3900 %{ 3901 instruction_count(0); 3902 %} 3903 3904 // Define the class for the Nop node 3905 define 3906 %{ 3907 MachNop = empty; 3908 %} 3909 3910 %} 3911 3912 //----------INSTRUCTIONS------------------------------------------------------- 3913 // 3914 // match -- States which machine-independent subtree may be replaced 3915 // by this instruction. 3916 // ins_cost -- The estimated cost of this instruction is used by instruction 3917 // selection to identify a minimum cost tree of machine 3918 // instructions that matches a tree of machine-independent 3919 // instructions. 3920 // format -- A string providing the disassembly for this instruction. 3921 // The value of an instruction's operand may be inserted 3922 // by referring to it with a '$' prefix. 3923 // opcode -- Three instruction opcodes may be provided. These are referred 3924 // to within an encode class as $primary, $secondary, and $tertiary 3925 // rrspectively. The primary opcode is commonly used to 3926 // indicate the type of machine instruction, while secondary 3927 // and tertiary are often used for prefix options or addressing 3928 // modes. 3929 // ins_encode -- A list of encode classes with parameters. The encode class 3930 // name must have been defined in an 'enc_class' specification 3931 // in the encode section of the architecture description. 3932 3933 // Dummy reg-to-reg vector moves. Removed during post-selection cleanup. 3934 // Load Float 3935 instruct MoveF2VL(vlRegF dst, regF src) %{ 3936 match(Set dst src); 3937 format %{ "movss $dst,$src\t! load float (4 bytes)" %} 3938 ins_encode %{ 3939 ShouldNotReachHere(); 3940 %} 3941 ins_pipe( fpu_reg_reg ); 3942 %} 3943 3944 // Load Float 3945 instruct MoveF2LEG(legRegF dst, regF src) %{ 3946 match(Set dst src); 3947 format %{ "movss $dst,$src\t# if src != dst load float (4 bytes)" %} 3948 ins_encode %{ 3949 ShouldNotReachHere(); 3950 %} 3951 ins_pipe( fpu_reg_reg ); 3952 %} 3953 3954 // Load Float 3955 instruct MoveVL2F(regF dst, vlRegF src) %{ 3956 match(Set dst src); 3957 format %{ "movss $dst,$src\t! load float (4 bytes)" %} 3958 ins_encode %{ 3959 ShouldNotReachHere(); 3960 %} 3961 ins_pipe( fpu_reg_reg ); 3962 %} 3963 3964 // Load Float 3965 instruct MoveLEG2F(regF dst, legRegF src) %{ 3966 match(Set dst src); 3967 format %{ "movss $dst,$src\t# if src != dst load float (4 bytes)" %} 3968 ins_encode %{ 3969 ShouldNotReachHere(); 3970 %} 3971 ins_pipe( fpu_reg_reg ); 3972 %} 3973 3974 // Load Double 3975 instruct MoveD2VL(vlRegD dst, regD src) %{ 3976 match(Set dst src); 3977 format %{ "movsd $dst,$src\t! load double (8 bytes)" %} 3978 ins_encode %{ 3979 ShouldNotReachHere(); 3980 %} 3981 ins_pipe( fpu_reg_reg ); 3982 %} 3983 3984 // Load Double 3985 instruct MoveD2LEG(legRegD dst, regD src) %{ 3986 match(Set dst src); 3987 format %{ "movsd $dst,$src\t# if src != dst load double (8 bytes)" %} 3988 ins_encode %{ 3989 ShouldNotReachHere(); 3990 %} 3991 ins_pipe( fpu_reg_reg ); 3992 %} 3993 3994 // Load Double 3995 instruct MoveVL2D(regD dst, vlRegD src) %{ 3996 match(Set dst src); 3997 format %{ "movsd $dst,$src\t! load double (8 bytes)" %} 3998 ins_encode %{ 3999 ShouldNotReachHere(); 4000 %} 4001 ins_pipe( fpu_reg_reg ); 4002 %} 4003 4004 // Load Double 4005 instruct MoveLEG2D(regD dst, legRegD src) %{ 4006 match(Set dst src); 4007 format %{ "movsd $dst,$src\t# if src != dst load double (8 bytes)" %} 4008 ins_encode %{ 4009 ShouldNotReachHere(); 4010 %} 4011 ins_pipe( fpu_reg_reg ); 4012 %} 4013 4014 //----------Load/Store/Move Instructions--------------------------------------- 4015 //----------Load Instructions-------------------------------------------------- 4016 4017 // Load Byte (8 bit signed) 4018 instruct loadB(rRegI dst, memory mem) 4019 %{ 4020 match(Set dst (LoadB mem)); 4021 4022 ins_cost(125); 4023 format %{ "movsbl $dst, $mem\t# byte" %} 4024 4025 ins_encode %{ 4026 __ movsbl($dst$$Register, $mem$$Address); 4027 %} 4028 4029 ins_pipe(ialu_reg_mem); 4030 %} 4031 4032 // Load Byte (8 bit signed) into Long Register 4033 instruct loadB2L(rRegL dst, memory mem) 4034 %{ 4035 match(Set dst (ConvI2L (LoadB mem))); 4036 4037 ins_cost(125); 4038 format %{ "movsbq $dst, $mem\t# byte -> long" %} 4039 4040 ins_encode %{ 4041 __ movsbq($dst$$Register, $mem$$Address); 4042 %} 4043 4044 ins_pipe(ialu_reg_mem); 4045 %} 4046 4047 // Load Unsigned Byte (8 bit UNsigned) 4048 instruct loadUB(rRegI dst, memory mem) 4049 %{ 4050 match(Set dst (LoadUB mem)); 4051 4052 ins_cost(125); 4053 format %{ "movzbl $dst, $mem\t# ubyte" %} 4054 4055 ins_encode %{ 4056 __ movzbl($dst$$Register, $mem$$Address); 4057 %} 4058 4059 ins_pipe(ialu_reg_mem); 4060 %} 4061 4062 // Load Unsigned Byte (8 bit UNsigned) into Long Register 4063 instruct loadUB2L(rRegL dst, memory mem) 4064 %{ 4065 match(Set dst (ConvI2L (LoadUB mem))); 4066 4067 ins_cost(125); 4068 format %{ "movzbq $dst, $mem\t# ubyte -> long" %} 4069 4070 ins_encode %{ 4071 __ movzbq($dst$$Register, $mem$$Address); 4072 %} 4073 4074 ins_pipe(ialu_reg_mem); 4075 %} 4076 4077 // Load Unsigned Byte (8 bit UNsigned) with 32-bit mask into Long Register 4078 instruct loadUB2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 4079 match(Set dst (ConvI2L (AndI (LoadUB mem) mask))); 4080 effect(KILL cr); 4081 4082 format %{ "movzbq $dst, $mem\t# ubyte & 32-bit mask -> long\n\t" 4083 "andl $dst, right_n_bits($mask, 8)" %} 4084 ins_encode %{ 4085 Register Rdst = $dst$$Register; 4086 __ movzbq(Rdst, $mem$$Address); 4087 __ andl(Rdst, $mask$$constant & right_n_bits(8)); 4088 %} 4089 ins_pipe(ialu_reg_mem); 4090 %} 4091 4092 // Load Short (16 bit signed) 4093 instruct loadS(rRegI dst, memory mem) 4094 %{ 4095 match(Set dst (LoadS mem)); 4096 4097 ins_cost(125); 4098 format %{ "movswl $dst, $mem\t# short" %} 4099 4100 ins_encode %{ 4101 __ movswl($dst$$Register, $mem$$Address); 4102 %} 4103 4104 ins_pipe(ialu_reg_mem); 4105 %} 4106 4107 // Load Short (16 bit signed) to Byte (8 bit signed) 4108 instruct loadS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4109 match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour)); 4110 4111 ins_cost(125); 4112 format %{ "movsbl $dst, $mem\t# short -> byte" %} 4113 ins_encode %{ 4114 __ movsbl($dst$$Register, $mem$$Address); 4115 %} 4116 ins_pipe(ialu_reg_mem); 4117 %} 4118 4119 // Load Short (16 bit signed) into Long Register 4120 instruct loadS2L(rRegL dst, memory mem) 4121 %{ 4122 match(Set dst (ConvI2L (LoadS mem))); 4123 4124 ins_cost(125); 4125 format %{ "movswq $dst, $mem\t# short -> long" %} 4126 4127 ins_encode %{ 4128 __ movswq($dst$$Register, $mem$$Address); 4129 %} 4130 4131 ins_pipe(ialu_reg_mem); 4132 %} 4133 4134 // Load Unsigned Short/Char (16 bit UNsigned) 4135 instruct loadUS(rRegI dst, memory mem) 4136 %{ 4137 match(Set dst (LoadUS mem)); 4138 4139 ins_cost(125); 4140 format %{ "movzwl $dst, $mem\t# ushort/char" %} 4141 4142 ins_encode %{ 4143 __ movzwl($dst$$Register, $mem$$Address); 4144 %} 4145 4146 ins_pipe(ialu_reg_mem); 4147 %} 4148 4149 // Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed) 4150 instruct loadUS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4151 match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour)); 4152 4153 ins_cost(125); 4154 format %{ "movsbl $dst, $mem\t# ushort -> byte" %} 4155 ins_encode %{ 4156 __ movsbl($dst$$Register, $mem$$Address); 4157 %} 4158 ins_pipe(ialu_reg_mem); 4159 %} 4160 4161 // Load Unsigned Short/Char (16 bit UNsigned) into Long Register 4162 instruct loadUS2L(rRegL dst, memory mem) 4163 %{ 4164 match(Set dst (ConvI2L (LoadUS mem))); 4165 4166 ins_cost(125); 4167 format %{ "movzwq $dst, $mem\t# ushort/char -> long" %} 4168 4169 ins_encode %{ 4170 __ movzwq($dst$$Register, $mem$$Address); 4171 %} 4172 4173 ins_pipe(ialu_reg_mem); 4174 %} 4175 4176 // Load Unsigned Short/Char (16 bit UNsigned) with mask 0xFF into Long Register 4177 instruct loadUS2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 4178 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 4179 4180 format %{ "movzbq $dst, $mem\t# ushort/char & 0xFF -> long" %} 4181 ins_encode %{ 4182 __ movzbq($dst$$Register, $mem$$Address); 4183 %} 4184 ins_pipe(ialu_reg_mem); 4185 %} 4186 4187 // Load Unsigned Short/Char (16 bit UNsigned) with 32-bit mask into Long Register 4188 instruct loadUS2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 4189 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 4190 effect(KILL cr); 4191 4192 format %{ "movzwq $dst, $mem\t# ushort/char & 32-bit mask -> long\n\t" 4193 "andl $dst, right_n_bits($mask, 16)" %} 4194 ins_encode %{ 4195 Register Rdst = $dst$$Register; 4196 __ movzwq(Rdst, $mem$$Address); 4197 __ andl(Rdst, $mask$$constant & right_n_bits(16)); 4198 %} 4199 ins_pipe(ialu_reg_mem); 4200 %} 4201 4202 // Load Integer 4203 instruct loadI(rRegI dst, memory mem) 4204 %{ 4205 match(Set dst (LoadI mem)); 4206 4207 ins_cost(125); 4208 format %{ "movl $dst, $mem\t# int" %} 4209 4210 ins_encode %{ 4211 __ movl($dst$$Register, $mem$$Address); 4212 %} 4213 4214 ins_pipe(ialu_reg_mem); 4215 %} 4216 4217 // Load Integer (32 bit signed) to Byte (8 bit signed) 4218 instruct loadI2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4219 match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour)); 4220 4221 ins_cost(125); 4222 format %{ "movsbl $dst, $mem\t# int -> byte" %} 4223 ins_encode %{ 4224 __ movsbl($dst$$Register, $mem$$Address); 4225 %} 4226 ins_pipe(ialu_reg_mem); 4227 %} 4228 4229 // Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned) 4230 instruct loadI2UB(rRegI dst, memory mem, immI_255 mask) %{ 4231 match(Set dst (AndI (LoadI mem) mask)); 4232 4233 ins_cost(125); 4234 format %{ "movzbl $dst, $mem\t# int -> ubyte" %} 4235 ins_encode %{ 4236 __ movzbl($dst$$Register, $mem$$Address); 4237 %} 4238 ins_pipe(ialu_reg_mem); 4239 %} 4240 4241 // Load Integer (32 bit signed) to Short (16 bit signed) 4242 instruct loadI2S(rRegI dst, memory mem, immI_16 sixteen) %{ 4243 match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen)); 4244 4245 ins_cost(125); 4246 format %{ "movswl $dst, $mem\t# int -> short" %} 4247 ins_encode %{ 4248 __ movswl($dst$$Register, $mem$$Address); 4249 %} 4250 ins_pipe(ialu_reg_mem); 4251 %} 4252 4253 // Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned) 4254 instruct loadI2US(rRegI dst, memory mem, immI_65535 mask) %{ 4255 match(Set dst (AndI (LoadI mem) mask)); 4256 4257 ins_cost(125); 4258 format %{ "movzwl $dst, $mem\t# int -> ushort/char" %} 4259 ins_encode %{ 4260 __ movzwl($dst$$Register, $mem$$Address); 4261 %} 4262 ins_pipe(ialu_reg_mem); 4263 %} 4264 4265 // Load Integer into Long Register 4266 instruct loadI2L(rRegL dst, memory mem) 4267 %{ 4268 match(Set dst (ConvI2L (LoadI mem))); 4269 4270 ins_cost(125); 4271 format %{ "movslq $dst, $mem\t# int -> long" %} 4272 4273 ins_encode %{ 4274 __ movslq($dst$$Register, $mem$$Address); 4275 %} 4276 4277 ins_pipe(ialu_reg_mem); 4278 %} 4279 4280 // Load Integer with mask 0xFF into Long Register 4281 instruct loadI2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 4282 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4283 4284 format %{ "movzbq $dst, $mem\t# int & 0xFF -> long" %} 4285 ins_encode %{ 4286 __ movzbq($dst$$Register, $mem$$Address); 4287 %} 4288 ins_pipe(ialu_reg_mem); 4289 %} 4290 4291 // Load Integer with mask 0xFFFF into Long Register 4292 instruct loadI2L_immI_65535(rRegL dst, memory mem, immI_65535 mask) %{ 4293 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4294 4295 format %{ "movzwq $dst, $mem\t# int & 0xFFFF -> long" %} 4296 ins_encode %{ 4297 __ movzwq($dst$$Register, $mem$$Address); 4298 %} 4299 ins_pipe(ialu_reg_mem); 4300 %} 4301 4302 // Load Integer with a 31-bit mask into Long Register 4303 instruct loadI2L_immU31(rRegL dst, memory mem, immU31 mask, rFlagsReg cr) %{ 4304 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4305 effect(KILL cr); 4306 4307 format %{ "movl $dst, $mem\t# int & 31-bit mask -> long\n\t" 4308 "andl $dst, $mask" %} 4309 ins_encode %{ 4310 Register Rdst = $dst$$Register; 4311 __ movl(Rdst, $mem$$Address); 4312 __ andl(Rdst, $mask$$constant); 4313 %} 4314 ins_pipe(ialu_reg_mem); 4315 %} 4316 4317 // Load Unsigned Integer into Long Register 4318 instruct loadUI2L(rRegL dst, memory mem, immL_32bits mask) 4319 %{ 4320 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 4321 4322 ins_cost(125); 4323 format %{ "movl $dst, $mem\t# uint -> long" %} 4324 4325 ins_encode %{ 4326 __ movl($dst$$Register, $mem$$Address); 4327 %} 4328 4329 ins_pipe(ialu_reg_mem); 4330 %} 4331 4332 // Load Long 4333 instruct loadL(rRegL dst, memory mem) 4334 %{ 4335 match(Set dst (LoadL mem)); 4336 4337 ins_cost(125); 4338 format %{ "movq $dst, $mem\t# long" %} 4339 4340 ins_encode %{ 4341 __ movq($dst$$Register, $mem$$Address); 4342 %} 4343 4344 ins_pipe(ialu_reg_mem); // XXX 4345 %} 4346 4347 // Load Range 4348 instruct loadRange(rRegI dst, memory mem) 4349 %{ 4350 match(Set dst (LoadRange mem)); 4351 4352 ins_cost(125); // XXX 4353 format %{ "movl $dst, $mem\t# range" %} 4354 ins_encode %{ 4355 __ movl($dst$$Register, $mem$$Address); 4356 %} 4357 ins_pipe(ialu_reg_mem); 4358 %} 4359 4360 // Load Pointer 4361 instruct loadP(rRegP dst, memory mem) 4362 %{ 4363 match(Set dst (LoadP mem)); 4364 predicate(n->as_Load()->barrier_data() == 0); 4365 4366 ins_cost(125); // XXX 4367 format %{ "movq $dst, $mem\t# ptr" %} 4368 ins_encode %{ 4369 __ movq($dst$$Register, $mem$$Address); 4370 %} 4371 ins_pipe(ialu_reg_mem); // XXX 4372 %} 4373 4374 // Load Compressed Pointer 4375 instruct loadN(rRegN dst, memory mem) 4376 %{ 4377 predicate(n->as_Load()->barrier_data() == 0); 4378 match(Set dst (LoadN mem)); 4379 4380 ins_cost(125); // XXX 4381 format %{ "movl $dst, $mem\t# compressed ptr" %} 4382 ins_encode %{ 4383 __ movl($dst$$Register, $mem$$Address); 4384 %} 4385 ins_pipe(ialu_reg_mem); // XXX 4386 %} 4387 4388 4389 // Load Klass Pointer 4390 instruct loadKlass(rRegP dst, memory mem) 4391 %{ 4392 match(Set dst (LoadKlass mem)); 4393 4394 ins_cost(125); // XXX 4395 format %{ "movq $dst, $mem\t# class" %} 4396 ins_encode %{ 4397 __ movq($dst$$Register, $mem$$Address); 4398 %} 4399 ins_pipe(ialu_reg_mem); // XXX 4400 %} 4401 4402 // Load narrow Klass Pointer 4403 instruct loadNKlass(rRegN dst, memory mem) 4404 %{ 4405 predicate(!UseCompactObjectHeaders); 4406 match(Set dst (LoadNKlass mem)); 4407 4408 ins_cost(125); // XXX 4409 format %{ "movl $dst, $mem\t# compressed klass ptr" %} 4410 ins_encode %{ 4411 __ movl($dst$$Register, $mem$$Address); 4412 %} 4413 ins_pipe(ialu_reg_mem); // XXX 4414 %} 4415 4416 instruct loadNKlassCompactHeaders(rRegN dst, memory mem, rFlagsReg cr) 4417 %{ 4418 predicate(UseCompactObjectHeaders); 4419 match(Set dst (LoadNKlass mem)); 4420 effect(KILL cr); 4421 ins_cost(125); 4422 format %{ 4423 "movl $dst, $mem\t# compressed klass ptr, shifted\n\t" 4424 "shrl $dst, markWord::klass_shift_at_offset" 4425 %} 4426 ins_encode %{ 4427 if (UseAPX) { 4428 __ eshrl($dst$$Register, $mem$$Address, markWord::klass_shift_at_offset, false); 4429 } 4430 else { 4431 __ movl($dst$$Register, $mem$$Address); 4432 __ shrl($dst$$Register, markWord::klass_shift_at_offset); 4433 } 4434 %} 4435 ins_pipe(ialu_reg_mem); 4436 %} 4437 4438 // Load Float 4439 instruct loadF(regF dst, memory mem) 4440 %{ 4441 match(Set dst (LoadF mem)); 4442 4443 ins_cost(145); // XXX 4444 format %{ "movss $dst, $mem\t# float" %} 4445 ins_encode %{ 4446 __ movflt($dst$$XMMRegister, $mem$$Address); 4447 %} 4448 ins_pipe(pipe_slow); // XXX 4449 %} 4450 4451 // Load Double 4452 instruct loadD_partial(regD dst, memory mem) 4453 %{ 4454 predicate(!UseXmmLoadAndClearUpper); 4455 match(Set dst (LoadD mem)); 4456 4457 ins_cost(145); // XXX 4458 format %{ "movlpd $dst, $mem\t# double" %} 4459 ins_encode %{ 4460 __ movdbl($dst$$XMMRegister, $mem$$Address); 4461 %} 4462 ins_pipe(pipe_slow); // XXX 4463 %} 4464 4465 instruct loadD(regD dst, memory mem) 4466 %{ 4467 predicate(UseXmmLoadAndClearUpper); 4468 match(Set dst (LoadD mem)); 4469 4470 ins_cost(145); // XXX 4471 format %{ "movsd $dst, $mem\t# double" %} 4472 ins_encode %{ 4473 __ movdbl($dst$$XMMRegister, $mem$$Address); 4474 %} 4475 ins_pipe(pipe_slow); // XXX 4476 %} 4477 4478 // max = java.lang.Math.max(float a, float b) 4479 instruct maxF_avx10_reg(regF dst, regF a, regF b) %{ 4480 predicate(VM_Version::supports_avx10_2()); 4481 match(Set dst (MaxF a b)); 4482 format %{ "maxF $dst, $a, $b" %} 4483 ins_encode %{ 4484 __ eminmaxss($dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, AVX10_MINMAX_MAX_COMPARE_SIGN); 4485 %} 4486 ins_pipe( pipe_slow ); 4487 %} 4488 4489 // max = java.lang.Math.max(float a, float b) 4490 instruct maxF_reg(legRegF dst, legRegF a, legRegF b, legRegF tmp, legRegF atmp, legRegF btmp) %{ 4491 predicate(!VM_Version::supports_avx10_2() && UseAVX > 0 && !VLoopReductions::is_reduction(n)); 4492 match(Set dst (MaxF a b)); 4493 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 4494 format %{ "maxF $dst, $a, $b \t! using $tmp, $atmp and $btmp as TEMP" %} 4495 ins_encode %{ 4496 __ vminmax_fp(Op_MaxV, T_FLOAT, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, Assembler::AVX_128bit); 4497 %} 4498 ins_pipe( pipe_slow ); 4499 %} 4500 4501 instruct maxF_reduction_reg(legRegF dst, legRegF a, legRegF b, legRegF xtmp, rRegI rtmp, rFlagsReg cr) %{ 4502 predicate(!VM_Version::supports_avx10_2() && UseAVX > 0 && VLoopReductions::is_reduction(n)); 4503 match(Set dst (MaxF a b)); 4504 effect(USE a, USE b, TEMP xtmp, TEMP rtmp, KILL cr); 4505 4506 format %{ "maxF_reduction $dst, $a, $b \t!using $xtmp and $rtmp as TEMP" %} 4507 ins_encode %{ 4508 emit_fp_min_max(masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xtmp$$XMMRegister, $rtmp$$Register, 4509 false /*min*/, true /*single*/); 4510 %} 4511 ins_pipe( pipe_slow ); 4512 %} 4513 4514 // max = java.lang.Math.max(double a, double b) 4515 instruct maxD_avx10_reg(regD dst, regD a, regD b) %{ 4516 predicate(VM_Version::supports_avx10_2()); 4517 match(Set dst (MaxD a b)); 4518 format %{ "maxD $dst, $a, $b" %} 4519 ins_encode %{ 4520 __ eminmaxsd($dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, AVX10_MINMAX_MAX_COMPARE_SIGN); 4521 %} 4522 ins_pipe( pipe_slow ); 4523 %} 4524 4525 // max = java.lang.Math.max(double a, double b) 4526 instruct maxD_reg(legRegD dst, legRegD a, legRegD b, legRegD tmp, legRegD atmp, legRegD btmp) %{ 4527 predicate(!VM_Version::supports_avx10_2() && UseAVX > 0 && !VLoopReductions::is_reduction(n)); 4528 match(Set dst (MaxD a b)); 4529 effect(USE a, USE b, TEMP atmp, TEMP btmp, TEMP tmp); 4530 format %{ "maxD $dst, $a, $b \t! using $tmp, $atmp and $btmp as TEMP" %} 4531 ins_encode %{ 4532 __ vminmax_fp(Op_MaxV, T_DOUBLE, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, Assembler::AVX_128bit); 4533 %} 4534 ins_pipe( pipe_slow ); 4535 %} 4536 4537 instruct maxD_reduction_reg(legRegD dst, legRegD a, legRegD b, legRegD xtmp, rRegL rtmp, rFlagsReg cr) %{ 4538 predicate(!VM_Version::supports_avx10_2() && UseAVX > 0 && VLoopReductions::is_reduction(n)); 4539 match(Set dst (MaxD a b)); 4540 effect(USE a, USE b, TEMP xtmp, TEMP rtmp, KILL cr); 4541 4542 format %{ "maxD_reduction $dst, $a, $b \t! using $xtmp and $rtmp as TEMP" %} 4543 ins_encode %{ 4544 emit_fp_min_max(masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xtmp$$XMMRegister, $rtmp$$Register, 4545 false /*min*/, false /*single*/); 4546 %} 4547 ins_pipe( pipe_slow ); 4548 %} 4549 4550 // max = java.lang.Math.min(float a, float b) 4551 instruct minF_avx10_reg(regF dst, regF a, regF b) %{ 4552 predicate(VM_Version::supports_avx10_2()); 4553 match(Set dst (MinF a b)); 4554 format %{ "minF $dst, $a, $b" %} 4555 ins_encode %{ 4556 __ eminmaxss($dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, AVX10_MINMAX_MIN_COMPARE_SIGN); 4557 %} 4558 ins_pipe( pipe_slow ); 4559 %} 4560 4561 // min = java.lang.Math.min(float a, float b) 4562 instruct minF_reg(legRegF dst, legRegF a, legRegF b, legRegF tmp, legRegF atmp, legRegF btmp) %{ 4563 predicate(!VM_Version::supports_avx10_2() && UseAVX > 0 && !VLoopReductions::is_reduction(n)); 4564 match(Set dst (MinF a b)); 4565 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 4566 format %{ "minF $dst, $a, $b \t! using $tmp, $atmp and $btmp as TEMP" %} 4567 ins_encode %{ 4568 __ vminmax_fp(Op_MinV, T_FLOAT, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, Assembler::AVX_128bit); 4569 %} 4570 ins_pipe( pipe_slow ); 4571 %} 4572 4573 instruct minF_reduction_reg(legRegF dst, legRegF a, legRegF b, legRegF xtmp, rRegI rtmp, rFlagsReg cr) %{ 4574 predicate(!VM_Version::supports_avx10_2() && UseAVX > 0 && VLoopReductions::is_reduction(n)); 4575 match(Set dst (MinF a b)); 4576 effect(USE a, USE b, TEMP xtmp, TEMP rtmp, KILL cr); 4577 4578 format %{ "minF_reduction $dst, $a, $b \t! using $xtmp and $rtmp as TEMP" %} 4579 ins_encode %{ 4580 emit_fp_min_max(masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xtmp$$XMMRegister, $rtmp$$Register, 4581 true /*min*/, true /*single*/); 4582 %} 4583 ins_pipe( pipe_slow ); 4584 %} 4585 4586 // max = java.lang.Math.min(double a, double b) 4587 instruct minD_avx10_reg(regD dst, regD a, regD b) %{ 4588 predicate(VM_Version::supports_avx10_2()); 4589 match(Set dst (MinD a b)); 4590 format %{ "minD $dst, $a, $b" %} 4591 ins_encode %{ 4592 __ eminmaxsd($dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, AVX10_MINMAX_MIN_COMPARE_SIGN); 4593 %} 4594 ins_pipe( pipe_slow ); 4595 %} 4596 4597 // min = java.lang.Math.min(double a, double b) 4598 instruct minD_reg(legRegD dst, legRegD a, legRegD b, legRegD tmp, legRegD atmp, legRegD btmp) %{ 4599 predicate(!VM_Version::supports_avx10_2() && UseAVX > 0 && !VLoopReductions::is_reduction(n)); 4600 match(Set dst (MinD a b)); 4601 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 4602 format %{ "minD $dst, $a, $b \t! using $tmp, $atmp and $btmp as TEMP" %} 4603 ins_encode %{ 4604 __ vminmax_fp(Op_MinV, T_DOUBLE, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, Assembler::AVX_128bit); 4605 %} 4606 ins_pipe( pipe_slow ); 4607 %} 4608 4609 instruct minD_reduction_reg(legRegD dst, legRegD a, legRegD b, legRegD xtmp, rRegL rtmp, rFlagsReg cr) %{ 4610 predicate(!VM_Version::supports_avx10_2() && UseAVX > 0 && VLoopReductions::is_reduction(n)); 4611 match(Set dst (MinD a b)); 4612 effect(USE a, USE b, TEMP xtmp, TEMP rtmp, KILL cr); 4613 4614 format %{ "maxD_reduction $dst, $a, $b \t! using $xtmp and $rtmp as TEMP" %} 4615 ins_encode %{ 4616 emit_fp_min_max(masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xtmp$$XMMRegister, $rtmp$$Register, 4617 true /*min*/, false /*single*/); 4618 %} 4619 ins_pipe( pipe_slow ); 4620 %} 4621 4622 // Load Effective Address 4623 instruct leaP8(rRegP dst, indOffset8 mem) 4624 %{ 4625 match(Set dst mem); 4626 4627 ins_cost(110); // XXX 4628 format %{ "leaq $dst, $mem\t# ptr 8" %} 4629 ins_encode %{ 4630 __ leaq($dst$$Register, $mem$$Address); 4631 %} 4632 ins_pipe(ialu_reg_reg_fat); 4633 %} 4634 4635 instruct leaP32(rRegP dst, indOffset32 mem) 4636 %{ 4637 match(Set dst mem); 4638 4639 ins_cost(110); 4640 format %{ "leaq $dst, $mem\t# ptr 32" %} 4641 ins_encode %{ 4642 __ leaq($dst$$Register, $mem$$Address); 4643 %} 4644 ins_pipe(ialu_reg_reg_fat); 4645 %} 4646 4647 instruct leaPIdxOff(rRegP dst, indIndexOffset mem) 4648 %{ 4649 match(Set dst mem); 4650 4651 ins_cost(110); 4652 format %{ "leaq $dst, $mem\t# ptr idxoff" %} 4653 ins_encode %{ 4654 __ leaq($dst$$Register, $mem$$Address); 4655 %} 4656 ins_pipe(ialu_reg_reg_fat); 4657 %} 4658 4659 instruct leaPIdxScale(rRegP dst, indIndexScale mem) 4660 %{ 4661 match(Set dst mem); 4662 4663 ins_cost(110); 4664 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 4665 ins_encode %{ 4666 __ leaq($dst$$Register, $mem$$Address); 4667 %} 4668 ins_pipe(ialu_reg_reg_fat); 4669 %} 4670 4671 instruct leaPPosIdxScale(rRegP dst, indPosIndexScale mem) 4672 %{ 4673 match(Set dst mem); 4674 4675 ins_cost(110); 4676 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 4677 ins_encode %{ 4678 __ leaq($dst$$Register, $mem$$Address); 4679 %} 4680 ins_pipe(ialu_reg_reg_fat); 4681 %} 4682 4683 instruct leaPIdxScaleOff(rRegP dst, indIndexScaleOffset mem) 4684 %{ 4685 match(Set dst mem); 4686 4687 ins_cost(110); 4688 format %{ "leaq $dst, $mem\t# ptr idxscaleoff" %} 4689 ins_encode %{ 4690 __ leaq($dst$$Register, $mem$$Address); 4691 %} 4692 ins_pipe(ialu_reg_reg_fat); 4693 %} 4694 4695 instruct leaPPosIdxOff(rRegP dst, indPosIndexOffset mem) 4696 %{ 4697 match(Set dst mem); 4698 4699 ins_cost(110); 4700 format %{ "leaq $dst, $mem\t# ptr posidxoff" %} 4701 ins_encode %{ 4702 __ leaq($dst$$Register, $mem$$Address); 4703 %} 4704 ins_pipe(ialu_reg_reg_fat); 4705 %} 4706 4707 instruct leaPPosIdxScaleOff(rRegP dst, indPosIndexScaleOffset mem) 4708 %{ 4709 match(Set dst mem); 4710 4711 ins_cost(110); 4712 format %{ "leaq $dst, $mem\t# ptr posidxscaleoff" %} 4713 ins_encode %{ 4714 __ leaq($dst$$Register, $mem$$Address); 4715 %} 4716 ins_pipe(ialu_reg_reg_fat); 4717 %} 4718 4719 // Load Effective Address which uses Narrow (32-bits) oop 4720 instruct leaPCompressedOopOffset(rRegP dst, indCompressedOopOffset mem) 4721 %{ 4722 predicate(UseCompressedOops && (CompressedOops::shift() != 0)); 4723 match(Set dst mem); 4724 4725 ins_cost(110); 4726 format %{ "leaq $dst, $mem\t# ptr compressedoopoff32" %} 4727 ins_encode %{ 4728 __ leaq($dst$$Register, $mem$$Address); 4729 %} 4730 ins_pipe(ialu_reg_reg_fat); 4731 %} 4732 4733 instruct leaP8Narrow(rRegP dst, indOffset8Narrow mem) 4734 %{ 4735 predicate(CompressedOops::shift() == 0); 4736 match(Set dst mem); 4737 4738 ins_cost(110); // XXX 4739 format %{ "leaq $dst, $mem\t# ptr off8narrow" %} 4740 ins_encode %{ 4741 __ leaq($dst$$Register, $mem$$Address); 4742 %} 4743 ins_pipe(ialu_reg_reg_fat); 4744 %} 4745 4746 instruct leaP32Narrow(rRegP dst, indOffset32Narrow mem) 4747 %{ 4748 predicate(CompressedOops::shift() == 0); 4749 match(Set dst mem); 4750 4751 ins_cost(110); 4752 format %{ "leaq $dst, $mem\t# ptr off32narrow" %} 4753 ins_encode %{ 4754 __ leaq($dst$$Register, $mem$$Address); 4755 %} 4756 ins_pipe(ialu_reg_reg_fat); 4757 %} 4758 4759 instruct leaPIdxOffNarrow(rRegP dst, indIndexOffsetNarrow mem) 4760 %{ 4761 predicate(CompressedOops::shift() == 0); 4762 match(Set dst mem); 4763 4764 ins_cost(110); 4765 format %{ "leaq $dst, $mem\t# ptr idxoffnarrow" %} 4766 ins_encode %{ 4767 __ leaq($dst$$Register, $mem$$Address); 4768 %} 4769 ins_pipe(ialu_reg_reg_fat); 4770 %} 4771 4772 instruct leaPIdxScaleNarrow(rRegP dst, indIndexScaleNarrow mem) 4773 %{ 4774 predicate(CompressedOops::shift() == 0); 4775 match(Set dst mem); 4776 4777 ins_cost(110); 4778 format %{ "leaq $dst, $mem\t# ptr idxscalenarrow" %} 4779 ins_encode %{ 4780 __ leaq($dst$$Register, $mem$$Address); 4781 %} 4782 ins_pipe(ialu_reg_reg_fat); 4783 %} 4784 4785 instruct leaPIdxScaleOffNarrow(rRegP dst, indIndexScaleOffsetNarrow mem) 4786 %{ 4787 predicate(CompressedOops::shift() == 0); 4788 match(Set dst mem); 4789 4790 ins_cost(110); 4791 format %{ "leaq $dst, $mem\t# ptr idxscaleoffnarrow" %} 4792 ins_encode %{ 4793 __ leaq($dst$$Register, $mem$$Address); 4794 %} 4795 ins_pipe(ialu_reg_reg_fat); 4796 %} 4797 4798 instruct leaPPosIdxOffNarrow(rRegP dst, indPosIndexOffsetNarrow mem) 4799 %{ 4800 predicate(CompressedOops::shift() == 0); 4801 match(Set dst mem); 4802 4803 ins_cost(110); 4804 format %{ "leaq $dst, $mem\t# ptr posidxoffnarrow" %} 4805 ins_encode %{ 4806 __ leaq($dst$$Register, $mem$$Address); 4807 %} 4808 ins_pipe(ialu_reg_reg_fat); 4809 %} 4810 4811 instruct leaPPosIdxScaleOffNarrow(rRegP dst, indPosIndexScaleOffsetNarrow mem) 4812 %{ 4813 predicate(CompressedOops::shift() == 0); 4814 match(Set dst mem); 4815 4816 ins_cost(110); 4817 format %{ "leaq $dst, $mem\t# ptr posidxscaleoffnarrow" %} 4818 ins_encode %{ 4819 __ leaq($dst$$Register, $mem$$Address); 4820 %} 4821 ins_pipe(ialu_reg_reg_fat); 4822 %} 4823 4824 instruct loadConI(rRegI dst, immI src) 4825 %{ 4826 match(Set dst src); 4827 4828 format %{ "movl $dst, $src\t# int" %} 4829 ins_encode %{ 4830 __ movl($dst$$Register, $src$$constant); 4831 %} 4832 ins_pipe(ialu_reg_fat); // XXX 4833 %} 4834 4835 instruct loadConI0(rRegI dst, immI_0 src, rFlagsReg cr) 4836 %{ 4837 match(Set dst src); 4838 effect(KILL cr); 4839 4840 ins_cost(50); 4841 format %{ "xorl $dst, $dst\t# int" %} 4842 ins_encode %{ 4843 __ xorl($dst$$Register, $dst$$Register); 4844 %} 4845 ins_pipe(ialu_reg); 4846 %} 4847 4848 instruct loadConL(rRegL dst, immL src) 4849 %{ 4850 match(Set dst src); 4851 4852 ins_cost(150); 4853 format %{ "movq $dst, $src\t# long" %} 4854 ins_encode %{ 4855 __ mov64($dst$$Register, $src$$constant); 4856 %} 4857 ins_pipe(ialu_reg); 4858 %} 4859 4860 instruct loadConL0(rRegL dst, immL0 src, rFlagsReg cr) 4861 %{ 4862 match(Set dst src); 4863 effect(KILL cr); 4864 4865 ins_cost(50); 4866 format %{ "xorl $dst, $dst\t# long" %} 4867 ins_encode %{ 4868 __ xorl($dst$$Register, $dst$$Register); 4869 %} 4870 ins_pipe(ialu_reg); // XXX 4871 %} 4872 4873 instruct loadConUL32(rRegL dst, immUL32 src) 4874 %{ 4875 match(Set dst src); 4876 4877 ins_cost(60); 4878 format %{ "movl $dst, $src\t# long (unsigned 32-bit)" %} 4879 ins_encode %{ 4880 __ movl($dst$$Register, $src$$constant); 4881 %} 4882 ins_pipe(ialu_reg); 4883 %} 4884 4885 instruct loadConL32(rRegL dst, immL32 src) 4886 %{ 4887 match(Set dst src); 4888 4889 ins_cost(70); 4890 format %{ "movq $dst, $src\t# long (32-bit)" %} 4891 ins_encode %{ 4892 __ movq($dst$$Register, $src$$constant); 4893 %} 4894 ins_pipe(ialu_reg); 4895 %} 4896 4897 instruct loadConP(rRegP dst, immP con) %{ 4898 match(Set dst con); 4899 4900 format %{ "movq $dst, $con\t# ptr" %} 4901 ins_encode %{ 4902 __ mov64($dst$$Register, $con$$constant, $con->constant_reloc(), RELOC_IMM64); 4903 %} 4904 ins_pipe(ialu_reg_fat); // XXX 4905 %} 4906 4907 instruct loadConP0(rRegP dst, immP0 src, rFlagsReg cr) 4908 %{ 4909 match(Set dst src); 4910 effect(KILL cr); 4911 4912 ins_cost(50); 4913 format %{ "xorl $dst, $dst\t# ptr" %} 4914 ins_encode %{ 4915 __ xorl($dst$$Register, $dst$$Register); 4916 %} 4917 ins_pipe(ialu_reg); 4918 %} 4919 4920 instruct loadConP31(rRegP dst, immP31 src, rFlagsReg cr) 4921 %{ 4922 match(Set dst src); 4923 effect(KILL cr); 4924 4925 ins_cost(60); 4926 format %{ "movl $dst, $src\t# ptr (positive 32-bit)" %} 4927 ins_encode %{ 4928 __ movl($dst$$Register, $src$$constant); 4929 %} 4930 ins_pipe(ialu_reg); 4931 %} 4932 4933 instruct loadConF(regF dst, immF con) %{ 4934 match(Set dst con); 4935 ins_cost(125); 4936 format %{ "movss $dst, [$constantaddress]\t# load from constant table: float=$con" %} 4937 ins_encode %{ 4938 __ movflt($dst$$XMMRegister, $constantaddress($con)); 4939 %} 4940 ins_pipe(pipe_slow); 4941 %} 4942 4943 instruct loadConH(regF dst, immH con) %{ 4944 match(Set dst con); 4945 ins_cost(125); 4946 format %{ "movss $dst, [$constantaddress]\t# load from constant table: halffloat=$con" %} 4947 ins_encode %{ 4948 __ movflt($dst$$XMMRegister, $constantaddress($con)); 4949 %} 4950 ins_pipe(pipe_slow); 4951 %} 4952 4953 instruct loadConN0(rRegN dst, immN0 src, rFlagsReg cr) %{ 4954 match(Set dst src); 4955 effect(KILL cr); 4956 format %{ "xorq $dst, $src\t# compressed null pointer" %} 4957 ins_encode %{ 4958 __ xorq($dst$$Register, $dst$$Register); 4959 %} 4960 ins_pipe(ialu_reg); 4961 %} 4962 4963 instruct loadConN(rRegN dst, immN src) %{ 4964 match(Set dst src); 4965 4966 ins_cost(125); 4967 format %{ "movl $dst, $src\t# compressed ptr" %} 4968 ins_encode %{ 4969 address con = (address)$src$$constant; 4970 if (con == nullptr) { 4971 ShouldNotReachHere(); 4972 } else { 4973 __ set_narrow_oop($dst$$Register, (jobject)$src$$constant); 4974 } 4975 %} 4976 ins_pipe(ialu_reg_fat); // XXX 4977 %} 4978 4979 instruct loadConNKlass(rRegN dst, immNKlass src) %{ 4980 match(Set dst src); 4981 4982 ins_cost(125); 4983 format %{ "movl $dst, $src\t# compressed klass ptr" %} 4984 ins_encode %{ 4985 address con = (address)$src$$constant; 4986 if (con == nullptr) { 4987 ShouldNotReachHere(); 4988 } else { 4989 __ set_narrow_klass($dst$$Register, (Klass*)$src$$constant); 4990 } 4991 %} 4992 ins_pipe(ialu_reg_fat); // XXX 4993 %} 4994 4995 instruct loadConF0(regF dst, immF0 src) 4996 %{ 4997 match(Set dst src); 4998 ins_cost(100); 4999 5000 format %{ "xorps $dst, $dst\t# float 0.0" %} 5001 ins_encode %{ 5002 __ xorps($dst$$XMMRegister, $dst$$XMMRegister); 5003 %} 5004 ins_pipe(pipe_slow); 5005 %} 5006 5007 // Use the same format since predicate() can not be used here. 5008 instruct loadConD(regD dst, immD con) %{ 5009 match(Set dst con); 5010 ins_cost(125); 5011 format %{ "movsd $dst, [$constantaddress]\t# load from constant table: double=$con" %} 5012 ins_encode %{ 5013 __ movdbl($dst$$XMMRegister, $constantaddress($con)); 5014 %} 5015 ins_pipe(pipe_slow); 5016 %} 5017 5018 instruct loadConD0(regD dst, immD0 src) 5019 %{ 5020 match(Set dst src); 5021 ins_cost(100); 5022 5023 format %{ "xorpd $dst, $dst\t# double 0.0" %} 5024 ins_encode %{ 5025 __ xorpd($dst$$XMMRegister, $dst$$XMMRegister); 5026 %} 5027 ins_pipe(pipe_slow); 5028 %} 5029 5030 instruct loadSSI(rRegI dst, stackSlotI src) 5031 %{ 5032 match(Set dst src); 5033 5034 ins_cost(125); 5035 format %{ "movl $dst, $src\t# int stk" %} 5036 ins_encode %{ 5037 __ movl($dst$$Register, $src$$Address); 5038 %} 5039 ins_pipe(ialu_reg_mem); 5040 %} 5041 5042 instruct loadSSL(rRegL dst, stackSlotL src) 5043 %{ 5044 match(Set dst src); 5045 5046 ins_cost(125); 5047 format %{ "movq $dst, $src\t# long stk" %} 5048 ins_encode %{ 5049 __ movq($dst$$Register, $src$$Address); 5050 %} 5051 ins_pipe(ialu_reg_mem); 5052 %} 5053 5054 instruct loadSSP(rRegP dst, stackSlotP src) 5055 %{ 5056 match(Set dst src); 5057 5058 ins_cost(125); 5059 format %{ "movq $dst, $src\t# ptr stk" %} 5060 ins_encode %{ 5061 __ movq($dst$$Register, $src$$Address); 5062 %} 5063 ins_pipe(ialu_reg_mem); 5064 %} 5065 5066 instruct loadSSF(regF dst, stackSlotF src) 5067 %{ 5068 match(Set dst src); 5069 5070 ins_cost(125); 5071 format %{ "movss $dst, $src\t# float stk" %} 5072 ins_encode %{ 5073 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 5074 %} 5075 ins_pipe(pipe_slow); // XXX 5076 %} 5077 5078 // Use the same format since predicate() can not be used here. 5079 instruct loadSSD(regD dst, stackSlotD src) 5080 %{ 5081 match(Set dst src); 5082 5083 ins_cost(125); 5084 format %{ "movsd $dst, $src\t# double stk" %} 5085 ins_encode %{ 5086 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 5087 %} 5088 ins_pipe(pipe_slow); // XXX 5089 %} 5090 5091 // Prefetch instructions for allocation. 5092 // Must be safe to execute with invalid address (cannot fault). 5093 5094 instruct prefetchAlloc( memory mem ) %{ 5095 predicate(AllocatePrefetchInstr==3); 5096 match(PrefetchAllocation mem); 5097 ins_cost(125); 5098 5099 format %{ "PREFETCHW $mem\t# Prefetch allocation into level 1 cache and mark modified" %} 5100 ins_encode %{ 5101 __ prefetchw($mem$$Address); 5102 %} 5103 ins_pipe(ialu_mem); 5104 %} 5105 5106 instruct prefetchAllocNTA( memory mem ) %{ 5107 predicate(AllocatePrefetchInstr==0); 5108 match(PrefetchAllocation mem); 5109 ins_cost(125); 5110 5111 format %{ "PREFETCHNTA $mem\t# Prefetch allocation to non-temporal cache for write" %} 5112 ins_encode %{ 5113 __ prefetchnta($mem$$Address); 5114 %} 5115 ins_pipe(ialu_mem); 5116 %} 5117 5118 instruct prefetchAllocT0( memory mem ) %{ 5119 predicate(AllocatePrefetchInstr==1); 5120 match(PrefetchAllocation mem); 5121 ins_cost(125); 5122 5123 format %{ "PREFETCHT0 $mem\t# Prefetch allocation to level 1 and 2 caches for write" %} 5124 ins_encode %{ 5125 __ prefetcht0($mem$$Address); 5126 %} 5127 ins_pipe(ialu_mem); 5128 %} 5129 5130 instruct prefetchAllocT2( memory mem ) %{ 5131 predicate(AllocatePrefetchInstr==2); 5132 match(PrefetchAllocation mem); 5133 ins_cost(125); 5134 5135 format %{ "PREFETCHT2 $mem\t# Prefetch allocation to level 2 cache for write" %} 5136 ins_encode %{ 5137 __ prefetcht2($mem$$Address); 5138 %} 5139 ins_pipe(ialu_mem); 5140 %} 5141 5142 //----------Store Instructions------------------------------------------------- 5143 5144 // Store Byte 5145 instruct storeB(memory mem, rRegI src) 5146 %{ 5147 match(Set mem (StoreB mem src)); 5148 5149 ins_cost(125); // XXX 5150 format %{ "movb $mem, $src\t# byte" %} 5151 ins_encode %{ 5152 __ movb($mem$$Address, $src$$Register); 5153 %} 5154 ins_pipe(ialu_mem_reg); 5155 %} 5156 5157 // Store Char/Short 5158 instruct storeC(memory mem, rRegI src) 5159 %{ 5160 match(Set mem (StoreC mem src)); 5161 5162 ins_cost(125); // XXX 5163 format %{ "movw $mem, $src\t# char/short" %} 5164 ins_encode %{ 5165 __ movw($mem$$Address, $src$$Register); 5166 %} 5167 ins_pipe(ialu_mem_reg); 5168 %} 5169 5170 // Store Integer 5171 instruct storeI(memory mem, rRegI src) 5172 %{ 5173 match(Set mem (StoreI mem src)); 5174 5175 ins_cost(125); // XXX 5176 format %{ "movl $mem, $src\t# int" %} 5177 ins_encode %{ 5178 __ movl($mem$$Address, $src$$Register); 5179 %} 5180 ins_pipe(ialu_mem_reg); 5181 %} 5182 5183 // Store Long 5184 instruct storeL(memory mem, rRegL src) 5185 %{ 5186 match(Set mem (StoreL mem src)); 5187 5188 ins_cost(125); // XXX 5189 format %{ "movq $mem, $src\t# long" %} 5190 ins_encode %{ 5191 __ movq($mem$$Address, $src$$Register); 5192 %} 5193 ins_pipe(ialu_mem_reg); // XXX 5194 %} 5195 5196 // Store Pointer 5197 instruct storeP(memory mem, any_RegP src) 5198 %{ 5199 predicate(n->as_Store()->barrier_data() == 0); 5200 match(Set mem (StoreP mem src)); 5201 5202 ins_cost(125); // XXX 5203 format %{ "movq $mem, $src\t# ptr" %} 5204 ins_encode %{ 5205 __ movq($mem$$Address, $src$$Register); 5206 %} 5207 ins_pipe(ialu_mem_reg); 5208 %} 5209 5210 instruct storeImmP0(memory mem, immP0 zero) 5211 %{ 5212 predicate(UseCompressedOops && (CompressedOops::base() == nullptr) && n->as_Store()->barrier_data() == 0); 5213 match(Set mem (StoreP mem zero)); 5214 5215 ins_cost(125); // XXX 5216 format %{ "movq $mem, R12\t# ptr (R12_heapbase==0)" %} 5217 ins_encode %{ 5218 __ movq($mem$$Address, r12); 5219 %} 5220 ins_pipe(ialu_mem_reg); 5221 %} 5222 5223 // Store Null Pointer, mark word, or other simple pointer constant. 5224 instruct storeImmP(memory mem, immP31 src) 5225 %{ 5226 predicate(n->as_Store()->barrier_data() == 0); 5227 match(Set mem (StoreP mem src)); 5228 5229 ins_cost(150); // XXX 5230 format %{ "movq $mem, $src\t# ptr" %} 5231 ins_encode %{ 5232 __ movq($mem$$Address, $src$$constant); 5233 %} 5234 ins_pipe(ialu_mem_imm); 5235 %} 5236 5237 // Store Compressed Pointer 5238 instruct storeN(memory mem, rRegN src) 5239 %{ 5240 predicate(n->as_Store()->barrier_data() == 0); 5241 match(Set mem (StoreN mem src)); 5242 5243 ins_cost(125); // XXX 5244 format %{ "movl $mem, $src\t# compressed ptr" %} 5245 ins_encode %{ 5246 __ movl($mem$$Address, $src$$Register); 5247 %} 5248 ins_pipe(ialu_mem_reg); 5249 %} 5250 5251 instruct storeNKlass(memory mem, rRegN src) 5252 %{ 5253 match(Set mem (StoreNKlass mem src)); 5254 5255 ins_cost(125); // XXX 5256 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5257 ins_encode %{ 5258 __ movl($mem$$Address, $src$$Register); 5259 %} 5260 ins_pipe(ialu_mem_reg); 5261 %} 5262 5263 instruct storeImmN0(memory mem, immN0 zero) 5264 %{ 5265 predicate(CompressedOops::base() == nullptr && n->as_Store()->barrier_data() == 0); 5266 match(Set mem (StoreN mem zero)); 5267 5268 ins_cost(125); // XXX 5269 format %{ "movl $mem, R12\t# compressed ptr (R12_heapbase==0)" %} 5270 ins_encode %{ 5271 __ movl($mem$$Address, r12); 5272 %} 5273 ins_pipe(ialu_mem_reg); 5274 %} 5275 5276 instruct storeImmN(memory mem, immN src) 5277 %{ 5278 predicate(n->as_Store()->barrier_data() == 0); 5279 match(Set mem (StoreN mem src)); 5280 5281 ins_cost(150); // XXX 5282 format %{ "movl $mem, $src\t# compressed ptr" %} 5283 ins_encode %{ 5284 address con = (address)$src$$constant; 5285 if (con == nullptr) { 5286 __ movl($mem$$Address, 0); 5287 } else { 5288 __ set_narrow_oop($mem$$Address, (jobject)$src$$constant); 5289 } 5290 %} 5291 ins_pipe(ialu_mem_imm); 5292 %} 5293 5294 instruct storeImmNKlass(memory mem, immNKlass src) 5295 %{ 5296 match(Set mem (StoreNKlass mem src)); 5297 5298 ins_cost(150); // XXX 5299 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5300 ins_encode %{ 5301 __ set_narrow_klass($mem$$Address, (Klass*)$src$$constant); 5302 %} 5303 ins_pipe(ialu_mem_imm); 5304 %} 5305 5306 // Store Integer Immediate 5307 instruct storeImmI0(memory mem, immI_0 zero) 5308 %{ 5309 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5310 match(Set mem (StoreI mem zero)); 5311 5312 ins_cost(125); // XXX 5313 format %{ "movl $mem, R12\t# int (R12_heapbase==0)" %} 5314 ins_encode %{ 5315 __ movl($mem$$Address, r12); 5316 %} 5317 ins_pipe(ialu_mem_reg); 5318 %} 5319 5320 instruct storeImmI(memory mem, immI src) 5321 %{ 5322 match(Set mem (StoreI mem src)); 5323 5324 ins_cost(150); 5325 format %{ "movl $mem, $src\t# int" %} 5326 ins_encode %{ 5327 __ movl($mem$$Address, $src$$constant); 5328 %} 5329 ins_pipe(ialu_mem_imm); 5330 %} 5331 5332 // Store Long Immediate 5333 instruct storeImmL0(memory mem, immL0 zero) 5334 %{ 5335 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5336 match(Set mem (StoreL mem zero)); 5337 5338 ins_cost(125); // XXX 5339 format %{ "movq $mem, R12\t# long (R12_heapbase==0)" %} 5340 ins_encode %{ 5341 __ movq($mem$$Address, r12); 5342 %} 5343 ins_pipe(ialu_mem_reg); 5344 %} 5345 5346 instruct storeImmL(memory mem, immL32 src) 5347 %{ 5348 match(Set mem (StoreL mem src)); 5349 5350 ins_cost(150); 5351 format %{ "movq $mem, $src\t# long" %} 5352 ins_encode %{ 5353 __ movq($mem$$Address, $src$$constant); 5354 %} 5355 ins_pipe(ialu_mem_imm); 5356 %} 5357 5358 // Store Short/Char Immediate 5359 instruct storeImmC0(memory mem, immI_0 zero) 5360 %{ 5361 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5362 match(Set mem (StoreC mem zero)); 5363 5364 ins_cost(125); // XXX 5365 format %{ "movw $mem, R12\t# short/char (R12_heapbase==0)" %} 5366 ins_encode %{ 5367 __ movw($mem$$Address, r12); 5368 %} 5369 ins_pipe(ialu_mem_reg); 5370 %} 5371 5372 instruct storeImmI16(memory mem, immI16 src) 5373 %{ 5374 predicate(UseStoreImmI16); 5375 match(Set mem (StoreC mem src)); 5376 5377 ins_cost(150); 5378 format %{ "movw $mem, $src\t# short/char" %} 5379 ins_encode %{ 5380 __ movw($mem$$Address, $src$$constant); 5381 %} 5382 ins_pipe(ialu_mem_imm); 5383 %} 5384 5385 // Store Byte Immediate 5386 instruct storeImmB0(memory mem, immI_0 zero) 5387 %{ 5388 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5389 match(Set mem (StoreB mem zero)); 5390 5391 ins_cost(125); // XXX 5392 format %{ "movb $mem, R12\t# short/char (R12_heapbase==0)" %} 5393 ins_encode %{ 5394 __ movb($mem$$Address, r12); 5395 %} 5396 ins_pipe(ialu_mem_reg); 5397 %} 5398 5399 instruct storeImmB(memory mem, immI8 src) 5400 %{ 5401 match(Set mem (StoreB mem src)); 5402 5403 ins_cost(150); // XXX 5404 format %{ "movb $mem, $src\t# byte" %} 5405 ins_encode %{ 5406 __ movb($mem$$Address, $src$$constant); 5407 %} 5408 ins_pipe(ialu_mem_imm); 5409 %} 5410 5411 // Store Float 5412 instruct storeF(memory mem, regF src) 5413 %{ 5414 match(Set mem (StoreF mem src)); 5415 5416 ins_cost(95); // XXX 5417 format %{ "movss $mem, $src\t# float" %} 5418 ins_encode %{ 5419 __ movflt($mem$$Address, $src$$XMMRegister); 5420 %} 5421 ins_pipe(pipe_slow); // XXX 5422 %} 5423 5424 // Store immediate Float value (it is faster than store from XMM register) 5425 instruct storeF0(memory mem, immF0 zero) 5426 %{ 5427 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5428 match(Set mem (StoreF mem zero)); 5429 5430 ins_cost(25); // XXX 5431 format %{ "movl $mem, R12\t# float 0. (R12_heapbase==0)" %} 5432 ins_encode %{ 5433 __ movl($mem$$Address, r12); 5434 %} 5435 ins_pipe(ialu_mem_reg); 5436 %} 5437 5438 instruct storeF_imm(memory mem, immF src) 5439 %{ 5440 match(Set mem (StoreF mem src)); 5441 5442 ins_cost(50); 5443 format %{ "movl $mem, $src\t# float" %} 5444 ins_encode %{ 5445 __ movl($mem$$Address, jint_cast($src$$constant)); 5446 %} 5447 ins_pipe(ialu_mem_imm); 5448 %} 5449 5450 // Store Double 5451 instruct storeD(memory mem, regD src) 5452 %{ 5453 match(Set mem (StoreD mem src)); 5454 5455 ins_cost(95); // XXX 5456 format %{ "movsd $mem, $src\t# double" %} 5457 ins_encode %{ 5458 __ movdbl($mem$$Address, $src$$XMMRegister); 5459 %} 5460 ins_pipe(pipe_slow); // XXX 5461 %} 5462 5463 // Store immediate double 0.0 (it is faster than store from XMM register) 5464 instruct storeD0_imm(memory mem, immD0 src) 5465 %{ 5466 predicate(!UseCompressedOops || (CompressedOops::base() != nullptr)); 5467 match(Set mem (StoreD mem src)); 5468 5469 ins_cost(50); 5470 format %{ "movq $mem, $src\t# double 0." %} 5471 ins_encode %{ 5472 __ movq($mem$$Address, $src$$constant); 5473 %} 5474 ins_pipe(ialu_mem_imm); 5475 %} 5476 5477 instruct storeD0(memory mem, immD0 zero) 5478 %{ 5479 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5480 match(Set mem (StoreD mem zero)); 5481 5482 ins_cost(25); // XXX 5483 format %{ "movq $mem, R12\t# double 0. (R12_heapbase==0)" %} 5484 ins_encode %{ 5485 __ movq($mem$$Address, r12); 5486 %} 5487 ins_pipe(ialu_mem_reg); 5488 %} 5489 5490 instruct storeSSI(stackSlotI dst, rRegI src) 5491 %{ 5492 match(Set dst src); 5493 5494 ins_cost(100); 5495 format %{ "movl $dst, $src\t# int stk" %} 5496 ins_encode %{ 5497 __ movl($dst$$Address, $src$$Register); 5498 %} 5499 ins_pipe( ialu_mem_reg ); 5500 %} 5501 5502 instruct storeSSL(stackSlotL dst, rRegL src) 5503 %{ 5504 match(Set dst src); 5505 5506 ins_cost(100); 5507 format %{ "movq $dst, $src\t# long stk" %} 5508 ins_encode %{ 5509 __ movq($dst$$Address, $src$$Register); 5510 %} 5511 ins_pipe(ialu_mem_reg); 5512 %} 5513 5514 instruct storeSSP(stackSlotP dst, rRegP src) 5515 %{ 5516 match(Set dst src); 5517 5518 ins_cost(100); 5519 format %{ "movq $dst, $src\t# ptr stk" %} 5520 ins_encode %{ 5521 __ movq($dst$$Address, $src$$Register); 5522 %} 5523 ins_pipe(ialu_mem_reg); 5524 %} 5525 5526 instruct storeSSF(stackSlotF dst, regF src) 5527 %{ 5528 match(Set dst src); 5529 5530 ins_cost(95); // XXX 5531 format %{ "movss $dst, $src\t# float stk" %} 5532 ins_encode %{ 5533 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 5534 %} 5535 ins_pipe(pipe_slow); // XXX 5536 %} 5537 5538 instruct storeSSD(stackSlotD dst, regD src) 5539 %{ 5540 match(Set dst src); 5541 5542 ins_cost(95); // XXX 5543 format %{ "movsd $dst, $src\t# double stk" %} 5544 ins_encode %{ 5545 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 5546 %} 5547 ins_pipe(pipe_slow); // XXX 5548 %} 5549 5550 instruct cacheWB(indirect addr) 5551 %{ 5552 predicate(VM_Version::supports_data_cache_line_flush()); 5553 match(CacheWB addr); 5554 5555 ins_cost(100); 5556 format %{"cache wb $addr" %} 5557 ins_encode %{ 5558 assert($addr->index_position() < 0, "should be"); 5559 assert($addr$$disp == 0, "should be"); 5560 __ cache_wb(Address($addr$$base$$Register, 0)); 5561 %} 5562 ins_pipe(pipe_slow); // XXX 5563 %} 5564 5565 instruct cacheWBPreSync() 5566 %{ 5567 predicate(VM_Version::supports_data_cache_line_flush()); 5568 match(CacheWBPreSync); 5569 5570 ins_cost(100); 5571 format %{"cache wb presync" %} 5572 ins_encode %{ 5573 __ cache_wbsync(true); 5574 %} 5575 ins_pipe(pipe_slow); // XXX 5576 %} 5577 5578 instruct cacheWBPostSync() 5579 %{ 5580 predicate(VM_Version::supports_data_cache_line_flush()); 5581 match(CacheWBPostSync); 5582 5583 ins_cost(100); 5584 format %{"cache wb postsync" %} 5585 ins_encode %{ 5586 __ cache_wbsync(false); 5587 %} 5588 ins_pipe(pipe_slow); // XXX 5589 %} 5590 5591 //----------BSWAP Instructions------------------------------------------------- 5592 instruct bytes_reverse_int(rRegI dst) %{ 5593 match(Set dst (ReverseBytesI dst)); 5594 5595 format %{ "bswapl $dst" %} 5596 ins_encode %{ 5597 __ bswapl($dst$$Register); 5598 %} 5599 ins_pipe( ialu_reg ); 5600 %} 5601 5602 instruct bytes_reverse_long(rRegL dst) %{ 5603 match(Set dst (ReverseBytesL dst)); 5604 5605 format %{ "bswapq $dst" %} 5606 ins_encode %{ 5607 __ bswapq($dst$$Register); 5608 %} 5609 ins_pipe( ialu_reg); 5610 %} 5611 5612 instruct bytes_reverse_unsigned_short(rRegI dst, rFlagsReg cr) %{ 5613 match(Set dst (ReverseBytesUS dst)); 5614 effect(KILL cr); 5615 5616 format %{ "bswapl $dst\n\t" 5617 "shrl $dst,16\n\t" %} 5618 ins_encode %{ 5619 __ bswapl($dst$$Register); 5620 __ shrl($dst$$Register, 16); 5621 %} 5622 ins_pipe( ialu_reg ); 5623 %} 5624 5625 instruct bytes_reverse_short(rRegI dst, rFlagsReg cr) %{ 5626 match(Set dst (ReverseBytesS dst)); 5627 effect(KILL cr); 5628 5629 format %{ "bswapl $dst\n\t" 5630 "sar $dst,16\n\t" %} 5631 ins_encode %{ 5632 __ bswapl($dst$$Register); 5633 __ sarl($dst$$Register, 16); 5634 %} 5635 ins_pipe( ialu_reg ); 5636 %} 5637 5638 //---------- Zeros Count Instructions ------------------------------------------ 5639 5640 instruct countLeadingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 5641 predicate(UseCountLeadingZerosInstruction); 5642 match(Set dst (CountLeadingZerosI src)); 5643 effect(KILL cr); 5644 5645 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 5646 ins_encode %{ 5647 __ lzcntl($dst$$Register, $src$$Register); 5648 %} 5649 ins_pipe(ialu_reg); 5650 %} 5651 5652 instruct countLeadingZerosI_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5653 predicate(UseCountLeadingZerosInstruction); 5654 match(Set dst (CountLeadingZerosI (LoadI src))); 5655 effect(KILL cr); 5656 ins_cost(175); 5657 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 5658 ins_encode %{ 5659 __ lzcntl($dst$$Register, $src$$Address); 5660 %} 5661 ins_pipe(ialu_reg_mem); 5662 %} 5663 5664 instruct countLeadingZerosI_bsr(rRegI dst, rRegI src, rFlagsReg cr) %{ 5665 predicate(!UseCountLeadingZerosInstruction); 5666 match(Set dst (CountLeadingZerosI src)); 5667 effect(KILL cr); 5668 5669 format %{ "bsrl $dst, $src\t# count leading zeros (int)\n\t" 5670 "jnz skip\n\t" 5671 "movl $dst, -1\n" 5672 "skip:\n\t" 5673 "negl $dst\n\t" 5674 "addl $dst, 31" %} 5675 ins_encode %{ 5676 Register Rdst = $dst$$Register; 5677 Register Rsrc = $src$$Register; 5678 Label skip; 5679 __ bsrl(Rdst, Rsrc); 5680 __ jccb(Assembler::notZero, skip); 5681 __ movl(Rdst, -1); 5682 __ bind(skip); 5683 __ negl(Rdst); 5684 __ addl(Rdst, BitsPerInt - 1); 5685 %} 5686 ins_pipe(ialu_reg); 5687 %} 5688 5689 instruct countLeadingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 5690 predicate(UseCountLeadingZerosInstruction); 5691 match(Set dst (CountLeadingZerosL src)); 5692 effect(KILL cr); 5693 5694 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 5695 ins_encode %{ 5696 __ lzcntq($dst$$Register, $src$$Register); 5697 %} 5698 ins_pipe(ialu_reg); 5699 %} 5700 5701 instruct countLeadingZerosL_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5702 predicate(UseCountLeadingZerosInstruction); 5703 match(Set dst (CountLeadingZerosL (LoadL src))); 5704 effect(KILL cr); 5705 ins_cost(175); 5706 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 5707 ins_encode %{ 5708 __ lzcntq($dst$$Register, $src$$Address); 5709 %} 5710 ins_pipe(ialu_reg_mem); 5711 %} 5712 5713 instruct countLeadingZerosL_bsr(rRegI dst, rRegL src, rFlagsReg cr) %{ 5714 predicate(!UseCountLeadingZerosInstruction); 5715 match(Set dst (CountLeadingZerosL src)); 5716 effect(KILL cr); 5717 5718 format %{ "bsrq $dst, $src\t# count leading zeros (long)\n\t" 5719 "jnz skip\n\t" 5720 "movl $dst, -1\n" 5721 "skip:\n\t" 5722 "negl $dst\n\t" 5723 "addl $dst, 63" %} 5724 ins_encode %{ 5725 Register Rdst = $dst$$Register; 5726 Register Rsrc = $src$$Register; 5727 Label skip; 5728 __ bsrq(Rdst, Rsrc); 5729 __ jccb(Assembler::notZero, skip); 5730 __ movl(Rdst, -1); 5731 __ bind(skip); 5732 __ negl(Rdst); 5733 __ addl(Rdst, BitsPerLong - 1); 5734 %} 5735 ins_pipe(ialu_reg); 5736 %} 5737 5738 instruct countTrailingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 5739 predicate(UseCountTrailingZerosInstruction); 5740 match(Set dst (CountTrailingZerosI src)); 5741 effect(KILL cr); 5742 5743 format %{ "tzcntl $dst, $src\t# count trailing zeros (int)" %} 5744 ins_encode %{ 5745 __ tzcntl($dst$$Register, $src$$Register); 5746 %} 5747 ins_pipe(ialu_reg); 5748 %} 5749 5750 instruct countTrailingZerosI_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5751 predicate(UseCountTrailingZerosInstruction); 5752 match(Set dst (CountTrailingZerosI (LoadI src))); 5753 effect(KILL cr); 5754 ins_cost(175); 5755 format %{ "tzcntl $dst, $src\t# count trailing zeros (int)" %} 5756 ins_encode %{ 5757 __ tzcntl($dst$$Register, $src$$Address); 5758 %} 5759 ins_pipe(ialu_reg_mem); 5760 %} 5761 5762 instruct countTrailingZerosI_bsf(rRegI dst, rRegI src, rFlagsReg cr) %{ 5763 predicate(!UseCountTrailingZerosInstruction); 5764 match(Set dst (CountTrailingZerosI src)); 5765 effect(KILL cr); 5766 5767 format %{ "bsfl $dst, $src\t# count trailing zeros (int)\n\t" 5768 "jnz done\n\t" 5769 "movl $dst, 32\n" 5770 "done:" %} 5771 ins_encode %{ 5772 Register Rdst = $dst$$Register; 5773 Label done; 5774 __ bsfl(Rdst, $src$$Register); 5775 __ jccb(Assembler::notZero, done); 5776 __ movl(Rdst, BitsPerInt); 5777 __ bind(done); 5778 %} 5779 ins_pipe(ialu_reg); 5780 %} 5781 5782 instruct countTrailingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 5783 predicate(UseCountTrailingZerosInstruction); 5784 match(Set dst (CountTrailingZerosL src)); 5785 effect(KILL cr); 5786 5787 format %{ "tzcntq $dst, $src\t# count trailing zeros (long)" %} 5788 ins_encode %{ 5789 __ tzcntq($dst$$Register, $src$$Register); 5790 %} 5791 ins_pipe(ialu_reg); 5792 %} 5793 5794 instruct countTrailingZerosL_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5795 predicate(UseCountTrailingZerosInstruction); 5796 match(Set dst (CountTrailingZerosL (LoadL src))); 5797 effect(KILL cr); 5798 ins_cost(175); 5799 format %{ "tzcntq $dst, $src\t# count trailing zeros (long)" %} 5800 ins_encode %{ 5801 __ tzcntq($dst$$Register, $src$$Address); 5802 %} 5803 ins_pipe(ialu_reg_mem); 5804 %} 5805 5806 instruct countTrailingZerosL_bsf(rRegI dst, rRegL src, rFlagsReg cr) %{ 5807 predicate(!UseCountTrailingZerosInstruction); 5808 match(Set dst (CountTrailingZerosL src)); 5809 effect(KILL cr); 5810 5811 format %{ "bsfq $dst, $src\t# count trailing zeros (long)\n\t" 5812 "jnz done\n\t" 5813 "movl $dst, 64\n" 5814 "done:" %} 5815 ins_encode %{ 5816 Register Rdst = $dst$$Register; 5817 Label done; 5818 __ bsfq(Rdst, $src$$Register); 5819 __ jccb(Assembler::notZero, done); 5820 __ movl(Rdst, BitsPerLong); 5821 __ bind(done); 5822 %} 5823 ins_pipe(ialu_reg); 5824 %} 5825 5826 //--------------- Reverse Operation Instructions ---------------- 5827 instruct bytes_reversebit_int(rRegI dst, rRegI src, rRegI rtmp, rFlagsReg cr) %{ 5828 predicate(!VM_Version::supports_gfni()); 5829 match(Set dst (ReverseI src)); 5830 effect(TEMP dst, TEMP rtmp, KILL cr); 5831 format %{ "reverse_int $dst $src\t! using $rtmp as TEMP" %} 5832 ins_encode %{ 5833 __ reverseI($dst$$Register, $src$$Register, xnoreg, xnoreg, $rtmp$$Register); 5834 %} 5835 ins_pipe( ialu_reg ); 5836 %} 5837 5838 instruct bytes_reversebit_int_gfni(rRegI dst, rRegI src, vlRegF xtmp1, vlRegF xtmp2, rRegL rtmp, rFlagsReg cr) %{ 5839 predicate(VM_Version::supports_gfni()); 5840 match(Set dst (ReverseI src)); 5841 effect(TEMP dst, TEMP xtmp1, TEMP xtmp2, TEMP rtmp, KILL cr); 5842 format %{ "reverse_int $dst $src\t! using $rtmp, $xtmp1 and $xtmp2 as TEMP" %} 5843 ins_encode %{ 5844 __ reverseI($dst$$Register, $src$$Register, $xtmp1$$XMMRegister, $xtmp2$$XMMRegister, $rtmp$$Register); 5845 %} 5846 ins_pipe( ialu_reg ); 5847 %} 5848 5849 instruct bytes_reversebit_long(rRegL dst, rRegL src, rRegL rtmp1, rRegL rtmp2, rFlagsReg cr) %{ 5850 predicate(!VM_Version::supports_gfni()); 5851 match(Set dst (ReverseL src)); 5852 effect(TEMP dst, TEMP rtmp1, TEMP rtmp2, KILL cr); 5853 format %{ "reverse_long $dst $src\t! using $rtmp1 and $rtmp2 as TEMP" %} 5854 ins_encode %{ 5855 __ reverseL($dst$$Register, $src$$Register, xnoreg, xnoreg, $rtmp1$$Register, $rtmp2$$Register); 5856 %} 5857 ins_pipe( ialu_reg ); 5858 %} 5859 5860 instruct bytes_reversebit_long_gfni(rRegL dst, rRegL src, vlRegD xtmp1, vlRegD xtmp2, rRegL rtmp, rFlagsReg cr) %{ 5861 predicate(VM_Version::supports_gfni()); 5862 match(Set dst (ReverseL src)); 5863 effect(TEMP dst, TEMP xtmp1, TEMP xtmp2, TEMP rtmp, KILL cr); 5864 format %{ "reverse_long $dst $src\t! using $rtmp, $xtmp1 and $xtmp2 as TEMP" %} 5865 ins_encode %{ 5866 __ reverseL($dst$$Register, $src$$Register, $xtmp1$$XMMRegister, $xtmp2$$XMMRegister, $rtmp$$Register, noreg); 5867 %} 5868 ins_pipe( ialu_reg ); 5869 %} 5870 5871 //---------- Population Count Instructions ------------------------------------- 5872 5873 instruct popCountI(rRegI dst, rRegI src, rFlagsReg cr) %{ 5874 predicate(UsePopCountInstruction); 5875 match(Set dst (PopCountI src)); 5876 effect(KILL cr); 5877 5878 format %{ "popcnt $dst, $src" %} 5879 ins_encode %{ 5880 __ popcntl($dst$$Register, $src$$Register); 5881 %} 5882 ins_pipe(ialu_reg); 5883 %} 5884 5885 instruct popCountI_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 5886 predicate(UsePopCountInstruction); 5887 match(Set dst (PopCountI (LoadI mem))); 5888 effect(KILL cr); 5889 5890 format %{ "popcnt $dst, $mem" %} 5891 ins_encode %{ 5892 __ popcntl($dst$$Register, $mem$$Address); 5893 %} 5894 ins_pipe(ialu_reg); 5895 %} 5896 5897 // Note: Long.bitCount(long) returns an int. 5898 instruct popCountL(rRegI dst, rRegL src, rFlagsReg cr) %{ 5899 predicate(UsePopCountInstruction); 5900 match(Set dst (PopCountL src)); 5901 effect(KILL cr); 5902 5903 format %{ "popcnt $dst, $src" %} 5904 ins_encode %{ 5905 __ popcntq($dst$$Register, $src$$Register); 5906 %} 5907 ins_pipe(ialu_reg); 5908 %} 5909 5910 // Note: Long.bitCount(long) returns an int. 5911 instruct popCountL_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 5912 predicate(UsePopCountInstruction); 5913 match(Set dst (PopCountL (LoadL mem))); 5914 effect(KILL cr); 5915 5916 format %{ "popcnt $dst, $mem" %} 5917 ins_encode %{ 5918 __ popcntq($dst$$Register, $mem$$Address); 5919 %} 5920 ins_pipe(ialu_reg); 5921 %} 5922 5923 5924 //----------MemBar Instructions----------------------------------------------- 5925 // Memory barrier flavors 5926 5927 instruct membar_acquire() 5928 %{ 5929 match(MemBarAcquire); 5930 match(LoadFence); 5931 ins_cost(0); 5932 5933 size(0); 5934 format %{ "MEMBAR-acquire ! (empty encoding)" %} 5935 ins_encode(); 5936 ins_pipe(empty); 5937 %} 5938 5939 instruct membar_acquire_lock() 5940 %{ 5941 match(MemBarAcquireLock); 5942 ins_cost(0); 5943 5944 size(0); 5945 format %{ "MEMBAR-acquire (prior CMPXCHG in FastLock so empty encoding)" %} 5946 ins_encode(); 5947 ins_pipe(empty); 5948 %} 5949 5950 instruct membar_release() 5951 %{ 5952 match(MemBarRelease); 5953 match(StoreFence); 5954 ins_cost(0); 5955 5956 size(0); 5957 format %{ "MEMBAR-release ! (empty encoding)" %} 5958 ins_encode(); 5959 ins_pipe(empty); 5960 %} 5961 5962 instruct membar_release_lock() 5963 %{ 5964 match(MemBarReleaseLock); 5965 ins_cost(0); 5966 5967 size(0); 5968 format %{ "MEMBAR-release (a FastUnlock follows so empty encoding)" %} 5969 ins_encode(); 5970 ins_pipe(empty); 5971 %} 5972 5973 instruct membar_volatile(rFlagsReg cr) %{ 5974 match(MemBarVolatile); 5975 effect(KILL cr); 5976 ins_cost(400); 5977 5978 format %{ 5979 $$template 5980 $$emit$$"lock addl [rsp + #0], 0\t! membar_volatile" 5981 %} 5982 ins_encode %{ 5983 __ membar(Assembler::StoreLoad); 5984 %} 5985 ins_pipe(pipe_slow); 5986 %} 5987 5988 instruct unnecessary_membar_volatile() 5989 %{ 5990 match(MemBarVolatile); 5991 predicate(Matcher::post_store_load_barrier(n)); 5992 ins_cost(0); 5993 5994 size(0); 5995 format %{ "MEMBAR-volatile (unnecessary so empty encoding)" %} 5996 ins_encode(); 5997 ins_pipe(empty); 5998 %} 5999 6000 instruct membar_storestore() %{ 6001 match(MemBarStoreStore); 6002 match(StoreStoreFence); 6003 ins_cost(0); 6004 6005 size(0); 6006 format %{ "MEMBAR-storestore (empty encoding)" %} 6007 ins_encode( ); 6008 ins_pipe(empty); 6009 %} 6010 6011 //----------Move Instructions-------------------------------------------------- 6012 6013 instruct castX2P(rRegP dst, rRegL src) 6014 %{ 6015 match(Set dst (CastX2P src)); 6016 6017 format %{ "movq $dst, $src\t# long->ptr" %} 6018 ins_encode %{ 6019 if ($dst$$reg != $src$$reg) { 6020 __ movptr($dst$$Register, $src$$Register); 6021 } 6022 %} 6023 ins_pipe(ialu_reg_reg); // XXX 6024 %} 6025 6026 instruct castI2N(rRegN dst, rRegI src) 6027 %{ 6028 match(Set dst (CastI2N src)); 6029 6030 format %{ "movq $dst, $src\t# int -> narrow ptr" %} 6031 ins_encode %{ 6032 if ($dst$$reg != $src$$reg) { 6033 __ movl($dst$$Register, $src$$Register); 6034 } 6035 %} 6036 ins_pipe(ialu_reg_reg); // XXX 6037 %} 6038 6039 instruct castN2X(rRegL dst, rRegN src) 6040 %{ 6041 match(Set dst (CastP2X src)); 6042 6043 format %{ "movq $dst, $src\t# ptr -> long" %} 6044 ins_encode %{ 6045 if ($dst$$reg != $src$$reg) { 6046 __ movptr($dst$$Register, $src$$Register); 6047 } 6048 %} 6049 ins_pipe(ialu_reg_reg); // XXX 6050 %} 6051 6052 instruct castP2X(rRegL dst, rRegP src) 6053 %{ 6054 match(Set dst (CastP2X src)); 6055 6056 format %{ "movq $dst, $src\t# ptr -> long" %} 6057 ins_encode %{ 6058 if ($dst$$reg != $src$$reg) { 6059 __ movptr($dst$$Register, $src$$Register); 6060 } 6061 %} 6062 ins_pipe(ialu_reg_reg); // XXX 6063 %} 6064 6065 // Convert oop into int for vectors alignment masking 6066 instruct convP2I(rRegI dst, rRegP src) 6067 %{ 6068 match(Set dst (ConvL2I (CastP2X src))); 6069 6070 format %{ "movl $dst, $src\t# ptr -> int" %} 6071 ins_encode %{ 6072 __ movl($dst$$Register, $src$$Register); 6073 %} 6074 ins_pipe(ialu_reg_reg); // XXX 6075 %} 6076 6077 // Convert compressed oop into int for vectors alignment masking 6078 // in case of 32bit oops (heap < 4Gb). 6079 instruct convN2I(rRegI dst, rRegN src) 6080 %{ 6081 predicate(CompressedOops::shift() == 0); 6082 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 6083 6084 format %{ "movl $dst, $src\t# compressed ptr -> int" %} 6085 ins_encode %{ 6086 __ movl($dst$$Register, $src$$Register); 6087 %} 6088 ins_pipe(ialu_reg_reg); // XXX 6089 %} 6090 6091 // Convert oop pointer into compressed form 6092 instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{ 6093 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 6094 match(Set dst (EncodeP src)); 6095 effect(KILL cr); 6096 format %{ "encode_heap_oop $dst,$src" %} 6097 ins_encode %{ 6098 Register s = $src$$Register; 6099 Register d = $dst$$Register; 6100 if (s != d) { 6101 __ movq(d, s); 6102 } 6103 __ encode_heap_oop(d); 6104 %} 6105 ins_pipe(ialu_reg_long); 6106 %} 6107 6108 instruct encodeHeapOop_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6109 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 6110 match(Set dst (EncodeP src)); 6111 effect(KILL cr); 6112 format %{ "encode_heap_oop_not_null $dst,$src" %} 6113 ins_encode %{ 6114 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 6115 %} 6116 ins_pipe(ialu_reg_long); 6117 %} 6118 6119 instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{ 6120 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 6121 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 6122 match(Set dst (DecodeN src)); 6123 effect(KILL cr); 6124 format %{ "decode_heap_oop $dst,$src" %} 6125 ins_encode %{ 6126 Register s = $src$$Register; 6127 Register d = $dst$$Register; 6128 if (s != d) { 6129 __ movq(d, s); 6130 } 6131 __ decode_heap_oop(d); 6132 %} 6133 ins_pipe(ialu_reg_long); 6134 %} 6135 6136 instruct decodeHeapOop_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6137 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 6138 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 6139 match(Set dst (DecodeN src)); 6140 effect(KILL cr); 6141 format %{ "decode_heap_oop_not_null $dst,$src" %} 6142 ins_encode %{ 6143 Register s = $src$$Register; 6144 Register d = $dst$$Register; 6145 if (s != d) { 6146 __ decode_heap_oop_not_null(d, s); 6147 } else { 6148 __ decode_heap_oop_not_null(d); 6149 } 6150 %} 6151 ins_pipe(ialu_reg_long); 6152 %} 6153 6154 instruct encodeKlass_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6155 match(Set dst (EncodePKlass src)); 6156 effect(TEMP dst, KILL cr); 6157 format %{ "encode_and_move_klass_not_null $dst,$src" %} 6158 ins_encode %{ 6159 __ encode_and_move_klass_not_null($dst$$Register, $src$$Register); 6160 %} 6161 ins_pipe(ialu_reg_long); 6162 %} 6163 6164 instruct decodeKlass_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6165 match(Set dst (DecodeNKlass src)); 6166 effect(TEMP dst, KILL cr); 6167 format %{ "decode_and_move_klass_not_null $dst,$src" %} 6168 ins_encode %{ 6169 __ decode_and_move_klass_not_null($dst$$Register, $src$$Register); 6170 %} 6171 ins_pipe(ialu_reg_long); 6172 %} 6173 6174 //----------Conditional Move--------------------------------------------------- 6175 // Jump 6176 // dummy instruction for generating temp registers 6177 instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{ 6178 match(Jump (LShiftL switch_val shift)); 6179 ins_cost(350); 6180 predicate(false); 6181 effect(TEMP dest); 6182 6183 format %{ "leaq $dest, [$constantaddress]\n\t" 6184 "jmp [$dest + $switch_val << $shift]\n\t" %} 6185 ins_encode %{ 6186 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6187 // to do that and the compiler is using that register as one it can allocate. 6188 // So we build it all by hand. 6189 // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant); 6190 // ArrayAddress dispatch(table, index); 6191 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant); 6192 __ lea($dest$$Register, $constantaddress); 6193 __ jmp(dispatch); 6194 %} 6195 ins_pipe(pipe_jmp); 6196 %} 6197 6198 instruct jumpXtnd_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{ 6199 match(Jump (AddL (LShiftL switch_val shift) offset)); 6200 ins_cost(350); 6201 effect(TEMP dest); 6202 6203 format %{ "leaq $dest, [$constantaddress]\n\t" 6204 "jmp [$dest + $switch_val << $shift + $offset]\n\t" %} 6205 ins_encode %{ 6206 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6207 // to do that and the compiler is using that register as one it can allocate. 6208 // So we build it all by hand. 6209 // Address index(noreg, switch_reg, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6210 // ArrayAddress dispatch(table, index); 6211 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6212 __ lea($dest$$Register, $constantaddress); 6213 __ jmp(dispatch); 6214 %} 6215 ins_pipe(pipe_jmp); 6216 %} 6217 6218 instruct jumpXtnd(rRegL switch_val, rRegI dest) %{ 6219 match(Jump switch_val); 6220 ins_cost(350); 6221 effect(TEMP dest); 6222 6223 format %{ "leaq $dest, [$constantaddress]\n\t" 6224 "jmp [$dest + $switch_val]\n\t" %} 6225 ins_encode %{ 6226 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6227 // to do that and the compiler is using that register as one it can allocate. 6228 // So we build it all by hand. 6229 // Address index(noreg, switch_reg, Address::times_1); 6230 // ArrayAddress dispatch(table, index); 6231 Address dispatch($dest$$Register, $switch_val$$Register, Address::times_1); 6232 __ lea($dest$$Register, $constantaddress); 6233 __ jmp(dispatch); 6234 %} 6235 ins_pipe(pipe_jmp); 6236 %} 6237 6238 // Conditional move 6239 instruct cmovI_imm_01(rRegI dst, immI_1 src, rFlagsReg cr, cmpOp 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# signed, 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_reg(rRegI dst, rRegI src, rFlagsReg cr, cmpOp cop) 6254 %{ 6255 predicate(!UseAPX); 6256 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6257 6258 ins_cost(200); // XXX 6259 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6260 ins_encode %{ 6261 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6262 %} 6263 ins_pipe(pipe_cmov_reg); 6264 %} 6265 6266 instruct cmovI_reg_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr, cmpOp cop) 6267 %{ 6268 predicate(UseAPX); 6269 match(Set dst (CMoveI (Binary cop cr) (Binary src1 src2))); 6270 6271 ins_cost(200); 6272 format %{ "ecmovl$cop $dst, $src1, $src2\t# signed, int ndd" %} 6273 ins_encode %{ 6274 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6275 %} 6276 ins_pipe(pipe_cmov_reg); 6277 %} 6278 6279 instruct cmovI_imm_01U(rRegI dst, immI_1 src, rFlagsRegU cr, cmpOpU cop) 6280 %{ 6281 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_int() == 0); 6282 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6283 6284 ins_cost(100); // XXX 6285 format %{ "setbn$cop $dst\t# unsigned, int" %} 6286 ins_encode %{ 6287 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6288 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6289 %} 6290 ins_pipe(ialu_reg); 6291 %} 6292 6293 instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{ 6294 predicate(!UseAPX); 6295 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6296 6297 ins_cost(200); // XXX 6298 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6299 ins_encode %{ 6300 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6301 %} 6302 ins_pipe(pipe_cmov_reg); 6303 %} 6304 6305 instruct cmovI_regU_ndd(rRegI dst, cmpOpU cop, rFlagsRegU cr, rRegI src1, rRegI src2) %{ 6306 predicate(UseAPX); 6307 match(Set dst (CMoveI (Binary cop cr) (Binary src1 src2))); 6308 6309 ins_cost(200); 6310 format %{ "ecmovl$cop $dst, $src1, $src2\t# unsigned, int ndd" %} 6311 ins_encode %{ 6312 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6313 %} 6314 ins_pipe(pipe_cmov_reg); 6315 %} 6316 6317 instruct cmovI_imm_01UCF(rRegI dst, immI_1 src, rFlagsRegUCF cr, cmpOpUCF cop) 6318 %{ 6319 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_int() == 0); 6320 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6321 6322 ins_cost(100); // XXX 6323 format %{ "setbn$cop $dst\t# unsigned, int" %} 6324 ins_encode %{ 6325 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6326 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6327 %} 6328 ins_pipe(ialu_reg); 6329 %} 6330 6331 instruct cmovI_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6332 predicate(!UseAPX); 6333 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6334 ins_cost(200); 6335 expand %{ 6336 cmovI_regU(cop, cr, dst, src); 6337 %} 6338 %} 6339 6340 instruct cmovI_regUCF_ndd(rRegI dst, cmpOpUCF cop, rFlagsRegUCF cr, rRegI src1, rRegI src2) %{ 6341 predicate(UseAPX); 6342 match(Set dst (CMoveI (Binary cop cr) (Binary src1 src2))); 6343 ins_cost(200); 6344 format %{ "ecmovl$cop $dst, $src1, $src2\t# unsigned, int ndd" %} 6345 ins_encode %{ 6346 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6347 %} 6348 ins_pipe(pipe_cmov_reg); 6349 %} 6350 6351 instruct cmovI_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6352 predicate(!UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6353 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6354 6355 ins_cost(200); // XXX 6356 format %{ "cmovpl $dst, $src\n\t" 6357 "cmovnel $dst, $src" %} 6358 ins_encode %{ 6359 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6360 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6361 %} 6362 ins_pipe(pipe_cmov_reg); 6363 %} 6364 6365 instruct cmovI_regUCF2_ne_ndd(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegI dst, rRegI src1, rRegI src2) %{ 6366 predicate(UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6367 match(Set dst (CMoveI (Binary cop cr) (Binary src1 src2))); 6368 effect(TEMP dst); 6369 6370 ins_cost(200); 6371 format %{ "ecmovpl $dst, $src1, $src2\n\t" 6372 "cmovnel $dst, $src2" %} 6373 ins_encode %{ 6374 __ ecmovl(Assembler::parity, $dst$$Register, $src1$$Register, $src2$$Register); 6375 __ cmovl(Assembler::notEqual, $dst$$Register, $src2$$Register); 6376 %} 6377 ins_pipe(pipe_cmov_reg); 6378 %} 6379 6380 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6381 // inputs of the CMove 6382 instruct cmovI_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6383 predicate(!UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6384 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6385 effect(TEMP dst); 6386 6387 ins_cost(200); // XXX 6388 format %{ "cmovpl $dst, $src\n\t" 6389 "cmovnel $dst, $src" %} 6390 ins_encode %{ 6391 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6392 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6393 %} 6394 ins_pipe(pipe_cmov_reg); 6395 %} 6396 6397 // We need this special handling for only eq / neq comparison since NaN == NaN is false, 6398 // and parity flag bit is set if any of the operand is a NaN. 6399 instruct cmovI_regUCF2_eq_ndd(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegI dst, rRegI src1, rRegI src2) %{ 6400 predicate(UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6401 match(Set dst (CMoveI (Binary cop cr) (Binary src2 src1))); 6402 effect(TEMP dst); 6403 6404 ins_cost(200); 6405 format %{ "ecmovpl $dst, $src1, $src2\n\t" 6406 "cmovnel $dst, $src2" %} 6407 ins_encode %{ 6408 __ ecmovl(Assembler::parity, $dst$$Register, $src1$$Register, $src2$$Register); 6409 __ cmovl(Assembler::notEqual, $dst$$Register, $src2$$Register); 6410 %} 6411 ins_pipe(pipe_cmov_reg); 6412 %} 6413 6414 // Conditional move 6415 instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{ 6416 predicate(!UseAPX); 6417 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6418 6419 ins_cost(250); // XXX 6420 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6421 ins_encode %{ 6422 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6423 %} 6424 ins_pipe(pipe_cmov_mem); 6425 %} 6426 6427 // Conditional move 6428 instruct cmovI_rReg_rReg_mem_ndd(rRegI dst, cmpOp cop, rFlagsReg cr, rRegI src1, memory src2) 6429 %{ 6430 predicate(UseAPX); 6431 match(Set dst (CMoveI (Binary cop cr) (Binary src1 (LoadI src2)))); 6432 6433 ins_cost(250); 6434 format %{ "ecmovl$cop $dst, $src1, $src2\t# signed, int ndd" %} 6435 ins_encode %{ 6436 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Address); 6437 %} 6438 ins_pipe(pipe_cmov_mem); 6439 %} 6440 6441 // Conditional move 6442 instruct cmovI_memU(cmpOpU cop, rFlagsRegU cr, rRegI dst, memory src) 6443 %{ 6444 predicate(!UseAPX); 6445 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6446 6447 ins_cost(250); // XXX 6448 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6449 ins_encode %{ 6450 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6451 %} 6452 ins_pipe(pipe_cmov_mem); 6453 %} 6454 6455 instruct cmovI_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, memory src) %{ 6456 predicate(!UseAPX); 6457 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6458 ins_cost(250); 6459 expand %{ 6460 cmovI_memU(cop, cr, dst, src); 6461 %} 6462 %} 6463 6464 instruct cmovI_rReg_rReg_memU_ndd(rRegI dst, cmpOpU cop, rFlagsRegU cr, rRegI src1, memory src2) 6465 %{ 6466 predicate(UseAPX); 6467 match(Set dst (CMoveI (Binary cop cr) (Binary src1 (LoadI src2)))); 6468 6469 ins_cost(250); 6470 format %{ "ecmovl$cop $dst, $src1, $src2\t# unsigned, int ndd" %} 6471 ins_encode %{ 6472 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Address); 6473 %} 6474 ins_pipe(pipe_cmov_mem); 6475 %} 6476 6477 instruct cmovI_rReg_rReg_memUCF_ndd(rRegI dst, cmpOpUCF cop, rFlagsRegUCF cr, rRegI src1, memory src2) 6478 %{ 6479 predicate(UseAPX); 6480 match(Set dst (CMoveI (Binary cop cr) (Binary src1 (LoadI src2)))); 6481 ins_cost(250); 6482 format %{ "ecmovl$cop $dst, $src1, $src2\t# unsigned, int ndd" %} 6483 ins_encode %{ 6484 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Address); 6485 %} 6486 ins_pipe(pipe_cmov_mem); 6487 %} 6488 6489 // Conditional move 6490 instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop) 6491 %{ 6492 predicate(!UseAPX); 6493 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6494 6495 ins_cost(200); // XXX 6496 format %{ "cmovl$cop $dst, $src\t# signed, compressed ptr" %} 6497 ins_encode %{ 6498 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6499 %} 6500 ins_pipe(pipe_cmov_reg); 6501 %} 6502 6503 // Conditional move ndd 6504 instruct cmovN_reg_ndd(rRegN dst, rRegN src1, rRegN src2, rFlagsReg cr, cmpOp cop) 6505 %{ 6506 predicate(UseAPX); 6507 match(Set dst (CMoveN (Binary cop cr) (Binary src1 src2))); 6508 6509 ins_cost(200); 6510 format %{ "ecmovl$cop $dst, $src1, $src2\t# signed, compressed ptr ndd" %} 6511 ins_encode %{ 6512 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6513 %} 6514 ins_pipe(pipe_cmov_reg); 6515 %} 6516 6517 // Conditional move 6518 instruct cmovN_regU(cmpOpU cop, rFlagsRegU cr, rRegN dst, rRegN src) 6519 %{ 6520 predicate(!UseAPX); 6521 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6522 6523 ins_cost(200); // XXX 6524 format %{ "cmovl$cop $dst, $src\t# unsigned, compressed ptr" %} 6525 ins_encode %{ 6526 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6527 %} 6528 ins_pipe(pipe_cmov_reg); 6529 %} 6530 6531 instruct cmovN_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6532 predicate(!UseAPX); 6533 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6534 ins_cost(200); 6535 expand %{ 6536 cmovN_regU(cop, cr, dst, src); 6537 %} 6538 %} 6539 6540 // Conditional move ndd 6541 instruct cmovN_regU_ndd(rRegN dst, cmpOpU cop, rFlagsRegU cr, rRegN src1, rRegN src2) 6542 %{ 6543 predicate(UseAPX); 6544 match(Set dst (CMoveN (Binary cop cr) (Binary src1 src2))); 6545 6546 ins_cost(200); 6547 format %{ "ecmovl$cop $dst, $src1, $src2\t# unsigned, compressed ptr ndd" %} 6548 ins_encode %{ 6549 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6550 %} 6551 ins_pipe(pipe_cmov_reg); 6552 %} 6553 6554 instruct cmovN_regUCF_ndd(rRegN dst, cmpOpUCF cop, rFlagsRegUCF cr, rRegN src1, rRegN src2) %{ 6555 predicate(UseAPX); 6556 match(Set dst (CMoveN (Binary cop cr) (Binary src1 src2))); 6557 ins_cost(200); 6558 format %{ "ecmovl$cop $dst, $src1, $src2\t# unsigned, compressed ptr ndd" %} 6559 ins_encode %{ 6560 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6561 %} 6562 ins_pipe(pipe_cmov_reg); 6563 %} 6564 6565 instruct cmovN_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6566 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6567 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6568 6569 ins_cost(200); // XXX 6570 format %{ "cmovpl $dst, $src\n\t" 6571 "cmovnel $dst, $src" %} 6572 ins_encode %{ 6573 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6574 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6575 %} 6576 ins_pipe(pipe_cmov_reg); 6577 %} 6578 6579 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6580 // inputs of the CMove 6581 instruct cmovN_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6582 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6583 match(Set dst (CMoveN (Binary cop cr) (Binary src dst))); 6584 6585 ins_cost(200); // XXX 6586 format %{ "cmovpl $dst, $src\n\t" 6587 "cmovnel $dst, $src" %} 6588 ins_encode %{ 6589 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6590 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6591 %} 6592 ins_pipe(pipe_cmov_reg); 6593 %} 6594 6595 // Conditional move 6596 instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop) 6597 %{ 6598 predicate(!UseAPX); 6599 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6600 6601 ins_cost(200); // XXX 6602 format %{ "cmovq$cop $dst, $src\t# signed, ptr" %} 6603 ins_encode %{ 6604 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6605 %} 6606 ins_pipe(pipe_cmov_reg); // XXX 6607 %} 6608 6609 // Conditional move ndd 6610 instruct cmovP_reg_ndd(rRegP dst, rRegP src1, rRegP src2, rFlagsReg cr, cmpOp cop) 6611 %{ 6612 predicate(UseAPX); 6613 match(Set dst (CMoveP (Binary cop cr) (Binary src1 src2))); 6614 6615 ins_cost(200); 6616 format %{ "ecmovq$cop $dst, $src1, $src2\t# signed, ptr ndd" %} 6617 ins_encode %{ 6618 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6619 %} 6620 ins_pipe(pipe_cmov_reg); 6621 %} 6622 6623 // Conditional move 6624 instruct cmovP_regU(cmpOpU cop, rFlagsRegU cr, rRegP dst, rRegP src) 6625 %{ 6626 predicate(!UseAPX); 6627 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6628 6629 ins_cost(200); // XXX 6630 format %{ "cmovq$cop $dst, $src\t# unsigned, ptr" %} 6631 ins_encode %{ 6632 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6633 %} 6634 ins_pipe(pipe_cmov_reg); // XXX 6635 %} 6636 6637 // Conditional move ndd 6638 instruct cmovP_regU_ndd(rRegP dst, cmpOpU cop, rFlagsRegU cr, rRegP src1, rRegP src2) 6639 %{ 6640 predicate(UseAPX); 6641 match(Set dst (CMoveP (Binary cop cr) (Binary src1 src2))); 6642 6643 ins_cost(200); 6644 format %{ "ecmovq$cop $dst, $src1, $src2\t# unsigned, ptr ndd" %} 6645 ins_encode %{ 6646 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6647 %} 6648 ins_pipe(pipe_cmov_reg); 6649 %} 6650 6651 instruct cmovP_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6652 predicate(!UseAPX); 6653 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6654 ins_cost(200); 6655 expand %{ 6656 cmovP_regU(cop, cr, dst, src); 6657 %} 6658 %} 6659 6660 instruct cmovP_regUCF_ndd(rRegP dst, cmpOpUCF cop, rFlagsRegUCF cr, rRegP src1, rRegP src2) %{ 6661 predicate(UseAPX); 6662 match(Set dst (CMoveP (Binary cop cr) (Binary src1 src2))); 6663 ins_cost(200); 6664 format %{ "ecmovq$cop $dst, $src1, $src2\t# unsigned, ptr ndd" %} 6665 ins_encode %{ 6666 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6667 %} 6668 ins_pipe(pipe_cmov_reg); 6669 %} 6670 6671 instruct cmovP_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6672 predicate(!UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6673 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6674 6675 ins_cost(200); // XXX 6676 format %{ "cmovpq $dst, $src\n\t" 6677 "cmovneq $dst, $src" %} 6678 ins_encode %{ 6679 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6680 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6681 %} 6682 ins_pipe(pipe_cmov_reg); 6683 %} 6684 6685 instruct cmovP_regUCF2_ne_ndd(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegP dst, rRegP src1, rRegP src2) %{ 6686 predicate(UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6687 match(Set dst (CMoveP (Binary cop cr) (Binary src1 src2))); 6688 effect(TEMP dst); 6689 6690 ins_cost(200); 6691 format %{ "ecmovpq $dst, $src1, $src2\n\t" 6692 "cmovneq $dst, $src2" %} 6693 ins_encode %{ 6694 __ ecmovq(Assembler::parity, $dst$$Register, $src1$$Register, $src2$$Register); 6695 __ cmovq(Assembler::notEqual, $dst$$Register, $src2$$Register); 6696 %} 6697 ins_pipe(pipe_cmov_reg); 6698 %} 6699 6700 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6701 // inputs of the CMove 6702 instruct cmovP_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6703 predicate(!UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6704 match(Set dst (CMoveP (Binary cop cr) (Binary src dst))); 6705 6706 ins_cost(200); // XXX 6707 format %{ "cmovpq $dst, $src\n\t" 6708 "cmovneq $dst, $src" %} 6709 ins_encode %{ 6710 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6711 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6712 %} 6713 ins_pipe(pipe_cmov_reg); 6714 %} 6715 6716 instruct cmovP_regUCF2_eq_ndd(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegP dst, rRegP src1, rRegP src2) %{ 6717 predicate(UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6718 match(Set dst (CMoveP (Binary cop cr) (Binary src2 src1))); 6719 effect(TEMP dst); 6720 6721 ins_cost(200); 6722 format %{ "ecmovpq $dst, $src1, $src2\n\t" 6723 "cmovneq $dst, $src2" %} 6724 ins_encode %{ 6725 __ ecmovq(Assembler::parity, $dst$$Register, $src1$$Register, $src2$$Register); 6726 __ cmovq(Assembler::notEqual, $dst$$Register, $src2$$Register); 6727 %} 6728 ins_pipe(pipe_cmov_reg); 6729 %} 6730 6731 instruct cmovL_imm_01(rRegL dst, immL1 src, rFlagsReg cr, cmpOp cop) 6732 %{ 6733 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_long() == 0); 6734 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6735 6736 ins_cost(100); // XXX 6737 format %{ "setbn$cop $dst\t# signed, long" %} 6738 ins_encode %{ 6739 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6740 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6741 %} 6742 ins_pipe(ialu_reg); 6743 %} 6744 6745 instruct cmovL_reg(cmpOp cop, rFlagsReg cr, rRegL dst, rRegL src) 6746 %{ 6747 predicate(!UseAPX); 6748 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6749 6750 ins_cost(200); // XXX 6751 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6752 ins_encode %{ 6753 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6754 %} 6755 ins_pipe(pipe_cmov_reg); // XXX 6756 %} 6757 6758 instruct cmovL_reg_ndd(rRegL dst, cmpOp cop, rFlagsReg cr, rRegL src1, rRegL src2) 6759 %{ 6760 predicate(UseAPX); 6761 match(Set dst (CMoveL (Binary cop cr) (Binary src1 src2))); 6762 6763 ins_cost(200); 6764 format %{ "ecmovq$cop $dst, $src1, $src2\t# signed, long ndd" %} 6765 ins_encode %{ 6766 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6767 %} 6768 ins_pipe(pipe_cmov_reg); 6769 %} 6770 6771 instruct cmovL_mem(cmpOp cop, rFlagsReg cr, rRegL dst, memory src) 6772 %{ 6773 predicate(!UseAPX); 6774 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6775 6776 ins_cost(200); // XXX 6777 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6778 ins_encode %{ 6779 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6780 %} 6781 ins_pipe(pipe_cmov_mem); // XXX 6782 %} 6783 6784 instruct cmovL_rReg_rReg_mem_ndd(rRegL dst, cmpOp cop, rFlagsReg cr, rRegL src1, memory src2) 6785 %{ 6786 predicate(UseAPX); 6787 match(Set dst (CMoveL (Binary cop cr) (Binary src1 (LoadL src2)))); 6788 6789 ins_cost(200); 6790 format %{ "ecmovq$cop $dst, $src1, $src2\t# signed, long ndd" %} 6791 ins_encode %{ 6792 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Address); 6793 %} 6794 ins_pipe(pipe_cmov_mem); 6795 %} 6796 6797 instruct cmovL_imm_01U(rRegL dst, immL1 src, rFlagsRegU cr, cmpOpU cop) 6798 %{ 6799 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_long() == 0); 6800 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6801 6802 ins_cost(100); // XXX 6803 format %{ "setbn$cop $dst\t# unsigned, long" %} 6804 ins_encode %{ 6805 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6806 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6807 %} 6808 ins_pipe(ialu_reg); 6809 %} 6810 6811 instruct cmovL_regU(cmpOpU cop, rFlagsRegU cr, rRegL dst, rRegL src) 6812 %{ 6813 predicate(!UseAPX); 6814 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6815 6816 ins_cost(200); // XXX 6817 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 6818 ins_encode %{ 6819 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6820 %} 6821 ins_pipe(pipe_cmov_reg); // XXX 6822 %} 6823 6824 instruct cmovL_regU_ndd(rRegL dst, cmpOpU cop, rFlagsRegU cr, rRegL src1, rRegL src2) 6825 %{ 6826 predicate(UseAPX); 6827 match(Set dst (CMoveL (Binary cop cr) (Binary src1 src2))); 6828 6829 ins_cost(200); 6830 format %{ "ecmovq$cop $dst, $src1, $src2\t# unsigned, long ndd" %} 6831 ins_encode %{ 6832 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6833 %} 6834 ins_pipe(pipe_cmov_reg); 6835 %} 6836 6837 instruct cmovL_imm_01UCF(rRegL dst, immL1 src, rFlagsRegUCF cr, cmpOpUCF cop) 6838 %{ 6839 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_long() == 0); 6840 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6841 6842 ins_cost(100); // XXX 6843 format %{ "setbn$cop $dst\t# unsigned, long" %} 6844 ins_encode %{ 6845 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6846 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6847 %} 6848 ins_pipe(ialu_reg); 6849 %} 6850 6851 instruct cmovL_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6852 predicate(!UseAPX); 6853 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6854 ins_cost(200); 6855 expand %{ 6856 cmovL_regU(cop, cr, dst, src); 6857 %} 6858 %} 6859 6860 instruct cmovL_regUCF_ndd(rRegL dst, cmpOpUCF cop, rFlagsRegUCF cr, rRegL src1, rRegL src2) 6861 %{ 6862 predicate(UseAPX); 6863 match(Set dst (CMoveL (Binary cop cr) (Binary src1 src2))); 6864 ins_cost(200); 6865 format %{ "ecmovq$cop $dst, $src1, $src2\t# unsigned, long ndd" %} 6866 ins_encode %{ 6867 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6868 %} 6869 ins_pipe(pipe_cmov_reg); 6870 %} 6871 6872 instruct cmovL_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6873 predicate(!UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6874 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6875 6876 ins_cost(200); // XXX 6877 format %{ "cmovpq $dst, $src\n\t" 6878 "cmovneq $dst, $src" %} 6879 ins_encode %{ 6880 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6881 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6882 %} 6883 ins_pipe(pipe_cmov_reg); 6884 %} 6885 6886 instruct cmovL_regUCF2_ne_ndd(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegL dst, rRegL src1, rRegL src2) %{ 6887 predicate(UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6888 match(Set dst (CMoveL (Binary cop cr) (Binary src1 src2))); 6889 effect(TEMP dst); 6890 6891 ins_cost(200); 6892 format %{ "ecmovpq $dst, $src1, $src2\n\t" 6893 "cmovneq $dst, $src2" %} 6894 ins_encode %{ 6895 __ ecmovq(Assembler::parity, $dst$$Register, $src1$$Register, $src2$$Register); 6896 __ cmovq(Assembler::notEqual, $dst$$Register, $src2$$Register); 6897 %} 6898 ins_pipe(pipe_cmov_reg); 6899 %} 6900 6901 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6902 // inputs of the CMove 6903 instruct cmovL_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6904 predicate(!UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6905 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6906 6907 ins_cost(200); // XXX 6908 format %{ "cmovpq $dst, $src\n\t" 6909 "cmovneq $dst, $src" %} 6910 ins_encode %{ 6911 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6912 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6913 %} 6914 ins_pipe(pipe_cmov_reg); 6915 %} 6916 6917 instruct cmovL_regUCF2_eq_ndd(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegL dst, rRegL src1, rRegL src2) %{ 6918 predicate(UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6919 match(Set dst (CMoveL (Binary cop cr) (Binary src2 src1))); 6920 effect(TEMP dst); 6921 6922 ins_cost(200); 6923 format %{ "ecmovpq $dst, $src1, $src2\n\t" 6924 "cmovneq $dst, $src2" %} 6925 ins_encode %{ 6926 __ ecmovq(Assembler::parity, $dst$$Register, $src1$$Register, $src2$$Register); 6927 __ cmovq(Assembler::notEqual, $dst$$Register, $src2$$Register); 6928 %} 6929 ins_pipe(pipe_cmov_reg); 6930 %} 6931 6932 instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src) 6933 %{ 6934 predicate(!UseAPX); 6935 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6936 6937 ins_cost(200); // XXX 6938 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 6939 ins_encode %{ 6940 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6941 %} 6942 ins_pipe(pipe_cmov_mem); // XXX 6943 %} 6944 6945 instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{ 6946 predicate(!UseAPX); 6947 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6948 ins_cost(200); 6949 expand %{ 6950 cmovL_memU(cop, cr, dst, src); 6951 %} 6952 %} 6953 6954 instruct cmovL_rReg_rReg_memU_ndd(rRegL dst, cmpOpU cop, rFlagsRegU cr, rRegL src1, memory src2) 6955 %{ 6956 predicate(UseAPX); 6957 match(Set dst (CMoveL (Binary cop cr) (Binary src1 (LoadL src2)))); 6958 6959 ins_cost(200); 6960 format %{ "ecmovq$cop $dst, $src1, $src2\t# unsigned, long ndd" %} 6961 ins_encode %{ 6962 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Address); 6963 %} 6964 ins_pipe(pipe_cmov_mem); 6965 %} 6966 6967 instruct cmovL_rReg_rReg_memUCF_ndd(rRegL dst, cmpOpUCF cop, rFlagsRegUCF cr, rRegL src1, memory src2) 6968 %{ 6969 predicate(UseAPX); 6970 match(Set dst (CMoveL (Binary cop cr) (Binary src1 (LoadL src2)))); 6971 ins_cost(200); 6972 format %{ "ecmovq$cop $dst, $src1, $src2\t# unsigned, long ndd" %} 6973 ins_encode %{ 6974 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Address); 6975 %} 6976 ins_pipe(pipe_cmov_mem); 6977 %} 6978 6979 instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src) 6980 %{ 6981 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6982 6983 ins_cost(200); // XXX 6984 format %{ "jn$cop skip\t# signed cmove float\n\t" 6985 "movss $dst, $src\n" 6986 "skip:" %} 6987 ins_encode %{ 6988 Label Lskip; 6989 // Invert sense of branch from sense of CMOV 6990 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6991 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 6992 __ bind(Lskip); 6993 %} 6994 ins_pipe(pipe_slow); 6995 %} 6996 6997 instruct cmovF_regU(cmpOpU cop, rFlagsRegU cr, regF dst, regF src) 6998 %{ 6999 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7000 7001 ins_cost(200); // XXX 7002 format %{ "jn$cop skip\t# unsigned cmove float\n\t" 7003 "movss $dst, $src\n" 7004 "skip:" %} 7005 ins_encode %{ 7006 Label Lskip; 7007 // Invert sense of branch from sense of CMOV 7008 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7009 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 7010 __ bind(Lskip); 7011 %} 7012 ins_pipe(pipe_slow); 7013 %} 7014 7015 instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{ 7016 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7017 ins_cost(200); 7018 expand %{ 7019 cmovF_regU(cop, cr, dst, src); 7020 %} 7021 %} 7022 7023 instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src) 7024 %{ 7025 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7026 7027 ins_cost(200); // XXX 7028 format %{ "jn$cop skip\t# signed cmove double\n\t" 7029 "movsd $dst, $src\n" 7030 "skip:" %} 7031 ins_encode %{ 7032 Label Lskip; 7033 // Invert sense of branch from sense of CMOV 7034 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7035 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 7036 __ bind(Lskip); 7037 %} 7038 ins_pipe(pipe_slow); 7039 %} 7040 7041 instruct cmovD_regU(cmpOpU cop, rFlagsRegU cr, regD dst, regD src) 7042 %{ 7043 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7044 7045 ins_cost(200); // XXX 7046 format %{ "jn$cop skip\t# unsigned cmove double\n\t" 7047 "movsd $dst, $src\n" 7048 "skip:" %} 7049 ins_encode %{ 7050 Label Lskip; 7051 // Invert sense of branch from sense of CMOV 7052 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7053 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 7054 __ bind(Lskip); 7055 %} 7056 ins_pipe(pipe_slow); 7057 %} 7058 7059 instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{ 7060 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7061 ins_cost(200); 7062 expand %{ 7063 cmovD_regU(cop, cr, dst, src); 7064 %} 7065 %} 7066 7067 //----------Arithmetic Instructions-------------------------------------------- 7068 //----------Addition Instructions---------------------------------------------- 7069 7070 instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7071 %{ 7072 predicate(!UseAPX); 7073 match(Set dst (AddI dst src)); 7074 effect(KILL cr); 7075 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); 7076 format %{ "addl $dst, $src\t# int" %} 7077 ins_encode %{ 7078 __ addl($dst$$Register, $src$$Register); 7079 %} 7080 ins_pipe(ialu_reg_reg); 7081 %} 7082 7083 instruct addI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr) 7084 %{ 7085 predicate(UseAPX); 7086 match(Set dst (AddI src1 src2)); 7087 effect(KILL cr); 7088 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); 7089 7090 format %{ "eaddl $dst, $src1, $src2\t# int ndd" %} 7091 ins_encode %{ 7092 __ eaddl($dst$$Register, $src1$$Register, $src2$$Register, false); 7093 %} 7094 ins_pipe(ialu_reg_reg); 7095 %} 7096 7097 instruct addI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 7098 %{ 7099 predicate(!UseAPX); 7100 match(Set dst (AddI dst src)); 7101 effect(KILL cr); 7102 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); 7103 7104 format %{ "addl $dst, $src\t# int" %} 7105 ins_encode %{ 7106 __ addl($dst$$Register, $src$$constant); 7107 %} 7108 ins_pipe( ialu_reg ); 7109 %} 7110 7111 instruct addI_rReg_rReg_imm_ndd(rRegI dst, rRegI src1, immI src2, rFlagsReg cr) 7112 %{ 7113 predicate(UseAPX); 7114 match(Set dst (AddI src1 src2)); 7115 effect(KILL cr); 7116 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); 7117 7118 format %{ "eaddl $dst, $src1, $src2\t# int ndd" %} 7119 ins_encode %{ 7120 __ eaddl($dst$$Register, $src1$$Register, $src2$$constant, false); 7121 %} 7122 ins_pipe( ialu_reg ); 7123 %} 7124 7125 instruct addI_rReg_mem_imm_ndd(rRegI dst, memory src1, immI src2, rFlagsReg cr) 7126 %{ 7127 predicate(UseAPX); 7128 match(Set dst (AddI (LoadI src1) src2)); 7129 effect(KILL cr); 7130 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); 7131 7132 format %{ "eaddl $dst, $src1, $src2\t# int ndd" %} 7133 ins_encode %{ 7134 __ eaddl($dst$$Register, $src1$$Address, $src2$$constant, false); 7135 %} 7136 ins_pipe( ialu_reg ); 7137 %} 7138 7139 instruct addI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 7140 %{ 7141 predicate(!UseAPX); 7142 match(Set dst (AddI dst (LoadI src))); 7143 effect(KILL cr); 7144 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); 7145 7146 ins_cost(150); // XXX 7147 format %{ "addl $dst, $src\t# int" %} 7148 ins_encode %{ 7149 __ addl($dst$$Register, $src$$Address); 7150 %} 7151 ins_pipe(ialu_reg_mem); 7152 %} 7153 7154 instruct addI_rReg_rReg_mem_ndd(rRegI dst, rRegI src1, memory src2, rFlagsReg cr) 7155 %{ 7156 predicate(UseAPX); 7157 match(Set dst (AddI src1 (LoadI src2))); 7158 effect(KILL cr); 7159 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); 7160 7161 ins_cost(150); 7162 format %{ "eaddl $dst, $src1, $src2\t# int ndd" %} 7163 ins_encode %{ 7164 __ eaddl($dst$$Register, $src1$$Register, $src2$$Address, false); 7165 %} 7166 ins_pipe(ialu_reg_mem); 7167 %} 7168 7169 instruct addI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 7170 %{ 7171 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7172 effect(KILL cr); 7173 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); 7174 7175 ins_cost(150); // XXX 7176 format %{ "addl $dst, $src\t# int" %} 7177 ins_encode %{ 7178 __ addl($dst$$Address, $src$$Register); 7179 %} 7180 ins_pipe(ialu_mem_reg); 7181 %} 7182 7183 instruct addI_mem_imm(memory dst, immI src, rFlagsReg cr) 7184 %{ 7185 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7186 effect(KILL cr); 7187 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); 7188 7189 7190 ins_cost(125); // XXX 7191 format %{ "addl $dst, $src\t# int" %} 7192 ins_encode %{ 7193 __ addl($dst$$Address, $src$$constant); 7194 %} 7195 ins_pipe(ialu_mem_imm); 7196 %} 7197 7198 instruct incI_rReg(rRegI dst, immI_1 src, rFlagsReg cr) 7199 %{ 7200 predicate(!UseAPX && UseIncDec); 7201 match(Set dst (AddI dst src)); 7202 effect(KILL cr); 7203 7204 format %{ "incl $dst\t# int" %} 7205 ins_encode %{ 7206 __ incrementl($dst$$Register); 7207 %} 7208 ins_pipe(ialu_reg); 7209 %} 7210 7211 instruct incI_rReg_ndd(rRegI dst, rRegI src, immI_1 val, rFlagsReg cr) 7212 %{ 7213 predicate(UseAPX && UseIncDec); 7214 match(Set dst (AddI src val)); 7215 effect(KILL cr); 7216 7217 format %{ "eincl $dst, $src\t# int ndd" %} 7218 ins_encode %{ 7219 __ eincl($dst$$Register, $src$$Register, false); 7220 %} 7221 ins_pipe(ialu_reg); 7222 %} 7223 7224 instruct incI_rReg_mem_ndd(rRegI dst, memory src, immI_1 val, rFlagsReg cr) 7225 %{ 7226 predicate(UseAPX && UseIncDec); 7227 match(Set dst (AddI (LoadI src) val)); 7228 effect(KILL cr); 7229 7230 format %{ "eincl $dst, $src\t# int ndd" %} 7231 ins_encode %{ 7232 __ eincl($dst$$Register, $src$$Address, false); 7233 %} 7234 ins_pipe(ialu_reg); 7235 %} 7236 7237 instruct incI_mem(memory dst, immI_1 src, rFlagsReg cr) 7238 %{ 7239 predicate(UseIncDec); 7240 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7241 effect(KILL cr); 7242 7243 ins_cost(125); // XXX 7244 format %{ "incl $dst\t# int" %} 7245 ins_encode %{ 7246 __ incrementl($dst$$Address); 7247 %} 7248 ins_pipe(ialu_mem_imm); 7249 %} 7250 7251 // XXX why does that use AddI 7252 instruct decI_rReg(rRegI dst, immI_M1 src, rFlagsReg cr) 7253 %{ 7254 predicate(!UseAPX && UseIncDec); 7255 match(Set dst (AddI dst src)); 7256 effect(KILL cr); 7257 7258 format %{ "decl $dst\t# int" %} 7259 ins_encode %{ 7260 __ decrementl($dst$$Register); 7261 %} 7262 ins_pipe(ialu_reg); 7263 %} 7264 7265 instruct decI_rReg_ndd(rRegI dst, rRegI src, immI_M1 val, rFlagsReg cr) 7266 %{ 7267 predicate(UseAPX && UseIncDec); 7268 match(Set dst (AddI src val)); 7269 effect(KILL cr); 7270 7271 format %{ "edecl $dst, $src\t# int ndd" %} 7272 ins_encode %{ 7273 __ edecl($dst$$Register, $src$$Register, false); 7274 %} 7275 ins_pipe(ialu_reg); 7276 %} 7277 7278 instruct decI_rReg_mem_ndd(rRegI dst, memory src, immI_M1 val, rFlagsReg cr) 7279 %{ 7280 predicate(UseAPX && UseIncDec); 7281 match(Set dst (AddI (LoadI src) val)); 7282 effect(KILL cr); 7283 7284 format %{ "edecl $dst, $src\t# int ndd" %} 7285 ins_encode %{ 7286 __ edecl($dst$$Register, $src$$Address, false); 7287 %} 7288 ins_pipe(ialu_reg); 7289 %} 7290 7291 // XXX why does that use AddI 7292 instruct decI_mem(memory dst, immI_M1 src, rFlagsReg cr) 7293 %{ 7294 predicate(UseIncDec); 7295 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7296 effect(KILL cr); 7297 7298 ins_cost(125); // XXX 7299 format %{ "decl $dst\t# int" %} 7300 ins_encode %{ 7301 __ decrementl($dst$$Address); 7302 %} 7303 ins_pipe(ialu_mem_imm); 7304 %} 7305 7306 instruct leaI_rReg_immI2_immI(rRegI dst, rRegI index, immI2 scale, immI disp) 7307 %{ 7308 predicate(VM_Version::supports_fast_2op_lea()); 7309 match(Set dst (AddI (LShiftI index scale) disp)); 7310 7311 format %{ "leal $dst, [$index << $scale + $disp]\t# int" %} 7312 ins_encode %{ 7313 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 7314 __ leal($dst$$Register, Address(noreg, $index$$Register, scale, $disp$$constant)); 7315 %} 7316 ins_pipe(ialu_reg_reg); 7317 %} 7318 7319 instruct leaI_rReg_rReg_immI(rRegI dst, rRegI base, rRegI index, immI disp) 7320 %{ 7321 predicate(VM_Version::supports_fast_3op_lea()); 7322 match(Set dst (AddI (AddI base index) disp)); 7323 7324 format %{ "leal $dst, [$base + $index + $disp]\t# int" %} 7325 ins_encode %{ 7326 __ leal($dst$$Register, Address($base$$Register, $index$$Register, Address::times_1, $disp$$constant)); 7327 %} 7328 ins_pipe(ialu_reg_reg); 7329 %} 7330 7331 instruct leaI_rReg_rReg_immI2(rRegI dst, no_rbp_r13_RegI base, rRegI index, immI2 scale) 7332 %{ 7333 predicate(VM_Version::supports_fast_2op_lea()); 7334 match(Set dst (AddI base (LShiftI index scale))); 7335 7336 format %{ "leal $dst, [$base + $index << $scale]\t# int" %} 7337 ins_encode %{ 7338 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 7339 __ leal($dst$$Register, Address($base$$Register, $index$$Register, scale)); 7340 %} 7341 ins_pipe(ialu_reg_reg); 7342 %} 7343 7344 instruct leaI_rReg_rReg_immI2_immI(rRegI dst, rRegI base, rRegI index, immI2 scale, immI disp) 7345 %{ 7346 predicate(VM_Version::supports_fast_3op_lea()); 7347 match(Set dst (AddI (AddI base (LShiftI index scale)) disp)); 7348 7349 format %{ "leal $dst, [$base + $index << $scale + $disp]\t# int" %} 7350 ins_encode %{ 7351 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 7352 __ leal($dst$$Register, Address($base$$Register, $index$$Register, scale, $disp$$constant)); 7353 %} 7354 ins_pipe(ialu_reg_reg); 7355 %} 7356 7357 instruct addL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7358 %{ 7359 predicate(!UseAPX); 7360 match(Set dst (AddL dst src)); 7361 effect(KILL cr); 7362 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); 7363 7364 format %{ "addq $dst, $src\t# long" %} 7365 ins_encode %{ 7366 __ addq($dst$$Register, $src$$Register); 7367 %} 7368 ins_pipe(ialu_reg_reg); 7369 %} 7370 7371 instruct addL_rReg_ndd(rRegL dst, rRegL src1, rRegL src2, rFlagsReg cr) 7372 %{ 7373 predicate(UseAPX); 7374 match(Set dst (AddL src1 src2)); 7375 effect(KILL cr); 7376 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); 7377 7378 format %{ "eaddq $dst, $src1, $src2\t# long ndd" %} 7379 ins_encode %{ 7380 __ eaddq($dst$$Register, $src1$$Register, $src2$$Register, false); 7381 %} 7382 ins_pipe(ialu_reg_reg); 7383 %} 7384 7385 instruct addL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 7386 %{ 7387 predicate(!UseAPX); 7388 match(Set dst (AddL dst src)); 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 format %{ "addq $dst, $src\t# long" %} 7393 ins_encode %{ 7394 __ addq($dst$$Register, $src$$constant); 7395 %} 7396 ins_pipe( ialu_reg ); 7397 %} 7398 7399 instruct addL_rReg_rReg_imm_ndd(rRegL dst, rRegL src1, immL32 src2, rFlagsReg cr) 7400 %{ 7401 predicate(UseAPX); 7402 match(Set dst (AddL src1 src2)); 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 format %{ "eaddq $dst, $src1, $src2\t# long ndd" %} 7407 ins_encode %{ 7408 __ eaddq($dst$$Register, $src1$$Register, $src2$$constant, false); 7409 %} 7410 ins_pipe( ialu_reg ); 7411 %} 7412 7413 instruct addL_rReg_mem_imm_ndd(rRegL dst, memory src1, immL32 src2, rFlagsReg cr) 7414 %{ 7415 predicate(UseAPX); 7416 match(Set dst (AddL (LoadL src1) src2)); 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 format %{ "eaddq $dst, $src1, $src2\t# long ndd" %} 7421 ins_encode %{ 7422 __ eaddq($dst$$Register, $src1$$Address, $src2$$constant, false); 7423 %} 7424 ins_pipe( ialu_reg ); 7425 %} 7426 7427 instruct addL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 7428 %{ 7429 predicate(!UseAPX); 7430 match(Set dst (AddL dst (LoadL src))); 7431 effect(KILL cr); 7432 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); 7433 7434 ins_cost(150); // XXX 7435 format %{ "addq $dst, $src\t# long" %} 7436 ins_encode %{ 7437 __ addq($dst$$Register, $src$$Address); 7438 %} 7439 ins_pipe(ialu_reg_mem); 7440 %} 7441 7442 instruct addL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr) 7443 %{ 7444 predicate(UseAPX); 7445 match(Set dst (AddL src1 (LoadL src2))); 7446 effect(KILL cr); 7447 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); 7448 7449 ins_cost(150); 7450 format %{ "eaddq $dst, $src1, $src2\t# long ndd" %} 7451 ins_encode %{ 7452 __ eaddq($dst$$Register, $src1$$Register, $src2$$Address, false); 7453 %} 7454 ins_pipe(ialu_reg_mem); 7455 %} 7456 7457 instruct addL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 7458 %{ 7459 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7460 effect(KILL cr); 7461 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); 7462 7463 ins_cost(150); // XXX 7464 format %{ "addq $dst, $src\t# long" %} 7465 ins_encode %{ 7466 __ addq($dst$$Address, $src$$Register); 7467 %} 7468 ins_pipe(ialu_mem_reg); 7469 %} 7470 7471 instruct addL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 7472 %{ 7473 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7474 effect(KILL cr); 7475 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); 7476 7477 ins_cost(125); // XXX 7478 format %{ "addq $dst, $src\t# long" %} 7479 ins_encode %{ 7480 __ addq($dst$$Address, $src$$constant); 7481 %} 7482 ins_pipe(ialu_mem_imm); 7483 %} 7484 7485 instruct incL_rReg(rRegL dst, immL1 src, rFlagsReg cr) 7486 %{ 7487 predicate(!UseAPX && UseIncDec); 7488 match(Set dst (AddL dst src)); 7489 effect(KILL cr); 7490 7491 format %{ "incq $dst\t# long" %} 7492 ins_encode %{ 7493 __ incrementq($dst$$Register); 7494 %} 7495 ins_pipe(ialu_reg); 7496 %} 7497 7498 instruct incL_rReg_ndd(rRegL dst, rRegI src, immL1 val, rFlagsReg cr) 7499 %{ 7500 predicate(UseAPX && UseIncDec); 7501 match(Set dst (AddL src val)); 7502 effect(KILL cr); 7503 7504 format %{ "eincq $dst, $src\t# long ndd" %} 7505 ins_encode %{ 7506 __ eincq($dst$$Register, $src$$Register, false); 7507 %} 7508 ins_pipe(ialu_reg); 7509 %} 7510 7511 instruct incL_rReg_mem_ndd(rRegL dst, memory src, immL1 val, rFlagsReg cr) 7512 %{ 7513 predicate(UseAPX && UseIncDec); 7514 match(Set dst (AddL (LoadL src) val)); 7515 effect(KILL cr); 7516 7517 format %{ "eincq $dst, $src\t# long ndd" %} 7518 ins_encode %{ 7519 __ eincq($dst$$Register, $src$$Address, false); 7520 %} 7521 ins_pipe(ialu_reg); 7522 %} 7523 7524 instruct incL_mem(memory dst, immL1 src, rFlagsReg cr) 7525 %{ 7526 predicate(UseIncDec); 7527 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7528 effect(KILL cr); 7529 7530 ins_cost(125); // XXX 7531 format %{ "incq $dst\t# long" %} 7532 ins_encode %{ 7533 __ incrementq($dst$$Address); 7534 %} 7535 ins_pipe(ialu_mem_imm); 7536 %} 7537 7538 // XXX why does that use AddL 7539 instruct decL_rReg(rRegL dst, immL_M1 src, rFlagsReg cr) 7540 %{ 7541 predicate(!UseAPX && UseIncDec); 7542 match(Set dst (AddL dst src)); 7543 effect(KILL cr); 7544 7545 format %{ "decq $dst\t# long" %} 7546 ins_encode %{ 7547 __ decrementq($dst$$Register); 7548 %} 7549 ins_pipe(ialu_reg); 7550 %} 7551 7552 instruct decL_rReg_ndd(rRegL dst, rRegL src, immL_M1 val, rFlagsReg cr) 7553 %{ 7554 predicate(UseAPX && UseIncDec); 7555 match(Set dst (AddL src val)); 7556 effect(KILL cr); 7557 7558 format %{ "edecq $dst, $src\t# long ndd" %} 7559 ins_encode %{ 7560 __ edecq($dst$$Register, $src$$Register, false); 7561 %} 7562 ins_pipe(ialu_reg); 7563 %} 7564 7565 instruct decL_rReg_mem_ndd(rRegL dst, memory src, immL_M1 val, rFlagsReg cr) 7566 %{ 7567 predicate(UseAPX && UseIncDec); 7568 match(Set dst (AddL (LoadL src) val)); 7569 effect(KILL cr); 7570 7571 format %{ "edecq $dst, $src\t# long ndd" %} 7572 ins_encode %{ 7573 __ edecq($dst$$Register, $src$$Address, false); 7574 %} 7575 ins_pipe(ialu_reg); 7576 %} 7577 7578 // XXX why does that use AddL 7579 instruct decL_mem(memory dst, immL_M1 src, rFlagsReg cr) 7580 %{ 7581 predicate(UseIncDec); 7582 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7583 effect(KILL cr); 7584 7585 ins_cost(125); // XXX 7586 format %{ "decq $dst\t# long" %} 7587 ins_encode %{ 7588 __ decrementq($dst$$Address); 7589 %} 7590 ins_pipe(ialu_mem_imm); 7591 %} 7592 7593 instruct leaL_rReg_immI2_immL32(rRegL dst, rRegL index, immI2 scale, immL32 disp) 7594 %{ 7595 predicate(VM_Version::supports_fast_2op_lea()); 7596 match(Set dst (AddL (LShiftL index scale) disp)); 7597 7598 format %{ "leaq $dst, [$index << $scale + $disp]\t# long" %} 7599 ins_encode %{ 7600 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 7601 __ leaq($dst$$Register, Address(noreg, $index$$Register, scale, $disp$$constant)); 7602 %} 7603 ins_pipe(ialu_reg_reg); 7604 %} 7605 7606 instruct leaL_rReg_rReg_immL32(rRegL dst, rRegL base, rRegL index, immL32 disp) 7607 %{ 7608 predicate(VM_Version::supports_fast_3op_lea()); 7609 match(Set dst (AddL (AddL base index) disp)); 7610 7611 format %{ "leaq $dst, [$base + $index + $disp]\t# long" %} 7612 ins_encode %{ 7613 __ leaq($dst$$Register, Address($base$$Register, $index$$Register, Address::times_1, $disp$$constant)); 7614 %} 7615 ins_pipe(ialu_reg_reg); 7616 %} 7617 7618 instruct leaL_rReg_rReg_immI2(rRegL dst, no_rbp_r13_RegL base, rRegL index, immI2 scale) 7619 %{ 7620 predicate(VM_Version::supports_fast_2op_lea()); 7621 match(Set dst (AddL base (LShiftL index scale))); 7622 7623 format %{ "leaq $dst, [$base + $index << $scale]\t# long" %} 7624 ins_encode %{ 7625 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 7626 __ leaq($dst$$Register, Address($base$$Register, $index$$Register, scale)); 7627 %} 7628 ins_pipe(ialu_reg_reg); 7629 %} 7630 7631 instruct leaL_rReg_rReg_immI2_immL32(rRegL dst, rRegL base, rRegL index, immI2 scale, immL32 disp) 7632 %{ 7633 predicate(VM_Version::supports_fast_3op_lea()); 7634 match(Set dst (AddL (AddL base (LShiftL index scale)) disp)); 7635 7636 format %{ "leaq $dst, [$base + $index << $scale + $disp]\t# long" %} 7637 ins_encode %{ 7638 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 7639 __ leaq($dst$$Register, Address($base$$Register, $index$$Register, scale, $disp$$constant)); 7640 %} 7641 ins_pipe(ialu_reg_reg); 7642 %} 7643 7644 instruct addP_rReg(rRegP dst, rRegL src, rFlagsReg cr) 7645 %{ 7646 match(Set dst (AddP dst src)); 7647 effect(KILL cr); 7648 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); 7649 7650 format %{ "addq $dst, $src\t# ptr" %} 7651 ins_encode %{ 7652 __ addq($dst$$Register, $src$$Register); 7653 %} 7654 ins_pipe(ialu_reg_reg); 7655 %} 7656 7657 instruct addP_rReg_imm(rRegP dst, immL32 src, rFlagsReg cr) 7658 %{ 7659 match(Set dst (AddP dst src)); 7660 effect(KILL cr); 7661 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); 7662 7663 format %{ "addq $dst, $src\t# ptr" %} 7664 ins_encode %{ 7665 __ addq($dst$$Register, $src$$constant); 7666 %} 7667 ins_pipe( ialu_reg ); 7668 %} 7669 7670 // XXX addP mem ops ???? 7671 7672 instruct checkCastPP(rRegP dst) 7673 %{ 7674 match(Set dst (CheckCastPP dst)); 7675 7676 size(0); 7677 format %{ "# checkcastPP of $dst" %} 7678 ins_encode(/* empty encoding */); 7679 ins_pipe(empty); 7680 %} 7681 7682 instruct castPP(rRegP dst) 7683 %{ 7684 match(Set dst (CastPP dst)); 7685 7686 size(0); 7687 format %{ "# castPP of $dst" %} 7688 ins_encode(/* empty encoding */); 7689 ins_pipe(empty); 7690 %} 7691 7692 instruct castII(rRegI dst) 7693 %{ 7694 predicate(VerifyConstraintCasts == 0); 7695 match(Set dst (CastII dst)); 7696 7697 size(0); 7698 format %{ "# castII of $dst" %} 7699 ins_encode(/* empty encoding */); 7700 ins_cost(0); 7701 ins_pipe(empty); 7702 %} 7703 7704 instruct castII_checked(rRegI dst, rFlagsReg cr) 7705 %{ 7706 predicate(VerifyConstraintCasts > 0); 7707 match(Set dst (CastII dst)); 7708 7709 effect(KILL cr); 7710 format %{ "# cast_checked_II $dst" %} 7711 ins_encode %{ 7712 __ verify_int_in_range(_idx, bottom_type()->is_int(), $dst$$Register); 7713 %} 7714 ins_pipe(pipe_slow); 7715 %} 7716 7717 instruct castLL(rRegL dst) 7718 %{ 7719 predicate(VerifyConstraintCasts == 0); 7720 match(Set dst (CastLL dst)); 7721 7722 size(0); 7723 format %{ "# castLL of $dst" %} 7724 ins_encode(/* empty encoding */); 7725 ins_cost(0); 7726 ins_pipe(empty); 7727 %} 7728 7729 instruct castLL_checked_L32(rRegL dst, rFlagsReg cr) 7730 %{ 7731 predicate(VerifyConstraintCasts > 0 && castLL_is_imm32(n)); 7732 match(Set dst (CastLL dst)); 7733 7734 effect(KILL cr); 7735 format %{ "# cast_checked_LL $dst" %} 7736 ins_encode %{ 7737 __ verify_long_in_range(_idx, bottom_type()->is_long(), $dst$$Register, noreg); 7738 %} 7739 ins_pipe(pipe_slow); 7740 %} 7741 7742 instruct castLL_checked(rRegL dst, rRegL tmp, rFlagsReg cr) 7743 %{ 7744 predicate(VerifyConstraintCasts > 0 && !castLL_is_imm32(n)); 7745 match(Set dst (CastLL dst)); 7746 7747 effect(KILL cr, TEMP tmp); 7748 format %{ "# cast_checked_LL $dst\tusing $tmp as TEMP" %} 7749 ins_encode %{ 7750 __ verify_long_in_range(_idx, bottom_type()->is_long(), $dst$$Register, $tmp$$Register); 7751 %} 7752 ins_pipe(pipe_slow); 7753 %} 7754 7755 instruct castFF(regF dst) 7756 %{ 7757 match(Set dst (CastFF dst)); 7758 7759 size(0); 7760 format %{ "# castFF of $dst" %} 7761 ins_encode(/* empty encoding */); 7762 ins_cost(0); 7763 ins_pipe(empty); 7764 %} 7765 7766 instruct castHH(regF dst) 7767 %{ 7768 match(Set dst (CastHH dst)); 7769 7770 size(0); 7771 format %{ "# castHH of $dst" %} 7772 ins_encode(/* empty encoding */); 7773 ins_cost(0); 7774 ins_pipe(empty); 7775 %} 7776 7777 instruct castDD(regD dst) 7778 %{ 7779 match(Set dst (CastDD dst)); 7780 7781 size(0); 7782 format %{ "# castDD of $dst" %} 7783 ins_encode(/* empty encoding */); 7784 ins_cost(0); 7785 ins_pipe(empty); 7786 %} 7787 7788 // XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them 7789 instruct compareAndSwapP(rRegI res, 7790 memory mem_ptr, 7791 rax_RegP oldval, rRegP newval, 7792 rFlagsReg cr) 7793 %{ 7794 predicate(n->as_LoadStore()->barrier_data() == 0); 7795 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); 7796 match(Set res (WeakCompareAndSwapP mem_ptr (Binary oldval newval))); 7797 effect(KILL cr, KILL oldval); 7798 7799 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7800 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7801 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7802 ins_encode %{ 7803 __ lock(); 7804 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7805 __ setcc(Assembler::equal, $res$$Register); 7806 %} 7807 ins_pipe( pipe_cmpxchg ); 7808 %} 7809 7810 instruct compareAndSwapL(rRegI res, 7811 memory mem_ptr, 7812 rax_RegL oldval, rRegL newval, 7813 rFlagsReg cr) 7814 %{ 7815 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval))); 7816 match(Set res (WeakCompareAndSwapL mem_ptr (Binary oldval newval))); 7817 effect(KILL cr, KILL oldval); 7818 7819 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7820 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7821 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7822 ins_encode %{ 7823 __ lock(); 7824 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7825 __ setcc(Assembler::equal, $res$$Register); 7826 %} 7827 ins_pipe( pipe_cmpxchg ); 7828 %} 7829 7830 instruct compareAndSwapI(rRegI res, 7831 memory mem_ptr, 7832 rax_RegI oldval, rRegI newval, 7833 rFlagsReg cr) 7834 %{ 7835 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval))); 7836 match(Set res (WeakCompareAndSwapI mem_ptr (Binary oldval newval))); 7837 effect(KILL cr, KILL oldval); 7838 7839 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7840 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7841 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7842 ins_encode %{ 7843 __ lock(); 7844 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7845 __ setcc(Assembler::equal, $res$$Register); 7846 %} 7847 ins_pipe( pipe_cmpxchg ); 7848 %} 7849 7850 instruct compareAndSwapB(rRegI res, 7851 memory mem_ptr, 7852 rax_RegI oldval, rRegI newval, 7853 rFlagsReg cr) 7854 %{ 7855 match(Set res (CompareAndSwapB mem_ptr (Binary oldval newval))); 7856 match(Set res (WeakCompareAndSwapB mem_ptr (Binary oldval newval))); 7857 effect(KILL cr, KILL oldval); 7858 7859 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7860 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7861 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7862 ins_encode %{ 7863 __ lock(); 7864 __ cmpxchgb($newval$$Register, $mem_ptr$$Address); 7865 __ setcc(Assembler::equal, $res$$Register); 7866 %} 7867 ins_pipe( pipe_cmpxchg ); 7868 %} 7869 7870 instruct compareAndSwapS(rRegI res, 7871 memory mem_ptr, 7872 rax_RegI oldval, rRegI newval, 7873 rFlagsReg cr) 7874 %{ 7875 match(Set res (CompareAndSwapS mem_ptr (Binary oldval newval))); 7876 match(Set res (WeakCompareAndSwapS mem_ptr (Binary oldval newval))); 7877 effect(KILL cr, KILL oldval); 7878 7879 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7880 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7881 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7882 ins_encode %{ 7883 __ lock(); 7884 __ cmpxchgw($newval$$Register, $mem_ptr$$Address); 7885 __ setcc(Assembler::equal, $res$$Register); 7886 %} 7887 ins_pipe( pipe_cmpxchg ); 7888 %} 7889 7890 instruct compareAndSwapN(rRegI res, 7891 memory mem_ptr, 7892 rax_RegN oldval, rRegN newval, 7893 rFlagsReg cr) %{ 7894 predicate(n->as_LoadStore()->barrier_data() == 0); 7895 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval))); 7896 match(Set res (WeakCompareAndSwapN mem_ptr (Binary oldval newval))); 7897 effect(KILL cr, KILL oldval); 7898 7899 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7900 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7901 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7902 ins_encode %{ 7903 __ lock(); 7904 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7905 __ setcc(Assembler::equal, $res$$Register); 7906 %} 7907 ins_pipe( pipe_cmpxchg ); 7908 %} 7909 7910 instruct compareAndExchangeB( 7911 memory mem_ptr, 7912 rax_RegI oldval, rRegI newval, 7913 rFlagsReg cr) 7914 %{ 7915 match(Set oldval (CompareAndExchangeB mem_ptr (Binary oldval newval))); 7916 effect(KILL cr); 7917 7918 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7919 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7920 ins_encode %{ 7921 __ lock(); 7922 __ cmpxchgb($newval$$Register, $mem_ptr$$Address); 7923 %} 7924 ins_pipe( pipe_cmpxchg ); 7925 %} 7926 7927 instruct compareAndExchangeS( 7928 memory mem_ptr, 7929 rax_RegI oldval, rRegI newval, 7930 rFlagsReg cr) 7931 %{ 7932 match(Set oldval (CompareAndExchangeS mem_ptr (Binary oldval newval))); 7933 effect(KILL cr); 7934 7935 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7936 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7937 ins_encode %{ 7938 __ lock(); 7939 __ cmpxchgw($newval$$Register, $mem_ptr$$Address); 7940 %} 7941 ins_pipe( pipe_cmpxchg ); 7942 %} 7943 7944 instruct compareAndExchangeI( 7945 memory mem_ptr, 7946 rax_RegI oldval, rRegI newval, 7947 rFlagsReg cr) 7948 %{ 7949 match(Set oldval (CompareAndExchangeI mem_ptr (Binary oldval newval))); 7950 effect(KILL cr); 7951 7952 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7953 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7954 ins_encode %{ 7955 __ lock(); 7956 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7957 %} 7958 ins_pipe( pipe_cmpxchg ); 7959 %} 7960 7961 instruct compareAndExchangeL( 7962 memory mem_ptr, 7963 rax_RegL oldval, rRegL newval, 7964 rFlagsReg cr) 7965 %{ 7966 match(Set oldval (CompareAndExchangeL mem_ptr (Binary oldval newval))); 7967 effect(KILL cr); 7968 7969 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7970 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7971 ins_encode %{ 7972 __ lock(); 7973 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7974 %} 7975 ins_pipe( pipe_cmpxchg ); 7976 %} 7977 7978 instruct compareAndExchangeN( 7979 memory mem_ptr, 7980 rax_RegN oldval, rRegN newval, 7981 rFlagsReg cr) %{ 7982 predicate(n->as_LoadStore()->barrier_data() == 0); 7983 match(Set oldval (CompareAndExchangeN mem_ptr (Binary oldval newval))); 7984 effect(KILL cr); 7985 7986 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7987 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7988 ins_encode %{ 7989 __ lock(); 7990 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7991 %} 7992 ins_pipe( pipe_cmpxchg ); 7993 %} 7994 7995 instruct compareAndExchangeP( 7996 memory mem_ptr, 7997 rax_RegP oldval, rRegP newval, 7998 rFlagsReg cr) 7999 %{ 8000 predicate(n->as_LoadStore()->barrier_data() == 0); 8001 match(Set oldval (CompareAndExchangeP mem_ptr (Binary oldval newval))); 8002 effect(KILL cr); 8003 8004 format %{ "cmpxchgq $mem_ptr,$newval\t# " 8005 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 8006 ins_encode %{ 8007 __ lock(); 8008 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 8009 %} 8010 ins_pipe( pipe_cmpxchg ); 8011 %} 8012 8013 instruct xaddB_reg_no_res(memory mem, Universe dummy, rRegI add, rFlagsReg cr) %{ 8014 predicate(n->as_LoadStore()->result_not_used()); 8015 match(Set dummy (GetAndAddB mem add)); 8016 effect(KILL cr); 8017 format %{ "addb_lock $mem, $add" %} 8018 ins_encode %{ 8019 __ lock(); 8020 __ addb($mem$$Address, $add$$Register); 8021 %} 8022 ins_pipe(pipe_cmpxchg); 8023 %} 8024 8025 instruct xaddB_imm_no_res(memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 8026 predicate(n->as_LoadStore()->result_not_used()); 8027 match(Set dummy (GetAndAddB mem add)); 8028 effect(KILL cr); 8029 format %{ "addb_lock $mem, $add" %} 8030 ins_encode %{ 8031 __ lock(); 8032 __ addb($mem$$Address, $add$$constant); 8033 %} 8034 ins_pipe(pipe_cmpxchg); 8035 %} 8036 8037 instruct xaddB(memory mem, rRegI newval, rFlagsReg cr) %{ 8038 predicate(!n->as_LoadStore()->result_not_used()); 8039 match(Set newval (GetAndAddB mem newval)); 8040 effect(KILL cr); 8041 format %{ "xaddb_lock $mem, $newval" %} 8042 ins_encode %{ 8043 __ lock(); 8044 __ xaddb($mem$$Address, $newval$$Register); 8045 %} 8046 ins_pipe(pipe_cmpxchg); 8047 %} 8048 8049 instruct xaddS_reg_no_res(memory mem, Universe dummy, rRegI add, rFlagsReg cr) %{ 8050 predicate(n->as_LoadStore()->result_not_used()); 8051 match(Set dummy (GetAndAddS mem add)); 8052 effect(KILL cr); 8053 format %{ "addw_lock $mem, $add" %} 8054 ins_encode %{ 8055 __ lock(); 8056 __ addw($mem$$Address, $add$$Register); 8057 %} 8058 ins_pipe(pipe_cmpxchg); 8059 %} 8060 8061 instruct xaddS_imm_no_res(memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 8062 predicate(UseStoreImmI16 && n->as_LoadStore()->result_not_used()); 8063 match(Set dummy (GetAndAddS mem add)); 8064 effect(KILL cr); 8065 format %{ "addw_lock $mem, $add" %} 8066 ins_encode %{ 8067 __ lock(); 8068 __ addw($mem$$Address, $add$$constant); 8069 %} 8070 ins_pipe(pipe_cmpxchg); 8071 %} 8072 8073 instruct xaddS(memory mem, rRegI newval, rFlagsReg cr) %{ 8074 predicate(!n->as_LoadStore()->result_not_used()); 8075 match(Set newval (GetAndAddS mem newval)); 8076 effect(KILL cr); 8077 format %{ "xaddw_lock $mem, $newval" %} 8078 ins_encode %{ 8079 __ lock(); 8080 __ xaddw($mem$$Address, $newval$$Register); 8081 %} 8082 ins_pipe(pipe_cmpxchg); 8083 %} 8084 8085 instruct xaddI_reg_no_res(memory mem, Universe dummy, rRegI add, rFlagsReg cr) %{ 8086 predicate(n->as_LoadStore()->result_not_used()); 8087 match(Set dummy (GetAndAddI mem add)); 8088 effect(KILL cr); 8089 format %{ "addl_lock $mem, $add" %} 8090 ins_encode %{ 8091 __ lock(); 8092 __ addl($mem$$Address, $add$$Register); 8093 %} 8094 ins_pipe(pipe_cmpxchg); 8095 %} 8096 8097 instruct xaddI_imm_no_res(memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 8098 predicate(n->as_LoadStore()->result_not_used()); 8099 match(Set dummy (GetAndAddI mem add)); 8100 effect(KILL cr); 8101 format %{ "addl_lock $mem, $add" %} 8102 ins_encode %{ 8103 __ lock(); 8104 __ addl($mem$$Address, $add$$constant); 8105 %} 8106 ins_pipe(pipe_cmpxchg); 8107 %} 8108 8109 instruct xaddI(memory mem, rRegI newval, rFlagsReg cr) %{ 8110 predicate(!n->as_LoadStore()->result_not_used()); 8111 match(Set newval (GetAndAddI mem newval)); 8112 effect(KILL cr); 8113 format %{ "xaddl_lock $mem, $newval" %} 8114 ins_encode %{ 8115 __ lock(); 8116 __ xaddl($mem$$Address, $newval$$Register); 8117 %} 8118 ins_pipe(pipe_cmpxchg); 8119 %} 8120 8121 instruct xaddL_reg_no_res(memory mem, Universe dummy, rRegL add, rFlagsReg cr) %{ 8122 predicate(n->as_LoadStore()->result_not_used()); 8123 match(Set dummy (GetAndAddL mem add)); 8124 effect(KILL cr); 8125 format %{ "addq_lock $mem, $add" %} 8126 ins_encode %{ 8127 __ lock(); 8128 __ addq($mem$$Address, $add$$Register); 8129 %} 8130 ins_pipe(pipe_cmpxchg); 8131 %} 8132 8133 instruct xaddL_imm_no_res(memory mem, Universe dummy, immL32 add, rFlagsReg cr) %{ 8134 predicate(n->as_LoadStore()->result_not_used()); 8135 match(Set dummy (GetAndAddL mem add)); 8136 effect(KILL cr); 8137 format %{ "addq_lock $mem, $add" %} 8138 ins_encode %{ 8139 __ lock(); 8140 __ addq($mem$$Address, $add$$constant); 8141 %} 8142 ins_pipe(pipe_cmpxchg); 8143 %} 8144 8145 instruct xaddL(memory mem, rRegL newval, rFlagsReg cr) %{ 8146 predicate(!n->as_LoadStore()->result_not_used()); 8147 match(Set newval (GetAndAddL mem newval)); 8148 effect(KILL cr); 8149 format %{ "xaddq_lock $mem, $newval" %} 8150 ins_encode %{ 8151 __ lock(); 8152 __ xaddq($mem$$Address, $newval$$Register); 8153 %} 8154 ins_pipe(pipe_cmpxchg); 8155 %} 8156 8157 instruct xchgB( memory mem, rRegI newval) %{ 8158 match(Set newval (GetAndSetB mem newval)); 8159 format %{ "XCHGB $newval,[$mem]" %} 8160 ins_encode %{ 8161 __ xchgb($newval$$Register, $mem$$Address); 8162 %} 8163 ins_pipe( pipe_cmpxchg ); 8164 %} 8165 8166 instruct xchgS( memory mem, rRegI newval) %{ 8167 match(Set newval (GetAndSetS mem newval)); 8168 format %{ "XCHGW $newval,[$mem]" %} 8169 ins_encode %{ 8170 __ xchgw($newval$$Register, $mem$$Address); 8171 %} 8172 ins_pipe( pipe_cmpxchg ); 8173 %} 8174 8175 instruct xchgI( memory mem, rRegI newval) %{ 8176 match(Set newval (GetAndSetI mem newval)); 8177 format %{ "XCHGL $newval,[$mem]" %} 8178 ins_encode %{ 8179 __ xchgl($newval$$Register, $mem$$Address); 8180 %} 8181 ins_pipe( pipe_cmpxchg ); 8182 %} 8183 8184 instruct xchgL( memory mem, rRegL newval) %{ 8185 match(Set newval (GetAndSetL mem newval)); 8186 format %{ "XCHGL $newval,[$mem]" %} 8187 ins_encode %{ 8188 __ xchgq($newval$$Register, $mem$$Address); 8189 %} 8190 ins_pipe( pipe_cmpxchg ); 8191 %} 8192 8193 instruct xchgP( memory mem, rRegP newval) %{ 8194 match(Set newval (GetAndSetP mem newval)); 8195 predicate(n->as_LoadStore()->barrier_data() == 0); 8196 format %{ "XCHGQ $newval,[$mem]" %} 8197 ins_encode %{ 8198 __ xchgq($newval$$Register, $mem$$Address); 8199 %} 8200 ins_pipe( pipe_cmpxchg ); 8201 %} 8202 8203 instruct xchgN( memory mem, rRegN newval) %{ 8204 predicate(n->as_LoadStore()->barrier_data() == 0); 8205 match(Set newval (GetAndSetN mem newval)); 8206 format %{ "XCHGL $newval,$mem]" %} 8207 ins_encode %{ 8208 __ xchgl($newval$$Register, $mem$$Address); 8209 %} 8210 ins_pipe( pipe_cmpxchg ); 8211 %} 8212 8213 //----------Abs Instructions------------------------------------------- 8214 8215 // Integer Absolute Instructions 8216 instruct absI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8217 %{ 8218 match(Set dst (AbsI src)); 8219 effect(TEMP dst, KILL cr); 8220 format %{ "xorl $dst, $dst\t# abs int\n\t" 8221 "subl $dst, $src\n\t" 8222 "cmovll $dst, $src" %} 8223 ins_encode %{ 8224 __ xorl($dst$$Register, $dst$$Register); 8225 __ subl($dst$$Register, $src$$Register); 8226 __ cmovl(Assembler::less, $dst$$Register, $src$$Register); 8227 %} 8228 8229 ins_pipe(ialu_reg_reg); 8230 %} 8231 8232 // Long Absolute Instructions 8233 instruct absL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 8234 %{ 8235 match(Set dst (AbsL src)); 8236 effect(TEMP dst, KILL cr); 8237 format %{ "xorl $dst, $dst\t# abs long\n\t" 8238 "subq $dst, $src\n\t" 8239 "cmovlq $dst, $src" %} 8240 ins_encode %{ 8241 __ xorl($dst$$Register, $dst$$Register); 8242 __ subq($dst$$Register, $src$$Register); 8243 __ cmovq(Assembler::less, $dst$$Register, $src$$Register); 8244 %} 8245 8246 ins_pipe(ialu_reg_reg); 8247 %} 8248 8249 //----------Subtraction Instructions------------------------------------------- 8250 8251 // Integer Subtraction Instructions 8252 instruct subI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8253 %{ 8254 predicate(!UseAPX); 8255 match(Set dst (SubI dst src)); 8256 effect(KILL cr); 8257 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); 8258 8259 format %{ "subl $dst, $src\t# int" %} 8260 ins_encode %{ 8261 __ subl($dst$$Register, $src$$Register); 8262 %} 8263 ins_pipe(ialu_reg_reg); 8264 %} 8265 8266 instruct subI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr) 8267 %{ 8268 predicate(UseAPX); 8269 match(Set dst (SubI src1 src2)); 8270 effect(KILL cr); 8271 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); 8272 8273 format %{ "esubl $dst, $src1, $src2\t# int ndd" %} 8274 ins_encode %{ 8275 __ esubl($dst$$Register, $src1$$Register, $src2$$Register, false); 8276 %} 8277 ins_pipe(ialu_reg_reg); 8278 %} 8279 8280 instruct subI_rReg_rReg_imm_ndd(rRegI dst, rRegI src1, immI src2, rFlagsReg cr) 8281 %{ 8282 predicate(UseAPX); 8283 match(Set dst (SubI src1 src2)); 8284 effect(KILL cr); 8285 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); 8286 8287 format %{ "esubl $dst, $src1, $src2\t# int ndd" %} 8288 ins_encode %{ 8289 __ esubl($dst$$Register, $src1$$Register, $src2$$constant, false); 8290 %} 8291 ins_pipe(ialu_reg_reg); 8292 %} 8293 8294 instruct subI_rReg_mem_imm_ndd(rRegI dst, memory src1, immI src2, rFlagsReg cr) 8295 %{ 8296 predicate(UseAPX); 8297 match(Set dst (SubI (LoadI src1) src2)); 8298 effect(KILL cr); 8299 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); 8300 8301 format %{ "esubl $dst, $src1, $src2\t# int ndd" %} 8302 ins_encode %{ 8303 __ esubl($dst$$Register, $src1$$Address, $src2$$constant, false); 8304 %} 8305 ins_pipe(ialu_reg_reg); 8306 %} 8307 8308 instruct subI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 8309 %{ 8310 predicate(!UseAPX); 8311 match(Set dst (SubI dst (LoadI src))); 8312 effect(KILL cr); 8313 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); 8314 8315 ins_cost(150); 8316 format %{ "subl $dst, $src\t# int" %} 8317 ins_encode %{ 8318 __ subl($dst$$Register, $src$$Address); 8319 %} 8320 ins_pipe(ialu_reg_mem); 8321 %} 8322 8323 instruct subI_rReg_rReg_mem_ndd(rRegI dst, rRegI src1, memory src2, rFlagsReg cr) 8324 %{ 8325 predicate(UseAPX); 8326 match(Set dst (SubI src1 (LoadI src2))); 8327 effect(KILL cr); 8328 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); 8329 8330 ins_cost(150); 8331 format %{ "esubl $dst, $src1, $src2\t# int ndd" %} 8332 ins_encode %{ 8333 __ esubl($dst$$Register, $src1$$Register, $src2$$Address, false); 8334 %} 8335 ins_pipe(ialu_reg_mem); 8336 %} 8337 8338 instruct subI_rReg_mem_rReg_ndd(rRegI dst, memory src1, rRegI src2, rFlagsReg cr) 8339 %{ 8340 predicate(UseAPX); 8341 match(Set dst (SubI (LoadI src1) src2)); 8342 effect(KILL cr); 8343 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); 8344 8345 ins_cost(150); 8346 format %{ "esubl $dst, $src1, $src2\t# int ndd" %} 8347 ins_encode %{ 8348 __ esubl($dst$$Register, $src1$$Address, $src2$$Register, false); 8349 %} 8350 ins_pipe(ialu_reg_mem); 8351 %} 8352 8353 instruct subI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 8354 %{ 8355 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 8356 effect(KILL cr); 8357 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); 8358 8359 ins_cost(150); 8360 format %{ "subl $dst, $src\t# int" %} 8361 ins_encode %{ 8362 __ subl($dst$$Address, $src$$Register); 8363 %} 8364 ins_pipe(ialu_mem_reg); 8365 %} 8366 8367 instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 8368 %{ 8369 predicate(!UseAPX); 8370 match(Set dst (SubL dst src)); 8371 effect(KILL cr); 8372 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); 8373 8374 format %{ "subq $dst, $src\t# long" %} 8375 ins_encode %{ 8376 __ subq($dst$$Register, $src$$Register); 8377 %} 8378 ins_pipe(ialu_reg_reg); 8379 %} 8380 8381 instruct subL_rReg_ndd(rRegL dst, rRegL src1, rRegL src2, rFlagsReg cr) 8382 %{ 8383 predicate(UseAPX); 8384 match(Set dst (SubL src1 src2)); 8385 effect(KILL cr); 8386 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); 8387 8388 format %{ "esubq $dst, $src1, $src2\t# long ndd" %} 8389 ins_encode %{ 8390 __ esubq($dst$$Register, $src1$$Register, $src2$$Register, false); 8391 %} 8392 ins_pipe(ialu_reg_reg); 8393 %} 8394 8395 instruct subL_rReg_rReg_imm_ndd(rRegL dst, rRegL src1, immL32 src2, rFlagsReg cr) 8396 %{ 8397 predicate(UseAPX); 8398 match(Set dst (SubL src1 src2)); 8399 effect(KILL cr); 8400 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); 8401 8402 format %{ "esubq $dst, $src1, $src2\t# long ndd" %} 8403 ins_encode %{ 8404 __ esubq($dst$$Register, $src1$$Register, $src2$$constant, false); 8405 %} 8406 ins_pipe(ialu_reg_reg); 8407 %} 8408 8409 instruct subL_rReg_mem_imm_ndd(rRegL dst, memory src1, immL32 src2, rFlagsReg cr) 8410 %{ 8411 predicate(UseAPX); 8412 match(Set dst (SubL (LoadL src1) src2)); 8413 effect(KILL cr); 8414 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); 8415 8416 format %{ "esubq $dst, $src1, $src2\t# long ndd" %} 8417 ins_encode %{ 8418 __ esubq($dst$$Register, $src1$$Address, $src2$$constant, false); 8419 %} 8420 ins_pipe(ialu_reg_reg); 8421 %} 8422 8423 instruct subL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 8424 %{ 8425 predicate(!UseAPX); 8426 match(Set dst (SubL dst (LoadL src))); 8427 effect(KILL cr); 8428 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); 8429 8430 ins_cost(150); 8431 format %{ "subq $dst, $src\t# long" %} 8432 ins_encode %{ 8433 __ subq($dst$$Register, $src$$Address); 8434 %} 8435 ins_pipe(ialu_reg_mem); 8436 %} 8437 8438 instruct subL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr) 8439 %{ 8440 predicate(UseAPX); 8441 match(Set dst (SubL src1 (LoadL src2))); 8442 effect(KILL cr); 8443 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); 8444 8445 ins_cost(150); 8446 format %{ "esubq $dst, $src1, $src2\t# long ndd" %} 8447 ins_encode %{ 8448 __ esubq($dst$$Register, $src1$$Register, $src2$$Address, false); 8449 %} 8450 ins_pipe(ialu_reg_mem); 8451 %} 8452 8453 instruct subL_rReg_mem_rReg_ndd(rRegL dst, memory src1, rRegL src2, rFlagsReg cr) 8454 %{ 8455 predicate(UseAPX); 8456 match(Set dst (SubL (LoadL src1) src2)); 8457 effect(KILL cr); 8458 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); 8459 8460 ins_cost(150); 8461 format %{ "esubq $dst, $src1, $src2\t# long ndd" %} 8462 ins_encode %{ 8463 __ esubq($dst$$Register, $src1$$Address, $src2$$Register, false); 8464 %} 8465 ins_pipe(ialu_reg_mem); 8466 %} 8467 8468 instruct subL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 8469 %{ 8470 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 8471 effect(KILL cr); 8472 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); 8473 8474 ins_cost(150); 8475 format %{ "subq $dst, $src\t# long" %} 8476 ins_encode %{ 8477 __ subq($dst$$Address, $src$$Register); 8478 %} 8479 ins_pipe(ialu_mem_reg); 8480 %} 8481 8482 // Subtract from a pointer 8483 // XXX hmpf??? 8484 instruct subP_rReg(rRegP dst, rRegI src, immI_0 zero, rFlagsReg cr) 8485 %{ 8486 match(Set dst (AddP dst (SubI zero src))); 8487 effect(KILL cr); 8488 8489 format %{ "subq $dst, $src\t# ptr - int" %} 8490 ins_encode %{ 8491 __ subq($dst$$Register, $src$$Register); 8492 %} 8493 ins_pipe(ialu_reg_reg); 8494 %} 8495 8496 instruct negI_rReg(rRegI dst, immI_0 zero, rFlagsReg cr) 8497 %{ 8498 predicate(!UseAPX); 8499 match(Set dst (SubI zero dst)); 8500 effect(KILL cr); 8501 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8502 8503 format %{ "negl $dst\t# int" %} 8504 ins_encode %{ 8505 __ negl($dst$$Register); 8506 %} 8507 ins_pipe(ialu_reg); 8508 %} 8509 8510 instruct negI_rReg_ndd(rRegI dst, rRegI src, immI_0 zero, rFlagsReg cr) 8511 %{ 8512 predicate(UseAPX); 8513 match(Set dst (SubI zero src)); 8514 effect(KILL cr); 8515 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8516 8517 format %{ "enegl $dst, $src\t# int ndd" %} 8518 ins_encode %{ 8519 __ enegl($dst$$Register, $src$$Register, false); 8520 %} 8521 ins_pipe(ialu_reg); 8522 %} 8523 8524 instruct negI_rReg_2(rRegI dst, rFlagsReg cr) 8525 %{ 8526 predicate(!UseAPX); 8527 match(Set dst (NegI dst)); 8528 effect(KILL cr); 8529 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8530 8531 format %{ "negl $dst\t# int" %} 8532 ins_encode %{ 8533 __ negl($dst$$Register); 8534 %} 8535 ins_pipe(ialu_reg); 8536 %} 8537 8538 instruct negI_rReg_2_ndd(rRegI dst, rRegI src, rFlagsReg cr) 8539 %{ 8540 predicate(UseAPX); 8541 match(Set dst (NegI src)); 8542 effect(KILL cr); 8543 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8544 8545 format %{ "enegl $dst, $src\t# int ndd" %} 8546 ins_encode %{ 8547 __ enegl($dst$$Register, $src$$Register, false); 8548 %} 8549 ins_pipe(ialu_reg); 8550 %} 8551 8552 instruct negI_mem(memory dst, immI_0 zero, rFlagsReg cr) 8553 %{ 8554 match(Set dst (StoreI dst (SubI zero (LoadI dst)))); 8555 effect(KILL cr); 8556 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8557 8558 format %{ "negl $dst\t# int" %} 8559 ins_encode %{ 8560 __ negl($dst$$Address); 8561 %} 8562 ins_pipe(ialu_reg); 8563 %} 8564 8565 instruct negL_rReg(rRegL dst, immL0 zero, rFlagsReg cr) 8566 %{ 8567 predicate(!UseAPX); 8568 match(Set dst (SubL zero dst)); 8569 effect(KILL cr); 8570 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8571 8572 format %{ "negq $dst\t# long" %} 8573 ins_encode %{ 8574 __ negq($dst$$Register); 8575 %} 8576 ins_pipe(ialu_reg); 8577 %} 8578 8579 instruct negL_rReg_ndd(rRegL dst, rRegL src, immL0 zero, rFlagsReg cr) 8580 %{ 8581 predicate(UseAPX); 8582 match(Set dst (SubL zero src)); 8583 effect(KILL cr); 8584 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8585 8586 format %{ "enegq $dst, $src\t# long ndd" %} 8587 ins_encode %{ 8588 __ enegq($dst$$Register, $src$$Register, false); 8589 %} 8590 ins_pipe(ialu_reg); 8591 %} 8592 8593 instruct negL_rReg_2(rRegL dst, rFlagsReg cr) 8594 %{ 8595 predicate(!UseAPX); 8596 match(Set dst (NegL dst)); 8597 effect(KILL cr); 8598 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8599 8600 format %{ "negq $dst\t# int" %} 8601 ins_encode %{ 8602 __ negq($dst$$Register); 8603 %} 8604 ins_pipe(ialu_reg); 8605 %} 8606 8607 instruct negL_rReg_2_ndd(rRegL dst, rRegL src, rFlagsReg cr) 8608 %{ 8609 predicate(UseAPX); 8610 match(Set dst (NegL src)); 8611 effect(KILL cr); 8612 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8613 8614 format %{ "enegq $dst, $src\t# long ndd" %} 8615 ins_encode %{ 8616 __ enegq($dst$$Register, $src$$Register, false); 8617 %} 8618 ins_pipe(ialu_reg); 8619 %} 8620 8621 instruct negL_mem(memory dst, immL0 zero, rFlagsReg cr) 8622 %{ 8623 match(Set dst (StoreL dst (SubL zero (LoadL dst)))); 8624 effect(KILL cr); 8625 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8626 8627 format %{ "negq $dst\t# long" %} 8628 ins_encode %{ 8629 __ negq($dst$$Address); 8630 %} 8631 ins_pipe(ialu_reg); 8632 %} 8633 8634 //----------Multiplication/Division Instructions------------------------------- 8635 // Integer Multiplication Instructions 8636 // Multiply Register 8637 8638 instruct mulI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8639 %{ 8640 predicate(!UseAPX); 8641 match(Set dst (MulI dst src)); 8642 effect(KILL cr); 8643 8644 ins_cost(300); 8645 format %{ "imull $dst, $src\t# int" %} 8646 ins_encode %{ 8647 __ imull($dst$$Register, $src$$Register); 8648 %} 8649 ins_pipe(ialu_reg_reg_alu0); 8650 %} 8651 8652 instruct mulI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr) 8653 %{ 8654 predicate(UseAPX); 8655 match(Set dst (MulI src1 src2)); 8656 effect(KILL cr); 8657 8658 ins_cost(300); 8659 format %{ "eimull $dst, $src1, $src2\t# int ndd" %} 8660 ins_encode %{ 8661 __ eimull($dst$$Register, $src1$$Register, $src2$$Register, false); 8662 %} 8663 ins_pipe(ialu_reg_reg_alu0); 8664 %} 8665 8666 instruct mulI_rReg_imm(rRegI dst, rRegI src, immI imm, rFlagsReg cr) 8667 %{ 8668 match(Set dst (MulI src imm)); 8669 effect(KILL cr); 8670 8671 ins_cost(300); 8672 format %{ "imull $dst, $src, $imm\t# int" %} 8673 ins_encode %{ 8674 __ imull($dst$$Register, $src$$Register, $imm$$constant); 8675 %} 8676 ins_pipe(ialu_reg_reg_alu0); 8677 %} 8678 8679 instruct mulI_mem(rRegI dst, memory src, rFlagsReg cr) 8680 %{ 8681 predicate(!UseAPX); 8682 match(Set dst (MulI dst (LoadI src))); 8683 effect(KILL cr); 8684 8685 ins_cost(350); 8686 format %{ "imull $dst, $src\t# int" %} 8687 ins_encode %{ 8688 __ imull($dst$$Register, $src$$Address); 8689 %} 8690 ins_pipe(ialu_reg_mem_alu0); 8691 %} 8692 8693 instruct mulI_rReg_rReg_mem_ndd(rRegI dst, rRegI src1, memory src2, rFlagsReg cr) 8694 %{ 8695 predicate(UseAPX); 8696 match(Set dst (MulI src1 (LoadI src2))); 8697 effect(KILL cr); 8698 8699 ins_cost(350); 8700 format %{ "eimull $dst, $src1, $src2\t# int ndd" %} 8701 ins_encode %{ 8702 __ eimull($dst$$Register, $src1$$Register, $src2$$Address, false); 8703 %} 8704 ins_pipe(ialu_reg_mem_alu0); 8705 %} 8706 8707 instruct mulI_mem_imm(rRegI dst, memory src, immI imm, rFlagsReg cr) 8708 %{ 8709 match(Set dst (MulI (LoadI src) imm)); 8710 effect(KILL cr); 8711 8712 ins_cost(300); 8713 format %{ "imull $dst, $src, $imm\t# int" %} 8714 ins_encode %{ 8715 __ imull($dst$$Register, $src$$Address, $imm$$constant); 8716 %} 8717 ins_pipe(ialu_reg_mem_alu0); 8718 %} 8719 8720 instruct mulAddS2I_rReg(rRegI dst, rRegI src1, rRegI src2, rRegI src3, rFlagsReg cr) 8721 %{ 8722 match(Set dst (MulAddS2I (Binary dst src1) (Binary src2 src3))); 8723 effect(KILL cr, KILL src2); 8724 8725 expand %{ mulI_rReg(dst, src1, cr); 8726 mulI_rReg(src2, src3, cr); 8727 addI_rReg(dst, src2, cr); %} 8728 %} 8729 8730 instruct mulL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 8731 %{ 8732 predicate(!UseAPX); 8733 match(Set dst (MulL dst src)); 8734 effect(KILL cr); 8735 8736 ins_cost(300); 8737 format %{ "imulq $dst, $src\t# long" %} 8738 ins_encode %{ 8739 __ imulq($dst$$Register, $src$$Register); 8740 %} 8741 ins_pipe(ialu_reg_reg_alu0); 8742 %} 8743 8744 instruct mulL_rReg_ndd(rRegL dst, rRegL src1, rRegL src2, rFlagsReg cr) 8745 %{ 8746 predicate(UseAPX); 8747 match(Set dst (MulL src1 src2)); 8748 effect(KILL cr); 8749 8750 ins_cost(300); 8751 format %{ "eimulq $dst, $src1, $src2\t# long ndd" %} 8752 ins_encode %{ 8753 __ eimulq($dst$$Register, $src1$$Register, $src2$$Register, false); 8754 %} 8755 ins_pipe(ialu_reg_reg_alu0); 8756 %} 8757 8758 instruct mulL_rReg_imm(rRegL dst, rRegL src, immL32 imm, rFlagsReg cr) 8759 %{ 8760 match(Set dst (MulL src imm)); 8761 effect(KILL cr); 8762 8763 ins_cost(300); 8764 format %{ "imulq $dst, $src, $imm\t# long" %} 8765 ins_encode %{ 8766 __ imulq($dst$$Register, $src$$Register, $imm$$constant); 8767 %} 8768 ins_pipe(ialu_reg_reg_alu0); 8769 %} 8770 8771 instruct mulL_mem(rRegL dst, memory src, rFlagsReg cr) 8772 %{ 8773 predicate(!UseAPX); 8774 match(Set dst (MulL dst (LoadL src))); 8775 effect(KILL cr); 8776 8777 ins_cost(350); 8778 format %{ "imulq $dst, $src\t# long" %} 8779 ins_encode %{ 8780 __ imulq($dst$$Register, $src$$Address); 8781 %} 8782 ins_pipe(ialu_reg_mem_alu0); 8783 %} 8784 8785 instruct mulL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr) 8786 %{ 8787 predicate(UseAPX); 8788 match(Set dst (MulL src1 (LoadL src2))); 8789 effect(KILL cr); 8790 8791 ins_cost(350); 8792 format %{ "eimulq $dst, $src1, $src2 \t# long" %} 8793 ins_encode %{ 8794 __ eimulq($dst$$Register, $src1$$Register, $src2$$Address, false); 8795 %} 8796 ins_pipe(ialu_reg_mem_alu0); 8797 %} 8798 8799 instruct mulL_mem_imm(rRegL dst, memory src, immL32 imm, rFlagsReg cr) 8800 %{ 8801 match(Set dst (MulL (LoadL src) imm)); 8802 effect(KILL cr); 8803 8804 ins_cost(300); 8805 format %{ "imulq $dst, $src, $imm\t# long" %} 8806 ins_encode %{ 8807 __ imulq($dst$$Register, $src$$Address, $imm$$constant); 8808 %} 8809 ins_pipe(ialu_reg_mem_alu0); 8810 %} 8811 8812 instruct mulHiL_rReg(rdx_RegL dst, rRegL src, rax_RegL rax, rFlagsReg cr) 8813 %{ 8814 match(Set dst (MulHiL src rax)); 8815 effect(USE_KILL rax, KILL cr); 8816 8817 ins_cost(300); 8818 format %{ "imulq RDX:RAX, RAX, $src\t# mulhi" %} 8819 ins_encode %{ 8820 __ imulq($src$$Register); 8821 %} 8822 ins_pipe(ialu_reg_reg_alu0); 8823 %} 8824 8825 instruct umulHiL_rReg(rdx_RegL dst, rRegL src, rax_RegL rax, rFlagsReg cr) 8826 %{ 8827 match(Set dst (UMulHiL src rax)); 8828 effect(USE_KILL rax, KILL cr); 8829 8830 ins_cost(300); 8831 format %{ "mulq RDX:RAX, RAX, $src\t# umulhi" %} 8832 ins_encode %{ 8833 __ mulq($src$$Register); 8834 %} 8835 ins_pipe(ialu_reg_reg_alu0); 8836 %} 8837 8838 instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 8839 rFlagsReg cr) 8840 %{ 8841 match(Set rax (DivI rax div)); 8842 effect(KILL rdx, KILL cr); 8843 8844 ins_cost(30*100+10*100); // XXX 8845 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 8846 "jne,s normal\n\t" 8847 "xorl rdx, rdx\n\t" 8848 "cmpl $div, -1\n\t" 8849 "je,s done\n" 8850 "normal: cdql\n\t" 8851 "idivl $div\n" 8852 "done:" %} 8853 ins_encode(cdql_enc(div)); 8854 ins_pipe(ialu_reg_reg_alu0); 8855 %} 8856 8857 instruct divL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 8858 rFlagsReg cr) 8859 %{ 8860 match(Set rax (DivL rax div)); 8861 effect(KILL rdx, KILL cr); 8862 8863 ins_cost(30*100+10*100); // XXX 8864 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 8865 "cmpq rax, rdx\n\t" 8866 "jne,s normal\n\t" 8867 "xorl rdx, rdx\n\t" 8868 "cmpq $div, -1\n\t" 8869 "je,s done\n" 8870 "normal: cdqq\n\t" 8871 "idivq $div\n" 8872 "done:" %} 8873 ins_encode(cdqq_enc(div)); 8874 ins_pipe(ialu_reg_reg_alu0); 8875 %} 8876 8877 instruct udivI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, rFlagsReg cr) 8878 %{ 8879 match(Set rax (UDivI rax div)); 8880 effect(KILL rdx, KILL cr); 8881 8882 ins_cost(300); 8883 format %{ "udivl $rax,$rax,$div\t# UDivI\n" %} 8884 ins_encode %{ 8885 __ udivI($rax$$Register, $div$$Register, $rdx$$Register); 8886 %} 8887 ins_pipe(ialu_reg_reg_alu0); 8888 %} 8889 8890 instruct udivL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, rFlagsReg cr) 8891 %{ 8892 match(Set rax (UDivL rax div)); 8893 effect(KILL rdx, KILL cr); 8894 8895 ins_cost(300); 8896 format %{ "udivq $rax,$rax,$div\t# UDivL\n" %} 8897 ins_encode %{ 8898 __ udivL($rax$$Register, $div$$Register, $rdx$$Register); 8899 %} 8900 ins_pipe(ialu_reg_reg_alu0); 8901 %} 8902 8903 // Integer DIVMOD with Register, both quotient and mod results 8904 instruct divModI_rReg_divmod(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 8905 rFlagsReg cr) 8906 %{ 8907 match(DivModI rax div); 8908 effect(KILL cr); 8909 8910 ins_cost(30*100+10*100); // XXX 8911 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 8912 "jne,s normal\n\t" 8913 "xorl rdx, rdx\n\t" 8914 "cmpl $div, -1\n\t" 8915 "je,s done\n" 8916 "normal: cdql\n\t" 8917 "idivl $div\n" 8918 "done:" %} 8919 ins_encode(cdql_enc(div)); 8920 ins_pipe(pipe_slow); 8921 %} 8922 8923 // Long DIVMOD with Register, both quotient and mod results 8924 instruct divModL_rReg_divmod(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 8925 rFlagsReg cr) 8926 %{ 8927 match(DivModL rax div); 8928 effect(KILL cr); 8929 8930 ins_cost(30*100+10*100); // XXX 8931 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 8932 "cmpq rax, rdx\n\t" 8933 "jne,s normal\n\t" 8934 "xorl rdx, rdx\n\t" 8935 "cmpq $div, -1\n\t" 8936 "je,s done\n" 8937 "normal: cdqq\n\t" 8938 "idivq $div\n" 8939 "done:" %} 8940 ins_encode(cdqq_enc(div)); 8941 ins_pipe(pipe_slow); 8942 %} 8943 8944 // Unsigned integer DIVMOD with Register, both quotient and mod results 8945 instruct udivModI_rReg_divmod(rax_RegI rax, no_rax_rdx_RegI tmp, rdx_RegI rdx, 8946 no_rax_rdx_RegI div, rFlagsReg cr) 8947 %{ 8948 match(UDivModI rax div); 8949 effect(TEMP tmp, KILL cr); 8950 8951 ins_cost(300); 8952 format %{ "udivl $rax,$rax,$div\t# begin UDivModI\n\t" 8953 "umodl $rdx,$rax,$div\t! using $tmp as TEMP # end UDivModI\n" 8954 %} 8955 ins_encode %{ 8956 __ udivmodI($rax$$Register, $div$$Register, $rdx$$Register, $tmp$$Register); 8957 %} 8958 ins_pipe(pipe_slow); 8959 %} 8960 8961 // Unsigned long DIVMOD with Register, both quotient and mod results 8962 instruct udivModL_rReg_divmod(rax_RegL rax, no_rax_rdx_RegL tmp, rdx_RegL rdx, 8963 no_rax_rdx_RegL div, rFlagsReg cr) 8964 %{ 8965 match(UDivModL rax div); 8966 effect(TEMP tmp, KILL cr); 8967 8968 ins_cost(300); 8969 format %{ "udivq $rax,$rax,$div\t# begin UDivModL\n\t" 8970 "umodq $rdx,$rax,$div\t! using $tmp as TEMP # end UDivModL\n" 8971 %} 8972 ins_encode %{ 8973 __ udivmodL($rax$$Register, $div$$Register, $rdx$$Register, $tmp$$Register); 8974 %} 8975 ins_pipe(pipe_slow); 8976 %} 8977 8978 instruct modI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, 8979 rFlagsReg cr) 8980 %{ 8981 match(Set rdx (ModI rax div)); 8982 effect(KILL rax, KILL cr); 8983 8984 ins_cost(300); // XXX 8985 format %{ "cmpl rax, 0x80000000\t# irem\n\t" 8986 "jne,s normal\n\t" 8987 "xorl rdx, rdx\n\t" 8988 "cmpl $div, -1\n\t" 8989 "je,s done\n" 8990 "normal: cdql\n\t" 8991 "idivl $div\n" 8992 "done:" %} 8993 ins_encode(cdql_enc(div)); 8994 ins_pipe(ialu_reg_reg_alu0); 8995 %} 8996 8997 instruct modL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, 8998 rFlagsReg cr) 8999 %{ 9000 match(Set rdx (ModL rax div)); 9001 effect(KILL rax, KILL cr); 9002 9003 ins_cost(300); // XXX 9004 format %{ "movq rdx, 0x8000000000000000\t# lrem\n\t" 9005 "cmpq rax, rdx\n\t" 9006 "jne,s normal\n\t" 9007 "xorl rdx, rdx\n\t" 9008 "cmpq $div, -1\n\t" 9009 "je,s done\n" 9010 "normal: cdqq\n\t" 9011 "idivq $div\n" 9012 "done:" %} 9013 ins_encode(cdqq_enc(div)); 9014 ins_pipe(ialu_reg_reg_alu0); 9015 %} 9016 9017 instruct umodI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, rFlagsReg cr) 9018 %{ 9019 match(Set rdx (UModI rax div)); 9020 effect(KILL rax, KILL cr); 9021 9022 ins_cost(300); 9023 format %{ "umodl $rdx,$rax,$div\t# UModI\n" %} 9024 ins_encode %{ 9025 __ umodI($rax$$Register, $div$$Register, $rdx$$Register); 9026 %} 9027 ins_pipe(ialu_reg_reg_alu0); 9028 %} 9029 9030 instruct umodL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, rFlagsReg cr) 9031 %{ 9032 match(Set rdx (UModL rax div)); 9033 effect(KILL rax, KILL cr); 9034 9035 ins_cost(300); 9036 format %{ "umodq $rdx,$rax,$div\t# UModL\n" %} 9037 ins_encode %{ 9038 __ umodL($rax$$Register, $div$$Register, $rdx$$Register); 9039 %} 9040 ins_pipe(ialu_reg_reg_alu0); 9041 %} 9042 9043 // Integer Shift Instructions 9044 // Shift Left by one, two, three 9045 instruct salI_rReg_immI2(rRegI dst, immI2 shift, rFlagsReg cr) 9046 %{ 9047 predicate(!UseAPX); 9048 match(Set dst (LShiftI dst shift)); 9049 effect(KILL cr); 9050 9051 format %{ "sall $dst, $shift" %} 9052 ins_encode %{ 9053 __ sall($dst$$Register, $shift$$constant); 9054 %} 9055 ins_pipe(ialu_reg); 9056 %} 9057 9058 // Shift Left by one, two, three 9059 instruct salI_rReg_immI2_ndd(rRegI dst, rRegI src, immI2 shift, rFlagsReg cr) 9060 %{ 9061 predicate(UseAPX); 9062 match(Set dst (LShiftI src shift)); 9063 effect(KILL cr); 9064 9065 format %{ "esall $dst, $src, $shift\t# int(ndd)" %} 9066 ins_encode %{ 9067 __ esall($dst$$Register, $src$$Register, $shift$$constant, false); 9068 %} 9069 ins_pipe(ialu_reg); 9070 %} 9071 9072 // Shift Left by 8-bit immediate 9073 instruct salI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 9074 %{ 9075 predicate(!UseAPX); 9076 match(Set dst (LShiftI dst shift)); 9077 effect(KILL cr); 9078 9079 format %{ "sall $dst, $shift" %} 9080 ins_encode %{ 9081 __ sall($dst$$Register, $shift$$constant); 9082 %} 9083 ins_pipe(ialu_reg); 9084 %} 9085 9086 // Shift Left by 8-bit immediate 9087 instruct salI_rReg_imm_ndd(rRegI dst, rRegI src, immI8 shift, rFlagsReg cr) 9088 %{ 9089 predicate(UseAPX); 9090 match(Set dst (LShiftI src shift)); 9091 effect(KILL cr); 9092 9093 format %{ "esall $dst, $src, $shift\t# int (ndd)" %} 9094 ins_encode %{ 9095 __ esall($dst$$Register, $src$$Register, $shift$$constant, false); 9096 %} 9097 ins_pipe(ialu_reg); 9098 %} 9099 9100 instruct salI_rReg_mem_imm_ndd(rRegI dst, memory src, immI8 shift, rFlagsReg cr) 9101 %{ 9102 predicate(UseAPX); 9103 match(Set dst (LShiftI (LoadI src) shift)); 9104 effect(KILL cr); 9105 9106 format %{ "esall $dst, $src, $shift\t# int (ndd)" %} 9107 ins_encode %{ 9108 __ esall($dst$$Register, $src$$Address, $shift$$constant, false); 9109 %} 9110 ins_pipe(ialu_reg); 9111 %} 9112 9113 // Shift Left by 8-bit immediate 9114 instruct salI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 9115 %{ 9116 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 9117 effect(KILL cr); 9118 9119 format %{ "sall $dst, $shift" %} 9120 ins_encode %{ 9121 __ sall($dst$$Address, $shift$$constant); 9122 %} 9123 ins_pipe(ialu_mem_imm); 9124 %} 9125 9126 // Shift Left by variable 9127 instruct salI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 9128 %{ 9129 predicate(!VM_Version::supports_bmi2()); 9130 match(Set dst (LShiftI dst shift)); 9131 effect(KILL cr); 9132 9133 format %{ "sall $dst, $shift" %} 9134 ins_encode %{ 9135 __ sall($dst$$Register); 9136 %} 9137 ins_pipe(ialu_reg_reg); 9138 %} 9139 9140 // Shift Left by variable 9141 instruct salI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 9142 %{ 9143 predicate(!VM_Version::supports_bmi2()); 9144 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 9145 effect(KILL cr); 9146 9147 format %{ "sall $dst, $shift" %} 9148 ins_encode %{ 9149 __ sall($dst$$Address); 9150 %} 9151 ins_pipe(ialu_mem_reg); 9152 %} 9153 9154 instruct salI_rReg_rReg(rRegI dst, rRegI src, rRegI shift) 9155 %{ 9156 predicate(VM_Version::supports_bmi2()); 9157 match(Set dst (LShiftI src shift)); 9158 9159 format %{ "shlxl $dst, $src, $shift" %} 9160 ins_encode %{ 9161 __ shlxl($dst$$Register, $src$$Register, $shift$$Register); 9162 %} 9163 ins_pipe(ialu_reg_reg); 9164 %} 9165 9166 instruct salI_mem_rReg(rRegI dst, memory src, rRegI shift) 9167 %{ 9168 predicate(VM_Version::supports_bmi2()); 9169 match(Set dst (LShiftI (LoadI src) shift)); 9170 ins_cost(175); 9171 format %{ "shlxl $dst, $src, $shift" %} 9172 ins_encode %{ 9173 __ shlxl($dst$$Register, $src$$Address, $shift$$Register); 9174 %} 9175 ins_pipe(ialu_reg_mem); 9176 %} 9177 9178 // Arithmetic Shift Right by 8-bit immediate 9179 instruct sarI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 9180 %{ 9181 predicate(!UseAPX); 9182 match(Set dst (RShiftI dst shift)); 9183 effect(KILL cr); 9184 9185 format %{ "sarl $dst, $shift" %} 9186 ins_encode %{ 9187 __ sarl($dst$$Register, $shift$$constant); 9188 %} 9189 ins_pipe(ialu_mem_imm); 9190 %} 9191 9192 // Arithmetic Shift Right by 8-bit immediate 9193 instruct sarI_rReg_imm_ndd(rRegI dst, rRegI src, immI8 shift, rFlagsReg cr) 9194 %{ 9195 predicate(UseAPX); 9196 match(Set dst (RShiftI src shift)); 9197 effect(KILL cr); 9198 9199 format %{ "esarl $dst, $src, $shift\t# int (ndd)" %} 9200 ins_encode %{ 9201 __ esarl($dst$$Register, $src$$Register, $shift$$constant, false); 9202 %} 9203 ins_pipe(ialu_mem_imm); 9204 %} 9205 9206 instruct sarI_rReg_mem_imm_ndd(rRegI dst, memory src, immI8 shift, rFlagsReg cr) 9207 %{ 9208 predicate(UseAPX); 9209 match(Set dst (RShiftI (LoadI src) shift)); 9210 effect(KILL cr); 9211 9212 format %{ "esarl $dst, $src, $shift\t# int (ndd)" %} 9213 ins_encode %{ 9214 __ esarl($dst$$Register, $src$$Address, $shift$$constant, false); 9215 %} 9216 ins_pipe(ialu_mem_imm); 9217 %} 9218 9219 // Arithmetic Shift Right by 8-bit immediate 9220 instruct sarI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 9221 %{ 9222 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 9223 effect(KILL cr); 9224 9225 format %{ "sarl $dst, $shift" %} 9226 ins_encode %{ 9227 __ sarl($dst$$Address, $shift$$constant); 9228 %} 9229 ins_pipe(ialu_mem_imm); 9230 %} 9231 9232 // Arithmetic Shift Right by variable 9233 instruct sarI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 9234 %{ 9235 predicate(!VM_Version::supports_bmi2()); 9236 match(Set dst (RShiftI dst shift)); 9237 effect(KILL cr); 9238 9239 format %{ "sarl $dst, $shift" %} 9240 ins_encode %{ 9241 __ sarl($dst$$Register); 9242 %} 9243 ins_pipe(ialu_reg_reg); 9244 %} 9245 9246 // Arithmetic Shift Right by variable 9247 instruct sarI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 9248 %{ 9249 predicate(!VM_Version::supports_bmi2()); 9250 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 9251 effect(KILL cr); 9252 9253 format %{ "sarl $dst, $shift" %} 9254 ins_encode %{ 9255 __ sarl($dst$$Address); 9256 %} 9257 ins_pipe(ialu_mem_reg); 9258 %} 9259 9260 instruct sarI_rReg_rReg(rRegI dst, rRegI src, rRegI shift) 9261 %{ 9262 predicate(VM_Version::supports_bmi2()); 9263 match(Set dst (RShiftI src shift)); 9264 9265 format %{ "sarxl $dst, $src, $shift" %} 9266 ins_encode %{ 9267 __ sarxl($dst$$Register, $src$$Register, $shift$$Register); 9268 %} 9269 ins_pipe(ialu_reg_reg); 9270 %} 9271 9272 instruct sarI_mem_rReg(rRegI dst, memory src, rRegI shift) 9273 %{ 9274 predicate(VM_Version::supports_bmi2()); 9275 match(Set dst (RShiftI (LoadI src) shift)); 9276 ins_cost(175); 9277 format %{ "sarxl $dst, $src, $shift" %} 9278 ins_encode %{ 9279 __ sarxl($dst$$Register, $src$$Address, $shift$$Register); 9280 %} 9281 ins_pipe(ialu_reg_mem); 9282 %} 9283 9284 // Logical Shift Right by 8-bit immediate 9285 instruct shrI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 9286 %{ 9287 predicate(!UseAPX); 9288 match(Set dst (URShiftI dst shift)); 9289 effect(KILL cr); 9290 9291 format %{ "shrl $dst, $shift" %} 9292 ins_encode %{ 9293 __ shrl($dst$$Register, $shift$$constant); 9294 %} 9295 ins_pipe(ialu_reg); 9296 %} 9297 9298 // Logical Shift Right by 8-bit immediate 9299 instruct shrI_rReg_imm_ndd(rRegI dst, rRegI src, immI8 shift, rFlagsReg cr) 9300 %{ 9301 predicate(UseAPX); 9302 match(Set dst (URShiftI src shift)); 9303 effect(KILL cr); 9304 9305 format %{ "eshrl $dst, $src, $shift\t # int (ndd)" %} 9306 ins_encode %{ 9307 __ eshrl($dst$$Register, $src$$Register, $shift$$constant, false); 9308 %} 9309 ins_pipe(ialu_reg); 9310 %} 9311 9312 instruct shrI_rReg_mem_imm_ndd(rRegI dst, memory src, immI8 shift, rFlagsReg cr) 9313 %{ 9314 predicate(UseAPX); 9315 match(Set dst (URShiftI (LoadI src) shift)); 9316 effect(KILL cr); 9317 9318 format %{ "eshrl $dst, $src, $shift\t # int (ndd)" %} 9319 ins_encode %{ 9320 __ eshrl($dst$$Register, $src$$Address, $shift$$constant, false); 9321 %} 9322 ins_pipe(ialu_reg); 9323 %} 9324 9325 // Logical Shift Right by 8-bit immediate 9326 instruct shrI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 9327 %{ 9328 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 9329 effect(KILL cr); 9330 9331 format %{ "shrl $dst, $shift" %} 9332 ins_encode %{ 9333 __ shrl($dst$$Address, $shift$$constant); 9334 %} 9335 ins_pipe(ialu_mem_imm); 9336 %} 9337 9338 // Logical Shift Right by variable 9339 instruct shrI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 9340 %{ 9341 predicate(!VM_Version::supports_bmi2()); 9342 match(Set dst (URShiftI dst shift)); 9343 effect(KILL cr); 9344 9345 format %{ "shrl $dst, $shift" %} 9346 ins_encode %{ 9347 __ shrl($dst$$Register); 9348 %} 9349 ins_pipe(ialu_reg_reg); 9350 %} 9351 9352 // Logical Shift Right by variable 9353 instruct shrI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 9354 %{ 9355 predicate(!VM_Version::supports_bmi2()); 9356 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 9357 effect(KILL cr); 9358 9359 format %{ "shrl $dst, $shift" %} 9360 ins_encode %{ 9361 __ shrl($dst$$Address); 9362 %} 9363 ins_pipe(ialu_mem_reg); 9364 %} 9365 9366 instruct shrI_rReg_rReg(rRegI dst, rRegI src, rRegI shift) 9367 %{ 9368 predicate(VM_Version::supports_bmi2()); 9369 match(Set dst (URShiftI src shift)); 9370 9371 format %{ "shrxl $dst, $src, $shift" %} 9372 ins_encode %{ 9373 __ shrxl($dst$$Register, $src$$Register, $shift$$Register); 9374 %} 9375 ins_pipe(ialu_reg_reg); 9376 %} 9377 9378 instruct shrI_mem_rReg(rRegI dst, memory src, rRegI shift) 9379 %{ 9380 predicate(VM_Version::supports_bmi2()); 9381 match(Set dst (URShiftI (LoadI src) shift)); 9382 ins_cost(175); 9383 format %{ "shrxl $dst, $src, $shift" %} 9384 ins_encode %{ 9385 __ shrxl($dst$$Register, $src$$Address, $shift$$Register); 9386 %} 9387 ins_pipe(ialu_reg_mem); 9388 %} 9389 9390 // Long Shift Instructions 9391 // Shift Left by one, two, three 9392 instruct salL_rReg_immI2(rRegL dst, immI2 shift, rFlagsReg cr) 9393 %{ 9394 predicate(!UseAPX); 9395 match(Set dst (LShiftL dst shift)); 9396 effect(KILL cr); 9397 9398 format %{ "salq $dst, $shift" %} 9399 ins_encode %{ 9400 __ salq($dst$$Register, $shift$$constant); 9401 %} 9402 ins_pipe(ialu_reg); 9403 %} 9404 9405 // Shift Left by one, two, three 9406 instruct salL_rReg_immI2_ndd(rRegL dst, rRegL src, immI2 shift, rFlagsReg cr) 9407 %{ 9408 predicate(UseAPX); 9409 match(Set dst (LShiftL src shift)); 9410 effect(KILL cr); 9411 9412 format %{ "esalq $dst, $src, $shift\t# long (ndd)" %} 9413 ins_encode %{ 9414 __ esalq($dst$$Register, $src$$Register, $shift$$constant, false); 9415 %} 9416 ins_pipe(ialu_reg); 9417 %} 9418 9419 // Shift Left by 8-bit immediate 9420 instruct salL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 9421 %{ 9422 predicate(!UseAPX); 9423 match(Set dst (LShiftL dst shift)); 9424 effect(KILL cr); 9425 9426 format %{ "salq $dst, $shift" %} 9427 ins_encode %{ 9428 __ salq($dst$$Register, $shift$$constant); 9429 %} 9430 ins_pipe(ialu_reg); 9431 %} 9432 9433 // Shift Left by 8-bit immediate 9434 instruct salL_rReg_imm_ndd(rRegL dst, rRegL src, immI8 shift, rFlagsReg cr) 9435 %{ 9436 predicate(UseAPX); 9437 match(Set dst (LShiftL src shift)); 9438 effect(KILL cr); 9439 9440 format %{ "esalq $dst, $src, $shift\t# long (ndd)" %} 9441 ins_encode %{ 9442 __ esalq($dst$$Register, $src$$Register, $shift$$constant, false); 9443 %} 9444 ins_pipe(ialu_reg); 9445 %} 9446 9447 instruct salL_rReg_mem_imm_ndd(rRegL dst, memory src, immI8 shift, rFlagsReg cr) 9448 %{ 9449 predicate(UseAPX); 9450 match(Set dst (LShiftL (LoadL src) shift)); 9451 effect(KILL cr); 9452 9453 format %{ "esalq $dst, $src, $shift\t# long (ndd)" %} 9454 ins_encode %{ 9455 __ esalq($dst$$Register, $src$$Address, $shift$$constant, false); 9456 %} 9457 ins_pipe(ialu_reg); 9458 %} 9459 9460 // Shift Left by 8-bit immediate 9461 instruct salL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 9462 %{ 9463 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 9464 effect(KILL cr); 9465 9466 format %{ "salq $dst, $shift" %} 9467 ins_encode %{ 9468 __ salq($dst$$Address, $shift$$constant); 9469 %} 9470 ins_pipe(ialu_mem_imm); 9471 %} 9472 9473 // Shift Left by variable 9474 instruct salL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 9475 %{ 9476 predicate(!VM_Version::supports_bmi2()); 9477 match(Set dst (LShiftL dst shift)); 9478 effect(KILL cr); 9479 9480 format %{ "salq $dst, $shift" %} 9481 ins_encode %{ 9482 __ salq($dst$$Register); 9483 %} 9484 ins_pipe(ialu_reg_reg); 9485 %} 9486 9487 // Shift Left by variable 9488 instruct salL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 9489 %{ 9490 predicate(!VM_Version::supports_bmi2()); 9491 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 9492 effect(KILL cr); 9493 9494 format %{ "salq $dst, $shift" %} 9495 ins_encode %{ 9496 __ salq($dst$$Address); 9497 %} 9498 ins_pipe(ialu_mem_reg); 9499 %} 9500 9501 instruct salL_rReg_rReg(rRegL dst, rRegL src, rRegI shift) 9502 %{ 9503 predicate(VM_Version::supports_bmi2()); 9504 match(Set dst (LShiftL src shift)); 9505 9506 format %{ "shlxq $dst, $src, $shift" %} 9507 ins_encode %{ 9508 __ shlxq($dst$$Register, $src$$Register, $shift$$Register); 9509 %} 9510 ins_pipe(ialu_reg_reg); 9511 %} 9512 9513 instruct salL_mem_rReg(rRegL dst, memory src, rRegI shift) 9514 %{ 9515 predicate(VM_Version::supports_bmi2()); 9516 match(Set dst (LShiftL (LoadL src) shift)); 9517 ins_cost(175); 9518 format %{ "shlxq $dst, $src, $shift" %} 9519 ins_encode %{ 9520 __ shlxq($dst$$Register, $src$$Address, $shift$$Register); 9521 %} 9522 ins_pipe(ialu_reg_mem); 9523 %} 9524 9525 // Arithmetic Shift Right by 8-bit immediate 9526 instruct sarL_rReg_imm(rRegL dst, immI shift, rFlagsReg cr) 9527 %{ 9528 predicate(!UseAPX); 9529 match(Set dst (RShiftL dst shift)); 9530 effect(KILL cr); 9531 9532 format %{ "sarq $dst, $shift" %} 9533 ins_encode %{ 9534 __ sarq($dst$$Register, (unsigned char)($shift$$constant & 0x3F)); 9535 %} 9536 ins_pipe(ialu_mem_imm); 9537 %} 9538 9539 // Arithmetic Shift Right by 8-bit immediate 9540 instruct sarL_rReg_imm_ndd(rRegL dst, rRegL src, immI shift, rFlagsReg cr) 9541 %{ 9542 predicate(UseAPX); 9543 match(Set dst (RShiftL src shift)); 9544 effect(KILL cr); 9545 9546 format %{ "esarq $dst, $src, $shift\t# long (ndd)" %} 9547 ins_encode %{ 9548 __ esarq($dst$$Register, $src$$Register, (unsigned char)($shift$$constant & 0x3F), false); 9549 %} 9550 ins_pipe(ialu_mem_imm); 9551 %} 9552 9553 instruct sarL_rReg_mem_imm_ndd(rRegL dst, memory src, immI shift, rFlagsReg cr) 9554 %{ 9555 predicate(UseAPX); 9556 match(Set dst (RShiftL (LoadL src) shift)); 9557 effect(KILL cr); 9558 9559 format %{ "esarq $dst, $src, $shift\t# long (ndd)" %} 9560 ins_encode %{ 9561 __ esarq($dst$$Register, $src$$Address, (unsigned char)($shift$$constant & 0x3F), false); 9562 %} 9563 ins_pipe(ialu_mem_imm); 9564 %} 9565 9566 // Arithmetic Shift Right by 8-bit immediate 9567 instruct sarL_mem_imm(memory dst, immI shift, rFlagsReg cr) 9568 %{ 9569 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 9570 effect(KILL cr); 9571 9572 format %{ "sarq $dst, $shift" %} 9573 ins_encode %{ 9574 __ sarq($dst$$Address, (unsigned char)($shift$$constant & 0x3F)); 9575 %} 9576 ins_pipe(ialu_mem_imm); 9577 %} 9578 9579 // Arithmetic Shift Right by variable 9580 instruct sarL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 9581 %{ 9582 predicate(!VM_Version::supports_bmi2()); 9583 match(Set dst (RShiftL dst shift)); 9584 effect(KILL cr); 9585 9586 format %{ "sarq $dst, $shift" %} 9587 ins_encode %{ 9588 __ sarq($dst$$Register); 9589 %} 9590 ins_pipe(ialu_reg_reg); 9591 %} 9592 9593 // Arithmetic Shift Right by variable 9594 instruct sarL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 9595 %{ 9596 predicate(!VM_Version::supports_bmi2()); 9597 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 9598 effect(KILL cr); 9599 9600 format %{ "sarq $dst, $shift" %} 9601 ins_encode %{ 9602 __ sarq($dst$$Address); 9603 %} 9604 ins_pipe(ialu_mem_reg); 9605 %} 9606 9607 instruct sarL_rReg_rReg(rRegL dst, rRegL src, rRegI shift) 9608 %{ 9609 predicate(VM_Version::supports_bmi2()); 9610 match(Set dst (RShiftL src shift)); 9611 9612 format %{ "sarxq $dst, $src, $shift" %} 9613 ins_encode %{ 9614 __ sarxq($dst$$Register, $src$$Register, $shift$$Register); 9615 %} 9616 ins_pipe(ialu_reg_reg); 9617 %} 9618 9619 instruct sarL_mem_rReg(rRegL dst, memory src, rRegI shift) 9620 %{ 9621 predicate(VM_Version::supports_bmi2()); 9622 match(Set dst (RShiftL (LoadL src) shift)); 9623 ins_cost(175); 9624 format %{ "sarxq $dst, $src, $shift" %} 9625 ins_encode %{ 9626 __ sarxq($dst$$Register, $src$$Address, $shift$$Register); 9627 %} 9628 ins_pipe(ialu_reg_mem); 9629 %} 9630 9631 // Logical Shift Right by 8-bit immediate 9632 instruct shrL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 9633 %{ 9634 predicate(!UseAPX); 9635 match(Set dst (URShiftL dst shift)); 9636 effect(KILL cr); 9637 9638 format %{ "shrq $dst, $shift" %} 9639 ins_encode %{ 9640 __ shrq($dst$$Register, $shift$$constant); 9641 %} 9642 ins_pipe(ialu_reg); 9643 %} 9644 9645 // Logical Shift Right by 8-bit immediate 9646 instruct shrL_rReg_imm_ndd(rRegL dst, rRegL src, immI8 shift, rFlagsReg cr) 9647 %{ 9648 predicate(UseAPX); 9649 match(Set dst (URShiftL src shift)); 9650 effect(KILL cr); 9651 9652 format %{ "eshrq $dst, $src, $shift\t# long (ndd)" %} 9653 ins_encode %{ 9654 __ eshrq($dst$$Register, $src$$Register, $shift$$constant, false); 9655 %} 9656 ins_pipe(ialu_reg); 9657 %} 9658 9659 instruct shrL_rReg_mem_imm_ndd(rRegL dst, memory src, immI8 shift, rFlagsReg cr) 9660 %{ 9661 predicate(UseAPX); 9662 match(Set dst (URShiftL (LoadL src) shift)); 9663 effect(KILL cr); 9664 9665 format %{ "eshrq $dst, $src, $shift\t# long (ndd)" %} 9666 ins_encode %{ 9667 __ eshrq($dst$$Register, $src$$Address, $shift$$constant, false); 9668 %} 9669 ins_pipe(ialu_reg); 9670 %} 9671 9672 // Logical Shift Right by 8-bit immediate 9673 instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 9674 %{ 9675 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 9676 effect(KILL cr); 9677 9678 format %{ "shrq $dst, $shift" %} 9679 ins_encode %{ 9680 __ shrq($dst$$Address, $shift$$constant); 9681 %} 9682 ins_pipe(ialu_mem_imm); 9683 %} 9684 9685 // Logical Shift Right by variable 9686 instruct shrL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 9687 %{ 9688 predicate(!VM_Version::supports_bmi2()); 9689 match(Set dst (URShiftL dst shift)); 9690 effect(KILL cr); 9691 9692 format %{ "shrq $dst, $shift" %} 9693 ins_encode %{ 9694 __ shrq($dst$$Register); 9695 %} 9696 ins_pipe(ialu_reg_reg); 9697 %} 9698 9699 // Logical Shift Right by variable 9700 instruct shrL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 9701 %{ 9702 predicate(!VM_Version::supports_bmi2()); 9703 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 9704 effect(KILL cr); 9705 9706 format %{ "shrq $dst, $shift" %} 9707 ins_encode %{ 9708 __ shrq($dst$$Address); 9709 %} 9710 ins_pipe(ialu_mem_reg); 9711 %} 9712 9713 instruct shrL_rReg_rReg(rRegL dst, rRegL src, rRegI shift) 9714 %{ 9715 predicate(VM_Version::supports_bmi2()); 9716 match(Set dst (URShiftL src shift)); 9717 9718 format %{ "shrxq $dst, $src, $shift" %} 9719 ins_encode %{ 9720 __ shrxq($dst$$Register, $src$$Register, $shift$$Register); 9721 %} 9722 ins_pipe(ialu_reg_reg); 9723 %} 9724 9725 instruct shrL_mem_rReg(rRegL dst, memory src, rRegI shift) 9726 %{ 9727 predicate(VM_Version::supports_bmi2()); 9728 match(Set dst (URShiftL (LoadL src) shift)); 9729 ins_cost(175); 9730 format %{ "shrxq $dst, $src, $shift" %} 9731 ins_encode %{ 9732 __ shrxq($dst$$Register, $src$$Address, $shift$$Register); 9733 %} 9734 ins_pipe(ialu_reg_mem); 9735 %} 9736 9737 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24. 9738 // This idiom is used by the compiler for the i2b bytecode. 9739 instruct i2b(rRegI dst, rRegI src, immI_24 twentyfour) 9740 %{ 9741 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour)); 9742 9743 format %{ "movsbl $dst, $src\t# i2b" %} 9744 ins_encode %{ 9745 __ movsbl($dst$$Register, $src$$Register); 9746 %} 9747 ins_pipe(ialu_reg_reg); 9748 %} 9749 9750 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16. 9751 // This idiom is used by the compiler the i2s bytecode. 9752 instruct i2s(rRegI dst, rRegI src, immI_16 sixteen) 9753 %{ 9754 match(Set dst (RShiftI (LShiftI src sixteen) sixteen)); 9755 9756 format %{ "movswl $dst, $src\t# i2s" %} 9757 ins_encode %{ 9758 __ movswl($dst$$Register, $src$$Register); 9759 %} 9760 ins_pipe(ialu_reg_reg); 9761 %} 9762 9763 // ROL/ROR instructions 9764 9765 // Rotate left by constant. 9766 instruct rolI_immI8_legacy(rRegI dst, immI8 shift, rFlagsReg cr) 9767 %{ 9768 predicate(!VM_Version::supports_bmi2() && 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, $shift$$constant); 9774 %} 9775 ins_pipe(ialu_reg); 9776 %} 9777 9778 instruct rolI_immI8(rRegI dst, rRegI src, immI8 shift) 9779 %{ 9780 predicate(!UseAPX && VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 9781 match(Set dst (RotateLeft src shift)); 9782 format %{ "rolxl $dst, $src, $shift" %} 9783 ins_encode %{ 9784 int shift = 32 - ($shift$$constant & 31); 9785 __ rorxl($dst$$Register, $src$$Register, shift); 9786 %} 9787 ins_pipe(ialu_reg_reg); 9788 %} 9789 9790 instruct rolI_mem_immI8(rRegI dst, memory src, immI8 shift) 9791 %{ 9792 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 9793 match(Set dst (RotateLeft (LoadI src) shift)); 9794 ins_cost(175); 9795 format %{ "rolxl $dst, $src, $shift" %} 9796 ins_encode %{ 9797 int shift = 32 - ($shift$$constant & 31); 9798 __ rorxl($dst$$Register, $src$$Address, shift); 9799 %} 9800 ins_pipe(ialu_reg_mem); 9801 %} 9802 9803 // Rotate Left by variable 9804 instruct rolI_rReg_Var(rRegI dst, rcx_RegI shift, rFlagsReg cr) 9805 %{ 9806 predicate(!UseAPX && n->bottom_type()->basic_type() == T_INT); 9807 match(Set dst (RotateLeft dst shift)); 9808 effect(KILL cr); 9809 format %{ "roll $dst, $shift" %} 9810 ins_encode %{ 9811 __ roll($dst$$Register); 9812 %} 9813 ins_pipe(ialu_reg_reg); 9814 %} 9815 9816 // Rotate Left by variable 9817 instruct rolI_rReg_Var_ndd(rRegI dst, rRegI src, rcx_RegI shift, rFlagsReg cr) 9818 %{ 9819 predicate(UseAPX && n->bottom_type()->basic_type() == T_INT); 9820 match(Set dst (RotateLeft src shift)); 9821 effect(KILL cr); 9822 9823 format %{ "eroll $dst, $src, $shift\t# rotate left (int ndd)" %} 9824 ins_encode %{ 9825 __ eroll($dst$$Register, $src$$Register, false); 9826 %} 9827 ins_pipe(ialu_reg_reg); 9828 %} 9829 9830 // Rotate Right by constant. 9831 instruct rorI_immI8_legacy(rRegI dst, immI8 shift, rFlagsReg cr) 9832 %{ 9833 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 9834 match(Set dst (RotateRight dst shift)); 9835 effect(KILL cr); 9836 format %{ "rorl $dst, $shift" %} 9837 ins_encode %{ 9838 __ rorl($dst$$Register, $shift$$constant); 9839 %} 9840 ins_pipe(ialu_reg); 9841 %} 9842 9843 // Rotate Right by constant. 9844 instruct rorI_immI8(rRegI dst, rRegI src, immI8 shift) 9845 %{ 9846 predicate(!UseAPX && VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 9847 match(Set dst (RotateRight src shift)); 9848 format %{ "rorxl $dst, $src, $shift" %} 9849 ins_encode %{ 9850 __ rorxl($dst$$Register, $src$$Register, $shift$$constant); 9851 %} 9852 ins_pipe(ialu_reg_reg); 9853 %} 9854 9855 instruct rorI_mem_immI8(rRegI dst, memory src, immI8 shift) 9856 %{ 9857 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 9858 match(Set dst (RotateRight (LoadI src) shift)); 9859 ins_cost(175); 9860 format %{ "rorxl $dst, $src, $shift" %} 9861 ins_encode %{ 9862 __ rorxl($dst$$Register, $src$$Address, $shift$$constant); 9863 %} 9864 ins_pipe(ialu_reg_mem); 9865 %} 9866 9867 // Rotate Right by variable 9868 instruct rorI_rReg_Var(rRegI dst, rcx_RegI shift, rFlagsReg cr) 9869 %{ 9870 predicate(!UseAPX && n->bottom_type()->basic_type() == T_INT); 9871 match(Set dst (RotateRight dst shift)); 9872 effect(KILL cr); 9873 format %{ "rorl $dst, $shift" %} 9874 ins_encode %{ 9875 __ rorl($dst$$Register); 9876 %} 9877 ins_pipe(ialu_reg_reg); 9878 %} 9879 9880 // Rotate Right by variable 9881 instruct rorI_rReg_Var_ndd(rRegI dst, rRegI src, rcx_RegI shift, rFlagsReg cr) 9882 %{ 9883 predicate(UseAPX && n->bottom_type()->basic_type() == T_INT); 9884 match(Set dst (RotateRight src shift)); 9885 effect(KILL cr); 9886 9887 format %{ "erorl $dst, $src, $shift\t# rotate right(int ndd)" %} 9888 ins_encode %{ 9889 __ erorl($dst$$Register, $src$$Register, false); 9890 %} 9891 ins_pipe(ialu_reg_reg); 9892 %} 9893 9894 // Rotate Left by constant. 9895 instruct rolL_immI8_legacy(rRegL dst, immI8 shift, rFlagsReg cr) 9896 %{ 9897 predicate(!VM_Version::supports_bmi2() && 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, $shift$$constant); 9903 %} 9904 ins_pipe(ialu_reg); 9905 %} 9906 9907 instruct rolL_immI8(rRegL dst, rRegL src, immI8 shift) 9908 %{ 9909 predicate(!UseAPX && VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 9910 match(Set dst (RotateLeft src shift)); 9911 format %{ "rolxq $dst, $src, $shift" %} 9912 ins_encode %{ 9913 int shift = 64 - ($shift$$constant & 63); 9914 __ rorxq($dst$$Register, $src$$Register, shift); 9915 %} 9916 ins_pipe(ialu_reg_reg); 9917 %} 9918 9919 instruct rolL_mem_immI8(rRegL dst, memory src, immI8 shift) 9920 %{ 9921 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 9922 match(Set dst (RotateLeft (LoadL src) shift)); 9923 ins_cost(175); 9924 format %{ "rolxq $dst, $src, $shift" %} 9925 ins_encode %{ 9926 int shift = 64 - ($shift$$constant & 63); 9927 __ rorxq($dst$$Register, $src$$Address, shift); 9928 %} 9929 ins_pipe(ialu_reg_mem); 9930 %} 9931 9932 // Rotate Left by variable 9933 instruct rolL_rReg_Var(rRegL dst, rcx_RegI shift, rFlagsReg cr) 9934 %{ 9935 predicate(!UseAPX && n->bottom_type()->basic_type() == T_LONG); 9936 match(Set dst (RotateLeft dst shift)); 9937 effect(KILL cr); 9938 format %{ "rolq $dst, $shift" %} 9939 ins_encode %{ 9940 __ rolq($dst$$Register); 9941 %} 9942 ins_pipe(ialu_reg_reg); 9943 %} 9944 9945 // Rotate Left by variable 9946 instruct rolL_rReg_Var_ndd(rRegL dst, rRegL src, rcx_RegI shift, rFlagsReg cr) 9947 %{ 9948 predicate(UseAPX && n->bottom_type()->basic_type() == T_LONG); 9949 match(Set dst (RotateLeft src shift)); 9950 effect(KILL cr); 9951 9952 format %{ "erolq $dst, $src, $shift\t# rotate left(long ndd)" %} 9953 ins_encode %{ 9954 __ erolq($dst$$Register, $src$$Register, false); 9955 %} 9956 ins_pipe(ialu_reg_reg); 9957 %} 9958 9959 // Rotate Right by constant. 9960 instruct rorL_immI8_legacy(rRegL dst, immI8 shift, rFlagsReg cr) 9961 %{ 9962 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 9963 match(Set dst (RotateRight dst shift)); 9964 effect(KILL cr); 9965 format %{ "rorq $dst, $shift" %} 9966 ins_encode %{ 9967 __ rorq($dst$$Register, $shift$$constant); 9968 %} 9969 ins_pipe(ialu_reg); 9970 %} 9971 9972 // Rotate Right by constant 9973 instruct rorL_immI8(rRegL dst, rRegL src, immI8 shift) 9974 %{ 9975 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 9976 match(Set dst (RotateRight src shift)); 9977 format %{ "rorxq $dst, $src, $shift" %} 9978 ins_encode %{ 9979 __ rorxq($dst$$Register, $src$$Register, $shift$$constant); 9980 %} 9981 ins_pipe(ialu_reg_reg); 9982 %} 9983 9984 instruct rorL_mem_immI8(rRegL dst, memory src, immI8 shift) 9985 %{ 9986 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 9987 match(Set dst (RotateRight (LoadL src) shift)); 9988 ins_cost(175); 9989 format %{ "rorxq $dst, $src, $shift" %} 9990 ins_encode %{ 9991 __ rorxq($dst$$Register, $src$$Address, $shift$$constant); 9992 %} 9993 ins_pipe(ialu_reg_mem); 9994 %} 9995 9996 // Rotate Right by variable 9997 instruct rorL_rReg_Var(rRegL dst, rcx_RegI shift, rFlagsReg cr) 9998 %{ 9999 predicate(!UseAPX && n->bottom_type()->basic_type() == T_LONG); 10000 match(Set dst (RotateRight dst shift)); 10001 effect(KILL cr); 10002 format %{ "rorq $dst, $shift" %} 10003 ins_encode %{ 10004 __ rorq($dst$$Register); 10005 %} 10006 ins_pipe(ialu_reg_reg); 10007 %} 10008 10009 // Rotate Right by variable 10010 instruct rorL_rReg_Var_ndd(rRegL dst, rRegL src, rcx_RegI shift, rFlagsReg cr) 10011 %{ 10012 predicate(UseAPX && n->bottom_type()->basic_type() == T_LONG); 10013 match(Set dst (RotateRight src shift)); 10014 effect(KILL cr); 10015 10016 format %{ "erorq $dst, $src, $shift\t# rotate right(long ndd)" %} 10017 ins_encode %{ 10018 __ erorq($dst$$Register, $src$$Register, false); 10019 %} 10020 ins_pipe(ialu_reg_reg); 10021 %} 10022 10023 //----------------------------- CompressBits/ExpandBits ------------------------ 10024 10025 instruct compressBitsL_reg(rRegL dst, rRegL src, rRegL mask) %{ 10026 predicate(n->bottom_type()->isa_long()); 10027 match(Set dst (CompressBits src mask)); 10028 format %{ "pextq $dst, $src, $mask\t! parallel bit extract" %} 10029 ins_encode %{ 10030 __ pextq($dst$$Register, $src$$Register, $mask$$Register); 10031 %} 10032 ins_pipe( pipe_slow ); 10033 %} 10034 10035 instruct expandBitsL_reg(rRegL dst, rRegL src, rRegL mask) %{ 10036 predicate(n->bottom_type()->isa_long()); 10037 match(Set dst (ExpandBits src mask)); 10038 format %{ "pdepq $dst, $src, $mask\t! parallel bit deposit" %} 10039 ins_encode %{ 10040 __ pdepq($dst$$Register, $src$$Register, $mask$$Register); 10041 %} 10042 ins_pipe( pipe_slow ); 10043 %} 10044 10045 instruct compressBitsL_mem(rRegL dst, rRegL src, memory mask) %{ 10046 predicate(n->bottom_type()->isa_long()); 10047 match(Set dst (CompressBits src (LoadL mask))); 10048 format %{ "pextq $dst, $src, $mask\t! parallel bit extract" %} 10049 ins_encode %{ 10050 __ pextq($dst$$Register, $src$$Register, $mask$$Address); 10051 %} 10052 ins_pipe( pipe_slow ); 10053 %} 10054 10055 instruct expandBitsL_mem(rRegL dst, rRegL src, memory mask) %{ 10056 predicate(n->bottom_type()->isa_long()); 10057 match(Set dst (ExpandBits src (LoadL mask))); 10058 format %{ "pdepq $dst, $src, $mask\t! parallel bit deposit" %} 10059 ins_encode %{ 10060 __ pdepq($dst$$Register, $src$$Register, $mask$$Address); 10061 %} 10062 ins_pipe( pipe_slow ); 10063 %} 10064 10065 10066 // Logical Instructions 10067 10068 // Integer Logical Instructions 10069 10070 // And Instructions 10071 // And Register with Register 10072 instruct andI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 10073 %{ 10074 predicate(!UseAPX); 10075 match(Set dst (AndI dst src)); 10076 effect(KILL cr); 10077 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); 10078 10079 format %{ "andl $dst, $src\t# int" %} 10080 ins_encode %{ 10081 __ andl($dst$$Register, $src$$Register); 10082 %} 10083 ins_pipe(ialu_reg_reg); 10084 %} 10085 10086 // And Register with Register using New Data Destination (NDD) 10087 instruct andI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr) 10088 %{ 10089 predicate(UseAPX); 10090 match(Set dst (AndI src1 src2)); 10091 effect(KILL cr); 10092 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); 10093 10094 format %{ "eandl $dst, $src1, $src2\t# int ndd" %} 10095 ins_encode %{ 10096 __ eandl($dst$$Register, $src1$$Register, $src2$$Register, false); 10097 10098 %} 10099 ins_pipe(ialu_reg_reg); 10100 %} 10101 10102 // And Register with Immediate 255 10103 instruct andI_rReg_imm255(rRegI dst, rRegI src, immI_255 mask) 10104 %{ 10105 match(Set dst (AndI src mask)); 10106 10107 format %{ "movzbl $dst, $src\t# int & 0xFF" %} 10108 ins_encode %{ 10109 __ movzbl($dst$$Register, $src$$Register); 10110 %} 10111 ins_pipe(ialu_reg); 10112 %} 10113 10114 // And Register with Immediate 255 and promote to long 10115 instruct andI2L_rReg_imm255(rRegL dst, rRegI src, immI_255 mask) 10116 %{ 10117 match(Set dst (ConvI2L (AndI src mask))); 10118 10119 format %{ "movzbl $dst, $src\t# int & 0xFF -> long" %} 10120 ins_encode %{ 10121 __ movzbl($dst$$Register, $src$$Register); 10122 %} 10123 ins_pipe(ialu_reg); 10124 %} 10125 10126 // And Register with Immediate 65535 10127 instruct andI_rReg_imm65535(rRegI dst, rRegI src, immI_65535 mask) 10128 %{ 10129 match(Set dst (AndI src mask)); 10130 10131 format %{ "movzwl $dst, $src\t# int & 0xFFFF" %} 10132 ins_encode %{ 10133 __ movzwl($dst$$Register, $src$$Register); 10134 %} 10135 ins_pipe(ialu_reg); 10136 %} 10137 10138 // And Register with Immediate 65535 and promote to long 10139 instruct andI2L_rReg_imm65535(rRegL dst, rRegI src, immI_65535 mask) 10140 %{ 10141 match(Set dst (ConvI2L (AndI src mask))); 10142 10143 format %{ "movzwl $dst, $src\t# int & 0xFFFF -> long" %} 10144 ins_encode %{ 10145 __ movzwl($dst$$Register, $src$$Register); 10146 %} 10147 ins_pipe(ialu_reg); 10148 %} 10149 10150 // Can skip int2long conversions after AND with small bitmask 10151 instruct convI2LAndI_reg_immIbitmask(rRegL dst, rRegI src, immI_Pow2M1 mask, rRegI tmp, rFlagsReg cr) 10152 %{ 10153 predicate(VM_Version::supports_bmi2()); 10154 ins_cost(125); 10155 effect(TEMP tmp, KILL cr); 10156 match(Set dst (ConvI2L (AndI src mask))); 10157 format %{ "bzhiq $dst, $src, $mask \t# using $tmp as TEMP, int & immI_Pow2M1 -> long" %} 10158 ins_encode %{ 10159 __ movl($tmp$$Register, exact_log2($mask$$constant + 1)); 10160 __ bzhiq($dst$$Register, $src$$Register, $tmp$$Register); 10161 %} 10162 ins_pipe(ialu_reg_reg); 10163 %} 10164 10165 // And Register with Immediate 10166 instruct andI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 10167 %{ 10168 predicate(!UseAPX); 10169 match(Set dst (AndI dst src)); 10170 effect(KILL cr); 10171 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); 10172 10173 format %{ "andl $dst, $src\t# int" %} 10174 ins_encode %{ 10175 __ andl($dst$$Register, $src$$constant); 10176 %} 10177 ins_pipe(ialu_reg); 10178 %} 10179 10180 instruct andI_rReg_rReg_imm_ndd(rRegI dst, rRegI src1, immI src2, rFlagsReg cr) 10181 %{ 10182 predicate(UseAPX); 10183 match(Set dst (AndI src1 src2)); 10184 effect(KILL cr); 10185 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); 10186 10187 format %{ "eandl $dst, $src1, $src2\t# int ndd" %} 10188 ins_encode %{ 10189 __ eandl($dst$$Register, $src1$$Register, $src2$$constant, false); 10190 %} 10191 ins_pipe(ialu_reg); 10192 %} 10193 10194 instruct andI_rReg_mem_imm_ndd(rRegI dst, memory src1, immI src2, rFlagsReg cr) 10195 %{ 10196 predicate(UseAPX); 10197 match(Set dst (AndI (LoadI src1) src2)); 10198 effect(KILL cr); 10199 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); 10200 10201 format %{ "eandl $dst, $src1, $src2\t# int ndd" %} 10202 ins_encode %{ 10203 __ eandl($dst$$Register, $src1$$Address, $src2$$constant, false); 10204 %} 10205 ins_pipe(ialu_reg); 10206 %} 10207 10208 // And Register with Memory 10209 instruct andI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 10210 %{ 10211 predicate(!UseAPX); 10212 match(Set dst (AndI dst (LoadI src))); 10213 effect(KILL cr); 10214 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); 10215 10216 ins_cost(150); 10217 format %{ "andl $dst, $src\t# int" %} 10218 ins_encode %{ 10219 __ andl($dst$$Register, $src$$Address); 10220 %} 10221 ins_pipe(ialu_reg_mem); 10222 %} 10223 10224 instruct andI_rReg_rReg_mem_ndd(rRegI dst, rRegI src1, memory src2, rFlagsReg cr) 10225 %{ 10226 predicate(UseAPX); 10227 match(Set dst (AndI src1 (LoadI src2))); 10228 effect(KILL cr); 10229 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); 10230 10231 ins_cost(150); 10232 format %{ "eandl $dst, $src1, $src2\t# int ndd" %} 10233 ins_encode %{ 10234 __ eandl($dst$$Register, $src1$$Register, $src2$$Address, false); 10235 %} 10236 ins_pipe(ialu_reg_mem); 10237 %} 10238 10239 // And Memory with Register 10240 instruct andB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 10241 %{ 10242 match(Set dst (StoreB dst (AndI (LoadB dst) src))); 10243 effect(KILL cr); 10244 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); 10245 10246 ins_cost(150); 10247 format %{ "andb $dst, $src\t# byte" %} 10248 ins_encode %{ 10249 __ andb($dst$$Address, $src$$Register); 10250 %} 10251 ins_pipe(ialu_mem_reg); 10252 %} 10253 10254 instruct andI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 10255 %{ 10256 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 10257 effect(KILL cr); 10258 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); 10259 10260 ins_cost(150); 10261 format %{ "andl $dst, $src\t# int" %} 10262 ins_encode %{ 10263 __ andl($dst$$Address, $src$$Register); 10264 %} 10265 ins_pipe(ialu_mem_reg); 10266 %} 10267 10268 // And Memory with Immediate 10269 instruct andI_mem_imm(memory dst, immI src, rFlagsReg cr) 10270 %{ 10271 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 10272 effect(KILL cr); 10273 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); 10274 10275 ins_cost(125); 10276 format %{ "andl $dst, $src\t# int" %} 10277 ins_encode %{ 10278 __ andl($dst$$Address, $src$$constant); 10279 %} 10280 ins_pipe(ialu_mem_imm); 10281 %} 10282 10283 // BMI1 instructions 10284 instruct andnI_rReg_rReg_mem(rRegI dst, rRegI src1, memory src2, immI_M1 minus_1, rFlagsReg cr) %{ 10285 match(Set dst (AndI (XorI src1 minus_1) (LoadI src2))); 10286 predicate(UseBMI1Instructions); 10287 effect(KILL cr); 10288 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10289 10290 ins_cost(125); 10291 format %{ "andnl $dst, $src1, $src2" %} 10292 10293 ins_encode %{ 10294 __ andnl($dst$$Register, $src1$$Register, $src2$$Address); 10295 %} 10296 ins_pipe(ialu_reg_mem); 10297 %} 10298 10299 instruct andnI_rReg_rReg_rReg(rRegI dst, rRegI src1, rRegI src2, immI_M1 minus_1, rFlagsReg cr) %{ 10300 match(Set dst (AndI (XorI src1 minus_1) src2)); 10301 predicate(UseBMI1Instructions); 10302 effect(KILL cr); 10303 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10304 10305 format %{ "andnl $dst, $src1, $src2" %} 10306 10307 ins_encode %{ 10308 __ andnl($dst$$Register, $src1$$Register, $src2$$Register); 10309 %} 10310 ins_pipe(ialu_reg); 10311 %} 10312 10313 instruct blsiI_rReg_rReg(rRegI dst, rRegI src, immI_0 imm_zero, rFlagsReg cr) %{ 10314 match(Set dst (AndI (SubI imm_zero src) src)); 10315 predicate(UseBMI1Instructions); 10316 effect(KILL cr); 10317 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 10318 10319 format %{ "blsil $dst, $src" %} 10320 10321 ins_encode %{ 10322 __ blsil($dst$$Register, $src$$Register); 10323 %} 10324 ins_pipe(ialu_reg); 10325 %} 10326 10327 instruct blsiI_rReg_mem(rRegI dst, memory src, immI_0 imm_zero, rFlagsReg cr) %{ 10328 match(Set dst (AndI (SubI imm_zero (LoadI src) ) (LoadI src) )); 10329 predicate(UseBMI1Instructions); 10330 effect(KILL cr); 10331 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 10332 10333 ins_cost(125); 10334 format %{ "blsil $dst, $src" %} 10335 10336 ins_encode %{ 10337 __ blsil($dst$$Register, $src$$Address); 10338 %} 10339 ins_pipe(ialu_reg_mem); 10340 %} 10341 10342 instruct blsmskI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 10343 %{ 10344 match(Set dst (XorI (AddI (LoadI src) minus_1) (LoadI src) ) ); 10345 predicate(UseBMI1Instructions); 10346 effect(KILL cr); 10347 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 10348 10349 ins_cost(125); 10350 format %{ "blsmskl $dst, $src" %} 10351 10352 ins_encode %{ 10353 __ blsmskl($dst$$Register, $src$$Address); 10354 %} 10355 ins_pipe(ialu_reg_mem); 10356 %} 10357 10358 instruct blsmskI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 10359 %{ 10360 match(Set dst (XorI (AddI src minus_1) src)); 10361 predicate(UseBMI1Instructions); 10362 effect(KILL cr); 10363 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 10364 10365 format %{ "blsmskl $dst, $src" %} 10366 10367 ins_encode %{ 10368 __ blsmskl($dst$$Register, $src$$Register); 10369 %} 10370 10371 ins_pipe(ialu_reg); 10372 %} 10373 10374 instruct blsrI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 10375 %{ 10376 match(Set dst (AndI (AddI src minus_1) src) ); 10377 predicate(UseBMI1Instructions); 10378 effect(KILL cr); 10379 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 10380 10381 format %{ "blsrl $dst, $src" %} 10382 10383 ins_encode %{ 10384 __ blsrl($dst$$Register, $src$$Register); 10385 %} 10386 10387 ins_pipe(ialu_reg_mem); 10388 %} 10389 10390 instruct blsrI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 10391 %{ 10392 match(Set dst (AndI (AddI (LoadI src) minus_1) (LoadI src) ) ); 10393 predicate(UseBMI1Instructions); 10394 effect(KILL cr); 10395 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 10396 10397 ins_cost(125); 10398 format %{ "blsrl $dst, $src" %} 10399 10400 ins_encode %{ 10401 __ blsrl($dst$$Register, $src$$Address); 10402 %} 10403 10404 ins_pipe(ialu_reg); 10405 %} 10406 10407 // Or Instructions 10408 // Or Register with Register 10409 instruct orI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 10410 %{ 10411 predicate(!UseAPX); 10412 match(Set dst (OrI dst src)); 10413 effect(KILL cr); 10414 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); 10415 10416 format %{ "orl $dst, $src\t# int" %} 10417 ins_encode %{ 10418 __ orl($dst$$Register, $src$$Register); 10419 %} 10420 ins_pipe(ialu_reg_reg); 10421 %} 10422 10423 // Or Register with Register using New Data Destination (NDD) 10424 instruct orI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr) 10425 %{ 10426 predicate(UseAPX); 10427 match(Set dst (OrI src1 src2)); 10428 effect(KILL cr); 10429 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); 10430 10431 format %{ "eorl $dst, $src1, $src2\t# int ndd" %} 10432 ins_encode %{ 10433 __ eorl($dst$$Register, $src1$$Register, $src2$$Register, false); 10434 %} 10435 ins_pipe(ialu_reg_reg); 10436 %} 10437 10438 // Or Register with Immediate 10439 instruct orI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 10440 %{ 10441 predicate(!UseAPX); 10442 match(Set dst (OrI dst src)); 10443 effect(KILL cr); 10444 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); 10445 10446 format %{ "orl $dst, $src\t# int" %} 10447 ins_encode %{ 10448 __ orl($dst$$Register, $src$$constant); 10449 %} 10450 ins_pipe(ialu_reg); 10451 %} 10452 10453 instruct orI_rReg_rReg_imm_ndd(rRegI dst, rRegI src1, immI src2, rFlagsReg cr) 10454 %{ 10455 predicate(UseAPX); 10456 match(Set dst (OrI src1 src2)); 10457 effect(KILL cr); 10458 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); 10459 10460 format %{ "eorl $dst, $src1, $src2\t# int ndd" %} 10461 ins_encode %{ 10462 __ eorl($dst$$Register, $src1$$Register, $src2$$constant, false); 10463 %} 10464 ins_pipe(ialu_reg); 10465 %} 10466 10467 instruct orI_rReg_imm_rReg_ndd(rRegI dst, immI src1, rRegI src2, rFlagsReg cr) 10468 %{ 10469 predicate(UseAPX); 10470 match(Set dst (OrI src1 src2)); 10471 effect(KILL cr); 10472 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); 10473 10474 format %{ "eorl $dst, $src2, $src1\t# int ndd" %} 10475 ins_encode %{ 10476 __ eorl($dst$$Register, $src2$$Register, $src1$$constant, false); 10477 %} 10478 ins_pipe(ialu_reg); 10479 %} 10480 10481 instruct orI_rReg_mem_imm_ndd(rRegI dst, memory src1, immI src2, rFlagsReg cr) 10482 %{ 10483 predicate(UseAPX); 10484 match(Set dst (OrI (LoadI src1) src2)); 10485 effect(KILL cr); 10486 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); 10487 10488 format %{ "eorl $dst, $src1, $src2\t# int ndd" %} 10489 ins_encode %{ 10490 __ eorl($dst$$Register, $src1$$Address, $src2$$constant, false); 10491 %} 10492 ins_pipe(ialu_reg); 10493 %} 10494 10495 // Or Register with Memory 10496 instruct orI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 10497 %{ 10498 predicate(!UseAPX); 10499 match(Set dst (OrI dst (LoadI src))); 10500 effect(KILL cr); 10501 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); 10502 10503 ins_cost(150); 10504 format %{ "orl $dst, $src\t# int" %} 10505 ins_encode %{ 10506 __ orl($dst$$Register, $src$$Address); 10507 %} 10508 ins_pipe(ialu_reg_mem); 10509 %} 10510 10511 instruct orI_rReg_rReg_mem_ndd(rRegI dst, rRegI src1, memory src2, rFlagsReg cr) 10512 %{ 10513 predicate(UseAPX); 10514 match(Set dst (OrI src1 (LoadI src2))); 10515 effect(KILL cr); 10516 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); 10517 10518 ins_cost(150); 10519 format %{ "eorl $dst, $src1, $src2\t# int ndd" %} 10520 ins_encode %{ 10521 __ eorl($dst$$Register, $src1$$Register, $src2$$Address, false); 10522 %} 10523 ins_pipe(ialu_reg_mem); 10524 %} 10525 10526 // Or Memory with Register 10527 instruct orB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 10528 %{ 10529 match(Set dst (StoreB dst (OrI (LoadB dst) src))); 10530 effect(KILL cr); 10531 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); 10532 10533 ins_cost(150); 10534 format %{ "orb $dst, $src\t# byte" %} 10535 ins_encode %{ 10536 __ orb($dst$$Address, $src$$Register); 10537 %} 10538 ins_pipe(ialu_mem_reg); 10539 %} 10540 10541 instruct orI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 10542 %{ 10543 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 10544 effect(KILL cr); 10545 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); 10546 10547 ins_cost(150); 10548 format %{ "orl $dst, $src\t# int" %} 10549 ins_encode %{ 10550 __ orl($dst$$Address, $src$$Register); 10551 %} 10552 ins_pipe(ialu_mem_reg); 10553 %} 10554 10555 // Or Memory with Immediate 10556 instruct orI_mem_imm(memory dst, immI src, rFlagsReg cr) 10557 %{ 10558 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 10559 effect(KILL cr); 10560 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); 10561 10562 ins_cost(125); 10563 format %{ "orl $dst, $src\t# int" %} 10564 ins_encode %{ 10565 __ orl($dst$$Address, $src$$constant); 10566 %} 10567 ins_pipe(ialu_mem_imm); 10568 %} 10569 10570 // Xor Instructions 10571 // Xor Register with Register 10572 instruct xorI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 10573 %{ 10574 predicate(!UseAPX); 10575 match(Set dst (XorI dst src)); 10576 effect(KILL cr); 10577 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); 10578 10579 format %{ "xorl $dst, $src\t# int" %} 10580 ins_encode %{ 10581 __ xorl($dst$$Register, $src$$Register); 10582 %} 10583 ins_pipe(ialu_reg_reg); 10584 %} 10585 10586 // Xor Register with Register using New Data Destination (NDD) 10587 instruct xorI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr) 10588 %{ 10589 predicate(UseAPX); 10590 match(Set dst (XorI src1 src2)); 10591 effect(KILL cr); 10592 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); 10593 10594 format %{ "exorl $dst, $src1, $src2\t# int ndd" %} 10595 ins_encode %{ 10596 __ exorl($dst$$Register, $src1$$Register, $src2$$Register, false); 10597 %} 10598 ins_pipe(ialu_reg_reg); 10599 %} 10600 10601 // Xor Register with Immediate -1 10602 instruct xorI_rReg_im1(rRegI dst, immI_M1 imm) 10603 %{ 10604 predicate(!UseAPX); 10605 match(Set dst (XorI dst imm)); 10606 10607 format %{ "notl $dst" %} 10608 ins_encode %{ 10609 __ notl($dst$$Register); 10610 %} 10611 ins_pipe(ialu_reg); 10612 %} 10613 10614 instruct xorI_rReg_im1_ndd(rRegI dst, rRegI src, immI_M1 imm) 10615 %{ 10616 match(Set dst (XorI src imm)); 10617 predicate(UseAPX); 10618 10619 format %{ "enotl $dst, $src" %} 10620 ins_encode %{ 10621 __ enotl($dst$$Register, $src$$Register); 10622 %} 10623 ins_pipe(ialu_reg); 10624 %} 10625 10626 // Xor Register with Immediate 10627 instruct xorI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 10628 %{ 10629 // Strict predicate check to make selection of xorI_rReg_im1 cost agnostic if immI src is -1. 10630 predicate(!UseAPX && n->in(2)->bottom_type()->is_int()->get_con() != -1); 10631 match(Set dst (XorI dst src)); 10632 effect(KILL cr); 10633 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); 10634 10635 format %{ "xorl $dst, $src\t# int" %} 10636 ins_encode %{ 10637 __ xorl($dst$$Register, $src$$constant); 10638 %} 10639 ins_pipe(ialu_reg); 10640 %} 10641 10642 instruct xorI_rReg_rReg_imm_ndd(rRegI dst, rRegI src1, immI src2, rFlagsReg cr) 10643 %{ 10644 // Strict predicate check to make selection of xorI_rReg_im1_ndd cost agnostic if immI src2 is -1. 10645 predicate(UseAPX && n->in(2)->bottom_type()->is_int()->get_con() != -1); 10646 match(Set dst (XorI src1 src2)); 10647 effect(KILL cr); 10648 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); 10649 10650 format %{ "exorl $dst, $src1, $src2\t# int ndd" %} 10651 ins_encode %{ 10652 __ exorl($dst$$Register, $src1$$Register, $src2$$constant, false); 10653 %} 10654 ins_pipe(ialu_reg); 10655 %} 10656 10657 // Xor Memory with Immediate 10658 instruct xorI_rReg_mem_imm_ndd(rRegI dst, memory src1, immI src2, rFlagsReg cr) 10659 %{ 10660 predicate(UseAPX); 10661 match(Set dst (XorI (LoadI src1) src2)); 10662 effect(KILL cr); 10663 ins_cost(150); 10664 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); 10665 10666 format %{ "exorl $dst, $src1, $src2\t# int ndd" %} 10667 ins_encode %{ 10668 __ exorl($dst$$Register, $src1$$Address, $src2$$constant, false); 10669 %} 10670 ins_pipe(ialu_reg); 10671 %} 10672 10673 // Xor Register with Memory 10674 instruct xorI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 10675 %{ 10676 predicate(!UseAPX); 10677 match(Set dst (XorI dst (LoadI src))); 10678 effect(KILL cr); 10679 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); 10680 10681 ins_cost(150); 10682 format %{ "xorl $dst, $src\t# int" %} 10683 ins_encode %{ 10684 __ xorl($dst$$Register, $src$$Address); 10685 %} 10686 ins_pipe(ialu_reg_mem); 10687 %} 10688 10689 instruct xorI_rReg_rReg_mem_ndd(rRegI dst, rRegI src1, memory src2, rFlagsReg cr) 10690 %{ 10691 predicate(UseAPX); 10692 match(Set dst (XorI src1 (LoadI src2))); 10693 effect(KILL cr); 10694 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); 10695 10696 ins_cost(150); 10697 format %{ "exorl $dst, $src1, $src2\t# int ndd" %} 10698 ins_encode %{ 10699 __ exorl($dst$$Register, $src1$$Register, $src2$$Address, false); 10700 %} 10701 ins_pipe(ialu_reg_mem); 10702 %} 10703 10704 // Xor Memory with Register 10705 instruct xorB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 10706 %{ 10707 match(Set dst (StoreB dst (XorI (LoadB dst) src))); 10708 effect(KILL cr); 10709 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); 10710 10711 ins_cost(150); 10712 format %{ "xorb $dst, $src\t# byte" %} 10713 ins_encode %{ 10714 __ xorb($dst$$Address, $src$$Register); 10715 %} 10716 ins_pipe(ialu_mem_reg); 10717 %} 10718 10719 instruct xorI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 10720 %{ 10721 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 10722 effect(KILL cr); 10723 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); 10724 10725 ins_cost(150); 10726 format %{ "xorl $dst, $src\t# int" %} 10727 ins_encode %{ 10728 __ xorl($dst$$Address, $src$$Register); 10729 %} 10730 ins_pipe(ialu_mem_reg); 10731 %} 10732 10733 // Xor Memory with Immediate 10734 instruct xorI_mem_imm(memory dst, immI src, rFlagsReg cr) 10735 %{ 10736 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 10737 effect(KILL cr); 10738 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); 10739 10740 ins_cost(125); 10741 format %{ "xorl $dst, $src\t# int" %} 10742 ins_encode %{ 10743 __ xorl($dst$$Address, $src$$constant); 10744 %} 10745 ins_pipe(ialu_mem_imm); 10746 %} 10747 10748 10749 // Long Logical Instructions 10750 10751 // And Instructions 10752 // And Register with Register 10753 instruct andL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 10754 %{ 10755 predicate(!UseAPX); 10756 match(Set dst (AndL dst src)); 10757 effect(KILL cr); 10758 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); 10759 10760 format %{ "andq $dst, $src\t# long" %} 10761 ins_encode %{ 10762 __ andq($dst$$Register, $src$$Register); 10763 %} 10764 ins_pipe(ialu_reg_reg); 10765 %} 10766 10767 // And Register with Register using New Data Destination (NDD) 10768 instruct andL_rReg_ndd(rRegL dst, rRegL src1, rRegL src2, rFlagsReg cr) 10769 %{ 10770 predicate(UseAPX); 10771 match(Set dst (AndL src1 src2)); 10772 effect(KILL cr); 10773 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); 10774 10775 format %{ "eandq $dst, $src1, $src2\t# long ndd" %} 10776 ins_encode %{ 10777 __ eandq($dst$$Register, $src1$$Register, $src2$$Register, false); 10778 10779 %} 10780 ins_pipe(ialu_reg_reg); 10781 %} 10782 10783 // And Register with Immediate 255 10784 instruct andL_rReg_imm255(rRegL dst, rRegL src, immL_255 mask) 10785 %{ 10786 match(Set dst (AndL src mask)); 10787 10788 format %{ "movzbl $dst, $src\t# long & 0xFF" %} 10789 ins_encode %{ 10790 // movzbl zeroes out the upper 32-bit and does not need REX.W 10791 __ movzbl($dst$$Register, $src$$Register); 10792 %} 10793 ins_pipe(ialu_reg); 10794 %} 10795 10796 // And Register with Immediate 65535 10797 instruct andL_rReg_imm65535(rRegL dst, rRegL src, immL_65535 mask) 10798 %{ 10799 match(Set dst (AndL src mask)); 10800 10801 format %{ "movzwl $dst, $src\t# long & 0xFFFF" %} 10802 ins_encode %{ 10803 // movzwl zeroes out the upper 32-bit and does not need REX.W 10804 __ movzwl($dst$$Register, $src$$Register); 10805 %} 10806 ins_pipe(ialu_reg); 10807 %} 10808 10809 // And Register with Immediate 10810 instruct andL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 10811 %{ 10812 predicate(!UseAPX); 10813 match(Set dst (AndL dst src)); 10814 effect(KILL cr); 10815 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); 10816 10817 format %{ "andq $dst, $src\t# long" %} 10818 ins_encode %{ 10819 __ andq($dst$$Register, $src$$constant); 10820 %} 10821 ins_pipe(ialu_reg); 10822 %} 10823 10824 instruct andL_rReg_rReg_imm_ndd(rRegL dst, rRegL src1, immL32 src2, rFlagsReg cr) 10825 %{ 10826 predicate(UseAPX); 10827 match(Set dst (AndL src1 src2)); 10828 effect(KILL cr); 10829 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); 10830 10831 format %{ "eandq $dst, $src1, $src2\t# long ndd" %} 10832 ins_encode %{ 10833 __ eandq($dst$$Register, $src1$$Register, $src2$$constant, false); 10834 %} 10835 ins_pipe(ialu_reg); 10836 %} 10837 10838 instruct andL_rReg_mem_imm_ndd(rRegL dst, memory src1, immL32 src2, rFlagsReg cr) 10839 %{ 10840 predicate(UseAPX); 10841 match(Set dst (AndL (LoadL src1) src2)); 10842 effect(KILL cr); 10843 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); 10844 10845 format %{ "eandq $dst, $src1, $src2\t# long ndd" %} 10846 ins_encode %{ 10847 __ eandq($dst$$Register, $src1$$Address, $src2$$constant, false); 10848 %} 10849 ins_pipe(ialu_reg); 10850 %} 10851 10852 // And Register with Memory 10853 instruct andL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 10854 %{ 10855 predicate(!UseAPX); 10856 match(Set dst (AndL dst (LoadL src))); 10857 effect(KILL cr); 10858 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); 10859 10860 ins_cost(150); 10861 format %{ "andq $dst, $src\t# long" %} 10862 ins_encode %{ 10863 __ andq($dst$$Register, $src$$Address); 10864 %} 10865 ins_pipe(ialu_reg_mem); 10866 %} 10867 10868 instruct andL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr) 10869 %{ 10870 predicate(UseAPX); 10871 match(Set dst (AndL src1 (LoadL src2))); 10872 effect(KILL cr); 10873 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); 10874 10875 ins_cost(150); 10876 format %{ "eandq $dst, $src1, $src2\t# long ndd" %} 10877 ins_encode %{ 10878 __ eandq($dst$$Register, $src1$$Register, $src2$$Address, false); 10879 %} 10880 ins_pipe(ialu_reg_mem); 10881 %} 10882 10883 // And Memory with Register 10884 instruct andL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 10885 %{ 10886 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 10887 effect(KILL cr); 10888 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); 10889 10890 ins_cost(150); 10891 format %{ "andq $dst, $src\t# long" %} 10892 ins_encode %{ 10893 __ andq($dst$$Address, $src$$Register); 10894 %} 10895 ins_pipe(ialu_mem_reg); 10896 %} 10897 10898 // And Memory with Immediate 10899 instruct andL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 10900 %{ 10901 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 10902 effect(KILL cr); 10903 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); 10904 10905 ins_cost(125); 10906 format %{ "andq $dst, $src\t# long" %} 10907 ins_encode %{ 10908 __ andq($dst$$Address, $src$$constant); 10909 %} 10910 ins_pipe(ialu_mem_imm); 10911 %} 10912 10913 instruct btrL_mem_imm(memory dst, immL_NotPow2 con, rFlagsReg cr) 10914 %{ 10915 // con should be a pure 64-bit immediate given that not(con) is a power of 2 10916 // because AND/OR works well enough for 8/32-bit values. 10917 predicate(log2i_graceful(~n->in(3)->in(2)->get_long()) > 30); 10918 10919 match(Set dst (StoreL dst (AndL (LoadL dst) con))); 10920 effect(KILL cr); 10921 10922 ins_cost(125); 10923 format %{ "btrq $dst, log2(not($con))\t# long" %} 10924 ins_encode %{ 10925 __ btrq($dst$$Address, log2i_exact((julong)~$con$$constant)); 10926 %} 10927 ins_pipe(ialu_mem_imm); 10928 %} 10929 10930 // BMI1 instructions 10931 instruct andnL_rReg_rReg_mem(rRegL dst, rRegL src1, memory src2, immL_M1 minus_1, rFlagsReg cr) %{ 10932 match(Set dst (AndL (XorL src1 minus_1) (LoadL src2))); 10933 predicate(UseBMI1Instructions); 10934 effect(KILL cr); 10935 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10936 10937 ins_cost(125); 10938 format %{ "andnq $dst, $src1, $src2" %} 10939 10940 ins_encode %{ 10941 __ andnq($dst$$Register, $src1$$Register, $src2$$Address); 10942 %} 10943 ins_pipe(ialu_reg_mem); 10944 %} 10945 10946 instruct andnL_rReg_rReg_rReg(rRegL dst, rRegL src1, rRegL src2, immL_M1 minus_1, rFlagsReg cr) %{ 10947 match(Set dst (AndL (XorL src1 minus_1) src2)); 10948 predicate(UseBMI1Instructions); 10949 effect(KILL cr); 10950 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10951 10952 format %{ "andnq $dst, $src1, $src2" %} 10953 10954 ins_encode %{ 10955 __ andnq($dst$$Register, $src1$$Register, $src2$$Register); 10956 %} 10957 ins_pipe(ialu_reg_mem); 10958 %} 10959 10960 instruct blsiL_rReg_rReg(rRegL dst, rRegL src, immL0 imm_zero, rFlagsReg cr) %{ 10961 match(Set dst (AndL (SubL imm_zero src) src)); 10962 predicate(UseBMI1Instructions); 10963 effect(KILL cr); 10964 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 10965 10966 format %{ "blsiq $dst, $src" %} 10967 10968 ins_encode %{ 10969 __ blsiq($dst$$Register, $src$$Register); 10970 %} 10971 ins_pipe(ialu_reg); 10972 %} 10973 10974 instruct blsiL_rReg_mem(rRegL dst, memory src, immL0 imm_zero, rFlagsReg cr) %{ 10975 match(Set dst (AndL (SubL imm_zero (LoadL src) ) (LoadL src) )); 10976 predicate(UseBMI1Instructions); 10977 effect(KILL cr); 10978 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 10979 10980 ins_cost(125); 10981 format %{ "blsiq $dst, $src" %} 10982 10983 ins_encode %{ 10984 __ blsiq($dst$$Register, $src$$Address); 10985 %} 10986 ins_pipe(ialu_reg_mem); 10987 %} 10988 10989 instruct blsmskL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 10990 %{ 10991 match(Set dst (XorL (AddL (LoadL src) minus_1) (LoadL src) ) ); 10992 predicate(UseBMI1Instructions); 10993 effect(KILL cr); 10994 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 10995 10996 ins_cost(125); 10997 format %{ "blsmskq $dst, $src" %} 10998 10999 ins_encode %{ 11000 __ blsmskq($dst$$Register, $src$$Address); 11001 %} 11002 ins_pipe(ialu_reg_mem); 11003 %} 11004 11005 instruct blsmskL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 11006 %{ 11007 match(Set dst (XorL (AddL src minus_1) src)); 11008 predicate(UseBMI1Instructions); 11009 effect(KILL cr); 11010 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 11011 11012 format %{ "blsmskq $dst, $src" %} 11013 11014 ins_encode %{ 11015 __ blsmskq($dst$$Register, $src$$Register); 11016 %} 11017 11018 ins_pipe(ialu_reg); 11019 %} 11020 11021 instruct blsrL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 11022 %{ 11023 match(Set dst (AndL (AddL src minus_1) src) ); 11024 predicate(UseBMI1Instructions); 11025 effect(KILL cr); 11026 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 11027 11028 format %{ "blsrq $dst, $src" %} 11029 11030 ins_encode %{ 11031 __ blsrq($dst$$Register, $src$$Register); 11032 %} 11033 11034 ins_pipe(ialu_reg); 11035 %} 11036 11037 instruct blsrL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 11038 %{ 11039 match(Set dst (AndL (AddL (LoadL src) minus_1) (LoadL src)) ); 11040 predicate(UseBMI1Instructions); 11041 effect(KILL cr); 11042 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 11043 11044 ins_cost(125); 11045 format %{ "blsrq $dst, $src" %} 11046 11047 ins_encode %{ 11048 __ blsrq($dst$$Register, $src$$Address); 11049 %} 11050 11051 ins_pipe(ialu_reg); 11052 %} 11053 11054 // Or Instructions 11055 // Or Register with Register 11056 instruct orL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 11057 %{ 11058 predicate(!UseAPX); 11059 match(Set dst (OrL dst src)); 11060 effect(KILL cr); 11061 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); 11062 11063 format %{ "orq $dst, $src\t# long" %} 11064 ins_encode %{ 11065 __ orq($dst$$Register, $src$$Register); 11066 %} 11067 ins_pipe(ialu_reg_reg); 11068 %} 11069 11070 // Or Register with Register using New Data Destination (NDD) 11071 instruct orL_rReg_ndd(rRegL dst, rRegL src1, rRegL src2, rFlagsReg cr) 11072 %{ 11073 predicate(UseAPX); 11074 match(Set dst (OrL src1 src2)); 11075 effect(KILL cr); 11076 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); 11077 11078 format %{ "eorq $dst, $src1, $src2\t# long ndd" %} 11079 ins_encode %{ 11080 __ eorq($dst$$Register, $src1$$Register, $src2$$Register, false); 11081 11082 %} 11083 ins_pipe(ialu_reg_reg); 11084 %} 11085 11086 // Use any_RegP to match R15 (TLS register) without spilling. 11087 instruct orL_rReg_castP2X(rRegL dst, any_RegP src, rFlagsReg cr) %{ 11088 match(Set dst (OrL dst (CastP2X src))); 11089 effect(KILL cr); 11090 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); 11091 11092 format %{ "orq $dst, $src\t# long" %} 11093 ins_encode %{ 11094 __ orq($dst$$Register, $src$$Register); 11095 %} 11096 ins_pipe(ialu_reg_reg); 11097 %} 11098 11099 instruct orL_rReg_castP2X_ndd(rRegL dst, any_RegP src1, any_RegP src2, rFlagsReg cr) %{ 11100 match(Set dst (OrL src1 (CastP2X src2))); 11101 effect(KILL cr); 11102 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); 11103 11104 format %{ "eorq $dst, $src1, $src2\t# long ndd" %} 11105 ins_encode %{ 11106 __ eorq($dst$$Register, $src1$$Register, $src2$$Register, false); 11107 %} 11108 ins_pipe(ialu_reg_reg); 11109 %} 11110 11111 // Or Register with Immediate 11112 instruct orL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 11113 %{ 11114 predicate(!UseAPX); 11115 match(Set dst (OrL dst src)); 11116 effect(KILL cr); 11117 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); 11118 11119 format %{ "orq $dst, $src\t# long" %} 11120 ins_encode %{ 11121 __ orq($dst$$Register, $src$$constant); 11122 %} 11123 ins_pipe(ialu_reg); 11124 %} 11125 11126 instruct orL_rReg_rReg_imm_ndd(rRegL dst, rRegL src1, immL32 src2, rFlagsReg cr) 11127 %{ 11128 predicate(UseAPX); 11129 match(Set dst (OrL src1 src2)); 11130 effect(KILL cr); 11131 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); 11132 11133 format %{ "eorq $dst, $src1, $src2\t# long ndd" %} 11134 ins_encode %{ 11135 __ eorq($dst$$Register, $src1$$Register, $src2$$constant, false); 11136 %} 11137 ins_pipe(ialu_reg); 11138 %} 11139 11140 instruct orL_rReg_imm_rReg_ndd(rRegL dst, immL32 src1, rRegL src2, rFlagsReg cr) 11141 %{ 11142 predicate(UseAPX); 11143 match(Set dst (OrL src1 src2)); 11144 effect(KILL cr); 11145 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); 11146 11147 format %{ "eorq $dst, $src2, $src1\t# long ndd" %} 11148 ins_encode %{ 11149 __ eorq($dst$$Register, $src2$$Register, $src1$$constant, false); 11150 %} 11151 ins_pipe(ialu_reg); 11152 %} 11153 11154 // Or Memory with Immediate 11155 instruct orL_rReg_mem_imm_ndd(rRegL dst, memory src1, immL32 src2, rFlagsReg cr) 11156 %{ 11157 predicate(UseAPX); 11158 match(Set dst (OrL (LoadL src1) src2)); 11159 effect(KILL cr); 11160 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); 11161 11162 format %{ "eorq $dst, $src1, $src2\t# long ndd" %} 11163 ins_encode %{ 11164 __ eorq($dst$$Register, $src1$$Address, $src2$$constant, false); 11165 %} 11166 ins_pipe(ialu_reg); 11167 %} 11168 11169 // Or Register with Memory 11170 instruct orL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 11171 %{ 11172 predicate(!UseAPX); 11173 match(Set dst (OrL dst (LoadL src))); 11174 effect(KILL cr); 11175 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); 11176 11177 ins_cost(150); 11178 format %{ "orq $dst, $src\t# long" %} 11179 ins_encode %{ 11180 __ orq($dst$$Register, $src$$Address); 11181 %} 11182 ins_pipe(ialu_reg_mem); 11183 %} 11184 11185 instruct orL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr) 11186 %{ 11187 predicate(UseAPX); 11188 match(Set dst (OrL src1 (LoadL src2))); 11189 effect(KILL cr); 11190 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); 11191 11192 ins_cost(150); 11193 format %{ "eorq $dst, $src1, $src2\t# long ndd" %} 11194 ins_encode %{ 11195 __ eorq($dst$$Register, $src1$$Register, $src2$$Address, false); 11196 %} 11197 ins_pipe(ialu_reg_mem); 11198 %} 11199 11200 // Or Memory with Register 11201 instruct orL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 11202 %{ 11203 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 11204 effect(KILL cr); 11205 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); 11206 11207 ins_cost(150); 11208 format %{ "orq $dst, $src\t# long" %} 11209 ins_encode %{ 11210 __ orq($dst$$Address, $src$$Register); 11211 %} 11212 ins_pipe(ialu_mem_reg); 11213 %} 11214 11215 // Or Memory with Immediate 11216 instruct orL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 11217 %{ 11218 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 11219 effect(KILL cr); 11220 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); 11221 11222 ins_cost(125); 11223 format %{ "orq $dst, $src\t# long" %} 11224 ins_encode %{ 11225 __ orq($dst$$Address, $src$$constant); 11226 %} 11227 ins_pipe(ialu_mem_imm); 11228 %} 11229 11230 instruct btsL_mem_imm(memory dst, immL_Pow2 con, rFlagsReg cr) 11231 %{ 11232 // con should be a pure 64-bit power of 2 immediate 11233 // because AND/OR works well enough for 8/32-bit values. 11234 predicate(log2i_graceful(n->in(3)->in(2)->get_long()) > 31); 11235 11236 match(Set dst (StoreL dst (OrL (LoadL dst) con))); 11237 effect(KILL cr); 11238 11239 ins_cost(125); 11240 format %{ "btsq $dst, log2($con)\t# long" %} 11241 ins_encode %{ 11242 __ btsq($dst$$Address, log2i_exact((julong)$con$$constant)); 11243 %} 11244 ins_pipe(ialu_mem_imm); 11245 %} 11246 11247 // Xor Instructions 11248 // Xor Register with Register 11249 instruct xorL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 11250 %{ 11251 predicate(!UseAPX); 11252 match(Set dst (XorL dst src)); 11253 effect(KILL cr); 11254 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); 11255 11256 format %{ "xorq $dst, $src\t# long" %} 11257 ins_encode %{ 11258 __ xorq($dst$$Register, $src$$Register); 11259 %} 11260 ins_pipe(ialu_reg_reg); 11261 %} 11262 11263 // Xor Register with Register using New Data Destination (NDD) 11264 instruct xorL_rReg_ndd(rRegL dst, rRegL src1, rRegL src2, rFlagsReg cr) 11265 %{ 11266 predicate(UseAPX); 11267 match(Set dst (XorL src1 src2)); 11268 effect(KILL cr); 11269 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); 11270 11271 format %{ "exorq $dst, $src1, $src2\t# long ndd" %} 11272 ins_encode %{ 11273 __ exorq($dst$$Register, $src1$$Register, $src2$$Register, false); 11274 %} 11275 ins_pipe(ialu_reg_reg); 11276 %} 11277 11278 // Xor Register with Immediate -1 11279 instruct xorL_rReg_im1(rRegL dst, immL_M1 imm) 11280 %{ 11281 predicate(!UseAPX); 11282 match(Set dst (XorL dst imm)); 11283 11284 format %{ "notq $dst" %} 11285 ins_encode %{ 11286 __ notq($dst$$Register); 11287 %} 11288 ins_pipe(ialu_reg); 11289 %} 11290 11291 instruct xorL_rReg_im1_ndd(rRegL dst,rRegL src, immL_M1 imm) 11292 %{ 11293 predicate(UseAPX); 11294 match(Set dst (XorL src imm)); 11295 11296 format %{ "enotq $dst, $src" %} 11297 ins_encode %{ 11298 __ enotq($dst$$Register, $src$$Register); 11299 %} 11300 ins_pipe(ialu_reg); 11301 %} 11302 11303 // Xor Register with Immediate 11304 instruct xorL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 11305 %{ 11306 // Strict predicate check to make selection of xorL_rReg_im1 cost agnostic if immL32 src is -1. 11307 predicate(!UseAPX && n->in(2)->bottom_type()->is_long()->get_con() != -1L); 11308 match(Set dst (XorL dst src)); 11309 effect(KILL cr); 11310 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); 11311 11312 format %{ "xorq $dst, $src\t# long" %} 11313 ins_encode %{ 11314 __ xorq($dst$$Register, $src$$constant); 11315 %} 11316 ins_pipe(ialu_reg); 11317 %} 11318 11319 instruct xorL_rReg_rReg_imm(rRegL dst, rRegL src1, immL32 src2, rFlagsReg cr) 11320 %{ 11321 // Strict predicate check to make selection of xorL_rReg_im1_ndd cost agnostic if immL32 src2 is -1. 11322 predicate(UseAPX && n->in(2)->bottom_type()->is_long()->get_con() != -1L); 11323 match(Set dst (XorL src1 src2)); 11324 effect(KILL cr); 11325 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); 11326 11327 format %{ "exorq $dst, $src1, $src2\t# long ndd" %} 11328 ins_encode %{ 11329 __ exorq($dst$$Register, $src1$$Register, $src2$$constant, false); 11330 %} 11331 ins_pipe(ialu_reg); 11332 %} 11333 11334 // Xor Memory with Immediate 11335 instruct xorL_rReg_mem_imm(rRegL dst, memory src1, immL32 src2, rFlagsReg cr) 11336 %{ 11337 predicate(UseAPX); 11338 match(Set dst (XorL (LoadL src1) src2)); 11339 effect(KILL cr); 11340 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); 11341 ins_cost(150); 11342 11343 format %{ "exorq $dst, $src1, $src2\t# long ndd" %} 11344 ins_encode %{ 11345 __ exorq($dst$$Register, $src1$$Address, $src2$$constant, false); 11346 %} 11347 ins_pipe(ialu_reg); 11348 %} 11349 11350 // Xor Register with Memory 11351 instruct xorL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 11352 %{ 11353 predicate(!UseAPX); 11354 match(Set dst (XorL dst (LoadL src))); 11355 effect(KILL cr); 11356 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); 11357 11358 ins_cost(150); 11359 format %{ "xorq $dst, $src\t# long" %} 11360 ins_encode %{ 11361 __ xorq($dst$$Register, $src$$Address); 11362 %} 11363 ins_pipe(ialu_reg_mem); 11364 %} 11365 11366 instruct xorL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr) 11367 %{ 11368 predicate(UseAPX); 11369 match(Set dst (XorL src1 (LoadL src2))); 11370 effect(KILL cr); 11371 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); 11372 11373 ins_cost(150); 11374 format %{ "exorq $dst, $src1, $src2\t# long ndd" %} 11375 ins_encode %{ 11376 __ exorq($dst$$Register, $src1$$Register, $src2$$Address, false); 11377 %} 11378 ins_pipe(ialu_reg_mem); 11379 %} 11380 11381 // Xor Memory with Register 11382 instruct xorL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 11383 %{ 11384 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 11385 effect(KILL cr); 11386 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); 11387 11388 ins_cost(150); 11389 format %{ "xorq $dst, $src\t# long" %} 11390 ins_encode %{ 11391 __ xorq($dst$$Address, $src$$Register); 11392 %} 11393 ins_pipe(ialu_mem_reg); 11394 %} 11395 11396 // Xor Memory with Immediate 11397 instruct xorL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 11398 %{ 11399 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 11400 effect(KILL cr); 11401 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); 11402 11403 ins_cost(125); 11404 format %{ "xorq $dst, $src\t# long" %} 11405 ins_encode %{ 11406 __ xorq($dst$$Address, $src$$constant); 11407 %} 11408 ins_pipe(ialu_mem_imm); 11409 %} 11410 11411 instruct cmpLTMask(rRegI dst, rRegI p, rRegI q, rFlagsReg cr) 11412 %{ 11413 match(Set dst (CmpLTMask p q)); 11414 effect(KILL cr); 11415 11416 ins_cost(400); 11417 format %{ "cmpl $p, $q\t# cmpLTMask\n\t" 11418 "setcc $dst \t# emits setlt + movzbl or setzul for APX" 11419 "negl $dst" %} 11420 ins_encode %{ 11421 __ cmpl($p$$Register, $q$$Register); 11422 __ setcc(Assembler::less, $dst$$Register); 11423 __ negl($dst$$Register); 11424 %} 11425 ins_pipe(pipe_slow); 11426 %} 11427 11428 instruct cmpLTMask0(rRegI dst, immI_0 zero, rFlagsReg cr) 11429 %{ 11430 match(Set dst (CmpLTMask dst zero)); 11431 effect(KILL cr); 11432 11433 ins_cost(100); 11434 format %{ "sarl $dst, #31\t# cmpLTMask0" %} 11435 ins_encode %{ 11436 __ sarl($dst$$Register, 31); 11437 %} 11438 ins_pipe(ialu_reg); 11439 %} 11440 11441 /* Better to save a register than avoid a branch */ 11442 instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 11443 %{ 11444 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q))); 11445 effect(KILL cr); 11446 ins_cost(300); 11447 format %{ "subl $p,$q\t# cadd_cmpLTMask\n\t" 11448 "jge done\n\t" 11449 "addl $p,$y\n" 11450 "done: " %} 11451 ins_encode %{ 11452 Register Rp = $p$$Register; 11453 Register Rq = $q$$Register; 11454 Register Ry = $y$$Register; 11455 Label done; 11456 __ subl(Rp, Rq); 11457 __ jccb(Assembler::greaterEqual, done); 11458 __ addl(Rp, Ry); 11459 __ bind(done); 11460 %} 11461 ins_pipe(pipe_cmplt); 11462 %} 11463 11464 /* Better to save a register than avoid a branch */ 11465 instruct and_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 11466 %{ 11467 match(Set y (AndI (CmpLTMask p q) y)); 11468 effect(KILL cr); 11469 11470 ins_cost(300); 11471 11472 format %{ "cmpl $p, $q\t# and_cmpLTMask\n\t" 11473 "jlt done\n\t" 11474 "xorl $y, $y\n" 11475 "done: " %} 11476 ins_encode %{ 11477 Register Rp = $p$$Register; 11478 Register Rq = $q$$Register; 11479 Register Ry = $y$$Register; 11480 Label done; 11481 __ cmpl(Rp, Rq); 11482 __ jccb(Assembler::less, done); 11483 __ xorl(Ry, Ry); 11484 __ bind(done); 11485 %} 11486 ins_pipe(pipe_cmplt); 11487 %} 11488 11489 11490 //---------- FP Instructions------------------------------------------------ 11491 11492 // Really expensive, avoid 11493 instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2) 11494 %{ 11495 match(Set cr (CmpF src1 src2)); 11496 11497 ins_cost(500); 11498 format %{ "ucomiss $src1, $src2\n\t" 11499 "jnp,s exit\n\t" 11500 "pushfq\t# saw NaN, set CF\n\t" 11501 "andq [rsp], #0xffffff2b\n\t" 11502 "popfq\n" 11503 "exit:" %} 11504 ins_encode %{ 11505 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 11506 emit_cmpfp_fixup(masm); 11507 %} 11508 ins_pipe(pipe_slow); 11509 %} 11510 11511 instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{ 11512 match(Set cr (CmpF src1 src2)); 11513 11514 ins_cost(100); 11515 format %{ "ucomiss $src1, $src2" %} 11516 ins_encode %{ 11517 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 11518 %} 11519 ins_pipe(pipe_slow); 11520 %} 11521 11522 instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{ 11523 match(Set cr (CmpF src1 (LoadF src2))); 11524 11525 ins_cost(100); 11526 format %{ "ucomiss $src1, $src2" %} 11527 ins_encode %{ 11528 __ ucomiss($src1$$XMMRegister, $src2$$Address); 11529 %} 11530 ins_pipe(pipe_slow); 11531 %} 11532 11533 instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src, immF con) %{ 11534 match(Set cr (CmpF src con)); 11535 ins_cost(100); 11536 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con" %} 11537 ins_encode %{ 11538 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 11539 %} 11540 ins_pipe(pipe_slow); 11541 %} 11542 11543 // Really expensive, avoid 11544 instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2) 11545 %{ 11546 match(Set cr (CmpD src1 src2)); 11547 11548 ins_cost(500); 11549 format %{ "ucomisd $src1, $src2\n\t" 11550 "jnp,s exit\n\t" 11551 "pushfq\t# saw NaN, set CF\n\t" 11552 "andq [rsp], #0xffffff2b\n\t" 11553 "popfq\n" 11554 "exit:" %} 11555 ins_encode %{ 11556 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 11557 emit_cmpfp_fixup(masm); 11558 %} 11559 ins_pipe(pipe_slow); 11560 %} 11561 11562 instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{ 11563 match(Set cr (CmpD src1 src2)); 11564 11565 ins_cost(100); 11566 format %{ "ucomisd $src1, $src2 test" %} 11567 ins_encode %{ 11568 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 11569 %} 11570 ins_pipe(pipe_slow); 11571 %} 11572 11573 instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{ 11574 match(Set cr (CmpD src1 (LoadD src2))); 11575 11576 ins_cost(100); 11577 format %{ "ucomisd $src1, $src2" %} 11578 ins_encode %{ 11579 __ ucomisd($src1$$XMMRegister, $src2$$Address); 11580 %} 11581 ins_pipe(pipe_slow); 11582 %} 11583 11584 instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src, immD con) %{ 11585 match(Set cr (CmpD src con)); 11586 ins_cost(100); 11587 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con" %} 11588 ins_encode %{ 11589 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 11590 %} 11591 ins_pipe(pipe_slow); 11592 %} 11593 11594 // Compare into -1,0,1 11595 instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr) 11596 %{ 11597 match(Set dst (CmpF3 src1 src2)); 11598 effect(KILL cr); 11599 11600 ins_cost(275); 11601 format %{ "ucomiss $src1, $src2\n\t" 11602 "movl $dst, #-1\n\t" 11603 "jp,s done\n\t" 11604 "jb,s done\n\t" 11605 "setne $dst\n\t" 11606 "movzbl $dst, $dst\n" 11607 "done:" %} 11608 ins_encode %{ 11609 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 11610 emit_cmpfp3(masm, $dst$$Register); 11611 %} 11612 ins_pipe(pipe_slow); 11613 %} 11614 11615 // Compare into -1,0,1 11616 instruct cmpF_mem(rRegI dst, regF src1, memory src2, rFlagsReg cr) 11617 %{ 11618 match(Set dst (CmpF3 src1 (LoadF src2))); 11619 effect(KILL cr); 11620 11621 ins_cost(275); 11622 format %{ "ucomiss $src1, $src2\n\t" 11623 "movl $dst, #-1\n\t" 11624 "jp,s done\n\t" 11625 "jb,s done\n\t" 11626 "setne $dst\n\t" 11627 "movzbl $dst, $dst\n" 11628 "done:" %} 11629 ins_encode %{ 11630 __ ucomiss($src1$$XMMRegister, $src2$$Address); 11631 emit_cmpfp3(masm, $dst$$Register); 11632 %} 11633 ins_pipe(pipe_slow); 11634 %} 11635 11636 // Compare into -1,0,1 11637 instruct cmpF_imm(rRegI dst, regF src, immF con, rFlagsReg cr) %{ 11638 match(Set dst (CmpF3 src con)); 11639 effect(KILL cr); 11640 11641 ins_cost(275); 11642 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 11643 "movl $dst, #-1\n\t" 11644 "jp,s done\n\t" 11645 "jb,s done\n\t" 11646 "setne $dst\n\t" 11647 "movzbl $dst, $dst\n" 11648 "done:" %} 11649 ins_encode %{ 11650 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 11651 emit_cmpfp3(masm, $dst$$Register); 11652 %} 11653 ins_pipe(pipe_slow); 11654 %} 11655 11656 // Compare into -1,0,1 11657 instruct cmpD_reg(rRegI dst, regD src1, regD src2, rFlagsReg cr) 11658 %{ 11659 match(Set dst (CmpD3 src1 src2)); 11660 effect(KILL cr); 11661 11662 ins_cost(275); 11663 format %{ "ucomisd $src1, $src2\n\t" 11664 "movl $dst, #-1\n\t" 11665 "jp,s done\n\t" 11666 "jb,s done\n\t" 11667 "setne $dst\n\t" 11668 "movzbl $dst, $dst\n" 11669 "done:" %} 11670 ins_encode %{ 11671 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 11672 emit_cmpfp3(masm, $dst$$Register); 11673 %} 11674 ins_pipe(pipe_slow); 11675 %} 11676 11677 // Compare into -1,0,1 11678 instruct cmpD_mem(rRegI dst, regD src1, memory src2, rFlagsReg cr) 11679 %{ 11680 match(Set dst (CmpD3 src1 (LoadD src2))); 11681 effect(KILL cr); 11682 11683 ins_cost(275); 11684 format %{ "ucomisd $src1, $src2\n\t" 11685 "movl $dst, #-1\n\t" 11686 "jp,s done\n\t" 11687 "jb,s done\n\t" 11688 "setne $dst\n\t" 11689 "movzbl $dst, $dst\n" 11690 "done:" %} 11691 ins_encode %{ 11692 __ ucomisd($src1$$XMMRegister, $src2$$Address); 11693 emit_cmpfp3(masm, $dst$$Register); 11694 %} 11695 ins_pipe(pipe_slow); 11696 %} 11697 11698 // Compare into -1,0,1 11699 instruct cmpD_imm(rRegI dst, regD src, immD con, rFlagsReg cr) %{ 11700 match(Set dst (CmpD3 src con)); 11701 effect(KILL cr); 11702 11703 ins_cost(275); 11704 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 11705 "movl $dst, #-1\n\t" 11706 "jp,s done\n\t" 11707 "jb,s done\n\t" 11708 "setne $dst\n\t" 11709 "movzbl $dst, $dst\n" 11710 "done:" %} 11711 ins_encode %{ 11712 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 11713 emit_cmpfp3(masm, $dst$$Register); 11714 %} 11715 ins_pipe(pipe_slow); 11716 %} 11717 11718 //----------Arithmetic Conversion Instructions--------------------------------- 11719 11720 instruct convF2D_reg_reg(regD dst, regF src) 11721 %{ 11722 match(Set dst (ConvF2D src)); 11723 11724 format %{ "cvtss2sd $dst, $src" %} 11725 ins_encode %{ 11726 __ cvtss2sd ($dst$$XMMRegister, $src$$XMMRegister); 11727 %} 11728 ins_pipe(pipe_slow); // XXX 11729 %} 11730 11731 instruct convF2D_reg_mem(regD dst, memory src) 11732 %{ 11733 predicate(UseAVX == 0); 11734 match(Set dst (ConvF2D (LoadF src))); 11735 11736 format %{ "cvtss2sd $dst, $src" %} 11737 ins_encode %{ 11738 __ cvtss2sd ($dst$$XMMRegister, $src$$Address); 11739 %} 11740 ins_pipe(pipe_slow); // XXX 11741 %} 11742 11743 instruct convD2F_reg_reg(regF dst, regD src) 11744 %{ 11745 match(Set dst (ConvD2F src)); 11746 11747 format %{ "cvtsd2ss $dst, $src" %} 11748 ins_encode %{ 11749 __ cvtsd2ss ($dst$$XMMRegister, $src$$XMMRegister); 11750 %} 11751 ins_pipe(pipe_slow); // XXX 11752 %} 11753 11754 instruct convD2F_reg_mem(regF dst, memory src) 11755 %{ 11756 predicate(UseAVX == 0); 11757 match(Set dst (ConvD2F (LoadD src))); 11758 11759 format %{ "cvtsd2ss $dst, $src" %} 11760 ins_encode %{ 11761 __ cvtsd2ss ($dst$$XMMRegister, $src$$Address); 11762 %} 11763 ins_pipe(pipe_slow); // XXX 11764 %} 11765 11766 // XXX do mem variants 11767 instruct convF2I_reg_reg(rRegI dst, regF src, rFlagsReg cr) 11768 %{ 11769 match(Set dst (ConvF2I src)); 11770 effect(KILL cr); 11771 format %{ "convert_f2i $dst, $src" %} 11772 ins_encode %{ 11773 __ convertF2I(T_INT, T_FLOAT, $dst$$Register, $src$$XMMRegister); 11774 %} 11775 ins_pipe(pipe_slow); 11776 %} 11777 11778 instruct convF2L_reg_reg(rRegL dst, regF src, rFlagsReg cr) 11779 %{ 11780 match(Set dst (ConvF2L src)); 11781 effect(KILL cr); 11782 format %{ "convert_f2l $dst, $src"%} 11783 ins_encode %{ 11784 __ convertF2I(T_LONG, T_FLOAT, $dst$$Register, $src$$XMMRegister); 11785 %} 11786 ins_pipe(pipe_slow); 11787 %} 11788 11789 instruct convD2I_reg_reg(rRegI dst, regD src, rFlagsReg cr) 11790 %{ 11791 match(Set dst (ConvD2I src)); 11792 effect(KILL cr); 11793 format %{ "convert_d2i $dst, $src"%} 11794 ins_encode %{ 11795 __ convertF2I(T_INT, T_DOUBLE, $dst$$Register, $src$$XMMRegister); 11796 %} 11797 ins_pipe(pipe_slow); 11798 %} 11799 11800 instruct convD2L_reg_reg(rRegL dst, regD src, rFlagsReg cr) 11801 %{ 11802 match(Set dst (ConvD2L src)); 11803 effect(KILL cr); 11804 format %{ "convert_d2l $dst, $src"%} 11805 ins_encode %{ 11806 __ convertF2I(T_LONG, T_DOUBLE, $dst$$Register, $src$$XMMRegister); 11807 %} 11808 ins_pipe(pipe_slow); 11809 %} 11810 11811 instruct round_double_reg(rRegL dst, regD src, rRegL rtmp, rcx_RegL rcx, rFlagsReg cr) 11812 %{ 11813 match(Set dst (RoundD src)); 11814 effect(TEMP dst, TEMP rtmp, TEMP rcx, KILL cr); 11815 format %{ "round_double $dst,$src \t! using $rtmp and $rcx as TEMP"%} 11816 ins_encode %{ 11817 __ round_double($dst$$Register, $src$$XMMRegister, $rtmp$$Register, $rcx$$Register); 11818 %} 11819 ins_pipe(pipe_slow); 11820 %} 11821 11822 instruct round_float_reg(rRegI dst, regF src, rRegL rtmp, rcx_RegL rcx, rFlagsReg cr) 11823 %{ 11824 match(Set dst (RoundF src)); 11825 effect(TEMP dst, TEMP rtmp, TEMP rcx, KILL cr); 11826 format %{ "round_float $dst,$src" %} 11827 ins_encode %{ 11828 __ round_float($dst$$Register, $src$$XMMRegister, $rtmp$$Register, $rcx$$Register); 11829 %} 11830 ins_pipe(pipe_slow); 11831 %} 11832 11833 instruct convI2F_reg_reg(vlRegF dst, rRegI src) 11834 %{ 11835 predicate(!UseXmmI2F); 11836 match(Set dst (ConvI2F src)); 11837 11838 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 11839 ins_encode %{ 11840 if (UseAVX > 0) { 11841 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 11842 } 11843 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Register); 11844 %} 11845 ins_pipe(pipe_slow); // XXX 11846 %} 11847 11848 instruct convI2F_reg_mem(regF dst, memory src) 11849 %{ 11850 predicate(UseAVX == 0); 11851 match(Set dst (ConvI2F (LoadI src))); 11852 11853 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 11854 ins_encode %{ 11855 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Address); 11856 %} 11857 ins_pipe(pipe_slow); // XXX 11858 %} 11859 11860 instruct convI2D_reg_reg(vlRegD dst, rRegI src) 11861 %{ 11862 predicate(!UseXmmI2D); 11863 match(Set dst (ConvI2D src)); 11864 11865 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 11866 ins_encode %{ 11867 if (UseAVX > 0) { 11868 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 11869 } 11870 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Register); 11871 %} 11872 ins_pipe(pipe_slow); // XXX 11873 %} 11874 11875 instruct convI2D_reg_mem(regD dst, memory src) 11876 %{ 11877 predicate(UseAVX == 0); 11878 match(Set dst (ConvI2D (LoadI src))); 11879 11880 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 11881 ins_encode %{ 11882 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Address); 11883 %} 11884 ins_pipe(pipe_slow); // XXX 11885 %} 11886 11887 instruct convXI2F_reg(regF dst, rRegI src) 11888 %{ 11889 predicate(UseXmmI2F); 11890 match(Set dst (ConvI2F src)); 11891 11892 format %{ "movdl $dst, $src\n\t" 11893 "cvtdq2psl $dst, $dst\t# i2f" %} 11894 ins_encode %{ 11895 __ movdl($dst$$XMMRegister, $src$$Register); 11896 __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister); 11897 %} 11898 ins_pipe(pipe_slow); // XXX 11899 %} 11900 11901 instruct convXI2D_reg(regD dst, rRegI src) 11902 %{ 11903 predicate(UseXmmI2D); 11904 match(Set dst (ConvI2D src)); 11905 11906 format %{ "movdl $dst, $src\n\t" 11907 "cvtdq2pdl $dst, $dst\t# i2d" %} 11908 ins_encode %{ 11909 __ movdl($dst$$XMMRegister, $src$$Register); 11910 __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister); 11911 %} 11912 ins_pipe(pipe_slow); // XXX 11913 %} 11914 11915 instruct convL2F_reg_reg(vlRegF dst, rRegL src) 11916 %{ 11917 match(Set dst (ConvL2F src)); 11918 11919 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 11920 ins_encode %{ 11921 if (UseAVX > 0) { 11922 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 11923 } 11924 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Register); 11925 %} 11926 ins_pipe(pipe_slow); // XXX 11927 %} 11928 11929 instruct convL2F_reg_mem(regF dst, memory src) 11930 %{ 11931 predicate(UseAVX == 0); 11932 match(Set dst (ConvL2F (LoadL src))); 11933 11934 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 11935 ins_encode %{ 11936 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Address); 11937 %} 11938 ins_pipe(pipe_slow); // XXX 11939 %} 11940 11941 instruct convL2D_reg_reg(vlRegD dst, rRegL src) 11942 %{ 11943 match(Set dst (ConvL2D src)); 11944 11945 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 11946 ins_encode %{ 11947 if (UseAVX > 0) { 11948 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 11949 } 11950 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Register); 11951 %} 11952 ins_pipe(pipe_slow); // XXX 11953 %} 11954 11955 instruct convL2D_reg_mem(regD dst, memory src) 11956 %{ 11957 predicate(UseAVX == 0); 11958 match(Set dst (ConvL2D (LoadL src))); 11959 11960 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 11961 ins_encode %{ 11962 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Address); 11963 %} 11964 ins_pipe(pipe_slow); // XXX 11965 %} 11966 11967 instruct convI2L_reg_reg(rRegL dst, rRegI src) 11968 %{ 11969 match(Set dst (ConvI2L src)); 11970 11971 ins_cost(125); 11972 format %{ "movslq $dst, $src\t# i2l" %} 11973 ins_encode %{ 11974 __ movslq($dst$$Register, $src$$Register); 11975 %} 11976 ins_pipe(ialu_reg_reg); 11977 %} 11978 11979 // Zero-extend convert int to long 11980 instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask) 11981 %{ 11982 match(Set dst (AndL (ConvI2L src) mask)); 11983 11984 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 11985 ins_encode %{ 11986 if ($dst$$reg != $src$$reg) { 11987 __ movl($dst$$Register, $src$$Register); 11988 } 11989 %} 11990 ins_pipe(ialu_reg_reg); 11991 %} 11992 11993 // Zero-extend convert int to long 11994 instruct convI2L_reg_mem_zex(rRegL dst, memory src, immL_32bits mask) 11995 %{ 11996 match(Set dst (AndL (ConvI2L (LoadI src)) mask)); 11997 11998 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 11999 ins_encode %{ 12000 __ movl($dst$$Register, $src$$Address); 12001 %} 12002 ins_pipe(ialu_reg_mem); 12003 %} 12004 12005 instruct zerox_long_reg_reg(rRegL dst, rRegL src, immL_32bits mask) 12006 %{ 12007 match(Set dst (AndL src mask)); 12008 12009 format %{ "movl $dst, $src\t# zero-extend long" %} 12010 ins_encode %{ 12011 __ movl($dst$$Register, $src$$Register); 12012 %} 12013 ins_pipe(ialu_reg_reg); 12014 %} 12015 12016 instruct convL2I_reg_reg(rRegI dst, rRegL src) 12017 %{ 12018 match(Set dst (ConvL2I src)); 12019 12020 format %{ "movl $dst, $src\t# l2i" %} 12021 ins_encode %{ 12022 __ movl($dst$$Register, $src$$Register); 12023 %} 12024 ins_pipe(ialu_reg_reg); 12025 %} 12026 12027 12028 instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{ 12029 match(Set dst (MoveF2I src)); 12030 effect(DEF dst, USE src); 12031 12032 ins_cost(125); 12033 format %{ "movl $dst, $src\t# MoveF2I_stack_reg" %} 12034 ins_encode %{ 12035 __ movl($dst$$Register, Address(rsp, $src$$disp)); 12036 %} 12037 ins_pipe(ialu_reg_mem); 12038 %} 12039 12040 instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{ 12041 match(Set dst (MoveI2F src)); 12042 effect(DEF dst, USE src); 12043 12044 ins_cost(125); 12045 format %{ "movss $dst, $src\t# MoveI2F_stack_reg" %} 12046 ins_encode %{ 12047 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 12048 %} 12049 ins_pipe(pipe_slow); 12050 %} 12051 12052 instruct MoveD2L_stack_reg(rRegL dst, stackSlotD src) %{ 12053 match(Set dst (MoveD2L src)); 12054 effect(DEF dst, USE src); 12055 12056 ins_cost(125); 12057 format %{ "movq $dst, $src\t# MoveD2L_stack_reg" %} 12058 ins_encode %{ 12059 __ movq($dst$$Register, Address(rsp, $src$$disp)); 12060 %} 12061 ins_pipe(ialu_reg_mem); 12062 %} 12063 12064 instruct MoveL2D_stack_reg_partial(regD dst, stackSlotL src) %{ 12065 predicate(!UseXmmLoadAndClearUpper); 12066 match(Set dst (MoveL2D src)); 12067 effect(DEF dst, USE src); 12068 12069 ins_cost(125); 12070 format %{ "movlpd $dst, $src\t# MoveL2D_stack_reg" %} 12071 ins_encode %{ 12072 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 12073 %} 12074 ins_pipe(pipe_slow); 12075 %} 12076 12077 instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{ 12078 predicate(UseXmmLoadAndClearUpper); 12079 match(Set dst (MoveL2D src)); 12080 effect(DEF dst, USE src); 12081 12082 ins_cost(125); 12083 format %{ "movsd $dst, $src\t# MoveL2D_stack_reg" %} 12084 ins_encode %{ 12085 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 12086 %} 12087 ins_pipe(pipe_slow); 12088 %} 12089 12090 12091 instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{ 12092 match(Set dst (MoveF2I src)); 12093 effect(DEF dst, USE src); 12094 12095 ins_cost(95); // XXX 12096 format %{ "movss $dst, $src\t# MoveF2I_reg_stack" %} 12097 ins_encode %{ 12098 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 12099 %} 12100 ins_pipe(pipe_slow); 12101 %} 12102 12103 instruct MoveI2F_reg_stack(stackSlotF dst, rRegI src) %{ 12104 match(Set dst (MoveI2F src)); 12105 effect(DEF dst, USE src); 12106 12107 ins_cost(100); 12108 format %{ "movl $dst, $src\t# MoveI2F_reg_stack" %} 12109 ins_encode %{ 12110 __ movl(Address(rsp, $dst$$disp), $src$$Register); 12111 %} 12112 ins_pipe( ialu_mem_reg ); 12113 %} 12114 12115 instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{ 12116 match(Set dst (MoveD2L src)); 12117 effect(DEF dst, USE src); 12118 12119 ins_cost(95); // XXX 12120 format %{ "movsd $dst, $src\t# MoveL2D_reg_stack" %} 12121 ins_encode %{ 12122 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 12123 %} 12124 ins_pipe(pipe_slow); 12125 %} 12126 12127 instruct MoveL2D_reg_stack(stackSlotD dst, rRegL src) %{ 12128 match(Set dst (MoveL2D src)); 12129 effect(DEF dst, USE src); 12130 12131 ins_cost(100); 12132 format %{ "movq $dst, $src\t# MoveL2D_reg_stack" %} 12133 ins_encode %{ 12134 __ movq(Address(rsp, $dst$$disp), $src$$Register); 12135 %} 12136 ins_pipe(ialu_mem_reg); 12137 %} 12138 12139 instruct MoveF2I_reg_reg(rRegI dst, regF src) %{ 12140 match(Set dst (MoveF2I src)); 12141 effect(DEF dst, USE src); 12142 ins_cost(85); 12143 format %{ "movd $dst,$src\t# MoveF2I" %} 12144 ins_encode %{ 12145 __ movdl($dst$$Register, $src$$XMMRegister); 12146 %} 12147 ins_pipe( pipe_slow ); 12148 %} 12149 12150 instruct MoveD2L_reg_reg(rRegL dst, regD src) %{ 12151 match(Set dst (MoveD2L src)); 12152 effect(DEF dst, USE src); 12153 ins_cost(85); 12154 format %{ "movd $dst,$src\t# MoveD2L" %} 12155 ins_encode %{ 12156 __ movdq($dst$$Register, $src$$XMMRegister); 12157 %} 12158 ins_pipe( pipe_slow ); 12159 %} 12160 12161 instruct MoveI2F_reg_reg(regF dst, rRegI src) %{ 12162 match(Set dst (MoveI2F src)); 12163 effect(DEF dst, USE src); 12164 ins_cost(100); 12165 format %{ "movd $dst,$src\t# MoveI2F" %} 12166 ins_encode %{ 12167 __ movdl($dst$$XMMRegister, $src$$Register); 12168 %} 12169 ins_pipe( pipe_slow ); 12170 %} 12171 12172 instruct MoveL2D_reg_reg(regD dst, rRegL src) %{ 12173 match(Set dst (MoveL2D src)); 12174 effect(DEF dst, USE src); 12175 ins_cost(100); 12176 format %{ "movd $dst,$src\t# MoveL2D" %} 12177 ins_encode %{ 12178 __ movdq($dst$$XMMRegister, $src$$Register); 12179 %} 12180 ins_pipe( pipe_slow ); 12181 %} 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_RegL val, 12187 Universe dummy, rFlagsReg cr) 12188 %{ 12189 predicate(!((ClearArrayNode*)n)->is_large() && !((ClearArrayNode*)n)->word_copy_only() && (UseAVX <= 2)); 12190 match(Set dummy (ClearArray (Binary cnt base) val)); 12191 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, USE_KILL val, KILL cr); 12192 12193 format %{ $$template 12194 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 12195 $$emit$$"jg LARGE\n\t" 12196 $$emit$$"dec rcx\n\t" 12197 $$emit$$"js DONE\t# Zero length\n\t" 12198 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 12199 $$emit$$"dec rcx\n\t" 12200 $$emit$$"jge LOOP\n\t" 12201 $$emit$$"jmp DONE\n\t" 12202 $$emit$$"# LARGE:\n\t" 12203 if (UseFastStosb) { 12204 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 12205 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--\n\t" 12206 } else if (UseXMMForObjInit) { 12207 $$emit$$"movdq $tmp, $val\n\t" 12208 $$emit$$"punpcklqdq $tmp, $tmp\n\t" 12209 $$emit$$"vinserti128_high $tmp, $tmp\n\t" 12210 $$emit$$"jmpq L_zero_64_bytes\n\t" 12211 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 12212 $$emit$$"vmovdqu $tmp,(rax)\n\t" 12213 $$emit$$"vmovdqu $tmp,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 $tmp,(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, $val$$Register, 12240 $tmp$$XMMRegister, false, false); 12241 %} 12242 ins_pipe(pipe_slow); 12243 %} 12244 12245 instruct rep_stos_word_copy(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegL val, 12246 Universe dummy, rFlagsReg cr) 12247 %{ 12248 predicate(!((ClearArrayNode*)n)->is_large() && ((ClearArrayNode*)n)->word_copy_only() && (UseAVX <= 2)); 12249 match(Set dummy (ClearArray (Binary cnt base) val)); 12250 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, USE_KILL val, KILL cr); 12251 12252 format %{ $$template 12253 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 12254 $$emit$$"jg LARGE\n\t" 12255 $$emit$$"dec rcx\n\t" 12256 $$emit$$"js DONE\t# Zero length\n\t" 12257 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 12258 $$emit$$"dec rcx\n\t" 12259 $$emit$$"jge LOOP\n\t" 12260 $$emit$$"jmp DONE\n\t" 12261 $$emit$$"# LARGE:\n\t" 12262 if (UseXMMForObjInit) { 12263 $$emit$$"movdq $tmp, $val\n\t" 12264 $$emit$$"punpcklqdq $tmp, $tmp\n\t" 12265 $$emit$$"vinserti128_high $tmp, $tmp\n\t" 12266 $$emit$$"jmpq L_zero_64_bytes\n\t" 12267 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 12268 $$emit$$"vmovdqu $tmp,(rax)\n\t" 12269 $$emit$$"vmovdqu $tmp,0x20(rax)\n\t" 12270 $$emit$$"add 0x40,rax\n\t" 12271 $$emit$$"# L_zero_64_bytes:\n\t" 12272 $$emit$$"sub 0x8,rcx\n\t" 12273 $$emit$$"jge L_loop\n\t" 12274 $$emit$$"add 0x4,rcx\n\t" 12275 $$emit$$"jl L_tail\n\t" 12276 $$emit$$"vmovdqu $tmp,(rax)\n\t" 12277 $$emit$$"add 0x20,rax\n\t" 12278 $$emit$$"sub 0x4,rcx\n\t" 12279 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 12280 $$emit$$"add 0x4,rcx\n\t" 12281 $$emit$$"jle L_end\n\t" 12282 $$emit$$"dec rcx\n\t" 12283 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 12284 $$emit$$"vmovq xmm0,(rax)\n\t" 12285 $$emit$$"add 0x8,rax\n\t" 12286 $$emit$$"dec rcx\n\t" 12287 $$emit$$"jge L_sloop\n\t" 12288 $$emit$$"# L_end:\n\t" 12289 } else { 12290 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 12291 } 12292 $$emit$$"# DONE" 12293 %} 12294 ins_encode %{ 12295 __ clear_mem($base$$Register, $cnt$$Register, $val$$Register, 12296 $tmp$$XMMRegister, false, true); 12297 %} 12298 ins_pipe(pipe_slow); 12299 %} 12300 12301 // Small non-constant length ClearArray for AVX512 targets. 12302 instruct rep_stos_evex(rcx_RegL cnt, rdi_RegP base, legRegD tmp, kReg ktmp, rax_RegL val, 12303 Universe dummy, rFlagsReg cr) 12304 %{ 12305 predicate(!((ClearArrayNode*)n)->is_large() && !((ClearArrayNode*)n)->word_copy_only() && (UseAVX > 2)); 12306 match(Set dummy (ClearArray (Binary cnt base) val)); 12307 ins_cost(125); 12308 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, TEMP ktmp, USE_KILL val, KILL cr); 12309 12310 format %{ $$template 12311 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 12312 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 12313 $$emit$$"jg LARGE\n\t" 12314 $$emit$$"dec rcx\n\t" 12315 $$emit$$"js DONE\t# Zero length\n\t" 12316 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 12317 $$emit$$"dec rcx\n\t" 12318 $$emit$$"jge LOOP\n\t" 12319 $$emit$$"jmp DONE\n\t" 12320 $$emit$$"# LARGE:\n\t" 12321 if (UseFastStosb) { 12322 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 12323 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--\n\t" 12324 } else if (UseXMMForObjInit) { 12325 $$emit$$"mov rdi,rax\n\t" 12326 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 12327 $$emit$$"jmpq L_zero_64_bytes\n\t" 12328 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 12329 $$emit$$"vmovdqu ymm0,(rax)\n\t" 12330 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 12331 $$emit$$"add 0x40,rax\n\t" 12332 $$emit$$"# L_zero_64_bytes:\n\t" 12333 $$emit$$"sub 0x8,rcx\n\t" 12334 $$emit$$"jge L_loop\n\t" 12335 $$emit$$"add 0x4,rcx\n\t" 12336 $$emit$$"jl L_tail\n\t" 12337 $$emit$$"vmovdqu ymm0,(rax)\n\t" 12338 $$emit$$"add 0x20,rax\n\t" 12339 $$emit$$"sub 0x4,rcx\n\t" 12340 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 12341 $$emit$$"add 0x4,rcx\n\t" 12342 $$emit$$"jle L_end\n\t" 12343 $$emit$$"dec rcx\n\t" 12344 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 12345 $$emit$$"vmovq xmm0,(rax)\n\t" 12346 $$emit$$"add 0x8,rax\n\t" 12347 $$emit$$"dec rcx\n\t" 12348 $$emit$$"jge L_sloop\n\t" 12349 $$emit$$"# L_end:\n\t" 12350 } else { 12351 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 12352 } 12353 $$emit$$"# DONE" 12354 %} 12355 ins_encode %{ 12356 __ clear_mem($base$$Register, $cnt$$Register, $val$$Register, 12357 $tmp$$XMMRegister, false, false, $ktmp$$KRegister); 12358 %} 12359 ins_pipe(pipe_slow); 12360 %} 12361 12362 instruct rep_stos_evex_word_copy(rcx_RegL cnt, rdi_RegP base, legRegD tmp, kReg ktmp, rax_RegL val, 12363 Universe dummy, rFlagsReg cr) 12364 %{ 12365 predicate(!((ClearArrayNode*)n)->is_large() && ((ClearArrayNode*)n)->word_copy_only() && (UseAVX > 2)); 12366 match(Set dummy (ClearArray (Binary cnt base) val)); 12367 ins_cost(125); 12368 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, TEMP ktmp, USE_KILL val, KILL cr); 12369 12370 format %{ $$template 12371 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 12372 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 12373 $$emit$$"jg LARGE\n\t" 12374 $$emit$$"dec rcx\n\t" 12375 $$emit$$"js DONE\t# Zero length\n\t" 12376 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 12377 $$emit$$"dec rcx\n\t" 12378 $$emit$$"jge LOOP\n\t" 12379 $$emit$$"jmp DONE\n\t" 12380 $$emit$$"# LARGE:\n\t" 12381 if (UseFastStosb) { 12382 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 12383 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--\n\t" 12384 } else if (UseXMMForObjInit) { 12385 $$emit$$"mov rdi,rax\n\t" 12386 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 12387 $$emit$$"jmpq L_zero_64_bytes\n\t" 12388 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 12389 $$emit$$"vmovdqu ymm0,(rax)\n\t" 12390 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 12391 $$emit$$"add 0x40,rax\n\t" 12392 $$emit$$"# L_zero_64_bytes:\n\t" 12393 $$emit$$"sub 0x8,rcx\n\t" 12394 $$emit$$"jge L_loop\n\t" 12395 $$emit$$"add 0x4,rcx\n\t" 12396 $$emit$$"jl L_tail\n\t" 12397 $$emit$$"vmovdqu ymm0,(rax)\n\t" 12398 $$emit$$"add 0x20,rax\n\t" 12399 $$emit$$"sub 0x4,rcx\n\t" 12400 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 12401 $$emit$$"add 0x4,rcx\n\t" 12402 $$emit$$"jle L_end\n\t" 12403 $$emit$$"dec rcx\n\t" 12404 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 12405 $$emit$$"vmovq xmm0,(rax)\n\t" 12406 $$emit$$"add 0x8,rax\n\t" 12407 $$emit$$"dec rcx\n\t" 12408 $$emit$$"jge L_sloop\n\t" 12409 $$emit$$"# L_end:\n\t" 12410 } else { 12411 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 12412 } 12413 $$emit$$"# DONE" 12414 %} 12415 ins_encode %{ 12416 __ clear_mem($base$$Register, $cnt$$Register, $val$$Register, 12417 $tmp$$XMMRegister, false, true, $ktmp$$KRegister); 12418 %} 12419 ins_pipe(pipe_slow); 12420 %} 12421 12422 // Large non-constant length ClearArray for non-AVX512 targets. 12423 instruct rep_stos_large(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegL val, 12424 Universe dummy, rFlagsReg cr) 12425 %{ 12426 predicate(((ClearArrayNode*)n)->is_large() && !((ClearArrayNode*)n)->word_copy_only() && (UseAVX <= 2)); 12427 match(Set dummy (ClearArray (Binary cnt base) val)); 12428 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, USE_KILL val, KILL cr); 12429 12430 format %{ $$template 12431 if (UseFastStosb) { 12432 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 12433 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--" 12434 } else if (UseXMMForObjInit) { 12435 $$emit$$"movdq $tmp, $val\n\t" 12436 $$emit$$"punpcklqdq $tmp, $tmp\n\t" 12437 $$emit$$"vinserti128_high $tmp, $tmp\n\t" 12438 $$emit$$"jmpq L_zero_64_bytes\n\t" 12439 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 12440 $$emit$$"vmovdqu $tmp,(rax)\n\t" 12441 $$emit$$"vmovdqu $tmp,0x20(rax)\n\t" 12442 $$emit$$"add 0x40,rax\n\t" 12443 $$emit$$"# L_zero_64_bytes:\n\t" 12444 $$emit$$"sub 0x8,rcx\n\t" 12445 $$emit$$"jge L_loop\n\t" 12446 $$emit$$"add 0x4,rcx\n\t" 12447 $$emit$$"jl L_tail\n\t" 12448 $$emit$$"vmovdqu $tmp,(rax)\n\t" 12449 $$emit$$"add 0x20,rax\n\t" 12450 $$emit$$"sub 0x4,rcx\n\t" 12451 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 12452 $$emit$$"add 0x4,rcx\n\t" 12453 $$emit$$"jle L_end\n\t" 12454 $$emit$$"dec rcx\n\t" 12455 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 12456 $$emit$$"vmovq xmm0,(rax)\n\t" 12457 $$emit$$"add 0x8,rax\n\t" 12458 $$emit$$"dec rcx\n\t" 12459 $$emit$$"jge L_sloop\n\t" 12460 $$emit$$"# L_end:\n\t" 12461 } else { 12462 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 12463 } 12464 %} 12465 ins_encode %{ 12466 __ clear_mem($base$$Register, $cnt$$Register, $val$$Register, 12467 $tmp$$XMMRegister, true, false); 12468 %} 12469 ins_pipe(pipe_slow); 12470 %} 12471 12472 instruct rep_stos_large_word_copy(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegL val, 12473 Universe dummy, rFlagsReg cr) 12474 %{ 12475 predicate(((ClearArrayNode*)n)->is_large() && ((ClearArrayNode*)n)->word_copy_only() && (UseAVX <= 2)); 12476 match(Set dummy (ClearArray (Binary cnt base) val)); 12477 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, USE_KILL val, KILL cr); 12478 12479 format %{ $$template 12480 if (UseXMMForObjInit) { 12481 $$emit$$"movdq $tmp, $val\n\t" 12482 $$emit$$"punpcklqdq $tmp, $tmp\n\t" 12483 $$emit$$"vinserti128_high $tmp, $tmp\n\t" 12484 $$emit$$"jmpq L_zero_64_bytes\n\t" 12485 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 12486 $$emit$$"vmovdqu $tmp,(rax)\n\t" 12487 $$emit$$"vmovdqu $tmp,0x20(rax)\n\t" 12488 $$emit$$"add 0x40,rax\n\t" 12489 $$emit$$"# L_zero_64_bytes:\n\t" 12490 $$emit$$"sub 0x8,rcx\n\t" 12491 $$emit$$"jge L_loop\n\t" 12492 $$emit$$"add 0x4,rcx\n\t" 12493 $$emit$$"jl L_tail\n\t" 12494 $$emit$$"vmovdqu $tmp,(rax)\n\t" 12495 $$emit$$"add 0x20,rax\n\t" 12496 $$emit$$"sub 0x4,rcx\n\t" 12497 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 12498 $$emit$$"add 0x4,rcx\n\t" 12499 $$emit$$"jle L_end\n\t" 12500 $$emit$$"dec rcx\n\t" 12501 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 12502 $$emit$$"vmovq xmm0,(rax)\n\t" 12503 $$emit$$"add 0x8,rax\n\t" 12504 $$emit$$"dec rcx\n\t" 12505 $$emit$$"jge L_sloop\n\t" 12506 $$emit$$"# L_end:\n\t" 12507 } else { 12508 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 12509 } 12510 %} 12511 ins_encode %{ 12512 __ clear_mem($base$$Register, $cnt$$Register, $val$$Register, 12513 $tmp$$XMMRegister, true, true); 12514 %} 12515 ins_pipe(pipe_slow); 12516 %} 12517 12518 // Large non-constant length ClearArray for AVX512 targets. 12519 instruct rep_stos_large_evex(rcx_RegL cnt, rdi_RegP base, legRegD tmp, kReg ktmp, rax_RegL val, 12520 Universe dummy, rFlagsReg cr) 12521 %{ 12522 predicate(((ClearArrayNode*)n)->is_large() && !((ClearArrayNode*)n)->word_copy_only() && (UseAVX > 2)); 12523 match(Set dummy (ClearArray (Binary cnt base) val)); 12524 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, TEMP ktmp, USE_KILL val, KILL cr); 12525 12526 format %{ $$template 12527 if (UseFastStosb) { 12528 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 12529 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 12530 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--" 12531 } else if (UseXMMForObjInit) { 12532 $$emit$$"mov rdi,rax\t# ClearArray:\n\t" 12533 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 12534 $$emit$$"jmpq L_zero_64_bytes\n\t" 12535 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 12536 $$emit$$"vmovdqu ymm0,(rax)\n\t" 12537 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 12538 $$emit$$"add 0x40,rax\n\t" 12539 $$emit$$"# L_zero_64_bytes:\n\t" 12540 $$emit$$"sub 0x8,rcx\n\t" 12541 $$emit$$"jge L_loop\n\t" 12542 $$emit$$"add 0x4,rcx\n\t" 12543 $$emit$$"jl L_tail\n\t" 12544 $$emit$$"vmovdqu ymm0,(rax)\n\t" 12545 $$emit$$"add 0x20,rax\n\t" 12546 $$emit$$"sub 0x4,rcx\n\t" 12547 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 12548 $$emit$$"add 0x4,rcx\n\t" 12549 $$emit$$"jle L_end\n\t" 12550 $$emit$$"dec rcx\n\t" 12551 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 12552 $$emit$$"vmovq xmm0,(rax)\n\t" 12553 $$emit$$"add 0x8,rax\n\t" 12554 $$emit$$"dec rcx\n\t" 12555 $$emit$$"jge L_sloop\n\t" 12556 $$emit$$"# L_end:\n\t" 12557 } else { 12558 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 12559 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 12560 } 12561 %} 12562 ins_encode %{ 12563 __ clear_mem($base$$Register, $cnt$$Register, $val$$Register, 12564 $tmp$$XMMRegister, true, false, $ktmp$$KRegister); 12565 %} 12566 ins_pipe(pipe_slow); 12567 %} 12568 12569 instruct rep_stos_large_evex_word_copy(rcx_RegL cnt, rdi_RegP base, legRegD tmp, kReg ktmp, rax_RegL val, 12570 Universe dummy, rFlagsReg cr) 12571 %{ 12572 predicate(((ClearArrayNode*)n)->is_large() && ((ClearArrayNode*)n)->word_copy_only() && (UseAVX > 2)); 12573 match(Set dummy (ClearArray (Binary cnt base) val)); 12574 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, TEMP ktmp, USE_KILL val, KILL cr); 12575 12576 format %{ $$template 12577 if (UseFastStosb) { 12578 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 12579 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 12580 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--" 12581 } else if (UseXMMForObjInit) { 12582 $$emit$$"mov rdi,rax\t# ClearArray:\n\t" 12583 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 12584 $$emit$$"jmpq L_zero_64_bytes\n\t" 12585 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 12586 $$emit$$"vmovdqu ymm0,(rax)\n\t" 12587 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 12588 $$emit$$"add 0x40,rax\n\t" 12589 $$emit$$"# L_zero_64_bytes:\n\t" 12590 $$emit$$"sub 0x8,rcx\n\t" 12591 $$emit$$"jge L_loop\n\t" 12592 $$emit$$"add 0x4,rcx\n\t" 12593 $$emit$$"jl L_tail\n\t" 12594 $$emit$$"vmovdqu ymm0,(rax)\n\t" 12595 $$emit$$"add 0x20,rax\n\t" 12596 $$emit$$"sub 0x4,rcx\n\t" 12597 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 12598 $$emit$$"add 0x4,rcx\n\t" 12599 $$emit$$"jle L_end\n\t" 12600 $$emit$$"dec rcx\n\t" 12601 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 12602 $$emit$$"vmovq xmm0,(rax)\n\t" 12603 $$emit$$"add 0x8,rax\n\t" 12604 $$emit$$"dec rcx\n\t" 12605 $$emit$$"jge L_sloop\n\t" 12606 $$emit$$"# L_end:\n\t" 12607 } else { 12608 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 12609 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 12610 } 12611 %} 12612 ins_encode %{ 12613 __ clear_mem($base$$Register, $cnt$$Register, $val$$Register, 12614 $tmp$$XMMRegister, true, true, $ktmp$$KRegister); 12615 %} 12616 ins_pipe(pipe_slow); 12617 %} 12618 12619 // Small constant length ClearArray for AVX512 targets. 12620 instruct rep_stos_im(immL cnt, rRegP base, regD tmp, rax_RegL val, kReg ktmp, Universe dummy, rFlagsReg cr) 12621 %{ 12622 predicate(!((ClearArrayNode*)n)->is_large() && !((ClearArrayNode*)n)->word_copy_only() && 12623 ((MaxVectorSize >= 32) && VM_Version::supports_avx512vl())); 12624 match(Set dummy (ClearArray (Binary cnt base) val)); 12625 ins_cost(100); 12626 effect(TEMP tmp, USE_KILL val, TEMP ktmp, KILL cr); 12627 format %{ "clear_mem_imm $base , $cnt \n\t" %} 12628 ins_encode %{ 12629 __ clear_mem($base$$Register, $cnt$$constant, $val$$Register, $tmp$$XMMRegister, $ktmp$$KRegister); 12630 %} 12631 ins_pipe(pipe_slow); 12632 %} 12633 12634 instruct string_compareL(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 12635 rax_RegI result, legRegD tmp1, rFlagsReg cr) 12636 %{ 12637 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 12638 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12639 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 12640 12641 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 12642 ins_encode %{ 12643 __ string_compare($str1$$Register, $str2$$Register, 12644 $cnt1$$Register, $cnt2$$Register, $result$$Register, 12645 $tmp1$$XMMRegister, StrIntrinsicNode::LL, knoreg); 12646 %} 12647 ins_pipe( pipe_slow ); 12648 %} 12649 12650 instruct string_compareL_evex(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 12651 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 12652 %{ 12653 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 12654 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12655 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 12656 12657 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 12658 ins_encode %{ 12659 __ string_compare($str1$$Register, $str2$$Register, 12660 $cnt1$$Register, $cnt2$$Register, $result$$Register, 12661 $tmp1$$XMMRegister, StrIntrinsicNode::LL, $ktmp$$KRegister); 12662 %} 12663 ins_pipe( pipe_slow ); 12664 %} 12665 12666 instruct string_compareU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 12667 rax_RegI result, legRegD tmp1, rFlagsReg cr) 12668 %{ 12669 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 12670 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12671 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 12672 12673 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 12674 ins_encode %{ 12675 __ string_compare($str1$$Register, $str2$$Register, 12676 $cnt1$$Register, $cnt2$$Register, $result$$Register, 12677 $tmp1$$XMMRegister, StrIntrinsicNode::UU, knoreg); 12678 %} 12679 ins_pipe( pipe_slow ); 12680 %} 12681 12682 instruct string_compareU_evex(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 12683 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 12684 %{ 12685 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 12686 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12687 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 12688 12689 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 12690 ins_encode %{ 12691 __ string_compare($str1$$Register, $str2$$Register, 12692 $cnt1$$Register, $cnt2$$Register, $result$$Register, 12693 $tmp1$$XMMRegister, StrIntrinsicNode::UU, $ktmp$$KRegister); 12694 %} 12695 ins_pipe( pipe_slow ); 12696 %} 12697 12698 instruct string_compareLU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 12699 rax_RegI result, legRegD tmp1, rFlagsReg cr) 12700 %{ 12701 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 12702 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12703 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 12704 12705 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 12706 ins_encode %{ 12707 __ string_compare($str1$$Register, $str2$$Register, 12708 $cnt1$$Register, $cnt2$$Register, $result$$Register, 12709 $tmp1$$XMMRegister, StrIntrinsicNode::LU, knoreg); 12710 %} 12711 ins_pipe( pipe_slow ); 12712 %} 12713 12714 instruct string_compareLU_evex(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 12715 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 12716 %{ 12717 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 12718 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12719 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 12720 12721 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 12722 ins_encode %{ 12723 __ string_compare($str1$$Register, $str2$$Register, 12724 $cnt1$$Register, $cnt2$$Register, $result$$Register, 12725 $tmp1$$XMMRegister, StrIntrinsicNode::LU, $ktmp$$KRegister); 12726 %} 12727 ins_pipe( pipe_slow ); 12728 %} 12729 12730 instruct string_compareUL(rsi_RegP str1, rdx_RegI cnt1, rdi_RegP str2, rcx_RegI cnt2, 12731 rax_RegI result, legRegD tmp1, rFlagsReg cr) 12732 %{ 12733 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 12734 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12735 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 12736 12737 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 12738 ins_encode %{ 12739 __ string_compare($str2$$Register, $str1$$Register, 12740 $cnt2$$Register, $cnt1$$Register, $result$$Register, 12741 $tmp1$$XMMRegister, StrIntrinsicNode::UL, knoreg); 12742 %} 12743 ins_pipe( pipe_slow ); 12744 %} 12745 12746 instruct string_compareUL_evex(rsi_RegP str1, rdx_RegI cnt1, rdi_RegP str2, rcx_RegI cnt2, 12747 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 12748 %{ 12749 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 12750 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12751 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 12752 12753 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 12754 ins_encode %{ 12755 __ string_compare($str2$$Register, $str1$$Register, 12756 $cnt2$$Register, $cnt1$$Register, $result$$Register, 12757 $tmp1$$XMMRegister, StrIntrinsicNode::UL, $ktmp$$KRegister); 12758 %} 12759 ins_pipe( pipe_slow ); 12760 %} 12761 12762 // fast search of substring with known size. 12763 instruct string_indexof_conL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 12764 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 12765 %{ 12766 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 12767 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 12768 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 12769 12770 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %} 12771 ins_encode %{ 12772 int icnt2 = (int)$int_cnt2$$constant; 12773 if (icnt2 >= 16) { 12774 // IndexOf for constant substrings with size >= 16 elements 12775 // which don't need to be loaded through stack. 12776 __ string_indexofC8($str1$$Register, $str2$$Register, 12777 $cnt1$$Register, $cnt2$$Register, 12778 icnt2, $result$$Register, 12779 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 12780 } else { 12781 // Small strings are loaded through stack if they cross page boundary. 12782 __ string_indexof($str1$$Register, $str2$$Register, 12783 $cnt1$$Register, $cnt2$$Register, 12784 icnt2, $result$$Register, 12785 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 12786 } 12787 %} 12788 ins_pipe( pipe_slow ); 12789 %} 12790 12791 // fast search of substring with known size. 12792 instruct string_indexof_conU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 12793 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 12794 %{ 12795 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 12796 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 12797 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 12798 12799 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %} 12800 ins_encode %{ 12801 int icnt2 = (int)$int_cnt2$$constant; 12802 if (icnt2 >= 8) { 12803 // IndexOf for constant substrings with size >= 8 elements 12804 // which don't need to be loaded through stack. 12805 __ string_indexofC8($str1$$Register, $str2$$Register, 12806 $cnt1$$Register, $cnt2$$Register, 12807 icnt2, $result$$Register, 12808 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 12809 } else { 12810 // Small strings are loaded through stack if they cross page boundary. 12811 __ string_indexof($str1$$Register, $str2$$Register, 12812 $cnt1$$Register, $cnt2$$Register, 12813 icnt2, $result$$Register, 12814 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 12815 } 12816 %} 12817 ins_pipe( pipe_slow ); 12818 %} 12819 12820 // fast search of substring with known size. 12821 instruct string_indexof_conUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 12822 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 12823 %{ 12824 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 12825 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 12826 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 12827 12828 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %} 12829 ins_encode %{ 12830 int icnt2 = (int)$int_cnt2$$constant; 12831 if (icnt2 >= 8) { 12832 // IndexOf for constant substrings with size >= 8 elements 12833 // which don't need to be loaded through stack. 12834 __ string_indexofC8($str1$$Register, $str2$$Register, 12835 $cnt1$$Register, $cnt2$$Register, 12836 icnt2, $result$$Register, 12837 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 12838 } else { 12839 // Small strings are loaded through stack if they cross page boundary. 12840 __ string_indexof($str1$$Register, $str2$$Register, 12841 $cnt1$$Register, $cnt2$$Register, 12842 icnt2, $result$$Register, 12843 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 12844 } 12845 %} 12846 ins_pipe( pipe_slow ); 12847 %} 12848 12849 instruct string_indexofL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 12850 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr) 12851 %{ 12852 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 12853 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 12854 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 12855 12856 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 12857 ins_encode %{ 12858 __ string_indexof($str1$$Register, $str2$$Register, 12859 $cnt1$$Register, $cnt2$$Register, 12860 (-1), $result$$Register, 12861 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 12862 %} 12863 ins_pipe( pipe_slow ); 12864 %} 12865 12866 instruct string_indexofU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 12867 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr) 12868 %{ 12869 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 12870 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 12871 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 12872 12873 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 12874 ins_encode %{ 12875 __ string_indexof($str1$$Register, $str2$$Register, 12876 $cnt1$$Register, $cnt2$$Register, 12877 (-1), $result$$Register, 12878 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 12879 %} 12880 ins_pipe( pipe_slow ); 12881 %} 12882 12883 instruct string_indexofUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 12884 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr) 12885 %{ 12886 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 12887 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 12888 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 12889 12890 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 12891 ins_encode %{ 12892 __ string_indexof($str1$$Register, $str2$$Register, 12893 $cnt1$$Register, $cnt2$$Register, 12894 (-1), $result$$Register, 12895 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 12896 %} 12897 ins_pipe( pipe_slow ); 12898 %} 12899 12900 instruct string_indexof_char(rdi_RegP str1, rdx_RegI cnt1, rax_RegI ch, 12901 rbx_RegI result, legRegD tmp_vec1, legRegD tmp_vec2, legRegD tmp_vec3, rcx_RegI tmp, rFlagsReg cr) 12902 %{ 12903 predicate(UseSSE42Intrinsics && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::U)); 12904 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 12905 effect(TEMP tmp_vec1, TEMP tmp_vec2, TEMP tmp_vec3, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP tmp, KILL cr); 12906 format %{ "StringUTF16 IndexOf char[] $str1,$cnt1,$ch -> $result // KILL all" %} 12907 ins_encode %{ 12908 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register, 12909 $tmp_vec1$$XMMRegister, $tmp_vec2$$XMMRegister, $tmp_vec3$$XMMRegister, $tmp$$Register); 12910 %} 12911 ins_pipe( pipe_slow ); 12912 %} 12913 12914 instruct stringL_indexof_char(rdi_RegP str1, rdx_RegI cnt1, rax_RegI ch, 12915 rbx_RegI result, legRegD tmp_vec1, legRegD tmp_vec2, legRegD tmp_vec3, rcx_RegI tmp, rFlagsReg cr) 12916 %{ 12917 predicate(UseSSE42Intrinsics && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::L)); 12918 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 12919 effect(TEMP tmp_vec1, TEMP tmp_vec2, TEMP tmp_vec3, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP tmp, KILL cr); 12920 format %{ "StringLatin1 IndexOf char[] $str1,$cnt1,$ch -> $result // KILL all" %} 12921 ins_encode %{ 12922 __ stringL_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register, 12923 $tmp_vec1$$XMMRegister, $tmp_vec2$$XMMRegister, $tmp_vec3$$XMMRegister, $tmp$$Register); 12924 %} 12925 ins_pipe( pipe_slow ); 12926 %} 12927 12928 // fast string equals 12929 instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 12930 legRegD tmp1, legRegD tmp2, rbx_RegI tmp3, rFlagsReg cr) 12931 %{ 12932 predicate(!VM_Version::supports_avx512vlbw()); 12933 match(Set result (StrEquals (Binary str1 str2) cnt)); 12934 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 12935 12936 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 12937 ins_encode %{ 12938 __ arrays_equals(false, $str1$$Register, $str2$$Register, 12939 $cnt$$Register, $result$$Register, $tmp3$$Register, 12940 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, knoreg); 12941 %} 12942 ins_pipe( pipe_slow ); 12943 %} 12944 12945 instruct string_equals_evex(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 12946 legRegD tmp1, legRegD tmp2, kReg ktmp, rbx_RegI tmp3, rFlagsReg cr) 12947 %{ 12948 predicate(VM_Version::supports_avx512vlbw()); 12949 match(Set result (StrEquals (Binary str1 str2) cnt)); 12950 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 12951 12952 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 12953 ins_encode %{ 12954 __ arrays_equals(false, $str1$$Register, $str2$$Register, 12955 $cnt$$Register, $result$$Register, $tmp3$$Register, 12956 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, $ktmp$$KRegister); 12957 %} 12958 ins_pipe( pipe_slow ); 12959 %} 12960 12961 // fast array equals 12962 instruct array_equalsB(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 12963 legRegD tmp1, legRegD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 12964 %{ 12965 predicate(!VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 12966 match(Set result (AryEq ary1 ary2)); 12967 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 12968 12969 format %{ "Array Equals byte[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 12970 ins_encode %{ 12971 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 12972 $tmp3$$Register, $result$$Register, $tmp4$$Register, 12973 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, knoreg); 12974 %} 12975 ins_pipe( pipe_slow ); 12976 %} 12977 12978 instruct array_equalsB_evex(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 12979 legRegD tmp1, legRegD tmp2, kReg ktmp, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 12980 %{ 12981 predicate(VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 12982 match(Set result (AryEq ary1 ary2)); 12983 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 12984 12985 format %{ "Array Equals byte[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 12986 ins_encode %{ 12987 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 12988 $tmp3$$Register, $result$$Register, $tmp4$$Register, 12989 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, $ktmp$$KRegister); 12990 %} 12991 ins_pipe( pipe_slow ); 12992 %} 12993 12994 instruct array_equalsC(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 12995 legRegD tmp1, legRegD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 12996 %{ 12997 predicate(!VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 12998 match(Set result (AryEq ary1 ary2)); 12999 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 13000 13001 format %{ "Array Equals char[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 13002 ins_encode %{ 13003 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 13004 $tmp3$$Register, $result$$Register, $tmp4$$Register, 13005 $tmp1$$XMMRegister, $tmp2$$XMMRegister, true /* char */, knoreg); 13006 %} 13007 ins_pipe( pipe_slow ); 13008 %} 13009 13010 instruct array_equalsC_evex(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 13011 legRegD tmp1, legRegD tmp2, kReg ktmp, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 13012 %{ 13013 predicate(VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 13014 match(Set result (AryEq ary1 ary2)); 13015 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 13016 13017 format %{ "Array Equals char[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 13018 ins_encode %{ 13019 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 13020 $tmp3$$Register, $result$$Register, $tmp4$$Register, 13021 $tmp1$$XMMRegister, $tmp2$$XMMRegister, true /* char */, $ktmp$$KRegister); 13022 %} 13023 ins_pipe( pipe_slow ); 13024 %} 13025 13026 instruct arrays_hashcode(rdi_RegP ary1, rdx_RegI cnt1, rbx_RegI result, immU8 basic_type, 13027 legRegD tmp_vec1, legRegD tmp_vec2, legRegD tmp_vec3, legRegD tmp_vec4, 13028 legRegD tmp_vec5, legRegD tmp_vec6, legRegD tmp_vec7, legRegD tmp_vec8, 13029 legRegD tmp_vec9, legRegD tmp_vec10, legRegD tmp_vec11, legRegD tmp_vec12, 13030 legRegD tmp_vec13, rRegI tmp1, rRegI tmp2, rRegI tmp3, rFlagsReg cr) 13031 %{ 13032 predicate(UseAVX >= 2); 13033 match(Set result (VectorizedHashCode (Binary ary1 cnt1) (Binary result basic_type))); 13034 effect(TEMP tmp_vec1, TEMP tmp_vec2, TEMP tmp_vec3, TEMP tmp_vec4, TEMP tmp_vec5, TEMP tmp_vec6, 13035 TEMP tmp_vec7, TEMP tmp_vec8, TEMP tmp_vec9, TEMP tmp_vec10, TEMP tmp_vec11, TEMP tmp_vec12, 13036 TEMP tmp_vec13, TEMP tmp1, TEMP tmp2, TEMP tmp3, USE_KILL ary1, USE_KILL cnt1, 13037 USE basic_type, KILL cr); 13038 13039 format %{ "Array HashCode array[] $ary1,$cnt1,$result,$basic_type -> $result // KILL all" %} 13040 ins_encode %{ 13041 __ arrays_hashcode($ary1$$Register, $cnt1$$Register, $result$$Register, 13042 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 13043 $tmp_vec1$$XMMRegister, $tmp_vec2$$XMMRegister, $tmp_vec3$$XMMRegister, 13044 $tmp_vec4$$XMMRegister, $tmp_vec5$$XMMRegister, $tmp_vec6$$XMMRegister, 13045 $tmp_vec7$$XMMRegister, $tmp_vec8$$XMMRegister, $tmp_vec9$$XMMRegister, 13046 $tmp_vec10$$XMMRegister, $tmp_vec11$$XMMRegister, $tmp_vec12$$XMMRegister, 13047 $tmp_vec13$$XMMRegister, (BasicType)$basic_type$$constant); 13048 %} 13049 ins_pipe( pipe_slow ); 13050 %} 13051 13052 instruct count_positives(rsi_RegP ary1, rcx_RegI len, rax_RegI result, 13053 legRegD tmp1, legRegD tmp2, rbx_RegI tmp3, rFlagsReg cr,) 13054 %{ 13055 predicate(!VM_Version::supports_avx512vlbw() || !VM_Version::supports_bmi2()); 13056 match(Set result (CountPositives ary1 len)); 13057 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr); 13058 13059 format %{ "countPositives byte[] $ary1,$len -> $result // KILL $tmp1, $tmp2, $tmp3" %} 13060 ins_encode %{ 13061 __ count_positives($ary1$$Register, $len$$Register, 13062 $result$$Register, $tmp3$$Register, 13063 $tmp1$$XMMRegister, $tmp2$$XMMRegister, knoreg, knoreg); 13064 %} 13065 ins_pipe( pipe_slow ); 13066 %} 13067 13068 instruct count_positives_evex(rsi_RegP ary1, rcx_RegI len, rax_RegI result, 13069 legRegD tmp1, legRegD tmp2, kReg ktmp1, kReg ktmp2, rbx_RegI tmp3, rFlagsReg cr,) 13070 %{ 13071 predicate(VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2()); 13072 match(Set result (CountPositives ary1 len)); 13073 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp1, TEMP ktmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr); 13074 13075 format %{ "countPositives byte[] $ary1,$len -> $result // KILL $tmp1, $tmp2, $tmp3" %} 13076 ins_encode %{ 13077 __ count_positives($ary1$$Register, $len$$Register, 13078 $result$$Register, $tmp3$$Register, 13079 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $ktmp1$$KRegister, $ktmp2$$KRegister); 13080 %} 13081 ins_pipe( pipe_slow ); 13082 %} 13083 13084 // fast char[] to byte[] compression 13085 instruct string_compress(rsi_RegP src, rdi_RegP dst, rdx_RegI len, legRegD tmp1, legRegD tmp2, legRegD tmp3, 13086 legRegD tmp4, rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 13087 predicate(!VM_Version::supports_avx512vlbw() || !VM_Version::supports_bmi2()); 13088 match(Set result (StrCompressedCopy src (Binary dst len))); 13089 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, 13090 USE_KILL len, KILL tmp5, KILL cr); 13091 13092 format %{ "String Compress $src,$dst -> $result // KILL RAX, RCX, RDX" %} 13093 ins_encode %{ 13094 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 13095 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 13096 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, 13097 knoreg, knoreg); 13098 %} 13099 ins_pipe( pipe_slow ); 13100 %} 13101 13102 instruct string_compress_evex(rsi_RegP src, rdi_RegP dst, rdx_RegI len, legRegD tmp1, legRegD tmp2, legRegD tmp3, 13103 legRegD tmp4, kReg ktmp1, kReg ktmp2, rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 13104 predicate(VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2()); 13105 match(Set result (StrCompressedCopy src (Binary dst len))); 13106 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP ktmp1, TEMP ktmp2, USE_KILL src, USE_KILL dst, 13107 USE_KILL len, KILL tmp5, KILL cr); 13108 13109 format %{ "String Compress $src,$dst -> $result // KILL RAX, RCX, RDX" %} 13110 ins_encode %{ 13111 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 13112 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 13113 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, 13114 $ktmp1$$KRegister, $ktmp2$$KRegister); 13115 %} 13116 ins_pipe( pipe_slow ); 13117 %} 13118 // fast byte[] to char[] inflation 13119 instruct string_inflate(Universe dummy, rsi_RegP src, rdi_RegP dst, rdx_RegI len, 13120 legRegD tmp1, rcx_RegI tmp2, rFlagsReg cr) %{ 13121 predicate(!VM_Version::supports_avx512vlbw() || !VM_Version::supports_bmi2()); 13122 match(Set dummy (StrInflatedCopy src (Binary dst len))); 13123 effect(TEMP tmp1, TEMP tmp2, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 13124 13125 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 13126 ins_encode %{ 13127 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 13128 $tmp1$$XMMRegister, $tmp2$$Register, knoreg); 13129 %} 13130 ins_pipe( pipe_slow ); 13131 %} 13132 13133 instruct string_inflate_evex(Universe dummy, rsi_RegP src, rdi_RegP dst, rdx_RegI len, 13134 legRegD tmp1, kReg ktmp, rcx_RegI tmp2, rFlagsReg cr) %{ 13135 predicate(VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2()); 13136 match(Set dummy (StrInflatedCopy src (Binary dst len))); 13137 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 13138 13139 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 13140 ins_encode %{ 13141 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 13142 $tmp1$$XMMRegister, $tmp2$$Register, $ktmp$$KRegister); 13143 %} 13144 ins_pipe( pipe_slow ); 13145 %} 13146 13147 // encode char[] to byte[] in ISO_8859_1 13148 instruct encode_iso_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len, 13149 legRegD tmp1, legRegD tmp2, legRegD tmp3, legRegD tmp4, 13150 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 13151 predicate(!((EncodeISOArrayNode*)n)->is_ascii()); 13152 match(Set result (EncodeISOArray src (Binary dst len))); 13153 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 13154 13155 format %{ "Encode iso array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %} 13156 ins_encode %{ 13157 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 13158 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 13159 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, false); 13160 %} 13161 ins_pipe( pipe_slow ); 13162 %} 13163 13164 // encode char[] to byte[] in ASCII 13165 instruct encode_ascii_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len, 13166 legRegD tmp1, legRegD tmp2, legRegD tmp3, legRegD tmp4, 13167 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 13168 predicate(((EncodeISOArrayNode*)n)->is_ascii()); 13169 match(Set result (EncodeISOArray src (Binary dst len))); 13170 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 13171 13172 format %{ "Encode ascii array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %} 13173 ins_encode %{ 13174 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 13175 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 13176 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, true); 13177 %} 13178 ins_pipe( pipe_slow ); 13179 %} 13180 13181 //----------Overflow Math Instructions----------------------------------------- 13182 13183 instruct overflowAddI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 13184 %{ 13185 match(Set cr (OverflowAddI op1 op2)); 13186 effect(DEF cr, USE_KILL op1, USE op2); 13187 13188 format %{ "addl $op1, $op2\t# overflow check int" %} 13189 13190 ins_encode %{ 13191 __ addl($op1$$Register, $op2$$Register); 13192 %} 13193 ins_pipe(ialu_reg_reg); 13194 %} 13195 13196 instruct overflowAddI_rReg_imm(rFlagsReg cr, rax_RegI op1, immI op2) 13197 %{ 13198 match(Set cr (OverflowAddI op1 op2)); 13199 effect(DEF cr, USE_KILL op1, USE op2); 13200 13201 format %{ "addl $op1, $op2\t# overflow check int" %} 13202 13203 ins_encode %{ 13204 __ addl($op1$$Register, $op2$$constant); 13205 %} 13206 ins_pipe(ialu_reg_reg); 13207 %} 13208 13209 instruct overflowAddL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 13210 %{ 13211 match(Set cr (OverflowAddL op1 op2)); 13212 effect(DEF cr, USE_KILL op1, USE op2); 13213 13214 format %{ "addq $op1, $op2\t# overflow check long" %} 13215 ins_encode %{ 13216 __ addq($op1$$Register, $op2$$Register); 13217 %} 13218 ins_pipe(ialu_reg_reg); 13219 %} 13220 13221 instruct overflowAddL_rReg_imm(rFlagsReg cr, rax_RegL op1, immL32 op2) 13222 %{ 13223 match(Set cr (OverflowAddL op1 op2)); 13224 effect(DEF cr, USE_KILL op1, USE op2); 13225 13226 format %{ "addq $op1, $op2\t# overflow check long" %} 13227 ins_encode %{ 13228 __ addq($op1$$Register, $op2$$constant); 13229 %} 13230 ins_pipe(ialu_reg_reg); 13231 %} 13232 13233 instruct overflowSubI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 13234 %{ 13235 match(Set cr (OverflowSubI op1 op2)); 13236 13237 format %{ "cmpl $op1, $op2\t# overflow check int" %} 13238 ins_encode %{ 13239 __ cmpl($op1$$Register, $op2$$Register); 13240 %} 13241 ins_pipe(ialu_reg_reg); 13242 %} 13243 13244 instruct overflowSubI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 13245 %{ 13246 match(Set cr (OverflowSubI op1 op2)); 13247 13248 format %{ "cmpl $op1, $op2\t# overflow check int" %} 13249 ins_encode %{ 13250 __ cmpl($op1$$Register, $op2$$constant); 13251 %} 13252 ins_pipe(ialu_reg_reg); 13253 %} 13254 13255 instruct overflowSubL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 13256 %{ 13257 match(Set cr (OverflowSubL op1 op2)); 13258 13259 format %{ "cmpq $op1, $op2\t# overflow check long" %} 13260 ins_encode %{ 13261 __ cmpq($op1$$Register, $op2$$Register); 13262 %} 13263 ins_pipe(ialu_reg_reg); 13264 %} 13265 13266 instruct overflowSubL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 13267 %{ 13268 match(Set cr (OverflowSubL op1 op2)); 13269 13270 format %{ "cmpq $op1, $op2\t# overflow check long" %} 13271 ins_encode %{ 13272 __ cmpq($op1$$Register, $op2$$constant); 13273 %} 13274 ins_pipe(ialu_reg_reg); 13275 %} 13276 13277 instruct overflowNegI_rReg(rFlagsReg cr, immI_0 zero, rax_RegI op2) 13278 %{ 13279 match(Set cr (OverflowSubI zero op2)); 13280 effect(DEF cr, USE_KILL op2); 13281 13282 format %{ "negl $op2\t# overflow check int" %} 13283 ins_encode %{ 13284 __ negl($op2$$Register); 13285 %} 13286 ins_pipe(ialu_reg_reg); 13287 %} 13288 13289 instruct overflowNegL_rReg(rFlagsReg cr, immL0 zero, rax_RegL op2) 13290 %{ 13291 match(Set cr (OverflowSubL zero op2)); 13292 effect(DEF cr, USE_KILL op2); 13293 13294 format %{ "negq $op2\t# overflow check long" %} 13295 ins_encode %{ 13296 __ negq($op2$$Register); 13297 %} 13298 ins_pipe(ialu_reg_reg); 13299 %} 13300 13301 instruct overflowMulI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 13302 %{ 13303 match(Set cr (OverflowMulI op1 op2)); 13304 effect(DEF cr, USE_KILL op1, USE op2); 13305 13306 format %{ "imull $op1, $op2\t# overflow check int" %} 13307 ins_encode %{ 13308 __ imull($op1$$Register, $op2$$Register); 13309 %} 13310 ins_pipe(ialu_reg_reg_alu0); 13311 %} 13312 13313 instruct overflowMulI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2, rRegI tmp) 13314 %{ 13315 match(Set cr (OverflowMulI op1 op2)); 13316 effect(DEF cr, TEMP tmp, USE op1, USE op2); 13317 13318 format %{ "imull $tmp, $op1, $op2\t# overflow check int" %} 13319 ins_encode %{ 13320 __ imull($tmp$$Register, $op1$$Register, $op2$$constant); 13321 %} 13322 ins_pipe(ialu_reg_reg_alu0); 13323 %} 13324 13325 instruct overflowMulL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 13326 %{ 13327 match(Set cr (OverflowMulL op1 op2)); 13328 effect(DEF cr, USE_KILL op1, USE op2); 13329 13330 format %{ "imulq $op1, $op2\t# overflow check long" %} 13331 ins_encode %{ 13332 __ imulq($op1$$Register, $op2$$Register); 13333 %} 13334 ins_pipe(ialu_reg_reg_alu0); 13335 %} 13336 13337 instruct overflowMulL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2, rRegL tmp) 13338 %{ 13339 match(Set cr (OverflowMulL op1 op2)); 13340 effect(DEF cr, TEMP tmp, USE op1, USE op2); 13341 13342 format %{ "imulq $tmp, $op1, $op2\t# overflow check long" %} 13343 ins_encode %{ 13344 __ imulq($tmp$$Register, $op1$$Register, $op2$$constant); 13345 %} 13346 ins_pipe(ialu_reg_reg_alu0); 13347 %} 13348 13349 13350 //----------Control Flow Instructions------------------------------------------ 13351 // Signed compare Instructions 13352 13353 // XXX more variants!! 13354 instruct compI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 13355 %{ 13356 match(Set cr (CmpI op1 op2)); 13357 effect(DEF cr, USE op1, USE op2); 13358 13359 format %{ "cmpl $op1, $op2" %} 13360 ins_encode %{ 13361 __ cmpl($op1$$Register, $op2$$Register); 13362 %} 13363 ins_pipe(ialu_cr_reg_reg); 13364 %} 13365 13366 instruct compI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 13367 %{ 13368 match(Set cr (CmpI op1 op2)); 13369 13370 format %{ "cmpl $op1, $op2" %} 13371 ins_encode %{ 13372 __ cmpl($op1$$Register, $op2$$constant); 13373 %} 13374 ins_pipe(ialu_cr_reg_imm); 13375 %} 13376 13377 instruct compI_rReg_mem(rFlagsReg cr, rRegI op1, memory op2) 13378 %{ 13379 match(Set cr (CmpI op1 (LoadI op2))); 13380 13381 ins_cost(500); // XXX 13382 format %{ "cmpl $op1, $op2" %} 13383 ins_encode %{ 13384 __ cmpl($op1$$Register, $op2$$Address); 13385 %} 13386 ins_pipe(ialu_cr_reg_mem); 13387 %} 13388 13389 instruct testI_reg(rFlagsReg cr, rRegI src, immI_0 zero) 13390 %{ 13391 match(Set cr (CmpI src zero)); 13392 13393 format %{ "testl $src, $src" %} 13394 ins_encode %{ 13395 __ testl($src$$Register, $src$$Register); 13396 %} 13397 ins_pipe(ialu_cr_reg_imm); 13398 %} 13399 13400 instruct testI_reg_imm(rFlagsReg cr, rRegI src, immI con, immI_0 zero) 13401 %{ 13402 match(Set cr (CmpI (AndI src con) zero)); 13403 13404 format %{ "testl $src, $con" %} 13405 ins_encode %{ 13406 __ testl($src$$Register, $con$$constant); 13407 %} 13408 ins_pipe(ialu_cr_reg_imm); 13409 %} 13410 13411 instruct testI_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2, immI_0 zero) 13412 %{ 13413 match(Set cr (CmpI (AndI src1 src2) zero)); 13414 13415 format %{ "testl $src1, $src2" %} 13416 ins_encode %{ 13417 __ testl($src1$$Register, $src2$$Register); 13418 %} 13419 ins_pipe(ialu_cr_reg_imm); 13420 %} 13421 13422 instruct testI_reg_mem(rFlagsReg cr, rRegI src, memory mem, immI_0 zero) 13423 %{ 13424 match(Set cr (CmpI (AndI src (LoadI mem)) zero)); 13425 13426 format %{ "testl $src, $mem" %} 13427 ins_encode %{ 13428 __ testl($src$$Register, $mem$$Address); 13429 %} 13430 ins_pipe(ialu_cr_reg_mem); 13431 %} 13432 13433 // Unsigned compare Instructions; really, same as signed except they 13434 // produce an rFlagsRegU instead of rFlagsReg. 13435 instruct compU_rReg(rFlagsRegU cr, rRegI op1, rRegI op2) 13436 %{ 13437 match(Set cr (CmpU op1 op2)); 13438 13439 format %{ "cmpl $op1, $op2\t# unsigned" %} 13440 ins_encode %{ 13441 __ cmpl($op1$$Register, $op2$$Register); 13442 %} 13443 ins_pipe(ialu_cr_reg_reg); 13444 %} 13445 13446 instruct compU_rReg_imm(rFlagsRegU cr, rRegI op1, immI op2) 13447 %{ 13448 match(Set cr (CmpU op1 op2)); 13449 13450 format %{ "cmpl $op1, $op2\t# unsigned" %} 13451 ins_encode %{ 13452 __ cmpl($op1$$Register, $op2$$constant); 13453 %} 13454 ins_pipe(ialu_cr_reg_imm); 13455 %} 13456 13457 instruct compU_rReg_mem(rFlagsRegU cr, rRegI op1, memory op2) 13458 %{ 13459 match(Set cr (CmpU op1 (LoadI op2))); 13460 13461 ins_cost(500); // XXX 13462 format %{ "cmpl $op1, $op2\t# unsigned" %} 13463 ins_encode %{ 13464 __ cmpl($op1$$Register, $op2$$Address); 13465 %} 13466 ins_pipe(ialu_cr_reg_mem); 13467 %} 13468 13469 instruct testU_reg(rFlagsRegU cr, rRegI src, immI_0 zero) 13470 %{ 13471 match(Set cr (CmpU src zero)); 13472 13473 format %{ "testl $src, $src\t# unsigned" %} 13474 ins_encode %{ 13475 __ testl($src$$Register, $src$$Register); 13476 %} 13477 ins_pipe(ialu_cr_reg_imm); 13478 %} 13479 13480 instruct compP_rReg(rFlagsRegU cr, rRegP op1, rRegP op2) 13481 %{ 13482 match(Set cr (CmpP op1 op2)); 13483 13484 format %{ "cmpq $op1, $op2\t# ptr" %} 13485 ins_encode %{ 13486 __ cmpq($op1$$Register, $op2$$Register); 13487 %} 13488 ins_pipe(ialu_cr_reg_reg); 13489 %} 13490 13491 instruct compP_rReg_mem(rFlagsRegU cr, rRegP op1, memory op2) 13492 %{ 13493 match(Set cr (CmpP op1 (LoadP op2))); 13494 predicate(n->in(2)->as_Load()->barrier_data() == 0); 13495 13496 ins_cost(500); // XXX 13497 format %{ "cmpq $op1, $op2\t# ptr" %} 13498 ins_encode %{ 13499 __ cmpq($op1$$Register, $op2$$Address); 13500 %} 13501 ins_pipe(ialu_cr_reg_mem); 13502 %} 13503 13504 // XXX this is generalized by compP_rReg_mem??? 13505 // Compare raw pointer (used in out-of-heap check). 13506 // Only works because non-oop pointers must be raw pointers 13507 // and raw pointers have no anti-dependencies. 13508 instruct compP_mem_rReg(rFlagsRegU cr, rRegP op1, memory op2) 13509 %{ 13510 predicate(n->in(2)->in(2)->bottom_type()->reloc() == relocInfo::none && 13511 n->in(2)->as_Load()->barrier_data() == 0); 13512 match(Set cr (CmpP op1 (LoadP op2))); 13513 13514 format %{ "cmpq $op1, $op2\t# raw ptr" %} 13515 ins_encode %{ 13516 __ cmpq($op1$$Register, $op2$$Address); 13517 %} 13518 ins_pipe(ialu_cr_reg_mem); 13519 %} 13520 13521 // This will generate a signed flags result. This should be OK since 13522 // any compare to a zero should be eq/neq. 13523 instruct testP_reg(rFlagsReg cr, rRegP src, immP0 zero) 13524 %{ 13525 match(Set cr (CmpP src zero)); 13526 13527 format %{ "testq $src, $src\t# ptr" %} 13528 ins_encode %{ 13529 __ testq($src$$Register, $src$$Register); 13530 %} 13531 ins_pipe(ialu_cr_reg_imm); 13532 %} 13533 13534 // This will generate a signed flags result. This should be OK since 13535 // any compare to a zero should be eq/neq. 13536 instruct testP_mem(rFlagsReg cr, memory op, immP0 zero) 13537 %{ 13538 predicate((!UseCompressedOops || (CompressedOops::base() != nullptr)) && 13539 n->in(1)->as_Load()->barrier_data() == 0); 13540 match(Set cr (CmpP (LoadP op) zero)); 13541 13542 ins_cost(500); // XXX 13543 format %{ "testq $op, 0xffffffffffffffff\t# ptr" %} 13544 ins_encode %{ 13545 __ testq($op$$Address, 0xFFFFFFFF); 13546 %} 13547 ins_pipe(ialu_cr_reg_imm); 13548 %} 13549 13550 instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero) 13551 %{ 13552 predicate(UseCompressedOops && (CompressedOops::base() == nullptr) && 13553 n->in(1)->as_Load()->barrier_data() == 0); 13554 match(Set cr (CmpP (LoadP mem) zero)); 13555 13556 format %{ "cmpq R12, $mem\t# ptr (R12_heapbase==0)" %} 13557 ins_encode %{ 13558 __ cmpq(r12, $mem$$Address); 13559 %} 13560 ins_pipe(ialu_cr_reg_mem); 13561 %} 13562 13563 instruct compN_rReg(rFlagsRegU cr, rRegN op1, rRegN op2) 13564 %{ 13565 match(Set cr (CmpN op1 op2)); 13566 13567 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 13568 ins_encode %{ __ cmpl($op1$$Register, $op2$$Register); %} 13569 ins_pipe(ialu_cr_reg_reg); 13570 %} 13571 13572 instruct compN_rReg_mem(rFlagsRegU cr, rRegN src, memory mem) 13573 %{ 13574 predicate(n->in(2)->as_Load()->barrier_data() == 0); 13575 match(Set cr (CmpN src (LoadN mem))); 13576 13577 format %{ "cmpl $src, $mem\t# compressed ptr" %} 13578 ins_encode %{ 13579 __ cmpl($src$$Register, $mem$$Address); 13580 %} 13581 ins_pipe(ialu_cr_reg_mem); 13582 %} 13583 13584 instruct compN_rReg_imm(rFlagsRegU cr, rRegN op1, immN op2) %{ 13585 match(Set cr (CmpN op1 op2)); 13586 13587 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 13588 ins_encode %{ 13589 __ cmp_narrow_oop($op1$$Register, (jobject)$op2$$constant); 13590 %} 13591 ins_pipe(ialu_cr_reg_imm); 13592 %} 13593 13594 instruct compN_mem_imm(rFlagsRegU cr, memory mem, immN src) 13595 %{ 13596 predicate(n->in(2)->as_Load()->barrier_data() == 0); 13597 match(Set cr (CmpN src (LoadN mem))); 13598 13599 format %{ "cmpl $mem, $src\t# compressed ptr" %} 13600 ins_encode %{ 13601 __ cmp_narrow_oop($mem$$Address, (jobject)$src$$constant); 13602 %} 13603 ins_pipe(ialu_cr_reg_mem); 13604 %} 13605 13606 instruct compN_rReg_imm_klass(rFlagsRegU cr, rRegN op1, immNKlass op2) %{ 13607 match(Set cr (CmpN op1 op2)); 13608 13609 format %{ "cmpl $op1, $op2\t# compressed klass ptr" %} 13610 ins_encode %{ 13611 __ cmp_narrow_klass($op1$$Register, (Klass*)$op2$$constant); 13612 %} 13613 ins_pipe(ialu_cr_reg_imm); 13614 %} 13615 13616 instruct compN_mem_imm_klass(rFlagsRegU cr, memory mem, immNKlass src) 13617 %{ 13618 predicate(!UseCompactObjectHeaders); 13619 match(Set cr (CmpN src (LoadNKlass mem))); 13620 13621 format %{ "cmpl $mem, $src\t# compressed klass ptr" %} 13622 ins_encode %{ 13623 __ cmp_narrow_klass($mem$$Address, (Klass*)$src$$constant); 13624 %} 13625 ins_pipe(ialu_cr_reg_mem); 13626 %} 13627 13628 instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{ 13629 match(Set cr (CmpN src zero)); 13630 13631 format %{ "testl $src, $src\t# compressed ptr" %} 13632 ins_encode %{ __ testl($src$$Register, $src$$Register); %} 13633 ins_pipe(ialu_cr_reg_imm); 13634 %} 13635 13636 instruct testN_mem(rFlagsReg cr, memory mem, immN0 zero) 13637 %{ 13638 predicate(CompressedOops::base() != nullptr && 13639 n->in(1)->as_Load()->barrier_data() == 0); 13640 match(Set cr (CmpN (LoadN mem) zero)); 13641 13642 ins_cost(500); // XXX 13643 format %{ "testl $mem, 0xffffffff\t# compressed ptr" %} 13644 ins_encode %{ 13645 __ cmpl($mem$$Address, (int)0xFFFFFFFF); 13646 %} 13647 ins_pipe(ialu_cr_reg_mem); 13648 %} 13649 13650 instruct testN_mem_reg0(rFlagsReg cr, memory mem, immN0 zero) 13651 %{ 13652 predicate(CompressedOops::base() == nullptr && 13653 n->in(1)->as_Load()->barrier_data() == 0); 13654 match(Set cr (CmpN (LoadN mem) zero)); 13655 13656 format %{ "cmpl R12, $mem\t# compressed ptr (R12_heapbase==0)" %} 13657 ins_encode %{ 13658 __ cmpl(r12, $mem$$Address); 13659 %} 13660 ins_pipe(ialu_cr_reg_mem); 13661 %} 13662 13663 // Yanked all unsigned pointer compare operations. 13664 // Pointer compares are done with CmpP which is already unsigned. 13665 13666 instruct compL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 13667 %{ 13668 match(Set cr (CmpL op1 op2)); 13669 13670 format %{ "cmpq $op1, $op2" %} 13671 ins_encode %{ 13672 __ cmpq($op1$$Register, $op2$$Register); 13673 %} 13674 ins_pipe(ialu_cr_reg_reg); 13675 %} 13676 13677 instruct compL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 13678 %{ 13679 match(Set cr (CmpL op1 op2)); 13680 13681 format %{ "cmpq $op1, $op2" %} 13682 ins_encode %{ 13683 __ cmpq($op1$$Register, $op2$$constant); 13684 %} 13685 ins_pipe(ialu_cr_reg_imm); 13686 %} 13687 13688 instruct compL_rReg_mem(rFlagsReg cr, rRegL op1, memory op2) 13689 %{ 13690 match(Set cr (CmpL op1 (LoadL op2))); 13691 13692 format %{ "cmpq $op1, $op2" %} 13693 ins_encode %{ 13694 __ cmpq($op1$$Register, $op2$$Address); 13695 %} 13696 ins_pipe(ialu_cr_reg_mem); 13697 %} 13698 13699 instruct testL_reg(rFlagsReg cr, rRegL src, immL0 zero) 13700 %{ 13701 match(Set cr (CmpL src zero)); 13702 13703 format %{ "testq $src, $src" %} 13704 ins_encode %{ 13705 __ testq($src$$Register, $src$$Register); 13706 %} 13707 ins_pipe(ialu_cr_reg_imm); 13708 %} 13709 13710 instruct testL_reg_imm(rFlagsReg cr, rRegL src, immL32 con, immL0 zero) 13711 %{ 13712 match(Set cr (CmpL (AndL src con) zero)); 13713 13714 format %{ "testq $src, $con\t# long" %} 13715 ins_encode %{ 13716 __ testq($src$$Register, $con$$constant); 13717 %} 13718 ins_pipe(ialu_cr_reg_imm); 13719 %} 13720 13721 instruct testL_reg_reg(rFlagsReg cr, rRegL src1, rRegL src2, immL0 zero) 13722 %{ 13723 match(Set cr (CmpL (AndL src1 src2) zero)); 13724 13725 format %{ "testq $src1, $src2\t# long" %} 13726 ins_encode %{ 13727 __ testq($src1$$Register, $src2$$Register); 13728 %} 13729 ins_pipe(ialu_cr_reg_imm); 13730 %} 13731 13732 instruct testL_reg_mem(rFlagsReg cr, rRegL src, memory mem, immL0 zero) 13733 %{ 13734 match(Set cr (CmpL (AndL src (LoadL mem)) zero)); 13735 13736 format %{ "testq $src, $mem" %} 13737 ins_encode %{ 13738 __ testq($src$$Register, $mem$$Address); 13739 %} 13740 ins_pipe(ialu_cr_reg_mem); 13741 %} 13742 13743 instruct testL_reg_mem2(rFlagsReg cr, rRegP src, memory mem, immL0 zero) 13744 %{ 13745 match(Set cr (CmpL (AndL (CastP2X src) (LoadL mem)) zero)); 13746 13747 format %{ "testq $src, $mem" %} 13748 ins_encode %{ 13749 __ testq($src$$Register, $mem$$Address); 13750 %} 13751 ins_pipe(ialu_cr_reg_mem); 13752 %} 13753 13754 // Manifest a CmpU result in an integer register. Very painful. 13755 // This is the test to avoid. 13756 instruct cmpU3_reg_reg(rRegI dst, rRegI src1, rRegI src2, rFlagsReg flags) 13757 %{ 13758 match(Set dst (CmpU3 src1 src2)); 13759 effect(KILL flags); 13760 13761 ins_cost(275); // XXX 13762 format %{ "cmpl $src1, $src2\t# CmpL3\n\t" 13763 "movl $dst, -1\n\t" 13764 "jb,u done\n\t" 13765 "setcc $dst \t# emits setne + movzbl or setzune for APX" 13766 "done:" %} 13767 ins_encode %{ 13768 Label done; 13769 __ cmpl($src1$$Register, $src2$$Register); 13770 __ movl($dst$$Register, -1); 13771 __ jccb(Assembler::below, done); 13772 __ setcc(Assembler::notZero, $dst$$Register); 13773 __ bind(done); 13774 %} 13775 ins_pipe(pipe_slow); 13776 %} 13777 13778 // Manifest a CmpL result in an integer register. Very painful. 13779 // This is the test to avoid. 13780 instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 13781 %{ 13782 match(Set dst (CmpL3 src1 src2)); 13783 effect(KILL flags); 13784 13785 ins_cost(275); // XXX 13786 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 13787 "movl $dst, -1\n\t" 13788 "jl,s done\n\t" 13789 "setcc $dst \t# emits setne + movzbl or setzune for APX" 13790 "done:" %} 13791 ins_encode %{ 13792 Label done; 13793 __ cmpq($src1$$Register, $src2$$Register); 13794 __ movl($dst$$Register, -1); 13795 __ jccb(Assembler::less, done); 13796 __ setcc(Assembler::notZero, $dst$$Register); 13797 __ bind(done); 13798 %} 13799 ins_pipe(pipe_slow); 13800 %} 13801 13802 // Manifest a CmpUL result in an integer register. Very painful. 13803 // This is the test to avoid. 13804 instruct cmpUL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 13805 %{ 13806 match(Set dst (CmpUL3 src1 src2)); 13807 effect(KILL flags); 13808 13809 ins_cost(275); // XXX 13810 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 13811 "movl $dst, -1\n\t" 13812 "jb,u done\n\t" 13813 "setcc $dst \t# emits setne + movzbl or setzune for APX" 13814 "done:" %} 13815 ins_encode %{ 13816 Label done; 13817 __ cmpq($src1$$Register, $src2$$Register); 13818 __ movl($dst$$Register, -1); 13819 __ jccb(Assembler::below, done); 13820 __ setcc(Assembler::notZero, $dst$$Register); 13821 __ bind(done); 13822 %} 13823 ins_pipe(pipe_slow); 13824 %} 13825 13826 // Unsigned long compare Instructions; really, same as signed long except they 13827 // produce an rFlagsRegU instead of rFlagsReg. 13828 instruct compUL_rReg(rFlagsRegU cr, rRegL op1, rRegL op2) 13829 %{ 13830 match(Set cr (CmpUL op1 op2)); 13831 13832 format %{ "cmpq $op1, $op2\t# unsigned" %} 13833 ins_encode %{ 13834 __ cmpq($op1$$Register, $op2$$Register); 13835 %} 13836 ins_pipe(ialu_cr_reg_reg); 13837 %} 13838 13839 instruct compUL_rReg_imm(rFlagsRegU cr, rRegL op1, immL32 op2) 13840 %{ 13841 match(Set cr (CmpUL op1 op2)); 13842 13843 format %{ "cmpq $op1, $op2\t# unsigned" %} 13844 ins_encode %{ 13845 __ cmpq($op1$$Register, $op2$$constant); 13846 %} 13847 ins_pipe(ialu_cr_reg_imm); 13848 %} 13849 13850 instruct compUL_rReg_mem(rFlagsRegU cr, rRegL op1, memory op2) 13851 %{ 13852 match(Set cr (CmpUL op1 (LoadL op2))); 13853 13854 format %{ "cmpq $op1, $op2\t# unsigned" %} 13855 ins_encode %{ 13856 __ cmpq($op1$$Register, $op2$$Address); 13857 %} 13858 ins_pipe(ialu_cr_reg_mem); 13859 %} 13860 13861 instruct testUL_reg(rFlagsRegU cr, rRegL src, immL0 zero) 13862 %{ 13863 match(Set cr (CmpUL src zero)); 13864 13865 format %{ "testq $src, $src\t# unsigned" %} 13866 ins_encode %{ 13867 __ testq($src$$Register, $src$$Register); 13868 %} 13869 ins_pipe(ialu_cr_reg_imm); 13870 %} 13871 13872 instruct compB_mem_imm(rFlagsReg cr, memory mem, immI8 imm) 13873 %{ 13874 match(Set cr (CmpI (LoadB mem) imm)); 13875 13876 ins_cost(125); 13877 format %{ "cmpb $mem, $imm" %} 13878 ins_encode %{ __ cmpb($mem$$Address, $imm$$constant); %} 13879 ins_pipe(ialu_cr_reg_mem); 13880 %} 13881 13882 instruct testUB_mem_imm(rFlagsReg cr, memory mem, immU7 imm, immI_0 zero) 13883 %{ 13884 match(Set cr (CmpI (AndI (LoadUB mem) imm) zero)); 13885 13886 ins_cost(125); 13887 format %{ "testb $mem, $imm\t# ubyte" %} 13888 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %} 13889 ins_pipe(ialu_cr_reg_mem); 13890 %} 13891 13892 instruct testB_mem_imm(rFlagsReg cr, memory mem, immI8 imm, immI_0 zero) 13893 %{ 13894 match(Set cr (CmpI (AndI (LoadB mem) imm) zero)); 13895 13896 ins_cost(125); 13897 format %{ "testb $mem, $imm\t# byte" %} 13898 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %} 13899 ins_pipe(ialu_cr_reg_mem); 13900 %} 13901 13902 //----------Max and Min-------------------------------------------------------- 13903 // Min Instructions 13904 13905 instruct cmovI_reg_g(rRegI dst, rRegI src, rFlagsReg cr) 13906 %{ 13907 predicate(!UseAPX); 13908 effect(USE_DEF dst, USE src, USE cr); 13909 13910 format %{ "cmovlgt $dst, $src\t# min" %} 13911 ins_encode %{ 13912 __ cmovl(Assembler::greater, $dst$$Register, $src$$Register); 13913 %} 13914 ins_pipe(pipe_cmov_reg); 13915 %} 13916 13917 instruct cmovI_reg_g_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr) 13918 %{ 13919 predicate(UseAPX); 13920 effect(DEF dst, USE src1, USE src2, USE cr); 13921 13922 format %{ "ecmovlgt $dst, $src1, $src2\t# min ndd" %} 13923 ins_encode %{ 13924 __ ecmovl(Assembler::greater, $dst$$Register, $src1$$Register, $src2$$Register); 13925 %} 13926 ins_pipe(pipe_cmov_reg); 13927 %} 13928 13929 instruct minI_rReg(rRegI dst, rRegI src) 13930 %{ 13931 predicate(!UseAPX); 13932 match(Set dst (MinI dst src)); 13933 13934 ins_cost(200); 13935 expand %{ 13936 rFlagsReg cr; 13937 compI_rReg(cr, dst, src); 13938 cmovI_reg_g(dst, src, cr); 13939 %} 13940 %} 13941 13942 instruct minI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2) 13943 %{ 13944 predicate(UseAPX); 13945 match(Set dst (MinI src1 src2)); 13946 effect(DEF dst, USE src1, USE src2); 13947 13948 ins_cost(200); 13949 expand %{ 13950 rFlagsReg cr; 13951 compI_rReg(cr, src1, src2); 13952 cmovI_reg_g_ndd(dst, src1, src2, cr); 13953 %} 13954 %} 13955 13956 instruct cmovI_reg_l(rRegI dst, rRegI src, rFlagsReg cr) 13957 %{ 13958 predicate(!UseAPX); 13959 effect(USE_DEF dst, USE src, USE cr); 13960 13961 format %{ "cmovllt $dst, $src\t# max" %} 13962 ins_encode %{ 13963 __ cmovl(Assembler::less, $dst$$Register, $src$$Register); 13964 %} 13965 ins_pipe(pipe_cmov_reg); 13966 %} 13967 13968 instruct cmovI_reg_l_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr) 13969 %{ 13970 predicate(UseAPX); 13971 effect(DEF dst, USE src1, USE src2, USE cr); 13972 13973 format %{ "ecmovllt $dst, $src1, $src2\t# max ndd" %} 13974 ins_encode %{ 13975 __ ecmovl(Assembler::less, $dst$$Register, $src1$$Register, $src2$$Register); 13976 %} 13977 ins_pipe(pipe_cmov_reg); 13978 %} 13979 13980 instruct maxI_rReg(rRegI dst, rRegI src) 13981 %{ 13982 predicate(!UseAPX); 13983 match(Set dst (MaxI dst src)); 13984 13985 ins_cost(200); 13986 expand %{ 13987 rFlagsReg cr; 13988 compI_rReg(cr, dst, src); 13989 cmovI_reg_l(dst, src, cr); 13990 %} 13991 %} 13992 13993 instruct maxI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2) 13994 %{ 13995 predicate(UseAPX); 13996 match(Set dst (MaxI src1 src2)); 13997 effect(DEF dst, USE src1, USE src2); 13998 13999 ins_cost(200); 14000 expand %{ 14001 rFlagsReg cr; 14002 compI_rReg(cr, src1, src2); 14003 cmovI_reg_l_ndd(dst, src1, src2, cr); 14004 %} 14005 %} 14006 14007 // ============================================================================ 14008 // Branch Instructions 14009 14010 // Jump Direct - Label defines a relative address from JMP+1 14011 instruct jmpDir(label labl) 14012 %{ 14013 match(Goto); 14014 effect(USE labl); 14015 14016 ins_cost(300); 14017 format %{ "jmp $labl" %} 14018 size(5); 14019 ins_encode %{ 14020 Label* L = $labl$$label; 14021 __ jmp(*L, false); // Always long jump 14022 %} 14023 ins_pipe(pipe_jmp); 14024 %} 14025 14026 // Jump Direct Conditional - Label defines a relative address from Jcc+1 14027 instruct jmpCon(cmpOp cop, rFlagsReg cr, label labl) 14028 %{ 14029 match(If cop cr); 14030 effect(USE labl); 14031 14032 ins_cost(300); 14033 format %{ "j$cop $labl" %} 14034 size(6); 14035 ins_encode %{ 14036 Label* L = $labl$$label; 14037 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 14038 %} 14039 ins_pipe(pipe_jcc); 14040 %} 14041 14042 // Jump Direct Conditional - Label defines a relative address from Jcc+1 14043 instruct jmpLoopEnd(cmpOp cop, rFlagsReg cr, label labl) 14044 %{ 14045 match(CountedLoopEnd cop cr); 14046 effect(USE labl); 14047 14048 ins_cost(300); 14049 format %{ "j$cop $labl\t# loop end" %} 14050 size(6); 14051 ins_encode %{ 14052 Label* L = $labl$$label; 14053 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 14054 %} 14055 ins_pipe(pipe_jcc); 14056 %} 14057 14058 // Jump Direct Conditional - using unsigned comparison 14059 instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 14060 match(If cop cmp); 14061 effect(USE labl); 14062 14063 ins_cost(300); 14064 format %{ "j$cop,u $labl" %} 14065 size(6); 14066 ins_encode %{ 14067 Label* L = $labl$$label; 14068 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 14069 %} 14070 ins_pipe(pipe_jcc); 14071 %} 14072 14073 instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 14074 match(If cop cmp); 14075 effect(USE labl); 14076 14077 ins_cost(200); 14078 format %{ "j$cop,u $labl" %} 14079 size(6); 14080 ins_encode %{ 14081 Label* L = $labl$$label; 14082 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 14083 %} 14084 ins_pipe(pipe_jcc); 14085 %} 14086 14087 instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 14088 match(If cop cmp); 14089 effect(USE labl); 14090 14091 ins_cost(200); 14092 format %{ $$template 14093 if ($cop$$cmpcode == Assembler::notEqual) { 14094 $$emit$$"jp,u $labl\n\t" 14095 $$emit$$"j$cop,u $labl" 14096 } else { 14097 $$emit$$"jp,u done\n\t" 14098 $$emit$$"j$cop,u $labl\n\t" 14099 $$emit$$"done:" 14100 } 14101 %} 14102 ins_encode %{ 14103 Label* l = $labl$$label; 14104 if ($cop$$cmpcode == Assembler::notEqual) { 14105 __ jcc(Assembler::parity, *l, false); 14106 __ jcc(Assembler::notEqual, *l, false); 14107 } else if ($cop$$cmpcode == Assembler::equal) { 14108 Label done; 14109 __ jccb(Assembler::parity, done); 14110 __ jcc(Assembler::equal, *l, false); 14111 __ bind(done); 14112 } else { 14113 ShouldNotReachHere(); 14114 } 14115 %} 14116 ins_pipe(pipe_jcc); 14117 %} 14118 14119 // ============================================================================ 14120 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary 14121 // superklass array for an instance of the superklass. Set a hidden 14122 // internal cache on a hit (cache is checked with exposed code in 14123 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The 14124 // encoding ALSO sets flags. 14125 14126 instruct partialSubtypeCheck(rdi_RegP result, 14127 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 14128 rFlagsReg cr) 14129 %{ 14130 match(Set result (PartialSubtypeCheck sub super)); 14131 predicate(!UseSecondarySupersTable); 14132 effect(KILL rcx, KILL cr); 14133 14134 ins_cost(1100); // slightly larger than the next version 14135 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 14136 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 14137 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 14138 "repne scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t" 14139 "jne,s miss\t\t# Missed: rdi not-zero\n\t" 14140 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 14141 "xorq $result, $result\t\t Hit: rdi zero\n\t" 14142 "miss:\t" %} 14143 14144 ins_encode %{ 14145 Label miss; 14146 // NB: Callers may assume that, when $result is a valid register, 14147 // check_klass_subtype_slow_path_linear sets it to a nonzero 14148 // value. 14149 __ check_klass_subtype_slow_path_linear($sub$$Register, $super$$Register, 14150 $rcx$$Register, $result$$Register, 14151 nullptr, &miss, 14152 /*set_cond_codes:*/ true); 14153 __ xorptr($result$$Register, $result$$Register); 14154 __ bind(miss); 14155 %} 14156 14157 ins_pipe(pipe_slow); 14158 %} 14159 14160 // ============================================================================ 14161 // Two versions of hashtable-based partialSubtypeCheck, both used when 14162 // we need to search for a super class in the secondary supers array. 14163 // The first is used when we don't know _a priori_ the class being 14164 // searched for. The second, far more common, is used when we do know: 14165 // this is used for instanceof, checkcast, and any case where C2 can 14166 // determine it by constant propagation. 14167 14168 instruct partialSubtypeCheckVarSuper(rsi_RegP sub, rax_RegP super, rdi_RegP result, 14169 rdx_RegL temp1, rcx_RegL temp2, rbx_RegP temp3, r11_RegL temp4, 14170 rFlagsReg cr) 14171 %{ 14172 match(Set result (PartialSubtypeCheck sub super)); 14173 predicate(UseSecondarySupersTable); 14174 effect(KILL cr, TEMP temp1, TEMP temp2, TEMP temp3, TEMP temp4); 14175 14176 ins_cost(1000); 14177 format %{ "partialSubtypeCheck $result, $sub, $super" %} 14178 14179 ins_encode %{ 14180 __ lookup_secondary_supers_table_var($sub$$Register, $super$$Register, $temp1$$Register, $temp2$$Register, 14181 $temp3$$Register, $temp4$$Register, $result$$Register); 14182 %} 14183 14184 ins_pipe(pipe_slow); 14185 %} 14186 14187 instruct partialSubtypeCheckConstSuper(rsi_RegP sub, rax_RegP super_reg, immP super_con, rdi_RegP result, 14188 rdx_RegL temp1, rcx_RegL temp2, rbx_RegP temp3, r11_RegL temp4, 14189 rFlagsReg cr) 14190 %{ 14191 match(Set result (PartialSubtypeCheck sub (Binary super_reg super_con))); 14192 predicate(UseSecondarySupersTable); 14193 effect(KILL cr, TEMP temp1, TEMP temp2, TEMP temp3, TEMP temp4); 14194 14195 ins_cost(700); // smaller than the next version 14196 format %{ "partialSubtypeCheck $result, $sub, $super_reg, $super_con" %} 14197 14198 ins_encode %{ 14199 u1 super_klass_slot = ((Klass*)$super_con$$constant)->hash_slot(); 14200 if (InlineSecondarySupersTest) { 14201 __ lookup_secondary_supers_table_const($sub$$Register, $super_reg$$Register, $temp1$$Register, $temp2$$Register, 14202 $temp3$$Register, $temp4$$Register, $result$$Register, 14203 super_klass_slot); 14204 } else { 14205 __ call(RuntimeAddress(StubRoutines::lookup_secondary_supers_table_stub(super_klass_slot))); 14206 } 14207 %} 14208 14209 ins_pipe(pipe_slow); 14210 %} 14211 14212 // ============================================================================ 14213 // Branch Instructions -- short offset versions 14214 // 14215 // These instructions are used to replace jumps of a long offset (the default 14216 // match) with jumps of a shorter offset. These instructions are all tagged 14217 // with the ins_short_branch attribute, which causes the ADLC to suppress the 14218 // match rules in general matching. Instead, the ADLC generates a conversion 14219 // method in the MachNode which can be used to do in-place replacement of the 14220 // long variant with the shorter variant. The compiler will determine if a 14221 // branch can be taken by the is_short_branch_offset() predicate in the machine 14222 // specific code section of the file. 14223 14224 // Jump Direct - Label defines a relative address from JMP+1 14225 instruct jmpDir_short(label labl) %{ 14226 match(Goto); 14227 effect(USE labl); 14228 14229 ins_cost(300); 14230 format %{ "jmp,s $labl" %} 14231 size(2); 14232 ins_encode %{ 14233 Label* L = $labl$$label; 14234 __ jmpb(*L); 14235 %} 14236 ins_pipe(pipe_jmp); 14237 ins_short_branch(1); 14238 %} 14239 14240 // Jump Direct Conditional - Label defines a relative address from Jcc+1 14241 instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{ 14242 match(If cop cr); 14243 effect(USE labl); 14244 14245 ins_cost(300); 14246 format %{ "j$cop,s $labl" %} 14247 size(2); 14248 ins_encode %{ 14249 Label* L = $labl$$label; 14250 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 14251 %} 14252 ins_pipe(pipe_jcc); 14253 ins_short_branch(1); 14254 %} 14255 14256 // Jump Direct Conditional - Label defines a relative address from Jcc+1 14257 instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{ 14258 match(CountedLoopEnd cop cr); 14259 effect(USE labl); 14260 14261 ins_cost(300); 14262 format %{ "j$cop,s $labl\t# loop end" %} 14263 size(2); 14264 ins_encode %{ 14265 Label* L = $labl$$label; 14266 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 14267 %} 14268 ins_pipe(pipe_jcc); 14269 ins_short_branch(1); 14270 %} 14271 14272 // Jump Direct Conditional - using unsigned comparison 14273 instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 14274 match(If cop cmp); 14275 effect(USE labl); 14276 14277 ins_cost(300); 14278 format %{ "j$cop,us $labl" %} 14279 size(2); 14280 ins_encode %{ 14281 Label* L = $labl$$label; 14282 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 14283 %} 14284 ins_pipe(pipe_jcc); 14285 ins_short_branch(1); 14286 %} 14287 14288 instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 14289 match(If cop cmp); 14290 effect(USE labl); 14291 14292 ins_cost(300); 14293 format %{ "j$cop,us $labl" %} 14294 size(2); 14295 ins_encode %{ 14296 Label* L = $labl$$label; 14297 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 14298 %} 14299 ins_pipe(pipe_jcc); 14300 ins_short_branch(1); 14301 %} 14302 14303 instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 14304 match(If cop cmp); 14305 effect(USE labl); 14306 14307 ins_cost(300); 14308 format %{ $$template 14309 if ($cop$$cmpcode == Assembler::notEqual) { 14310 $$emit$$"jp,u,s $labl\n\t" 14311 $$emit$$"j$cop,u,s $labl" 14312 } else { 14313 $$emit$$"jp,u,s done\n\t" 14314 $$emit$$"j$cop,u,s $labl\n\t" 14315 $$emit$$"done:" 14316 } 14317 %} 14318 size(4); 14319 ins_encode %{ 14320 Label* l = $labl$$label; 14321 if ($cop$$cmpcode == Assembler::notEqual) { 14322 __ jccb(Assembler::parity, *l); 14323 __ jccb(Assembler::notEqual, *l); 14324 } else if ($cop$$cmpcode == Assembler::equal) { 14325 Label done; 14326 __ jccb(Assembler::parity, done); 14327 __ jccb(Assembler::equal, *l); 14328 __ bind(done); 14329 } else { 14330 ShouldNotReachHere(); 14331 } 14332 %} 14333 ins_pipe(pipe_jcc); 14334 ins_short_branch(1); 14335 %} 14336 14337 // ============================================================================ 14338 // inlined locking and unlocking 14339 14340 instruct cmpFastLock(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr) %{ 14341 predicate(LockingMode != LM_LIGHTWEIGHT); 14342 match(Set cr (FastLock object box)); 14343 effect(TEMP tmp, TEMP scr, USE_KILL box); 14344 ins_cost(300); 14345 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr" %} 14346 ins_encode %{ 14347 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, 14348 $scr$$Register, noreg, noreg, r15_thread, nullptr); 14349 %} 14350 ins_pipe(pipe_slow); 14351 %} 14352 14353 instruct cmpFastUnlock(rFlagsReg cr, rRegP object, rax_RegP box, rRegP tmp) %{ 14354 predicate(LockingMode != LM_LIGHTWEIGHT); 14355 match(Set cr (FastUnlock object box)); 14356 effect(TEMP tmp, USE_KILL box); 14357 ins_cost(300); 14358 format %{ "fastunlock $object,$box\t! kills $box,$tmp" %} 14359 ins_encode %{ 14360 __ fast_unlock($object$$Register, $box$$Register, $tmp$$Register); 14361 %} 14362 ins_pipe(pipe_slow); 14363 %} 14364 14365 instruct cmpFastLockLightweight(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI rax_reg, rRegP tmp) %{ 14366 predicate(LockingMode == LM_LIGHTWEIGHT); 14367 match(Set cr (FastLock object box)); 14368 effect(TEMP rax_reg, TEMP tmp, USE_KILL box); 14369 ins_cost(300); 14370 format %{ "fastlock $object,$box\t! kills $box,$rax_reg,$tmp" %} 14371 ins_encode %{ 14372 __ fast_lock_lightweight($object$$Register, $box$$Register, $rax_reg$$Register, $tmp$$Register, r15_thread); 14373 %} 14374 ins_pipe(pipe_slow); 14375 %} 14376 14377 instruct cmpFastUnlockLightweight(rFlagsReg cr, rRegP object, rax_RegP rax_reg, rRegP tmp) %{ 14378 predicate(LockingMode == LM_LIGHTWEIGHT); 14379 match(Set cr (FastUnlock object rax_reg)); 14380 effect(TEMP tmp, USE_KILL rax_reg); 14381 ins_cost(300); 14382 format %{ "fastunlock $object,$rax_reg\t! kills $rax_reg,$tmp" %} 14383 ins_encode %{ 14384 __ fast_unlock_lightweight($object$$Register, $rax_reg$$Register, $tmp$$Register, r15_thread); 14385 %} 14386 ins_pipe(pipe_slow); 14387 %} 14388 14389 14390 // ============================================================================ 14391 // Safepoint Instructions 14392 instruct safePoint_poll_tls(rFlagsReg cr, rRegP poll) 14393 %{ 14394 match(SafePoint poll); 14395 effect(KILL cr, USE poll); 14396 14397 format %{ "testl rax, [$poll]\t" 14398 "# Safepoint: poll for GC" %} 14399 ins_cost(125); 14400 ins_encode %{ 14401 __ relocate(relocInfo::poll_type); 14402 address pre_pc = __ pc(); 14403 __ testl(rax, Address($poll$$Register, 0)); 14404 assert(nativeInstruction_at(pre_pc)->is_safepoint_poll(), "must emit test %%eax [reg]"); 14405 %} 14406 ins_pipe(ialu_reg_mem); 14407 %} 14408 14409 instruct mask_all_evexL(kReg dst, rRegL src) %{ 14410 match(Set dst (MaskAll src)); 14411 format %{ "mask_all_evexL $dst, $src \t! mask all operation" %} 14412 ins_encode %{ 14413 int mask_len = Matcher::vector_length(this); 14414 __ vector_maskall_operation($dst$$KRegister, $src$$Register, mask_len); 14415 %} 14416 ins_pipe( pipe_slow ); 14417 %} 14418 14419 instruct mask_all_evexI_GT32(kReg dst, rRegI src, rRegL tmp) %{ 14420 predicate(Matcher::vector_length(n) > 32); 14421 match(Set dst (MaskAll src)); 14422 effect(TEMP tmp); 14423 format %{ "mask_all_evexI_GT32 $dst, $src \t! using $tmp as TEMP" %} 14424 ins_encode %{ 14425 int mask_len = Matcher::vector_length(this); 14426 __ movslq($tmp$$Register, $src$$Register); 14427 __ vector_maskall_operation($dst$$KRegister, $tmp$$Register, mask_len); 14428 %} 14429 ins_pipe( pipe_slow ); 14430 %} 14431 14432 // ============================================================================ 14433 // Procedure Call/Return Instructions 14434 // Call Java Static Instruction 14435 // Note: If this code changes, the corresponding ret_addr_offset() and 14436 // compute_padding() functions will have to be adjusted. 14437 instruct CallStaticJavaDirect(method meth) %{ 14438 match(CallStaticJava); 14439 effect(USE meth); 14440 14441 ins_cost(300); 14442 format %{ "call,static " %} 14443 opcode(0xE8); /* E8 cd */ 14444 ins_encode(clear_avx, Java_Static_Call(meth), call_epilog); 14445 ins_pipe(pipe_slow); 14446 ins_alignment(4); 14447 %} 14448 14449 // Call Java Dynamic Instruction 14450 // Note: If this code changes, the corresponding ret_addr_offset() and 14451 // compute_padding() functions will have to be adjusted. 14452 instruct CallDynamicJavaDirect(method meth) 14453 %{ 14454 match(CallDynamicJava); 14455 effect(USE meth); 14456 14457 ins_cost(300); 14458 format %{ "movq rax, #Universe::non_oop_word()\n\t" 14459 "call,dynamic " %} 14460 ins_encode(clear_avx, Java_Dynamic_Call(meth), call_epilog); 14461 ins_pipe(pipe_slow); 14462 ins_alignment(4); 14463 %} 14464 14465 // Call Runtime Instruction 14466 instruct CallRuntimeDirect(method meth) 14467 %{ 14468 match(CallRuntime); 14469 effect(USE meth); 14470 14471 ins_cost(300); 14472 format %{ "call,runtime " %} 14473 ins_encode(clear_avx, Java_To_Runtime(meth)); 14474 ins_pipe(pipe_slow); 14475 %} 14476 14477 // Call runtime without safepoint 14478 instruct CallLeafDirect(method meth) 14479 %{ 14480 match(CallLeaf); 14481 effect(USE meth); 14482 14483 ins_cost(300); 14484 format %{ "call_leaf,runtime " %} 14485 ins_encode(clear_avx, Java_To_Runtime(meth)); 14486 ins_pipe(pipe_slow); 14487 %} 14488 14489 // Call runtime without safepoint and with vector arguments 14490 instruct CallLeafDirectVector(method meth) 14491 %{ 14492 match(CallLeafVector); 14493 effect(USE meth); 14494 14495 ins_cost(300); 14496 format %{ "call_leaf,vector " %} 14497 ins_encode(Java_To_Runtime(meth)); 14498 ins_pipe(pipe_slow); 14499 %} 14500 14501 // Call runtime without safepoint 14502 // entry point is null, target holds the address to call 14503 instruct CallLeafNoFPInDirect(rRegP target) 14504 %{ 14505 predicate(n->as_Call()->entry_point() == nullptr); 14506 match(CallLeafNoFP target); 14507 14508 ins_cost(300); 14509 format %{ "call_leaf_nofp,runtime indirect " %} 14510 ins_encode %{ 14511 __ call($target$$Register); 14512 %} 14513 14514 ins_pipe(pipe_slow); 14515 %} 14516 14517 instruct CallLeafNoFPDirect(method meth) 14518 %{ 14519 predicate(n->as_Call()->entry_point() != nullptr); 14520 match(CallLeafNoFP); 14521 effect(USE meth); 14522 14523 ins_cost(300); 14524 format %{ "call_leaf_nofp,runtime " %} 14525 ins_encode(clear_avx, Java_To_Runtime(meth)); 14526 ins_pipe(pipe_slow); 14527 %} 14528 14529 // Return Instruction 14530 // Remove the return address & jump to it. 14531 // Notice: We always emit a nop after a ret to make sure there is room 14532 // for safepoint patching 14533 instruct Ret() 14534 %{ 14535 match(Return); 14536 14537 format %{ "ret" %} 14538 ins_encode %{ 14539 __ ret(0); 14540 %} 14541 ins_pipe(pipe_jmp); 14542 %} 14543 14544 // Tail Call; Jump from runtime stub to Java code. 14545 // Also known as an 'interprocedural jump'. 14546 // Target of jump will eventually return to caller. 14547 // TailJump below removes the return address. 14548 // Don't use rbp for 'jump_target' because a MachEpilogNode has already been 14549 // emitted just above the TailCall which has reset rbp to the caller state. 14550 instruct TailCalljmpInd(no_rbp_RegP jump_target, rbx_RegP method_ptr) 14551 %{ 14552 match(TailCall jump_target method_ptr); 14553 14554 ins_cost(300); 14555 format %{ "jmp $jump_target\t# rbx holds method" %} 14556 ins_encode %{ 14557 __ jmp($jump_target$$Register); 14558 %} 14559 ins_pipe(pipe_jmp); 14560 %} 14561 14562 // Tail Jump; remove the return address; jump to target. 14563 // TailCall above leaves the return address around. 14564 instruct tailjmpInd(no_rbp_RegP jump_target, rax_RegP ex_oop) 14565 %{ 14566 match(TailJump jump_target ex_oop); 14567 14568 ins_cost(300); 14569 format %{ "popq rdx\t# pop return address\n\t" 14570 "jmp $jump_target" %} 14571 ins_encode %{ 14572 __ popq(as_Register(RDX_enc)); 14573 __ jmp($jump_target$$Register); 14574 %} 14575 ins_pipe(pipe_jmp); 14576 %} 14577 14578 // Forward exception. 14579 instruct ForwardExceptionjmp() 14580 %{ 14581 match(ForwardException); 14582 14583 format %{ "jmp forward_exception_stub" %} 14584 ins_encode %{ 14585 __ jump(RuntimeAddress(StubRoutines::forward_exception_entry()), noreg); 14586 %} 14587 ins_pipe(pipe_jmp); 14588 %} 14589 14590 // Create exception oop: created by stack-crawling runtime code. 14591 // Created exception is now available to this handler, and is setup 14592 // just prior to jumping to this handler. No code emitted. 14593 instruct CreateException(rax_RegP ex_oop) 14594 %{ 14595 match(Set ex_oop (CreateEx)); 14596 14597 size(0); 14598 // use the following format syntax 14599 format %{ "# exception oop is in rax; no code emitted" %} 14600 ins_encode(); 14601 ins_pipe(empty); 14602 %} 14603 14604 // Rethrow exception: 14605 // The exception oop will come in the first argument position. 14606 // Then JUMP (not call) to the rethrow stub code. 14607 instruct RethrowException() 14608 %{ 14609 match(Rethrow); 14610 14611 // use the following format syntax 14612 format %{ "jmp rethrow_stub" %} 14613 ins_encode %{ 14614 __ jump(RuntimeAddress(OptoRuntime::rethrow_stub()), noreg); 14615 %} 14616 ins_pipe(pipe_jmp); 14617 %} 14618 14619 // ============================================================================ 14620 // This name is KNOWN by the ADLC and cannot be changed. 14621 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type 14622 // for this guy. 14623 instruct tlsLoadP(r15_RegP dst) %{ 14624 match(Set dst (ThreadLocal)); 14625 effect(DEF dst); 14626 14627 size(0); 14628 format %{ "# TLS is in R15" %} 14629 ins_encode( /*empty encoding*/ ); 14630 ins_pipe(ialu_reg_reg); 14631 %} 14632 14633 14634 //----------PEEPHOLE RULES----------------------------------------------------- 14635 // These must follow all instruction definitions as they use the names 14636 // defined in the instructions definitions. 14637 // 14638 // peeppredicate ( rule_predicate ); 14639 // // the predicate unless which the peephole rule will be ignored 14640 // 14641 // peepmatch ( root_instr_name [preceding_instruction]* ); 14642 // 14643 // peepprocedure ( procedure_name ); 14644 // // provide a procedure name to perform the optimization, the procedure should 14645 // // reside in the architecture dependent peephole file, the method has the 14646 // // signature of MachNode* (Block*, int, PhaseRegAlloc*, (MachNode*)(*)(), int...) 14647 // // with the arguments being the basic block, the current node index inside the 14648 // // block, the register allocator, the functions upon invoked return a new node 14649 // // defined in peepreplace, and the rules of the nodes appearing in the 14650 // // corresponding peepmatch, the function return true if successful, else 14651 // // return false 14652 // 14653 // peepconstraint %{ 14654 // (instruction_number.operand_name relational_op instruction_number.operand_name 14655 // [, ...] ); 14656 // // instruction numbers are zero-based using left to right order in peepmatch 14657 // 14658 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 14659 // // provide an instruction_number.operand_name for each operand that appears 14660 // // in the replacement instruction's match rule 14661 // 14662 // ---------VM FLAGS--------------------------------------------------------- 14663 // 14664 // All peephole optimizations can be turned off using -XX:-OptoPeephole 14665 // 14666 // Each peephole rule is given an identifying number starting with zero and 14667 // increasing by one in the order seen by the parser. An individual peephole 14668 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 14669 // on the command-line. 14670 // 14671 // ---------CURRENT LIMITATIONS---------------------------------------------- 14672 // 14673 // Only transformations inside a basic block (do we need more for peephole) 14674 // 14675 // ---------EXAMPLE---------------------------------------------------------- 14676 // 14677 // // pertinent parts of existing instructions in architecture description 14678 // instruct movI(rRegI dst, rRegI src) 14679 // %{ 14680 // match(Set dst (CopyI src)); 14681 // %} 14682 // 14683 // instruct incI_rReg(rRegI dst, immI_1 src, rFlagsReg cr) 14684 // %{ 14685 // match(Set dst (AddI dst src)); 14686 // effect(KILL cr); 14687 // %} 14688 // 14689 // instruct leaI_rReg_immI(rRegI dst, immI_1 src) 14690 // %{ 14691 // match(Set dst (AddI dst src)); 14692 // %} 14693 // 14694 // 1. Simple replacement 14695 // - Only match adjacent instructions in same basic block 14696 // - Only equality constraints 14697 // - Only constraints between operands, not (0.dest_reg == RAX_enc) 14698 // - Only one replacement instruction 14699 // 14700 // // Change (inc mov) to lea 14701 // peephole %{ 14702 // // lea should only be emitted when beneficial 14703 // peeppredicate( VM_Version::supports_fast_2op_lea() ); 14704 // // increment preceded by register-register move 14705 // peepmatch ( incI_rReg movI ); 14706 // // require that the destination register of the increment 14707 // // match the destination register of the move 14708 // peepconstraint ( 0.dst == 1.dst ); 14709 // // construct a replacement instruction that sets 14710 // // the destination to ( move's source register + one ) 14711 // peepreplace ( leaI_rReg_immI( 0.dst 1.src 0.src ) ); 14712 // %} 14713 // 14714 // 2. Procedural replacement 14715 // - More flexible finding relevent nodes 14716 // - More flexible constraints 14717 // - More flexible transformations 14718 // - May utilise architecture-dependent API more effectively 14719 // - Currently only one replacement instruction due to adlc parsing capabilities 14720 // 14721 // // Change (inc mov) to lea 14722 // peephole %{ 14723 // // lea should only be emitted when beneficial 14724 // peeppredicate( VM_Version::supports_fast_2op_lea() ); 14725 // // the rule numbers of these nodes inside are passed into the function below 14726 // peepmatch ( incI_rReg movI ); 14727 // // the method that takes the responsibility of transformation 14728 // peepprocedure ( inc_mov_to_lea ); 14729 // // the replacement is a leaI_rReg_immI, a lambda upon invoked creating this 14730 // // node is passed into the function above 14731 // peepreplace ( leaI_rReg_immI() ); 14732 // %} 14733 14734 // These instructions is not matched by the matcher but used by the peephole 14735 instruct leaI_rReg_rReg_peep(rRegI dst, rRegI src1, rRegI src2) 14736 %{ 14737 predicate(false); 14738 match(Set dst (AddI src1 src2)); 14739 format %{ "leal $dst, [$src1 + $src2]" %} 14740 ins_encode %{ 14741 Register dst = $dst$$Register; 14742 Register src1 = $src1$$Register; 14743 Register src2 = $src2$$Register; 14744 if (src1 != rbp && src1 != r13) { 14745 __ leal(dst, Address(src1, src2, Address::times_1)); 14746 } else { 14747 assert(src2 != rbp && src2 != r13, ""); 14748 __ leal(dst, Address(src2, src1, Address::times_1)); 14749 } 14750 %} 14751 ins_pipe(ialu_reg_reg); 14752 %} 14753 14754 instruct leaI_rReg_immI_peep(rRegI dst, rRegI src1, immI src2) 14755 %{ 14756 predicate(false); 14757 match(Set dst (AddI src1 src2)); 14758 format %{ "leal $dst, [$src1 + $src2]" %} 14759 ins_encode %{ 14760 __ leal($dst$$Register, Address($src1$$Register, $src2$$constant)); 14761 %} 14762 ins_pipe(ialu_reg_reg); 14763 %} 14764 14765 instruct leaI_rReg_immI2_peep(rRegI dst, rRegI src, immI2 shift) 14766 %{ 14767 predicate(false); 14768 match(Set dst (LShiftI src shift)); 14769 format %{ "leal $dst, [$src << $shift]" %} 14770 ins_encode %{ 14771 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($shift$$constant); 14772 Register src = $src$$Register; 14773 if (scale == Address::times_2 && src != rbp && src != r13) { 14774 __ leal($dst$$Register, Address(src, src, Address::times_1)); 14775 } else { 14776 __ leal($dst$$Register, Address(noreg, src, scale)); 14777 } 14778 %} 14779 ins_pipe(ialu_reg_reg); 14780 %} 14781 14782 instruct leaL_rReg_rReg_peep(rRegL dst, rRegL src1, rRegL src2) 14783 %{ 14784 predicate(false); 14785 match(Set dst (AddL src1 src2)); 14786 format %{ "leaq $dst, [$src1 + $src2]" %} 14787 ins_encode %{ 14788 Register dst = $dst$$Register; 14789 Register src1 = $src1$$Register; 14790 Register src2 = $src2$$Register; 14791 if (src1 != rbp && src1 != r13) { 14792 __ leaq(dst, Address(src1, src2, Address::times_1)); 14793 } else { 14794 assert(src2 != rbp && src2 != r13, ""); 14795 __ leaq(dst, Address(src2, src1, Address::times_1)); 14796 } 14797 %} 14798 ins_pipe(ialu_reg_reg); 14799 %} 14800 14801 instruct leaL_rReg_immL32_peep(rRegL dst, rRegL src1, immL32 src2) 14802 %{ 14803 predicate(false); 14804 match(Set dst (AddL src1 src2)); 14805 format %{ "leaq $dst, [$src1 + $src2]" %} 14806 ins_encode %{ 14807 __ leaq($dst$$Register, Address($src1$$Register, $src2$$constant)); 14808 %} 14809 ins_pipe(ialu_reg_reg); 14810 %} 14811 14812 instruct leaL_rReg_immI2_peep(rRegL dst, rRegL src, immI2 shift) 14813 %{ 14814 predicate(false); 14815 match(Set dst (LShiftL src shift)); 14816 format %{ "leaq $dst, [$src << $shift]" %} 14817 ins_encode %{ 14818 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($shift$$constant); 14819 Register src = $src$$Register; 14820 if (scale == Address::times_2 && src != rbp && src != r13) { 14821 __ leaq($dst$$Register, Address(src, src, Address::times_1)); 14822 } else { 14823 __ leaq($dst$$Register, Address(noreg, src, scale)); 14824 } 14825 %} 14826 ins_pipe(ialu_reg_reg); 14827 %} 14828 14829 // These peephole rules replace mov + I pairs (where I is one of {add, inc, dec, 14830 // sal}) with lea instructions. The {add, sal} rules are beneficial in 14831 // processors with at least partial ALU support for lea 14832 // (supports_fast_2op_lea()), whereas the {inc, dec} rules are only generally 14833 // beneficial for processors with full ALU support 14834 // (VM_Version::supports_fast_3op_lea()) and Intel Cascade Lake. 14835 14836 peephole 14837 %{ 14838 peeppredicate(VM_Version::supports_fast_2op_lea()); 14839 peepmatch (addI_rReg); 14840 peepprocedure (lea_coalesce_reg); 14841 peepreplace (leaI_rReg_rReg_peep()); 14842 %} 14843 14844 peephole 14845 %{ 14846 peeppredicate(VM_Version::supports_fast_2op_lea()); 14847 peepmatch (addI_rReg_imm); 14848 peepprocedure (lea_coalesce_imm); 14849 peepreplace (leaI_rReg_immI_peep()); 14850 %} 14851 14852 peephole 14853 %{ 14854 peeppredicate(VM_Version::supports_fast_3op_lea() || 14855 VM_Version::is_intel_cascade_lake()); 14856 peepmatch (incI_rReg); 14857 peepprocedure (lea_coalesce_imm); 14858 peepreplace (leaI_rReg_immI_peep()); 14859 %} 14860 14861 peephole 14862 %{ 14863 peeppredicate(VM_Version::supports_fast_3op_lea() || 14864 VM_Version::is_intel_cascade_lake()); 14865 peepmatch (decI_rReg); 14866 peepprocedure (lea_coalesce_imm); 14867 peepreplace (leaI_rReg_immI_peep()); 14868 %} 14869 14870 peephole 14871 %{ 14872 peeppredicate(VM_Version::supports_fast_2op_lea()); 14873 peepmatch (salI_rReg_immI2); 14874 peepprocedure (lea_coalesce_imm); 14875 peepreplace (leaI_rReg_immI2_peep()); 14876 %} 14877 14878 peephole 14879 %{ 14880 peeppredicate(VM_Version::supports_fast_2op_lea()); 14881 peepmatch (addL_rReg); 14882 peepprocedure (lea_coalesce_reg); 14883 peepreplace (leaL_rReg_rReg_peep()); 14884 %} 14885 14886 peephole 14887 %{ 14888 peeppredicate(VM_Version::supports_fast_2op_lea()); 14889 peepmatch (addL_rReg_imm); 14890 peepprocedure (lea_coalesce_imm); 14891 peepreplace (leaL_rReg_immL32_peep()); 14892 %} 14893 14894 peephole 14895 %{ 14896 peeppredicate(VM_Version::supports_fast_3op_lea() || 14897 VM_Version::is_intel_cascade_lake()); 14898 peepmatch (incL_rReg); 14899 peepprocedure (lea_coalesce_imm); 14900 peepreplace (leaL_rReg_immL32_peep()); 14901 %} 14902 14903 peephole 14904 %{ 14905 peeppredicate(VM_Version::supports_fast_3op_lea() || 14906 VM_Version::is_intel_cascade_lake()); 14907 peepmatch (decL_rReg); 14908 peepprocedure (lea_coalesce_imm); 14909 peepreplace (leaL_rReg_immL32_peep()); 14910 %} 14911 14912 peephole 14913 %{ 14914 peeppredicate(VM_Version::supports_fast_2op_lea()); 14915 peepmatch (salL_rReg_immI2); 14916 peepprocedure (lea_coalesce_imm); 14917 peepreplace (leaL_rReg_immI2_peep()); 14918 %} 14919 14920 peephole 14921 %{ 14922 peepmatch (leaPCompressedOopOffset); 14923 peepprocedure (lea_remove_redundant); 14924 %} 14925 14926 peephole 14927 %{ 14928 peepmatch (leaP8Narrow); 14929 peepprocedure (lea_remove_redundant); 14930 %} 14931 14932 peephole 14933 %{ 14934 peepmatch (leaP32Narrow); 14935 peepprocedure (lea_remove_redundant); 14936 %} 14937 14938 // These peephole rules matches instructions which set flags and are followed by a testI/L_reg 14939 // 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 14940 14941 //int variant 14942 peephole 14943 %{ 14944 peepmatch (testI_reg); 14945 peepprocedure (test_may_remove); 14946 %} 14947 14948 //long variant 14949 peephole 14950 %{ 14951 peepmatch (testL_reg); 14952 peepprocedure (test_may_remove); 14953 %} 14954 14955 14956 //----------SMARTSPILL RULES--------------------------------------------------- 14957 // These must follow all instruction definitions as they use the names 14958 // defined in the instructions definitions.