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 // No relocation needed 1872 __ mov64(r10, (int64_t) $meth$$method); 1873 __ call(r10); 1874 __ post_call_nop(); 1875 %} 1876 1877 enc_class Java_Static_Call(method meth) 1878 %{ 1879 // JAVA STATIC CALL 1880 // CALL to fixup routine. Fixup routine uses ScopeDesc info to 1881 // determine who we intended to call. 1882 if (!_method) { 1883 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, $meth$$method))); 1884 } else if (_method->intrinsic_id() == vmIntrinsicID::_ensureMaterializedForStackWalk) { 1885 // The NOP here is purely to ensure that eliding a call to 1886 // JVM_EnsureMaterializedForStackWalk doesn't change the code size. 1887 __ addr_nop_5(); 1888 __ block_comment("call JVM_EnsureMaterializedForStackWalk (elided)"); 1889 } else { 1890 int method_index = resolved_method_index(masm); 1891 RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 1892 : static_call_Relocation::spec(method_index); 1893 address mark = __ pc(); 1894 int call_offset = __ offset(); 1895 __ call(AddressLiteral(CAST_FROM_FN_PTR(address, $meth$$method), rspec)); 1896 if (CodeBuffer::supports_shared_stubs() && _method->can_be_statically_bound()) { 1897 // Calls of the same statically bound method can share 1898 // a stub to the interpreter. 1899 __ code()->shared_stub_to_interp_for(_method, call_offset); 1900 } else { 1901 // Emit stubs for static call. 1902 address stub = CompiledDirectCall::emit_to_interp_stub(masm, mark); 1903 __ clear_inst_mark(); 1904 if (stub == nullptr) { 1905 ciEnv::current()->record_failure("CodeCache is full"); 1906 return; 1907 } 1908 } 1909 } 1910 __ post_call_nop(); 1911 %} 1912 1913 enc_class Java_Dynamic_Call(method meth) %{ 1914 __ ic_call((address)$meth$$method, resolved_method_index(masm)); 1915 __ post_call_nop(); 1916 %} 1917 1918 %} 1919 1920 1921 1922 //----------FRAME-------------------------------------------------------------- 1923 // Definition of frame structure and management information. 1924 // 1925 // S T A C K L A Y O U T Allocators stack-slot number 1926 // | (to get allocators register number 1927 // G Owned by | | v add OptoReg::stack0()) 1928 // r CALLER | | 1929 // o | +--------+ pad to even-align allocators stack-slot 1930 // w V | pad0 | numbers; owned by CALLER 1931 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned 1932 // h ^ | in | 5 1933 // | | args | 4 Holes in incoming args owned by SELF 1934 // | | | | 3 1935 // | | +--------+ 1936 // V | | old out| Empty on Intel, window on Sparc 1937 // | old |preserve| Must be even aligned. 1938 // | SP-+--------+----> Matcher::_old_SP, even aligned 1939 // | | in | 3 area for Intel ret address 1940 // Owned by |preserve| Empty on Sparc. 1941 // SELF +--------+ 1942 // | | pad2 | 2 pad to align old SP 1943 // | +--------+ 1 1944 // | | locks | 0 1945 // | +--------+----> OptoReg::stack0(), even aligned 1946 // | | pad1 | 11 pad to align new SP 1947 // | +--------+ 1948 // | | | 10 1949 // | | spills | 9 spills 1950 // V | | 8 (pad0 slot for callee) 1951 // -----------+--------+----> Matcher::_out_arg_limit, unaligned 1952 // ^ | out | 7 1953 // | | args | 6 Holes in outgoing args owned by CALLEE 1954 // Owned by +--------+ 1955 // CALLEE | new out| 6 Empty on Intel, window on Sparc 1956 // | new |preserve| Must be even-aligned. 1957 // | SP-+--------+----> Matcher::_new_SP, even aligned 1958 // | | | 1959 // 1960 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 1961 // known from SELF's arguments and the Java calling convention. 1962 // Region 6-7 is determined per call site. 1963 // Note 2: If the calling convention leaves holes in the incoming argument 1964 // area, those holes are owned by SELF. Holes in the outgoing area 1965 // are owned by the CALLEE. Holes should not be necessary in the 1966 // incoming area, as the Java calling convention is completely under 1967 // the control of the AD file. Doubles can be sorted and packed to 1968 // avoid holes. Holes in the outgoing arguments may be necessary for 1969 // varargs C calling conventions. 1970 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 1971 // even aligned with pad0 as needed. 1972 // Region 6 is even aligned. Region 6-7 is NOT even aligned; 1973 // region 6-11 is even aligned; it may be padded out more so that 1974 // the region from SP to FP meets the minimum stack alignment. 1975 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 1976 // alignment. Region 11, pad1, may be dynamically extended so that 1977 // SP meets the minimum alignment. 1978 1979 frame 1980 %{ 1981 // These three registers define part of the calling convention 1982 // between compiled code and the interpreter. 1983 inline_cache_reg(RAX); // Inline Cache Register 1984 1985 // Optional: name the operand used by cisc-spilling to access 1986 // [stack_pointer + offset] 1987 cisc_spilling_operand_name(indOffset32); 1988 1989 // Number of stack slots consumed by locking an object 1990 sync_stack_slots(2); 1991 1992 // Compiled code's Frame Pointer 1993 frame_pointer(RSP); 1994 1995 // Interpreter stores its frame pointer in a register which is 1996 // stored to the stack by I2CAdaptors. 1997 // I2CAdaptors convert from interpreted java to compiled java. 1998 interpreter_frame_pointer(RBP); 1999 2000 // Stack alignment requirement 2001 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 2002 2003 // Number of outgoing stack slots killed above the out_preserve_stack_slots 2004 // for calls to C. Supports the var-args backing area for register parms. 2005 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 2006 2007 // The after-PROLOG location of the return address. Location of 2008 // return address specifies a type (REG or STACK) and a number 2009 // representing the register number (i.e. - use a register name) or 2010 // stack slot. 2011 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 2012 // Otherwise, it is above the locks and verification slot and alignment word 2013 return_addr(STACK - 2 + 2014 align_up((Compile::current()->in_preserve_stack_slots() + 2015 Compile::current()->fixed_slots()), 2016 stack_alignment_in_slots())); 2017 2018 // Location of compiled Java return values. Same as C for now. 2019 return_value 2020 %{ 2021 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 2022 "only return normal values"); 2023 2024 static const int lo[Op_RegL + 1] = { 2025 0, 2026 0, 2027 RAX_num, // Op_RegN 2028 RAX_num, // Op_RegI 2029 RAX_num, // Op_RegP 2030 XMM0_num, // Op_RegF 2031 XMM0_num, // Op_RegD 2032 RAX_num // Op_RegL 2033 }; 2034 static const int hi[Op_RegL + 1] = { 2035 0, 2036 0, 2037 OptoReg::Bad, // Op_RegN 2038 OptoReg::Bad, // Op_RegI 2039 RAX_H_num, // Op_RegP 2040 OptoReg::Bad, // Op_RegF 2041 XMM0b_num, // Op_RegD 2042 RAX_H_num // Op_RegL 2043 }; 2044 // Excluded flags and vector registers. 2045 assert(ARRAY_SIZE(hi) == _last_machine_leaf - 8, "missing type"); 2046 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 2047 %} 2048 %} 2049 2050 //----------ATTRIBUTES--------------------------------------------------------- 2051 //----------Operand Attributes------------------------------------------------- 2052 op_attrib op_cost(0); // Required cost attribute 2053 2054 //----------Instruction Attributes--------------------------------------------- 2055 ins_attrib ins_cost(100); // Required cost attribute 2056 ins_attrib ins_size(8); // Required size attribute (in bits) 2057 ins_attrib ins_short_branch(0); // Required flag: is this instruction 2058 // a non-matching short branch variant 2059 // of some long branch? 2060 ins_attrib ins_alignment(1); // Required alignment attribute (must 2061 // be a power of 2) specifies the 2062 // alignment that some part of the 2063 // instruction (not necessarily the 2064 // start) requires. If > 1, a 2065 // compute_padding() function must be 2066 // provided for the instruction 2067 2068 //----------OPERANDS----------------------------------------------------------- 2069 // Operand definitions must precede instruction definitions for correct parsing 2070 // in the ADLC because operands constitute user defined types which are used in 2071 // instruction definitions. 2072 2073 //----------Simple Operands---------------------------------------------------- 2074 // Immediate Operands 2075 // Integer Immediate 2076 operand immI() 2077 %{ 2078 match(ConI); 2079 2080 op_cost(10); 2081 format %{ %} 2082 interface(CONST_INTER); 2083 %} 2084 2085 // Constant for test vs zero 2086 operand immI_0() 2087 %{ 2088 predicate(n->get_int() == 0); 2089 match(ConI); 2090 2091 op_cost(0); 2092 format %{ %} 2093 interface(CONST_INTER); 2094 %} 2095 2096 // Constant for increment 2097 operand immI_1() 2098 %{ 2099 predicate(n->get_int() == 1); 2100 match(ConI); 2101 2102 op_cost(0); 2103 format %{ %} 2104 interface(CONST_INTER); 2105 %} 2106 2107 // Constant for decrement 2108 operand immI_M1() 2109 %{ 2110 predicate(n->get_int() == -1); 2111 match(ConI); 2112 2113 op_cost(0); 2114 format %{ %} 2115 interface(CONST_INTER); 2116 %} 2117 2118 operand immI_2() 2119 %{ 2120 predicate(n->get_int() == 2); 2121 match(ConI); 2122 2123 op_cost(0); 2124 format %{ %} 2125 interface(CONST_INTER); 2126 %} 2127 2128 operand immI_4() 2129 %{ 2130 predicate(n->get_int() == 4); 2131 match(ConI); 2132 2133 op_cost(0); 2134 format %{ %} 2135 interface(CONST_INTER); 2136 %} 2137 2138 operand immI_8() 2139 %{ 2140 predicate(n->get_int() == 8); 2141 match(ConI); 2142 2143 op_cost(0); 2144 format %{ %} 2145 interface(CONST_INTER); 2146 %} 2147 2148 // Valid scale values for addressing modes 2149 operand immI2() 2150 %{ 2151 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 2152 match(ConI); 2153 2154 format %{ %} 2155 interface(CONST_INTER); 2156 %} 2157 2158 operand immU7() 2159 %{ 2160 predicate((0 <= n->get_int()) && (n->get_int() <= 0x7F)); 2161 match(ConI); 2162 2163 op_cost(5); 2164 format %{ %} 2165 interface(CONST_INTER); 2166 %} 2167 2168 operand immI8() 2169 %{ 2170 predicate((-0x80 <= n->get_int()) && (n->get_int() < 0x80)); 2171 match(ConI); 2172 2173 op_cost(5); 2174 format %{ %} 2175 interface(CONST_INTER); 2176 %} 2177 2178 operand immU8() 2179 %{ 2180 predicate((0 <= n->get_int()) && (n->get_int() <= 255)); 2181 match(ConI); 2182 2183 op_cost(5); 2184 format %{ %} 2185 interface(CONST_INTER); 2186 %} 2187 2188 operand immI16() 2189 %{ 2190 predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767)); 2191 match(ConI); 2192 2193 op_cost(10); 2194 format %{ %} 2195 interface(CONST_INTER); 2196 %} 2197 2198 // Int Immediate non-negative 2199 operand immU31() 2200 %{ 2201 predicate(n->get_int() >= 0); 2202 match(ConI); 2203 2204 op_cost(0); 2205 format %{ %} 2206 interface(CONST_INTER); 2207 %} 2208 2209 // Pointer Immediate 2210 operand immP() 2211 %{ 2212 match(ConP); 2213 2214 op_cost(10); 2215 format %{ %} 2216 interface(CONST_INTER); 2217 %} 2218 2219 // Null Pointer Immediate 2220 operand immP0() 2221 %{ 2222 predicate(n->get_ptr() == 0); 2223 match(ConP); 2224 2225 op_cost(5); 2226 format %{ %} 2227 interface(CONST_INTER); 2228 %} 2229 2230 // Pointer Immediate 2231 operand immN() %{ 2232 match(ConN); 2233 2234 op_cost(10); 2235 format %{ %} 2236 interface(CONST_INTER); 2237 %} 2238 2239 operand immNKlass() %{ 2240 match(ConNKlass); 2241 2242 op_cost(10); 2243 format %{ %} 2244 interface(CONST_INTER); 2245 %} 2246 2247 // Null Pointer Immediate 2248 operand immN0() %{ 2249 predicate(n->get_narrowcon() == 0); 2250 match(ConN); 2251 2252 op_cost(5); 2253 format %{ %} 2254 interface(CONST_INTER); 2255 %} 2256 2257 operand immP31() 2258 %{ 2259 predicate(n->as_Type()->type()->reloc() == relocInfo::none 2260 && (n->get_ptr() >> 31) == 0); 2261 match(ConP); 2262 2263 op_cost(5); 2264 format %{ %} 2265 interface(CONST_INTER); 2266 %} 2267 2268 2269 // Long Immediate 2270 operand immL() 2271 %{ 2272 match(ConL); 2273 2274 op_cost(20); 2275 format %{ %} 2276 interface(CONST_INTER); 2277 %} 2278 2279 // Long Immediate 8-bit 2280 operand immL8() 2281 %{ 2282 predicate(-0x80L <= n->get_long() && n->get_long() < 0x80L); 2283 match(ConL); 2284 2285 op_cost(5); 2286 format %{ %} 2287 interface(CONST_INTER); 2288 %} 2289 2290 // Long Immediate 32-bit unsigned 2291 operand immUL32() 2292 %{ 2293 predicate(n->get_long() == (unsigned int) (n->get_long())); 2294 match(ConL); 2295 2296 op_cost(10); 2297 format %{ %} 2298 interface(CONST_INTER); 2299 %} 2300 2301 // Long Immediate 32-bit signed 2302 operand immL32() 2303 %{ 2304 predicate(n->get_long() == (int) (n->get_long())); 2305 match(ConL); 2306 2307 op_cost(15); 2308 format %{ %} 2309 interface(CONST_INTER); 2310 %} 2311 2312 operand immL_Pow2() 2313 %{ 2314 predicate(is_power_of_2((julong)n->get_long())); 2315 match(ConL); 2316 2317 op_cost(15); 2318 format %{ %} 2319 interface(CONST_INTER); 2320 %} 2321 2322 operand immL_NotPow2() 2323 %{ 2324 predicate(is_power_of_2((julong)~n->get_long())); 2325 match(ConL); 2326 2327 op_cost(15); 2328 format %{ %} 2329 interface(CONST_INTER); 2330 %} 2331 2332 // Long Immediate zero 2333 operand immL0() 2334 %{ 2335 predicate(n->get_long() == 0L); 2336 match(ConL); 2337 2338 op_cost(10); 2339 format %{ %} 2340 interface(CONST_INTER); 2341 %} 2342 2343 // Constant for increment 2344 operand immL1() 2345 %{ 2346 predicate(n->get_long() == 1); 2347 match(ConL); 2348 2349 format %{ %} 2350 interface(CONST_INTER); 2351 %} 2352 2353 // Constant for decrement 2354 operand immL_M1() 2355 %{ 2356 predicate(n->get_long() == -1); 2357 match(ConL); 2358 2359 format %{ %} 2360 interface(CONST_INTER); 2361 %} 2362 2363 // Long Immediate: low 32-bit mask 2364 operand immL_32bits() 2365 %{ 2366 predicate(n->get_long() == 0xFFFFFFFFL); 2367 match(ConL); 2368 op_cost(20); 2369 2370 format %{ %} 2371 interface(CONST_INTER); 2372 %} 2373 2374 // Int Immediate: 2^n-1, positive 2375 operand immI_Pow2M1() 2376 %{ 2377 predicate((n->get_int() > 0) 2378 && is_power_of_2((juint)n->get_int() + 1)); 2379 match(ConI); 2380 2381 op_cost(20); 2382 format %{ %} 2383 interface(CONST_INTER); 2384 %} 2385 2386 // Float Immediate zero 2387 operand immF0() 2388 %{ 2389 predicate(jint_cast(n->getf()) == 0); 2390 match(ConF); 2391 2392 op_cost(5); 2393 format %{ %} 2394 interface(CONST_INTER); 2395 %} 2396 2397 // Float Immediate 2398 operand immF() 2399 %{ 2400 match(ConF); 2401 2402 op_cost(15); 2403 format %{ %} 2404 interface(CONST_INTER); 2405 %} 2406 2407 // Half Float Immediate 2408 operand immH() 2409 %{ 2410 match(ConH); 2411 2412 op_cost(15); 2413 format %{ %} 2414 interface(CONST_INTER); 2415 %} 2416 2417 // Double Immediate zero 2418 operand immD0() 2419 %{ 2420 predicate(jlong_cast(n->getd()) == 0); 2421 match(ConD); 2422 2423 op_cost(5); 2424 format %{ %} 2425 interface(CONST_INTER); 2426 %} 2427 2428 // Double Immediate 2429 operand immD() 2430 %{ 2431 match(ConD); 2432 2433 op_cost(15); 2434 format %{ %} 2435 interface(CONST_INTER); 2436 %} 2437 2438 // Immediates for special shifts (sign extend) 2439 2440 // Constants for increment 2441 operand immI_16() 2442 %{ 2443 predicate(n->get_int() == 16); 2444 match(ConI); 2445 2446 format %{ %} 2447 interface(CONST_INTER); 2448 %} 2449 2450 operand immI_24() 2451 %{ 2452 predicate(n->get_int() == 24); 2453 match(ConI); 2454 2455 format %{ %} 2456 interface(CONST_INTER); 2457 %} 2458 2459 // Constant for byte-wide masking 2460 operand immI_255() 2461 %{ 2462 predicate(n->get_int() == 255); 2463 match(ConI); 2464 2465 format %{ %} 2466 interface(CONST_INTER); 2467 %} 2468 2469 // Constant for short-wide masking 2470 operand immI_65535() 2471 %{ 2472 predicate(n->get_int() == 65535); 2473 match(ConI); 2474 2475 format %{ %} 2476 interface(CONST_INTER); 2477 %} 2478 2479 // Constant for byte-wide masking 2480 operand immL_255() 2481 %{ 2482 predicate(n->get_long() == 255); 2483 match(ConL); 2484 2485 format %{ %} 2486 interface(CONST_INTER); 2487 %} 2488 2489 // Constant for short-wide masking 2490 operand immL_65535() 2491 %{ 2492 predicate(n->get_long() == 65535); 2493 match(ConL); 2494 2495 format %{ %} 2496 interface(CONST_INTER); 2497 %} 2498 2499 operand kReg() 2500 %{ 2501 constraint(ALLOC_IN_RC(vectmask_reg)); 2502 match(RegVectMask); 2503 format %{%} 2504 interface(REG_INTER); 2505 %} 2506 2507 // Register Operands 2508 // Integer Register 2509 operand rRegI() 2510 %{ 2511 constraint(ALLOC_IN_RC(int_reg)); 2512 match(RegI); 2513 2514 match(rax_RegI); 2515 match(rbx_RegI); 2516 match(rcx_RegI); 2517 match(rdx_RegI); 2518 match(rdi_RegI); 2519 2520 format %{ %} 2521 interface(REG_INTER); 2522 %} 2523 2524 // Special Registers 2525 operand rax_RegI() 2526 %{ 2527 constraint(ALLOC_IN_RC(int_rax_reg)); 2528 match(RegI); 2529 match(rRegI); 2530 2531 format %{ "RAX" %} 2532 interface(REG_INTER); 2533 %} 2534 2535 // Special Registers 2536 operand rbx_RegI() 2537 %{ 2538 constraint(ALLOC_IN_RC(int_rbx_reg)); 2539 match(RegI); 2540 match(rRegI); 2541 2542 format %{ "RBX" %} 2543 interface(REG_INTER); 2544 %} 2545 2546 operand rcx_RegI() 2547 %{ 2548 constraint(ALLOC_IN_RC(int_rcx_reg)); 2549 match(RegI); 2550 match(rRegI); 2551 2552 format %{ "RCX" %} 2553 interface(REG_INTER); 2554 %} 2555 2556 operand rdx_RegI() 2557 %{ 2558 constraint(ALLOC_IN_RC(int_rdx_reg)); 2559 match(RegI); 2560 match(rRegI); 2561 2562 format %{ "RDX" %} 2563 interface(REG_INTER); 2564 %} 2565 2566 operand rdi_RegI() 2567 %{ 2568 constraint(ALLOC_IN_RC(int_rdi_reg)); 2569 match(RegI); 2570 match(rRegI); 2571 2572 format %{ "RDI" %} 2573 interface(REG_INTER); 2574 %} 2575 2576 operand no_rax_rdx_RegI() 2577 %{ 2578 constraint(ALLOC_IN_RC(int_no_rax_rdx_reg)); 2579 match(RegI); 2580 match(rbx_RegI); 2581 match(rcx_RegI); 2582 match(rdi_RegI); 2583 2584 format %{ %} 2585 interface(REG_INTER); 2586 %} 2587 2588 operand no_rbp_r13_RegI() 2589 %{ 2590 constraint(ALLOC_IN_RC(int_no_rbp_r13_reg)); 2591 match(RegI); 2592 match(rRegI); 2593 match(rax_RegI); 2594 match(rbx_RegI); 2595 match(rcx_RegI); 2596 match(rdx_RegI); 2597 match(rdi_RegI); 2598 2599 format %{ %} 2600 interface(REG_INTER); 2601 %} 2602 2603 // Pointer Register 2604 operand any_RegP() 2605 %{ 2606 constraint(ALLOC_IN_RC(any_reg)); 2607 match(RegP); 2608 match(rax_RegP); 2609 match(rbx_RegP); 2610 match(rdi_RegP); 2611 match(rsi_RegP); 2612 match(rbp_RegP); 2613 match(r15_RegP); 2614 match(rRegP); 2615 2616 format %{ %} 2617 interface(REG_INTER); 2618 %} 2619 2620 operand rRegP() 2621 %{ 2622 constraint(ALLOC_IN_RC(ptr_reg)); 2623 match(RegP); 2624 match(rax_RegP); 2625 match(rbx_RegP); 2626 match(rdi_RegP); 2627 match(rsi_RegP); 2628 match(rbp_RegP); // See Q&A below about 2629 match(r15_RegP); // r15_RegP and rbp_RegP. 2630 2631 format %{ %} 2632 interface(REG_INTER); 2633 %} 2634 2635 operand rRegN() %{ 2636 constraint(ALLOC_IN_RC(int_reg)); 2637 match(RegN); 2638 2639 format %{ %} 2640 interface(REG_INTER); 2641 %} 2642 2643 // Question: Why is r15_RegP (the read-only TLS register) a match for rRegP? 2644 // Answer: Operand match rules govern the DFA as it processes instruction inputs. 2645 // It's fine for an instruction input that expects rRegP to match a r15_RegP. 2646 // The output of an instruction is controlled by the allocator, which respects 2647 // register class masks, not match rules. Unless an instruction mentions 2648 // r15_RegP or any_RegP explicitly as its output, r15 will not be considered 2649 // by the allocator as an input. 2650 // The same logic applies to rbp_RegP being a match for rRegP: If PreserveFramePointer==true, 2651 // the RBP is used as a proper frame pointer and is not included in ptr_reg. As a 2652 // result, RBP is not included in the output of the instruction either. 2653 2654 // This operand is not allowed to use RBP even if 2655 // RBP is not used to hold the frame pointer. 2656 operand no_rbp_RegP() 2657 %{ 2658 constraint(ALLOC_IN_RC(ptr_reg_no_rbp)); 2659 match(RegP); 2660 match(rbx_RegP); 2661 match(rsi_RegP); 2662 match(rdi_RegP); 2663 2664 format %{ %} 2665 interface(REG_INTER); 2666 %} 2667 2668 // Special Registers 2669 // Return a pointer value 2670 operand rax_RegP() 2671 %{ 2672 constraint(ALLOC_IN_RC(ptr_rax_reg)); 2673 match(RegP); 2674 match(rRegP); 2675 2676 format %{ %} 2677 interface(REG_INTER); 2678 %} 2679 2680 // Special Registers 2681 // Return a compressed pointer value 2682 operand rax_RegN() 2683 %{ 2684 constraint(ALLOC_IN_RC(int_rax_reg)); 2685 match(RegN); 2686 match(rRegN); 2687 2688 format %{ %} 2689 interface(REG_INTER); 2690 %} 2691 2692 // Used in AtomicAdd 2693 operand rbx_RegP() 2694 %{ 2695 constraint(ALLOC_IN_RC(ptr_rbx_reg)); 2696 match(RegP); 2697 match(rRegP); 2698 2699 format %{ %} 2700 interface(REG_INTER); 2701 %} 2702 2703 operand rsi_RegP() 2704 %{ 2705 constraint(ALLOC_IN_RC(ptr_rsi_reg)); 2706 match(RegP); 2707 match(rRegP); 2708 2709 format %{ %} 2710 interface(REG_INTER); 2711 %} 2712 2713 operand rbp_RegP() 2714 %{ 2715 constraint(ALLOC_IN_RC(ptr_rbp_reg)); 2716 match(RegP); 2717 match(rRegP); 2718 2719 format %{ %} 2720 interface(REG_INTER); 2721 %} 2722 2723 // Used in rep stosq 2724 operand rdi_RegP() 2725 %{ 2726 constraint(ALLOC_IN_RC(ptr_rdi_reg)); 2727 match(RegP); 2728 match(rRegP); 2729 2730 format %{ %} 2731 interface(REG_INTER); 2732 %} 2733 2734 operand r15_RegP() 2735 %{ 2736 constraint(ALLOC_IN_RC(ptr_r15_reg)); 2737 match(RegP); 2738 match(rRegP); 2739 2740 format %{ %} 2741 interface(REG_INTER); 2742 %} 2743 2744 operand rRegL() 2745 %{ 2746 constraint(ALLOC_IN_RC(long_reg)); 2747 match(RegL); 2748 match(rax_RegL); 2749 match(rdx_RegL); 2750 2751 format %{ %} 2752 interface(REG_INTER); 2753 %} 2754 2755 // Special Registers 2756 operand no_rax_rdx_RegL() 2757 %{ 2758 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 2759 match(RegL); 2760 match(rRegL); 2761 2762 format %{ %} 2763 interface(REG_INTER); 2764 %} 2765 2766 operand rax_RegL() 2767 %{ 2768 constraint(ALLOC_IN_RC(long_rax_reg)); 2769 match(RegL); 2770 match(rRegL); 2771 2772 format %{ "RAX" %} 2773 interface(REG_INTER); 2774 %} 2775 2776 operand rcx_RegL() 2777 %{ 2778 constraint(ALLOC_IN_RC(long_rcx_reg)); 2779 match(RegL); 2780 match(rRegL); 2781 2782 format %{ %} 2783 interface(REG_INTER); 2784 %} 2785 2786 operand rdx_RegL() 2787 %{ 2788 constraint(ALLOC_IN_RC(long_rdx_reg)); 2789 match(RegL); 2790 match(rRegL); 2791 2792 format %{ %} 2793 interface(REG_INTER); 2794 %} 2795 2796 operand r11_RegL() 2797 %{ 2798 constraint(ALLOC_IN_RC(long_r11_reg)); 2799 match(RegL); 2800 match(rRegL); 2801 2802 format %{ %} 2803 interface(REG_INTER); 2804 %} 2805 2806 operand no_rbp_r13_RegL() 2807 %{ 2808 constraint(ALLOC_IN_RC(long_no_rbp_r13_reg)); 2809 match(RegL); 2810 match(rRegL); 2811 match(rax_RegL); 2812 match(rcx_RegL); 2813 match(rdx_RegL); 2814 2815 format %{ %} 2816 interface(REG_INTER); 2817 %} 2818 2819 // Flags register, used as output of compare instructions 2820 operand rFlagsReg() 2821 %{ 2822 constraint(ALLOC_IN_RC(int_flags)); 2823 match(RegFlags); 2824 2825 format %{ "RFLAGS" %} 2826 interface(REG_INTER); 2827 %} 2828 2829 // Flags register, used as output of FLOATING POINT compare instructions 2830 operand rFlagsRegU() 2831 %{ 2832 constraint(ALLOC_IN_RC(int_flags)); 2833 match(RegFlags); 2834 2835 format %{ "RFLAGS_U" %} 2836 interface(REG_INTER); 2837 %} 2838 2839 operand rFlagsRegUCF() %{ 2840 constraint(ALLOC_IN_RC(int_flags)); 2841 match(RegFlags); 2842 predicate(false); 2843 2844 format %{ "RFLAGS_U_CF" %} 2845 interface(REG_INTER); 2846 %} 2847 2848 // Float register operands 2849 operand regF() %{ 2850 constraint(ALLOC_IN_RC(float_reg)); 2851 match(RegF); 2852 2853 format %{ %} 2854 interface(REG_INTER); 2855 %} 2856 2857 // Float register operands 2858 operand legRegF() %{ 2859 constraint(ALLOC_IN_RC(float_reg_legacy)); 2860 match(RegF); 2861 2862 format %{ %} 2863 interface(REG_INTER); 2864 %} 2865 2866 // Float register operands 2867 operand vlRegF() %{ 2868 constraint(ALLOC_IN_RC(float_reg_vl)); 2869 match(RegF); 2870 2871 format %{ %} 2872 interface(REG_INTER); 2873 %} 2874 2875 // Double register operands 2876 operand regD() %{ 2877 constraint(ALLOC_IN_RC(double_reg)); 2878 match(RegD); 2879 2880 format %{ %} 2881 interface(REG_INTER); 2882 %} 2883 2884 // Double register operands 2885 operand legRegD() %{ 2886 constraint(ALLOC_IN_RC(double_reg_legacy)); 2887 match(RegD); 2888 2889 format %{ %} 2890 interface(REG_INTER); 2891 %} 2892 2893 // Double register operands 2894 operand vlRegD() %{ 2895 constraint(ALLOC_IN_RC(double_reg_vl)); 2896 match(RegD); 2897 2898 format %{ %} 2899 interface(REG_INTER); 2900 %} 2901 2902 //----------Memory Operands---------------------------------------------------- 2903 // Direct Memory Operand 2904 // operand direct(immP addr) 2905 // %{ 2906 // match(addr); 2907 2908 // format %{ "[$addr]" %} 2909 // interface(MEMORY_INTER) %{ 2910 // base(0xFFFFFFFF); 2911 // index(0x4); 2912 // scale(0x0); 2913 // disp($addr); 2914 // %} 2915 // %} 2916 2917 // Indirect Memory Operand 2918 operand indirect(any_RegP reg) 2919 %{ 2920 constraint(ALLOC_IN_RC(ptr_reg)); 2921 match(reg); 2922 2923 format %{ "[$reg]" %} 2924 interface(MEMORY_INTER) %{ 2925 base($reg); 2926 index(0x4); 2927 scale(0x0); 2928 disp(0x0); 2929 %} 2930 %} 2931 2932 // Indirect Memory Plus Short Offset Operand 2933 operand indOffset8(any_RegP reg, immL8 off) 2934 %{ 2935 constraint(ALLOC_IN_RC(ptr_reg)); 2936 match(AddP reg off); 2937 2938 format %{ "[$reg + $off (8-bit)]" %} 2939 interface(MEMORY_INTER) %{ 2940 base($reg); 2941 index(0x4); 2942 scale(0x0); 2943 disp($off); 2944 %} 2945 %} 2946 2947 // Indirect Memory Plus Long Offset Operand 2948 operand indOffset32(any_RegP reg, immL32 off) 2949 %{ 2950 constraint(ALLOC_IN_RC(ptr_reg)); 2951 match(AddP reg off); 2952 2953 format %{ "[$reg + $off (32-bit)]" %} 2954 interface(MEMORY_INTER) %{ 2955 base($reg); 2956 index(0x4); 2957 scale(0x0); 2958 disp($off); 2959 %} 2960 %} 2961 2962 // Indirect Memory Plus Index Register Plus Offset Operand 2963 operand indIndexOffset(any_RegP reg, rRegL lreg, immL32 off) 2964 %{ 2965 constraint(ALLOC_IN_RC(ptr_reg)); 2966 match(AddP (AddP reg lreg) off); 2967 2968 op_cost(10); 2969 format %{"[$reg + $off + $lreg]" %} 2970 interface(MEMORY_INTER) %{ 2971 base($reg); 2972 index($lreg); 2973 scale(0x0); 2974 disp($off); 2975 %} 2976 %} 2977 2978 // Indirect Memory Plus Index Register Plus Offset Operand 2979 operand indIndex(any_RegP reg, rRegL lreg) 2980 %{ 2981 constraint(ALLOC_IN_RC(ptr_reg)); 2982 match(AddP reg lreg); 2983 2984 op_cost(10); 2985 format %{"[$reg + $lreg]" %} 2986 interface(MEMORY_INTER) %{ 2987 base($reg); 2988 index($lreg); 2989 scale(0x0); 2990 disp(0x0); 2991 %} 2992 %} 2993 2994 // Indirect Memory Times Scale Plus Index Register 2995 operand indIndexScale(any_RegP reg, rRegL lreg, immI2 scale) 2996 %{ 2997 constraint(ALLOC_IN_RC(ptr_reg)); 2998 match(AddP reg (LShiftL lreg scale)); 2999 3000 op_cost(10); 3001 format %{"[$reg + $lreg << $scale]" %} 3002 interface(MEMORY_INTER) %{ 3003 base($reg); 3004 index($lreg); 3005 scale($scale); 3006 disp(0x0); 3007 %} 3008 %} 3009 3010 operand indPosIndexScale(any_RegP reg, rRegI idx, immI2 scale) 3011 %{ 3012 constraint(ALLOC_IN_RC(ptr_reg)); 3013 predicate(n->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3014 match(AddP reg (LShiftL (ConvI2L idx) scale)); 3015 3016 op_cost(10); 3017 format %{"[$reg + pos $idx << $scale]" %} 3018 interface(MEMORY_INTER) %{ 3019 base($reg); 3020 index($idx); 3021 scale($scale); 3022 disp(0x0); 3023 %} 3024 %} 3025 3026 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 3027 operand indIndexScaleOffset(any_RegP reg, immL32 off, rRegL lreg, immI2 scale) 3028 %{ 3029 constraint(ALLOC_IN_RC(ptr_reg)); 3030 match(AddP (AddP reg (LShiftL lreg scale)) off); 3031 3032 op_cost(10); 3033 format %{"[$reg + $off + $lreg << $scale]" %} 3034 interface(MEMORY_INTER) %{ 3035 base($reg); 3036 index($lreg); 3037 scale($scale); 3038 disp($off); 3039 %} 3040 %} 3041 3042 // Indirect Memory Plus Positive Index Register Plus Offset Operand 3043 operand indPosIndexOffset(any_RegP reg, immL32 off, rRegI idx) 3044 %{ 3045 constraint(ALLOC_IN_RC(ptr_reg)); 3046 predicate(n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 3047 match(AddP (AddP reg (ConvI2L idx)) off); 3048 3049 op_cost(10); 3050 format %{"[$reg + $off + $idx]" %} 3051 interface(MEMORY_INTER) %{ 3052 base($reg); 3053 index($idx); 3054 scale(0x0); 3055 disp($off); 3056 %} 3057 %} 3058 3059 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 3060 operand indPosIndexScaleOffset(any_RegP reg, immL32 off, rRegI idx, immI2 scale) 3061 %{ 3062 constraint(ALLOC_IN_RC(ptr_reg)); 3063 predicate(n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3064 match(AddP (AddP reg (LShiftL (ConvI2L idx) scale)) off); 3065 3066 op_cost(10); 3067 format %{"[$reg + $off + $idx << $scale]" %} 3068 interface(MEMORY_INTER) %{ 3069 base($reg); 3070 index($idx); 3071 scale($scale); 3072 disp($off); 3073 %} 3074 %} 3075 3076 // Indirect Narrow Oop Operand 3077 operand indCompressedOop(rRegN reg) %{ 3078 predicate(UseCompressedOops && (CompressedOops::shift() == Address::times_8)); 3079 constraint(ALLOC_IN_RC(ptr_reg)); 3080 match(DecodeN reg); 3081 3082 op_cost(10); 3083 format %{"[R12 + $reg << 3] (compressed oop addressing)" %} 3084 interface(MEMORY_INTER) %{ 3085 base(0xc); // R12 3086 index($reg); 3087 scale(0x3); 3088 disp(0x0); 3089 %} 3090 %} 3091 3092 // Indirect Narrow Oop Plus Offset Operand 3093 // Note: x86 architecture doesn't support "scale * index + offset" without a base 3094 // we can't free r12 even with CompressedOops::base() == nullptr. 3095 operand indCompressedOopOffset(rRegN reg, immL32 off) %{ 3096 predicate(UseCompressedOops && (CompressedOops::shift() == Address::times_8)); 3097 constraint(ALLOC_IN_RC(ptr_reg)); 3098 match(AddP (DecodeN reg) off); 3099 3100 op_cost(10); 3101 format %{"[R12 + $reg << 3 + $off] (compressed oop addressing)" %} 3102 interface(MEMORY_INTER) %{ 3103 base(0xc); // R12 3104 index($reg); 3105 scale(0x3); 3106 disp($off); 3107 %} 3108 %} 3109 3110 // Indirect Memory Operand 3111 operand indirectNarrow(rRegN reg) 3112 %{ 3113 predicate(CompressedOops::shift() == 0); 3114 constraint(ALLOC_IN_RC(ptr_reg)); 3115 match(DecodeN reg); 3116 3117 format %{ "[$reg]" %} 3118 interface(MEMORY_INTER) %{ 3119 base($reg); 3120 index(0x4); 3121 scale(0x0); 3122 disp(0x0); 3123 %} 3124 %} 3125 3126 // Indirect Memory Plus Short Offset Operand 3127 operand indOffset8Narrow(rRegN reg, immL8 off) 3128 %{ 3129 predicate(CompressedOops::shift() == 0); 3130 constraint(ALLOC_IN_RC(ptr_reg)); 3131 match(AddP (DecodeN reg) off); 3132 3133 format %{ "[$reg + $off (8-bit)]" %} 3134 interface(MEMORY_INTER) %{ 3135 base($reg); 3136 index(0x4); 3137 scale(0x0); 3138 disp($off); 3139 %} 3140 %} 3141 3142 // Indirect Memory Plus Long Offset Operand 3143 operand indOffset32Narrow(rRegN reg, immL32 off) 3144 %{ 3145 predicate(CompressedOops::shift() == 0); 3146 constraint(ALLOC_IN_RC(ptr_reg)); 3147 match(AddP (DecodeN reg) off); 3148 3149 format %{ "[$reg + $off (32-bit)]" %} 3150 interface(MEMORY_INTER) %{ 3151 base($reg); 3152 index(0x4); 3153 scale(0x0); 3154 disp($off); 3155 %} 3156 %} 3157 3158 // Indirect Memory Plus Index Register Plus Offset Operand 3159 operand indIndexOffsetNarrow(rRegN reg, rRegL lreg, immL32 off) 3160 %{ 3161 predicate(CompressedOops::shift() == 0); 3162 constraint(ALLOC_IN_RC(ptr_reg)); 3163 match(AddP (AddP (DecodeN reg) lreg) off); 3164 3165 op_cost(10); 3166 format %{"[$reg + $off + $lreg]" %} 3167 interface(MEMORY_INTER) %{ 3168 base($reg); 3169 index($lreg); 3170 scale(0x0); 3171 disp($off); 3172 %} 3173 %} 3174 3175 // Indirect Memory Plus Index Register Plus Offset Operand 3176 operand indIndexNarrow(rRegN reg, rRegL lreg) 3177 %{ 3178 predicate(CompressedOops::shift() == 0); 3179 constraint(ALLOC_IN_RC(ptr_reg)); 3180 match(AddP (DecodeN reg) lreg); 3181 3182 op_cost(10); 3183 format %{"[$reg + $lreg]" %} 3184 interface(MEMORY_INTER) %{ 3185 base($reg); 3186 index($lreg); 3187 scale(0x0); 3188 disp(0x0); 3189 %} 3190 %} 3191 3192 // Indirect Memory Times Scale Plus Index Register 3193 operand indIndexScaleNarrow(rRegN reg, rRegL lreg, immI2 scale) 3194 %{ 3195 predicate(CompressedOops::shift() == 0); 3196 constraint(ALLOC_IN_RC(ptr_reg)); 3197 match(AddP (DecodeN reg) (LShiftL lreg scale)); 3198 3199 op_cost(10); 3200 format %{"[$reg + $lreg << $scale]" %} 3201 interface(MEMORY_INTER) %{ 3202 base($reg); 3203 index($lreg); 3204 scale($scale); 3205 disp(0x0); 3206 %} 3207 %} 3208 3209 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 3210 operand indIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegL lreg, immI2 scale) 3211 %{ 3212 predicate(CompressedOops::shift() == 0); 3213 constraint(ALLOC_IN_RC(ptr_reg)); 3214 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off); 3215 3216 op_cost(10); 3217 format %{"[$reg + $off + $lreg << $scale]" %} 3218 interface(MEMORY_INTER) %{ 3219 base($reg); 3220 index($lreg); 3221 scale($scale); 3222 disp($off); 3223 %} 3224 %} 3225 3226 // Indirect Memory Times Plus Positive Index Register Plus Offset Operand 3227 operand indPosIndexOffsetNarrow(rRegN reg, immL32 off, rRegI idx) 3228 %{ 3229 constraint(ALLOC_IN_RC(ptr_reg)); 3230 predicate(CompressedOops::shift() == 0 && n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 3231 match(AddP (AddP (DecodeN reg) (ConvI2L idx)) off); 3232 3233 op_cost(10); 3234 format %{"[$reg + $off + $idx]" %} 3235 interface(MEMORY_INTER) %{ 3236 base($reg); 3237 index($idx); 3238 scale(0x0); 3239 disp($off); 3240 %} 3241 %} 3242 3243 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 3244 operand indPosIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegI idx, immI2 scale) 3245 %{ 3246 constraint(ALLOC_IN_RC(ptr_reg)); 3247 predicate(CompressedOops::shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3248 match(AddP (AddP (DecodeN reg) (LShiftL (ConvI2L idx) scale)) off); 3249 3250 op_cost(10); 3251 format %{"[$reg + $off + $idx << $scale]" %} 3252 interface(MEMORY_INTER) %{ 3253 base($reg); 3254 index($idx); 3255 scale($scale); 3256 disp($off); 3257 %} 3258 %} 3259 3260 //----------Special Memory Operands-------------------------------------------- 3261 // Stack Slot Operand - This operand is used for loading and storing temporary 3262 // values on the stack where a match requires a value to 3263 // flow through memory. 3264 operand stackSlotP(sRegP reg) 3265 %{ 3266 constraint(ALLOC_IN_RC(stack_slots)); 3267 // No match rule because this operand is only generated in matching 3268 3269 format %{ "[$reg]" %} 3270 interface(MEMORY_INTER) %{ 3271 base(0x4); // RSP 3272 index(0x4); // No Index 3273 scale(0x0); // No Scale 3274 disp($reg); // Stack Offset 3275 %} 3276 %} 3277 3278 operand stackSlotI(sRegI reg) 3279 %{ 3280 constraint(ALLOC_IN_RC(stack_slots)); 3281 // No match rule because this operand is only generated in matching 3282 3283 format %{ "[$reg]" %} 3284 interface(MEMORY_INTER) %{ 3285 base(0x4); // RSP 3286 index(0x4); // No Index 3287 scale(0x0); // No Scale 3288 disp($reg); // Stack Offset 3289 %} 3290 %} 3291 3292 operand stackSlotF(sRegF reg) 3293 %{ 3294 constraint(ALLOC_IN_RC(stack_slots)); 3295 // No match rule because this operand is only generated in matching 3296 3297 format %{ "[$reg]" %} 3298 interface(MEMORY_INTER) %{ 3299 base(0x4); // RSP 3300 index(0x4); // No Index 3301 scale(0x0); // No Scale 3302 disp($reg); // Stack Offset 3303 %} 3304 %} 3305 3306 operand stackSlotD(sRegD reg) 3307 %{ 3308 constraint(ALLOC_IN_RC(stack_slots)); 3309 // No match rule because this operand is only generated in matching 3310 3311 format %{ "[$reg]" %} 3312 interface(MEMORY_INTER) %{ 3313 base(0x4); // RSP 3314 index(0x4); // No Index 3315 scale(0x0); // No Scale 3316 disp($reg); // Stack Offset 3317 %} 3318 %} 3319 operand stackSlotL(sRegL reg) 3320 %{ 3321 constraint(ALLOC_IN_RC(stack_slots)); 3322 // No match rule because this operand is only generated in matching 3323 3324 format %{ "[$reg]" %} 3325 interface(MEMORY_INTER) %{ 3326 base(0x4); // RSP 3327 index(0x4); // No Index 3328 scale(0x0); // No Scale 3329 disp($reg); // Stack Offset 3330 %} 3331 %} 3332 3333 //----------Conditional Branch Operands---------------------------------------- 3334 // Comparison Op - This is the operation of the comparison, and is limited to 3335 // the following set of codes: 3336 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 3337 // 3338 // Other attributes of the comparison, such as unsignedness, are specified 3339 // by the comparison instruction that sets a condition code flags register. 3340 // That result is represented by a flags operand whose subtype is appropriate 3341 // to the unsignedness (etc.) of the comparison. 3342 // 3343 // Later, the instruction which matches both the Comparison Op (a Bool) and 3344 // the flags (produced by the Cmp) specifies the coding of the comparison op 3345 // by matching a specific subtype of Bool operand below, such as cmpOpU. 3346 3347 // Comparison Code 3348 operand cmpOp() 3349 %{ 3350 match(Bool); 3351 3352 format %{ "" %} 3353 interface(COND_INTER) %{ 3354 equal(0x4, "e"); 3355 not_equal(0x5, "ne"); 3356 less(0xC, "l"); 3357 greater_equal(0xD, "ge"); 3358 less_equal(0xE, "le"); 3359 greater(0xF, "g"); 3360 overflow(0x0, "o"); 3361 no_overflow(0x1, "no"); 3362 %} 3363 %} 3364 3365 // Comparison Code, unsigned compare. Used by FP also, with 3366 // C2 (unordered) turned into GT or LT already. The other bits 3367 // C0 and C3 are turned into Carry & Zero flags. 3368 operand cmpOpU() 3369 %{ 3370 match(Bool); 3371 3372 format %{ "" %} 3373 interface(COND_INTER) %{ 3374 equal(0x4, "e"); 3375 not_equal(0x5, "ne"); 3376 less(0x2, "b"); 3377 greater_equal(0x3, "ae"); 3378 less_equal(0x6, "be"); 3379 greater(0x7, "a"); 3380 overflow(0x0, "o"); 3381 no_overflow(0x1, "no"); 3382 %} 3383 %} 3384 3385 3386 // Floating comparisons that don't require any fixup for the unordered case, 3387 // If both inputs of the comparison are the same, ZF is always set so we 3388 // don't need to use cmpOpUCF2 for eq/ne 3389 operand cmpOpUCF() %{ 3390 match(Bool); 3391 predicate(n->as_Bool()->_test._test == BoolTest::lt || 3392 n->as_Bool()->_test._test == BoolTest::ge || 3393 n->as_Bool()->_test._test == BoolTest::le || 3394 n->as_Bool()->_test._test == BoolTest::gt || 3395 n->in(1)->in(1) == n->in(1)->in(2)); 3396 format %{ "" %} 3397 interface(COND_INTER) %{ 3398 equal(0xb, "np"); 3399 not_equal(0xa, "p"); 3400 less(0x2, "b"); 3401 greater_equal(0x3, "ae"); 3402 less_equal(0x6, "be"); 3403 greater(0x7, "a"); 3404 overflow(0x0, "o"); 3405 no_overflow(0x1, "no"); 3406 %} 3407 %} 3408 3409 3410 // Floating comparisons that can be fixed up with extra conditional jumps 3411 operand cmpOpUCF2() %{ 3412 match(Bool); 3413 predicate((n->as_Bool()->_test._test == BoolTest::ne || 3414 n->as_Bool()->_test._test == BoolTest::eq) && 3415 n->in(1)->in(1) != n->in(1)->in(2)); 3416 format %{ "" %} 3417 interface(COND_INTER) %{ 3418 equal(0x4, "e"); 3419 not_equal(0x5, "ne"); 3420 less(0x2, "b"); 3421 greater_equal(0x3, "ae"); 3422 less_equal(0x6, "be"); 3423 greater(0x7, "a"); 3424 overflow(0x0, "o"); 3425 no_overflow(0x1, "no"); 3426 %} 3427 %} 3428 3429 //----------OPERAND CLASSES---------------------------------------------------- 3430 // Operand Classes are groups of operands that are used as to simplify 3431 // instruction definitions by not requiring the AD writer to specify separate 3432 // instructions for every form of operand when the instruction accepts 3433 // multiple operand types with the same basic encoding and format. The classic 3434 // case of this is memory operands. 3435 3436 opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex, 3437 indIndexScale, indPosIndexScale, indIndexScaleOffset, indPosIndexOffset, indPosIndexScaleOffset, 3438 indCompressedOop, indCompressedOopOffset, 3439 indirectNarrow, indOffset8Narrow, indOffset32Narrow, 3440 indIndexOffsetNarrow, indIndexNarrow, indIndexScaleNarrow, 3441 indIndexScaleOffsetNarrow, indPosIndexOffsetNarrow, indPosIndexScaleOffsetNarrow); 3442 3443 //----------PIPELINE----------------------------------------------------------- 3444 // Rules which define the behavior of the target architectures pipeline. 3445 pipeline %{ 3446 3447 //----------ATTRIBUTES--------------------------------------------------------- 3448 attributes %{ 3449 variable_size_instructions; // Fixed size instructions 3450 max_instructions_per_bundle = 3; // Up to 3 instructions per bundle 3451 instruction_unit_size = 1; // An instruction is 1 bytes long 3452 instruction_fetch_unit_size = 16; // The processor fetches one line 3453 instruction_fetch_units = 1; // of 16 bytes 3454 3455 // List of nop instructions 3456 nops( MachNop ); 3457 %} 3458 3459 //----------RESOURCES---------------------------------------------------------- 3460 // Resources are the functional units available to the machine 3461 3462 // Generic P2/P3 pipeline 3463 // 3 decoders, only D0 handles big operands; a "bundle" is the limit of 3464 // 3 instructions decoded per cycle. 3465 // 2 load/store ops per cycle, 1 branch, 1 FPU, 3466 // 3 ALU op, only ALU0 handles mul instructions. 3467 resources( D0, D1, D2, DECODE = D0 | D1 | D2, 3468 MS0, MS1, MS2, MEM = MS0 | MS1 | MS2, 3469 BR, FPU, 3470 ALU0, ALU1, ALU2, ALU = ALU0 | ALU1 | ALU2); 3471 3472 //----------PIPELINE DESCRIPTION----------------------------------------------- 3473 // Pipeline Description specifies the stages in the machine's pipeline 3474 3475 // Generic P2/P3 pipeline 3476 pipe_desc(S0, S1, S2, S3, S4, S5); 3477 3478 //----------PIPELINE CLASSES--------------------------------------------------- 3479 // Pipeline Classes describe the stages in which input and output are 3480 // referenced by the hardware pipeline. 3481 3482 // Naming convention: ialu or fpu 3483 // Then: _reg 3484 // Then: _reg if there is a 2nd register 3485 // Then: _long if it's a pair of instructions implementing a long 3486 // Then: _fat if it requires the big decoder 3487 // Or: _mem if it requires the big decoder and a memory unit. 3488 3489 // Integer ALU reg operation 3490 pipe_class ialu_reg(rRegI dst) 3491 %{ 3492 single_instruction; 3493 dst : S4(write); 3494 dst : S3(read); 3495 DECODE : S0; // any decoder 3496 ALU : S3; // any alu 3497 %} 3498 3499 // Long ALU reg operation 3500 pipe_class ialu_reg_long(rRegL dst) 3501 %{ 3502 instruction_count(2); 3503 dst : S4(write); 3504 dst : S3(read); 3505 DECODE : S0(2); // any 2 decoders 3506 ALU : S3(2); // both alus 3507 %} 3508 3509 // Integer ALU reg operation using big decoder 3510 pipe_class ialu_reg_fat(rRegI dst) 3511 %{ 3512 single_instruction; 3513 dst : S4(write); 3514 dst : S3(read); 3515 D0 : S0; // big decoder only 3516 ALU : S3; // any alu 3517 %} 3518 3519 // Integer ALU reg-reg operation 3520 pipe_class ialu_reg_reg(rRegI dst, rRegI src) 3521 %{ 3522 single_instruction; 3523 dst : S4(write); 3524 src : S3(read); 3525 DECODE : S0; // any decoder 3526 ALU : S3; // any alu 3527 %} 3528 3529 // Integer ALU reg-reg operation 3530 pipe_class ialu_reg_reg_fat(rRegI dst, memory src) 3531 %{ 3532 single_instruction; 3533 dst : S4(write); 3534 src : S3(read); 3535 D0 : S0; // big decoder only 3536 ALU : S3; // any alu 3537 %} 3538 3539 // Integer ALU reg-mem operation 3540 pipe_class ialu_reg_mem(rRegI dst, memory mem) 3541 %{ 3542 single_instruction; 3543 dst : S5(write); 3544 mem : S3(read); 3545 D0 : S0; // big decoder only 3546 ALU : S4; // any alu 3547 MEM : S3; // any mem 3548 %} 3549 3550 // Integer mem operation (prefetch) 3551 pipe_class ialu_mem(memory mem) 3552 %{ 3553 single_instruction; 3554 mem : S3(read); 3555 D0 : S0; // big decoder only 3556 MEM : S3; // any mem 3557 %} 3558 3559 // Integer Store to Memory 3560 pipe_class ialu_mem_reg(memory mem, rRegI src) 3561 %{ 3562 single_instruction; 3563 mem : S3(read); 3564 src : S5(read); 3565 D0 : S0; // big decoder only 3566 ALU : S4; // any alu 3567 MEM : S3; 3568 %} 3569 3570 // // Long Store to Memory 3571 // pipe_class ialu_mem_long_reg(memory mem, rRegL src) 3572 // %{ 3573 // instruction_count(2); 3574 // mem : S3(read); 3575 // src : S5(read); 3576 // D0 : S0(2); // big decoder only; twice 3577 // ALU : S4(2); // any 2 alus 3578 // MEM : S3(2); // Both mems 3579 // %} 3580 3581 // Integer Store to Memory 3582 pipe_class ialu_mem_imm(memory mem) 3583 %{ 3584 single_instruction; 3585 mem : S3(read); 3586 D0 : S0; // big decoder only 3587 ALU : S4; // any alu 3588 MEM : S3; 3589 %} 3590 3591 // Integer ALU0 reg-reg operation 3592 pipe_class ialu_reg_reg_alu0(rRegI dst, rRegI src) 3593 %{ 3594 single_instruction; 3595 dst : S4(write); 3596 src : S3(read); 3597 D0 : S0; // Big decoder only 3598 ALU0 : S3; // only alu0 3599 %} 3600 3601 // Integer ALU0 reg-mem operation 3602 pipe_class ialu_reg_mem_alu0(rRegI dst, memory mem) 3603 %{ 3604 single_instruction; 3605 dst : S5(write); 3606 mem : S3(read); 3607 D0 : S0; // big decoder only 3608 ALU0 : S4; // ALU0 only 3609 MEM : S3; // any mem 3610 %} 3611 3612 // Integer ALU reg-reg operation 3613 pipe_class ialu_cr_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2) 3614 %{ 3615 single_instruction; 3616 cr : S4(write); 3617 src1 : S3(read); 3618 src2 : S3(read); 3619 DECODE : S0; // any decoder 3620 ALU : S3; // any alu 3621 %} 3622 3623 // Integer ALU reg-imm operation 3624 pipe_class ialu_cr_reg_imm(rFlagsReg cr, rRegI src1) 3625 %{ 3626 single_instruction; 3627 cr : S4(write); 3628 src1 : S3(read); 3629 DECODE : S0; // any decoder 3630 ALU : S3; // any alu 3631 %} 3632 3633 // Integer ALU reg-mem operation 3634 pipe_class ialu_cr_reg_mem(rFlagsReg cr, rRegI src1, memory src2) 3635 %{ 3636 single_instruction; 3637 cr : S4(write); 3638 src1 : S3(read); 3639 src2 : S3(read); 3640 D0 : S0; // big decoder only 3641 ALU : S4; // any alu 3642 MEM : S3; 3643 %} 3644 3645 // Conditional move reg-reg 3646 pipe_class pipe_cmplt( rRegI p, rRegI q, rRegI y) 3647 %{ 3648 instruction_count(4); 3649 y : S4(read); 3650 q : S3(read); 3651 p : S3(read); 3652 DECODE : S0(4); // any decoder 3653 %} 3654 3655 // Conditional move reg-reg 3656 pipe_class pipe_cmov_reg( rRegI dst, rRegI src, rFlagsReg cr) 3657 %{ 3658 single_instruction; 3659 dst : S4(write); 3660 src : S3(read); 3661 cr : S3(read); 3662 DECODE : S0; // any decoder 3663 %} 3664 3665 // Conditional move reg-mem 3666 pipe_class pipe_cmov_mem( rFlagsReg cr, rRegI dst, memory src) 3667 %{ 3668 single_instruction; 3669 dst : S4(write); 3670 src : S3(read); 3671 cr : S3(read); 3672 DECODE : S0; // any decoder 3673 MEM : S3; 3674 %} 3675 3676 // Conditional move reg-reg long 3677 pipe_class pipe_cmov_reg_long( rFlagsReg cr, rRegL dst, rRegL src) 3678 %{ 3679 single_instruction; 3680 dst : S4(write); 3681 src : S3(read); 3682 cr : S3(read); 3683 DECODE : S0(2); // any 2 decoders 3684 %} 3685 3686 // Float reg-reg operation 3687 pipe_class fpu_reg(regD dst) 3688 %{ 3689 instruction_count(2); 3690 dst : S3(read); 3691 DECODE : S0(2); // any 2 decoders 3692 FPU : S3; 3693 %} 3694 3695 // Float reg-reg operation 3696 pipe_class fpu_reg_reg(regD dst, regD src) 3697 %{ 3698 instruction_count(2); 3699 dst : S4(write); 3700 src : S3(read); 3701 DECODE : S0(2); // any 2 decoders 3702 FPU : S3; 3703 %} 3704 3705 // Float reg-reg operation 3706 pipe_class fpu_reg_reg_reg(regD dst, regD src1, regD src2) 3707 %{ 3708 instruction_count(3); 3709 dst : S4(write); 3710 src1 : S3(read); 3711 src2 : S3(read); 3712 DECODE : S0(3); // any 3 decoders 3713 FPU : S3(2); 3714 %} 3715 3716 // Float reg-reg operation 3717 pipe_class fpu_reg_reg_reg_reg(regD dst, regD src1, regD src2, regD src3) 3718 %{ 3719 instruction_count(4); 3720 dst : S4(write); 3721 src1 : S3(read); 3722 src2 : S3(read); 3723 src3 : S3(read); 3724 DECODE : S0(4); // any 3 decoders 3725 FPU : S3(2); 3726 %} 3727 3728 // Float reg-reg operation 3729 pipe_class fpu_reg_mem_reg_reg(regD dst, memory src1, regD src2, regD src3) 3730 %{ 3731 instruction_count(4); 3732 dst : S4(write); 3733 src1 : S3(read); 3734 src2 : S3(read); 3735 src3 : S3(read); 3736 DECODE : S1(3); // any 3 decoders 3737 D0 : S0; // Big decoder only 3738 FPU : S3(2); 3739 MEM : S3; 3740 %} 3741 3742 // Float reg-mem operation 3743 pipe_class fpu_reg_mem(regD dst, memory mem) 3744 %{ 3745 instruction_count(2); 3746 dst : S5(write); 3747 mem : S3(read); 3748 D0 : S0; // big decoder only 3749 DECODE : S1; // any decoder for FPU POP 3750 FPU : S4; 3751 MEM : S3; // any mem 3752 %} 3753 3754 // Float reg-mem operation 3755 pipe_class fpu_reg_reg_mem(regD dst, regD src1, memory mem) 3756 %{ 3757 instruction_count(3); 3758 dst : S5(write); 3759 src1 : S3(read); 3760 mem : S3(read); 3761 D0 : S0; // big decoder only 3762 DECODE : S1(2); // any decoder for FPU POP 3763 FPU : S4; 3764 MEM : S3; // any mem 3765 %} 3766 3767 // Float mem-reg operation 3768 pipe_class fpu_mem_reg(memory mem, regD src) 3769 %{ 3770 instruction_count(2); 3771 src : S5(read); 3772 mem : S3(read); 3773 DECODE : S0; // any decoder for FPU PUSH 3774 D0 : S1; // big decoder only 3775 FPU : S4; 3776 MEM : S3; // any mem 3777 %} 3778 3779 pipe_class fpu_mem_reg_reg(memory mem, regD src1, regD src2) 3780 %{ 3781 instruction_count(3); 3782 src1 : S3(read); 3783 src2 : S3(read); 3784 mem : S3(read); 3785 DECODE : S0(2); // any decoder for FPU PUSH 3786 D0 : S1; // big decoder only 3787 FPU : S4; 3788 MEM : S3; // any mem 3789 %} 3790 3791 pipe_class fpu_mem_reg_mem(memory mem, regD src1, memory src2) 3792 %{ 3793 instruction_count(3); 3794 src1 : S3(read); 3795 src2 : S3(read); 3796 mem : S4(read); 3797 DECODE : S0; // any decoder for FPU PUSH 3798 D0 : S0(2); // big decoder only 3799 FPU : S4; 3800 MEM : S3(2); // any mem 3801 %} 3802 3803 pipe_class fpu_mem_mem(memory dst, memory src1) 3804 %{ 3805 instruction_count(2); 3806 src1 : S3(read); 3807 dst : S4(read); 3808 D0 : S0(2); // big decoder only 3809 MEM : S3(2); // any mem 3810 %} 3811 3812 pipe_class fpu_mem_mem_mem(memory dst, memory src1, memory src2) 3813 %{ 3814 instruction_count(3); 3815 src1 : S3(read); 3816 src2 : S3(read); 3817 dst : S4(read); 3818 D0 : S0(3); // big decoder only 3819 FPU : S4; 3820 MEM : S3(3); // any mem 3821 %} 3822 3823 pipe_class fpu_mem_reg_con(memory mem, regD src1) 3824 %{ 3825 instruction_count(3); 3826 src1 : S4(read); 3827 mem : S4(read); 3828 DECODE : S0; // any decoder for FPU PUSH 3829 D0 : S0(2); // big decoder only 3830 FPU : S4; 3831 MEM : S3(2); // any mem 3832 %} 3833 3834 // Float load constant 3835 pipe_class fpu_reg_con(regD dst) 3836 %{ 3837 instruction_count(2); 3838 dst : S5(write); 3839 D0 : S0; // big decoder only for the load 3840 DECODE : S1; // any decoder for FPU POP 3841 FPU : S4; 3842 MEM : S3; // any mem 3843 %} 3844 3845 // Float load constant 3846 pipe_class fpu_reg_reg_con(regD dst, regD src) 3847 %{ 3848 instruction_count(3); 3849 dst : S5(write); 3850 src : S3(read); 3851 D0 : S0; // big decoder only for the load 3852 DECODE : S1(2); // any decoder for FPU POP 3853 FPU : S4; 3854 MEM : S3; // any mem 3855 %} 3856 3857 // UnConditional branch 3858 pipe_class pipe_jmp(label labl) 3859 %{ 3860 single_instruction; 3861 BR : S3; 3862 %} 3863 3864 // Conditional branch 3865 pipe_class pipe_jcc(cmpOp cmp, rFlagsReg cr, label labl) 3866 %{ 3867 single_instruction; 3868 cr : S1(read); 3869 BR : S3; 3870 %} 3871 3872 // Allocation idiom 3873 pipe_class pipe_cmpxchg(rRegP dst, rRegP heap_ptr) 3874 %{ 3875 instruction_count(1); force_serialization; 3876 fixed_latency(6); 3877 heap_ptr : S3(read); 3878 DECODE : S0(3); 3879 D0 : S2; 3880 MEM : S3; 3881 ALU : S3(2); 3882 dst : S5(write); 3883 BR : S5; 3884 %} 3885 3886 // Generic big/slow expanded idiom 3887 pipe_class pipe_slow() 3888 %{ 3889 instruction_count(10); multiple_bundles; force_serialization; 3890 fixed_latency(100); 3891 D0 : S0(2); 3892 MEM : S3(2); 3893 %} 3894 3895 // The real do-nothing guy 3896 pipe_class empty() 3897 %{ 3898 instruction_count(0); 3899 %} 3900 3901 // Define the class for the Nop node 3902 define 3903 %{ 3904 MachNop = empty; 3905 %} 3906 3907 %} 3908 3909 //----------INSTRUCTIONS------------------------------------------------------- 3910 // 3911 // match -- States which machine-independent subtree may be replaced 3912 // by this instruction. 3913 // ins_cost -- The estimated cost of this instruction is used by instruction 3914 // selection to identify a minimum cost tree of machine 3915 // instructions that matches a tree of machine-independent 3916 // instructions. 3917 // format -- A string providing the disassembly for this instruction. 3918 // The value of an instruction's operand may be inserted 3919 // by referring to it with a '$' prefix. 3920 // opcode -- Three instruction opcodes may be provided. These are referred 3921 // to within an encode class as $primary, $secondary, and $tertiary 3922 // rrspectively. The primary opcode is commonly used to 3923 // indicate the type of machine instruction, while secondary 3924 // and tertiary are often used for prefix options or addressing 3925 // modes. 3926 // ins_encode -- A list of encode classes with parameters. The encode class 3927 // name must have been defined in an 'enc_class' specification 3928 // in the encode section of the architecture description. 3929 3930 // Dummy reg-to-reg vector moves. Removed during post-selection cleanup. 3931 // Load Float 3932 instruct MoveF2VL(vlRegF dst, regF src) %{ 3933 match(Set dst src); 3934 format %{ "movss $dst,$src\t! load float (4 bytes)" %} 3935 ins_encode %{ 3936 ShouldNotReachHere(); 3937 %} 3938 ins_pipe( fpu_reg_reg ); 3939 %} 3940 3941 // Load Float 3942 instruct MoveF2LEG(legRegF dst, regF src) %{ 3943 match(Set dst src); 3944 format %{ "movss $dst,$src\t# if src != dst load float (4 bytes)" %} 3945 ins_encode %{ 3946 ShouldNotReachHere(); 3947 %} 3948 ins_pipe( fpu_reg_reg ); 3949 %} 3950 3951 // Load Float 3952 instruct MoveVL2F(regF dst, vlRegF src) %{ 3953 match(Set dst src); 3954 format %{ "movss $dst,$src\t! load float (4 bytes)" %} 3955 ins_encode %{ 3956 ShouldNotReachHere(); 3957 %} 3958 ins_pipe( fpu_reg_reg ); 3959 %} 3960 3961 // Load Float 3962 instruct MoveLEG2F(regF dst, legRegF src) %{ 3963 match(Set dst src); 3964 format %{ "movss $dst,$src\t# if src != dst load float (4 bytes)" %} 3965 ins_encode %{ 3966 ShouldNotReachHere(); 3967 %} 3968 ins_pipe( fpu_reg_reg ); 3969 %} 3970 3971 // Load Double 3972 instruct MoveD2VL(vlRegD dst, regD src) %{ 3973 match(Set dst src); 3974 format %{ "movsd $dst,$src\t! load double (8 bytes)" %} 3975 ins_encode %{ 3976 ShouldNotReachHere(); 3977 %} 3978 ins_pipe( fpu_reg_reg ); 3979 %} 3980 3981 // Load Double 3982 instruct MoveD2LEG(legRegD dst, regD src) %{ 3983 match(Set dst src); 3984 format %{ "movsd $dst,$src\t# if src != dst load double (8 bytes)" %} 3985 ins_encode %{ 3986 ShouldNotReachHere(); 3987 %} 3988 ins_pipe( fpu_reg_reg ); 3989 %} 3990 3991 // Load Double 3992 instruct MoveVL2D(regD dst, vlRegD src) %{ 3993 match(Set dst src); 3994 format %{ "movsd $dst,$src\t! load double (8 bytes)" %} 3995 ins_encode %{ 3996 ShouldNotReachHere(); 3997 %} 3998 ins_pipe( fpu_reg_reg ); 3999 %} 4000 4001 // Load Double 4002 instruct MoveLEG2D(regD dst, legRegD src) %{ 4003 match(Set dst src); 4004 format %{ "movsd $dst,$src\t# if src != dst load double (8 bytes)" %} 4005 ins_encode %{ 4006 ShouldNotReachHere(); 4007 %} 4008 ins_pipe( fpu_reg_reg ); 4009 %} 4010 4011 //----------Load/Store/Move Instructions--------------------------------------- 4012 //----------Load Instructions-------------------------------------------------- 4013 4014 // Load Byte (8 bit signed) 4015 instruct loadB(rRegI dst, memory mem) 4016 %{ 4017 match(Set dst (LoadB mem)); 4018 4019 ins_cost(125); 4020 format %{ "movsbl $dst, $mem\t# byte" %} 4021 4022 ins_encode %{ 4023 __ movsbl($dst$$Register, $mem$$Address); 4024 %} 4025 4026 ins_pipe(ialu_reg_mem); 4027 %} 4028 4029 // Load Byte (8 bit signed) into Long Register 4030 instruct loadB2L(rRegL dst, memory mem) 4031 %{ 4032 match(Set dst (ConvI2L (LoadB mem))); 4033 4034 ins_cost(125); 4035 format %{ "movsbq $dst, $mem\t# byte -> long" %} 4036 4037 ins_encode %{ 4038 __ movsbq($dst$$Register, $mem$$Address); 4039 %} 4040 4041 ins_pipe(ialu_reg_mem); 4042 %} 4043 4044 // Load Unsigned Byte (8 bit UNsigned) 4045 instruct loadUB(rRegI dst, memory mem) 4046 %{ 4047 match(Set dst (LoadUB mem)); 4048 4049 ins_cost(125); 4050 format %{ "movzbl $dst, $mem\t# ubyte" %} 4051 4052 ins_encode %{ 4053 __ movzbl($dst$$Register, $mem$$Address); 4054 %} 4055 4056 ins_pipe(ialu_reg_mem); 4057 %} 4058 4059 // Load Unsigned Byte (8 bit UNsigned) into Long Register 4060 instruct loadUB2L(rRegL dst, memory mem) 4061 %{ 4062 match(Set dst (ConvI2L (LoadUB mem))); 4063 4064 ins_cost(125); 4065 format %{ "movzbq $dst, $mem\t# ubyte -> long" %} 4066 4067 ins_encode %{ 4068 __ movzbq($dst$$Register, $mem$$Address); 4069 %} 4070 4071 ins_pipe(ialu_reg_mem); 4072 %} 4073 4074 // Load Unsigned Byte (8 bit UNsigned) with 32-bit mask into Long Register 4075 instruct loadUB2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 4076 match(Set dst (ConvI2L (AndI (LoadUB mem) mask))); 4077 effect(KILL cr); 4078 4079 format %{ "movzbq $dst, $mem\t# ubyte & 32-bit mask -> long\n\t" 4080 "andl $dst, right_n_bits($mask, 8)" %} 4081 ins_encode %{ 4082 Register Rdst = $dst$$Register; 4083 __ movzbq(Rdst, $mem$$Address); 4084 __ andl(Rdst, $mask$$constant & right_n_bits(8)); 4085 %} 4086 ins_pipe(ialu_reg_mem); 4087 %} 4088 4089 // Load Short (16 bit signed) 4090 instruct loadS(rRegI dst, memory mem) 4091 %{ 4092 match(Set dst (LoadS mem)); 4093 4094 ins_cost(125); 4095 format %{ "movswl $dst, $mem\t# short" %} 4096 4097 ins_encode %{ 4098 __ movswl($dst$$Register, $mem$$Address); 4099 %} 4100 4101 ins_pipe(ialu_reg_mem); 4102 %} 4103 4104 // Load Short (16 bit signed) to Byte (8 bit signed) 4105 instruct loadS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4106 match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour)); 4107 4108 ins_cost(125); 4109 format %{ "movsbl $dst, $mem\t# short -> byte" %} 4110 ins_encode %{ 4111 __ movsbl($dst$$Register, $mem$$Address); 4112 %} 4113 ins_pipe(ialu_reg_mem); 4114 %} 4115 4116 // Load Short (16 bit signed) into Long Register 4117 instruct loadS2L(rRegL dst, memory mem) 4118 %{ 4119 match(Set dst (ConvI2L (LoadS mem))); 4120 4121 ins_cost(125); 4122 format %{ "movswq $dst, $mem\t# short -> long" %} 4123 4124 ins_encode %{ 4125 __ movswq($dst$$Register, $mem$$Address); 4126 %} 4127 4128 ins_pipe(ialu_reg_mem); 4129 %} 4130 4131 // Load Unsigned Short/Char (16 bit UNsigned) 4132 instruct loadUS(rRegI dst, memory mem) 4133 %{ 4134 match(Set dst (LoadUS mem)); 4135 4136 ins_cost(125); 4137 format %{ "movzwl $dst, $mem\t# ushort/char" %} 4138 4139 ins_encode %{ 4140 __ movzwl($dst$$Register, $mem$$Address); 4141 %} 4142 4143 ins_pipe(ialu_reg_mem); 4144 %} 4145 4146 // Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed) 4147 instruct loadUS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4148 match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour)); 4149 4150 ins_cost(125); 4151 format %{ "movsbl $dst, $mem\t# ushort -> byte" %} 4152 ins_encode %{ 4153 __ movsbl($dst$$Register, $mem$$Address); 4154 %} 4155 ins_pipe(ialu_reg_mem); 4156 %} 4157 4158 // Load Unsigned Short/Char (16 bit UNsigned) into Long Register 4159 instruct loadUS2L(rRegL dst, memory mem) 4160 %{ 4161 match(Set dst (ConvI2L (LoadUS mem))); 4162 4163 ins_cost(125); 4164 format %{ "movzwq $dst, $mem\t# ushort/char -> long" %} 4165 4166 ins_encode %{ 4167 __ movzwq($dst$$Register, $mem$$Address); 4168 %} 4169 4170 ins_pipe(ialu_reg_mem); 4171 %} 4172 4173 // Load Unsigned Short/Char (16 bit UNsigned) with mask 0xFF into Long Register 4174 instruct loadUS2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 4175 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 4176 4177 format %{ "movzbq $dst, $mem\t# ushort/char & 0xFF -> long" %} 4178 ins_encode %{ 4179 __ movzbq($dst$$Register, $mem$$Address); 4180 %} 4181 ins_pipe(ialu_reg_mem); 4182 %} 4183 4184 // Load Unsigned Short/Char (16 bit UNsigned) with 32-bit mask into Long Register 4185 instruct loadUS2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 4186 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 4187 effect(KILL cr); 4188 4189 format %{ "movzwq $dst, $mem\t# ushort/char & 32-bit mask -> long\n\t" 4190 "andl $dst, right_n_bits($mask, 16)" %} 4191 ins_encode %{ 4192 Register Rdst = $dst$$Register; 4193 __ movzwq(Rdst, $mem$$Address); 4194 __ andl(Rdst, $mask$$constant & right_n_bits(16)); 4195 %} 4196 ins_pipe(ialu_reg_mem); 4197 %} 4198 4199 // Load Integer 4200 instruct loadI(rRegI dst, memory mem) 4201 %{ 4202 match(Set dst (LoadI mem)); 4203 4204 ins_cost(125); 4205 format %{ "movl $dst, $mem\t# int" %} 4206 4207 ins_encode %{ 4208 __ movl($dst$$Register, $mem$$Address); 4209 %} 4210 4211 ins_pipe(ialu_reg_mem); 4212 %} 4213 4214 // Load Integer (32 bit signed) to Byte (8 bit signed) 4215 instruct loadI2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4216 match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour)); 4217 4218 ins_cost(125); 4219 format %{ "movsbl $dst, $mem\t# int -> byte" %} 4220 ins_encode %{ 4221 __ movsbl($dst$$Register, $mem$$Address); 4222 %} 4223 ins_pipe(ialu_reg_mem); 4224 %} 4225 4226 // Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned) 4227 instruct loadI2UB(rRegI dst, memory mem, immI_255 mask) %{ 4228 match(Set dst (AndI (LoadI mem) mask)); 4229 4230 ins_cost(125); 4231 format %{ "movzbl $dst, $mem\t# int -> ubyte" %} 4232 ins_encode %{ 4233 __ movzbl($dst$$Register, $mem$$Address); 4234 %} 4235 ins_pipe(ialu_reg_mem); 4236 %} 4237 4238 // Load Integer (32 bit signed) to Short (16 bit signed) 4239 instruct loadI2S(rRegI dst, memory mem, immI_16 sixteen) %{ 4240 match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen)); 4241 4242 ins_cost(125); 4243 format %{ "movswl $dst, $mem\t# int -> short" %} 4244 ins_encode %{ 4245 __ movswl($dst$$Register, $mem$$Address); 4246 %} 4247 ins_pipe(ialu_reg_mem); 4248 %} 4249 4250 // Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned) 4251 instruct loadI2US(rRegI dst, memory mem, immI_65535 mask) %{ 4252 match(Set dst (AndI (LoadI mem) mask)); 4253 4254 ins_cost(125); 4255 format %{ "movzwl $dst, $mem\t# int -> ushort/char" %} 4256 ins_encode %{ 4257 __ movzwl($dst$$Register, $mem$$Address); 4258 %} 4259 ins_pipe(ialu_reg_mem); 4260 %} 4261 4262 // Load Integer into Long Register 4263 instruct loadI2L(rRegL dst, memory mem) 4264 %{ 4265 match(Set dst (ConvI2L (LoadI mem))); 4266 4267 ins_cost(125); 4268 format %{ "movslq $dst, $mem\t# int -> long" %} 4269 4270 ins_encode %{ 4271 __ movslq($dst$$Register, $mem$$Address); 4272 %} 4273 4274 ins_pipe(ialu_reg_mem); 4275 %} 4276 4277 // Load Integer with mask 0xFF into Long Register 4278 instruct loadI2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 4279 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4280 4281 format %{ "movzbq $dst, $mem\t# int & 0xFF -> long" %} 4282 ins_encode %{ 4283 __ movzbq($dst$$Register, $mem$$Address); 4284 %} 4285 ins_pipe(ialu_reg_mem); 4286 %} 4287 4288 // Load Integer with mask 0xFFFF into Long Register 4289 instruct loadI2L_immI_65535(rRegL dst, memory mem, immI_65535 mask) %{ 4290 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4291 4292 format %{ "movzwq $dst, $mem\t# int & 0xFFFF -> long" %} 4293 ins_encode %{ 4294 __ movzwq($dst$$Register, $mem$$Address); 4295 %} 4296 ins_pipe(ialu_reg_mem); 4297 %} 4298 4299 // Load Integer with a 31-bit mask into Long Register 4300 instruct loadI2L_immU31(rRegL dst, memory mem, immU31 mask, rFlagsReg cr) %{ 4301 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4302 effect(KILL cr); 4303 4304 format %{ "movl $dst, $mem\t# int & 31-bit mask -> long\n\t" 4305 "andl $dst, $mask" %} 4306 ins_encode %{ 4307 Register Rdst = $dst$$Register; 4308 __ movl(Rdst, $mem$$Address); 4309 __ andl(Rdst, $mask$$constant); 4310 %} 4311 ins_pipe(ialu_reg_mem); 4312 %} 4313 4314 // Load Unsigned Integer into Long Register 4315 instruct loadUI2L(rRegL dst, memory mem, immL_32bits mask) 4316 %{ 4317 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 4318 4319 ins_cost(125); 4320 format %{ "movl $dst, $mem\t# uint -> long" %} 4321 4322 ins_encode %{ 4323 __ movl($dst$$Register, $mem$$Address); 4324 %} 4325 4326 ins_pipe(ialu_reg_mem); 4327 %} 4328 4329 // Load Long 4330 instruct loadL(rRegL dst, memory mem) 4331 %{ 4332 match(Set dst (LoadL mem)); 4333 4334 ins_cost(125); 4335 format %{ "movq $dst, $mem\t# long" %} 4336 4337 ins_encode %{ 4338 __ movq($dst$$Register, $mem$$Address); 4339 %} 4340 4341 ins_pipe(ialu_reg_mem); // XXX 4342 %} 4343 4344 // Load Range 4345 instruct loadRange(rRegI dst, memory mem) 4346 %{ 4347 match(Set dst (LoadRange mem)); 4348 4349 ins_cost(125); // XXX 4350 format %{ "movl $dst, $mem\t# range" %} 4351 ins_encode %{ 4352 __ movl($dst$$Register, $mem$$Address); 4353 %} 4354 ins_pipe(ialu_reg_mem); 4355 %} 4356 4357 // Load Pointer 4358 instruct loadP(rRegP dst, memory mem) 4359 %{ 4360 match(Set dst (LoadP mem)); 4361 predicate(n->as_Load()->barrier_data() == 0); 4362 4363 ins_cost(125); // XXX 4364 format %{ "movq $dst, $mem\t# ptr" %} 4365 ins_encode %{ 4366 __ movq($dst$$Register, $mem$$Address); 4367 %} 4368 ins_pipe(ialu_reg_mem); // XXX 4369 %} 4370 4371 // Load Compressed Pointer 4372 instruct loadN(rRegN dst, memory mem) 4373 %{ 4374 predicate(n->as_Load()->barrier_data() == 0); 4375 match(Set dst (LoadN mem)); 4376 4377 ins_cost(125); // XXX 4378 format %{ "movl $dst, $mem\t# compressed ptr" %} 4379 ins_encode %{ 4380 __ movl($dst$$Register, $mem$$Address); 4381 %} 4382 ins_pipe(ialu_reg_mem); // XXX 4383 %} 4384 4385 4386 // Load Klass Pointer 4387 instruct loadKlass(rRegP dst, memory mem) 4388 %{ 4389 match(Set dst (LoadKlass mem)); 4390 4391 ins_cost(125); // XXX 4392 format %{ "movq $dst, $mem\t# class" %} 4393 ins_encode %{ 4394 __ movq($dst$$Register, $mem$$Address); 4395 %} 4396 ins_pipe(ialu_reg_mem); // XXX 4397 %} 4398 4399 // Load narrow Klass Pointer 4400 instruct loadNKlass(rRegN dst, memory mem) 4401 %{ 4402 predicate(!UseCompactObjectHeaders); 4403 match(Set dst (LoadNKlass mem)); 4404 4405 ins_cost(125); // XXX 4406 format %{ "movl $dst, $mem\t# compressed klass ptr" %} 4407 ins_encode %{ 4408 __ movl($dst$$Register, $mem$$Address); 4409 %} 4410 ins_pipe(ialu_reg_mem); // XXX 4411 %} 4412 4413 instruct loadNKlassCompactHeaders(rRegN dst, memory mem, rFlagsReg cr) 4414 %{ 4415 predicate(UseCompactObjectHeaders); 4416 match(Set dst (LoadNKlass mem)); 4417 effect(KILL cr); 4418 ins_cost(125); 4419 format %{ 4420 "movl $dst, $mem\t# compressed klass ptr, shifted\n\t" 4421 "shrl $dst, markWord::klass_shift_at_offset" 4422 %} 4423 ins_encode %{ 4424 if (UseAPX) { 4425 __ eshrl($dst$$Register, $mem$$Address, markWord::klass_shift_at_offset, false); 4426 } 4427 else { 4428 __ movl($dst$$Register, $mem$$Address); 4429 __ shrl($dst$$Register, markWord::klass_shift_at_offset); 4430 } 4431 %} 4432 ins_pipe(ialu_reg_mem); 4433 %} 4434 4435 // Load Float 4436 instruct loadF(regF dst, memory mem) 4437 %{ 4438 match(Set dst (LoadF mem)); 4439 4440 ins_cost(145); // XXX 4441 format %{ "movss $dst, $mem\t# float" %} 4442 ins_encode %{ 4443 __ movflt($dst$$XMMRegister, $mem$$Address); 4444 %} 4445 ins_pipe(pipe_slow); // XXX 4446 %} 4447 4448 // Load Double 4449 instruct loadD_partial(regD dst, memory mem) 4450 %{ 4451 predicate(!UseXmmLoadAndClearUpper); 4452 match(Set dst (LoadD mem)); 4453 4454 ins_cost(145); // XXX 4455 format %{ "movlpd $dst, $mem\t# double" %} 4456 ins_encode %{ 4457 __ movdbl($dst$$XMMRegister, $mem$$Address); 4458 %} 4459 ins_pipe(pipe_slow); // XXX 4460 %} 4461 4462 instruct loadD(regD dst, memory mem) 4463 %{ 4464 predicate(UseXmmLoadAndClearUpper); 4465 match(Set dst (LoadD mem)); 4466 4467 ins_cost(145); // XXX 4468 format %{ "movsd $dst, $mem\t# double" %} 4469 ins_encode %{ 4470 __ movdbl($dst$$XMMRegister, $mem$$Address); 4471 %} 4472 ins_pipe(pipe_slow); // XXX 4473 %} 4474 4475 // max = java.lang.Math.max(float a, float b) 4476 instruct maxF_reg(legRegF dst, legRegF a, legRegF b, legRegF tmp, legRegF atmp, legRegF btmp) %{ 4477 predicate(UseAVX > 0 && !VLoopReductions::is_reduction(n)); 4478 match(Set dst (MaxF a b)); 4479 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 4480 format %{ "maxF $dst, $a, $b \t! using $tmp, $atmp and $btmp as TEMP" %} 4481 ins_encode %{ 4482 __ vminmax_fp(Op_MaxV, T_FLOAT, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, Assembler::AVX_128bit); 4483 %} 4484 ins_pipe( pipe_slow ); 4485 %} 4486 4487 instruct maxF_reduction_reg(legRegF dst, legRegF a, legRegF b, legRegF xtmp, rRegI rtmp, rFlagsReg cr) %{ 4488 predicate(UseAVX > 0 && VLoopReductions::is_reduction(n)); 4489 match(Set dst (MaxF a b)); 4490 effect(USE a, USE b, TEMP xtmp, TEMP rtmp, KILL cr); 4491 4492 format %{ "maxF_reduction $dst, $a, $b \t!using $xtmp and $rtmp as TEMP" %} 4493 ins_encode %{ 4494 emit_fp_min_max(masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xtmp$$XMMRegister, $rtmp$$Register, 4495 false /*min*/, true /*single*/); 4496 %} 4497 ins_pipe( pipe_slow ); 4498 %} 4499 4500 // max = java.lang.Math.max(double a, double b) 4501 instruct maxD_reg(legRegD dst, legRegD a, legRegD b, legRegD tmp, legRegD atmp, legRegD btmp) %{ 4502 predicate(UseAVX > 0 && !VLoopReductions::is_reduction(n)); 4503 match(Set dst (MaxD a b)); 4504 effect(USE a, USE b, TEMP atmp, TEMP btmp, TEMP tmp); 4505 format %{ "maxD $dst, $a, $b \t! using $tmp, $atmp and $btmp as TEMP" %} 4506 ins_encode %{ 4507 __ vminmax_fp(Op_MaxV, T_DOUBLE, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, Assembler::AVX_128bit); 4508 %} 4509 ins_pipe( pipe_slow ); 4510 %} 4511 4512 instruct maxD_reduction_reg(legRegD dst, legRegD a, legRegD b, legRegD xtmp, rRegL rtmp, rFlagsReg cr) %{ 4513 predicate(UseAVX > 0 && VLoopReductions::is_reduction(n)); 4514 match(Set dst (MaxD a b)); 4515 effect(USE a, USE b, TEMP xtmp, TEMP rtmp, KILL cr); 4516 4517 format %{ "maxD_reduction $dst, $a, $b \t! using $xtmp and $rtmp as TEMP" %} 4518 ins_encode %{ 4519 emit_fp_min_max(masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xtmp$$XMMRegister, $rtmp$$Register, 4520 false /*min*/, false /*single*/); 4521 %} 4522 ins_pipe( pipe_slow ); 4523 %} 4524 4525 // min = java.lang.Math.min(float a, float b) 4526 instruct minF_reg(legRegF dst, legRegF a, legRegF b, legRegF tmp, legRegF atmp, legRegF btmp) %{ 4527 predicate(UseAVX > 0 && !VLoopReductions::is_reduction(n)); 4528 match(Set dst (MinF a b)); 4529 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 4530 format %{ "minF $dst, $a, $b \t! using $tmp, $atmp and $btmp as TEMP" %} 4531 ins_encode %{ 4532 __ vminmax_fp(Op_MinV, T_FLOAT, $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 minF_reduction_reg(legRegF dst, legRegF a, legRegF b, legRegF xtmp, rRegI rtmp, rFlagsReg cr) %{ 4538 predicate(UseAVX > 0 && VLoopReductions::is_reduction(n)); 4539 match(Set dst (MinF a b)); 4540 effect(USE a, USE b, TEMP xtmp, TEMP rtmp, KILL cr); 4541 4542 format %{ "minF_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 true /*min*/, true /*single*/); 4546 %} 4547 ins_pipe( pipe_slow ); 4548 %} 4549 4550 // min = java.lang.Math.min(double a, double b) 4551 instruct minD_reg(legRegD dst, legRegD a, legRegD b, legRegD tmp, legRegD atmp, legRegD btmp) %{ 4552 predicate(UseAVX > 0 && !VLoopReductions::is_reduction(n)); 4553 match(Set dst (MinD a b)); 4554 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 4555 format %{ "minD $dst, $a, $b \t! using $tmp, $atmp and $btmp as TEMP" %} 4556 ins_encode %{ 4557 __ vminmax_fp(Op_MinV, T_DOUBLE, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, Assembler::AVX_128bit); 4558 %} 4559 ins_pipe( pipe_slow ); 4560 %} 4561 4562 instruct minD_reduction_reg(legRegD dst, legRegD a, legRegD b, legRegD xtmp, rRegL rtmp, rFlagsReg cr) %{ 4563 predicate(UseAVX > 0 && VLoopReductions::is_reduction(n)); 4564 match(Set dst (MinD a b)); 4565 effect(USE a, USE b, TEMP xtmp, TEMP rtmp, KILL cr); 4566 4567 format %{ "maxD_reduction $dst, $a, $b \t! using $xtmp and $rtmp as TEMP" %} 4568 ins_encode %{ 4569 emit_fp_min_max(masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xtmp$$XMMRegister, $rtmp$$Register, 4570 true /*min*/, false /*single*/); 4571 %} 4572 ins_pipe( pipe_slow ); 4573 %} 4574 4575 // Load Effective Address 4576 instruct leaP8(rRegP dst, indOffset8 mem) 4577 %{ 4578 match(Set dst mem); 4579 4580 ins_cost(110); // XXX 4581 format %{ "leaq $dst, $mem\t# ptr 8" %} 4582 ins_encode %{ 4583 __ leaq($dst$$Register, $mem$$Address); 4584 %} 4585 ins_pipe(ialu_reg_reg_fat); 4586 %} 4587 4588 instruct leaP32(rRegP dst, indOffset32 mem) 4589 %{ 4590 match(Set dst mem); 4591 4592 ins_cost(110); 4593 format %{ "leaq $dst, $mem\t# ptr 32" %} 4594 ins_encode %{ 4595 __ leaq($dst$$Register, $mem$$Address); 4596 %} 4597 ins_pipe(ialu_reg_reg_fat); 4598 %} 4599 4600 instruct leaPIdxOff(rRegP dst, indIndexOffset mem) 4601 %{ 4602 match(Set dst mem); 4603 4604 ins_cost(110); 4605 format %{ "leaq $dst, $mem\t# ptr idxoff" %} 4606 ins_encode %{ 4607 __ leaq($dst$$Register, $mem$$Address); 4608 %} 4609 ins_pipe(ialu_reg_reg_fat); 4610 %} 4611 4612 instruct leaPIdxScale(rRegP dst, indIndexScale mem) 4613 %{ 4614 match(Set dst mem); 4615 4616 ins_cost(110); 4617 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 4618 ins_encode %{ 4619 __ leaq($dst$$Register, $mem$$Address); 4620 %} 4621 ins_pipe(ialu_reg_reg_fat); 4622 %} 4623 4624 instruct leaPPosIdxScale(rRegP dst, indPosIndexScale mem) 4625 %{ 4626 match(Set dst mem); 4627 4628 ins_cost(110); 4629 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 4630 ins_encode %{ 4631 __ leaq($dst$$Register, $mem$$Address); 4632 %} 4633 ins_pipe(ialu_reg_reg_fat); 4634 %} 4635 4636 instruct leaPIdxScaleOff(rRegP dst, indIndexScaleOffset mem) 4637 %{ 4638 match(Set dst mem); 4639 4640 ins_cost(110); 4641 format %{ "leaq $dst, $mem\t# ptr idxscaleoff" %} 4642 ins_encode %{ 4643 __ leaq($dst$$Register, $mem$$Address); 4644 %} 4645 ins_pipe(ialu_reg_reg_fat); 4646 %} 4647 4648 instruct leaPPosIdxOff(rRegP dst, indPosIndexOffset mem) 4649 %{ 4650 match(Set dst mem); 4651 4652 ins_cost(110); 4653 format %{ "leaq $dst, $mem\t# ptr posidxoff" %} 4654 ins_encode %{ 4655 __ leaq($dst$$Register, $mem$$Address); 4656 %} 4657 ins_pipe(ialu_reg_reg_fat); 4658 %} 4659 4660 instruct leaPPosIdxScaleOff(rRegP dst, indPosIndexScaleOffset mem) 4661 %{ 4662 match(Set dst mem); 4663 4664 ins_cost(110); 4665 format %{ "leaq $dst, $mem\t# ptr posidxscaleoff" %} 4666 ins_encode %{ 4667 __ leaq($dst$$Register, $mem$$Address); 4668 %} 4669 ins_pipe(ialu_reg_reg_fat); 4670 %} 4671 4672 // Load Effective Address which uses Narrow (32-bits) oop 4673 instruct leaPCompressedOopOffset(rRegP dst, indCompressedOopOffset mem) 4674 %{ 4675 predicate(UseCompressedOops && (CompressedOops::shift() != 0)); 4676 match(Set dst mem); 4677 4678 ins_cost(110); 4679 format %{ "leaq $dst, $mem\t# ptr compressedoopoff32" %} 4680 ins_encode %{ 4681 __ leaq($dst$$Register, $mem$$Address); 4682 %} 4683 ins_pipe(ialu_reg_reg_fat); 4684 %} 4685 4686 instruct leaP8Narrow(rRegP dst, indOffset8Narrow mem) 4687 %{ 4688 predicate(CompressedOops::shift() == 0); 4689 match(Set dst mem); 4690 4691 ins_cost(110); // XXX 4692 format %{ "leaq $dst, $mem\t# ptr off8narrow" %} 4693 ins_encode %{ 4694 __ leaq($dst$$Register, $mem$$Address); 4695 %} 4696 ins_pipe(ialu_reg_reg_fat); 4697 %} 4698 4699 instruct leaP32Narrow(rRegP dst, indOffset32Narrow mem) 4700 %{ 4701 predicate(CompressedOops::shift() == 0); 4702 match(Set dst mem); 4703 4704 ins_cost(110); 4705 format %{ "leaq $dst, $mem\t# ptr off32narrow" %} 4706 ins_encode %{ 4707 __ leaq($dst$$Register, $mem$$Address); 4708 %} 4709 ins_pipe(ialu_reg_reg_fat); 4710 %} 4711 4712 instruct leaPIdxOffNarrow(rRegP dst, indIndexOffsetNarrow mem) 4713 %{ 4714 predicate(CompressedOops::shift() == 0); 4715 match(Set dst mem); 4716 4717 ins_cost(110); 4718 format %{ "leaq $dst, $mem\t# ptr idxoffnarrow" %} 4719 ins_encode %{ 4720 __ leaq($dst$$Register, $mem$$Address); 4721 %} 4722 ins_pipe(ialu_reg_reg_fat); 4723 %} 4724 4725 instruct leaPIdxScaleNarrow(rRegP dst, indIndexScaleNarrow mem) 4726 %{ 4727 predicate(CompressedOops::shift() == 0); 4728 match(Set dst mem); 4729 4730 ins_cost(110); 4731 format %{ "leaq $dst, $mem\t# ptr idxscalenarrow" %} 4732 ins_encode %{ 4733 __ leaq($dst$$Register, $mem$$Address); 4734 %} 4735 ins_pipe(ialu_reg_reg_fat); 4736 %} 4737 4738 instruct leaPIdxScaleOffNarrow(rRegP dst, indIndexScaleOffsetNarrow mem) 4739 %{ 4740 predicate(CompressedOops::shift() == 0); 4741 match(Set dst mem); 4742 4743 ins_cost(110); 4744 format %{ "leaq $dst, $mem\t# ptr idxscaleoffnarrow" %} 4745 ins_encode %{ 4746 __ leaq($dst$$Register, $mem$$Address); 4747 %} 4748 ins_pipe(ialu_reg_reg_fat); 4749 %} 4750 4751 instruct leaPPosIdxOffNarrow(rRegP dst, indPosIndexOffsetNarrow mem) 4752 %{ 4753 predicate(CompressedOops::shift() == 0); 4754 match(Set dst mem); 4755 4756 ins_cost(110); 4757 format %{ "leaq $dst, $mem\t# ptr posidxoffnarrow" %} 4758 ins_encode %{ 4759 __ leaq($dst$$Register, $mem$$Address); 4760 %} 4761 ins_pipe(ialu_reg_reg_fat); 4762 %} 4763 4764 instruct leaPPosIdxScaleOffNarrow(rRegP dst, indPosIndexScaleOffsetNarrow mem) 4765 %{ 4766 predicate(CompressedOops::shift() == 0); 4767 match(Set dst mem); 4768 4769 ins_cost(110); 4770 format %{ "leaq $dst, $mem\t# ptr posidxscaleoffnarrow" %} 4771 ins_encode %{ 4772 __ leaq($dst$$Register, $mem$$Address); 4773 %} 4774 ins_pipe(ialu_reg_reg_fat); 4775 %} 4776 4777 instruct loadConI(rRegI dst, immI src) 4778 %{ 4779 match(Set dst src); 4780 4781 format %{ "movl $dst, $src\t# int" %} 4782 ins_encode %{ 4783 __ movl($dst$$Register, $src$$constant); 4784 %} 4785 ins_pipe(ialu_reg_fat); // XXX 4786 %} 4787 4788 instruct loadConI0(rRegI dst, immI_0 src, rFlagsReg cr) 4789 %{ 4790 match(Set dst src); 4791 effect(KILL cr); 4792 4793 ins_cost(50); 4794 format %{ "xorl $dst, $dst\t# int" %} 4795 ins_encode %{ 4796 __ xorl($dst$$Register, $dst$$Register); 4797 %} 4798 ins_pipe(ialu_reg); 4799 %} 4800 4801 instruct loadConL(rRegL dst, immL src) 4802 %{ 4803 match(Set dst src); 4804 4805 ins_cost(150); 4806 format %{ "movq $dst, $src\t# long" %} 4807 ins_encode %{ 4808 __ mov64($dst$$Register, $src$$constant); 4809 %} 4810 ins_pipe(ialu_reg); 4811 %} 4812 4813 instruct loadConL0(rRegL dst, immL0 src, rFlagsReg cr) 4814 %{ 4815 match(Set dst src); 4816 effect(KILL cr); 4817 4818 ins_cost(50); 4819 format %{ "xorl $dst, $dst\t# long" %} 4820 ins_encode %{ 4821 __ xorl($dst$$Register, $dst$$Register); 4822 %} 4823 ins_pipe(ialu_reg); // XXX 4824 %} 4825 4826 instruct loadConUL32(rRegL dst, immUL32 src) 4827 %{ 4828 match(Set dst src); 4829 4830 ins_cost(60); 4831 format %{ "movl $dst, $src\t# long (unsigned 32-bit)" %} 4832 ins_encode %{ 4833 __ movl($dst$$Register, $src$$constant); 4834 %} 4835 ins_pipe(ialu_reg); 4836 %} 4837 4838 instruct loadConL32(rRegL dst, immL32 src) 4839 %{ 4840 match(Set dst src); 4841 4842 ins_cost(70); 4843 format %{ "movq $dst, $src\t# long (32-bit)" %} 4844 ins_encode %{ 4845 __ movq($dst$$Register, $src$$constant); 4846 %} 4847 ins_pipe(ialu_reg); 4848 %} 4849 4850 instruct loadConP(rRegP dst, immP con) %{ 4851 match(Set dst con); 4852 4853 format %{ "movq $dst, $con\t# ptr" %} 4854 ins_encode %{ 4855 __ mov64($dst$$Register, $con$$constant, $con->constant_reloc(), RELOC_IMM64); 4856 %} 4857 ins_pipe(ialu_reg_fat); // XXX 4858 %} 4859 4860 instruct loadConP0(rRegP dst, immP0 src, rFlagsReg cr) 4861 %{ 4862 match(Set dst src); 4863 effect(KILL cr); 4864 4865 ins_cost(50); 4866 format %{ "xorl $dst, $dst\t# ptr" %} 4867 ins_encode %{ 4868 __ xorl($dst$$Register, $dst$$Register); 4869 %} 4870 ins_pipe(ialu_reg); 4871 %} 4872 4873 instruct loadConP31(rRegP dst, immP31 src, rFlagsReg cr) 4874 %{ 4875 match(Set dst src); 4876 effect(KILL cr); 4877 4878 ins_cost(60); 4879 format %{ "movl $dst, $src\t# ptr (positive 32-bit)" %} 4880 ins_encode %{ 4881 __ movl($dst$$Register, $src$$constant); 4882 %} 4883 ins_pipe(ialu_reg); 4884 %} 4885 4886 instruct loadConF(regF dst, immF con) %{ 4887 match(Set dst con); 4888 ins_cost(125); 4889 format %{ "movss $dst, [$constantaddress]\t# load from constant table: float=$con" %} 4890 ins_encode %{ 4891 __ movflt($dst$$XMMRegister, $constantaddress($con)); 4892 %} 4893 ins_pipe(pipe_slow); 4894 %} 4895 4896 instruct loadConH(regF dst, immH con) %{ 4897 match(Set dst con); 4898 ins_cost(125); 4899 format %{ "movss $dst, [$constantaddress]\t# load from constant table: halffloat=$con" %} 4900 ins_encode %{ 4901 __ movflt($dst$$XMMRegister, $constantaddress($con)); 4902 %} 4903 ins_pipe(pipe_slow); 4904 %} 4905 4906 instruct loadConN0(rRegN dst, immN0 src, rFlagsReg cr) %{ 4907 match(Set dst src); 4908 effect(KILL cr); 4909 format %{ "xorq $dst, $src\t# compressed null pointer" %} 4910 ins_encode %{ 4911 __ xorq($dst$$Register, $dst$$Register); 4912 %} 4913 ins_pipe(ialu_reg); 4914 %} 4915 4916 instruct loadConN(rRegN dst, immN src) %{ 4917 match(Set dst src); 4918 4919 ins_cost(125); 4920 format %{ "movl $dst, $src\t# compressed ptr" %} 4921 ins_encode %{ 4922 address con = (address)$src$$constant; 4923 if (con == nullptr) { 4924 ShouldNotReachHere(); 4925 } else { 4926 __ set_narrow_oop($dst$$Register, (jobject)$src$$constant); 4927 } 4928 %} 4929 ins_pipe(ialu_reg_fat); // XXX 4930 %} 4931 4932 instruct loadConNKlass(rRegN dst, immNKlass src) %{ 4933 match(Set dst src); 4934 4935 ins_cost(125); 4936 format %{ "movl $dst, $src\t# compressed klass ptr" %} 4937 ins_encode %{ 4938 address con = (address)$src$$constant; 4939 if (con == nullptr) { 4940 ShouldNotReachHere(); 4941 } else { 4942 __ set_narrow_klass($dst$$Register, (Klass*)$src$$constant); 4943 } 4944 %} 4945 ins_pipe(ialu_reg_fat); // XXX 4946 %} 4947 4948 instruct loadConF0(regF dst, immF0 src) 4949 %{ 4950 match(Set dst src); 4951 ins_cost(100); 4952 4953 format %{ "xorps $dst, $dst\t# float 0.0" %} 4954 ins_encode %{ 4955 __ xorps($dst$$XMMRegister, $dst$$XMMRegister); 4956 %} 4957 ins_pipe(pipe_slow); 4958 %} 4959 4960 // Use the same format since predicate() can not be used here. 4961 instruct loadConD(regD dst, immD con) %{ 4962 match(Set dst con); 4963 ins_cost(125); 4964 format %{ "movsd $dst, [$constantaddress]\t# load from constant table: double=$con" %} 4965 ins_encode %{ 4966 __ movdbl($dst$$XMMRegister, $constantaddress($con)); 4967 %} 4968 ins_pipe(pipe_slow); 4969 %} 4970 4971 instruct loadConD0(regD dst, immD0 src) 4972 %{ 4973 match(Set dst src); 4974 ins_cost(100); 4975 4976 format %{ "xorpd $dst, $dst\t# double 0.0" %} 4977 ins_encode %{ 4978 __ xorpd($dst$$XMMRegister, $dst$$XMMRegister); 4979 %} 4980 ins_pipe(pipe_slow); 4981 %} 4982 4983 instruct loadSSI(rRegI dst, stackSlotI src) 4984 %{ 4985 match(Set dst src); 4986 4987 ins_cost(125); 4988 format %{ "movl $dst, $src\t# int stk" %} 4989 ins_encode %{ 4990 __ movl($dst$$Register, $src$$Address); 4991 %} 4992 ins_pipe(ialu_reg_mem); 4993 %} 4994 4995 instruct loadSSL(rRegL dst, stackSlotL src) 4996 %{ 4997 match(Set dst src); 4998 4999 ins_cost(125); 5000 format %{ "movq $dst, $src\t# long stk" %} 5001 ins_encode %{ 5002 __ movq($dst$$Register, $src$$Address); 5003 %} 5004 ins_pipe(ialu_reg_mem); 5005 %} 5006 5007 instruct loadSSP(rRegP dst, stackSlotP src) 5008 %{ 5009 match(Set dst src); 5010 5011 ins_cost(125); 5012 format %{ "movq $dst, $src\t# ptr stk" %} 5013 ins_encode %{ 5014 __ movq($dst$$Register, $src$$Address); 5015 %} 5016 ins_pipe(ialu_reg_mem); 5017 %} 5018 5019 instruct loadSSF(regF dst, stackSlotF src) 5020 %{ 5021 match(Set dst src); 5022 5023 ins_cost(125); 5024 format %{ "movss $dst, $src\t# float stk" %} 5025 ins_encode %{ 5026 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 5027 %} 5028 ins_pipe(pipe_slow); // XXX 5029 %} 5030 5031 // Use the same format since predicate() can not be used here. 5032 instruct loadSSD(regD dst, stackSlotD src) 5033 %{ 5034 match(Set dst src); 5035 5036 ins_cost(125); 5037 format %{ "movsd $dst, $src\t# double stk" %} 5038 ins_encode %{ 5039 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 5040 %} 5041 ins_pipe(pipe_slow); // XXX 5042 %} 5043 5044 // Prefetch instructions for allocation. 5045 // Must be safe to execute with invalid address (cannot fault). 5046 5047 instruct prefetchAlloc( memory mem ) %{ 5048 predicate(AllocatePrefetchInstr==3); 5049 match(PrefetchAllocation mem); 5050 ins_cost(125); 5051 5052 format %{ "PREFETCHW $mem\t# Prefetch allocation into level 1 cache and mark modified" %} 5053 ins_encode %{ 5054 __ prefetchw($mem$$Address); 5055 %} 5056 ins_pipe(ialu_mem); 5057 %} 5058 5059 instruct prefetchAllocNTA( memory mem ) %{ 5060 predicate(AllocatePrefetchInstr==0); 5061 match(PrefetchAllocation mem); 5062 ins_cost(125); 5063 5064 format %{ "PREFETCHNTA $mem\t# Prefetch allocation to non-temporal cache for write" %} 5065 ins_encode %{ 5066 __ prefetchnta($mem$$Address); 5067 %} 5068 ins_pipe(ialu_mem); 5069 %} 5070 5071 instruct prefetchAllocT0( memory mem ) %{ 5072 predicate(AllocatePrefetchInstr==1); 5073 match(PrefetchAllocation mem); 5074 ins_cost(125); 5075 5076 format %{ "PREFETCHT0 $mem\t# Prefetch allocation to level 1 and 2 caches for write" %} 5077 ins_encode %{ 5078 __ prefetcht0($mem$$Address); 5079 %} 5080 ins_pipe(ialu_mem); 5081 %} 5082 5083 instruct prefetchAllocT2( memory mem ) %{ 5084 predicate(AllocatePrefetchInstr==2); 5085 match(PrefetchAllocation mem); 5086 ins_cost(125); 5087 5088 format %{ "PREFETCHT2 $mem\t# Prefetch allocation to level 2 cache for write" %} 5089 ins_encode %{ 5090 __ prefetcht2($mem$$Address); 5091 %} 5092 ins_pipe(ialu_mem); 5093 %} 5094 5095 //----------Store Instructions------------------------------------------------- 5096 5097 // Store Byte 5098 instruct storeB(memory mem, rRegI src) 5099 %{ 5100 match(Set mem (StoreB mem src)); 5101 5102 ins_cost(125); // XXX 5103 format %{ "movb $mem, $src\t# byte" %} 5104 ins_encode %{ 5105 __ movb($mem$$Address, $src$$Register); 5106 %} 5107 ins_pipe(ialu_mem_reg); 5108 %} 5109 5110 // Store Char/Short 5111 instruct storeC(memory mem, rRegI src) 5112 %{ 5113 match(Set mem (StoreC mem src)); 5114 5115 ins_cost(125); // XXX 5116 format %{ "movw $mem, $src\t# char/short" %} 5117 ins_encode %{ 5118 __ movw($mem$$Address, $src$$Register); 5119 %} 5120 ins_pipe(ialu_mem_reg); 5121 %} 5122 5123 // Store Integer 5124 instruct storeI(memory mem, rRegI src) 5125 %{ 5126 match(Set mem (StoreI mem src)); 5127 5128 ins_cost(125); // XXX 5129 format %{ "movl $mem, $src\t# int" %} 5130 ins_encode %{ 5131 __ movl($mem$$Address, $src$$Register); 5132 %} 5133 ins_pipe(ialu_mem_reg); 5134 %} 5135 5136 // Store Long 5137 instruct storeL(memory mem, rRegL src) 5138 %{ 5139 match(Set mem (StoreL mem src)); 5140 5141 ins_cost(125); // XXX 5142 format %{ "movq $mem, $src\t# long" %} 5143 ins_encode %{ 5144 __ movq($mem$$Address, $src$$Register); 5145 %} 5146 ins_pipe(ialu_mem_reg); // XXX 5147 %} 5148 5149 // Store Pointer 5150 instruct storeP(memory mem, any_RegP src) 5151 %{ 5152 predicate(n->as_Store()->barrier_data() == 0); 5153 match(Set mem (StoreP mem src)); 5154 5155 ins_cost(125); // XXX 5156 format %{ "movq $mem, $src\t# ptr" %} 5157 ins_encode %{ 5158 __ movq($mem$$Address, $src$$Register); 5159 %} 5160 ins_pipe(ialu_mem_reg); 5161 %} 5162 5163 instruct storeImmP0(memory mem, immP0 zero) 5164 %{ 5165 predicate(UseCompressedOops && (CompressedOops::base() == nullptr) && n->as_Store()->barrier_data() == 0); 5166 match(Set mem (StoreP mem zero)); 5167 5168 ins_cost(125); // XXX 5169 format %{ "movq $mem, R12\t# ptr (R12_heapbase==0)" %} 5170 ins_encode %{ 5171 __ movq($mem$$Address, r12); 5172 %} 5173 ins_pipe(ialu_mem_reg); 5174 %} 5175 5176 // Store Null Pointer, mark word, or other simple pointer constant. 5177 instruct storeImmP(memory mem, immP31 src) 5178 %{ 5179 predicate(n->as_Store()->barrier_data() == 0); 5180 match(Set mem (StoreP mem src)); 5181 5182 ins_cost(150); // XXX 5183 format %{ "movq $mem, $src\t# ptr" %} 5184 ins_encode %{ 5185 __ movq($mem$$Address, $src$$constant); 5186 %} 5187 ins_pipe(ialu_mem_imm); 5188 %} 5189 5190 // Store Compressed Pointer 5191 instruct storeN(memory mem, rRegN src) 5192 %{ 5193 predicate(n->as_Store()->barrier_data() == 0); 5194 match(Set mem (StoreN mem src)); 5195 5196 ins_cost(125); // XXX 5197 format %{ "movl $mem, $src\t# compressed ptr" %} 5198 ins_encode %{ 5199 __ movl($mem$$Address, $src$$Register); 5200 %} 5201 ins_pipe(ialu_mem_reg); 5202 %} 5203 5204 instruct storeNKlass(memory mem, rRegN src) 5205 %{ 5206 match(Set mem (StoreNKlass mem src)); 5207 5208 ins_cost(125); // XXX 5209 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5210 ins_encode %{ 5211 __ movl($mem$$Address, $src$$Register); 5212 %} 5213 ins_pipe(ialu_mem_reg); 5214 %} 5215 5216 instruct storeImmN0(memory mem, immN0 zero) 5217 %{ 5218 predicate(CompressedOops::base() == nullptr && n->as_Store()->barrier_data() == 0); 5219 match(Set mem (StoreN mem zero)); 5220 5221 ins_cost(125); // XXX 5222 format %{ "movl $mem, R12\t# compressed ptr (R12_heapbase==0)" %} 5223 ins_encode %{ 5224 __ movl($mem$$Address, r12); 5225 %} 5226 ins_pipe(ialu_mem_reg); 5227 %} 5228 5229 instruct storeImmN(memory mem, immN src) 5230 %{ 5231 predicate(n->as_Store()->barrier_data() == 0); 5232 match(Set mem (StoreN mem src)); 5233 5234 ins_cost(150); // XXX 5235 format %{ "movl $mem, $src\t# compressed ptr" %} 5236 ins_encode %{ 5237 address con = (address)$src$$constant; 5238 if (con == nullptr) { 5239 __ movl($mem$$Address, 0); 5240 } else { 5241 __ set_narrow_oop($mem$$Address, (jobject)$src$$constant); 5242 } 5243 %} 5244 ins_pipe(ialu_mem_imm); 5245 %} 5246 5247 instruct storeImmNKlass(memory mem, immNKlass src) 5248 %{ 5249 match(Set mem (StoreNKlass mem src)); 5250 5251 ins_cost(150); // XXX 5252 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5253 ins_encode %{ 5254 __ set_narrow_klass($mem$$Address, (Klass*)$src$$constant); 5255 %} 5256 ins_pipe(ialu_mem_imm); 5257 %} 5258 5259 // Store Integer Immediate 5260 instruct storeImmI0(memory mem, immI_0 zero) 5261 %{ 5262 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5263 match(Set mem (StoreI mem zero)); 5264 5265 ins_cost(125); // XXX 5266 format %{ "movl $mem, R12\t# int (R12_heapbase==0)" %} 5267 ins_encode %{ 5268 __ movl($mem$$Address, r12); 5269 %} 5270 ins_pipe(ialu_mem_reg); 5271 %} 5272 5273 instruct storeImmI(memory mem, immI src) 5274 %{ 5275 match(Set mem (StoreI mem src)); 5276 5277 ins_cost(150); 5278 format %{ "movl $mem, $src\t# int" %} 5279 ins_encode %{ 5280 __ movl($mem$$Address, $src$$constant); 5281 %} 5282 ins_pipe(ialu_mem_imm); 5283 %} 5284 5285 // Store Long Immediate 5286 instruct storeImmL0(memory mem, immL0 zero) 5287 %{ 5288 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5289 match(Set mem (StoreL mem zero)); 5290 5291 ins_cost(125); // XXX 5292 format %{ "movq $mem, R12\t# long (R12_heapbase==0)" %} 5293 ins_encode %{ 5294 __ movq($mem$$Address, r12); 5295 %} 5296 ins_pipe(ialu_mem_reg); 5297 %} 5298 5299 instruct storeImmL(memory mem, immL32 src) 5300 %{ 5301 match(Set mem (StoreL mem src)); 5302 5303 ins_cost(150); 5304 format %{ "movq $mem, $src\t# long" %} 5305 ins_encode %{ 5306 __ movq($mem$$Address, $src$$constant); 5307 %} 5308 ins_pipe(ialu_mem_imm); 5309 %} 5310 5311 // Store Short/Char Immediate 5312 instruct storeImmC0(memory mem, immI_0 zero) 5313 %{ 5314 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5315 match(Set mem (StoreC mem zero)); 5316 5317 ins_cost(125); // XXX 5318 format %{ "movw $mem, R12\t# short/char (R12_heapbase==0)" %} 5319 ins_encode %{ 5320 __ movw($mem$$Address, r12); 5321 %} 5322 ins_pipe(ialu_mem_reg); 5323 %} 5324 5325 instruct storeImmI16(memory mem, immI16 src) 5326 %{ 5327 predicate(UseStoreImmI16); 5328 match(Set mem (StoreC mem src)); 5329 5330 ins_cost(150); 5331 format %{ "movw $mem, $src\t# short/char" %} 5332 ins_encode %{ 5333 __ movw($mem$$Address, $src$$constant); 5334 %} 5335 ins_pipe(ialu_mem_imm); 5336 %} 5337 5338 // Store Byte Immediate 5339 instruct storeImmB0(memory mem, immI_0 zero) 5340 %{ 5341 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5342 match(Set mem (StoreB mem zero)); 5343 5344 ins_cost(125); // XXX 5345 format %{ "movb $mem, R12\t# short/char (R12_heapbase==0)" %} 5346 ins_encode %{ 5347 __ movb($mem$$Address, r12); 5348 %} 5349 ins_pipe(ialu_mem_reg); 5350 %} 5351 5352 instruct storeImmB(memory mem, immI8 src) 5353 %{ 5354 match(Set mem (StoreB mem src)); 5355 5356 ins_cost(150); // XXX 5357 format %{ "movb $mem, $src\t# byte" %} 5358 ins_encode %{ 5359 __ movb($mem$$Address, $src$$constant); 5360 %} 5361 ins_pipe(ialu_mem_imm); 5362 %} 5363 5364 // Store Float 5365 instruct storeF(memory mem, regF src) 5366 %{ 5367 match(Set mem (StoreF mem src)); 5368 5369 ins_cost(95); // XXX 5370 format %{ "movss $mem, $src\t# float" %} 5371 ins_encode %{ 5372 __ movflt($mem$$Address, $src$$XMMRegister); 5373 %} 5374 ins_pipe(pipe_slow); // XXX 5375 %} 5376 5377 // Store immediate Float value (it is faster than store from XMM register) 5378 instruct storeF0(memory mem, immF0 zero) 5379 %{ 5380 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5381 match(Set mem (StoreF mem zero)); 5382 5383 ins_cost(25); // XXX 5384 format %{ "movl $mem, R12\t# float 0. (R12_heapbase==0)" %} 5385 ins_encode %{ 5386 __ movl($mem$$Address, r12); 5387 %} 5388 ins_pipe(ialu_mem_reg); 5389 %} 5390 5391 instruct storeF_imm(memory mem, immF src) 5392 %{ 5393 match(Set mem (StoreF mem src)); 5394 5395 ins_cost(50); 5396 format %{ "movl $mem, $src\t# float" %} 5397 ins_encode %{ 5398 __ movl($mem$$Address, jint_cast($src$$constant)); 5399 %} 5400 ins_pipe(ialu_mem_imm); 5401 %} 5402 5403 // Store Double 5404 instruct storeD(memory mem, regD src) 5405 %{ 5406 match(Set mem (StoreD mem src)); 5407 5408 ins_cost(95); // XXX 5409 format %{ "movsd $mem, $src\t# double" %} 5410 ins_encode %{ 5411 __ movdbl($mem$$Address, $src$$XMMRegister); 5412 %} 5413 ins_pipe(pipe_slow); // XXX 5414 %} 5415 5416 // Store immediate double 0.0 (it is faster than store from XMM register) 5417 instruct storeD0_imm(memory mem, immD0 src) 5418 %{ 5419 predicate(!UseCompressedOops || (CompressedOops::base() != nullptr)); 5420 match(Set mem (StoreD mem src)); 5421 5422 ins_cost(50); 5423 format %{ "movq $mem, $src\t# double 0." %} 5424 ins_encode %{ 5425 __ movq($mem$$Address, $src$$constant); 5426 %} 5427 ins_pipe(ialu_mem_imm); 5428 %} 5429 5430 instruct storeD0(memory mem, immD0 zero) 5431 %{ 5432 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5433 match(Set mem (StoreD mem zero)); 5434 5435 ins_cost(25); // XXX 5436 format %{ "movq $mem, R12\t# double 0. (R12_heapbase==0)" %} 5437 ins_encode %{ 5438 __ movq($mem$$Address, r12); 5439 %} 5440 ins_pipe(ialu_mem_reg); 5441 %} 5442 5443 instruct storeSSI(stackSlotI dst, rRegI src) 5444 %{ 5445 match(Set dst src); 5446 5447 ins_cost(100); 5448 format %{ "movl $dst, $src\t# int stk" %} 5449 ins_encode %{ 5450 __ movl($dst$$Address, $src$$Register); 5451 %} 5452 ins_pipe( ialu_mem_reg ); 5453 %} 5454 5455 instruct storeSSL(stackSlotL dst, rRegL src) 5456 %{ 5457 match(Set dst src); 5458 5459 ins_cost(100); 5460 format %{ "movq $dst, $src\t# long stk" %} 5461 ins_encode %{ 5462 __ movq($dst$$Address, $src$$Register); 5463 %} 5464 ins_pipe(ialu_mem_reg); 5465 %} 5466 5467 instruct storeSSP(stackSlotP dst, rRegP src) 5468 %{ 5469 match(Set dst src); 5470 5471 ins_cost(100); 5472 format %{ "movq $dst, $src\t# ptr stk" %} 5473 ins_encode %{ 5474 __ movq($dst$$Address, $src$$Register); 5475 %} 5476 ins_pipe(ialu_mem_reg); 5477 %} 5478 5479 instruct storeSSF(stackSlotF dst, regF src) 5480 %{ 5481 match(Set dst src); 5482 5483 ins_cost(95); // XXX 5484 format %{ "movss $dst, $src\t# float stk" %} 5485 ins_encode %{ 5486 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 5487 %} 5488 ins_pipe(pipe_slow); // XXX 5489 %} 5490 5491 instruct storeSSD(stackSlotD dst, regD src) 5492 %{ 5493 match(Set dst src); 5494 5495 ins_cost(95); // XXX 5496 format %{ "movsd $dst, $src\t# double stk" %} 5497 ins_encode %{ 5498 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 5499 %} 5500 ins_pipe(pipe_slow); // XXX 5501 %} 5502 5503 instruct cacheWB(indirect addr) 5504 %{ 5505 predicate(VM_Version::supports_data_cache_line_flush()); 5506 match(CacheWB addr); 5507 5508 ins_cost(100); 5509 format %{"cache wb $addr" %} 5510 ins_encode %{ 5511 assert($addr->index_position() < 0, "should be"); 5512 assert($addr$$disp == 0, "should be"); 5513 __ cache_wb(Address($addr$$base$$Register, 0)); 5514 %} 5515 ins_pipe(pipe_slow); // XXX 5516 %} 5517 5518 instruct cacheWBPreSync() 5519 %{ 5520 predicate(VM_Version::supports_data_cache_line_flush()); 5521 match(CacheWBPreSync); 5522 5523 ins_cost(100); 5524 format %{"cache wb presync" %} 5525 ins_encode %{ 5526 __ cache_wbsync(true); 5527 %} 5528 ins_pipe(pipe_slow); // XXX 5529 %} 5530 5531 instruct cacheWBPostSync() 5532 %{ 5533 predicate(VM_Version::supports_data_cache_line_flush()); 5534 match(CacheWBPostSync); 5535 5536 ins_cost(100); 5537 format %{"cache wb postsync" %} 5538 ins_encode %{ 5539 __ cache_wbsync(false); 5540 %} 5541 ins_pipe(pipe_slow); // XXX 5542 %} 5543 5544 //----------BSWAP Instructions------------------------------------------------- 5545 instruct bytes_reverse_int(rRegI dst) %{ 5546 match(Set dst (ReverseBytesI dst)); 5547 5548 format %{ "bswapl $dst" %} 5549 ins_encode %{ 5550 __ bswapl($dst$$Register); 5551 %} 5552 ins_pipe( ialu_reg ); 5553 %} 5554 5555 instruct bytes_reverse_long(rRegL dst) %{ 5556 match(Set dst (ReverseBytesL dst)); 5557 5558 format %{ "bswapq $dst" %} 5559 ins_encode %{ 5560 __ bswapq($dst$$Register); 5561 %} 5562 ins_pipe( ialu_reg); 5563 %} 5564 5565 instruct bytes_reverse_unsigned_short(rRegI dst, rFlagsReg cr) %{ 5566 match(Set dst (ReverseBytesUS dst)); 5567 effect(KILL cr); 5568 5569 format %{ "bswapl $dst\n\t" 5570 "shrl $dst,16\n\t" %} 5571 ins_encode %{ 5572 __ bswapl($dst$$Register); 5573 __ shrl($dst$$Register, 16); 5574 %} 5575 ins_pipe( ialu_reg ); 5576 %} 5577 5578 instruct bytes_reverse_short(rRegI dst, rFlagsReg cr) %{ 5579 match(Set dst (ReverseBytesS dst)); 5580 effect(KILL cr); 5581 5582 format %{ "bswapl $dst\n\t" 5583 "sar $dst,16\n\t" %} 5584 ins_encode %{ 5585 __ bswapl($dst$$Register); 5586 __ sarl($dst$$Register, 16); 5587 %} 5588 ins_pipe( ialu_reg ); 5589 %} 5590 5591 //---------- Zeros Count Instructions ------------------------------------------ 5592 5593 instruct countLeadingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 5594 predicate(UseCountLeadingZerosInstruction); 5595 match(Set dst (CountLeadingZerosI src)); 5596 effect(KILL cr); 5597 5598 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 5599 ins_encode %{ 5600 __ lzcntl($dst$$Register, $src$$Register); 5601 %} 5602 ins_pipe(ialu_reg); 5603 %} 5604 5605 instruct countLeadingZerosI_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5606 predicate(UseCountLeadingZerosInstruction); 5607 match(Set dst (CountLeadingZerosI (LoadI src))); 5608 effect(KILL cr); 5609 ins_cost(175); 5610 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 5611 ins_encode %{ 5612 __ lzcntl($dst$$Register, $src$$Address); 5613 %} 5614 ins_pipe(ialu_reg_mem); 5615 %} 5616 5617 instruct countLeadingZerosI_bsr(rRegI dst, rRegI src, rFlagsReg cr) %{ 5618 predicate(!UseCountLeadingZerosInstruction); 5619 match(Set dst (CountLeadingZerosI src)); 5620 effect(KILL cr); 5621 5622 format %{ "bsrl $dst, $src\t# count leading zeros (int)\n\t" 5623 "jnz skip\n\t" 5624 "movl $dst, -1\n" 5625 "skip:\n\t" 5626 "negl $dst\n\t" 5627 "addl $dst, 31" %} 5628 ins_encode %{ 5629 Register Rdst = $dst$$Register; 5630 Register Rsrc = $src$$Register; 5631 Label skip; 5632 __ bsrl(Rdst, Rsrc); 5633 __ jccb(Assembler::notZero, skip); 5634 __ movl(Rdst, -1); 5635 __ bind(skip); 5636 __ negl(Rdst); 5637 __ addl(Rdst, BitsPerInt - 1); 5638 %} 5639 ins_pipe(ialu_reg); 5640 %} 5641 5642 instruct countLeadingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 5643 predicate(UseCountLeadingZerosInstruction); 5644 match(Set dst (CountLeadingZerosL src)); 5645 effect(KILL cr); 5646 5647 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 5648 ins_encode %{ 5649 __ lzcntq($dst$$Register, $src$$Register); 5650 %} 5651 ins_pipe(ialu_reg); 5652 %} 5653 5654 instruct countLeadingZerosL_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5655 predicate(UseCountLeadingZerosInstruction); 5656 match(Set dst (CountLeadingZerosL (LoadL src))); 5657 effect(KILL cr); 5658 ins_cost(175); 5659 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 5660 ins_encode %{ 5661 __ lzcntq($dst$$Register, $src$$Address); 5662 %} 5663 ins_pipe(ialu_reg_mem); 5664 %} 5665 5666 instruct countLeadingZerosL_bsr(rRegI dst, rRegL src, rFlagsReg cr) %{ 5667 predicate(!UseCountLeadingZerosInstruction); 5668 match(Set dst (CountLeadingZerosL src)); 5669 effect(KILL cr); 5670 5671 format %{ "bsrq $dst, $src\t# count leading zeros (long)\n\t" 5672 "jnz skip\n\t" 5673 "movl $dst, -1\n" 5674 "skip:\n\t" 5675 "negl $dst\n\t" 5676 "addl $dst, 63" %} 5677 ins_encode %{ 5678 Register Rdst = $dst$$Register; 5679 Register Rsrc = $src$$Register; 5680 Label skip; 5681 __ bsrq(Rdst, Rsrc); 5682 __ jccb(Assembler::notZero, skip); 5683 __ movl(Rdst, -1); 5684 __ bind(skip); 5685 __ negl(Rdst); 5686 __ addl(Rdst, BitsPerLong - 1); 5687 %} 5688 ins_pipe(ialu_reg); 5689 %} 5690 5691 instruct countTrailingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 5692 predicate(UseCountTrailingZerosInstruction); 5693 match(Set dst (CountTrailingZerosI src)); 5694 effect(KILL cr); 5695 5696 format %{ "tzcntl $dst, $src\t# count trailing zeros (int)" %} 5697 ins_encode %{ 5698 __ tzcntl($dst$$Register, $src$$Register); 5699 %} 5700 ins_pipe(ialu_reg); 5701 %} 5702 5703 instruct countTrailingZerosI_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5704 predicate(UseCountTrailingZerosInstruction); 5705 match(Set dst (CountTrailingZerosI (LoadI src))); 5706 effect(KILL cr); 5707 ins_cost(175); 5708 format %{ "tzcntl $dst, $src\t# count trailing zeros (int)" %} 5709 ins_encode %{ 5710 __ tzcntl($dst$$Register, $src$$Address); 5711 %} 5712 ins_pipe(ialu_reg_mem); 5713 %} 5714 5715 instruct countTrailingZerosI_bsf(rRegI dst, rRegI src, rFlagsReg cr) %{ 5716 predicate(!UseCountTrailingZerosInstruction); 5717 match(Set dst (CountTrailingZerosI src)); 5718 effect(KILL cr); 5719 5720 format %{ "bsfl $dst, $src\t# count trailing zeros (int)\n\t" 5721 "jnz done\n\t" 5722 "movl $dst, 32\n" 5723 "done:" %} 5724 ins_encode %{ 5725 Register Rdst = $dst$$Register; 5726 Label done; 5727 __ bsfl(Rdst, $src$$Register); 5728 __ jccb(Assembler::notZero, done); 5729 __ movl(Rdst, BitsPerInt); 5730 __ bind(done); 5731 %} 5732 ins_pipe(ialu_reg); 5733 %} 5734 5735 instruct countTrailingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 5736 predicate(UseCountTrailingZerosInstruction); 5737 match(Set dst (CountTrailingZerosL src)); 5738 effect(KILL cr); 5739 5740 format %{ "tzcntq $dst, $src\t# count trailing zeros (long)" %} 5741 ins_encode %{ 5742 __ tzcntq($dst$$Register, $src$$Register); 5743 %} 5744 ins_pipe(ialu_reg); 5745 %} 5746 5747 instruct countTrailingZerosL_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5748 predicate(UseCountTrailingZerosInstruction); 5749 match(Set dst (CountTrailingZerosL (LoadL src))); 5750 effect(KILL cr); 5751 ins_cost(175); 5752 format %{ "tzcntq $dst, $src\t# count trailing zeros (long)" %} 5753 ins_encode %{ 5754 __ tzcntq($dst$$Register, $src$$Address); 5755 %} 5756 ins_pipe(ialu_reg_mem); 5757 %} 5758 5759 instruct countTrailingZerosL_bsf(rRegI dst, rRegL src, rFlagsReg cr) %{ 5760 predicate(!UseCountTrailingZerosInstruction); 5761 match(Set dst (CountTrailingZerosL src)); 5762 effect(KILL cr); 5763 5764 format %{ "bsfq $dst, $src\t# count trailing zeros (long)\n\t" 5765 "jnz done\n\t" 5766 "movl $dst, 64\n" 5767 "done:" %} 5768 ins_encode %{ 5769 Register Rdst = $dst$$Register; 5770 Label done; 5771 __ bsfq(Rdst, $src$$Register); 5772 __ jccb(Assembler::notZero, done); 5773 __ movl(Rdst, BitsPerLong); 5774 __ bind(done); 5775 %} 5776 ins_pipe(ialu_reg); 5777 %} 5778 5779 //--------------- Reverse Operation Instructions ---------------- 5780 instruct bytes_reversebit_int(rRegI dst, rRegI src, rRegI rtmp, rFlagsReg cr) %{ 5781 predicate(!VM_Version::supports_gfni()); 5782 match(Set dst (ReverseI src)); 5783 effect(TEMP dst, TEMP rtmp, KILL cr); 5784 format %{ "reverse_int $dst $src\t! using $rtmp as TEMP" %} 5785 ins_encode %{ 5786 __ reverseI($dst$$Register, $src$$Register, xnoreg, xnoreg, $rtmp$$Register); 5787 %} 5788 ins_pipe( ialu_reg ); 5789 %} 5790 5791 instruct bytes_reversebit_int_gfni(rRegI dst, rRegI src, vlRegF xtmp1, vlRegF xtmp2, rRegL rtmp, rFlagsReg cr) %{ 5792 predicate(VM_Version::supports_gfni()); 5793 match(Set dst (ReverseI src)); 5794 effect(TEMP dst, TEMP xtmp1, TEMP xtmp2, TEMP rtmp, KILL cr); 5795 format %{ "reverse_int $dst $src\t! using $rtmp, $xtmp1 and $xtmp2 as TEMP" %} 5796 ins_encode %{ 5797 __ reverseI($dst$$Register, $src$$Register, $xtmp1$$XMMRegister, $xtmp2$$XMMRegister, $rtmp$$Register); 5798 %} 5799 ins_pipe( ialu_reg ); 5800 %} 5801 5802 instruct bytes_reversebit_long(rRegL dst, rRegL src, rRegL rtmp1, rRegL rtmp2, rFlagsReg cr) %{ 5803 predicate(!VM_Version::supports_gfni()); 5804 match(Set dst (ReverseL src)); 5805 effect(TEMP dst, TEMP rtmp1, TEMP rtmp2, KILL cr); 5806 format %{ "reverse_long $dst $src\t! using $rtmp1 and $rtmp2 as TEMP" %} 5807 ins_encode %{ 5808 __ reverseL($dst$$Register, $src$$Register, xnoreg, xnoreg, $rtmp1$$Register, $rtmp2$$Register); 5809 %} 5810 ins_pipe( ialu_reg ); 5811 %} 5812 5813 instruct bytes_reversebit_long_gfni(rRegL dst, rRegL src, vlRegD xtmp1, vlRegD xtmp2, rRegL rtmp, rFlagsReg cr) %{ 5814 predicate(VM_Version::supports_gfni()); 5815 match(Set dst (ReverseL src)); 5816 effect(TEMP dst, TEMP xtmp1, TEMP xtmp2, TEMP rtmp, KILL cr); 5817 format %{ "reverse_long $dst $src\t! using $rtmp, $xtmp1 and $xtmp2 as TEMP" %} 5818 ins_encode %{ 5819 __ reverseL($dst$$Register, $src$$Register, $xtmp1$$XMMRegister, $xtmp2$$XMMRegister, $rtmp$$Register, noreg); 5820 %} 5821 ins_pipe( ialu_reg ); 5822 %} 5823 5824 //---------- Population Count Instructions ------------------------------------- 5825 5826 instruct popCountI(rRegI dst, rRegI src, rFlagsReg cr) %{ 5827 predicate(UsePopCountInstruction); 5828 match(Set dst (PopCountI src)); 5829 effect(KILL cr); 5830 5831 format %{ "popcnt $dst, $src" %} 5832 ins_encode %{ 5833 __ popcntl($dst$$Register, $src$$Register); 5834 %} 5835 ins_pipe(ialu_reg); 5836 %} 5837 5838 instruct popCountI_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 5839 predicate(UsePopCountInstruction); 5840 match(Set dst (PopCountI (LoadI mem))); 5841 effect(KILL cr); 5842 5843 format %{ "popcnt $dst, $mem" %} 5844 ins_encode %{ 5845 __ popcntl($dst$$Register, $mem$$Address); 5846 %} 5847 ins_pipe(ialu_reg); 5848 %} 5849 5850 // Note: Long.bitCount(long) returns an int. 5851 instruct popCountL(rRegI dst, rRegL src, rFlagsReg cr) %{ 5852 predicate(UsePopCountInstruction); 5853 match(Set dst (PopCountL src)); 5854 effect(KILL cr); 5855 5856 format %{ "popcnt $dst, $src" %} 5857 ins_encode %{ 5858 __ popcntq($dst$$Register, $src$$Register); 5859 %} 5860 ins_pipe(ialu_reg); 5861 %} 5862 5863 // Note: Long.bitCount(long) returns an int. 5864 instruct popCountL_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 5865 predicate(UsePopCountInstruction); 5866 match(Set dst (PopCountL (LoadL mem))); 5867 effect(KILL cr); 5868 5869 format %{ "popcnt $dst, $mem" %} 5870 ins_encode %{ 5871 __ popcntq($dst$$Register, $mem$$Address); 5872 %} 5873 ins_pipe(ialu_reg); 5874 %} 5875 5876 5877 //----------MemBar Instructions----------------------------------------------- 5878 // Memory barrier flavors 5879 5880 instruct membar_acquire() 5881 %{ 5882 match(MemBarAcquire); 5883 match(LoadFence); 5884 ins_cost(0); 5885 5886 size(0); 5887 format %{ "MEMBAR-acquire ! (empty encoding)" %} 5888 ins_encode(); 5889 ins_pipe(empty); 5890 %} 5891 5892 instruct membar_acquire_lock() 5893 %{ 5894 match(MemBarAcquireLock); 5895 ins_cost(0); 5896 5897 size(0); 5898 format %{ "MEMBAR-acquire (prior CMPXCHG in FastLock so empty encoding)" %} 5899 ins_encode(); 5900 ins_pipe(empty); 5901 %} 5902 5903 instruct membar_release() 5904 %{ 5905 match(MemBarRelease); 5906 match(StoreFence); 5907 ins_cost(0); 5908 5909 size(0); 5910 format %{ "MEMBAR-release ! (empty encoding)" %} 5911 ins_encode(); 5912 ins_pipe(empty); 5913 %} 5914 5915 instruct membar_release_lock() 5916 %{ 5917 match(MemBarReleaseLock); 5918 ins_cost(0); 5919 5920 size(0); 5921 format %{ "MEMBAR-release (a FastUnlock follows so empty encoding)" %} 5922 ins_encode(); 5923 ins_pipe(empty); 5924 %} 5925 5926 instruct membar_volatile(rFlagsReg cr) %{ 5927 match(MemBarVolatile); 5928 effect(KILL cr); 5929 ins_cost(400); 5930 5931 format %{ 5932 $$template 5933 $$emit$$"lock addl [rsp + #0], 0\t! membar_volatile" 5934 %} 5935 ins_encode %{ 5936 __ membar(Assembler::StoreLoad); 5937 %} 5938 ins_pipe(pipe_slow); 5939 %} 5940 5941 instruct unnecessary_membar_volatile() 5942 %{ 5943 match(MemBarVolatile); 5944 predicate(Matcher::post_store_load_barrier(n)); 5945 ins_cost(0); 5946 5947 size(0); 5948 format %{ "MEMBAR-volatile (unnecessary so empty encoding)" %} 5949 ins_encode(); 5950 ins_pipe(empty); 5951 %} 5952 5953 instruct membar_storestore() %{ 5954 match(MemBarStoreStore); 5955 match(StoreStoreFence); 5956 ins_cost(0); 5957 5958 size(0); 5959 format %{ "MEMBAR-storestore (empty encoding)" %} 5960 ins_encode( ); 5961 ins_pipe(empty); 5962 %} 5963 5964 //----------Move Instructions-------------------------------------------------- 5965 5966 instruct castX2P(rRegP dst, rRegL src) 5967 %{ 5968 match(Set dst (CastX2P src)); 5969 5970 format %{ "movq $dst, $src\t# long->ptr" %} 5971 ins_encode %{ 5972 if ($dst$$reg != $src$$reg) { 5973 __ movptr($dst$$Register, $src$$Register); 5974 } 5975 %} 5976 ins_pipe(ialu_reg_reg); // XXX 5977 %} 5978 5979 instruct castI2N(rRegN dst, rRegI src) 5980 %{ 5981 match(Set dst (CastI2N src)); 5982 5983 format %{ "movq $dst, $src\t# int -> narrow ptr" %} 5984 ins_encode %{ 5985 if ($dst$$reg != $src$$reg) { 5986 __ movl($dst$$Register, $src$$Register); 5987 } 5988 %} 5989 ins_pipe(ialu_reg_reg); // XXX 5990 %} 5991 5992 instruct castN2X(rRegL dst, rRegN src) 5993 %{ 5994 match(Set dst (CastP2X src)); 5995 5996 format %{ "movq $dst, $src\t# ptr -> long" %} 5997 ins_encode %{ 5998 if ($dst$$reg != $src$$reg) { 5999 __ movptr($dst$$Register, $src$$Register); 6000 } 6001 %} 6002 ins_pipe(ialu_reg_reg); // XXX 6003 %} 6004 6005 instruct castP2X(rRegL dst, rRegP src) 6006 %{ 6007 match(Set dst (CastP2X src)); 6008 6009 format %{ "movq $dst, $src\t# ptr -> long" %} 6010 ins_encode %{ 6011 if ($dst$$reg != $src$$reg) { 6012 __ movptr($dst$$Register, $src$$Register); 6013 } 6014 %} 6015 ins_pipe(ialu_reg_reg); // XXX 6016 %} 6017 6018 // Convert oop into int for vectors alignment masking 6019 instruct convP2I(rRegI dst, rRegP src) 6020 %{ 6021 match(Set dst (ConvL2I (CastP2X src))); 6022 6023 format %{ "movl $dst, $src\t# ptr -> int" %} 6024 ins_encode %{ 6025 __ movl($dst$$Register, $src$$Register); 6026 %} 6027 ins_pipe(ialu_reg_reg); // XXX 6028 %} 6029 6030 // Convert compressed oop into int for vectors alignment masking 6031 // in case of 32bit oops (heap < 4Gb). 6032 instruct convN2I(rRegI dst, rRegN src) 6033 %{ 6034 predicate(CompressedOops::shift() == 0); 6035 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 6036 6037 format %{ "movl $dst, $src\t# compressed ptr -> int" %} 6038 ins_encode %{ 6039 __ movl($dst$$Register, $src$$Register); 6040 %} 6041 ins_pipe(ialu_reg_reg); // XXX 6042 %} 6043 6044 // Convert oop pointer into compressed form 6045 instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{ 6046 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 6047 match(Set dst (EncodeP src)); 6048 effect(KILL cr); 6049 format %{ "encode_heap_oop $dst,$src" %} 6050 ins_encode %{ 6051 Register s = $src$$Register; 6052 Register d = $dst$$Register; 6053 if (s != d) { 6054 __ movq(d, s); 6055 } 6056 __ encode_heap_oop(d); 6057 %} 6058 ins_pipe(ialu_reg_long); 6059 %} 6060 6061 instruct encodeHeapOop_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6062 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 6063 match(Set dst (EncodeP src)); 6064 effect(KILL cr); 6065 format %{ "encode_heap_oop_not_null $dst,$src" %} 6066 ins_encode %{ 6067 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 6068 %} 6069 ins_pipe(ialu_reg_long); 6070 %} 6071 6072 instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{ 6073 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 6074 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 6075 match(Set dst (DecodeN src)); 6076 effect(KILL cr); 6077 format %{ "decode_heap_oop $dst,$src" %} 6078 ins_encode %{ 6079 Register s = $src$$Register; 6080 Register d = $dst$$Register; 6081 if (s != d) { 6082 __ movq(d, s); 6083 } 6084 __ decode_heap_oop(d); 6085 %} 6086 ins_pipe(ialu_reg_long); 6087 %} 6088 6089 instruct decodeHeapOop_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6090 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 6091 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 6092 match(Set dst (DecodeN src)); 6093 effect(KILL cr); 6094 format %{ "decode_heap_oop_not_null $dst,$src" %} 6095 ins_encode %{ 6096 Register s = $src$$Register; 6097 Register d = $dst$$Register; 6098 if (s != d) { 6099 __ decode_heap_oop_not_null(d, s); 6100 } else { 6101 __ decode_heap_oop_not_null(d); 6102 } 6103 %} 6104 ins_pipe(ialu_reg_long); 6105 %} 6106 6107 instruct encodeKlass_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6108 match(Set dst (EncodePKlass src)); 6109 effect(TEMP dst, KILL cr); 6110 format %{ "encode_and_move_klass_not_null $dst,$src" %} 6111 ins_encode %{ 6112 __ encode_and_move_klass_not_null($dst$$Register, $src$$Register); 6113 %} 6114 ins_pipe(ialu_reg_long); 6115 %} 6116 6117 instruct decodeKlass_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6118 match(Set dst (DecodeNKlass src)); 6119 effect(TEMP dst, KILL cr); 6120 format %{ "decode_and_move_klass_not_null $dst,$src" %} 6121 ins_encode %{ 6122 __ decode_and_move_klass_not_null($dst$$Register, $src$$Register); 6123 %} 6124 ins_pipe(ialu_reg_long); 6125 %} 6126 6127 //----------Conditional Move--------------------------------------------------- 6128 // Jump 6129 // dummy instruction for generating temp registers 6130 instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{ 6131 match(Jump (LShiftL switch_val shift)); 6132 ins_cost(350); 6133 predicate(false); 6134 effect(TEMP dest); 6135 6136 format %{ "leaq $dest, [$constantaddress]\n\t" 6137 "jmp [$dest + $switch_val << $shift]\n\t" %} 6138 ins_encode %{ 6139 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6140 // to do that and the compiler is using that register as one it can allocate. 6141 // So we build it all by hand. 6142 // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant); 6143 // ArrayAddress dispatch(table, index); 6144 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant); 6145 __ lea($dest$$Register, $constantaddress); 6146 __ jmp(dispatch); 6147 %} 6148 ins_pipe(pipe_jmp); 6149 %} 6150 6151 instruct jumpXtnd_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{ 6152 match(Jump (AddL (LShiftL switch_val shift) offset)); 6153 ins_cost(350); 6154 effect(TEMP dest); 6155 6156 format %{ "leaq $dest, [$constantaddress]\n\t" 6157 "jmp [$dest + $switch_val << $shift + $offset]\n\t" %} 6158 ins_encode %{ 6159 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6160 // to do that and the compiler is using that register as one it can allocate. 6161 // So we build it all by hand. 6162 // Address index(noreg, switch_reg, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6163 // ArrayAddress dispatch(table, index); 6164 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6165 __ lea($dest$$Register, $constantaddress); 6166 __ jmp(dispatch); 6167 %} 6168 ins_pipe(pipe_jmp); 6169 %} 6170 6171 instruct jumpXtnd(rRegL switch_val, rRegI dest) %{ 6172 match(Jump switch_val); 6173 ins_cost(350); 6174 effect(TEMP dest); 6175 6176 format %{ "leaq $dest, [$constantaddress]\n\t" 6177 "jmp [$dest + $switch_val]\n\t" %} 6178 ins_encode %{ 6179 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6180 // to do that and the compiler is using that register as one it can allocate. 6181 // So we build it all by hand. 6182 // Address index(noreg, switch_reg, Address::times_1); 6183 // ArrayAddress dispatch(table, index); 6184 Address dispatch($dest$$Register, $switch_val$$Register, Address::times_1); 6185 __ lea($dest$$Register, $constantaddress); 6186 __ jmp(dispatch); 6187 %} 6188 ins_pipe(pipe_jmp); 6189 %} 6190 6191 // Conditional move 6192 instruct cmovI_imm_01(rRegI dst, immI_1 src, rFlagsReg cr, cmpOp cop) 6193 %{ 6194 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_int() == 0); 6195 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6196 6197 ins_cost(100); // XXX 6198 format %{ "setbn$cop $dst\t# signed, int" %} 6199 ins_encode %{ 6200 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6201 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6202 %} 6203 ins_pipe(ialu_reg); 6204 %} 6205 6206 instruct cmovI_reg(rRegI dst, rRegI src, rFlagsReg cr, cmpOp cop) 6207 %{ 6208 predicate(!UseAPX); 6209 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6210 6211 ins_cost(200); // XXX 6212 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6213 ins_encode %{ 6214 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6215 %} 6216 ins_pipe(pipe_cmov_reg); 6217 %} 6218 6219 instruct cmovI_reg_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr, cmpOp cop) 6220 %{ 6221 predicate(UseAPX); 6222 match(Set dst (CMoveI (Binary cop cr) (Binary src1 src2))); 6223 6224 ins_cost(200); 6225 format %{ "ecmovl$cop $dst, $src1, $src2\t# signed, int ndd" %} 6226 ins_encode %{ 6227 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6228 %} 6229 ins_pipe(pipe_cmov_reg); 6230 %} 6231 6232 instruct cmovI_imm_01U(rRegI dst, immI_1 src, rFlagsRegU cr, cmpOpU cop) 6233 %{ 6234 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_int() == 0); 6235 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6236 6237 ins_cost(100); // XXX 6238 format %{ "setbn$cop $dst\t# unsigned, int" %} 6239 ins_encode %{ 6240 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6241 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6242 %} 6243 ins_pipe(ialu_reg); 6244 %} 6245 6246 instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{ 6247 predicate(!UseAPX); 6248 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6249 6250 ins_cost(200); // XXX 6251 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6252 ins_encode %{ 6253 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6254 %} 6255 ins_pipe(pipe_cmov_reg); 6256 %} 6257 6258 instruct cmovI_regU_ndd(rRegI dst, cmpOpU cop, rFlagsRegU cr, rRegI src1, rRegI src2) %{ 6259 predicate(UseAPX); 6260 match(Set dst (CMoveI (Binary cop cr) (Binary src1 src2))); 6261 6262 ins_cost(200); 6263 format %{ "ecmovl$cop $dst, $src1, $src2\t# unsigned, int ndd" %} 6264 ins_encode %{ 6265 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6266 %} 6267 ins_pipe(pipe_cmov_reg); 6268 %} 6269 6270 instruct cmovI_imm_01UCF(rRegI dst, immI_1 src, rFlagsRegUCF cr, cmpOpUCF cop) 6271 %{ 6272 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_int() == 0); 6273 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6274 6275 ins_cost(100); // XXX 6276 format %{ "setbn$cop $dst\t# unsigned, int" %} 6277 ins_encode %{ 6278 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6279 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6280 %} 6281 ins_pipe(ialu_reg); 6282 %} 6283 6284 instruct cmovI_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6285 predicate(!UseAPX); 6286 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6287 ins_cost(200); 6288 expand %{ 6289 cmovI_regU(cop, cr, dst, src); 6290 %} 6291 %} 6292 6293 instruct cmovI_regUCF_ndd(rRegI dst, cmpOpUCF cop, rFlagsRegUCF cr, rRegI src1, rRegI src2) %{ 6294 predicate(UseAPX); 6295 match(Set dst (CMoveI (Binary cop cr) (Binary src1 src2))); 6296 ins_cost(200); 6297 format %{ "ecmovl$cop $dst, $src1, $src2\t# unsigned, int ndd" %} 6298 ins_encode %{ 6299 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6300 %} 6301 ins_pipe(pipe_cmov_reg); 6302 %} 6303 6304 instruct cmovI_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6305 predicate(!UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6306 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6307 6308 ins_cost(200); // XXX 6309 format %{ "cmovpl $dst, $src\n\t" 6310 "cmovnel $dst, $src" %} 6311 ins_encode %{ 6312 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6313 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6314 %} 6315 ins_pipe(pipe_cmov_reg); 6316 %} 6317 6318 instruct cmovI_regUCF2_ne_ndd(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegI dst, rRegI src1, rRegI src2) %{ 6319 predicate(UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6320 match(Set dst (CMoveI (Binary cop cr) (Binary src1 src2))); 6321 6322 ins_cost(200); 6323 format %{ "ecmovpl $dst, $src1, $src2\n\t" 6324 "ecmovnel $dst, $src1, $src2" %} 6325 ins_encode %{ 6326 __ ecmovl(Assembler::parity, $dst$$Register, $src1$$Register, $src2$$Register); 6327 __ ecmovl(Assembler::notEqual, $dst$$Register, $src1$$Register, $src2$$Register); 6328 %} 6329 ins_pipe(pipe_cmov_reg); 6330 %} 6331 6332 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6333 // inputs of the CMove 6334 instruct cmovI_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6335 predicate(!UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6336 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6337 6338 ins_cost(200); // XXX 6339 format %{ "cmovpl $dst, $src\n\t" 6340 "cmovnel $dst, $src" %} 6341 ins_encode %{ 6342 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6343 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6344 %} 6345 ins_pipe(pipe_cmov_reg); 6346 %} 6347 6348 // We need this special handling for only eq / neq comparison since NaN == NaN is false, 6349 // and parity flag bit is set if any of the operand is a NaN. 6350 instruct cmovI_regUCF2_eq_ndd(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegI dst, rRegI src1, rRegI src2) %{ 6351 predicate(UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6352 match(Set dst (CMoveI (Binary cop cr) (Binary src1 src2))); 6353 6354 ins_cost(200); 6355 format %{ "ecmovpl $dst, $src1, $src2\n\t" 6356 "ecmovnel $dst, $src1, $src2" %} 6357 ins_encode %{ 6358 __ ecmovl(Assembler::parity, $dst$$Register, $src1$$Register, $src2$$Register); 6359 __ ecmovl(Assembler::notEqual, $dst$$Register, $src1$$Register, $src2$$Register); 6360 %} 6361 ins_pipe(pipe_cmov_reg); 6362 %} 6363 6364 // Conditional move 6365 instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{ 6366 predicate(!UseAPX); 6367 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6368 6369 ins_cost(250); // XXX 6370 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6371 ins_encode %{ 6372 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6373 %} 6374 ins_pipe(pipe_cmov_mem); 6375 %} 6376 6377 // Conditional move 6378 instruct cmovI_rReg_rReg_mem_ndd(rRegI dst, cmpOp cop, rFlagsReg cr, rRegI src1, memory src2) 6379 %{ 6380 predicate(UseAPX); 6381 match(Set dst (CMoveI (Binary cop cr) (Binary src1 (LoadI src2)))); 6382 6383 ins_cost(250); 6384 format %{ "ecmovl$cop $dst, $src1, $src2\t# signed, int ndd" %} 6385 ins_encode %{ 6386 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Address); 6387 %} 6388 ins_pipe(pipe_cmov_mem); 6389 %} 6390 6391 // Conditional move 6392 instruct cmovI_memU(cmpOpU cop, rFlagsRegU cr, rRegI dst, memory src) 6393 %{ 6394 predicate(!UseAPX); 6395 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6396 6397 ins_cost(250); // XXX 6398 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6399 ins_encode %{ 6400 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6401 %} 6402 ins_pipe(pipe_cmov_mem); 6403 %} 6404 6405 instruct cmovI_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, memory src) %{ 6406 predicate(!UseAPX); 6407 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6408 ins_cost(250); 6409 expand %{ 6410 cmovI_memU(cop, cr, dst, src); 6411 %} 6412 %} 6413 6414 instruct cmovI_rReg_rReg_memU_ndd(rRegI dst, cmpOpU cop, rFlagsRegU cr, rRegI src1, memory src2) 6415 %{ 6416 predicate(UseAPX); 6417 match(Set dst (CMoveI (Binary cop cr) (Binary src1 (LoadI src2)))); 6418 6419 ins_cost(250); 6420 format %{ "ecmovl$cop $dst, $src1, $src2\t# unsigned, int ndd" %} 6421 ins_encode %{ 6422 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Address); 6423 %} 6424 ins_pipe(pipe_cmov_mem); 6425 %} 6426 6427 instruct cmovI_rReg_rReg_memUCF_ndd(rRegI dst, cmpOpUCF cop, rFlagsRegUCF cr, rRegI src1, memory src2) 6428 %{ 6429 predicate(UseAPX); 6430 match(Set dst (CMoveI (Binary cop cr) (Binary src1 (LoadI src2)))); 6431 ins_cost(250); 6432 format %{ "ecmovl$cop $dst, $src1, $src2\t# unsigned, int ndd" %} 6433 ins_encode %{ 6434 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Address); 6435 %} 6436 ins_pipe(pipe_cmov_mem); 6437 %} 6438 6439 // Conditional move 6440 instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop) 6441 %{ 6442 predicate(!UseAPX); 6443 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6444 6445 ins_cost(200); // XXX 6446 format %{ "cmovl$cop $dst, $src\t# signed, compressed ptr" %} 6447 ins_encode %{ 6448 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6449 %} 6450 ins_pipe(pipe_cmov_reg); 6451 %} 6452 6453 // Conditional move ndd 6454 instruct cmovN_reg_ndd(rRegN dst, rRegN src1, rRegN src2, rFlagsReg cr, cmpOp cop) 6455 %{ 6456 predicate(UseAPX); 6457 match(Set dst (CMoveN (Binary cop cr) (Binary src1 src2))); 6458 6459 ins_cost(200); 6460 format %{ "ecmovl$cop $dst, $src1, $src2\t# signed, compressed ptr ndd" %} 6461 ins_encode %{ 6462 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6463 %} 6464 ins_pipe(pipe_cmov_reg); 6465 %} 6466 6467 // Conditional move 6468 instruct cmovN_regU(cmpOpU cop, rFlagsRegU cr, rRegN dst, rRegN src) 6469 %{ 6470 predicate(!UseAPX); 6471 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6472 6473 ins_cost(200); // XXX 6474 format %{ "cmovl$cop $dst, $src\t# unsigned, compressed ptr" %} 6475 ins_encode %{ 6476 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6477 %} 6478 ins_pipe(pipe_cmov_reg); 6479 %} 6480 6481 instruct cmovN_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6482 predicate(!UseAPX); 6483 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6484 ins_cost(200); 6485 expand %{ 6486 cmovN_regU(cop, cr, dst, src); 6487 %} 6488 %} 6489 6490 // Conditional move ndd 6491 instruct cmovN_regU_ndd(rRegN dst, cmpOpU cop, rFlagsRegU cr, rRegN src1, rRegN src2) 6492 %{ 6493 predicate(UseAPX); 6494 match(Set dst (CMoveN (Binary cop cr) (Binary src1 src2))); 6495 6496 ins_cost(200); 6497 format %{ "ecmovl$cop $dst, $src1, $src2\t# unsigned, compressed ptr ndd" %} 6498 ins_encode %{ 6499 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6500 %} 6501 ins_pipe(pipe_cmov_reg); 6502 %} 6503 6504 instruct cmovN_regUCF_ndd(rRegN dst, cmpOpUCF cop, rFlagsRegUCF cr, rRegN src1, rRegN src2) %{ 6505 predicate(UseAPX); 6506 match(Set dst (CMoveN (Binary cop cr) (Binary src1 src2))); 6507 ins_cost(200); 6508 format %{ "ecmovl$cop $dst, $src1, $src2\t# unsigned, compressed ptr ndd" %} 6509 ins_encode %{ 6510 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6511 %} 6512 ins_pipe(pipe_cmov_reg); 6513 %} 6514 6515 instruct cmovN_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6516 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6517 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6518 6519 ins_cost(200); // XXX 6520 format %{ "cmovpl $dst, $src\n\t" 6521 "cmovnel $dst, $src" %} 6522 ins_encode %{ 6523 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6524 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6525 %} 6526 ins_pipe(pipe_cmov_reg); 6527 %} 6528 6529 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6530 // inputs of the CMove 6531 instruct cmovN_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6532 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6533 match(Set dst (CMoveN (Binary cop cr) (Binary src dst))); 6534 6535 ins_cost(200); // XXX 6536 format %{ "cmovpl $dst, $src\n\t" 6537 "cmovnel $dst, $src" %} 6538 ins_encode %{ 6539 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6540 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6541 %} 6542 ins_pipe(pipe_cmov_reg); 6543 %} 6544 6545 // Conditional move 6546 instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop) 6547 %{ 6548 predicate(!UseAPX); 6549 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6550 6551 ins_cost(200); // XXX 6552 format %{ "cmovq$cop $dst, $src\t# signed, ptr" %} 6553 ins_encode %{ 6554 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6555 %} 6556 ins_pipe(pipe_cmov_reg); // XXX 6557 %} 6558 6559 // Conditional move ndd 6560 instruct cmovP_reg_ndd(rRegP dst, rRegP src1, rRegP src2, rFlagsReg cr, cmpOp cop) 6561 %{ 6562 predicate(UseAPX); 6563 match(Set dst (CMoveP (Binary cop cr) (Binary src1 src2))); 6564 6565 ins_cost(200); 6566 format %{ "ecmovq$cop $dst, $src1, $src2\t# signed, ptr ndd" %} 6567 ins_encode %{ 6568 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6569 %} 6570 ins_pipe(pipe_cmov_reg); 6571 %} 6572 6573 // Conditional move 6574 instruct cmovP_regU(cmpOpU cop, rFlagsRegU cr, rRegP dst, rRegP src) 6575 %{ 6576 predicate(!UseAPX); 6577 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6578 6579 ins_cost(200); // XXX 6580 format %{ "cmovq$cop $dst, $src\t# unsigned, ptr" %} 6581 ins_encode %{ 6582 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6583 %} 6584 ins_pipe(pipe_cmov_reg); // XXX 6585 %} 6586 6587 // Conditional move ndd 6588 instruct cmovP_regU_ndd(rRegP dst, cmpOpU cop, rFlagsRegU cr, rRegP src1, rRegP src2) 6589 %{ 6590 predicate(UseAPX); 6591 match(Set dst (CMoveP (Binary cop cr) (Binary src1 src2))); 6592 6593 ins_cost(200); 6594 format %{ "ecmovq$cop $dst, $src1, $src2\t# unsigned, ptr ndd" %} 6595 ins_encode %{ 6596 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6597 %} 6598 ins_pipe(pipe_cmov_reg); 6599 %} 6600 6601 instruct cmovP_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6602 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6603 ins_cost(200); 6604 expand %{ 6605 cmovP_regU(cop, cr, dst, src); 6606 %} 6607 %} 6608 6609 instruct cmovP_regUCF_ndd(rRegP dst, cmpOpUCF cop, rFlagsRegUCF cr, rRegP src1, rRegP src2) %{ 6610 match(Set dst (CMoveP (Binary cop cr) (Binary src1 src2))); 6611 ins_cost(200); 6612 format %{ "ecmovq$cop $dst, $src1, $src2\t# unsigned, ptr ndd" %} 6613 ins_encode %{ 6614 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6615 %} 6616 ins_pipe(pipe_cmov_reg); 6617 %} 6618 6619 instruct cmovP_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6620 predicate(!UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6621 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6622 6623 ins_cost(200); // XXX 6624 format %{ "cmovpq $dst, $src\n\t" 6625 "cmovneq $dst, $src" %} 6626 ins_encode %{ 6627 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6628 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6629 %} 6630 ins_pipe(pipe_cmov_reg); 6631 %} 6632 6633 instruct cmovP_regUCF2_ne_ndd(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegP dst, rRegP src1, rRegP src2) %{ 6634 predicate(UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6635 match(Set dst (CMoveP (Binary cop cr) (Binary src1 src2))); 6636 6637 ins_cost(200); 6638 format %{ "ecmovpq $dst, $src1, $src2\n\t" 6639 "ecmovneq $dst, $src1, $src2" %} 6640 ins_encode %{ 6641 __ ecmovq(Assembler::parity, $dst$$Register, $src1$$Register, $src2$$Register); 6642 __ ecmovq(Assembler::notEqual, $dst$$Register, $src1$$Register, $src2$$Register); 6643 %} 6644 ins_pipe(pipe_cmov_reg); 6645 %} 6646 6647 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6648 // inputs of the CMove 6649 instruct cmovP_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6650 predicate(!UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6651 match(Set dst (CMoveP (Binary cop cr) (Binary src dst))); 6652 6653 ins_cost(200); // XXX 6654 format %{ "cmovpq $dst, $src\n\t" 6655 "cmovneq $dst, $src" %} 6656 ins_encode %{ 6657 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6658 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6659 %} 6660 ins_pipe(pipe_cmov_reg); 6661 %} 6662 6663 instruct cmovP_regUCF2_eq_ndd(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegP dst, rRegP src1, rRegP src2) %{ 6664 predicate(UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6665 match(Set dst (CMoveP (Binary cop cr) (Binary src1 src2))); 6666 6667 ins_cost(200); 6668 format %{ "ecmovpq $dst, $src1, $src2\n\t" 6669 "ecmovneq $dst, $src1, $src2" %} 6670 ins_encode %{ 6671 __ ecmovq(Assembler::parity, $dst$$Register, $src1$$Register, $src2$$Register); 6672 __ ecmovq(Assembler::notEqual, $dst$$Register, $src1$$Register, $src2$$Register); 6673 %} 6674 ins_pipe(pipe_cmov_reg); 6675 %} 6676 6677 instruct cmovL_imm_01(rRegL dst, immL1 src, rFlagsReg cr, cmpOp cop) 6678 %{ 6679 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_long() == 0); 6680 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6681 6682 ins_cost(100); // XXX 6683 format %{ "setbn$cop $dst\t# signed, long" %} 6684 ins_encode %{ 6685 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6686 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6687 %} 6688 ins_pipe(ialu_reg); 6689 %} 6690 6691 instruct cmovL_reg(cmpOp cop, rFlagsReg cr, rRegL dst, rRegL src) 6692 %{ 6693 predicate(!UseAPX); 6694 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6695 6696 ins_cost(200); // XXX 6697 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6698 ins_encode %{ 6699 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6700 %} 6701 ins_pipe(pipe_cmov_reg); // XXX 6702 %} 6703 6704 instruct cmovL_reg_ndd(rRegL dst, cmpOp cop, rFlagsReg cr, rRegL src1, rRegL src2) 6705 %{ 6706 predicate(UseAPX); 6707 match(Set dst (CMoveL (Binary cop cr) (Binary src1 src2))); 6708 6709 ins_cost(200); 6710 format %{ "ecmovq$cop $dst, $src1, $src2\t# signed, long ndd" %} 6711 ins_encode %{ 6712 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6713 %} 6714 ins_pipe(pipe_cmov_reg); 6715 %} 6716 6717 instruct cmovL_mem(cmpOp cop, rFlagsReg cr, rRegL dst, memory src) 6718 %{ 6719 predicate(!UseAPX); 6720 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6721 6722 ins_cost(200); // XXX 6723 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6724 ins_encode %{ 6725 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6726 %} 6727 ins_pipe(pipe_cmov_mem); // XXX 6728 %} 6729 6730 instruct cmovL_rReg_rReg_mem_ndd(rRegL dst, cmpOp cop, rFlagsReg cr, rRegL src1, memory src2) 6731 %{ 6732 predicate(UseAPX); 6733 match(Set dst (CMoveL (Binary cop cr) (Binary src1 (LoadL src2)))); 6734 6735 ins_cost(200); 6736 format %{ "ecmovq$cop $dst, $src1, $src2\t# signed, long ndd" %} 6737 ins_encode %{ 6738 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Address); 6739 %} 6740 ins_pipe(pipe_cmov_mem); 6741 %} 6742 6743 instruct cmovL_imm_01U(rRegL dst, immL1 src, rFlagsRegU cr, cmpOpU cop) 6744 %{ 6745 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_long() == 0); 6746 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6747 6748 ins_cost(100); // XXX 6749 format %{ "setbn$cop $dst\t# unsigned, long" %} 6750 ins_encode %{ 6751 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6752 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6753 %} 6754 ins_pipe(ialu_reg); 6755 %} 6756 6757 instruct cmovL_regU(cmpOpU cop, rFlagsRegU cr, rRegL dst, rRegL src) 6758 %{ 6759 predicate(!UseAPX); 6760 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6761 6762 ins_cost(200); // XXX 6763 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 6764 ins_encode %{ 6765 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6766 %} 6767 ins_pipe(pipe_cmov_reg); // XXX 6768 %} 6769 6770 instruct cmovL_regU_ndd(rRegL dst, cmpOpU cop, rFlagsRegU cr, rRegL src1, rRegL src2) 6771 %{ 6772 predicate(UseAPX); 6773 match(Set dst (CMoveL (Binary cop cr) (Binary src1 src2))); 6774 6775 ins_cost(200); 6776 format %{ "ecmovq$cop $dst, $src1, $src2\t# unsigned, long ndd" %} 6777 ins_encode %{ 6778 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6779 %} 6780 ins_pipe(pipe_cmov_reg); 6781 %} 6782 6783 instruct cmovL_imm_01UCF(rRegL dst, immL1 src, rFlagsRegUCF cr, cmpOpUCF cop) 6784 %{ 6785 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_long() == 0); 6786 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6787 6788 ins_cost(100); // XXX 6789 format %{ "setbn$cop $dst\t# unsigned, long" %} 6790 ins_encode %{ 6791 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6792 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6793 %} 6794 ins_pipe(ialu_reg); 6795 %} 6796 6797 instruct cmovL_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6798 predicate(!UseAPX); 6799 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6800 ins_cost(200); 6801 expand %{ 6802 cmovL_regU(cop, cr, dst, src); 6803 %} 6804 %} 6805 6806 instruct cmovL_regUCF_ndd(rRegL dst, cmpOpUCF cop, rFlagsRegUCF cr, rRegL src1, rRegL src2) 6807 %{ 6808 predicate(UseAPX); 6809 match(Set dst (CMoveL (Binary cop cr) (Binary src1 src2))); 6810 ins_cost(200); 6811 format %{ "ecmovq$cop $dst, $src1, $src2\t# unsigned, long ndd" %} 6812 ins_encode %{ 6813 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6814 %} 6815 ins_pipe(pipe_cmov_reg); 6816 %} 6817 6818 instruct cmovL_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6819 predicate(!UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6820 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6821 6822 ins_cost(200); // XXX 6823 format %{ "cmovpq $dst, $src\n\t" 6824 "cmovneq $dst, $src" %} 6825 ins_encode %{ 6826 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6827 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6828 %} 6829 ins_pipe(pipe_cmov_reg); 6830 %} 6831 6832 instruct cmovL_regUCF2_ne_ndd(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegL dst, rRegL src1, rRegL src2) %{ 6833 predicate(UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6834 match(Set dst (CMoveL (Binary cop cr) (Binary src1 src2))); 6835 6836 ins_cost(200); 6837 format %{ "ecmovpq $dst, $src1, $src2\n\t" 6838 "ecmovneq $dst, $src1, $src2" %} 6839 ins_encode %{ 6840 __ ecmovq(Assembler::parity, $dst$$Register, $src1$$Register, $src2$$Register); 6841 __ ecmovq(Assembler::notEqual, $dst$$Register, $src1$$Register, $src2$$Register); 6842 %} 6843 ins_pipe(pipe_cmov_reg); 6844 %} 6845 6846 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6847 // inputs of the CMove 6848 instruct cmovL_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6849 predicate(!UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6850 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6851 6852 ins_cost(200); // XXX 6853 format %{ "cmovpq $dst, $src\n\t" 6854 "cmovneq $dst, $src" %} 6855 ins_encode %{ 6856 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6857 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6858 %} 6859 ins_pipe(pipe_cmov_reg); 6860 %} 6861 6862 instruct cmovL_regUCF2_eq_ndd(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegL dst, rRegL src1, rRegL src2) %{ 6863 predicate(UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6864 match(Set dst (CMoveL (Binary cop cr) (Binary src1 src2))); 6865 6866 ins_cost(200); 6867 format %{ "ecmovpq $dst, $src1, $src2\n\t" 6868 "ecmovneq $dst, $src1, $src2" %} 6869 ins_encode %{ 6870 __ ecmovq(Assembler::parity, $dst$$Register, $src1$$Register, $src2$$Register); 6871 __ ecmovq(Assembler::notEqual, $dst$$Register, $src1$$Register, $src2$$Register); 6872 %} 6873 ins_pipe(pipe_cmov_reg); 6874 %} 6875 6876 instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src) 6877 %{ 6878 predicate(!UseAPX); 6879 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6880 6881 ins_cost(200); // XXX 6882 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 6883 ins_encode %{ 6884 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6885 %} 6886 ins_pipe(pipe_cmov_mem); // XXX 6887 %} 6888 6889 instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{ 6890 predicate(!UseAPX); 6891 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6892 ins_cost(200); 6893 expand %{ 6894 cmovL_memU(cop, cr, dst, src); 6895 %} 6896 %} 6897 6898 instruct cmovL_rReg_rReg_memU_ndd(rRegL dst, cmpOpU cop, rFlagsRegU cr, rRegL src1, memory src2) 6899 %{ 6900 predicate(UseAPX); 6901 match(Set dst (CMoveL (Binary cop cr) (Binary src1 (LoadL src2)))); 6902 6903 ins_cost(200); 6904 format %{ "ecmovq$cop $dst, $src1, $src2\t# unsigned, long ndd" %} 6905 ins_encode %{ 6906 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Address); 6907 %} 6908 ins_pipe(pipe_cmov_mem); 6909 %} 6910 6911 instruct cmovL_rReg_rReg_memUCF_ndd(rRegL dst, cmpOpUCF cop, rFlagsRegUCF cr, rRegL src1, memory src2) 6912 %{ 6913 predicate(UseAPX); 6914 match(Set dst (CMoveL (Binary cop cr) (Binary src1 (LoadL src2)))); 6915 ins_cost(200); 6916 format %{ "ecmovq$cop $dst, $src1, $src2\t# unsigned, long ndd" %} 6917 ins_encode %{ 6918 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Address); 6919 %} 6920 ins_pipe(pipe_cmov_mem); 6921 %} 6922 6923 instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src) 6924 %{ 6925 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6926 6927 ins_cost(200); // XXX 6928 format %{ "jn$cop skip\t# signed cmove float\n\t" 6929 "movss $dst, $src\n" 6930 "skip:" %} 6931 ins_encode %{ 6932 Label Lskip; 6933 // Invert sense of branch from sense of CMOV 6934 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6935 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 6936 __ bind(Lskip); 6937 %} 6938 ins_pipe(pipe_slow); 6939 %} 6940 6941 instruct cmovF_regU(cmpOpU cop, rFlagsRegU cr, regF dst, regF src) 6942 %{ 6943 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6944 6945 ins_cost(200); // XXX 6946 format %{ "jn$cop skip\t# unsigned cmove float\n\t" 6947 "movss $dst, $src\n" 6948 "skip:" %} 6949 ins_encode %{ 6950 Label Lskip; 6951 // Invert sense of branch from sense of CMOV 6952 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6953 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 6954 __ bind(Lskip); 6955 %} 6956 ins_pipe(pipe_slow); 6957 %} 6958 6959 instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{ 6960 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6961 ins_cost(200); 6962 expand %{ 6963 cmovF_regU(cop, cr, dst, src); 6964 %} 6965 %} 6966 6967 instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src) 6968 %{ 6969 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6970 6971 ins_cost(200); // XXX 6972 format %{ "jn$cop skip\t# signed cmove double\n\t" 6973 "movsd $dst, $src\n" 6974 "skip:" %} 6975 ins_encode %{ 6976 Label Lskip; 6977 // Invert sense of branch from sense of CMOV 6978 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6979 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 6980 __ bind(Lskip); 6981 %} 6982 ins_pipe(pipe_slow); 6983 %} 6984 6985 instruct cmovD_regU(cmpOpU cop, rFlagsRegU cr, regD dst, regD src) 6986 %{ 6987 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6988 6989 ins_cost(200); // XXX 6990 format %{ "jn$cop skip\t# unsigned cmove double\n\t" 6991 "movsd $dst, $src\n" 6992 "skip:" %} 6993 ins_encode %{ 6994 Label Lskip; 6995 // Invert sense of branch from sense of CMOV 6996 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6997 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 6998 __ bind(Lskip); 6999 %} 7000 ins_pipe(pipe_slow); 7001 %} 7002 7003 instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{ 7004 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7005 ins_cost(200); 7006 expand %{ 7007 cmovD_regU(cop, cr, dst, src); 7008 %} 7009 %} 7010 7011 //----------Arithmetic Instructions-------------------------------------------- 7012 //----------Addition Instructions---------------------------------------------- 7013 7014 instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7015 %{ 7016 predicate(!UseAPX); 7017 match(Set dst (AddI dst src)); 7018 effect(KILL cr); 7019 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); 7020 format %{ "addl $dst, $src\t# int" %} 7021 ins_encode %{ 7022 __ addl($dst$$Register, $src$$Register); 7023 %} 7024 ins_pipe(ialu_reg_reg); 7025 %} 7026 7027 instruct addI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr) 7028 %{ 7029 predicate(UseAPX); 7030 match(Set dst (AddI src1 src2)); 7031 effect(KILL cr); 7032 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); 7033 7034 format %{ "eaddl $dst, $src1, $src2\t# int ndd" %} 7035 ins_encode %{ 7036 __ eaddl($dst$$Register, $src1$$Register, $src2$$Register, false); 7037 %} 7038 ins_pipe(ialu_reg_reg); 7039 %} 7040 7041 instruct addI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 7042 %{ 7043 predicate(!UseAPX); 7044 match(Set dst (AddI dst src)); 7045 effect(KILL cr); 7046 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); 7047 7048 format %{ "addl $dst, $src\t# int" %} 7049 ins_encode %{ 7050 __ addl($dst$$Register, $src$$constant); 7051 %} 7052 ins_pipe( ialu_reg ); 7053 %} 7054 7055 instruct addI_rReg_rReg_imm_ndd(rRegI dst, rRegI src1, immI src2, rFlagsReg cr) 7056 %{ 7057 predicate(UseAPX); 7058 match(Set dst (AddI src1 src2)); 7059 effect(KILL cr); 7060 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); 7061 7062 format %{ "eaddl $dst, $src1, $src2\t# int ndd" %} 7063 ins_encode %{ 7064 __ eaddl($dst$$Register, $src1$$Register, $src2$$constant, false); 7065 %} 7066 ins_pipe( ialu_reg ); 7067 %} 7068 7069 instruct addI_rReg_mem_imm_ndd(rRegI dst, memory src1, immI src2, rFlagsReg cr) 7070 %{ 7071 predicate(UseAPX); 7072 match(Set dst (AddI (LoadI src1) src2)); 7073 effect(KILL cr); 7074 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); 7075 7076 format %{ "eaddl $dst, $src1, $src2\t# int ndd" %} 7077 ins_encode %{ 7078 __ eaddl($dst$$Register, $src1$$Address, $src2$$constant, false); 7079 %} 7080 ins_pipe( ialu_reg ); 7081 %} 7082 7083 instruct addI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 7084 %{ 7085 predicate(!UseAPX); 7086 match(Set dst (AddI dst (LoadI src))); 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 ins_cost(150); // XXX 7091 format %{ "addl $dst, $src\t# int" %} 7092 ins_encode %{ 7093 __ addl($dst$$Register, $src$$Address); 7094 %} 7095 ins_pipe(ialu_reg_mem); 7096 %} 7097 7098 instruct addI_rReg_mem_rReg_ndd(rRegI dst, memory src1, rRegI src2, rFlagsReg cr) 7099 %{ 7100 predicate(UseAPX); 7101 match(Set dst (AddI (LoadI src1) src2)); 7102 effect(KILL cr); 7103 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); 7104 7105 ins_cost(150); 7106 format %{ "eaddl $dst, $src1, $src2\t# int ndd" %} 7107 ins_encode %{ 7108 __ eaddl($dst$$Register, $src1$$Address, $src2$$Register, false); 7109 %} 7110 ins_pipe(ialu_reg_mem); 7111 %} 7112 7113 instruct addI_rReg_rReg_mem_ndd(rRegI dst, rRegI src1, memory src2, rFlagsReg cr) 7114 %{ 7115 predicate(UseAPX); 7116 match(Set dst (AddI src1 (LoadI src2))); 7117 effect(KILL cr); 7118 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); 7119 7120 ins_cost(150); 7121 format %{ "eaddl $dst, $src1, $src2\t# int ndd" %} 7122 ins_encode %{ 7123 __ eaddl($dst$$Register, $src1$$Register, $src2$$Address, false); 7124 %} 7125 ins_pipe(ialu_reg_mem); 7126 %} 7127 7128 instruct addI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 7129 %{ 7130 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7131 effect(KILL cr); 7132 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); 7133 7134 ins_cost(150); // XXX 7135 format %{ "addl $dst, $src\t# int" %} 7136 ins_encode %{ 7137 __ addl($dst$$Address, $src$$Register); 7138 %} 7139 ins_pipe(ialu_mem_reg); 7140 %} 7141 7142 instruct addI_mem_imm(memory dst, immI src, rFlagsReg cr) 7143 %{ 7144 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7145 effect(KILL cr); 7146 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); 7147 7148 7149 ins_cost(125); // XXX 7150 format %{ "addl $dst, $src\t# int" %} 7151 ins_encode %{ 7152 __ addl($dst$$Address, $src$$constant); 7153 %} 7154 ins_pipe(ialu_mem_imm); 7155 %} 7156 7157 instruct incI_rReg(rRegI dst, immI_1 src, rFlagsReg cr) 7158 %{ 7159 predicate(!UseAPX && UseIncDec); 7160 match(Set dst (AddI dst src)); 7161 effect(KILL cr); 7162 7163 format %{ "incl $dst\t# int" %} 7164 ins_encode %{ 7165 __ incrementl($dst$$Register); 7166 %} 7167 ins_pipe(ialu_reg); 7168 %} 7169 7170 instruct incI_rReg_ndd(rRegI dst, rRegI src, immI_1 val, rFlagsReg cr) 7171 %{ 7172 predicate(UseAPX && UseIncDec); 7173 match(Set dst (AddI src val)); 7174 effect(KILL cr); 7175 7176 format %{ "eincl $dst, $src\t# int ndd" %} 7177 ins_encode %{ 7178 __ eincl($dst$$Register, $src$$Register, false); 7179 %} 7180 ins_pipe(ialu_reg); 7181 %} 7182 7183 instruct incI_rReg_mem_ndd(rRegI dst, memory src, immI_1 val, rFlagsReg cr) 7184 %{ 7185 predicate(UseAPX && UseIncDec); 7186 match(Set dst (AddI (LoadI src) val)); 7187 effect(KILL cr); 7188 7189 format %{ "eincl $dst, $src\t# int ndd" %} 7190 ins_encode %{ 7191 __ eincl($dst$$Register, $src$$Address, false); 7192 %} 7193 ins_pipe(ialu_reg); 7194 %} 7195 7196 instruct incI_mem(memory dst, immI_1 src, rFlagsReg cr) 7197 %{ 7198 predicate(UseIncDec); 7199 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7200 effect(KILL cr); 7201 7202 ins_cost(125); // XXX 7203 format %{ "incl $dst\t# int" %} 7204 ins_encode %{ 7205 __ incrementl($dst$$Address); 7206 %} 7207 ins_pipe(ialu_mem_imm); 7208 %} 7209 7210 // XXX why does that use AddI 7211 instruct decI_rReg(rRegI dst, immI_M1 src, rFlagsReg cr) 7212 %{ 7213 predicate(!UseAPX && UseIncDec); 7214 match(Set dst (AddI dst src)); 7215 effect(KILL cr); 7216 7217 format %{ "decl $dst\t# int" %} 7218 ins_encode %{ 7219 __ decrementl($dst$$Register); 7220 %} 7221 ins_pipe(ialu_reg); 7222 %} 7223 7224 instruct decI_rReg_ndd(rRegI dst, rRegI src, immI_M1 val, rFlagsReg cr) 7225 %{ 7226 predicate(UseAPX && UseIncDec); 7227 match(Set dst (AddI src val)); 7228 effect(KILL cr); 7229 7230 format %{ "edecl $dst, $src\t# int ndd" %} 7231 ins_encode %{ 7232 __ edecl($dst$$Register, $src$$Register, false); 7233 %} 7234 ins_pipe(ialu_reg); 7235 %} 7236 7237 instruct decI_rReg_mem_ndd(rRegI dst, memory src, immI_M1 val, rFlagsReg cr) 7238 %{ 7239 predicate(UseAPX && UseIncDec); 7240 match(Set dst (AddI (LoadI src) val)); 7241 effect(KILL cr); 7242 7243 format %{ "edecl $dst, $src\t# int ndd" %} 7244 ins_encode %{ 7245 __ edecl($dst$$Register, $src$$Address, false); 7246 %} 7247 ins_pipe(ialu_reg); 7248 %} 7249 7250 // XXX why does that use AddI 7251 instruct decI_mem(memory dst, immI_M1 src, rFlagsReg cr) 7252 %{ 7253 predicate(UseIncDec); 7254 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7255 effect(KILL cr); 7256 7257 ins_cost(125); // XXX 7258 format %{ "decl $dst\t# int" %} 7259 ins_encode %{ 7260 __ decrementl($dst$$Address); 7261 %} 7262 ins_pipe(ialu_mem_imm); 7263 %} 7264 7265 instruct leaI_rReg_immI2_immI(rRegI dst, rRegI index, immI2 scale, immI disp) 7266 %{ 7267 predicate(VM_Version::supports_fast_2op_lea()); 7268 match(Set dst (AddI (LShiftI index scale) disp)); 7269 7270 format %{ "leal $dst, [$index << $scale + $disp]\t# int" %} 7271 ins_encode %{ 7272 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 7273 __ leal($dst$$Register, Address(noreg, $index$$Register, scale, $disp$$constant)); 7274 %} 7275 ins_pipe(ialu_reg_reg); 7276 %} 7277 7278 instruct leaI_rReg_rReg_immI(rRegI dst, rRegI base, rRegI index, immI disp) 7279 %{ 7280 predicate(VM_Version::supports_fast_3op_lea()); 7281 match(Set dst (AddI (AddI base index) disp)); 7282 7283 format %{ "leal $dst, [$base + $index + $disp]\t# int" %} 7284 ins_encode %{ 7285 __ leal($dst$$Register, Address($base$$Register, $index$$Register, Address::times_1, $disp$$constant)); 7286 %} 7287 ins_pipe(ialu_reg_reg); 7288 %} 7289 7290 instruct leaI_rReg_rReg_immI2(rRegI dst, no_rbp_r13_RegI base, rRegI index, immI2 scale) 7291 %{ 7292 predicate(VM_Version::supports_fast_2op_lea()); 7293 match(Set dst (AddI base (LShiftI index scale))); 7294 7295 format %{ "leal $dst, [$base + $index << $scale]\t# int" %} 7296 ins_encode %{ 7297 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 7298 __ leal($dst$$Register, Address($base$$Register, $index$$Register, scale)); 7299 %} 7300 ins_pipe(ialu_reg_reg); 7301 %} 7302 7303 instruct leaI_rReg_rReg_immI2_immI(rRegI dst, rRegI base, rRegI index, immI2 scale, immI disp) 7304 %{ 7305 predicate(VM_Version::supports_fast_3op_lea()); 7306 match(Set dst (AddI (AddI base (LShiftI index scale)) disp)); 7307 7308 format %{ "leal $dst, [$base + $index << $scale + $disp]\t# int" %} 7309 ins_encode %{ 7310 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 7311 __ leal($dst$$Register, Address($base$$Register, $index$$Register, scale, $disp$$constant)); 7312 %} 7313 ins_pipe(ialu_reg_reg); 7314 %} 7315 7316 instruct addL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7317 %{ 7318 predicate(!UseAPX); 7319 match(Set dst (AddL dst src)); 7320 effect(KILL cr); 7321 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); 7322 7323 format %{ "addq $dst, $src\t# long" %} 7324 ins_encode %{ 7325 __ addq($dst$$Register, $src$$Register); 7326 %} 7327 ins_pipe(ialu_reg_reg); 7328 %} 7329 7330 instruct addL_rReg_ndd(rRegL dst, rRegL src1, rRegL src2, rFlagsReg cr) 7331 %{ 7332 predicate(UseAPX); 7333 match(Set dst (AddL src1 src2)); 7334 effect(KILL cr); 7335 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); 7336 7337 format %{ "eaddq $dst, $src1, $src2\t# long ndd" %} 7338 ins_encode %{ 7339 __ eaddq($dst$$Register, $src1$$Register, $src2$$Register, false); 7340 %} 7341 ins_pipe(ialu_reg_reg); 7342 %} 7343 7344 instruct addL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 7345 %{ 7346 predicate(!UseAPX); 7347 match(Set dst (AddL dst src)); 7348 effect(KILL cr); 7349 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); 7350 7351 format %{ "addq $dst, $src\t# long" %} 7352 ins_encode %{ 7353 __ addq($dst$$Register, $src$$constant); 7354 %} 7355 ins_pipe( ialu_reg ); 7356 %} 7357 7358 instruct addL_rReg_rReg_imm_ndd(rRegL dst, rRegL src1, immL32 src2, rFlagsReg cr) 7359 %{ 7360 predicate(UseAPX); 7361 match(Set dst (AddL src1 src2)); 7362 effect(KILL cr); 7363 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); 7364 7365 format %{ "eaddq $dst, $src1, $src2\t# long ndd" %} 7366 ins_encode %{ 7367 __ eaddq($dst$$Register, $src1$$Register, $src2$$constant, false); 7368 %} 7369 ins_pipe( ialu_reg ); 7370 %} 7371 7372 instruct addL_rReg_mem_imm_ndd(rRegL dst, memory src1, immL32 src2, rFlagsReg cr) 7373 %{ 7374 predicate(UseAPX); 7375 match(Set dst (AddL (LoadL src1) src2)); 7376 effect(KILL cr); 7377 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); 7378 7379 format %{ "eaddq $dst, $src1, $src2\t# long ndd" %} 7380 ins_encode %{ 7381 __ eaddq($dst$$Register, $src1$$Address, $src2$$constant, false); 7382 %} 7383 ins_pipe( ialu_reg ); 7384 %} 7385 7386 instruct addL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 7387 %{ 7388 predicate(!UseAPX); 7389 match(Set dst (AddL dst (LoadL src))); 7390 effect(KILL cr); 7391 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); 7392 7393 ins_cost(150); // XXX 7394 format %{ "addq $dst, $src\t# long" %} 7395 ins_encode %{ 7396 __ addq($dst$$Register, $src$$Address); 7397 %} 7398 ins_pipe(ialu_reg_mem); 7399 %} 7400 7401 instruct addL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr) 7402 %{ 7403 predicate(UseAPX); 7404 match(Set dst (AddL src1 (LoadL src2))); 7405 effect(KILL cr); 7406 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); 7407 7408 ins_cost(150); 7409 format %{ "eaddq $dst, $src1, $src2\t# long ndd" %} 7410 ins_encode %{ 7411 __ eaddq($dst$$Register, $src1$$Register, $src2$$Address, false); 7412 %} 7413 ins_pipe(ialu_reg_mem); 7414 %} 7415 7416 instruct addL_rReg_mem_rReg_ndd(rRegL dst, memory src1, rRegL src2, rFlagsReg cr) 7417 %{ 7418 predicate(UseAPX); 7419 match(Set dst (AddL (LoadL src1) src2)); 7420 effect(KILL cr); 7421 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); 7422 7423 ins_cost(150); 7424 format %{ "eaddq $dst, $src1, $src2\t# long ndd" %} 7425 ins_encode %{ 7426 __ eaddq($dst$$Register, $src1$$Address, $src2$$Register, false); 7427 %} 7428 ins_pipe(ialu_reg_mem); 7429 %} 7430 7431 instruct addL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 7432 %{ 7433 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7434 effect(KILL cr); 7435 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); 7436 7437 ins_cost(150); // XXX 7438 format %{ "addq $dst, $src\t# long" %} 7439 ins_encode %{ 7440 __ addq($dst$$Address, $src$$Register); 7441 %} 7442 ins_pipe(ialu_mem_reg); 7443 %} 7444 7445 instruct addL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 7446 %{ 7447 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7448 effect(KILL cr); 7449 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); 7450 7451 ins_cost(125); // XXX 7452 format %{ "addq $dst, $src\t# long" %} 7453 ins_encode %{ 7454 __ addq($dst$$Address, $src$$constant); 7455 %} 7456 ins_pipe(ialu_mem_imm); 7457 %} 7458 7459 instruct incL_rReg(rRegL dst, immL1 src, rFlagsReg cr) 7460 %{ 7461 predicate(!UseAPX && UseIncDec); 7462 match(Set dst (AddL dst src)); 7463 effect(KILL cr); 7464 7465 format %{ "incq $dst\t# long" %} 7466 ins_encode %{ 7467 __ incrementq($dst$$Register); 7468 %} 7469 ins_pipe(ialu_reg); 7470 %} 7471 7472 instruct incL_rReg_ndd(rRegL dst, rRegI src, immL1 val, rFlagsReg cr) 7473 %{ 7474 predicate(UseAPX && UseIncDec); 7475 match(Set dst (AddL src val)); 7476 effect(KILL cr); 7477 7478 format %{ "eincq $dst, $src\t# long ndd" %} 7479 ins_encode %{ 7480 __ eincq($dst$$Register, $src$$Register, false); 7481 %} 7482 ins_pipe(ialu_reg); 7483 %} 7484 7485 instruct incL_rReg_mem_ndd(rRegL dst, memory src, immL1 val, rFlagsReg cr) 7486 %{ 7487 predicate(UseAPX && UseIncDec); 7488 match(Set dst (AddL (LoadL src) val)); 7489 effect(KILL cr); 7490 7491 format %{ "eincq $dst, $src\t# long ndd" %} 7492 ins_encode %{ 7493 __ eincq($dst$$Register, $src$$Address, false); 7494 %} 7495 ins_pipe(ialu_reg); 7496 %} 7497 7498 instruct incL_mem(memory dst, immL1 src, rFlagsReg cr) 7499 %{ 7500 predicate(UseIncDec); 7501 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7502 effect(KILL cr); 7503 7504 ins_cost(125); // XXX 7505 format %{ "incq $dst\t# long" %} 7506 ins_encode %{ 7507 __ incrementq($dst$$Address); 7508 %} 7509 ins_pipe(ialu_mem_imm); 7510 %} 7511 7512 // XXX why does that use AddL 7513 instruct decL_rReg(rRegL dst, immL_M1 src, rFlagsReg cr) 7514 %{ 7515 predicate(!UseAPX && UseIncDec); 7516 match(Set dst (AddL dst src)); 7517 effect(KILL cr); 7518 7519 format %{ "decq $dst\t# long" %} 7520 ins_encode %{ 7521 __ decrementq($dst$$Register); 7522 %} 7523 ins_pipe(ialu_reg); 7524 %} 7525 7526 instruct decL_rReg_ndd(rRegL dst, rRegL src, immL_M1 val, rFlagsReg cr) 7527 %{ 7528 predicate(UseAPX && UseIncDec); 7529 match(Set dst (AddL src val)); 7530 effect(KILL cr); 7531 7532 format %{ "edecq $dst, $src\t# long ndd" %} 7533 ins_encode %{ 7534 __ edecq($dst$$Register, $src$$Register, false); 7535 %} 7536 ins_pipe(ialu_reg); 7537 %} 7538 7539 instruct decL_rReg_mem_ndd(rRegL dst, memory src, immL_M1 val, rFlagsReg cr) 7540 %{ 7541 predicate(UseAPX && UseIncDec); 7542 match(Set dst (AddL (LoadL src) val)); 7543 effect(KILL cr); 7544 7545 format %{ "edecq $dst, $src\t# long ndd" %} 7546 ins_encode %{ 7547 __ edecq($dst$$Register, $src$$Address, false); 7548 %} 7549 ins_pipe(ialu_reg); 7550 %} 7551 7552 // XXX why does that use AddL 7553 instruct decL_mem(memory dst, immL_M1 src, rFlagsReg cr) 7554 %{ 7555 predicate(UseIncDec); 7556 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7557 effect(KILL cr); 7558 7559 ins_cost(125); // XXX 7560 format %{ "decq $dst\t# long" %} 7561 ins_encode %{ 7562 __ decrementq($dst$$Address); 7563 %} 7564 ins_pipe(ialu_mem_imm); 7565 %} 7566 7567 instruct leaL_rReg_immI2_immL32(rRegL dst, rRegL index, immI2 scale, immL32 disp) 7568 %{ 7569 predicate(VM_Version::supports_fast_2op_lea()); 7570 match(Set dst (AddL (LShiftL index scale) disp)); 7571 7572 format %{ "leaq $dst, [$index << $scale + $disp]\t# long" %} 7573 ins_encode %{ 7574 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 7575 __ leaq($dst$$Register, Address(noreg, $index$$Register, scale, $disp$$constant)); 7576 %} 7577 ins_pipe(ialu_reg_reg); 7578 %} 7579 7580 instruct leaL_rReg_rReg_immL32(rRegL dst, rRegL base, rRegL index, immL32 disp) 7581 %{ 7582 predicate(VM_Version::supports_fast_3op_lea()); 7583 match(Set dst (AddL (AddL base index) disp)); 7584 7585 format %{ "leaq $dst, [$base + $index + $disp]\t# long" %} 7586 ins_encode %{ 7587 __ leaq($dst$$Register, Address($base$$Register, $index$$Register, Address::times_1, $disp$$constant)); 7588 %} 7589 ins_pipe(ialu_reg_reg); 7590 %} 7591 7592 instruct leaL_rReg_rReg_immI2(rRegL dst, no_rbp_r13_RegL base, rRegL index, immI2 scale) 7593 %{ 7594 predicate(VM_Version::supports_fast_2op_lea()); 7595 match(Set dst (AddL base (LShiftL index scale))); 7596 7597 format %{ "leaq $dst, [$base + $index << $scale]\t# long" %} 7598 ins_encode %{ 7599 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 7600 __ leaq($dst$$Register, Address($base$$Register, $index$$Register, scale)); 7601 %} 7602 ins_pipe(ialu_reg_reg); 7603 %} 7604 7605 instruct leaL_rReg_rReg_immI2_immL32(rRegL dst, rRegL base, rRegL index, immI2 scale, immL32 disp) 7606 %{ 7607 predicate(VM_Version::supports_fast_3op_lea()); 7608 match(Set dst (AddL (AddL base (LShiftL index scale)) disp)); 7609 7610 format %{ "leaq $dst, [$base + $index << $scale + $disp]\t# long" %} 7611 ins_encode %{ 7612 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 7613 __ leaq($dst$$Register, Address($base$$Register, $index$$Register, scale, $disp$$constant)); 7614 %} 7615 ins_pipe(ialu_reg_reg); 7616 %} 7617 7618 instruct addP_rReg(rRegP dst, rRegL src, rFlagsReg cr) 7619 %{ 7620 match(Set dst (AddP dst src)); 7621 effect(KILL cr); 7622 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); 7623 7624 format %{ "addq $dst, $src\t# ptr" %} 7625 ins_encode %{ 7626 __ addq($dst$$Register, $src$$Register); 7627 %} 7628 ins_pipe(ialu_reg_reg); 7629 %} 7630 7631 instruct addP_rReg_imm(rRegP dst, immL32 src, rFlagsReg cr) 7632 %{ 7633 match(Set dst (AddP dst src)); 7634 effect(KILL cr); 7635 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); 7636 7637 format %{ "addq $dst, $src\t# ptr" %} 7638 ins_encode %{ 7639 __ addq($dst$$Register, $src$$constant); 7640 %} 7641 ins_pipe( ialu_reg ); 7642 %} 7643 7644 // XXX addP mem ops ???? 7645 7646 instruct checkCastPP(rRegP dst) 7647 %{ 7648 match(Set dst (CheckCastPP dst)); 7649 7650 size(0); 7651 format %{ "# checkcastPP of $dst" %} 7652 ins_encode(/* empty encoding */); 7653 ins_pipe(empty); 7654 %} 7655 7656 instruct castPP(rRegP dst) 7657 %{ 7658 match(Set dst (CastPP dst)); 7659 7660 size(0); 7661 format %{ "# castPP of $dst" %} 7662 ins_encode(/* empty encoding */); 7663 ins_pipe(empty); 7664 %} 7665 7666 instruct castII(rRegI dst) 7667 %{ 7668 predicate(VerifyConstraintCasts == 0); 7669 match(Set dst (CastII dst)); 7670 7671 size(0); 7672 format %{ "# castII of $dst" %} 7673 ins_encode(/* empty encoding */); 7674 ins_cost(0); 7675 ins_pipe(empty); 7676 %} 7677 7678 instruct castII_checked(rRegI dst, rFlagsReg cr) 7679 %{ 7680 predicate(VerifyConstraintCasts > 0); 7681 match(Set dst (CastII dst)); 7682 7683 effect(KILL cr); 7684 format %{ "# cast_checked_II $dst" %} 7685 ins_encode %{ 7686 __ verify_int_in_range(_idx, bottom_type()->is_int(), $dst$$Register); 7687 %} 7688 ins_pipe(pipe_slow); 7689 %} 7690 7691 instruct castLL(rRegL dst) 7692 %{ 7693 predicate(VerifyConstraintCasts == 0); 7694 match(Set dst (CastLL dst)); 7695 7696 size(0); 7697 format %{ "# castLL of $dst" %} 7698 ins_encode(/* empty encoding */); 7699 ins_cost(0); 7700 ins_pipe(empty); 7701 %} 7702 7703 instruct castLL_checked_L32(rRegL dst, rFlagsReg cr) 7704 %{ 7705 predicate(VerifyConstraintCasts > 0 && castLL_is_imm32(n)); 7706 match(Set dst (CastLL dst)); 7707 7708 effect(KILL cr); 7709 format %{ "# cast_checked_LL $dst" %} 7710 ins_encode %{ 7711 __ verify_long_in_range(_idx, bottom_type()->is_long(), $dst$$Register, noreg); 7712 %} 7713 ins_pipe(pipe_slow); 7714 %} 7715 7716 instruct castLL_checked(rRegL dst, rRegL tmp, rFlagsReg cr) 7717 %{ 7718 predicate(VerifyConstraintCasts > 0 && !castLL_is_imm32(n)); 7719 match(Set dst (CastLL dst)); 7720 7721 effect(KILL cr, TEMP tmp); 7722 format %{ "# cast_checked_LL $dst\tusing $tmp as TEMP" %} 7723 ins_encode %{ 7724 __ verify_long_in_range(_idx, bottom_type()->is_long(), $dst$$Register, $tmp$$Register); 7725 %} 7726 ins_pipe(pipe_slow); 7727 %} 7728 7729 instruct castFF(regF dst) 7730 %{ 7731 match(Set dst (CastFF dst)); 7732 7733 size(0); 7734 format %{ "# castFF of $dst" %} 7735 ins_encode(/* empty encoding */); 7736 ins_cost(0); 7737 ins_pipe(empty); 7738 %} 7739 7740 instruct castHH(regF dst) 7741 %{ 7742 match(Set dst (CastHH dst)); 7743 7744 size(0); 7745 format %{ "# castHH of $dst" %} 7746 ins_encode(/* empty encoding */); 7747 ins_cost(0); 7748 ins_pipe(empty); 7749 %} 7750 7751 instruct castDD(regD dst) 7752 %{ 7753 match(Set dst (CastDD dst)); 7754 7755 size(0); 7756 format %{ "# castDD of $dst" %} 7757 ins_encode(/* empty encoding */); 7758 ins_cost(0); 7759 ins_pipe(empty); 7760 %} 7761 7762 // XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them 7763 instruct compareAndSwapP(rRegI res, 7764 memory mem_ptr, 7765 rax_RegP oldval, rRegP newval, 7766 rFlagsReg cr) 7767 %{ 7768 predicate(n->as_LoadStore()->barrier_data() == 0); 7769 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); 7770 match(Set res (WeakCompareAndSwapP mem_ptr (Binary oldval newval))); 7771 effect(KILL cr, KILL oldval); 7772 7773 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7774 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7775 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7776 ins_encode %{ 7777 __ lock(); 7778 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7779 __ setcc(Assembler::equal, $res$$Register); 7780 %} 7781 ins_pipe( pipe_cmpxchg ); 7782 %} 7783 7784 instruct compareAndSwapL(rRegI res, 7785 memory mem_ptr, 7786 rax_RegL oldval, rRegL newval, 7787 rFlagsReg cr) 7788 %{ 7789 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval))); 7790 match(Set res (WeakCompareAndSwapL mem_ptr (Binary oldval newval))); 7791 effect(KILL cr, KILL oldval); 7792 7793 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7794 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7795 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7796 ins_encode %{ 7797 __ lock(); 7798 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7799 __ setcc(Assembler::equal, $res$$Register); 7800 %} 7801 ins_pipe( pipe_cmpxchg ); 7802 %} 7803 7804 instruct compareAndSwapI(rRegI res, 7805 memory mem_ptr, 7806 rax_RegI oldval, rRegI newval, 7807 rFlagsReg cr) 7808 %{ 7809 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval))); 7810 match(Set res (WeakCompareAndSwapI mem_ptr (Binary oldval newval))); 7811 effect(KILL cr, KILL oldval); 7812 7813 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7814 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7815 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7816 ins_encode %{ 7817 __ lock(); 7818 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7819 __ setcc(Assembler::equal, $res$$Register); 7820 %} 7821 ins_pipe( pipe_cmpxchg ); 7822 %} 7823 7824 instruct compareAndSwapB(rRegI res, 7825 memory mem_ptr, 7826 rax_RegI oldval, rRegI newval, 7827 rFlagsReg cr) 7828 %{ 7829 match(Set res (CompareAndSwapB mem_ptr (Binary oldval newval))); 7830 match(Set res (WeakCompareAndSwapB mem_ptr (Binary oldval newval))); 7831 effect(KILL cr, KILL oldval); 7832 7833 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7834 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7835 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7836 ins_encode %{ 7837 __ lock(); 7838 __ cmpxchgb($newval$$Register, $mem_ptr$$Address); 7839 __ setcc(Assembler::equal, $res$$Register); 7840 %} 7841 ins_pipe( pipe_cmpxchg ); 7842 %} 7843 7844 instruct compareAndSwapS(rRegI res, 7845 memory mem_ptr, 7846 rax_RegI oldval, rRegI newval, 7847 rFlagsReg cr) 7848 %{ 7849 match(Set res (CompareAndSwapS mem_ptr (Binary oldval newval))); 7850 match(Set res (WeakCompareAndSwapS mem_ptr (Binary oldval newval))); 7851 effect(KILL cr, KILL oldval); 7852 7853 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7854 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7855 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7856 ins_encode %{ 7857 __ lock(); 7858 __ cmpxchgw($newval$$Register, $mem_ptr$$Address); 7859 __ setcc(Assembler::equal, $res$$Register); 7860 %} 7861 ins_pipe( pipe_cmpxchg ); 7862 %} 7863 7864 instruct compareAndSwapN(rRegI res, 7865 memory mem_ptr, 7866 rax_RegN oldval, rRegN newval, 7867 rFlagsReg cr) %{ 7868 predicate(n->as_LoadStore()->barrier_data() == 0); 7869 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval))); 7870 match(Set res (WeakCompareAndSwapN mem_ptr (Binary oldval newval))); 7871 effect(KILL cr, KILL oldval); 7872 7873 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7874 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7875 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7876 ins_encode %{ 7877 __ lock(); 7878 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7879 __ setcc(Assembler::equal, $res$$Register); 7880 %} 7881 ins_pipe( pipe_cmpxchg ); 7882 %} 7883 7884 instruct compareAndExchangeB( 7885 memory mem_ptr, 7886 rax_RegI oldval, rRegI newval, 7887 rFlagsReg cr) 7888 %{ 7889 match(Set oldval (CompareAndExchangeB mem_ptr (Binary oldval newval))); 7890 effect(KILL cr); 7891 7892 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7893 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7894 ins_encode %{ 7895 __ lock(); 7896 __ cmpxchgb($newval$$Register, $mem_ptr$$Address); 7897 %} 7898 ins_pipe( pipe_cmpxchg ); 7899 %} 7900 7901 instruct compareAndExchangeS( 7902 memory mem_ptr, 7903 rax_RegI oldval, rRegI newval, 7904 rFlagsReg cr) 7905 %{ 7906 match(Set oldval (CompareAndExchangeS mem_ptr (Binary oldval newval))); 7907 effect(KILL cr); 7908 7909 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7910 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7911 ins_encode %{ 7912 __ lock(); 7913 __ cmpxchgw($newval$$Register, $mem_ptr$$Address); 7914 %} 7915 ins_pipe( pipe_cmpxchg ); 7916 %} 7917 7918 instruct compareAndExchangeI( 7919 memory mem_ptr, 7920 rax_RegI oldval, rRegI newval, 7921 rFlagsReg cr) 7922 %{ 7923 match(Set oldval (CompareAndExchangeI mem_ptr (Binary oldval newval))); 7924 effect(KILL cr); 7925 7926 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7927 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7928 ins_encode %{ 7929 __ lock(); 7930 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7931 %} 7932 ins_pipe( pipe_cmpxchg ); 7933 %} 7934 7935 instruct compareAndExchangeL( 7936 memory mem_ptr, 7937 rax_RegL oldval, rRegL newval, 7938 rFlagsReg cr) 7939 %{ 7940 match(Set oldval (CompareAndExchangeL mem_ptr (Binary oldval newval))); 7941 effect(KILL cr); 7942 7943 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7944 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7945 ins_encode %{ 7946 __ lock(); 7947 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7948 %} 7949 ins_pipe( pipe_cmpxchg ); 7950 %} 7951 7952 instruct compareAndExchangeN( 7953 memory mem_ptr, 7954 rax_RegN oldval, rRegN newval, 7955 rFlagsReg cr) %{ 7956 predicate(n->as_LoadStore()->barrier_data() == 0); 7957 match(Set oldval (CompareAndExchangeN mem_ptr (Binary oldval newval))); 7958 effect(KILL cr); 7959 7960 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7961 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7962 ins_encode %{ 7963 __ lock(); 7964 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7965 %} 7966 ins_pipe( pipe_cmpxchg ); 7967 %} 7968 7969 instruct compareAndExchangeP( 7970 memory mem_ptr, 7971 rax_RegP oldval, rRegP newval, 7972 rFlagsReg cr) 7973 %{ 7974 predicate(n->as_LoadStore()->barrier_data() == 0); 7975 match(Set oldval (CompareAndExchangeP mem_ptr (Binary oldval newval))); 7976 effect(KILL cr); 7977 7978 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7979 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7980 ins_encode %{ 7981 __ lock(); 7982 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7983 %} 7984 ins_pipe( pipe_cmpxchg ); 7985 %} 7986 7987 instruct xaddB_reg_no_res(memory mem, Universe dummy, rRegI add, rFlagsReg cr) %{ 7988 predicate(n->as_LoadStore()->result_not_used()); 7989 match(Set dummy (GetAndAddB mem add)); 7990 effect(KILL cr); 7991 format %{ "addb_lock $mem, $add" %} 7992 ins_encode %{ 7993 __ lock(); 7994 __ addb($mem$$Address, $add$$Register); 7995 %} 7996 ins_pipe(pipe_cmpxchg); 7997 %} 7998 7999 instruct xaddB_imm_no_res(memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 8000 predicate(n->as_LoadStore()->result_not_used()); 8001 match(Set dummy (GetAndAddB mem add)); 8002 effect(KILL cr); 8003 format %{ "addb_lock $mem, $add" %} 8004 ins_encode %{ 8005 __ lock(); 8006 __ addb($mem$$Address, $add$$constant); 8007 %} 8008 ins_pipe(pipe_cmpxchg); 8009 %} 8010 8011 instruct xaddB(memory mem, rRegI newval, rFlagsReg cr) %{ 8012 predicate(!n->as_LoadStore()->result_not_used()); 8013 match(Set newval (GetAndAddB mem newval)); 8014 effect(KILL cr); 8015 format %{ "xaddb_lock $mem, $newval" %} 8016 ins_encode %{ 8017 __ lock(); 8018 __ xaddb($mem$$Address, $newval$$Register); 8019 %} 8020 ins_pipe(pipe_cmpxchg); 8021 %} 8022 8023 instruct xaddS_reg_no_res(memory mem, Universe dummy, rRegI add, rFlagsReg cr) %{ 8024 predicate(n->as_LoadStore()->result_not_used()); 8025 match(Set dummy (GetAndAddS mem add)); 8026 effect(KILL cr); 8027 format %{ "addw_lock $mem, $add" %} 8028 ins_encode %{ 8029 __ lock(); 8030 __ addw($mem$$Address, $add$$Register); 8031 %} 8032 ins_pipe(pipe_cmpxchg); 8033 %} 8034 8035 instruct xaddS_imm_no_res(memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 8036 predicate(UseStoreImmI16 && n->as_LoadStore()->result_not_used()); 8037 match(Set dummy (GetAndAddS mem add)); 8038 effect(KILL cr); 8039 format %{ "addw_lock $mem, $add" %} 8040 ins_encode %{ 8041 __ lock(); 8042 __ addw($mem$$Address, $add$$constant); 8043 %} 8044 ins_pipe(pipe_cmpxchg); 8045 %} 8046 8047 instruct xaddS(memory mem, rRegI newval, rFlagsReg cr) %{ 8048 predicate(!n->as_LoadStore()->result_not_used()); 8049 match(Set newval (GetAndAddS mem newval)); 8050 effect(KILL cr); 8051 format %{ "xaddw_lock $mem, $newval" %} 8052 ins_encode %{ 8053 __ lock(); 8054 __ xaddw($mem$$Address, $newval$$Register); 8055 %} 8056 ins_pipe(pipe_cmpxchg); 8057 %} 8058 8059 instruct xaddI_reg_no_res(memory mem, Universe dummy, rRegI add, rFlagsReg cr) %{ 8060 predicate(n->as_LoadStore()->result_not_used()); 8061 match(Set dummy (GetAndAddI mem add)); 8062 effect(KILL cr); 8063 format %{ "addl_lock $mem, $add" %} 8064 ins_encode %{ 8065 __ lock(); 8066 __ addl($mem$$Address, $add$$Register); 8067 %} 8068 ins_pipe(pipe_cmpxchg); 8069 %} 8070 8071 instruct xaddI_imm_no_res(memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 8072 predicate(n->as_LoadStore()->result_not_used()); 8073 match(Set dummy (GetAndAddI mem add)); 8074 effect(KILL cr); 8075 format %{ "addl_lock $mem, $add" %} 8076 ins_encode %{ 8077 __ lock(); 8078 __ addl($mem$$Address, $add$$constant); 8079 %} 8080 ins_pipe(pipe_cmpxchg); 8081 %} 8082 8083 instruct xaddI(memory mem, rRegI newval, rFlagsReg cr) %{ 8084 predicate(!n->as_LoadStore()->result_not_used()); 8085 match(Set newval (GetAndAddI mem newval)); 8086 effect(KILL cr); 8087 format %{ "xaddl_lock $mem, $newval" %} 8088 ins_encode %{ 8089 __ lock(); 8090 __ xaddl($mem$$Address, $newval$$Register); 8091 %} 8092 ins_pipe(pipe_cmpxchg); 8093 %} 8094 8095 instruct xaddL_reg_no_res(memory mem, Universe dummy, rRegL add, rFlagsReg cr) %{ 8096 predicate(n->as_LoadStore()->result_not_used()); 8097 match(Set dummy (GetAndAddL mem add)); 8098 effect(KILL cr); 8099 format %{ "addq_lock $mem, $add" %} 8100 ins_encode %{ 8101 __ lock(); 8102 __ addq($mem$$Address, $add$$Register); 8103 %} 8104 ins_pipe(pipe_cmpxchg); 8105 %} 8106 8107 instruct xaddL_imm_no_res(memory mem, Universe dummy, immL32 add, rFlagsReg cr) %{ 8108 predicate(n->as_LoadStore()->result_not_used()); 8109 match(Set dummy (GetAndAddL mem add)); 8110 effect(KILL cr); 8111 format %{ "addq_lock $mem, $add" %} 8112 ins_encode %{ 8113 __ lock(); 8114 __ addq($mem$$Address, $add$$constant); 8115 %} 8116 ins_pipe(pipe_cmpxchg); 8117 %} 8118 8119 instruct xaddL(memory mem, rRegL newval, rFlagsReg cr) %{ 8120 predicate(!n->as_LoadStore()->result_not_used()); 8121 match(Set newval (GetAndAddL mem newval)); 8122 effect(KILL cr); 8123 format %{ "xaddq_lock $mem, $newval" %} 8124 ins_encode %{ 8125 __ lock(); 8126 __ xaddq($mem$$Address, $newval$$Register); 8127 %} 8128 ins_pipe(pipe_cmpxchg); 8129 %} 8130 8131 instruct xchgB( memory mem, rRegI newval) %{ 8132 match(Set newval (GetAndSetB mem newval)); 8133 format %{ "XCHGB $newval,[$mem]" %} 8134 ins_encode %{ 8135 __ xchgb($newval$$Register, $mem$$Address); 8136 %} 8137 ins_pipe( pipe_cmpxchg ); 8138 %} 8139 8140 instruct xchgS( memory mem, rRegI newval) %{ 8141 match(Set newval (GetAndSetS mem newval)); 8142 format %{ "XCHGW $newval,[$mem]" %} 8143 ins_encode %{ 8144 __ xchgw($newval$$Register, $mem$$Address); 8145 %} 8146 ins_pipe( pipe_cmpxchg ); 8147 %} 8148 8149 instruct xchgI( memory mem, rRegI newval) %{ 8150 match(Set newval (GetAndSetI mem newval)); 8151 format %{ "XCHGL $newval,[$mem]" %} 8152 ins_encode %{ 8153 __ xchgl($newval$$Register, $mem$$Address); 8154 %} 8155 ins_pipe( pipe_cmpxchg ); 8156 %} 8157 8158 instruct xchgL( memory mem, rRegL newval) %{ 8159 match(Set newval (GetAndSetL mem newval)); 8160 format %{ "XCHGL $newval,[$mem]" %} 8161 ins_encode %{ 8162 __ xchgq($newval$$Register, $mem$$Address); 8163 %} 8164 ins_pipe( pipe_cmpxchg ); 8165 %} 8166 8167 instruct xchgP( memory mem, rRegP newval) %{ 8168 match(Set newval (GetAndSetP mem newval)); 8169 predicate(n->as_LoadStore()->barrier_data() == 0); 8170 format %{ "XCHGQ $newval,[$mem]" %} 8171 ins_encode %{ 8172 __ xchgq($newval$$Register, $mem$$Address); 8173 %} 8174 ins_pipe( pipe_cmpxchg ); 8175 %} 8176 8177 instruct xchgN( memory mem, rRegN newval) %{ 8178 predicate(n->as_LoadStore()->barrier_data() == 0); 8179 match(Set newval (GetAndSetN mem newval)); 8180 format %{ "XCHGL $newval,$mem]" %} 8181 ins_encode %{ 8182 __ xchgl($newval$$Register, $mem$$Address); 8183 %} 8184 ins_pipe( pipe_cmpxchg ); 8185 %} 8186 8187 //----------Abs Instructions------------------------------------------- 8188 8189 // Integer Absolute Instructions 8190 instruct absI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8191 %{ 8192 match(Set dst (AbsI src)); 8193 effect(TEMP dst, KILL cr); 8194 format %{ "xorl $dst, $dst\t# abs int\n\t" 8195 "subl $dst, $src\n\t" 8196 "cmovll $dst, $src" %} 8197 ins_encode %{ 8198 __ xorl($dst$$Register, $dst$$Register); 8199 __ subl($dst$$Register, $src$$Register); 8200 __ cmovl(Assembler::less, $dst$$Register, $src$$Register); 8201 %} 8202 8203 ins_pipe(ialu_reg_reg); 8204 %} 8205 8206 // Long Absolute Instructions 8207 instruct absL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 8208 %{ 8209 match(Set dst (AbsL src)); 8210 effect(TEMP dst, KILL cr); 8211 format %{ "xorl $dst, $dst\t# abs long\n\t" 8212 "subq $dst, $src\n\t" 8213 "cmovlq $dst, $src" %} 8214 ins_encode %{ 8215 __ xorl($dst$$Register, $dst$$Register); 8216 __ subq($dst$$Register, $src$$Register); 8217 __ cmovq(Assembler::less, $dst$$Register, $src$$Register); 8218 %} 8219 8220 ins_pipe(ialu_reg_reg); 8221 %} 8222 8223 //----------Subtraction Instructions------------------------------------------- 8224 8225 // Integer Subtraction Instructions 8226 instruct subI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8227 %{ 8228 predicate(!UseAPX); 8229 match(Set dst (SubI dst src)); 8230 effect(KILL cr); 8231 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); 8232 8233 format %{ "subl $dst, $src\t# int" %} 8234 ins_encode %{ 8235 __ subl($dst$$Register, $src$$Register); 8236 %} 8237 ins_pipe(ialu_reg_reg); 8238 %} 8239 8240 instruct subI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr) 8241 %{ 8242 predicate(UseAPX); 8243 match(Set dst (SubI src1 src2)); 8244 effect(KILL cr); 8245 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 8246 8247 format %{ "esubl $dst, $src1, $src2\t# int ndd" %} 8248 ins_encode %{ 8249 __ esubl($dst$$Register, $src1$$Register, $src2$$Register, false); 8250 %} 8251 ins_pipe(ialu_reg_reg); 8252 %} 8253 8254 instruct subI_rReg_rReg_imm_ndd(rRegI dst, rRegI src1, immI src2, rFlagsReg cr) 8255 %{ 8256 predicate(UseAPX); 8257 match(Set dst (SubI src1 src2)); 8258 effect(KILL cr); 8259 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 8260 8261 format %{ "esubl $dst, $src1, $src2\t# int ndd" %} 8262 ins_encode %{ 8263 __ esubl($dst$$Register, $src1$$Register, $src2$$constant, false); 8264 %} 8265 ins_pipe(ialu_reg_reg); 8266 %} 8267 8268 instruct subI_rReg_mem_imm_ndd(rRegI dst, memory src1, immI src2, rFlagsReg cr) 8269 %{ 8270 predicate(UseAPX); 8271 match(Set dst (SubI (LoadI src1) src2)); 8272 effect(KILL cr); 8273 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); 8274 8275 format %{ "esubl $dst, $src1, $src2\t# int ndd" %} 8276 ins_encode %{ 8277 __ esubl($dst$$Register, $src1$$Address, $src2$$constant, false); 8278 %} 8279 ins_pipe(ialu_reg_reg); 8280 %} 8281 8282 instruct subI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 8283 %{ 8284 predicate(!UseAPX); 8285 match(Set dst (SubI dst (LoadI src))); 8286 effect(KILL cr); 8287 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); 8288 8289 ins_cost(150); 8290 format %{ "subl $dst, $src\t# int" %} 8291 ins_encode %{ 8292 __ subl($dst$$Register, $src$$Address); 8293 %} 8294 ins_pipe(ialu_reg_mem); 8295 %} 8296 8297 instruct subI_rReg_rReg_mem_ndd(rRegI dst, rRegI src1, memory src2, rFlagsReg cr) 8298 %{ 8299 predicate(UseAPX); 8300 match(Set dst (SubI src1 (LoadI src2))); 8301 effect(KILL cr); 8302 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 8303 8304 ins_cost(150); 8305 format %{ "esubl $dst, $src1, $src2\t# int ndd" %} 8306 ins_encode %{ 8307 __ esubl($dst$$Register, $src1$$Register, $src2$$Address, false); 8308 %} 8309 ins_pipe(ialu_reg_mem); 8310 %} 8311 8312 instruct subI_rReg_mem_rReg_ndd(rRegI dst, memory src1, rRegI src2, rFlagsReg cr) 8313 %{ 8314 predicate(UseAPX); 8315 match(Set dst (SubI (LoadI src1) src2)); 8316 effect(KILL cr); 8317 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); 8318 8319 ins_cost(150); 8320 format %{ "esubl $dst, $src1, $src2\t# int ndd" %} 8321 ins_encode %{ 8322 __ esubl($dst$$Register, $src1$$Address, $src2$$Register, false); 8323 %} 8324 ins_pipe(ialu_reg_mem); 8325 %} 8326 8327 instruct subI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 8328 %{ 8329 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 8330 effect(KILL cr); 8331 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); 8332 8333 ins_cost(150); 8334 format %{ "subl $dst, $src\t# int" %} 8335 ins_encode %{ 8336 __ subl($dst$$Address, $src$$Register); 8337 %} 8338 ins_pipe(ialu_mem_reg); 8339 %} 8340 8341 instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 8342 %{ 8343 predicate(!UseAPX); 8344 match(Set dst (SubL dst src)); 8345 effect(KILL cr); 8346 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); 8347 8348 format %{ "subq $dst, $src\t# long" %} 8349 ins_encode %{ 8350 __ subq($dst$$Register, $src$$Register); 8351 %} 8352 ins_pipe(ialu_reg_reg); 8353 %} 8354 8355 instruct subL_rReg_ndd(rRegL dst, rRegL src1, rRegL src2, rFlagsReg cr) 8356 %{ 8357 predicate(UseAPX); 8358 match(Set dst (SubL src1 src2)); 8359 effect(KILL cr); 8360 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 8361 8362 format %{ "esubq $dst, $src1, $src2\t# long ndd" %} 8363 ins_encode %{ 8364 __ esubq($dst$$Register, $src1$$Register, $src2$$Register, false); 8365 %} 8366 ins_pipe(ialu_reg_reg); 8367 %} 8368 8369 instruct subL_rReg_rReg_imm_ndd(rRegL dst, rRegL src1, immL32 src2, rFlagsReg cr) 8370 %{ 8371 predicate(UseAPX); 8372 match(Set dst (SubL src1 src2)); 8373 effect(KILL cr); 8374 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 8375 8376 format %{ "esubq $dst, $src1, $src2\t# long ndd" %} 8377 ins_encode %{ 8378 __ esubq($dst$$Register, $src1$$Register, $src2$$constant, false); 8379 %} 8380 ins_pipe(ialu_reg_reg); 8381 %} 8382 8383 instruct subL_rReg_mem_imm_ndd(rRegL dst, memory src1, immL32 src2, rFlagsReg cr) 8384 %{ 8385 predicate(UseAPX); 8386 match(Set dst (SubL (LoadL src1) src2)); 8387 effect(KILL cr); 8388 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); 8389 8390 format %{ "esubq $dst, $src1, $src2\t# long ndd" %} 8391 ins_encode %{ 8392 __ esubq($dst$$Register, $src1$$Address, $src2$$constant, false); 8393 %} 8394 ins_pipe(ialu_reg_reg); 8395 %} 8396 8397 instruct subL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 8398 %{ 8399 predicate(!UseAPX); 8400 match(Set dst (SubL dst (LoadL src))); 8401 effect(KILL cr); 8402 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); 8403 8404 ins_cost(150); 8405 format %{ "subq $dst, $src\t# long" %} 8406 ins_encode %{ 8407 __ subq($dst$$Register, $src$$Address); 8408 %} 8409 ins_pipe(ialu_reg_mem); 8410 %} 8411 8412 instruct subL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr) 8413 %{ 8414 predicate(UseAPX); 8415 match(Set dst (SubL src1 (LoadL src2))); 8416 effect(KILL cr); 8417 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); 8418 8419 ins_cost(150); 8420 format %{ "esubq $dst, $src1, $src2\t# long ndd" %} 8421 ins_encode %{ 8422 __ esubq($dst$$Register, $src1$$Register, $src2$$Address, false); 8423 %} 8424 ins_pipe(ialu_reg_mem); 8425 %} 8426 8427 instruct subL_rReg_mem_rReg_ndd(rRegL dst, memory src1, rRegL src2, rFlagsReg cr) 8428 %{ 8429 predicate(UseAPX); 8430 match(Set dst (SubL (LoadL src1) src2)); 8431 effect(KILL cr); 8432 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); 8433 8434 ins_cost(150); 8435 format %{ "esubq $dst, $src1, $src2\t# long ndd" %} 8436 ins_encode %{ 8437 __ esubq($dst$$Register, $src1$$Address, $src2$$Register, false); 8438 %} 8439 ins_pipe(ialu_reg_mem); 8440 %} 8441 8442 instruct subL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 8443 %{ 8444 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 8445 effect(KILL cr); 8446 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); 8447 8448 ins_cost(150); 8449 format %{ "subq $dst, $src\t# long" %} 8450 ins_encode %{ 8451 __ subq($dst$$Address, $src$$Register); 8452 %} 8453 ins_pipe(ialu_mem_reg); 8454 %} 8455 8456 // Subtract from a pointer 8457 // XXX hmpf??? 8458 instruct subP_rReg(rRegP dst, rRegI src, immI_0 zero, rFlagsReg cr) 8459 %{ 8460 match(Set dst (AddP dst (SubI zero src))); 8461 effect(KILL cr); 8462 8463 format %{ "subq $dst, $src\t# ptr - int" %} 8464 ins_encode %{ 8465 __ subq($dst$$Register, $src$$Register); 8466 %} 8467 ins_pipe(ialu_reg_reg); 8468 %} 8469 8470 instruct negI_rReg(rRegI dst, immI_0 zero, rFlagsReg cr) 8471 %{ 8472 predicate(!UseAPX); 8473 match(Set dst (SubI zero dst)); 8474 effect(KILL cr); 8475 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8476 8477 format %{ "negl $dst\t# int" %} 8478 ins_encode %{ 8479 __ negl($dst$$Register); 8480 %} 8481 ins_pipe(ialu_reg); 8482 %} 8483 8484 instruct negI_rReg_ndd(rRegI dst, rRegI src, immI_0 zero, rFlagsReg cr) 8485 %{ 8486 predicate(UseAPX); 8487 match(Set dst (SubI zero src)); 8488 effect(KILL cr); 8489 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8490 8491 format %{ "enegl $dst, $src\t# int ndd" %} 8492 ins_encode %{ 8493 __ enegl($dst$$Register, $src$$Register, false); 8494 %} 8495 ins_pipe(ialu_reg); 8496 %} 8497 8498 instruct negI_rReg_2(rRegI dst, rFlagsReg cr) 8499 %{ 8500 predicate(!UseAPX); 8501 match(Set dst (NegI dst)); 8502 effect(KILL cr); 8503 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8504 8505 format %{ "negl $dst\t# int" %} 8506 ins_encode %{ 8507 __ negl($dst$$Register); 8508 %} 8509 ins_pipe(ialu_reg); 8510 %} 8511 8512 instruct negI_rReg_2_ndd(rRegI dst, rRegI src, rFlagsReg cr) 8513 %{ 8514 predicate(UseAPX); 8515 match(Set dst (NegI src)); 8516 effect(KILL cr); 8517 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8518 8519 format %{ "enegl $dst, $src\t# int ndd" %} 8520 ins_encode %{ 8521 __ enegl($dst$$Register, $src$$Register, false); 8522 %} 8523 ins_pipe(ialu_reg); 8524 %} 8525 8526 instruct negI_mem(memory dst, immI_0 zero, rFlagsReg cr) 8527 %{ 8528 match(Set dst (StoreI dst (SubI zero (LoadI dst)))); 8529 effect(KILL cr); 8530 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8531 8532 format %{ "negl $dst\t# int" %} 8533 ins_encode %{ 8534 __ negl($dst$$Address); 8535 %} 8536 ins_pipe(ialu_reg); 8537 %} 8538 8539 instruct negL_rReg(rRegL dst, immL0 zero, rFlagsReg cr) 8540 %{ 8541 predicate(!UseAPX); 8542 match(Set dst (SubL zero dst)); 8543 effect(KILL cr); 8544 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8545 8546 format %{ "negq $dst\t# long" %} 8547 ins_encode %{ 8548 __ negq($dst$$Register); 8549 %} 8550 ins_pipe(ialu_reg); 8551 %} 8552 8553 instruct negL_rReg_ndd(rRegL dst, rRegL src, immL0 zero, rFlagsReg cr) 8554 %{ 8555 predicate(UseAPX); 8556 match(Set dst (SubL zero src)); 8557 effect(KILL cr); 8558 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8559 8560 format %{ "enegq $dst, $src\t# long ndd" %} 8561 ins_encode %{ 8562 __ enegq($dst$$Register, $src$$Register, false); 8563 %} 8564 ins_pipe(ialu_reg); 8565 %} 8566 8567 instruct negL_rReg_2(rRegL dst, rFlagsReg cr) 8568 %{ 8569 predicate(!UseAPX); 8570 match(Set dst (NegL dst)); 8571 effect(KILL cr); 8572 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8573 8574 format %{ "negq $dst\t# int" %} 8575 ins_encode %{ 8576 __ negq($dst$$Register); 8577 %} 8578 ins_pipe(ialu_reg); 8579 %} 8580 8581 instruct negL_rReg_2_ndd(rRegL dst, rRegL src, rFlagsReg cr) 8582 %{ 8583 predicate(UseAPX); 8584 match(Set dst (NegL src)); 8585 effect(KILL cr); 8586 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8587 8588 format %{ "enegq $dst, $src\t# long ndd" %} 8589 ins_encode %{ 8590 __ enegq($dst$$Register, $src$$Register, false); 8591 %} 8592 ins_pipe(ialu_reg); 8593 %} 8594 8595 instruct negL_mem(memory dst, immL0 zero, rFlagsReg cr) 8596 %{ 8597 match(Set dst (StoreL dst (SubL zero (LoadL dst)))); 8598 effect(KILL cr); 8599 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8600 8601 format %{ "negq $dst\t# long" %} 8602 ins_encode %{ 8603 __ negq($dst$$Address); 8604 %} 8605 ins_pipe(ialu_reg); 8606 %} 8607 8608 //----------Multiplication/Division Instructions------------------------------- 8609 // Integer Multiplication Instructions 8610 // Multiply Register 8611 8612 instruct mulI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8613 %{ 8614 predicate(!UseAPX); 8615 match(Set dst (MulI dst src)); 8616 effect(KILL cr); 8617 8618 ins_cost(300); 8619 format %{ "imull $dst, $src\t# int" %} 8620 ins_encode %{ 8621 __ imull($dst$$Register, $src$$Register); 8622 %} 8623 ins_pipe(ialu_reg_reg_alu0); 8624 %} 8625 8626 instruct mulI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr) 8627 %{ 8628 predicate(UseAPX); 8629 match(Set dst (MulI src1 src2)); 8630 effect(KILL cr); 8631 8632 ins_cost(300); 8633 format %{ "eimull $dst, $src1, $src2\t# int ndd" %} 8634 ins_encode %{ 8635 __ eimull($dst$$Register, $src1$$Register, $src2$$Register, false); 8636 %} 8637 ins_pipe(ialu_reg_reg_alu0); 8638 %} 8639 8640 instruct mulI_rReg_imm(rRegI dst, rRegI src, immI imm, rFlagsReg cr) 8641 %{ 8642 predicate(!UseAPX); 8643 match(Set dst (MulI src imm)); 8644 effect(KILL cr); 8645 8646 ins_cost(300); 8647 format %{ "imull $dst, $src, $imm\t# int" %} 8648 ins_encode %{ 8649 __ imull($dst$$Register, $src$$Register, $imm$$constant); 8650 %} 8651 ins_pipe(ialu_reg_reg_alu0); 8652 %} 8653 8654 instruct mulI_rReg_rReg_imm_ndd(rRegI dst, rRegI src1, immI src2, rFlagsReg cr) 8655 %{ 8656 predicate(UseAPX); 8657 match(Set dst (MulI src1 src2)); 8658 effect(KILL cr); 8659 8660 ins_cost(300); 8661 format %{ "eimull $dst, $src1, $src2\t# int ndd" %} 8662 ins_encode %{ 8663 __ eimull($dst$$Register, $src1$$Register, $src2$$constant, false); 8664 %} 8665 ins_pipe(ialu_reg_reg_alu0); 8666 %} 8667 8668 instruct mulI_mem(rRegI dst, memory src, rFlagsReg cr) 8669 %{ 8670 predicate(!UseAPX); 8671 match(Set dst (MulI dst (LoadI src))); 8672 effect(KILL cr); 8673 8674 ins_cost(350); 8675 format %{ "imull $dst, $src\t# int" %} 8676 ins_encode %{ 8677 __ imull($dst$$Register, $src$$Address); 8678 %} 8679 ins_pipe(ialu_reg_mem_alu0); 8680 %} 8681 8682 instruct mulI_rReg_rReg_mem_ndd(rRegI dst, rRegI src1, memory src2, rFlagsReg cr) 8683 %{ 8684 predicate(UseAPX); 8685 match(Set dst (MulI src1 (LoadI src2))); 8686 effect(KILL cr); 8687 8688 ins_cost(350); 8689 format %{ "eimull $dst, $src1, $src2\t# int ndd" %} 8690 ins_encode %{ 8691 __ eimull($dst$$Register, $src1$$Register, $src2$$Address, false); 8692 %} 8693 ins_pipe(ialu_reg_mem_alu0); 8694 %} 8695 8696 instruct mulI_mem_imm(rRegI dst, memory src, immI imm, rFlagsReg cr) 8697 %{ 8698 predicate(!UseAPX); 8699 match(Set dst (MulI (LoadI src) imm)); 8700 effect(KILL cr); 8701 8702 ins_cost(300); 8703 format %{ "imull $dst, $src, $imm\t# int" %} 8704 ins_encode %{ 8705 __ imull($dst$$Register, $src$$Address, $imm$$constant); 8706 %} 8707 ins_pipe(ialu_reg_mem_alu0); 8708 %} 8709 8710 instruct mulI_rReg_mem_imm(rRegI dst, memory src1, immI src2, rFlagsReg cr) 8711 %{ 8712 predicate(UseAPX); 8713 match(Set dst (MulI (LoadI src1) src2)); 8714 effect(KILL cr); 8715 8716 ins_cost(300); 8717 format %{ "eimull $dst, $src1, $src2\t# int ndd" %} 8718 ins_encode %{ 8719 __ eimull($dst$$Register, $src1$$Address, $src2$$constant, false); 8720 %} 8721 ins_pipe(ialu_reg_mem_alu0); 8722 %} 8723 8724 instruct mulAddS2I_rReg(rRegI dst, rRegI src1, rRegI src2, rRegI src3, rFlagsReg cr) 8725 %{ 8726 match(Set dst (MulAddS2I (Binary dst src1) (Binary src2 src3))); 8727 effect(KILL cr, KILL src2); 8728 8729 expand %{ mulI_rReg(dst, src1, cr); 8730 mulI_rReg(src2, src3, cr); 8731 addI_rReg(dst, src2, cr); %} 8732 %} 8733 8734 instruct mulL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 8735 %{ 8736 predicate(!UseAPX); 8737 match(Set dst (MulL dst src)); 8738 effect(KILL cr); 8739 8740 ins_cost(300); 8741 format %{ "imulq $dst, $src\t# long" %} 8742 ins_encode %{ 8743 __ imulq($dst$$Register, $src$$Register); 8744 %} 8745 ins_pipe(ialu_reg_reg_alu0); 8746 %} 8747 8748 instruct mulL_rReg_ndd(rRegL dst, rRegL src1, rRegL src2, rFlagsReg cr) 8749 %{ 8750 predicate(UseAPX); 8751 match(Set dst (MulL src1 src2)); 8752 effect(KILL cr); 8753 8754 ins_cost(300); 8755 format %{ "eimulq $dst, $src1, $src2\t# long ndd" %} 8756 ins_encode %{ 8757 __ eimulq($dst$$Register, $src1$$Register, $src2$$Register, false); 8758 %} 8759 ins_pipe(ialu_reg_reg_alu0); 8760 %} 8761 8762 instruct mulL_rReg_imm(rRegL dst, rRegL src, immL32 imm, rFlagsReg cr) 8763 %{ 8764 predicate(!UseAPX); 8765 match(Set dst (MulL src imm)); 8766 effect(KILL cr); 8767 8768 ins_cost(300); 8769 format %{ "imulq $dst, $src, $imm\t# long" %} 8770 ins_encode %{ 8771 __ imulq($dst$$Register, $src$$Register, $imm$$constant); 8772 %} 8773 ins_pipe(ialu_reg_reg_alu0); 8774 %} 8775 8776 instruct mulL_rReg_rReg_imm_ndd(rRegL dst, rRegL src1, immL32 src2, rFlagsReg cr) 8777 %{ 8778 predicate(UseAPX); 8779 match(Set dst (MulL src1 src2)); 8780 effect(KILL cr); 8781 8782 ins_cost(300); 8783 format %{ "eimulq $dst, $src1, $src2\t# long ndd" %} 8784 ins_encode %{ 8785 __ eimulq($dst$$Register, $src1$$Register, $src2$$constant, false); 8786 %} 8787 ins_pipe(ialu_reg_reg_alu0); 8788 %} 8789 8790 instruct mulL_mem(rRegL dst, memory src, rFlagsReg cr) 8791 %{ 8792 predicate(!UseAPX); 8793 match(Set dst (MulL dst (LoadL src))); 8794 effect(KILL cr); 8795 8796 ins_cost(350); 8797 format %{ "imulq $dst, $src\t# long" %} 8798 ins_encode %{ 8799 __ imulq($dst$$Register, $src$$Address); 8800 %} 8801 ins_pipe(ialu_reg_mem_alu0); 8802 %} 8803 8804 instruct mulL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr) 8805 %{ 8806 predicate(UseAPX); 8807 match(Set dst (MulL src1 (LoadL src2))); 8808 effect(KILL cr); 8809 8810 ins_cost(350); 8811 format %{ "eimulq $dst, $src1, $src2 \t# long" %} 8812 ins_encode %{ 8813 __ eimulq($dst$$Register, $src1$$Register, $src2$$Address, false); 8814 %} 8815 ins_pipe(ialu_reg_mem_alu0); 8816 %} 8817 8818 instruct mulL_mem_imm(rRegL dst, memory src, immL32 imm, rFlagsReg cr) 8819 %{ 8820 predicate(!UseAPX); 8821 match(Set dst (MulL (LoadL src) imm)); 8822 effect(KILL cr); 8823 8824 ins_cost(300); 8825 format %{ "imulq $dst, $src, $imm\t# long" %} 8826 ins_encode %{ 8827 __ imulq($dst$$Register, $src$$Address, $imm$$constant); 8828 %} 8829 ins_pipe(ialu_reg_mem_alu0); 8830 %} 8831 8832 instruct mulL_rReg_mem_imm_ndd(rRegL dst, memory src1, immL32 src2, rFlagsReg cr) 8833 %{ 8834 predicate(UseAPX); 8835 match(Set dst (MulL (LoadL src1) src2)); 8836 effect(KILL cr); 8837 8838 ins_cost(300); 8839 format %{ "eimulq $dst, $src1, $src2\t# long ndd" %} 8840 ins_encode %{ 8841 __ eimulq($dst$$Register, $src1$$Address, $src2$$constant, false); 8842 %} 8843 ins_pipe(ialu_reg_mem_alu0); 8844 %} 8845 8846 instruct mulHiL_rReg(rdx_RegL dst, rRegL src, rax_RegL rax, rFlagsReg cr) 8847 %{ 8848 match(Set dst (MulHiL src rax)); 8849 effect(USE_KILL rax, KILL cr); 8850 8851 ins_cost(300); 8852 format %{ "imulq RDX:RAX, RAX, $src\t# mulhi" %} 8853 ins_encode %{ 8854 __ imulq($src$$Register); 8855 %} 8856 ins_pipe(ialu_reg_reg_alu0); 8857 %} 8858 8859 instruct umulHiL_rReg(rdx_RegL dst, rRegL src, rax_RegL rax, rFlagsReg cr) 8860 %{ 8861 match(Set dst (UMulHiL src rax)); 8862 effect(USE_KILL rax, KILL cr); 8863 8864 ins_cost(300); 8865 format %{ "mulq RDX:RAX, RAX, $src\t# umulhi" %} 8866 ins_encode %{ 8867 __ mulq($src$$Register); 8868 %} 8869 ins_pipe(ialu_reg_reg_alu0); 8870 %} 8871 8872 instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 8873 rFlagsReg cr) 8874 %{ 8875 match(Set rax (DivI rax div)); 8876 effect(KILL rdx, KILL cr); 8877 8878 ins_cost(30*100+10*100); // XXX 8879 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 8880 "jne,s normal\n\t" 8881 "xorl rdx, rdx\n\t" 8882 "cmpl $div, -1\n\t" 8883 "je,s done\n" 8884 "normal: cdql\n\t" 8885 "idivl $div\n" 8886 "done:" %} 8887 ins_encode(cdql_enc(div)); 8888 ins_pipe(ialu_reg_reg_alu0); 8889 %} 8890 8891 instruct divL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 8892 rFlagsReg cr) 8893 %{ 8894 match(Set rax (DivL rax div)); 8895 effect(KILL rdx, KILL cr); 8896 8897 ins_cost(30*100+10*100); // XXX 8898 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 8899 "cmpq rax, rdx\n\t" 8900 "jne,s normal\n\t" 8901 "xorl rdx, rdx\n\t" 8902 "cmpq $div, -1\n\t" 8903 "je,s done\n" 8904 "normal: cdqq\n\t" 8905 "idivq $div\n" 8906 "done:" %} 8907 ins_encode(cdqq_enc(div)); 8908 ins_pipe(ialu_reg_reg_alu0); 8909 %} 8910 8911 instruct udivI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, rFlagsReg cr) 8912 %{ 8913 match(Set rax (UDivI rax div)); 8914 effect(KILL rdx, KILL cr); 8915 8916 ins_cost(300); 8917 format %{ "udivl $rax,$rax,$div\t# UDivI\n" %} 8918 ins_encode %{ 8919 __ udivI($rax$$Register, $div$$Register, $rdx$$Register); 8920 %} 8921 ins_pipe(ialu_reg_reg_alu0); 8922 %} 8923 8924 instruct udivL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, rFlagsReg cr) 8925 %{ 8926 match(Set rax (UDivL rax div)); 8927 effect(KILL rdx, KILL cr); 8928 8929 ins_cost(300); 8930 format %{ "udivq $rax,$rax,$div\t# UDivL\n" %} 8931 ins_encode %{ 8932 __ udivL($rax$$Register, $div$$Register, $rdx$$Register); 8933 %} 8934 ins_pipe(ialu_reg_reg_alu0); 8935 %} 8936 8937 // Integer DIVMOD with Register, both quotient and mod results 8938 instruct divModI_rReg_divmod(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 8939 rFlagsReg cr) 8940 %{ 8941 match(DivModI rax div); 8942 effect(KILL cr); 8943 8944 ins_cost(30*100+10*100); // XXX 8945 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 8946 "jne,s normal\n\t" 8947 "xorl rdx, rdx\n\t" 8948 "cmpl $div, -1\n\t" 8949 "je,s done\n" 8950 "normal: cdql\n\t" 8951 "idivl $div\n" 8952 "done:" %} 8953 ins_encode(cdql_enc(div)); 8954 ins_pipe(pipe_slow); 8955 %} 8956 8957 // Long DIVMOD with Register, both quotient and mod results 8958 instruct divModL_rReg_divmod(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 8959 rFlagsReg cr) 8960 %{ 8961 match(DivModL rax div); 8962 effect(KILL cr); 8963 8964 ins_cost(30*100+10*100); // XXX 8965 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 8966 "cmpq rax, rdx\n\t" 8967 "jne,s normal\n\t" 8968 "xorl rdx, rdx\n\t" 8969 "cmpq $div, -1\n\t" 8970 "je,s done\n" 8971 "normal: cdqq\n\t" 8972 "idivq $div\n" 8973 "done:" %} 8974 ins_encode(cdqq_enc(div)); 8975 ins_pipe(pipe_slow); 8976 %} 8977 8978 // Unsigned integer DIVMOD with Register, both quotient and mod results 8979 instruct udivModI_rReg_divmod(rax_RegI rax, no_rax_rdx_RegI tmp, rdx_RegI rdx, 8980 no_rax_rdx_RegI div, rFlagsReg cr) 8981 %{ 8982 match(UDivModI rax div); 8983 effect(TEMP tmp, KILL cr); 8984 8985 ins_cost(300); 8986 format %{ "udivl $rax,$rax,$div\t# begin UDivModI\n\t" 8987 "umodl $rdx,$rax,$div\t! using $tmp as TEMP # end UDivModI\n" 8988 %} 8989 ins_encode %{ 8990 __ udivmodI($rax$$Register, $div$$Register, $rdx$$Register, $tmp$$Register); 8991 %} 8992 ins_pipe(pipe_slow); 8993 %} 8994 8995 // Unsigned long DIVMOD with Register, both quotient and mod results 8996 instruct udivModL_rReg_divmod(rax_RegL rax, no_rax_rdx_RegL tmp, rdx_RegL rdx, 8997 no_rax_rdx_RegL div, rFlagsReg cr) 8998 %{ 8999 match(UDivModL rax div); 9000 effect(TEMP tmp, KILL cr); 9001 9002 ins_cost(300); 9003 format %{ "udivq $rax,$rax,$div\t# begin UDivModL\n\t" 9004 "umodq $rdx,$rax,$div\t! using $tmp as TEMP # end UDivModL\n" 9005 %} 9006 ins_encode %{ 9007 __ udivmodL($rax$$Register, $div$$Register, $rdx$$Register, $tmp$$Register); 9008 %} 9009 ins_pipe(pipe_slow); 9010 %} 9011 9012 instruct modI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, 9013 rFlagsReg cr) 9014 %{ 9015 match(Set rdx (ModI rax div)); 9016 effect(KILL rax, KILL cr); 9017 9018 ins_cost(300); // XXX 9019 format %{ "cmpl rax, 0x80000000\t# irem\n\t" 9020 "jne,s normal\n\t" 9021 "xorl rdx, rdx\n\t" 9022 "cmpl $div, -1\n\t" 9023 "je,s done\n" 9024 "normal: cdql\n\t" 9025 "idivl $div\n" 9026 "done:" %} 9027 ins_encode(cdql_enc(div)); 9028 ins_pipe(ialu_reg_reg_alu0); 9029 %} 9030 9031 instruct modL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, 9032 rFlagsReg cr) 9033 %{ 9034 match(Set rdx (ModL rax div)); 9035 effect(KILL rax, KILL cr); 9036 9037 ins_cost(300); // XXX 9038 format %{ "movq rdx, 0x8000000000000000\t# lrem\n\t" 9039 "cmpq rax, rdx\n\t" 9040 "jne,s normal\n\t" 9041 "xorl rdx, rdx\n\t" 9042 "cmpq $div, -1\n\t" 9043 "je,s done\n" 9044 "normal: cdqq\n\t" 9045 "idivq $div\n" 9046 "done:" %} 9047 ins_encode(cdqq_enc(div)); 9048 ins_pipe(ialu_reg_reg_alu0); 9049 %} 9050 9051 instruct umodI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, rFlagsReg cr) 9052 %{ 9053 match(Set rdx (UModI rax div)); 9054 effect(KILL rax, KILL cr); 9055 9056 ins_cost(300); 9057 format %{ "umodl $rdx,$rax,$div\t# UModI\n" %} 9058 ins_encode %{ 9059 __ umodI($rax$$Register, $div$$Register, $rdx$$Register); 9060 %} 9061 ins_pipe(ialu_reg_reg_alu0); 9062 %} 9063 9064 instruct umodL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, rFlagsReg cr) 9065 %{ 9066 match(Set rdx (UModL rax div)); 9067 effect(KILL rax, KILL cr); 9068 9069 ins_cost(300); 9070 format %{ "umodq $rdx,$rax,$div\t# UModL\n" %} 9071 ins_encode %{ 9072 __ umodL($rax$$Register, $div$$Register, $rdx$$Register); 9073 %} 9074 ins_pipe(ialu_reg_reg_alu0); 9075 %} 9076 9077 // Integer Shift Instructions 9078 // Shift Left by one, two, three 9079 instruct salI_rReg_immI2(rRegI dst, immI2 shift, rFlagsReg cr) 9080 %{ 9081 predicate(!UseAPX); 9082 match(Set dst (LShiftI dst shift)); 9083 effect(KILL cr); 9084 9085 format %{ "sall $dst, $shift" %} 9086 ins_encode %{ 9087 __ sall($dst$$Register, $shift$$constant); 9088 %} 9089 ins_pipe(ialu_reg); 9090 %} 9091 9092 // Shift Left by one, two, three 9093 instruct salI_rReg_immI2_ndd(rRegI dst, rRegI src, immI2 shift, rFlagsReg cr) 9094 %{ 9095 predicate(UseAPX); 9096 match(Set dst (LShiftI src shift)); 9097 effect(KILL cr); 9098 9099 format %{ "esall $dst, $src, $shift\t# int(ndd)" %} 9100 ins_encode %{ 9101 __ esall($dst$$Register, $src$$Register, $shift$$constant, false); 9102 %} 9103 ins_pipe(ialu_reg); 9104 %} 9105 9106 // Shift Left by 8-bit immediate 9107 instruct salI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 9108 %{ 9109 predicate(!UseAPX); 9110 match(Set dst (LShiftI dst shift)); 9111 effect(KILL cr); 9112 9113 format %{ "sall $dst, $shift" %} 9114 ins_encode %{ 9115 __ sall($dst$$Register, $shift$$constant); 9116 %} 9117 ins_pipe(ialu_reg); 9118 %} 9119 9120 // Shift Left by 8-bit immediate 9121 instruct salI_rReg_imm_ndd(rRegI dst, rRegI src, immI8 shift, rFlagsReg cr) 9122 %{ 9123 predicate(UseAPX); 9124 match(Set dst (LShiftI src shift)); 9125 effect(KILL cr); 9126 9127 format %{ "esall $dst, $src, $shift\t# int (ndd)" %} 9128 ins_encode %{ 9129 __ esall($dst$$Register, $src$$Register, $shift$$constant, false); 9130 %} 9131 ins_pipe(ialu_reg); 9132 %} 9133 9134 instruct salI_rReg_mem_imm_ndd(rRegI dst, memory src, immI8 shift, rFlagsReg cr) 9135 %{ 9136 predicate(UseAPX); 9137 match(Set dst (LShiftI (LoadI src) shift)); 9138 effect(KILL cr); 9139 9140 format %{ "esall $dst, $src, $shift\t# int (ndd)" %} 9141 ins_encode %{ 9142 __ esall($dst$$Register, $src$$Address, $shift$$constant, false); 9143 %} 9144 ins_pipe(ialu_reg); 9145 %} 9146 9147 // Shift Left by 8-bit immediate 9148 instruct salI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 9149 %{ 9150 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 9151 effect(KILL cr); 9152 9153 format %{ "sall $dst, $shift" %} 9154 ins_encode %{ 9155 __ sall($dst$$Address, $shift$$constant); 9156 %} 9157 ins_pipe(ialu_mem_imm); 9158 %} 9159 9160 // Shift Left by variable 9161 instruct salI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 9162 %{ 9163 predicate(!VM_Version::supports_bmi2()); 9164 match(Set dst (LShiftI dst shift)); 9165 effect(KILL cr); 9166 9167 format %{ "sall $dst, $shift" %} 9168 ins_encode %{ 9169 __ sall($dst$$Register); 9170 %} 9171 ins_pipe(ialu_reg_reg); 9172 %} 9173 9174 // Shift Left by variable 9175 instruct salI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 9176 %{ 9177 predicate(!VM_Version::supports_bmi2()); 9178 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 9179 effect(KILL cr); 9180 9181 format %{ "sall $dst, $shift" %} 9182 ins_encode %{ 9183 __ sall($dst$$Address); 9184 %} 9185 ins_pipe(ialu_mem_reg); 9186 %} 9187 9188 instruct salI_rReg_rReg(rRegI dst, rRegI src, rRegI shift) 9189 %{ 9190 predicate(VM_Version::supports_bmi2()); 9191 match(Set dst (LShiftI src shift)); 9192 9193 format %{ "shlxl $dst, $src, $shift" %} 9194 ins_encode %{ 9195 __ shlxl($dst$$Register, $src$$Register, $shift$$Register); 9196 %} 9197 ins_pipe(ialu_reg_reg); 9198 %} 9199 9200 instruct salI_mem_rReg(rRegI dst, memory src, rRegI shift) 9201 %{ 9202 predicate(VM_Version::supports_bmi2()); 9203 match(Set dst (LShiftI (LoadI src) shift)); 9204 ins_cost(175); 9205 format %{ "shlxl $dst, $src, $shift" %} 9206 ins_encode %{ 9207 __ shlxl($dst$$Register, $src$$Address, $shift$$Register); 9208 %} 9209 ins_pipe(ialu_reg_mem); 9210 %} 9211 9212 // Arithmetic Shift Right by 8-bit immediate 9213 instruct sarI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 9214 %{ 9215 predicate(!UseAPX); 9216 match(Set dst (RShiftI dst shift)); 9217 effect(KILL cr); 9218 9219 format %{ "sarl $dst, $shift" %} 9220 ins_encode %{ 9221 __ sarl($dst$$Register, $shift$$constant); 9222 %} 9223 ins_pipe(ialu_mem_imm); 9224 %} 9225 9226 // Arithmetic Shift Right by 8-bit immediate 9227 instruct sarI_rReg_imm_ndd(rRegI dst, rRegI src, immI8 shift, rFlagsReg cr) 9228 %{ 9229 predicate(UseAPX); 9230 match(Set dst (RShiftI src shift)); 9231 effect(KILL cr); 9232 9233 format %{ "esarl $dst, $src, $shift\t# int (ndd)" %} 9234 ins_encode %{ 9235 __ esarl($dst$$Register, $src$$Register, $shift$$constant, false); 9236 %} 9237 ins_pipe(ialu_mem_imm); 9238 %} 9239 9240 instruct sarI_rReg_mem_imm_ndd(rRegI dst, memory src, immI8 shift, rFlagsReg cr) 9241 %{ 9242 predicate(UseAPX); 9243 match(Set dst (RShiftI (LoadI src) shift)); 9244 effect(KILL cr); 9245 9246 format %{ "esarl $dst, $src, $shift\t# int (ndd)" %} 9247 ins_encode %{ 9248 __ esarl($dst$$Register, $src$$Address, $shift$$constant, false); 9249 %} 9250 ins_pipe(ialu_mem_imm); 9251 %} 9252 9253 // Arithmetic Shift Right by 8-bit immediate 9254 instruct sarI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 9255 %{ 9256 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 9257 effect(KILL cr); 9258 9259 format %{ "sarl $dst, $shift" %} 9260 ins_encode %{ 9261 __ sarl($dst$$Address, $shift$$constant); 9262 %} 9263 ins_pipe(ialu_mem_imm); 9264 %} 9265 9266 // Arithmetic Shift Right by variable 9267 instruct sarI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 9268 %{ 9269 predicate(!VM_Version::supports_bmi2()); 9270 match(Set dst (RShiftI dst shift)); 9271 effect(KILL cr); 9272 9273 format %{ "sarl $dst, $shift" %} 9274 ins_encode %{ 9275 __ sarl($dst$$Register); 9276 %} 9277 ins_pipe(ialu_reg_reg); 9278 %} 9279 9280 // Arithmetic Shift Right by variable 9281 instruct sarI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 9282 %{ 9283 predicate(!VM_Version::supports_bmi2()); 9284 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 9285 effect(KILL cr); 9286 9287 format %{ "sarl $dst, $shift" %} 9288 ins_encode %{ 9289 __ sarl($dst$$Address); 9290 %} 9291 ins_pipe(ialu_mem_reg); 9292 %} 9293 9294 instruct sarI_rReg_rReg(rRegI dst, rRegI src, rRegI shift) 9295 %{ 9296 predicate(VM_Version::supports_bmi2()); 9297 match(Set dst (RShiftI src shift)); 9298 9299 format %{ "sarxl $dst, $src, $shift" %} 9300 ins_encode %{ 9301 __ sarxl($dst$$Register, $src$$Register, $shift$$Register); 9302 %} 9303 ins_pipe(ialu_reg_reg); 9304 %} 9305 9306 instruct sarI_mem_rReg(rRegI dst, memory src, rRegI shift) 9307 %{ 9308 predicate(VM_Version::supports_bmi2()); 9309 match(Set dst (RShiftI (LoadI src) shift)); 9310 ins_cost(175); 9311 format %{ "sarxl $dst, $src, $shift" %} 9312 ins_encode %{ 9313 __ sarxl($dst$$Register, $src$$Address, $shift$$Register); 9314 %} 9315 ins_pipe(ialu_reg_mem); 9316 %} 9317 9318 // Logical Shift Right by 8-bit immediate 9319 instruct shrI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 9320 %{ 9321 predicate(!UseAPX); 9322 match(Set dst (URShiftI dst shift)); 9323 effect(KILL cr); 9324 9325 format %{ "shrl $dst, $shift" %} 9326 ins_encode %{ 9327 __ shrl($dst$$Register, $shift$$constant); 9328 %} 9329 ins_pipe(ialu_reg); 9330 %} 9331 9332 // Logical Shift Right by 8-bit immediate 9333 instruct shrI_rReg_imm_ndd(rRegI dst, rRegI src, immI8 shift, rFlagsReg cr) 9334 %{ 9335 predicate(UseAPX); 9336 match(Set dst (URShiftI src shift)); 9337 effect(KILL cr); 9338 9339 format %{ "eshrl $dst, $src, $shift\t # int (ndd)" %} 9340 ins_encode %{ 9341 __ eshrl($dst$$Register, $src$$Register, $shift$$constant, false); 9342 %} 9343 ins_pipe(ialu_reg); 9344 %} 9345 9346 instruct shrI_rReg_mem_imm_ndd(rRegI dst, memory src, immI8 shift, rFlagsReg cr) 9347 %{ 9348 predicate(UseAPX); 9349 match(Set dst (URShiftI (LoadI src) shift)); 9350 effect(KILL cr); 9351 9352 format %{ "eshrl $dst, $src, $shift\t # int (ndd)" %} 9353 ins_encode %{ 9354 __ eshrl($dst$$Register, $src$$Address, $shift$$constant, false); 9355 %} 9356 ins_pipe(ialu_reg); 9357 %} 9358 9359 // Logical Shift Right by 8-bit immediate 9360 instruct shrI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 9361 %{ 9362 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 9363 effect(KILL cr); 9364 9365 format %{ "shrl $dst, $shift" %} 9366 ins_encode %{ 9367 __ shrl($dst$$Address, $shift$$constant); 9368 %} 9369 ins_pipe(ialu_mem_imm); 9370 %} 9371 9372 // Logical Shift Right by variable 9373 instruct shrI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 9374 %{ 9375 predicate(!VM_Version::supports_bmi2()); 9376 match(Set dst (URShiftI dst shift)); 9377 effect(KILL cr); 9378 9379 format %{ "shrl $dst, $shift" %} 9380 ins_encode %{ 9381 __ shrl($dst$$Register); 9382 %} 9383 ins_pipe(ialu_reg_reg); 9384 %} 9385 9386 // Logical Shift Right by variable 9387 instruct shrI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 9388 %{ 9389 predicate(!VM_Version::supports_bmi2()); 9390 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 9391 effect(KILL cr); 9392 9393 format %{ "shrl $dst, $shift" %} 9394 ins_encode %{ 9395 __ shrl($dst$$Address); 9396 %} 9397 ins_pipe(ialu_mem_reg); 9398 %} 9399 9400 instruct shrI_rReg_rReg(rRegI dst, rRegI src, rRegI shift) 9401 %{ 9402 predicate(VM_Version::supports_bmi2()); 9403 match(Set dst (URShiftI src shift)); 9404 9405 format %{ "shrxl $dst, $src, $shift" %} 9406 ins_encode %{ 9407 __ shrxl($dst$$Register, $src$$Register, $shift$$Register); 9408 %} 9409 ins_pipe(ialu_reg_reg); 9410 %} 9411 9412 instruct shrI_mem_rReg(rRegI dst, memory src, rRegI shift) 9413 %{ 9414 predicate(VM_Version::supports_bmi2()); 9415 match(Set dst (URShiftI (LoadI src) shift)); 9416 ins_cost(175); 9417 format %{ "shrxl $dst, $src, $shift" %} 9418 ins_encode %{ 9419 __ shrxl($dst$$Register, $src$$Address, $shift$$Register); 9420 %} 9421 ins_pipe(ialu_reg_mem); 9422 %} 9423 9424 // Long Shift Instructions 9425 // Shift Left by one, two, three 9426 instruct salL_rReg_immI2(rRegL dst, immI2 shift, rFlagsReg cr) 9427 %{ 9428 predicate(!UseAPX); 9429 match(Set dst (LShiftL dst shift)); 9430 effect(KILL cr); 9431 9432 format %{ "salq $dst, $shift" %} 9433 ins_encode %{ 9434 __ salq($dst$$Register, $shift$$constant); 9435 %} 9436 ins_pipe(ialu_reg); 9437 %} 9438 9439 // Shift Left by one, two, three 9440 instruct salL_rReg_immI2_ndd(rRegL dst, rRegL src, immI2 shift, rFlagsReg cr) 9441 %{ 9442 predicate(UseAPX); 9443 match(Set dst (LShiftL src shift)); 9444 effect(KILL cr); 9445 9446 format %{ "esalq $dst, $src, $shift\t# long (ndd)" %} 9447 ins_encode %{ 9448 __ esalq($dst$$Register, $src$$Register, $shift$$constant, false); 9449 %} 9450 ins_pipe(ialu_reg); 9451 %} 9452 9453 // Shift Left by 8-bit immediate 9454 instruct salL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 9455 %{ 9456 predicate(!UseAPX); 9457 match(Set dst (LShiftL dst shift)); 9458 effect(KILL cr); 9459 9460 format %{ "salq $dst, $shift" %} 9461 ins_encode %{ 9462 __ salq($dst$$Register, $shift$$constant); 9463 %} 9464 ins_pipe(ialu_reg); 9465 %} 9466 9467 // Shift Left by 8-bit immediate 9468 instruct salL_rReg_imm_ndd(rRegL dst, rRegL src, immI8 shift, rFlagsReg cr) 9469 %{ 9470 predicate(UseAPX); 9471 match(Set dst (LShiftL src shift)); 9472 effect(KILL cr); 9473 9474 format %{ "esalq $dst, $src, $shift\t# long (ndd)" %} 9475 ins_encode %{ 9476 __ esalq($dst$$Register, $src$$Register, $shift$$constant, false); 9477 %} 9478 ins_pipe(ialu_reg); 9479 %} 9480 9481 instruct salL_rReg_mem_imm_ndd(rRegL dst, memory src, immI8 shift, rFlagsReg cr) 9482 %{ 9483 predicate(UseAPX); 9484 match(Set dst (LShiftL (LoadL src) shift)); 9485 effect(KILL cr); 9486 9487 format %{ "esalq $dst, $src, $shift\t# long (ndd)" %} 9488 ins_encode %{ 9489 __ esalq($dst$$Register, $src$$Address, $shift$$constant, false); 9490 %} 9491 ins_pipe(ialu_reg); 9492 %} 9493 9494 // Shift Left by 8-bit immediate 9495 instruct salL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 9496 %{ 9497 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 9498 effect(KILL cr); 9499 9500 format %{ "salq $dst, $shift" %} 9501 ins_encode %{ 9502 __ salq($dst$$Address, $shift$$constant); 9503 %} 9504 ins_pipe(ialu_mem_imm); 9505 %} 9506 9507 // Shift Left by variable 9508 instruct salL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 9509 %{ 9510 predicate(!VM_Version::supports_bmi2()); 9511 match(Set dst (LShiftL dst shift)); 9512 effect(KILL cr); 9513 9514 format %{ "salq $dst, $shift" %} 9515 ins_encode %{ 9516 __ salq($dst$$Register); 9517 %} 9518 ins_pipe(ialu_reg_reg); 9519 %} 9520 9521 // Shift Left by variable 9522 instruct salL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 9523 %{ 9524 predicate(!VM_Version::supports_bmi2()); 9525 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 9526 effect(KILL cr); 9527 9528 format %{ "salq $dst, $shift" %} 9529 ins_encode %{ 9530 __ salq($dst$$Address); 9531 %} 9532 ins_pipe(ialu_mem_reg); 9533 %} 9534 9535 instruct salL_rReg_rReg(rRegL dst, rRegL src, rRegI shift) 9536 %{ 9537 predicate(VM_Version::supports_bmi2()); 9538 match(Set dst (LShiftL src shift)); 9539 9540 format %{ "shlxq $dst, $src, $shift" %} 9541 ins_encode %{ 9542 __ shlxq($dst$$Register, $src$$Register, $shift$$Register); 9543 %} 9544 ins_pipe(ialu_reg_reg); 9545 %} 9546 9547 instruct salL_mem_rReg(rRegL dst, memory src, rRegI shift) 9548 %{ 9549 predicate(VM_Version::supports_bmi2()); 9550 match(Set dst (LShiftL (LoadL src) shift)); 9551 ins_cost(175); 9552 format %{ "shlxq $dst, $src, $shift" %} 9553 ins_encode %{ 9554 __ shlxq($dst$$Register, $src$$Address, $shift$$Register); 9555 %} 9556 ins_pipe(ialu_reg_mem); 9557 %} 9558 9559 // Arithmetic Shift Right by 8-bit immediate 9560 instruct sarL_rReg_imm(rRegL dst, immI shift, rFlagsReg cr) 9561 %{ 9562 predicate(!UseAPX); 9563 match(Set dst (RShiftL dst shift)); 9564 effect(KILL cr); 9565 9566 format %{ "sarq $dst, $shift" %} 9567 ins_encode %{ 9568 __ sarq($dst$$Register, (unsigned char)($shift$$constant & 0x3F)); 9569 %} 9570 ins_pipe(ialu_mem_imm); 9571 %} 9572 9573 // Arithmetic Shift Right by 8-bit immediate 9574 instruct sarL_rReg_imm_ndd(rRegL dst, rRegL src, immI shift, rFlagsReg cr) 9575 %{ 9576 predicate(UseAPX); 9577 match(Set dst (RShiftL src shift)); 9578 effect(KILL cr); 9579 9580 format %{ "esarq $dst, $src, $shift\t# long (ndd)" %} 9581 ins_encode %{ 9582 __ esarq($dst$$Register, $src$$Register, (unsigned char)($shift$$constant & 0x3F), false); 9583 %} 9584 ins_pipe(ialu_mem_imm); 9585 %} 9586 9587 instruct sarL_rReg_mem_imm_ndd(rRegL dst, memory src, immI shift, rFlagsReg cr) 9588 %{ 9589 predicate(UseAPX); 9590 match(Set dst (RShiftL (LoadL src) shift)); 9591 effect(KILL cr); 9592 9593 format %{ "esarq $dst, $src, $shift\t# long (ndd)" %} 9594 ins_encode %{ 9595 __ esarq($dst$$Register, $src$$Address, (unsigned char)($shift$$constant & 0x3F), false); 9596 %} 9597 ins_pipe(ialu_mem_imm); 9598 %} 9599 9600 // Arithmetic Shift Right by 8-bit immediate 9601 instruct sarL_mem_imm(memory dst, immI shift, rFlagsReg cr) 9602 %{ 9603 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 9604 effect(KILL cr); 9605 9606 format %{ "sarq $dst, $shift" %} 9607 ins_encode %{ 9608 __ sarq($dst$$Address, (unsigned char)($shift$$constant & 0x3F)); 9609 %} 9610 ins_pipe(ialu_mem_imm); 9611 %} 9612 9613 // Arithmetic Shift Right by variable 9614 instruct sarL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 9615 %{ 9616 predicate(!VM_Version::supports_bmi2()); 9617 match(Set dst (RShiftL dst shift)); 9618 effect(KILL cr); 9619 9620 format %{ "sarq $dst, $shift" %} 9621 ins_encode %{ 9622 __ sarq($dst$$Register); 9623 %} 9624 ins_pipe(ialu_reg_reg); 9625 %} 9626 9627 // Arithmetic Shift Right by variable 9628 instruct sarL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 9629 %{ 9630 predicate(!VM_Version::supports_bmi2()); 9631 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 9632 effect(KILL cr); 9633 9634 format %{ "sarq $dst, $shift" %} 9635 ins_encode %{ 9636 __ sarq($dst$$Address); 9637 %} 9638 ins_pipe(ialu_mem_reg); 9639 %} 9640 9641 instruct sarL_rReg_rReg(rRegL dst, rRegL src, rRegI shift) 9642 %{ 9643 predicate(VM_Version::supports_bmi2()); 9644 match(Set dst (RShiftL src shift)); 9645 9646 format %{ "sarxq $dst, $src, $shift" %} 9647 ins_encode %{ 9648 __ sarxq($dst$$Register, $src$$Register, $shift$$Register); 9649 %} 9650 ins_pipe(ialu_reg_reg); 9651 %} 9652 9653 instruct sarL_mem_rReg(rRegL dst, memory src, rRegI shift) 9654 %{ 9655 predicate(VM_Version::supports_bmi2()); 9656 match(Set dst (RShiftL (LoadL src) shift)); 9657 ins_cost(175); 9658 format %{ "sarxq $dst, $src, $shift" %} 9659 ins_encode %{ 9660 __ sarxq($dst$$Register, $src$$Address, $shift$$Register); 9661 %} 9662 ins_pipe(ialu_reg_mem); 9663 %} 9664 9665 // Logical Shift Right by 8-bit immediate 9666 instruct shrL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 9667 %{ 9668 predicate(!UseAPX); 9669 match(Set dst (URShiftL dst shift)); 9670 effect(KILL cr); 9671 9672 format %{ "shrq $dst, $shift" %} 9673 ins_encode %{ 9674 __ shrq($dst$$Register, $shift$$constant); 9675 %} 9676 ins_pipe(ialu_reg); 9677 %} 9678 9679 // Logical Shift Right by 8-bit immediate 9680 instruct shrL_rReg_imm_ndd(rRegL dst, rRegL src, immI8 shift, rFlagsReg cr) 9681 %{ 9682 predicate(UseAPX); 9683 match(Set dst (URShiftL src shift)); 9684 effect(KILL cr); 9685 9686 format %{ "eshrq $dst, $src, $shift\t# long (ndd)" %} 9687 ins_encode %{ 9688 __ eshrq($dst$$Register, $src$$Register, $shift$$constant, false); 9689 %} 9690 ins_pipe(ialu_reg); 9691 %} 9692 9693 instruct shrL_rReg_mem_imm_ndd(rRegL dst, memory src, immI8 shift, rFlagsReg cr) 9694 %{ 9695 predicate(UseAPX); 9696 match(Set dst (URShiftL (LoadL src) shift)); 9697 effect(KILL cr); 9698 9699 format %{ "eshrq $dst, $src, $shift\t# long (ndd)" %} 9700 ins_encode %{ 9701 __ eshrq($dst$$Register, $src$$Address, $shift$$constant, false); 9702 %} 9703 ins_pipe(ialu_reg); 9704 %} 9705 9706 // Logical Shift Right by 8-bit immediate 9707 instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 9708 %{ 9709 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 9710 effect(KILL cr); 9711 9712 format %{ "shrq $dst, $shift" %} 9713 ins_encode %{ 9714 __ shrq($dst$$Address, $shift$$constant); 9715 %} 9716 ins_pipe(ialu_mem_imm); 9717 %} 9718 9719 // Logical Shift Right by variable 9720 instruct shrL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 9721 %{ 9722 predicate(!VM_Version::supports_bmi2()); 9723 match(Set dst (URShiftL dst shift)); 9724 effect(KILL cr); 9725 9726 format %{ "shrq $dst, $shift" %} 9727 ins_encode %{ 9728 __ shrq($dst$$Register); 9729 %} 9730 ins_pipe(ialu_reg_reg); 9731 %} 9732 9733 // Logical Shift Right by variable 9734 instruct shrL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 9735 %{ 9736 predicate(!VM_Version::supports_bmi2()); 9737 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 9738 effect(KILL cr); 9739 9740 format %{ "shrq $dst, $shift" %} 9741 ins_encode %{ 9742 __ shrq($dst$$Address); 9743 %} 9744 ins_pipe(ialu_mem_reg); 9745 %} 9746 9747 instruct shrL_rReg_rReg(rRegL dst, rRegL src, rRegI shift) 9748 %{ 9749 predicate(VM_Version::supports_bmi2()); 9750 match(Set dst (URShiftL src shift)); 9751 9752 format %{ "shrxq $dst, $src, $shift" %} 9753 ins_encode %{ 9754 __ shrxq($dst$$Register, $src$$Register, $shift$$Register); 9755 %} 9756 ins_pipe(ialu_reg_reg); 9757 %} 9758 9759 instruct shrL_mem_rReg(rRegL dst, memory src, rRegI shift) 9760 %{ 9761 predicate(VM_Version::supports_bmi2()); 9762 match(Set dst (URShiftL (LoadL src) shift)); 9763 ins_cost(175); 9764 format %{ "shrxq $dst, $src, $shift" %} 9765 ins_encode %{ 9766 __ shrxq($dst$$Register, $src$$Address, $shift$$Register); 9767 %} 9768 ins_pipe(ialu_reg_mem); 9769 %} 9770 9771 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24. 9772 // This idiom is used by the compiler for the i2b bytecode. 9773 instruct i2b(rRegI dst, rRegI src, immI_24 twentyfour) 9774 %{ 9775 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour)); 9776 9777 format %{ "movsbl $dst, $src\t# i2b" %} 9778 ins_encode %{ 9779 __ movsbl($dst$$Register, $src$$Register); 9780 %} 9781 ins_pipe(ialu_reg_reg); 9782 %} 9783 9784 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16. 9785 // This idiom is used by the compiler the i2s bytecode. 9786 instruct i2s(rRegI dst, rRegI src, immI_16 sixteen) 9787 %{ 9788 match(Set dst (RShiftI (LShiftI src sixteen) sixteen)); 9789 9790 format %{ "movswl $dst, $src\t# i2s" %} 9791 ins_encode %{ 9792 __ movswl($dst$$Register, $src$$Register); 9793 %} 9794 ins_pipe(ialu_reg_reg); 9795 %} 9796 9797 // ROL/ROR instructions 9798 9799 // Rotate left by constant. 9800 instruct rolI_immI8_legacy(rRegI dst, immI8 shift, rFlagsReg cr) 9801 %{ 9802 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 9803 match(Set dst (RotateLeft dst shift)); 9804 effect(KILL cr); 9805 format %{ "roll $dst, $shift" %} 9806 ins_encode %{ 9807 __ roll($dst$$Register, $shift$$constant); 9808 %} 9809 ins_pipe(ialu_reg); 9810 %} 9811 9812 instruct rolI_immI8(rRegI dst, rRegI src, immI8 shift) 9813 %{ 9814 predicate(!UseAPX && VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 9815 match(Set dst (RotateLeft src shift)); 9816 format %{ "rolxl $dst, $src, $shift" %} 9817 ins_encode %{ 9818 int shift = 32 - ($shift$$constant & 31); 9819 __ rorxl($dst$$Register, $src$$Register, shift); 9820 %} 9821 ins_pipe(ialu_reg_reg); 9822 %} 9823 9824 instruct rolI_mem_immI8(rRegI dst, memory src, immI8 shift) 9825 %{ 9826 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 9827 match(Set dst (RotateLeft (LoadI src) shift)); 9828 ins_cost(175); 9829 format %{ "rolxl $dst, $src, $shift" %} 9830 ins_encode %{ 9831 int shift = 32 - ($shift$$constant & 31); 9832 __ rorxl($dst$$Register, $src$$Address, shift); 9833 %} 9834 ins_pipe(ialu_reg_mem); 9835 %} 9836 9837 // Rotate Left by variable 9838 instruct rolI_rReg_Var(rRegI dst, rcx_RegI shift, rFlagsReg cr) 9839 %{ 9840 predicate(!UseAPX && n->bottom_type()->basic_type() == T_INT); 9841 match(Set dst (RotateLeft dst shift)); 9842 effect(KILL cr); 9843 format %{ "roll $dst, $shift" %} 9844 ins_encode %{ 9845 __ roll($dst$$Register); 9846 %} 9847 ins_pipe(ialu_reg_reg); 9848 %} 9849 9850 // Rotate Left by variable 9851 instruct rolI_rReg_Var_ndd(rRegI dst, rRegI src, rcx_RegI shift, rFlagsReg cr) 9852 %{ 9853 predicate(UseAPX && n->bottom_type()->basic_type() == T_INT); 9854 match(Set dst (RotateLeft src shift)); 9855 effect(KILL cr); 9856 9857 format %{ "eroll $dst, $src, $shift\t# rotate left (int ndd)" %} 9858 ins_encode %{ 9859 __ eroll($dst$$Register, $src$$Register, false); 9860 %} 9861 ins_pipe(ialu_reg_reg); 9862 %} 9863 9864 // Rotate Right by constant. 9865 instruct rorI_immI8_legacy(rRegI dst, immI8 shift, rFlagsReg cr) 9866 %{ 9867 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 9868 match(Set dst (RotateRight dst shift)); 9869 effect(KILL cr); 9870 format %{ "rorl $dst, $shift" %} 9871 ins_encode %{ 9872 __ rorl($dst$$Register, $shift$$constant); 9873 %} 9874 ins_pipe(ialu_reg); 9875 %} 9876 9877 // Rotate Right by constant. 9878 instruct rorI_immI8(rRegI dst, rRegI src, immI8 shift) 9879 %{ 9880 predicate(!UseAPX && VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 9881 match(Set dst (RotateRight src shift)); 9882 format %{ "rorxl $dst, $src, $shift" %} 9883 ins_encode %{ 9884 __ rorxl($dst$$Register, $src$$Register, $shift$$constant); 9885 %} 9886 ins_pipe(ialu_reg_reg); 9887 %} 9888 9889 instruct rorI_mem_immI8(rRegI dst, memory src, immI8 shift) 9890 %{ 9891 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 9892 match(Set dst (RotateRight (LoadI src) shift)); 9893 ins_cost(175); 9894 format %{ "rorxl $dst, $src, $shift" %} 9895 ins_encode %{ 9896 __ rorxl($dst$$Register, $src$$Address, $shift$$constant); 9897 %} 9898 ins_pipe(ialu_reg_mem); 9899 %} 9900 9901 // Rotate Right by variable 9902 instruct rorI_rReg_Var(rRegI dst, rcx_RegI shift, rFlagsReg cr) 9903 %{ 9904 predicate(!UseAPX && n->bottom_type()->basic_type() == T_INT); 9905 match(Set dst (RotateRight dst shift)); 9906 effect(KILL cr); 9907 format %{ "rorl $dst, $shift" %} 9908 ins_encode %{ 9909 __ rorl($dst$$Register); 9910 %} 9911 ins_pipe(ialu_reg_reg); 9912 %} 9913 9914 // Rotate Right by variable 9915 instruct rorI_rReg_Var_ndd(rRegI dst, rRegI src, rcx_RegI shift, rFlagsReg cr) 9916 %{ 9917 predicate(UseAPX && n->bottom_type()->basic_type() == T_INT); 9918 match(Set dst (RotateRight src shift)); 9919 effect(KILL cr); 9920 9921 format %{ "erorl $dst, $src, $shift\t# rotate right(int ndd)" %} 9922 ins_encode %{ 9923 __ erorl($dst$$Register, $src$$Register, false); 9924 %} 9925 ins_pipe(ialu_reg_reg); 9926 %} 9927 9928 // Rotate Left by constant. 9929 instruct rolL_immI8_legacy(rRegL dst, immI8 shift, rFlagsReg cr) 9930 %{ 9931 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 9932 match(Set dst (RotateLeft dst shift)); 9933 effect(KILL cr); 9934 format %{ "rolq $dst, $shift" %} 9935 ins_encode %{ 9936 __ rolq($dst$$Register, $shift$$constant); 9937 %} 9938 ins_pipe(ialu_reg); 9939 %} 9940 9941 instruct rolL_immI8(rRegL dst, rRegL src, immI8 shift) 9942 %{ 9943 predicate(!UseAPX && VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 9944 match(Set dst (RotateLeft src shift)); 9945 format %{ "rolxq $dst, $src, $shift" %} 9946 ins_encode %{ 9947 int shift = 64 - ($shift$$constant & 63); 9948 __ rorxq($dst$$Register, $src$$Register, shift); 9949 %} 9950 ins_pipe(ialu_reg_reg); 9951 %} 9952 9953 instruct rolL_mem_immI8(rRegL dst, memory src, immI8 shift) 9954 %{ 9955 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 9956 match(Set dst (RotateLeft (LoadL src) shift)); 9957 ins_cost(175); 9958 format %{ "rolxq $dst, $src, $shift" %} 9959 ins_encode %{ 9960 int shift = 64 - ($shift$$constant & 63); 9961 __ rorxq($dst$$Register, $src$$Address, shift); 9962 %} 9963 ins_pipe(ialu_reg_mem); 9964 %} 9965 9966 // Rotate Left by variable 9967 instruct rolL_rReg_Var(rRegL dst, rcx_RegI shift, rFlagsReg cr) 9968 %{ 9969 predicate(!UseAPX && n->bottom_type()->basic_type() == T_LONG); 9970 match(Set dst (RotateLeft dst shift)); 9971 effect(KILL cr); 9972 format %{ "rolq $dst, $shift" %} 9973 ins_encode %{ 9974 __ rolq($dst$$Register); 9975 %} 9976 ins_pipe(ialu_reg_reg); 9977 %} 9978 9979 // Rotate Left by variable 9980 instruct rolL_rReg_Var_ndd(rRegL dst, rRegL src, rcx_RegI shift, rFlagsReg cr) 9981 %{ 9982 predicate(UseAPX && n->bottom_type()->basic_type() == T_LONG); 9983 match(Set dst (RotateLeft src shift)); 9984 effect(KILL cr); 9985 9986 format %{ "erolq $dst, $src, $shift\t# rotate left(long ndd)" %} 9987 ins_encode %{ 9988 __ erolq($dst$$Register, $src$$Register, false); 9989 %} 9990 ins_pipe(ialu_reg_reg); 9991 %} 9992 9993 // Rotate Right by constant. 9994 instruct rorL_immI8_legacy(rRegL dst, immI8 shift, rFlagsReg cr) 9995 %{ 9996 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 9997 match(Set dst (RotateRight dst shift)); 9998 effect(KILL cr); 9999 format %{ "rorq $dst, $shift" %} 10000 ins_encode %{ 10001 __ rorq($dst$$Register, $shift$$constant); 10002 %} 10003 ins_pipe(ialu_reg); 10004 %} 10005 10006 // Rotate Right by constant 10007 instruct rorL_immI8(rRegL dst, rRegL src, immI8 shift) 10008 %{ 10009 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 10010 match(Set dst (RotateRight src shift)); 10011 format %{ "rorxq $dst, $src, $shift" %} 10012 ins_encode %{ 10013 __ rorxq($dst$$Register, $src$$Register, $shift$$constant); 10014 %} 10015 ins_pipe(ialu_reg_reg); 10016 %} 10017 10018 instruct rorL_mem_immI8(rRegL dst, memory src, immI8 shift) 10019 %{ 10020 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 10021 match(Set dst (RotateRight (LoadL src) shift)); 10022 ins_cost(175); 10023 format %{ "rorxq $dst, $src, $shift" %} 10024 ins_encode %{ 10025 __ rorxq($dst$$Register, $src$$Address, $shift$$constant); 10026 %} 10027 ins_pipe(ialu_reg_mem); 10028 %} 10029 10030 // Rotate Right by variable 10031 instruct rorL_rReg_Var(rRegL dst, rcx_RegI shift, rFlagsReg cr) 10032 %{ 10033 predicate(!UseAPX && n->bottom_type()->basic_type() == T_LONG); 10034 match(Set dst (RotateRight dst shift)); 10035 effect(KILL cr); 10036 format %{ "rorq $dst, $shift" %} 10037 ins_encode %{ 10038 __ rorq($dst$$Register); 10039 %} 10040 ins_pipe(ialu_reg_reg); 10041 %} 10042 10043 // Rotate Right by variable 10044 instruct rorL_rReg_Var_ndd(rRegL dst, rRegL src, rcx_RegI shift, rFlagsReg cr) 10045 %{ 10046 predicate(UseAPX && n->bottom_type()->basic_type() == T_LONG); 10047 match(Set dst (RotateRight src shift)); 10048 effect(KILL cr); 10049 10050 format %{ "erorq $dst, $src, $shift\t# rotate right(long ndd)" %} 10051 ins_encode %{ 10052 __ erorq($dst$$Register, $src$$Register, false); 10053 %} 10054 ins_pipe(ialu_reg_reg); 10055 %} 10056 10057 //----------------------------- CompressBits/ExpandBits ------------------------ 10058 10059 instruct compressBitsL_reg(rRegL dst, rRegL src, rRegL mask) %{ 10060 predicate(n->bottom_type()->isa_long()); 10061 match(Set dst (CompressBits src mask)); 10062 format %{ "pextq $dst, $src, $mask\t! parallel bit extract" %} 10063 ins_encode %{ 10064 __ pextq($dst$$Register, $src$$Register, $mask$$Register); 10065 %} 10066 ins_pipe( pipe_slow ); 10067 %} 10068 10069 instruct expandBitsL_reg(rRegL dst, rRegL src, rRegL mask) %{ 10070 predicate(n->bottom_type()->isa_long()); 10071 match(Set dst (ExpandBits src mask)); 10072 format %{ "pdepq $dst, $src, $mask\t! parallel bit deposit" %} 10073 ins_encode %{ 10074 __ pdepq($dst$$Register, $src$$Register, $mask$$Register); 10075 %} 10076 ins_pipe( pipe_slow ); 10077 %} 10078 10079 instruct compressBitsL_mem(rRegL dst, rRegL src, memory mask) %{ 10080 predicate(n->bottom_type()->isa_long()); 10081 match(Set dst (CompressBits src (LoadL mask))); 10082 format %{ "pextq $dst, $src, $mask\t! parallel bit extract" %} 10083 ins_encode %{ 10084 __ pextq($dst$$Register, $src$$Register, $mask$$Address); 10085 %} 10086 ins_pipe( pipe_slow ); 10087 %} 10088 10089 instruct expandBitsL_mem(rRegL dst, rRegL src, memory mask) %{ 10090 predicate(n->bottom_type()->isa_long()); 10091 match(Set dst (ExpandBits src (LoadL mask))); 10092 format %{ "pdepq $dst, $src, $mask\t! parallel bit deposit" %} 10093 ins_encode %{ 10094 __ pdepq($dst$$Register, $src$$Register, $mask$$Address); 10095 %} 10096 ins_pipe( pipe_slow ); 10097 %} 10098 10099 10100 // Logical Instructions 10101 10102 // Integer Logical Instructions 10103 10104 // And Instructions 10105 // And Register with Register 10106 instruct andI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 10107 %{ 10108 predicate(!UseAPX); 10109 match(Set dst (AndI dst src)); 10110 effect(KILL cr); 10111 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); 10112 10113 format %{ "andl $dst, $src\t# int" %} 10114 ins_encode %{ 10115 __ andl($dst$$Register, $src$$Register); 10116 %} 10117 ins_pipe(ialu_reg_reg); 10118 %} 10119 10120 // And Register with Register using New Data Destination (NDD) 10121 instruct andI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr) 10122 %{ 10123 predicate(UseAPX); 10124 match(Set dst (AndI src1 src2)); 10125 effect(KILL cr); 10126 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); 10127 10128 format %{ "eandl $dst, $src1, $src2\t# int ndd" %} 10129 ins_encode %{ 10130 __ eandl($dst$$Register, $src1$$Register, $src2$$Register, false); 10131 10132 %} 10133 ins_pipe(ialu_reg_reg); 10134 %} 10135 10136 // And Register with Immediate 255 10137 instruct andI_rReg_imm255(rRegI dst, rRegI src, immI_255 mask) 10138 %{ 10139 match(Set dst (AndI src mask)); 10140 10141 format %{ "movzbl $dst, $src\t# int & 0xFF" %} 10142 ins_encode %{ 10143 __ movzbl($dst$$Register, $src$$Register); 10144 %} 10145 ins_pipe(ialu_reg); 10146 %} 10147 10148 // And Register with Immediate 255 and promote to long 10149 instruct andI2L_rReg_imm255(rRegL dst, rRegI src, immI_255 mask) 10150 %{ 10151 match(Set dst (ConvI2L (AndI src mask))); 10152 10153 format %{ "movzbl $dst, $src\t# int & 0xFF -> long" %} 10154 ins_encode %{ 10155 __ movzbl($dst$$Register, $src$$Register); 10156 %} 10157 ins_pipe(ialu_reg); 10158 %} 10159 10160 // And Register with Immediate 65535 10161 instruct andI_rReg_imm65535(rRegI dst, rRegI src, immI_65535 mask) 10162 %{ 10163 match(Set dst (AndI src mask)); 10164 10165 format %{ "movzwl $dst, $src\t# int & 0xFFFF" %} 10166 ins_encode %{ 10167 __ movzwl($dst$$Register, $src$$Register); 10168 %} 10169 ins_pipe(ialu_reg); 10170 %} 10171 10172 // And Register with Immediate 65535 and promote to long 10173 instruct andI2L_rReg_imm65535(rRegL dst, rRegI src, immI_65535 mask) 10174 %{ 10175 match(Set dst (ConvI2L (AndI src mask))); 10176 10177 format %{ "movzwl $dst, $src\t# int & 0xFFFF -> long" %} 10178 ins_encode %{ 10179 __ movzwl($dst$$Register, $src$$Register); 10180 %} 10181 ins_pipe(ialu_reg); 10182 %} 10183 10184 // Can skip int2long conversions after AND with small bitmask 10185 instruct convI2LAndI_reg_immIbitmask(rRegL dst, rRegI src, immI_Pow2M1 mask, rRegI tmp, rFlagsReg cr) 10186 %{ 10187 predicate(VM_Version::supports_bmi2()); 10188 ins_cost(125); 10189 effect(TEMP tmp, KILL cr); 10190 match(Set dst (ConvI2L (AndI src mask))); 10191 format %{ "bzhiq $dst, $src, $mask \t# using $tmp as TEMP, int & immI_Pow2M1 -> long" %} 10192 ins_encode %{ 10193 __ movl($tmp$$Register, exact_log2($mask$$constant + 1)); 10194 __ bzhiq($dst$$Register, $src$$Register, $tmp$$Register); 10195 %} 10196 ins_pipe(ialu_reg_reg); 10197 %} 10198 10199 // And Register with Immediate 10200 instruct andI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 10201 %{ 10202 predicate(!UseAPX); 10203 match(Set dst (AndI dst src)); 10204 effect(KILL cr); 10205 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); 10206 10207 format %{ "andl $dst, $src\t# int" %} 10208 ins_encode %{ 10209 __ andl($dst$$Register, $src$$constant); 10210 %} 10211 ins_pipe(ialu_reg); 10212 %} 10213 10214 instruct andI_rReg_rReg_imm_ndd(rRegI dst, rRegI src1, immI src2, rFlagsReg cr) 10215 %{ 10216 predicate(UseAPX); 10217 match(Set dst (AndI src1 src2)); 10218 effect(KILL cr); 10219 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); 10220 10221 format %{ "eandl $dst, $src1, $src2\t# int ndd" %} 10222 ins_encode %{ 10223 __ eandl($dst$$Register, $src1$$Register, $src2$$constant, false); 10224 %} 10225 ins_pipe(ialu_reg); 10226 %} 10227 10228 instruct andI_rReg_mem_imm_ndd(rRegI dst, memory src1, immI src2, rFlagsReg cr) 10229 %{ 10230 predicate(UseAPX); 10231 match(Set dst (AndI (LoadI src1) src2)); 10232 effect(KILL cr); 10233 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); 10234 10235 format %{ "eandl $dst, $src1, $src2\t# int ndd" %} 10236 ins_encode %{ 10237 __ eandl($dst$$Register, $src1$$Address, $src2$$constant, false); 10238 %} 10239 ins_pipe(ialu_reg); 10240 %} 10241 10242 // And Register with Memory 10243 instruct andI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 10244 %{ 10245 predicate(!UseAPX); 10246 match(Set dst (AndI dst (LoadI src))); 10247 effect(KILL cr); 10248 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); 10249 10250 ins_cost(150); 10251 format %{ "andl $dst, $src\t# int" %} 10252 ins_encode %{ 10253 __ andl($dst$$Register, $src$$Address); 10254 %} 10255 ins_pipe(ialu_reg_mem); 10256 %} 10257 10258 instruct andI_rReg_rReg_mem_ndd(rRegI dst, rRegI src1, memory src2, rFlagsReg cr) 10259 %{ 10260 predicate(UseAPX); 10261 match(Set dst (AndI src1 (LoadI src2))); 10262 effect(KILL cr); 10263 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); 10264 10265 ins_cost(150); 10266 format %{ "eandl $dst, $src1, $src2\t# int ndd" %} 10267 ins_encode %{ 10268 __ eandl($dst$$Register, $src1$$Register, $src2$$Address, false); 10269 %} 10270 ins_pipe(ialu_reg_mem); 10271 %} 10272 10273 // And Memory with Register 10274 instruct andB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 10275 %{ 10276 match(Set dst (StoreB dst (AndI (LoadB dst) src))); 10277 effect(KILL cr); 10278 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); 10279 10280 ins_cost(150); 10281 format %{ "andb $dst, $src\t# byte" %} 10282 ins_encode %{ 10283 __ andb($dst$$Address, $src$$Register); 10284 %} 10285 ins_pipe(ialu_mem_reg); 10286 %} 10287 10288 instruct andI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 10289 %{ 10290 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 10291 effect(KILL cr); 10292 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); 10293 10294 ins_cost(150); 10295 format %{ "andl $dst, $src\t# int" %} 10296 ins_encode %{ 10297 __ andl($dst$$Address, $src$$Register); 10298 %} 10299 ins_pipe(ialu_mem_reg); 10300 %} 10301 10302 // And Memory with Immediate 10303 instruct andI_mem_imm(memory dst, immI src, rFlagsReg cr) 10304 %{ 10305 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 10306 effect(KILL cr); 10307 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); 10308 10309 ins_cost(125); 10310 format %{ "andl $dst, $src\t# int" %} 10311 ins_encode %{ 10312 __ andl($dst$$Address, $src$$constant); 10313 %} 10314 ins_pipe(ialu_mem_imm); 10315 %} 10316 10317 // BMI1 instructions 10318 instruct andnI_rReg_rReg_mem(rRegI dst, rRegI src1, memory src2, immI_M1 minus_1, rFlagsReg cr) %{ 10319 match(Set dst (AndI (XorI src1 minus_1) (LoadI src2))); 10320 predicate(UseBMI1Instructions); 10321 effect(KILL cr); 10322 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10323 10324 ins_cost(125); 10325 format %{ "andnl $dst, $src1, $src2" %} 10326 10327 ins_encode %{ 10328 __ andnl($dst$$Register, $src1$$Register, $src2$$Address); 10329 %} 10330 ins_pipe(ialu_reg_mem); 10331 %} 10332 10333 instruct andnI_rReg_rReg_rReg(rRegI dst, rRegI src1, rRegI src2, immI_M1 minus_1, rFlagsReg cr) %{ 10334 match(Set dst (AndI (XorI src1 minus_1) src2)); 10335 predicate(UseBMI1Instructions); 10336 effect(KILL cr); 10337 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10338 10339 format %{ "andnl $dst, $src1, $src2" %} 10340 10341 ins_encode %{ 10342 __ andnl($dst$$Register, $src1$$Register, $src2$$Register); 10343 %} 10344 ins_pipe(ialu_reg); 10345 %} 10346 10347 instruct blsiI_rReg_rReg(rRegI dst, rRegI src, immI_0 imm_zero, rFlagsReg cr) %{ 10348 match(Set dst (AndI (SubI imm_zero src) src)); 10349 predicate(UseBMI1Instructions); 10350 effect(KILL cr); 10351 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 10352 10353 format %{ "blsil $dst, $src" %} 10354 10355 ins_encode %{ 10356 __ blsil($dst$$Register, $src$$Register); 10357 %} 10358 ins_pipe(ialu_reg); 10359 %} 10360 10361 instruct blsiI_rReg_mem(rRegI dst, memory src, immI_0 imm_zero, rFlagsReg cr) %{ 10362 match(Set dst (AndI (SubI imm_zero (LoadI src) ) (LoadI src) )); 10363 predicate(UseBMI1Instructions); 10364 effect(KILL cr); 10365 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 10366 10367 ins_cost(125); 10368 format %{ "blsil $dst, $src" %} 10369 10370 ins_encode %{ 10371 __ blsil($dst$$Register, $src$$Address); 10372 %} 10373 ins_pipe(ialu_reg_mem); 10374 %} 10375 10376 instruct blsmskI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 10377 %{ 10378 match(Set dst (XorI (AddI (LoadI src) minus_1) (LoadI src) ) ); 10379 predicate(UseBMI1Instructions); 10380 effect(KILL cr); 10381 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 10382 10383 ins_cost(125); 10384 format %{ "blsmskl $dst, $src" %} 10385 10386 ins_encode %{ 10387 __ blsmskl($dst$$Register, $src$$Address); 10388 %} 10389 ins_pipe(ialu_reg_mem); 10390 %} 10391 10392 instruct blsmskI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 10393 %{ 10394 match(Set dst (XorI (AddI src minus_1) src)); 10395 predicate(UseBMI1Instructions); 10396 effect(KILL cr); 10397 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 10398 10399 format %{ "blsmskl $dst, $src" %} 10400 10401 ins_encode %{ 10402 __ blsmskl($dst$$Register, $src$$Register); 10403 %} 10404 10405 ins_pipe(ialu_reg); 10406 %} 10407 10408 instruct blsrI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 10409 %{ 10410 match(Set dst (AndI (AddI src minus_1) src) ); 10411 predicate(UseBMI1Instructions); 10412 effect(KILL cr); 10413 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 10414 10415 format %{ "blsrl $dst, $src" %} 10416 10417 ins_encode %{ 10418 __ blsrl($dst$$Register, $src$$Register); 10419 %} 10420 10421 ins_pipe(ialu_reg_mem); 10422 %} 10423 10424 instruct blsrI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 10425 %{ 10426 match(Set dst (AndI (AddI (LoadI src) minus_1) (LoadI src) ) ); 10427 predicate(UseBMI1Instructions); 10428 effect(KILL cr); 10429 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 10430 10431 ins_cost(125); 10432 format %{ "blsrl $dst, $src" %} 10433 10434 ins_encode %{ 10435 __ blsrl($dst$$Register, $src$$Address); 10436 %} 10437 10438 ins_pipe(ialu_reg); 10439 %} 10440 10441 // Or Instructions 10442 // Or Register with Register 10443 instruct orI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 10444 %{ 10445 predicate(!UseAPX); 10446 match(Set dst (OrI dst src)); 10447 effect(KILL cr); 10448 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10449 10450 format %{ "orl $dst, $src\t# int" %} 10451 ins_encode %{ 10452 __ orl($dst$$Register, $src$$Register); 10453 %} 10454 ins_pipe(ialu_reg_reg); 10455 %} 10456 10457 // Or Register with Register using New Data Destination (NDD) 10458 instruct orI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr) 10459 %{ 10460 predicate(UseAPX); 10461 match(Set dst (OrI src1 src2)); 10462 effect(KILL cr); 10463 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10464 10465 format %{ "eorl $dst, $src1, $src2\t# int ndd" %} 10466 ins_encode %{ 10467 __ eorl($dst$$Register, $src1$$Register, $src2$$Register, false); 10468 %} 10469 ins_pipe(ialu_reg_reg); 10470 %} 10471 10472 // Or Register with Immediate 10473 instruct orI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 10474 %{ 10475 predicate(!UseAPX); 10476 match(Set dst (OrI dst src)); 10477 effect(KILL cr); 10478 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10479 10480 format %{ "orl $dst, $src\t# int" %} 10481 ins_encode %{ 10482 __ orl($dst$$Register, $src$$constant); 10483 %} 10484 ins_pipe(ialu_reg); 10485 %} 10486 10487 instruct orI_rReg_rReg_imm_ndd(rRegI dst, rRegI src1, immI src2, rFlagsReg cr) 10488 %{ 10489 predicate(UseAPX); 10490 match(Set dst (OrI src1 src2)); 10491 effect(KILL cr); 10492 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); 10493 10494 format %{ "eorl $dst, $src1, $src2\t# int ndd" %} 10495 ins_encode %{ 10496 __ eorl($dst$$Register, $src1$$Register, $src2$$constant, false); 10497 %} 10498 ins_pipe(ialu_reg); 10499 %} 10500 10501 instruct orI_rReg_imm_rReg_ndd(rRegI dst, immI src1, rRegI src2, rFlagsReg cr) 10502 %{ 10503 predicate(UseAPX); 10504 match(Set dst (OrI src1 src2)); 10505 effect(KILL cr); 10506 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); 10507 10508 format %{ "eorl $dst, $src2, $src1\t# int ndd" %} 10509 ins_encode %{ 10510 __ eorl($dst$$Register, $src2$$Register, $src1$$constant, false); 10511 %} 10512 ins_pipe(ialu_reg); 10513 %} 10514 10515 instruct orI_rReg_mem_imm_ndd(rRegI dst, memory src1, immI src2, rFlagsReg cr) 10516 %{ 10517 predicate(UseAPX); 10518 match(Set dst (OrI (LoadI src1) src2)); 10519 effect(KILL cr); 10520 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); 10521 10522 format %{ "eorl $dst, $src1, $src2\t# int ndd" %} 10523 ins_encode %{ 10524 __ eorl($dst$$Register, $src1$$Address, $src2$$constant, false); 10525 %} 10526 ins_pipe(ialu_reg); 10527 %} 10528 10529 // Or Register with Memory 10530 instruct orI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 10531 %{ 10532 predicate(!UseAPX); 10533 match(Set dst (OrI dst (LoadI src))); 10534 effect(KILL cr); 10535 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); 10536 10537 ins_cost(150); 10538 format %{ "orl $dst, $src\t# int" %} 10539 ins_encode %{ 10540 __ orl($dst$$Register, $src$$Address); 10541 %} 10542 ins_pipe(ialu_reg_mem); 10543 %} 10544 10545 instruct orI_rReg_rReg_mem_ndd(rRegI dst, rRegI src1, memory src2, rFlagsReg cr) 10546 %{ 10547 predicate(UseAPX); 10548 match(Set dst (OrI src1 (LoadI src2))); 10549 effect(KILL cr); 10550 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); 10551 10552 ins_cost(150); 10553 format %{ "eorl $dst, $src1, $src2\t# int ndd" %} 10554 ins_encode %{ 10555 __ eorl($dst$$Register, $src1$$Register, $src2$$Address, false); 10556 %} 10557 ins_pipe(ialu_reg_mem); 10558 %} 10559 10560 // Or Memory with Register 10561 instruct orB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 10562 %{ 10563 match(Set dst (StoreB dst (OrI (LoadB dst) src))); 10564 effect(KILL cr); 10565 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); 10566 10567 ins_cost(150); 10568 format %{ "orb $dst, $src\t# byte" %} 10569 ins_encode %{ 10570 __ orb($dst$$Address, $src$$Register); 10571 %} 10572 ins_pipe(ialu_mem_reg); 10573 %} 10574 10575 instruct orI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 10576 %{ 10577 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 10578 effect(KILL cr); 10579 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); 10580 10581 ins_cost(150); 10582 format %{ "orl $dst, $src\t# int" %} 10583 ins_encode %{ 10584 __ orl($dst$$Address, $src$$Register); 10585 %} 10586 ins_pipe(ialu_mem_reg); 10587 %} 10588 10589 // Or Memory with Immediate 10590 instruct orI_mem_imm(memory dst, immI src, rFlagsReg cr) 10591 %{ 10592 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 10593 effect(KILL cr); 10594 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10595 10596 ins_cost(125); 10597 format %{ "orl $dst, $src\t# int" %} 10598 ins_encode %{ 10599 __ orl($dst$$Address, $src$$constant); 10600 %} 10601 ins_pipe(ialu_mem_imm); 10602 %} 10603 10604 // Xor Instructions 10605 // Xor Register with Register 10606 instruct xorI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 10607 %{ 10608 predicate(!UseAPX); 10609 match(Set dst (XorI dst src)); 10610 effect(KILL cr); 10611 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); 10612 10613 format %{ "xorl $dst, $src\t# int" %} 10614 ins_encode %{ 10615 __ xorl($dst$$Register, $src$$Register); 10616 %} 10617 ins_pipe(ialu_reg_reg); 10618 %} 10619 10620 // Xor Register with Register using New Data Destination (NDD) 10621 instruct xorI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr) 10622 %{ 10623 predicate(UseAPX); 10624 match(Set dst (XorI src1 src2)); 10625 effect(KILL cr); 10626 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); 10627 10628 format %{ "exorl $dst, $src1, $src2\t# int ndd" %} 10629 ins_encode %{ 10630 __ exorl($dst$$Register, $src1$$Register, $src2$$Register, false); 10631 %} 10632 ins_pipe(ialu_reg_reg); 10633 %} 10634 10635 // Xor Register with Immediate -1 10636 instruct xorI_rReg_im1(rRegI dst, immI_M1 imm) 10637 %{ 10638 predicate(!UseAPX); 10639 match(Set dst (XorI dst imm)); 10640 10641 format %{ "notl $dst" %} 10642 ins_encode %{ 10643 __ notl($dst$$Register); 10644 %} 10645 ins_pipe(ialu_reg); 10646 %} 10647 10648 instruct xorI_rReg_im1_ndd(rRegI dst, rRegI src, immI_M1 imm) 10649 %{ 10650 match(Set dst (XorI src imm)); 10651 predicate(UseAPX); 10652 10653 format %{ "enotl $dst, $src" %} 10654 ins_encode %{ 10655 __ enotl($dst$$Register, $src$$Register); 10656 %} 10657 ins_pipe(ialu_reg); 10658 %} 10659 10660 // Xor Register with Immediate 10661 instruct xorI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 10662 %{ 10663 predicate(!UseAPX); 10664 match(Set dst (XorI dst src)); 10665 effect(KILL cr); 10666 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); 10667 10668 format %{ "xorl $dst, $src\t# int" %} 10669 ins_encode %{ 10670 __ xorl($dst$$Register, $src$$constant); 10671 %} 10672 ins_pipe(ialu_reg); 10673 %} 10674 10675 instruct xorI_rReg_rReg_imm_ndd(rRegI dst, rRegI src1, immI src2, rFlagsReg cr) 10676 %{ 10677 predicate(UseAPX); 10678 match(Set dst (XorI src1 src2)); 10679 effect(KILL cr); 10680 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); 10681 10682 format %{ "exorl $dst, $src1, $src2\t# int ndd" %} 10683 ins_encode %{ 10684 __ exorl($dst$$Register, $src1$$Register, $src2$$constant, false); 10685 %} 10686 ins_pipe(ialu_reg); 10687 %} 10688 10689 // Xor Memory with Immediate 10690 instruct xorI_rReg_mem_imm_ndd(rRegI dst, memory src1, immI src2, rFlagsReg cr) 10691 %{ 10692 predicate(UseAPX); 10693 match(Set dst (XorI (LoadI src1) src2)); 10694 effect(KILL cr); 10695 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); 10696 10697 format %{ "exorl $dst, $src1, $src2\t# int ndd" %} 10698 ins_encode %{ 10699 __ exorl($dst$$Register, $src1$$Address, $src2$$constant, false); 10700 %} 10701 ins_pipe(ialu_reg); 10702 %} 10703 10704 // Xor Register with Memory 10705 instruct xorI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 10706 %{ 10707 predicate(!UseAPX); 10708 match(Set dst (XorI dst (LoadI src))); 10709 effect(KILL cr); 10710 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); 10711 10712 ins_cost(150); 10713 format %{ "xorl $dst, $src\t# int" %} 10714 ins_encode %{ 10715 __ xorl($dst$$Register, $src$$Address); 10716 %} 10717 ins_pipe(ialu_reg_mem); 10718 %} 10719 10720 instruct xorI_rReg_rReg_mem_ndd(rRegI dst, rRegI src1, memory src2, rFlagsReg cr) 10721 %{ 10722 predicate(UseAPX); 10723 match(Set dst (XorI src1 (LoadI src2))); 10724 effect(KILL cr); 10725 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); 10726 10727 ins_cost(150); 10728 format %{ "exorl $dst, $src1, $src2\t# int ndd" %} 10729 ins_encode %{ 10730 __ exorl($dst$$Register, $src1$$Register, $src2$$Address, false); 10731 %} 10732 ins_pipe(ialu_reg_mem); 10733 %} 10734 10735 instruct xorI_rReg_mem_rReg_ndd(rRegI dst, memory src1, rRegI src2, rFlagsReg cr) 10736 %{ 10737 predicate(UseAPX); 10738 match(Set dst (XorI (LoadI src1) src2)); 10739 effect(KILL cr); 10740 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); 10741 10742 ins_cost(150); 10743 format %{ "exorl $dst, $src1, $src2\t# int ndd" %} 10744 ins_encode %{ 10745 __ exorl($dst$$Register, $src1$$Address, $src2$$Register, false); 10746 %} 10747 ins_pipe(ialu_reg_mem); 10748 %} 10749 10750 // Xor Memory with Register 10751 instruct xorB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 10752 %{ 10753 match(Set dst (StoreB dst (XorI (LoadB dst) src))); 10754 effect(KILL cr); 10755 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); 10756 10757 ins_cost(150); 10758 format %{ "xorb $dst, $src\t# byte" %} 10759 ins_encode %{ 10760 __ xorb($dst$$Address, $src$$Register); 10761 %} 10762 ins_pipe(ialu_mem_reg); 10763 %} 10764 10765 instruct xorI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 10766 %{ 10767 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 10768 effect(KILL cr); 10769 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); 10770 10771 ins_cost(150); 10772 format %{ "xorl $dst, $src\t# int" %} 10773 ins_encode %{ 10774 __ xorl($dst$$Address, $src$$Register); 10775 %} 10776 ins_pipe(ialu_mem_reg); 10777 %} 10778 10779 // Xor Memory with Immediate 10780 instruct xorI_mem_imm(memory dst, immI src, rFlagsReg cr) 10781 %{ 10782 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 10783 effect(KILL cr); 10784 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); 10785 10786 ins_cost(125); 10787 format %{ "xorl $dst, $src\t# int" %} 10788 ins_encode %{ 10789 __ xorl($dst$$Address, $src$$constant); 10790 %} 10791 ins_pipe(ialu_mem_imm); 10792 %} 10793 10794 10795 // Long Logical Instructions 10796 10797 // And Instructions 10798 // And Register with Register 10799 instruct andL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 10800 %{ 10801 predicate(!UseAPX); 10802 match(Set dst (AndL dst src)); 10803 effect(KILL cr); 10804 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); 10805 10806 format %{ "andq $dst, $src\t# long" %} 10807 ins_encode %{ 10808 __ andq($dst$$Register, $src$$Register); 10809 %} 10810 ins_pipe(ialu_reg_reg); 10811 %} 10812 10813 // And Register with Register using New Data Destination (NDD) 10814 instruct andL_rReg_ndd(rRegL dst, rRegL src1, rRegL src2, rFlagsReg cr) 10815 %{ 10816 predicate(UseAPX); 10817 match(Set dst (AndL src1 src2)); 10818 effect(KILL cr); 10819 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); 10820 10821 format %{ "eandq $dst, $src1, $src2\t# long ndd" %} 10822 ins_encode %{ 10823 __ eandq($dst$$Register, $src1$$Register, $src2$$Register, false); 10824 10825 %} 10826 ins_pipe(ialu_reg_reg); 10827 %} 10828 10829 // And Register with Immediate 255 10830 instruct andL_rReg_imm255(rRegL dst, rRegL src, immL_255 mask) 10831 %{ 10832 match(Set dst (AndL src mask)); 10833 10834 format %{ "movzbl $dst, $src\t# long & 0xFF" %} 10835 ins_encode %{ 10836 // movzbl zeroes out the upper 32-bit and does not need REX.W 10837 __ movzbl($dst$$Register, $src$$Register); 10838 %} 10839 ins_pipe(ialu_reg); 10840 %} 10841 10842 // And Register with Immediate 65535 10843 instruct andL_rReg_imm65535(rRegL dst, rRegL src, immL_65535 mask) 10844 %{ 10845 match(Set dst (AndL src mask)); 10846 10847 format %{ "movzwl $dst, $src\t# long & 0xFFFF" %} 10848 ins_encode %{ 10849 // movzwl zeroes out the upper 32-bit and does not need REX.W 10850 __ movzwl($dst$$Register, $src$$Register); 10851 %} 10852 ins_pipe(ialu_reg); 10853 %} 10854 10855 // And Register with Immediate 10856 instruct andL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 10857 %{ 10858 predicate(!UseAPX); 10859 match(Set dst (AndL dst src)); 10860 effect(KILL cr); 10861 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); 10862 10863 format %{ "andq $dst, $src\t# long" %} 10864 ins_encode %{ 10865 __ andq($dst$$Register, $src$$constant); 10866 %} 10867 ins_pipe(ialu_reg); 10868 %} 10869 10870 instruct andL_rReg_rReg_imm_ndd(rRegL dst, rRegL src1, immL32 src2, rFlagsReg cr) 10871 %{ 10872 predicate(UseAPX); 10873 match(Set dst (AndL src1 src2)); 10874 effect(KILL cr); 10875 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); 10876 10877 format %{ "eandq $dst, $src1, $src2\t# long ndd" %} 10878 ins_encode %{ 10879 __ eandq($dst$$Register, $src1$$Register, $src2$$constant, false); 10880 %} 10881 ins_pipe(ialu_reg); 10882 %} 10883 10884 instruct andL_rReg_mem_imm_ndd(rRegL dst, memory src1, immL32 src2, rFlagsReg cr) 10885 %{ 10886 predicate(UseAPX); 10887 match(Set dst (AndL (LoadL src1) src2)); 10888 effect(KILL cr); 10889 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); 10890 10891 format %{ "eandq $dst, $src1, $src2\t# long ndd" %} 10892 ins_encode %{ 10893 __ eandq($dst$$Register, $src1$$Address, $src2$$constant, false); 10894 %} 10895 ins_pipe(ialu_reg); 10896 %} 10897 10898 // And Register with Memory 10899 instruct andL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 10900 %{ 10901 predicate(!UseAPX); 10902 match(Set dst (AndL dst (LoadL src))); 10903 effect(KILL cr); 10904 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); 10905 10906 ins_cost(150); 10907 format %{ "andq $dst, $src\t# long" %} 10908 ins_encode %{ 10909 __ andq($dst$$Register, $src$$Address); 10910 %} 10911 ins_pipe(ialu_reg_mem); 10912 %} 10913 10914 instruct andL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr) 10915 %{ 10916 predicate(UseAPX); 10917 match(Set dst (AndL src1 (LoadL src2))); 10918 effect(KILL cr); 10919 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); 10920 10921 ins_cost(150); 10922 format %{ "eandq $dst, $src1, $src2\t# long ndd" %} 10923 ins_encode %{ 10924 __ eandq($dst$$Register, $src1$$Register, $src2$$Address, false); 10925 %} 10926 ins_pipe(ialu_reg_mem); 10927 %} 10928 10929 instruct andL_rReg_mem_rReg_ndd(rRegL dst, memory src1, rRegL src2, rFlagsReg cr) 10930 %{ 10931 predicate(UseAPX); 10932 match(Set dst (AndL (LoadL src1) src2)); 10933 effect(KILL cr); 10934 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); 10935 10936 ins_cost(150); 10937 format %{ "eandq $dst, $src1, $src2\t# long ndd" %} 10938 ins_encode %{ 10939 __ eandq($dst$$Register, $src1$$Address, $src2$$Register, false); 10940 %} 10941 ins_pipe(ialu_reg_mem); 10942 %} 10943 10944 // And Memory with Register 10945 instruct andL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 10946 %{ 10947 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 10948 effect(KILL cr); 10949 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); 10950 10951 ins_cost(150); 10952 format %{ "andq $dst, $src\t# long" %} 10953 ins_encode %{ 10954 __ andq($dst$$Address, $src$$Register); 10955 %} 10956 ins_pipe(ialu_mem_reg); 10957 %} 10958 10959 // And Memory with Immediate 10960 instruct andL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 10961 %{ 10962 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 10963 effect(KILL cr); 10964 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); 10965 10966 ins_cost(125); 10967 format %{ "andq $dst, $src\t# long" %} 10968 ins_encode %{ 10969 __ andq($dst$$Address, $src$$constant); 10970 %} 10971 ins_pipe(ialu_mem_imm); 10972 %} 10973 10974 instruct btrL_mem_imm(memory dst, immL_NotPow2 con, rFlagsReg cr) 10975 %{ 10976 // con should be a pure 64-bit immediate given that not(con) is a power of 2 10977 // because AND/OR works well enough for 8/32-bit values. 10978 predicate(log2i_graceful(~n->in(3)->in(2)->get_long()) > 30); 10979 10980 match(Set dst (StoreL dst (AndL (LoadL dst) con))); 10981 effect(KILL cr); 10982 10983 ins_cost(125); 10984 format %{ "btrq $dst, log2(not($con))\t# long" %} 10985 ins_encode %{ 10986 __ btrq($dst$$Address, log2i_exact((julong)~$con$$constant)); 10987 %} 10988 ins_pipe(ialu_mem_imm); 10989 %} 10990 10991 // BMI1 instructions 10992 instruct andnL_rReg_rReg_mem(rRegL dst, rRegL src1, memory src2, immL_M1 minus_1, rFlagsReg cr) %{ 10993 match(Set dst (AndL (XorL src1 minus_1) (LoadL src2))); 10994 predicate(UseBMI1Instructions); 10995 effect(KILL cr); 10996 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10997 10998 ins_cost(125); 10999 format %{ "andnq $dst, $src1, $src2" %} 11000 11001 ins_encode %{ 11002 __ andnq($dst$$Register, $src1$$Register, $src2$$Address); 11003 %} 11004 ins_pipe(ialu_reg_mem); 11005 %} 11006 11007 instruct andnL_rReg_rReg_rReg(rRegL dst, rRegL src1, rRegL src2, immL_M1 minus_1, rFlagsReg cr) %{ 11008 match(Set dst (AndL (XorL src1 minus_1) src2)); 11009 predicate(UseBMI1Instructions); 11010 effect(KILL cr); 11011 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11012 11013 format %{ "andnq $dst, $src1, $src2" %} 11014 11015 ins_encode %{ 11016 __ andnq($dst$$Register, $src1$$Register, $src2$$Register); 11017 %} 11018 ins_pipe(ialu_reg_mem); 11019 %} 11020 11021 instruct blsiL_rReg_rReg(rRegL dst, rRegL src, immL0 imm_zero, rFlagsReg cr) %{ 11022 match(Set dst (AndL (SubL imm_zero src) src)); 11023 predicate(UseBMI1Instructions); 11024 effect(KILL cr); 11025 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 11026 11027 format %{ "blsiq $dst, $src" %} 11028 11029 ins_encode %{ 11030 __ blsiq($dst$$Register, $src$$Register); 11031 %} 11032 ins_pipe(ialu_reg); 11033 %} 11034 11035 instruct blsiL_rReg_mem(rRegL dst, memory src, immL0 imm_zero, rFlagsReg cr) %{ 11036 match(Set dst (AndL (SubL imm_zero (LoadL src) ) (LoadL src) )); 11037 predicate(UseBMI1Instructions); 11038 effect(KILL cr); 11039 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 11040 11041 ins_cost(125); 11042 format %{ "blsiq $dst, $src" %} 11043 11044 ins_encode %{ 11045 __ blsiq($dst$$Register, $src$$Address); 11046 %} 11047 ins_pipe(ialu_reg_mem); 11048 %} 11049 11050 instruct blsmskL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 11051 %{ 11052 match(Set dst (XorL (AddL (LoadL src) minus_1) (LoadL src) ) ); 11053 predicate(UseBMI1Instructions); 11054 effect(KILL cr); 11055 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 11056 11057 ins_cost(125); 11058 format %{ "blsmskq $dst, $src" %} 11059 11060 ins_encode %{ 11061 __ blsmskq($dst$$Register, $src$$Address); 11062 %} 11063 ins_pipe(ialu_reg_mem); 11064 %} 11065 11066 instruct blsmskL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 11067 %{ 11068 match(Set dst (XorL (AddL src minus_1) src)); 11069 predicate(UseBMI1Instructions); 11070 effect(KILL cr); 11071 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 11072 11073 format %{ "blsmskq $dst, $src" %} 11074 11075 ins_encode %{ 11076 __ blsmskq($dst$$Register, $src$$Register); 11077 %} 11078 11079 ins_pipe(ialu_reg); 11080 %} 11081 11082 instruct blsrL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 11083 %{ 11084 match(Set dst (AndL (AddL src minus_1) src) ); 11085 predicate(UseBMI1Instructions); 11086 effect(KILL cr); 11087 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 11088 11089 format %{ "blsrq $dst, $src" %} 11090 11091 ins_encode %{ 11092 __ blsrq($dst$$Register, $src$$Register); 11093 %} 11094 11095 ins_pipe(ialu_reg); 11096 %} 11097 11098 instruct blsrL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 11099 %{ 11100 match(Set dst (AndL (AddL (LoadL src) minus_1) (LoadL src)) ); 11101 predicate(UseBMI1Instructions); 11102 effect(KILL cr); 11103 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 11104 11105 ins_cost(125); 11106 format %{ "blsrq $dst, $src" %} 11107 11108 ins_encode %{ 11109 __ blsrq($dst$$Register, $src$$Address); 11110 %} 11111 11112 ins_pipe(ialu_reg); 11113 %} 11114 11115 // Or Instructions 11116 // Or Register with Register 11117 instruct orL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 11118 %{ 11119 predicate(!UseAPX); 11120 match(Set dst (OrL dst src)); 11121 effect(KILL cr); 11122 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); 11123 11124 format %{ "orq $dst, $src\t# long" %} 11125 ins_encode %{ 11126 __ orq($dst$$Register, $src$$Register); 11127 %} 11128 ins_pipe(ialu_reg_reg); 11129 %} 11130 11131 // Or Register with Register using New Data Destination (NDD) 11132 instruct orL_rReg_ndd(rRegL dst, rRegL src1, rRegL src2, rFlagsReg cr) 11133 %{ 11134 predicate(UseAPX); 11135 match(Set dst (OrL src1 src2)); 11136 effect(KILL cr); 11137 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); 11138 11139 format %{ "eorq $dst, $src1, $src2\t# long ndd" %} 11140 ins_encode %{ 11141 __ eorq($dst$$Register, $src1$$Register, $src2$$Register, false); 11142 11143 %} 11144 ins_pipe(ialu_reg_reg); 11145 %} 11146 11147 // Use any_RegP to match R15 (TLS register) without spilling. 11148 instruct orL_rReg_castP2X(rRegL dst, any_RegP src, rFlagsReg cr) %{ 11149 match(Set dst (OrL dst (CastP2X src))); 11150 effect(KILL cr); 11151 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); 11152 11153 format %{ "orq $dst, $src\t# long" %} 11154 ins_encode %{ 11155 __ orq($dst$$Register, $src$$Register); 11156 %} 11157 ins_pipe(ialu_reg_reg); 11158 %} 11159 11160 instruct orL_rReg_castP2X_ndd(rRegL dst, any_RegP src1, any_RegP src2, rFlagsReg cr) %{ 11161 match(Set dst (OrL src1 (CastP2X src2))); 11162 effect(KILL cr); 11163 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); 11164 11165 format %{ "eorq $dst, $src1, $src2\t# long ndd" %} 11166 ins_encode %{ 11167 __ eorq($dst$$Register, $src1$$Register, $src2$$Register, false); 11168 %} 11169 ins_pipe(ialu_reg_reg); 11170 %} 11171 11172 // Or Register with Immediate 11173 instruct orL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 11174 %{ 11175 predicate(!UseAPX); 11176 match(Set dst (OrL dst src)); 11177 effect(KILL cr); 11178 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); 11179 11180 format %{ "orq $dst, $src\t# long" %} 11181 ins_encode %{ 11182 __ orq($dst$$Register, $src$$constant); 11183 %} 11184 ins_pipe(ialu_reg); 11185 %} 11186 11187 instruct orL_rReg_rReg_imm_ndd(rRegL dst, rRegL src1, immL32 src2, rFlagsReg cr) 11188 %{ 11189 predicate(UseAPX); 11190 match(Set dst (OrL src1 src2)); 11191 effect(KILL cr); 11192 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); 11193 11194 format %{ "eorq $dst, $src1, $src2\t# long ndd" %} 11195 ins_encode %{ 11196 __ eorq($dst$$Register, $src1$$Register, $src2$$constant, false); 11197 %} 11198 ins_pipe(ialu_reg); 11199 %} 11200 11201 instruct orL_rReg_imm_rReg_ndd(rRegL dst, immL32 src1, rRegL src2, rFlagsReg cr) 11202 %{ 11203 predicate(UseAPX); 11204 match(Set dst (OrL src1 src2)); 11205 effect(KILL cr); 11206 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); 11207 11208 format %{ "eorq $dst, $src2, $src1\t# long ndd" %} 11209 ins_encode %{ 11210 __ eorq($dst$$Register, $src2$$Register, $src1$$constant, false); 11211 %} 11212 ins_pipe(ialu_reg); 11213 %} 11214 11215 // Or Memory with Immediate 11216 instruct orL_rReg_mem_imm_ndd(rRegL dst, memory src1, immL32 src2, rFlagsReg cr) 11217 %{ 11218 predicate(UseAPX); 11219 match(Set dst (OrL (LoadL src1) src2)); 11220 effect(KILL cr); 11221 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); 11222 11223 format %{ "eorq $dst, $src1, $src2\t# long ndd" %} 11224 ins_encode %{ 11225 __ eorq($dst$$Register, $src1$$Address, $src2$$constant, false); 11226 %} 11227 ins_pipe(ialu_reg); 11228 %} 11229 11230 // Or Register with Memory 11231 instruct orL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 11232 %{ 11233 predicate(!UseAPX); 11234 match(Set dst (OrL dst (LoadL src))); 11235 effect(KILL cr); 11236 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); 11237 11238 ins_cost(150); 11239 format %{ "orq $dst, $src\t# long" %} 11240 ins_encode %{ 11241 __ orq($dst$$Register, $src$$Address); 11242 %} 11243 ins_pipe(ialu_reg_mem); 11244 %} 11245 11246 instruct orL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr) 11247 %{ 11248 predicate(UseAPX); 11249 match(Set dst (OrL src1 (LoadL src2))); 11250 effect(KILL cr); 11251 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); 11252 11253 ins_cost(150); 11254 format %{ "eorq $dst, $src1, $src2\t# long ndd" %} 11255 ins_encode %{ 11256 __ eorq($dst$$Register, $src1$$Register, $src2$$Address, false); 11257 %} 11258 ins_pipe(ialu_reg_mem); 11259 %} 11260 11261 // Or Memory with Register 11262 instruct orL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 11263 %{ 11264 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 11265 effect(KILL cr); 11266 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); 11267 11268 ins_cost(150); 11269 format %{ "orq $dst, $src\t# long" %} 11270 ins_encode %{ 11271 __ orq($dst$$Address, $src$$Register); 11272 %} 11273 ins_pipe(ialu_mem_reg); 11274 %} 11275 11276 // Or Memory with Immediate 11277 instruct orL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 11278 %{ 11279 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 11280 effect(KILL cr); 11281 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); 11282 11283 ins_cost(125); 11284 format %{ "orq $dst, $src\t# long" %} 11285 ins_encode %{ 11286 __ orq($dst$$Address, $src$$constant); 11287 %} 11288 ins_pipe(ialu_mem_imm); 11289 %} 11290 11291 instruct btsL_mem_imm(memory dst, immL_Pow2 con, rFlagsReg cr) 11292 %{ 11293 // con should be a pure 64-bit power of 2 immediate 11294 // because AND/OR works well enough for 8/32-bit values. 11295 predicate(log2i_graceful(n->in(3)->in(2)->get_long()) > 31); 11296 11297 match(Set dst (StoreL dst (OrL (LoadL dst) con))); 11298 effect(KILL cr); 11299 11300 ins_cost(125); 11301 format %{ "btsq $dst, log2($con)\t# long" %} 11302 ins_encode %{ 11303 __ btsq($dst$$Address, log2i_exact((julong)$con$$constant)); 11304 %} 11305 ins_pipe(ialu_mem_imm); 11306 %} 11307 11308 // Xor Instructions 11309 // Xor Register with Register 11310 instruct xorL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 11311 %{ 11312 predicate(!UseAPX); 11313 match(Set dst (XorL dst src)); 11314 effect(KILL cr); 11315 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); 11316 11317 format %{ "xorq $dst, $src\t# long" %} 11318 ins_encode %{ 11319 __ xorq($dst$$Register, $src$$Register); 11320 %} 11321 ins_pipe(ialu_reg_reg); 11322 %} 11323 11324 // Xor Register with Register using New Data Destination (NDD) 11325 instruct xorL_rReg_ndd(rRegL dst, rRegL src1, rRegL src2, rFlagsReg cr) 11326 %{ 11327 predicate(UseAPX); 11328 match(Set dst (XorL src1 src2)); 11329 effect(KILL cr); 11330 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); 11331 11332 format %{ "exorq $dst, $src1, $src2\t# long ndd" %} 11333 ins_encode %{ 11334 __ exorq($dst$$Register, $src1$$Register, $src2$$Register, false); 11335 %} 11336 ins_pipe(ialu_reg_reg); 11337 %} 11338 11339 // Xor Register with Immediate -1 11340 instruct xorL_rReg_im1(rRegL dst, immL_M1 imm) 11341 %{ 11342 predicate(!UseAPX); 11343 match(Set dst (XorL dst imm)); 11344 11345 format %{ "notq $dst" %} 11346 ins_encode %{ 11347 __ notq($dst$$Register); 11348 %} 11349 ins_pipe(ialu_reg); 11350 %} 11351 11352 instruct xorL_rReg_im1_ndd(rRegL dst,rRegL src, immL_M1 imm) 11353 %{ 11354 predicate(UseAPX); 11355 match(Set dst (XorL src imm)); 11356 11357 format %{ "enotq $dst, $src" %} 11358 ins_encode %{ 11359 __ enotq($dst$$Register, $src$$Register); 11360 %} 11361 ins_pipe(ialu_reg); 11362 %} 11363 11364 // Xor Register with Immediate 11365 instruct xorL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 11366 %{ 11367 predicate(!UseAPX); 11368 match(Set dst (XorL dst src)); 11369 effect(KILL cr); 11370 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); 11371 11372 format %{ "xorq $dst, $src\t# long" %} 11373 ins_encode %{ 11374 __ xorq($dst$$Register, $src$$constant); 11375 %} 11376 ins_pipe(ialu_reg); 11377 %} 11378 11379 instruct xorL_rReg_rReg_imm(rRegL dst, rRegL src1, immL32 src2, rFlagsReg cr) 11380 %{ 11381 predicate(UseAPX); 11382 match(Set dst (XorL src1 src2)); 11383 effect(KILL cr); 11384 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); 11385 11386 format %{ "exorq $dst, $src1, $src2\t# long ndd" %} 11387 ins_encode %{ 11388 __ exorq($dst$$Register, $src1$$Register, $src2$$constant, false); 11389 %} 11390 ins_pipe(ialu_reg); 11391 %} 11392 11393 // Xor Memory with Immediate 11394 instruct xorL_rReg_mem_imm(rRegL dst, memory src1, immL32 src2, rFlagsReg cr) 11395 %{ 11396 predicate(UseAPX); 11397 match(Set dst (XorL (LoadL src1) src2)); 11398 effect(KILL cr); 11399 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); 11400 11401 format %{ "exorq $dst, $src1, $src2\t# long ndd" %} 11402 ins_encode %{ 11403 __ exorq($dst$$Register, $src1$$Address, $src2$$constant, false); 11404 %} 11405 ins_pipe(ialu_reg); 11406 %} 11407 11408 // Xor Register with Memory 11409 instruct xorL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 11410 %{ 11411 predicate(!UseAPX); 11412 match(Set dst (XorL dst (LoadL src))); 11413 effect(KILL cr); 11414 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); 11415 11416 ins_cost(150); 11417 format %{ "xorq $dst, $src\t# long" %} 11418 ins_encode %{ 11419 __ xorq($dst$$Register, $src$$Address); 11420 %} 11421 ins_pipe(ialu_reg_mem); 11422 %} 11423 11424 instruct xorL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr) 11425 %{ 11426 predicate(UseAPX); 11427 match(Set dst (XorL src1 (LoadL src2))); 11428 effect(KILL cr); 11429 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); 11430 11431 ins_cost(150); 11432 format %{ "exorq $dst, $src1, $src2\t# long ndd" %} 11433 ins_encode %{ 11434 __ exorq($dst$$Register, $src1$$Register, $src2$$Address, false); 11435 %} 11436 ins_pipe(ialu_reg_mem); 11437 %} 11438 11439 instruct xorL_rReg_mem_rReg_ndd(rRegL dst, memory src1, rRegL src2, rFlagsReg cr) 11440 %{ 11441 predicate(UseAPX); 11442 match(Set dst (XorL (LoadL src1) src2)); 11443 effect(KILL cr); 11444 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); 11445 11446 ins_cost(150); 11447 format %{ "exorq $dst, $src1, $src2\t# long ndd" %} 11448 ins_encode %{ 11449 __ exorq($dst$$Register, $src1$$Address, $src2$$Register, false); 11450 %} 11451 ins_pipe(ialu_reg_mem); 11452 %} 11453 11454 // Xor Memory with Register 11455 instruct xorL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 11456 %{ 11457 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 11458 effect(KILL cr); 11459 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); 11460 11461 ins_cost(150); 11462 format %{ "xorq $dst, $src\t# long" %} 11463 ins_encode %{ 11464 __ xorq($dst$$Address, $src$$Register); 11465 %} 11466 ins_pipe(ialu_mem_reg); 11467 %} 11468 11469 // Xor Memory with Immediate 11470 instruct xorL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 11471 %{ 11472 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 11473 effect(KILL cr); 11474 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); 11475 11476 ins_cost(125); 11477 format %{ "xorq $dst, $src\t# long" %} 11478 ins_encode %{ 11479 __ xorq($dst$$Address, $src$$constant); 11480 %} 11481 ins_pipe(ialu_mem_imm); 11482 %} 11483 11484 instruct cmpLTMask(rRegI dst, rRegI p, rRegI q, rFlagsReg cr) 11485 %{ 11486 match(Set dst (CmpLTMask p q)); 11487 effect(KILL cr); 11488 11489 ins_cost(400); 11490 format %{ "cmpl $p, $q\t# cmpLTMask\n\t" 11491 "setcc $dst \t# emits setlt + movzbl or setzul for APX" 11492 "negl $dst" %} 11493 ins_encode %{ 11494 __ cmpl($p$$Register, $q$$Register); 11495 __ setcc(Assembler::less, $dst$$Register); 11496 __ negl($dst$$Register); 11497 %} 11498 ins_pipe(pipe_slow); 11499 %} 11500 11501 instruct cmpLTMask0(rRegI dst, immI_0 zero, rFlagsReg cr) 11502 %{ 11503 match(Set dst (CmpLTMask dst zero)); 11504 effect(KILL cr); 11505 11506 ins_cost(100); 11507 format %{ "sarl $dst, #31\t# cmpLTMask0" %} 11508 ins_encode %{ 11509 __ sarl($dst$$Register, 31); 11510 %} 11511 ins_pipe(ialu_reg); 11512 %} 11513 11514 /* Better to save a register than avoid a branch */ 11515 instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 11516 %{ 11517 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q))); 11518 effect(KILL cr); 11519 ins_cost(300); 11520 format %{ "subl $p,$q\t# cadd_cmpLTMask\n\t" 11521 "jge done\n\t" 11522 "addl $p,$y\n" 11523 "done: " %} 11524 ins_encode %{ 11525 Register Rp = $p$$Register; 11526 Register Rq = $q$$Register; 11527 Register Ry = $y$$Register; 11528 Label done; 11529 __ subl(Rp, Rq); 11530 __ jccb(Assembler::greaterEqual, done); 11531 __ addl(Rp, Ry); 11532 __ bind(done); 11533 %} 11534 ins_pipe(pipe_cmplt); 11535 %} 11536 11537 /* Better to save a register than avoid a branch */ 11538 instruct and_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 11539 %{ 11540 match(Set y (AndI (CmpLTMask p q) y)); 11541 effect(KILL cr); 11542 11543 ins_cost(300); 11544 11545 format %{ "cmpl $p, $q\t# and_cmpLTMask\n\t" 11546 "jlt done\n\t" 11547 "xorl $y, $y\n" 11548 "done: " %} 11549 ins_encode %{ 11550 Register Rp = $p$$Register; 11551 Register Rq = $q$$Register; 11552 Register Ry = $y$$Register; 11553 Label done; 11554 __ cmpl(Rp, Rq); 11555 __ jccb(Assembler::less, done); 11556 __ xorl(Ry, Ry); 11557 __ bind(done); 11558 %} 11559 ins_pipe(pipe_cmplt); 11560 %} 11561 11562 11563 //---------- FP Instructions------------------------------------------------ 11564 11565 // Really expensive, avoid 11566 instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2) 11567 %{ 11568 match(Set cr (CmpF src1 src2)); 11569 11570 ins_cost(500); 11571 format %{ "ucomiss $src1, $src2\n\t" 11572 "jnp,s exit\n\t" 11573 "pushfq\t# saw NaN, set CF\n\t" 11574 "andq [rsp], #0xffffff2b\n\t" 11575 "popfq\n" 11576 "exit:" %} 11577 ins_encode %{ 11578 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 11579 emit_cmpfp_fixup(masm); 11580 %} 11581 ins_pipe(pipe_slow); 11582 %} 11583 11584 instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{ 11585 match(Set cr (CmpF src1 src2)); 11586 11587 ins_cost(100); 11588 format %{ "ucomiss $src1, $src2" %} 11589 ins_encode %{ 11590 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 11591 %} 11592 ins_pipe(pipe_slow); 11593 %} 11594 11595 instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{ 11596 match(Set cr (CmpF src1 (LoadF src2))); 11597 11598 ins_cost(100); 11599 format %{ "ucomiss $src1, $src2" %} 11600 ins_encode %{ 11601 __ ucomiss($src1$$XMMRegister, $src2$$Address); 11602 %} 11603 ins_pipe(pipe_slow); 11604 %} 11605 11606 instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src, immF con) %{ 11607 match(Set cr (CmpF src con)); 11608 ins_cost(100); 11609 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con" %} 11610 ins_encode %{ 11611 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 11612 %} 11613 ins_pipe(pipe_slow); 11614 %} 11615 11616 // Really expensive, avoid 11617 instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2) 11618 %{ 11619 match(Set cr (CmpD src1 src2)); 11620 11621 ins_cost(500); 11622 format %{ "ucomisd $src1, $src2\n\t" 11623 "jnp,s exit\n\t" 11624 "pushfq\t# saw NaN, set CF\n\t" 11625 "andq [rsp], #0xffffff2b\n\t" 11626 "popfq\n" 11627 "exit:" %} 11628 ins_encode %{ 11629 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 11630 emit_cmpfp_fixup(masm); 11631 %} 11632 ins_pipe(pipe_slow); 11633 %} 11634 11635 instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{ 11636 match(Set cr (CmpD src1 src2)); 11637 11638 ins_cost(100); 11639 format %{ "ucomisd $src1, $src2 test" %} 11640 ins_encode %{ 11641 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 11642 %} 11643 ins_pipe(pipe_slow); 11644 %} 11645 11646 instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{ 11647 match(Set cr (CmpD src1 (LoadD src2))); 11648 11649 ins_cost(100); 11650 format %{ "ucomisd $src1, $src2" %} 11651 ins_encode %{ 11652 __ ucomisd($src1$$XMMRegister, $src2$$Address); 11653 %} 11654 ins_pipe(pipe_slow); 11655 %} 11656 11657 instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src, immD con) %{ 11658 match(Set cr (CmpD src con)); 11659 ins_cost(100); 11660 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con" %} 11661 ins_encode %{ 11662 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 11663 %} 11664 ins_pipe(pipe_slow); 11665 %} 11666 11667 // Compare into -1,0,1 11668 instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr) 11669 %{ 11670 match(Set dst (CmpF3 src1 src2)); 11671 effect(KILL cr); 11672 11673 ins_cost(275); 11674 format %{ "ucomiss $src1, $src2\n\t" 11675 "movl $dst, #-1\n\t" 11676 "jp,s done\n\t" 11677 "jb,s done\n\t" 11678 "setne $dst\n\t" 11679 "movzbl $dst, $dst\n" 11680 "done:" %} 11681 ins_encode %{ 11682 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 11683 emit_cmpfp3(masm, $dst$$Register); 11684 %} 11685 ins_pipe(pipe_slow); 11686 %} 11687 11688 // Compare into -1,0,1 11689 instruct cmpF_mem(rRegI dst, regF src1, memory src2, rFlagsReg cr) 11690 %{ 11691 match(Set dst (CmpF3 src1 (LoadF src2))); 11692 effect(KILL cr); 11693 11694 ins_cost(275); 11695 format %{ "ucomiss $src1, $src2\n\t" 11696 "movl $dst, #-1\n\t" 11697 "jp,s done\n\t" 11698 "jb,s done\n\t" 11699 "setne $dst\n\t" 11700 "movzbl $dst, $dst\n" 11701 "done:" %} 11702 ins_encode %{ 11703 __ ucomiss($src1$$XMMRegister, $src2$$Address); 11704 emit_cmpfp3(masm, $dst$$Register); 11705 %} 11706 ins_pipe(pipe_slow); 11707 %} 11708 11709 // Compare into -1,0,1 11710 instruct cmpF_imm(rRegI dst, regF src, immF con, rFlagsReg cr) %{ 11711 match(Set dst (CmpF3 src con)); 11712 effect(KILL cr); 11713 11714 ins_cost(275); 11715 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 11716 "movl $dst, #-1\n\t" 11717 "jp,s done\n\t" 11718 "jb,s done\n\t" 11719 "setne $dst\n\t" 11720 "movzbl $dst, $dst\n" 11721 "done:" %} 11722 ins_encode %{ 11723 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 11724 emit_cmpfp3(masm, $dst$$Register); 11725 %} 11726 ins_pipe(pipe_slow); 11727 %} 11728 11729 // Compare into -1,0,1 11730 instruct cmpD_reg(rRegI dst, regD src1, regD src2, rFlagsReg cr) 11731 %{ 11732 match(Set dst (CmpD3 src1 src2)); 11733 effect(KILL cr); 11734 11735 ins_cost(275); 11736 format %{ "ucomisd $src1, $src2\n\t" 11737 "movl $dst, #-1\n\t" 11738 "jp,s done\n\t" 11739 "jb,s done\n\t" 11740 "setne $dst\n\t" 11741 "movzbl $dst, $dst\n" 11742 "done:" %} 11743 ins_encode %{ 11744 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 11745 emit_cmpfp3(masm, $dst$$Register); 11746 %} 11747 ins_pipe(pipe_slow); 11748 %} 11749 11750 // Compare into -1,0,1 11751 instruct cmpD_mem(rRegI dst, regD src1, memory src2, rFlagsReg cr) 11752 %{ 11753 match(Set dst (CmpD3 src1 (LoadD src2))); 11754 effect(KILL cr); 11755 11756 ins_cost(275); 11757 format %{ "ucomisd $src1, $src2\n\t" 11758 "movl $dst, #-1\n\t" 11759 "jp,s done\n\t" 11760 "jb,s done\n\t" 11761 "setne $dst\n\t" 11762 "movzbl $dst, $dst\n" 11763 "done:" %} 11764 ins_encode %{ 11765 __ ucomisd($src1$$XMMRegister, $src2$$Address); 11766 emit_cmpfp3(masm, $dst$$Register); 11767 %} 11768 ins_pipe(pipe_slow); 11769 %} 11770 11771 // Compare into -1,0,1 11772 instruct cmpD_imm(rRegI dst, regD src, immD con, rFlagsReg cr) %{ 11773 match(Set dst (CmpD3 src con)); 11774 effect(KILL cr); 11775 11776 ins_cost(275); 11777 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 11778 "movl $dst, #-1\n\t" 11779 "jp,s done\n\t" 11780 "jb,s done\n\t" 11781 "setne $dst\n\t" 11782 "movzbl $dst, $dst\n" 11783 "done:" %} 11784 ins_encode %{ 11785 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 11786 emit_cmpfp3(masm, $dst$$Register); 11787 %} 11788 ins_pipe(pipe_slow); 11789 %} 11790 11791 //----------Arithmetic Conversion Instructions--------------------------------- 11792 11793 instruct convF2D_reg_reg(regD dst, regF src) 11794 %{ 11795 match(Set dst (ConvF2D src)); 11796 11797 format %{ "cvtss2sd $dst, $src" %} 11798 ins_encode %{ 11799 __ cvtss2sd ($dst$$XMMRegister, $src$$XMMRegister); 11800 %} 11801 ins_pipe(pipe_slow); // XXX 11802 %} 11803 11804 instruct convF2D_reg_mem(regD dst, memory src) 11805 %{ 11806 predicate(UseAVX == 0); 11807 match(Set dst (ConvF2D (LoadF src))); 11808 11809 format %{ "cvtss2sd $dst, $src" %} 11810 ins_encode %{ 11811 __ cvtss2sd ($dst$$XMMRegister, $src$$Address); 11812 %} 11813 ins_pipe(pipe_slow); // XXX 11814 %} 11815 11816 instruct convD2F_reg_reg(regF dst, regD src) 11817 %{ 11818 match(Set dst (ConvD2F src)); 11819 11820 format %{ "cvtsd2ss $dst, $src" %} 11821 ins_encode %{ 11822 __ cvtsd2ss ($dst$$XMMRegister, $src$$XMMRegister); 11823 %} 11824 ins_pipe(pipe_slow); // XXX 11825 %} 11826 11827 instruct convD2F_reg_mem(regF dst, memory src) 11828 %{ 11829 predicate(UseAVX == 0); 11830 match(Set dst (ConvD2F (LoadD src))); 11831 11832 format %{ "cvtsd2ss $dst, $src" %} 11833 ins_encode %{ 11834 __ cvtsd2ss ($dst$$XMMRegister, $src$$Address); 11835 %} 11836 ins_pipe(pipe_slow); // XXX 11837 %} 11838 11839 // XXX do mem variants 11840 instruct convF2I_reg_reg(rRegI dst, regF src, rFlagsReg cr) 11841 %{ 11842 match(Set dst (ConvF2I src)); 11843 effect(KILL cr); 11844 format %{ "convert_f2i $dst, $src" %} 11845 ins_encode %{ 11846 __ convertF2I(T_INT, T_FLOAT, $dst$$Register, $src$$XMMRegister); 11847 %} 11848 ins_pipe(pipe_slow); 11849 %} 11850 11851 instruct convF2L_reg_reg(rRegL dst, regF src, rFlagsReg cr) 11852 %{ 11853 match(Set dst (ConvF2L src)); 11854 effect(KILL cr); 11855 format %{ "convert_f2l $dst, $src"%} 11856 ins_encode %{ 11857 __ convertF2I(T_LONG, T_FLOAT, $dst$$Register, $src$$XMMRegister); 11858 %} 11859 ins_pipe(pipe_slow); 11860 %} 11861 11862 instruct convD2I_reg_reg(rRegI dst, regD src, rFlagsReg cr) 11863 %{ 11864 match(Set dst (ConvD2I src)); 11865 effect(KILL cr); 11866 format %{ "convert_d2i $dst, $src"%} 11867 ins_encode %{ 11868 __ convertF2I(T_INT, T_DOUBLE, $dst$$Register, $src$$XMMRegister); 11869 %} 11870 ins_pipe(pipe_slow); 11871 %} 11872 11873 instruct convD2L_reg_reg(rRegL dst, regD src, rFlagsReg cr) 11874 %{ 11875 match(Set dst (ConvD2L src)); 11876 effect(KILL cr); 11877 format %{ "convert_d2l $dst, $src"%} 11878 ins_encode %{ 11879 __ convertF2I(T_LONG, T_DOUBLE, $dst$$Register, $src$$XMMRegister); 11880 %} 11881 ins_pipe(pipe_slow); 11882 %} 11883 11884 instruct round_double_reg(rRegL dst, regD src, rRegL rtmp, rcx_RegL rcx, rFlagsReg cr) 11885 %{ 11886 match(Set dst (RoundD src)); 11887 effect(TEMP dst, TEMP rtmp, TEMP rcx, KILL cr); 11888 format %{ "round_double $dst,$src \t! using $rtmp and $rcx as TEMP"%} 11889 ins_encode %{ 11890 __ round_double($dst$$Register, $src$$XMMRegister, $rtmp$$Register, $rcx$$Register); 11891 %} 11892 ins_pipe(pipe_slow); 11893 %} 11894 11895 instruct round_float_reg(rRegI dst, regF src, rRegL rtmp, rcx_RegL rcx, rFlagsReg cr) 11896 %{ 11897 match(Set dst (RoundF src)); 11898 effect(TEMP dst, TEMP rtmp, TEMP rcx, KILL cr); 11899 format %{ "round_float $dst,$src" %} 11900 ins_encode %{ 11901 __ round_float($dst$$Register, $src$$XMMRegister, $rtmp$$Register, $rcx$$Register); 11902 %} 11903 ins_pipe(pipe_slow); 11904 %} 11905 11906 instruct convI2F_reg_reg(vlRegF dst, rRegI src) 11907 %{ 11908 predicate(!UseXmmI2F); 11909 match(Set dst (ConvI2F src)); 11910 11911 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 11912 ins_encode %{ 11913 if (UseAVX > 0) { 11914 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 11915 } 11916 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Register); 11917 %} 11918 ins_pipe(pipe_slow); // XXX 11919 %} 11920 11921 instruct convI2F_reg_mem(regF dst, memory src) 11922 %{ 11923 predicate(UseAVX == 0); 11924 match(Set dst (ConvI2F (LoadI src))); 11925 11926 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 11927 ins_encode %{ 11928 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Address); 11929 %} 11930 ins_pipe(pipe_slow); // XXX 11931 %} 11932 11933 instruct convI2D_reg_reg(vlRegD dst, rRegI src) 11934 %{ 11935 predicate(!UseXmmI2D); 11936 match(Set dst (ConvI2D src)); 11937 11938 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 11939 ins_encode %{ 11940 if (UseAVX > 0) { 11941 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 11942 } 11943 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Register); 11944 %} 11945 ins_pipe(pipe_slow); // XXX 11946 %} 11947 11948 instruct convI2D_reg_mem(regD dst, memory src) 11949 %{ 11950 predicate(UseAVX == 0); 11951 match(Set dst (ConvI2D (LoadI src))); 11952 11953 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 11954 ins_encode %{ 11955 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Address); 11956 %} 11957 ins_pipe(pipe_slow); // XXX 11958 %} 11959 11960 instruct convXI2F_reg(regF dst, rRegI src) 11961 %{ 11962 predicate(UseXmmI2F); 11963 match(Set dst (ConvI2F src)); 11964 11965 format %{ "movdl $dst, $src\n\t" 11966 "cvtdq2psl $dst, $dst\t# i2f" %} 11967 ins_encode %{ 11968 __ movdl($dst$$XMMRegister, $src$$Register); 11969 __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister); 11970 %} 11971 ins_pipe(pipe_slow); // XXX 11972 %} 11973 11974 instruct convXI2D_reg(regD dst, rRegI src) 11975 %{ 11976 predicate(UseXmmI2D); 11977 match(Set dst (ConvI2D src)); 11978 11979 format %{ "movdl $dst, $src\n\t" 11980 "cvtdq2pdl $dst, $dst\t# i2d" %} 11981 ins_encode %{ 11982 __ movdl($dst$$XMMRegister, $src$$Register); 11983 __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister); 11984 %} 11985 ins_pipe(pipe_slow); // XXX 11986 %} 11987 11988 instruct convL2F_reg_reg(vlRegF dst, rRegL src) 11989 %{ 11990 match(Set dst (ConvL2F src)); 11991 11992 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 11993 ins_encode %{ 11994 if (UseAVX > 0) { 11995 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 11996 } 11997 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Register); 11998 %} 11999 ins_pipe(pipe_slow); // XXX 12000 %} 12001 12002 instruct convL2F_reg_mem(regF dst, memory src) 12003 %{ 12004 predicate(UseAVX == 0); 12005 match(Set dst (ConvL2F (LoadL src))); 12006 12007 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 12008 ins_encode %{ 12009 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Address); 12010 %} 12011 ins_pipe(pipe_slow); // XXX 12012 %} 12013 12014 instruct convL2D_reg_reg(vlRegD dst, rRegL src) 12015 %{ 12016 match(Set dst (ConvL2D src)); 12017 12018 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 12019 ins_encode %{ 12020 if (UseAVX > 0) { 12021 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 12022 } 12023 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Register); 12024 %} 12025 ins_pipe(pipe_slow); // XXX 12026 %} 12027 12028 instruct convL2D_reg_mem(regD dst, memory src) 12029 %{ 12030 predicate(UseAVX == 0); 12031 match(Set dst (ConvL2D (LoadL src))); 12032 12033 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 12034 ins_encode %{ 12035 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Address); 12036 %} 12037 ins_pipe(pipe_slow); // XXX 12038 %} 12039 12040 instruct convI2L_reg_reg(rRegL dst, rRegI src) 12041 %{ 12042 match(Set dst (ConvI2L src)); 12043 12044 ins_cost(125); 12045 format %{ "movslq $dst, $src\t# i2l" %} 12046 ins_encode %{ 12047 __ movslq($dst$$Register, $src$$Register); 12048 %} 12049 ins_pipe(ialu_reg_reg); 12050 %} 12051 12052 // Zero-extend convert int to long 12053 instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask) 12054 %{ 12055 match(Set dst (AndL (ConvI2L src) mask)); 12056 12057 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 12058 ins_encode %{ 12059 if ($dst$$reg != $src$$reg) { 12060 __ movl($dst$$Register, $src$$Register); 12061 } 12062 %} 12063 ins_pipe(ialu_reg_reg); 12064 %} 12065 12066 // Zero-extend convert int to long 12067 instruct convI2L_reg_mem_zex(rRegL dst, memory src, immL_32bits mask) 12068 %{ 12069 match(Set dst (AndL (ConvI2L (LoadI src)) mask)); 12070 12071 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 12072 ins_encode %{ 12073 __ movl($dst$$Register, $src$$Address); 12074 %} 12075 ins_pipe(ialu_reg_mem); 12076 %} 12077 12078 instruct zerox_long_reg_reg(rRegL dst, rRegL src, immL_32bits mask) 12079 %{ 12080 match(Set dst (AndL src mask)); 12081 12082 format %{ "movl $dst, $src\t# zero-extend long" %} 12083 ins_encode %{ 12084 __ movl($dst$$Register, $src$$Register); 12085 %} 12086 ins_pipe(ialu_reg_reg); 12087 %} 12088 12089 instruct convL2I_reg_reg(rRegI dst, rRegL src) 12090 %{ 12091 match(Set dst (ConvL2I src)); 12092 12093 format %{ "movl $dst, $src\t# l2i" %} 12094 ins_encode %{ 12095 __ movl($dst$$Register, $src$$Register); 12096 %} 12097 ins_pipe(ialu_reg_reg); 12098 %} 12099 12100 12101 instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{ 12102 match(Set dst (MoveF2I src)); 12103 effect(DEF dst, USE src); 12104 12105 ins_cost(125); 12106 format %{ "movl $dst, $src\t# MoveF2I_stack_reg" %} 12107 ins_encode %{ 12108 __ movl($dst$$Register, Address(rsp, $src$$disp)); 12109 %} 12110 ins_pipe(ialu_reg_mem); 12111 %} 12112 12113 instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{ 12114 match(Set dst (MoveI2F src)); 12115 effect(DEF dst, USE src); 12116 12117 ins_cost(125); 12118 format %{ "movss $dst, $src\t# MoveI2F_stack_reg" %} 12119 ins_encode %{ 12120 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 12121 %} 12122 ins_pipe(pipe_slow); 12123 %} 12124 12125 instruct MoveD2L_stack_reg(rRegL dst, stackSlotD src) %{ 12126 match(Set dst (MoveD2L src)); 12127 effect(DEF dst, USE src); 12128 12129 ins_cost(125); 12130 format %{ "movq $dst, $src\t# MoveD2L_stack_reg" %} 12131 ins_encode %{ 12132 __ movq($dst$$Register, Address(rsp, $src$$disp)); 12133 %} 12134 ins_pipe(ialu_reg_mem); 12135 %} 12136 12137 instruct MoveL2D_stack_reg_partial(regD dst, stackSlotL src) %{ 12138 predicate(!UseXmmLoadAndClearUpper); 12139 match(Set dst (MoveL2D src)); 12140 effect(DEF dst, USE src); 12141 12142 ins_cost(125); 12143 format %{ "movlpd $dst, $src\t# MoveL2D_stack_reg" %} 12144 ins_encode %{ 12145 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 12146 %} 12147 ins_pipe(pipe_slow); 12148 %} 12149 12150 instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{ 12151 predicate(UseXmmLoadAndClearUpper); 12152 match(Set dst (MoveL2D src)); 12153 effect(DEF dst, USE src); 12154 12155 ins_cost(125); 12156 format %{ "movsd $dst, $src\t# MoveL2D_stack_reg" %} 12157 ins_encode %{ 12158 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 12159 %} 12160 ins_pipe(pipe_slow); 12161 %} 12162 12163 12164 instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{ 12165 match(Set dst (MoveF2I src)); 12166 effect(DEF dst, USE src); 12167 12168 ins_cost(95); // XXX 12169 format %{ "movss $dst, $src\t# MoveF2I_reg_stack" %} 12170 ins_encode %{ 12171 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 12172 %} 12173 ins_pipe(pipe_slow); 12174 %} 12175 12176 instruct MoveI2F_reg_stack(stackSlotF dst, rRegI src) %{ 12177 match(Set dst (MoveI2F src)); 12178 effect(DEF dst, USE src); 12179 12180 ins_cost(100); 12181 format %{ "movl $dst, $src\t# MoveI2F_reg_stack" %} 12182 ins_encode %{ 12183 __ movl(Address(rsp, $dst$$disp), $src$$Register); 12184 %} 12185 ins_pipe( ialu_mem_reg ); 12186 %} 12187 12188 instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{ 12189 match(Set dst (MoveD2L src)); 12190 effect(DEF dst, USE src); 12191 12192 ins_cost(95); // XXX 12193 format %{ "movsd $dst, $src\t# MoveL2D_reg_stack" %} 12194 ins_encode %{ 12195 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 12196 %} 12197 ins_pipe(pipe_slow); 12198 %} 12199 12200 instruct MoveL2D_reg_stack(stackSlotD dst, rRegL src) %{ 12201 match(Set dst (MoveL2D src)); 12202 effect(DEF dst, USE src); 12203 12204 ins_cost(100); 12205 format %{ "movq $dst, $src\t# MoveL2D_reg_stack" %} 12206 ins_encode %{ 12207 __ movq(Address(rsp, $dst$$disp), $src$$Register); 12208 %} 12209 ins_pipe(ialu_mem_reg); 12210 %} 12211 12212 instruct MoveF2I_reg_reg(rRegI dst, regF src) %{ 12213 match(Set dst (MoveF2I src)); 12214 effect(DEF dst, USE src); 12215 ins_cost(85); 12216 format %{ "movd $dst,$src\t# MoveF2I" %} 12217 ins_encode %{ 12218 __ movdl($dst$$Register, $src$$XMMRegister); 12219 %} 12220 ins_pipe( pipe_slow ); 12221 %} 12222 12223 instruct MoveD2L_reg_reg(rRegL dst, regD src) %{ 12224 match(Set dst (MoveD2L src)); 12225 effect(DEF dst, USE src); 12226 ins_cost(85); 12227 format %{ "movd $dst,$src\t# MoveD2L" %} 12228 ins_encode %{ 12229 __ movdq($dst$$Register, $src$$XMMRegister); 12230 %} 12231 ins_pipe( pipe_slow ); 12232 %} 12233 12234 instruct MoveI2F_reg_reg(regF dst, rRegI src) %{ 12235 match(Set dst (MoveI2F src)); 12236 effect(DEF dst, USE src); 12237 ins_cost(100); 12238 format %{ "movd $dst,$src\t# MoveI2F" %} 12239 ins_encode %{ 12240 __ movdl($dst$$XMMRegister, $src$$Register); 12241 %} 12242 ins_pipe( pipe_slow ); 12243 %} 12244 12245 instruct MoveL2D_reg_reg(regD dst, rRegL src) %{ 12246 match(Set dst (MoveL2D src)); 12247 effect(DEF dst, USE src); 12248 ins_cost(100); 12249 format %{ "movd $dst,$src\t# MoveL2D" %} 12250 ins_encode %{ 12251 __ movdq($dst$$XMMRegister, $src$$Register); 12252 %} 12253 ins_pipe( pipe_slow ); 12254 %} 12255 12256 12257 // Fast clearing of an array 12258 // Small non-constant lenght ClearArray for non-AVX512 targets. 12259 instruct rep_stos(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegL val, 12260 Universe dummy, rFlagsReg cr) 12261 %{ 12262 predicate(!((ClearArrayNode*)n)->is_large() && !((ClearArrayNode*)n)->word_copy_only() && (UseAVX <= 2)); 12263 match(Set dummy (ClearArray (Binary cnt base) val)); 12264 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, USE_KILL val, KILL cr); 12265 12266 format %{ $$template 12267 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 12268 $$emit$$"jg LARGE\n\t" 12269 $$emit$$"dec rcx\n\t" 12270 $$emit$$"js DONE\t# Zero length\n\t" 12271 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 12272 $$emit$$"dec rcx\n\t" 12273 $$emit$$"jge LOOP\n\t" 12274 $$emit$$"jmp DONE\n\t" 12275 $$emit$$"# LARGE:\n\t" 12276 if (UseFastStosb) { 12277 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 12278 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--\n\t" 12279 } else if (UseXMMForObjInit) { 12280 $$emit$$"movdq $tmp, $val\n\t" 12281 $$emit$$"punpcklqdq $tmp, $tmp\n\t" 12282 $$emit$$"vinserti128_high $tmp, $tmp\n\t" 12283 $$emit$$"jmpq L_zero_64_bytes\n\t" 12284 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 12285 $$emit$$"vmovdqu $tmp,(rax)\n\t" 12286 $$emit$$"vmovdqu $tmp,0x20(rax)\n\t" 12287 $$emit$$"add 0x40,rax\n\t" 12288 $$emit$$"# L_zero_64_bytes:\n\t" 12289 $$emit$$"sub 0x8,rcx\n\t" 12290 $$emit$$"jge L_loop\n\t" 12291 $$emit$$"add 0x4,rcx\n\t" 12292 $$emit$$"jl L_tail\n\t" 12293 $$emit$$"vmovdqu $tmp,(rax)\n\t" 12294 $$emit$$"add 0x20,rax\n\t" 12295 $$emit$$"sub 0x4,rcx\n\t" 12296 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 12297 $$emit$$"add 0x4,rcx\n\t" 12298 $$emit$$"jle L_end\n\t" 12299 $$emit$$"dec rcx\n\t" 12300 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 12301 $$emit$$"vmovq xmm0,(rax)\n\t" 12302 $$emit$$"add 0x8,rax\n\t" 12303 $$emit$$"dec rcx\n\t" 12304 $$emit$$"jge L_sloop\n\t" 12305 $$emit$$"# L_end:\n\t" 12306 } else { 12307 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 12308 } 12309 $$emit$$"# DONE" 12310 %} 12311 ins_encode %{ 12312 __ clear_mem($base$$Register, $cnt$$Register, $val$$Register, 12313 $tmp$$XMMRegister, false, false); 12314 %} 12315 ins_pipe(pipe_slow); 12316 %} 12317 12318 instruct rep_stos_word_copy(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegL val, 12319 Universe dummy, rFlagsReg cr) 12320 %{ 12321 predicate(!((ClearArrayNode*)n)->is_large() && ((ClearArrayNode*)n)->word_copy_only() && (UseAVX <= 2)); 12322 match(Set dummy (ClearArray (Binary cnt base) val)); 12323 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, USE_KILL val, KILL cr); 12324 12325 format %{ $$template 12326 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 12327 $$emit$$"jg LARGE\n\t" 12328 $$emit$$"dec rcx\n\t" 12329 $$emit$$"js DONE\t# Zero length\n\t" 12330 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 12331 $$emit$$"dec rcx\n\t" 12332 $$emit$$"jge LOOP\n\t" 12333 $$emit$$"jmp DONE\n\t" 12334 $$emit$$"# LARGE:\n\t" 12335 if (UseXMMForObjInit) { 12336 $$emit$$"movdq $tmp, $val\n\t" 12337 $$emit$$"punpcklqdq $tmp, $tmp\n\t" 12338 $$emit$$"vinserti128_high $tmp, $tmp\n\t" 12339 $$emit$$"jmpq L_zero_64_bytes\n\t" 12340 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 12341 $$emit$$"vmovdqu $tmp,(rax)\n\t" 12342 $$emit$$"vmovdqu $tmp,0x20(rax)\n\t" 12343 $$emit$$"add 0x40,rax\n\t" 12344 $$emit$$"# L_zero_64_bytes:\n\t" 12345 $$emit$$"sub 0x8,rcx\n\t" 12346 $$emit$$"jge L_loop\n\t" 12347 $$emit$$"add 0x4,rcx\n\t" 12348 $$emit$$"jl L_tail\n\t" 12349 $$emit$$"vmovdqu $tmp,(rax)\n\t" 12350 $$emit$$"add 0x20,rax\n\t" 12351 $$emit$$"sub 0x4,rcx\n\t" 12352 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 12353 $$emit$$"add 0x4,rcx\n\t" 12354 $$emit$$"jle L_end\n\t" 12355 $$emit$$"dec rcx\n\t" 12356 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 12357 $$emit$$"vmovq xmm0,(rax)\n\t" 12358 $$emit$$"add 0x8,rax\n\t" 12359 $$emit$$"dec rcx\n\t" 12360 $$emit$$"jge L_sloop\n\t" 12361 $$emit$$"# L_end:\n\t" 12362 } else { 12363 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 12364 } 12365 $$emit$$"# DONE" 12366 %} 12367 ins_encode %{ 12368 __ clear_mem($base$$Register, $cnt$$Register, $val$$Register, 12369 $tmp$$XMMRegister, false, true); 12370 %} 12371 ins_pipe(pipe_slow); 12372 %} 12373 12374 // Small non-constant length ClearArray for AVX512 targets. 12375 instruct rep_stos_evex(rcx_RegL cnt, rdi_RegP base, legRegD tmp, kReg ktmp, rax_RegL val, 12376 Universe dummy, rFlagsReg cr) 12377 %{ 12378 predicate(!((ClearArrayNode*)n)->is_large() && !((ClearArrayNode*)n)->word_copy_only() && (UseAVX > 2)); 12379 match(Set dummy (ClearArray (Binary cnt base) val)); 12380 ins_cost(125); 12381 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, TEMP ktmp, USE_KILL val, KILL cr); 12382 12383 format %{ $$template 12384 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 12385 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 12386 $$emit$$"jg LARGE\n\t" 12387 $$emit$$"dec rcx\n\t" 12388 $$emit$$"js DONE\t# Zero length\n\t" 12389 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 12390 $$emit$$"dec rcx\n\t" 12391 $$emit$$"jge LOOP\n\t" 12392 $$emit$$"jmp DONE\n\t" 12393 $$emit$$"# LARGE:\n\t" 12394 if (UseFastStosb) { 12395 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 12396 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--\n\t" 12397 } else if (UseXMMForObjInit) { 12398 $$emit$$"mov rdi,rax\n\t" 12399 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 12400 $$emit$$"jmpq L_zero_64_bytes\n\t" 12401 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 12402 $$emit$$"vmovdqu ymm0,(rax)\n\t" 12403 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 12404 $$emit$$"add 0x40,rax\n\t" 12405 $$emit$$"# L_zero_64_bytes:\n\t" 12406 $$emit$$"sub 0x8,rcx\n\t" 12407 $$emit$$"jge L_loop\n\t" 12408 $$emit$$"add 0x4,rcx\n\t" 12409 $$emit$$"jl L_tail\n\t" 12410 $$emit$$"vmovdqu ymm0,(rax)\n\t" 12411 $$emit$$"add 0x20,rax\n\t" 12412 $$emit$$"sub 0x4,rcx\n\t" 12413 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 12414 $$emit$$"add 0x4,rcx\n\t" 12415 $$emit$$"jle L_end\n\t" 12416 $$emit$$"dec rcx\n\t" 12417 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 12418 $$emit$$"vmovq xmm0,(rax)\n\t" 12419 $$emit$$"add 0x8,rax\n\t" 12420 $$emit$$"dec rcx\n\t" 12421 $$emit$$"jge L_sloop\n\t" 12422 $$emit$$"# L_end:\n\t" 12423 } else { 12424 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 12425 } 12426 $$emit$$"# DONE" 12427 %} 12428 ins_encode %{ 12429 __ clear_mem($base$$Register, $cnt$$Register, $val$$Register, 12430 $tmp$$XMMRegister, false, false, $ktmp$$KRegister); 12431 %} 12432 ins_pipe(pipe_slow); 12433 %} 12434 12435 instruct rep_stos_evex_word_copy(rcx_RegL cnt, rdi_RegP base, legRegD tmp, kReg ktmp, rax_RegL val, 12436 Universe dummy, rFlagsReg cr) 12437 %{ 12438 predicate(!((ClearArrayNode*)n)->is_large() && ((ClearArrayNode*)n)->word_copy_only() && (UseAVX > 2)); 12439 match(Set dummy (ClearArray (Binary cnt base) val)); 12440 ins_cost(125); 12441 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, TEMP ktmp, USE_KILL val, KILL cr); 12442 12443 format %{ $$template 12444 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 12445 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 12446 $$emit$$"jg LARGE\n\t" 12447 $$emit$$"dec rcx\n\t" 12448 $$emit$$"js DONE\t# Zero length\n\t" 12449 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 12450 $$emit$$"dec rcx\n\t" 12451 $$emit$$"jge LOOP\n\t" 12452 $$emit$$"jmp DONE\n\t" 12453 $$emit$$"# LARGE:\n\t" 12454 if (UseFastStosb) { 12455 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 12456 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--\n\t" 12457 } else if (UseXMMForObjInit) { 12458 $$emit$$"mov rdi,rax\n\t" 12459 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 12460 $$emit$$"jmpq L_zero_64_bytes\n\t" 12461 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 12462 $$emit$$"vmovdqu ymm0,(rax)\n\t" 12463 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 12464 $$emit$$"add 0x40,rax\n\t" 12465 $$emit$$"# L_zero_64_bytes:\n\t" 12466 $$emit$$"sub 0x8,rcx\n\t" 12467 $$emit$$"jge L_loop\n\t" 12468 $$emit$$"add 0x4,rcx\n\t" 12469 $$emit$$"jl L_tail\n\t" 12470 $$emit$$"vmovdqu ymm0,(rax)\n\t" 12471 $$emit$$"add 0x20,rax\n\t" 12472 $$emit$$"sub 0x4,rcx\n\t" 12473 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 12474 $$emit$$"add 0x4,rcx\n\t" 12475 $$emit$$"jle L_end\n\t" 12476 $$emit$$"dec rcx\n\t" 12477 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 12478 $$emit$$"vmovq xmm0,(rax)\n\t" 12479 $$emit$$"add 0x8,rax\n\t" 12480 $$emit$$"dec rcx\n\t" 12481 $$emit$$"jge L_sloop\n\t" 12482 $$emit$$"# L_end:\n\t" 12483 } else { 12484 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 12485 } 12486 $$emit$$"# DONE" 12487 %} 12488 ins_encode %{ 12489 __ clear_mem($base$$Register, $cnt$$Register, $val$$Register, 12490 $tmp$$XMMRegister, false, true, $ktmp$$KRegister); 12491 %} 12492 ins_pipe(pipe_slow); 12493 %} 12494 12495 // Large non-constant length ClearArray for non-AVX512 targets. 12496 instruct rep_stos_large(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegL val, 12497 Universe dummy, rFlagsReg cr) 12498 %{ 12499 predicate(((ClearArrayNode*)n)->is_large() && !((ClearArrayNode*)n)->word_copy_only() && (UseAVX <= 2)); 12500 match(Set dummy (ClearArray (Binary cnt base) val)); 12501 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, USE_KILL val, KILL cr); 12502 12503 format %{ $$template 12504 if (UseFastStosb) { 12505 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 12506 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--" 12507 } else if (UseXMMForObjInit) { 12508 $$emit$$"movdq $tmp, $val\n\t" 12509 $$emit$$"punpcklqdq $tmp, $tmp\n\t" 12510 $$emit$$"vinserti128_high $tmp, $tmp\n\t" 12511 $$emit$$"jmpq L_zero_64_bytes\n\t" 12512 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 12513 $$emit$$"vmovdqu $tmp,(rax)\n\t" 12514 $$emit$$"vmovdqu $tmp,0x20(rax)\n\t" 12515 $$emit$$"add 0x40,rax\n\t" 12516 $$emit$$"# L_zero_64_bytes:\n\t" 12517 $$emit$$"sub 0x8,rcx\n\t" 12518 $$emit$$"jge L_loop\n\t" 12519 $$emit$$"add 0x4,rcx\n\t" 12520 $$emit$$"jl L_tail\n\t" 12521 $$emit$$"vmovdqu $tmp,(rax)\n\t" 12522 $$emit$$"add 0x20,rax\n\t" 12523 $$emit$$"sub 0x4,rcx\n\t" 12524 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 12525 $$emit$$"add 0x4,rcx\n\t" 12526 $$emit$$"jle L_end\n\t" 12527 $$emit$$"dec rcx\n\t" 12528 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 12529 $$emit$$"vmovq xmm0,(rax)\n\t" 12530 $$emit$$"add 0x8,rax\n\t" 12531 $$emit$$"dec rcx\n\t" 12532 $$emit$$"jge L_sloop\n\t" 12533 $$emit$$"# L_end:\n\t" 12534 } else { 12535 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 12536 } 12537 %} 12538 ins_encode %{ 12539 __ clear_mem($base$$Register, $cnt$$Register, $val$$Register, 12540 $tmp$$XMMRegister, true, false); 12541 %} 12542 ins_pipe(pipe_slow); 12543 %} 12544 12545 instruct rep_stos_large_word_copy(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegL val, 12546 Universe dummy, rFlagsReg cr) 12547 %{ 12548 predicate(((ClearArrayNode*)n)->is_large() && ((ClearArrayNode*)n)->word_copy_only() && (UseAVX <= 2)); 12549 match(Set dummy (ClearArray (Binary cnt base) val)); 12550 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, USE_KILL val, KILL cr); 12551 12552 format %{ $$template 12553 if (UseXMMForObjInit) { 12554 $$emit$$"movdq $tmp, $val\n\t" 12555 $$emit$$"punpcklqdq $tmp, $tmp\n\t" 12556 $$emit$$"vinserti128_high $tmp, $tmp\n\t" 12557 $$emit$$"jmpq L_zero_64_bytes\n\t" 12558 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 12559 $$emit$$"vmovdqu $tmp,(rax)\n\t" 12560 $$emit$$"vmovdqu $tmp,0x20(rax)\n\t" 12561 $$emit$$"add 0x40,rax\n\t" 12562 $$emit$$"# L_zero_64_bytes:\n\t" 12563 $$emit$$"sub 0x8,rcx\n\t" 12564 $$emit$$"jge L_loop\n\t" 12565 $$emit$$"add 0x4,rcx\n\t" 12566 $$emit$$"jl L_tail\n\t" 12567 $$emit$$"vmovdqu $tmp,(rax)\n\t" 12568 $$emit$$"add 0x20,rax\n\t" 12569 $$emit$$"sub 0x4,rcx\n\t" 12570 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 12571 $$emit$$"add 0x4,rcx\n\t" 12572 $$emit$$"jle L_end\n\t" 12573 $$emit$$"dec rcx\n\t" 12574 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 12575 $$emit$$"vmovq xmm0,(rax)\n\t" 12576 $$emit$$"add 0x8,rax\n\t" 12577 $$emit$$"dec rcx\n\t" 12578 $$emit$$"jge L_sloop\n\t" 12579 $$emit$$"# L_end:\n\t" 12580 } else { 12581 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 12582 } 12583 %} 12584 ins_encode %{ 12585 __ clear_mem($base$$Register, $cnt$$Register, $val$$Register, 12586 $tmp$$XMMRegister, true, true); 12587 %} 12588 ins_pipe(pipe_slow); 12589 %} 12590 12591 // Large non-constant length ClearArray for AVX512 targets. 12592 instruct rep_stos_large_evex(rcx_RegL cnt, rdi_RegP base, legRegD tmp, kReg ktmp, rax_RegL val, 12593 Universe dummy, rFlagsReg cr) 12594 %{ 12595 predicate(((ClearArrayNode*)n)->is_large() && !((ClearArrayNode*)n)->word_copy_only() && (UseAVX > 2)); 12596 match(Set dummy (ClearArray (Binary cnt base) val)); 12597 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, TEMP ktmp, USE_KILL val, KILL cr); 12598 12599 format %{ $$template 12600 if (UseFastStosb) { 12601 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 12602 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 12603 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--" 12604 } else if (UseXMMForObjInit) { 12605 $$emit$$"mov rdi,rax\t# ClearArray:\n\t" 12606 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 12607 $$emit$$"jmpq L_zero_64_bytes\n\t" 12608 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 12609 $$emit$$"vmovdqu ymm0,(rax)\n\t" 12610 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 12611 $$emit$$"add 0x40,rax\n\t" 12612 $$emit$$"# L_zero_64_bytes:\n\t" 12613 $$emit$$"sub 0x8,rcx\n\t" 12614 $$emit$$"jge L_loop\n\t" 12615 $$emit$$"add 0x4,rcx\n\t" 12616 $$emit$$"jl L_tail\n\t" 12617 $$emit$$"vmovdqu ymm0,(rax)\n\t" 12618 $$emit$$"add 0x20,rax\n\t" 12619 $$emit$$"sub 0x4,rcx\n\t" 12620 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 12621 $$emit$$"add 0x4,rcx\n\t" 12622 $$emit$$"jle L_end\n\t" 12623 $$emit$$"dec rcx\n\t" 12624 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 12625 $$emit$$"vmovq xmm0,(rax)\n\t" 12626 $$emit$$"add 0x8,rax\n\t" 12627 $$emit$$"dec rcx\n\t" 12628 $$emit$$"jge L_sloop\n\t" 12629 $$emit$$"# L_end:\n\t" 12630 } else { 12631 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 12632 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 12633 } 12634 %} 12635 ins_encode %{ 12636 __ clear_mem($base$$Register, $cnt$$Register, $val$$Register, 12637 $tmp$$XMMRegister, true, false, $ktmp$$KRegister); 12638 %} 12639 ins_pipe(pipe_slow); 12640 %} 12641 12642 instruct rep_stos_large_evex_word_copy(rcx_RegL cnt, rdi_RegP base, legRegD tmp, kReg ktmp, rax_RegL val, 12643 Universe dummy, rFlagsReg cr) 12644 %{ 12645 predicate(((ClearArrayNode*)n)->is_large() && ((ClearArrayNode*)n)->word_copy_only() && (UseAVX > 2)); 12646 match(Set dummy (ClearArray (Binary cnt base) val)); 12647 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, TEMP ktmp, USE_KILL val, KILL cr); 12648 12649 format %{ $$template 12650 if (UseFastStosb) { 12651 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 12652 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 12653 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--" 12654 } else if (UseXMMForObjInit) { 12655 $$emit$$"mov rdi,rax\t# ClearArray:\n\t" 12656 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 12657 $$emit$$"jmpq L_zero_64_bytes\n\t" 12658 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 12659 $$emit$$"vmovdqu ymm0,(rax)\n\t" 12660 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 12661 $$emit$$"add 0x40,rax\n\t" 12662 $$emit$$"# L_zero_64_bytes:\n\t" 12663 $$emit$$"sub 0x8,rcx\n\t" 12664 $$emit$$"jge L_loop\n\t" 12665 $$emit$$"add 0x4,rcx\n\t" 12666 $$emit$$"jl L_tail\n\t" 12667 $$emit$$"vmovdqu ymm0,(rax)\n\t" 12668 $$emit$$"add 0x20,rax\n\t" 12669 $$emit$$"sub 0x4,rcx\n\t" 12670 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 12671 $$emit$$"add 0x4,rcx\n\t" 12672 $$emit$$"jle L_end\n\t" 12673 $$emit$$"dec rcx\n\t" 12674 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 12675 $$emit$$"vmovq xmm0,(rax)\n\t" 12676 $$emit$$"add 0x8,rax\n\t" 12677 $$emit$$"dec rcx\n\t" 12678 $$emit$$"jge L_sloop\n\t" 12679 $$emit$$"# L_end:\n\t" 12680 } else { 12681 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 12682 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 12683 } 12684 %} 12685 ins_encode %{ 12686 __ clear_mem($base$$Register, $cnt$$Register, $val$$Register, 12687 $tmp$$XMMRegister, true, true, $ktmp$$KRegister); 12688 %} 12689 ins_pipe(pipe_slow); 12690 %} 12691 12692 // Small constant length ClearArray for AVX512 targets. 12693 instruct rep_stos_im(immL cnt, rRegP base, regD tmp, rax_RegL val, kReg ktmp, Universe dummy, rFlagsReg cr) 12694 %{ 12695 predicate(!((ClearArrayNode*)n)->is_large() && !((ClearArrayNode*)n)->word_copy_only() && 12696 ((MaxVectorSize >= 32) && VM_Version::supports_avx512vl())); 12697 match(Set dummy (ClearArray (Binary cnt base) val)); 12698 ins_cost(100); 12699 effect(TEMP tmp, USE_KILL val, TEMP ktmp, KILL cr); 12700 format %{ "clear_mem_imm $base , $cnt \n\t" %} 12701 ins_encode %{ 12702 __ clear_mem($base$$Register, $cnt$$constant, $val$$Register, $tmp$$XMMRegister, $ktmp$$KRegister); 12703 %} 12704 ins_pipe(pipe_slow); 12705 %} 12706 12707 instruct string_compareL(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 12708 rax_RegI result, legRegD tmp1, rFlagsReg cr) 12709 %{ 12710 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 12711 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12712 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 12713 12714 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 12715 ins_encode %{ 12716 __ string_compare($str1$$Register, $str2$$Register, 12717 $cnt1$$Register, $cnt2$$Register, $result$$Register, 12718 $tmp1$$XMMRegister, StrIntrinsicNode::LL, knoreg); 12719 %} 12720 ins_pipe( pipe_slow ); 12721 %} 12722 12723 instruct string_compareL_evex(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 12724 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 12725 %{ 12726 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 12727 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12728 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 12729 12730 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 12731 ins_encode %{ 12732 __ string_compare($str1$$Register, $str2$$Register, 12733 $cnt1$$Register, $cnt2$$Register, $result$$Register, 12734 $tmp1$$XMMRegister, StrIntrinsicNode::LL, $ktmp$$KRegister); 12735 %} 12736 ins_pipe( pipe_slow ); 12737 %} 12738 12739 instruct string_compareU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 12740 rax_RegI result, legRegD tmp1, rFlagsReg cr) 12741 %{ 12742 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 12743 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12744 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 12745 12746 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 12747 ins_encode %{ 12748 __ string_compare($str1$$Register, $str2$$Register, 12749 $cnt1$$Register, $cnt2$$Register, $result$$Register, 12750 $tmp1$$XMMRegister, StrIntrinsicNode::UU, knoreg); 12751 %} 12752 ins_pipe( pipe_slow ); 12753 %} 12754 12755 instruct string_compareU_evex(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 12756 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 12757 %{ 12758 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 12759 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12760 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 12761 12762 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 12763 ins_encode %{ 12764 __ string_compare($str1$$Register, $str2$$Register, 12765 $cnt1$$Register, $cnt2$$Register, $result$$Register, 12766 $tmp1$$XMMRegister, StrIntrinsicNode::UU, $ktmp$$KRegister); 12767 %} 12768 ins_pipe( pipe_slow ); 12769 %} 12770 12771 instruct string_compareLU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 12772 rax_RegI result, legRegD tmp1, rFlagsReg cr) 12773 %{ 12774 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 12775 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12776 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 12777 12778 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 12779 ins_encode %{ 12780 __ string_compare($str1$$Register, $str2$$Register, 12781 $cnt1$$Register, $cnt2$$Register, $result$$Register, 12782 $tmp1$$XMMRegister, StrIntrinsicNode::LU, knoreg); 12783 %} 12784 ins_pipe( pipe_slow ); 12785 %} 12786 12787 instruct string_compareLU_evex(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 12788 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 12789 %{ 12790 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 12791 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12792 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 12793 12794 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 12795 ins_encode %{ 12796 __ string_compare($str1$$Register, $str2$$Register, 12797 $cnt1$$Register, $cnt2$$Register, $result$$Register, 12798 $tmp1$$XMMRegister, StrIntrinsicNode::LU, $ktmp$$KRegister); 12799 %} 12800 ins_pipe( pipe_slow ); 12801 %} 12802 12803 instruct string_compareUL(rsi_RegP str1, rdx_RegI cnt1, rdi_RegP str2, rcx_RegI cnt2, 12804 rax_RegI result, legRegD tmp1, rFlagsReg cr) 12805 %{ 12806 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 12807 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12808 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 12809 12810 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 12811 ins_encode %{ 12812 __ string_compare($str2$$Register, $str1$$Register, 12813 $cnt2$$Register, $cnt1$$Register, $result$$Register, 12814 $tmp1$$XMMRegister, StrIntrinsicNode::UL, knoreg); 12815 %} 12816 ins_pipe( pipe_slow ); 12817 %} 12818 12819 instruct string_compareUL_evex(rsi_RegP str1, rdx_RegI cnt1, rdi_RegP str2, rcx_RegI cnt2, 12820 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 12821 %{ 12822 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 12823 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12824 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 12825 12826 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 12827 ins_encode %{ 12828 __ string_compare($str2$$Register, $str1$$Register, 12829 $cnt2$$Register, $cnt1$$Register, $result$$Register, 12830 $tmp1$$XMMRegister, StrIntrinsicNode::UL, $ktmp$$KRegister); 12831 %} 12832 ins_pipe( pipe_slow ); 12833 %} 12834 12835 // fast search of substring with known size. 12836 instruct string_indexof_conL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 12837 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 12838 %{ 12839 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 12840 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 12841 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 12842 12843 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %} 12844 ins_encode %{ 12845 int icnt2 = (int)$int_cnt2$$constant; 12846 if (icnt2 >= 16) { 12847 // IndexOf for constant substrings with size >= 16 elements 12848 // which don't need to be loaded through stack. 12849 __ string_indexofC8($str1$$Register, $str2$$Register, 12850 $cnt1$$Register, $cnt2$$Register, 12851 icnt2, $result$$Register, 12852 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 12853 } else { 12854 // Small strings are loaded through stack if they cross page boundary. 12855 __ string_indexof($str1$$Register, $str2$$Register, 12856 $cnt1$$Register, $cnt2$$Register, 12857 icnt2, $result$$Register, 12858 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 12859 } 12860 %} 12861 ins_pipe( pipe_slow ); 12862 %} 12863 12864 // fast search of substring with known size. 12865 instruct string_indexof_conU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 12866 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 12867 %{ 12868 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 12869 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 12870 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 12871 12872 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %} 12873 ins_encode %{ 12874 int icnt2 = (int)$int_cnt2$$constant; 12875 if (icnt2 >= 8) { 12876 // IndexOf for constant substrings with size >= 8 elements 12877 // which don't need to be loaded through stack. 12878 __ string_indexofC8($str1$$Register, $str2$$Register, 12879 $cnt1$$Register, $cnt2$$Register, 12880 icnt2, $result$$Register, 12881 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 12882 } else { 12883 // Small strings are loaded through stack if they cross page boundary. 12884 __ string_indexof($str1$$Register, $str2$$Register, 12885 $cnt1$$Register, $cnt2$$Register, 12886 icnt2, $result$$Register, 12887 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 12888 } 12889 %} 12890 ins_pipe( pipe_slow ); 12891 %} 12892 12893 // fast search of substring with known size. 12894 instruct string_indexof_conUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 12895 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 12896 %{ 12897 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 12898 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 12899 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 12900 12901 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %} 12902 ins_encode %{ 12903 int icnt2 = (int)$int_cnt2$$constant; 12904 if (icnt2 >= 8) { 12905 // IndexOf for constant substrings with size >= 8 elements 12906 // which don't need to be loaded through stack. 12907 __ string_indexofC8($str1$$Register, $str2$$Register, 12908 $cnt1$$Register, $cnt2$$Register, 12909 icnt2, $result$$Register, 12910 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 12911 } else { 12912 // Small strings are loaded through stack if they cross page boundary. 12913 __ string_indexof($str1$$Register, $str2$$Register, 12914 $cnt1$$Register, $cnt2$$Register, 12915 icnt2, $result$$Register, 12916 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 12917 } 12918 %} 12919 ins_pipe( pipe_slow ); 12920 %} 12921 12922 instruct string_indexofL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 12923 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr) 12924 %{ 12925 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 12926 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 12927 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 12928 12929 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 12930 ins_encode %{ 12931 __ string_indexof($str1$$Register, $str2$$Register, 12932 $cnt1$$Register, $cnt2$$Register, 12933 (-1), $result$$Register, 12934 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 12935 %} 12936 ins_pipe( pipe_slow ); 12937 %} 12938 12939 instruct string_indexofU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 12940 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr) 12941 %{ 12942 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 12943 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 12944 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 12945 12946 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 12947 ins_encode %{ 12948 __ string_indexof($str1$$Register, $str2$$Register, 12949 $cnt1$$Register, $cnt2$$Register, 12950 (-1), $result$$Register, 12951 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 12952 %} 12953 ins_pipe( pipe_slow ); 12954 %} 12955 12956 instruct string_indexofUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 12957 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr) 12958 %{ 12959 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 12960 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 12961 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 12962 12963 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 12964 ins_encode %{ 12965 __ string_indexof($str1$$Register, $str2$$Register, 12966 $cnt1$$Register, $cnt2$$Register, 12967 (-1), $result$$Register, 12968 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 12969 %} 12970 ins_pipe( pipe_slow ); 12971 %} 12972 12973 instruct string_indexof_char(rdi_RegP str1, rdx_RegI cnt1, rax_RegI ch, 12974 rbx_RegI result, legRegD tmp_vec1, legRegD tmp_vec2, legRegD tmp_vec3, rcx_RegI tmp, rFlagsReg cr) 12975 %{ 12976 predicate(UseSSE42Intrinsics && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::U)); 12977 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 12978 effect(TEMP tmp_vec1, TEMP tmp_vec2, TEMP tmp_vec3, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP tmp, KILL cr); 12979 format %{ "StringUTF16 IndexOf char[] $str1,$cnt1,$ch -> $result // KILL all" %} 12980 ins_encode %{ 12981 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register, 12982 $tmp_vec1$$XMMRegister, $tmp_vec2$$XMMRegister, $tmp_vec3$$XMMRegister, $tmp$$Register); 12983 %} 12984 ins_pipe( pipe_slow ); 12985 %} 12986 12987 instruct stringL_indexof_char(rdi_RegP str1, rdx_RegI cnt1, rax_RegI ch, 12988 rbx_RegI result, legRegD tmp_vec1, legRegD tmp_vec2, legRegD tmp_vec3, rcx_RegI tmp, rFlagsReg cr) 12989 %{ 12990 predicate(UseSSE42Intrinsics && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::L)); 12991 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 12992 effect(TEMP tmp_vec1, TEMP tmp_vec2, TEMP tmp_vec3, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP tmp, KILL cr); 12993 format %{ "StringLatin1 IndexOf char[] $str1,$cnt1,$ch -> $result // KILL all" %} 12994 ins_encode %{ 12995 __ stringL_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register, 12996 $tmp_vec1$$XMMRegister, $tmp_vec2$$XMMRegister, $tmp_vec3$$XMMRegister, $tmp$$Register); 12997 %} 12998 ins_pipe( pipe_slow ); 12999 %} 13000 13001 // fast string equals 13002 instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 13003 legRegD tmp1, legRegD tmp2, rbx_RegI tmp3, rFlagsReg cr) 13004 %{ 13005 predicate(!VM_Version::supports_avx512vlbw()); 13006 match(Set result (StrEquals (Binary str1 str2) cnt)); 13007 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 13008 13009 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 13010 ins_encode %{ 13011 __ arrays_equals(false, $str1$$Register, $str2$$Register, 13012 $cnt$$Register, $result$$Register, $tmp3$$Register, 13013 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, knoreg); 13014 %} 13015 ins_pipe( pipe_slow ); 13016 %} 13017 13018 instruct string_equals_evex(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 13019 legRegD tmp1, legRegD tmp2, kReg ktmp, rbx_RegI tmp3, rFlagsReg cr) 13020 %{ 13021 predicate(VM_Version::supports_avx512vlbw()); 13022 match(Set result (StrEquals (Binary str1 str2) cnt)); 13023 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 13024 13025 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 13026 ins_encode %{ 13027 __ arrays_equals(false, $str1$$Register, $str2$$Register, 13028 $cnt$$Register, $result$$Register, $tmp3$$Register, 13029 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, $ktmp$$KRegister); 13030 %} 13031 ins_pipe( pipe_slow ); 13032 %} 13033 13034 // fast array equals 13035 instruct array_equalsB(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 13036 legRegD tmp1, legRegD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 13037 %{ 13038 predicate(!VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 13039 match(Set result (AryEq ary1 ary2)); 13040 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 13041 13042 format %{ "Array Equals byte[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 13043 ins_encode %{ 13044 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 13045 $tmp3$$Register, $result$$Register, $tmp4$$Register, 13046 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, knoreg); 13047 %} 13048 ins_pipe( pipe_slow ); 13049 %} 13050 13051 instruct array_equalsB_evex(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 13052 legRegD tmp1, legRegD tmp2, kReg ktmp, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 13053 %{ 13054 predicate(VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 13055 match(Set result (AryEq ary1 ary2)); 13056 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 13057 13058 format %{ "Array Equals byte[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 13059 ins_encode %{ 13060 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 13061 $tmp3$$Register, $result$$Register, $tmp4$$Register, 13062 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, $ktmp$$KRegister); 13063 %} 13064 ins_pipe( pipe_slow ); 13065 %} 13066 13067 instruct array_equalsC(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 13068 legRegD tmp1, legRegD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 13069 %{ 13070 predicate(!VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 13071 match(Set result (AryEq ary1 ary2)); 13072 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 13073 13074 format %{ "Array Equals char[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 13075 ins_encode %{ 13076 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 13077 $tmp3$$Register, $result$$Register, $tmp4$$Register, 13078 $tmp1$$XMMRegister, $tmp2$$XMMRegister, true /* char */, knoreg); 13079 %} 13080 ins_pipe( pipe_slow ); 13081 %} 13082 13083 instruct array_equalsC_evex(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 13084 legRegD tmp1, legRegD tmp2, kReg ktmp, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 13085 %{ 13086 predicate(VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 13087 match(Set result (AryEq ary1 ary2)); 13088 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 13089 13090 format %{ "Array Equals char[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 13091 ins_encode %{ 13092 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 13093 $tmp3$$Register, $result$$Register, $tmp4$$Register, 13094 $tmp1$$XMMRegister, $tmp2$$XMMRegister, true /* char */, $ktmp$$KRegister); 13095 %} 13096 ins_pipe( pipe_slow ); 13097 %} 13098 13099 instruct arrays_hashcode(rdi_RegP ary1, rdx_RegI cnt1, rbx_RegI result, immU8 basic_type, 13100 legRegD tmp_vec1, legRegD tmp_vec2, legRegD tmp_vec3, legRegD tmp_vec4, 13101 legRegD tmp_vec5, legRegD tmp_vec6, legRegD tmp_vec7, legRegD tmp_vec8, 13102 legRegD tmp_vec9, legRegD tmp_vec10, legRegD tmp_vec11, legRegD tmp_vec12, 13103 legRegD tmp_vec13, rRegI tmp1, rRegI tmp2, rRegI tmp3, rFlagsReg cr) 13104 %{ 13105 predicate(UseAVX >= 2); 13106 match(Set result (VectorizedHashCode (Binary ary1 cnt1) (Binary result basic_type))); 13107 effect(TEMP tmp_vec1, TEMP tmp_vec2, TEMP tmp_vec3, TEMP tmp_vec4, TEMP tmp_vec5, TEMP tmp_vec6, 13108 TEMP tmp_vec7, TEMP tmp_vec8, TEMP tmp_vec9, TEMP tmp_vec10, TEMP tmp_vec11, TEMP tmp_vec12, 13109 TEMP tmp_vec13, TEMP tmp1, TEMP tmp2, TEMP tmp3, USE_KILL ary1, USE_KILL cnt1, 13110 USE basic_type, KILL cr); 13111 13112 format %{ "Array HashCode array[] $ary1,$cnt1,$result,$basic_type -> $result // KILL all" %} 13113 ins_encode %{ 13114 __ arrays_hashcode($ary1$$Register, $cnt1$$Register, $result$$Register, 13115 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 13116 $tmp_vec1$$XMMRegister, $tmp_vec2$$XMMRegister, $tmp_vec3$$XMMRegister, 13117 $tmp_vec4$$XMMRegister, $tmp_vec5$$XMMRegister, $tmp_vec6$$XMMRegister, 13118 $tmp_vec7$$XMMRegister, $tmp_vec8$$XMMRegister, $tmp_vec9$$XMMRegister, 13119 $tmp_vec10$$XMMRegister, $tmp_vec11$$XMMRegister, $tmp_vec12$$XMMRegister, 13120 $tmp_vec13$$XMMRegister, (BasicType)$basic_type$$constant); 13121 %} 13122 ins_pipe( pipe_slow ); 13123 %} 13124 13125 instruct count_positives(rsi_RegP ary1, rcx_RegI len, rax_RegI result, 13126 legRegD tmp1, legRegD tmp2, rbx_RegI tmp3, rFlagsReg cr,) 13127 %{ 13128 predicate(!VM_Version::supports_avx512vlbw() || !VM_Version::supports_bmi2()); 13129 match(Set result (CountPositives ary1 len)); 13130 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr); 13131 13132 format %{ "countPositives byte[] $ary1,$len -> $result // KILL $tmp1, $tmp2, $tmp3" %} 13133 ins_encode %{ 13134 __ count_positives($ary1$$Register, $len$$Register, 13135 $result$$Register, $tmp3$$Register, 13136 $tmp1$$XMMRegister, $tmp2$$XMMRegister, knoreg, knoreg); 13137 %} 13138 ins_pipe( pipe_slow ); 13139 %} 13140 13141 instruct count_positives_evex(rsi_RegP ary1, rcx_RegI len, rax_RegI result, 13142 legRegD tmp1, legRegD tmp2, kReg ktmp1, kReg ktmp2, rbx_RegI tmp3, rFlagsReg cr,) 13143 %{ 13144 predicate(VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2()); 13145 match(Set result (CountPositives ary1 len)); 13146 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp1, TEMP ktmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr); 13147 13148 format %{ "countPositives byte[] $ary1,$len -> $result // KILL $tmp1, $tmp2, $tmp3" %} 13149 ins_encode %{ 13150 __ count_positives($ary1$$Register, $len$$Register, 13151 $result$$Register, $tmp3$$Register, 13152 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $ktmp1$$KRegister, $ktmp2$$KRegister); 13153 %} 13154 ins_pipe( pipe_slow ); 13155 %} 13156 13157 // fast char[] to byte[] compression 13158 instruct string_compress(rsi_RegP src, rdi_RegP dst, rdx_RegI len, legRegD tmp1, legRegD tmp2, legRegD tmp3, 13159 legRegD tmp4, rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 13160 predicate(!VM_Version::supports_avx512vlbw() || !VM_Version::supports_bmi2()); 13161 match(Set result (StrCompressedCopy src (Binary dst len))); 13162 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, 13163 USE_KILL len, KILL tmp5, KILL cr); 13164 13165 format %{ "String Compress $src,$dst -> $result // KILL RAX, RCX, RDX" %} 13166 ins_encode %{ 13167 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 13168 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 13169 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, 13170 knoreg, knoreg); 13171 %} 13172 ins_pipe( pipe_slow ); 13173 %} 13174 13175 instruct string_compress_evex(rsi_RegP src, rdi_RegP dst, rdx_RegI len, legRegD tmp1, legRegD tmp2, legRegD tmp3, 13176 legRegD tmp4, kReg ktmp1, kReg ktmp2, rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 13177 predicate(VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2()); 13178 match(Set result (StrCompressedCopy src (Binary dst len))); 13179 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP ktmp1, TEMP ktmp2, USE_KILL src, USE_KILL dst, 13180 USE_KILL len, KILL tmp5, KILL cr); 13181 13182 format %{ "String Compress $src,$dst -> $result // KILL RAX, RCX, RDX" %} 13183 ins_encode %{ 13184 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 13185 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 13186 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, 13187 $ktmp1$$KRegister, $ktmp2$$KRegister); 13188 %} 13189 ins_pipe( pipe_slow ); 13190 %} 13191 // fast byte[] to char[] inflation 13192 instruct string_inflate(Universe dummy, rsi_RegP src, rdi_RegP dst, rdx_RegI len, 13193 legRegD tmp1, rcx_RegI tmp2, rFlagsReg cr) %{ 13194 predicate(!VM_Version::supports_avx512vlbw() || !VM_Version::supports_bmi2()); 13195 match(Set dummy (StrInflatedCopy src (Binary dst len))); 13196 effect(TEMP tmp1, TEMP tmp2, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 13197 13198 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 13199 ins_encode %{ 13200 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 13201 $tmp1$$XMMRegister, $tmp2$$Register, knoreg); 13202 %} 13203 ins_pipe( pipe_slow ); 13204 %} 13205 13206 instruct string_inflate_evex(Universe dummy, rsi_RegP src, rdi_RegP dst, rdx_RegI len, 13207 legRegD tmp1, kReg ktmp, rcx_RegI tmp2, rFlagsReg cr) %{ 13208 predicate(VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2()); 13209 match(Set dummy (StrInflatedCopy src (Binary dst len))); 13210 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 13211 13212 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 13213 ins_encode %{ 13214 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 13215 $tmp1$$XMMRegister, $tmp2$$Register, $ktmp$$KRegister); 13216 %} 13217 ins_pipe( pipe_slow ); 13218 %} 13219 13220 // encode char[] to byte[] in ISO_8859_1 13221 instruct encode_iso_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len, 13222 legRegD tmp1, legRegD tmp2, legRegD tmp3, legRegD tmp4, 13223 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 13224 predicate(!((EncodeISOArrayNode*)n)->is_ascii()); 13225 match(Set result (EncodeISOArray src (Binary dst len))); 13226 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 13227 13228 format %{ "Encode iso array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %} 13229 ins_encode %{ 13230 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 13231 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 13232 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, false); 13233 %} 13234 ins_pipe( pipe_slow ); 13235 %} 13236 13237 // encode char[] to byte[] in ASCII 13238 instruct encode_ascii_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len, 13239 legRegD tmp1, legRegD tmp2, legRegD tmp3, legRegD tmp4, 13240 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 13241 predicate(((EncodeISOArrayNode*)n)->is_ascii()); 13242 match(Set result (EncodeISOArray src (Binary dst len))); 13243 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 13244 13245 format %{ "Encode ascii array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %} 13246 ins_encode %{ 13247 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 13248 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 13249 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, true); 13250 %} 13251 ins_pipe( pipe_slow ); 13252 %} 13253 13254 //----------Overflow Math Instructions----------------------------------------- 13255 13256 instruct overflowAddI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 13257 %{ 13258 match(Set cr (OverflowAddI op1 op2)); 13259 effect(DEF cr, USE_KILL op1, USE op2); 13260 13261 format %{ "addl $op1, $op2\t# overflow check int" %} 13262 13263 ins_encode %{ 13264 __ addl($op1$$Register, $op2$$Register); 13265 %} 13266 ins_pipe(ialu_reg_reg); 13267 %} 13268 13269 instruct overflowAddI_rReg_imm(rFlagsReg cr, rax_RegI op1, immI op2) 13270 %{ 13271 match(Set cr (OverflowAddI op1 op2)); 13272 effect(DEF cr, USE_KILL op1, USE op2); 13273 13274 format %{ "addl $op1, $op2\t# overflow check int" %} 13275 13276 ins_encode %{ 13277 __ addl($op1$$Register, $op2$$constant); 13278 %} 13279 ins_pipe(ialu_reg_reg); 13280 %} 13281 13282 instruct overflowAddL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 13283 %{ 13284 match(Set cr (OverflowAddL op1 op2)); 13285 effect(DEF cr, USE_KILL op1, USE op2); 13286 13287 format %{ "addq $op1, $op2\t# overflow check long" %} 13288 ins_encode %{ 13289 __ addq($op1$$Register, $op2$$Register); 13290 %} 13291 ins_pipe(ialu_reg_reg); 13292 %} 13293 13294 instruct overflowAddL_rReg_imm(rFlagsReg cr, rax_RegL op1, immL32 op2) 13295 %{ 13296 match(Set cr (OverflowAddL op1 op2)); 13297 effect(DEF cr, USE_KILL op1, USE op2); 13298 13299 format %{ "addq $op1, $op2\t# overflow check long" %} 13300 ins_encode %{ 13301 __ addq($op1$$Register, $op2$$constant); 13302 %} 13303 ins_pipe(ialu_reg_reg); 13304 %} 13305 13306 instruct overflowSubI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 13307 %{ 13308 match(Set cr (OverflowSubI op1 op2)); 13309 13310 format %{ "cmpl $op1, $op2\t# overflow check int" %} 13311 ins_encode %{ 13312 __ cmpl($op1$$Register, $op2$$Register); 13313 %} 13314 ins_pipe(ialu_reg_reg); 13315 %} 13316 13317 instruct overflowSubI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 13318 %{ 13319 match(Set cr (OverflowSubI op1 op2)); 13320 13321 format %{ "cmpl $op1, $op2\t# overflow check int" %} 13322 ins_encode %{ 13323 __ cmpl($op1$$Register, $op2$$constant); 13324 %} 13325 ins_pipe(ialu_reg_reg); 13326 %} 13327 13328 instruct overflowSubL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 13329 %{ 13330 match(Set cr (OverflowSubL op1 op2)); 13331 13332 format %{ "cmpq $op1, $op2\t# overflow check long" %} 13333 ins_encode %{ 13334 __ cmpq($op1$$Register, $op2$$Register); 13335 %} 13336 ins_pipe(ialu_reg_reg); 13337 %} 13338 13339 instruct overflowSubL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 13340 %{ 13341 match(Set cr (OverflowSubL op1 op2)); 13342 13343 format %{ "cmpq $op1, $op2\t# overflow check long" %} 13344 ins_encode %{ 13345 __ cmpq($op1$$Register, $op2$$constant); 13346 %} 13347 ins_pipe(ialu_reg_reg); 13348 %} 13349 13350 instruct overflowNegI_rReg(rFlagsReg cr, immI_0 zero, rax_RegI op2) 13351 %{ 13352 match(Set cr (OverflowSubI zero op2)); 13353 effect(DEF cr, USE_KILL op2); 13354 13355 format %{ "negl $op2\t# overflow check int" %} 13356 ins_encode %{ 13357 __ negl($op2$$Register); 13358 %} 13359 ins_pipe(ialu_reg_reg); 13360 %} 13361 13362 instruct overflowNegL_rReg(rFlagsReg cr, immL0 zero, rax_RegL op2) 13363 %{ 13364 match(Set cr (OverflowSubL zero op2)); 13365 effect(DEF cr, USE_KILL op2); 13366 13367 format %{ "negq $op2\t# overflow check long" %} 13368 ins_encode %{ 13369 __ negq($op2$$Register); 13370 %} 13371 ins_pipe(ialu_reg_reg); 13372 %} 13373 13374 instruct overflowMulI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 13375 %{ 13376 match(Set cr (OverflowMulI op1 op2)); 13377 effect(DEF cr, USE_KILL op1, USE op2); 13378 13379 format %{ "imull $op1, $op2\t# overflow check int" %} 13380 ins_encode %{ 13381 __ imull($op1$$Register, $op2$$Register); 13382 %} 13383 ins_pipe(ialu_reg_reg_alu0); 13384 %} 13385 13386 instruct overflowMulI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2, rRegI tmp) 13387 %{ 13388 match(Set cr (OverflowMulI op1 op2)); 13389 effect(DEF cr, TEMP tmp, USE op1, USE op2); 13390 13391 format %{ "imull $tmp, $op1, $op2\t# overflow check int" %} 13392 ins_encode %{ 13393 __ imull($tmp$$Register, $op1$$Register, $op2$$constant); 13394 %} 13395 ins_pipe(ialu_reg_reg_alu0); 13396 %} 13397 13398 instruct overflowMulL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 13399 %{ 13400 match(Set cr (OverflowMulL op1 op2)); 13401 effect(DEF cr, USE_KILL op1, USE op2); 13402 13403 format %{ "imulq $op1, $op2\t# overflow check long" %} 13404 ins_encode %{ 13405 __ imulq($op1$$Register, $op2$$Register); 13406 %} 13407 ins_pipe(ialu_reg_reg_alu0); 13408 %} 13409 13410 instruct overflowMulL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2, rRegL tmp) 13411 %{ 13412 match(Set cr (OverflowMulL op1 op2)); 13413 effect(DEF cr, TEMP tmp, USE op1, USE op2); 13414 13415 format %{ "imulq $tmp, $op1, $op2\t# overflow check long" %} 13416 ins_encode %{ 13417 __ imulq($tmp$$Register, $op1$$Register, $op2$$constant); 13418 %} 13419 ins_pipe(ialu_reg_reg_alu0); 13420 %} 13421 13422 13423 //----------Control Flow Instructions------------------------------------------ 13424 // Signed compare Instructions 13425 13426 // XXX more variants!! 13427 instruct compI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 13428 %{ 13429 match(Set cr (CmpI op1 op2)); 13430 effect(DEF cr, USE op1, USE op2); 13431 13432 format %{ "cmpl $op1, $op2" %} 13433 ins_encode %{ 13434 __ cmpl($op1$$Register, $op2$$Register); 13435 %} 13436 ins_pipe(ialu_cr_reg_reg); 13437 %} 13438 13439 instruct compI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 13440 %{ 13441 match(Set cr (CmpI op1 op2)); 13442 13443 format %{ "cmpl $op1, $op2" %} 13444 ins_encode %{ 13445 __ cmpl($op1$$Register, $op2$$constant); 13446 %} 13447 ins_pipe(ialu_cr_reg_imm); 13448 %} 13449 13450 instruct compI_rReg_mem(rFlagsReg cr, rRegI op1, memory op2) 13451 %{ 13452 match(Set cr (CmpI op1 (LoadI op2))); 13453 13454 ins_cost(500); // XXX 13455 format %{ "cmpl $op1, $op2" %} 13456 ins_encode %{ 13457 __ cmpl($op1$$Register, $op2$$Address); 13458 %} 13459 ins_pipe(ialu_cr_reg_mem); 13460 %} 13461 13462 instruct testI_reg(rFlagsReg cr, rRegI src, immI_0 zero) 13463 %{ 13464 match(Set cr (CmpI src zero)); 13465 13466 format %{ "testl $src, $src" %} 13467 ins_encode %{ 13468 __ testl($src$$Register, $src$$Register); 13469 %} 13470 ins_pipe(ialu_cr_reg_imm); 13471 %} 13472 13473 instruct testI_reg_imm(rFlagsReg cr, rRegI src, immI con, immI_0 zero) 13474 %{ 13475 match(Set cr (CmpI (AndI src con) zero)); 13476 13477 format %{ "testl $src, $con" %} 13478 ins_encode %{ 13479 __ testl($src$$Register, $con$$constant); 13480 %} 13481 ins_pipe(ialu_cr_reg_imm); 13482 %} 13483 13484 instruct testI_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2, immI_0 zero) 13485 %{ 13486 match(Set cr (CmpI (AndI src1 src2) zero)); 13487 13488 format %{ "testl $src1, $src2" %} 13489 ins_encode %{ 13490 __ testl($src1$$Register, $src2$$Register); 13491 %} 13492 ins_pipe(ialu_cr_reg_imm); 13493 %} 13494 13495 instruct testI_reg_mem(rFlagsReg cr, rRegI src, memory mem, immI_0 zero) 13496 %{ 13497 match(Set cr (CmpI (AndI src (LoadI mem)) zero)); 13498 13499 format %{ "testl $src, $mem" %} 13500 ins_encode %{ 13501 __ testl($src$$Register, $mem$$Address); 13502 %} 13503 ins_pipe(ialu_cr_reg_mem); 13504 %} 13505 13506 // Unsigned compare Instructions; really, same as signed except they 13507 // produce an rFlagsRegU instead of rFlagsReg. 13508 instruct compU_rReg(rFlagsRegU cr, rRegI op1, rRegI op2) 13509 %{ 13510 match(Set cr (CmpU op1 op2)); 13511 13512 format %{ "cmpl $op1, $op2\t# unsigned" %} 13513 ins_encode %{ 13514 __ cmpl($op1$$Register, $op2$$Register); 13515 %} 13516 ins_pipe(ialu_cr_reg_reg); 13517 %} 13518 13519 instruct compU_rReg_imm(rFlagsRegU cr, rRegI op1, immI op2) 13520 %{ 13521 match(Set cr (CmpU op1 op2)); 13522 13523 format %{ "cmpl $op1, $op2\t# unsigned" %} 13524 ins_encode %{ 13525 __ cmpl($op1$$Register, $op2$$constant); 13526 %} 13527 ins_pipe(ialu_cr_reg_imm); 13528 %} 13529 13530 instruct compU_rReg_mem(rFlagsRegU cr, rRegI op1, memory op2) 13531 %{ 13532 match(Set cr (CmpU op1 (LoadI op2))); 13533 13534 ins_cost(500); // XXX 13535 format %{ "cmpl $op1, $op2\t# unsigned" %} 13536 ins_encode %{ 13537 __ cmpl($op1$$Register, $op2$$Address); 13538 %} 13539 ins_pipe(ialu_cr_reg_mem); 13540 %} 13541 13542 instruct testU_reg(rFlagsRegU cr, rRegI src, immI_0 zero) 13543 %{ 13544 match(Set cr (CmpU src zero)); 13545 13546 format %{ "testl $src, $src\t# unsigned" %} 13547 ins_encode %{ 13548 __ testl($src$$Register, $src$$Register); 13549 %} 13550 ins_pipe(ialu_cr_reg_imm); 13551 %} 13552 13553 instruct compP_rReg(rFlagsRegU cr, rRegP op1, rRegP op2) 13554 %{ 13555 match(Set cr (CmpP op1 op2)); 13556 13557 format %{ "cmpq $op1, $op2\t# ptr" %} 13558 ins_encode %{ 13559 __ cmpq($op1$$Register, $op2$$Register); 13560 %} 13561 ins_pipe(ialu_cr_reg_reg); 13562 %} 13563 13564 instruct compP_rReg_mem(rFlagsRegU cr, rRegP op1, memory op2) 13565 %{ 13566 match(Set cr (CmpP op1 (LoadP op2))); 13567 predicate(n->in(2)->as_Load()->barrier_data() == 0); 13568 13569 ins_cost(500); // XXX 13570 format %{ "cmpq $op1, $op2\t# ptr" %} 13571 ins_encode %{ 13572 __ cmpq($op1$$Register, $op2$$Address); 13573 %} 13574 ins_pipe(ialu_cr_reg_mem); 13575 %} 13576 13577 // XXX this is generalized by compP_rReg_mem??? 13578 // Compare raw pointer (used in out-of-heap check). 13579 // Only works because non-oop pointers must be raw pointers 13580 // and raw pointers have no anti-dependencies. 13581 instruct compP_mem_rReg(rFlagsRegU cr, rRegP op1, memory op2) 13582 %{ 13583 predicate(n->in(2)->in(2)->bottom_type()->reloc() == relocInfo::none && 13584 n->in(2)->as_Load()->barrier_data() == 0); 13585 match(Set cr (CmpP op1 (LoadP op2))); 13586 13587 format %{ "cmpq $op1, $op2\t# raw ptr" %} 13588 ins_encode %{ 13589 __ cmpq($op1$$Register, $op2$$Address); 13590 %} 13591 ins_pipe(ialu_cr_reg_mem); 13592 %} 13593 13594 // This will generate a signed flags result. This should be OK since 13595 // any compare to a zero should be eq/neq. 13596 instruct testP_reg(rFlagsReg cr, rRegP src, immP0 zero) 13597 %{ 13598 match(Set cr (CmpP src zero)); 13599 13600 format %{ "testq $src, $src\t# ptr" %} 13601 ins_encode %{ 13602 __ testq($src$$Register, $src$$Register); 13603 %} 13604 ins_pipe(ialu_cr_reg_imm); 13605 %} 13606 13607 // This will generate a signed flags result. This should be OK since 13608 // any compare to a zero should be eq/neq. 13609 instruct testP_mem(rFlagsReg cr, memory op, immP0 zero) 13610 %{ 13611 predicate((!UseCompressedOops || (CompressedOops::base() != nullptr)) && 13612 n->in(1)->as_Load()->barrier_data() == 0); 13613 match(Set cr (CmpP (LoadP op) zero)); 13614 13615 ins_cost(500); // XXX 13616 format %{ "testq $op, 0xffffffffffffffff\t# ptr" %} 13617 ins_encode %{ 13618 __ testq($op$$Address, 0xFFFFFFFF); 13619 %} 13620 ins_pipe(ialu_cr_reg_imm); 13621 %} 13622 13623 instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero) 13624 %{ 13625 predicate(UseCompressedOops && (CompressedOops::base() == nullptr) && 13626 n->in(1)->as_Load()->barrier_data() == 0); 13627 match(Set cr (CmpP (LoadP mem) zero)); 13628 13629 format %{ "cmpq R12, $mem\t# ptr (R12_heapbase==0)" %} 13630 ins_encode %{ 13631 __ cmpq(r12, $mem$$Address); 13632 %} 13633 ins_pipe(ialu_cr_reg_mem); 13634 %} 13635 13636 instruct compN_rReg(rFlagsRegU cr, rRegN op1, rRegN op2) 13637 %{ 13638 match(Set cr (CmpN op1 op2)); 13639 13640 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 13641 ins_encode %{ __ cmpl($op1$$Register, $op2$$Register); %} 13642 ins_pipe(ialu_cr_reg_reg); 13643 %} 13644 13645 instruct compN_rReg_mem(rFlagsRegU cr, rRegN src, memory mem) 13646 %{ 13647 predicate(n->in(2)->as_Load()->barrier_data() == 0); 13648 match(Set cr (CmpN src (LoadN mem))); 13649 13650 format %{ "cmpl $src, $mem\t# compressed ptr" %} 13651 ins_encode %{ 13652 __ cmpl($src$$Register, $mem$$Address); 13653 %} 13654 ins_pipe(ialu_cr_reg_mem); 13655 %} 13656 13657 instruct compN_rReg_imm(rFlagsRegU cr, rRegN op1, immN op2) %{ 13658 match(Set cr (CmpN op1 op2)); 13659 13660 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 13661 ins_encode %{ 13662 __ cmp_narrow_oop($op1$$Register, (jobject)$op2$$constant); 13663 %} 13664 ins_pipe(ialu_cr_reg_imm); 13665 %} 13666 13667 instruct compN_mem_imm(rFlagsRegU cr, memory mem, immN src) 13668 %{ 13669 predicate(n->in(2)->as_Load()->barrier_data() == 0); 13670 match(Set cr (CmpN src (LoadN mem))); 13671 13672 format %{ "cmpl $mem, $src\t# compressed ptr" %} 13673 ins_encode %{ 13674 __ cmp_narrow_oop($mem$$Address, (jobject)$src$$constant); 13675 %} 13676 ins_pipe(ialu_cr_reg_mem); 13677 %} 13678 13679 instruct compN_rReg_imm_klass(rFlagsRegU cr, rRegN op1, immNKlass op2) %{ 13680 match(Set cr (CmpN op1 op2)); 13681 13682 format %{ "cmpl $op1, $op2\t# compressed klass ptr" %} 13683 ins_encode %{ 13684 __ cmp_narrow_klass($op1$$Register, (Klass*)$op2$$constant); 13685 %} 13686 ins_pipe(ialu_cr_reg_imm); 13687 %} 13688 13689 instruct compN_mem_imm_klass(rFlagsRegU cr, memory mem, immNKlass src) 13690 %{ 13691 predicate(!UseCompactObjectHeaders); 13692 match(Set cr (CmpN src (LoadNKlass mem))); 13693 13694 format %{ "cmpl $mem, $src\t# compressed klass ptr" %} 13695 ins_encode %{ 13696 __ cmp_narrow_klass($mem$$Address, (Klass*)$src$$constant); 13697 %} 13698 ins_pipe(ialu_cr_reg_mem); 13699 %} 13700 13701 instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{ 13702 match(Set cr (CmpN src zero)); 13703 13704 format %{ "testl $src, $src\t# compressed ptr" %} 13705 ins_encode %{ __ testl($src$$Register, $src$$Register); %} 13706 ins_pipe(ialu_cr_reg_imm); 13707 %} 13708 13709 instruct testN_mem(rFlagsReg cr, memory mem, immN0 zero) 13710 %{ 13711 predicate(CompressedOops::base() != nullptr && 13712 n->in(1)->as_Load()->barrier_data() == 0); 13713 match(Set cr (CmpN (LoadN mem) zero)); 13714 13715 ins_cost(500); // XXX 13716 format %{ "testl $mem, 0xffffffff\t# compressed ptr" %} 13717 ins_encode %{ 13718 __ cmpl($mem$$Address, (int)0xFFFFFFFF); 13719 %} 13720 ins_pipe(ialu_cr_reg_mem); 13721 %} 13722 13723 instruct testN_mem_reg0(rFlagsReg cr, memory mem, immN0 zero) 13724 %{ 13725 predicate(CompressedOops::base() == nullptr && 13726 n->in(1)->as_Load()->barrier_data() == 0); 13727 match(Set cr (CmpN (LoadN mem) zero)); 13728 13729 format %{ "cmpl R12, $mem\t# compressed ptr (R12_heapbase==0)" %} 13730 ins_encode %{ 13731 __ cmpl(r12, $mem$$Address); 13732 %} 13733 ins_pipe(ialu_cr_reg_mem); 13734 %} 13735 13736 // Yanked all unsigned pointer compare operations. 13737 // Pointer compares are done with CmpP which is already unsigned. 13738 13739 instruct compL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 13740 %{ 13741 match(Set cr (CmpL op1 op2)); 13742 13743 format %{ "cmpq $op1, $op2" %} 13744 ins_encode %{ 13745 __ cmpq($op1$$Register, $op2$$Register); 13746 %} 13747 ins_pipe(ialu_cr_reg_reg); 13748 %} 13749 13750 instruct compL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 13751 %{ 13752 match(Set cr (CmpL op1 op2)); 13753 13754 format %{ "cmpq $op1, $op2" %} 13755 ins_encode %{ 13756 __ cmpq($op1$$Register, $op2$$constant); 13757 %} 13758 ins_pipe(ialu_cr_reg_imm); 13759 %} 13760 13761 instruct compL_rReg_mem(rFlagsReg cr, rRegL op1, memory op2) 13762 %{ 13763 match(Set cr (CmpL op1 (LoadL op2))); 13764 13765 format %{ "cmpq $op1, $op2" %} 13766 ins_encode %{ 13767 __ cmpq($op1$$Register, $op2$$Address); 13768 %} 13769 ins_pipe(ialu_cr_reg_mem); 13770 %} 13771 13772 instruct testL_reg(rFlagsReg cr, rRegL src, immL0 zero) 13773 %{ 13774 match(Set cr (CmpL src zero)); 13775 13776 format %{ "testq $src, $src" %} 13777 ins_encode %{ 13778 __ testq($src$$Register, $src$$Register); 13779 %} 13780 ins_pipe(ialu_cr_reg_imm); 13781 %} 13782 13783 instruct testL_reg_imm(rFlagsReg cr, rRegL src, immL32 con, immL0 zero) 13784 %{ 13785 match(Set cr (CmpL (AndL src con) zero)); 13786 13787 format %{ "testq $src, $con\t# long" %} 13788 ins_encode %{ 13789 __ testq($src$$Register, $con$$constant); 13790 %} 13791 ins_pipe(ialu_cr_reg_imm); 13792 %} 13793 13794 instruct testL_reg_reg(rFlagsReg cr, rRegL src1, rRegL src2, immL0 zero) 13795 %{ 13796 match(Set cr (CmpL (AndL src1 src2) zero)); 13797 13798 format %{ "testq $src1, $src2\t# long" %} 13799 ins_encode %{ 13800 __ testq($src1$$Register, $src2$$Register); 13801 %} 13802 ins_pipe(ialu_cr_reg_imm); 13803 %} 13804 13805 instruct testL_reg_mem(rFlagsReg cr, rRegL src, memory mem, immL0 zero) 13806 %{ 13807 match(Set cr (CmpL (AndL src (LoadL mem)) zero)); 13808 13809 format %{ "testq $src, $mem" %} 13810 ins_encode %{ 13811 __ testq($src$$Register, $mem$$Address); 13812 %} 13813 ins_pipe(ialu_cr_reg_mem); 13814 %} 13815 13816 instruct testL_reg_mem2(rFlagsReg cr, rRegP src, memory mem, immL0 zero) 13817 %{ 13818 match(Set cr (CmpL (AndL (CastP2X src) (LoadL mem)) zero)); 13819 13820 format %{ "testq $src, $mem" %} 13821 ins_encode %{ 13822 __ testq($src$$Register, $mem$$Address); 13823 %} 13824 ins_pipe(ialu_cr_reg_mem); 13825 %} 13826 13827 // Manifest a CmpU result in an integer register. Very painful. 13828 // This is the test to avoid. 13829 instruct cmpU3_reg_reg(rRegI dst, rRegI src1, rRegI src2, rFlagsReg flags) 13830 %{ 13831 match(Set dst (CmpU3 src1 src2)); 13832 effect(KILL flags); 13833 13834 ins_cost(275); // XXX 13835 format %{ "cmpl $src1, $src2\t# CmpL3\n\t" 13836 "movl $dst, -1\n\t" 13837 "jb,u done\n\t" 13838 "setcc $dst \t# emits setne + movzbl or setzune for APX" 13839 "done:" %} 13840 ins_encode %{ 13841 Label done; 13842 __ cmpl($src1$$Register, $src2$$Register); 13843 __ movl($dst$$Register, -1); 13844 __ jccb(Assembler::below, done); 13845 __ setcc(Assembler::notZero, $dst$$Register); 13846 __ bind(done); 13847 %} 13848 ins_pipe(pipe_slow); 13849 %} 13850 13851 // Manifest a CmpL result in an integer register. Very painful. 13852 // This is the test to avoid. 13853 instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 13854 %{ 13855 match(Set dst (CmpL3 src1 src2)); 13856 effect(KILL flags); 13857 13858 ins_cost(275); // XXX 13859 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 13860 "movl $dst, -1\n\t" 13861 "jl,s done\n\t" 13862 "setcc $dst \t# emits setne + movzbl or setzune for APX" 13863 "done:" %} 13864 ins_encode %{ 13865 Label done; 13866 __ cmpq($src1$$Register, $src2$$Register); 13867 __ movl($dst$$Register, -1); 13868 __ jccb(Assembler::less, done); 13869 __ setcc(Assembler::notZero, $dst$$Register); 13870 __ bind(done); 13871 %} 13872 ins_pipe(pipe_slow); 13873 %} 13874 13875 // Manifest a CmpUL result in an integer register. Very painful. 13876 // This is the test to avoid. 13877 instruct cmpUL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 13878 %{ 13879 match(Set dst (CmpUL3 src1 src2)); 13880 effect(KILL flags); 13881 13882 ins_cost(275); // XXX 13883 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 13884 "movl $dst, -1\n\t" 13885 "jb,u done\n\t" 13886 "setcc $dst \t# emits setne + movzbl or setzune for APX" 13887 "done:" %} 13888 ins_encode %{ 13889 Label done; 13890 __ cmpq($src1$$Register, $src2$$Register); 13891 __ movl($dst$$Register, -1); 13892 __ jccb(Assembler::below, done); 13893 __ setcc(Assembler::notZero, $dst$$Register); 13894 __ bind(done); 13895 %} 13896 ins_pipe(pipe_slow); 13897 %} 13898 13899 // Unsigned long compare Instructions; really, same as signed long except they 13900 // produce an rFlagsRegU instead of rFlagsReg. 13901 instruct compUL_rReg(rFlagsRegU cr, rRegL op1, rRegL op2) 13902 %{ 13903 match(Set cr (CmpUL op1 op2)); 13904 13905 format %{ "cmpq $op1, $op2\t# unsigned" %} 13906 ins_encode %{ 13907 __ cmpq($op1$$Register, $op2$$Register); 13908 %} 13909 ins_pipe(ialu_cr_reg_reg); 13910 %} 13911 13912 instruct compUL_rReg_imm(rFlagsRegU cr, rRegL op1, immL32 op2) 13913 %{ 13914 match(Set cr (CmpUL op1 op2)); 13915 13916 format %{ "cmpq $op1, $op2\t# unsigned" %} 13917 ins_encode %{ 13918 __ cmpq($op1$$Register, $op2$$constant); 13919 %} 13920 ins_pipe(ialu_cr_reg_imm); 13921 %} 13922 13923 instruct compUL_rReg_mem(rFlagsRegU cr, rRegL op1, memory op2) 13924 %{ 13925 match(Set cr (CmpUL op1 (LoadL op2))); 13926 13927 format %{ "cmpq $op1, $op2\t# unsigned" %} 13928 ins_encode %{ 13929 __ cmpq($op1$$Register, $op2$$Address); 13930 %} 13931 ins_pipe(ialu_cr_reg_mem); 13932 %} 13933 13934 instruct testUL_reg(rFlagsRegU cr, rRegL src, immL0 zero) 13935 %{ 13936 match(Set cr (CmpUL src zero)); 13937 13938 format %{ "testq $src, $src\t# unsigned" %} 13939 ins_encode %{ 13940 __ testq($src$$Register, $src$$Register); 13941 %} 13942 ins_pipe(ialu_cr_reg_imm); 13943 %} 13944 13945 instruct compB_mem_imm(rFlagsReg cr, memory mem, immI8 imm) 13946 %{ 13947 match(Set cr (CmpI (LoadB mem) imm)); 13948 13949 ins_cost(125); 13950 format %{ "cmpb $mem, $imm" %} 13951 ins_encode %{ __ cmpb($mem$$Address, $imm$$constant); %} 13952 ins_pipe(ialu_cr_reg_mem); 13953 %} 13954 13955 instruct testUB_mem_imm(rFlagsReg cr, memory mem, immU7 imm, immI_0 zero) 13956 %{ 13957 match(Set cr (CmpI (AndI (LoadUB mem) imm) zero)); 13958 13959 ins_cost(125); 13960 format %{ "testb $mem, $imm\t# ubyte" %} 13961 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %} 13962 ins_pipe(ialu_cr_reg_mem); 13963 %} 13964 13965 instruct testB_mem_imm(rFlagsReg cr, memory mem, immI8 imm, immI_0 zero) 13966 %{ 13967 match(Set cr (CmpI (AndI (LoadB mem) imm) zero)); 13968 13969 ins_cost(125); 13970 format %{ "testb $mem, $imm\t# byte" %} 13971 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %} 13972 ins_pipe(ialu_cr_reg_mem); 13973 %} 13974 13975 //----------Max and Min-------------------------------------------------------- 13976 // Min Instructions 13977 13978 instruct cmovI_reg_g(rRegI dst, rRegI src, rFlagsReg cr) 13979 %{ 13980 predicate(!UseAPX); 13981 effect(USE_DEF dst, USE src, USE cr); 13982 13983 format %{ "cmovlgt $dst, $src\t# min" %} 13984 ins_encode %{ 13985 __ cmovl(Assembler::greater, $dst$$Register, $src$$Register); 13986 %} 13987 ins_pipe(pipe_cmov_reg); 13988 %} 13989 13990 instruct cmovI_reg_g_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr) 13991 %{ 13992 predicate(UseAPX); 13993 effect(DEF dst, USE src1, USE src2, USE cr); 13994 13995 format %{ "ecmovlgt $dst, $src1, $src2\t# min ndd" %} 13996 ins_encode %{ 13997 __ ecmovl(Assembler::greater, $dst$$Register, $src1$$Register, $src2$$Register); 13998 %} 13999 ins_pipe(pipe_cmov_reg); 14000 %} 14001 14002 instruct minI_rReg(rRegI dst, rRegI src) 14003 %{ 14004 predicate(!UseAPX); 14005 match(Set dst (MinI dst src)); 14006 14007 ins_cost(200); 14008 expand %{ 14009 rFlagsReg cr; 14010 compI_rReg(cr, dst, src); 14011 cmovI_reg_g(dst, src, cr); 14012 %} 14013 %} 14014 14015 instruct minI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2) 14016 %{ 14017 predicate(UseAPX); 14018 match(Set dst (MinI src1 src2)); 14019 effect(DEF dst, USE src1, USE src2); 14020 14021 ins_cost(200); 14022 expand %{ 14023 rFlagsReg cr; 14024 compI_rReg(cr, src1, src2); 14025 cmovI_reg_g_ndd(dst, src1, src2, cr); 14026 %} 14027 %} 14028 14029 instruct cmovI_reg_l(rRegI dst, rRegI src, rFlagsReg cr) 14030 %{ 14031 predicate(!UseAPX); 14032 effect(USE_DEF dst, USE src, USE cr); 14033 14034 format %{ "cmovllt $dst, $src\t# max" %} 14035 ins_encode %{ 14036 __ cmovl(Assembler::less, $dst$$Register, $src$$Register); 14037 %} 14038 ins_pipe(pipe_cmov_reg); 14039 %} 14040 14041 instruct cmovI_reg_l_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr) 14042 %{ 14043 predicate(UseAPX); 14044 effect(DEF dst, USE src1, USE src2, USE cr); 14045 14046 format %{ "ecmovllt $dst, $src1, $src2\t# max ndd" %} 14047 ins_encode %{ 14048 __ ecmovl(Assembler::less, $dst$$Register, $src1$$Register, $src2$$Register); 14049 %} 14050 ins_pipe(pipe_cmov_reg); 14051 %} 14052 14053 instruct maxI_rReg(rRegI dst, rRegI src) 14054 %{ 14055 predicate(!UseAPX); 14056 match(Set dst (MaxI dst src)); 14057 14058 ins_cost(200); 14059 expand %{ 14060 rFlagsReg cr; 14061 compI_rReg(cr, dst, src); 14062 cmovI_reg_l(dst, src, cr); 14063 %} 14064 %} 14065 14066 instruct maxI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2) 14067 %{ 14068 predicate(UseAPX); 14069 match(Set dst (MaxI src1 src2)); 14070 effect(DEF dst, USE src1, USE src2); 14071 14072 ins_cost(200); 14073 expand %{ 14074 rFlagsReg cr; 14075 compI_rReg(cr, src1, src2); 14076 cmovI_reg_l_ndd(dst, src1, src2, cr); 14077 %} 14078 %} 14079 14080 // ============================================================================ 14081 // Branch Instructions 14082 14083 // Jump Direct - Label defines a relative address from JMP+1 14084 instruct jmpDir(label labl) 14085 %{ 14086 match(Goto); 14087 effect(USE labl); 14088 14089 ins_cost(300); 14090 format %{ "jmp $labl" %} 14091 size(5); 14092 ins_encode %{ 14093 Label* L = $labl$$label; 14094 __ jmp(*L, false); // Always long jump 14095 %} 14096 ins_pipe(pipe_jmp); 14097 %} 14098 14099 // Jump Direct Conditional - Label defines a relative address from Jcc+1 14100 instruct jmpCon(cmpOp cop, rFlagsReg cr, label labl) 14101 %{ 14102 match(If cop cr); 14103 effect(USE labl); 14104 14105 ins_cost(300); 14106 format %{ "j$cop $labl" %} 14107 size(6); 14108 ins_encode %{ 14109 Label* L = $labl$$label; 14110 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 14111 %} 14112 ins_pipe(pipe_jcc); 14113 %} 14114 14115 // Jump Direct Conditional - Label defines a relative address from Jcc+1 14116 instruct jmpLoopEnd(cmpOp cop, rFlagsReg cr, label labl) 14117 %{ 14118 match(CountedLoopEnd cop cr); 14119 effect(USE labl); 14120 14121 ins_cost(300); 14122 format %{ "j$cop $labl\t# loop end" %} 14123 size(6); 14124 ins_encode %{ 14125 Label* L = $labl$$label; 14126 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 14127 %} 14128 ins_pipe(pipe_jcc); 14129 %} 14130 14131 // Jump Direct Conditional - using unsigned comparison 14132 instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 14133 match(If cop cmp); 14134 effect(USE labl); 14135 14136 ins_cost(300); 14137 format %{ "j$cop,u $labl" %} 14138 size(6); 14139 ins_encode %{ 14140 Label* L = $labl$$label; 14141 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 14142 %} 14143 ins_pipe(pipe_jcc); 14144 %} 14145 14146 instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 14147 match(If cop cmp); 14148 effect(USE labl); 14149 14150 ins_cost(200); 14151 format %{ "j$cop,u $labl" %} 14152 size(6); 14153 ins_encode %{ 14154 Label* L = $labl$$label; 14155 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 14156 %} 14157 ins_pipe(pipe_jcc); 14158 %} 14159 14160 instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 14161 match(If cop cmp); 14162 effect(USE labl); 14163 14164 ins_cost(200); 14165 format %{ $$template 14166 if ($cop$$cmpcode == Assembler::notEqual) { 14167 $$emit$$"jp,u $labl\n\t" 14168 $$emit$$"j$cop,u $labl" 14169 } else { 14170 $$emit$$"jp,u done\n\t" 14171 $$emit$$"j$cop,u $labl\n\t" 14172 $$emit$$"done:" 14173 } 14174 %} 14175 ins_encode %{ 14176 Label* l = $labl$$label; 14177 if ($cop$$cmpcode == Assembler::notEqual) { 14178 __ jcc(Assembler::parity, *l, false); 14179 __ jcc(Assembler::notEqual, *l, false); 14180 } else if ($cop$$cmpcode == Assembler::equal) { 14181 Label done; 14182 __ jccb(Assembler::parity, done); 14183 __ jcc(Assembler::equal, *l, false); 14184 __ bind(done); 14185 } else { 14186 ShouldNotReachHere(); 14187 } 14188 %} 14189 ins_pipe(pipe_jcc); 14190 %} 14191 14192 // ============================================================================ 14193 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary 14194 // superklass array for an instance of the superklass. Set a hidden 14195 // internal cache on a hit (cache is checked with exposed code in 14196 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The 14197 // encoding ALSO sets flags. 14198 14199 instruct partialSubtypeCheck(rdi_RegP result, 14200 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 14201 rFlagsReg cr) 14202 %{ 14203 match(Set result (PartialSubtypeCheck sub super)); 14204 predicate(!UseSecondarySupersTable); 14205 effect(KILL rcx, KILL cr); 14206 14207 ins_cost(1100); // slightly larger than the next version 14208 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 14209 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 14210 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 14211 "repne scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t" 14212 "jne,s miss\t\t# Missed: rdi not-zero\n\t" 14213 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 14214 "xorq $result, $result\t\t Hit: rdi zero\n\t" 14215 "miss:\t" %} 14216 14217 ins_encode %{ 14218 Label miss; 14219 // NB: Callers may assume that, when $result is a valid register, 14220 // check_klass_subtype_slow_path_linear sets it to a nonzero 14221 // value. 14222 __ check_klass_subtype_slow_path_linear($sub$$Register, $super$$Register, 14223 $rcx$$Register, $result$$Register, 14224 nullptr, &miss, 14225 /*set_cond_codes:*/ true); 14226 __ xorptr($result$$Register, $result$$Register); 14227 __ bind(miss); 14228 %} 14229 14230 ins_pipe(pipe_slow); 14231 %} 14232 14233 // ============================================================================ 14234 // Two versions of hashtable-based partialSubtypeCheck, both used when 14235 // we need to search for a super class in the secondary supers array. 14236 // The first is used when we don't know _a priori_ the class being 14237 // searched for. The second, far more common, is used when we do know: 14238 // this is used for instanceof, checkcast, and any case where C2 can 14239 // determine it by constant propagation. 14240 14241 instruct partialSubtypeCheckVarSuper(rsi_RegP sub, rax_RegP super, rdi_RegP result, 14242 rdx_RegL temp1, rcx_RegL temp2, rbx_RegP temp3, r11_RegL temp4, 14243 rFlagsReg cr) 14244 %{ 14245 match(Set result (PartialSubtypeCheck sub super)); 14246 predicate(UseSecondarySupersTable); 14247 effect(KILL cr, TEMP temp1, TEMP temp2, TEMP temp3, TEMP temp4); 14248 14249 ins_cost(1000); 14250 format %{ "partialSubtypeCheck $result, $sub, $super" %} 14251 14252 ins_encode %{ 14253 __ lookup_secondary_supers_table_var($sub$$Register, $super$$Register, $temp1$$Register, $temp2$$Register, 14254 $temp3$$Register, $temp4$$Register, $result$$Register); 14255 %} 14256 14257 ins_pipe(pipe_slow); 14258 %} 14259 14260 instruct partialSubtypeCheckConstSuper(rsi_RegP sub, rax_RegP super_reg, immP super_con, rdi_RegP result, 14261 rdx_RegL temp1, rcx_RegL temp2, rbx_RegP temp3, r11_RegL temp4, 14262 rFlagsReg cr) 14263 %{ 14264 match(Set result (PartialSubtypeCheck sub (Binary super_reg super_con))); 14265 predicate(UseSecondarySupersTable); 14266 effect(KILL cr, TEMP temp1, TEMP temp2, TEMP temp3, TEMP temp4); 14267 14268 ins_cost(700); // smaller than the next version 14269 format %{ "partialSubtypeCheck $result, $sub, $super_reg, $super_con" %} 14270 14271 ins_encode %{ 14272 u1 super_klass_slot = ((Klass*)$super_con$$constant)->hash_slot(); 14273 if (InlineSecondarySupersTest) { 14274 __ lookup_secondary_supers_table_const($sub$$Register, $super_reg$$Register, $temp1$$Register, $temp2$$Register, 14275 $temp3$$Register, $temp4$$Register, $result$$Register, 14276 super_klass_slot); 14277 } else { 14278 __ call(RuntimeAddress(StubRoutines::lookup_secondary_supers_table_stub(super_klass_slot))); 14279 } 14280 %} 14281 14282 ins_pipe(pipe_slow); 14283 %} 14284 14285 // ============================================================================ 14286 // Branch Instructions -- short offset versions 14287 // 14288 // These instructions are used to replace jumps of a long offset (the default 14289 // match) with jumps of a shorter offset. These instructions are all tagged 14290 // with the ins_short_branch attribute, which causes the ADLC to suppress the 14291 // match rules in general matching. Instead, the ADLC generates a conversion 14292 // method in the MachNode which can be used to do in-place replacement of the 14293 // long variant with the shorter variant. The compiler will determine if a 14294 // branch can be taken by the is_short_branch_offset() predicate in the machine 14295 // specific code section of the file. 14296 14297 // Jump Direct - Label defines a relative address from JMP+1 14298 instruct jmpDir_short(label labl) %{ 14299 match(Goto); 14300 effect(USE labl); 14301 14302 ins_cost(300); 14303 format %{ "jmp,s $labl" %} 14304 size(2); 14305 ins_encode %{ 14306 Label* L = $labl$$label; 14307 __ jmpb(*L); 14308 %} 14309 ins_pipe(pipe_jmp); 14310 ins_short_branch(1); 14311 %} 14312 14313 // Jump Direct Conditional - Label defines a relative address from Jcc+1 14314 instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{ 14315 match(If cop cr); 14316 effect(USE labl); 14317 14318 ins_cost(300); 14319 format %{ "j$cop,s $labl" %} 14320 size(2); 14321 ins_encode %{ 14322 Label* L = $labl$$label; 14323 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 14324 %} 14325 ins_pipe(pipe_jcc); 14326 ins_short_branch(1); 14327 %} 14328 14329 // Jump Direct Conditional - Label defines a relative address from Jcc+1 14330 instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{ 14331 match(CountedLoopEnd cop cr); 14332 effect(USE labl); 14333 14334 ins_cost(300); 14335 format %{ "j$cop,s $labl\t# loop end" %} 14336 size(2); 14337 ins_encode %{ 14338 Label* L = $labl$$label; 14339 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 14340 %} 14341 ins_pipe(pipe_jcc); 14342 ins_short_branch(1); 14343 %} 14344 14345 // Jump Direct Conditional - using unsigned comparison 14346 instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 14347 match(If cop cmp); 14348 effect(USE labl); 14349 14350 ins_cost(300); 14351 format %{ "j$cop,us $labl" %} 14352 size(2); 14353 ins_encode %{ 14354 Label* L = $labl$$label; 14355 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 14356 %} 14357 ins_pipe(pipe_jcc); 14358 ins_short_branch(1); 14359 %} 14360 14361 instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 14362 match(If cop cmp); 14363 effect(USE labl); 14364 14365 ins_cost(300); 14366 format %{ "j$cop,us $labl" %} 14367 size(2); 14368 ins_encode %{ 14369 Label* L = $labl$$label; 14370 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 14371 %} 14372 ins_pipe(pipe_jcc); 14373 ins_short_branch(1); 14374 %} 14375 14376 instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 14377 match(If cop cmp); 14378 effect(USE labl); 14379 14380 ins_cost(300); 14381 format %{ $$template 14382 if ($cop$$cmpcode == Assembler::notEqual) { 14383 $$emit$$"jp,u,s $labl\n\t" 14384 $$emit$$"j$cop,u,s $labl" 14385 } else { 14386 $$emit$$"jp,u,s done\n\t" 14387 $$emit$$"j$cop,u,s $labl\n\t" 14388 $$emit$$"done:" 14389 } 14390 %} 14391 size(4); 14392 ins_encode %{ 14393 Label* l = $labl$$label; 14394 if ($cop$$cmpcode == Assembler::notEqual) { 14395 __ jccb(Assembler::parity, *l); 14396 __ jccb(Assembler::notEqual, *l); 14397 } else if ($cop$$cmpcode == Assembler::equal) { 14398 Label done; 14399 __ jccb(Assembler::parity, done); 14400 __ jccb(Assembler::equal, *l); 14401 __ bind(done); 14402 } else { 14403 ShouldNotReachHere(); 14404 } 14405 %} 14406 ins_pipe(pipe_jcc); 14407 ins_short_branch(1); 14408 %} 14409 14410 // ============================================================================ 14411 // inlined locking and unlocking 14412 14413 instruct cmpFastLock(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr) %{ 14414 predicate(LockingMode != LM_LIGHTWEIGHT); 14415 match(Set cr (FastLock object box)); 14416 effect(TEMP tmp, TEMP scr, USE_KILL box); 14417 ins_cost(300); 14418 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr" %} 14419 ins_encode %{ 14420 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, 14421 $scr$$Register, noreg, noreg, r15_thread, nullptr); 14422 %} 14423 ins_pipe(pipe_slow); 14424 %} 14425 14426 instruct cmpFastUnlock(rFlagsReg cr, rRegP object, rax_RegP box, rRegP tmp) %{ 14427 predicate(LockingMode != LM_LIGHTWEIGHT); 14428 match(Set cr (FastUnlock object box)); 14429 effect(TEMP tmp, USE_KILL box); 14430 ins_cost(300); 14431 format %{ "fastunlock $object,$box\t! kills $box,$tmp" %} 14432 ins_encode %{ 14433 __ fast_unlock($object$$Register, $box$$Register, $tmp$$Register); 14434 %} 14435 ins_pipe(pipe_slow); 14436 %} 14437 14438 instruct cmpFastLockLightweight(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI rax_reg, rRegP tmp) %{ 14439 predicate(LockingMode == LM_LIGHTWEIGHT); 14440 match(Set cr (FastLock object box)); 14441 effect(TEMP rax_reg, TEMP tmp, USE_KILL box); 14442 ins_cost(300); 14443 format %{ "fastlock $object,$box\t! kills $box,$rax_reg,$tmp" %} 14444 ins_encode %{ 14445 __ fast_lock_lightweight($object$$Register, $box$$Register, $rax_reg$$Register, $tmp$$Register, r15_thread); 14446 %} 14447 ins_pipe(pipe_slow); 14448 %} 14449 14450 instruct cmpFastUnlockLightweight(rFlagsReg cr, rRegP object, rax_RegP rax_reg, rRegP tmp) %{ 14451 predicate(LockingMode == LM_LIGHTWEIGHT); 14452 match(Set cr (FastUnlock object rax_reg)); 14453 effect(TEMP tmp, USE_KILL rax_reg); 14454 ins_cost(300); 14455 format %{ "fastunlock $object,$rax_reg\t! kills $rax_reg,$tmp" %} 14456 ins_encode %{ 14457 __ fast_unlock_lightweight($object$$Register, $rax_reg$$Register, $tmp$$Register, r15_thread); 14458 %} 14459 ins_pipe(pipe_slow); 14460 %} 14461 14462 14463 // ============================================================================ 14464 // Safepoint Instructions 14465 instruct safePoint_poll_tls(rFlagsReg cr, rRegP poll) 14466 %{ 14467 match(SafePoint poll); 14468 effect(KILL cr, USE poll); 14469 14470 format %{ "testl rax, [$poll]\t" 14471 "# Safepoint: poll for GC" %} 14472 ins_cost(125); 14473 ins_encode %{ 14474 __ relocate(relocInfo::poll_type); 14475 address pre_pc = __ pc(); 14476 __ testl(rax, Address($poll$$Register, 0)); 14477 assert(nativeInstruction_at(pre_pc)->is_safepoint_poll(), "must emit test %%eax [reg]"); 14478 %} 14479 ins_pipe(ialu_reg_mem); 14480 %} 14481 14482 instruct mask_all_evexL(kReg dst, rRegL src) %{ 14483 match(Set dst (MaskAll src)); 14484 format %{ "mask_all_evexL $dst, $src \t! mask all operation" %} 14485 ins_encode %{ 14486 int mask_len = Matcher::vector_length(this); 14487 __ vector_maskall_operation($dst$$KRegister, $src$$Register, mask_len); 14488 %} 14489 ins_pipe( pipe_slow ); 14490 %} 14491 14492 instruct mask_all_evexI_GT32(kReg dst, rRegI src, rRegL tmp) %{ 14493 predicate(Matcher::vector_length(n) > 32); 14494 match(Set dst (MaskAll src)); 14495 effect(TEMP tmp); 14496 format %{ "mask_all_evexI_GT32 $dst, $src \t! using $tmp as TEMP" %} 14497 ins_encode %{ 14498 int mask_len = Matcher::vector_length(this); 14499 __ movslq($tmp$$Register, $src$$Register); 14500 __ vector_maskall_operation($dst$$KRegister, $tmp$$Register, mask_len); 14501 %} 14502 ins_pipe( pipe_slow ); 14503 %} 14504 14505 // ============================================================================ 14506 // Procedure Call/Return Instructions 14507 // Call Java Static Instruction 14508 // Note: If this code changes, the corresponding ret_addr_offset() and 14509 // compute_padding() functions will have to be adjusted. 14510 instruct CallStaticJavaDirect(method meth) %{ 14511 match(CallStaticJava); 14512 effect(USE meth); 14513 14514 ins_cost(300); 14515 format %{ "call,static " %} 14516 opcode(0xE8); /* E8 cd */ 14517 ins_encode(clear_avx, Java_Static_Call(meth), call_epilog); 14518 ins_pipe(pipe_slow); 14519 ins_alignment(4); 14520 %} 14521 14522 // Call Java Dynamic Instruction 14523 // Note: If this code changes, the corresponding ret_addr_offset() and 14524 // compute_padding() functions will have to be adjusted. 14525 instruct CallDynamicJavaDirect(method meth) 14526 %{ 14527 match(CallDynamicJava); 14528 effect(USE meth); 14529 14530 ins_cost(300); 14531 format %{ "movq rax, #Universe::non_oop_word()\n\t" 14532 "call,dynamic " %} 14533 ins_encode(clear_avx, Java_Dynamic_Call(meth), call_epilog); 14534 ins_pipe(pipe_slow); 14535 ins_alignment(4); 14536 %} 14537 14538 // Call Runtime Instruction 14539 instruct CallRuntimeDirect(method meth) 14540 %{ 14541 match(CallRuntime); 14542 effect(USE meth); 14543 14544 ins_cost(300); 14545 format %{ "call,runtime " %} 14546 ins_encode(clear_avx, Java_To_Runtime(meth)); 14547 ins_pipe(pipe_slow); 14548 %} 14549 14550 // Call runtime without safepoint 14551 instruct CallLeafDirect(method meth) 14552 %{ 14553 match(CallLeaf); 14554 effect(USE meth); 14555 14556 ins_cost(300); 14557 format %{ "call_leaf,runtime " %} 14558 ins_encode(clear_avx, Java_To_Runtime(meth)); 14559 ins_pipe(pipe_slow); 14560 %} 14561 14562 // Call runtime without safepoint and with vector arguments 14563 instruct CallLeafDirectVector(method meth) 14564 %{ 14565 match(CallLeafVector); 14566 effect(USE meth); 14567 14568 ins_cost(300); 14569 format %{ "call_leaf,vector " %} 14570 ins_encode(Java_To_Runtime(meth)); 14571 ins_pipe(pipe_slow); 14572 %} 14573 14574 // Call runtime without safepoint 14575 // entry point is null, target holds the address to call 14576 instruct CallLeafNoFPInDirect(rRegP target) 14577 %{ 14578 predicate(n->as_Call()->entry_point() == nullptr); 14579 match(CallLeafNoFP target); 14580 14581 ins_cost(300); 14582 format %{ "call_leaf_nofp,runtime indirect " %} 14583 ins_encode %{ 14584 __ call($target$$Register); 14585 %} 14586 14587 ins_pipe(pipe_slow); 14588 %} 14589 14590 instruct CallLeafNoFPDirect(method meth) 14591 %{ 14592 predicate(n->as_Call()->entry_point() != nullptr); 14593 match(CallLeafNoFP); 14594 effect(USE meth); 14595 14596 ins_cost(300); 14597 format %{ "call_leaf_nofp,runtime " %} 14598 ins_encode(clear_avx, Java_To_Runtime(meth)); 14599 ins_pipe(pipe_slow); 14600 %} 14601 14602 // Return Instruction 14603 // Remove the return address & jump to it. 14604 // Notice: We always emit a nop after a ret to make sure there is room 14605 // for safepoint patching 14606 instruct Ret() 14607 %{ 14608 match(Return); 14609 14610 format %{ "ret" %} 14611 ins_encode %{ 14612 __ ret(0); 14613 %} 14614 ins_pipe(pipe_jmp); 14615 %} 14616 14617 // Tail Call; Jump from runtime stub to Java code. 14618 // Also known as an 'interprocedural jump'. 14619 // Target of jump will eventually return to caller. 14620 // TailJump below removes the return address. 14621 // Don't use rbp for 'jump_target' because a MachEpilogNode has already been 14622 // emitted just above the TailCall which has reset rbp to the caller state. 14623 instruct TailCalljmpInd(no_rbp_RegP jump_target, rbx_RegP method_ptr) 14624 %{ 14625 match(TailCall jump_target method_ptr); 14626 14627 ins_cost(300); 14628 format %{ "jmp $jump_target\t# rbx holds method" %} 14629 ins_encode %{ 14630 __ jmp($jump_target$$Register); 14631 %} 14632 ins_pipe(pipe_jmp); 14633 %} 14634 14635 // Tail Jump; remove the return address; jump to target. 14636 // TailCall above leaves the return address around. 14637 instruct tailjmpInd(no_rbp_RegP jump_target, rax_RegP ex_oop) 14638 %{ 14639 match(TailJump jump_target ex_oop); 14640 14641 ins_cost(300); 14642 format %{ "popq rdx\t# pop return address\n\t" 14643 "jmp $jump_target" %} 14644 ins_encode %{ 14645 __ popq(as_Register(RDX_enc)); 14646 __ jmp($jump_target$$Register); 14647 %} 14648 ins_pipe(pipe_jmp); 14649 %} 14650 14651 // Forward exception. 14652 instruct ForwardExceptionjmp() 14653 %{ 14654 match(ForwardException); 14655 14656 format %{ "jmp forward_exception_stub" %} 14657 ins_encode %{ 14658 __ jump(RuntimeAddress(StubRoutines::forward_exception_entry()), noreg); 14659 %} 14660 ins_pipe(pipe_jmp); 14661 %} 14662 14663 // Create exception oop: created by stack-crawling runtime code. 14664 // Created exception is now available to this handler, and is setup 14665 // just prior to jumping to this handler. No code emitted. 14666 instruct CreateException(rax_RegP ex_oop) 14667 %{ 14668 match(Set ex_oop (CreateEx)); 14669 14670 size(0); 14671 // use the following format syntax 14672 format %{ "# exception oop is in rax; no code emitted" %} 14673 ins_encode(); 14674 ins_pipe(empty); 14675 %} 14676 14677 // Rethrow exception: 14678 // The exception oop will come in the first argument position. 14679 // Then JUMP (not call) to the rethrow stub code. 14680 instruct RethrowException() 14681 %{ 14682 match(Rethrow); 14683 14684 // use the following format syntax 14685 format %{ "jmp rethrow_stub" %} 14686 ins_encode %{ 14687 __ jump(RuntimeAddress(OptoRuntime::rethrow_stub()), noreg); 14688 %} 14689 ins_pipe(pipe_jmp); 14690 %} 14691 14692 // ============================================================================ 14693 // This name is KNOWN by the ADLC and cannot be changed. 14694 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type 14695 // for this guy. 14696 instruct tlsLoadP(r15_RegP dst) %{ 14697 match(Set dst (ThreadLocal)); 14698 effect(DEF dst); 14699 14700 size(0); 14701 format %{ "# TLS is in R15" %} 14702 ins_encode( /*empty encoding*/ ); 14703 ins_pipe(ialu_reg_reg); 14704 %} 14705 14706 14707 //----------PEEPHOLE RULES----------------------------------------------------- 14708 // These must follow all instruction definitions as they use the names 14709 // defined in the instructions definitions. 14710 // 14711 // peeppredicate ( rule_predicate ); 14712 // // the predicate unless which the peephole rule will be ignored 14713 // 14714 // peepmatch ( root_instr_name [preceding_instruction]* ); 14715 // 14716 // peepprocedure ( procedure_name ); 14717 // // provide a procedure name to perform the optimization, the procedure should 14718 // // reside in the architecture dependent peephole file, the method has the 14719 // // signature of MachNode* (Block*, int, PhaseRegAlloc*, (MachNode*)(*)(), int...) 14720 // // with the arguments being the basic block, the current node index inside the 14721 // // block, the register allocator, the functions upon invoked return a new node 14722 // // defined in peepreplace, and the rules of the nodes appearing in the 14723 // // corresponding peepmatch, the function return true if successful, else 14724 // // return false 14725 // 14726 // peepconstraint %{ 14727 // (instruction_number.operand_name relational_op instruction_number.operand_name 14728 // [, ...] ); 14729 // // instruction numbers are zero-based using left to right order in peepmatch 14730 // 14731 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 14732 // // provide an instruction_number.operand_name for each operand that appears 14733 // // in the replacement instruction's match rule 14734 // 14735 // ---------VM FLAGS--------------------------------------------------------- 14736 // 14737 // All peephole optimizations can be turned off using -XX:-OptoPeephole 14738 // 14739 // Each peephole rule is given an identifying number starting with zero and 14740 // increasing by one in the order seen by the parser. An individual peephole 14741 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 14742 // on the command-line. 14743 // 14744 // ---------CURRENT LIMITATIONS---------------------------------------------- 14745 // 14746 // Only transformations inside a basic block (do we need more for peephole) 14747 // 14748 // ---------EXAMPLE---------------------------------------------------------- 14749 // 14750 // // pertinent parts of existing instructions in architecture description 14751 // instruct movI(rRegI dst, rRegI src) 14752 // %{ 14753 // match(Set dst (CopyI src)); 14754 // %} 14755 // 14756 // instruct incI_rReg(rRegI dst, immI_1 src, rFlagsReg cr) 14757 // %{ 14758 // match(Set dst (AddI dst src)); 14759 // effect(KILL cr); 14760 // %} 14761 // 14762 // instruct leaI_rReg_immI(rRegI dst, immI_1 src) 14763 // %{ 14764 // match(Set dst (AddI dst src)); 14765 // %} 14766 // 14767 // 1. Simple replacement 14768 // - Only match adjacent instructions in same basic block 14769 // - Only equality constraints 14770 // - Only constraints between operands, not (0.dest_reg == RAX_enc) 14771 // - Only one replacement instruction 14772 // 14773 // // Change (inc mov) to lea 14774 // peephole %{ 14775 // // lea should only be emitted when beneficial 14776 // peeppredicate( VM_Version::supports_fast_2op_lea() ); 14777 // // increment preceded by register-register move 14778 // peepmatch ( incI_rReg movI ); 14779 // // require that the destination register of the increment 14780 // // match the destination register of the move 14781 // peepconstraint ( 0.dst == 1.dst ); 14782 // // construct a replacement instruction that sets 14783 // // the destination to ( move's source register + one ) 14784 // peepreplace ( leaI_rReg_immI( 0.dst 1.src 0.src ) ); 14785 // %} 14786 // 14787 // 2. Procedural replacement 14788 // - More flexible finding relevent nodes 14789 // - More flexible constraints 14790 // - More flexible transformations 14791 // - May utilise architecture-dependent API more effectively 14792 // - Currently only one replacement instruction due to adlc parsing capabilities 14793 // 14794 // // Change (inc mov) to lea 14795 // peephole %{ 14796 // // lea should only be emitted when beneficial 14797 // peeppredicate( VM_Version::supports_fast_2op_lea() ); 14798 // // the rule numbers of these nodes inside are passed into the function below 14799 // peepmatch ( incI_rReg movI ); 14800 // // the method that takes the responsibility of transformation 14801 // peepprocedure ( inc_mov_to_lea ); 14802 // // the replacement is a leaI_rReg_immI, a lambda upon invoked creating this 14803 // // node is passed into the function above 14804 // peepreplace ( leaI_rReg_immI() ); 14805 // %} 14806 14807 // These instructions is not matched by the matcher but used by the peephole 14808 instruct leaI_rReg_rReg_peep(rRegI dst, rRegI src1, rRegI src2) 14809 %{ 14810 predicate(false); 14811 match(Set dst (AddI src1 src2)); 14812 format %{ "leal $dst, [$src1 + $src2]" %} 14813 ins_encode %{ 14814 Register dst = $dst$$Register; 14815 Register src1 = $src1$$Register; 14816 Register src2 = $src2$$Register; 14817 if (src1 != rbp && src1 != r13) { 14818 __ leal(dst, Address(src1, src2, Address::times_1)); 14819 } else { 14820 assert(src2 != rbp && src2 != r13, ""); 14821 __ leal(dst, Address(src2, src1, Address::times_1)); 14822 } 14823 %} 14824 ins_pipe(ialu_reg_reg); 14825 %} 14826 14827 instruct leaI_rReg_immI_peep(rRegI dst, rRegI src1, immI src2) 14828 %{ 14829 predicate(false); 14830 match(Set dst (AddI src1 src2)); 14831 format %{ "leal $dst, [$src1 + $src2]" %} 14832 ins_encode %{ 14833 __ leal($dst$$Register, Address($src1$$Register, $src2$$constant)); 14834 %} 14835 ins_pipe(ialu_reg_reg); 14836 %} 14837 14838 instruct leaI_rReg_immI2_peep(rRegI dst, rRegI src, immI2 shift) 14839 %{ 14840 predicate(false); 14841 match(Set dst (LShiftI src shift)); 14842 format %{ "leal $dst, [$src << $shift]" %} 14843 ins_encode %{ 14844 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($shift$$constant); 14845 Register src = $src$$Register; 14846 if (scale == Address::times_2 && src != rbp && src != r13) { 14847 __ leal($dst$$Register, Address(src, src, Address::times_1)); 14848 } else { 14849 __ leal($dst$$Register, Address(noreg, src, scale)); 14850 } 14851 %} 14852 ins_pipe(ialu_reg_reg); 14853 %} 14854 14855 instruct leaL_rReg_rReg_peep(rRegL dst, rRegL src1, rRegL src2) 14856 %{ 14857 predicate(false); 14858 match(Set dst (AddL src1 src2)); 14859 format %{ "leaq $dst, [$src1 + $src2]" %} 14860 ins_encode %{ 14861 Register dst = $dst$$Register; 14862 Register src1 = $src1$$Register; 14863 Register src2 = $src2$$Register; 14864 if (src1 != rbp && src1 != r13) { 14865 __ leaq(dst, Address(src1, src2, Address::times_1)); 14866 } else { 14867 assert(src2 != rbp && src2 != r13, ""); 14868 __ leaq(dst, Address(src2, src1, Address::times_1)); 14869 } 14870 %} 14871 ins_pipe(ialu_reg_reg); 14872 %} 14873 14874 instruct leaL_rReg_immL32_peep(rRegL dst, rRegL src1, immL32 src2) 14875 %{ 14876 predicate(false); 14877 match(Set dst (AddL src1 src2)); 14878 format %{ "leaq $dst, [$src1 + $src2]" %} 14879 ins_encode %{ 14880 __ leaq($dst$$Register, Address($src1$$Register, $src2$$constant)); 14881 %} 14882 ins_pipe(ialu_reg_reg); 14883 %} 14884 14885 instruct leaL_rReg_immI2_peep(rRegL dst, rRegL src, immI2 shift) 14886 %{ 14887 predicate(false); 14888 match(Set dst (LShiftL src shift)); 14889 format %{ "leaq $dst, [$src << $shift]" %} 14890 ins_encode %{ 14891 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($shift$$constant); 14892 Register src = $src$$Register; 14893 if (scale == Address::times_2 && src != rbp && src != r13) { 14894 __ leaq($dst$$Register, Address(src, src, Address::times_1)); 14895 } else { 14896 __ leaq($dst$$Register, Address(noreg, src, scale)); 14897 } 14898 %} 14899 ins_pipe(ialu_reg_reg); 14900 %} 14901 14902 // These peephole rules replace mov + I pairs (where I is one of {add, inc, dec, 14903 // sal}) with lea instructions. The {add, sal} rules are beneficial in 14904 // processors with at least partial ALU support for lea 14905 // (supports_fast_2op_lea()), whereas the {inc, dec} rules are only generally 14906 // beneficial for processors with full ALU support 14907 // (VM_Version::supports_fast_3op_lea()) and Intel Cascade Lake. 14908 14909 peephole 14910 %{ 14911 peeppredicate(VM_Version::supports_fast_2op_lea()); 14912 peepmatch (addI_rReg); 14913 peepprocedure (lea_coalesce_reg); 14914 peepreplace (leaI_rReg_rReg_peep()); 14915 %} 14916 14917 peephole 14918 %{ 14919 peeppredicate(VM_Version::supports_fast_2op_lea()); 14920 peepmatch (addI_rReg_imm); 14921 peepprocedure (lea_coalesce_imm); 14922 peepreplace (leaI_rReg_immI_peep()); 14923 %} 14924 14925 peephole 14926 %{ 14927 peeppredicate(VM_Version::supports_fast_3op_lea() || 14928 VM_Version::is_intel_cascade_lake()); 14929 peepmatch (incI_rReg); 14930 peepprocedure (lea_coalesce_imm); 14931 peepreplace (leaI_rReg_immI_peep()); 14932 %} 14933 14934 peephole 14935 %{ 14936 peeppredicate(VM_Version::supports_fast_3op_lea() || 14937 VM_Version::is_intel_cascade_lake()); 14938 peepmatch (decI_rReg); 14939 peepprocedure (lea_coalesce_imm); 14940 peepreplace (leaI_rReg_immI_peep()); 14941 %} 14942 14943 peephole 14944 %{ 14945 peeppredicate(VM_Version::supports_fast_2op_lea()); 14946 peepmatch (salI_rReg_immI2); 14947 peepprocedure (lea_coalesce_imm); 14948 peepreplace (leaI_rReg_immI2_peep()); 14949 %} 14950 14951 peephole 14952 %{ 14953 peeppredicate(VM_Version::supports_fast_2op_lea()); 14954 peepmatch (addL_rReg); 14955 peepprocedure (lea_coalesce_reg); 14956 peepreplace (leaL_rReg_rReg_peep()); 14957 %} 14958 14959 peephole 14960 %{ 14961 peeppredicate(VM_Version::supports_fast_2op_lea()); 14962 peepmatch (addL_rReg_imm); 14963 peepprocedure (lea_coalesce_imm); 14964 peepreplace (leaL_rReg_immL32_peep()); 14965 %} 14966 14967 peephole 14968 %{ 14969 peeppredicate(VM_Version::supports_fast_3op_lea() || 14970 VM_Version::is_intel_cascade_lake()); 14971 peepmatch (incL_rReg); 14972 peepprocedure (lea_coalesce_imm); 14973 peepreplace (leaL_rReg_immL32_peep()); 14974 %} 14975 14976 peephole 14977 %{ 14978 peeppredicate(VM_Version::supports_fast_3op_lea() || 14979 VM_Version::is_intel_cascade_lake()); 14980 peepmatch (decL_rReg); 14981 peepprocedure (lea_coalesce_imm); 14982 peepreplace (leaL_rReg_immL32_peep()); 14983 %} 14984 14985 peephole 14986 %{ 14987 peeppredicate(VM_Version::supports_fast_2op_lea()); 14988 peepmatch (salL_rReg_immI2); 14989 peepprocedure (lea_coalesce_imm); 14990 peepreplace (leaL_rReg_immI2_peep()); 14991 %} 14992 14993 // These peephole rules matches instructions which set flags and are followed by a testI/L_reg 14994 // 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 14995 14996 //int variant 14997 peephole 14998 %{ 14999 peepmatch (testI_reg); 15000 peepprocedure (test_may_remove); 15001 %} 15002 15003 //long variant 15004 peephole 15005 %{ 15006 peepmatch (testL_reg); 15007 peepprocedure (test_may_remove); 15008 %} 15009 15010 15011 //----------SMARTSPILL RULES--------------------------------------------------- 15012 // These must follow all instruction definitions as they use the names 15013 // defined in the instructions definitions.