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 int offset = 13; // movq r10,#addr; callq (r10) 619 if (this->ideal_Opcode() != Op_CallLeafVector) { 620 offset += clear_avx_size(); 621 } 622 return offset; 623 } 624 // 625 // Compute padding required for nodes which need alignment 626 // 627 628 // The address of the call instruction needs to be 4-byte aligned to 629 // ensure that it does not span a cache line so that it can be patched. 630 int CallStaticJavaDirectNode::compute_padding(int current_offset) const 631 { 632 current_offset += clear_avx_size(); // skip vzeroupper 633 current_offset += 1; // skip call opcode byte 634 return align_up(current_offset, alignment_required()) - current_offset; 635 } 636 637 // The address of the call instruction needs to be 4-byte aligned to 638 // ensure that it does not span a cache line so that it can be patched. 639 int CallDynamicJavaDirectNode::compute_padding(int current_offset) const 640 { 641 current_offset += clear_avx_size(); // skip vzeroupper 642 current_offset += 11; // skip movq instruction + call opcode byte 643 return align_up(current_offset, alignment_required()) - current_offset; 644 } 645 646 // This could be in MacroAssembler but it's fairly C2 specific 647 static void emit_cmpfp_fixup(MacroAssembler* masm) { 648 Label exit; 649 __ jccb(Assembler::noParity, exit); 650 __ pushf(); 651 // 652 // comiss/ucomiss instructions set ZF,PF,CF flags and 653 // zero OF,AF,SF for NaN values. 654 // Fixup flags by zeroing ZF,PF so that compare of NaN 655 // values returns 'less than' result (CF is set). 656 // Leave the rest of flags unchanged. 657 // 658 // 7 6 5 4 3 2 1 0 659 // |S|Z|r|A|r|P|r|C| (r - reserved bit) 660 // 0 0 1 0 1 0 1 1 (0x2B) 661 // 662 __ andq(Address(rsp, 0), 0xffffff2b); 663 __ popf(); 664 __ bind(exit); 665 } 666 667 static void emit_cmpfp3(MacroAssembler* masm, Register dst) { 668 Label done; 669 __ movl(dst, -1); 670 __ jcc(Assembler::parity, done); 671 __ jcc(Assembler::below, done); 672 __ setcc(Assembler::notEqual, dst); 673 __ bind(done); 674 } 675 676 // Math.min() # Math.max() 677 // -------------------------- 678 // ucomis[s/d] # 679 // ja -> b # a 680 // jp -> NaN # NaN 681 // jb -> a # b 682 // je # 683 // |-jz -> a | b # a & b 684 // | -> a # 685 static void emit_fp_min_max(MacroAssembler* masm, XMMRegister dst, 686 XMMRegister a, XMMRegister b, 687 XMMRegister xmmt, Register rt, 688 bool min, bool single) { 689 690 Label nan, zero, below, above, done; 691 692 if (single) 693 __ ucomiss(a, b); 694 else 695 __ ucomisd(a, b); 696 697 if (dst->encoding() != (min ? b : a)->encoding()) 698 __ jccb(Assembler::above, above); // CF=0 & ZF=0 699 else 700 __ jccb(Assembler::above, done); 701 702 __ jccb(Assembler::parity, nan); // PF=1 703 __ jccb(Assembler::below, below); // CF=1 704 705 // equal 706 __ vpxor(xmmt, xmmt, xmmt, Assembler::AVX_128bit); 707 if (single) { 708 __ ucomiss(a, xmmt); 709 __ jccb(Assembler::equal, zero); 710 711 __ movflt(dst, a); 712 __ jmp(done); 713 } 714 else { 715 __ ucomisd(a, xmmt); 716 __ jccb(Assembler::equal, zero); 717 718 __ movdbl(dst, a); 719 __ jmp(done); 720 } 721 722 __ bind(zero); 723 if (min) 724 __ vpor(dst, a, b, Assembler::AVX_128bit); 725 else 726 __ vpand(dst, a, b, Assembler::AVX_128bit); 727 728 __ jmp(done); 729 730 __ bind(above); 731 if (single) 732 __ movflt(dst, min ? b : a); 733 else 734 __ movdbl(dst, min ? b : a); 735 736 __ jmp(done); 737 738 __ bind(nan); 739 if (single) { 740 __ movl(rt, 0x7fc00000); // Float.NaN 741 __ movdl(dst, rt); 742 } 743 else { 744 __ mov64(rt, 0x7ff8000000000000L); // Double.NaN 745 __ movdq(dst, rt); 746 } 747 __ jmp(done); 748 749 __ bind(below); 750 if (single) 751 __ movflt(dst, min ? a : b); 752 else 753 __ movdbl(dst, min ? a : b); 754 755 __ bind(done); 756 } 757 758 //============================================================================= 759 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; 760 761 int ConstantTable::calculate_table_base_offset() const { 762 return 0; // absolute addressing, no offset 763 } 764 765 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; } 766 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 767 ShouldNotReachHere(); 768 } 769 770 void MachConstantBaseNode::emit(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const { 771 // Empty encoding 772 } 773 774 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 775 return 0; 776 } 777 778 #ifndef PRODUCT 779 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 780 st->print("# MachConstantBaseNode (empty encoding)"); 781 } 782 #endif 783 784 785 //============================================================================= 786 #ifndef PRODUCT 787 void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 788 Compile* C = ra_->C; 789 790 int framesize = C->output()->frame_size_in_bytes(); 791 int bangsize = C->output()->bang_size_in_bytes(); 792 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 793 // Remove wordSize for return addr which is already pushed. 794 framesize -= wordSize; 795 796 if (C->output()->need_stack_bang(bangsize)) { 797 framesize -= wordSize; 798 st->print("# stack bang (%d bytes)", bangsize); 799 st->print("\n\t"); 800 st->print("pushq rbp\t# Save rbp"); 801 if (PreserveFramePointer) { 802 st->print("\n\t"); 803 st->print("movq rbp, rsp\t# Save the caller's SP into rbp"); 804 } 805 if (framesize) { 806 st->print("\n\t"); 807 st->print("subq rsp, #%d\t# Create frame",framesize); 808 } 809 } else { 810 st->print("subq rsp, #%d\t# Create frame",framesize); 811 st->print("\n\t"); 812 framesize -= wordSize; 813 st->print("movq [rsp + #%d], rbp\t# Save rbp",framesize); 814 if (PreserveFramePointer) { 815 st->print("\n\t"); 816 st->print("movq rbp, rsp\t# Save the caller's SP into rbp"); 817 if (framesize > 0) { 818 st->print("\n\t"); 819 st->print("addq rbp, #%d", framesize); 820 } 821 } 822 } 823 824 if (VerifyStackAtCalls) { 825 st->print("\n\t"); 826 framesize -= wordSize; 827 st->print("movq [rsp + #%d], 0xbadb100d\t# Majik cookie for stack depth check",framesize); 828 #ifdef ASSERT 829 st->print("\n\t"); 830 st->print("# stack alignment check"); 831 #endif 832 } 833 if (C->stub_function() != nullptr) { 834 st->print("\n\t"); 835 st->print("cmpl [r15_thread + #disarmed_guard_value_offset], #disarmed_guard_value\t"); 836 st->print("\n\t"); 837 st->print("je fast_entry\t"); 838 st->print("\n\t"); 839 st->print("call #nmethod_entry_barrier_stub\t"); 840 st->print("\n\tfast_entry:"); 841 } 842 st->cr(); 843 } 844 #endif 845 846 void MachPrologNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const { 847 Compile* C = ra_->C; 848 849 int framesize = C->output()->frame_size_in_bytes(); 850 int bangsize = C->output()->bang_size_in_bytes(); 851 852 if (C->clinit_barrier_on_entry()) { 853 assert(VM_Version::supports_fast_class_init_checks(), "sanity"); 854 assert(!C->method()->holder()->is_not_initialized(), "initialization should have been started"); 855 856 Label L_skip_barrier; 857 Register klass = rscratch1; 858 859 __ mov_metadata(klass, C->method()->holder()->constant_encoding()); 860 __ clinit_barrier(klass, &L_skip_barrier /*L_fast_path*/); 861 862 __ jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub())); // slow path 863 864 __ bind(L_skip_barrier); 865 } 866 867 __ verified_entry(framesize, C->output()->need_stack_bang(bangsize)?bangsize:0, false, C->stub_function() != nullptr); 868 869 C->output()->set_frame_complete(__ offset()); 870 871 if (C->has_mach_constant_base_node()) { 872 // NOTE: We set the table base offset here because users might be 873 // emitted before MachConstantBaseNode. 874 ConstantTable& constant_table = C->output()->constant_table(); 875 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset()); 876 } 877 } 878 879 uint MachPrologNode::size(PhaseRegAlloc* ra_) const 880 { 881 return MachNode::size(ra_); // too many variables; just compute it 882 // the hard way 883 } 884 885 int MachPrologNode::reloc() const 886 { 887 return 0; // a large enough number 888 } 889 890 //============================================================================= 891 #ifndef PRODUCT 892 void MachEpilogNode::format(PhaseRegAlloc* ra_, outputStream* st) const 893 { 894 Compile* C = ra_->C; 895 if (generate_vzeroupper(C)) { 896 st->print("vzeroupper"); 897 st->cr(); st->print("\t"); 898 } 899 900 int framesize = C->output()->frame_size_in_bytes(); 901 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 902 // Remove word for return adr already pushed 903 // and RBP 904 framesize -= 2*wordSize; 905 906 if (framesize) { 907 st->print_cr("addq rsp, %d\t# Destroy frame", framesize); 908 st->print("\t"); 909 } 910 911 st->print_cr("popq rbp"); 912 if (do_polling() && C->is_method_compilation()) { 913 st->print("\t"); 914 st->print_cr("cmpq rsp, poll_offset[r15_thread] \n\t" 915 "ja #safepoint_stub\t" 916 "# Safepoint: poll for GC"); 917 } 918 } 919 #endif 920 921 void MachEpilogNode::emit(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const 922 { 923 Compile* C = ra_->C; 924 925 if (generate_vzeroupper(C)) { 926 // Clear upper bits of YMM registers when current compiled code uses 927 // wide vectors to avoid AVX <-> SSE transition penalty during call. 928 __ vzeroupper(); 929 } 930 931 int framesize = C->output()->frame_size_in_bytes(); 932 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 933 // Remove word for return adr already pushed 934 // and RBP 935 framesize -= 2*wordSize; 936 937 // Note that VerifyStackAtCalls' Majik cookie does not change the frame size popped here 938 939 if (framesize) { 940 __ addq(rsp, framesize); 941 } 942 943 __ popq(rbp); 944 945 if (StackReservedPages > 0 && C->has_reserved_stack_access()) { 946 __ reserved_stack_check(); 947 } 948 949 if (do_polling() && C->is_method_compilation()) { 950 Label dummy_label; 951 Label* code_stub = &dummy_label; 952 if (!C->output()->in_scratch_emit_size()) { 953 C2SafepointPollStub* stub = new (C->comp_arena()) C2SafepointPollStub(__ offset()); 954 C->output()->add_stub(stub); 955 code_stub = &stub->entry(); 956 } 957 __ relocate(relocInfo::poll_return_type); 958 __ safepoint_poll(*code_stub, true /* at_return */, true /* in_nmethod */); 959 } 960 } 961 962 uint MachEpilogNode::size(PhaseRegAlloc* ra_) const 963 { 964 return MachNode::size(ra_); // too many variables; just compute it 965 // the hard way 966 } 967 968 int MachEpilogNode::reloc() const 969 { 970 return 2; // a large enough number 971 } 972 973 const Pipeline* MachEpilogNode::pipeline() const 974 { 975 return MachNode::pipeline_class(); 976 } 977 978 //============================================================================= 979 980 enum RC { 981 rc_bad, 982 rc_int, 983 rc_kreg, 984 rc_float, 985 rc_stack 986 }; 987 988 static enum RC rc_class(OptoReg::Name reg) 989 { 990 if( !OptoReg::is_valid(reg) ) return rc_bad; 991 992 if (OptoReg::is_stack(reg)) return rc_stack; 993 994 VMReg r = OptoReg::as_VMReg(reg); 995 996 if (r->is_Register()) return rc_int; 997 998 if (r->is_KRegister()) return rc_kreg; 999 1000 assert(r->is_XMMRegister(), "must be"); 1001 return rc_float; 1002 } 1003 1004 // Next two methods are shared by 32- and 64-bit VM. They are defined in x86.ad. 1005 static void vec_mov_helper(C2_MacroAssembler *masm, int src_lo, int dst_lo, 1006 int src_hi, int dst_hi, uint ireg, outputStream* st); 1007 1008 void vec_spill_helper(C2_MacroAssembler *masm, bool is_load, 1009 int stack_offset, int reg, uint ireg, outputStream* st); 1010 1011 static void vec_stack_to_stack_helper(C2_MacroAssembler *masm, int src_offset, 1012 int dst_offset, uint ireg, outputStream* st) { 1013 if (masm) { 1014 switch (ireg) { 1015 case Op_VecS: 1016 __ movq(Address(rsp, -8), rax); 1017 __ movl(rax, Address(rsp, src_offset)); 1018 __ movl(Address(rsp, dst_offset), rax); 1019 __ movq(rax, Address(rsp, -8)); 1020 break; 1021 case Op_VecD: 1022 __ pushq(Address(rsp, src_offset)); 1023 __ popq (Address(rsp, dst_offset)); 1024 break; 1025 case Op_VecX: 1026 __ pushq(Address(rsp, src_offset)); 1027 __ popq (Address(rsp, dst_offset)); 1028 __ pushq(Address(rsp, src_offset+8)); 1029 __ popq (Address(rsp, dst_offset+8)); 1030 break; 1031 case Op_VecY: 1032 __ vmovdqu(Address(rsp, -32), xmm0); 1033 __ vmovdqu(xmm0, Address(rsp, src_offset)); 1034 __ vmovdqu(Address(rsp, dst_offset), xmm0); 1035 __ vmovdqu(xmm0, Address(rsp, -32)); 1036 break; 1037 case Op_VecZ: 1038 __ evmovdquq(Address(rsp, -64), xmm0, 2); 1039 __ evmovdquq(xmm0, Address(rsp, src_offset), 2); 1040 __ evmovdquq(Address(rsp, dst_offset), xmm0, 2); 1041 __ evmovdquq(xmm0, Address(rsp, -64), 2); 1042 break; 1043 default: 1044 ShouldNotReachHere(); 1045 } 1046 #ifndef PRODUCT 1047 } else { 1048 switch (ireg) { 1049 case Op_VecS: 1050 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1051 "movl rax, [rsp + #%d]\n\t" 1052 "movl [rsp + #%d], rax\n\t" 1053 "movq rax, [rsp - #8]", 1054 src_offset, dst_offset); 1055 break; 1056 case Op_VecD: 1057 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1058 "popq [rsp + #%d]", 1059 src_offset, dst_offset); 1060 break; 1061 case Op_VecX: 1062 st->print("pushq [rsp + #%d]\t# 128-bit mem-mem spill\n\t" 1063 "popq [rsp + #%d]\n\t" 1064 "pushq [rsp + #%d]\n\t" 1065 "popq [rsp + #%d]", 1066 src_offset, dst_offset, src_offset+8, dst_offset+8); 1067 break; 1068 case Op_VecY: 1069 st->print("vmovdqu [rsp - #32], xmm0\t# 256-bit mem-mem spill\n\t" 1070 "vmovdqu xmm0, [rsp + #%d]\n\t" 1071 "vmovdqu [rsp + #%d], xmm0\n\t" 1072 "vmovdqu xmm0, [rsp - #32]", 1073 src_offset, dst_offset); 1074 break; 1075 case Op_VecZ: 1076 st->print("vmovdqu [rsp - #64], xmm0\t# 512-bit mem-mem spill\n\t" 1077 "vmovdqu xmm0, [rsp + #%d]\n\t" 1078 "vmovdqu [rsp + #%d], xmm0\n\t" 1079 "vmovdqu xmm0, [rsp - #64]", 1080 src_offset, dst_offset); 1081 break; 1082 default: 1083 ShouldNotReachHere(); 1084 } 1085 #endif 1086 } 1087 } 1088 1089 uint MachSpillCopyNode::implementation(C2_MacroAssembler* masm, 1090 PhaseRegAlloc* ra_, 1091 bool do_size, 1092 outputStream* st) const { 1093 assert(masm != nullptr || st != nullptr, "sanity"); 1094 // Get registers to move 1095 OptoReg::Name src_second = ra_->get_reg_second(in(1)); 1096 OptoReg::Name src_first = ra_->get_reg_first(in(1)); 1097 OptoReg::Name dst_second = ra_->get_reg_second(this); 1098 OptoReg::Name dst_first = ra_->get_reg_first(this); 1099 1100 enum RC src_second_rc = rc_class(src_second); 1101 enum RC src_first_rc = rc_class(src_first); 1102 enum RC dst_second_rc = rc_class(dst_second); 1103 enum RC dst_first_rc = rc_class(dst_first); 1104 1105 assert(OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), 1106 "must move at least 1 register" ); 1107 1108 if (src_first == dst_first && src_second == dst_second) { 1109 // Self copy, no move 1110 return 0; 1111 } 1112 if (bottom_type()->isa_vect() != nullptr && bottom_type()->isa_vectmask() == nullptr) { 1113 uint ireg = ideal_reg(); 1114 assert((src_first_rc != rc_int && dst_first_rc != rc_int), "sanity"); 1115 assert((ireg == Op_VecS || ireg == Op_VecD || ireg == Op_VecX || ireg == Op_VecY || ireg == Op_VecZ ), "sanity"); 1116 if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) { 1117 // mem -> mem 1118 int src_offset = ra_->reg2offset(src_first); 1119 int dst_offset = ra_->reg2offset(dst_first); 1120 vec_stack_to_stack_helper(masm, src_offset, dst_offset, ireg, st); 1121 } else if (src_first_rc == rc_float && dst_first_rc == rc_float ) { 1122 vec_mov_helper(masm, src_first, dst_first, src_second, dst_second, ireg, st); 1123 } else if (src_first_rc == rc_float && dst_first_rc == rc_stack ) { 1124 int stack_offset = ra_->reg2offset(dst_first); 1125 vec_spill_helper(masm, false, stack_offset, src_first, ireg, st); 1126 } else if (src_first_rc == rc_stack && dst_first_rc == rc_float ) { 1127 int stack_offset = ra_->reg2offset(src_first); 1128 vec_spill_helper(masm, true, stack_offset, dst_first, ireg, st); 1129 } else { 1130 ShouldNotReachHere(); 1131 } 1132 return 0; 1133 } 1134 if (src_first_rc == rc_stack) { 1135 // mem -> 1136 if (dst_first_rc == rc_stack) { 1137 // mem -> mem 1138 assert(src_second != dst_first, "overlap"); 1139 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1140 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1141 // 64-bit 1142 int src_offset = ra_->reg2offset(src_first); 1143 int dst_offset = ra_->reg2offset(dst_first); 1144 if (masm) { 1145 __ pushq(Address(rsp, src_offset)); 1146 __ popq (Address(rsp, dst_offset)); 1147 #ifndef PRODUCT 1148 } else { 1149 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1150 "popq [rsp + #%d]", 1151 src_offset, dst_offset); 1152 #endif 1153 } 1154 } else { 1155 // 32-bit 1156 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1157 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1158 // No pushl/popl, so: 1159 int src_offset = ra_->reg2offset(src_first); 1160 int dst_offset = ra_->reg2offset(dst_first); 1161 if (masm) { 1162 __ movq(Address(rsp, -8), rax); 1163 __ movl(rax, Address(rsp, src_offset)); 1164 __ movl(Address(rsp, dst_offset), rax); 1165 __ movq(rax, Address(rsp, -8)); 1166 #ifndef PRODUCT 1167 } else { 1168 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1169 "movl rax, [rsp + #%d]\n\t" 1170 "movl [rsp + #%d], rax\n\t" 1171 "movq rax, [rsp - #8]", 1172 src_offset, dst_offset); 1173 #endif 1174 } 1175 } 1176 return 0; 1177 } else if (dst_first_rc == rc_int) { 1178 // mem -> gpr 1179 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1180 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1181 // 64-bit 1182 int offset = ra_->reg2offset(src_first); 1183 if (masm) { 1184 __ movq(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1185 #ifndef PRODUCT 1186 } else { 1187 st->print("movq %s, [rsp + #%d]\t# spill", 1188 Matcher::regName[dst_first], 1189 offset); 1190 #endif 1191 } 1192 } else { 1193 // 32-bit 1194 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1195 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1196 int offset = ra_->reg2offset(src_first); 1197 if (masm) { 1198 __ movl(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1199 #ifndef PRODUCT 1200 } else { 1201 st->print("movl %s, [rsp + #%d]\t# spill", 1202 Matcher::regName[dst_first], 1203 offset); 1204 #endif 1205 } 1206 } 1207 return 0; 1208 } else if (dst_first_rc == rc_float) { 1209 // mem-> xmm 1210 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1211 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1212 // 64-bit 1213 int offset = ra_->reg2offset(src_first); 1214 if (masm) { 1215 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1216 #ifndef PRODUCT 1217 } else { 1218 st->print("%s %s, [rsp + #%d]\t# spill", 1219 UseXmmLoadAndClearUpper ? "movsd " : "movlpd", 1220 Matcher::regName[dst_first], 1221 offset); 1222 #endif 1223 } 1224 } else { 1225 // 32-bit 1226 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1227 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1228 int offset = ra_->reg2offset(src_first); 1229 if (masm) { 1230 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1231 #ifndef PRODUCT 1232 } else { 1233 st->print("movss %s, [rsp + #%d]\t# spill", 1234 Matcher::regName[dst_first], 1235 offset); 1236 #endif 1237 } 1238 } 1239 return 0; 1240 } else if (dst_first_rc == rc_kreg) { 1241 // mem -> kreg 1242 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1243 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1244 // 64-bit 1245 int offset = ra_->reg2offset(src_first); 1246 if (masm) { 1247 __ kmov(as_KRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1248 #ifndef PRODUCT 1249 } else { 1250 st->print("kmovq %s, [rsp + #%d]\t# spill", 1251 Matcher::regName[dst_first], 1252 offset); 1253 #endif 1254 } 1255 } 1256 return 0; 1257 } 1258 } else if (src_first_rc == rc_int) { 1259 // gpr -> 1260 if (dst_first_rc == rc_stack) { 1261 // gpr -> mem 1262 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1263 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1264 // 64-bit 1265 int offset = ra_->reg2offset(dst_first); 1266 if (masm) { 1267 __ movq(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1268 #ifndef PRODUCT 1269 } else { 1270 st->print("movq [rsp + #%d], %s\t# spill", 1271 offset, 1272 Matcher::regName[src_first]); 1273 #endif 1274 } 1275 } else { 1276 // 32-bit 1277 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1278 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1279 int offset = ra_->reg2offset(dst_first); 1280 if (masm) { 1281 __ movl(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1282 #ifndef PRODUCT 1283 } else { 1284 st->print("movl [rsp + #%d], %s\t# spill", 1285 offset, 1286 Matcher::regName[src_first]); 1287 #endif 1288 } 1289 } 1290 return 0; 1291 } else if (dst_first_rc == rc_int) { 1292 // gpr -> gpr 1293 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1294 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1295 // 64-bit 1296 if (masm) { 1297 __ movq(as_Register(Matcher::_regEncode[dst_first]), 1298 as_Register(Matcher::_regEncode[src_first])); 1299 #ifndef PRODUCT 1300 } else { 1301 st->print("movq %s, %s\t# spill", 1302 Matcher::regName[dst_first], 1303 Matcher::regName[src_first]); 1304 #endif 1305 } 1306 return 0; 1307 } else { 1308 // 32-bit 1309 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1310 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1311 if (masm) { 1312 __ movl(as_Register(Matcher::_regEncode[dst_first]), 1313 as_Register(Matcher::_regEncode[src_first])); 1314 #ifndef PRODUCT 1315 } else { 1316 st->print("movl %s, %s\t# spill", 1317 Matcher::regName[dst_first], 1318 Matcher::regName[src_first]); 1319 #endif 1320 } 1321 return 0; 1322 } 1323 } else if (dst_first_rc == rc_float) { 1324 // gpr -> xmm 1325 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1326 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1327 // 64-bit 1328 if (masm) { 1329 __ movdq( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1330 #ifndef PRODUCT 1331 } else { 1332 st->print("movdq %s, %s\t# spill", 1333 Matcher::regName[dst_first], 1334 Matcher::regName[src_first]); 1335 #endif 1336 } 1337 } else { 1338 // 32-bit 1339 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1340 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1341 if (masm) { 1342 __ movdl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1343 #ifndef PRODUCT 1344 } else { 1345 st->print("movdl %s, %s\t# spill", 1346 Matcher::regName[dst_first], 1347 Matcher::regName[src_first]); 1348 #endif 1349 } 1350 } 1351 return 0; 1352 } else if (dst_first_rc == rc_kreg) { 1353 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1354 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1355 // 64-bit 1356 if (masm) { 1357 __ kmov(as_KRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1358 #ifndef PRODUCT 1359 } else { 1360 st->print("kmovq %s, %s\t# spill", 1361 Matcher::regName[dst_first], 1362 Matcher::regName[src_first]); 1363 #endif 1364 } 1365 } 1366 Unimplemented(); 1367 return 0; 1368 } 1369 } else if (src_first_rc == rc_float) { 1370 // xmm -> 1371 if (dst_first_rc == rc_stack) { 1372 // xmm -> mem 1373 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1374 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1375 // 64-bit 1376 int offset = ra_->reg2offset(dst_first); 1377 if (masm) { 1378 __ movdbl( Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1379 #ifndef PRODUCT 1380 } else { 1381 st->print("movsd [rsp + #%d], %s\t# spill", 1382 offset, 1383 Matcher::regName[src_first]); 1384 #endif 1385 } 1386 } else { 1387 // 32-bit 1388 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1389 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1390 int offset = ra_->reg2offset(dst_first); 1391 if (masm) { 1392 __ movflt(Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1393 #ifndef PRODUCT 1394 } else { 1395 st->print("movss [rsp + #%d], %s\t# spill", 1396 offset, 1397 Matcher::regName[src_first]); 1398 #endif 1399 } 1400 } 1401 return 0; 1402 } else if (dst_first_rc == rc_int) { 1403 // xmm -> gpr 1404 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1405 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1406 // 64-bit 1407 if (masm) { 1408 __ movdq( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1409 #ifndef PRODUCT 1410 } else { 1411 st->print("movdq %s, %s\t# spill", 1412 Matcher::regName[dst_first], 1413 Matcher::regName[src_first]); 1414 #endif 1415 } 1416 } else { 1417 // 32-bit 1418 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1419 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1420 if (masm) { 1421 __ movdl( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1422 #ifndef PRODUCT 1423 } else { 1424 st->print("movdl %s, %s\t# spill", 1425 Matcher::regName[dst_first], 1426 Matcher::regName[src_first]); 1427 #endif 1428 } 1429 } 1430 return 0; 1431 } else if (dst_first_rc == rc_float) { 1432 // xmm -> xmm 1433 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1434 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1435 // 64-bit 1436 if (masm) { 1437 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1438 #ifndef PRODUCT 1439 } else { 1440 st->print("%s %s, %s\t# spill", 1441 UseXmmRegToRegMoveAll ? "movapd" : "movsd ", 1442 Matcher::regName[dst_first], 1443 Matcher::regName[src_first]); 1444 #endif 1445 } 1446 } else { 1447 // 32-bit 1448 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1449 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1450 if (masm) { 1451 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1452 #ifndef PRODUCT 1453 } else { 1454 st->print("%s %s, %s\t# spill", 1455 UseXmmRegToRegMoveAll ? "movaps" : "movss ", 1456 Matcher::regName[dst_first], 1457 Matcher::regName[src_first]); 1458 #endif 1459 } 1460 } 1461 return 0; 1462 } else if (dst_first_rc == rc_kreg) { 1463 assert(false, "Illegal spilling"); 1464 return 0; 1465 } 1466 } else if (src_first_rc == rc_kreg) { 1467 if (dst_first_rc == rc_stack) { 1468 // mem -> kreg 1469 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1470 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1471 // 64-bit 1472 int offset = ra_->reg2offset(dst_first); 1473 if (masm) { 1474 __ kmov(Address(rsp, offset), as_KRegister(Matcher::_regEncode[src_first])); 1475 #ifndef PRODUCT 1476 } else { 1477 st->print("kmovq [rsp + #%d] , %s\t# spill", 1478 offset, 1479 Matcher::regName[src_first]); 1480 #endif 1481 } 1482 } 1483 return 0; 1484 } else if (dst_first_rc == rc_int) { 1485 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1486 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1487 // 64-bit 1488 if (masm) { 1489 __ kmov(as_Register(Matcher::_regEncode[dst_first]), as_KRegister(Matcher::_regEncode[src_first])); 1490 #ifndef PRODUCT 1491 } else { 1492 st->print("kmovq %s, %s\t# spill", 1493 Matcher::regName[dst_first], 1494 Matcher::regName[src_first]); 1495 #endif 1496 } 1497 } 1498 Unimplemented(); 1499 return 0; 1500 } else if (dst_first_rc == rc_kreg) { 1501 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1502 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1503 // 64-bit 1504 if (masm) { 1505 __ kmov(as_KRegister(Matcher::_regEncode[dst_first]), as_KRegister(Matcher::_regEncode[src_first])); 1506 #ifndef PRODUCT 1507 } else { 1508 st->print("kmovq %s, %s\t# spill", 1509 Matcher::regName[dst_first], 1510 Matcher::regName[src_first]); 1511 #endif 1512 } 1513 } 1514 return 0; 1515 } else if (dst_first_rc == rc_float) { 1516 assert(false, "Illegal spill"); 1517 return 0; 1518 } 1519 } 1520 1521 assert(0," foo "); 1522 Unimplemented(); 1523 return 0; 1524 } 1525 1526 #ifndef PRODUCT 1527 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream* st) const { 1528 implementation(nullptr, ra_, false, st); 1529 } 1530 #endif 1531 1532 void MachSpillCopyNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const { 1533 implementation(masm, ra_, false, nullptr); 1534 } 1535 1536 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1537 return MachNode::size(ra_); 1538 } 1539 1540 //============================================================================= 1541 #ifndef PRODUCT 1542 void BoxLockNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1543 { 1544 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1545 int reg = ra_->get_reg_first(this); 1546 st->print("leaq %s, [rsp + #%d]\t# box lock", 1547 Matcher::regName[reg], offset); 1548 } 1549 #endif 1550 1551 void BoxLockNode::emit(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const 1552 { 1553 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1554 int reg = ra_->get_encode(this); 1555 1556 __ lea(as_Register(reg), Address(rsp, offset)); 1557 } 1558 1559 uint BoxLockNode::size(PhaseRegAlloc *ra_) const 1560 { 1561 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1562 if (ra_->get_encode(this) > 15) { 1563 return (offset < 0x80) ? 6 : 9; // REX2 1564 } else { 1565 return (offset < 0x80) ? 5 : 8; // REX 1566 } 1567 } 1568 1569 //============================================================================= 1570 #ifndef PRODUCT 1571 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1572 { 1573 if (UseCompressedClassPointers) { 1574 st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1575 st->print_cr("\tcmpl rscratch1, [rax + CompiledICData::speculated_klass_offset()]\t # Inline cache check"); 1576 } else { 1577 st->print_cr("movq rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1578 st->print_cr("\tcmpq rscratch1, [rax + CompiledICData::speculated_klass_offset()]\t # Inline cache check"); 1579 } 1580 st->print_cr("\tjne SharedRuntime::_ic_miss_stub"); 1581 } 1582 #endif 1583 1584 void MachUEPNode::emit(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const 1585 { 1586 __ ic_check(InteriorEntryAlignment); 1587 } 1588 1589 uint MachUEPNode::size(PhaseRegAlloc* ra_) const 1590 { 1591 return MachNode::size(ra_); // too many variables; just compute it 1592 // the hard way 1593 } 1594 1595 1596 //============================================================================= 1597 1598 bool Matcher::supports_vector_calling_convention(void) { 1599 return EnableVectorSupport; 1600 } 1601 1602 OptoRegPair Matcher::vector_return_value(uint ideal_reg) { 1603 assert(EnableVectorSupport, "sanity"); 1604 int lo = XMM0_num; 1605 int hi = XMM0b_num; 1606 if (ideal_reg == Op_VecX) hi = XMM0d_num; 1607 else if (ideal_reg == Op_VecY) hi = XMM0h_num; 1608 else if (ideal_reg == Op_VecZ) hi = XMM0p_num; 1609 return OptoRegPair(hi, lo); 1610 } 1611 1612 // Is this branch offset short enough that a short branch can be used? 1613 // 1614 // NOTE: If the platform does not provide any short branch variants, then 1615 // this method should return false for offset 0. 1616 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 1617 // The passed offset is relative to address of the branch. 1618 // On 86 a branch displacement is calculated relative to address 1619 // of a next instruction. 1620 offset -= br_size; 1621 1622 // the short version of jmpConUCF2 contains multiple branches, 1623 // making the reach slightly less 1624 if (rule == jmpConUCF2_rule) 1625 return (-126 <= offset && offset <= 125); 1626 return (-128 <= offset && offset <= 127); 1627 } 1628 1629 // Return whether or not this register is ever used as an argument. 1630 // This function is used on startup to build the trampoline stubs in 1631 // generateOptoStub. Registers not mentioned will be killed by the VM 1632 // call in the trampoline, and arguments in those registers not be 1633 // available to the callee. 1634 bool Matcher::can_be_java_arg(int reg) 1635 { 1636 return 1637 reg == RDI_num || reg == RDI_H_num || 1638 reg == RSI_num || reg == RSI_H_num || 1639 reg == RDX_num || reg == RDX_H_num || 1640 reg == RCX_num || reg == RCX_H_num || 1641 reg == R8_num || reg == R8_H_num || 1642 reg == R9_num || reg == R9_H_num || 1643 reg == R12_num || reg == R12_H_num || 1644 reg == XMM0_num || reg == XMM0b_num || 1645 reg == XMM1_num || reg == XMM1b_num || 1646 reg == XMM2_num || reg == XMM2b_num || 1647 reg == XMM3_num || reg == XMM3b_num || 1648 reg == XMM4_num || reg == XMM4b_num || 1649 reg == XMM5_num || reg == XMM5b_num || 1650 reg == XMM6_num || reg == XMM6b_num || 1651 reg == XMM7_num || reg == XMM7b_num; 1652 } 1653 1654 bool Matcher::is_spillable_arg(int reg) 1655 { 1656 return can_be_java_arg(reg); 1657 } 1658 1659 uint Matcher::int_pressure_limit() 1660 { 1661 return (INTPRESSURE == -1) ? _INT_REG_mask.Size() : INTPRESSURE; 1662 } 1663 1664 uint Matcher::float_pressure_limit() 1665 { 1666 // After experiment around with different values, the following default threshold 1667 // works best for LCM's register pressure scheduling on x64. 1668 uint dec_count = VM_Version::supports_evex() ? 4 : 2; 1669 uint default_float_pressure_threshold = _FLOAT_REG_mask.Size() - dec_count; 1670 return (FLOATPRESSURE == -1) ? default_float_pressure_threshold : FLOATPRESSURE; 1671 } 1672 1673 bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) { 1674 // In 64 bit mode a code which use multiply when 1675 // devisor is constant is faster than hardware 1676 // DIV instruction (it uses MulHiL). 1677 return false; 1678 } 1679 1680 // Register for DIVI projection of divmodI 1681 RegMask Matcher::divI_proj_mask() { 1682 return INT_RAX_REG_mask(); 1683 } 1684 1685 // Register for MODI projection of divmodI 1686 RegMask Matcher::modI_proj_mask() { 1687 return INT_RDX_REG_mask(); 1688 } 1689 1690 // Register for DIVL projection of divmodL 1691 RegMask Matcher::divL_proj_mask() { 1692 return LONG_RAX_REG_mask(); 1693 } 1694 1695 // Register for MODL projection of divmodL 1696 RegMask Matcher::modL_proj_mask() { 1697 return LONG_RDX_REG_mask(); 1698 } 1699 1700 // Register for saving SP into on method handle invokes. Not used on x86_64. 1701 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 1702 return NO_REG_mask(); 1703 } 1704 1705 %} 1706 1707 //----------ENCODING BLOCK----------------------------------------------------- 1708 // This block specifies the encoding classes used by the compiler to 1709 // output byte streams. Encoding classes are parameterized macros 1710 // used by Machine Instruction Nodes in order to generate the bit 1711 // encoding of the instruction. Operands specify their base encoding 1712 // interface with the interface keyword. There are currently 1713 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & 1714 // COND_INTER. REG_INTER causes an operand to generate a function 1715 // which returns its register number when queried. CONST_INTER causes 1716 // an operand to generate a function which returns the value of the 1717 // constant when queried. MEMORY_INTER causes an operand to generate 1718 // four functions which return the Base Register, the Index Register, 1719 // the Scale Value, and the Offset Value of the operand when queried. 1720 // COND_INTER causes an operand to generate six functions which return 1721 // the encoding code (ie - encoding bits for the instruction) 1722 // associated with each basic boolean condition for a conditional 1723 // instruction. 1724 // 1725 // Instructions specify two basic values for encoding. Again, a 1726 // function is available to check if the constant displacement is an 1727 // oop. They use the ins_encode keyword to specify their encoding 1728 // classes (which must be a sequence of enc_class names, and their 1729 // parameters, specified in the encoding block), and they use the 1730 // opcode keyword to specify, in order, their primary, secondary, and 1731 // tertiary opcode. Only the opcode sections which a particular 1732 // instruction needs for encoding need to be specified. 1733 encode %{ 1734 enc_class cdql_enc(no_rax_rdx_RegI div) 1735 %{ 1736 // Full implementation of Java idiv and irem; checks for 1737 // special case as described in JVM spec., p.243 & p.271. 1738 // 1739 // normal case special case 1740 // 1741 // input : rax: dividend min_int 1742 // reg: divisor -1 1743 // 1744 // output: rax: quotient (= rax idiv reg) min_int 1745 // rdx: remainder (= rax irem reg) 0 1746 // 1747 // Code sequnce: 1748 // 1749 // 0: 3d 00 00 00 80 cmp $0x80000000,%eax 1750 // 5: 75 07/08 jne e <normal> 1751 // 7: 33 d2 xor %edx,%edx 1752 // [div >= 8 -> offset + 1] 1753 // [REX_B] 1754 // 9: 83 f9 ff cmp $0xffffffffffffffff,$div 1755 // c: 74 03/04 je 11 <done> 1756 // 000000000000000e <normal>: 1757 // e: 99 cltd 1758 // [div >= 8 -> offset + 1] 1759 // [REX_B] 1760 // f: f7 f9 idiv $div 1761 // 0000000000000011 <done>: 1762 Label normal; 1763 Label done; 1764 1765 // cmp $0x80000000,%eax 1766 __ cmpl(as_Register(RAX_enc), 0x80000000); 1767 1768 // jne e <normal> 1769 __ jccb(Assembler::notEqual, normal); 1770 1771 // xor %edx,%edx 1772 __ xorl(as_Register(RDX_enc), as_Register(RDX_enc)); 1773 1774 // cmp $0xffffffffffffffff,%ecx 1775 __ cmpl($div$$Register, -1); 1776 1777 // je 11 <done> 1778 __ jccb(Assembler::equal, done); 1779 1780 // <normal> 1781 // cltd 1782 __ bind(normal); 1783 __ cdql(); 1784 1785 // idivl 1786 // <done> 1787 __ idivl($div$$Register); 1788 __ bind(done); 1789 %} 1790 1791 enc_class cdqq_enc(no_rax_rdx_RegL div) 1792 %{ 1793 // Full implementation of Java ldiv and lrem; checks for 1794 // special case as described in JVM spec., p.243 & p.271. 1795 // 1796 // normal case special case 1797 // 1798 // input : rax: dividend min_long 1799 // reg: divisor -1 1800 // 1801 // output: rax: quotient (= rax idiv reg) min_long 1802 // rdx: remainder (= rax irem reg) 0 1803 // 1804 // Code sequnce: 1805 // 1806 // 0: 48 ba 00 00 00 00 00 mov $0x8000000000000000,%rdx 1807 // 7: 00 00 80 1808 // a: 48 39 d0 cmp %rdx,%rax 1809 // d: 75 08 jne 17 <normal> 1810 // f: 33 d2 xor %edx,%edx 1811 // 11: 48 83 f9 ff cmp $0xffffffffffffffff,$div 1812 // 15: 74 05 je 1c <done> 1813 // 0000000000000017 <normal>: 1814 // 17: 48 99 cqto 1815 // 19: 48 f7 f9 idiv $div 1816 // 000000000000001c <done>: 1817 Label normal; 1818 Label done; 1819 1820 // mov $0x8000000000000000,%rdx 1821 __ mov64(as_Register(RDX_enc), 0x8000000000000000); 1822 1823 // cmp %rdx,%rax 1824 __ cmpq(as_Register(RAX_enc), as_Register(RDX_enc)); 1825 1826 // jne 17 <normal> 1827 __ jccb(Assembler::notEqual, normal); 1828 1829 // xor %edx,%edx 1830 __ xorl(as_Register(RDX_enc), as_Register(RDX_enc)); 1831 1832 // cmp $0xffffffffffffffff,$div 1833 __ cmpq($div$$Register, -1); 1834 1835 // je 1e <done> 1836 __ jccb(Assembler::equal, done); 1837 1838 // <normal> 1839 // cqto 1840 __ bind(normal); 1841 __ cdqq(); 1842 1843 // idivq (note: must be emitted by the user of this rule) 1844 // <done> 1845 __ idivq($div$$Register); 1846 __ bind(done); 1847 %} 1848 1849 enc_class clear_avx %{ 1850 DEBUG_ONLY(int off0 = __ offset()); 1851 if (generate_vzeroupper(Compile::current())) { 1852 // Clear upper bits of YMM registers to avoid AVX <-> SSE transition penalty 1853 // Clear upper bits of YMM registers when current compiled code uses 1854 // wide vectors to avoid AVX <-> SSE transition penalty during call. 1855 __ vzeroupper(); 1856 } 1857 DEBUG_ONLY(int off1 = __ offset()); 1858 assert(off1 - off0 == clear_avx_size(), "correct size prediction"); 1859 %} 1860 1861 enc_class Java_To_Runtime(method meth) %{ 1862 __ lea(r10, RuntimeAddress((address)$meth$$method)); 1863 __ call(r10); 1864 __ post_call_nop(); 1865 %} 1866 1867 enc_class Java_Static_Call(method meth) 1868 %{ 1869 // JAVA STATIC CALL 1870 // CALL to fixup routine. Fixup routine uses ScopeDesc info to 1871 // determine who we intended to call. 1872 if (!_method) { 1873 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, $meth$$method))); 1874 } else if (_method->intrinsic_id() == vmIntrinsicID::_ensureMaterializedForStackWalk) { 1875 // The NOP here is purely to ensure that eliding a call to 1876 // JVM_EnsureMaterializedForStackWalk doesn't change the code size. 1877 __ addr_nop_5(); 1878 __ block_comment("call JVM_EnsureMaterializedForStackWalk (elided)"); 1879 } else { 1880 int method_index = resolved_method_index(masm); 1881 RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 1882 : static_call_Relocation::spec(method_index); 1883 address mark = __ pc(); 1884 int call_offset = __ offset(); 1885 __ call(AddressLiteral(CAST_FROM_FN_PTR(address, $meth$$method), rspec)); 1886 if (CodeBuffer::supports_shared_stubs() && _method->can_be_statically_bound()) { 1887 // Calls of the same statically bound method can share 1888 // a stub to the interpreter. 1889 __ code()->shared_stub_to_interp_for(_method, call_offset); 1890 } else { 1891 // Emit stubs for static call. 1892 address stub = CompiledDirectCall::emit_to_interp_stub(masm, mark); 1893 __ clear_inst_mark(); 1894 if (stub == nullptr) { 1895 ciEnv::current()->record_failure("CodeCache is full"); 1896 return; 1897 } 1898 } 1899 } 1900 __ post_call_nop(); 1901 %} 1902 1903 enc_class Java_Dynamic_Call(method meth) %{ 1904 __ ic_call((address)$meth$$method, resolved_method_index(masm)); 1905 __ post_call_nop(); 1906 %} 1907 1908 %} 1909 1910 1911 1912 //----------FRAME-------------------------------------------------------------- 1913 // Definition of frame structure and management information. 1914 // 1915 // S T A C K L A Y O U T Allocators stack-slot number 1916 // | (to get allocators register number 1917 // G Owned by | | v add OptoReg::stack0()) 1918 // r CALLER | | 1919 // o | +--------+ pad to even-align allocators stack-slot 1920 // w V | pad0 | numbers; owned by CALLER 1921 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned 1922 // h ^ | in | 5 1923 // | | args | 4 Holes in incoming args owned by SELF 1924 // | | | | 3 1925 // | | +--------+ 1926 // V | | old out| Empty on Intel, window on Sparc 1927 // | old |preserve| Must be even aligned. 1928 // | SP-+--------+----> Matcher::_old_SP, even aligned 1929 // | | in | 3 area for Intel ret address 1930 // Owned by |preserve| Empty on Sparc. 1931 // SELF +--------+ 1932 // | | pad2 | 2 pad to align old SP 1933 // | +--------+ 1 1934 // | | locks | 0 1935 // | +--------+----> OptoReg::stack0(), even aligned 1936 // | | pad1 | 11 pad to align new SP 1937 // | +--------+ 1938 // | | | 10 1939 // | | spills | 9 spills 1940 // V | | 8 (pad0 slot for callee) 1941 // -----------+--------+----> Matcher::_out_arg_limit, unaligned 1942 // ^ | out | 7 1943 // | | args | 6 Holes in outgoing args owned by CALLEE 1944 // Owned by +--------+ 1945 // CALLEE | new out| 6 Empty on Intel, window on Sparc 1946 // | new |preserve| Must be even-aligned. 1947 // | SP-+--------+----> Matcher::_new_SP, even aligned 1948 // | | | 1949 // 1950 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 1951 // known from SELF's arguments and the Java calling convention. 1952 // Region 6-7 is determined per call site. 1953 // Note 2: If the calling convention leaves holes in the incoming argument 1954 // area, those holes are owned by SELF. Holes in the outgoing area 1955 // are owned by the CALLEE. Holes should not be necessary in the 1956 // incoming area, as the Java calling convention is completely under 1957 // the control of the AD file. Doubles can be sorted and packed to 1958 // avoid holes. Holes in the outgoing arguments may be necessary for 1959 // varargs C calling conventions. 1960 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 1961 // even aligned with pad0 as needed. 1962 // Region 6 is even aligned. Region 6-7 is NOT even aligned; 1963 // region 6-11 is even aligned; it may be padded out more so that 1964 // the region from SP to FP meets the minimum stack alignment. 1965 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 1966 // alignment. Region 11, pad1, may be dynamically extended so that 1967 // SP meets the minimum alignment. 1968 1969 frame 1970 %{ 1971 // These three registers define part of the calling convention 1972 // between compiled code and the interpreter. 1973 inline_cache_reg(RAX); // Inline Cache Register 1974 1975 // Optional: name the operand used by cisc-spilling to access 1976 // [stack_pointer + offset] 1977 cisc_spilling_operand_name(indOffset32); 1978 1979 // Number of stack slots consumed by locking an object 1980 sync_stack_slots(2); 1981 1982 // Compiled code's Frame Pointer 1983 frame_pointer(RSP); 1984 1985 // Interpreter stores its frame pointer in a register which is 1986 // stored to the stack by I2CAdaptors. 1987 // I2CAdaptors convert from interpreted java to compiled java. 1988 interpreter_frame_pointer(RBP); 1989 1990 // Stack alignment requirement 1991 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 1992 1993 // Number of outgoing stack slots killed above the out_preserve_stack_slots 1994 // for calls to C. Supports the var-args backing area for register parms. 1995 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 1996 1997 // The after-PROLOG location of the return address. Location of 1998 // return address specifies a type (REG or STACK) and a number 1999 // representing the register number (i.e. - use a register name) or 2000 // stack slot. 2001 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 2002 // Otherwise, it is above the locks and verification slot and alignment word 2003 return_addr(STACK - 2 + 2004 align_up((Compile::current()->in_preserve_stack_slots() + 2005 Compile::current()->fixed_slots()), 2006 stack_alignment_in_slots())); 2007 2008 // Location of compiled Java return values. Same as C for now. 2009 return_value 2010 %{ 2011 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 2012 "only return normal values"); 2013 2014 static const int lo[Op_RegL + 1] = { 2015 0, 2016 0, 2017 RAX_num, // Op_RegN 2018 RAX_num, // Op_RegI 2019 RAX_num, // Op_RegP 2020 XMM0_num, // Op_RegF 2021 XMM0_num, // Op_RegD 2022 RAX_num // Op_RegL 2023 }; 2024 static const int hi[Op_RegL + 1] = { 2025 0, 2026 0, 2027 OptoReg::Bad, // Op_RegN 2028 OptoReg::Bad, // Op_RegI 2029 RAX_H_num, // Op_RegP 2030 OptoReg::Bad, // Op_RegF 2031 XMM0b_num, // Op_RegD 2032 RAX_H_num // Op_RegL 2033 }; 2034 // Excluded flags and vector registers. 2035 assert(ARRAY_SIZE(hi) == _last_machine_leaf - 8, "missing type"); 2036 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 2037 %} 2038 %} 2039 2040 //----------ATTRIBUTES--------------------------------------------------------- 2041 //----------Operand Attributes------------------------------------------------- 2042 op_attrib op_cost(0); // Required cost attribute 2043 2044 //----------Instruction Attributes--------------------------------------------- 2045 ins_attrib ins_cost(100); // Required cost attribute 2046 ins_attrib ins_size(8); // Required size attribute (in bits) 2047 ins_attrib ins_short_branch(0); // Required flag: is this instruction 2048 // a non-matching short branch variant 2049 // of some long branch? 2050 ins_attrib ins_alignment(1); // Required alignment attribute (must 2051 // be a power of 2) specifies the 2052 // alignment that some part of the 2053 // instruction (not necessarily the 2054 // start) requires. If > 1, a 2055 // compute_padding() function must be 2056 // provided for the instruction 2057 2058 //----------OPERANDS----------------------------------------------------------- 2059 // Operand definitions must precede instruction definitions for correct parsing 2060 // in the ADLC because operands constitute user defined types which are used in 2061 // instruction definitions. 2062 2063 //----------Simple Operands---------------------------------------------------- 2064 // Immediate Operands 2065 // Integer Immediate 2066 operand immI() 2067 %{ 2068 match(ConI); 2069 2070 op_cost(10); 2071 format %{ %} 2072 interface(CONST_INTER); 2073 %} 2074 2075 // Constant for test vs zero 2076 operand immI_0() 2077 %{ 2078 predicate(n->get_int() == 0); 2079 match(ConI); 2080 2081 op_cost(0); 2082 format %{ %} 2083 interface(CONST_INTER); 2084 %} 2085 2086 // Constant for increment 2087 operand immI_1() 2088 %{ 2089 predicate(n->get_int() == 1); 2090 match(ConI); 2091 2092 op_cost(0); 2093 format %{ %} 2094 interface(CONST_INTER); 2095 %} 2096 2097 // Constant for decrement 2098 operand immI_M1() 2099 %{ 2100 predicate(n->get_int() == -1); 2101 match(ConI); 2102 2103 op_cost(0); 2104 format %{ %} 2105 interface(CONST_INTER); 2106 %} 2107 2108 operand immI_2() 2109 %{ 2110 predicate(n->get_int() == 2); 2111 match(ConI); 2112 2113 op_cost(0); 2114 format %{ %} 2115 interface(CONST_INTER); 2116 %} 2117 2118 operand immI_4() 2119 %{ 2120 predicate(n->get_int() == 4); 2121 match(ConI); 2122 2123 op_cost(0); 2124 format %{ %} 2125 interface(CONST_INTER); 2126 %} 2127 2128 operand immI_8() 2129 %{ 2130 predicate(n->get_int() == 8); 2131 match(ConI); 2132 2133 op_cost(0); 2134 format %{ %} 2135 interface(CONST_INTER); 2136 %} 2137 2138 // Valid scale values for addressing modes 2139 operand immI2() 2140 %{ 2141 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 2142 match(ConI); 2143 2144 format %{ %} 2145 interface(CONST_INTER); 2146 %} 2147 2148 operand immU7() 2149 %{ 2150 predicate((0 <= n->get_int()) && (n->get_int() <= 0x7F)); 2151 match(ConI); 2152 2153 op_cost(5); 2154 format %{ %} 2155 interface(CONST_INTER); 2156 %} 2157 2158 operand immI8() 2159 %{ 2160 predicate((-0x80 <= n->get_int()) && (n->get_int() < 0x80)); 2161 match(ConI); 2162 2163 op_cost(5); 2164 format %{ %} 2165 interface(CONST_INTER); 2166 %} 2167 2168 operand immU8() 2169 %{ 2170 predicate((0 <= n->get_int()) && (n->get_int() <= 255)); 2171 match(ConI); 2172 2173 op_cost(5); 2174 format %{ %} 2175 interface(CONST_INTER); 2176 %} 2177 2178 operand immI16() 2179 %{ 2180 predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767)); 2181 match(ConI); 2182 2183 op_cost(10); 2184 format %{ %} 2185 interface(CONST_INTER); 2186 %} 2187 2188 // Int Immediate non-negative 2189 operand immU31() 2190 %{ 2191 predicate(n->get_int() >= 0); 2192 match(ConI); 2193 2194 op_cost(0); 2195 format %{ %} 2196 interface(CONST_INTER); 2197 %} 2198 2199 // Pointer Immediate 2200 operand immP() 2201 %{ 2202 match(ConP); 2203 2204 op_cost(10); 2205 format %{ %} 2206 interface(CONST_INTER); 2207 %} 2208 2209 // Null Pointer Immediate 2210 operand immP0() 2211 %{ 2212 predicate(n->get_ptr() == 0); 2213 match(ConP); 2214 2215 op_cost(5); 2216 format %{ %} 2217 interface(CONST_INTER); 2218 %} 2219 2220 // Pointer Immediate 2221 operand immN() %{ 2222 match(ConN); 2223 2224 op_cost(10); 2225 format %{ %} 2226 interface(CONST_INTER); 2227 %} 2228 2229 operand immNKlass() %{ 2230 match(ConNKlass); 2231 2232 op_cost(10); 2233 format %{ %} 2234 interface(CONST_INTER); 2235 %} 2236 2237 // Null Pointer Immediate 2238 operand immN0() %{ 2239 predicate(n->get_narrowcon() == 0); 2240 match(ConN); 2241 2242 op_cost(5); 2243 format %{ %} 2244 interface(CONST_INTER); 2245 %} 2246 2247 operand immP31() 2248 %{ 2249 predicate(n->as_Type()->type()->reloc() == relocInfo::none 2250 && (n->get_ptr() >> 31) == 0); 2251 match(ConP); 2252 2253 op_cost(5); 2254 format %{ %} 2255 interface(CONST_INTER); 2256 %} 2257 2258 2259 // Long Immediate 2260 operand immL() 2261 %{ 2262 match(ConL); 2263 2264 op_cost(20); 2265 format %{ %} 2266 interface(CONST_INTER); 2267 %} 2268 2269 // Long Immediate 8-bit 2270 operand immL8() 2271 %{ 2272 predicate(-0x80L <= n->get_long() && n->get_long() < 0x80L); 2273 match(ConL); 2274 2275 op_cost(5); 2276 format %{ %} 2277 interface(CONST_INTER); 2278 %} 2279 2280 // Long Immediate 32-bit unsigned 2281 operand immUL32() 2282 %{ 2283 predicate(n->get_long() == (unsigned int) (n->get_long())); 2284 match(ConL); 2285 2286 op_cost(10); 2287 format %{ %} 2288 interface(CONST_INTER); 2289 %} 2290 2291 // Long Immediate 32-bit signed 2292 operand immL32() 2293 %{ 2294 predicate(n->get_long() == (int) (n->get_long())); 2295 match(ConL); 2296 2297 op_cost(15); 2298 format %{ %} 2299 interface(CONST_INTER); 2300 %} 2301 2302 operand immL_Pow2() 2303 %{ 2304 predicate(is_power_of_2((julong)n->get_long())); 2305 match(ConL); 2306 2307 op_cost(15); 2308 format %{ %} 2309 interface(CONST_INTER); 2310 %} 2311 2312 operand immL_NotPow2() 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 // Long Immediate zero 2323 operand immL0() 2324 %{ 2325 predicate(n->get_long() == 0L); 2326 match(ConL); 2327 2328 op_cost(10); 2329 format %{ %} 2330 interface(CONST_INTER); 2331 %} 2332 2333 // Constant for increment 2334 operand immL1() 2335 %{ 2336 predicate(n->get_long() == 1); 2337 match(ConL); 2338 2339 format %{ %} 2340 interface(CONST_INTER); 2341 %} 2342 2343 // Constant for decrement 2344 operand immL_M1() 2345 %{ 2346 predicate(n->get_long() == -1); 2347 match(ConL); 2348 2349 format %{ %} 2350 interface(CONST_INTER); 2351 %} 2352 2353 // Long Immediate: low 32-bit mask 2354 operand immL_32bits() 2355 %{ 2356 predicate(n->get_long() == 0xFFFFFFFFL); 2357 match(ConL); 2358 op_cost(20); 2359 2360 format %{ %} 2361 interface(CONST_INTER); 2362 %} 2363 2364 // Int Immediate: 2^n-1, positive 2365 operand immI_Pow2M1() 2366 %{ 2367 predicate((n->get_int() > 0) 2368 && is_power_of_2((juint)n->get_int() + 1)); 2369 match(ConI); 2370 2371 op_cost(20); 2372 format %{ %} 2373 interface(CONST_INTER); 2374 %} 2375 2376 // Float Immediate zero 2377 operand immF0() 2378 %{ 2379 predicate(jint_cast(n->getf()) == 0); 2380 match(ConF); 2381 2382 op_cost(5); 2383 format %{ %} 2384 interface(CONST_INTER); 2385 %} 2386 2387 // Float Immediate 2388 operand immF() 2389 %{ 2390 match(ConF); 2391 2392 op_cost(15); 2393 format %{ %} 2394 interface(CONST_INTER); 2395 %} 2396 2397 // Half Float Immediate 2398 operand immH() 2399 %{ 2400 match(ConH); 2401 2402 op_cost(15); 2403 format %{ %} 2404 interface(CONST_INTER); 2405 %} 2406 2407 // Double Immediate zero 2408 operand immD0() 2409 %{ 2410 predicate(jlong_cast(n->getd()) == 0); 2411 match(ConD); 2412 2413 op_cost(5); 2414 format %{ %} 2415 interface(CONST_INTER); 2416 %} 2417 2418 // Double Immediate 2419 operand immD() 2420 %{ 2421 match(ConD); 2422 2423 op_cost(15); 2424 format %{ %} 2425 interface(CONST_INTER); 2426 %} 2427 2428 // Immediates for special shifts (sign extend) 2429 2430 // Constants for increment 2431 operand immI_16() 2432 %{ 2433 predicate(n->get_int() == 16); 2434 match(ConI); 2435 2436 format %{ %} 2437 interface(CONST_INTER); 2438 %} 2439 2440 operand immI_24() 2441 %{ 2442 predicate(n->get_int() == 24); 2443 match(ConI); 2444 2445 format %{ %} 2446 interface(CONST_INTER); 2447 %} 2448 2449 // Constant for byte-wide masking 2450 operand immI_255() 2451 %{ 2452 predicate(n->get_int() == 255); 2453 match(ConI); 2454 2455 format %{ %} 2456 interface(CONST_INTER); 2457 %} 2458 2459 // Constant for short-wide masking 2460 operand immI_65535() 2461 %{ 2462 predicate(n->get_int() == 65535); 2463 match(ConI); 2464 2465 format %{ %} 2466 interface(CONST_INTER); 2467 %} 2468 2469 // Constant for byte-wide masking 2470 operand immL_255() 2471 %{ 2472 predicate(n->get_long() == 255); 2473 match(ConL); 2474 2475 format %{ %} 2476 interface(CONST_INTER); 2477 %} 2478 2479 // Constant for short-wide masking 2480 operand immL_65535() 2481 %{ 2482 predicate(n->get_long() == 65535); 2483 match(ConL); 2484 2485 format %{ %} 2486 interface(CONST_INTER); 2487 %} 2488 2489 operand kReg() 2490 %{ 2491 constraint(ALLOC_IN_RC(vectmask_reg)); 2492 match(RegVectMask); 2493 format %{%} 2494 interface(REG_INTER); 2495 %} 2496 2497 // Register Operands 2498 // Integer Register 2499 operand rRegI() 2500 %{ 2501 constraint(ALLOC_IN_RC(int_reg)); 2502 match(RegI); 2503 2504 match(rax_RegI); 2505 match(rbx_RegI); 2506 match(rcx_RegI); 2507 match(rdx_RegI); 2508 match(rdi_RegI); 2509 2510 format %{ %} 2511 interface(REG_INTER); 2512 %} 2513 2514 // Special Registers 2515 operand rax_RegI() 2516 %{ 2517 constraint(ALLOC_IN_RC(int_rax_reg)); 2518 match(RegI); 2519 match(rRegI); 2520 2521 format %{ "RAX" %} 2522 interface(REG_INTER); 2523 %} 2524 2525 // Special Registers 2526 operand rbx_RegI() 2527 %{ 2528 constraint(ALLOC_IN_RC(int_rbx_reg)); 2529 match(RegI); 2530 match(rRegI); 2531 2532 format %{ "RBX" %} 2533 interface(REG_INTER); 2534 %} 2535 2536 operand rcx_RegI() 2537 %{ 2538 constraint(ALLOC_IN_RC(int_rcx_reg)); 2539 match(RegI); 2540 match(rRegI); 2541 2542 format %{ "RCX" %} 2543 interface(REG_INTER); 2544 %} 2545 2546 operand rdx_RegI() 2547 %{ 2548 constraint(ALLOC_IN_RC(int_rdx_reg)); 2549 match(RegI); 2550 match(rRegI); 2551 2552 format %{ "RDX" %} 2553 interface(REG_INTER); 2554 %} 2555 2556 operand rdi_RegI() 2557 %{ 2558 constraint(ALLOC_IN_RC(int_rdi_reg)); 2559 match(RegI); 2560 match(rRegI); 2561 2562 format %{ "RDI" %} 2563 interface(REG_INTER); 2564 %} 2565 2566 operand no_rax_rdx_RegI() 2567 %{ 2568 constraint(ALLOC_IN_RC(int_no_rax_rdx_reg)); 2569 match(RegI); 2570 match(rbx_RegI); 2571 match(rcx_RegI); 2572 match(rdi_RegI); 2573 2574 format %{ %} 2575 interface(REG_INTER); 2576 %} 2577 2578 operand no_rbp_r13_RegI() 2579 %{ 2580 constraint(ALLOC_IN_RC(int_no_rbp_r13_reg)); 2581 match(RegI); 2582 match(rRegI); 2583 match(rax_RegI); 2584 match(rbx_RegI); 2585 match(rcx_RegI); 2586 match(rdx_RegI); 2587 match(rdi_RegI); 2588 2589 format %{ %} 2590 interface(REG_INTER); 2591 %} 2592 2593 // Pointer Register 2594 operand any_RegP() 2595 %{ 2596 constraint(ALLOC_IN_RC(any_reg)); 2597 match(RegP); 2598 match(rax_RegP); 2599 match(rbx_RegP); 2600 match(rdi_RegP); 2601 match(rsi_RegP); 2602 match(rbp_RegP); 2603 match(r15_RegP); 2604 match(rRegP); 2605 2606 format %{ %} 2607 interface(REG_INTER); 2608 %} 2609 2610 operand rRegP() 2611 %{ 2612 constraint(ALLOC_IN_RC(ptr_reg)); 2613 match(RegP); 2614 match(rax_RegP); 2615 match(rbx_RegP); 2616 match(rdi_RegP); 2617 match(rsi_RegP); 2618 match(rbp_RegP); // See Q&A below about 2619 match(r15_RegP); // r15_RegP and rbp_RegP. 2620 2621 format %{ %} 2622 interface(REG_INTER); 2623 %} 2624 2625 operand rRegN() %{ 2626 constraint(ALLOC_IN_RC(int_reg)); 2627 match(RegN); 2628 2629 format %{ %} 2630 interface(REG_INTER); 2631 %} 2632 2633 // Question: Why is r15_RegP (the read-only TLS register) a match for rRegP? 2634 // Answer: Operand match rules govern the DFA as it processes instruction inputs. 2635 // It's fine for an instruction input that expects rRegP to match a r15_RegP. 2636 // The output of an instruction is controlled by the allocator, which respects 2637 // register class masks, not match rules. Unless an instruction mentions 2638 // r15_RegP or any_RegP explicitly as its output, r15 will not be considered 2639 // by the allocator as an input. 2640 // The same logic applies to rbp_RegP being a match for rRegP: If PreserveFramePointer==true, 2641 // the RBP is used as a proper frame pointer and is not included in ptr_reg. As a 2642 // result, RBP is not included in the output of the instruction either. 2643 2644 // This operand is not allowed to use RBP even if 2645 // RBP is not used to hold the frame pointer. 2646 operand no_rbp_RegP() 2647 %{ 2648 constraint(ALLOC_IN_RC(ptr_reg_no_rbp)); 2649 match(RegP); 2650 match(rbx_RegP); 2651 match(rsi_RegP); 2652 match(rdi_RegP); 2653 2654 format %{ %} 2655 interface(REG_INTER); 2656 %} 2657 2658 // Special Registers 2659 // Return a pointer value 2660 operand rax_RegP() 2661 %{ 2662 constraint(ALLOC_IN_RC(ptr_rax_reg)); 2663 match(RegP); 2664 match(rRegP); 2665 2666 format %{ %} 2667 interface(REG_INTER); 2668 %} 2669 2670 // Special Registers 2671 // Return a compressed pointer value 2672 operand rax_RegN() 2673 %{ 2674 constraint(ALLOC_IN_RC(int_rax_reg)); 2675 match(RegN); 2676 match(rRegN); 2677 2678 format %{ %} 2679 interface(REG_INTER); 2680 %} 2681 2682 // Used in AtomicAdd 2683 operand rbx_RegP() 2684 %{ 2685 constraint(ALLOC_IN_RC(ptr_rbx_reg)); 2686 match(RegP); 2687 match(rRegP); 2688 2689 format %{ %} 2690 interface(REG_INTER); 2691 %} 2692 2693 operand rsi_RegP() 2694 %{ 2695 constraint(ALLOC_IN_RC(ptr_rsi_reg)); 2696 match(RegP); 2697 match(rRegP); 2698 2699 format %{ %} 2700 interface(REG_INTER); 2701 %} 2702 2703 operand rbp_RegP() 2704 %{ 2705 constraint(ALLOC_IN_RC(ptr_rbp_reg)); 2706 match(RegP); 2707 match(rRegP); 2708 2709 format %{ %} 2710 interface(REG_INTER); 2711 %} 2712 2713 // Used in rep stosq 2714 operand rdi_RegP() 2715 %{ 2716 constraint(ALLOC_IN_RC(ptr_rdi_reg)); 2717 match(RegP); 2718 match(rRegP); 2719 2720 format %{ %} 2721 interface(REG_INTER); 2722 %} 2723 2724 operand r15_RegP() 2725 %{ 2726 constraint(ALLOC_IN_RC(ptr_r15_reg)); 2727 match(RegP); 2728 match(rRegP); 2729 2730 format %{ %} 2731 interface(REG_INTER); 2732 %} 2733 2734 operand rRegL() 2735 %{ 2736 constraint(ALLOC_IN_RC(long_reg)); 2737 match(RegL); 2738 match(rax_RegL); 2739 match(rdx_RegL); 2740 2741 format %{ %} 2742 interface(REG_INTER); 2743 %} 2744 2745 // Special Registers 2746 operand no_rax_rdx_RegL() 2747 %{ 2748 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 2749 match(RegL); 2750 match(rRegL); 2751 2752 format %{ %} 2753 interface(REG_INTER); 2754 %} 2755 2756 operand rax_RegL() 2757 %{ 2758 constraint(ALLOC_IN_RC(long_rax_reg)); 2759 match(RegL); 2760 match(rRegL); 2761 2762 format %{ "RAX" %} 2763 interface(REG_INTER); 2764 %} 2765 2766 operand rcx_RegL() 2767 %{ 2768 constraint(ALLOC_IN_RC(long_rcx_reg)); 2769 match(RegL); 2770 match(rRegL); 2771 2772 format %{ %} 2773 interface(REG_INTER); 2774 %} 2775 2776 operand rdx_RegL() 2777 %{ 2778 constraint(ALLOC_IN_RC(long_rdx_reg)); 2779 match(RegL); 2780 match(rRegL); 2781 2782 format %{ %} 2783 interface(REG_INTER); 2784 %} 2785 2786 operand r11_RegL() 2787 %{ 2788 constraint(ALLOC_IN_RC(long_r11_reg)); 2789 match(RegL); 2790 match(rRegL); 2791 2792 format %{ %} 2793 interface(REG_INTER); 2794 %} 2795 2796 operand no_rbp_r13_RegL() 2797 %{ 2798 constraint(ALLOC_IN_RC(long_no_rbp_r13_reg)); 2799 match(RegL); 2800 match(rRegL); 2801 match(rax_RegL); 2802 match(rcx_RegL); 2803 match(rdx_RegL); 2804 2805 format %{ %} 2806 interface(REG_INTER); 2807 %} 2808 2809 // Flags register, used as output of compare instructions 2810 operand rFlagsReg() 2811 %{ 2812 constraint(ALLOC_IN_RC(int_flags)); 2813 match(RegFlags); 2814 2815 format %{ "RFLAGS" %} 2816 interface(REG_INTER); 2817 %} 2818 2819 // Flags register, used as output of FLOATING POINT compare instructions 2820 operand rFlagsRegU() 2821 %{ 2822 constraint(ALLOC_IN_RC(int_flags)); 2823 match(RegFlags); 2824 2825 format %{ "RFLAGS_U" %} 2826 interface(REG_INTER); 2827 %} 2828 2829 operand rFlagsRegUCF() %{ 2830 constraint(ALLOC_IN_RC(int_flags)); 2831 match(RegFlags); 2832 predicate(false); 2833 2834 format %{ "RFLAGS_U_CF" %} 2835 interface(REG_INTER); 2836 %} 2837 2838 // Float register operands 2839 operand regF() %{ 2840 constraint(ALLOC_IN_RC(float_reg)); 2841 match(RegF); 2842 2843 format %{ %} 2844 interface(REG_INTER); 2845 %} 2846 2847 // Float register operands 2848 operand legRegF() %{ 2849 constraint(ALLOC_IN_RC(float_reg_legacy)); 2850 match(RegF); 2851 2852 format %{ %} 2853 interface(REG_INTER); 2854 %} 2855 2856 // Float register operands 2857 operand vlRegF() %{ 2858 constraint(ALLOC_IN_RC(float_reg_vl)); 2859 match(RegF); 2860 2861 format %{ %} 2862 interface(REG_INTER); 2863 %} 2864 2865 // Double register operands 2866 operand regD() %{ 2867 constraint(ALLOC_IN_RC(double_reg)); 2868 match(RegD); 2869 2870 format %{ %} 2871 interface(REG_INTER); 2872 %} 2873 2874 // Double register operands 2875 operand legRegD() %{ 2876 constraint(ALLOC_IN_RC(double_reg_legacy)); 2877 match(RegD); 2878 2879 format %{ %} 2880 interface(REG_INTER); 2881 %} 2882 2883 // Double register operands 2884 operand vlRegD() %{ 2885 constraint(ALLOC_IN_RC(double_reg_vl)); 2886 match(RegD); 2887 2888 format %{ %} 2889 interface(REG_INTER); 2890 %} 2891 2892 //----------Memory Operands---------------------------------------------------- 2893 // Direct Memory Operand 2894 // operand direct(immP addr) 2895 // %{ 2896 // match(addr); 2897 2898 // format %{ "[$addr]" %} 2899 // interface(MEMORY_INTER) %{ 2900 // base(0xFFFFFFFF); 2901 // index(0x4); 2902 // scale(0x0); 2903 // disp($addr); 2904 // %} 2905 // %} 2906 2907 // Indirect Memory Operand 2908 operand indirect(any_RegP reg) 2909 %{ 2910 constraint(ALLOC_IN_RC(ptr_reg)); 2911 match(reg); 2912 2913 format %{ "[$reg]" %} 2914 interface(MEMORY_INTER) %{ 2915 base($reg); 2916 index(0x4); 2917 scale(0x0); 2918 disp(0x0); 2919 %} 2920 %} 2921 2922 // Indirect Memory Plus Short Offset Operand 2923 operand indOffset8(any_RegP reg, immL8 off) 2924 %{ 2925 constraint(ALLOC_IN_RC(ptr_reg)); 2926 match(AddP reg off); 2927 2928 format %{ "[$reg + $off (8-bit)]" %} 2929 interface(MEMORY_INTER) %{ 2930 base($reg); 2931 index(0x4); 2932 scale(0x0); 2933 disp($off); 2934 %} 2935 %} 2936 2937 // Indirect Memory Plus Long Offset Operand 2938 operand indOffset32(any_RegP reg, immL32 off) 2939 %{ 2940 constraint(ALLOC_IN_RC(ptr_reg)); 2941 match(AddP reg off); 2942 2943 format %{ "[$reg + $off (32-bit)]" %} 2944 interface(MEMORY_INTER) %{ 2945 base($reg); 2946 index(0x4); 2947 scale(0x0); 2948 disp($off); 2949 %} 2950 %} 2951 2952 // Indirect Memory Plus Index Register Plus Offset Operand 2953 operand indIndexOffset(any_RegP reg, rRegL lreg, immL32 off) 2954 %{ 2955 constraint(ALLOC_IN_RC(ptr_reg)); 2956 match(AddP (AddP reg lreg) off); 2957 2958 op_cost(10); 2959 format %{"[$reg + $off + $lreg]" %} 2960 interface(MEMORY_INTER) %{ 2961 base($reg); 2962 index($lreg); 2963 scale(0x0); 2964 disp($off); 2965 %} 2966 %} 2967 2968 // Indirect Memory Plus Index Register Plus Offset Operand 2969 operand indIndex(any_RegP reg, rRegL lreg) 2970 %{ 2971 constraint(ALLOC_IN_RC(ptr_reg)); 2972 match(AddP reg lreg); 2973 2974 op_cost(10); 2975 format %{"[$reg + $lreg]" %} 2976 interface(MEMORY_INTER) %{ 2977 base($reg); 2978 index($lreg); 2979 scale(0x0); 2980 disp(0x0); 2981 %} 2982 %} 2983 2984 // Indirect Memory Times Scale Plus Index Register 2985 operand indIndexScale(any_RegP reg, rRegL lreg, immI2 scale) 2986 %{ 2987 constraint(ALLOC_IN_RC(ptr_reg)); 2988 match(AddP reg (LShiftL lreg scale)); 2989 2990 op_cost(10); 2991 format %{"[$reg + $lreg << $scale]" %} 2992 interface(MEMORY_INTER) %{ 2993 base($reg); 2994 index($lreg); 2995 scale($scale); 2996 disp(0x0); 2997 %} 2998 %} 2999 3000 operand indPosIndexScale(any_RegP reg, rRegI idx, immI2 scale) 3001 %{ 3002 constraint(ALLOC_IN_RC(ptr_reg)); 3003 predicate(n->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3004 match(AddP reg (LShiftL (ConvI2L idx) scale)); 3005 3006 op_cost(10); 3007 format %{"[$reg + pos $idx << $scale]" %} 3008 interface(MEMORY_INTER) %{ 3009 base($reg); 3010 index($idx); 3011 scale($scale); 3012 disp(0x0); 3013 %} 3014 %} 3015 3016 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 3017 operand indIndexScaleOffset(any_RegP reg, immL32 off, rRegL lreg, immI2 scale) 3018 %{ 3019 constraint(ALLOC_IN_RC(ptr_reg)); 3020 match(AddP (AddP reg (LShiftL lreg scale)) off); 3021 3022 op_cost(10); 3023 format %{"[$reg + $off + $lreg << $scale]" %} 3024 interface(MEMORY_INTER) %{ 3025 base($reg); 3026 index($lreg); 3027 scale($scale); 3028 disp($off); 3029 %} 3030 %} 3031 3032 // Indirect Memory Plus Positive Index Register Plus Offset Operand 3033 operand indPosIndexOffset(any_RegP reg, immL32 off, rRegI idx) 3034 %{ 3035 constraint(ALLOC_IN_RC(ptr_reg)); 3036 predicate(n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 3037 match(AddP (AddP reg (ConvI2L idx)) off); 3038 3039 op_cost(10); 3040 format %{"[$reg + $off + $idx]" %} 3041 interface(MEMORY_INTER) %{ 3042 base($reg); 3043 index($idx); 3044 scale(0x0); 3045 disp($off); 3046 %} 3047 %} 3048 3049 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 3050 operand indPosIndexScaleOffset(any_RegP reg, immL32 off, rRegI idx, immI2 scale) 3051 %{ 3052 constraint(ALLOC_IN_RC(ptr_reg)); 3053 predicate(n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3054 match(AddP (AddP reg (LShiftL (ConvI2L idx) scale)) off); 3055 3056 op_cost(10); 3057 format %{"[$reg + $off + $idx << $scale]" %} 3058 interface(MEMORY_INTER) %{ 3059 base($reg); 3060 index($idx); 3061 scale($scale); 3062 disp($off); 3063 %} 3064 %} 3065 3066 // Indirect Narrow Oop Plus Offset Operand 3067 // Note: x86 architecture doesn't support "scale * index + offset" without a base 3068 // we can't free r12 even with CompressedOops::base() == nullptr. 3069 operand indCompressedOopOffset(rRegN reg, immL32 off) %{ 3070 predicate(UseCompressedOops && (CompressedOops::shift() == Address::times_8)); 3071 constraint(ALLOC_IN_RC(ptr_reg)); 3072 match(AddP (DecodeN reg) off); 3073 3074 op_cost(10); 3075 format %{"[R12 + $reg << 3 + $off] (compressed oop addressing)" %} 3076 interface(MEMORY_INTER) %{ 3077 base(0xc); // R12 3078 index($reg); 3079 scale(0x3); 3080 disp($off); 3081 %} 3082 %} 3083 3084 // Indirect Memory Operand 3085 operand indirectNarrow(rRegN reg) 3086 %{ 3087 predicate(CompressedOops::shift() == 0); 3088 constraint(ALLOC_IN_RC(ptr_reg)); 3089 match(DecodeN reg); 3090 3091 format %{ "[$reg]" %} 3092 interface(MEMORY_INTER) %{ 3093 base($reg); 3094 index(0x4); 3095 scale(0x0); 3096 disp(0x0); 3097 %} 3098 %} 3099 3100 // Indirect Memory Plus Short Offset Operand 3101 operand indOffset8Narrow(rRegN reg, immL8 off) 3102 %{ 3103 predicate(CompressedOops::shift() == 0); 3104 constraint(ALLOC_IN_RC(ptr_reg)); 3105 match(AddP (DecodeN reg) off); 3106 3107 format %{ "[$reg + $off (8-bit)]" %} 3108 interface(MEMORY_INTER) %{ 3109 base($reg); 3110 index(0x4); 3111 scale(0x0); 3112 disp($off); 3113 %} 3114 %} 3115 3116 // Indirect Memory Plus Long Offset Operand 3117 operand indOffset32Narrow(rRegN reg, immL32 off) 3118 %{ 3119 predicate(CompressedOops::shift() == 0); 3120 constraint(ALLOC_IN_RC(ptr_reg)); 3121 match(AddP (DecodeN reg) off); 3122 3123 format %{ "[$reg + $off (32-bit)]" %} 3124 interface(MEMORY_INTER) %{ 3125 base($reg); 3126 index(0x4); 3127 scale(0x0); 3128 disp($off); 3129 %} 3130 %} 3131 3132 // Indirect Memory Plus Index Register Plus Offset Operand 3133 operand indIndexOffsetNarrow(rRegN reg, rRegL lreg, immL32 off) 3134 %{ 3135 predicate(CompressedOops::shift() == 0); 3136 constraint(ALLOC_IN_RC(ptr_reg)); 3137 match(AddP (AddP (DecodeN reg) lreg) off); 3138 3139 op_cost(10); 3140 format %{"[$reg + $off + $lreg]" %} 3141 interface(MEMORY_INTER) %{ 3142 base($reg); 3143 index($lreg); 3144 scale(0x0); 3145 disp($off); 3146 %} 3147 %} 3148 3149 // Indirect Memory Plus Index Register Plus Offset Operand 3150 operand indIndexNarrow(rRegN reg, rRegL lreg) 3151 %{ 3152 predicate(CompressedOops::shift() == 0); 3153 constraint(ALLOC_IN_RC(ptr_reg)); 3154 match(AddP (DecodeN reg) lreg); 3155 3156 op_cost(10); 3157 format %{"[$reg + $lreg]" %} 3158 interface(MEMORY_INTER) %{ 3159 base($reg); 3160 index($lreg); 3161 scale(0x0); 3162 disp(0x0); 3163 %} 3164 %} 3165 3166 // Indirect Memory Times Scale Plus Index Register 3167 operand indIndexScaleNarrow(rRegN reg, rRegL lreg, immI2 scale) 3168 %{ 3169 predicate(CompressedOops::shift() == 0); 3170 constraint(ALLOC_IN_RC(ptr_reg)); 3171 match(AddP (DecodeN reg) (LShiftL lreg scale)); 3172 3173 op_cost(10); 3174 format %{"[$reg + $lreg << $scale]" %} 3175 interface(MEMORY_INTER) %{ 3176 base($reg); 3177 index($lreg); 3178 scale($scale); 3179 disp(0x0); 3180 %} 3181 %} 3182 3183 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 3184 operand indIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegL lreg, immI2 scale) 3185 %{ 3186 predicate(CompressedOops::shift() == 0); 3187 constraint(ALLOC_IN_RC(ptr_reg)); 3188 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off); 3189 3190 op_cost(10); 3191 format %{"[$reg + $off + $lreg << $scale]" %} 3192 interface(MEMORY_INTER) %{ 3193 base($reg); 3194 index($lreg); 3195 scale($scale); 3196 disp($off); 3197 %} 3198 %} 3199 3200 // Indirect Memory Times Plus Positive Index Register Plus Offset Operand 3201 operand indPosIndexOffsetNarrow(rRegN reg, immL32 off, rRegI idx) 3202 %{ 3203 constraint(ALLOC_IN_RC(ptr_reg)); 3204 predicate(CompressedOops::shift() == 0 && n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 3205 match(AddP (AddP (DecodeN reg) (ConvI2L idx)) off); 3206 3207 op_cost(10); 3208 format %{"[$reg + $off + $idx]" %} 3209 interface(MEMORY_INTER) %{ 3210 base($reg); 3211 index($idx); 3212 scale(0x0); 3213 disp($off); 3214 %} 3215 %} 3216 3217 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 3218 operand indPosIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegI idx, immI2 scale) 3219 %{ 3220 constraint(ALLOC_IN_RC(ptr_reg)); 3221 predicate(CompressedOops::shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3222 match(AddP (AddP (DecodeN reg) (LShiftL (ConvI2L idx) scale)) off); 3223 3224 op_cost(10); 3225 format %{"[$reg + $off + $idx << $scale]" %} 3226 interface(MEMORY_INTER) %{ 3227 base($reg); 3228 index($idx); 3229 scale($scale); 3230 disp($off); 3231 %} 3232 %} 3233 3234 //----------Special Memory Operands-------------------------------------------- 3235 // Stack Slot Operand - This operand is used for loading and storing temporary 3236 // values on the stack where a match requires a value to 3237 // flow through memory. 3238 operand stackSlotP(sRegP reg) 3239 %{ 3240 constraint(ALLOC_IN_RC(stack_slots)); 3241 // No match rule because this operand is only generated in matching 3242 3243 format %{ "[$reg]" %} 3244 interface(MEMORY_INTER) %{ 3245 base(0x4); // RSP 3246 index(0x4); // No Index 3247 scale(0x0); // No Scale 3248 disp($reg); // Stack Offset 3249 %} 3250 %} 3251 3252 operand stackSlotI(sRegI reg) 3253 %{ 3254 constraint(ALLOC_IN_RC(stack_slots)); 3255 // No match rule because this operand is only generated in matching 3256 3257 format %{ "[$reg]" %} 3258 interface(MEMORY_INTER) %{ 3259 base(0x4); // RSP 3260 index(0x4); // No Index 3261 scale(0x0); // No Scale 3262 disp($reg); // Stack Offset 3263 %} 3264 %} 3265 3266 operand stackSlotF(sRegF reg) 3267 %{ 3268 constraint(ALLOC_IN_RC(stack_slots)); 3269 // No match rule because this operand is only generated in matching 3270 3271 format %{ "[$reg]" %} 3272 interface(MEMORY_INTER) %{ 3273 base(0x4); // RSP 3274 index(0x4); // No Index 3275 scale(0x0); // No Scale 3276 disp($reg); // Stack Offset 3277 %} 3278 %} 3279 3280 operand stackSlotD(sRegD reg) 3281 %{ 3282 constraint(ALLOC_IN_RC(stack_slots)); 3283 // No match rule because this operand is only generated in matching 3284 3285 format %{ "[$reg]" %} 3286 interface(MEMORY_INTER) %{ 3287 base(0x4); // RSP 3288 index(0x4); // No Index 3289 scale(0x0); // No Scale 3290 disp($reg); // Stack Offset 3291 %} 3292 %} 3293 operand stackSlotL(sRegL reg) 3294 %{ 3295 constraint(ALLOC_IN_RC(stack_slots)); 3296 // No match rule because this operand is only generated in matching 3297 3298 format %{ "[$reg]" %} 3299 interface(MEMORY_INTER) %{ 3300 base(0x4); // RSP 3301 index(0x4); // No Index 3302 scale(0x0); // No Scale 3303 disp($reg); // Stack Offset 3304 %} 3305 %} 3306 3307 //----------Conditional Branch Operands---------------------------------------- 3308 // Comparison Op - This is the operation of the comparison, and is limited to 3309 // the following set of codes: 3310 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 3311 // 3312 // Other attributes of the comparison, such as unsignedness, are specified 3313 // by the comparison instruction that sets a condition code flags register. 3314 // That result is represented by a flags operand whose subtype is appropriate 3315 // to the unsignedness (etc.) of the comparison. 3316 // 3317 // Later, the instruction which matches both the Comparison Op (a Bool) and 3318 // the flags (produced by the Cmp) specifies the coding of the comparison op 3319 // by matching a specific subtype of Bool operand below, such as cmpOpU. 3320 3321 // Comparison Code 3322 operand cmpOp() 3323 %{ 3324 match(Bool); 3325 3326 format %{ "" %} 3327 interface(COND_INTER) %{ 3328 equal(0x4, "e"); 3329 not_equal(0x5, "ne"); 3330 less(0xC, "l"); 3331 greater_equal(0xD, "ge"); 3332 less_equal(0xE, "le"); 3333 greater(0xF, "g"); 3334 overflow(0x0, "o"); 3335 no_overflow(0x1, "no"); 3336 %} 3337 %} 3338 3339 // Comparison Code, unsigned compare. Used by FP also, with 3340 // C2 (unordered) turned into GT or LT already. The other bits 3341 // C0 and C3 are turned into Carry & Zero flags. 3342 operand cmpOpU() 3343 %{ 3344 match(Bool); 3345 3346 format %{ "" %} 3347 interface(COND_INTER) %{ 3348 equal(0x4, "e"); 3349 not_equal(0x5, "ne"); 3350 less(0x2, "b"); 3351 greater_equal(0x3, "ae"); 3352 less_equal(0x6, "be"); 3353 greater(0x7, "a"); 3354 overflow(0x0, "o"); 3355 no_overflow(0x1, "no"); 3356 %} 3357 %} 3358 3359 3360 // Floating comparisons that don't require any fixup for the unordered case, 3361 // If both inputs of the comparison are the same, ZF is always set so we 3362 // don't need to use cmpOpUCF2 for eq/ne 3363 operand cmpOpUCF() %{ 3364 match(Bool); 3365 predicate(n->as_Bool()->_test._test == BoolTest::lt || 3366 n->as_Bool()->_test._test == BoolTest::ge || 3367 n->as_Bool()->_test._test == BoolTest::le || 3368 n->as_Bool()->_test._test == BoolTest::gt || 3369 n->in(1)->in(1) == n->in(1)->in(2)); 3370 format %{ "" %} 3371 interface(COND_INTER) %{ 3372 equal(0xb, "np"); 3373 not_equal(0xa, "p"); 3374 less(0x2, "b"); 3375 greater_equal(0x3, "ae"); 3376 less_equal(0x6, "be"); 3377 greater(0x7, "a"); 3378 overflow(0x0, "o"); 3379 no_overflow(0x1, "no"); 3380 %} 3381 %} 3382 3383 3384 // Floating comparisons that can be fixed up with extra conditional jumps 3385 operand cmpOpUCF2() %{ 3386 match(Bool); 3387 predicate((n->as_Bool()->_test._test == BoolTest::ne || 3388 n->as_Bool()->_test._test == BoolTest::eq) && 3389 n->in(1)->in(1) != n->in(1)->in(2)); 3390 format %{ "" %} 3391 interface(COND_INTER) %{ 3392 equal(0x4, "e"); 3393 not_equal(0x5, "ne"); 3394 less(0x2, "b"); 3395 greater_equal(0x3, "ae"); 3396 less_equal(0x6, "be"); 3397 greater(0x7, "a"); 3398 overflow(0x0, "o"); 3399 no_overflow(0x1, "no"); 3400 %} 3401 %} 3402 3403 //----------OPERAND CLASSES---------------------------------------------------- 3404 // Operand Classes are groups of operands that are used as to simplify 3405 // instruction definitions by not requiring the AD writer to specify separate 3406 // instructions for every form of operand when the instruction accepts 3407 // multiple operand types with the same basic encoding and format. The classic 3408 // case of this is memory operands. 3409 3410 opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex, 3411 indIndexScale, indPosIndexScale, indIndexScaleOffset, indPosIndexOffset, indPosIndexScaleOffset, 3412 indCompressedOopOffset, 3413 indirectNarrow, indOffset8Narrow, indOffset32Narrow, 3414 indIndexOffsetNarrow, indIndexNarrow, indIndexScaleNarrow, 3415 indIndexScaleOffsetNarrow, indPosIndexOffsetNarrow, indPosIndexScaleOffsetNarrow); 3416 3417 //----------PIPELINE----------------------------------------------------------- 3418 // Rules which define the behavior of the target architectures pipeline. 3419 pipeline %{ 3420 3421 //----------ATTRIBUTES--------------------------------------------------------- 3422 attributes %{ 3423 variable_size_instructions; // Fixed size instructions 3424 max_instructions_per_bundle = 3; // Up to 3 instructions per bundle 3425 instruction_unit_size = 1; // An instruction is 1 bytes long 3426 instruction_fetch_unit_size = 16; // The processor fetches one line 3427 instruction_fetch_units = 1; // of 16 bytes 3428 3429 // List of nop instructions 3430 nops( MachNop ); 3431 %} 3432 3433 //----------RESOURCES---------------------------------------------------------- 3434 // Resources are the functional units available to the machine 3435 3436 // Generic P2/P3 pipeline 3437 // 3 decoders, only D0 handles big operands; a "bundle" is the limit of 3438 // 3 instructions decoded per cycle. 3439 // 2 load/store ops per cycle, 1 branch, 1 FPU, 3440 // 3 ALU op, only ALU0 handles mul instructions. 3441 resources( D0, D1, D2, DECODE = D0 | D1 | D2, 3442 MS0, MS1, MS2, MEM = MS0 | MS1 | MS2, 3443 BR, FPU, 3444 ALU0, ALU1, ALU2, ALU = ALU0 | ALU1 | ALU2); 3445 3446 //----------PIPELINE DESCRIPTION----------------------------------------------- 3447 // Pipeline Description specifies the stages in the machine's pipeline 3448 3449 // Generic P2/P3 pipeline 3450 pipe_desc(S0, S1, S2, S3, S4, S5); 3451 3452 //----------PIPELINE CLASSES--------------------------------------------------- 3453 // Pipeline Classes describe the stages in which input and output are 3454 // referenced by the hardware pipeline. 3455 3456 // Naming convention: ialu or fpu 3457 // Then: _reg 3458 // Then: _reg if there is a 2nd register 3459 // Then: _long if it's a pair of instructions implementing a long 3460 // Then: _fat if it requires the big decoder 3461 // Or: _mem if it requires the big decoder and a memory unit. 3462 3463 // Integer ALU reg operation 3464 pipe_class ialu_reg(rRegI dst) 3465 %{ 3466 single_instruction; 3467 dst : S4(write); 3468 dst : S3(read); 3469 DECODE : S0; // any decoder 3470 ALU : S3; // any alu 3471 %} 3472 3473 // Long ALU reg operation 3474 pipe_class ialu_reg_long(rRegL dst) 3475 %{ 3476 instruction_count(2); 3477 dst : S4(write); 3478 dst : S3(read); 3479 DECODE : S0(2); // any 2 decoders 3480 ALU : S3(2); // both alus 3481 %} 3482 3483 // Integer ALU reg operation using big decoder 3484 pipe_class ialu_reg_fat(rRegI dst) 3485 %{ 3486 single_instruction; 3487 dst : S4(write); 3488 dst : S3(read); 3489 D0 : S0; // big decoder only 3490 ALU : S3; // any alu 3491 %} 3492 3493 // Integer ALU reg-reg operation 3494 pipe_class ialu_reg_reg(rRegI dst, rRegI src) 3495 %{ 3496 single_instruction; 3497 dst : S4(write); 3498 src : S3(read); 3499 DECODE : S0; // any decoder 3500 ALU : S3; // any alu 3501 %} 3502 3503 // Integer ALU reg-reg operation 3504 pipe_class ialu_reg_reg_fat(rRegI dst, memory src) 3505 %{ 3506 single_instruction; 3507 dst : S4(write); 3508 src : S3(read); 3509 D0 : S0; // big decoder only 3510 ALU : S3; // any alu 3511 %} 3512 3513 // Integer ALU reg-mem operation 3514 pipe_class ialu_reg_mem(rRegI dst, memory mem) 3515 %{ 3516 single_instruction; 3517 dst : S5(write); 3518 mem : S3(read); 3519 D0 : S0; // big decoder only 3520 ALU : S4; // any alu 3521 MEM : S3; // any mem 3522 %} 3523 3524 // Integer mem operation (prefetch) 3525 pipe_class ialu_mem(memory mem) 3526 %{ 3527 single_instruction; 3528 mem : S3(read); 3529 D0 : S0; // big decoder only 3530 MEM : S3; // any mem 3531 %} 3532 3533 // Integer Store to Memory 3534 pipe_class ialu_mem_reg(memory mem, rRegI src) 3535 %{ 3536 single_instruction; 3537 mem : S3(read); 3538 src : S5(read); 3539 D0 : S0; // big decoder only 3540 ALU : S4; // any alu 3541 MEM : S3; 3542 %} 3543 3544 // // Long Store to Memory 3545 // pipe_class ialu_mem_long_reg(memory mem, rRegL src) 3546 // %{ 3547 // instruction_count(2); 3548 // mem : S3(read); 3549 // src : S5(read); 3550 // D0 : S0(2); // big decoder only; twice 3551 // ALU : S4(2); // any 2 alus 3552 // MEM : S3(2); // Both mems 3553 // %} 3554 3555 // Integer Store to Memory 3556 pipe_class ialu_mem_imm(memory mem) 3557 %{ 3558 single_instruction; 3559 mem : S3(read); 3560 D0 : S0; // big decoder only 3561 ALU : S4; // any alu 3562 MEM : S3; 3563 %} 3564 3565 // Integer ALU0 reg-reg operation 3566 pipe_class ialu_reg_reg_alu0(rRegI dst, rRegI src) 3567 %{ 3568 single_instruction; 3569 dst : S4(write); 3570 src : S3(read); 3571 D0 : S0; // Big decoder only 3572 ALU0 : S3; // only alu0 3573 %} 3574 3575 // Integer ALU0 reg-mem operation 3576 pipe_class ialu_reg_mem_alu0(rRegI dst, memory mem) 3577 %{ 3578 single_instruction; 3579 dst : S5(write); 3580 mem : S3(read); 3581 D0 : S0; // big decoder only 3582 ALU0 : S4; // ALU0 only 3583 MEM : S3; // any mem 3584 %} 3585 3586 // Integer ALU reg-reg operation 3587 pipe_class ialu_cr_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2) 3588 %{ 3589 single_instruction; 3590 cr : S4(write); 3591 src1 : S3(read); 3592 src2 : S3(read); 3593 DECODE : S0; // any decoder 3594 ALU : S3; // any alu 3595 %} 3596 3597 // Integer ALU reg-imm operation 3598 pipe_class ialu_cr_reg_imm(rFlagsReg cr, rRegI src1) 3599 %{ 3600 single_instruction; 3601 cr : S4(write); 3602 src1 : S3(read); 3603 DECODE : S0; // any decoder 3604 ALU : S3; // any alu 3605 %} 3606 3607 // Integer ALU reg-mem operation 3608 pipe_class ialu_cr_reg_mem(rFlagsReg cr, rRegI src1, memory src2) 3609 %{ 3610 single_instruction; 3611 cr : S4(write); 3612 src1 : S3(read); 3613 src2 : S3(read); 3614 D0 : S0; // big decoder only 3615 ALU : S4; // any alu 3616 MEM : S3; 3617 %} 3618 3619 // Conditional move reg-reg 3620 pipe_class pipe_cmplt( rRegI p, rRegI q, rRegI y) 3621 %{ 3622 instruction_count(4); 3623 y : S4(read); 3624 q : S3(read); 3625 p : S3(read); 3626 DECODE : S0(4); // any decoder 3627 %} 3628 3629 // Conditional move reg-reg 3630 pipe_class pipe_cmov_reg( rRegI dst, rRegI src, rFlagsReg cr) 3631 %{ 3632 single_instruction; 3633 dst : S4(write); 3634 src : S3(read); 3635 cr : S3(read); 3636 DECODE : S0; // any decoder 3637 %} 3638 3639 // Conditional move reg-mem 3640 pipe_class pipe_cmov_mem( rFlagsReg cr, rRegI dst, memory src) 3641 %{ 3642 single_instruction; 3643 dst : S4(write); 3644 src : S3(read); 3645 cr : S3(read); 3646 DECODE : S0; // any decoder 3647 MEM : S3; 3648 %} 3649 3650 // Conditional move reg-reg long 3651 pipe_class pipe_cmov_reg_long( rFlagsReg cr, rRegL dst, rRegL src) 3652 %{ 3653 single_instruction; 3654 dst : S4(write); 3655 src : S3(read); 3656 cr : S3(read); 3657 DECODE : S0(2); // any 2 decoders 3658 %} 3659 3660 // Float reg-reg operation 3661 pipe_class fpu_reg(regD dst) 3662 %{ 3663 instruction_count(2); 3664 dst : S3(read); 3665 DECODE : S0(2); // any 2 decoders 3666 FPU : S3; 3667 %} 3668 3669 // Float reg-reg operation 3670 pipe_class fpu_reg_reg(regD dst, regD src) 3671 %{ 3672 instruction_count(2); 3673 dst : S4(write); 3674 src : S3(read); 3675 DECODE : S0(2); // any 2 decoders 3676 FPU : S3; 3677 %} 3678 3679 // Float reg-reg operation 3680 pipe_class fpu_reg_reg_reg(regD dst, regD src1, regD src2) 3681 %{ 3682 instruction_count(3); 3683 dst : S4(write); 3684 src1 : S3(read); 3685 src2 : S3(read); 3686 DECODE : S0(3); // any 3 decoders 3687 FPU : S3(2); 3688 %} 3689 3690 // Float reg-reg operation 3691 pipe_class fpu_reg_reg_reg_reg(regD dst, regD src1, regD src2, regD src3) 3692 %{ 3693 instruction_count(4); 3694 dst : S4(write); 3695 src1 : S3(read); 3696 src2 : S3(read); 3697 src3 : S3(read); 3698 DECODE : S0(4); // any 3 decoders 3699 FPU : S3(2); 3700 %} 3701 3702 // Float reg-reg operation 3703 pipe_class fpu_reg_mem_reg_reg(regD dst, memory src1, regD src2, regD src3) 3704 %{ 3705 instruction_count(4); 3706 dst : S4(write); 3707 src1 : S3(read); 3708 src2 : S3(read); 3709 src3 : S3(read); 3710 DECODE : S1(3); // any 3 decoders 3711 D0 : S0; // Big decoder only 3712 FPU : S3(2); 3713 MEM : S3; 3714 %} 3715 3716 // Float reg-mem operation 3717 pipe_class fpu_reg_mem(regD dst, memory mem) 3718 %{ 3719 instruction_count(2); 3720 dst : S5(write); 3721 mem : S3(read); 3722 D0 : S0; // big decoder only 3723 DECODE : S1; // any decoder for FPU POP 3724 FPU : S4; 3725 MEM : S3; // any mem 3726 %} 3727 3728 // Float reg-mem operation 3729 pipe_class fpu_reg_reg_mem(regD dst, regD src1, memory mem) 3730 %{ 3731 instruction_count(3); 3732 dst : S5(write); 3733 src1 : S3(read); 3734 mem : S3(read); 3735 D0 : S0; // big decoder only 3736 DECODE : S1(2); // any decoder for FPU POP 3737 FPU : S4; 3738 MEM : S3; // any mem 3739 %} 3740 3741 // Float mem-reg operation 3742 pipe_class fpu_mem_reg(memory mem, regD src) 3743 %{ 3744 instruction_count(2); 3745 src : S5(read); 3746 mem : S3(read); 3747 DECODE : S0; // any decoder for FPU PUSH 3748 D0 : S1; // big decoder only 3749 FPU : S4; 3750 MEM : S3; // any mem 3751 %} 3752 3753 pipe_class fpu_mem_reg_reg(memory mem, regD src1, regD src2) 3754 %{ 3755 instruction_count(3); 3756 src1 : S3(read); 3757 src2 : S3(read); 3758 mem : S3(read); 3759 DECODE : S0(2); // any decoder for FPU PUSH 3760 D0 : S1; // big decoder only 3761 FPU : S4; 3762 MEM : S3; // any mem 3763 %} 3764 3765 pipe_class fpu_mem_reg_mem(memory mem, regD src1, memory src2) 3766 %{ 3767 instruction_count(3); 3768 src1 : S3(read); 3769 src2 : S3(read); 3770 mem : S4(read); 3771 DECODE : S0; // any decoder for FPU PUSH 3772 D0 : S0(2); // big decoder only 3773 FPU : S4; 3774 MEM : S3(2); // any mem 3775 %} 3776 3777 pipe_class fpu_mem_mem(memory dst, memory src1) 3778 %{ 3779 instruction_count(2); 3780 src1 : S3(read); 3781 dst : S4(read); 3782 D0 : S0(2); // big decoder only 3783 MEM : S3(2); // any mem 3784 %} 3785 3786 pipe_class fpu_mem_mem_mem(memory dst, memory src1, memory src2) 3787 %{ 3788 instruction_count(3); 3789 src1 : S3(read); 3790 src2 : S3(read); 3791 dst : S4(read); 3792 D0 : S0(3); // big decoder only 3793 FPU : S4; 3794 MEM : S3(3); // any mem 3795 %} 3796 3797 pipe_class fpu_mem_reg_con(memory mem, regD src1) 3798 %{ 3799 instruction_count(3); 3800 src1 : S4(read); 3801 mem : S4(read); 3802 DECODE : S0; // any decoder for FPU PUSH 3803 D0 : S0(2); // big decoder only 3804 FPU : S4; 3805 MEM : S3(2); // any mem 3806 %} 3807 3808 // Float load constant 3809 pipe_class fpu_reg_con(regD dst) 3810 %{ 3811 instruction_count(2); 3812 dst : S5(write); 3813 D0 : S0; // big decoder only for the load 3814 DECODE : S1; // any decoder for FPU POP 3815 FPU : S4; 3816 MEM : S3; // any mem 3817 %} 3818 3819 // Float load constant 3820 pipe_class fpu_reg_reg_con(regD dst, regD src) 3821 %{ 3822 instruction_count(3); 3823 dst : S5(write); 3824 src : S3(read); 3825 D0 : S0; // big decoder only for the load 3826 DECODE : S1(2); // any decoder for FPU POP 3827 FPU : S4; 3828 MEM : S3; // any mem 3829 %} 3830 3831 // UnConditional branch 3832 pipe_class pipe_jmp(label labl) 3833 %{ 3834 single_instruction; 3835 BR : S3; 3836 %} 3837 3838 // Conditional branch 3839 pipe_class pipe_jcc(cmpOp cmp, rFlagsReg cr, label labl) 3840 %{ 3841 single_instruction; 3842 cr : S1(read); 3843 BR : S3; 3844 %} 3845 3846 // Allocation idiom 3847 pipe_class pipe_cmpxchg(rRegP dst, rRegP heap_ptr) 3848 %{ 3849 instruction_count(1); force_serialization; 3850 fixed_latency(6); 3851 heap_ptr : S3(read); 3852 DECODE : S0(3); 3853 D0 : S2; 3854 MEM : S3; 3855 ALU : S3(2); 3856 dst : S5(write); 3857 BR : S5; 3858 %} 3859 3860 // Generic big/slow expanded idiom 3861 pipe_class pipe_slow() 3862 %{ 3863 instruction_count(10); multiple_bundles; force_serialization; 3864 fixed_latency(100); 3865 D0 : S0(2); 3866 MEM : S3(2); 3867 %} 3868 3869 // The real do-nothing guy 3870 pipe_class empty() 3871 %{ 3872 instruction_count(0); 3873 %} 3874 3875 // Define the class for the Nop node 3876 define 3877 %{ 3878 MachNop = empty; 3879 %} 3880 3881 %} 3882 3883 //----------INSTRUCTIONS------------------------------------------------------- 3884 // 3885 // match -- States which machine-independent subtree may be replaced 3886 // by this instruction. 3887 // ins_cost -- The estimated cost of this instruction is used by instruction 3888 // selection to identify a minimum cost tree of machine 3889 // instructions that matches a tree of machine-independent 3890 // instructions. 3891 // format -- A string providing the disassembly for this instruction. 3892 // The value of an instruction's operand may be inserted 3893 // by referring to it with a '$' prefix. 3894 // opcode -- Three instruction opcodes may be provided. These are referred 3895 // to within an encode class as $primary, $secondary, and $tertiary 3896 // rrspectively. The primary opcode is commonly used to 3897 // indicate the type of machine instruction, while secondary 3898 // and tertiary are often used for prefix options or addressing 3899 // modes. 3900 // ins_encode -- A list of encode classes with parameters. The encode class 3901 // name must have been defined in an 'enc_class' specification 3902 // in the encode section of the architecture description. 3903 3904 // Dummy reg-to-reg vector moves. Removed during post-selection cleanup. 3905 // Load Float 3906 instruct MoveF2VL(vlRegF dst, regF src) %{ 3907 match(Set dst src); 3908 format %{ "movss $dst,$src\t! load float (4 bytes)" %} 3909 ins_encode %{ 3910 ShouldNotReachHere(); 3911 %} 3912 ins_pipe( fpu_reg_reg ); 3913 %} 3914 3915 // Load Float 3916 instruct MoveF2LEG(legRegF dst, regF src) %{ 3917 match(Set dst src); 3918 format %{ "movss $dst,$src\t# if src != dst load float (4 bytes)" %} 3919 ins_encode %{ 3920 ShouldNotReachHere(); 3921 %} 3922 ins_pipe( fpu_reg_reg ); 3923 %} 3924 3925 // Load Float 3926 instruct MoveVL2F(regF dst, vlRegF src) %{ 3927 match(Set dst src); 3928 format %{ "movss $dst,$src\t! load float (4 bytes)" %} 3929 ins_encode %{ 3930 ShouldNotReachHere(); 3931 %} 3932 ins_pipe( fpu_reg_reg ); 3933 %} 3934 3935 // Load Float 3936 instruct MoveLEG2F(regF dst, legRegF src) %{ 3937 match(Set dst src); 3938 format %{ "movss $dst,$src\t# if src != dst load float (4 bytes)" %} 3939 ins_encode %{ 3940 ShouldNotReachHere(); 3941 %} 3942 ins_pipe( fpu_reg_reg ); 3943 %} 3944 3945 // Load Double 3946 instruct MoveD2VL(vlRegD dst, regD src) %{ 3947 match(Set dst src); 3948 format %{ "movsd $dst,$src\t! load double (8 bytes)" %} 3949 ins_encode %{ 3950 ShouldNotReachHere(); 3951 %} 3952 ins_pipe( fpu_reg_reg ); 3953 %} 3954 3955 // Load Double 3956 instruct MoveD2LEG(legRegD dst, regD src) %{ 3957 match(Set dst src); 3958 format %{ "movsd $dst,$src\t# if src != dst load double (8 bytes)" %} 3959 ins_encode %{ 3960 ShouldNotReachHere(); 3961 %} 3962 ins_pipe( fpu_reg_reg ); 3963 %} 3964 3965 // Load Double 3966 instruct MoveVL2D(regD dst, vlRegD src) %{ 3967 match(Set dst src); 3968 format %{ "movsd $dst,$src\t! load double (8 bytes)" %} 3969 ins_encode %{ 3970 ShouldNotReachHere(); 3971 %} 3972 ins_pipe( fpu_reg_reg ); 3973 %} 3974 3975 // Load Double 3976 instruct MoveLEG2D(regD dst, legRegD src) %{ 3977 match(Set dst src); 3978 format %{ "movsd $dst,$src\t# if src != dst load double (8 bytes)" %} 3979 ins_encode %{ 3980 ShouldNotReachHere(); 3981 %} 3982 ins_pipe( fpu_reg_reg ); 3983 %} 3984 3985 //----------Load/Store/Move Instructions--------------------------------------- 3986 //----------Load Instructions-------------------------------------------------- 3987 3988 // Load Byte (8 bit signed) 3989 instruct loadB(rRegI dst, memory mem) 3990 %{ 3991 match(Set dst (LoadB mem)); 3992 3993 ins_cost(125); 3994 format %{ "movsbl $dst, $mem\t# byte" %} 3995 3996 ins_encode %{ 3997 __ movsbl($dst$$Register, $mem$$Address); 3998 %} 3999 4000 ins_pipe(ialu_reg_mem); 4001 %} 4002 4003 // Load Byte (8 bit signed) into Long Register 4004 instruct loadB2L(rRegL dst, memory mem) 4005 %{ 4006 match(Set dst (ConvI2L (LoadB mem))); 4007 4008 ins_cost(125); 4009 format %{ "movsbq $dst, $mem\t# byte -> long" %} 4010 4011 ins_encode %{ 4012 __ movsbq($dst$$Register, $mem$$Address); 4013 %} 4014 4015 ins_pipe(ialu_reg_mem); 4016 %} 4017 4018 // Load Unsigned Byte (8 bit UNsigned) 4019 instruct loadUB(rRegI dst, memory mem) 4020 %{ 4021 match(Set dst (LoadUB mem)); 4022 4023 ins_cost(125); 4024 format %{ "movzbl $dst, $mem\t# ubyte" %} 4025 4026 ins_encode %{ 4027 __ movzbl($dst$$Register, $mem$$Address); 4028 %} 4029 4030 ins_pipe(ialu_reg_mem); 4031 %} 4032 4033 // Load Unsigned Byte (8 bit UNsigned) into Long Register 4034 instruct loadUB2L(rRegL dst, memory mem) 4035 %{ 4036 match(Set dst (ConvI2L (LoadUB mem))); 4037 4038 ins_cost(125); 4039 format %{ "movzbq $dst, $mem\t# ubyte -> long" %} 4040 4041 ins_encode %{ 4042 __ movzbq($dst$$Register, $mem$$Address); 4043 %} 4044 4045 ins_pipe(ialu_reg_mem); 4046 %} 4047 4048 // Load Unsigned Byte (8 bit UNsigned) with 32-bit mask into Long Register 4049 instruct loadUB2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 4050 match(Set dst (ConvI2L (AndI (LoadUB mem) mask))); 4051 effect(KILL cr); 4052 4053 format %{ "movzbq $dst, $mem\t# ubyte & 32-bit mask -> long\n\t" 4054 "andl $dst, right_n_bits($mask, 8)" %} 4055 ins_encode %{ 4056 Register Rdst = $dst$$Register; 4057 __ movzbq(Rdst, $mem$$Address); 4058 __ andl(Rdst, $mask$$constant & right_n_bits(8)); 4059 %} 4060 ins_pipe(ialu_reg_mem); 4061 %} 4062 4063 // Load Short (16 bit signed) 4064 instruct loadS(rRegI dst, memory mem) 4065 %{ 4066 match(Set dst (LoadS mem)); 4067 4068 ins_cost(125); 4069 format %{ "movswl $dst, $mem\t# short" %} 4070 4071 ins_encode %{ 4072 __ movswl($dst$$Register, $mem$$Address); 4073 %} 4074 4075 ins_pipe(ialu_reg_mem); 4076 %} 4077 4078 // Load Short (16 bit signed) to Byte (8 bit signed) 4079 instruct loadS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4080 match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour)); 4081 4082 ins_cost(125); 4083 format %{ "movsbl $dst, $mem\t# short -> byte" %} 4084 ins_encode %{ 4085 __ movsbl($dst$$Register, $mem$$Address); 4086 %} 4087 ins_pipe(ialu_reg_mem); 4088 %} 4089 4090 // Load Short (16 bit signed) into Long Register 4091 instruct loadS2L(rRegL dst, memory mem) 4092 %{ 4093 match(Set dst (ConvI2L (LoadS mem))); 4094 4095 ins_cost(125); 4096 format %{ "movswq $dst, $mem\t# short -> long" %} 4097 4098 ins_encode %{ 4099 __ movswq($dst$$Register, $mem$$Address); 4100 %} 4101 4102 ins_pipe(ialu_reg_mem); 4103 %} 4104 4105 // Load Unsigned Short/Char (16 bit UNsigned) 4106 instruct loadUS(rRegI dst, memory mem) 4107 %{ 4108 match(Set dst (LoadUS mem)); 4109 4110 ins_cost(125); 4111 format %{ "movzwl $dst, $mem\t# ushort/char" %} 4112 4113 ins_encode %{ 4114 __ movzwl($dst$$Register, $mem$$Address); 4115 %} 4116 4117 ins_pipe(ialu_reg_mem); 4118 %} 4119 4120 // Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed) 4121 instruct loadUS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4122 match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour)); 4123 4124 ins_cost(125); 4125 format %{ "movsbl $dst, $mem\t# ushort -> byte" %} 4126 ins_encode %{ 4127 __ movsbl($dst$$Register, $mem$$Address); 4128 %} 4129 ins_pipe(ialu_reg_mem); 4130 %} 4131 4132 // Load Unsigned Short/Char (16 bit UNsigned) into Long Register 4133 instruct loadUS2L(rRegL dst, memory mem) 4134 %{ 4135 match(Set dst (ConvI2L (LoadUS mem))); 4136 4137 ins_cost(125); 4138 format %{ "movzwq $dst, $mem\t# ushort/char -> long" %} 4139 4140 ins_encode %{ 4141 __ movzwq($dst$$Register, $mem$$Address); 4142 %} 4143 4144 ins_pipe(ialu_reg_mem); 4145 %} 4146 4147 // Load Unsigned Short/Char (16 bit UNsigned) with mask 0xFF into Long Register 4148 instruct loadUS2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 4149 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 4150 4151 format %{ "movzbq $dst, $mem\t# ushort/char & 0xFF -> long" %} 4152 ins_encode %{ 4153 __ movzbq($dst$$Register, $mem$$Address); 4154 %} 4155 ins_pipe(ialu_reg_mem); 4156 %} 4157 4158 // Load Unsigned Short/Char (16 bit UNsigned) with 32-bit mask into Long Register 4159 instruct loadUS2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 4160 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 4161 effect(KILL cr); 4162 4163 format %{ "movzwq $dst, $mem\t# ushort/char & 32-bit mask -> long\n\t" 4164 "andl $dst, right_n_bits($mask, 16)" %} 4165 ins_encode %{ 4166 Register Rdst = $dst$$Register; 4167 __ movzwq(Rdst, $mem$$Address); 4168 __ andl(Rdst, $mask$$constant & right_n_bits(16)); 4169 %} 4170 ins_pipe(ialu_reg_mem); 4171 %} 4172 4173 // Load Integer 4174 instruct loadI(rRegI dst, memory mem) 4175 %{ 4176 match(Set dst (LoadI mem)); 4177 4178 ins_cost(125); 4179 format %{ "movl $dst, $mem\t# int" %} 4180 4181 ins_encode %{ 4182 __ movl($dst$$Register, $mem$$Address); 4183 %} 4184 4185 ins_pipe(ialu_reg_mem); 4186 %} 4187 4188 // Load Integer (32 bit signed) to Byte (8 bit signed) 4189 instruct loadI2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4190 match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour)); 4191 4192 ins_cost(125); 4193 format %{ "movsbl $dst, $mem\t# int -> byte" %} 4194 ins_encode %{ 4195 __ movsbl($dst$$Register, $mem$$Address); 4196 %} 4197 ins_pipe(ialu_reg_mem); 4198 %} 4199 4200 // Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned) 4201 instruct loadI2UB(rRegI dst, memory mem, immI_255 mask) %{ 4202 match(Set dst (AndI (LoadI mem) mask)); 4203 4204 ins_cost(125); 4205 format %{ "movzbl $dst, $mem\t# int -> ubyte" %} 4206 ins_encode %{ 4207 __ movzbl($dst$$Register, $mem$$Address); 4208 %} 4209 ins_pipe(ialu_reg_mem); 4210 %} 4211 4212 // Load Integer (32 bit signed) to Short (16 bit signed) 4213 instruct loadI2S(rRegI dst, memory mem, immI_16 sixteen) %{ 4214 match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen)); 4215 4216 ins_cost(125); 4217 format %{ "movswl $dst, $mem\t# int -> short" %} 4218 ins_encode %{ 4219 __ movswl($dst$$Register, $mem$$Address); 4220 %} 4221 ins_pipe(ialu_reg_mem); 4222 %} 4223 4224 // Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned) 4225 instruct loadI2US(rRegI dst, memory mem, immI_65535 mask) %{ 4226 match(Set dst (AndI (LoadI mem) mask)); 4227 4228 ins_cost(125); 4229 format %{ "movzwl $dst, $mem\t# int -> ushort/char" %} 4230 ins_encode %{ 4231 __ movzwl($dst$$Register, $mem$$Address); 4232 %} 4233 ins_pipe(ialu_reg_mem); 4234 %} 4235 4236 // Load Integer into Long Register 4237 instruct loadI2L(rRegL dst, memory mem) 4238 %{ 4239 match(Set dst (ConvI2L (LoadI mem))); 4240 4241 ins_cost(125); 4242 format %{ "movslq $dst, $mem\t# int -> long" %} 4243 4244 ins_encode %{ 4245 __ movslq($dst$$Register, $mem$$Address); 4246 %} 4247 4248 ins_pipe(ialu_reg_mem); 4249 %} 4250 4251 // Load Integer with mask 0xFF into Long Register 4252 instruct loadI2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 4253 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4254 4255 format %{ "movzbq $dst, $mem\t# int & 0xFF -> long" %} 4256 ins_encode %{ 4257 __ movzbq($dst$$Register, $mem$$Address); 4258 %} 4259 ins_pipe(ialu_reg_mem); 4260 %} 4261 4262 // Load Integer with mask 0xFFFF into Long Register 4263 instruct loadI2L_immI_65535(rRegL dst, memory mem, immI_65535 mask) %{ 4264 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4265 4266 format %{ "movzwq $dst, $mem\t# int & 0xFFFF -> long" %} 4267 ins_encode %{ 4268 __ movzwq($dst$$Register, $mem$$Address); 4269 %} 4270 ins_pipe(ialu_reg_mem); 4271 %} 4272 4273 // Load Integer with a 31-bit mask into Long Register 4274 instruct loadI2L_immU31(rRegL dst, memory mem, immU31 mask, rFlagsReg cr) %{ 4275 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4276 effect(KILL cr); 4277 4278 format %{ "movl $dst, $mem\t# int & 31-bit mask -> long\n\t" 4279 "andl $dst, $mask" %} 4280 ins_encode %{ 4281 Register Rdst = $dst$$Register; 4282 __ movl(Rdst, $mem$$Address); 4283 __ andl(Rdst, $mask$$constant); 4284 %} 4285 ins_pipe(ialu_reg_mem); 4286 %} 4287 4288 // Load Unsigned Integer into Long Register 4289 instruct loadUI2L(rRegL dst, memory mem, immL_32bits mask) 4290 %{ 4291 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 4292 4293 ins_cost(125); 4294 format %{ "movl $dst, $mem\t# uint -> long" %} 4295 4296 ins_encode %{ 4297 __ movl($dst$$Register, $mem$$Address); 4298 %} 4299 4300 ins_pipe(ialu_reg_mem); 4301 %} 4302 4303 // Load Long 4304 instruct loadL(rRegL dst, memory mem) 4305 %{ 4306 match(Set dst (LoadL mem)); 4307 4308 ins_cost(125); 4309 format %{ "movq $dst, $mem\t# long" %} 4310 4311 ins_encode %{ 4312 __ movq($dst$$Register, $mem$$Address); 4313 %} 4314 4315 ins_pipe(ialu_reg_mem); // XXX 4316 %} 4317 4318 // Load Range 4319 instruct loadRange(rRegI dst, memory mem) 4320 %{ 4321 match(Set dst (LoadRange mem)); 4322 4323 ins_cost(125); // XXX 4324 format %{ "movl $dst, $mem\t# range" %} 4325 ins_encode %{ 4326 __ movl($dst$$Register, $mem$$Address); 4327 %} 4328 ins_pipe(ialu_reg_mem); 4329 %} 4330 4331 // Load Pointer 4332 instruct loadP(rRegP dst, memory mem) 4333 %{ 4334 match(Set dst (LoadP mem)); 4335 predicate(n->as_Load()->barrier_data() == 0); 4336 4337 ins_cost(125); // XXX 4338 format %{ "movq $dst, $mem\t# ptr" %} 4339 ins_encode %{ 4340 __ movq($dst$$Register, $mem$$Address); 4341 %} 4342 ins_pipe(ialu_reg_mem); // XXX 4343 %} 4344 4345 // Load Compressed Pointer 4346 instruct loadN(rRegN dst, memory mem) 4347 %{ 4348 predicate(n->as_Load()->barrier_data() == 0); 4349 match(Set dst (LoadN mem)); 4350 4351 ins_cost(125); // XXX 4352 format %{ "movl $dst, $mem\t# compressed ptr" %} 4353 ins_encode %{ 4354 __ movl($dst$$Register, $mem$$Address); 4355 %} 4356 ins_pipe(ialu_reg_mem); // XXX 4357 %} 4358 4359 4360 // Load Klass Pointer 4361 instruct loadKlass(rRegP dst, memory mem) 4362 %{ 4363 match(Set dst (LoadKlass mem)); 4364 4365 ins_cost(125); // XXX 4366 format %{ "movq $dst, $mem\t# class" %} 4367 ins_encode %{ 4368 __ movq($dst$$Register, $mem$$Address); 4369 %} 4370 ins_pipe(ialu_reg_mem); // XXX 4371 %} 4372 4373 // Load narrow Klass Pointer 4374 instruct loadNKlass(rRegN dst, memory mem) 4375 %{ 4376 predicate(!UseCompactObjectHeaders); 4377 match(Set dst (LoadNKlass mem)); 4378 4379 ins_cost(125); // XXX 4380 format %{ "movl $dst, $mem\t# compressed klass ptr" %} 4381 ins_encode %{ 4382 __ movl($dst$$Register, $mem$$Address); 4383 %} 4384 ins_pipe(ialu_reg_mem); // XXX 4385 %} 4386 4387 instruct loadNKlassCompactHeaders(rRegN dst, memory mem, rFlagsReg cr) 4388 %{ 4389 predicate(UseCompactObjectHeaders); 4390 match(Set dst (LoadNKlass mem)); 4391 effect(KILL cr); 4392 ins_cost(125); 4393 format %{ 4394 "movl $dst, $mem\t# compressed klass ptr, shifted\n\t" 4395 "shrl $dst, markWord::klass_shift_at_offset" 4396 %} 4397 ins_encode %{ 4398 if (UseAPX) { 4399 __ eshrl($dst$$Register, $mem$$Address, markWord::klass_shift_at_offset, false); 4400 } 4401 else { 4402 __ movl($dst$$Register, $mem$$Address); 4403 __ shrl($dst$$Register, markWord::klass_shift_at_offset); 4404 } 4405 %} 4406 ins_pipe(ialu_reg_mem); 4407 %} 4408 4409 // Load Float 4410 instruct loadF(regF dst, memory mem) 4411 %{ 4412 match(Set dst (LoadF mem)); 4413 4414 ins_cost(145); // XXX 4415 format %{ "movss $dst, $mem\t# float" %} 4416 ins_encode %{ 4417 __ movflt($dst$$XMMRegister, $mem$$Address); 4418 %} 4419 ins_pipe(pipe_slow); // XXX 4420 %} 4421 4422 // Load Double 4423 instruct loadD_partial(regD dst, memory mem) 4424 %{ 4425 predicate(!UseXmmLoadAndClearUpper); 4426 match(Set dst (LoadD mem)); 4427 4428 ins_cost(145); // XXX 4429 format %{ "movlpd $dst, $mem\t# double" %} 4430 ins_encode %{ 4431 __ movdbl($dst$$XMMRegister, $mem$$Address); 4432 %} 4433 ins_pipe(pipe_slow); // XXX 4434 %} 4435 4436 instruct loadD(regD dst, memory mem) 4437 %{ 4438 predicate(UseXmmLoadAndClearUpper); 4439 match(Set dst (LoadD mem)); 4440 4441 ins_cost(145); // XXX 4442 format %{ "movsd $dst, $mem\t# double" %} 4443 ins_encode %{ 4444 __ movdbl($dst$$XMMRegister, $mem$$Address); 4445 %} 4446 ins_pipe(pipe_slow); // XXX 4447 %} 4448 4449 // max = java.lang.Math.max(float a, float b) 4450 instruct maxF_reg(legRegF dst, legRegF a, legRegF b, legRegF tmp, legRegF atmp, legRegF btmp) %{ 4451 predicate(UseAVX > 0 && !VLoopReductions::is_reduction(n)); 4452 match(Set dst (MaxF a b)); 4453 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 4454 format %{ "maxF $dst, $a, $b \t! using $tmp, $atmp and $btmp as TEMP" %} 4455 ins_encode %{ 4456 __ vminmax_fp(Op_MaxV, T_FLOAT, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, Assembler::AVX_128bit); 4457 %} 4458 ins_pipe( pipe_slow ); 4459 %} 4460 4461 instruct maxF_reduction_reg(legRegF dst, legRegF a, legRegF b, legRegF xtmp, rRegI rtmp, rFlagsReg cr) %{ 4462 predicate(UseAVX > 0 && VLoopReductions::is_reduction(n)); 4463 match(Set dst (MaxF a b)); 4464 effect(USE a, USE b, TEMP xtmp, TEMP rtmp, KILL cr); 4465 4466 format %{ "maxF_reduction $dst, $a, $b \t!using $xtmp and $rtmp as TEMP" %} 4467 ins_encode %{ 4468 emit_fp_min_max(masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xtmp$$XMMRegister, $rtmp$$Register, 4469 false /*min*/, true /*single*/); 4470 %} 4471 ins_pipe( pipe_slow ); 4472 %} 4473 4474 // max = java.lang.Math.max(double a, double b) 4475 instruct maxD_reg(legRegD dst, legRegD a, legRegD b, legRegD tmp, legRegD atmp, legRegD btmp) %{ 4476 predicate(UseAVX > 0 && !VLoopReductions::is_reduction(n)); 4477 match(Set dst (MaxD a b)); 4478 effect(USE a, USE b, TEMP atmp, TEMP btmp, TEMP tmp); 4479 format %{ "maxD $dst, $a, $b \t! using $tmp, $atmp and $btmp as TEMP" %} 4480 ins_encode %{ 4481 __ vminmax_fp(Op_MaxV, T_DOUBLE, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, Assembler::AVX_128bit); 4482 %} 4483 ins_pipe( pipe_slow ); 4484 %} 4485 4486 instruct maxD_reduction_reg(legRegD dst, legRegD a, legRegD b, legRegD xtmp, rRegL rtmp, rFlagsReg cr) %{ 4487 predicate(UseAVX > 0 && VLoopReductions::is_reduction(n)); 4488 match(Set dst (MaxD a b)); 4489 effect(USE a, USE b, TEMP xtmp, TEMP rtmp, KILL cr); 4490 4491 format %{ "maxD_reduction $dst, $a, $b \t! using $xtmp and $rtmp as TEMP" %} 4492 ins_encode %{ 4493 emit_fp_min_max(masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xtmp$$XMMRegister, $rtmp$$Register, 4494 false /*min*/, false /*single*/); 4495 %} 4496 ins_pipe( pipe_slow ); 4497 %} 4498 4499 // min = java.lang.Math.min(float a, float b) 4500 instruct minF_reg(legRegF dst, legRegF a, legRegF b, legRegF tmp, legRegF atmp, legRegF btmp) %{ 4501 predicate(UseAVX > 0 && !VLoopReductions::is_reduction(n)); 4502 match(Set dst (MinF a b)); 4503 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 4504 format %{ "minF $dst, $a, $b \t! using $tmp, $atmp and $btmp as TEMP" %} 4505 ins_encode %{ 4506 __ vminmax_fp(Op_MinV, T_FLOAT, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, Assembler::AVX_128bit); 4507 %} 4508 ins_pipe( pipe_slow ); 4509 %} 4510 4511 instruct minF_reduction_reg(legRegF dst, legRegF a, legRegF b, legRegF xtmp, rRegI rtmp, rFlagsReg cr) %{ 4512 predicate(UseAVX > 0 && VLoopReductions::is_reduction(n)); 4513 match(Set dst (MinF a b)); 4514 effect(USE a, USE b, TEMP xtmp, TEMP rtmp, KILL cr); 4515 4516 format %{ "minF_reduction $dst, $a, $b \t! using $xtmp and $rtmp as TEMP" %} 4517 ins_encode %{ 4518 emit_fp_min_max(masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xtmp$$XMMRegister, $rtmp$$Register, 4519 true /*min*/, true /*single*/); 4520 %} 4521 ins_pipe( pipe_slow ); 4522 %} 4523 4524 // min = java.lang.Math.min(double a, double b) 4525 instruct minD_reg(legRegD dst, legRegD a, legRegD b, legRegD tmp, legRegD atmp, legRegD btmp) %{ 4526 predicate(UseAVX > 0 && !VLoopReductions::is_reduction(n)); 4527 match(Set dst (MinD a b)); 4528 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 4529 format %{ "minD $dst, $a, $b \t! using $tmp, $atmp and $btmp as TEMP" %} 4530 ins_encode %{ 4531 __ vminmax_fp(Op_MinV, T_DOUBLE, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, Assembler::AVX_128bit); 4532 %} 4533 ins_pipe( pipe_slow ); 4534 %} 4535 4536 instruct minD_reduction_reg(legRegD dst, legRegD a, legRegD b, legRegD xtmp, rRegL rtmp, rFlagsReg cr) %{ 4537 predicate(UseAVX > 0 && VLoopReductions::is_reduction(n)); 4538 match(Set dst (MinD a b)); 4539 effect(USE a, USE b, TEMP xtmp, TEMP rtmp, KILL cr); 4540 4541 format %{ "maxD_reduction $dst, $a, $b \t! using $xtmp and $rtmp as TEMP" %} 4542 ins_encode %{ 4543 emit_fp_min_max(masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xtmp$$XMMRegister, $rtmp$$Register, 4544 true /*min*/, false /*single*/); 4545 %} 4546 ins_pipe( pipe_slow ); 4547 %} 4548 4549 // Load Effective Address 4550 instruct leaP8(rRegP dst, indOffset8 mem) 4551 %{ 4552 match(Set dst mem); 4553 4554 ins_cost(110); // XXX 4555 format %{ "leaq $dst, $mem\t# ptr 8" %} 4556 ins_encode %{ 4557 __ leaq($dst$$Register, $mem$$Address); 4558 %} 4559 ins_pipe(ialu_reg_reg_fat); 4560 %} 4561 4562 instruct leaP32(rRegP dst, indOffset32 mem) 4563 %{ 4564 match(Set dst mem); 4565 4566 ins_cost(110); 4567 format %{ "leaq $dst, $mem\t# ptr 32" %} 4568 ins_encode %{ 4569 __ leaq($dst$$Register, $mem$$Address); 4570 %} 4571 ins_pipe(ialu_reg_reg_fat); 4572 %} 4573 4574 instruct leaPIdxOff(rRegP dst, indIndexOffset mem) 4575 %{ 4576 match(Set dst mem); 4577 4578 ins_cost(110); 4579 format %{ "leaq $dst, $mem\t# ptr idxoff" %} 4580 ins_encode %{ 4581 __ leaq($dst$$Register, $mem$$Address); 4582 %} 4583 ins_pipe(ialu_reg_reg_fat); 4584 %} 4585 4586 instruct leaPIdxScale(rRegP dst, indIndexScale mem) 4587 %{ 4588 match(Set dst mem); 4589 4590 ins_cost(110); 4591 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 4592 ins_encode %{ 4593 __ leaq($dst$$Register, $mem$$Address); 4594 %} 4595 ins_pipe(ialu_reg_reg_fat); 4596 %} 4597 4598 instruct leaPPosIdxScale(rRegP dst, indPosIndexScale mem) 4599 %{ 4600 match(Set dst mem); 4601 4602 ins_cost(110); 4603 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 4604 ins_encode %{ 4605 __ leaq($dst$$Register, $mem$$Address); 4606 %} 4607 ins_pipe(ialu_reg_reg_fat); 4608 %} 4609 4610 instruct leaPIdxScaleOff(rRegP dst, indIndexScaleOffset mem) 4611 %{ 4612 match(Set dst mem); 4613 4614 ins_cost(110); 4615 format %{ "leaq $dst, $mem\t# ptr idxscaleoff" %} 4616 ins_encode %{ 4617 __ leaq($dst$$Register, $mem$$Address); 4618 %} 4619 ins_pipe(ialu_reg_reg_fat); 4620 %} 4621 4622 instruct leaPPosIdxOff(rRegP dst, indPosIndexOffset mem) 4623 %{ 4624 match(Set dst mem); 4625 4626 ins_cost(110); 4627 format %{ "leaq $dst, $mem\t# ptr posidxoff" %} 4628 ins_encode %{ 4629 __ leaq($dst$$Register, $mem$$Address); 4630 %} 4631 ins_pipe(ialu_reg_reg_fat); 4632 %} 4633 4634 instruct leaPPosIdxScaleOff(rRegP dst, indPosIndexScaleOffset mem) 4635 %{ 4636 match(Set dst mem); 4637 4638 ins_cost(110); 4639 format %{ "leaq $dst, $mem\t# ptr posidxscaleoff" %} 4640 ins_encode %{ 4641 __ leaq($dst$$Register, $mem$$Address); 4642 %} 4643 ins_pipe(ialu_reg_reg_fat); 4644 %} 4645 4646 // Load Effective Address which uses Narrow (32-bits) oop 4647 instruct leaPCompressedOopOffset(rRegP dst, indCompressedOopOffset mem) 4648 %{ 4649 predicate(UseCompressedOops && (CompressedOops::shift() != 0)); 4650 match(Set dst mem); 4651 4652 ins_cost(110); 4653 format %{ "leaq $dst, $mem\t# ptr compressedoopoff32" %} 4654 ins_encode %{ 4655 __ leaq($dst$$Register, $mem$$Address); 4656 %} 4657 ins_pipe(ialu_reg_reg_fat); 4658 %} 4659 4660 instruct leaP8Narrow(rRegP dst, indOffset8Narrow mem) 4661 %{ 4662 predicate(CompressedOops::shift() == 0); 4663 match(Set dst mem); 4664 4665 ins_cost(110); // XXX 4666 format %{ "leaq $dst, $mem\t# ptr off8narrow" %} 4667 ins_encode %{ 4668 __ leaq($dst$$Register, $mem$$Address); 4669 %} 4670 ins_pipe(ialu_reg_reg_fat); 4671 %} 4672 4673 instruct leaP32Narrow(rRegP dst, indOffset32Narrow mem) 4674 %{ 4675 predicate(CompressedOops::shift() == 0); 4676 match(Set dst mem); 4677 4678 ins_cost(110); 4679 format %{ "leaq $dst, $mem\t# ptr off32narrow" %} 4680 ins_encode %{ 4681 __ leaq($dst$$Register, $mem$$Address); 4682 %} 4683 ins_pipe(ialu_reg_reg_fat); 4684 %} 4685 4686 instruct leaPIdxOffNarrow(rRegP dst, indIndexOffsetNarrow mem) 4687 %{ 4688 predicate(CompressedOops::shift() == 0); 4689 match(Set dst mem); 4690 4691 ins_cost(110); 4692 format %{ "leaq $dst, $mem\t# ptr idxoffnarrow" %} 4693 ins_encode %{ 4694 __ leaq($dst$$Register, $mem$$Address); 4695 %} 4696 ins_pipe(ialu_reg_reg_fat); 4697 %} 4698 4699 instruct leaPIdxScaleNarrow(rRegP dst, indIndexScaleNarrow mem) 4700 %{ 4701 predicate(CompressedOops::shift() == 0); 4702 match(Set dst mem); 4703 4704 ins_cost(110); 4705 format %{ "leaq $dst, $mem\t# ptr idxscalenarrow" %} 4706 ins_encode %{ 4707 __ leaq($dst$$Register, $mem$$Address); 4708 %} 4709 ins_pipe(ialu_reg_reg_fat); 4710 %} 4711 4712 instruct leaPIdxScaleOffNarrow(rRegP dst, indIndexScaleOffsetNarrow mem) 4713 %{ 4714 predicate(CompressedOops::shift() == 0); 4715 match(Set dst mem); 4716 4717 ins_cost(110); 4718 format %{ "leaq $dst, $mem\t# ptr idxscaleoffnarrow" %} 4719 ins_encode %{ 4720 __ leaq($dst$$Register, $mem$$Address); 4721 %} 4722 ins_pipe(ialu_reg_reg_fat); 4723 %} 4724 4725 instruct leaPPosIdxOffNarrow(rRegP dst, indPosIndexOffsetNarrow mem) 4726 %{ 4727 predicate(CompressedOops::shift() == 0); 4728 match(Set dst mem); 4729 4730 ins_cost(110); 4731 format %{ "leaq $dst, $mem\t# ptr posidxoffnarrow" %} 4732 ins_encode %{ 4733 __ leaq($dst$$Register, $mem$$Address); 4734 %} 4735 ins_pipe(ialu_reg_reg_fat); 4736 %} 4737 4738 instruct leaPPosIdxScaleOffNarrow(rRegP dst, indPosIndexScaleOffsetNarrow mem) 4739 %{ 4740 predicate(CompressedOops::shift() == 0); 4741 match(Set dst mem); 4742 4743 ins_cost(110); 4744 format %{ "leaq $dst, $mem\t# ptr posidxscaleoffnarrow" %} 4745 ins_encode %{ 4746 __ leaq($dst$$Register, $mem$$Address); 4747 %} 4748 ins_pipe(ialu_reg_reg_fat); 4749 %} 4750 4751 instruct loadConI(rRegI dst, immI src) 4752 %{ 4753 match(Set dst src); 4754 4755 format %{ "movl $dst, $src\t# int" %} 4756 ins_encode %{ 4757 __ movl($dst$$Register, $src$$constant); 4758 %} 4759 ins_pipe(ialu_reg_fat); // XXX 4760 %} 4761 4762 instruct loadConI0(rRegI dst, immI_0 src, rFlagsReg cr) 4763 %{ 4764 match(Set dst src); 4765 effect(KILL cr); 4766 4767 ins_cost(50); 4768 format %{ "xorl $dst, $dst\t# int" %} 4769 ins_encode %{ 4770 __ xorl($dst$$Register, $dst$$Register); 4771 %} 4772 ins_pipe(ialu_reg); 4773 %} 4774 4775 instruct loadConL(rRegL dst, immL src) 4776 %{ 4777 match(Set dst src); 4778 4779 ins_cost(150); 4780 format %{ "movq $dst, $src\t# long" %} 4781 ins_encode %{ 4782 __ mov64($dst$$Register, $src$$constant); 4783 %} 4784 ins_pipe(ialu_reg); 4785 %} 4786 4787 instruct loadConL0(rRegL dst, immL0 src, rFlagsReg cr) 4788 %{ 4789 match(Set dst src); 4790 effect(KILL cr); 4791 4792 ins_cost(50); 4793 format %{ "xorl $dst, $dst\t# long" %} 4794 ins_encode %{ 4795 __ xorl($dst$$Register, $dst$$Register); 4796 %} 4797 ins_pipe(ialu_reg); // XXX 4798 %} 4799 4800 instruct loadConUL32(rRegL dst, immUL32 src) 4801 %{ 4802 match(Set dst src); 4803 4804 ins_cost(60); 4805 format %{ "movl $dst, $src\t# long (unsigned 32-bit)" %} 4806 ins_encode %{ 4807 __ movl($dst$$Register, $src$$constant); 4808 %} 4809 ins_pipe(ialu_reg); 4810 %} 4811 4812 instruct loadConL32(rRegL dst, immL32 src) 4813 %{ 4814 match(Set dst src); 4815 4816 ins_cost(70); 4817 format %{ "movq $dst, $src\t# long (32-bit)" %} 4818 ins_encode %{ 4819 __ movq($dst$$Register, $src$$constant); 4820 %} 4821 ins_pipe(ialu_reg); 4822 %} 4823 4824 instruct loadConP(rRegP dst, immP con) %{ 4825 match(Set dst con); 4826 4827 format %{ "movq $dst, $con\t# ptr" %} 4828 ins_encode %{ 4829 __ mov64($dst$$Register, $con$$constant, $con->constant_reloc(), RELOC_IMM64); 4830 %} 4831 ins_pipe(ialu_reg_fat); // XXX 4832 %} 4833 4834 instruct loadConP0(rRegP dst, immP0 src, rFlagsReg cr) 4835 %{ 4836 match(Set dst src); 4837 effect(KILL cr); 4838 4839 ins_cost(50); 4840 format %{ "xorl $dst, $dst\t# ptr" %} 4841 ins_encode %{ 4842 __ xorl($dst$$Register, $dst$$Register); 4843 %} 4844 ins_pipe(ialu_reg); 4845 %} 4846 4847 instruct loadConP31(rRegP dst, immP31 src, rFlagsReg cr) 4848 %{ 4849 match(Set dst src); 4850 effect(KILL cr); 4851 4852 ins_cost(60); 4853 format %{ "movl $dst, $src\t# ptr (positive 32-bit)" %} 4854 ins_encode %{ 4855 __ movl($dst$$Register, $src$$constant); 4856 %} 4857 ins_pipe(ialu_reg); 4858 %} 4859 4860 instruct loadConF(regF dst, immF con) %{ 4861 match(Set dst con); 4862 ins_cost(125); 4863 format %{ "movss $dst, [$constantaddress]\t# load from constant table: float=$con" %} 4864 ins_encode %{ 4865 __ movflt($dst$$XMMRegister, $constantaddress($con)); 4866 %} 4867 ins_pipe(pipe_slow); 4868 %} 4869 4870 instruct loadConH(regF dst, immH con) %{ 4871 match(Set dst con); 4872 ins_cost(125); 4873 format %{ "movss $dst, [$constantaddress]\t# load from constant table: halffloat=$con" %} 4874 ins_encode %{ 4875 __ movflt($dst$$XMMRegister, $constantaddress($con)); 4876 %} 4877 ins_pipe(pipe_slow); 4878 %} 4879 4880 instruct loadConN0(rRegN dst, immN0 src, rFlagsReg cr) %{ 4881 match(Set dst src); 4882 effect(KILL cr); 4883 format %{ "xorq $dst, $src\t# compressed null pointer" %} 4884 ins_encode %{ 4885 __ xorq($dst$$Register, $dst$$Register); 4886 %} 4887 ins_pipe(ialu_reg); 4888 %} 4889 4890 instruct loadConN(rRegN dst, immN src) %{ 4891 match(Set dst src); 4892 4893 ins_cost(125); 4894 format %{ "movl $dst, $src\t# compressed ptr" %} 4895 ins_encode %{ 4896 address con = (address)$src$$constant; 4897 if (con == nullptr) { 4898 ShouldNotReachHere(); 4899 } else { 4900 __ set_narrow_oop($dst$$Register, (jobject)$src$$constant); 4901 } 4902 %} 4903 ins_pipe(ialu_reg_fat); // XXX 4904 %} 4905 4906 instruct loadConNKlass(rRegN dst, immNKlass src) %{ 4907 match(Set dst src); 4908 4909 ins_cost(125); 4910 format %{ "movl $dst, $src\t# compressed klass ptr" %} 4911 ins_encode %{ 4912 address con = (address)$src$$constant; 4913 if (con == nullptr) { 4914 ShouldNotReachHere(); 4915 } else { 4916 __ set_narrow_klass($dst$$Register, (Klass*)$src$$constant); 4917 } 4918 %} 4919 ins_pipe(ialu_reg_fat); // XXX 4920 %} 4921 4922 instruct loadConF0(regF dst, immF0 src) 4923 %{ 4924 match(Set dst src); 4925 ins_cost(100); 4926 4927 format %{ "xorps $dst, $dst\t# float 0.0" %} 4928 ins_encode %{ 4929 __ xorps($dst$$XMMRegister, $dst$$XMMRegister); 4930 %} 4931 ins_pipe(pipe_slow); 4932 %} 4933 4934 // Use the same format since predicate() can not be used here. 4935 instruct loadConD(regD dst, immD con) %{ 4936 match(Set dst con); 4937 ins_cost(125); 4938 format %{ "movsd $dst, [$constantaddress]\t# load from constant table: double=$con" %} 4939 ins_encode %{ 4940 __ movdbl($dst$$XMMRegister, $constantaddress($con)); 4941 %} 4942 ins_pipe(pipe_slow); 4943 %} 4944 4945 instruct loadConD0(regD dst, immD0 src) 4946 %{ 4947 match(Set dst src); 4948 ins_cost(100); 4949 4950 format %{ "xorpd $dst, $dst\t# double 0.0" %} 4951 ins_encode %{ 4952 __ xorpd($dst$$XMMRegister, $dst$$XMMRegister); 4953 %} 4954 ins_pipe(pipe_slow); 4955 %} 4956 4957 instruct loadSSI(rRegI dst, stackSlotI src) 4958 %{ 4959 match(Set dst src); 4960 4961 ins_cost(125); 4962 format %{ "movl $dst, $src\t# int stk" %} 4963 ins_encode %{ 4964 __ movl($dst$$Register, $src$$Address); 4965 %} 4966 ins_pipe(ialu_reg_mem); 4967 %} 4968 4969 instruct loadSSL(rRegL dst, stackSlotL src) 4970 %{ 4971 match(Set dst src); 4972 4973 ins_cost(125); 4974 format %{ "movq $dst, $src\t# long stk" %} 4975 ins_encode %{ 4976 __ movq($dst$$Register, $src$$Address); 4977 %} 4978 ins_pipe(ialu_reg_mem); 4979 %} 4980 4981 instruct loadSSP(rRegP dst, stackSlotP src) 4982 %{ 4983 match(Set dst src); 4984 4985 ins_cost(125); 4986 format %{ "movq $dst, $src\t# ptr stk" %} 4987 ins_encode %{ 4988 __ movq($dst$$Register, $src$$Address); 4989 %} 4990 ins_pipe(ialu_reg_mem); 4991 %} 4992 4993 instruct loadSSF(regF dst, stackSlotF src) 4994 %{ 4995 match(Set dst src); 4996 4997 ins_cost(125); 4998 format %{ "movss $dst, $src\t# float stk" %} 4999 ins_encode %{ 5000 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 5001 %} 5002 ins_pipe(pipe_slow); // XXX 5003 %} 5004 5005 // Use the same format since predicate() can not be used here. 5006 instruct loadSSD(regD dst, stackSlotD src) 5007 %{ 5008 match(Set dst src); 5009 5010 ins_cost(125); 5011 format %{ "movsd $dst, $src\t# double stk" %} 5012 ins_encode %{ 5013 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 5014 %} 5015 ins_pipe(pipe_slow); // XXX 5016 %} 5017 5018 // Prefetch instructions for allocation. 5019 // Must be safe to execute with invalid address (cannot fault). 5020 5021 instruct prefetchAlloc( memory mem ) %{ 5022 predicate(AllocatePrefetchInstr==3); 5023 match(PrefetchAllocation mem); 5024 ins_cost(125); 5025 5026 format %{ "PREFETCHW $mem\t# Prefetch allocation into level 1 cache and mark modified" %} 5027 ins_encode %{ 5028 __ prefetchw($mem$$Address); 5029 %} 5030 ins_pipe(ialu_mem); 5031 %} 5032 5033 instruct prefetchAllocNTA( memory mem ) %{ 5034 predicate(AllocatePrefetchInstr==0); 5035 match(PrefetchAllocation mem); 5036 ins_cost(125); 5037 5038 format %{ "PREFETCHNTA $mem\t# Prefetch allocation to non-temporal cache for write" %} 5039 ins_encode %{ 5040 __ prefetchnta($mem$$Address); 5041 %} 5042 ins_pipe(ialu_mem); 5043 %} 5044 5045 instruct prefetchAllocT0( memory mem ) %{ 5046 predicate(AllocatePrefetchInstr==1); 5047 match(PrefetchAllocation mem); 5048 ins_cost(125); 5049 5050 format %{ "PREFETCHT0 $mem\t# Prefetch allocation to level 1 and 2 caches for write" %} 5051 ins_encode %{ 5052 __ prefetcht0($mem$$Address); 5053 %} 5054 ins_pipe(ialu_mem); 5055 %} 5056 5057 instruct prefetchAllocT2( memory mem ) %{ 5058 predicate(AllocatePrefetchInstr==2); 5059 match(PrefetchAllocation mem); 5060 ins_cost(125); 5061 5062 format %{ "PREFETCHT2 $mem\t# Prefetch allocation to level 2 cache for write" %} 5063 ins_encode %{ 5064 __ prefetcht2($mem$$Address); 5065 %} 5066 ins_pipe(ialu_mem); 5067 %} 5068 5069 //----------Store Instructions------------------------------------------------- 5070 5071 // Store Byte 5072 instruct storeB(memory mem, rRegI src) 5073 %{ 5074 match(Set mem (StoreB mem src)); 5075 5076 ins_cost(125); // XXX 5077 format %{ "movb $mem, $src\t# byte" %} 5078 ins_encode %{ 5079 __ movb($mem$$Address, $src$$Register); 5080 %} 5081 ins_pipe(ialu_mem_reg); 5082 %} 5083 5084 // Store Char/Short 5085 instruct storeC(memory mem, rRegI src) 5086 %{ 5087 match(Set mem (StoreC mem src)); 5088 5089 ins_cost(125); // XXX 5090 format %{ "movw $mem, $src\t# char/short" %} 5091 ins_encode %{ 5092 __ movw($mem$$Address, $src$$Register); 5093 %} 5094 ins_pipe(ialu_mem_reg); 5095 %} 5096 5097 // Store Integer 5098 instruct storeI(memory mem, rRegI src) 5099 %{ 5100 match(Set mem (StoreI mem src)); 5101 5102 ins_cost(125); // XXX 5103 format %{ "movl $mem, $src\t# int" %} 5104 ins_encode %{ 5105 __ movl($mem$$Address, $src$$Register); 5106 %} 5107 ins_pipe(ialu_mem_reg); 5108 %} 5109 5110 // Store Long 5111 instruct storeL(memory mem, rRegL src) 5112 %{ 5113 match(Set mem (StoreL mem src)); 5114 5115 ins_cost(125); // XXX 5116 format %{ "movq $mem, $src\t# long" %} 5117 ins_encode %{ 5118 __ movq($mem$$Address, $src$$Register); 5119 %} 5120 ins_pipe(ialu_mem_reg); // XXX 5121 %} 5122 5123 // Store Pointer 5124 instruct storeP(memory mem, any_RegP src) 5125 %{ 5126 predicate(n->as_Store()->barrier_data() == 0); 5127 match(Set mem (StoreP mem src)); 5128 5129 ins_cost(125); // XXX 5130 format %{ "movq $mem, $src\t# ptr" %} 5131 ins_encode %{ 5132 __ movq($mem$$Address, $src$$Register); 5133 %} 5134 ins_pipe(ialu_mem_reg); 5135 %} 5136 5137 instruct storeImmP0(memory mem, immP0 zero) 5138 %{ 5139 predicate(UseCompressedOops && (CompressedOops::base() == nullptr) && n->as_Store()->barrier_data() == 0); 5140 match(Set mem (StoreP mem zero)); 5141 5142 ins_cost(125); // XXX 5143 format %{ "movq $mem, R12\t# ptr (R12_heapbase==0)" %} 5144 ins_encode %{ 5145 __ movq($mem$$Address, r12); 5146 %} 5147 ins_pipe(ialu_mem_reg); 5148 %} 5149 5150 // Store Null Pointer, mark word, or other simple pointer constant. 5151 instruct storeImmP(memory mem, immP31 src) 5152 %{ 5153 predicate(n->as_Store()->barrier_data() == 0); 5154 match(Set mem (StoreP mem src)); 5155 5156 ins_cost(150); // XXX 5157 format %{ "movq $mem, $src\t# ptr" %} 5158 ins_encode %{ 5159 __ movq($mem$$Address, $src$$constant); 5160 %} 5161 ins_pipe(ialu_mem_imm); 5162 %} 5163 5164 // Store Compressed Pointer 5165 instruct storeN(memory mem, rRegN src) 5166 %{ 5167 predicate(n->as_Store()->barrier_data() == 0); 5168 match(Set mem (StoreN mem src)); 5169 5170 ins_cost(125); // XXX 5171 format %{ "movl $mem, $src\t# compressed ptr" %} 5172 ins_encode %{ 5173 __ movl($mem$$Address, $src$$Register); 5174 %} 5175 ins_pipe(ialu_mem_reg); 5176 %} 5177 5178 instruct storeNKlass(memory mem, rRegN src) 5179 %{ 5180 match(Set mem (StoreNKlass mem src)); 5181 5182 ins_cost(125); // XXX 5183 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5184 ins_encode %{ 5185 __ movl($mem$$Address, $src$$Register); 5186 %} 5187 ins_pipe(ialu_mem_reg); 5188 %} 5189 5190 instruct storeImmN0(memory mem, immN0 zero) 5191 %{ 5192 predicate(CompressedOops::base() == nullptr && n->as_Store()->barrier_data() == 0); 5193 match(Set mem (StoreN mem zero)); 5194 5195 ins_cost(125); // XXX 5196 format %{ "movl $mem, R12\t# compressed ptr (R12_heapbase==0)" %} 5197 ins_encode %{ 5198 __ movl($mem$$Address, r12); 5199 %} 5200 ins_pipe(ialu_mem_reg); 5201 %} 5202 5203 instruct storeImmN(memory mem, immN src) 5204 %{ 5205 predicate(n->as_Store()->barrier_data() == 0); 5206 match(Set mem (StoreN mem src)); 5207 5208 ins_cost(150); // XXX 5209 format %{ "movl $mem, $src\t# compressed ptr" %} 5210 ins_encode %{ 5211 address con = (address)$src$$constant; 5212 if (con == nullptr) { 5213 __ movl($mem$$Address, 0); 5214 } else { 5215 __ set_narrow_oop($mem$$Address, (jobject)$src$$constant); 5216 } 5217 %} 5218 ins_pipe(ialu_mem_imm); 5219 %} 5220 5221 instruct storeImmNKlass(memory mem, immNKlass src) 5222 %{ 5223 match(Set mem (StoreNKlass mem src)); 5224 5225 ins_cost(150); // XXX 5226 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5227 ins_encode %{ 5228 __ set_narrow_klass($mem$$Address, (Klass*)$src$$constant); 5229 %} 5230 ins_pipe(ialu_mem_imm); 5231 %} 5232 5233 // Store Integer Immediate 5234 instruct storeImmI0(memory mem, immI_0 zero) 5235 %{ 5236 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5237 match(Set mem (StoreI mem zero)); 5238 5239 ins_cost(125); // XXX 5240 format %{ "movl $mem, R12\t# int (R12_heapbase==0)" %} 5241 ins_encode %{ 5242 __ movl($mem$$Address, r12); 5243 %} 5244 ins_pipe(ialu_mem_reg); 5245 %} 5246 5247 instruct storeImmI(memory mem, immI src) 5248 %{ 5249 match(Set mem (StoreI mem src)); 5250 5251 ins_cost(150); 5252 format %{ "movl $mem, $src\t# int" %} 5253 ins_encode %{ 5254 __ movl($mem$$Address, $src$$constant); 5255 %} 5256 ins_pipe(ialu_mem_imm); 5257 %} 5258 5259 // Store Long Immediate 5260 instruct storeImmL0(memory mem, immL0 zero) 5261 %{ 5262 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5263 match(Set mem (StoreL mem zero)); 5264 5265 ins_cost(125); // XXX 5266 format %{ "movq $mem, R12\t# long (R12_heapbase==0)" %} 5267 ins_encode %{ 5268 __ movq($mem$$Address, r12); 5269 %} 5270 ins_pipe(ialu_mem_reg); 5271 %} 5272 5273 instruct storeImmL(memory mem, immL32 src) 5274 %{ 5275 match(Set mem (StoreL mem src)); 5276 5277 ins_cost(150); 5278 format %{ "movq $mem, $src\t# long" %} 5279 ins_encode %{ 5280 __ movq($mem$$Address, $src$$constant); 5281 %} 5282 ins_pipe(ialu_mem_imm); 5283 %} 5284 5285 // Store Short/Char Immediate 5286 instruct storeImmC0(memory mem, immI_0 zero) 5287 %{ 5288 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5289 match(Set mem (StoreC mem zero)); 5290 5291 ins_cost(125); // XXX 5292 format %{ "movw $mem, R12\t# short/char (R12_heapbase==0)" %} 5293 ins_encode %{ 5294 __ movw($mem$$Address, r12); 5295 %} 5296 ins_pipe(ialu_mem_reg); 5297 %} 5298 5299 instruct storeImmI16(memory mem, immI16 src) 5300 %{ 5301 predicate(UseStoreImmI16); 5302 match(Set mem (StoreC mem src)); 5303 5304 ins_cost(150); 5305 format %{ "movw $mem, $src\t# short/char" %} 5306 ins_encode %{ 5307 __ movw($mem$$Address, $src$$constant); 5308 %} 5309 ins_pipe(ialu_mem_imm); 5310 %} 5311 5312 // Store Byte Immediate 5313 instruct storeImmB0(memory mem, immI_0 zero) 5314 %{ 5315 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5316 match(Set mem (StoreB mem zero)); 5317 5318 ins_cost(125); // XXX 5319 format %{ "movb $mem, R12\t# short/char (R12_heapbase==0)" %} 5320 ins_encode %{ 5321 __ movb($mem$$Address, r12); 5322 %} 5323 ins_pipe(ialu_mem_reg); 5324 %} 5325 5326 instruct storeImmB(memory mem, immI8 src) 5327 %{ 5328 match(Set mem (StoreB mem src)); 5329 5330 ins_cost(150); // XXX 5331 format %{ "movb $mem, $src\t# byte" %} 5332 ins_encode %{ 5333 __ movb($mem$$Address, $src$$constant); 5334 %} 5335 ins_pipe(ialu_mem_imm); 5336 %} 5337 5338 // Store Float 5339 instruct storeF(memory mem, regF src) 5340 %{ 5341 match(Set mem (StoreF mem src)); 5342 5343 ins_cost(95); // XXX 5344 format %{ "movss $mem, $src\t# float" %} 5345 ins_encode %{ 5346 __ movflt($mem$$Address, $src$$XMMRegister); 5347 %} 5348 ins_pipe(pipe_slow); // XXX 5349 %} 5350 5351 // Store immediate Float value (it is faster than store from XMM register) 5352 instruct storeF0(memory mem, immF0 zero) 5353 %{ 5354 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5355 match(Set mem (StoreF mem zero)); 5356 5357 ins_cost(25); // XXX 5358 format %{ "movl $mem, R12\t# float 0. (R12_heapbase==0)" %} 5359 ins_encode %{ 5360 __ movl($mem$$Address, r12); 5361 %} 5362 ins_pipe(ialu_mem_reg); 5363 %} 5364 5365 instruct storeF_imm(memory mem, immF src) 5366 %{ 5367 match(Set mem (StoreF mem src)); 5368 5369 ins_cost(50); 5370 format %{ "movl $mem, $src\t# float" %} 5371 ins_encode %{ 5372 __ movl($mem$$Address, jint_cast($src$$constant)); 5373 %} 5374 ins_pipe(ialu_mem_imm); 5375 %} 5376 5377 // Store Double 5378 instruct storeD(memory mem, regD src) 5379 %{ 5380 match(Set mem (StoreD mem src)); 5381 5382 ins_cost(95); // XXX 5383 format %{ "movsd $mem, $src\t# double" %} 5384 ins_encode %{ 5385 __ movdbl($mem$$Address, $src$$XMMRegister); 5386 %} 5387 ins_pipe(pipe_slow); // XXX 5388 %} 5389 5390 // Store immediate double 0.0 (it is faster than store from XMM register) 5391 instruct storeD0_imm(memory mem, immD0 src) 5392 %{ 5393 predicate(!UseCompressedOops || (CompressedOops::base() != nullptr)); 5394 match(Set mem (StoreD mem src)); 5395 5396 ins_cost(50); 5397 format %{ "movq $mem, $src\t# double 0." %} 5398 ins_encode %{ 5399 __ movq($mem$$Address, $src$$constant); 5400 %} 5401 ins_pipe(ialu_mem_imm); 5402 %} 5403 5404 instruct storeD0(memory mem, immD0 zero) 5405 %{ 5406 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5407 match(Set mem (StoreD mem zero)); 5408 5409 ins_cost(25); // XXX 5410 format %{ "movq $mem, R12\t# double 0. (R12_heapbase==0)" %} 5411 ins_encode %{ 5412 __ movq($mem$$Address, r12); 5413 %} 5414 ins_pipe(ialu_mem_reg); 5415 %} 5416 5417 instruct storeSSI(stackSlotI dst, rRegI src) 5418 %{ 5419 match(Set dst src); 5420 5421 ins_cost(100); 5422 format %{ "movl $dst, $src\t# int stk" %} 5423 ins_encode %{ 5424 __ movl($dst$$Address, $src$$Register); 5425 %} 5426 ins_pipe( ialu_mem_reg ); 5427 %} 5428 5429 instruct storeSSL(stackSlotL dst, rRegL src) 5430 %{ 5431 match(Set dst src); 5432 5433 ins_cost(100); 5434 format %{ "movq $dst, $src\t# long stk" %} 5435 ins_encode %{ 5436 __ movq($dst$$Address, $src$$Register); 5437 %} 5438 ins_pipe(ialu_mem_reg); 5439 %} 5440 5441 instruct storeSSP(stackSlotP dst, rRegP src) 5442 %{ 5443 match(Set dst src); 5444 5445 ins_cost(100); 5446 format %{ "movq $dst, $src\t# ptr stk" %} 5447 ins_encode %{ 5448 __ movq($dst$$Address, $src$$Register); 5449 %} 5450 ins_pipe(ialu_mem_reg); 5451 %} 5452 5453 instruct storeSSF(stackSlotF dst, regF src) 5454 %{ 5455 match(Set dst src); 5456 5457 ins_cost(95); // XXX 5458 format %{ "movss $dst, $src\t# float stk" %} 5459 ins_encode %{ 5460 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 5461 %} 5462 ins_pipe(pipe_slow); // XXX 5463 %} 5464 5465 instruct storeSSD(stackSlotD dst, regD src) 5466 %{ 5467 match(Set dst src); 5468 5469 ins_cost(95); // XXX 5470 format %{ "movsd $dst, $src\t# double stk" %} 5471 ins_encode %{ 5472 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 5473 %} 5474 ins_pipe(pipe_slow); // XXX 5475 %} 5476 5477 instruct cacheWB(indirect addr) 5478 %{ 5479 predicate(VM_Version::supports_data_cache_line_flush()); 5480 match(CacheWB addr); 5481 5482 ins_cost(100); 5483 format %{"cache wb $addr" %} 5484 ins_encode %{ 5485 assert($addr->index_position() < 0, "should be"); 5486 assert($addr$$disp == 0, "should be"); 5487 __ cache_wb(Address($addr$$base$$Register, 0)); 5488 %} 5489 ins_pipe(pipe_slow); // XXX 5490 %} 5491 5492 instruct cacheWBPreSync() 5493 %{ 5494 predicate(VM_Version::supports_data_cache_line_flush()); 5495 match(CacheWBPreSync); 5496 5497 ins_cost(100); 5498 format %{"cache wb presync" %} 5499 ins_encode %{ 5500 __ cache_wbsync(true); 5501 %} 5502 ins_pipe(pipe_slow); // XXX 5503 %} 5504 5505 instruct cacheWBPostSync() 5506 %{ 5507 predicate(VM_Version::supports_data_cache_line_flush()); 5508 match(CacheWBPostSync); 5509 5510 ins_cost(100); 5511 format %{"cache wb postsync" %} 5512 ins_encode %{ 5513 __ cache_wbsync(false); 5514 %} 5515 ins_pipe(pipe_slow); // XXX 5516 %} 5517 5518 //----------BSWAP Instructions------------------------------------------------- 5519 instruct bytes_reverse_int(rRegI dst) %{ 5520 match(Set dst (ReverseBytesI dst)); 5521 5522 format %{ "bswapl $dst" %} 5523 ins_encode %{ 5524 __ bswapl($dst$$Register); 5525 %} 5526 ins_pipe( ialu_reg ); 5527 %} 5528 5529 instruct bytes_reverse_long(rRegL dst) %{ 5530 match(Set dst (ReverseBytesL dst)); 5531 5532 format %{ "bswapq $dst" %} 5533 ins_encode %{ 5534 __ bswapq($dst$$Register); 5535 %} 5536 ins_pipe( ialu_reg); 5537 %} 5538 5539 instruct bytes_reverse_unsigned_short(rRegI dst, rFlagsReg cr) %{ 5540 match(Set dst (ReverseBytesUS dst)); 5541 effect(KILL cr); 5542 5543 format %{ "bswapl $dst\n\t" 5544 "shrl $dst,16\n\t" %} 5545 ins_encode %{ 5546 __ bswapl($dst$$Register); 5547 __ shrl($dst$$Register, 16); 5548 %} 5549 ins_pipe( ialu_reg ); 5550 %} 5551 5552 instruct bytes_reverse_short(rRegI dst, rFlagsReg cr) %{ 5553 match(Set dst (ReverseBytesS dst)); 5554 effect(KILL cr); 5555 5556 format %{ "bswapl $dst\n\t" 5557 "sar $dst,16\n\t" %} 5558 ins_encode %{ 5559 __ bswapl($dst$$Register); 5560 __ sarl($dst$$Register, 16); 5561 %} 5562 ins_pipe( ialu_reg ); 5563 %} 5564 5565 //---------- Zeros Count Instructions ------------------------------------------ 5566 5567 instruct countLeadingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 5568 predicate(UseCountLeadingZerosInstruction); 5569 match(Set dst (CountLeadingZerosI src)); 5570 effect(KILL cr); 5571 5572 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 5573 ins_encode %{ 5574 __ lzcntl($dst$$Register, $src$$Register); 5575 %} 5576 ins_pipe(ialu_reg); 5577 %} 5578 5579 instruct countLeadingZerosI_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5580 predicate(UseCountLeadingZerosInstruction); 5581 match(Set dst (CountLeadingZerosI (LoadI src))); 5582 effect(KILL cr); 5583 ins_cost(175); 5584 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 5585 ins_encode %{ 5586 __ lzcntl($dst$$Register, $src$$Address); 5587 %} 5588 ins_pipe(ialu_reg_mem); 5589 %} 5590 5591 instruct countLeadingZerosI_bsr(rRegI dst, rRegI src, rFlagsReg cr) %{ 5592 predicate(!UseCountLeadingZerosInstruction); 5593 match(Set dst (CountLeadingZerosI src)); 5594 effect(KILL cr); 5595 5596 format %{ "bsrl $dst, $src\t# count leading zeros (int)\n\t" 5597 "jnz skip\n\t" 5598 "movl $dst, -1\n" 5599 "skip:\n\t" 5600 "negl $dst\n\t" 5601 "addl $dst, 31" %} 5602 ins_encode %{ 5603 Register Rdst = $dst$$Register; 5604 Register Rsrc = $src$$Register; 5605 Label skip; 5606 __ bsrl(Rdst, Rsrc); 5607 __ jccb(Assembler::notZero, skip); 5608 __ movl(Rdst, -1); 5609 __ bind(skip); 5610 __ negl(Rdst); 5611 __ addl(Rdst, BitsPerInt - 1); 5612 %} 5613 ins_pipe(ialu_reg); 5614 %} 5615 5616 instruct countLeadingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 5617 predicate(UseCountLeadingZerosInstruction); 5618 match(Set dst (CountLeadingZerosL src)); 5619 effect(KILL cr); 5620 5621 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 5622 ins_encode %{ 5623 __ lzcntq($dst$$Register, $src$$Register); 5624 %} 5625 ins_pipe(ialu_reg); 5626 %} 5627 5628 instruct countLeadingZerosL_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5629 predicate(UseCountLeadingZerosInstruction); 5630 match(Set dst (CountLeadingZerosL (LoadL src))); 5631 effect(KILL cr); 5632 ins_cost(175); 5633 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 5634 ins_encode %{ 5635 __ lzcntq($dst$$Register, $src$$Address); 5636 %} 5637 ins_pipe(ialu_reg_mem); 5638 %} 5639 5640 instruct countLeadingZerosL_bsr(rRegI dst, rRegL src, rFlagsReg cr) %{ 5641 predicate(!UseCountLeadingZerosInstruction); 5642 match(Set dst (CountLeadingZerosL src)); 5643 effect(KILL cr); 5644 5645 format %{ "bsrq $dst, $src\t# count leading zeros (long)\n\t" 5646 "jnz skip\n\t" 5647 "movl $dst, -1\n" 5648 "skip:\n\t" 5649 "negl $dst\n\t" 5650 "addl $dst, 63" %} 5651 ins_encode %{ 5652 Register Rdst = $dst$$Register; 5653 Register Rsrc = $src$$Register; 5654 Label skip; 5655 __ bsrq(Rdst, Rsrc); 5656 __ jccb(Assembler::notZero, skip); 5657 __ movl(Rdst, -1); 5658 __ bind(skip); 5659 __ negl(Rdst); 5660 __ addl(Rdst, BitsPerLong - 1); 5661 %} 5662 ins_pipe(ialu_reg); 5663 %} 5664 5665 instruct countTrailingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 5666 predicate(UseCountTrailingZerosInstruction); 5667 match(Set dst (CountTrailingZerosI src)); 5668 effect(KILL cr); 5669 5670 format %{ "tzcntl $dst, $src\t# count trailing zeros (int)" %} 5671 ins_encode %{ 5672 __ tzcntl($dst$$Register, $src$$Register); 5673 %} 5674 ins_pipe(ialu_reg); 5675 %} 5676 5677 instruct countTrailingZerosI_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5678 predicate(UseCountTrailingZerosInstruction); 5679 match(Set dst (CountTrailingZerosI (LoadI src))); 5680 effect(KILL cr); 5681 ins_cost(175); 5682 format %{ "tzcntl $dst, $src\t# count trailing zeros (int)" %} 5683 ins_encode %{ 5684 __ tzcntl($dst$$Register, $src$$Address); 5685 %} 5686 ins_pipe(ialu_reg_mem); 5687 %} 5688 5689 instruct countTrailingZerosI_bsf(rRegI dst, rRegI src, rFlagsReg cr) %{ 5690 predicate(!UseCountTrailingZerosInstruction); 5691 match(Set dst (CountTrailingZerosI src)); 5692 effect(KILL cr); 5693 5694 format %{ "bsfl $dst, $src\t# count trailing zeros (int)\n\t" 5695 "jnz done\n\t" 5696 "movl $dst, 32\n" 5697 "done:" %} 5698 ins_encode %{ 5699 Register Rdst = $dst$$Register; 5700 Label done; 5701 __ bsfl(Rdst, $src$$Register); 5702 __ jccb(Assembler::notZero, done); 5703 __ movl(Rdst, BitsPerInt); 5704 __ bind(done); 5705 %} 5706 ins_pipe(ialu_reg); 5707 %} 5708 5709 instruct countTrailingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 5710 predicate(UseCountTrailingZerosInstruction); 5711 match(Set dst (CountTrailingZerosL src)); 5712 effect(KILL cr); 5713 5714 format %{ "tzcntq $dst, $src\t# count trailing zeros (long)" %} 5715 ins_encode %{ 5716 __ tzcntq($dst$$Register, $src$$Register); 5717 %} 5718 ins_pipe(ialu_reg); 5719 %} 5720 5721 instruct countTrailingZerosL_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5722 predicate(UseCountTrailingZerosInstruction); 5723 match(Set dst (CountTrailingZerosL (LoadL src))); 5724 effect(KILL cr); 5725 ins_cost(175); 5726 format %{ "tzcntq $dst, $src\t# count trailing zeros (long)" %} 5727 ins_encode %{ 5728 __ tzcntq($dst$$Register, $src$$Address); 5729 %} 5730 ins_pipe(ialu_reg_mem); 5731 %} 5732 5733 instruct countTrailingZerosL_bsf(rRegI dst, rRegL src, rFlagsReg cr) %{ 5734 predicate(!UseCountTrailingZerosInstruction); 5735 match(Set dst (CountTrailingZerosL src)); 5736 effect(KILL cr); 5737 5738 format %{ "bsfq $dst, $src\t# count trailing zeros (long)\n\t" 5739 "jnz done\n\t" 5740 "movl $dst, 64\n" 5741 "done:" %} 5742 ins_encode %{ 5743 Register Rdst = $dst$$Register; 5744 Label done; 5745 __ bsfq(Rdst, $src$$Register); 5746 __ jccb(Assembler::notZero, done); 5747 __ movl(Rdst, BitsPerLong); 5748 __ bind(done); 5749 %} 5750 ins_pipe(ialu_reg); 5751 %} 5752 5753 //--------------- Reverse Operation Instructions ---------------- 5754 instruct bytes_reversebit_int(rRegI dst, rRegI src, rRegI rtmp, rFlagsReg cr) %{ 5755 predicate(!VM_Version::supports_gfni()); 5756 match(Set dst (ReverseI src)); 5757 effect(TEMP dst, TEMP rtmp, KILL cr); 5758 format %{ "reverse_int $dst $src\t! using $rtmp as TEMP" %} 5759 ins_encode %{ 5760 __ reverseI($dst$$Register, $src$$Register, xnoreg, xnoreg, $rtmp$$Register); 5761 %} 5762 ins_pipe( ialu_reg ); 5763 %} 5764 5765 instruct bytes_reversebit_int_gfni(rRegI dst, rRegI src, vlRegF xtmp1, vlRegF xtmp2, rRegL rtmp, rFlagsReg cr) %{ 5766 predicate(VM_Version::supports_gfni()); 5767 match(Set dst (ReverseI src)); 5768 effect(TEMP dst, TEMP xtmp1, TEMP xtmp2, TEMP rtmp, KILL cr); 5769 format %{ "reverse_int $dst $src\t! using $rtmp, $xtmp1 and $xtmp2 as TEMP" %} 5770 ins_encode %{ 5771 __ reverseI($dst$$Register, $src$$Register, $xtmp1$$XMMRegister, $xtmp2$$XMMRegister, $rtmp$$Register); 5772 %} 5773 ins_pipe( ialu_reg ); 5774 %} 5775 5776 instruct bytes_reversebit_long(rRegL dst, rRegL src, rRegL rtmp1, rRegL rtmp2, rFlagsReg cr) %{ 5777 predicate(!VM_Version::supports_gfni()); 5778 match(Set dst (ReverseL src)); 5779 effect(TEMP dst, TEMP rtmp1, TEMP rtmp2, KILL cr); 5780 format %{ "reverse_long $dst $src\t! using $rtmp1 and $rtmp2 as TEMP" %} 5781 ins_encode %{ 5782 __ reverseL($dst$$Register, $src$$Register, xnoreg, xnoreg, $rtmp1$$Register, $rtmp2$$Register); 5783 %} 5784 ins_pipe( ialu_reg ); 5785 %} 5786 5787 instruct bytes_reversebit_long_gfni(rRegL dst, rRegL src, vlRegD xtmp1, vlRegD xtmp2, rRegL rtmp, rFlagsReg cr) %{ 5788 predicate(VM_Version::supports_gfni()); 5789 match(Set dst (ReverseL src)); 5790 effect(TEMP dst, TEMP xtmp1, TEMP xtmp2, TEMP rtmp, KILL cr); 5791 format %{ "reverse_long $dst $src\t! using $rtmp, $xtmp1 and $xtmp2 as TEMP" %} 5792 ins_encode %{ 5793 __ reverseL($dst$$Register, $src$$Register, $xtmp1$$XMMRegister, $xtmp2$$XMMRegister, $rtmp$$Register, noreg); 5794 %} 5795 ins_pipe( ialu_reg ); 5796 %} 5797 5798 //---------- Population Count Instructions ------------------------------------- 5799 5800 instruct popCountI(rRegI dst, rRegI src, rFlagsReg cr) %{ 5801 predicate(UsePopCountInstruction); 5802 match(Set dst (PopCountI src)); 5803 effect(KILL cr); 5804 5805 format %{ "popcnt $dst, $src" %} 5806 ins_encode %{ 5807 __ popcntl($dst$$Register, $src$$Register); 5808 %} 5809 ins_pipe(ialu_reg); 5810 %} 5811 5812 instruct popCountI_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 5813 predicate(UsePopCountInstruction); 5814 match(Set dst (PopCountI (LoadI mem))); 5815 effect(KILL cr); 5816 5817 format %{ "popcnt $dst, $mem" %} 5818 ins_encode %{ 5819 __ popcntl($dst$$Register, $mem$$Address); 5820 %} 5821 ins_pipe(ialu_reg); 5822 %} 5823 5824 // Note: Long.bitCount(long) returns an int. 5825 instruct popCountL(rRegI dst, rRegL src, rFlagsReg cr) %{ 5826 predicate(UsePopCountInstruction); 5827 match(Set dst (PopCountL src)); 5828 effect(KILL cr); 5829 5830 format %{ "popcnt $dst, $src" %} 5831 ins_encode %{ 5832 __ popcntq($dst$$Register, $src$$Register); 5833 %} 5834 ins_pipe(ialu_reg); 5835 %} 5836 5837 // Note: Long.bitCount(long) returns an int. 5838 instruct popCountL_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 5839 predicate(UsePopCountInstruction); 5840 match(Set dst (PopCountL (LoadL mem))); 5841 effect(KILL cr); 5842 5843 format %{ "popcnt $dst, $mem" %} 5844 ins_encode %{ 5845 __ popcntq($dst$$Register, $mem$$Address); 5846 %} 5847 ins_pipe(ialu_reg); 5848 %} 5849 5850 5851 //----------MemBar Instructions----------------------------------------------- 5852 // Memory barrier flavors 5853 5854 instruct membar_acquire() 5855 %{ 5856 match(MemBarAcquire); 5857 match(LoadFence); 5858 ins_cost(0); 5859 5860 size(0); 5861 format %{ "MEMBAR-acquire ! (empty encoding)" %} 5862 ins_encode(); 5863 ins_pipe(empty); 5864 %} 5865 5866 instruct membar_acquire_lock() 5867 %{ 5868 match(MemBarAcquireLock); 5869 ins_cost(0); 5870 5871 size(0); 5872 format %{ "MEMBAR-acquire (prior CMPXCHG in FastLock so empty encoding)" %} 5873 ins_encode(); 5874 ins_pipe(empty); 5875 %} 5876 5877 instruct membar_release() 5878 %{ 5879 match(MemBarRelease); 5880 match(StoreFence); 5881 ins_cost(0); 5882 5883 size(0); 5884 format %{ "MEMBAR-release ! (empty encoding)" %} 5885 ins_encode(); 5886 ins_pipe(empty); 5887 %} 5888 5889 instruct membar_release_lock() 5890 %{ 5891 match(MemBarReleaseLock); 5892 ins_cost(0); 5893 5894 size(0); 5895 format %{ "MEMBAR-release (a FastUnlock follows so empty encoding)" %} 5896 ins_encode(); 5897 ins_pipe(empty); 5898 %} 5899 5900 instruct membar_volatile(rFlagsReg cr) %{ 5901 match(MemBarVolatile); 5902 effect(KILL cr); 5903 ins_cost(400); 5904 5905 format %{ 5906 $$template 5907 $$emit$$"lock addl [rsp + #0], 0\t! membar_volatile" 5908 %} 5909 ins_encode %{ 5910 __ membar(Assembler::StoreLoad); 5911 %} 5912 ins_pipe(pipe_slow); 5913 %} 5914 5915 instruct unnecessary_membar_volatile() 5916 %{ 5917 match(MemBarVolatile); 5918 predicate(Matcher::post_store_load_barrier(n)); 5919 ins_cost(0); 5920 5921 size(0); 5922 format %{ "MEMBAR-volatile (unnecessary so empty encoding)" %} 5923 ins_encode(); 5924 ins_pipe(empty); 5925 %} 5926 5927 instruct membar_storestore() %{ 5928 match(MemBarStoreStore); 5929 match(StoreStoreFence); 5930 ins_cost(0); 5931 5932 size(0); 5933 format %{ "MEMBAR-storestore (empty encoding)" %} 5934 ins_encode( ); 5935 ins_pipe(empty); 5936 %} 5937 5938 //----------Move Instructions-------------------------------------------------- 5939 5940 instruct castX2P(rRegP dst, rRegL src) 5941 %{ 5942 match(Set dst (CastX2P src)); 5943 5944 format %{ "movq $dst, $src\t# long->ptr" %} 5945 ins_encode %{ 5946 if ($dst$$reg != $src$$reg) { 5947 __ movptr($dst$$Register, $src$$Register); 5948 } 5949 %} 5950 ins_pipe(ialu_reg_reg); // XXX 5951 %} 5952 5953 instruct castP2X(rRegL dst, rRegP src) 5954 %{ 5955 match(Set dst (CastP2X src)); 5956 5957 format %{ "movq $dst, $src\t# ptr -> long" %} 5958 ins_encode %{ 5959 if ($dst$$reg != $src$$reg) { 5960 __ movptr($dst$$Register, $src$$Register); 5961 } 5962 %} 5963 ins_pipe(ialu_reg_reg); // XXX 5964 %} 5965 5966 // Convert oop into int for vectors alignment masking 5967 instruct convP2I(rRegI dst, rRegP src) 5968 %{ 5969 match(Set dst (ConvL2I (CastP2X src))); 5970 5971 format %{ "movl $dst, $src\t# ptr -> int" %} 5972 ins_encode %{ 5973 __ movl($dst$$Register, $src$$Register); 5974 %} 5975 ins_pipe(ialu_reg_reg); // XXX 5976 %} 5977 5978 // Convert compressed oop into int for vectors alignment masking 5979 // in case of 32bit oops (heap < 4Gb). 5980 instruct convN2I(rRegI dst, rRegN src) 5981 %{ 5982 predicate(CompressedOops::shift() == 0); 5983 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 5984 5985 format %{ "movl $dst, $src\t# compressed ptr -> int" %} 5986 ins_encode %{ 5987 __ movl($dst$$Register, $src$$Register); 5988 %} 5989 ins_pipe(ialu_reg_reg); // XXX 5990 %} 5991 5992 // Convert oop pointer into compressed form 5993 instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{ 5994 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 5995 match(Set dst (EncodeP src)); 5996 effect(KILL cr); 5997 format %{ "encode_heap_oop $dst,$src" %} 5998 ins_encode %{ 5999 Register s = $src$$Register; 6000 Register d = $dst$$Register; 6001 if (s != d) { 6002 __ movq(d, s); 6003 } 6004 __ encode_heap_oop(d); 6005 %} 6006 ins_pipe(ialu_reg_long); 6007 %} 6008 6009 instruct encodeHeapOop_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6010 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 6011 match(Set dst (EncodeP src)); 6012 effect(KILL cr); 6013 format %{ "encode_heap_oop_not_null $dst,$src" %} 6014 ins_encode %{ 6015 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 6016 %} 6017 ins_pipe(ialu_reg_long); 6018 %} 6019 6020 instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{ 6021 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 6022 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 6023 match(Set dst (DecodeN src)); 6024 effect(KILL cr); 6025 format %{ "decode_heap_oop $dst,$src" %} 6026 ins_encode %{ 6027 Register s = $src$$Register; 6028 Register d = $dst$$Register; 6029 if (s != d) { 6030 __ movq(d, s); 6031 } 6032 __ decode_heap_oop(d); 6033 %} 6034 ins_pipe(ialu_reg_long); 6035 %} 6036 6037 instruct decodeHeapOop_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6038 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 6039 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 6040 match(Set dst (DecodeN src)); 6041 effect(KILL cr); 6042 format %{ "decode_heap_oop_not_null $dst,$src" %} 6043 ins_encode %{ 6044 Register s = $src$$Register; 6045 Register d = $dst$$Register; 6046 if (s != d) { 6047 __ decode_heap_oop_not_null(d, s); 6048 } else { 6049 __ decode_heap_oop_not_null(d); 6050 } 6051 %} 6052 ins_pipe(ialu_reg_long); 6053 %} 6054 6055 instruct encodeKlass_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6056 match(Set dst (EncodePKlass src)); 6057 effect(TEMP dst, KILL cr); 6058 format %{ "encode_and_move_klass_not_null $dst,$src" %} 6059 ins_encode %{ 6060 __ encode_and_move_klass_not_null($dst$$Register, $src$$Register); 6061 %} 6062 ins_pipe(ialu_reg_long); 6063 %} 6064 6065 instruct decodeKlass_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6066 match(Set dst (DecodeNKlass src)); 6067 effect(TEMP dst, KILL cr); 6068 format %{ "decode_and_move_klass_not_null $dst,$src" %} 6069 ins_encode %{ 6070 __ decode_and_move_klass_not_null($dst$$Register, $src$$Register); 6071 %} 6072 ins_pipe(ialu_reg_long); 6073 %} 6074 6075 //----------Conditional Move--------------------------------------------------- 6076 // Jump 6077 // dummy instruction for generating temp registers 6078 instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{ 6079 match(Jump (LShiftL switch_val shift)); 6080 ins_cost(350); 6081 predicate(false); 6082 effect(TEMP dest); 6083 6084 format %{ "leaq $dest, [$constantaddress]\n\t" 6085 "jmp [$dest + $switch_val << $shift]\n\t" %} 6086 ins_encode %{ 6087 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6088 // to do that and the compiler is using that register as one it can allocate. 6089 // So we build it all by hand. 6090 // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant); 6091 // ArrayAddress dispatch(table, index); 6092 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant); 6093 __ lea($dest$$Register, $constantaddress); 6094 __ jmp(dispatch); 6095 %} 6096 ins_pipe(pipe_jmp); 6097 %} 6098 6099 instruct jumpXtnd_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{ 6100 match(Jump (AddL (LShiftL switch_val shift) offset)); 6101 ins_cost(350); 6102 effect(TEMP dest); 6103 6104 format %{ "leaq $dest, [$constantaddress]\n\t" 6105 "jmp [$dest + $switch_val << $shift + $offset]\n\t" %} 6106 ins_encode %{ 6107 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6108 // to do that and the compiler is using that register as one it can allocate. 6109 // So we build it all by hand. 6110 // Address index(noreg, switch_reg, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6111 // ArrayAddress dispatch(table, index); 6112 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6113 __ lea($dest$$Register, $constantaddress); 6114 __ jmp(dispatch); 6115 %} 6116 ins_pipe(pipe_jmp); 6117 %} 6118 6119 instruct jumpXtnd(rRegL switch_val, rRegI dest) %{ 6120 match(Jump switch_val); 6121 ins_cost(350); 6122 effect(TEMP dest); 6123 6124 format %{ "leaq $dest, [$constantaddress]\n\t" 6125 "jmp [$dest + $switch_val]\n\t" %} 6126 ins_encode %{ 6127 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6128 // to do that and the compiler is using that register as one it can allocate. 6129 // So we build it all by hand. 6130 // Address index(noreg, switch_reg, Address::times_1); 6131 // ArrayAddress dispatch(table, index); 6132 Address dispatch($dest$$Register, $switch_val$$Register, Address::times_1); 6133 __ lea($dest$$Register, $constantaddress); 6134 __ jmp(dispatch); 6135 %} 6136 ins_pipe(pipe_jmp); 6137 %} 6138 6139 // Conditional move 6140 instruct cmovI_imm_01(rRegI dst, immI_1 src, rFlagsReg cr, cmpOp cop) 6141 %{ 6142 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_int() == 0); 6143 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6144 6145 ins_cost(100); // XXX 6146 format %{ "setbn$cop $dst\t# signed, int" %} 6147 ins_encode %{ 6148 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6149 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6150 %} 6151 ins_pipe(ialu_reg); 6152 %} 6153 6154 instruct cmovI_reg(rRegI dst, rRegI src, rFlagsReg cr, cmpOp cop) 6155 %{ 6156 predicate(!UseAPX); 6157 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6158 6159 ins_cost(200); // XXX 6160 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6161 ins_encode %{ 6162 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6163 %} 6164 ins_pipe(pipe_cmov_reg); 6165 %} 6166 6167 instruct cmovI_reg_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr, cmpOp cop) 6168 %{ 6169 predicate(UseAPX); 6170 match(Set dst (CMoveI (Binary cop cr) (Binary src1 src2))); 6171 6172 ins_cost(200); 6173 format %{ "ecmovl$cop $dst, $src1, $src2\t# signed, int ndd" %} 6174 ins_encode %{ 6175 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6176 %} 6177 ins_pipe(pipe_cmov_reg); 6178 %} 6179 6180 instruct cmovI_imm_01U(rRegI dst, immI_1 src, rFlagsRegU cr, cmpOpU cop) 6181 %{ 6182 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_int() == 0); 6183 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6184 6185 ins_cost(100); // XXX 6186 format %{ "setbn$cop $dst\t# unsigned, int" %} 6187 ins_encode %{ 6188 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6189 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6190 %} 6191 ins_pipe(ialu_reg); 6192 %} 6193 6194 instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{ 6195 predicate(!UseAPX); 6196 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6197 6198 ins_cost(200); // XXX 6199 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6200 ins_encode %{ 6201 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6202 %} 6203 ins_pipe(pipe_cmov_reg); 6204 %} 6205 6206 instruct cmovI_regU_ndd(rRegI dst, cmpOpU cop, rFlagsRegU cr, rRegI src1, rRegI src2) %{ 6207 predicate(UseAPX); 6208 match(Set dst (CMoveI (Binary cop cr) (Binary src1 src2))); 6209 6210 ins_cost(200); 6211 format %{ "ecmovl$cop $dst, $src1, $src2\t# unsigned, int ndd" %} 6212 ins_encode %{ 6213 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6214 %} 6215 ins_pipe(pipe_cmov_reg); 6216 %} 6217 6218 instruct cmovI_imm_01UCF(rRegI dst, immI_1 src, rFlagsRegUCF cr, cmpOpUCF cop) 6219 %{ 6220 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_int() == 0); 6221 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6222 6223 ins_cost(100); // XXX 6224 format %{ "setbn$cop $dst\t# unsigned, int" %} 6225 ins_encode %{ 6226 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6227 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6228 %} 6229 ins_pipe(ialu_reg); 6230 %} 6231 6232 instruct cmovI_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6233 predicate(!UseAPX); 6234 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6235 ins_cost(200); 6236 expand %{ 6237 cmovI_regU(cop, cr, dst, src); 6238 %} 6239 %} 6240 6241 instruct cmovI_regUCF_ndd(rRegI dst, cmpOpUCF cop, rFlagsRegUCF cr, rRegI src1, rRegI src2) %{ 6242 predicate(UseAPX); 6243 match(Set dst (CMoveI (Binary cop cr) (Binary src1 src2))); 6244 ins_cost(200); 6245 format %{ "ecmovl$cop $dst, $src1, $src2\t# unsigned, int ndd" %} 6246 ins_encode %{ 6247 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6248 %} 6249 ins_pipe(pipe_cmov_reg); 6250 %} 6251 6252 instruct cmovI_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6253 predicate(!UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6254 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6255 6256 ins_cost(200); // XXX 6257 format %{ "cmovpl $dst, $src\n\t" 6258 "cmovnel $dst, $src" %} 6259 ins_encode %{ 6260 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6261 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6262 %} 6263 ins_pipe(pipe_cmov_reg); 6264 %} 6265 6266 instruct cmovI_regUCF2_ne_ndd(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegI dst, rRegI src1, rRegI src2) %{ 6267 predicate(UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6268 match(Set dst (CMoveI (Binary cop cr) (Binary src1 src2))); 6269 effect(TEMP dst); 6270 6271 ins_cost(200); 6272 format %{ "ecmovpl $dst, $src1, $src2\n\t" 6273 "cmovnel $dst, $src2" %} 6274 ins_encode %{ 6275 __ ecmovl(Assembler::parity, $dst$$Register, $src1$$Register, $src2$$Register); 6276 __ cmovl(Assembler::notEqual, $dst$$Register, $src2$$Register); 6277 %} 6278 ins_pipe(pipe_cmov_reg); 6279 %} 6280 6281 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6282 // inputs of the CMove 6283 instruct cmovI_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6284 predicate(!UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6285 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6286 effect(TEMP dst); 6287 6288 ins_cost(200); // XXX 6289 format %{ "cmovpl $dst, $src\n\t" 6290 "cmovnel $dst, $src" %} 6291 ins_encode %{ 6292 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6293 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6294 %} 6295 ins_pipe(pipe_cmov_reg); 6296 %} 6297 6298 // We need this special handling for only eq / neq comparison since NaN == NaN is false, 6299 // and parity flag bit is set if any of the operand is a NaN. 6300 instruct cmovI_regUCF2_eq_ndd(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegI dst, rRegI src1, rRegI src2) %{ 6301 predicate(UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6302 match(Set dst (CMoveI (Binary cop cr) (Binary src2 src1))); 6303 effect(TEMP dst); 6304 6305 ins_cost(200); 6306 format %{ "ecmovpl $dst, $src1, $src2\n\t" 6307 "cmovnel $dst, $src2" %} 6308 ins_encode %{ 6309 __ ecmovl(Assembler::parity, $dst$$Register, $src1$$Register, $src2$$Register); 6310 __ cmovl(Assembler::notEqual, $dst$$Register, $src2$$Register); 6311 %} 6312 ins_pipe(pipe_cmov_reg); 6313 %} 6314 6315 // Conditional move 6316 instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{ 6317 predicate(!UseAPX); 6318 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6319 6320 ins_cost(250); // XXX 6321 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6322 ins_encode %{ 6323 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6324 %} 6325 ins_pipe(pipe_cmov_mem); 6326 %} 6327 6328 // Conditional move 6329 instruct cmovI_rReg_rReg_mem_ndd(rRegI dst, cmpOp cop, rFlagsReg cr, rRegI src1, memory src2) 6330 %{ 6331 predicate(UseAPX); 6332 match(Set dst (CMoveI (Binary cop cr) (Binary src1 (LoadI src2)))); 6333 6334 ins_cost(250); 6335 format %{ "ecmovl$cop $dst, $src1, $src2\t# signed, int ndd" %} 6336 ins_encode %{ 6337 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Address); 6338 %} 6339 ins_pipe(pipe_cmov_mem); 6340 %} 6341 6342 // Conditional move 6343 instruct cmovI_memU(cmpOpU cop, rFlagsRegU cr, rRegI dst, memory src) 6344 %{ 6345 predicate(!UseAPX); 6346 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6347 6348 ins_cost(250); // XXX 6349 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6350 ins_encode %{ 6351 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6352 %} 6353 ins_pipe(pipe_cmov_mem); 6354 %} 6355 6356 instruct cmovI_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, memory src) %{ 6357 predicate(!UseAPX); 6358 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6359 ins_cost(250); 6360 expand %{ 6361 cmovI_memU(cop, cr, dst, src); 6362 %} 6363 %} 6364 6365 instruct cmovI_rReg_rReg_memU_ndd(rRegI dst, cmpOpU cop, rFlagsRegU cr, rRegI src1, memory src2) 6366 %{ 6367 predicate(UseAPX); 6368 match(Set dst (CMoveI (Binary cop cr) (Binary src1 (LoadI src2)))); 6369 6370 ins_cost(250); 6371 format %{ "ecmovl$cop $dst, $src1, $src2\t# unsigned, int ndd" %} 6372 ins_encode %{ 6373 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Address); 6374 %} 6375 ins_pipe(pipe_cmov_mem); 6376 %} 6377 6378 instruct cmovI_rReg_rReg_memUCF_ndd(rRegI dst, cmpOpUCF cop, rFlagsRegUCF cr, rRegI src1, memory src2) 6379 %{ 6380 predicate(UseAPX); 6381 match(Set dst (CMoveI (Binary cop cr) (Binary src1 (LoadI src2)))); 6382 ins_cost(250); 6383 format %{ "ecmovl$cop $dst, $src1, $src2\t# unsigned, int ndd" %} 6384 ins_encode %{ 6385 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Address); 6386 %} 6387 ins_pipe(pipe_cmov_mem); 6388 %} 6389 6390 // Conditional move 6391 instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop) 6392 %{ 6393 predicate(!UseAPX); 6394 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6395 6396 ins_cost(200); // XXX 6397 format %{ "cmovl$cop $dst, $src\t# signed, compressed ptr" %} 6398 ins_encode %{ 6399 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6400 %} 6401 ins_pipe(pipe_cmov_reg); 6402 %} 6403 6404 // Conditional move ndd 6405 instruct cmovN_reg_ndd(rRegN dst, rRegN src1, rRegN src2, rFlagsReg cr, cmpOp cop) 6406 %{ 6407 predicate(UseAPX); 6408 match(Set dst (CMoveN (Binary cop cr) (Binary src1 src2))); 6409 6410 ins_cost(200); 6411 format %{ "ecmovl$cop $dst, $src1, $src2\t# signed, compressed ptr ndd" %} 6412 ins_encode %{ 6413 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6414 %} 6415 ins_pipe(pipe_cmov_reg); 6416 %} 6417 6418 // Conditional move 6419 instruct cmovN_regU(cmpOpU cop, rFlagsRegU cr, rRegN dst, rRegN src) 6420 %{ 6421 predicate(!UseAPX); 6422 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6423 6424 ins_cost(200); // XXX 6425 format %{ "cmovl$cop $dst, $src\t# unsigned, compressed ptr" %} 6426 ins_encode %{ 6427 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6428 %} 6429 ins_pipe(pipe_cmov_reg); 6430 %} 6431 6432 instruct cmovN_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6433 predicate(!UseAPX); 6434 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6435 ins_cost(200); 6436 expand %{ 6437 cmovN_regU(cop, cr, dst, src); 6438 %} 6439 %} 6440 6441 // Conditional move ndd 6442 instruct cmovN_regU_ndd(rRegN dst, cmpOpU cop, rFlagsRegU cr, rRegN src1, rRegN src2) 6443 %{ 6444 predicate(UseAPX); 6445 match(Set dst (CMoveN (Binary cop cr) (Binary src1 src2))); 6446 6447 ins_cost(200); 6448 format %{ "ecmovl$cop $dst, $src1, $src2\t# unsigned, compressed ptr ndd" %} 6449 ins_encode %{ 6450 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6451 %} 6452 ins_pipe(pipe_cmov_reg); 6453 %} 6454 6455 instruct cmovN_regUCF_ndd(rRegN dst, cmpOpUCF cop, rFlagsRegUCF cr, rRegN src1, rRegN src2) %{ 6456 predicate(UseAPX); 6457 match(Set dst (CMoveN (Binary cop cr) (Binary src1 src2))); 6458 ins_cost(200); 6459 format %{ "ecmovl$cop $dst, $src1, $src2\t# unsigned, compressed ptr ndd" %} 6460 ins_encode %{ 6461 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6462 %} 6463 ins_pipe(pipe_cmov_reg); 6464 %} 6465 6466 instruct cmovN_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6467 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6468 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6469 6470 ins_cost(200); // XXX 6471 format %{ "cmovpl $dst, $src\n\t" 6472 "cmovnel $dst, $src" %} 6473 ins_encode %{ 6474 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6475 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6476 %} 6477 ins_pipe(pipe_cmov_reg); 6478 %} 6479 6480 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6481 // inputs of the CMove 6482 instruct cmovN_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6483 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6484 match(Set dst (CMoveN (Binary cop cr) (Binary src dst))); 6485 6486 ins_cost(200); // XXX 6487 format %{ "cmovpl $dst, $src\n\t" 6488 "cmovnel $dst, $src" %} 6489 ins_encode %{ 6490 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6491 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6492 %} 6493 ins_pipe(pipe_cmov_reg); 6494 %} 6495 6496 // Conditional move 6497 instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop) 6498 %{ 6499 predicate(!UseAPX); 6500 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6501 6502 ins_cost(200); // XXX 6503 format %{ "cmovq$cop $dst, $src\t# signed, ptr" %} 6504 ins_encode %{ 6505 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6506 %} 6507 ins_pipe(pipe_cmov_reg); // XXX 6508 %} 6509 6510 // Conditional move ndd 6511 instruct cmovP_reg_ndd(rRegP dst, rRegP src1, rRegP src2, rFlagsReg cr, cmpOp cop) 6512 %{ 6513 predicate(UseAPX); 6514 match(Set dst (CMoveP (Binary cop cr) (Binary src1 src2))); 6515 6516 ins_cost(200); 6517 format %{ "ecmovq$cop $dst, $src1, $src2\t# signed, ptr ndd" %} 6518 ins_encode %{ 6519 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6520 %} 6521 ins_pipe(pipe_cmov_reg); 6522 %} 6523 6524 // Conditional move 6525 instruct cmovP_regU(cmpOpU cop, rFlagsRegU cr, rRegP dst, rRegP src) 6526 %{ 6527 predicate(!UseAPX); 6528 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6529 6530 ins_cost(200); // XXX 6531 format %{ "cmovq$cop $dst, $src\t# unsigned, ptr" %} 6532 ins_encode %{ 6533 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6534 %} 6535 ins_pipe(pipe_cmov_reg); // XXX 6536 %} 6537 6538 // Conditional move ndd 6539 instruct cmovP_regU_ndd(rRegP dst, cmpOpU cop, rFlagsRegU cr, rRegP src1, rRegP src2) 6540 %{ 6541 predicate(UseAPX); 6542 match(Set dst (CMoveP (Binary cop cr) (Binary src1 src2))); 6543 6544 ins_cost(200); 6545 format %{ "ecmovq$cop $dst, $src1, $src2\t# unsigned, ptr ndd" %} 6546 ins_encode %{ 6547 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6548 %} 6549 ins_pipe(pipe_cmov_reg); 6550 %} 6551 6552 instruct cmovP_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6553 predicate(!UseAPX); 6554 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6555 ins_cost(200); 6556 expand %{ 6557 cmovP_regU(cop, cr, dst, src); 6558 %} 6559 %} 6560 6561 instruct cmovP_regUCF_ndd(rRegP dst, cmpOpUCF cop, rFlagsRegUCF cr, rRegP src1, rRegP src2) %{ 6562 predicate(UseAPX); 6563 match(Set dst (CMoveP (Binary cop cr) (Binary src1 src2))); 6564 ins_cost(200); 6565 format %{ "ecmovq$cop $dst, $src1, $src2\t# unsigned, ptr ndd" %} 6566 ins_encode %{ 6567 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6568 %} 6569 ins_pipe(pipe_cmov_reg); 6570 %} 6571 6572 instruct cmovP_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6573 predicate(!UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6574 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6575 6576 ins_cost(200); // XXX 6577 format %{ "cmovpq $dst, $src\n\t" 6578 "cmovneq $dst, $src" %} 6579 ins_encode %{ 6580 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6581 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6582 %} 6583 ins_pipe(pipe_cmov_reg); 6584 %} 6585 6586 instruct cmovP_regUCF2_ne_ndd(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegP dst, rRegP src1, rRegP src2) %{ 6587 predicate(UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6588 match(Set dst (CMoveP (Binary cop cr) (Binary src1 src2))); 6589 effect(TEMP dst); 6590 6591 ins_cost(200); 6592 format %{ "ecmovpq $dst, $src1, $src2\n\t" 6593 "cmovneq $dst, $src2" %} 6594 ins_encode %{ 6595 __ ecmovq(Assembler::parity, $dst$$Register, $src1$$Register, $src2$$Register); 6596 __ cmovq(Assembler::notEqual, $dst$$Register, $src2$$Register); 6597 %} 6598 ins_pipe(pipe_cmov_reg); 6599 %} 6600 6601 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6602 // inputs of the CMove 6603 instruct cmovP_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6604 predicate(!UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6605 match(Set dst (CMoveP (Binary cop cr) (Binary src dst))); 6606 6607 ins_cost(200); // XXX 6608 format %{ "cmovpq $dst, $src\n\t" 6609 "cmovneq $dst, $src" %} 6610 ins_encode %{ 6611 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6612 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6613 %} 6614 ins_pipe(pipe_cmov_reg); 6615 %} 6616 6617 instruct cmovP_regUCF2_eq_ndd(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegP dst, rRegP src1, rRegP src2) %{ 6618 predicate(UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6619 match(Set dst (CMoveP (Binary cop cr) (Binary src2 src1))); 6620 effect(TEMP dst); 6621 6622 ins_cost(200); 6623 format %{ "ecmovpq $dst, $src1, $src2\n\t" 6624 "cmovneq $dst, $src2" %} 6625 ins_encode %{ 6626 __ ecmovq(Assembler::parity, $dst$$Register, $src1$$Register, $src2$$Register); 6627 __ cmovq(Assembler::notEqual, $dst$$Register, $src2$$Register); 6628 %} 6629 ins_pipe(pipe_cmov_reg); 6630 %} 6631 6632 instruct cmovL_imm_01(rRegL dst, immL1 src, rFlagsReg cr, cmpOp cop) 6633 %{ 6634 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_long() == 0); 6635 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6636 6637 ins_cost(100); // XXX 6638 format %{ "setbn$cop $dst\t# signed, long" %} 6639 ins_encode %{ 6640 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6641 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6642 %} 6643 ins_pipe(ialu_reg); 6644 %} 6645 6646 instruct cmovL_reg(cmpOp cop, rFlagsReg cr, rRegL dst, rRegL src) 6647 %{ 6648 predicate(!UseAPX); 6649 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6650 6651 ins_cost(200); // XXX 6652 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6653 ins_encode %{ 6654 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6655 %} 6656 ins_pipe(pipe_cmov_reg); // XXX 6657 %} 6658 6659 instruct cmovL_reg_ndd(rRegL dst, cmpOp cop, rFlagsReg cr, rRegL src1, rRegL src2) 6660 %{ 6661 predicate(UseAPX); 6662 match(Set dst (CMoveL (Binary cop cr) (Binary src1 src2))); 6663 6664 ins_cost(200); 6665 format %{ "ecmovq$cop $dst, $src1, $src2\t# signed, long ndd" %} 6666 ins_encode %{ 6667 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6668 %} 6669 ins_pipe(pipe_cmov_reg); 6670 %} 6671 6672 instruct cmovL_mem(cmpOp cop, rFlagsReg cr, rRegL dst, memory src) 6673 %{ 6674 predicate(!UseAPX); 6675 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6676 6677 ins_cost(200); // XXX 6678 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6679 ins_encode %{ 6680 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6681 %} 6682 ins_pipe(pipe_cmov_mem); // XXX 6683 %} 6684 6685 instruct cmovL_rReg_rReg_mem_ndd(rRegL dst, cmpOp cop, rFlagsReg cr, rRegL src1, memory src2) 6686 %{ 6687 predicate(UseAPX); 6688 match(Set dst (CMoveL (Binary cop cr) (Binary src1 (LoadL src2)))); 6689 6690 ins_cost(200); 6691 format %{ "ecmovq$cop $dst, $src1, $src2\t# signed, long ndd" %} 6692 ins_encode %{ 6693 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Address); 6694 %} 6695 ins_pipe(pipe_cmov_mem); 6696 %} 6697 6698 instruct cmovL_imm_01U(rRegL dst, immL1 src, rFlagsRegU cr, cmpOpU cop) 6699 %{ 6700 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_long() == 0); 6701 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6702 6703 ins_cost(100); // XXX 6704 format %{ "setbn$cop $dst\t# unsigned, long" %} 6705 ins_encode %{ 6706 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6707 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6708 %} 6709 ins_pipe(ialu_reg); 6710 %} 6711 6712 instruct cmovL_regU(cmpOpU cop, rFlagsRegU cr, rRegL dst, rRegL src) 6713 %{ 6714 predicate(!UseAPX); 6715 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6716 6717 ins_cost(200); // XXX 6718 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 6719 ins_encode %{ 6720 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6721 %} 6722 ins_pipe(pipe_cmov_reg); // XXX 6723 %} 6724 6725 instruct cmovL_regU_ndd(rRegL dst, cmpOpU cop, rFlagsRegU cr, rRegL src1, rRegL src2) 6726 %{ 6727 predicate(UseAPX); 6728 match(Set dst (CMoveL (Binary cop cr) (Binary src1 src2))); 6729 6730 ins_cost(200); 6731 format %{ "ecmovq$cop $dst, $src1, $src2\t# unsigned, long ndd" %} 6732 ins_encode %{ 6733 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6734 %} 6735 ins_pipe(pipe_cmov_reg); 6736 %} 6737 6738 instruct cmovL_imm_01UCF(rRegL dst, immL1 src, rFlagsRegUCF cr, cmpOpUCF cop) 6739 %{ 6740 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_long() == 0); 6741 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6742 6743 ins_cost(100); // XXX 6744 format %{ "setbn$cop $dst\t# unsigned, long" %} 6745 ins_encode %{ 6746 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6747 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6748 %} 6749 ins_pipe(ialu_reg); 6750 %} 6751 6752 instruct cmovL_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6753 predicate(!UseAPX); 6754 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6755 ins_cost(200); 6756 expand %{ 6757 cmovL_regU(cop, cr, dst, src); 6758 %} 6759 %} 6760 6761 instruct cmovL_regUCF_ndd(rRegL dst, cmpOpUCF cop, rFlagsRegUCF cr, rRegL src1, rRegL src2) 6762 %{ 6763 predicate(UseAPX); 6764 match(Set dst (CMoveL (Binary cop cr) (Binary src1 src2))); 6765 ins_cost(200); 6766 format %{ "ecmovq$cop $dst, $src1, $src2\t# unsigned, long ndd" %} 6767 ins_encode %{ 6768 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6769 %} 6770 ins_pipe(pipe_cmov_reg); 6771 %} 6772 6773 instruct cmovL_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6774 predicate(!UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6775 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6776 6777 ins_cost(200); // XXX 6778 format %{ "cmovpq $dst, $src\n\t" 6779 "cmovneq $dst, $src" %} 6780 ins_encode %{ 6781 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6782 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6783 %} 6784 ins_pipe(pipe_cmov_reg); 6785 %} 6786 6787 instruct cmovL_regUCF2_ne_ndd(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegL dst, rRegL src1, rRegL src2) %{ 6788 predicate(UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6789 match(Set dst (CMoveL (Binary cop cr) (Binary src1 src2))); 6790 effect(TEMP dst); 6791 6792 ins_cost(200); 6793 format %{ "ecmovpq $dst, $src1, $src2\n\t" 6794 "cmovneq $dst, $src2" %} 6795 ins_encode %{ 6796 __ ecmovq(Assembler::parity, $dst$$Register, $src1$$Register, $src2$$Register); 6797 __ cmovq(Assembler::notEqual, $dst$$Register, $src2$$Register); 6798 %} 6799 ins_pipe(pipe_cmov_reg); 6800 %} 6801 6802 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6803 // inputs of the CMove 6804 instruct cmovL_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6805 predicate(!UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6806 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6807 6808 ins_cost(200); // XXX 6809 format %{ "cmovpq $dst, $src\n\t" 6810 "cmovneq $dst, $src" %} 6811 ins_encode %{ 6812 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6813 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6814 %} 6815 ins_pipe(pipe_cmov_reg); 6816 %} 6817 6818 instruct cmovL_regUCF2_eq_ndd(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegL dst, rRegL src1, rRegL src2) %{ 6819 predicate(UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6820 match(Set dst (CMoveL (Binary cop cr) (Binary src2 src1))); 6821 effect(TEMP dst); 6822 6823 ins_cost(200); 6824 format %{ "ecmovpq $dst, $src1, $src2\n\t" 6825 "cmovneq $dst, $src2" %} 6826 ins_encode %{ 6827 __ ecmovq(Assembler::parity, $dst$$Register, $src1$$Register, $src2$$Register); 6828 __ cmovq(Assembler::notEqual, $dst$$Register, $src2$$Register); 6829 %} 6830 ins_pipe(pipe_cmov_reg); 6831 %} 6832 6833 instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src) 6834 %{ 6835 predicate(!UseAPX); 6836 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6837 6838 ins_cost(200); // XXX 6839 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 6840 ins_encode %{ 6841 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6842 %} 6843 ins_pipe(pipe_cmov_mem); // XXX 6844 %} 6845 6846 instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{ 6847 predicate(!UseAPX); 6848 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6849 ins_cost(200); 6850 expand %{ 6851 cmovL_memU(cop, cr, dst, src); 6852 %} 6853 %} 6854 6855 instruct cmovL_rReg_rReg_memU_ndd(rRegL dst, cmpOpU cop, rFlagsRegU cr, rRegL src1, memory src2) 6856 %{ 6857 predicate(UseAPX); 6858 match(Set dst (CMoveL (Binary cop cr) (Binary src1 (LoadL src2)))); 6859 6860 ins_cost(200); 6861 format %{ "ecmovq$cop $dst, $src1, $src2\t# unsigned, long ndd" %} 6862 ins_encode %{ 6863 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Address); 6864 %} 6865 ins_pipe(pipe_cmov_mem); 6866 %} 6867 6868 instruct cmovL_rReg_rReg_memUCF_ndd(rRegL dst, cmpOpUCF cop, rFlagsRegUCF cr, rRegL src1, memory src2) 6869 %{ 6870 predicate(UseAPX); 6871 match(Set dst (CMoveL (Binary cop cr) (Binary src1 (LoadL src2)))); 6872 ins_cost(200); 6873 format %{ "ecmovq$cop $dst, $src1, $src2\t# unsigned, long ndd" %} 6874 ins_encode %{ 6875 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Address); 6876 %} 6877 ins_pipe(pipe_cmov_mem); 6878 %} 6879 6880 instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src) 6881 %{ 6882 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6883 6884 ins_cost(200); // XXX 6885 format %{ "jn$cop skip\t# signed cmove float\n\t" 6886 "movss $dst, $src\n" 6887 "skip:" %} 6888 ins_encode %{ 6889 Label Lskip; 6890 // Invert sense of branch from sense of CMOV 6891 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6892 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 6893 __ bind(Lskip); 6894 %} 6895 ins_pipe(pipe_slow); 6896 %} 6897 6898 instruct cmovF_regU(cmpOpU cop, rFlagsRegU cr, regF dst, regF src) 6899 %{ 6900 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6901 6902 ins_cost(200); // XXX 6903 format %{ "jn$cop skip\t# unsigned cmove float\n\t" 6904 "movss $dst, $src\n" 6905 "skip:" %} 6906 ins_encode %{ 6907 Label Lskip; 6908 // Invert sense of branch from sense of CMOV 6909 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6910 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 6911 __ bind(Lskip); 6912 %} 6913 ins_pipe(pipe_slow); 6914 %} 6915 6916 instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{ 6917 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6918 ins_cost(200); 6919 expand %{ 6920 cmovF_regU(cop, cr, dst, src); 6921 %} 6922 %} 6923 6924 instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src) 6925 %{ 6926 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6927 6928 ins_cost(200); // XXX 6929 format %{ "jn$cop skip\t# signed cmove double\n\t" 6930 "movsd $dst, $src\n" 6931 "skip:" %} 6932 ins_encode %{ 6933 Label Lskip; 6934 // Invert sense of branch from sense of CMOV 6935 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6936 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 6937 __ bind(Lskip); 6938 %} 6939 ins_pipe(pipe_slow); 6940 %} 6941 6942 instruct cmovD_regU(cmpOpU cop, rFlagsRegU cr, regD dst, regD src) 6943 %{ 6944 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6945 6946 ins_cost(200); // XXX 6947 format %{ "jn$cop skip\t# unsigned cmove double\n\t" 6948 "movsd $dst, $src\n" 6949 "skip:" %} 6950 ins_encode %{ 6951 Label Lskip; 6952 // Invert sense of branch from sense of CMOV 6953 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6954 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 6955 __ bind(Lskip); 6956 %} 6957 ins_pipe(pipe_slow); 6958 %} 6959 6960 instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{ 6961 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6962 ins_cost(200); 6963 expand %{ 6964 cmovD_regU(cop, cr, dst, src); 6965 %} 6966 %} 6967 6968 //----------Arithmetic Instructions-------------------------------------------- 6969 //----------Addition Instructions---------------------------------------------- 6970 6971 instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 6972 %{ 6973 predicate(!UseAPX); 6974 match(Set dst (AddI dst src)); 6975 effect(KILL cr); 6976 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); 6977 format %{ "addl $dst, $src\t# int" %} 6978 ins_encode %{ 6979 __ addl($dst$$Register, $src$$Register); 6980 %} 6981 ins_pipe(ialu_reg_reg); 6982 %} 6983 6984 instruct addI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr) 6985 %{ 6986 predicate(UseAPX); 6987 match(Set dst (AddI src1 src2)); 6988 effect(KILL cr); 6989 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); 6990 6991 format %{ "eaddl $dst, $src1, $src2\t# int ndd" %} 6992 ins_encode %{ 6993 __ eaddl($dst$$Register, $src1$$Register, $src2$$Register, false); 6994 %} 6995 ins_pipe(ialu_reg_reg); 6996 %} 6997 6998 instruct addI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 6999 %{ 7000 predicate(!UseAPX); 7001 match(Set dst (AddI dst src)); 7002 effect(KILL cr); 7003 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 7004 7005 format %{ "addl $dst, $src\t# int" %} 7006 ins_encode %{ 7007 __ addl($dst$$Register, $src$$constant); 7008 %} 7009 ins_pipe( ialu_reg ); 7010 %} 7011 7012 instruct addI_rReg_rReg_imm_ndd(rRegI dst, rRegI src1, immI src2, rFlagsReg cr) 7013 %{ 7014 predicate(UseAPX); 7015 match(Set dst (AddI src1 src2)); 7016 effect(KILL cr); 7017 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); 7018 7019 format %{ "eaddl $dst, $src1, $src2\t# int ndd" %} 7020 ins_encode %{ 7021 __ eaddl($dst$$Register, $src1$$Register, $src2$$constant, false); 7022 %} 7023 ins_pipe( ialu_reg ); 7024 %} 7025 7026 instruct addI_rReg_mem_imm_ndd(rRegI dst, memory src1, immI src2, rFlagsReg cr) 7027 %{ 7028 predicate(UseAPX); 7029 match(Set dst (AddI (LoadI src1) src2)); 7030 effect(KILL cr); 7031 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); 7032 7033 format %{ "eaddl $dst, $src1, $src2\t# int ndd" %} 7034 ins_encode %{ 7035 __ eaddl($dst$$Register, $src1$$Address, $src2$$constant, false); 7036 %} 7037 ins_pipe( ialu_reg ); 7038 %} 7039 7040 instruct addI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 7041 %{ 7042 predicate(!UseAPX); 7043 match(Set dst (AddI dst (LoadI src))); 7044 effect(KILL cr); 7045 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); 7046 7047 ins_cost(150); // XXX 7048 format %{ "addl $dst, $src\t# int" %} 7049 ins_encode %{ 7050 __ addl($dst$$Register, $src$$Address); 7051 %} 7052 ins_pipe(ialu_reg_mem); 7053 %} 7054 7055 instruct addI_rReg_mem_rReg_ndd(rRegI dst, memory src1, rRegI src2, rFlagsReg cr) 7056 %{ 7057 predicate(UseAPX); 7058 match(Set dst (AddI (LoadI 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 ins_cost(150); 7063 format %{ "eaddl $dst, $src1, $src2\t# int ndd" %} 7064 ins_encode %{ 7065 __ eaddl($dst$$Register, $src1$$Address, $src2$$Register, false); 7066 %} 7067 ins_pipe(ialu_reg_mem); 7068 %} 7069 7070 instruct addI_rReg_rReg_mem_ndd(rRegI dst, rRegI src1, memory src2, rFlagsReg cr) 7071 %{ 7072 predicate(UseAPX); 7073 match(Set dst (AddI src1 (LoadI src2))); 7074 effect(KILL cr); 7075 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 7076 7077 ins_cost(150); 7078 format %{ "eaddl $dst, $src1, $src2\t# int ndd" %} 7079 ins_encode %{ 7080 __ eaddl($dst$$Register, $src1$$Register, $src2$$Address, false); 7081 %} 7082 ins_pipe(ialu_reg_mem); 7083 %} 7084 7085 instruct addI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 7086 %{ 7087 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7088 effect(KILL cr); 7089 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); 7090 7091 ins_cost(150); // XXX 7092 format %{ "addl $dst, $src\t# int" %} 7093 ins_encode %{ 7094 __ addl($dst$$Address, $src$$Register); 7095 %} 7096 ins_pipe(ialu_mem_reg); 7097 %} 7098 7099 instruct addI_mem_imm(memory dst, immI src, rFlagsReg cr) 7100 %{ 7101 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 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 7106 ins_cost(125); // XXX 7107 format %{ "addl $dst, $src\t# int" %} 7108 ins_encode %{ 7109 __ addl($dst$$Address, $src$$constant); 7110 %} 7111 ins_pipe(ialu_mem_imm); 7112 %} 7113 7114 instruct incI_rReg(rRegI dst, immI_1 src, rFlagsReg cr) 7115 %{ 7116 predicate(!UseAPX && UseIncDec); 7117 match(Set dst (AddI dst src)); 7118 effect(KILL cr); 7119 7120 format %{ "incl $dst\t# int" %} 7121 ins_encode %{ 7122 __ incrementl($dst$$Register); 7123 %} 7124 ins_pipe(ialu_reg); 7125 %} 7126 7127 instruct incI_rReg_ndd(rRegI dst, rRegI src, immI_1 val, rFlagsReg cr) 7128 %{ 7129 predicate(UseAPX && UseIncDec); 7130 match(Set dst (AddI src val)); 7131 effect(KILL cr); 7132 7133 format %{ "eincl $dst, $src\t# int ndd" %} 7134 ins_encode %{ 7135 __ eincl($dst$$Register, $src$$Register, false); 7136 %} 7137 ins_pipe(ialu_reg); 7138 %} 7139 7140 instruct incI_rReg_mem_ndd(rRegI dst, memory src, immI_1 val, rFlagsReg cr) 7141 %{ 7142 predicate(UseAPX && UseIncDec); 7143 match(Set dst (AddI (LoadI src) val)); 7144 effect(KILL cr); 7145 7146 format %{ "eincl $dst, $src\t# int ndd" %} 7147 ins_encode %{ 7148 __ eincl($dst$$Register, $src$$Address, false); 7149 %} 7150 ins_pipe(ialu_reg); 7151 %} 7152 7153 instruct incI_mem(memory dst, immI_1 src, rFlagsReg cr) 7154 %{ 7155 predicate(UseIncDec); 7156 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7157 effect(KILL cr); 7158 7159 ins_cost(125); // XXX 7160 format %{ "incl $dst\t# int" %} 7161 ins_encode %{ 7162 __ incrementl($dst$$Address); 7163 %} 7164 ins_pipe(ialu_mem_imm); 7165 %} 7166 7167 // XXX why does that use AddI 7168 instruct decI_rReg(rRegI dst, immI_M1 src, rFlagsReg cr) 7169 %{ 7170 predicate(!UseAPX && UseIncDec); 7171 match(Set dst (AddI dst src)); 7172 effect(KILL cr); 7173 7174 format %{ "decl $dst\t# int" %} 7175 ins_encode %{ 7176 __ decrementl($dst$$Register); 7177 %} 7178 ins_pipe(ialu_reg); 7179 %} 7180 7181 instruct decI_rReg_ndd(rRegI dst, rRegI src, immI_M1 val, rFlagsReg cr) 7182 %{ 7183 predicate(UseAPX && UseIncDec); 7184 match(Set dst (AddI src val)); 7185 effect(KILL cr); 7186 7187 format %{ "edecl $dst, $src\t# int ndd" %} 7188 ins_encode %{ 7189 __ edecl($dst$$Register, $src$$Register, false); 7190 %} 7191 ins_pipe(ialu_reg); 7192 %} 7193 7194 instruct decI_rReg_mem_ndd(rRegI dst, memory src, immI_M1 val, rFlagsReg cr) 7195 %{ 7196 predicate(UseAPX && UseIncDec); 7197 match(Set dst (AddI (LoadI src) val)); 7198 effect(KILL cr); 7199 7200 format %{ "edecl $dst, $src\t# int ndd" %} 7201 ins_encode %{ 7202 __ edecl($dst$$Register, $src$$Address, false); 7203 %} 7204 ins_pipe(ialu_reg); 7205 %} 7206 7207 // XXX why does that use AddI 7208 instruct decI_mem(memory dst, immI_M1 src, rFlagsReg cr) 7209 %{ 7210 predicate(UseIncDec); 7211 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7212 effect(KILL cr); 7213 7214 ins_cost(125); // XXX 7215 format %{ "decl $dst\t# int" %} 7216 ins_encode %{ 7217 __ decrementl($dst$$Address); 7218 %} 7219 ins_pipe(ialu_mem_imm); 7220 %} 7221 7222 instruct leaI_rReg_immI2_immI(rRegI dst, rRegI index, immI2 scale, immI disp) 7223 %{ 7224 predicate(VM_Version::supports_fast_2op_lea()); 7225 match(Set dst (AddI (LShiftI index scale) disp)); 7226 7227 format %{ "leal $dst, [$index << $scale + $disp]\t# int" %} 7228 ins_encode %{ 7229 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 7230 __ leal($dst$$Register, Address(noreg, $index$$Register, scale, $disp$$constant)); 7231 %} 7232 ins_pipe(ialu_reg_reg); 7233 %} 7234 7235 instruct leaI_rReg_rReg_immI(rRegI dst, rRegI base, rRegI index, immI disp) 7236 %{ 7237 predicate(VM_Version::supports_fast_3op_lea()); 7238 match(Set dst (AddI (AddI base index) disp)); 7239 7240 format %{ "leal $dst, [$base + $index + $disp]\t# int" %} 7241 ins_encode %{ 7242 __ leal($dst$$Register, Address($base$$Register, $index$$Register, Address::times_1, $disp$$constant)); 7243 %} 7244 ins_pipe(ialu_reg_reg); 7245 %} 7246 7247 instruct leaI_rReg_rReg_immI2(rRegI dst, no_rbp_r13_RegI base, rRegI index, immI2 scale) 7248 %{ 7249 predicate(VM_Version::supports_fast_2op_lea()); 7250 match(Set dst (AddI base (LShiftI index scale))); 7251 7252 format %{ "leal $dst, [$base + $index << $scale]\t# int" %} 7253 ins_encode %{ 7254 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 7255 __ leal($dst$$Register, Address($base$$Register, $index$$Register, scale)); 7256 %} 7257 ins_pipe(ialu_reg_reg); 7258 %} 7259 7260 instruct leaI_rReg_rReg_immI2_immI(rRegI dst, rRegI base, rRegI index, immI2 scale, immI disp) 7261 %{ 7262 predicate(VM_Version::supports_fast_3op_lea()); 7263 match(Set dst (AddI (AddI base (LShiftI index scale)) disp)); 7264 7265 format %{ "leal $dst, [$base + $index << $scale + $disp]\t# int" %} 7266 ins_encode %{ 7267 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 7268 __ leal($dst$$Register, Address($base$$Register, $index$$Register, scale, $disp$$constant)); 7269 %} 7270 ins_pipe(ialu_reg_reg); 7271 %} 7272 7273 instruct addL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7274 %{ 7275 predicate(!UseAPX); 7276 match(Set dst (AddL dst src)); 7277 effect(KILL cr); 7278 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); 7279 7280 format %{ "addq $dst, $src\t# long" %} 7281 ins_encode %{ 7282 __ addq($dst$$Register, $src$$Register); 7283 %} 7284 ins_pipe(ialu_reg_reg); 7285 %} 7286 7287 instruct addL_rReg_ndd(rRegL dst, rRegL src1, rRegL src2, rFlagsReg cr) 7288 %{ 7289 predicate(UseAPX); 7290 match(Set dst (AddL src1 src2)); 7291 effect(KILL cr); 7292 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); 7293 7294 format %{ "eaddq $dst, $src1, $src2\t# long ndd" %} 7295 ins_encode %{ 7296 __ eaddq($dst$$Register, $src1$$Register, $src2$$Register, false); 7297 %} 7298 ins_pipe(ialu_reg_reg); 7299 %} 7300 7301 instruct addL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 7302 %{ 7303 predicate(!UseAPX); 7304 match(Set dst (AddL dst src)); 7305 effect(KILL cr); 7306 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); 7307 7308 format %{ "addq $dst, $src\t# long" %} 7309 ins_encode %{ 7310 __ addq($dst$$Register, $src$$constant); 7311 %} 7312 ins_pipe( ialu_reg ); 7313 %} 7314 7315 instruct addL_rReg_rReg_imm_ndd(rRegL dst, rRegL src1, immL32 src2, rFlagsReg cr) 7316 %{ 7317 predicate(UseAPX); 7318 match(Set dst (AddL src1 src2)); 7319 effect(KILL cr); 7320 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); 7321 7322 format %{ "eaddq $dst, $src1, $src2\t# long ndd" %} 7323 ins_encode %{ 7324 __ eaddq($dst$$Register, $src1$$Register, $src2$$constant, false); 7325 %} 7326 ins_pipe( ialu_reg ); 7327 %} 7328 7329 instruct addL_rReg_mem_imm_ndd(rRegL dst, memory src1, immL32 src2, rFlagsReg cr) 7330 %{ 7331 predicate(UseAPX); 7332 match(Set dst (AddL (LoadL src1) src2)); 7333 effect(KILL cr); 7334 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); 7335 7336 format %{ "eaddq $dst, $src1, $src2\t# long ndd" %} 7337 ins_encode %{ 7338 __ eaddq($dst$$Register, $src1$$Address, $src2$$constant, false); 7339 %} 7340 ins_pipe( ialu_reg ); 7341 %} 7342 7343 instruct addL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 7344 %{ 7345 predicate(!UseAPX); 7346 match(Set dst (AddL dst (LoadL src))); 7347 effect(KILL cr); 7348 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); 7349 7350 ins_cost(150); // XXX 7351 format %{ "addq $dst, $src\t# long" %} 7352 ins_encode %{ 7353 __ addq($dst$$Register, $src$$Address); 7354 %} 7355 ins_pipe(ialu_reg_mem); 7356 %} 7357 7358 instruct addL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr) 7359 %{ 7360 predicate(UseAPX); 7361 match(Set dst (AddL src1 (LoadL 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 ins_cost(150); 7366 format %{ "eaddq $dst, $src1, $src2\t# long ndd" %} 7367 ins_encode %{ 7368 __ eaddq($dst$$Register, $src1$$Register, $src2$$Address, false); 7369 %} 7370 ins_pipe(ialu_reg_mem); 7371 %} 7372 7373 instruct addL_rReg_mem_rReg_ndd(rRegL dst, memory src1, rRegL src2, rFlagsReg cr) 7374 %{ 7375 predicate(UseAPX); 7376 match(Set dst (AddL (LoadL src1) src2)); 7377 effect(KILL cr); 7378 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); 7379 7380 ins_cost(150); 7381 format %{ "eaddq $dst, $src1, $src2\t# long ndd" %} 7382 ins_encode %{ 7383 __ eaddq($dst$$Register, $src1$$Address, $src2$$Register, false); 7384 %} 7385 ins_pipe(ialu_reg_mem); 7386 %} 7387 7388 instruct addL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 7389 %{ 7390 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7391 effect(KILL cr); 7392 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); 7393 7394 ins_cost(150); // XXX 7395 format %{ "addq $dst, $src\t# long" %} 7396 ins_encode %{ 7397 __ addq($dst$$Address, $src$$Register); 7398 %} 7399 ins_pipe(ialu_mem_reg); 7400 %} 7401 7402 instruct addL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 7403 %{ 7404 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 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(125); // XXX 7409 format %{ "addq $dst, $src\t# long" %} 7410 ins_encode %{ 7411 __ addq($dst$$Address, $src$$constant); 7412 %} 7413 ins_pipe(ialu_mem_imm); 7414 %} 7415 7416 instruct incL_rReg(rRegL dst, immL1 src, rFlagsReg cr) 7417 %{ 7418 predicate(!UseAPX && UseIncDec); 7419 match(Set dst (AddL dst src)); 7420 effect(KILL cr); 7421 7422 format %{ "incq $dst\t# long" %} 7423 ins_encode %{ 7424 __ incrementq($dst$$Register); 7425 %} 7426 ins_pipe(ialu_reg); 7427 %} 7428 7429 instruct incL_rReg_ndd(rRegL dst, rRegI src, immL1 val, rFlagsReg cr) 7430 %{ 7431 predicate(UseAPX && UseIncDec); 7432 match(Set dst (AddL src val)); 7433 effect(KILL cr); 7434 7435 format %{ "eincq $dst, $src\t# long ndd" %} 7436 ins_encode %{ 7437 __ eincq($dst$$Register, $src$$Register, false); 7438 %} 7439 ins_pipe(ialu_reg); 7440 %} 7441 7442 instruct incL_rReg_mem_ndd(rRegL dst, memory src, immL1 val, rFlagsReg cr) 7443 %{ 7444 predicate(UseAPX && UseIncDec); 7445 match(Set dst (AddL (LoadL src) val)); 7446 effect(KILL cr); 7447 7448 format %{ "eincq $dst, $src\t# long ndd" %} 7449 ins_encode %{ 7450 __ eincq($dst$$Register, $src$$Address, false); 7451 %} 7452 ins_pipe(ialu_reg); 7453 %} 7454 7455 instruct incL_mem(memory dst, immL1 src, rFlagsReg cr) 7456 %{ 7457 predicate(UseIncDec); 7458 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7459 effect(KILL cr); 7460 7461 ins_cost(125); // XXX 7462 format %{ "incq $dst\t# long" %} 7463 ins_encode %{ 7464 __ incrementq($dst$$Address); 7465 %} 7466 ins_pipe(ialu_mem_imm); 7467 %} 7468 7469 // XXX why does that use AddL 7470 instruct decL_rReg(rRegL dst, immL_M1 src, rFlagsReg cr) 7471 %{ 7472 predicate(!UseAPX && UseIncDec); 7473 match(Set dst (AddL dst src)); 7474 effect(KILL cr); 7475 7476 format %{ "decq $dst\t# long" %} 7477 ins_encode %{ 7478 __ decrementq($dst$$Register); 7479 %} 7480 ins_pipe(ialu_reg); 7481 %} 7482 7483 instruct decL_rReg_ndd(rRegL dst, rRegL src, immL_M1 val, rFlagsReg cr) 7484 %{ 7485 predicate(UseAPX && UseIncDec); 7486 match(Set dst (AddL src val)); 7487 effect(KILL cr); 7488 7489 format %{ "edecq $dst, $src\t# long ndd" %} 7490 ins_encode %{ 7491 __ edecq($dst$$Register, $src$$Register, false); 7492 %} 7493 ins_pipe(ialu_reg); 7494 %} 7495 7496 instruct decL_rReg_mem_ndd(rRegL dst, memory src, immL_M1 val, rFlagsReg cr) 7497 %{ 7498 predicate(UseAPX && UseIncDec); 7499 match(Set dst (AddL (LoadL src) val)); 7500 effect(KILL cr); 7501 7502 format %{ "edecq $dst, $src\t# long ndd" %} 7503 ins_encode %{ 7504 __ edecq($dst$$Register, $src$$Address, false); 7505 %} 7506 ins_pipe(ialu_reg); 7507 %} 7508 7509 // XXX why does that use AddL 7510 instruct decL_mem(memory dst, immL_M1 src, rFlagsReg cr) 7511 %{ 7512 predicate(UseIncDec); 7513 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7514 effect(KILL cr); 7515 7516 ins_cost(125); // XXX 7517 format %{ "decq $dst\t# long" %} 7518 ins_encode %{ 7519 __ decrementq($dst$$Address); 7520 %} 7521 ins_pipe(ialu_mem_imm); 7522 %} 7523 7524 instruct leaL_rReg_immI2_immL32(rRegL dst, rRegL index, immI2 scale, immL32 disp) 7525 %{ 7526 predicate(VM_Version::supports_fast_2op_lea()); 7527 match(Set dst (AddL (LShiftL index scale) disp)); 7528 7529 format %{ "leaq $dst, [$index << $scale + $disp]\t# long" %} 7530 ins_encode %{ 7531 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 7532 __ leaq($dst$$Register, Address(noreg, $index$$Register, scale, $disp$$constant)); 7533 %} 7534 ins_pipe(ialu_reg_reg); 7535 %} 7536 7537 instruct leaL_rReg_rReg_immL32(rRegL dst, rRegL base, rRegL index, immL32 disp) 7538 %{ 7539 predicate(VM_Version::supports_fast_3op_lea()); 7540 match(Set dst (AddL (AddL base index) disp)); 7541 7542 format %{ "leaq $dst, [$base + $index + $disp]\t# long" %} 7543 ins_encode %{ 7544 __ leaq($dst$$Register, Address($base$$Register, $index$$Register, Address::times_1, $disp$$constant)); 7545 %} 7546 ins_pipe(ialu_reg_reg); 7547 %} 7548 7549 instruct leaL_rReg_rReg_immI2(rRegL dst, no_rbp_r13_RegL base, rRegL index, immI2 scale) 7550 %{ 7551 predicate(VM_Version::supports_fast_2op_lea()); 7552 match(Set dst (AddL base (LShiftL index scale))); 7553 7554 format %{ "leaq $dst, [$base + $index << $scale]\t# long" %} 7555 ins_encode %{ 7556 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 7557 __ leaq($dst$$Register, Address($base$$Register, $index$$Register, scale)); 7558 %} 7559 ins_pipe(ialu_reg_reg); 7560 %} 7561 7562 instruct leaL_rReg_rReg_immI2_immL32(rRegL dst, rRegL base, rRegL index, immI2 scale, immL32 disp) 7563 %{ 7564 predicate(VM_Version::supports_fast_3op_lea()); 7565 match(Set dst (AddL (AddL base (LShiftL index scale)) disp)); 7566 7567 format %{ "leaq $dst, [$base + $index << $scale + $disp]\t# long" %} 7568 ins_encode %{ 7569 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 7570 __ leaq($dst$$Register, Address($base$$Register, $index$$Register, scale, $disp$$constant)); 7571 %} 7572 ins_pipe(ialu_reg_reg); 7573 %} 7574 7575 instruct addP_rReg(rRegP dst, rRegL src, rFlagsReg cr) 7576 %{ 7577 match(Set dst (AddP dst src)); 7578 effect(KILL cr); 7579 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); 7580 7581 format %{ "addq $dst, $src\t# ptr" %} 7582 ins_encode %{ 7583 __ addq($dst$$Register, $src$$Register); 7584 %} 7585 ins_pipe(ialu_reg_reg); 7586 %} 7587 7588 instruct addP_rReg_imm(rRegP dst, immL32 src, rFlagsReg cr) 7589 %{ 7590 match(Set dst (AddP dst src)); 7591 effect(KILL cr); 7592 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); 7593 7594 format %{ "addq $dst, $src\t# ptr" %} 7595 ins_encode %{ 7596 __ addq($dst$$Register, $src$$constant); 7597 %} 7598 ins_pipe( ialu_reg ); 7599 %} 7600 7601 // XXX addP mem ops ???? 7602 7603 instruct checkCastPP(rRegP dst) 7604 %{ 7605 match(Set dst (CheckCastPP dst)); 7606 7607 size(0); 7608 format %{ "# checkcastPP of $dst" %} 7609 ins_encode(/* empty encoding */); 7610 ins_pipe(empty); 7611 %} 7612 7613 instruct castPP(rRegP dst) 7614 %{ 7615 match(Set dst (CastPP dst)); 7616 7617 size(0); 7618 format %{ "# castPP of $dst" %} 7619 ins_encode(/* empty encoding */); 7620 ins_pipe(empty); 7621 %} 7622 7623 instruct castII(rRegI dst) 7624 %{ 7625 predicate(VerifyConstraintCasts == 0); 7626 match(Set dst (CastII dst)); 7627 7628 size(0); 7629 format %{ "# castII of $dst" %} 7630 ins_encode(/* empty encoding */); 7631 ins_cost(0); 7632 ins_pipe(empty); 7633 %} 7634 7635 instruct castII_checked(rRegI dst, rFlagsReg cr) 7636 %{ 7637 predicate(VerifyConstraintCasts > 0); 7638 match(Set dst (CastII dst)); 7639 7640 effect(KILL cr); 7641 format %{ "# cast_checked_II $dst" %} 7642 ins_encode %{ 7643 __ verify_int_in_range(_idx, bottom_type()->is_int(), $dst$$Register); 7644 %} 7645 ins_pipe(pipe_slow); 7646 %} 7647 7648 instruct castLL(rRegL dst) 7649 %{ 7650 predicate(VerifyConstraintCasts == 0); 7651 match(Set dst (CastLL dst)); 7652 7653 size(0); 7654 format %{ "# castLL of $dst" %} 7655 ins_encode(/* empty encoding */); 7656 ins_cost(0); 7657 ins_pipe(empty); 7658 %} 7659 7660 instruct castLL_checked_L32(rRegL dst, rFlagsReg cr) 7661 %{ 7662 predicate(VerifyConstraintCasts > 0 && castLL_is_imm32(n)); 7663 match(Set dst (CastLL dst)); 7664 7665 effect(KILL cr); 7666 format %{ "# cast_checked_LL $dst" %} 7667 ins_encode %{ 7668 __ verify_long_in_range(_idx, bottom_type()->is_long(), $dst$$Register, noreg); 7669 %} 7670 ins_pipe(pipe_slow); 7671 %} 7672 7673 instruct castLL_checked(rRegL dst, rRegL tmp, rFlagsReg cr) 7674 %{ 7675 predicate(VerifyConstraintCasts > 0 && !castLL_is_imm32(n)); 7676 match(Set dst (CastLL dst)); 7677 7678 effect(KILL cr, TEMP tmp); 7679 format %{ "# cast_checked_LL $dst\tusing $tmp as TEMP" %} 7680 ins_encode %{ 7681 __ verify_long_in_range(_idx, bottom_type()->is_long(), $dst$$Register, $tmp$$Register); 7682 %} 7683 ins_pipe(pipe_slow); 7684 %} 7685 7686 instruct castFF(regF dst) 7687 %{ 7688 match(Set dst (CastFF dst)); 7689 7690 size(0); 7691 format %{ "# castFF of $dst" %} 7692 ins_encode(/* empty encoding */); 7693 ins_cost(0); 7694 ins_pipe(empty); 7695 %} 7696 7697 instruct castHH(regF dst) 7698 %{ 7699 match(Set dst (CastHH dst)); 7700 7701 size(0); 7702 format %{ "# castHH of $dst" %} 7703 ins_encode(/* empty encoding */); 7704 ins_cost(0); 7705 ins_pipe(empty); 7706 %} 7707 7708 instruct castDD(regD dst) 7709 %{ 7710 match(Set dst (CastDD dst)); 7711 7712 size(0); 7713 format %{ "# castDD of $dst" %} 7714 ins_encode(/* empty encoding */); 7715 ins_cost(0); 7716 ins_pipe(empty); 7717 %} 7718 7719 // XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them 7720 instruct compareAndSwapP(rRegI res, 7721 memory mem_ptr, 7722 rax_RegP oldval, rRegP newval, 7723 rFlagsReg cr) 7724 %{ 7725 predicate(n->as_LoadStore()->barrier_data() == 0); 7726 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); 7727 match(Set res (WeakCompareAndSwapP mem_ptr (Binary oldval newval))); 7728 effect(KILL cr, KILL oldval); 7729 7730 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7731 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7732 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7733 ins_encode %{ 7734 __ lock(); 7735 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7736 __ setcc(Assembler::equal, $res$$Register); 7737 %} 7738 ins_pipe( pipe_cmpxchg ); 7739 %} 7740 7741 instruct compareAndSwapL(rRegI res, 7742 memory mem_ptr, 7743 rax_RegL oldval, rRegL newval, 7744 rFlagsReg cr) 7745 %{ 7746 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval))); 7747 match(Set res (WeakCompareAndSwapL mem_ptr (Binary oldval newval))); 7748 effect(KILL cr, KILL oldval); 7749 7750 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7751 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7752 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7753 ins_encode %{ 7754 __ lock(); 7755 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7756 __ setcc(Assembler::equal, $res$$Register); 7757 %} 7758 ins_pipe( pipe_cmpxchg ); 7759 %} 7760 7761 instruct compareAndSwapI(rRegI res, 7762 memory mem_ptr, 7763 rax_RegI oldval, rRegI newval, 7764 rFlagsReg cr) 7765 %{ 7766 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval))); 7767 match(Set res (WeakCompareAndSwapI mem_ptr (Binary oldval newval))); 7768 effect(KILL cr, KILL oldval); 7769 7770 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7771 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7772 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7773 ins_encode %{ 7774 __ lock(); 7775 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7776 __ setcc(Assembler::equal, $res$$Register); 7777 %} 7778 ins_pipe( pipe_cmpxchg ); 7779 %} 7780 7781 instruct compareAndSwapB(rRegI res, 7782 memory mem_ptr, 7783 rax_RegI oldval, rRegI newval, 7784 rFlagsReg cr) 7785 %{ 7786 match(Set res (CompareAndSwapB mem_ptr (Binary oldval newval))); 7787 match(Set res (WeakCompareAndSwapB mem_ptr (Binary oldval newval))); 7788 effect(KILL cr, KILL oldval); 7789 7790 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7791 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7792 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7793 ins_encode %{ 7794 __ lock(); 7795 __ cmpxchgb($newval$$Register, $mem_ptr$$Address); 7796 __ setcc(Assembler::equal, $res$$Register); 7797 %} 7798 ins_pipe( pipe_cmpxchg ); 7799 %} 7800 7801 instruct compareAndSwapS(rRegI res, 7802 memory mem_ptr, 7803 rax_RegI oldval, rRegI newval, 7804 rFlagsReg cr) 7805 %{ 7806 match(Set res (CompareAndSwapS mem_ptr (Binary oldval newval))); 7807 match(Set res (WeakCompareAndSwapS mem_ptr (Binary oldval newval))); 7808 effect(KILL cr, KILL oldval); 7809 7810 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7811 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7812 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7813 ins_encode %{ 7814 __ lock(); 7815 __ cmpxchgw($newval$$Register, $mem_ptr$$Address); 7816 __ setcc(Assembler::equal, $res$$Register); 7817 %} 7818 ins_pipe( pipe_cmpxchg ); 7819 %} 7820 7821 instruct compareAndSwapN(rRegI res, 7822 memory mem_ptr, 7823 rax_RegN oldval, rRegN newval, 7824 rFlagsReg cr) %{ 7825 predicate(n->as_LoadStore()->barrier_data() == 0); 7826 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval))); 7827 match(Set res (WeakCompareAndSwapN mem_ptr (Binary oldval newval))); 7828 effect(KILL cr, KILL oldval); 7829 7830 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7831 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7832 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7833 ins_encode %{ 7834 __ lock(); 7835 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7836 __ setcc(Assembler::equal, $res$$Register); 7837 %} 7838 ins_pipe( pipe_cmpxchg ); 7839 %} 7840 7841 instruct compareAndExchangeB( 7842 memory mem_ptr, 7843 rax_RegI oldval, rRegI newval, 7844 rFlagsReg cr) 7845 %{ 7846 match(Set oldval (CompareAndExchangeB mem_ptr (Binary oldval newval))); 7847 effect(KILL cr); 7848 7849 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7850 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7851 ins_encode %{ 7852 __ lock(); 7853 __ cmpxchgb($newval$$Register, $mem_ptr$$Address); 7854 %} 7855 ins_pipe( pipe_cmpxchg ); 7856 %} 7857 7858 instruct compareAndExchangeS( 7859 memory mem_ptr, 7860 rax_RegI oldval, rRegI newval, 7861 rFlagsReg cr) 7862 %{ 7863 match(Set oldval (CompareAndExchangeS mem_ptr (Binary oldval newval))); 7864 effect(KILL cr); 7865 7866 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7867 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7868 ins_encode %{ 7869 __ lock(); 7870 __ cmpxchgw($newval$$Register, $mem_ptr$$Address); 7871 %} 7872 ins_pipe( pipe_cmpxchg ); 7873 %} 7874 7875 instruct compareAndExchangeI( 7876 memory mem_ptr, 7877 rax_RegI oldval, rRegI newval, 7878 rFlagsReg cr) 7879 %{ 7880 match(Set oldval (CompareAndExchangeI mem_ptr (Binary oldval newval))); 7881 effect(KILL cr); 7882 7883 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7884 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7885 ins_encode %{ 7886 __ lock(); 7887 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7888 %} 7889 ins_pipe( pipe_cmpxchg ); 7890 %} 7891 7892 instruct compareAndExchangeL( 7893 memory mem_ptr, 7894 rax_RegL oldval, rRegL newval, 7895 rFlagsReg cr) 7896 %{ 7897 match(Set oldval (CompareAndExchangeL mem_ptr (Binary oldval newval))); 7898 effect(KILL cr); 7899 7900 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7901 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7902 ins_encode %{ 7903 __ lock(); 7904 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7905 %} 7906 ins_pipe( pipe_cmpxchg ); 7907 %} 7908 7909 instruct compareAndExchangeN( 7910 memory mem_ptr, 7911 rax_RegN oldval, rRegN newval, 7912 rFlagsReg cr) %{ 7913 predicate(n->as_LoadStore()->barrier_data() == 0); 7914 match(Set oldval (CompareAndExchangeN mem_ptr (Binary oldval newval))); 7915 effect(KILL cr); 7916 7917 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7918 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7919 ins_encode %{ 7920 __ lock(); 7921 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7922 %} 7923 ins_pipe( pipe_cmpxchg ); 7924 %} 7925 7926 instruct compareAndExchangeP( 7927 memory mem_ptr, 7928 rax_RegP oldval, rRegP newval, 7929 rFlagsReg cr) 7930 %{ 7931 predicate(n->as_LoadStore()->barrier_data() == 0); 7932 match(Set oldval (CompareAndExchangeP mem_ptr (Binary oldval newval))); 7933 effect(KILL cr); 7934 7935 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7936 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7937 ins_encode %{ 7938 __ lock(); 7939 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7940 %} 7941 ins_pipe( pipe_cmpxchg ); 7942 %} 7943 7944 instruct xaddB_reg_no_res(memory mem, Universe dummy, rRegI add, rFlagsReg cr) %{ 7945 predicate(n->as_LoadStore()->result_not_used()); 7946 match(Set dummy (GetAndAddB mem add)); 7947 effect(KILL cr); 7948 format %{ "addb_lock $mem, $add" %} 7949 ins_encode %{ 7950 __ lock(); 7951 __ addb($mem$$Address, $add$$Register); 7952 %} 7953 ins_pipe(pipe_cmpxchg); 7954 %} 7955 7956 instruct xaddB_imm_no_res(memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7957 predicate(n->as_LoadStore()->result_not_used()); 7958 match(Set dummy (GetAndAddB mem add)); 7959 effect(KILL cr); 7960 format %{ "addb_lock $mem, $add" %} 7961 ins_encode %{ 7962 __ lock(); 7963 __ addb($mem$$Address, $add$$constant); 7964 %} 7965 ins_pipe(pipe_cmpxchg); 7966 %} 7967 7968 instruct xaddB(memory mem, rRegI newval, rFlagsReg cr) %{ 7969 predicate(!n->as_LoadStore()->result_not_used()); 7970 match(Set newval (GetAndAddB mem newval)); 7971 effect(KILL cr); 7972 format %{ "xaddb_lock $mem, $newval" %} 7973 ins_encode %{ 7974 __ lock(); 7975 __ xaddb($mem$$Address, $newval$$Register); 7976 %} 7977 ins_pipe(pipe_cmpxchg); 7978 %} 7979 7980 instruct xaddS_reg_no_res(memory mem, Universe dummy, rRegI add, rFlagsReg cr) %{ 7981 predicate(n->as_LoadStore()->result_not_used()); 7982 match(Set dummy (GetAndAddS mem add)); 7983 effect(KILL cr); 7984 format %{ "addw_lock $mem, $add" %} 7985 ins_encode %{ 7986 __ lock(); 7987 __ addw($mem$$Address, $add$$Register); 7988 %} 7989 ins_pipe(pipe_cmpxchg); 7990 %} 7991 7992 instruct xaddS_imm_no_res(memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7993 predicate(UseStoreImmI16 && n->as_LoadStore()->result_not_used()); 7994 match(Set dummy (GetAndAddS mem add)); 7995 effect(KILL cr); 7996 format %{ "addw_lock $mem, $add" %} 7997 ins_encode %{ 7998 __ lock(); 7999 __ addw($mem$$Address, $add$$constant); 8000 %} 8001 ins_pipe(pipe_cmpxchg); 8002 %} 8003 8004 instruct xaddS(memory mem, rRegI newval, rFlagsReg cr) %{ 8005 predicate(!n->as_LoadStore()->result_not_used()); 8006 match(Set newval (GetAndAddS mem newval)); 8007 effect(KILL cr); 8008 format %{ "xaddw_lock $mem, $newval" %} 8009 ins_encode %{ 8010 __ lock(); 8011 __ xaddw($mem$$Address, $newval$$Register); 8012 %} 8013 ins_pipe(pipe_cmpxchg); 8014 %} 8015 8016 instruct xaddI_reg_no_res(memory mem, Universe dummy, rRegI add, rFlagsReg cr) %{ 8017 predicate(n->as_LoadStore()->result_not_used()); 8018 match(Set dummy (GetAndAddI mem add)); 8019 effect(KILL cr); 8020 format %{ "addl_lock $mem, $add" %} 8021 ins_encode %{ 8022 __ lock(); 8023 __ addl($mem$$Address, $add$$Register); 8024 %} 8025 ins_pipe(pipe_cmpxchg); 8026 %} 8027 8028 instruct xaddI_imm_no_res(memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 8029 predicate(n->as_LoadStore()->result_not_used()); 8030 match(Set dummy (GetAndAddI mem add)); 8031 effect(KILL cr); 8032 format %{ "addl_lock $mem, $add" %} 8033 ins_encode %{ 8034 __ lock(); 8035 __ addl($mem$$Address, $add$$constant); 8036 %} 8037 ins_pipe(pipe_cmpxchg); 8038 %} 8039 8040 instruct xaddI(memory mem, rRegI newval, rFlagsReg cr) %{ 8041 predicate(!n->as_LoadStore()->result_not_used()); 8042 match(Set newval (GetAndAddI mem newval)); 8043 effect(KILL cr); 8044 format %{ "xaddl_lock $mem, $newval" %} 8045 ins_encode %{ 8046 __ lock(); 8047 __ xaddl($mem$$Address, $newval$$Register); 8048 %} 8049 ins_pipe(pipe_cmpxchg); 8050 %} 8051 8052 instruct xaddL_reg_no_res(memory mem, Universe dummy, rRegL add, rFlagsReg cr) %{ 8053 predicate(n->as_LoadStore()->result_not_used()); 8054 match(Set dummy (GetAndAddL mem add)); 8055 effect(KILL cr); 8056 format %{ "addq_lock $mem, $add" %} 8057 ins_encode %{ 8058 __ lock(); 8059 __ addq($mem$$Address, $add$$Register); 8060 %} 8061 ins_pipe(pipe_cmpxchg); 8062 %} 8063 8064 instruct xaddL_imm_no_res(memory mem, Universe dummy, immL32 add, rFlagsReg cr) %{ 8065 predicate(n->as_LoadStore()->result_not_used()); 8066 match(Set dummy (GetAndAddL mem add)); 8067 effect(KILL cr); 8068 format %{ "addq_lock $mem, $add" %} 8069 ins_encode %{ 8070 __ lock(); 8071 __ addq($mem$$Address, $add$$constant); 8072 %} 8073 ins_pipe(pipe_cmpxchg); 8074 %} 8075 8076 instruct xaddL(memory mem, rRegL newval, rFlagsReg cr) %{ 8077 predicate(!n->as_LoadStore()->result_not_used()); 8078 match(Set newval (GetAndAddL mem newval)); 8079 effect(KILL cr); 8080 format %{ "xaddq_lock $mem, $newval" %} 8081 ins_encode %{ 8082 __ lock(); 8083 __ xaddq($mem$$Address, $newval$$Register); 8084 %} 8085 ins_pipe(pipe_cmpxchg); 8086 %} 8087 8088 instruct xchgB( memory mem, rRegI newval) %{ 8089 match(Set newval (GetAndSetB mem newval)); 8090 format %{ "XCHGB $newval,[$mem]" %} 8091 ins_encode %{ 8092 __ xchgb($newval$$Register, $mem$$Address); 8093 %} 8094 ins_pipe( pipe_cmpxchg ); 8095 %} 8096 8097 instruct xchgS( memory mem, rRegI newval) %{ 8098 match(Set newval (GetAndSetS mem newval)); 8099 format %{ "XCHGW $newval,[$mem]" %} 8100 ins_encode %{ 8101 __ xchgw($newval$$Register, $mem$$Address); 8102 %} 8103 ins_pipe( pipe_cmpxchg ); 8104 %} 8105 8106 instruct xchgI( memory mem, rRegI newval) %{ 8107 match(Set newval (GetAndSetI mem newval)); 8108 format %{ "XCHGL $newval,[$mem]" %} 8109 ins_encode %{ 8110 __ xchgl($newval$$Register, $mem$$Address); 8111 %} 8112 ins_pipe( pipe_cmpxchg ); 8113 %} 8114 8115 instruct xchgL( memory mem, rRegL newval) %{ 8116 match(Set newval (GetAndSetL mem newval)); 8117 format %{ "XCHGL $newval,[$mem]" %} 8118 ins_encode %{ 8119 __ xchgq($newval$$Register, $mem$$Address); 8120 %} 8121 ins_pipe( pipe_cmpxchg ); 8122 %} 8123 8124 instruct xchgP( memory mem, rRegP newval) %{ 8125 match(Set newval (GetAndSetP mem newval)); 8126 predicate(n->as_LoadStore()->barrier_data() == 0); 8127 format %{ "XCHGQ $newval,[$mem]" %} 8128 ins_encode %{ 8129 __ xchgq($newval$$Register, $mem$$Address); 8130 %} 8131 ins_pipe( pipe_cmpxchg ); 8132 %} 8133 8134 instruct xchgN( memory mem, rRegN newval) %{ 8135 predicate(n->as_LoadStore()->barrier_data() == 0); 8136 match(Set newval (GetAndSetN mem newval)); 8137 format %{ "XCHGL $newval,$mem]" %} 8138 ins_encode %{ 8139 __ xchgl($newval$$Register, $mem$$Address); 8140 %} 8141 ins_pipe( pipe_cmpxchg ); 8142 %} 8143 8144 //----------Abs Instructions------------------------------------------- 8145 8146 // Integer Absolute Instructions 8147 instruct absI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8148 %{ 8149 match(Set dst (AbsI src)); 8150 effect(TEMP dst, KILL cr); 8151 format %{ "xorl $dst, $dst\t# abs int\n\t" 8152 "subl $dst, $src\n\t" 8153 "cmovll $dst, $src" %} 8154 ins_encode %{ 8155 __ xorl($dst$$Register, $dst$$Register); 8156 __ subl($dst$$Register, $src$$Register); 8157 __ cmovl(Assembler::less, $dst$$Register, $src$$Register); 8158 %} 8159 8160 ins_pipe(ialu_reg_reg); 8161 %} 8162 8163 // Long Absolute Instructions 8164 instruct absL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 8165 %{ 8166 match(Set dst (AbsL src)); 8167 effect(TEMP dst, KILL cr); 8168 format %{ "xorl $dst, $dst\t# abs long\n\t" 8169 "subq $dst, $src\n\t" 8170 "cmovlq $dst, $src" %} 8171 ins_encode %{ 8172 __ xorl($dst$$Register, $dst$$Register); 8173 __ subq($dst$$Register, $src$$Register); 8174 __ cmovq(Assembler::less, $dst$$Register, $src$$Register); 8175 %} 8176 8177 ins_pipe(ialu_reg_reg); 8178 %} 8179 8180 //----------Subtraction Instructions------------------------------------------- 8181 8182 // Integer Subtraction Instructions 8183 instruct subI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8184 %{ 8185 predicate(!UseAPX); 8186 match(Set dst (SubI dst src)); 8187 effect(KILL cr); 8188 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); 8189 8190 format %{ "subl $dst, $src\t# int" %} 8191 ins_encode %{ 8192 __ subl($dst$$Register, $src$$Register); 8193 %} 8194 ins_pipe(ialu_reg_reg); 8195 %} 8196 8197 instruct subI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr) 8198 %{ 8199 predicate(UseAPX); 8200 match(Set dst (SubI src1 src2)); 8201 effect(KILL cr); 8202 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); 8203 8204 format %{ "esubl $dst, $src1, $src2\t# int ndd" %} 8205 ins_encode %{ 8206 __ esubl($dst$$Register, $src1$$Register, $src2$$Register, false); 8207 %} 8208 ins_pipe(ialu_reg_reg); 8209 %} 8210 8211 instruct subI_rReg_rReg_imm_ndd(rRegI dst, rRegI src1, immI src2, rFlagsReg cr) 8212 %{ 8213 predicate(UseAPX); 8214 match(Set dst (SubI src1 src2)); 8215 effect(KILL cr); 8216 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); 8217 8218 format %{ "esubl $dst, $src1, $src2\t# int ndd" %} 8219 ins_encode %{ 8220 __ esubl($dst$$Register, $src1$$Register, $src2$$constant, false); 8221 %} 8222 ins_pipe(ialu_reg_reg); 8223 %} 8224 8225 instruct subI_rReg_mem_imm_ndd(rRegI dst, memory src1, immI src2, rFlagsReg cr) 8226 %{ 8227 predicate(UseAPX); 8228 match(Set dst (SubI (LoadI src1) src2)); 8229 effect(KILL cr); 8230 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 8231 8232 format %{ "esubl $dst, $src1, $src2\t# int ndd" %} 8233 ins_encode %{ 8234 __ esubl($dst$$Register, $src1$$Address, $src2$$constant, false); 8235 %} 8236 ins_pipe(ialu_reg_reg); 8237 %} 8238 8239 instruct subI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 8240 %{ 8241 predicate(!UseAPX); 8242 match(Set dst (SubI dst (LoadI src))); 8243 effect(KILL cr); 8244 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); 8245 8246 ins_cost(150); 8247 format %{ "subl $dst, $src\t# int" %} 8248 ins_encode %{ 8249 __ subl($dst$$Register, $src$$Address); 8250 %} 8251 ins_pipe(ialu_reg_mem); 8252 %} 8253 8254 instruct subI_rReg_rReg_mem_ndd(rRegI dst, rRegI src1, memory src2, rFlagsReg cr) 8255 %{ 8256 predicate(UseAPX); 8257 match(Set dst (SubI src1 (LoadI 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 ins_cost(150); 8262 format %{ "esubl $dst, $src1, $src2\t# int ndd" %} 8263 ins_encode %{ 8264 __ esubl($dst$$Register, $src1$$Register, $src2$$Address, false); 8265 %} 8266 ins_pipe(ialu_reg_mem); 8267 %} 8268 8269 instruct subI_rReg_mem_rReg_ndd(rRegI dst, memory src1, rRegI src2, rFlagsReg cr) 8270 %{ 8271 predicate(UseAPX); 8272 match(Set dst (SubI (LoadI src1) src2)); 8273 effect(KILL cr); 8274 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 8275 8276 ins_cost(150); 8277 format %{ "esubl $dst, $src1, $src2\t# int ndd" %} 8278 ins_encode %{ 8279 __ esubl($dst$$Register, $src1$$Address, $src2$$Register, false); 8280 %} 8281 ins_pipe(ialu_reg_mem); 8282 %} 8283 8284 instruct subI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 8285 %{ 8286 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 8287 effect(KILL cr); 8288 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 8289 8290 ins_cost(150); 8291 format %{ "subl $dst, $src\t# int" %} 8292 ins_encode %{ 8293 __ subl($dst$$Address, $src$$Register); 8294 %} 8295 ins_pipe(ialu_mem_reg); 8296 %} 8297 8298 instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 8299 %{ 8300 predicate(!UseAPX); 8301 match(Set dst (SubL dst src)); 8302 effect(KILL cr); 8303 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); 8304 8305 format %{ "subq $dst, $src\t# long" %} 8306 ins_encode %{ 8307 __ subq($dst$$Register, $src$$Register); 8308 %} 8309 ins_pipe(ialu_reg_reg); 8310 %} 8311 8312 instruct subL_rReg_ndd(rRegL dst, rRegL src1, rRegL src2, rFlagsReg cr) 8313 %{ 8314 predicate(UseAPX); 8315 match(Set dst (SubL 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 format %{ "esubq $dst, $src1, $src2\t# long ndd" %} 8320 ins_encode %{ 8321 __ esubq($dst$$Register, $src1$$Register, $src2$$Register, false); 8322 %} 8323 ins_pipe(ialu_reg_reg); 8324 %} 8325 8326 instruct subL_rReg_rReg_imm_ndd(rRegL dst, rRegL src1, immL32 src2, rFlagsReg cr) 8327 %{ 8328 predicate(UseAPX); 8329 match(Set dst (SubL src1 src2)); 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 format %{ "esubq $dst, $src1, $src2\t# long ndd" %} 8334 ins_encode %{ 8335 __ esubq($dst$$Register, $src1$$Register, $src2$$constant, false); 8336 %} 8337 ins_pipe(ialu_reg_reg); 8338 %} 8339 8340 instruct subL_rReg_mem_imm_ndd(rRegL dst, memory src1, immL32 src2, rFlagsReg cr) 8341 %{ 8342 predicate(UseAPX); 8343 match(Set dst (SubL (LoadL src1) src2)); 8344 effect(KILL cr); 8345 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 8346 8347 format %{ "esubq $dst, $src1, $src2\t# long ndd" %} 8348 ins_encode %{ 8349 __ esubq($dst$$Register, $src1$$Address, $src2$$constant, false); 8350 %} 8351 ins_pipe(ialu_reg_reg); 8352 %} 8353 8354 instruct subL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 8355 %{ 8356 predicate(!UseAPX); 8357 match(Set dst (SubL dst (LoadL src))); 8358 effect(KILL cr); 8359 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); 8360 8361 ins_cost(150); 8362 format %{ "subq $dst, $src\t# long" %} 8363 ins_encode %{ 8364 __ subq($dst$$Register, $src$$Address); 8365 %} 8366 ins_pipe(ialu_reg_mem); 8367 %} 8368 8369 instruct subL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr) 8370 %{ 8371 predicate(UseAPX); 8372 match(Set dst (SubL src1 (LoadL 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 ins_cost(150); 8377 format %{ "esubq $dst, $src1, $src2\t# long ndd" %} 8378 ins_encode %{ 8379 __ esubq($dst$$Register, $src1$$Register, $src2$$Address, false); 8380 %} 8381 ins_pipe(ialu_reg_mem); 8382 %} 8383 8384 instruct subL_rReg_mem_rReg_ndd(rRegL dst, memory src1, rRegL src2, rFlagsReg cr) 8385 %{ 8386 predicate(UseAPX); 8387 match(Set dst (SubL (LoadL src1) src2)); 8388 effect(KILL cr); 8389 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); 8390 8391 ins_cost(150); 8392 format %{ "esubq $dst, $src1, $src2\t# long ndd" %} 8393 ins_encode %{ 8394 __ esubq($dst$$Register, $src1$$Address, $src2$$Register, false); 8395 %} 8396 ins_pipe(ialu_reg_mem); 8397 %} 8398 8399 instruct subL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 8400 %{ 8401 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 8402 effect(KILL cr); 8403 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); 8404 8405 ins_cost(150); 8406 format %{ "subq $dst, $src\t# long" %} 8407 ins_encode %{ 8408 __ subq($dst$$Address, $src$$Register); 8409 %} 8410 ins_pipe(ialu_mem_reg); 8411 %} 8412 8413 // Subtract from a pointer 8414 // XXX hmpf??? 8415 instruct subP_rReg(rRegP dst, rRegI src, immI_0 zero, rFlagsReg cr) 8416 %{ 8417 match(Set dst (AddP dst (SubI zero src))); 8418 effect(KILL cr); 8419 8420 format %{ "subq $dst, $src\t# ptr - int" %} 8421 ins_encode %{ 8422 __ subq($dst$$Register, $src$$Register); 8423 %} 8424 ins_pipe(ialu_reg_reg); 8425 %} 8426 8427 instruct negI_rReg(rRegI dst, immI_0 zero, rFlagsReg cr) 8428 %{ 8429 predicate(!UseAPX); 8430 match(Set dst (SubI zero dst)); 8431 effect(KILL cr); 8432 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8433 8434 format %{ "negl $dst\t# int" %} 8435 ins_encode %{ 8436 __ negl($dst$$Register); 8437 %} 8438 ins_pipe(ialu_reg); 8439 %} 8440 8441 instruct negI_rReg_ndd(rRegI dst, rRegI src, immI_0 zero, rFlagsReg cr) 8442 %{ 8443 predicate(UseAPX); 8444 match(Set dst (SubI zero 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_parity_flag); 8447 8448 format %{ "enegl $dst, $src\t# int ndd" %} 8449 ins_encode %{ 8450 __ enegl($dst$$Register, $src$$Register, false); 8451 %} 8452 ins_pipe(ialu_reg); 8453 %} 8454 8455 instruct negI_rReg_2(rRegI dst, rFlagsReg cr) 8456 %{ 8457 predicate(!UseAPX); 8458 match(Set dst (NegI dst)); 8459 effect(KILL cr); 8460 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8461 8462 format %{ "negl $dst\t# int" %} 8463 ins_encode %{ 8464 __ negl($dst$$Register); 8465 %} 8466 ins_pipe(ialu_reg); 8467 %} 8468 8469 instruct negI_rReg_2_ndd(rRegI dst, rRegI src, rFlagsReg cr) 8470 %{ 8471 predicate(UseAPX); 8472 match(Set dst (NegI src)); 8473 effect(KILL cr); 8474 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8475 8476 format %{ "enegl $dst, $src\t# int ndd" %} 8477 ins_encode %{ 8478 __ enegl($dst$$Register, $src$$Register, false); 8479 %} 8480 ins_pipe(ialu_reg); 8481 %} 8482 8483 instruct negI_mem(memory dst, immI_0 zero, rFlagsReg cr) 8484 %{ 8485 match(Set dst (StoreI dst (SubI zero (LoadI dst)))); 8486 effect(KILL cr); 8487 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8488 8489 format %{ "negl $dst\t# int" %} 8490 ins_encode %{ 8491 __ negl($dst$$Address); 8492 %} 8493 ins_pipe(ialu_reg); 8494 %} 8495 8496 instruct negL_rReg(rRegL dst, immL0 zero, rFlagsReg cr) 8497 %{ 8498 predicate(!UseAPX); 8499 match(Set dst (SubL zero dst)); 8500 effect(KILL cr); 8501 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8502 8503 format %{ "negq $dst\t# long" %} 8504 ins_encode %{ 8505 __ negq($dst$$Register); 8506 %} 8507 ins_pipe(ialu_reg); 8508 %} 8509 8510 instruct negL_rReg_ndd(rRegL dst, rRegL src, immL0 zero, rFlagsReg cr) 8511 %{ 8512 predicate(UseAPX); 8513 match(Set dst (SubL zero src)); 8514 effect(KILL cr); 8515 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8516 8517 format %{ "enegq $dst, $src\t# long ndd" %} 8518 ins_encode %{ 8519 __ enegq($dst$$Register, $src$$Register, false); 8520 %} 8521 ins_pipe(ialu_reg); 8522 %} 8523 8524 instruct negL_rReg_2(rRegL dst, rFlagsReg cr) 8525 %{ 8526 predicate(!UseAPX); 8527 match(Set dst (NegL dst)); 8528 effect(KILL cr); 8529 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8530 8531 format %{ "negq $dst\t# int" %} 8532 ins_encode %{ 8533 __ negq($dst$$Register); 8534 %} 8535 ins_pipe(ialu_reg); 8536 %} 8537 8538 instruct negL_rReg_2_ndd(rRegL dst, rRegL src, rFlagsReg cr) 8539 %{ 8540 predicate(UseAPX); 8541 match(Set dst (NegL src)); 8542 effect(KILL cr); 8543 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8544 8545 format %{ "enegq $dst, $src\t# long ndd" %} 8546 ins_encode %{ 8547 __ enegq($dst$$Register, $src$$Register, false); 8548 %} 8549 ins_pipe(ialu_reg); 8550 %} 8551 8552 instruct negL_mem(memory dst, immL0 zero, rFlagsReg cr) 8553 %{ 8554 match(Set dst (StoreL dst (SubL zero (LoadL dst)))); 8555 effect(KILL cr); 8556 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8557 8558 format %{ "negq $dst\t# long" %} 8559 ins_encode %{ 8560 __ negq($dst$$Address); 8561 %} 8562 ins_pipe(ialu_reg); 8563 %} 8564 8565 //----------Multiplication/Division Instructions------------------------------- 8566 // Integer Multiplication Instructions 8567 // Multiply Register 8568 8569 instruct mulI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8570 %{ 8571 predicate(!UseAPX); 8572 match(Set dst (MulI dst src)); 8573 effect(KILL cr); 8574 8575 ins_cost(300); 8576 format %{ "imull $dst, $src\t# int" %} 8577 ins_encode %{ 8578 __ imull($dst$$Register, $src$$Register); 8579 %} 8580 ins_pipe(ialu_reg_reg_alu0); 8581 %} 8582 8583 instruct mulI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr) 8584 %{ 8585 predicate(UseAPX); 8586 match(Set dst (MulI src1 src2)); 8587 effect(KILL cr); 8588 8589 ins_cost(300); 8590 format %{ "eimull $dst, $src1, $src2\t# int ndd" %} 8591 ins_encode %{ 8592 __ eimull($dst$$Register, $src1$$Register, $src2$$Register, false); 8593 %} 8594 ins_pipe(ialu_reg_reg_alu0); 8595 %} 8596 8597 instruct mulI_rReg_imm(rRegI dst, rRegI src, immI imm, rFlagsReg cr) 8598 %{ 8599 predicate(!UseAPX); 8600 match(Set dst (MulI src imm)); 8601 effect(KILL cr); 8602 8603 ins_cost(300); 8604 format %{ "imull $dst, $src, $imm\t# int" %} 8605 ins_encode %{ 8606 __ imull($dst$$Register, $src$$Register, $imm$$constant); 8607 %} 8608 ins_pipe(ialu_reg_reg_alu0); 8609 %} 8610 8611 instruct mulI_rReg_rReg_imm_ndd(rRegI dst, rRegI src1, immI src2, rFlagsReg cr) 8612 %{ 8613 predicate(UseAPX); 8614 match(Set dst (MulI src1 src2)); 8615 effect(KILL cr); 8616 8617 ins_cost(300); 8618 format %{ "eimull $dst, $src1, $src2\t# int ndd" %} 8619 ins_encode %{ 8620 __ eimull($dst$$Register, $src1$$Register, $src2$$constant, false); 8621 %} 8622 ins_pipe(ialu_reg_reg_alu0); 8623 %} 8624 8625 instruct mulI_mem(rRegI dst, memory src, rFlagsReg cr) 8626 %{ 8627 predicate(!UseAPX); 8628 match(Set dst (MulI dst (LoadI src))); 8629 effect(KILL cr); 8630 8631 ins_cost(350); 8632 format %{ "imull $dst, $src\t# int" %} 8633 ins_encode %{ 8634 __ imull($dst$$Register, $src$$Address); 8635 %} 8636 ins_pipe(ialu_reg_mem_alu0); 8637 %} 8638 8639 instruct mulI_rReg_rReg_mem_ndd(rRegI dst, rRegI src1, memory src2, rFlagsReg cr) 8640 %{ 8641 predicate(UseAPX); 8642 match(Set dst (MulI src1 (LoadI src2))); 8643 effect(KILL cr); 8644 8645 ins_cost(350); 8646 format %{ "eimull $dst, $src1, $src2\t# int ndd" %} 8647 ins_encode %{ 8648 __ eimull($dst$$Register, $src1$$Register, $src2$$Address, false); 8649 %} 8650 ins_pipe(ialu_reg_mem_alu0); 8651 %} 8652 8653 instruct mulI_mem_imm(rRegI dst, memory src, immI imm, rFlagsReg cr) 8654 %{ 8655 predicate(!UseAPX); 8656 match(Set dst (MulI (LoadI src) imm)); 8657 effect(KILL cr); 8658 8659 ins_cost(300); 8660 format %{ "imull $dst, $src, $imm\t# int" %} 8661 ins_encode %{ 8662 __ imull($dst$$Register, $src$$Address, $imm$$constant); 8663 %} 8664 ins_pipe(ialu_reg_mem_alu0); 8665 %} 8666 8667 instruct mulI_rReg_mem_imm(rRegI dst, memory src1, immI src2, rFlagsReg cr) 8668 %{ 8669 predicate(UseAPX); 8670 match(Set dst (MulI (LoadI src1) src2)); 8671 effect(KILL cr); 8672 8673 ins_cost(300); 8674 format %{ "eimull $dst, $src1, $src2\t# int ndd" %} 8675 ins_encode %{ 8676 __ eimull($dst$$Register, $src1$$Address, $src2$$constant, false); 8677 %} 8678 ins_pipe(ialu_reg_mem_alu0); 8679 %} 8680 8681 instruct mulAddS2I_rReg(rRegI dst, rRegI src1, rRegI src2, rRegI src3, rFlagsReg cr) 8682 %{ 8683 match(Set dst (MulAddS2I (Binary dst src1) (Binary src2 src3))); 8684 effect(KILL cr, KILL src2); 8685 8686 expand %{ mulI_rReg(dst, src1, cr); 8687 mulI_rReg(src2, src3, cr); 8688 addI_rReg(dst, src2, cr); %} 8689 %} 8690 8691 instruct mulL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 8692 %{ 8693 predicate(!UseAPX); 8694 match(Set dst (MulL dst src)); 8695 effect(KILL cr); 8696 8697 ins_cost(300); 8698 format %{ "imulq $dst, $src\t# long" %} 8699 ins_encode %{ 8700 __ imulq($dst$$Register, $src$$Register); 8701 %} 8702 ins_pipe(ialu_reg_reg_alu0); 8703 %} 8704 8705 instruct mulL_rReg_ndd(rRegL dst, rRegL src1, rRegL src2, rFlagsReg cr) 8706 %{ 8707 predicate(UseAPX); 8708 match(Set dst (MulL src1 src2)); 8709 effect(KILL cr); 8710 8711 ins_cost(300); 8712 format %{ "eimulq $dst, $src1, $src2\t# long ndd" %} 8713 ins_encode %{ 8714 __ eimulq($dst$$Register, $src1$$Register, $src2$$Register, false); 8715 %} 8716 ins_pipe(ialu_reg_reg_alu0); 8717 %} 8718 8719 instruct mulL_rReg_imm(rRegL dst, rRegL src, immL32 imm, rFlagsReg cr) 8720 %{ 8721 predicate(!UseAPX); 8722 match(Set dst (MulL src imm)); 8723 effect(KILL cr); 8724 8725 ins_cost(300); 8726 format %{ "imulq $dst, $src, $imm\t# long" %} 8727 ins_encode %{ 8728 __ imulq($dst$$Register, $src$$Register, $imm$$constant); 8729 %} 8730 ins_pipe(ialu_reg_reg_alu0); 8731 %} 8732 8733 instruct mulL_rReg_rReg_imm_ndd(rRegL dst, rRegL src1, immL32 src2, rFlagsReg cr) 8734 %{ 8735 predicate(UseAPX); 8736 match(Set dst (MulL src1 src2)); 8737 effect(KILL cr); 8738 8739 ins_cost(300); 8740 format %{ "eimulq $dst, $src1, $src2\t# long ndd" %} 8741 ins_encode %{ 8742 __ eimulq($dst$$Register, $src1$$Register, $src2$$constant, false); 8743 %} 8744 ins_pipe(ialu_reg_reg_alu0); 8745 %} 8746 8747 instruct mulL_mem(rRegL dst, memory src, rFlagsReg cr) 8748 %{ 8749 predicate(!UseAPX); 8750 match(Set dst (MulL dst (LoadL src))); 8751 effect(KILL cr); 8752 8753 ins_cost(350); 8754 format %{ "imulq $dst, $src\t# long" %} 8755 ins_encode %{ 8756 __ imulq($dst$$Register, $src$$Address); 8757 %} 8758 ins_pipe(ialu_reg_mem_alu0); 8759 %} 8760 8761 instruct mulL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr) 8762 %{ 8763 predicate(UseAPX); 8764 match(Set dst (MulL src1 (LoadL src2))); 8765 effect(KILL cr); 8766 8767 ins_cost(350); 8768 format %{ "eimulq $dst, $src1, $src2 \t# long" %} 8769 ins_encode %{ 8770 __ eimulq($dst$$Register, $src1$$Register, $src2$$Address, false); 8771 %} 8772 ins_pipe(ialu_reg_mem_alu0); 8773 %} 8774 8775 instruct mulL_mem_imm(rRegL dst, memory src, immL32 imm, rFlagsReg cr) 8776 %{ 8777 predicate(!UseAPX); 8778 match(Set dst (MulL (LoadL src) imm)); 8779 effect(KILL cr); 8780 8781 ins_cost(300); 8782 format %{ "imulq $dst, $src, $imm\t# long" %} 8783 ins_encode %{ 8784 __ imulq($dst$$Register, $src$$Address, $imm$$constant); 8785 %} 8786 ins_pipe(ialu_reg_mem_alu0); 8787 %} 8788 8789 instruct mulL_rReg_mem_imm_ndd(rRegL dst, memory src1, immL32 src2, rFlagsReg cr) 8790 %{ 8791 predicate(UseAPX); 8792 match(Set dst (MulL (LoadL src1) src2)); 8793 effect(KILL cr); 8794 8795 ins_cost(300); 8796 format %{ "eimulq $dst, $src1, $src2\t# long ndd" %} 8797 ins_encode %{ 8798 __ eimulq($dst$$Register, $src1$$Address, $src2$$constant, false); 8799 %} 8800 ins_pipe(ialu_reg_mem_alu0); 8801 %} 8802 8803 instruct mulHiL_rReg(rdx_RegL dst, rRegL src, rax_RegL rax, rFlagsReg cr) 8804 %{ 8805 match(Set dst (MulHiL src rax)); 8806 effect(USE_KILL rax, KILL cr); 8807 8808 ins_cost(300); 8809 format %{ "imulq RDX:RAX, RAX, $src\t# mulhi" %} 8810 ins_encode %{ 8811 __ imulq($src$$Register); 8812 %} 8813 ins_pipe(ialu_reg_reg_alu0); 8814 %} 8815 8816 instruct umulHiL_rReg(rdx_RegL dst, rRegL src, rax_RegL rax, rFlagsReg cr) 8817 %{ 8818 match(Set dst (UMulHiL src rax)); 8819 effect(USE_KILL rax, KILL cr); 8820 8821 ins_cost(300); 8822 format %{ "mulq RDX:RAX, RAX, $src\t# umulhi" %} 8823 ins_encode %{ 8824 __ mulq($src$$Register); 8825 %} 8826 ins_pipe(ialu_reg_reg_alu0); 8827 %} 8828 8829 instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 8830 rFlagsReg cr) 8831 %{ 8832 match(Set rax (DivI rax div)); 8833 effect(KILL rdx, KILL cr); 8834 8835 ins_cost(30*100+10*100); // XXX 8836 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 8837 "jne,s normal\n\t" 8838 "xorl rdx, rdx\n\t" 8839 "cmpl $div, -1\n\t" 8840 "je,s done\n" 8841 "normal: cdql\n\t" 8842 "idivl $div\n" 8843 "done:" %} 8844 ins_encode(cdql_enc(div)); 8845 ins_pipe(ialu_reg_reg_alu0); 8846 %} 8847 8848 instruct divL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 8849 rFlagsReg cr) 8850 %{ 8851 match(Set rax (DivL rax div)); 8852 effect(KILL rdx, KILL cr); 8853 8854 ins_cost(30*100+10*100); // XXX 8855 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 8856 "cmpq rax, rdx\n\t" 8857 "jne,s normal\n\t" 8858 "xorl rdx, rdx\n\t" 8859 "cmpq $div, -1\n\t" 8860 "je,s done\n" 8861 "normal: cdqq\n\t" 8862 "idivq $div\n" 8863 "done:" %} 8864 ins_encode(cdqq_enc(div)); 8865 ins_pipe(ialu_reg_reg_alu0); 8866 %} 8867 8868 instruct udivI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, rFlagsReg cr) 8869 %{ 8870 match(Set rax (UDivI rax div)); 8871 effect(KILL rdx, KILL cr); 8872 8873 ins_cost(300); 8874 format %{ "udivl $rax,$rax,$div\t# UDivI\n" %} 8875 ins_encode %{ 8876 __ udivI($rax$$Register, $div$$Register, $rdx$$Register); 8877 %} 8878 ins_pipe(ialu_reg_reg_alu0); 8879 %} 8880 8881 instruct udivL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, rFlagsReg cr) 8882 %{ 8883 match(Set rax (UDivL rax div)); 8884 effect(KILL rdx, KILL cr); 8885 8886 ins_cost(300); 8887 format %{ "udivq $rax,$rax,$div\t# UDivL\n" %} 8888 ins_encode %{ 8889 __ udivL($rax$$Register, $div$$Register, $rdx$$Register); 8890 %} 8891 ins_pipe(ialu_reg_reg_alu0); 8892 %} 8893 8894 // Integer DIVMOD with Register, both quotient and mod results 8895 instruct divModI_rReg_divmod(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 8896 rFlagsReg cr) 8897 %{ 8898 match(DivModI rax div); 8899 effect(KILL cr); 8900 8901 ins_cost(30*100+10*100); // XXX 8902 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 8903 "jne,s normal\n\t" 8904 "xorl rdx, rdx\n\t" 8905 "cmpl $div, -1\n\t" 8906 "je,s done\n" 8907 "normal: cdql\n\t" 8908 "idivl $div\n" 8909 "done:" %} 8910 ins_encode(cdql_enc(div)); 8911 ins_pipe(pipe_slow); 8912 %} 8913 8914 // Long DIVMOD with Register, both quotient and mod results 8915 instruct divModL_rReg_divmod(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 8916 rFlagsReg cr) 8917 %{ 8918 match(DivModL rax div); 8919 effect(KILL cr); 8920 8921 ins_cost(30*100+10*100); // XXX 8922 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 8923 "cmpq rax, rdx\n\t" 8924 "jne,s normal\n\t" 8925 "xorl rdx, rdx\n\t" 8926 "cmpq $div, -1\n\t" 8927 "je,s done\n" 8928 "normal: cdqq\n\t" 8929 "idivq $div\n" 8930 "done:" %} 8931 ins_encode(cdqq_enc(div)); 8932 ins_pipe(pipe_slow); 8933 %} 8934 8935 // Unsigned integer DIVMOD with Register, both quotient and mod results 8936 instruct udivModI_rReg_divmod(rax_RegI rax, no_rax_rdx_RegI tmp, rdx_RegI rdx, 8937 no_rax_rdx_RegI div, rFlagsReg cr) 8938 %{ 8939 match(UDivModI rax div); 8940 effect(TEMP tmp, KILL cr); 8941 8942 ins_cost(300); 8943 format %{ "udivl $rax,$rax,$div\t# begin UDivModI\n\t" 8944 "umodl $rdx,$rax,$div\t! using $tmp as TEMP # end UDivModI\n" 8945 %} 8946 ins_encode %{ 8947 __ udivmodI($rax$$Register, $div$$Register, $rdx$$Register, $tmp$$Register); 8948 %} 8949 ins_pipe(pipe_slow); 8950 %} 8951 8952 // Unsigned long DIVMOD with Register, both quotient and mod results 8953 instruct udivModL_rReg_divmod(rax_RegL rax, no_rax_rdx_RegL tmp, rdx_RegL rdx, 8954 no_rax_rdx_RegL div, rFlagsReg cr) 8955 %{ 8956 match(UDivModL rax div); 8957 effect(TEMP tmp, KILL cr); 8958 8959 ins_cost(300); 8960 format %{ "udivq $rax,$rax,$div\t# begin UDivModL\n\t" 8961 "umodq $rdx,$rax,$div\t! using $tmp as TEMP # end UDivModL\n" 8962 %} 8963 ins_encode %{ 8964 __ udivmodL($rax$$Register, $div$$Register, $rdx$$Register, $tmp$$Register); 8965 %} 8966 ins_pipe(pipe_slow); 8967 %} 8968 8969 instruct modI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, 8970 rFlagsReg cr) 8971 %{ 8972 match(Set rdx (ModI rax div)); 8973 effect(KILL rax, KILL cr); 8974 8975 ins_cost(300); // XXX 8976 format %{ "cmpl rax, 0x80000000\t# irem\n\t" 8977 "jne,s normal\n\t" 8978 "xorl rdx, rdx\n\t" 8979 "cmpl $div, -1\n\t" 8980 "je,s done\n" 8981 "normal: cdql\n\t" 8982 "idivl $div\n" 8983 "done:" %} 8984 ins_encode(cdql_enc(div)); 8985 ins_pipe(ialu_reg_reg_alu0); 8986 %} 8987 8988 instruct modL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, 8989 rFlagsReg cr) 8990 %{ 8991 match(Set rdx (ModL rax div)); 8992 effect(KILL rax, KILL cr); 8993 8994 ins_cost(300); // XXX 8995 format %{ "movq rdx, 0x8000000000000000\t# lrem\n\t" 8996 "cmpq rax, rdx\n\t" 8997 "jne,s normal\n\t" 8998 "xorl rdx, rdx\n\t" 8999 "cmpq $div, -1\n\t" 9000 "je,s done\n" 9001 "normal: cdqq\n\t" 9002 "idivq $div\n" 9003 "done:" %} 9004 ins_encode(cdqq_enc(div)); 9005 ins_pipe(ialu_reg_reg_alu0); 9006 %} 9007 9008 instruct umodI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, rFlagsReg cr) 9009 %{ 9010 match(Set rdx (UModI rax div)); 9011 effect(KILL rax, KILL cr); 9012 9013 ins_cost(300); 9014 format %{ "umodl $rdx,$rax,$div\t# UModI\n" %} 9015 ins_encode %{ 9016 __ umodI($rax$$Register, $div$$Register, $rdx$$Register); 9017 %} 9018 ins_pipe(ialu_reg_reg_alu0); 9019 %} 9020 9021 instruct umodL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, rFlagsReg cr) 9022 %{ 9023 match(Set rdx (UModL rax div)); 9024 effect(KILL rax, KILL cr); 9025 9026 ins_cost(300); 9027 format %{ "umodq $rdx,$rax,$div\t# UModL\n" %} 9028 ins_encode %{ 9029 __ umodL($rax$$Register, $div$$Register, $rdx$$Register); 9030 %} 9031 ins_pipe(ialu_reg_reg_alu0); 9032 %} 9033 9034 // Integer Shift Instructions 9035 // Shift Left by one, two, three 9036 instruct salI_rReg_immI2(rRegI dst, immI2 shift, rFlagsReg cr) 9037 %{ 9038 predicate(!UseAPX); 9039 match(Set dst (LShiftI dst shift)); 9040 effect(KILL cr); 9041 9042 format %{ "sall $dst, $shift" %} 9043 ins_encode %{ 9044 __ sall($dst$$Register, $shift$$constant); 9045 %} 9046 ins_pipe(ialu_reg); 9047 %} 9048 9049 // Shift Left by one, two, three 9050 instruct salI_rReg_immI2_ndd(rRegI dst, rRegI src, immI2 shift, rFlagsReg cr) 9051 %{ 9052 predicate(UseAPX); 9053 match(Set dst (LShiftI src shift)); 9054 effect(KILL cr); 9055 9056 format %{ "esall $dst, $src, $shift\t# int(ndd)" %} 9057 ins_encode %{ 9058 __ esall($dst$$Register, $src$$Register, $shift$$constant, false); 9059 %} 9060 ins_pipe(ialu_reg); 9061 %} 9062 9063 // Shift Left by 8-bit immediate 9064 instruct salI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 9065 %{ 9066 predicate(!UseAPX); 9067 match(Set dst (LShiftI dst shift)); 9068 effect(KILL cr); 9069 9070 format %{ "sall $dst, $shift" %} 9071 ins_encode %{ 9072 __ sall($dst$$Register, $shift$$constant); 9073 %} 9074 ins_pipe(ialu_reg); 9075 %} 9076 9077 // Shift Left by 8-bit immediate 9078 instruct salI_rReg_imm_ndd(rRegI dst, rRegI src, immI8 shift, rFlagsReg cr) 9079 %{ 9080 predicate(UseAPX); 9081 match(Set dst (LShiftI src shift)); 9082 effect(KILL cr); 9083 9084 format %{ "esall $dst, $src, $shift\t# int (ndd)" %} 9085 ins_encode %{ 9086 __ esall($dst$$Register, $src$$Register, $shift$$constant, false); 9087 %} 9088 ins_pipe(ialu_reg); 9089 %} 9090 9091 instruct salI_rReg_mem_imm_ndd(rRegI dst, memory src, immI8 shift, rFlagsReg cr) 9092 %{ 9093 predicate(UseAPX); 9094 match(Set dst (LShiftI (LoadI src) shift)); 9095 effect(KILL cr); 9096 9097 format %{ "esall $dst, $src, $shift\t# int (ndd)" %} 9098 ins_encode %{ 9099 __ esall($dst$$Register, $src$$Address, $shift$$constant, false); 9100 %} 9101 ins_pipe(ialu_reg); 9102 %} 9103 9104 // Shift Left by 8-bit immediate 9105 instruct salI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 9106 %{ 9107 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 9108 effect(KILL cr); 9109 9110 format %{ "sall $dst, $shift" %} 9111 ins_encode %{ 9112 __ sall($dst$$Address, $shift$$constant); 9113 %} 9114 ins_pipe(ialu_mem_imm); 9115 %} 9116 9117 // Shift Left by variable 9118 instruct salI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 9119 %{ 9120 predicate(!VM_Version::supports_bmi2()); 9121 match(Set dst (LShiftI dst shift)); 9122 effect(KILL cr); 9123 9124 format %{ "sall $dst, $shift" %} 9125 ins_encode %{ 9126 __ sall($dst$$Register); 9127 %} 9128 ins_pipe(ialu_reg_reg); 9129 %} 9130 9131 // Shift Left by variable 9132 instruct salI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 9133 %{ 9134 predicate(!VM_Version::supports_bmi2()); 9135 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 9136 effect(KILL cr); 9137 9138 format %{ "sall $dst, $shift" %} 9139 ins_encode %{ 9140 __ sall($dst$$Address); 9141 %} 9142 ins_pipe(ialu_mem_reg); 9143 %} 9144 9145 instruct salI_rReg_rReg(rRegI dst, rRegI src, rRegI shift) 9146 %{ 9147 predicate(VM_Version::supports_bmi2()); 9148 match(Set dst (LShiftI src shift)); 9149 9150 format %{ "shlxl $dst, $src, $shift" %} 9151 ins_encode %{ 9152 __ shlxl($dst$$Register, $src$$Register, $shift$$Register); 9153 %} 9154 ins_pipe(ialu_reg_reg); 9155 %} 9156 9157 instruct salI_mem_rReg(rRegI dst, memory src, rRegI shift) 9158 %{ 9159 predicate(VM_Version::supports_bmi2()); 9160 match(Set dst (LShiftI (LoadI src) shift)); 9161 ins_cost(175); 9162 format %{ "shlxl $dst, $src, $shift" %} 9163 ins_encode %{ 9164 __ shlxl($dst$$Register, $src$$Address, $shift$$Register); 9165 %} 9166 ins_pipe(ialu_reg_mem); 9167 %} 9168 9169 // Arithmetic Shift Right by 8-bit immediate 9170 instruct sarI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 9171 %{ 9172 predicate(!UseAPX); 9173 match(Set dst (RShiftI dst shift)); 9174 effect(KILL cr); 9175 9176 format %{ "sarl $dst, $shift" %} 9177 ins_encode %{ 9178 __ sarl($dst$$Register, $shift$$constant); 9179 %} 9180 ins_pipe(ialu_mem_imm); 9181 %} 9182 9183 // Arithmetic Shift Right by 8-bit immediate 9184 instruct sarI_rReg_imm_ndd(rRegI dst, rRegI src, immI8 shift, rFlagsReg cr) 9185 %{ 9186 predicate(UseAPX); 9187 match(Set dst (RShiftI src shift)); 9188 effect(KILL cr); 9189 9190 format %{ "esarl $dst, $src, $shift\t# int (ndd)" %} 9191 ins_encode %{ 9192 __ esarl($dst$$Register, $src$$Register, $shift$$constant, false); 9193 %} 9194 ins_pipe(ialu_mem_imm); 9195 %} 9196 9197 instruct sarI_rReg_mem_imm_ndd(rRegI dst, memory src, immI8 shift, rFlagsReg cr) 9198 %{ 9199 predicate(UseAPX); 9200 match(Set dst (RShiftI (LoadI src) shift)); 9201 effect(KILL cr); 9202 9203 format %{ "esarl $dst, $src, $shift\t# int (ndd)" %} 9204 ins_encode %{ 9205 __ esarl($dst$$Register, $src$$Address, $shift$$constant, false); 9206 %} 9207 ins_pipe(ialu_mem_imm); 9208 %} 9209 9210 // Arithmetic Shift Right by 8-bit immediate 9211 instruct sarI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 9212 %{ 9213 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 9214 effect(KILL cr); 9215 9216 format %{ "sarl $dst, $shift" %} 9217 ins_encode %{ 9218 __ sarl($dst$$Address, $shift$$constant); 9219 %} 9220 ins_pipe(ialu_mem_imm); 9221 %} 9222 9223 // Arithmetic Shift Right by variable 9224 instruct sarI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 9225 %{ 9226 predicate(!VM_Version::supports_bmi2()); 9227 match(Set dst (RShiftI dst shift)); 9228 effect(KILL cr); 9229 9230 format %{ "sarl $dst, $shift" %} 9231 ins_encode %{ 9232 __ sarl($dst$$Register); 9233 %} 9234 ins_pipe(ialu_reg_reg); 9235 %} 9236 9237 // Arithmetic Shift Right by variable 9238 instruct sarI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 9239 %{ 9240 predicate(!VM_Version::supports_bmi2()); 9241 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 9242 effect(KILL cr); 9243 9244 format %{ "sarl $dst, $shift" %} 9245 ins_encode %{ 9246 __ sarl($dst$$Address); 9247 %} 9248 ins_pipe(ialu_mem_reg); 9249 %} 9250 9251 instruct sarI_rReg_rReg(rRegI dst, rRegI src, rRegI shift) 9252 %{ 9253 predicate(VM_Version::supports_bmi2()); 9254 match(Set dst (RShiftI src shift)); 9255 9256 format %{ "sarxl $dst, $src, $shift" %} 9257 ins_encode %{ 9258 __ sarxl($dst$$Register, $src$$Register, $shift$$Register); 9259 %} 9260 ins_pipe(ialu_reg_reg); 9261 %} 9262 9263 instruct sarI_mem_rReg(rRegI dst, memory src, rRegI shift) 9264 %{ 9265 predicate(VM_Version::supports_bmi2()); 9266 match(Set dst (RShiftI (LoadI src) shift)); 9267 ins_cost(175); 9268 format %{ "sarxl $dst, $src, $shift" %} 9269 ins_encode %{ 9270 __ sarxl($dst$$Register, $src$$Address, $shift$$Register); 9271 %} 9272 ins_pipe(ialu_reg_mem); 9273 %} 9274 9275 // Logical Shift Right by 8-bit immediate 9276 instruct shrI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 9277 %{ 9278 predicate(!UseAPX); 9279 match(Set dst (URShiftI dst shift)); 9280 effect(KILL cr); 9281 9282 format %{ "shrl $dst, $shift" %} 9283 ins_encode %{ 9284 __ shrl($dst$$Register, $shift$$constant); 9285 %} 9286 ins_pipe(ialu_reg); 9287 %} 9288 9289 // Logical Shift Right by 8-bit immediate 9290 instruct shrI_rReg_imm_ndd(rRegI dst, rRegI src, immI8 shift, rFlagsReg cr) 9291 %{ 9292 predicate(UseAPX); 9293 match(Set dst (URShiftI src shift)); 9294 effect(KILL cr); 9295 9296 format %{ "eshrl $dst, $src, $shift\t # int (ndd)" %} 9297 ins_encode %{ 9298 __ eshrl($dst$$Register, $src$$Register, $shift$$constant, false); 9299 %} 9300 ins_pipe(ialu_reg); 9301 %} 9302 9303 instruct shrI_rReg_mem_imm_ndd(rRegI dst, memory src, immI8 shift, rFlagsReg cr) 9304 %{ 9305 predicate(UseAPX); 9306 match(Set dst (URShiftI (LoadI src) shift)); 9307 effect(KILL cr); 9308 9309 format %{ "eshrl $dst, $src, $shift\t # int (ndd)" %} 9310 ins_encode %{ 9311 __ eshrl($dst$$Register, $src$$Address, $shift$$constant, false); 9312 %} 9313 ins_pipe(ialu_reg); 9314 %} 9315 9316 // Logical Shift Right by 8-bit immediate 9317 instruct shrI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 9318 %{ 9319 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 9320 effect(KILL cr); 9321 9322 format %{ "shrl $dst, $shift" %} 9323 ins_encode %{ 9324 __ shrl($dst$$Address, $shift$$constant); 9325 %} 9326 ins_pipe(ialu_mem_imm); 9327 %} 9328 9329 // Logical Shift Right by variable 9330 instruct shrI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 9331 %{ 9332 predicate(!VM_Version::supports_bmi2()); 9333 match(Set dst (URShiftI dst shift)); 9334 effect(KILL cr); 9335 9336 format %{ "shrl $dst, $shift" %} 9337 ins_encode %{ 9338 __ shrl($dst$$Register); 9339 %} 9340 ins_pipe(ialu_reg_reg); 9341 %} 9342 9343 // Logical Shift Right by variable 9344 instruct shrI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 9345 %{ 9346 predicate(!VM_Version::supports_bmi2()); 9347 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 9348 effect(KILL cr); 9349 9350 format %{ "shrl $dst, $shift" %} 9351 ins_encode %{ 9352 __ shrl($dst$$Address); 9353 %} 9354 ins_pipe(ialu_mem_reg); 9355 %} 9356 9357 instruct shrI_rReg_rReg(rRegI dst, rRegI src, rRegI shift) 9358 %{ 9359 predicate(VM_Version::supports_bmi2()); 9360 match(Set dst (URShiftI src shift)); 9361 9362 format %{ "shrxl $dst, $src, $shift" %} 9363 ins_encode %{ 9364 __ shrxl($dst$$Register, $src$$Register, $shift$$Register); 9365 %} 9366 ins_pipe(ialu_reg_reg); 9367 %} 9368 9369 instruct shrI_mem_rReg(rRegI dst, memory src, rRegI shift) 9370 %{ 9371 predicate(VM_Version::supports_bmi2()); 9372 match(Set dst (URShiftI (LoadI src) shift)); 9373 ins_cost(175); 9374 format %{ "shrxl $dst, $src, $shift" %} 9375 ins_encode %{ 9376 __ shrxl($dst$$Register, $src$$Address, $shift$$Register); 9377 %} 9378 ins_pipe(ialu_reg_mem); 9379 %} 9380 9381 // Long Shift Instructions 9382 // Shift Left by one, two, three 9383 instruct salL_rReg_immI2(rRegL dst, immI2 shift, rFlagsReg cr) 9384 %{ 9385 predicate(!UseAPX); 9386 match(Set dst (LShiftL dst shift)); 9387 effect(KILL cr); 9388 9389 format %{ "salq $dst, $shift" %} 9390 ins_encode %{ 9391 __ salq($dst$$Register, $shift$$constant); 9392 %} 9393 ins_pipe(ialu_reg); 9394 %} 9395 9396 // Shift Left by one, two, three 9397 instruct salL_rReg_immI2_ndd(rRegL dst, rRegL src, immI2 shift, rFlagsReg cr) 9398 %{ 9399 predicate(UseAPX); 9400 match(Set dst (LShiftL src shift)); 9401 effect(KILL cr); 9402 9403 format %{ "esalq $dst, $src, $shift\t# long (ndd)" %} 9404 ins_encode %{ 9405 __ esalq($dst$$Register, $src$$Register, $shift$$constant, false); 9406 %} 9407 ins_pipe(ialu_reg); 9408 %} 9409 9410 // Shift Left by 8-bit immediate 9411 instruct salL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 9412 %{ 9413 predicate(!UseAPX); 9414 match(Set dst (LShiftL dst shift)); 9415 effect(KILL cr); 9416 9417 format %{ "salq $dst, $shift" %} 9418 ins_encode %{ 9419 __ salq($dst$$Register, $shift$$constant); 9420 %} 9421 ins_pipe(ialu_reg); 9422 %} 9423 9424 // Shift Left by 8-bit immediate 9425 instruct salL_rReg_imm_ndd(rRegL dst, rRegL src, immI8 shift, rFlagsReg cr) 9426 %{ 9427 predicate(UseAPX); 9428 match(Set dst (LShiftL src shift)); 9429 effect(KILL cr); 9430 9431 format %{ "esalq $dst, $src, $shift\t# long (ndd)" %} 9432 ins_encode %{ 9433 __ esalq($dst$$Register, $src$$Register, $shift$$constant, false); 9434 %} 9435 ins_pipe(ialu_reg); 9436 %} 9437 9438 instruct salL_rReg_mem_imm_ndd(rRegL dst, memory src, immI8 shift, rFlagsReg cr) 9439 %{ 9440 predicate(UseAPX); 9441 match(Set dst (LShiftL (LoadL src) shift)); 9442 effect(KILL cr); 9443 9444 format %{ "esalq $dst, $src, $shift\t# long (ndd)" %} 9445 ins_encode %{ 9446 __ esalq($dst$$Register, $src$$Address, $shift$$constant, false); 9447 %} 9448 ins_pipe(ialu_reg); 9449 %} 9450 9451 // Shift Left by 8-bit immediate 9452 instruct salL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 9453 %{ 9454 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 9455 effect(KILL cr); 9456 9457 format %{ "salq $dst, $shift" %} 9458 ins_encode %{ 9459 __ salq($dst$$Address, $shift$$constant); 9460 %} 9461 ins_pipe(ialu_mem_imm); 9462 %} 9463 9464 // Shift Left by variable 9465 instruct salL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 9466 %{ 9467 predicate(!VM_Version::supports_bmi2()); 9468 match(Set dst (LShiftL dst shift)); 9469 effect(KILL cr); 9470 9471 format %{ "salq $dst, $shift" %} 9472 ins_encode %{ 9473 __ salq($dst$$Register); 9474 %} 9475 ins_pipe(ialu_reg_reg); 9476 %} 9477 9478 // Shift Left by variable 9479 instruct salL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 9480 %{ 9481 predicate(!VM_Version::supports_bmi2()); 9482 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 9483 effect(KILL cr); 9484 9485 format %{ "salq $dst, $shift" %} 9486 ins_encode %{ 9487 __ salq($dst$$Address); 9488 %} 9489 ins_pipe(ialu_mem_reg); 9490 %} 9491 9492 instruct salL_rReg_rReg(rRegL dst, rRegL src, rRegI shift) 9493 %{ 9494 predicate(VM_Version::supports_bmi2()); 9495 match(Set dst (LShiftL src shift)); 9496 9497 format %{ "shlxq $dst, $src, $shift" %} 9498 ins_encode %{ 9499 __ shlxq($dst$$Register, $src$$Register, $shift$$Register); 9500 %} 9501 ins_pipe(ialu_reg_reg); 9502 %} 9503 9504 instruct salL_mem_rReg(rRegL dst, memory src, rRegI shift) 9505 %{ 9506 predicate(VM_Version::supports_bmi2()); 9507 match(Set dst (LShiftL (LoadL src) shift)); 9508 ins_cost(175); 9509 format %{ "shlxq $dst, $src, $shift" %} 9510 ins_encode %{ 9511 __ shlxq($dst$$Register, $src$$Address, $shift$$Register); 9512 %} 9513 ins_pipe(ialu_reg_mem); 9514 %} 9515 9516 // Arithmetic Shift Right by 8-bit immediate 9517 instruct sarL_rReg_imm(rRegL dst, immI shift, rFlagsReg cr) 9518 %{ 9519 predicate(!UseAPX); 9520 match(Set dst (RShiftL dst shift)); 9521 effect(KILL cr); 9522 9523 format %{ "sarq $dst, $shift" %} 9524 ins_encode %{ 9525 __ sarq($dst$$Register, (unsigned char)($shift$$constant & 0x3F)); 9526 %} 9527 ins_pipe(ialu_mem_imm); 9528 %} 9529 9530 // Arithmetic Shift Right by 8-bit immediate 9531 instruct sarL_rReg_imm_ndd(rRegL dst, rRegL src, immI shift, rFlagsReg cr) 9532 %{ 9533 predicate(UseAPX); 9534 match(Set dst (RShiftL src shift)); 9535 effect(KILL cr); 9536 9537 format %{ "esarq $dst, $src, $shift\t# long (ndd)" %} 9538 ins_encode %{ 9539 __ esarq($dst$$Register, $src$$Register, (unsigned char)($shift$$constant & 0x3F), false); 9540 %} 9541 ins_pipe(ialu_mem_imm); 9542 %} 9543 9544 instruct sarL_rReg_mem_imm_ndd(rRegL dst, memory src, immI shift, rFlagsReg cr) 9545 %{ 9546 predicate(UseAPX); 9547 match(Set dst (RShiftL (LoadL src) shift)); 9548 effect(KILL cr); 9549 9550 format %{ "esarq $dst, $src, $shift\t# long (ndd)" %} 9551 ins_encode %{ 9552 __ esarq($dst$$Register, $src$$Address, (unsigned char)($shift$$constant & 0x3F), false); 9553 %} 9554 ins_pipe(ialu_mem_imm); 9555 %} 9556 9557 // Arithmetic Shift Right by 8-bit immediate 9558 instruct sarL_mem_imm(memory dst, immI shift, rFlagsReg cr) 9559 %{ 9560 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 9561 effect(KILL cr); 9562 9563 format %{ "sarq $dst, $shift" %} 9564 ins_encode %{ 9565 __ sarq($dst$$Address, (unsigned char)($shift$$constant & 0x3F)); 9566 %} 9567 ins_pipe(ialu_mem_imm); 9568 %} 9569 9570 // Arithmetic Shift Right by variable 9571 instruct sarL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 9572 %{ 9573 predicate(!VM_Version::supports_bmi2()); 9574 match(Set dst (RShiftL dst shift)); 9575 effect(KILL cr); 9576 9577 format %{ "sarq $dst, $shift" %} 9578 ins_encode %{ 9579 __ sarq($dst$$Register); 9580 %} 9581 ins_pipe(ialu_reg_reg); 9582 %} 9583 9584 // Arithmetic Shift Right by variable 9585 instruct sarL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 9586 %{ 9587 predicate(!VM_Version::supports_bmi2()); 9588 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 9589 effect(KILL cr); 9590 9591 format %{ "sarq $dst, $shift" %} 9592 ins_encode %{ 9593 __ sarq($dst$$Address); 9594 %} 9595 ins_pipe(ialu_mem_reg); 9596 %} 9597 9598 instruct sarL_rReg_rReg(rRegL dst, rRegL src, rRegI shift) 9599 %{ 9600 predicate(VM_Version::supports_bmi2()); 9601 match(Set dst (RShiftL src shift)); 9602 9603 format %{ "sarxq $dst, $src, $shift" %} 9604 ins_encode %{ 9605 __ sarxq($dst$$Register, $src$$Register, $shift$$Register); 9606 %} 9607 ins_pipe(ialu_reg_reg); 9608 %} 9609 9610 instruct sarL_mem_rReg(rRegL dst, memory src, rRegI shift) 9611 %{ 9612 predicate(VM_Version::supports_bmi2()); 9613 match(Set dst (RShiftL (LoadL src) shift)); 9614 ins_cost(175); 9615 format %{ "sarxq $dst, $src, $shift" %} 9616 ins_encode %{ 9617 __ sarxq($dst$$Register, $src$$Address, $shift$$Register); 9618 %} 9619 ins_pipe(ialu_reg_mem); 9620 %} 9621 9622 // Logical Shift Right by 8-bit immediate 9623 instruct shrL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 9624 %{ 9625 predicate(!UseAPX); 9626 match(Set dst (URShiftL dst shift)); 9627 effect(KILL cr); 9628 9629 format %{ "shrq $dst, $shift" %} 9630 ins_encode %{ 9631 __ shrq($dst$$Register, $shift$$constant); 9632 %} 9633 ins_pipe(ialu_reg); 9634 %} 9635 9636 // Logical Shift Right by 8-bit immediate 9637 instruct shrL_rReg_imm_ndd(rRegL dst, rRegL src, immI8 shift, rFlagsReg cr) 9638 %{ 9639 predicate(UseAPX); 9640 match(Set dst (URShiftL src shift)); 9641 effect(KILL cr); 9642 9643 format %{ "eshrq $dst, $src, $shift\t# long (ndd)" %} 9644 ins_encode %{ 9645 __ eshrq($dst$$Register, $src$$Register, $shift$$constant, false); 9646 %} 9647 ins_pipe(ialu_reg); 9648 %} 9649 9650 instruct shrL_rReg_mem_imm_ndd(rRegL dst, memory src, immI8 shift, rFlagsReg cr) 9651 %{ 9652 predicate(UseAPX); 9653 match(Set dst (URShiftL (LoadL src) shift)); 9654 effect(KILL cr); 9655 9656 format %{ "eshrq $dst, $src, $shift\t# long (ndd)" %} 9657 ins_encode %{ 9658 __ eshrq($dst$$Register, $src$$Address, $shift$$constant, false); 9659 %} 9660 ins_pipe(ialu_reg); 9661 %} 9662 9663 // Logical Shift Right by 8-bit immediate 9664 instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 9665 %{ 9666 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 9667 effect(KILL cr); 9668 9669 format %{ "shrq $dst, $shift" %} 9670 ins_encode %{ 9671 __ shrq($dst$$Address, $shift$$constant); 9672 %} 9673 ins_pipe(ialu_mem_imm); 9674 %} 9675 9676 // Logical Shift Right by variable 9677 instruct shrL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 9678 %{ 9679 predicate(!VM_Version::supports_bmi2()); 9680 match(Set dst (URShiftL dst shift)); 9681 effect(KILL cr); 9682 9683 format %{ "shrq $dst, $shift" %} 9684 ins_encode %{ 9685 __ shrq($dst$$Register); 9686 %} 9687 ins_pipe(ialu_reg_reg); 9688 %} 9689 9690 // Logical Shift Right by variable 9691 instruct shrL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 9692 %{ 9693 predicate(!VM_Version::supports_bmi2()); 9694 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 9695 effect(KILL cr); 9696 9697 format %{ "shrq $dst, $shift" %} 9698 ins_encode %{ 9699 __ shrq($dst$$Address); 9700 %} 9701 ins_pipe(ialu_mem_reg); 9702 %} 9703 9704 instruct shrL_rReg_rReg(rRegL dst, rRegL src, rRegI shift) 9705 %{ 9706 predicate(VM_Version::supports_bmi2()); 9707 match(Set dst (URShiftL src shift)); 9708 9709 format %{ "shrxq $dst, $src, $shift" %} 9710 ins_encode %{ 9711 __ shrxq($dst$$Register, $src$$Register, $shift$$Register); 9712 %} 9713 ins_pipe(ialu_reg_reg); 9714 %} 9715 9716 instruct shrL_mem_rReg(rRegL dst, memory src, rRegI shift) 9717 %{ 9718 predicate(VM_Version::supports_bmi2()); 9719 match(Set dst (URShiftL (LoadL src) shift)); 9720 ins_cost(175); 9721 format %{ "shrxq $dst, $src, $shift" %} 9722 ins_encode %{ 9723 __ shrxq($dst$$Register, $src$$Address, $shift$$Register); 9724 %} 9725 ins_pipe(ialu_reg_mem); 9726 %} 9727 9728 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24. 9729 // This idiom is used by the compiler for the i2b bytecode. 9730 instruct i2b(rRegI dst, rRegI src, immI_24 twentyfour) 9731 %{ 9732 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour)); 9733 9734 format %{ "movsbl $dst, $src\t# i2b" %} 9735 ins_encode %{ 9736 __ movsbl($dst$$Register, $src$$Register); 9737 %} 9738 ins_pipe(ialu_reg_reg); 9739 %} 9740 9741 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16. 9742 // This idiom is used by the compiler the i2s bytecode. 9743 instruct i2s(rRegI dst, rRegI src, immI_16 sixteen) 9744 %{ 9745 match(Set dst (RShiftI (LShiftI src sixteen) sixteen)); 9746 9747 format %{ "movswl $dst, $src\t# i2s" %} 9748 ins_encode %{ 9749 __ movswl($dst$$Register, $src$$Register); 9750 %} 9751 ins_pipe(ialu_reg_reg); 9752 %} 9753 9754 // ROL/ROR instructions 9755 9756 // Rotate left by constant. 9757 instruct rolI_immI8_legacy(rRegI dst, immI8 shift, rFlagsReg cr) 9758 %{ 9759 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 9760 match(Set dst (RotateLeft dst shift)); 9761 effect(KILL cr); 9762 format %{ "roll $dst, $shift" %} 9763 ins_encode %{ 9764 __ roll($dst$$Register, $shift$$constant); 9765 %} 9766 ins_pipe(ialu_reg); 9767 %} 9768 9769 instruct rolI_immI8(rRegI dst, rRegI src, immI8 shift) 9770 %{ 9771 predicate(!UseAPX && VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 9772 match(Set dst (RotateLeft src shift)); 9773 format %{ "rolxl $dst, $src, $shift" %} 9774 ins_encode %{ 9775 int shift = 32 - ($shift$$constant & 31); 9776 __ rorxl($dst$$Register, $src$$Register, shift); 9777 %} 9778 ins_pipe(ialu_reg_reg); 9779 %} 9780 9781 instruct rolI_mem_immI8(rRegI dst, memory src, immI8 shift) 9782 %{ 9783 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 9784 match(Set dst (RotateLeft (LoadI src) shift)); 9785 ins_cost(175); 9786 format %{ "rolxl $dst, $src, $shift" %} 9787 ins_encode %{ 9788 int shift = 32 - ($shift$$constant & 31); 9789 __ rorxl($dst$$Register, $src$$Address, shift); 9790 %} 9791 ins_pipe(ialu_reg_mem); 9792 %} 9793 9794 // Rotate Left by variable 9795 instruct rolI_rReg_Var(rRegI dst, rcx_RegI shift, rFlagsReg cr) 9796 %{ 9797 predicate(!UseAPX && n->bottom_type()->basic_type() == T_INT); 9798 match(Set dst (RotateLeft dst shift)); 9799 effect(KILL cr); 9800 format %{ "roll $dst, $shift" %} 9801 ins_encode %{ 9802 __ roll($dst$$Register); 9803 %} 9804 ins_pipe(ialu_reg_reg); 9805 %} 9806 9807 // Rotate Left by variable 9808 instruct rolI_rReg_Var_ndd(rRegI dst, rRegI src, rcx_RegI shift, rFlagsReg cr) 9809 %{ 9810 predicate(UseAPX && n->bottom_type()->basic_type() == T_INT); 9811 match(Set dst (RotateLeft src shift)); 9812 effect(KILL cr); 9813 9814 format %{ "eroll $dst, $src, $shift\t# rotate left (int ndd)" %} 9815 ins_encode %{ 9816 __ eroll($dst$$Register, $src$$Register, false); 9817 %} 9818 ins_pipe(ialu_reg_reg); 9819 %} 9820 9821 // Rotate Right by constant. 9822 instruct rorI_immI8_legacy(rRegI dst, immI8 shift, rFlagsReg cr) 9823 %{ 9824 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 9825 match(Set dst (RotateRight dst shift)); 9826 effect(KILL cr); 9827 format %{ "rorl $dst, $shift" %} 9828 ins_encode %{ 9829 __ rorl($dst$$Register, $shift$$constant); 9830 %} 9831 ins_pipe(ialu_reg); 9832 %} 9833 9834 // Rotate Right by constant. 9835 instruct rorI_immI8(rRegI dst, rRegI src, immI8 shift) 9836 %{ 9837 predicate(!UseAPX && VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 9838 match(Set dst (RotateRight src shift)); 9839 format %{ "rorxl $dst, $src, $shift" %} 9840 ins_encode %{ 9841 __ rorxl($dst$$Register, $src$$Register, $shift$$constant); 9842 %} 9843 ins_pipe(ialu_reg_reg); 9844 %} 9845 9846 instruct rorI_mem_immI8(rRegI dst, memory src, immI8 shift) 9847 %{ 9848 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 9849 match(Set dst (RotateRight (LoadI src) shift)); 9850 ins_cost(175); 9851 format %{ "rorxl $dst, $src, $shift" %} 9852 ins_encode %{ 9853 __ rorxl($dst$$Register, $src$$Address, $shift$$constant); 9854 %} 9855 ins_pipe(ialu_reg_mem); 9856 %} 9857 9858 // Rotate Right by variable 9859 instruct rorI_rReg_Var(rRegI dst, rcx_RegI shift, rFlagsReg cr) 9860 %{ 9861 predicate(!UseAPX && n->bottom_type()->basic_type() == T_INT); 9862 match(Set dst (RotateRight dst shift)); 9863 effect(KILL cr); 9864 format %{ "rorl $dst, $shift" %} 9865 ins_encode %{ 9866 __ rorl($dst$$Register); 9867 %} 9868 ins_pipe(ialu_reg_reg); 9869 %} 9870 9871 // Rotate Right by variable 9872 instruct rorI_rReg_Var_ndd(rRegI dst, rRegI src, rcx_RegI shift, rFlagsReg cr) 9873 %{ 9874 predicate(UseAPX && n->bottom_type()->basic_type() == T_INT); 9875 match(Set dst (RotateRight src shift)); 9876 effect(KILL cr); 9877 9878 format %{ "erorl $dst, $src, $shift\t# rotate right(int ndd)" %} 9879 ins_encode %{ 9880 __ erorl($dst$$Register, $src$$Register, false); 9881 %} 9882 ins_pipe(ialu_reg_reg); 9883 %} 9884 9885 // Rotate Left by constant. 9886 instruct rolL_immI8_legacy(rRegL dst, immI8 shift, rFlagsReg cr) 9887 %{ 9888 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 9889 match(Set dst (RotateLeft dst shift)); 9890 effect(KILL cr); 9891 format %{ "rolq $dst, $shift" %} 9892 ins_encode %{ 9893 __ rolq($dst$$Register, $shift$$constant); 9894 %} 9895 ins_pipe(ialu_reg); 9896 %} 9897 9898 instruct rolL_immI8(rRegL dst, rRegL src, immI8 shift) 9899 %{ 9900 predicate(!UseAPX && VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 9901 match(Set dst (RotateLeft src shift)); 9902 format %{ "rolxq $dst, $src, $shift" %} 9903 ins_encode %{ 9904 int shift = 64 - ($shift$$constant & 63); 9905 __ rorxq($dst$$Register, $src$$Register, shift); 9906 %} 9907 ins_pipe(ialu_reg_reg); 9908 %} 9909 9910 instruct rolL_mem_immI8(rRegL dst, memory src, immI8 shift) 9911 %{ 9912 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 9913 match(Set dst (RotateLeft (LoadL src) shift)); 9914 ins_cost(175); 9915 format %{ "rolxq $dst, $src, $shift" %} 9916 ins_encode %{ 9917 int shift = 64 - ($shift$$constant & 63); 9918 __ rorxq($dst$$Register, $src$$Address, shift); 9919 %} 9920 ins_pipe(ialu_reg_mem); 9921 %} 9922 9923 // Rotate Left by variable 9924 instruct rolL_rReg_Var(rRegL dst, rcx_RegI shift, rFlagsReg cr) 9925 %{ 9926 predicate(!UseAPX && n->bottom_type()->basic_type() == T_LONG); 9927 match(Set dst (RotateLeft dst shift)); 9928 effect(KILL cr); 9929 format %{ "rolq $dst, $shift" %} 9930 ins_encode %{ 9931 __ rolq($dst$$Register); 9932 %} 9933 ins_pipe(ialu_reg_reg); 9934 %} 9935 9936 // Rotate Left by variable 9937 instruct rolL_rReg_Var_ndd(rRegL dst, rRegL src, rcx_RegI shift, rFlagsReg cr) 9938 %{ 9939 predicate(UseAPX && n->bottom_type()->basic_type() == T_LONG); 9940 match(Set dst (RotateLeft src shift)); 9941 effect(KILL cr); 9942 9943 format %{ "erolq $dst, $src, $shift\t# rotate left(long ndd)" %} 9944 ins_encode %{ 9945 __ erolq($dst$$Register, $src$$Register, false); 9946 %} 9947 ins_pipe(ialu_reg_reg); 9948 %} 9949 9950 // Rotate Right by constant. 9951 instruct rorL_immI8_legacy(rRegL dst, immI8 shift, rFlagsReg cr) 9952 %{ 9953 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 9954 match(Set dst (RotateRight dst shift)); 9955 effect(KILL cr); 9956 format %{ "rorq $dst, $shift" %} 9957 ins_encode %{ 9958 __ rorq($dst$$Register, $shift$$constant); 9959 %} 9960 ins_pipe(ialu_reg); 9961 %} 9962 9963 // Rotate Right by constant 9964 instruct rorL_immI8(rRegL dst, rRegL src, immI8 shift) 9965 %{ 9966 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 9967 match(Set dst (RotateRight src shift)); 9968 format %{ "rorxq $dst, $src, $shift" %} 9969 ins_encode %{ 9970 __ rorxq($dst$$Register, $src$$Register, $shift$$constant); 9971 %} 9972 ins_pipe(ialu_reg_reg); 9973 %} 9974 9975 instruct rorL_mem_immI8(rRegL dst, memory src, immI8 shift) 9976 %{ 9977 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 9978 match(Set dst (RotateRight (LoadL src) shift)); 9979 ins_cost(175); 9980 format %{ "rorxq $dst, $src, $shift" %} 9981 ins_encode %{ 9982 __ rorxq($dst$$Register, $src$$Address, $shift$$constant); 9983 %} 9984 ins_pipe(ialu_reg_mem); 9985 %} 9986 9987 // Rotate Right by variable 9988 instruct rorL_rReg_Var(rRegL dst, rcx_RegI shift, rFlagsReg cr) 9989 %{ 9990 predicate(!UseAPX && n->bottom_type()->basic_type() == T_LONG); 9991 match(Set dst (RotateRight dst shift)); 9992 effect(KILL cr); 9993 format %{ "rorq $dst, $shift" %} 9994 ins_encode %{ 9995 __ rorq($dst$$Register); 9996 %} 9997 ins_pipe(ialu_reg_reg); 9998 %} 9999 10000 // Rotate Right by variable 10001 instruct rorL_rReg_Var_ndd(rRegL dst, rRegL src, rcx_RegI shift, rFlagsReg cr) 10002 %{ 10003 predicate(UseAPX && n->bottom_type()->basic_type() == T_LONG); 10004 match(Set dst (RotateRight src shift)); 10005 effect(KILL cr); 10006 10007 format %{ "erorq $dst, $src, $shift\t# rotate right(long ndd)" %} 10008 ins_encode %{ 10009 __ erorq($dst$$Register, $src$$Register, false); 10010 %} 10011 ins_pipe(ialu_reg_reg); 10012 %} 10013 10014 //----------------------------- CompressBits/ExpandBits ------------------------ 10015 10016 instruct compressBitsL_reg(rRegL dst, rRegL src, rRegL mask) %{ 10017 predicate(n->bottom_type()->isa_long()); 10018 match(Set dst (CompressBits src mask)); 10019 format %{ "pextq $dst, $src, $mask\t! parallel bit extract" %} 10020 ins_encode %{ 10021 __ pextq($dst$$Register, $src$$Register, $mask$$Register); 10022 %} 10023 ins_pipe( pipe_slow ); 10024 %} 10025 10026 instruct expandBitsL_reg(rRegL dst, rRegL src, rRegL mask) %{ 10027 predicate(n->bottom_type()->isa_long()); 10028 match(Set dst (ExpandBits src mask)); 10029 format %{ "pdepq $dst, $src, $mask\t! parallel bit deposit" %} 10030 ins_encode %{ 10031 __ pdepq($dst$$Register, $src$$Register, $mask$$Register); 10032 %} 10033 ins_pipe( pipe_slow ); 10034 %} 10035 10036 instruct compressBitsL_mem(rRegL dst, rRegL src, memory mask) %{ 10037 predicate(n->bottom_type()->isa_long()); 10038 match(Set dst (CompressBits src (LoadL mask))); 10039 format %{ "pextq $dst, $src, $mask\t! parallel bit extract" %} 10040 ins_encode %{ 10041 __ pextq($dst$$Register, $src$$Register, $mask$$Address); 10042 %} 10043 ins_pipe( pipe_slow ); 10044 %} 10045 10046 instruct expandBitsL_mem(rRegL dst, rRegL src, memory mask) %{ 10047 predicate(n->bottom_type()->isa_long()); 10048 match(Set dst (ExpandBits src (LoadL mask))); 10049 format %{ "pdepq $dst, $src, $mask\t! parallel bit deposit" %} 10050 ins_encode %{ 10051 __ pdepq($dst$$Register, $src$$Register, $mask$$Address); 10052 %} 10053 ins_pipe( pipe_slow ); 10054 %} 10055 10056 10057 // Logical Instructions 10058 10059 // Integer Logical Instructions 10060 10061 // And Instructions 10062 // And Register with Register 10063 instruct andI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 10064 %{ 10065 predicate(!UseAPX); 10066 match(Set dst (AndI dst src)); 10067 effect(KILL cr); 10068 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10069 10070 format %{ "andl $dst, $src\t# int" %} 10071 ins_encode %{ 10072 __ andl($dst$$Register, $src$$Register); 10073 %} 10074 ins_pipe(ialu_reg_reg); 10075 %} 10076 10077 // And Register with Register using New Data Destination (NDD) 10078 instruct andI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr) 10079 %{ 10080 predicate(UseAPX); 10081 match(Set dst (AndI src1 src2)); 10082 effect(KILL cr); 10083 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10084 10085 format %{ "eandl $dst, $src1, $src2\t# int ndd" %} 10086 ins_encode %{ 10087 __ eandl($dst$$Register, $src1$$Register, $src2$$Register, false); 10088 10089 %} 10090 ins_pipe(ialu_reg_reg); 10091 %} 10092 10093 // And Register with Immediate 255 10094 instruct andI_rReg_imm255(rRegI dst, rRegI src, immI_255 mask) 10095 %{ 10096 match(Set dst (AndI src mask)); 10097 10098 format %{ "movzbl $dst, $src\t# int & 0xFF" %} 10099 ins_encode %{ 10100 __ movzbl($dst$$Register, $src$$Register); 10101 %} 10102 ins_pipe(ialu_reg); 10103 %} 10104 10105 // And Register with Immediate 255 and promote to long 10106 instruct andI2L_rReg_imm255(rRegL dst, rRegI src, immI_255 mask) 10107 %{ 10108 match(Set dst (ConvI2L (AndI src mask))); 10109 10110 format %{ "movzbl $dst, $src\t# int & 0xFF -> long" %} 10111 ins_encode %{ 10112 __ movzbl($dst$$Register, $src$$Register); 10113 %} 10114 ins_pipe(ialu_reg); 10115 %} 10116 10117 // And Register with Immediate 65535 10118 instruct andI_rReg_imm65535(rRegI dst, rRegI src, immI_65535 mask) 10119 %{ 10120 match(Set dst (AndI src mask)); 10121 10122 format %{ "movzwl $dst, $src\t# int & 0xFFFF" %} 10123 ins_encode %{ 10124 __ movzwl($dst$$Register, $src$$Register); 10125 %} 10126 ins_pipe(ialu_reg); 10127 %} 10128 10129 // And Register with Immediate 65535 and promote to long 10130 instruct andI2L_rReg_imm65535(rRegL dst, rRegI src, immI_65535 mask) 10131 %{ 10132 match(Set dst (ConvI2L (AndI src mask))); 10133 10134 format %{ "movzwl $dst, $src\t# int & 0xFFFF -> long" %} 10135 ins_encode %{ 10136 __ movzwl($dst$$Register, $src$$Register); 10137 %} 10138 ins_pipe(ialu_reg); 10139 %} 10140 10141 // Can skip int2long conversions after AND with small bitmask 10142 instruct convI2LAndI_reg_immIbitmask(rRegL dst, rRegI src, immI_Pow2M1 mask, rRegI tmp, rFlagsReg cr) 10143 %{ 10144 predicate(VM_Version::supports_bmi2()); 10145 ins_cost(125); 10146 effect(TEMP tmp, KILL cr); 10147 match(Set dst (ConvI2L (AndI src mask))); 10148 format %{ "bzhiq $dst, $src, $mask \t# using $tmp as TEMP, int & immI_Pow2M1 -> long" %} 10149 ins_encode %{ 10150 __ movl($tmp$$Register, exact_log2($mask$$constant + 1)); 10151 __ bzhiq($dst$$Register, $src$$Register, $tmp$$Register); 10152 %} 10153 ins_pipe(ialu_reg_reg); 10154 %} 10155 10156 // And Register with Immediate 10157 instruct andI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 10158 %{ 10159 predicate(!UseAPX); 10160 match(Set dst (AndI dst src)); 10161 effect(KILL cr); 10162 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10163 10164 format %{ "andl $dst, $src\t# int" %} 10165 ins_encode %{ 10166 __ andl($dst$$Register, $src$$constant); 10167 %} 10168 ins_pipe(ialu_reg); 10169 %} 10170 10171 instruct andI_rReg_rReg_imm_ndd(rRegI dst, rRegI src1, immI src2, rFlagsReg cr) 10172 %{ 10173 predicate(UseAPX); 10174 match(Set dst (AndI src1 src2)); 10175 effect(KILL cr); 10176 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10177 10178 format %{ "eandl $dst, $src1, $src2\t# int ndd" %} 10179 ins_encode %{ 10180 __ eandl($dst$$Register, $src1$$Register, $src2$$constant, false); 10181 %} 10182 ins_pipe(ialu_reg); 10183 %} 10184 10185 instruct andI_rReg_mem_imm_ndd(rRegI dst, memory src1, immI src2, rFlagsReg cr) 10186 %{ 10187 predicate(UseAPX); 10188 match(Set dst (AndI (LoadI src1) src2)); 10189 effect(KILL cr); 10190 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10191 10192 format %{ "eandl $dst, $src1, $src2\t# int ndd" %} 10193 ins_encode %{ 10194 __ eandl($dst$$Register, $src1$$Address, $src2$$constant, false); 10195 %} 10196 ins_pipe(ialu_reg); 10197 %} 10198 10199 // And Register with Memory 10200 instruct andI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 10201 %{ 10202 predicate(!UseAPX); 10203 match(Set dst (AndI dst (LoadI 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 ins_cost(150); 10208 format %{ "andl $dst, $src\t# int" %} 10209 ins_encode %{ 10210 __ andl($dst$$Register, $src$$Address); 10211 %} 10212 ins_pipe(ialu_reg_mem); 10213 %} 10214 10215 instruct andI_rReg_rReg_mem_ndd(rRegI dst, rRegI src1, memory src2, rFlagsReg cr) 10216 %{ 10217 predicate(UseAPX); 10218 match(Set dst (AndI src1 (LoadI src2))); 10219 effect(KILL cr); 10220 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10221 10222 ins_cost(150); 10223 format %{ "eandl $dst, $src1, $src2\t# int ndd" %} 10224 ins_encode %{ 10225 __ eandl($dst$$Register, $src1$$Register, $src2$$Address, false); 10226 %} 10227 ins_pipe(ialu_reg_mem); 10228 %} 10229 10230 // And Memory with Register 10231 instruct andB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 10232 %{ 10233 match(Set dst (StoreB dst (AndI (LoadB dst) src))); 10234 effect(KILL cr); 10235 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10236 10237 ins_cost(150); 10238 format %{ "andb $dst, $src\t# byte" %} 10239 ins_encode %{ 10240 __ andb($dst$$Address, $src$$Register); 10241 %} 10242 ins_pipe(ialu_mem_reg); 10243 %} 10244 10245 instruct andI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 10246 %{ 10247 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 10248 effect(KILL cr); 10249 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10250 10251 ins_cost(150); 10252 format %{ "andl $dst, $src\t# int" %} 10253 ins_encode %{ 10254 __ andl($dst$$Address, $src$$Register); 10255 %} 10256 ins_pipe(ialu_mem_reg); 10257 %} 10258 10259 // And Memory with Immediate 10260 instruct andI_mem_imm(memory dst, immI src, rFlagsReg cr) 10261 %{ 10262 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 10263 effect(KILL cr); 10264 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10265 10266 ins_cost(125); 10267 format %{ "andl $dst, $src\t# int" %} 10268 ins_encode %{ 10269 __ andl($dst$$Address, $src$$constant); 10270 %} 10271 ins_pipe(ialu_mem_imm); 10272 %} 10273 10274 // BMI1 instructions 10275 instruct andnI_rReg_rReg_mem(rRegI dst, rRegI src1, memory src2, immI_M1 minus_1, rFlagsReg cr) %{ 10276 match(Set dst (AndI (XorI src1 minus_1) (LoadI src2))); 10277 predicate(UseBMI1Instructions); 10278 effect(KILL cr); 10279 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10280 10281 ins_cost(125); 10282 format %{ "andnl $dst, $src1, $src2" %} 10283 10284 ins_encode %{ 10285 __ andnl($dst$$Register, $src1$$Register, $src2$$Address); 10286 %} 10287 ins_pipe(ialu_reg_mem); 10288 %} 10289 10290 instruct andnI_rReg_rReg_rReg(rRegI dst, rRegI src1, rRegI src2, immI_M1 minus_1, rFlagsReg cr) %{ 10291 match(Set dst (AndI (XorI src1 minus_1) src2)); 10292 predicate(UseBMI1Instructions); 10293 effect(KILL cr); 10294 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10295 10296 format %{ "andnl $dst, $src1, $src2" %} 10297 10298 ins_encode %{ 10299 __ andnl($dst$$Register, $src1$$Register, $src2$$Register); 10300 %} 10301 ins_pipe(ialu_reg); 10302 %} 10303 10304 instruct blsiI_rReg_rReg(rRegI dst, rRegI src, immI_0 imm_zero, rFlagsReg cr) %{ 10305 match(Set dst (AndI (SubI imm_zero src) src)); 10306 predicate(UseBMI1Instructions); 10307 effect(KILL cr); 10308 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 10309 10310 format %{ "blsil $dst, $src" %} 10311 10312 ins_encode %{ 10313 __ blsil($dst$$Register, $src$$Register); 10314 %} 10315 ins_pipe(ialu_reg); 10316 %} 10317 10318 instruct blsiI_rReg_mem(rRegI dst, memory src, immI_0 imm_zero, rFlagsReg cr) %{ 10319 match(Set dst (AndI (SubI imm_zero (LoadI src) ) (LoadI src) )); 10320 predicate(UseBMI1Instructions); 10321 effect(KILL cr); 10322 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 10323 10324 ins_cost(125); 10325 format %{ "blsil $dst, $src" %} 10326 10327 ins_encode %{ 10328 __ blsil($dst$$Register, $src$$Address); 10329 %} 10330 ins_pipe(ialu_reg_mem); 10331 %} 10332 10333 instruct blsmskI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 10334 %{ 10335 match(Set dst (XorI (AddI (LoadI src) minus_1) (LoadI src) ) ); 10336 predicate(UseBMI1Instructions); 10337 effect(KILL cr); 10338 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 10339 10340 ins_cost(125); 10341 format %{ "blsmskl $dst, $src" %} 10342 10343 ins_encode %{ 10344 __ blsmskl($dst$$Register, $src$$Address); 10345 %} 10346 ins_pipe(ialu_reg_mem); 10347 %} 10348 10349 instruct blsmskI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 10350 %{ 10351 match(Set dst (XorI (AddI src minus_1) src)); 10352 predicate(UseBMI1Instructions); 10353 effect(KILL cr); 10354 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 10355 10356 format %{ "blsmskl $dst, $src" %} 10357 10358 ins_encode %{ 10359 __ blsmskl($dst$$Register, $src$$Register); 10360 %} 10361 10362 ins_pipe(ialu_reg); 10363 %} 10364 10365 instruct blsrI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 10366 %{ 10367 match(Set dst (AndI (AddI src minus_1) src) ); 10368 predicate(UseBMI1Instructions); 10369 effect(KILL cr); 10370 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 10371 10372 format %{ "blsrl $dst, $src" %} 10373 10374 ins_encode %{ 10375 __ blsrl($dst$$Register, $src$$Register); 10376 %} 10377 10378 ins_pipe(ialu_reg_mem); 10379 %} 10380 10381 instruct blsrI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 10382 %{ 10383 match(Set dst (AndI (AddI (LoadI src) minus_1) (LoadI src) ) ); 10384 predicate(UseBMI1Instructions); 10385 effect(KILL cr); 10386 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 10387 10388 ins_cost(125); 10389 format %{ "blsrl $dst, $src" %} 10390 10391 ins_encode %{ 10392 __ blsrl($dst$$Register, $src$$Address); 10393 %} 10394 10395 ins_pipe(ialu_reg); 10396 %} 10397 10398 // Or Instructions 10399 // Or Register with Register 10400 instruct orI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 10401 %{ 10402 predicate(!UseAPX); 10403 match(Set dst (OrI dst src)); 10404 effect(KILL cr); 10405 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10406 10407 format %{ "orl $dst, $src\t# int" %} 10408 ins_encode %{ 10409 __ orl($dst$$Register, $src$$Register); 10410 %} 10411 ins_pipe(ialu_reg_reg); 10412 %} 10413 10414 // Or Register with Register using New Data Destination (NDD) 10415 instruct orI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr) 10416 %{ 10417 predicate(UseAPX); 10418 match(Set dst (OrI src1 src2)); 10419 effect(KILL cr); 10420 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10421 10422 format %{ "eorl $dst, $src1, $src2\t# int ndd" %} 10423 ins_encode %{ 10424 __ eorl($dst$$Register, $src1$$Register, $src2$$Register, false); 10425 %} 10426 ins_pipe(ialu_reg_reg); 10427 %} 10428 10429 // Or Register with Immediate 10430 instruct orI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 10431 %{ 10432 predicate(!UseAPX); 10433 match(Set dst (OrI dst src)); 10434 effect(KILL cr); 10435 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10436 10437 format %{ "orl $dst, $src\t# int" %} 10438 ins_encode %{ 10439 __ orl($dst$$Register, $src$$constant); 10440 %} 10441 ins_pipe(ialu_reg); 10442 %} 10443 10444 instruct orI_rReg_rReg_imm_ndd(rRegI dst, rRegI src1, immI src2, rFlagsReg cr) 10445 %{ 10446 predicate(UseAPX); 10447 match(Set dst (OrI src1 src2)); 10448 effect(KILL cr); 10449 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10450 10451 format %{ "eorl $dst, $src1, $src2\t# int ndd" %} 10452 ins_encode %{ 10453 __ eorl($dst$$Register, $src1$$Register, $src2$$constant, false); 10454 %} 10455 ins_pipe(ialu_reg); 10456 %} 10457 10458 instruct orI_rReg_imm_rReg_ndd(rRegI dst, immI 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, $src2, $src1\t# int ndd" %} 10466 ins_encode %{ 10467 __ eorl($dst$$Register, $src2$$Register, $src1$$constant, false); 10468 %} 10469 ins_pipe(ialu_reg); 10470 %} 10471 10472 instruct orI_rReg_mem_imm_ndd(rRegI dst, memory src1, immI src2, rFlagsReg cr) 10473 %{ 10474 predicate(UseAPX); 10475 match(Set dst (OrI (LoadI src1) src2)); 10476 effect(KILL cr); 10477 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10478 10479 format %{ "eorl $dst, $src1, $src2\t# int ndd" %} 10480 ins_encode %{ 10481 __ eorl($dst$$Register, $src1$$Address, $src2$$constant, false); 10482 %} 10483 ins_pipe(ialu_reg); 10484 %} 10485 10486 // Or Register with Memory 10487 instruct orI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 10488 %{ 10489 predicate(!UseAPX); 10490 match(Set dst (OrI dst (LoadI src))); 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 ins_cost(150); 10495 format %{ "orl $dst, $src\t# int" %} 10496 ins_encode %{ 10497 __ orl($dst$$Register, $src$$Address); 10498 %} 10499 ins_pipe(ialu_reg_mem); 10500 %} 10501 10502 instruct orI_rReg_rReg_mem_ndd(rRegI dst, rRegI src1, memory src2, rFlagsReg cr) 10503 %{ 10504 predicate(UseAPX); 10505 match(Set dst (OrI src1 (LoadI src2))); 10506 effect(KILL cr); 10507 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10508 10509 ins_cost(150); 10510 format %{ "eorl $dst, $src1, $src2\t# int ndd" %} 10511 ins_encode %{ 10512 __ eorl($dst$$Register, $src1$$Register, $src2$$Address, false); 10513 %} 10514 ins_pipe(ialu_reg_mem); 10515 %} 10516 10517 // Or Memory with Register 10518 instruct orB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 10519 %{ 10520 match(Set dst (StoreB dst (OrI (LoadB dst) src))); 10521 effect(KILL cr); 10522 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10523 10524 ins_cost(150); 10525 format %{ "orb $dst, $src\t# byte" %} 10526 ins_encode %{ 10527 __ orb($dst$$Address, $src$$Register); 10528 %} 10529 ins_pipe(ialu_mem_reg); 10530 %} 10531 10532 instruct orI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 10533 %{ 10534 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 10535 effect(KILL cr); 10536 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10537 10538 ins_cost(150); 10539 format %{ "orl $dst, $src\t# int" %} 10540 ins_encode %{ 10541 __ orl($dst$$Address, $src$$Register); 10542 %} 10543 ins_pipe(ialu_mem_reg); 10544 %} 10545 10546 // Or Memory with Immediate 10547 instruct orI_mem_imm(memory dst, immI src, rFlagsReg cr) 10548 %{ 10549 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 10550 effect(KILL cr); 10551 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10552 10553 ins_cost(125); 10554 format %{ "orl $dst, $src\t# int" %} 10555 ins_encode %{ 10556 __ orl($dst$$Address, $src$$constant); 10557 %} 10558 ins_pipe(ialu_mem_imm); 10559 %} 10560 10561 // Xor Instructions 10562 // Xor Register with Register 10563 instruct xorI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 10564 %{ 10565 predicate(!UseAPX); 10566 match(Set dst (XorI dst src)); 10567 effect(KILL cr); 10568 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10569 10570 format %{ "xorl $dst, $src\t# int" %} 10571 ins_encode %{ 10572 __ xorl($dst$$Register, $src$$Register); 10573 %} 10574 ins_pipe(ialu_reg_reg); 10575 %} 10576 10577 // Xor Register with Register using New Data Destination (NDD) 10578 instruct xorI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr) 10579 %{ 10580 predicate(UseAPX); 10581 match(Set dst (XorI src1 src2)); 10582 effect(KILL cr); 10583 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10584 10585 format %{ "exorl $dst, $src1, $src2\t# int ndd" %} 10586 ins_encode %{ 10587 __ exorl($dst$$Register, $src1$$Register, $src2$$Register, false); 10588 %} 10589 ins_pipe(ialu_reg_reg); 10590 %} 10591 10592 // Xor Register with Immediate -1 10593 instruct xorI_rReg_im1(rRegI dst, immI_M1 imm) 10594 %{ 10595 predicate(!UseAPX); 10596 match(Set dst (XorI dst imm)); 10597 10598 format %{ "notl $dst" %} 10599 ins_encode %{ 10600 __ notl($dst$$Register); 10601 %} 10602 ins_pipe(ialu_reg); 10603 %} 10604 10605 instruct xorI_rReg_im1_ndd(rRegI dst, rRegI src, immI_M1 imm) 10606 %{ 10607 match(Set dst (XorI src imm)); 10608 predicate(UseAPX); 10609 10610 format %{ "enotl $dst, $src" %} 10611 ins_encode %{ 10612 __ enotl($dst$$Register, $src$$Register); 10613 %} 10614 ins_pipe(ialu_reg); 10615 %} 10616 10617 // Xor Register with Immediate 10618 instruct xorI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 10619 %{ 10620 predicate(!UseAPX); 10621 match(Set dst (XorI dst src)); 10622 effect(KILL cr); 10623 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10624 10625 format %{ "xorl $dst, $src\t# int" %} 10626 ins_encode %{ 10627 __ xorl($dst$$Register, $src$$constant); 10628 %} 10629 ins_pipe(ialu_reg); 10630 %} 10631 10632 instruct xorI_rReg_rReg_imm_ndd(rRegI dst, rRegI src1, immI src2, rFlagsReg cr) 10633 %{ 10634 predicate(UseAPX); 10635 match(Set dst (XorI src1 src2)); 10636 effect(KILL cr); 10637 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10638 10639 format %{ "exorl $dst, $src1, $src2\t# int ndd" %} 10640 ins_encode %{ 10641 __ exorl($dst$$Register, $src1$$Register, $src2$$constant, false); 10642 %} 10643 ins_pipe(ialu_reg); 10644 %} 10645 10646 // Xor Memory with Immediate 10647 instruct xorI_rReg_mem_imm_ndd(rRegI dst, memory src1, immI src2, rFlagsReg cr) 10648 %{ 10649 predicate(UseAPX); 10650 match(Set dst (XorI (LoadI src1) src2)); 10651 effect(KILL cr); 10652 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10653 10654 format %{ "exorl $dst, $src1, $src2\t# int ndd" %} 10655 ins_encode %{ 10656 __ exorl($dst$$Register, $src1$$Address, $src2$$constant, false); 10657 %} 10658 ins_pipe(ialu_reg); 10659 %} 10660 10661 // Xor Register with Memory 10662 instruct xorI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 10663 %{ 10664 predicate(!UseAPX); 10665 match(Set dst (XorI dst (LoadI src))); 10666 effect(KILL cr); 10667 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10668 10669 ins_cost(150); 10670 format %{ "xorl $dst, $src\t# int" %} 10671 ins_encode %{ 10672 __ xorl($dst$$Register, $src$$Address); 10673 %} 10674 ins_pipe(ialu_reg_mem); 10675 %} 10676 10677 instruct xorI_rReg_rReg_mem_ndd(rRegI dst, rRegI src1, memory src2, rFlagsReg cr) 10678 %{ 10679 predicate(UseAPX); 10680 match(Set dst (XorI src1 (LoadI src2))); 10681 effect(KILL cr); 10682 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10683 10684 ins_cost(150); 10685 format %{ "exorl $dst, $src1, $src2\t# int ndd" %} 10686 ins_encode %{ 10687 __ exorl($dst$$Register, $src1$$Register, $src2$$Address, false); 10688 %} 10689 ins_pipe(ialu_reg_mem); 10690 %} 10691 10692 instruct xorI_rReg_mem_rReg_ndd(rRegI dst, memory src1, rRegI src2, rFlagsReg cr) 10693 %{ 10694 predicate(UseAPX); 10695 match(Set dst (XorI (LoadI src1) src2)); 10696 effect(KILL cr); 10697 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10698 10699 ins_cost(150); 10700 format %{ "exorl $dst, $src1, $src2\t# int ndd" %} 10701 ins_encode %{ 10702 __ exorl($dst$$Register, $src1$$Address, $src2$$Register, false); 10703 %} 10704 ins_pipe(ialu_reg_mem); 10705 %} 10706 10707 // Xor Memory with Register 10708 instruct xorB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 10709 %{ 10710 match(Set dst (StoreB dst (XorI (LoadB dst) src))); 10711 effect(KILL cr); 10712 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10713 10714 ins_cost(150); 10715 format %{ "xorb $dst, $src\t# byte" %} 10716 ins_encode %{ 10717 __ xorb($dst$$Address, $src$$Register); 10718 %} 10719 ins_pipe(ialu_mem_reg); 10720 %} 10721 10722 instruct xorI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 10723 %{ 10724 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 10725 effect(KILL cr); 10726 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10727 10728 ins_cost(150); 10729 format %{ "xorl $dst, $src\t# int" %} 10730 ins_encode %{ 10731 __ xorl($dst$$Address, $src$$Register); 10732 %} 10733 ins_pipe(ialu_mem_reg); 10734 %} 10735 10736 // Xor Memory with Immediate 10737 instruct xorI_mem_imm(memory dst, immI src, rFlagsReg cr) 10738 %{ 10739 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 10740 effect(KILL cr); 10741 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10742 10743 ins_cost(125); 10744 format %{ "xorl $dst, $src\t# int" %} 10745 ins_encode %{ 10746 __ xorl($dst$$Address, $src$$constant); 10747 %} 10748 ins_pipe(ialu_mem_imm); 10749 %} 10750 10751 10752 // Long Logical Instructions 10753 10754 // And Instructions 10755 // And Register with Register 10756 instruct andL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 10757 %{ 10758 predicate(!UseAPX); 10759 match(Set dst (AndL dst src)); 10760 effect(KILL cr); 10761 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10762 10763 format %{ "andq $dst, $src\t# long" %} 10764 ins_encode %{ 10765 __ andq($dst$$Register, $src$$Register); 10766 %} 10767 ins_pipe(ialu_reg_reg); 10768 %} 10769 10770 // And Register with Register using New Data Destination (NDD) 10771 instruct andL_rReg_ndd(rRegL dst, rRegL src1, rRegL src2, rFlagsReg cr) 10772 %{ 10773 predicate(UseAPX); 10774 match(Set dst (AndL src1 src2)); 10775 effect(KILL cr); 10776 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10777 10778 format %{ "eandq $dst, $src1, $src2\t# long ndd" %} 10779 ins_encode %{ 10780 __ eandq($dst$$Register, $src1$$Register, $src2$$Register, false); 10781 10782 %} 10783 ins_pipe(ialu_reg_reg); 10784 %} 10785 10786 // And Register with Immediate 255 10787 instruct andL_rReg_imm255(rRegL dst, rRegL src, immL_255 mask) 10788 %{ 10789 match(Set dst (AndL src mask)); 10790 10791 format %{ "movzbl $dst, $src\t# long & 0xFF" %} 10792 ins_encode %{ 10793 // movzbl zeroes out the upper 32-bit and does not need REX.W 10794 __ movzbl($dst$$Register, $src$$Register); 10795 %} 10796 ins_pipe(ialu_reg); 10797 %} 10798 10799 // And Register with Immediate 65535 10800 instruct andL_rReg_imm65535(rRegL dst, rRegL src, immL_65535 mask) 10801 %{ 10802 match(Set dst (AndL src mask)); 10803 10804 format %{ "movzwl $dst, $src\t# long & 0xFFFF" %} 10805 ins_encode %{ 10806 // movzwl zeroes out the upper 32-bit and does not need REX.W 10807 __ movzwl($dst$$Register, $src$$Register); 10808 %} 10809 ins_pipe(ialu_reg); 10810 %} 10811 10812 // And Register with Immediate 10813 instruct andL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 10814 %{ 10815 predicate(!UseAPX); 10816 match(Set dst (AndL dst src)); 10817 effect(KILL cr); 10818 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10819 10820 format %{ "andq $dst, $src\t# long" %} 10821 ins_encode %{ 10822 __ andq($dst$$Register, $src$$constant); 10823 %} 10824 ins_pipe(ialu_reg); 10825 %} 10826 10827 instruct andL_rReg_rReg_imm_ndd(rRegL dst, rRegL src1, immL32 src2, rFlagsReg cr) 10828 %{ 10829 predicate(UseAPX); 10830 match(Set dst (AndL src1 src2)); 10831 effect(KILL cr); 10832 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10833 10834 format %{ "eandq $dst, $src1, $src2\t# long ndd" %} 10835 ins_encode %{ 10836 __ eandq($dst$$Register, $src1$$Register, $src2$$constant, false); 10837 %} 10838 ins_pipe(ialu_reg); 10839 %} 10840 10841 instruct andL_rReg_mem_imm_ndd(rRegL dst, memory src1, immL32 src2, rFlagsReg cr) 10842 %{ 10843 predicate(UseAPX); 10844 match(Set dst (AndL (LoadL src1) src2)); 10845 effect(KILL cr); 10846 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10847 10848 format %{ "eandq $dst, $src1, $src2\t# long ndd" %} 10849 ins_encode %{ 10850 __ eandq($dst$$Register, $src1$$Address, $src2$$constant, false); 10851 %} 10852 ins_pipe(ialu_reg); 10853 %} 10854 10855 // And Register with Memory 10856 instruct andL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 10857 %{ 10858 predicate(!UseAPX); 10859 match(Set dst (AndL dst (LoadL 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 ins_cost(150); 10864 format %{ "andq $dst, $src\t# long" %} 10865 ins_encode %{ 10866 __ andq($dst$$Register, $src$$Address); 10867 %} 10868 ins_pipe(ialu_reg_mem); 10869 %} 10870 10871 instruct andL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr) 10872 %{ 10873 predicate(UseAPX); 10874 match(Set dst (AndL src1 (LoadL src2))); 10875 effect(KILL cr); 10876 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10877 10878 ins_cost(150); 10879 format %{ "eandq $dst, $src1, $src2\t# long ndd" %} 10880 ins_encode %{ 10881 __ eandq($dst$$Register, $src1$$Register, $src2$$Address, false); 10882 %} 10883 ins_pipe(ialu_reg_mem); 10884 %} 10885 10886 instruct andL_rReg_mem_rReg_ndd(rRegL dst, memory src1, rRegL src2, rFlagsReg cr) 10887 %{ 10888 predicate(UseAPX); 10889 match(Set dst (AndL (LoadL src1) src2)); 10890 effect(KILL cr); 10891 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10892 10893 ins_cost(150); 10894 format %{ "eandq $dst, $src1, $src2\t# long ndd" %} 10895 ins_encode %{ 10896 __ eandq($dst$$Register, $src1$$Address, $src2$$Register, false); 10897 %} 10898 ins_pipe(ialu_reg_mem); 10899 %} 10900 10901 // And Memory with Register 10902 instruct andL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 10903 %{ 10904 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 10905 effect(KILL cr); 10906 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10907 10908 ins_cost(150); 10909 format %{ "andq $dst, $src\t# long" %} 10910 ins_encode %{ 10911 __ andq($dst$$Address, $src$$Register); 10912 %} 10913 ins_pipe(ialu_mem_reg); 10914 %} 10915 10916 // And Memory with Immediate 10917 instruct andL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 10918 %{ 10919 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 10920 effect(KILL cr); 10921 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10922 10923 ins_cost(125); 10924 format %{ "andq $dst, $src\t# long" %} 10925 ins_encode %{ 10926 __ andq($dst$$Address, $src$$constant); 10927 %} 10928 ins_pipe(ialu_mem_imm); 10929 %} 10930 10931 instruct btrL_mem_imm(memory dst, immL_NotPow2 con, rFlagsReg cr) 10932 %{ 10933 // con should be a pure 64-bit immediate given that not(con) is a power of 2 10934 // because AND/OR works well enough for 8/32-bit values. 10935 predicate(log2i_graceful(~n->in(3)->in(2)->get_long()) > 30); 10936 10937 match(Set dst (StoreL dst (AndL (LoadL dst) con))); 10938 effect(KILL cr); 10939 10940 ins_cost(125); 10941 format %{ "btrq $dst, log2(not($con))\t# long" %} 10942 ins_encode %{ 10943 __ btrq($dst$$Address, log2i_exact((julong)~$con$$constant)); 10944 %} 10945 ins_pipe(ialu_mem_imm); 10946 %} 10947 10948 // BMI1 instructions 10949 instruct andnL_rReg_rReg_mem(rRegL dst, rRegL src1, memory src2, immL_M1 minus_1, rFlagsReg cr) %{ 10950 match(Set dst (AndL (XorL src1 minus_1) (LoadL src2))); 10951 predicate(UseBMI1Instructions); 10952 effect(KILL cr); 10953 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10954 10955 ins_cost(125); 10956 format %{ "andnq $dst, $src1, $src2" %} 10957 10958 ins_encode %{ 10959 __ andnq($dst$$Register, $src1$$Register, $src2$$Address); 10960 %} 10961 ins_pipe(ialu_reg_mem); 10962 %} 10963 10964 instruct andnL_rReg_rReg_rReg(rRegL dst, rRegL src1, rRegL src2, immL_M1 minus_1, rFlagsReg cr) %{ 10965 match(Set dst (AndL (XorL src1 minus_1) src2)); 10966 predicate(UseBMI1Instructions); 10967 effect(KILL cr); 10968 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10969 10970 format %{ "andnq $dst, $src1, $src2" %} 10971 10972 ins_encode %{ 10973 __ andnq($dst$$Register, $src1$$Register, $src2$$Register); 10974 %} 10975 ins_pipe(ialu_reg_mem); 10976 %} 10977 10978 instruct blsiL_rReg_rReg(rRegL dst, rRegL src, immL0 imm_zero, rFlagsReg cr) %{ 10979 match(Set dst (AndL (SubL imm_zero src) src)); 10980 predicate(UseBMI1Instructions); 10981 effect(KILL cr); 10982 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 10983 10984 format %{ "blsiq $dst, $src" %} 10985 10986 ins_encode %{ 10987 __ blsiq($dst$$Register, $src$$Register); 10988 %} 10989 ins_pipe(ialu_reg); 10990 %} 10991 10992 instruct blsiL_rReg_mem(rRegL dst, memory src, immL0 imm_zero, rFlagsReg cr) %{ 10993 match(Set dst (AndL (SubL imm_zero (LoadL src) ) (LoadL src) )); 10994 predicate(UseBMI1Instructions); 10995 effect(KILL cr); 10996 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 10997 10998 ins_cost(125); 10999 format %{ "blsiq $dst, $src" %} 11000 11001 ins_encode %{ 11002 __ blsiq($dst$$Register, $src$$Address); 11003 %} 11004 ins_pipe(ialu_reg_mem); 11005 %} 11006 11007 instruct blsmskL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 11008 %{ 11009 match(Set dst (XorL (AddL (LoadL src) minus_1) (LoadL src) ) ); 11010 predicate(UseBMI1Instructions); 11011 effect(KILL cr); 11012 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 11013 11014 ins_cost(125); 11015 format %{ "blsmskq $dst, $src" %} 11016 11017 ins_encode %{ 11018 __ blsmskq($dst$$Register, $src$$Address); 11019 %} 11020 ins_pipe(ialu_reg_mem); 11021 %} 11022 11023 instruct blsmskL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 11024 %{ 11025 match(Set dst (XorL (AddL src minus_1) src)); 11026 predicate(UseBMI1Instructions); 11027 effect(KILL cr); 11028 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 11029 11030 format %{ "blsmskq $dst, $src" %} 11031 11032 ins_encode %{ 11033 __ blsmskq($dst$$Register, $src$$Register); 11034 %} 11035 11036 ins_pipe(ialu_reg); 11037 %} 11038 11039 instruct blsrL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 11040 %{ 11041 match(Set dst (AndL (AddL src minus_1) src) ); 11042 predicate(UseBMI1Instructions); 11043 effect(KILL cr); 11044 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 11045 11046 format %{ "blsrq $dst, $src" %} 11047 11048 ins_encode %{ 11049 __ blsrq($dst$$Register, $src$$Register); 11050 %} 11051 11052 ins_pipe(ialu_reg); 11053 %} 11054 11055 instruct blsrL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 11056 %{ 11057 match(Set dst (AndL (AddL (LoadL src) minus_1) (LoadL src)) ); 11058 predicate(UseBMI1Instructions); 11059 effect(KILL cr); 11060 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 11061 11062 ins_cost(125); 11063 format %{ "blsrq $dst, $src" %} 11064 11065 ins_encode %{ 11066 __ blsrq($dst$$Register, $src$$Address); 11067 %} 11068 11069 ins_pipe(ialu_reg); 11070 %} 11071 11072 // Or Instructions 11073 // Or Register with Register 11074 instruct orL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 11075 %{ 11076 predicate(!UseAPX); 11077 match(Set dst (OrL dst src)); 11078 effect(KILL cr); 11079 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11080 11081 format %{ "orq $dst, $src\t# long" %} 11082 ins_encode %{ 11083 __ orq($dst$$Register, $src$$Register); 11084 %} 11085 ins_pipe(ialu_reg_reg); 11086 %} 11087 11088 // Or Register with Register using New Data Destination (NDD) 11089 instruct orL_rReg_ndd(rRegL dst, rRegL src1, rRegL src2, rFlagsReg cr) 11090 %{ 11091 predicate(UseAPX); 11092 match(Set dst (OrL src1 src2)); 11093 effect(KILL cr); 11094 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11095 11096 format %{ "eorq $dst, $src1, $src2\t# long ndd" %} 11097 ins_encode %{ 11098 __ eorq($dst$$Register, $src1$$Register, $src2$$Register, false); 11099 11100 %} 11101 ins_pipe(ialu_reg_reg); 11102 %} 11103 11104 // Use any_RegP to match R15 (TLS register) without spilling. 11105 instruct orL_rReg_castP2X(rRegL dst, any_RegP src, rFlagsReg cr) %{ 11106 match(Set dst (OrL dst (CastP2X src))); 11107 effect(KILL cr); 11108 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11109 11110 format %{ "orq $dst, $src\t# long" %} 11111 ins_encode %{ 11112 __ orq($dst$$Register, $src$$Register); 11113 %} 11114 ins_pipe(ialu_reg_reg); 11115 %} 11116 11117 instruct orL_rReg_castP2X_ndd(rRegL dst, any_RegP src1, any_RegP src2, rFlagsReg cr) %{ 11118 match(Set dst (OrL src1 (CastP2X src2))); 11119 effect(KILL cr); 11120 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11121 11122 format %{ "eorq $dst, $src1, $src2\t# long ndd" %} 11123 ins_encode %{ 11124 __ eorq($dst$$Register, $src1$$Register, $src2$$Register, false); 11125 %} 11126 ins_pipe(ialu_reg_reg); 11127 %} 11128 11129 // Or Register with Immediate 11130 instruct orL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 11131 %{ 11132 predicate(!UseAPX); 11133 match(Set dst (OrL dst src)); 11134 effect(KILL cr); 11135 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11136 11137 format %{ "orq $dst, $src\t# long" %} 11138 ins_encode %{ 11139 __ orq($dst$$Register, $src$$constant); 11140 %} 11141 ins_pipe(ialu_reg); 11142 %} 11143 11144 instruct orL_rReg_rReg_imm_ndd(rRegL dst, rRegL src1, immL32 src2, rFlagsReg cr) 11145 %{ 11146 predicate(UseAPX); 11147 match(Set dst (OrL src1 src2)); 11148 effect(KILL cr); 11149 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11150 11151 format %{ "eorq $dst, $src1, $src2\t# long ndd" %} 11152 ins_encode %{ 11153 __ eorq($dst$$Register, $src1$$Register, $src2$$constant, false); 11154 %} 11155 ins_pipe(ialu_reg); 11156 %} 11157 11158 instruct orL_rReg_imm_rReg_ndd(rRegL dst, immL32 src1, rRegL src2, rFlagsReg cr) 11159 %{ 11160 predicate(UseAPX); 11161 match(Set dst (OrL src1 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, $src2, $src1\t# long ndd" %} 11166 ins_encode %{ 11167 __ eorq($dst$$Register, $src2$$Register, $src1$$constant, false); 11168 %} 11169 ins_pipe(ialu_reg); 11170 %} 11171 11172 // Or Memory with Immediate 11173 instruct orL_rReg_mem_imm_ndd(rRegL dst, memory src1, immL32 src2, rFlagsReg cr) 11174 %{ 11175 predicate(UseAPX); 11176 match(Set dst (OrL (LoadL src1) src2)); 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 %{ "eorq $dst, $src1, $src2\t# long ndd" %} 11181 ins_encode %{ 11182 __ eorq($dst$$Register, $src1$$Address, $src2$$constant, false); 11183 %} 11184 ins_pipe(ialu_reg); 11185 %} 11186 11187 // Or Register with Memory 11188 instruct orL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 11189 %{ 11190 predicate(!UseAPX); 11191 match(Set dst (OrL dst (LoadL src))); 11192 effect(KILL cr); 11193 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11194 11195 ins_cost(150); 11196 format %{ "orq $dst, $src\t# long" %} 11197 ins_encode %{ 11198 __ orq($dst$$Register, $src$$Address); 11199 %} 11200 ins_pipe(ialu_reg_mem); 11201 %} 11202 11203 instruct orL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr) 11204 %{ 11205 predicate(UseAPX); 11206 match(Set dst (OrL src1 (LoadL src2))); 11207 effect(KILL cr); 11208 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11209 11210 ins_cost(150); 11211 format %{ "eorq $dst, $src1, $src2\t# long ndd" %} 11212 ins_encode %{ 11213 __ eorq($dst$$Register, $src1$$Register, $src2$$Address, false); 11214 %} 11215 ins_pipe(ialu_reg_mem); 11216 %} 11217 11218 // Or Memory with Register 11219 instruct orL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 11220 %{ 11221 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 11222 effect(KILL cr); 11223 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11224 11225 ins_cost(150); 11226 format %{ "orq $dst, $src\t# long" %} 11227 ins_encode %{ 11228 __ orq($dst$$Address, $src$$Register); 11229 %} 11230 ins_pipe(ialu_mem_reg); 11231 %} 11232 11233 // Or Memory with Immediate 11234 instruct orL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 11235 %{ 11236 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 11237 effect(KILL cr); 11238 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11239 11240 ins_cost(125); 11241 format %{ "orq $dst, $src\t# long" %} 11242 ins_encode %{ 11243 __ orq($dst$$Address, $src$$constant); 11244 %} 11245 ins_pipe(ialu_mem_imm); 11246 %} 11247 11248 instruct btsL_mem_imm(memory dst, immL_Pow2 con, rFlagsReg cr) 11249 %{ 11250 // con should be a pure 64-bit power of 2 immediate 11251 // because AND/OR works well enough for 8/32-bit values. 11252 predicate(log2i_graceful(n->in(3)->in(2)->get_long()) > 31); 11253 11254 match(Set dst (StoreL dst (OrL (LoadL dst) con))); 11255 effect(KILL cr); 11256 11257 ins_cost(125); 11258 format %{ "btsq $dst, log2($con)\t# long" %} 11259 ins_encode %{ 11260 __ btsq($dst$$Address, log2i_exact((julong)$con$$constant)); 11261 %} 11262 ins_pipe(ialu_mem_imm); 11263 %} 11264 11265 // Xor Instructions 11266 // Xor Register with Register 11267 instruct xorL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 11268 %{ 11269 predicate(!UseAPX); 11270 match(Set dst (XorL dst src)); 11271 effect(KILL cr); 11272 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11273 11274 format %{ "xorq $dst, $src\t# long" %} 11275 ins_encode %{ 11276 __ xorq($dst$$Register, $src$$Register); 11277 %} 11278 ins_pipe(ialu_reg_reg); 11279 %} 11280 11281 // Xor Register with Register using New Data Destination (NDD) 11282 instruct xorL_rReg_ndd(rRegL dst, rRegL src1, rRegL src2, rFlagsReg cr) 11283 %{ 11284 predicate(UseAPX); 11285 match(Set dst (XorL src1 src2)); 11286 effect(KILL cr); 11287 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11288 11289 format %{ "exorq $dst, $src1, $src2\t# long ndd" %} 11290 ins_encode %{ 11291 __ exorq($dst$$Register, $src1$$Register, $src2$$Register, false); 11292 %} 11293 ins_pipe(ialu_reg_reg); 11294 %} 11295 11296 // Xor Register with Immediate -1 11297 instruct xorL_rReg_im1(rRegL dst, immL_M1 imm) 11298 %{ 11299 predicate(!UseAPX); 11300 match(Set dst (XorL dst imm)); 11301 11302 format %{ "notq $dst" %} 11303 ins_encode %{ 11304 __ notq($dst$$Register); 11305 %} 11306 ins_pipe(ialu_reg); 11307 %} 11308 11309 instruct xorL_rReg_im1_ndd(rRegL dst,rRegL src, immL_M1 imm) 11310 %{ 11311 predicate(UseAPX); 11312 match(Set dst (XorL src imm)); 11313 11314 format %{ "enotq $dst, $src" %} 11315 ins_encode %{ 11316 __ enotq($dst$$Register, $src$$Register); 11317 %} 11318 ins_pipe(ialu_reg); 11319 %} 11320 11321 // Xor Register with Immediate 11322 instruct xorL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 11323 %{ 11324 predicate(!UseAPX); 11325 match(Set dst (XorL dst src)); 11326 effect(KILL cr); 11327 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11328 11329 format %{ "xorq $dst, $src\t# long" %} 11330 ins_encode %{ 11331 __ xorq($dst$$Register, $src$$constant); 11332 %} 11333 ins_pipe(ialu_reg); 11334 %} 11335 11336 instruct xorL_rReg_rReg_imm(rRegL dst, rRegL src1, immL32 src2, rFlagsReg cr) 11337 %{ 11338 predicate(UseAPX); 11339 match(Set dst (XorL src1 src2)); 11340 effect(KILL cr); 11341 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11342 11343 format %{ "exorq $dst, $src1, $src2\t# long ndd" %} 11344 ins_encode %{ 11345 __ exorq($dst$$Register, $src1$$Register, $src2$$constant, false); 11346 %} 11347 ins_pipe(ialu_reg); 11348 %} 11349 11350 // Xor Memory with Immediate 11351 instruct xorL_rReg_mem_imm(rRegL dst, memory src1, immL32 src2, rFlagsReg cr) 11352 %{ 11353 predicate(UseAPX); 11354 match(Set dst (XorL (LoadL src1) src2)); 11355 effect(KILL cr); 11356 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11357 11358 format %{ "exorq $dst, $src1, $src2\t# long ndd" %} 11359 ins_encode %{ 11360 __ exorq($dst$$Register, $src1$$Address, $src2$$constant, false); 11361 %} 11362 ins_pipe(ialu_reg); 11363 %} 11364 11365 // Xor Register with Memory 11366 instruct xorL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 11367 %{ 11368 predicate(!UseAPX); 11369 match(Set dst (XorL dst (LoadL src))); 11370 effect(KILL cr); 11371 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11372 11373 ins_cost(150); 11374 format %{ "xorq $dst, $src\t# long" %} 11375 ins_encode %{ 11376 __ xorq($dst$$Register, $src$$Address); 11377 %} 11378 ins_pipe(ialu_reg_mem); 11379 %} 11380 11381 instruct xorL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr) 11382 %{ 11383 predicate(UseAPX); 11384 match(Set dst (XorL src1 (LoadL src2))); 11385 effect(KILL cr); 11386 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11387 11388 ins_cost(150); 11389 format %{ "exorq $dst, $src1, $src2\t# long ndd" %} 11390 ins_encode %{ 11391 __ exorq($dst$$Register, $src1$$Register, $src2$$Address, false); 11392 %} 11393 ins_pipe(ialu_reg_mem); 11394 %} 11395 11396 instruct xorL_rReg_mem_rReg_ndd(rRegL dst, memory src1, rRegL src2, rFlagsReg cr) 11397 %{ 11398 predicate(UseAPX); 11399 match(Set dst (XorL (LoadL src1) src2)); 11400 effect(KILL cr); 11401 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11402 11403 ins_cost(150); 11404 format %{ "exorq $dst, $src1, $src2\t# long ndd" %} 11405 ins_encode %{ 11406 __ exorq($dst$$Register, $src1$$Address, $src2$$Register, false); 11407 %} 11408 ins_pipe(ialu_reg_mem); 11409 %} 11410 11411 // Xor Memory with Register 11412 instruct xorL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 11413 %{ 11414 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 11415 effect(KILL cr); 11416 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11417 11418 ins_cost(150); 11419 format %{ "xorq $dst, $src\t# long" %} 11420 ins_encode %{ 11421 __ xorq($dst$$Address, $src$$Register); 11422 %} 11423 ins_pipe(ialu_mem_reg); 11424 %} 11425 11426 // Xor Memory with Immediate 11427 instruct xorL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 11428 %{ 11429 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 11430 effect(KILL cr); 11431 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11432 11433 ins_cost(125); 11434 format %{ "xorq $dst, $src\t# long" %} 11435 ins_encode %{ 11436 __ xorq($dst$$Address, $src$$constant); 11437 %} 11438 ins_pipe(ialu_mem_imm); 11439 %} 11440 11441 instruct cmpLTMask(rRegI dst, rRegI p, rRegI q, rFlagsReg cr) 11442 %{ 11443 match(Set dst (CmpLTMask p q)); 11444 effect(KILL cr); 11445 11446 ins_cost(400); 11447 format %{ "cmpl $p, $q\t# cmpLTMask\n\t" 11448 "setcc $dst \t# emits setlt + movzbl or setzul for APX" 11449 "negl $dst" %} 11450 ins_encode %{ 11451 __ cmpl($p$$Register, $q$$Register); 11452 __ setcc(Assembler::less, $dst$$Register); 11453 __ negl($dst$$Register); 11454 %} 11455 ins_pipe(pipe_slow); 11456 %} 11457 11458 instruct cmpLTMask0(rRegI dst, immI_0 zero, rFlagsReg cr) 11459 %{ 11460 match(Set dst (CmpLTMask dst zero)); 11461 effect(KILL cr); 11462 11463 ins_cost(100); 11464 format %{ "sarl $dst, #31\t# cmpLTMask0" %} 11465 ins_encode %{ 11466 __ sarl($dst$$Register, 31); 11467 %} 11468 ins_pipe(ialu_reg); 11469 %} 11470 11471 /* Better to save a register than avoid a branch */ 11472 instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 11473 %{ 11474 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q))); 11475 effect(KILL cr); 11476 ins_cost(300); 11477 format %{ "subl $p,$q\t# cadd_cmpLTMask\n\t" 11478 "jge done\n\t" 11479 "addl $p,$y\n" 11480 "done: " %} 11481 ins_encode %{ 11482 Register Rp = $p$$Register; 11483 Register Rq = $q$$Register; 11484 Register Ry = $y$$Register; 11485 Label done; 11486 __ subl(Rp, Rq); 11487 __ jccb(Assembler::greaterEqual, done); 11488 __ addl(Rp, Ry); 11489 __ bind(done); 11490 %} 11491 ins_pipe(pipe_cmplt); 11492 %} 11493 11494 /* Better to save a register than avoid a branch */ 11495 instruct and_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 11496 %{ 11497 match(Set y (AndI (CmpLTMask p q) y)); 11498 effect(KILL cr); 11499 11500 ins_cost(300); 11501 11502 format %{ "cmpl $p, $q\t# and_cmpLTMask\n\t" 11503 "jlt done\n\t" 11504 "xorl $y, $y\n" 11505 "done: " %} 11506 ins_encode %{ 11507 Register Rp = $p$$Register; 11508 Register Rq = $q$$Register; 11509 Register Ry = $y$$Register; 11510 Label done; 11511 __ cmpl(Rp, Rq); 11512 __ jccb(Assembler::less, done); 11513 __ xorl(Ry, Ry); 11514 __ bind(done); 11515 %} 11516 ins_pipe(pipe_cmplt); 11517 %} 11518 11519 11520 //---------- FP Instructions------------------------------------------------ 11521 11522 // Really expensive, avoid 11523 instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2) 11524 %{ 11525 match(Set cr (CmpF src1 src2)); 11526 11527 ins_cost(500); 11528 format %{ "ucomiss $src1, $src2\n\t" 11529 "jnp,s exit\n\t" 11530 "pushfq\t# saw NaN, set CF\n\t" 11531 "andq [rsp], #0xffffff2b\n\t" 11532 "popfq\n" 11533 "exit:" %} 11534 ins_encode %{ 11535 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 11536 emit_cmpfp_fixup(masm); 11537 %} 11538 ins_pipe(pipe_slow); 11539 %} 11540 11541 instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{ 11542 match(Set cr (CmpF src1 src2)); 11543 11544 ins_cost(100); 11545 format %{ "ucomiss $src1, $src2" %} 11546 ins_encode %{ 11547 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 11548 %} 11549 ins_pipe(pipe_slow); 11550 %} 11551 11552 instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{ 11553 match(Set cr (CmpF src1 (LoadF src2))); 11554 11555 ins_cost(100); 11556 format %{ "ucomiss $src1, $src2" %} 11557 ins_encode %{ 11558 __ ucomiss($src1$$XMMRegister, $src2$$Address); 11559 %} 11560 ins_pipe(pipe_slow); 11561 %} 11562 11563 instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src, immF con) %{ 11564 match(Set cr (CmpF src con)); 11565 ins_cost(100); 11566 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con" %} 11567 ins_encode %{ 11568 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 11569 %} 11570 ins_pipe(pipe_slow); 11571 %} 11572 11573 // Really expensive, avoid 11574 instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2) 11575 %{ 11576 match(Set cr (CmpD src1 src2)); 11577 11578 ins_cost(500); 11579 format %{ "ucomisd $src1, $src2\n\t" 11580 "jnp,s exit\n\t" 11581 "pushfq\t# saw NaN, set CF\n\t" 11582 "andq [rsp], #0xffffff2b\n\t" 11583 "popfq\n" 11584 "exit:" %} 11585 ins_encode %{ 11586 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 11587 emit_cmpfp_fixup(masm); 11588 %} 11589 ins_pipe(pipe_slow); 11590 %} 11591 11592 instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{ 11593 match(Set cr (CmpD src1 src2)); 11594 11595 ins_cost(100); 11596 format %{ "ucomisd $src1, $src2 test" %} 11597 ins_encode %{ 11598 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 11599 %} 11600 ins_pipe(pipe_slow); 11601 %} 11602 11603 instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{ 11604 match(Set cr (CmpD src1 (LoadD src2))); 11605 11606 ins_cost(100); 11607 format %{ "ucomisd $src1, $src2" %} 11608 ins_encode %{ 11609 __ ucomisd($src1$$XMMRegister, $src2$$Address); 11610 %} 11611 ins_pipe(pipe_slow); 11612 %} 11613 11614 instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src, immD con) %{ 11615 match(Set cr (CmpD src con)); 11616 ins_cost(100); 11617 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con" %} 11618 ins_encode %{ 11619 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 11620 %} 11621 ins_pipe(pipe_slow); 11622 %} 11623 11624 // Compare into -1,0,1 11625 instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr) 11626 %{ 11627 match(Set dst (CmpF3 src1 src2)); 11628 effect(KILL cr); 11629 11630 ins_cost(275); 11631 format %{ "ucomiss $src1, $src2\n\t" 11632 "movl $dst, #-1\n\t" 11633 "jp,s done\n\t" 11634 "jb,s done\n\t" 11635 "setne $dst\n\t" 11636 "movzbl $dst, $dst\n" 11637 "done:" %} 11638 ins_encode %{ 11639 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 11640 emit_cmpfp3(masm, $dst$$Register); 11641 %} 11642 ins_pipe(pipe_slow); 11643 %} 11644 11645 // Compare into -1,0,1 11646 instruct cmpF_mem(rRegI dst, regF src1, memory src2, rFlagsReg cr) 11647 %{ 11648 match(Set dst (CmpF3 src1 (LoadF src2))); 11649 effect(KILL cr); 11650 11651 ins_cost(275); 11652 format %{ "ucomiss $src1, $src2\n\t" 11653 "movl $dst, #-1\n\t" 11654 "jp,s done\n\t" 11655 "jb,s done\n\t" 11656 "setne $dst\n\t" 11657 "movzbl $dst, $dst\n" 11658 "done:" %} 11659 ins_encode %{ 11660 __ ucomiss($src1$$XMMRegister, $src2$$Address); 11661 emit_cmpfp3(masm, $dst$$Register); 11662 %} 11663 ins_pipe(pipe_slow); 11664 %} 11665 11666 // Compare into -1,0,1 11667 instruct cmpF_imm(rRegI dst, regF src, immF con, rFlagsReg cr) %{ 11668 match(Set dst (CmpF3 src con)); 11669 effect(KILL cr); 11670 11671 ins_cost(275); 11672 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 11673 "movl $dst, #-1\n\t" 11674 "jp,s done\n\t" 11675 "jb,s done\n\t" 11676 "setne $dst\n\t" 11677 "movzbl $dst, $dst\n" 11678 "done:" %} 11679 ins_encode %{ 11680 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 11681 emit_cmpfp3(masm, $dst$$Register); 11682 %} 11683 ins_pipe(pipe_slow); 11684 %} 11685 11686 // Compare into -1,0,1 11687 instruct cmpD_reg(rRegI dst, regD src1, regD src2, rFlagsReg cr) 11688 %{ 11689 match(Set dst (CmpD3 src1 src2)); 11690 effect(KILL cr); 11691 11692 ins_cost(275); 11693 format %{ "ucomisd $src1, $src2\n\t" 11694 "movl $dst, #-1\n\t" 11695 "jp,s done\n\t" 11696 "jb,s done\n\t" 11697 "setne $dst\n\t" 11698 "movzbl $dst, $dst\n" 11699 "done:" %} 11700 ins_encode %{ 11701 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 11702 emit_cmpfp3(masm, $dst$$Register); 11703 %} 11704 ins_pipe(pipe_slow); 11705 %} 11706 11707 // Compare into -1,0,1 11708 instruct cmpD_mem(rRegI dst, regD src1, memory src2, rFlagsReg cr) 11709 %{ 11710 match(Set dst (CmpD3 src1 (LoadD src2))); 11711 effect(KILL cr); 11712 11713 ins_cost(275); 11714 format %{ "ucomisd $src1, $src2\n\t" 11715 "movl $dst, #-1\n\t" 11716 "jp,s done\n\t" 11717 "jb,s done\n\t" 11718 "setne $dst\n\t" 11719 "movzbl $dst, $dst\n" 11720 "done:" %} 11721 ins_encode %{ 11722 __ ucomisd($src1$$XMMRegister, $src2$$Address); 11723 emit_cmpfp3(masm, $dst$$Register); 11724 %} 11725 ins_pipe(pipe_slow); 11726 %} 11727 11728 // Compare into -1,0,1 11729 instruct cmpD_imm(rRegI dst, regD src, immD con, rFlagsReg cr) %{ 11730 match(Set dst (CmpD3 src con)); 11731 effect(KILL cr); 11732 11733 ins_cost(275); 11734 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 11735 "movl $dst, #-1\n\t" 11736 "jp,s done\n\t" 11737 "jb,s done\n\t" 11738 "setne $dst\n\t" 11739 "movzbl $dst, $dst\n" 11740 "done:" %} 11741 ins_encode %{ 11742 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 11743 emit_cmpfp3(masm, $dst$$Register); 11744 %} 11745 ins_pipe(pipe_slow); 11746 %} 11747 11748 //----------Arithmetic Conversion Instructions--------------------------------- 11749 11750 instruct convF2D_reg_reg(regD dst, regF src) 11751 %{ 11752 match(Set dst (ConvF2D src)); 11753 11754 format %{ "cvtss2sd $dst, $src" %} 11755 ins_encode %{ 11756 __ cvtss2sd ($dst$$XMMRegister, $src$$XMMRegister); 11757 %} 11758 ins_pipe(pipe_slow); // XXX 11759 %} 11760 11761 instruct convF2D_reg_mem(regD dst, memory src) 11762 %{ 11763 predicate(UseAVX == 0); 11764 match(Set dst (ConvF2D (LoadF src))); 11765 11766 format %{ "cvtss2sd $dst, $src" %} 11767 ins_encode %{ 11768 __ cvtss2sd ($dst$$XMMRegister, $src$$Address); 11769 %} 11770 ins_pipe(pipe_slow); // XXX 11771 %} 11772 11773 instruct convD2F_reg_reg(regF dst, regD src) 11774 %{ 11775 match(Set dst (ConvD2F src)); 11776 11777 format %{ "cvtsd2ss $dst, $src" %} 11778 ins_encode %{ 11779 __ cvtsd2ss ($dst$$XMMRegister, $src$$XMMRegister); 11780 %} 11781 ins_pipe(pipe_slow); // XXX 11782 %} 11783 11784 instruct convD2F_reg_mem(regF dst, memory src) 11785 %{ 11786 predicate(UseAVX == 0); 11787 match(Set dst (ConvD2F (LoadD src))); 11788 11789 format %{ "cvtsd2ss $dst, $src" %} 11790 ins_encode %{ 11791 __ cvtsd2ss ($dst$$XMMRegister, $src$$Address); 11792 %} 11793 ins_pipe(pipe_slow); // XXX 11794 %} 11795 11796 // XXX do mem variants 11797 instruct convF2I_reg_reg(rRegI dst, regF src, rFlagsReg cr) 11798 %{ 11799 match(Set dst (ConvF2I src)); 11800 effect(KILL cr); 11801 format %{ "convert_f2i $dst, $src" %} 11802 ins_encode %{ 11803 __ convertF2I(T_INT, T_FLOAT, $dst$$Register, $src$$XMMRegister); 11804 %} 11805 ins_pipe(pipe_slow); 11806 %} 11807 11808 instruct convF2L_reg_reg(rRegL dst, regF src, rFlagsReg cr) 11809 %{ 11810 match(Set dst (ConvF2L src)); 11811 effect(KILL cr); 11812 format %{ "convert_f2l $dst, $src"%} 11813 ins_encode %{ 11814 __ convertF2I(T_LONG, T_FLOAT, $dst$$Register, $src$$XMMRegister); 11815 %} 11816 ins_pipe(pipe_slow); 11817 %} 11818 11819 instruct convD2I_reg_reg(rRegI dst, regD src, rFlagsReg cr) 11820 %{ 11821 match(Set dst (ConvD2I src)); 11822 effect(KILL cr); 11823 format %{ "convert_d2i $dst, $src"%} 11824 ins_encode %{ 11825 __ convertF2I(T_INT, T_DOUBLE, $dst$$Register, $src$$XMMRegister); 11826 %} 11827 ins_pipe(pipe_slow); 11828 %} 11829 11830 instruct convD2L_reg_reg(rRegL dst, regD src, rFlagsReg cr) 11831 %{ 11832 match(Set dst (ConvD2L src)); 11833 effect(KILL cr); 11834 format %{ "convert_d2l $dst, $src"%} 11835 ins_encode %{ 11836 __ convertF2I(T_LONG, T_DOUBLE, $dst$$Register, $src$$XMMRegister); 11837 %} 11838 ins_pipe(pipe_slow); 11839 %} 11840 11841 instruct round_double_reg(rRegL dst, regD src, rRegL rtmp, rcx_RegL rcx, rFlagsReg cr) 11842 %{ 11843 match(Set dst (RoundD src)); 11844 effect(TEMP dst, TEMP rtmp, TEMP rcx, KILL cr); 11845 format %{ "round_double $dst,$src \t! using $rtmp and $rcx as TEMP"%} 11846 ins_encode %{ 11847 __ round_double($dst$$Register, $src$$XMMRegister, $rtmp$$Register, $rcx$$Register); 11848 %} 11849 ins_pipe(pipe_slow); 11850 %} 11851 11852 instruct round_float_reg(rRegI dst, regF src, rRegL rtmp, rcx_RegL rcx, rFlagsReg cr) 11853 %{ 11854 match(Set dst (RoundF src)); 11855 effect(TEMP dst, TEMP rtmp, TEMP rcx, KILL cr); 11856 format %{ "round_float $dst,$src" %} 11857 ins_encode %{ 11858 __ round_float($dst$$Register, $src$$XMMRegister, $rtmp$$Register, $rcx$$Register); 11859 %} 11860 ins_pipe(pipe_slow); 11861 %} 11862 11863 instruct convI2F_reg_reg(vlRegF dst, rRegI src) 11864 %{ 11865 predicate(!UseXmmI2F); 11866 match(Set dst (ConvI2F src)); 11867 11868 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 11869 ins_encode %{ 11870 if (UseAVX > 0) { 11871 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 11872 } 11873 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Register); 11874 %} 11875 ins_pipe(pipe_slow); // XXX 11876 %} 11877 11878 instruct convI2F_reg_mem(regF dst, memory src) 11879 %{ 11880 predicate(UseAVX == 0); 11881 match(Set dst (ConvI2F (LoadI src))); 11882 11883 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 11884 ins_encode %{ 11885 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Address); 11886 %} 11887 ins_pipe(pipe_slow); // XXX 11888 %} 11889 11890 instruct convI2D_reg_reg(vlRegD dst, rRegI src) 11891 %{ 11892 predicate(!UseXmmI2D); 11893 match(Set dst (ConvI2D src)); 11894 11895 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 11896 ins_encode %{ 11897 if (UseAVX > 0) { 11898 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 11899 } 11900 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Register); 11901 %} 11902 ins_pipe(pipe_slow); // XXX 11903 %} 11904 11905 instruct convI2D_reg_mem(regD dst, memory src) 11906 %{ 11907 predicate(UseAVX == 0); 11908 match(Set dst (ConvI2D (LoadI src))); 11909 11910 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 11911 ins_encode %{ 11912 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Address); 11913 %} 11914 ins_pipe(pipe_slow); // XXX 11915 %} 11916 11917 instruct convXI2F_reg(regF dst, rRegI src) 11918 %{ 11919 predicate(UseXmmI2F); 11920 match(Set dst (ConvI2F src)); 11921 11922 format %{ "movdl $dst, $src\n\t" 11923 "cvtdq2psl $dst, $dst\t# i2f" %} 11924 ins_encode %{ 11925 __ movdl($dst$$XMMRegister, $src$$Register); 11926 __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister); 11927 %} 11928 ins_pipe(pipe_slow); // XXX 11929 %} 11930 11931 instruct convXI2D_reg(regD dst, rRegI src) 11932 %{ 11933 predicate(UseXmmI2D); 11934 match(Set dst (ConvI2D src)); 11935 11936 format %{ "movdl $dst, $src\n\t" 11937 "cvtdq2pdl $dst, $dst\t# i2d" %} 11938 ins_encode %{ 11939 __ movdl($dst$$XMMRegister, $src$$Register); 11940 __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister); 11941 %} 11942 ins_pipe(pipe_slow); // XXX 11943 %} 11944 11945 instruct convL2F_reg_reg(vlRegF dst, rRegL src) 11946 %{ 11947 match(Set dst (ConvL2F src)); 11948 11949 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 11950 ins_encode %{ 11951 if (UseAVX > 0) { 11952 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 11953 } 11954 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Register); 11955 %} 11956 ins_pipe(pipe_slow); // XXX 11957 %} 11958 11959 instruct convL2F_reg_mem(regF dst, memory src) 11960 %{ 11961 predicate(UseAVX == 0); 11962 match(Set dst (ConvL2F (LoadL src))); 11963 11964 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 11965 ins_encode %{ 11966 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Address); 11967 %} 11968 ins_pipe(pipe_slow); // XXX 11969 %} 11970 11971 instruct convL2D_reg_reg(vlRegD dst, rRegL src) 11972 %{ 11973 match(Set dst (ConvL2D src)); 11974 11975 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 11976 ins_encode %{ 11977 if (UseAVX > 0) { 11978 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 11979 } 11980 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Register); 11981 %} 11982 ins_pipe(pipe_slow); // XXX 11983 %} 11984 11985 instruct convL2D_reg_mem(regD dst, memory src) 11986 %{ 11987 predicate(UseAVX == 0); 11988 match(Set dst (ConvL2D (LoadL src))); 11989 11990 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 11991 ins_encode %{ 11992 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Address); 11993 %} 11994 ins_pipe(pipe_slow); // XXX 11995 %} 11996 11997 instruct convI2L_reg_reg(rRegL dst, rRegI src) 11998 %{ 11999 match(Set dst (ConvI2L src)); 12000 12001 ins_cost(125); 12002 format %{ "movslq $dst, $src\t# i2l" %} 12003 ins_encode %{ 12004 __ movslq($dst$$Register, $src$$Register); 12005 %} 12006 ins_pipe(ialu_reg_reg); 12007 %} 12008 12009 // Zero-extend convert int to long 12010 instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask) 12011 %{ 12012 match(Set dst (AndL (ConvI2L src) mask)); 12013 12014 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 12015 ins_encode %{ 12016 if ($dst$$reg != $src$$reg) { 12017 __ movl($dst$$Register, $src$$Register); 12018 } 12019 %} 12020 ins_pipe(ialu_reg_reg); 12021 %} 12022 12023 // Zero-extend convert int to long 12024 instruct convI2L_reg_mem_zex(rRegL dst, memory src, immL_32bits mask) 12025 %{ 12026 match(Set dst (AndL (ConvI2L (LoadI src)) mask)); 12027 12028 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 12029 ins_encode %{ 12030 __ movl($dst$$Register, $src$$Address); 12031 %} 12032 ins_pipe(ialu_reg_mem); 12033 %} 12034 12035 instruct zerox_long_reg_reg(rRegL dst, rRegL src, immL_32bits mask) 12036 %{ 12037 match(Set dst (AndL src mask)); 12038 12039 format %{ "movl $dst, $src\t# zero-extend long" %} 12040 ins_encode %{ 12041 __ movl($dst$$Register, $src$$Register); 12042 %} 12043 ins_pipe(ialu_reg_reg); 12044 %} 12045 12046 instruct convL2I_reg_reg(rRegI dst, rRegL src) 12047 %{ 12048 match(Set dst (ConvL2I src)); 12049 12050 format %{ "movl $dst, $src\t# l2i" %} 12051 ins_encode %{ 12052 __ movl($dst$$Register, $src$$Register); 12053 %} 12054 ins_pipe(ialu_reg_reg); 12055 %} 12056 12057 12058 instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{ 12059 match(Set dst (MoveF2I src)); 12060 effect(DEF dst, USE src); 12061 12062 ins_cost(125); 12063 format %{ "movl $dst, $src\t# MoveF2I_stack_reg" %} 12064 ins_encode %{ 12065 __ movl($dst$$Register, Address(rsp, $src$$disp)); 12066 %} 12067 ins_pipe(ialu_reg_mem); 12068 %} 12069 12070 instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{ 12071 match(Set dst (MoveI2F src)); 12072 effect(DEF dst, USE src); 12073 12074 ins_cost(125); 12075 format %{ "movss $dst, $src\t# MoveI2F_stack_reg" %} 12076 ins_encode %{ 12077 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 12078 %} 12079 ins_pipe(pipe_slow); 12080 %} 12081 12082 instruct MoveD2L_stack_reg(rRegL dst, stackSlotD src) %{ 12083 match(Set dst (MoveD2L src)); 12084 effect(DEF dst, USE src); 12085 12086 ins_cost(125); 12087 format %{ "movq $dst, $src\t# MoveD2L_stack_reg" %} 12088 ins_encode %{ 12089 __ movq($dst$$Register, Address(rsp, $src$$disp)); 12090 %} 12091 ins_pipe(ialu_reg_mem); 12092 %} 12093 12094 instruct MoveL2D_stack_reg_partial(regD dst, stackSlotL src) %{ 12095 predicate(!UseXmmLoadAndClearUpper); 12096 match(Set dst (MoveL2D src)); 12097 effect(DEF dst, USE src); 12098 12099 ins_cost(125); 12100 format %{ "movlpd $dst, $src\t# MoveL2D_stack_reg" %} 12101 ins_encode %{ 12102 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 12103 %} 12104 ins_pipe(pipe_slow); 12105 %} 12106 12107 instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{ 12108 predicate(UseXmmLoadAndClearUpper); 12109 match(Set dst (MoveL2D src)); 12110 effect(DEF dst, USE src); 12111 12112 ins_cost(125); 12113 format %{ "movsd $dst, $src\t# MoveL2D_stack_reg" %} 12114 ins_encode %{ 12115 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 12116 %} 12117 ins_pipe(pipe_slow); 12118 %} 12119 12120 12121 instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{ 12122 match(Set dst (MoveF2I src)); 12123 effect(DEF dst, USE src); 12124 12125 ins_cost(95); // XXX 12126 format %{ "movss $dst, $src\t# MoveF2I_reg_stack" %} 12127 ins_encode %{ 12128 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 12129 %} 12130 ins_pipe(pipe_slow); 12131 %} 12132 12133 instruct MoveI2F_reg_stack(stackSlotF dst, rRegI src) %{ 12134 match(Set dst (MoveI2F src)); 12135 effect(DEF dst, USE src); 12136 12137 ins_cost(100); 12138 format %{ "movl $dst, $src\t# MoveI2F_reg_stack" %} 12139 ins_encode %{ 12140 __ movl(Address(rsp, $dst$$disp), $src$$Register); 12141 %} 12142 ins_pipe( ialu_mem_reg ); 12143 %} 12144 12145 instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{ 12146 match(Set dst (MoveD2L src)); 12147 effect(DEF dst, USE src); 12148 12149 ins_cost(95); // XXX 12150 format %{ "movsd $dst, $src\t# MoveL2D_reg_stack" %} 12151 ins_encode %{ 12152 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 12153 %} 12154 ins_pipe(pipe_slow); 12155 %} 12156 12157 instruct MoveL2D_reg_stack(stackSlotD dst, rRegL src) %{ 12158 match(Set dst (MoveL2D src)); 12159 effect(DEF dst, USE src); 12160 12161 ins_cost(100); 12162 format %{ "movq $dst, $src\t# MoveL2D_reg_stack" %} 12163 ins_encode %{ 12164 __ movq(Address(rsp, $dst$$disp), $src$$Register); 12165 %} 12166 ins_pipe(ialu_mem_reg); 12167 %} 12168 12169 instruct MoveF2I_reg_reg(rRegI dst, regF src) %{ 12170 match(Set dst (MoveF2I src)); 12171 effect(DEF dst, USE src); 12172 ins_cost(85); 12173 format %{ "movd $dst,$src\t# MoveF2I" %} 12174 ins_encode %{ 12175 __ movdl($dst$$Register, $src$$XMMRegister); 12176 %} 12177 ins_pipe( pipe_slow ); 12178 %} 12179 12180 instruct MoveD2L_reg_reg(rRegL dst, regD src) %{ 12181 match(Set dst (MoveD2L src)); 12182 effect(DEF dst, USE src); 12183 ins_cost(85); 12184 format %{ "movd $dst,$src\t# MoveD2L" %} 12185 ins_encode %{ 12186 __ movdq($dst$$Register, $src$$XMMRegister); 12187 %} 12188 ins_pipe( pipe_slow ); 12189 %} 12190 12191 instruct MoveI2F_reg_reg(regF dst, rRegI src) %{ 12192 match(Set dst (MoveI2F src)); 12193 effect(DEF dst, USE src); 12194 ins_cost(100); 12195 format %{ "movd $dst,$src\t# MoveI2F" %} 12196 ins_encode %{ 12197 __ movdl($dst$$XMMRegister, $src$$Register); 12198 %} 12199 ins_pipe( pipe_slow ); 12200 %} 12201 12202 instruct MoveL2D_reg_reg(regD dst, rRegL src) %{ 12203 match(Set dst (MoveL2D src)); 12204 effect(DEF dst, USE src); 12205 ins_cost(100); 12206 format %{ "movd $dst,$src\t# MoveL2D" %} 12207 ins_encode %{ 12208 __ movdq($dst$$XMMRegister, $src$$Register); 12209 %} 12210 ins_pipe( pipe_slow ); 12211 %} 12212 12213 // Fast clearing of an array 12214 // Small non-constant lenght ClearArray for non-AVX512 targets. 12215 instruct rep_stos(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegI zero, 12216 Universe dummy, rFlagsReg cr) 12217 %{ 12218 predicate(!((ClearArrayNode*)n)->is_large() && (UseAVX <= 2)); 12219 match(Set dummy (ClearArray cnt base)); 12220 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL zero, KILL cr); 12221 12222 format %{ $$template 12223 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 12224 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 12225 $$emit$$"jg LARGE\n\t" 12226 $$emit$$"dec rcx\n\t" 12227 $$emit$$"js DONE\t# Zero length\n\t" 12228 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 12229 $$emit$$"dec rcx\n\t" 12230 $$emit$$"jge LOOP\n\t" 12231 $$emit$$"jmp DONE\n\t" 12232 $$emit$$"# LARGE:\n\t" 12233 if (UseFastStosb) { 12234 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 12235 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--\n\t" 12236 } else if (UseXMMForObjInit) { 12237 $$emit$$"mov rdi,rax\n\t" 12238 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 12239 $$emit$$"jmpq L_zero_64_bytes\n\t" 12240 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 12241 $$emit$$"vmovdqu ymm0,(rax)\n\t" 12242 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 12243 $$emit$$"add 0x40,rax\n\t" 12244 $$emit$$"# L_zero_64_bytes:\n\t" 12245 $$emit$$"sub 0x8,rcx\n\t" 12246 $$emit$$"jge L_loop\n\t" 12247 $$emit$$"add 0x4,rcx\n\t" 12248 $$emit$$"jl L_tail\n\t" 12249 $$emit$$"vmovdqu ymm0,(rax)\n\t" 12250 $$emit$$"add 0x20,rax\n\t" 12251 $$emit$$"sub 0x4,rcx\n\t" 12252 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 12253 $$emit$$"add 0x4,rcx\n\t" 12254 $$emit$$"jle L_end\n\t" 12255 $$emit$$"dec rcx\n\t" 12256 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 12257 $$emit$$"vmovq xmm0,(rax)\n\t" 12258 $$emit$$"add 0x8,rax\n\t" 12259 $$emit$$"dec rcx\n\t" 12260 $$emit$$"jge L_sloop\n\t" 12261 $$emit$$"# L_end:\n\t" 12262 } else { 12263 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 12264 } 12265 $$emit$$"# DONE" 12266 %} 12267 ins_encode %{ 12268 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 12269 $tmp$$XMMRegister, false, knoreg); 12270 %} 12271 ins_pipe(pipe_slow); 12272 %} 12273 12274 // Small non-constant length ClearArray for AVX512 targets. 12275 instruct rep_stos_evex(rcx_RegL cnt, rdi_RegP base, legRegD tmp, kReg ktmp, rax_RegI zero, 12276 Universe dummy, rFlagsReg cr) 12277 %{ 12278 predicate(!((ClearArrayNode*)n)->is_large() && (UseAVX > 2)); 12279 match(Set dummy (ClearArray cnt base)); 12280 ins_cost(125); 12281 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, TEMP ktmp, KILL zero, KILL cr); 12282 12283 format %{ $$template 12284 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 12285 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 12286 $$emit$$"jg LARGE\n\t" 12287 $$emit$$"dec rcx\n\t" 12288 $$emit$$"js DONE\t# Zero length\n\t" 12289 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 12290 $$emit$$"dec rcx\n\t" 12291 $$emit$$"jge LOOP\n\t" 12292 $$emit$$"jmp DONE\n\t" 12293 $$emit$$"# LARGE:\n\t" 12294 if (UseFastStosb) { 12295 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 12296 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--\n\t" 12297 } else if (UseXMMForObjInit) { 12298 $$emit$$"mov rdi,rax\n\t" 12299 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 12300 $$emit$$"jmpq L_zero_64_bytes\n\t" 12301 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 12302 $$emit$$"vmovdqu ymm0,(rax)\n\t" 12303 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 12304 $$emit$$"add 0x40,rax\n\t" 12305 $$emit$$"# L_zero_64_bytes:\n\t" 12306 $$emit$$"sub 0x8,rcx\n\t" 12307 $$emit$$"jge L_loop\n\t" 12308 $$emit$$"add 0x4,rcx\n\t" 12309 $$emit$$"jl L_tail\n\t" 12310 $$emit$$"vmovdqu ymm0,(rax)\n\t" 12311 $$emit$$"add 0x20,rax\n\t" 12312 $$emit$$"sub 0x4,rcx\n\t" 12313 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 12314 $$emit$$"add 0x4,rcx\n\t" 12315 $$emit$$"jle L_end\n\t" 12316 $$emit$$"dec rcx\n\t" 12317 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 12318 $$emit$$"vmovq xmm0,(rax)\n\t" 12319 $$emit$$"add 0x8,rax\n\t" 12320 $$emit$$"dec rcx\n\t" 12321 $$emit$$"jge L_sloop\n\t" 12322 $$emit$$"# L_end:\n\t" 12323 } else { 12324 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 12325 } 12326 $$emit$$"# DONE" 12327 %} 12328 ins_encode %{ 12329 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 12330 $tmp$$XMMRegister, false, $ktmp$$KRegister); 12331 %} 12332 ins_pipe(pipe_slow); 12333 %} 12334 12335 // Large non-constant length ClearArray for non-AVX512 targets. 12336 instruct rep_stos_large(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegI zero, 12337 Universe dummy, rFlagsReg cr) 12338 %{ 12339 predicate((UseAVX <=2) && ((ClearArrayNode*)n)->is_large()); 12340 match(Set dummy (ClearArray cnt base)); 12341 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL zero, KILL cr); 12342 12343 format %{ $$template 12344 if (UseFastStosb) { 12345 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 12346 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 12347 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--" 12348 } else if (UseXMMForObjInit) { 12349 $$emit$$"mov rdi,rax\t# ClearArray:\n\t" 12350 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 12351 $$emit$$"jmpq L_zero_64_bytes\n\t" 12352 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 12353 $$emit$$"vmovdqu ymm0,(rax)\n\t" 12354 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 12355 $$emit$$"add 0x40,rax\n\t" 12356 $$emit$$"# L_zero_64_bytes:\n\t" 12357 $$emit$$"sub 0x8,rcx\n\t" 12358 $$emit$$"jge L_loop\n\t" 12359 $$emit$$"add 0x4,rcx\n\t" 12360 $$emit$$"jl L_tail\n\t" 12361 $$emit$$"vmovdqu ymm0,(rax)\n\t" 12362 $$emit$$"add 0x20,rax\n\t" 12363 $$emit$$"sub 0x4,rcx\n\t" 12364 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 12365 $$emit$$"add 0x4,rcx\n\t" 12366 $$emit$$"jle L_end\n\t" 12367 $$emit$$"dec rcx\n\t" 12368 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 12369 $$emit$$"vmovq xmm0,(rax)\n\t" 12370 $$emit$$"add 0x8,rax\n\t" 12371 $$emit$$"dec rcx\n\t" 12372 $$emit$$"jge L_sloop\n\t" 12373 $$emit$$"# L_end:\n\t" 12374 } else { 12375 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 12376 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 12377 } 12378 %} 12379 ins_encode %{ 12380 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 12381 $tmp$$XMMRegister, true, knoreg); 12382 %} 12383 ins_pipe(pipe_slow); 12384 %} 12385 12386 // Large non-constant length ClearArray for AVX512 targets. 12387 instruct rep_stos_large_evex(rcx_RegL cnt, rdi_RegP base, legRegD tmp, kReg ktmp, rax_RegI zero, 12388 Universe dummy, rFlagsReg cr) 12389 %{ 12390 predicate((UseAVX > 2) && ((ClearArrayNode*)n)->is_large()); 12391 match(Set dummy (ClearArray cnt base)); 12392 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, TEMP ktmp, KILL zero, KILL cr); 12393 12394 format %{ $$template 12395 if (UseFastStosb) { 12396 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 12397 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 12398 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--" 12399 } else if (UseXMMForObjInit) { 12400 $$emit$$"mov rdi,rax\t# ClearArray:\n\t" 12401 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 12402 $$emit$$"jmpq L_zero_64_bytes\n\t" 12403 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 12404 $$emit$$"vmovdqu ymm0,(rax)\n\t" 12405 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 12406 $$emit$$"add 0x40,rax\n\t" 12407 $$emit$$"# L_zero_64_bytes:\n\t" 12408 $$emit$$"sub 0x8,rcx\n\t" 12409 $$emit$$"jge L_loop\n\t" 12410 $$emit$$"add 0x4,rcx\n\t" 12411 $$emit$$"jl L_tail\n\t" 12412 $$emit$$"vmovdqu ymm0,(rax)\n\t" 12413 $$emit$$"add 0x20,rax\n\t" 12414 $$emit$$"sub 0x4,rcx\n\t" 12415 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 12416 $$emit$$"add 0x4,rcx\n\t" 12417 $$emit$$"jle L_end\n\t" 12418 $$emit$$"dec rcx\n\t" 12419 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 12420 $$emit$$"vmovq xmm0,(rax)\n\t" 12421 $$emit$$"add 0x8,rax\n\t" 12422 $$emit$$"dec rcx\n\t" 12423 $$emit$$"jge L_sloop\n\t" 12424 $$emit$$"# L_end:\n\t" 12425 } else { 12426 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 12427 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 12428 } 12429 %} 12430 ins_encode %{ 12431 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 12432 $tmp$$XMMRegister, true, $ktmp$$KRegister); 12433 %} 12434 ins_pipe(pipe_slow); 12435 %} 12436 12437 // Small constant length ClearArray for AVX512 targets. 12438 instruct rep_stos_im(immL cnt, rRegP base, regD tmp, rRegI zero, kReg ktmp, Universe dummy, rFlagsReg cr) 12439 %{ 12440 predicate(!((ClearArrayNode*)n)->is_large() && (MaxVectorSize >= 32) && VM_Version::supports_avx512vl()); 12441 match(Set dummy (ClearArray cnt base)); 12442 ins_cost(100); 12443 effect(TEMP tmp, TEMP zero, TEMP ktmp, KILL cr); 12444 format %{ "clear_mem_imm $base , $cnt \n\t" %} 12445 ins_encode %{ 12446 __ clear_mem($base$$Register, $cnt$$constant, $zero$$Register, $tmp$$XMMRegister, $ktmp$$KRegister); 12447 %} 12448 ins_pipe(pipe_slow); 12449 %} 12450 12451 instruct string_compareL(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 12452 rax_RegI result, legRegD tmp1, rFlagsReg cr) 12453 %{ 12454 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 12455 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12456 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 12457 12458 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 12459 ins_encode %{ 12460 __ string_compare($str1$$Register, $str2$$Register, 12461 $cnt1$$Register, $cnt2$$Register, $result$$Register, 12462 $tmp1$$XMMRegister, StrIntrinsicNode::LL, knoreg); 12463 %} 12464 ins_pipe( pipe_slow ); 12465 %} 12466 12467 instruct string_compareL_evex(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 12468 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 12469 %{ 12470 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 12471 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12472 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 12473 12474 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 12475 ins_encode %{ 12476 __ string_compare($str1$$Register, $str2$$Register, 12477 $cnt1$$Register, $cnt2$$Register, $result$$Register, 12478 $tmp1$$XMMRegister, StrIntrinsicNode::LL, $ktmp$$KRegister); 12479 %} 12480 ins_pipe( pipe_slow ); 12481 %} 12482 12483 instruct string_compareU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 12484 rax_RegI result, legRegD tmp1, rFlagsReg cr) 12485 %{ 12486 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 12487 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12488 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 12489 12490 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 12491 ins_encode %{ 12492 __ string_compare($str1$$Register, $str2$$Register, 12493 $cnt1$$Register, $cnt2$$Register, $result$$Register, 12494 $tmp1$$XMMRegister, StrIntrinsicNode::UU, knoreg); 12495 %} 12496 ins_pipe( pipe_slow ); 12497 %} 12498 12499 instruct string_compareU_evex(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 12500 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 12501 %{ 12502 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 12503 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12504 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 12505 12506 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 12507 ins_encode %{ 12508 __ string_compare($str1$$Register, $str2$$Register, 12509 $cnt1$$Register, $cnt2$$Register, $result$$Register, 12510 $tmp1$$XMMRegister, StrIntrinsicNode::UU, $ktmp$$KRegister); 12511 %} 12512 ins_pipe( pipe_slow ); 12513 %} 12514 12515 instruct string_compareLU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 12516 rax_RegI result, legRegD tmp1, rFlagsReg cr) 12517 %{ 12518 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 12519 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12520 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 12521 12522 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 12523 ins_encode %{ 12524 __ string_compare($str1$$Register, $str2$$Register, 12525 $cnt1$$Register, $cnt2$$Register, $result$$Register, 12526 $tmp1$$XMMRegister, StrIntrinsicNode::LU, knoreg); 12527 %} 12528 ins_pipe( pipe_slow ); 12529 %} 12530 12531 instruct string_compareLU_evex(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 12532 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 12533 %{ 12534 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 12535 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12536 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 12537 12538 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 12539 ins_encode %{ 12540 __ string_compare($str1$$Register, $str2$$Register, 12541 $cnt1$$Register, $cnt2$$Register, $result$$Register, 12542 $tmp1$$XMMRegister, StrIntrinsicNode::LU, $ktmp$$KRegister); 12543 %} 12544 ins_pipe( pipe_slow ); 12545 %} 12546 12547 instruct string_compareUL(rsi_RegP str1, rdx_RegI cnt1, rdi_RegP str2, rcx_RegI cnt2, 12548 rax_RegI result, legRegD tmp1, rFlagsReg cr) 12549 %{ 12550 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 12551 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12552 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 12553 12554 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 12555 ins_encode %{ 12556 __ string_compare($str2$$Register, $str1$$Register, 12557 $cnt2$$Register, $cnt1$$Register, $result$$Register, 12558 $tmp1$$XMMRegister, StrIntrinsicNode::UL, knoreg); 12559 %} 12560 ins_pipe( pipe_slow ); 12561 %} 12562 12563 instruct string_compareUL_evex(rsi_RegP str1, rdx_RegI cnt1, rdi_RegP str2, rcx_RegI cnt2, 12564 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 12565 %{ 12566 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 12567 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12568 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 12569 12570 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 12571 ins_encode %{ 12572 __ string_compare($str2$$Register, $str1$$Register, 12573 $cnt2$$Register, $cnt1$$Register, $result$$Register, 12574 $tmp1$$XMMRegister, StrIntrinsicNode::UL, $ktmp$$KRegister); 12575 %} 12576 ins_pipe( pipe_slow ); 12577 %} 12578 12579 // fast search of substring with known size. 12580 instruct string_indexof_conL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 12581 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 12582 %{ 12583 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 12584 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 12585 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 12586 12587 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %} 12588 ins_encode %{ 12589 int icnt2 = (int)$int_cnt2$$constant; 12590 if (icnt2 >= 16) { 12591 // IndexOf for constant substrings with size >= 16 elements 12592 // which don't need to be loaded through stack. 12593 __ string_indexofC8($str1$$Register, $str2$$Register, 12594 $cnt1$$Register, $cnt2$$Register, 12595 icnt2, $result$$Register, 12596 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 12597 } else { 12598 // Small strings are loaded through stack if they cross page boundary. 12599 __ string_indexof($str1$$Register, $str2$$Register, 12600 $cnt1$$Register, $cnt2$$Register, 12601 icnt2, $result$$Register, 12602 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 12603 } 12604 %} 12605 ins_pipe( pipe_slow ); 12606 %} 12607 12608 // fast search of substring with known size. 12609 instruct string_indexof_conU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 12610 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 12611 %{ 12612 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 12613 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 12614 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 12615 12616 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %} 12617 ins_encode %{ 12618 int icnt2 = (int)$int_cnt2$$constant; 12619 if (icnt2 >= 8) { 12620 // IndexOf for constant substrings with size >= 8 elements 12621 // which don't need to be loaded through stack. 12622 __ string_indexofC8($str1$$Register, $str2$$Register, 12623 $cnt1$$Register, $cnt2$$Register, 12624 icnt2, $result$$Register, 12625 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 12626 } else { 12627 // Small strings are loaded through stack if they cross page boundary. 12628 __ string_indexof($str1$$Register, $str2$$Register, 12629 $cnt1$$Register, $cnt2$$Register, 12630 icnt2, $result$$Register, 12631 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 12632 } 12633 %} 12634 ins_pipe( pipe_slow ); 12635 %} 12636 12637 // fast search of substring with known size. 12638 instruct string_indexof_conUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 12639 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 12640 %{ 12641 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 12642 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 12643 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 12644 12645 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %} 12646 ins_encode %{ 12647 int icnt2 = (int)$int_cnt2$$constant; 12648 if (icnt2 >= 8) { 12649 // IndexOf for constant substrings with size >= 8 elements 12650 // which don't need to be loaded through stack. 12651 __ string_indexofC8($str1$$Register, $str2$$Register, 12652 $cnt1$$Register, $cnt2$$Register, 12653 icnt2, $result$$Register, 12654 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 12655 } else { 12656 // Small strings are loaded through stack if they cross page boundary. 12657 __ string_indexof($str1$$Register, $str2$$Register, 12658 $cnt1$$Register, $cnt2$$Register, 12659 icnt2, $result$$Register, 12660 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 12661 } 12662 %} 12663 ins_pipe( pipe_slow ); 12664 %} 12665 12666 instruct string_indexofL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 12667 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr) 12668 %{ 12669 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 12670 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 12671 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 12672 12673 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 12674 ins_encode %{ 12675 __ string_indexof($str1$$Register, $str2$$Register, 12676 $cnt1$$Register, $cnt2$$Register, 12677 (-1), $result$$Register, 12678 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 12679 %} 12680 ins_pipe( pipe_slow ); 12681 %} 12682 12683 instruct string_indexofU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 12684 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr) 12685 %{ 12686 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 12687 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 12688 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 12689 12690 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 12691 ins_encode %{ 12692 __ string_indexof($str1$$Register, $str2$$Register, 12693 $cnt1$$Register, $cnt2$$Register, 12694 (-1), $result$$Register, 12695 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 12696 %} 12697 ins_pipe( pipe_slow ); 12698 %} 12699 12700 instruct string_indexofUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 12701 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr) 12702 %{ 12703 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 12704 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 12705 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 12706 12707 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 12708 ins_encode %{ 12709 __ string_indexof($str1$$Register, $str2$$Register, 12710 $cnt1$$Register, $cnt2$$Register, 12711 (-1), $result$$Register, 12712 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 12713 %} 12714 ins_pipe( pipe_slow ); 12715 %} 12716 12717 instruct string_indexof_char(rdi_RegP str1, rdx_RegI cnt1, rax_RegI ch, 12718 rbx_RegI result, legRegD tmp_vec1, legRegD tmp_vec2, legRegD tmp_vec3, rcx_RegI tmp, rFlagsReg cr) 12719 %{ 12720 predicate(UseSSE42Intrinsics && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::U)); 12721 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 12722 effect(TEMP tmp_vec1, TEMP tmp_vec2, TEMP tmp_vec3, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP tmp, KILL cr); 12723 format %{ "StringUTF16 IndexOf char[] $str1,$cnt1,$ch -> $result // KILL all" %} 12724 ins_encode %{ 12725 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register, 12726 $tmp_vec1$$XMMRegister, $tmp_vec2$$XMMRegister, $tmp_vec3$$XMMRegister, $tmp$$Register); 12727 %} 12728 ins_pipe( pipe_slow ); 12729 %} 12730 12731 instruct stringL_indexof_char(rdi_RegP str1, rdx_RegI cnt1, rax_RegI ch, 12732 rbx_RegI result, legRegD tmp_vec1, legRegD tmp_vec2, legRegD tmp_vec3, rcx_RegI tmp, rFlagsReg cr) 12733 %{ 12734 predicate(UseSSE42Intrinsics && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::L)); 12735 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 12736 effect(TEMP tmp_vec1, TEMP tmp_vec2, TEMP tmp_vec3, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP tmp, KILL cr); 12737 format %{ "StringLatin1 IndexOf char[] $str1,$cnt1,$ch -> $result // KILL all" %} 12738 ins_encode %{ 12739 __ stringL_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register, 12740 $tmp_vec1$$XMMRegister, $tmp_vec2$$XMMRegister, $tmp_vec3$$XMMRegister, $tmp$$Register); 12741 %} 12742 ins_pipe( pipe_slow ); 12743 %} 12744 12745 // fast string equals 12746 instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 12747 legRegD tmp1, legRegD tmp2, rbx_RegI tmp3, rFlagsReg cr) 12748 %{ 12749 predicate(!VM_Version::supports_avx512vlbw()); 12750 match(Set result (StrEquals (Binary str1 str2) cnt)); 12751 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 12752 12753 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 12754 ins_encode %{ 12755 __ arrays_equals(false, $str1$$Register, $str2$$Register, 12756 $cnt$$Register, $result$$Register, $tmp3$$Register, 12757 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, knoreg); 12758 %} 12759 ins_pipe( pipe_slow ); 12760 %} 12761 12762 instruct string_equals_evex(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 12763 legRegD tmp1, legRegD tmp2, kReg ktmp, rbx_RegI tmp3, rFlagsReg cr) 12764 %{ 12765 predicate(VM_Version::supports_avx512vlbw()); 12766 match(Set result (StrEquals (Binary str1 str2) cnt)); 12767 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 12768 12769 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 12770 ins_encode %{ 12771 __ arrays_equals(false, $str1$$Register, $str2$$Register, 12772 $cnt$$Register, $result$$Register, $tmp3$$Register, 12773 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, $ktmp$$KRegister); 12774 %} 12775 ins_pipe( pipe_slow ); 12776 %} 12777 12778 // fast array equals 12779 instruct array_equalsB(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 12780 legRegD tmp1, legRegD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 12781 %{ 12782 predicate(!VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 12783 match(Set result (AryEq ary1 ary2)); 12784 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 12785 12786 format %{ "Array Equals byte[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 12787 ins_encode %{ 12788 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 12789 $tmp3$$Register, $result$$Register, $tmp4$$Register, 12790 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, knoreg); 12791 %} 12792 ins_pipe( pipe_slow ); 12793 %} 12794 12795 instruct array_equalsB_evex(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 12796 legRegD tmp1, legRegD tmp2, kReg ktmp, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 12797 %{ 12798 predicate(VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 12799 match(Set result (AryEq ary1 ary2)); 12800 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 12801 12802 format %{ "Array Equals byte[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 12803 ins_encode %{ 12804 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 12805 $tmp3$$Register, $result$$Register, $tmp4$$Register, 12806 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, $ktmp$$KRegister); 12807 %} 12808 ins_pipe( pipe_slow ); 12809 %} 12810 12811 instruct array_equalsC(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 12812 legRegD tmp1, legRegD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 12813 %{ 12814 predicate(!VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 12815 match(Set result (AryEq ary1 ary2)); 12816 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 12817 12818 format %{ "Array Equals char[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 12819 ins_encode %{ 12820 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 12821 $tmp3$$Register, $result$$Register, $tmp4$$Register, 12822 $tmp1$$XMMRegister, $tmp2$$XMMRegister, true /* char */, knoreg); 12823 %} 12824 ins_pipe( pipe_slow ); 12825 %} 12826 12827 instruct array_equalsC_evex(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 12828 legRegD tmp1, legRegD tmp2, kReg ktmp, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 12829 %{ 12830 predicate(VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 12831 match(Set result (AryEq ary1 ary2)); 12832 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 12833 12834 format %{ "Array Equals char[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 12835 ins_encode %{ 12836 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 12837 $tmp3$$Register, $result$$Register, $tmp4$$Register, 12838 $tmp1$$XMMRegister, $tmp2$$XMMRegister, true /* char */, $ktmp$$KRegister); 12839 %} 12840 ins_pipe( pipe_slow ); 12841 %} 12842 12843 instruct arrays_hashcode(rdi_RegP ary1, rdx_RegI cnt1, rbx_RegI result, immU8 basic_type, 12844 legRegD tmp_vec1, legRegD tmp_vec2, legRegD tmp_vec3, legRegD tmp_vec4, 12845 legRegD tmp_vec5, legRegD tmp_vec6, legRegD tmp_vec7, legRegD tmp_vec8, 12846 legRegD tmp_vec9, legRegD tmp_vec10, legRegD tmp_vec11, legRegD tmp_vec12, 12847 legRegD tmp_vec13, rRegI tmp1, rRegI tmp2, rRegI tmp3, rFlagsReg cr) 12848 %{ 12849 predicate(UseAVX >= 2); 12850 match(Set result (VectorizedHashCode (Binary ary1 cnt1) (Binary result basic_type))); 12851 effect(TEMP tmp_vec1, TEMP tmp_vec2, TEMP tmp_vec3, TEMP tmp_vec4, TEMP tmp_vec5, TEMP tmp_vec6, 12852 TEMP tmp_vec7, TEMP tmp_vec8, TEMP tmp_vec9, TEMP tmp_vec10, TEMP tmp_vec11, TEMP tmp_vec12, 12853 TEMP tmp_vec13, TEMP tmp1, TEMP tmp2, TEMP tmp3, USE_KILL ary1, USE_KILL cnt1, 12854 USE basic_type, KILL cr); 12855 12856 format %{ "Array HashCode array[] $ary1,$cnt1,$result,$basic_type -> $result // KILL all" %} 12857 ins_encode %{ 12858 __ arrays_hashcode($ary1$$Register, $cnt1$$Register, $result$$Register, 12859 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 12860 $tmp_vec1$$XMMRegister, $tmp_vec2$$XMMRegister, $tmp_vec3$$XMMRegister, 12861 $tmp_vec4$$XMMRegister, $tmp_vec5$$XMMRegister, $tmp_vec6$$XMMRegister, 12862 $tmp_vec7$$XMMRegister, $tmp_vec8$$XMMRegister, $tmp_vec9$$XMMRegister, 12863 $tmp_vec10$$XMMRegister, $tmp_vec11$$XMMRegister, $tmp_vec12$$XMMRegister, 12864 $tmp_vec13$$XMMRegister, (BasicType)$basic_type$$constant); 12865 %} 12866 ins_pipe( pipe_slow ); 12867 %} 12868 12869 instruct count_positives(rsi_RegP ary1, rcx_RegI len, rax_RegI result, 12870 legRegD tmp1, legRegD tmp2, rbx_RegI tmp3, rFlagsReg cr,) 12871 %{ 12872 predicate(!VM_Version::supports_avx512vlbw() || !VM_Version::supports_bmi2()); 12873 match(Set result (CountPositives ary1 len)); 12874 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr); 12875 12876 format %{ "countPositives byte[] $ary1,$len -> $result // KILL $tmp1, $tmp2, $tmp3" %} 12877 ins_encode %{ 12878 __ count_positives($ary1$$Register, $len$$Register, 12879 $result$$Register, $tmp3$$Register, 12880 $tmp1$$XMMRegister, $tmp2$$XMMRegister, knoreg, knoreg); 12881 %} 12882 ins_pipe( pipe_slow ); 12883 %} 12884 12885 instruct count_positives_evex(rsi_RegP ary1, rcx_RegI len, rax_RegI result, 12886 legRegD tmp1, legRegD tmp2, kReg ktmp1, kReg ktmp2, rbx_RegI tmp3, rFlagsReg cr,) 12887 %{ 12888 predicate(VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2()); 12889 match(Set result (CountPositives ary1 len)); 12890 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp1, TEMP ktmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr); 12891 12892 format %{ "countPositives byte[] $ary1,$len -> $result // KILL $tmp1, $tmp2, $tmp3" %} 12893 ins_encode %{ 12894 __ count_positives($ary1$$Register, $len$$Register, 12895 $result$$Register, $tmp3$$Register, 12896 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $ktmp1$$KRegister, $ktmp2$$KRegister); 12897 %} 12898 ins_pipe( pipe_slow ); 12899 %} 12900 12901 // fast char[] to byte[] compression 12902 instruct string_compress(rsi_RegP src, rdi_RegP dst, rdx_RegI len, legRegD tmp1, legRegD tmp2, legRegD tmp3, 12903 legRegD tmp4, rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 12904 predicate(!VM_Version::supports_avx512vlbw() || !VM_Version::supports_bmi2()); 12905 match(Set result (StrCompressedCopy src (Binary dst len))); 12906 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, 12907 USE_KILL len, KILL tmp5, KILL cr); 12908 12909 format %{ "String Compress $src,$dst -> $result // KILL RAX, RCX, RDX" %} 12910 ins_encode %{ 12911 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 12912 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 12913 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, 12914 knoreg, knoreg); 12915 %} 12916 ins_pipe( pipe_slow ); 12917 %} 12918 12919 instruct string_compress_evex(rsi_RegP src, rdi_RegP dst, rdx_RegI len, legRegD tmp1, legRegD tmp2, legRegD tmp3, 12920 legRegD tmp4, kReg ktmp1, kReg ktmp2, rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 12921 predicate(VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2()); 12922 match(Set result (StrCompressedCopy src (Binary dst len))); 12923 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP ktmp1, TEMP ktmp2, USE_KILL src, USE_KILL dst, 12924 USE_KILL len, KILL tmp5, KILL cr); 12925 12926 format %{ "String Compress $src,$dst -> $result // KILL RAX, RCX, RDX" %} 12927 ins_encode %{ 12928 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 12929 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 12930 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, 12931 $ktmp1$$KRegister, $ktmp2$$KRegister); 12932 %} 12933 ins_pipe( pipe_slow ); 12934 %} 12935 // fast byte[] to char[] inflation 12936 instruct string_inflate(Universe dummy, rsi_RegP src, rdi_RegP dst, rdx_RegI len, 12937 legRegD tmp1, rcx_RegI tmp2, rFlagsReg cr) %{ 12938 predicate(!VM_Version::supports_avx512vlbw() || !VM_Version::supports_bmi2()); 12939 match(Set dummy (StrInflatedCopy src (Binary dst len))); 12940 effect(TEMP tmp1, TEMP tmp2, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 12941 12942 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 12943 ins_encode %{ 12944 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 12945 $tmp1$$XMMRegister, $tmp2$$Register, knoreg); 12946 %} 12947 ins_pipe( pipe_slow ); 12948 %} 12949 12950 instruct string_inflate_evex(Universe dummy, rsi_RegP src, rdi_RegP dst, rdx_RegI len, 12951 legRegD tmp1, kReg ktmp, rcx_RegI tmp2, rFlagsReg cr) %{ 12952 predicate(VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2()); 12953 match(Set dummy (StrInflatedCopy src (Binary dst len))); 12954 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 12955 12956 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 12957 ins_encode %{ 12958 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 12959 $tmp1$$XMMRegister, $tmp2$$Register, $ktmp$$KRegister); 12960 %} 12961 ins_pipe( pipe_slow ); 12962 %} 12963 12964 // encode char[] to byte[] in ISO_8859_1 12965 instruct encode_iso_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len, 12966 legRegD tmp1, legRegD tmp2, legRegD tmp3, legRegD tmp4, 12967 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 12968 predicate(!((EncodeISOArrayNode*)n)->is_ascii()); 12969 match(Set result (EncodeISOArray src (Binary dst len))); 12970 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 12971 12972 format %{ "Encode iso array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %} 12973 ins_encode %{ 12974 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 12975 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 12976 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, false); 12977 %} 12978 ins_pipe( pipe_slow ); 12979 %} 12980 12981 // encode char[] to byte[] in ASCII 12982 instruct encode_ascii_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len, 12983 legRegD tmp1, legRegD tmp2, legRegD tmp3, legRegD tmp4, 12984 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 12985 predicate(((EncodeISOArrayNode*)n)->is_ascii()); 12986 match(Set result (EncodeISOArray src (Binary dst len))); 12987 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 12988 12989 format %{ "Encode ascii array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %} 12990 ins_encode %{ 12991 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 12992 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 12993 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, true); 12994 %} 12995 ins_pipe( pipe_slow ); 12996 %} 12997 12998 //----------Overflow Math Instructions----------------------------------------- 12999 13000 instruct overflowAddI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 13001 %{ 13002 match(Set cr (OverflowAddI op1 op2)); 13003 effect(DEF cr, USE_KILL op1, USE op2); 13004 13005 format %{ "addl $op1, $op2\t# overflow check int" %} 13006 13007 ins_encode %{ 13008 __ addl($op1$$Register, $op2$$Register); 13009 %} 13010 ins_pipe(ialu_reg_reg); 13011 %} 13012 13013 instruct overflowAddI_rReg_imm(rFlagsReg cr, rax_RegI op1, immI op2) 13014 %{ 13015 match(Set cr (OverflowAddI op1 op2)); 13016 effect(DEF cr, USE_KILL op1, USE op2); 13017 13018 format %{ "addl $op1, $op2\t# overflow check int" %} 13019 13020 ins_encode %{ 13021 __ addl($op1$$Register, $op2$$constant); 13022 %} 13023 ins_pipe(ialu_reg_reg); 13024 %} 13025 13026 instruct overflowAddL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 13027 %{ 13028 match(Set cr (OverflowAddL op1 op2)); 13029 effect(DEF cr, USE_KILL op1, USE op2); 13030 13031 format %{ "addq $op1, $op2\t# overflow check long" %} 13032 ins_encode %{ 13033 __ addq($op1$$Register, $op2$$Register); 13034 %} 13035 ins_pipe(ialu_reg_reg); 13036 %} 13037 13038 instruct overflowAddL_rReg_imm(rFlagsReg cr, rax_RegL op1, immL32 op2) 13039 %{ 13040 match(Set cr (OverflowAddL op1 op2)); 13041 effect(DEF cr, USE_KILL op1, USE op2); 13042 13043 format %{ "addq $op1, $op2\t# overflow check long" %} 13044 ins_encode %{ 13045 __ addq($op1$$Register, $op2$$constant); 13046 %} 13047 ins_pipe(ialu_reg_reg); 13048 %} 13049 13050 instruct overflowSubI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 13051 %{ 13052 match(Set cr (OverflowSubI op1 op2)); 13053 13054 format %{ "cmpl $op1, $op2\t# overflow check int" %} 13055 ins_encode %{ 13056 __ cmpl($op1$$Register, $op2$$Register); 13057 %} 13058 ins_pipe(ialu_reg_reg); 13059 %} 13060 13061 instruct overflowSubI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 13062 %{ 13063 match(Set cr (OverflowSubI op1 op2)); 13064 13065 format %{ "cmpl $op1, $op2\t# overflow check int" %} 13066 ins_encode %{ 13067 __ cmpl($op1$$Register, $op2$$constant); 13068 %} 13069 ins_pipe(ialu_reg_reg); 13070 %} 13071 13072 instruct overflowSubL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 13073 %{ 13074 match(Set cr (OverflowSubL op1 op2)); 13075 13076 format %{ "cmpq $op1, $op2\t# overflow check long" %} 13077 ins_encode %{ 13078 __ cmpq($op1$$Register, $op2$$Register); 13079 %} 13080 ins_pipe(ialu_reg_reg); 13081 %} 13082 13083 instruct overflowSubL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 13084 %{ 13085 match(Set cr (OverflowSubL op1 op2)); 13086 13087 format %{ "cmpq $op1, $op2\t# overflow check long" %} 13088 ins_encode %{ 13089 __ cmpq($op1$$Register, $op2$$constant); 13090 %} 13091 ins_pipe(ialu_reg_reg); 13092 %} 13093 13094 instruct overflowNegI_rReg(rFlagsReg cr, immI_0 zero, rax_RegI op2) 13095 %{ 13096 match(Set cr (OverflowSubI zero op2)); 13097 effect(DEF cr, USE_KILL op2); 13098 13099 format %{ "negl $op2\t# overflow check int" %} 13100 ins_encode %{ 13101 __ negl($op2$$Register); 13102 %} 13103 ins_pipe(ialu_reg_reg); 13104 %} 13105 13106 instruct overflowNegL_rReg(rFlagsReg cr, immL0 zero, rax_RegL op2) 13107 %{ 13108 match(Set cr (OverflowSubL zero op2)); 13109 effect(DEF cr, USE_KILL op2); 13110 13111 format %{ "negq $op2\t# overflow check long" %} 13112 ins_encode %{ 13113 __ negq($op2$$Register); 13114 %} 13115 ins_pipe(ialu_reg_reg); 13116 %} 13117 13118 instruct overflowMulI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 13119 %{ 13120 match(Set cr (OverflowMulI op1 op2)); 13121 effect(DEF cr, USE_KILL op1, USE op2); 13122 13123 format %{ "imull $op1, $op2\t# overflow check int" %} 13124 ins_encode %{ 13125 __ imull($op1$$Register, $op2$$Register); 13126 %} 13127 ins_pipe(ialu_reg_reg_alu0); 13128 %} 13129 13130 instruct overflowMulI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2, rRegI tmp) 13131 %{ 13132 match(Set cr (OverflowMulI op1 op2)); 13133 effect(DEF cr, TEMP tmp, USE op1, USE op2); 13134 13135 format %{ "imull $tmp, $op1, $op2\t# overflow check int" %} 13136 ins_encode %{ 13137 __ imull($tmp$$Register, $op1$$Register, $op2$$constant); 13138 %} 13139 ins_pipe(ialu_reg_reg_alu0); 13140 %} 13141 13142 instruct overflowMulL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 13143 %{ 13144 match(Set cr (OverflowMulL op1 op2)); 13145 effect(DEF cr, USE_KILL op1, USE op2); 13146 13147 format %{ "imulq $op1, $op2\t# overflow check long" %} 13148 ins_encode %{ 13149 __ imulq($op1$$Register, $op2$$Register); 13150 %} 13151 ins_pipe(ialu_reg_reg_alu0); 13152 %} 13153 13154 instruct overflowMulL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2, rRegL tmp) 13155 %{ 13156 match(Set cr (OverflowMulL op1 op2)); 13157 effect(DEF cr, TEMP tmp, USE op1, USE op2); 13158 13159 format %{ "imulq $tmp, $op1, $op2\t# overflow check long" %} 13160 ins_encode %{ 13161 __ imulq($tmp$$Register, $op1$$Register, $op2$$constant); 13162 %} 13163 ins_pipe(ialu_reg_reg_alu0); 13164 %} 13165 13166 13167 //----------Control Flow Instructions------------------------------------------ 13168 // Signed compare Instructions 13169 13170 // XXX more variants!! 13171 instruct compI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 13172 %{ 13173 match(Set cr (CmpI op1 op2)); 13174 effect(DEF cr, USE op1, USE op2); 13175 13176 format %{ "cmpl $op1, $op2" %} 13177 ins_encode %{ 13178 __ cmpl($op1$$Register, $op2$$Register); 13179 %} 13180 ins_pipe(ialu_cr_reg_reg); 13181 %} 13182 13183 instruct compI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 13184 %{ 13185 match(Set cr (CmpI op1 op2)); 13186 13187 format %{ "cmpl $op1, $op2" %} 13188 ins_encode %{ 13189 __ cmpl($op1$$Register, $op2$$constant); 13190 %} 13191 ins_pipe(ialu_cr_reg_imm); 13192 %} 13193 13194 instruct compI_rReg_mem(rFlagsReg cr, rRegI op1, memory op2) 13195 %{ 13196 match(Set cr (CmpI op1 (LoadI op2))); 13197 13198 ins_cost(500); // XXX 13199 format %{ "cmpl $op1, $op2" %} 13200 ins_encode %{ 13201 __ cmpl($op1$$Register, $op2$$Address); 13202 %} 13203 ins_pipe(ialu_cr_reg_mem); 13204 %} 13205 13206 instruct testI_reg(rFlagsReg cr, rRegI src, immI_0 zero) 13207 %{ 13208 match(Set cr (CmpI src zero)); 13209 13210 format %{ "testl $src, $src" %} 13211 ins_encode %{ 13212 __ testl($src$$Register, $src$$Register); 13213 %} 13214 ins_pipe(ialu_cr_reg_imm); 13215 %} 13216 13217 instruct testI_reg_imm(rFlagsReg cr, rRegI src, immI con, immI_0 zero) 13218 %{ 13219 match(Set cr (CmpI (AndI src con) zero)); 13220 13221 format %{ "testl $src, $con" %} 13222 ins_encode %{ 13223 __ testl($src$$Register, $con$$constant); 13224 %} 13225 ins_pipe(ialu_cr_reg_imm); 13226 %} 13227 13228 instruct testI_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2, immI_0 zero) 13229 %{ 13230 match(Set cr (CmpI (AndI src1 src2) zero)); 13231 13232 format %{ "testl $src1, $src2" %} 13233 ins_encode %{ 13234 __ testl($src1$$Register, $src2$$Register); 13235 %} 13236 ins_pipe(ialu_cr_reg_imm); 13237 %} 13238 13239 instruct testI_reg_mem(rFlagsReg cr, rRegI src, memory mem, immI_0 zero) 13240 %{ 13241 match(Set cr (CmpI (AndI src (LoadI mem)) zero)); 13242 13243 format %{ "testl $src, $mem" %} 13244 ins_encode %{ 13245 __ testl($src$$Register, $mem$$Address); 13246 %} 13247 ins_pipe(ialu_cr_reg_mem); 13248 %} 13249 13250 // Unsigned compare Instructions; really, same as signed except they 13251 // produce an rFlagsRegU instead of rFlagsReg. 13252 instruct compU_rReg(rFlagsRegU cr, rRegI op1, rRegI op2) 13253 %{ 13254 match(Set cr (CmpU op1 op2)); 13255 13256 format %{ "cmpl $op1, $op2\t# unsigned" %} 13257 ins_encode %{ 13258 __ cmpl($op1$$Register, $op2$$Register); 13259 %} 13260 ins_pipe(ialu_cr_reg_reg); 13261 %} 13262 13263 instruct compU_rReg_imm(rFlagsRegU cr, rRegI op1, immI op2) 13264 %{ 13265 match(Set cr (CmpU op1 op2)); 13266 13267 format %{ "cmpl $op1, $op2\t# unsigned" %} 13268 ins_encode %{ 13269 __ cmpl($op1$$Register, $op2$$constant); 13270 %} 13271 ins_pipe(ialu_cr_reg_imm); 13272 %} 13273 13274 instruct compU_rReg_mem(rFlagsRegU cr, rRegI op1, memory op2) 13275 %{ 13276 match(Set cr (CmpU op1 (LoadI op2))); 13277 13278 ins_cost(500); // XXX 13279 format %{ "cmpl $op1, $op2\t# unsigned" %} 13280 ins_encode %{ 13281 __ cmpl($op1$$Register, $op2$$Address); 13282 %} 13283 ins_pipe(ialu_cr_reg_mem); 13284 %} 13285 13286 instruct testU_reg(rFlagsRegU cr, rRegI src, immI_0 zero) 13287 %{ 13288 match(Set cr (CmpU src zero)); 13289 13290 format %{ "testl $src, $src\t# unsigned" %} 13291 ins_encode %{ 13292 __ testl($src$$Register, $src$$Register); 13293 %} 13294 ins_pipe(ialu_cr_reg_imm); 13295 %} 13296 13297 instruct compP_rReg(rFlagsRegU cr, rRegP op1, rRegP op2) 13298 %{ 13299 match(Set cr (CmpP op1 op2)); 13300 13301 format %{ "cmpq $op1, $op2\t# ptr" %} 13302 ins_encode %{ 13303 __ cmpq($op1$$Register, $op2$$Register); 13304 %} 13305 ins_pipe(ialu_cr_reg_reg); 13306 %} 13307 13308 instruct compP_rReg_mem(rFlagsRegU cr, rRegP op1, memory op2) 13309 %{ 13310 match(Set cr (CmpP op1 (LoadP op2))); 13311 predicate(n->in(2)->as_Load()->barrier_data() == 0); 13312 13313 ins_cost(500); // XXX 13314 format %{ "cmpq $op1, $op2\t# ptr" %} 13315 ins_encode %{ 13316 __ cmpq($op1$$Register, $op2$$Address); 13317 %} 13318 ins_pipe(ialu_cr_reg_mem); 13319 %} 13320 13321 // XXX this is generalized by compP_rReg_mem??? 13322 // Compare raw pointer (used in out-of-heap check). 13323 // Only works because non-oop pointers must be raw pointers 13324 // and raw pointers have no anti-dependencies. 13325 instruct compP_mem_rReg(rFlagsRegU cr, rRegP op1, memory op2) 13326 %{ 13327 predicate(n->in(2)->in(2)->bottom_type()->reloc() == relocInfo::none && 13328 n->in(2)->as_Load()->barrier_data() == 0); 13329 match(Set cr (CmpP op1 (LoadP op2))); 13330 13331 format %{ "cmpq $op1, $op2\t# raw ptr" %} 13332 ins_encode %{ 13333 __ cmpq($op1$$Register, $op2$$Address); 13334 %} 13335 ins_pipe(ialu_cr_reg_mem); 13336 %} 13337 13338 // This will generate a signed flags result. This should be OK since 13339 // any compare to a zero should be eq/neq. 13340 instruct testP_reg(rFlagsReg cr, rRegP src, immP0 zero) 13341 %{ 13342 match(Set cr (CmpP src zero)); 13343 13344 format %{ "testq $src, $src\t# ptr" %} 13345 ins_encode %{ 13346 __ testq($src$$Register, $src$$Register); 13347 %} 13348 ins_pipe(ialu_cr_reg_imm); 13349 %} 13350 13351 // This will generate a signed flags result. This should be OK since 13352 // any compare to a zero should be eq/neq. 13353 instruct testP_mem(rFlagsReg cr, memory op, immP0 zero) 13354 %{ 13355 predicate((!UseCompressedOops || (CompressedOops::base() != nullptr)) && 13356 n->in(1)->as_Load()->barrier_data() == 0); 13357 match(Set cr (CmpP (LoadP op) zero)); 13358 13359 ins_cost(500); // XXX 13360 format %{ "testq $op, 0xffffffffffffffff\t# ptr" %} 13361 ins_encode %{ 13362 __ testq($op$$Address, 0xFFFFFFFF); 13363 %} 13364 ins_pipe(ialu_cr_reg_imm); 13365 %} 13366 13367 instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero) 13368 %{ 13369 predicate(UseCompressedOops && (CompressedOops::base() == nullptr) && 13370 n->in(1)->as_Load()->barrier_data() == 0); 13371 match(Set cr (CmpP (LoadP mem) zero)); 13372 13373 format %{ "cmpq R12, $mem\t# ptr (R12_heapbase==0)" %} 13374 ins_encode %{ 13375 __ cmpq(r12, $mem$$Address); 13376 %} 13377 ins_pipe(ialu_cr_reg_mem); 13378 %} 13379 13380 instruct compN_rReg(rFlagsRegU cr, rRegN op1, rRegN op2) 13381 %{ 13382 match(Set cr (CmpN op1 op2)); 13383 13384 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 13385 ins_encode %{ __ cmpl($op1$$Register, $op2$$Register); %} 13386 ins_pipe(ialu_cr_reg_reg); 13387 %} 13388 13389 instruct compN_rReg_mem(rFlagsRegU cr, rRegN src, memory mem) 13390 %{ 13391 predicate(n->in(2)->as_Load()->barrier_data() == 0); 13392 match(Set cr (CmpN src (LoadN mem))); 13393 13394 format %{ "cmpl $src, $mem\t# compressed ptr" %} 13395 ins_encode %{ 13396 __ cmpl($src$$Register, $mem$$Address); 13397 %} 13398 ins_pipe(ialu_cr_reg_mem); 13399 %} 13400 13401 instruct compN_rReg_imm(rFlagsRegU cr, rRegN op1, immN op2) %{ 13402 match(Set cr (CmpN op1 op2)); 13403 13404 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 13405 ins_encode %{ 13406 __ cmp_narrow_oop($op1$$Register, (jobject)$op2$$constant); 13407 %} 13408 ins_pipe(ialu_cr_reg_imm); 13409 %} 13410 13411 instruct compN_mem_imm(rFlagsRegU cr, memory mem, immN src) 13412 %{ 13413 predicate(n->in(2)->as_Load()->barrier_data() == 0); 13414 match(Set cr (CmpN src (LoadN mem))); 13415 13416 format %{ "cmpl $mem, $src\t# compressed ptr" %} 13417 ins_encode %{ 13418 __ cmp_narrow_oop($mem$$Address, (jobject)$src$$constant); 13419 %} 13420 ins_pipe(ialu_cr_reg_mem); 13421 %} 13422 13423 instruct compN_rReg_imm_klass(rFlagsRegU cr, rRegN op1, immNKlass op2) %{ 13424 match(Set cr (CmpN op1 op2)); 13425 13426 format %{ "cmpl $op1, $op2\t# compressed klass ptr" %} 13427 ins_encode %{ 13428 __ cmp_narrow_klass($op1$$Register, (Klass*)$op2$$constant); 13429 %} 13430 ins_pipe(ialu_cr_reg_imm); 13431 %} 13432 13433 instruct compN_mem_imm_klass(rFlagsRegU cr, memory mem, immNKlass src) 13434 %{ 13435 predicate(!UseCompactObjectHeaders); 13436 match(Set cr (CmpN src (LoadNKlass mem))); 13437 13438 format %{ "cmpl $mem, $src\t# compressed klass ptr" %} 13439 ins_encode %{ 13440 __ cmp_narrow_klass($mem$$Address, (Klass*)$src$$constant); 13441 %} 13442 ins_pipe(ialu_cr_reg_mem); 13443 %} 13444 13445 instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{ 13446 match(Set cr (CmpN src zero)); 13447 13448 format %{ "testl $src, $src\t# compressed ptr" %} 13449 ins_encode %{ __ testl($src$$Register, $src$$Register); %} 13450 ins_pipe(ialu_cr_reg_imm); 13451 %} 13452 13453 instruct testN_mem(rFlagsReg cr, memory mem, immN0 zero) 13454 %{ 13455 predicate(CompressedOops::base() != nullptr && 13456 n->in(1)->as_Load()->barrier_data() == 0); 13457 match(Set cr (CmpN (LoadN mem) zero)); 13458 13459 ins_cost(500); // XXX 13460 format %{ "testl $mem, 0xffffffff\t# compressed ptr" %} 13461 ins_encode %{ 13462 __ cmpl($mem$$Address, (int)0xFFFFFFFF); 13463 %} 13464 ins_pipe(ialu_cr_reg_mem); 13465 %} 13466 13467 instruct testN_mem_reg0(rFlagsReg cr, memory mem, immN0 zero) 13468 %{ 13469 predicate(CompressedOops::base() == nullptr && 13470 n->in(1)->as_Load()->barrier_data() == 0); 13471 match(Set cr (CmpN (LoadN mem) zero)); 13472 13473 format %{ "cmpl R12, $mem\t# compressed ptr (R12_heapbase==0)" %} 13474 ins_encode %{ 13475 __ cmpl(r12, $mem$$Address); 13476 %} 13477 ins_pipe(ialu_cr_reg_mem); 13478 %} 13479 13480 // Yanked all unsigned pointer compare operations. 13481 // Pointer compares are done with CmpP which is already unsigned. 13482 13483 instruct compL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 13484 %{ 13485 match(Set cr (CmpL op1 op2)); 13486 13487 format %{ "cmpq $op1, $op2" %} 13488 ins_encode %{ 13489 __ cmpq($op1$$Register, $op2$$Register); 13490 %} 13491 ins_pipe(ialu_cr_reg_reg); 13492 %} 13493 13494 instruct compL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 13495 %{ 13496 match(Set cr (CmpL op1 op2)); 13497 13498 format %{ "cmpq $op1, $op2" %} 13499 ins_encode %{ 13500 __ cmpq($op1$$Register, $op2$$constant); 13501 %} 13502 ins_pipe(ialu_cr_reg_imm); 13503 %} 13504 13505 instruct compL_rReg_mem(rFlagsReg cr, rRegL op1, memory op2) 13506 %{ 13507 match(Set cr (CmpL op1 (LoadL op2))); 13508 13509 format %{ "cmpq $op1, $op2" %} 13510 ins_encode %{ 13511 __ cmpq($op1$$Register, $op2$$Address); 13512 %} 13513 ins_pipe(ialu_cr_reg_mem); 13514 %} 13515 13516 instruct testL_reg(rFlagsReg cr, rRegL src, immL0 zero) 13517 %{ 13518 match(Set cr (CmpL src zero)); 13519 13520 format %{ "testq $src, $src" %} 13521 ins_encode %{ 13522 __ testq($src$$Register, $src$$Register); 13523 %} 13524 ins_pipe(ialu_cr_reg_imm); 13525 %} 13526 13527 instruct testL_reg_imm(rFlagsReg cr, rRegL src, immL32 con, immL0 zero) 13528 %{ 13529 match(Set cr (CmpL (AndL src con) zero)); 13530 13531 format %{ "testq $src, $con\t# long" %} 13532 ins_encode %{ 13533 __ testq($src$$Register, $con$$constant); 13534 %} 13535 ins_pipe(ialu_cr_reg_imm); 13536 %} 13537 13538 instruct testL_reg_reg(rFlagsReg cr, rRegL src1, rRegL src2, immL0 zero) 13539 %{ 13540 match(Set cr (CmpL (AndL src1 src2) zero)); 13541 13542 format %{ "testq $src1, $src2\t# long" %} 13543 ins_encode %{ 13544 __ testq($src1$$Register, $src2$$Register); 13545 %} 13546 ins_pipe(ialu_cr_reg_imm); 13547 %} 13548 13549 instruct testL_reg_mem(rFlagsReg cr, rRegL src, memory mem, immL0 zero) 13550 %{ 13551 match(Set cr (CmpL (AndL src (LoadL mem)) zero)); 13552 13553 format %{ "testq $src, $mem" %} 13554 ins_encode %{ 13555 __ testq($src$$Register, $mem$$Address); 13556 %} 13557 ins_pipe(ialu_cr_reg_mem); 13558 %} 13559 13560 instruct testL_reg_mem2(rFlagsReg cr, rRegP src, memory mem, immL0 zero) 13561 %{ 13562 match(Set cr (CmpL (AndL (CastP2X src) (LoadL mem)) zero)); 13563 13564 format %{ "testq $src, $mem" %} 13565 ins_encode %{ 13566 __ testq($src$$Register, $mem$$Address); 13567 %} 13568 ins_pipe(ialu_cr_reg_mem); 13569 %} 13570 13571 // Manifest a CmpU result in an integer register. Very painful. 13572 // This is the test to avoid. 13573 instruct cmpU3_reg_reg(rRegI dst, rRegI src1, rRegI src2, rFlagsReg flags) 13574 %{ 13575 match(Set dst (CmpU3 src1 src2)); 13576 effect(KILL flags); 13577 13578 ins_cost(275); // XXX 13579 format %{ "cmpl $src1, $src2\t# CmpL3\n\t" 13580 "movl $dst, -1\n\t" 13581 "jb,u done\n\t" 13582 "setcc $dst \t# emits setne + movzbl or setzune for APX" 13583 "done:" %} 13584 ins_encode %{ 13585 Label done; 13586 __ cmpl($src1$$Register, $src2$$Register); 13587 __ movl($dst$$Register, -1); 13588 __ jccb(Assembler::below, done); 13589 __ setcc(Assembler::notZero, $dst$$Register); 13590 __ bind(done); 13591 %} 13592 ins_pipe(pipe_slow); 13593 %} 13594 13595 // Manifest a CmpL result in an integer register. Very painful. 13596 // This is the test to avoid. 13597 instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 13598 %{ 13599 match(Set dst (CmpL3 src1 src2)); 13600 effect(KILL flags); 13601 13602 ins_cost(275); // XXX 13603 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 13604 "movl $dst, -1\n\t" 13605 "jl,s done\n\t" 13606 "setcc $dst \t# emits setne + movzbl or setzune for APX" 13607 "done:" %} 13608 ins_encode %{ 13609 Label done; 13610 __ cmpq($src1$$Register, $src2$$Register); 13611 __ movl($dst$$Register, -1); 13612 __ jccb(Assembler::less, done); 13613 __ setcc(Assembler::notZero, $dst$$Register); 13614 __ bind(done); 13615 %} 13616 ins_pipe(pipe_slow); 13617 %} 13618 13619 // Manifest a CmpUL result in an integer register. Very painful. 13620 // This is the test to avoid. 13621 instruct cmpUL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 13622 %{ 13623 match(Set dst (CmpUL3 src1 src2)); 13624 effect(KILL flags); 13625 13626 ins_cost(275); // XXX 13627 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 13628 "movl $dst, -1\n\t" 13629 "jb,u done\n\t" 13630 "setcc $dst \t# emits setne + movzbl or setzune for APX" 13631 "done:" %} 13632 ins_encode %{ 13633 Label done; 13634 __ cmpq($src1$$Register, $src2$$Register); 13635 __ movl($dst$$Register, -1); 13636 __ jccb(Assembler::below, done); 13637 __ setcc(Assembler::notZero, $dst$$Register); 13638 __ bind(done); 13639 %} 13640 ins_pipe(pipe_slow); 13641 %} 13642 13643 // Unsigned long compare Instructions; really, same as signed long except they 13644 // produce an rFlagsRegU instead of rFlagsReg. 13645 instruct compUL_rReg(rFlagsRegU cr, rRegL op1, rRegL op2) 13646 %{ 13647 match(Set cr (CmpUL op1 op2)); 13648 13649 format %{ "cmpq $op1, $op2\t# unsigned" %} 13650 ins_encode %{ 13651 __ cmpq($op1$$Register, $op2$$Register); 13652 %} 13653 ins_pipe(ialu_cr_reg_reg); 13654 %} 13655 13656 instruct compUL_rReg_imm(rFlagsRegU cr, rRegL op1, immL32 op2) 13657 %{ 13658 match(Set cr (CmpUL op1 op2)); 13659 13660 format %{ "cmpq $op1, $op2\t# unsigned" %} 13661 ins_encode %{ 13662 __ cmpq($op1$$Register, $op2$$constant); 13663 %} 13664 ins_pipe(ialu_cr_reg_imm); 13665 %} 13666 13667 instruct compUL_rReg_mem(rFlagsRegU cr, rRegL op1, memory op2) 13668 %{ 13669 match(Set cr (CmpUL op1 (LoadL op2))); 13670 13671 format %{ "cmpq $op1, $op2\t# unsigned" %} 13672 ins_encode %{ 13673 __ cmpq($op1$$Register, $op2$$Address); 13674 %} 13675 ins_pipe(ialu_cr_reg_mem); 13676 %} 13677 13678 instruct testUL_reg(rFlagsRegU cr, rRegL src, immL0 zero) 13679 %{ 13680 match(Set cr (CmpUL src zero)); 13681 13682 format %{ "testq $src, $src\t# unsigned" %} 13683 ins_encode %{ 13684 __ testq($src$$Register, $src$$Register); 13685 %} 13686 ins_pipe(ialu_cr_reg_imm); 13687 %} 13688 13689 instruct compB_mem_imm(rFlagsReg cr, memory mem, immI8 imm) 13690 %{ 13691 match(Set cr (CmpI (LoadB mem) imm)); 13692 13693 ins_cost(125); 13694 format %{ "cmpb $mem, $imm" %} 13695 ins_encode %{ __ cmpb($mem$$Address, $imm$$constant); %} 13696 ins_pipe(ialu_cr_reg_mem); 13697 %} 13698 13699 instruct testUB_mem_imm(rFlagsReg cr, memory mem, immU7 imm, immI_0 zero) 13700 %{ 13701 match(Set cr (CmpI (AndI (LoadUB mem) imm) zero)); 13702 13703 ins_cost(125); 13704 format %{ "testb $mem, $imm\t# ubyte" %} 13705 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %} 13706 ins_pipe(ialu_cr_reg_mem); 13707 %} 13708 13709 instruct testB_mem_imm(rFlagsReg cr, memory mem, immI8 imm, immI_0 zero) 13710 %{ 13711 match(Set cr (CmpI (AndI (LoadB mem) imm) zero)); 13712 13713 ins_cost(125); 13714 format %{ "testb $mem, $imm\t# byte" %} 13715 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %} 13716 ins_pipe(ialu_cr_reg_mem); 13717 %} 13718 13719 //----------Max and Min-------------------------------------------------------- 13720 // Min Instructions 13721 13722 instruct cmovI_reg_g(rRegI dst, rRegI src, rFlagsReg cr) 13723 %{ 13724 predicate(!UseAPX); 13725 effect(USE_DEF dst, USE src, USE cr); 13726 13727 format %{ "cmovlgt $dst, $src\t# min" %} 13728 ins_encode %{ 13729 __ cmovl(Assembler::greater, $dst$$Register, $src$$Register); 13730 %} 13731 ins_pipe(pipe_cmov_reg); 13732 %} 13733 13734 instruct cmovI_reg_g_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr) 13735 %{ 13736 predicate(UseAPX); 13737 effect(DEF dst, USE src1, USE src2, USE cr); 13738 13739 format %{ "ecmovlgt $dst, $src1, $src2\t# min ndd" %} 13740 ins_encode %{ 13741 __ ecmovl(Assembler::greater, $dst$$Register, $src1$$Register, $src2$$Register); 13742 %} 13743 ins_pipe(pipe_cmov_reg); 13744 %} 13745 13746 instruct minI_rReg(rRegI dst, rRegI src) 13747 %{ 13748 predicate(!UseAPX); 13749 match(Set dst (MinI dst src)); 13750 13751 ins_cost(200); 13752 expand %{ 13753 rFlagsReg cr; 13754 compI_rReg(cr, dst, src); 13755 cmovI_reg_g(dst, src, cr); 13756 %} 13757 %} 13758 13759 instruct minI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2) 13760 %{ 13761 predicate(UseAPX); 13762 match(Set dst (MinI src1 src2)); 13763 effect(DEF dst, USE src1, USE src2); 13764 13765 ins_cost(200); 13766 expand %{ 13767 rFlagsReg cr; 13768 compI_rReg(cr, src1, src2); 13769 cmovI_reg_g_ndd(dst, src1, src2, cr); 13770 %} 13771 %} 13772 13773 instruct cmovI_reg_l(rRegI dst, rRegI src, rFlagsReg cr) 13774 %{ 13775 predicate(!UseAPX); 13776 effect(USE_DEF dst, USE src, USE cr); 13777 13778 format %{ "cmovllt $dst, $src\t# max" %} 13779 ins_encode %{ 13780 __ cmovl(Assembler::less, $dst$$Register, $src$$Register); 13781 %} 13782 ins_pipe(pipe_cmov_reg); 13783 %} 13784 13785 instruct cmovI_reg_l_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr) 13786 %{ 13787 predicate(UseAPX); 13788 effect(DEF dst, USE src1, USE src2, USE cr); 13789 13790 format %{ "ecmovllt $dst, $src1, $src2\t# max ndd" %} 13791 ins_encode %{ 13792 __ ecmovl(Assembler::less, $dst$$Register, $src1$$Register, $src2$$Register); 13793 %} 13794 ins_pipe(pipe_cmov_reg); 13795 %} 13796 13797 instruct maxI_rReg(rRegI dst, rRegI src) 13798 %{ 13799 predicate(!UseAPX); 13800 match(Set dst (MaxI dst src)); 13801 13802 ins_cost(200); 13803 expand %{ 13804 rFlagsReg cr; 13805 compI_rReg(cr, dst, src); 13806 cmovI_reg_l(dst, src, cr); 13807 %} 13808 %} 13809 13810 instruct maxI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2) 13811 %{ 13812 predicate(UseAPX); 13813 match(Set dst (MaxI src1 src2)); 13814 effect(DEF dst, USE src1, USE src2); 13815 13816 ins_cost(200); 13817 expand %{ 13818 rFlagsReg cr; 13819 compI_rReg(cr, src1, src2); 13820 cmovI_reg_l_ndd(dst, src1, src2, cr); 13821 %} 13822 %} 13823 13824 // ============================================================================ 13825 // Branch Instructions 13826 13827 // Jump Direct - Label defines a relative address from JMP+1 13828 instruct jmpDir(label labl) 13829 %{ 13830 match(Goto); 13831 effect(USE labl); 13832 13833 ins_cost(300); 13834 format %{ "jmp $labl" %} 13835 size(5); 13836 ins_encode %{ 13837 Label* L = $labl$$label; 13838 __ jmp(*L, false); // Always long jump 13839 %} 13840 ins_pipe(pipe_jmp); 13841 %} 13842 13843 // Jump Direct Conditional - Label defines a relative address from Jcc+1 13844 instruct jmpCon(cmpOp cop, rFlagsReg cr, label labl) 13845 %{ 13846 match(If cop cr); 13847 effect(USE labl); 13848 13849 ins_cost(300); 13850 format %{ "j$cop $labl" %} 13851 size(6); 13852 ins_encode %{ 13853 Label* L = $labl$$label; 13854 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 13855 %} 13856 ins_pipe(pipe_jcc); 13857 %} 13858 13859 // Jump Direct Conditional - Label defines a relative address from Jcc+1 13860 instruct jmpLoopEnd(cmpOp cop, rFlagsReg cr, label labl) 13861 %{ 13862 match(CountedLoopEnd cop cr); 13863 effect(USE labl); 13864 13865 ins_cost(300); 13866 format %{ "j$cop $labl\t# loop end" %} 13867 size(6); 13868 ins_encode %{ 13869 Label* L = $labl$$label; 13870 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 13871 %} 13872 ins_pipe(pipe_jcc); 13873 %} 13874 13875 // Jump Direct Conditional - using unsigned comparison 13876 instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 13877 match(If cop cmp); 13878 effect(USE labl); 13879 13880 ins_cost(300); 13881 format %{ "j$cop,u $labl" %} 13882 size(6); 13883 ins_encode %{ 13884 Label* L = $labl$$label; 13885 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 13886 %} 13887 ins_pipe(pipe_jcc); 13888 %} 13889 13890 instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 13891 match(If cop cmp); 13892 effect(USE labl); 13893 13894 ins_cost(200); 13895 format %{ "j$cop,u $labl" %} 13896 size(6); 13897 ins_encode %{ 13898 Label* L = $labl$$label; 13899 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 13900 %} 13901 ins_pipe(pipe_jcc); 13902 %} 13903 13904 instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 13905 match(If cop cmp); 13906 effect(USE labl); 13907 13908 ins_cost(200); 13909 format %{ $$template 13910 if ($cop$$cmpcode == Assembler::notEqual) { 13911 $$emit$$"jp,u $labl\n\t" 13912 $$emit$$"j$cop,u $labl" 13913 } else { 13914 $$emit$$"jp,u done\n\t" 13915 $$emit$$"j$cop,u $labl\n\t" 13916 $$emit$$"done:" 13917 } 13918 %} 13919 ins_encode %{ 13920 Label* l = $labl$$label; 13921 if ($cop$$cmpcode == Assembler::notEqual) { 13922 __ jcc(Assembler::parity, *l, false); 13923 __ jcc(Assembler::notEqual, *l, false); 13924 } else if ($cop$$cmpcode == Assembler::equal) { 13925 Label done; 13926 __ jccb(Assembler::parity, done); 13927 __ jcc(Assembler::equal, *l, false); 13928 __ bind(done); 13929 } else { 13930 ShouldNotReachHere(); 13931 } 13932 %} 13933 ins_pipe(pipe_jcc); 13934 %} 13935 13936 // ============================================================================ 13937 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary 13938 // superklass array for an instance of the superklass. Set a hidden 13939 // internal cache on a hit (cache is checked with exposed code in 13940 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The 13941 // encoding ALSO sets flags. 13942 13943 instruct partialSubtypeCheck(rdi_RegP result, 13944 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 13945 rFlagsReg cr) 13946 %{ 13947 match(Set result (PartialSubtypeCheck sub super)); 13948 predicate(!UseSecondarySupersTable); 13949 effect(KILL rcx, KILL cr); 13950 13951 ins_cost(1100); // slightly larger than the next version 13952 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 13953 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 13954 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 13955 "repne scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t" 13956 "jne,s miss\t\t# Missed: rdi not-zero\n\t" 13957 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 13958 "xorq $result, $result\t\t Hit: rdi zero\n\t" 13959 "miss:\t" %} 13960 13961 ins_encode %{ 13962 Label miss; 13963 // NB: Callers may assume that, when $result is a valid register, 13964 // check_klass_subtype_slow_path_linear sets it to a nonzero 13965 // value. 13966 __ check_klass_subtype_slow_path_linear($sub$$Register, $super$$Register, 13967 $rcx$$Register, $result$$Register, 13968 nullptr, &miss, 13969 /*set_cond_codes:*/ true); 13970 __ xorptr($result$$Register, $result$$Register); 13971 __ bind(miss); 13972 %} 13973 13974 ins_pipe(pipe_slow); 13975 %} 13976 13977 // ============================================================================ 13978 // Two versions of hashtable-based partialSubtypeCheck, both used when 13979 // we need to search for a super class in the secondary supers array. 13980 // The first is used when we don't know _a priori_ the class being 13981 // searched for. The second, far more common, is used when we do know: 13982 // this is used for instanceof, checkcast, and any case where C2 can 13983 // determine it by constant propagation. 13984 13985 instruct partialSubtypeCheckVarSuper(rsi_RegP sub, rax_RegP super, rdi_RegP result, 13986 rdx_RegL temp1, rcx_RegL temp2, rbx_RegP temp3, r11_RegL temp4, 13987 rFlagsReg cr) 13988 %{ 13989 match(Set result (PartialSubtypeCheck sub super)); 13990 predicate(UseSecondarySupersTable); 13991 effect(KILL cr, TEMP temp1, TEMP temp2, TEMP temp3, TEMP temp4); 13992 13993 ins_cost(1000); 13994 format %{ "partialSubtypeCheck $result, $sub, $super" %} 13995 13996 ins_encode %{ 13997 __ lookup_secondary_supers_table_var($sub$$Register, $super$$Register, $temp1$$Register, $temp2$$Register, 13998 $temp3$$Register, $temp4$$Register, $result$$Register); 13999 %} 14000 14001 ins_pipe(pipe_slow); 14002 %} 14003 14004 instruct partialSubtypeCheckConstSuper(rsi_RegP sub, rax_RegP super_reg, immP super_con, rdi_RegP result, 14005 rdx_RegL temp1, rcx_RegL temp2, rbx_RegP temp3, r11_RegL temp4, 14006 rFlagsReg cr) 14007 %{ 14008 match(Set result (PartialSubtypeCheck sub (Binary super_reg super_con))); 14009 predicate(UseSecondarySupersTable); 14010 effect(KILL cr, TEMP temp1, TEMP temp2, TEMP temp3, TEMP temp4); 14011 14012 ins_cost(700); // smaller than the next version 14013 format %{ "partialSubtypeCheck $result, $sub, $super_reg, $super_con" %} 14014 14015 ins_encode %{ 14016 u1 super_klass_slot = ((Klass*)$super_con$$constant)->hash_slot(); 14017 if (InlineSecondarySupersTest) { 14018 __ lookup_secondary_supers_table_const($sub$$Register, $super_reg$$Register, $temp1$$Register, $temp2$$Register, 14019 $temp3$$Register, $temp4$$Register, $result$$Register, 14020 super_klass_slot); 14021 } else { 14022 __ call(RuntimeAddress(StubRoutines::lookup_secondary_supers_table_stub(super_klass_slot))); 14023 } 14024 %} 14025 14026 ins_pipe(pipe_slow); 14027 %} 14028 14029 // ============================================================================ 14030 // Branch Instructions -- short offset versions 14031 // 14032 // These instructions are used to replace jumps of a long offset (the default 14033 // match) with jumps of a shorter offset. These instructions are all tagged 14034 // with the ins_short_branch attribute, which causes the ADLC to suppress the 14035 // match rules in general matching. Instead, the ADLC generates a conversion 14036 // method in the MachNode which can be used to do in-place replacement of the 14037 // long variant with the shorter variant. The compiler will determine if a 14038 // branch can be taken by the is_short_branch_offset() predicate in the machine 14039 // specific code section of the file. 14040 14041 // Jump Direct - Label defines a relative address from JMP+1 14042 instruct jmpDir_short(label labl) %{ 14043 match(Goto); 14044 effect(USE labl); 14045 14046 ins_cost(300); 14047 format %{ "jmp,s $labl" %} 14048 size(2); 14049 ins_encode %{ 14050 Label* L = $labl$$label; 14051 __ jmpb(*L); 14052 %} 14053 ins_pipe(pipe_jmp); 14054 ins_short_branch(1); 14055 %} 14056 14057 // Jump Direct Conditional - Label defines a relative address from Jcc+1 14058 instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{ 14059 match(If cop cr); 14060 effect(USE labl); 14061 14062 ins_cost(300); 14063 format %{ "j$cop,s $labl" %} 14064 size(2); 14065 ins_encode %{ 14066 Label* L = $labl$$label; 14067 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 14068 %} 14069 ins_pipe(pipe_jcc); 14070 ins_short_branch(1); 14071 %} 14072 14073 // Jump Direct Conditional - Label defines a relative address from Jcc+1 14074 instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{ 14075 match(CountedLoopEnd cop cr); 14076 effect(USE labl); 14077 14078 ins_cost(300); 14079 format %{ "j$cop,s $labl\t# loop end" %} 14080 size(2); 14081 ins_encode %{ 14082 Label* L = $labl$$label; 14083 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 14084 %} 14085 ins_pipe(pipe_jcc); 14086 ins_short_branch(1); 14087 %} 14088 14089 // Jump Direct Conditional - using unsigned comparison 14090 instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 14091 match(If cop cmp); 14092 effect(USE labl); 14093 14094 ins_cost(300); 14095 format %{ "j$cop,us $labl" %} 14096 size(2); 14097 ins_encode %{ 14098 Label* L = $labl$$label; 14099 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 14100 %} 14101 ins_pipe(pipe_jcc); 14102 ins_short_branch(1); 14103 %} 14104 14105 instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 14106 match(If cop cmp); 14107 effect(USE labl); 14108 14109 ins_cost(300); 14110 format %{ "j$cop,us $labl" %} 14111 size(2); 14112 ins_encode %{ 14113 Label* L = $labl$$label; 14114 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 14115 %} 14116 ins_pipe(pipe_jcc); 14117 ins_short_branch(1); 14118 %} 14119 14120 instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 14121 match(If cop cmp); 14122 effect(USE labl); 14123 14124 ins_cost(300); 14125 format %{ $$template 14126 if ($cop$$cmpcode == Assembler::notEqual) { 14127 $$emit$$"jp,u,s $labl\n\t" 14128 $$emit$$"j$cop,u,s $labl" 14129 } else { 14130 $$emit$$"jp,u,s done\n\t" 14131 $$emit$$"j$cop,u,s $labl\n\t" 14132 $$emit$$"done:" 14133 } 14134 %} 14135 size(4); 14136 ins_encode %{ 14137 Label* l = $labl$$label; 14138 if ($cop$$cmpcode == Assembler::notEqual) { 14139 __ jccb(Assembler::parity, *l); 14140 __ jccb(Assembler::notEqual, *l); 14141 } else if ($cop$$cmpcode == Assembler::equal) { 14142 Label done; 14143 __ jccb(Assembler::parity, done); 14144 __ jccb(Assembler::equal, *l); 14145 __ bind(done); 14146 } else { 14147 ShouldNotReachHere(); 14148 } 14149 %} 14150 ins_pipe(pipe_jcc); 14151 ins_short_branch(1); 14152 %} 14153 14154 // ============================================================================ 14155 // inlined locking and unlocking 14156 14157 instruct cmpFastLock(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr) %{ 14158 predicate(LockingMode != LM_LIGHTWEIGHT); 14159 match(Set cr (FastLock object box)); 14160 effect(TEMP tmp, TEMP scr, USE_KILL box); 14161 ins_cost(300); 14162 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr" %} 14163 ins_encode %{ 14164 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, 14165 $scr$$Register, noreg, noreg, r15_thread, nullptr); 14166 %} 14167 ins_pipe(pipe_slow); 14168 %} 14169 14170 instruct cmpFastUnlock(rFlagsReg cr, rRegP object, rax_RegP box, rRegP tmp) %{ 14171 predicate(LockingMode != LM_LIGHTWEIGHT); 14172 match(Set cr (FastUnlock object box)); 14173 effect(TEMP tmp, USE_KILL box); 14174 ins_cost(300); 14175 format %{ "fastunlock $object,$box\t! kills $box,$tmp" %} 14176 ins_encode %{ 14177 __ fast_unlock($object$$Register, $box$$Register, $tmp$$Register); 14178 %} 14179 ins_pipe(pipe_slow); 14180 %} 14181 14182 instruct cmpFastLockLightweight(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI rax_reg, rRegP tmp) %{ 14183 predicate(LockingMode == LM_LIGHTWEIGHT); 14184 match(Set cr (FastLock object box)); 14185 effect(TEMP rax_reg, TEMP tmp, USE_KILL box); 14186 ins_cost(300); 14187 format %{ "fastlock $object,$box\t! kills $box,$rax_reg,$tmp" %} 14188 ins_encode %{ 14189 __ fast_lock_lightweight($object$$Register, $box$$Register, $rax_reg$$Register, $tmp$$Register, r15_thread); 14190 %} 14191 ins_pipe(pipe_slow); 14192 %} 14193 14194 instruct cmpFastUnlockLightweight(rFlagsReg cr, rRegP object, rax_RegP rax_reg, rRegP tmp) %{ 14195 predicate(LockingMode == LM_LIGHTWEIGHT); 14196 match(Set cr (FastUnlock object rax_reg)); 14197 effect(TEMP tmp, USE_KILL rax_reg); 14198 ins_cost(300); 14199 format %{ "fastunlock $object,$rax_reg\t! kills $rax_reg,$tmp" %} 14200 ins_encode %{ 14201 __ fast_unlock_lightweight($object$$Register, $rax_reg$$Register, $tmp$$Register, r15_thread); 14202 %} 14203 ins_pipe(pipe_slow); 14204 %} 14205 14206 14207 // ============================================================================ 14208 // Safepoint Instructions 14209 instruct safePoint_poll_tls(rFlagsReg cr, rRegP poll) 14210 %{ 14211 match(SafePoint poll); 14212 effect(KILL cr, USE poll); 14213 14214 format %{ "testl rax, [$poll]\t" 14215 "# Safepoint: poll for GC" %} 14216 ins_cost(125); 14217 ins_encode %{ 14218 __ relocate(relocInfo::poll_type); 14219 address pre_pc = __ pc(); 14220 __ testl(rax, Address($poll$$Register, 0)); 14221 assert(nativeInstruction_at(pre_pc)->is_safepoint_poll(), "must emit test %%eax [reg]"); 14222 %} 14223 ins_pipe(ialu_reg_mem); 14224 %} 14225 14226 instruct mask_all_evexL(kReg dst, rRegL src) %{ 14227 match(Set dst (MaskAll src)); 14228 format %{ "mask_all_evexL $dst, $src \t! mask all operation" %} 14229 ins_encode %{ 14230 int mask_len = Matcher::vector_length(this); 14231 __ vector_maskall_operation($dst$$KRegister, $src$$Register, mask_len); 14232 %} 14233 ins_pipe( pipe_slow ); 14234 %} 14235 14236 instruct mask_all_evexI_GT32(kReg dst, rRegI src, rRegL tmp) %{ 14237 predicate(Matcher::vector_length(n) > 32); 14238 match(Set dst (MaskAll src)); 14239 effect(TEMP tmp); 14240 format %{ "mask_all_evexI_GT32 $dst, $src \t! using $tmp as TEMP" %} 14241 ins_encode %{ 14242 int mask_len = Matcher::vector_length(this); 14243 __ movslq($tmp$$Register, $src$$Register); 14244 __ vector_maskall_operation($dst$$KRegister, $tmp$$Register, mask_len); 14245 %} 14246 ins_pipe( pipe_slow ); 14247 %} 14248 14249 // ============================================================================ 14250 // Procedure Call/Return Instructions 14251 // Call Java Static Instruction 14252 // Note: If this code changes, the corresponding ret_addr_offset() and 14253 // compute_padding() functions will have to be adjusted. 14254 instruct CallStaticJavaDirect(method meth) %{ 14255 match(CallStaticJava); 14256 effect(USE meth); 14257 14258 ins_cost(300); 14259 format %{ "call,static " %} 14260 opcode(0xE8); /* E8 cd */ 14261 ins_encode(clear_avx, Java_Static_Call(meth), call_epilog); 14262 ins_pipe(pipe_slow); 14263 ins_alignment(4); 14264 %} 14265 14266 // Call Java Dynamic Instruction 14267 // Note: If this code changes, the corresponding ret_addr_offset() and 14268 // compute_padding() functions will have to be adjusted. 14269 instruct CallDynamicJavaDirect(method meth) 14270 %{ 14271 match(CallDynamicJava); 14272 effect(USE meth); 14273 14274 ins_cost(300); 14275 format %{ "movq rax, #Universe::non_oop_word()\n\t" 14276 "call,dynamic " %} 14277 ins_encode(clear_avx, Java_Dynamic_Call(meth), call_epilog); 14278 ins_pipe(pipe_slow); 14279 ins_alignment(4); 14280 %} 14281 14282 // Call Runtime Instruction 14283 instruct CallRuntimeDirect(method meth) 14284 %{ 14285 match(CallRuntime); 14286 effect(USE meth); 14287 14288 ins_cost(300); 14289 format %{ "call,runtime " %} 14290 ins_encode(clear_avx, Java_To_Runtime(meth)); 14291 ins_pipe(pipe_slow); 14292 %} 14293 14294 // Call runtime without safepoint 14295 instruct CallLeafDirect(method meth) 14296 %{ 14297 match(CallLeaf); 14298 effect(USE meth); 14299 14300 ins_cost(300); 14301 format %{ "call_leaf,runtime " %} 14302 ins_encode(clear_avx, Java_To_Runtime(meth)); 14303 ins_pipe(pipe_slow); 14304 %} 14305 14306 // Call runtime without safepoint and with vector arguments 14307 instruct CallLeafDirectVector(method meth) 14308 %{ 14309 match(CallLeafVector); 14310 effect(USE meth); 14311 14312 ins_cost(300); 14313 format %{ "call_leaf,vector " %} 14314 ins_encode(Java_To_Runtime(meth)); 14315 ins_pipe(pipe_slow); 14316 %} 14317 14318 // Call runtime without safepoint 14319 instruct CallLeafNoFPDirect(method meth) 14320 %{ 14321 match(CallLeafNoFP); 14322 effect(USE meth); 14323 14324 ins_cost(300); 14325 format %{ "call_leaf_nofp,runtime " %} 14326 ins_encode(clear_avx, Java_To_Runtime(meth)); 14327 ins_pipe(pipe_slow); 14328 %} 14329 14330 // Return Instruction 14331 // Remove the return address & jump to it. 14332 // Notice: We always emit a nop after a ret to make sure there is room 14333 // for safepoint patching 14334 instruct Ret() 14335 %{ 14336 match(Return); 14337 14338 format %{ "ret" %} 14339 ins_encode %{ 14340 __ ret(0); 14341 %} 14342 ins_pipe(pipe_jmp); 14343 %} 14344 14345 // Tail Call; Jump from runtime stub to Java code. 14346 // Also known as an 'interprocedural jump'. 14347 // Target of jump will eventually return to caller. 14348 // TailJump below removes the return address. 14349 // Don't use rbp for 'jump_target' because a MachEpilogNode has already been 14350 // emitted just above the TailCall which has reset rbp to the caller state. 14351 instruct TailCalljmpInd(no_rbp_RegP jump_target, rbx_RegP method_ptr) 14352 %{ 14353 match(TailCall jump_target method_ptr); 14354 14355 ins_cost(300); 14356 format %{ "jmp $jump_target\t# rbx holds method" %} 14357 ins_encode %{ 14358 __ jmp($jump_target$$Register); 14359 %} 14360 ins_pipe(pipe_jmp); 14361 %} 14362 14363 // Tail Jump; remove the return address; jump to target. 14364 // TailCall above leaves the return address around. 14365 instruct tailjmpInd(no_rbp_RegP jump_target, rax_RegP ex_oop) 14366 %{ 14367 match(TailJump jump_target ex_oop); 14368 14369 ins_cost(300); 14370 format %{ "popq rdx\t# pop return address\n\t" 14371 "jmp $jump_target" %} 14372 ins_encode %{ 14373 __ popq(as_Register(RDX_enc)); 14374 __ jmp($jump_target$$Register); 14375 %} 14376 ins_pipe(pipe_jmp); 14377 %} 14378 14379 // Forward exception. 14380 instruct ForwardExceptionjmp() 14381 %{ 14382 match(ForwardException); 14383 14384 format %{ "jmp forward_exception_stub" %} 14385 ins_encode %{ 14386 __ jump(RuntimeAddress(StubRoutines::forward_exception_entry()), noreg); 14387 %} 14388 ins_pipe(pipe_jmp); 14389 %} 14390 14391 // Create exception oop: created by stack-crawling runtime code. 14392 // Created exception is now available to this handler, and is setup 14393 // just prior to jumping to this handler. No code emitted. 14394 instruct CreateException(rax_RegP ex_oop) 14395 %{ 14396 match(Set ex_oop (CreateEx)); 14397 14398 size(0); 14399 // use the following format syntax 14400 format %{ "# exception oop is in rax; no code emitted" %} 14401 ins_encode(); 14402 ins_pipe(empty); 14403 %} 14404 14405 // Rethrow exception: 14406 // The exception oop will come in the first argument position. 14407 // Then JUMP (not call) to the rethrow stub code. 14408 instruct RethrowException() 14409 %{ 14410 match(Rethrow); 14411 14412 // use the following format syntax 14413 format %{ "jmp rethrow_stub" %} 14414 ins_encode %{ 14415 __ jump(RuntimeAddress(OptoRuntime::rethrow_stub()), noreg); 14416 %} 14417 ins_pipe(pipe_jmp); 14418 %} 14419 14420 // ============================================================================ 14421 // This name is KNOWN by the ADLC and cannot be changed. 14422 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type 14423 // for this guy. 14424 instruct tlsLoadP(r15_RegP dst) %{ 14425 match(Set dst (ThreadLocal)); 14426 effect(DEF dst); 14427 14428 size(0); 14429 format %{ "# TLS is in R15" %} 14430 ins_encode( /*empty encoding*/ ); 14431 ins_pipe(ialu_reg_reg); 14432 %} 14433 14434 14435 //----------PEEPHOLE RULES----------------------------------------------------- 14436 // These must follow all instruction definitions as they use the names 14437 // defined in the instructions definitions. 14438 // 14439 // peeppredicate ( rule_predicate ); 14440 // // the predicate unless which the peephole rule will be ignored 14441 // 14442 // peepmatch ( root_instr_name [preceding_instruction]* ); 14443 // 14444 // peepprocedure ( procedure_name ); 14445 // // provide a procedure name to perform the optimization, the procedure should 14446 // // reside in the architecture dependent peephole file, the method has the 14447 // // signature of MachNode* (Block*, int, PhaseRegAlloc*, (MachNode*)(*)(), int...) 14448 // // with the arguments being the basic block, the current node index inside the 14449 // // block, the register allocator, the functions upon invoked return a new node 14450 // // defined in peepreplace, and the rules of the nodes appearing in the 14451 // // corresponding peepmatch, the function return true if successful, else 14452 // // return false 14453 // 14454 // peepconstraint %{ 14455 // (instruction_number.operand_name relational_op instruction_number.operand_name 14456 // [, ...] ); 14457 // // instruction numbers are zero-based using left to right order in peepmatch 14458 // 14459 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 14460 // // provide an instruction_number.operand_name for each operand that appears 14461 // // in the replacement instruction's match rule 14462 // 14463 // ---------VM FLAGS--------------------------------------------------------- 14464 // 14465 // All peephole optimizations can be turned off using -XX:-OptoPeephole 14466 // 14467 // Each peephole rule is given an identifying number starting with zero and 14468 // increasing by one in the order seen by the parser. An individual peephole 14469 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 14470 // on the command-line. 14471 // 14472 // ---------CURRENT LIMITATIONS---------------------------------------------- 14473 // 14474 // Only transformations inside a basic block (do we need more for peephole) 14475 // 14476 // ---------EXAMPLE---------------------------------------------------------- 14477 // 14478 // // pertinent parts of existing instructions in architecture description 14479 // instruct movI(rRegI dst, rRegI src) 14480 // %{ 14481 // match(Set dst (CopyI src)); 14482 // %} 14483 // 14484 // instruct incI_rReg(rRegI dst, immI_1 src, rFlagsReg cr) 14485 // %{ 14486 // match(Set dst (AddI dst src)); 14487 // effect(KILL cr); 14488 // %} 14489 // 14490 // instruct leaI_rReg_immI(rRegI dst, immI_1 src) 14491 // %{ 14492 // match(Set dst (AddI dst src)); 14493 // %} 14494 // 14495 // 1. Simple replacement 14496 // - Only match adjacent instructions in same basic block 14497 // - Only equality constraints 14498 // - Only constraints between operands, not (0.dest_reg == RAX_enc) 14499 // - Only one replacement instruction 14500 // 14501 // // Change (inc mov) to lea 14502 // peephole %{ 14503 // // lea should only be emitted when beneficial 14504 // peeppredicate( VM_Version::supports_fast_2op_lea() ); 14505 // // increment preceded by register-register move 14506 // peepmatch ( incI_rReg movI ); 14507 // // require that the destination register of the increment 14508 // // match the destination register of the move 14509 // peepconstraint ( 0.dst == 1.dst ); 14510 // // construct a replacement instruction that sets 14511 // // the destination to ( move's source register + one ) 14512 // peepreplace ( leaI_rReg_immI( 0.dst 1.src 0.src ) ); 14513 // %} 14514 // 14515 // 2. Procedural replacement 14516 // - More flexible finding relevent nodes 14517 // - More flexible constraints 14518 // - More flexible transformations 14519 // - May utilise architecture-dependent API more effectively 14520 // - Currently only one replacement instruction due to adlc parsing capabilities 14521 // 14522 // // Change (inc mov) to lea 14523 // peephole %{ 14524 // // lea should only be emitted when beneficial 14525 // peeppredicate( VM_Version::supports_fast_2op_lea() ); 14526 // // the rule numbers of these nodes inside are passed into the function below 14527 // peepmatch ( incI_rReg movI ); 14528 // // the method that takes the responsibility of transformation 14529 // peepprocedure ( inc_mov_to_lea ); 14530 // // the replacement is a leaI_rReg_immI, a lambda upon invoked creating this 14531 // // node is passed into the function above 14532 // peepreplace ( leaI_rReg_immI() ); 14533 // %} 14534 14535 // These instructions is not matched by the matcher but used by the peephole 14536 instruct leaI_rReg_rReg_peep(rRegI dst, rRegI src1, rRegI src2) 14537 %{ 14538 predicate(false); 14539 match(Set dst (AddI src1 src2)); 14540 format %{ "leal $dst, [$src1 + $src2]" %} 14541 ins_encode %{ 14542 Register dst = $dst$$Register; 14543 Register src1 = $src1$$Register; 14544 Register src2 = $src2$$Register; 14545 if (src1 != rbp && src1 != r13) { 14546 __ leal(dst, Address(src1, src2, Address::times_1)); 14547 } else { 14548 assert(src2 != rbp && src2 != r13, ""); 14549 __ leal(dst, Address(src2, src1, Address::times_1)); 14550 } 14551 %} 14552 ins_pipe(ialu_reg_reg); 14553 %} 14554 14555 instruct leaI_rReg_immI_peep(rRegI dst, rRegI src1, immI src2) 14556 %{ 14557 predicate(false); 14558 match(Set dst (AddI src1 src2)); 14559 format %{ "leal $dst, [$src1 + $src2]" %} 14560 ins_encode %{ 14561 __ leal($dst$$Register, Address($src1$$Register, $src2$$constant)); 14562 %} 14563 ins_pipe(ialu_reg_reg); 14564 %} 14565 14566 instruct leaI_rReg_immI2_peep(rRegI dst, rRegI src, immI2 shift) 14567 %{ 14568 predicate(false); 14569 match(Set dst (LShiftI src shift)); 14570 format %{ "leal $dst, [$src << $shift]" %} 14571 ins_encode %{ 14572 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($shift$$constant); 14573 Register src = $src$$Register; 14574 if (scale == Address::times_2 && src != rbp && src != r13) { 14575 __ leal($dst$$Register, Address(src, src, Address::times_1)); 14576 } else { 14577 __ leal($dst$$Register, Address(noreg, src, scale)); 14578 } 14579 %} 14580 ins_pipe(ialu_reg_reg); 14581 %} 14582 14583 instruct leaL_rReg_rReg_peep(rRegL dst, rRegL src1, rRegL src2) 14584 %{ 14585 predicate(false); 14586 match(Set dst (AddL src1 src2)); 14587 format %{ "leaq $dst, [$src1 + $src2]" %} 14588 ins_encode %{ 14589 Register dst = $dst$$Register; 14590 Register src1 = $src1$$Register; 14591 Register src2 = $src2$$Register; 14592 if (src1 != rbp && src1 != r13) { 14593 __ leaq(dst, Address(src1, src2, Address::times_1)); 14594 } else { 14595 assert(src2 != rbp && src2 != r13, ""); 14596 __ leaq(dst, Address(src2, src1, Address::times_1)); 14597 } 14598 %} 14599 ins_pipe(ialu_reg_reg); 14600 %} 14601 14602 instruct leaL_rReg_immL32_peep(rRegL dst, rRegL src1, immL32 src2) 14603 %{ 14604 predicate(false); 14605 match(Set dst (AddL src1 src2)); 14606 format %{ "leaq $dst, [$src1 + $src2]" %} 14607 ins_encode %{ 14608 __ leaq($dst$$Register, Address($src1$$Register, $src2$$constant)); 14609 %} 14610 ins_pipe(ialu_reg_reg); 14611 %} 14612 14613 instruct leaL_rReg_immI2_peep(rRegL dst, rRegL src, immI2 shift) 14614 %{ 14615 predicate(false); 14616 match(Set dst (LShiftL src shift)); 14617 format %{ "leaq $dst, [$src << $shift]" %} 14618 ins_encode %{ 14619 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($shift$$constant); 14620 Register src = $src$$Register; 14621 if (scale == Address::times_2 && src != rbp && src != r13) { 14622 __ leaq($dst$$Register, Address(src, src, Address::times_1)); 14623 } else { 14624 __ leaq($dst$$Register, Address(noreg, src, scale)); 14625 } 14626 %} 14627 ins_pipe(ialu_reg_reg); 14628 %} 14629 14630 // These peephole rules replace mov + I pairs (where I is one of {add, inc, dec, 14631 // sal}) with lea instructions. The {add, sal} rules are beneficial in 14632 // processors with at least partial ALU support for lea 14633 // (supports_fast_2op_lea()), whereas the {inc, dec} rules are only generally 14634 // beneficial for processors with full ALU support 14635 // (VM_Version::supports_fast_3op_lea()) and Intel Cascade Lake. 14636 14637 peephole 14638 %{ 14639 peeppredicate(VM_Version::supports_fast_2op_lea()); 14640 peepmatch (addI_rReg); 14641 peepprocedure (lea_coalesce_reg); 14642 peepreplace (leaI_rReg_rReg_peep()); 14643 %} 14644 14645 peephole 14646 %{ 14647 peeppredicate(VM_Version::supports_fast_2op_lea()); 14648 peepmatch (addI_rReg_imm); 14649 peepprocedure (lea_coalesce_imm); 14650 peepreplace (leaI_rReg_immI_peep()); 14651 %} 14652 14653 peephole 14654 %{ 14655 peeppredicate(VM_Version::supports_fast_3op_lea() || 14656 VM_Version::is_intel_cascade_lake()); 14657 peepmatch (incI_rReg); 14658 peepprocedure (lea_coalesce_imm); 14659 peepreplace (leaI_rReg_immI_peep()); 14660 %} 14661 14662 peephole 14663 %{ 14664 peeppredicate(VM_Version::supports_fast_3op_lea() || 14665 VM_Version::is_intel_cascade_lake()); 14666 peepmatch (decI_rReg); 14667 peepprocedure (lea_coalesce_imm); 14668 peepreplace (leaI_rReg_immI_peep()); 14669 %} 14670 14671 peephole 14672 %{ 14673 peeppredicate(VM_Version::supports_fast_2op_lea()); 14674 peepmatch (salI_rReg_immI2); 14675 peepprocedure (lea_coalesce_imm); 14676 peepreplace (leaI_rReg_immI2_peep()); 14677 %} 14678 14679 peephole 14680 %{ 14681 peeppredicate(VM_Version::supports_fast_2op_lea()); 14682 peepmatch (addL_rReg); 14683 peepprocedure (lea_coalesce_reg); 14684 peepreplace (leaL_rReg_rReg_peep()); 14685 %} 14686 14687 peephole 14688 %{ 14689 peeppredicate(VM_Version::supports_fast_2op_lea()); 14690 peepmatch (addL_rReg_imm); 14691 peepprocedure (lea_coalesce_imm); 14692 peepreplace (leaL_rReg_immL32_peep()); 14693 %} 14694 14695 peephole 14696 %{ 14697 peeppredicate(VM_Version::supports_fast_3op_lea() || 14698 VM_Version::is_intel_cascade_lake()); 14699 peepmatch (incL_rReg); 14700 peepprocedure (lea_coalesce_imm); 14701 peepreplace (leaL_rReg_immL32_peep()); 14702 %} 14703 14704 peephole 14705 %{ 14706 peeppredicate(VM_Version::supports_fast_3op_lea() || 14707 VM_Version::is_intel_cascade_lake()); 14708 peepmatch (decL_rReg); 14709 peepprocedure (lea_coalesce_imm); 14710 peepreplace (leaL_rReg_immL32_peep()); 14711 %} 14712 14713 peephole 14714 %{ 14715 peeppredicate(VM_Version::supports_fast_2op_lea()); 14716 peepmatch (salL_rReg_immI2); 14717 peepprocedure (lea_coalesce_imm); 14718 peepreplace (leaL_rReg_immI2_peep()); 14719 %} 14720 14721 // These peephole rules matches instructions which set flags and are followed by a testI/L_reg 14722 // 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 14723 14724 //int variant 14725 peephole 14726 %{ 14727 peepmatch (testI_reg); 14728 peepprocedure (test_may_remove); 14729 %} 14730 14731 //long variant 14732 peephole 14733 %{ 14734 peepmatch (testL_reg); 14735 peepprocedure (test_may_remove); 14736 %} 14737 14738 14739 //----------SMARTSPILL RULES--------------------------------------------------- 14740 // These must follow all instruction definitions as they use the names 14741 // defined in the instructions definitions.