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 // No relocation needed 1863 __ mov64(r10, (int64_t) $meth$$method); 1864 __ call(r10); 1865 __ post_call_nop(); 1866 %} 1867 1868 enc_class Java_Static_Call(method meth) 1869 %{ 1870 // JAVA STATIC CALL 1871 // CALL to fixup routine. Fixup routine uses ScopeDesc info to 1872 // determine who we intended to call. 1873 if (!_method) { 1874 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, $meth$$method))); 1875 } else if (_method->intrinsic_id() == vmIntrinsicID::_ensureMaterializedForStackWalk) { 1876 // The NOP here is purely to ensure that eliding a call to 1877 // JVM_EnsureMaterializedForStackWalk doesn't change the code size. 1878 __ addr_nop_5(); 1879 __ block_comment("call JVM_EnsureMaterializedForStackWalk (elided)"); 1880 } else { 1881 int method_index = resolved_method_index(masm); 1882 RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 1883 : static_call_Relocation::spec(method_index); 1884 address mark = __ pc(); 1885 int call_offset = __ offset(); 1886 __ call(AddressLiteral(CAST_FROM_FN_PTR(address, $meth$$method), rspec)); 1887 if (CodeBuffer::supports_shared_stubs() && _method->can_be_statically_bound()) { 1888 // Calls of the same statically bound method can share 1889 // a stub to the interpreter. 1890 __ code()->shared_stub_to_interp_for(_method, call_offset); 1891 } else { 1892 // Emit stubs for static call. 1893 address stub = CompiledDirectCall::emit_to_interp_stub(masm, mark); 1894 __ clear_inst_mark(); 1895 if (stub == nullptr) { 1896 ciEnv::current()->record_failure("CodeCache is full"); 1897 return; 1898 } 1899 } 1900 } 1901 __ post_call_nop(); 1902 %} 1903 1904 enc_class Java_Dynamic_Call(method meth) %{ 1905 __ ic_call((address)$meth$$method, resolved_method_index(masm)); 1906 __ post_call_nop(); 1907 %} 1908 1909 %} 1910 1911 1912 1913 //----------FRAME-------------------------------------------------------------- 1914 // Definition of frame structure and management information. 1915 // 1916 // S T A C K L A Y O U T Allocators stack-slot number 1917 // | (to get allocators register number 1918 // G Owned by | | v add OptoReg::stack0()) 1919 // r CALLER | | 1920 // o | +--------+ pad to even-align allocators stack-slot 1921 // w V | pad0 | numbers; owned by CALLER 1922 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned 1923 // h ^ | in | 5 1924 // | | args | 4 Holes in incoming args owned by SELF 1925 // | | | | 3 1926 // | | +--------+ 1927 // V | | old out| Empty on Intel, window on Sparc 1928 // | old |preserve| Must be even aligned. 1929 // | SP-+--------+----> Matcher::_old_SP, even aligned 1930 // | | in | 3 area for Intel ret address 1931 // Owned by |preserve| Empty on Sparc. 1932 // SELF +--------+ 1933 // | | pad2 | 2 pad to align old SP 1934 // | +--------+ 1 1935 // | | locks | 0 1936 // | +--------+----> OptoReg::stack0(), even aligned 1937 // | | pad1 | 11 pad to align new SP 1938 // | +--------+ 1939 // | | | 10 1940 // | | spills | 9 spills 1941 // V | | 8 (pad0 slot for callee) 1942 // -----------+--------+----> Matcher::_out_arg_limit, unaligned 1943 // ^ | out | 7 1944 // | | args | 6 Holes in outgoing args owned by CALLEE 1945 // Owned by +--------+ 1946 // CALLEE | new out| 6 Empty on Intel, window on Sparc 1947 // | new |preserve| Must be even-aligned. 1948 // | SP-+--------+----> Matcher::_new_SP, even aligned 1949 // | | | 1950 // 1951 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 1952 // known from SELF's arguments and the Java calling convention. 1953 // Region 6-7 is determined per call site. 1954 // Note 2: If the calling convention leaves holes in the incoming argument 1955 // area, those holes are owned by SELF. Holes in the outgoing area 1956 // are owned by the CALLEE. Holes should not be necessary in the 1957 // incoming area, as the Java calling convention is completely under 1958 // the control of the AD file. Doubles can be sorted and packed to 1959 // avoid holes. Holes in the outgoing arguments may be necessary for 1960 // varargs C calling conventions. 1961 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 1962 // even aligned with pad0 as needed. 1963 // Region 6 is even aligned. Region 6-7 is NOT even aligned; 1964 // region 6-11 is even aligned; it may be padded out more so that 1965 // the region from SP to FP meets the minimum stack alignment. 1966 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 1967 // alignment. Region 11, pad1, may be dynamically extended so that 1968 // SP meets the minimum alignment. 1969 1970 frame 1971 %{ 1972 // These three registers define part of the calling convention 1973 // between compiled code and the interpreter. 1974 inline_cache_reg(RAX); // Inline Cache Register 1975 1976 // Optional: name the operand used by cisc-spilling to access 1977 // [stack_pointer + offset] 1978 cisc_spilling_operand_name(indOffset32); 1979 1980 // Number of stack slots consumed by locking an object 1981 sync_stack_slots(2); 1982 1983 // Compiled code's Frame Pointer 1984 frame_pointer(RSP); 1985 1986 // Interpreter stores its frame pointer in a register which is 1987 // stored to the stack by I2CAdaptors. 1988 // I2CAdaptors convert from interpreted java to compiled java. 1989 interpreter_frame_pointer(RBP); 1990 1991 // Stack alignment requirement 1992 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 1993 1994 // Number of outgoing stack slots killed above the out_preserve_stack_slots 1995 // for calls to C. Supports the var-args backing area for register parms. 1996 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 1997 1998 // The after-PROLOG location of the return address. Location of 1999 // return address specifies a type (REG or STACK) and a number 2000 // representing the register number (i.e. - use a register name) or 2001 // stack slot. 2002 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 2003 // Otherwise, it is above the locks and verification slot and alignment word 2004 return_addr(STACK - 2 + 2005 align_up((Compile::current()->in_preserve_stack_slots() + 2006 Compile::current()->fixed_slots()), 2007 stack_alignment_in_slots())); 2008 2009 // Location of compiled Java return values. Same as C for now. 2010 return_value 2011 %{ 2012 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 2013 "only return normal values"); 2014 2015 static const int lo[Op_RegL + 1] = { 2016 0, 2017 0, 2018 RAX_num, // Op_RegN 2019 RAX_num, // Op_RegI 2020 RAX_num, // Op_RegP 2021 XMM0_num, // Op_RegF 2022 XMM0_num, // Op_RegD 2023 RAX_num // Op_RegL 2024 }; 2025 static const int hi[Op_RegL + 1] = { 2026 0, 2027 0, 2028 OptoReg::Bad, // Op_RegN 2029 OptoReg::Bad, // Op_RegI 2030 RAX_H_num, // Op_RegP 2031 OptoReg::Bad, // Op_RegF 2032 XMM0b_num, // Op_RegD 2033 RAX_H_num // Op_RegL 2034 }; 2035 // Excluded flags and vector registers. 2036 assert(ARRAY_SIZE(hi) == _last_machine_leaf - 8, "missing type"); 2037 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 2038 %} 2039 %} 2040 2041 //----------ATTRIBUTES--------------------------------------------------------- 2042 //----------Operand Attributes------------------------------------------------- 2043 op_attrib op_cost(0); // Required cost attribute 2044 2045 //----------Instruction Attributes--------------------------------------------- 2046 ins_attrib ins_cost(100); // Required cost attribute 2047 ins_attrib ins_size(8); // Required size attribute (in bits) 2048 ins_attrib ins_short_branch(0); // Required flag: is this instruction 2049 // a non-matching short branch variant 2050 // of some long branch? 2051 ins_attrib ins_alignment(1); // Required alignment attribute (must 2052 // be a power of 2) specifies the 2053 // alignment that some part of the 2054 // instruction (not necessarily the 2055 // start) requires. If > 1, a 2056 // compute_padding() function must be 2057 // provided for the instruction 2058 2059 //----------OPERANDS----------------------------------------------------------- 2060 // Operand definitions must precede instruction definitions for correct parsing 2061 // in the ADLC because operands constitute user defined types which are used in 2062 // instruction definitions. 2063 2064 //----------Simple Operands---------------------------------------------------- 2065 // Immediate Operands 2066 // Integer Immediate 2067 operand immI() 2068 %{ 2069 match(ConI); 2070 2071 op_cost(10); 2072 format %{ %} 2073 interface(CONST_INTER); 2074 %} 2075 2076 // Constant for test vs zero 2077 operand immI_0() 2078 %{ 2079 predicate(n->get_int() == 0); 2080 match(ConI); 2081 2082 op_cost(0); 2083 format %{ %} 2084 interface(CONST_INTER); 2085 %} 2086 2087 // Constant for increment 2088 operand immI_1() 2089 %{ 2090 predicate(n->get_int() == 1); 2091 match(ConI); 2092 2093 op_cost(0); 2094 format %{ %} 2095 interface(CONST_INTER); 2096 %} 2097 2098 // Constant for decrement 2099 operand immI_M1() 2100 %{ 2101 predicate(n->get_int() == -1); 2102 match(ConI); 2103 2104 op_cost(0); 2105 format %{ %} 2106 interface(CONST_INTER); 2107 %} 2108 2109 operand immI_2() 2110 %{ 2111 predicate(n->get_int() == 2); 2112 match(ConI); 2113 2114 op_cost(0); 2115 format %{ %} 2116 interface(CONST_INTER); 2117 %} 2118 2119 operand immI_4() 2120 %{ 2121 predicate(n->get_int() == 4); 2122 match(ConI); 2123 2124 op_cost(0); 2125 format %{ %} 2126 interface(CONST_INTER); 2127 %} 2128 2129 operand immI_8() 2130 %{ 2131 predicate(n->get_int() == 8); 2132 match(ConI); 2133 2134 op_cost(0); 2135 format %{ %} 2136 interface(CONST_INTER); 2137 %} 2138 2139 // Valid scale values for addressing modes 2140 operand immI2() 2141 %{ 2142 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 2143 match(ConI); 2144 2145 format %{ %} 2146 interface(CONST_INTER); 2147 %} 2148 2149 operand immU7() 2150 %{ 2151 predicate((0 <= n->get_int()) && (n->get_int() <= 0x7F)); 2152 match(ConI); 2153 2154 op_cost(5); 2155 format %{ %} 2156 interface(CONST_INTER); 2157 %} 2158 2159 operand immI8() 2160 %{ 2161 predicate((-0x80 <= n->get_int()) && (n->get_int() < 0x80)); 2162 match(ConI); 2163 2164 op_cost(5); 2165 format %{ %} 2166 interface(CONST_INTER); 2167 %} 2168 2169 operand immU8() 2170 %{ 2171 predicate((0 <= n->get_int()) && (n->get_int() <= 255)); 2172 match(ConI); 2173 2174 op_cost(5); 2175 format %{ %} 2176 interface(CONST_INTER); 2177 %} 2178 2179 operand immI16() 2180 %{ 2181 predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767)); 2182 match(ConI); 2183 2184 op_cost(10); 2185 format %{ %} 2186 interface(CONST_INTER); 2187 %} 2188 2189 // Int Immediate non-negative 2190 operand immU31() 2191 %{ 2192 predicate(n->get_int() >= 0); 2193 match(ConI); 2194 2195 op_cost(0); 2196 format %{ %} 2197 interface(CONST_INTER); 2198 %} 2199 2200 // Pointer Immediate 2201 operand immP() 2202 %{ 2203 match(ConP); 2204 2205 op_cost(10); 2206 format %{ %} 2207 interface(CONST_INTER); 2208 %} 2209 2210 // Null Pointer Immediate 2211 operand immP0() 2212 %{ 2213 predicate(n->get_ptr() == 0); 2214 match(ConP); 2215 2216 op_cost(5); 2217 format %{ %} 2218 interface(CONST_INTER); 2219 %} 2220 2221 // Pointer Immediate 2222 operand immN() %{ 2223 match(ConN); 2224 2225 op_cost(10); 2226 format %{ %} 2227 interface(CONST_INTER); 2228 %} 2229 2230 operand immNKlass() %{ 2231 match(ConNKlass); 2232 2233 op_cost(10); 2234 format %{ %} 2235 interface(CONST_INTER); 2236 %} 2237 2238 // Null Pointer Immediate 2239 operand immN0() %{ 2240 predicate(n->get_narrowcon() == 0); 2241 match(ConN); 2242 2243 op_cost(5); 2244 format %{ %} 2245 interface(CONST_INTER); 2246 %} 2247 2248 operand immP31() 2249 %{ 2250 predicate(n->as_Type()->type()->reloc() == relocInfo::none 2251 && (n->get_ptr() >> 31) == 0); 2252 match(ConP); 2253 2254 op_cost(5); 2255 format %{ %} 2256 interface(CONST_INTER); 2257 %} 2258 2259 2260 // Long Immediate 2261 operand immL() 2262 %{ 2263 match(ConL); 2264 2265 op_cost(20); 2266 format %{ %} 2267 interface(CONST_INTER); 2268 %} 2269 2270 // Long Immediate 8-bit 2271 operand immL8() 2272 %{ 2273 predicate(-0x80L <= n->get_long() && n->get_long() < 0x80L); 2274 match(ConL); 2275 2276 op_cost(5); 2277 format %{ %} 2278 interface(CONST_INTER); 2279 %} 2280 2281 // Long Immediate 32-bit unsigned 2282 operand immUL32() 2283 %{ 2284 predicate(n->get_long() == (unsigned int) (n->get_long())); 2285 match(ConL); 2286 2287 op_cost(10); 2288 format %{ %} 2289 interface(CONST_INTER); 2290 %} 2291 2292 // Long Immediate 32-bit signed 2293 operand immL32() 2294 %{ 2295 predicate(n->get_long() == (int) (n->get_long())); 2296 match(ConL); 2297 2298 op_cost(15); 2299 format %{ %} 2300 interface(CONST_INTER); 2301 %} 2302 2303 operand immL_Pow2() 2304 %{ 2305 predicate(is_power_of_2((julong)n->get_long())); 2306 match(ConL); 2307 2308 op_cost(15); 2309 format %{ %} 2310 interface(CONST_INTER); 2311 %} 2312 2313 operand immL_NotPow2() 2314 %{ 2315 predicate(is_power_of_2((julong)~n->get_long())); 2316 match(ConL); 2317 2318 op_cost(15); 2319 format %{ %} 2320 interface(CONST_INTER); 2321 %} 2322 2323 // Long Immediate zero 2324 operand immL0() 2325 %{ 2326 predicate(n->get_long() == 0L); 2327 match(ConL); 2328 2329 op_cost(10); 2330 format %{ %} 2331 interface(CONST_INTER); 2332 %} 2333 2334 // Constant for increment 2335 operand immL1() 2336 %{ 2337 predicate(n->get_long() == 1); 2338 match(ConL); 2339 2340 format %{ %} 2341 interface(CONST_INTER); 2342 %} 2343 2344 // Constant for decrement 2345 operand immL_M1() 2346 %{ 2347 predicate(n->get_long() == -1); 2348 match(ConL); 2349 2350 format %{ %} 2351 interface(CONST_INTER); 2352 %} 2353 2354 // Long Immediate: low 32-bit mask 2355 operand immL_32bits() 2356 %{ 2357 predicate(n->get_long() == 0xFFFFFFFFL); 2358 match(ConL); 2359 op_cost(20); 2360 2361 format %{ %} 2362 interface(CONST_INTER); 2363 %} 2364 2365 // Int Immediate: 2^n-1, positive 2366 operand immI_Pow2M1() 2367 %{ 2368 predicate((n->get_int() > 0) 2369 && is_power_of_2((juint)n->get_int() + 1)); 2370 match(ConI); 2371 2372 op_cost(20); 2373 format %{ %} 2374 interface(CONST_INTER); 2375 %} 2376 2377 // Float Immediate zero 2378 operand immF0() 2379 %{ 2380 predicate(jint_cast(n->getf()) == 0); 2381 match(ConF); 2382 2383 op_cost(5); 2384 format %{ %} 2385 interface(CONST_INTER); 2386 %} 2387 2388 // Float Immediate 2389 operand immF() 2390 %{ 2391 match(ConF); 2392 2393 op_cost(15); 2394 format %{ %} 2395 interface(CONST_INTER); 2396 %} 2397 2398 // Half Float Immediate 2399 operand immH() 2400 %{ 2401 match(ConH); 2402 2403 op_cost(15); 2404 format %{ %} 2405 interface(CONST_INTER); 2406 %} 2407 2408 // Double Immediate zero 2409 operand immD0() 2410 %{ 2411 predicate(jlong_cast(n->getd()) == 0); 2412 match(ConD); 2413 2414 op_cost(5); 2415 format %{ %} 2416 interface(CONST_INTER); 2417 %} 2418 2419 // Double Immediate 2420 operand immD() 2421 %{ 2422 match(ConD); 2423 2424 op_cost(15); 2425 format %{ %} 2426 interface(CONST_INTER); 2427 %} 2428 2429 // Immediates for special shifts (sign extend) 2430 2431 // Constants for increment 2432 operand immI_16() 2433 %{ 2434 predicate(n->get_int() == 16); 2435 match(ConI); 2436 2437 format %{ %} 2438 interface(CONST_INTER); 2439 %} 2440 2441 operand immI_24() 2442 %{ 2443 predicate(n->get_int() == 24); 2444 match(ConI); 2445 2446 format %{ %} 2447 interface(CONST_INTER); 2448 %} 2449 2450 // Constant for byte-wide masking 2451 operand immI_255() 2452 %{ 2453 predicate(n->get_int() == 255); 2454 match(ConI); 2455 2456 format %{ %} 2457 interface(CONST_INTER); 2458 %} 2459 2460 // Constant for short-wide masking 2461 operand immI_65535() 2462 %{ 2463 predicate(n->get_int() == 65535); 2464 match(ConI); 2465 2466 format %{ %} 2467 interface(CONST_INTER); 2468 %} 2469 2470 // Constant for byte-wide masking 2471 operand immL_255() 2472 %{ 2473 predicate(n->get_long() == 255); 2474 match(ConL); 2475 2476 format %{ %} 2477 interface(CONST_INTER); 2478 %} 2479 2480 // Constant for short-wide masking 2481 operand immL_65535() 2482 %{ 2483 predicate(n->get_long() == 65535); 2484 match(ConL); 2485 2486 format %{ %} 2487 interface(CONST_INTER); 2488 %} 2489 2490 operand kReg() 2491 %{ 2492 constraint(ALLOC_IN_RC(vectmask_reg)); 2493 match(RegVectMask); 2494 format %{%} 2495 interface(REG_INTER); 2496 %} 2497 2498 // Register Operands 2499 // Integer Register 2500 operand rRegI() 2501 %{ 2502 constraint(ALLOC_IN_RC(int_reg)); 2503 match(RegI); 2504 2505 match(rax_RegI); 2506 match(rbx_RegI); 2507 match(rcx_RegI); 2508 match(rdx_RegI); 2509 match(rdi_RegI); 2510 2511 format %{ %} 2512 interface(REG_INTER); 2513 %} 2514 2515 // Special Registers 2516 operand rax_RegI() 2517 %{ 2518 constraint(ALLOC_IN_RC(int_rax_reg)); 2519 match(RegI); 2520 match(rRegI); 2521 2522 format %{ "RAX" %} 2523 interface(REG_INTER); 2524 %} 2525 2526 // Special Registers 2527 operand rbx_RegI() 2528 %{ 2529 constraint(ALLOC_IN_RC(int_rbx_reg)); 2530 match(RegI); 2531 match(rRegI); 2532 2533 format %{ "RBX" %} 2534 interface(REG_INTER); 2535 %} 2536 2537 operand rcx_RegI() 2538 %{ 2539 constraint(ALLOC_IN_RC(int_rcx_reg)); 2540 match(RegI); 2541 match(rRegI); 2542 2543 format %{ "RCX" %} 2544 interface(REG_INTER); 2545 %} 2546 2547 operand rdx_RegI() 2548 %{ 2549 constraint(ALLOC_IN_RC(int_rdx_reg)); 2550 match(RegI); 2551 match(rRegI); 2552 2553 format %{ "RDX" %} 2554 interface(REG_INTER); 2555 %} 2556 2557 operand rdi_RegI() 2558 %{ 2559 constraint(ALLOC_IN_RC(int_rdi_reg)); 2560 match(RegI); 2561 match(rRegI); 2562 2563 format %{ "RDI" %} 2564 interface(REG_INTER); 2565 %} 2566 2567 operand no_rax_rdx_RegI() 2568 %{ 2569 constraint(ALLOC_IN_RC(int_no_rax_rdx_reg)); 2570 match(RegI); 2571 match(rbx_RegI); 2572 match(rcx_RegI); 2573 match(rdi_RegI); 2574 2575 format %{ %} 2576 interface(REG_INTER); 2577 %} 2578 2579 operand no_rbp_r13_RegI() 2580 %{ 2581 constraint(ALLOC_IN_RC(int_no_rbp_r13_reg)); 2582 match(RegI); 2583 match(rRegI); 2584 match(rax_RegI); 2585 match(rbx_RegI); 2586 match(rcx_RegI); 2587 match(rdx_RegI); 2588 match(rdi_RegI); 2589 2590 format %{ %} 2591 interface(REG_INTER); 2592 %} 2593 2594 // Pointer Register 2595 operand any_RegP() 2596 %{ 2597 constraint(ALLOC_IN_RC(any_reg)); 2598 match(RegP); 2599 match(rax_RegP); 2600 match(rbx_RegP); 2601 match(rdi_RegP); 2602 match(rsi_RegP); 2603 match(rbp_RegP); 2604 match(r15_RegP); 2605 match(rRegP); 2606 2607 format %{ %} 2608 interface(REG_INTER); 2609 %} 2610 2611 operand rRegP() 2612 %{ 2613 constraint(ALLOC_IN_RC(ptr_reg)); 2614 match(RegP); 2615 match(rax_RegP); 2616 match(rbx_RegP); 2617 match(rdi_RegP); 2618 match(rsi_RegP); 2619 match(rbp_RegP); // See Q&A below about 2620 match(r15_RegP); // r15_RegP and rbp_RegP. 2621 2622 format %{ %} 2623 interface(REG_INTER); 2624 %} 2625 2626 operand rRegN() %{ 2627 constraint(ALLOC_IN_RC(int_reg)); 2628 match(RegN); 2629 2630 format %{ %} 2631 interface(REG_INTER); 2632 %} 2633 2634 // Question: Why is r15_RegP (the read-only TLS register) a match for rRegP? 2635 // Answer: Operand match rules govern the DFA as it processes instruction inputs. 2636 // It's fine for an instruction input that expects rRegP to match a r15_RegP. 2637 // The output of an instruction is controlled by the allocator, which respects 2638 // register class masks, not match rules. Unless an instruction mentions 2639 // r15_RegP or any_RegP explicitly as its output, r15 will not be considered 2640 // by the allocator as an input. 2641 // The same logic applies to rbp_RegP being a match for rRegP: If PreserveFramePointer==true, 2642 // the RBP is used as a proper frame pointer and is not included in ptr_reg. As a 2643 // result, RBP is not included in the output of the instruction either. 2644 2645 // This operand is not allowed to use RBP even if 2646 // RBP is not used to hold the frame pointer. 2647 operand no_rbp_RegP() 2648 %{ 2649 constraint(ALLOC_IN_RC(ptr_reg_no_rbp)); 2650 match(RegP); 2651 match(rbx_RegP); 2652 match(rsi_RegP); 2653 match(rdi_RegP); 2654 2655 format %{ %} 2656 interface(REG_INTER); 2657 %} 2658 2659 // Special Registers 2660 // Return a pointer value 2661 operand rax_RegP() 2662 %{ 2663 constraint(ALLOC_IN_RC(ptr_rax_reg)); 2664 match(RegP); 2665 match(rRegP); 2666 2667 format %{ %} 2668 interface(REG_INTER); 2669 %} 2670 2671 // Special Registers 2672 // Return a compressed pointer value 2673 operand rax_RegN() 2674 %{ 2675 constraint(ALLOC_IN_RC(int_rax_reg)); 2676 match(RegN); 2677 match(rRegN); 2678 2679 format %{ %} 2680 interface(REG_INTER); 2681 %} 2682 2683 // Used in AtomicAdd 2684 operand rbx_RegP() 2685 %{ 2686 constraint(ALLOC_IN_RC(ptr_rbx_reg)); 2687 match(RegP); 2688 match(rRegP); 2689 2690 format %{ %} 2691 interface(REG_INTER); 2692 %} 2693 2694 operand rsi_RegP() 2695 %{ 2696 constraint(ALLOC_IN_RC(ptr_rsi_reg)); 2697 match(RegP); 2698 match(rRegP); 2699 2700 format %{ %} 2701 interface(REG_INTER); 2702 %} 2703 2704 operand rbp_RegP() 2705 %{ 2706 constraint(ALLOC_IN_RC(ptr_rbp_reg)); 2707 match(RegP); 2708 match(rRegP); 2709 2710 format %{ %} 2711 interface(REG_INTER); 2712 %} 2713 2714 // Used in rep stosq 2715 operand rdi_RegP() 2716 %{ 2717 constraint(ALLOC_IN_RC(ptr_rdi_reg)); 2718 match(RegP); 2719 match(rRegP); 2720 2721 format %{ %} 2722 interface(REG_INTER); 2723 %} 2724 2725 operand r15_RegP() 2726 %{ 2727 constraint(ALLOC_IN_RC(ptr_r15_reg)); 2728 match(RegP); 2729 match(rRegP); 2730 2731 format %{ %} 2732 interface(REG_INTER); 2733 %} 2734 2735 operand rRegL() 2736 %{ 2737 constraint(ALLOC_IN_RC(long_reg)); 2738 match(RegL); 2739 match(rax_RegL); 2740 match(rdx_RegL); 2741 2742 format %{ %} 2743 interface(REG_INTER); 2744 %} 2745 2746 // Special Registers 2747 operand no_rax_rdx_RegL() 2748 %{ 2749 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 2750 match(RegL); 2751 match(rRegL); 2752 2753 format %{ %} 2754 interface(REG_INTER); 2755 %} 2756 2757 operand rax_RegL() 2758 %{ 2759 constraint(ALLOC_IN_RC(long_rax_reg)); 2760 match(RegL); 2761 match(rRegL); 2762 2763 format %{ "RAX" %} 2764 interface(REG_INTER); 2765 %} 2766 2767 operand rcx_RegL() 2768 %{ 2769 constraint(ALLOC_IN_RC(long_rcx_reg)); 2770 match(RegL); 2771 match(rRegL); 2772 2773 format %{ %} 2774 interface(REG_INTER); 2775 %} 2776 2777 operand rdx_RegL() 2778 %{ 2779 constraint(ALLOC_IN_RC(long_rdx_reg)); 2780 match(RegL); 2781 match(rRegL); 2782 2783 format %{ %} 2784 interface(REG_INTER); 2785 %} 2786 2787 operand r11_RegL() 2788 %{ 2789 constraint(ALLOC_IN_RC(long_r11_reg)); 2790 match(RegL); 2791 match(rRegL); 2792 2793 format %{ %} 2794 interface(REG_INTER); 2795 %} 2796 2797 operand no_rbp_r13_RegL() 2798 %{ 2799 constraint(ALLOC_IN_RC(long_no_rbp_r13_reg)); 2800 match(RegL); 2801 match(rRegL); 2802 match(rax_RegL); 2803 match(rcx_RegL); 2804 match(rdx_RegL); 2805 2806 format %{ %} 2807 interface(REG_INTER); 2808 %} 2809 2810 // Flags register, used as output of compare instructions 2811 operand rFlagsReg() 2812 %{ 2813 constraint(ALLOC_IN_RC(int_flags)); 2814 match(RegFlags); 2815 2816 format %{ "RFLAGS" %} 2817 interface(REG_INTER); 2818 %} 2819 2820 // Flags register, used as output of FLOATING POINT compare instructions 2821 operand rFlagsRegU() 2822 %{ 2823 constraint(ALLOC_IN_RC(int_flags)); 2824 match(RegFlags); 2825 2826 format %{ "RFLAGS_U" %} 2827 interface(REG_INTER); 2828 %} 2829 2830 operand rFlagsRegUCF() %{ 2831 constraint(ALLOC_IN_RC(int_flags)); 2832 match(RegFlags); 2833 predicate(false); 2834 2835 format %{ "RFLAGS_U_CF" %} 2836 interface(REG_INTER); 2837 %} 2838 2839 // Float register operands 2840 operand regF() %{ 2841 constraint(ALLOC_IN_RC(float_reg)); 2842 match(RegF); 2843 2844 format %{ %} 2845 interface(REG_INTER); 2846 %} 2847 2848 // Float register operands 2849 operand legRegF() %{ 2850 constraint(ALLOC_IN_RC(float_reg_legacy)); 2851 match(RegF); 2852 2853 format %{ %} 2854 interface(REG_INTER); 2855 %} 2856 2857 // Float register operands 2858 operand vlRegF() %{ 2859 constraint(ALLOC_IN_RC(float_reg_vl)); 2860 match(RegF); 2861 2862 format %{ %} 2863 interface(REG_INTER); 2864 %} 2865 2866 // Double register operands 2867 operand regD() %{ 2868 constraint(ALLOC_IN_RC(double_reg)); 2869 match(RegD); 2870 2871 format %{ %} 2872 interface(REG_INTER); 2873 %} 2874 2875 // Double register operands 2876 operand legRegD() %{ 2877 constraint(ALLOC_IN_RC(double_reg_legacy)); 2878 match(RegD); 2879 2880 format %{ %} 2881 interface(REG_INTER); 2882 %} 2883 2884 // Double register operands 2885 operand vlRegD() %{ 2886 constraint(ALLOC_IN_RC(double_reg_vl)); 2887 match(RegD); 2888 2889 format %{ %} 2890 interface(REG_INTER); 2891 %} 2892 2893 //----------Memory Operands---------------------------------------------------- 2894 // Direct Memory Operand 2895 // operand direct(immP addr) 2896 // %{ 2897 // match(addr); 2898 2899 // format %{ "[$addr]" %} 2900 // interface(MEMORY_INTER) %{ 2901 // base(0xFFFFFFFF); 2902 // index(0x4); 2903 // scale(0x0); 2904 // disp($addr); 2905 // %} 2906 // %} 2907 2908 // Indirect Memory Operand 2909 operand indirect(any_RegP reg) 2910 %{ 2911 constraint(ALLOC_IN_RC(ptr_reg)); 2912 match(reg); 2913 2914 format %{ "[$reg]" %} 2915 interface(MEMORY_INTER) %{ 2916 base($reg); 2917 index(0x4); 2918 scale(0x0); 2919 disp(0x0); 2920 %} 2921 %} 2922 2923 // Indirect Memory Plus Short Offset Operand 2924 operand indOffset8(any_RegP reg, immL8 off) 2925 %{ 2926 constraint(ALLOC_IN_RC(ptr_reg)); 2927 match(AddP reg off); 2928 2929 format %{ "[$reg + $off (8-bit)]" %} 2930 interface(MEMORY_INTER) %{ 2931 base($reg); 2932 index(0x4); 2933 scale(0x0); 2934 disp($off); 2935 %} 2936 %} 2937 2938 // Indirect Memory Plus Long Offset Operand 2939 operand indOffset32(any_RegP reg, immL32 off) 2940 %{ 2941 constraint(ALLOC_IN_RC(ptr_reg)); 2942 match(AddP reg off); 2943 2944 format %{ "[$reg + $off (32-bit)]" %} 2945 interface(MEMORY_INTER) %{ 2946 base($reg); 2947 index(0x4); 2948 scale(0x0); 2949 disp($off); 2950 %} 2951 %} 2952 2953 // Indirect Memory Plus Index Register Plus Offset Operand 2954 operand indIndexOffset(any_RegP reg, rRegL lreg, immL32 off) 2955 %{ 2956 constraint(ALLOC_IN_RC(ptr_reg)); 2957 match(AddP (AddP reg lreg) off); 2958 2959 op_cost(10); 2960 format %{"[$reg + $off + $lreg]" %} 2961 interface(MEMORY_INTER) %{ 2962 base($reg); 2963 index($lreg); 2964 scale(0x0); 2965 disp($off); 2966 %} 2967 %} 2968 2969 // Indirect Memory Plus Index Register Plus Offset Operand 2970 operand indIndex(any_RegP reg, rRegL lreg) 2971 %{ 2972 constraint(ALLOC_IN_RC(ptr_reg)); 2973 match(AddP reg lreg); 2974 2975 op_cost(10); 2976 format %{"[$reg + $lreg]" %} 2977 interface(MEMORY_INTER) %{ 2978 base($reg); 2979 index($lreg); 2980 scale(0x0); 2981 disp(0x0); 2982 %} 2983 %} 2984 2985 // Indirect Memory Times Scale Plus Index Register 2986 operand indIndexScale(any_RegP reg, rRegL lreg, immI2 scale) 2987 %{ 2988 constraint(ALLOC_IN_RC(ptr_reg)); 2989 match(AddP reg (LShiftL lreg scale)); 2990 2991 op_cost(10); 2992 format %{"[$reg + $lreg << $scale]" %} 2993 interface(MEMORY_INTER) %{ 2994 base($reg); 2995 index($lreg); 2996 scale($scale); 2997 disp(0x0); 2998 %} 2999 %} 3000 3001 operand indPosIndexScale(any_RegP reg, rRegI idx, immI2 scale) 3002 %{ 3003 constraint(ALLOC_IN_RC(ptr_reg)); 3004 predicate(n->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3005 match(AddP reg (LShiftL (ConvI2L idx) scale)); 3006 3007 op_cost(10); 3008 format %{"[$reg + pos $idx << $scale]" %} 3009 interface(MEMORY_INTER) %{ 3010 base($reg); 3011 index($idx); 3012 scale($scale); 3013 disp(0x0); 3014 %} 3015 %} 3016 3017 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 3018 operand indIndexScaleOffset(any_RegP reg, immL32 off, rRegL lreg, immI2 scale) 3019 %{ 3020 constraint(ALLOC_IN_RC(ptr_reg)); 3021 match(AddP (AddP reg (LShiftL lreg scale)) off); 3022 3023 op_cost(10); 3024 format %{"[$reg + $off + $lreg << $scale]" %} 3025 interface(MEMORY_INTER) %{ 3026 base($reg); 3027 index($lreg); 3028 scale($scale); 3029 disp($off); 3030 %} 3031 %} 3032 3033 // Indirect Memory Plus Positive Index Register Plus Offset Operand 3034 operand indPosIndexOffset(any_RegP reg, immL32 off, rRegI idx) 3035 %{ 3036 constraint(ALLOC_IN_RC(ptr_reg)); 3037 predicate(n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 3038 match(AddP (AddP reg (ConvI2L idx)) off); 3039 3040 op_cost(10); 3041 format %{"[$reg + $off + $idx]" %} 3042 interface(MEMORY_INTER) %{ 3043 base($reg); 3044 index($idx); 3045 scale(0x0); 3046 disp($off); 3047 %} 3048 %} 3049 3050 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 3051 operand indPosIndexScaleOffset(any_RegP reg, immL32 off, rRegI idx, immI2 scale) 3052 %{ 3053 constraint(ALLOC_IN_RC(ptr_reg)); 3054 predicate(n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3055 match(AddP (AddP reg (LShiftL (ConvI2L idx) scale)) off); 3056 3057 op_cost(10); 3058 format %{"[$reg + $off + $idx << $scale]" %} 3059 interface(MEMORY_INTER) %{ 3060 base($reg); 3061 index($idx); 3062 scale($scale); 3063 disp($off); 3064 %} 3065 %} 3066 3067 // Indirect Narrow Oop Plus Offset Operand 3068 // Note: x86 architecture doesn't support "scale * index + offset" without a base 3069 // we can't free r12 even with CompressedOops::base() == nullptr. 3070 operand indCompressedOopOffset(rRegN reg, immL32 off) %{ 3071 predicate(UseCompressedOops && (CompressedOops::shift() == Address::times_8)); 3072 constraint(ALLOC_IN_RC(ptr_reg)); 3073 match(AddP (DecodeN reg) off); 3074 3075 op_cost(10); 3076 format %{"[R12 + $reg << 3 + $off] (compressed oop addressing)" %} 3077 interface(MEMORY_INTER) %{ 3078 base(0xc); // R12 3079 index($reg); 3080 scale(0x3); 3081 disp($off); 3082 %} 3083 %} 3084 3085 // Indirect Memory Operand 3086 operand indirectNarrow(rRegN reg) 3087 %{ 3088 predicate(CompressedOops::shift() == 0); 3089 constraint(ALLOC_IN_RC(ptr_reg)); 3090 match(DecodeN reg); 3091 3092 format %{ "[$reg]" %} 3093 interface(MEMORY_INTER) %{ 3094 base($reg); 3095 index(0x4); 3096 scale(0x0); 3097 disp(0x0); 3098 %} 3099 %} 3100 3101 // Indirect Memory Plus Short Offset Operand 3102 operand indOffset8Narrow(rRegN reg, immL8 off) 3103 %{ 3104 predicate(CompressedOops::shift() == 0); 3105 constraint(ALLOC_IN_RC(ptr_reg)); 3106 match(AddP (DecodeN reg) off); 3107 3108 format %{ "[$reg + $off (8-bit)]" %} 3109 interface(MEMORY_INTER) %{ 3110 base($reg); 3111 index(0x4); 3112 scale(0x0); 3113 disp($off); 3114 %} 3115 %} 3116 3117 // Indirect Memory Plus Long Offset Operand 3118 operand indOffset32Narrow(rRegN reg, immL32 off) 3119 %{ 3120 predicate(CompressedOops::shift() == 0); 3121 constraint(ALLOC_IN_RC(ptr_reg)); 3122 match(AddP (DecodeN reg) off); 3123 3124 format %{ "[$reg + $off (32-bit)]" %} 3125 interface(MEMORY_INTER) %{ 3126 base($reg); 3127 index(0x4); 3128 scale(0x0); 3129 disp($off); 3130 %} 3131 %} 3132 3133 // Indirect Memory Plus Index Register Plus Offset Operand 3134 operand indIndexOffsetNarrow(rRegN reg, rRegL lreg, immL32 off) 3135 %{ 3136 predicate(CompressedOops::shift() == 0); 3137 constraint(ALLOC_IN_RC(ptr_reg)); 3138 match(AddP (AddP (DecodeN reg) lreg) off); 3139 3140 op_cost(10); 3141 format %{"[$reg + $off + $lreg]" %} 3142 interface(MEMORY_INTER) %{ 3143 base($reg); 3144 index($lreg); 3145 scale(0x0); 3146 disp($off); 3147 %} 3148 %} 3149 3150 // Indirect Memory Plus Index Register Plus Offset Operand 3151 operand indIndexNarrow(rRegN reg, rRegL lreg) 3152 %{ 3153 predicate(CompressedOops::shift() == 0); 3154 constraint(ALLOC_IN_RC(ptr_reg)); 3155 match(AddP (DecodeN reg) lreg); 3156 3157 op_cost(10); 3158 format %{"[$reg + $lreg]" %} 3159 interface(MEMORY_INTER) %{ 3160 base($reg); 3161 index($lreg); 3162 scale(0x0); 3163 disp(0x0); 3164 %} 3165 %} 3166 3167 // Indirect Memory Times Scale Plus Index Register 3168 operand indIndexScaleNarrow(rRegN reg, rRegL lreg, immI2 scale) 3169 %{ 3170 predicate(CompressedOops::shift() == 0); 3171 constraint(ALLOC_IN_RC(ptr_reg)); 3172 match(AddP (DecodeN reg) (LShiftL lreg scale)); 3173 3174 op_cost(10); 3175 format %{"[$reg + $lreg << $scale]" %} 3176 interface(MEMORY_INTER) %{ 3177 base($reg); 3178 index($lreg); 3179 scale($scale); 3180 disp(0x0); 3181 %} 3182 %} 3183 3184 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 3185 operand indIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegL lreg, immI2 scale) 3186 %{ 3187 predicate(CompressedOops::shift() == 0); 3188 constraint(ALLOC_IN_RC(ptr_reg)); 3189 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off); 3190 3191 op_cost(10); 3192 format %{"[$reg + $off + $lreg << $scale]" %} 3193 interface(MEMORY_INTER) %{ 3194 base($reg); 3195 index($lreg); 3196 scale($scale); 3197 disp($off); 3198 %} 3199 %} 3200 3201 // Indirect Memory Times Plus Positive Index Register Plus Offset Operand 3202 operand indPosIndexOffsetNarrow(rRegN reg, immL32 off, rRegI idx) 3203 %{ 3204 constraint(ALLOC_IN_RC(ptr_reg)); 3205 predicate(CompressedOops::shift() == 0 && n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 3206 match(AddP (AddP (DecodeN reg) (ConvI2L idx)) off); 3207 3208 op_cost(10); 3209 format %{"[$reg + $off + $idx]" %} 3210 interface(MEMORY_INTER) %{ 3211 base($reg); 3212 index($idx); 3213 scale(0x0); 3214 disp($off); 3215 %} 3216 %} 3217 3218 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 3219 operand indPosIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegI idx, immI2 scale) 3220 %{ 3221 constraint(ALLOC_IN_RC(ptr_reg)); 3222 predicate(CompressedOops::shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3223 match(AddP (AddP (DecodeN reg) (LShiftL (ConvI2L idx) scale)) off); 3224 3225 op_cost(10); 3226 format %{"[$reg + $off + $idx << $scale]" %} 3227 interface(MEMORY_INTER) %{ 3228 base($reg); 3229 index($idx); 3230 scale($scale); 3231 disp($off); 3232 %} 3233 %} 3234 3235 //----------Special Memory Operands-------------------------------------------- 3236 // Stack Slot Operand - This operand is used for loading and storing temporary 3237 // values on the stack where a match requires a value to 3238 // flow through memory. 3239 operand stackSlotP(sRegP reg) 3240 %{ 3241 constraint(ALLOC_IN_RC(stack_slots)); 3242 // No match rule because this operand is only generated in matching 3243 3244 format %{ "[$reg]" %} 3245 interface(MEMORY_INTER) %{ 3246 base(0x4); // RSP 3247 index(0x4); // No Index 3248 scale(0x0); // No Scale 3249 disp($reg); // Stack Offset 3250 %} 3251 %} 3252 3253 operand stackSlotI(sRegI reg) 3254 %{ 3255 constraint(ALLOC_IN_RC(stack_slots)); 3256 // No match rule because this operand is only generated in matching 3257 3258 format %{ "[$reg]" %} 3259 interface(MEMORY_INTER) %{ 3260 base(0x4); // RSP 3261 index(0x4); // No Index 3262 scale(0x0); // No Scale 3263 disp($reg); // Stack Offset 3264 %} 3265 %} 3266 3267 operand stackSlotF(sRegF reg) 3268 %{ 3269 constraint(ALLOC_IN_RC(stack_slots)); 3270 // No match rule because this operand is only generated in matching 3271 3272 format %{ "[$reg]" %} 3273 interface(MEMORY_INTER) %{ 3274 base(0x4); // RSP 3275 index(0x4); // No Index 3276 scale(0x0); // No Scale 3277 disp($reg); // Stack Offset 3278 %} 3279 %} 3280 3281 operand stackSlotD(sRegD reg) 3282 %{ 3283 constraint(ALLOC_IN_RC(stack_slots)); 3284 // No match rule because this operand is only generated in matching 3285 3286 format %{ "[$reg]" %} 3287 interface(MEMORY_INTER) %{ 3288 base(0x4); // RSP 3289 index(0x4); // No Index 3290 scale(0x0); // No Scale 3291 disp($reg); // Stack Offset 3292 %} 3293 %} 3294 operand stackSlotL(sRegL reg) 3295 %{ 3296 constraint(ALLOC_IN_RC(stack_slots)); 3297 // No match rule because this operand is only generated in matching 3298 3299 format %{ "[$reg]" %} 3300 interface(MEMORY_INTER) %{ 3301 base(0x4); // RSP 3302 index(0x4); // No Index 3303 scale(0x0); // No Scale 3304 disp($reg); // Stack Offset 3305 %} 3306 %} 3307 3308 //----------Conditional Branch Operands---------------------------------------- 3309 // Comparison Op - This is the operation of the comparison, and is limited to 3310 // the following set of codes: 3311 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 3312 // 3313 // Other attributes of the comparison, such as unsignedness, are specified 3314 // by the comparison instruction that sets a condition code flags register. 3315 // That result is represented by a flags operand whose subtype is appropriate 3316 // to the unsignedness (etc.) of the comparison. 3317 // 3318 // Later, the instruction which matches both the Comparison Op (a Bool) and 3319 // the flags (produced by the Cmp) specifies the coding of the comparison op 3320 // by matching a specific subtype of Bool operand below, such as cmpOpU. 3321 3322 // Comparison Code 3323 operand cmpOp() 3324 %{ 3325 match(Bool); 3326 3327 format %{ "" %} 3328 interface(COND_INTER) %{ 3329 equal(0x4, "e"); 3330 not_equal(0x5, "ne"); 3331 less(0xC, "l"); 3332 greater_equal(0xD, "ge"); 3333 less_equal(0xE, "le"); 3334 greater(0xF, "g"); 3335 overflow(0x0, "o"); 3336 no_overflow(0x1, "no"); 3337 %} 3338 %} 3339 3340 // Comparison Code, unsigned compare. Used by FP also, with 3341 // C2 (unordered) turned into GT or LT already. The other bits 3342 // C0 and C3 are turned into Carry & Zero flags. 3343 operand cmpOpU() 3344 %{ 3345 match(Bool); 3346 3347 format %{ "" %} 3348 interface(COND_INTER) %{ 3349 equal(0x4, "e"); 3350 not_equal(0x5, "ne"); 3351 less(0x2, "b"); 3352 greater_equal(0x3, "ae"); 3353 less_equal(0x6, "be"); 3354 greater(0x7, "a"); 3355 overflow(0x0, "o"); 3356 no_overflow(0x1, "no"); 3357 %} 3358 %} 3359 3360 3361 // Floating comparisons that don't require any fixup for the unordered case, 3362 // If both inputs of the comparison are the same, ZF is always set so we 3363 // don't need to use cmpOpUCF2 for eq/ne 3364 operand cmpOpUCF() %{ 3365 match(Bool); 3366 predicate(n->as_Bool()->_test._test == BoolTest::lt || 3367 n->as_Bool()->_test._test == BoolTest::ge || 3368 n->as_Bool()->_test._test == BoolTest::le || 3369 n->as_Bool()->_test._test == BoolTest::gt || 3370 n->in(1)->in(1) == n->in(1)->in(2)); 3371 format %{ "" %} 3372 interface(COND_INTER) %{ 3373 equal(0xb, "np"); 3374 not_equal(0xa, "p"); 3375 less(0x2, "b"); 3376 greater_equal(0x3, "ae"); 3377 less_equal(0x6, "be"); 3378 greater(0x7, "a"); 3379 overflow(0x0, "o"); 3380 no_overflow(0x1, "no"); 3381 %} 3382 %} 3383 3384 3385 // Floating comparisons that can be fixed up with extra conditional jumps 3386 operand cmpOpUCF2() %{ 3387 match(Bool); 3388 predicate((n->as_Bool()->_test._test == BoolTest::ne || 3389 n->as_Bool()->_test._test == BoolTest::eq) && 3390 n->in(1)->in(1) != n->in(1)->in(2)); 3391 format %{ "" %} 3392 interface(COND_INTER) %{ 3393 equal(0x4, "e"); 3394 not_equal(0x5, "ne"); 3395 less(0x2, "b"); 3396 greater_equal(0x3, "ae"); 3397 less_equal(0x6, "be"); 3398 greater(0x7, "a"); 3399 overflow(0x0, "o"); 3400 no_overflow(0x1, "no"); 3401 %} 3402 %} 3403 3404 //----------OPERAND CLASSES---------------------------------------------------- 3405 // Operand Classes are groups of operands that are used as to simplify 3406 // instruction definitions by not requiring the AD writer to specify separate 3407 // instructions for every form of operand when the instruction accepts 3408 // multiple operand types with the same basic encoding and format. The classic 3409 // case of this is memory operands. 3410 3411 opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex, 3412 indIndexScale, indPosIndexScale, indIndexScaleOffset, indPosIndexOffset, indPosIndexScaleOffset, 3413 indCompressedOopOffset, 3414 indirectNarrow, indOffset8Narrow, indOffset32Narrow, 3415 indIndexOffsetNarrow, indIndexNarrow, indIndexScaleNarrow, 3416 indIndexScaleOffsetNarrow, indPosIndexOffsetNarrow, indPosIndexScaleOffsetNarrow); 3417 3418 //----------PIPELINE----------------------------------------------------------- 3419 // Rules which define the behavior of the target architectures pipeline. 3420 pipeline %{ 3421 3422 //----------ATTRIBUTES--------------------------------------------------------- 3423 attributes %{ 3424 variable_size_instructions; // Fixed size instructions 3425 max_instructions_per_bundle = 3; // Up to 3 instructions per bundle 3426 instruction_unit_size = 1; // An instruction is 1 bytes long 3427 instruction_fetch_unit_size = 16; // The processor fetches one line 3428 instruction_fetch_units = 1; // of 16 bytes 3429 3430 // List of nop instructions 3431 nops( MachNop ); 3432 %} 3433 3434 //----------RESOURCES---------------------------------------------------------- 3435 // Resources are the functional units available to the machine 3436 3437 // Generic P2/P3 pipeline 3438 // 3 decoders, only D0 handles big operands; a "bundle" is the limit of 3439 // 3 instructions decoded per cycle. 3440 // 2 load/store ops per cycle, 1 branch, 1 FPU, 3441 // 3 ALU op, only ALU0 handles mul instructions. 3442 resources( D0, D1, D2, DECODE = D0 | D1 | D2, 3443 MS0, MS1, MS2, MEM = MS0 | MS1 | MS2, 3444 BR, FPU, 3445 ALU0, ALU1, ALU2, ALU = ALU0 | ALU1 | ALU2); 3446 3447 //----------PIPELINE DESCRIPTION----------------------------------------------- 3448 // Pipeline Description specifies the stages in the machine's pipeline 3449 3450 // Generic P2/P3 pipeline 3451 pipe_desc(S0, S1, S2, S3, S4, S5); 3452 3453 //----------PIPELINE CLASSES--------------------------------------------------- 3454 // Pipeline Classes describe the stages in which input and output are 3455 // referenced by the hardware pipeline. 3456 3457 // Naming convention: ialu or fpu 3458 // Then: _reg 3459 // Then: _reg if there is a 2nd register 3460 // Then: _long if it's a pair of instructions implementing a long 3461 // Then: _fat if it requires the big decoder 3462 // Or: _mem if it requires the big decoder and a memory unit. 3463 3464 // Integer ALU reg operation 3465 pipe_class ialu_reg(rRegI dst) 3466 %{ 3467 single_instruction; 3468 dst : S4(write); 3469 dst : S3(read); 3470 DECODE : S0; // any decoder 3471 ALU : S3; // any alu 3472 %} 3473 3474 // Long ALU reg operation 3475 pipe_class ialu_reg_long(rRegL dst) 3476 %{ 3477 instruction_count(2); 3478 dst : S4(write); 3479 dst : S3(read); 3480 DECODE : S0(2); // any 2 decoders 3481 ALU : S3(2); // both alus 3482 %} 3483 3484 // Integer ALU reg operation using big decoder 3485 pipe_class ialu_reg_fat(rRegI dst) 3486 %{ 3487 single_instruction; 3488 dst : S4(write); 3489 dst : S3(read); 3490 D0 : S0; // big decoder only 3491 ALU : S3; // any alu 3492 %} 3493 3494 // Integer ALU reg-reg operation 3495 pipe_class ialu_reg_reg(rRegI dst, rRegI src) 3496 %{ 3497 single_instruction; 3498 dst : S4(write); 3499 src : S3(read); 3500 DECODE : S0; // any decoder 3501 ALU : S3; // any alu 3502 %} 3503 3504 // Integer ALU reg-reg operation 3505 pipe_class ialu_reg_reg_fat(rRegI dst, memory src) 3506 %{ 3507 single_instruction; 3508 dst : S4(write); 3509 src : S3(read); 3510 D0 : S0; // big decoder only 3511 ALU : S3; // any alu 3512 %} 3513 3514 // Integer ALU reg-mem operation 3515 pipe_class ialu_reg_mem(rRegI dst, memory mem) 3516 %{ 3517 single_instruction; 3518 dst : S5(write); 3519 mem : S3(read); 3520 D0 : S0; // big decoder only 3521 ALU : S4; // any alu 3522 MEM : S3; // any mem 3523 %} 3524 3525 // Integer mem operation (prefetch) 3526 pipe_class ialu_mem(memory mem) 3527 %{ 3528 single_instruction; 3529 mem : S3(read); 3530 D0 : S0; // big decoder only 3531 MEM : S3; // any mem 3532 %} 3533 3534 // Integer Store to Memory 3535 pipe_class ialu_mem_reg(memory mem, rRegI src) 3536 %{ 3537 single_instruction; 3538 mem : S3(read); 3539 src : S5(read); 3540 D0 : S0; // big decoder only 3541 ALU : S4; // any alu 3542 MEM : S3; 3543 %} 3544 3545 // // Long Store to Memory 3546 // pipe_class ialu_mem_long_reg(memory mem, rRegL src) 3547 // %{ 3548 // instruction_count(2); 3549 // mem : S3(read); 3550 // src : S5(read); 3551 // D0 : S0(2); // big decoder only; twice 3552 // ALU : S4(2); // any 2 alus 3553 // MEM : S3(2); // Both mems 3554 // %} 3555 3556 // Integer Store to Memory 3557 pipe_class ialu_mem_imm(memory mem) 3558 %{ 3559 single_instruction; 3560 mem : S3(read); 3561 D0 : S0; // big decoder only 3562 ALU : S4; // any alu 3563 MEM : S3; 3564 %} 3565 3566 // Integer ALU0 reg-reg operation 3567 pipe_class ialu_reg_reg_alu0(rRegI dst, rRegI src) 3568 %{ 3569 single_instruction; 3570 dst : S4(write); 3571 src : S3(read); 3572 D0 : S0; // Big decoder only 3573 ALU0 : S3; // only alu0 3574 %} 3575 3576 // Integer ALU0 reg-mem operation 3577 pipe_class ialu_reg_mem_alu0(rRegI dst, memory mem) 3578 %{ 3579 single_instruction; 3580 dst : S5(write); 3581 mem : S3(read); 3582 D0 : S0; // big decoder only 3583 ALU0 : S4; // ALU0 only 3584 MEM : S3; // any mem 3585 %} 3586 3587 // Integer ALU reg-reg operation 3588 pipe_class ialu_cr_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2) 3589 %{ 3590 single_instruction; 3591 cr : S4(write); 3592 src1 : S3(read); 3593 src2 : S3(read); 3594 DECODE : S0; // any decoder 3595 ALU : S3; // any alu 3596 %} 3597 3598 // Integer ALU reg-imm operation 3599 pipe_class ialu_cr_reg_imm(rFlagsReg cr, rRegI src1) 3600 %{ 3601 single_instruction; 3602 cr : S4(write); 3603 src1 : S3(read); 3604 DECODE : S0; // any decoder 3605 ALU : S3; // any alu 3606 %} 3607 3608 // Integer ALU reg-mem operation 3609 pipe_class ialu_cr_reg_mem(rFlagsReg cr, rRegI src1, memory src2) 3610 %{ 3611 single_instruction; 3612 cr : S4(write); 3613 src1 : S3(read); 3614 src2 : S3(read); 3615 D0 : S0; // big decoder only 3616 ALU : S4; // any alu 3617 MEM : S3; 3618 %} 3619 3620 // Conditional move reg-reg 3621 pipe_class pipe_cmplt( rRegI p, rRegI q, rRegI y) 3622 %{ 3623 instruction_count(4); 3624 y : S4(read); 3625 q : S3(read); 3626 p : S3(read); 3627 DECODE : S0(4); // any decoder 3628 %} 3629 3630 // Conditional move reg-reg 3631 pipe_class pipe_cmov_reg( rRegI dst, rRegI src, rFlagsReg cr) 3632 %{ 3633 single_instruction; 3634 dst : S4(write); 3635 src : S3(read); 3636 cr : S3(read); 3637 DECODE : S0; // any decoder 3638 %} 3639 3640 // Conditional move reg-mem 3641 pipe_class pipe_cmov_mem( rFlagsReg cr, rRegI dst, memory src) 3642 %{ 3643 single_instruction; 3644 dst : S4(write); 3645 src : S3(read); 3646 cr : S3(read); 3647 DECODE : S0; // any decoder 3648 MEM : S3; 3649 %} 3650 3651 // Conditional move reg-reg long 3652 pipe_class pipe_cmov_reg_long( rFlagsReg cr, rRegL dst, rRegL src) 3653 %{ 3654 single_instruction; 3655 dst : S4(write); 3656 src : S3(read); 3657 cr : S3(read); 3658 DECODE : S0(2); // any 2 decoders 3659 %} 3660 3661 // Float reg-reg operation 3662 pipe_class fpu_reg(regD dst) 3663 %{ 3664 instruction_count(2); 3665 dst : S3(read); 3666 DECODE : S0(2); // any 2 decoders 3667 FPU : S3; 3668 %} 3669 3670 // Float reg-reg operation 3671 pipe_class fpu_reg_reg(regD dst, regD src) 3672 %{ 3673 instruction_count(2); 3674 dst : S4(write); 3675 src : S3(read); 3676 DECODE : S0(2); // any 2 decoders 3677 FPU : S3; 3678 %} 3679 3680 // Float reg-reg operation 3681 pipe_class fpu_reg_reg_reg(regD dst, regD src1, regD src2) 3682 %{ 3683 instruction_count(3); 3684 dst : S4(write); 3685 src1 : S3(read); 3686 src2 : S3(read); 3687 DECODE : S0(3); // any 3 decoders 3688 FPU : S3(2); 3689 %} 3690 3691 // Float reg-reg operation 3692 pipe_class fpu_reg_reg_reg_reg(regD dst, regD src1, regD src2, regD src3) 3693 %{ 3694 instruction_count(4); 3695 dst : S4(write); 3696 src1 : S3(read); 3697 src2 : S3(read); 3698 src3 : S3(read); 3699 DECODE : S0(4); // any 3 decoders 3700 FPU : S3(2); 3701 %} 3702 3703 // Float reg-reg operation 3704 pipe_class fpu_reg_mem_reg_reg(regD dst, memory src1, regD src2, regD src3) 3705 %{ 3706 instruction_count(4); 3707 dst : S4(write); 3708 src1 : S3(read); 3709 src2 : S3(read); 3710 src3 : S3(read); 3711 DECODE : S1(3); // any 3 decoders 3712 D0 : S0; // Big decoder only 3713 FPU : S3(2); 3714 MEM : S3; 3715 %} 3716 3717 // Float reg-mem operation 3718 pipe_class fpu_reg_mem(regD dst, memory mem) 3719 %{ 3720 instruction_count(2); 3721 dst : S5(write); 3722 mem : S3(read); 3723 D0 : S0; // big decoder only 3724 DECODE : S1; // any decoder for FPU POP 3725 FPU : S4; 3726 MEM : S3; // any mem 3727 %} 3728 3729 // Float reg-mem operation 3730 pipe_class fpu_reg_reg_mem(regD dst, regD src1, memory mem) 3731 %{ 3732 instruction_count(3); 3733 dst : S5(write); 3734 src1 : S3(read); 3735 mem : S3(read); 3736 D0 : S0; // big decoder only 3737 DECODE : S1(2); // any decoder for FPU POP 3738 FPU : S4; 3739 MEM : S3; // any mem 3740 %} 3741 3742 // Float mem-reg operation 3743 pipe_class fpu_mem_reg(memory mem, regD src) 3744 %{ 3745 instruction_count(2); 3746 src : S5(read); 3747 mem : S3(read); 3748 DECODE : S0; // any decoder for FPU PUSH 3749 D0 : S1; // big decoder only 3750 FPU : S4; 3751 MEM : S3; // any mem 3752 %} 3753 3754 pipe_class fpu_mem_reg_reg(memory mem, regD src1, regD src2) 3755 %{ 3756 instruction_count(3); 3757 src1 : S3(read); 3758 src2 : S3(read); 3759 mem : S3(read); 3760 DECODE : S0(2); // any decoder for FPU PUSH 3761 D0 : S1; // big decoder only 3762 FPU : S4; 3763 MEM : S3; // any mem 3764 %} 3765 3766 pipe_class fpu_mem_reg_mem(memory mem, regD src1, memory src2) 3767 %{ 3768 instruction_count(3); 3769 src1 : S3(read); 3770 src2 : S3(read); 3771 mem : S4(read); 3772 DECODE : S0; // any decoder for FPU PUSH 3773 D0 : S0(2); // big decoder only 3774 FPU : S4; 3775 MEM : S3(2); // any mem 3776 %} 3777 3778 pipe_class fpu_mem_mem(memory dst, memory src1) 3779 %{ 3780 instruction_count(2); 3781 src1 : S3(read); 3782 dst : S4(read); 3783 D0 : S0(2); // big decoder only 3784 MEM : S3(2); // any mem 3785 %} 3786 3787 pipe_class fpu_mem_mem_mem(memory dst, memory src1, memory src2) 3788 %{ 3789 instruction_count(3); 3790 src1 : S3(read); 3791 src2 : S3(read); 3792 dst : S4(read); 3793 D0 : S0(3); // big decoder only 3794 FPU : S4; 3795 MEM : S3(3); // any mem 3796 %} 3797 3798 pipe_class fpu_mem_reg_con(memory mem, regD src1) 3799 %{ 3800 instruction_count(3); 3801 src1 : S4(read); 3802 mem : S4(read); 3803 DECODE : S0; // any decoder for FPU PUSH 3804 D0 : S0(2); // big decoder only 3805 FPU : S4; 3806 MEM : S3(2); // any mem 3807 %} 3808 3809 // Float load constant 3810 pipe_class fpu_reg_con(regD dst) 3811 %{ 3812 instruction_count(2); 3813 dst : S5(write); 3814 D0 : S0; // big decoder only for the load 3815 DECODE : S1; // any decoder for FPU POP 3816 FPU : S4; 3817 MEM : S3; // any mem 3818 %} 3819 3820 // Float load constant 3821 pipe_class fpu_reg_reg_con(regD dst, regD src) 3822 %{ 3823 instruction_count(3); 3824 dst : S5(write); 3825 src : S3(read); 3826 D0 : S0; // big decoder only for the load 3827 DECODE : S1(2); // any decoder for FPU POP 3828 FPU : S4; 3829 MEM : S3; // any mem 3830 %} 3831 3832 // UnConditional branch 3833 pipe_class pipe_jmp(label labl) 3834 %{ 3835 single_instruction; 3836 BR : S3; 3837 %} 3838 3839 // Conditional branch 3840 pipe_class pipe_jcc(cmpOp cmp, rFlagsReg cr, label labl) 3841 %{ 3842 single_instruction; 3843 cr : S1(read); 3844 BR : S3; 3845 %} 3846 3847 // Allocation idiom 3848 pipe_class pipe_cmpxchg(rRegP dst, rRegP heap_ptr) 3849 %{ 3850 instruction_count(1); force_serialization; 3851 fixed_latency(6); 3852 heap_ptr : S3(read); 3853 DECODE : S0(3); 3854 D0 : S2; 3855 MEM : S3; 3856 ALU : S3(2); 3857 dst : S5(write); 3858 BR : S5; 3859 %} 3860 3861 // Generic big/slow expanded idiom 3862 pipe_class pipe_slow() 3863 %{ 3864 instruction_count(10); multiple_bundles; force_serialization; 3865 fixed_latency(100); 3866 D0 : S0(2); 3867 MEM : S3(2); 3868 %} 3869 3870 // The real do-nothing guy 3871 pipe_class empty() 3872 %{ 3873 instruction_count(0); 3874 %} 3875 3876 // Define the class for the Nop node 3877 define 3878 %{ 3879 MachNop = empty; 3880 %} 3881 3882 %} 3883 3884 //----------INSTRUCTIONS------------------------------------------------------- 3885 // 3886 // match -- States which machine-independent subtree may be replaced 3887 // by this instruction. 3888 // ins_cost -- The estimated cost of this instruction is used by instruction 3889 // selection to identify a minimum cost tree of machine 3890 // instructions that matches a tree of machine-independent 3891 // instructions. 3892 // format -- A string providing the disassembly for this instruction. 3893 // The value of an instruction's operand may be inserted 3894 // by referring to it with a '$' prefix. 3895 // opcode -- Three instruction opcodes may be provided. These are referred 3896 // to within an encode class as $primary, $secondary, and $tertiary 3897 // rrspectively. The primary opcode is commonly used to 3898 // indicate the type of machine instruction, while secondary 3899 // and tertiary are often used for prefix options or addressing 3900 // modes. 3901 // ins_encode -- A list of encode classes with parameters. The encode class 3902 // name must have been defined in an 'enc_class' specification 3903 // in the encode section of the architecture description. 3904 3905 // Dummy reg-to-reg vector moves. Removed during post-selection cleanup. 3906 // Load Float 3907 instruct MoveF2VL(vlRegF dst, regF src) %{ 3908 match(Set dst src); 3909 format %{ "movss $dst,$src\t! load float (4 bytes)" %} 3910 ins_encode %{ 3911 ShouldNotReachHere(); 3912 %} 3913 ins_pipe( fpu_reg_reg ); 3914 %} 3915 3916 // Load Float 3917 instruct MoveF2LEG(legRegF dst, regF src) %{ 3918 match(Set dst src); 3919 format %{ "movss $dst,$src\t# if src != dst load float (4 bytes)" %} 3920 ins_encode %{ 3921 ShouldNotReachHere(); 3922 %} 3923 ins_pipe( fpu_reg_reg ); 3924 %} 3925 3926 // Load Float 3927 instruct MoveVL2F(regF dst, vlRegF src) %{ 3928 match(Set dst src); 3929 format %{ "movss $dst,$src\t! load float (4 bytes)" %} 3930 ins_encode %{ 3931 ShouldNotReachHere(); 3932 %} 3933 ins_pipe( fpu_reg_reg ); 3934 %} 3935 3936 // Load Float 3937 instruct MoveLEG2F(regF dst, legRegF src) %{ 3938 match(Set dst src); 3939 format %{ "movss $dst,$src\t# if src != dst load float (4 bytes)" %} 3940 ins_encode %{ 3941 ShouldNotReachHere(); 3942 %} 3943 ins_pipe( fpu_reg_reg ); 3944 %} 3945 3946 // Load Double 3947 instruct MoveD2VL(vlRegD dst, regD src) %{ 3948 match(Set dst src); 3949 format %{ "movsd $dst,$src\t! load double (8 bytes)" %} 3950 ins_encode %{ 3951 ShouldNotReachHere(); 3952 %} 3953 ins_pipe( fpu_reg_reg ); 3954 %} 3955 3956 // Load Double 3957 instruct MoveD2LEG(legRegD dst, regD src) %{ 3958 match(Set dst src); 3959 format %{ "movsd $dst,$src\t# if src != dst load double (8 bytes)" %} 3960 ins_encode %{ 3961 ShouldNotReachHere(); 3962 %} 3963 ins_pipe( fpu_reg_reg ); 3964 %} 3965 3966 // Load Double 3967 instruct MoveVL2D(regD dst, vlRegD src) %{ 3968 match(Set dst src); 3969 format %{ "movsd $dst,$src\t! load double (8 bytes)" %} 3970 ins_encode %{ 3971 ShouldNotReachHere(); 3972 %} 3973 ins_pipe( fpu_reg_reg ); 3974 %} 3975 3976 // Load Double 3977 instruct MoveLEG2D(regD dst, legRegD src) %{ 3978 match(Set dst src); 3979 format %{ "movsd $dst,$src\t# if src != dst load double (8 bytes)" %} 3980 ins_encode %{ 3981 ShouldNotReachHere(); 3982 %} 3983 ins_pipe( fpu_reg_reg ); 3984 %} 3985 3986 //----------Load/Store/Move Instructions--------------------------------------- 3987 //----------Load Instructions-------------------------------------------------- 3988 3989 // Load Byte (8 bit signed) 3990 instruct loadB(rRegI dst, memory mem) 3991 %{ 3992 match(Set dst (LoadB mem)); 3993 3994 ins_cost(125); 3995 format %{ "movsbl $dst, $mem\t# byte" %} 3996 3997 ins_encode %{ 3998 __ movsbl($dst$$Register, $mem$$Address); 3999 %} 4000 4001 ins_pipe(ialu_reg_mem); 4002 %} 4003 4004 // Load Byte (8 bit signed) into Long Register 4005 instruct loadB2L(rRegL dst, memory mem) 4006 %{ 4007 match(Set dst (ConvI2L (LoadB mem))); 4008 4009 ins_cost(125); 4010 format %{ "movsbq $dst, $mem\t# byte -> long" %} 4011 4012 ins_encode %{ 4013 __ movsbq($dst$$Register, $mem$$Address); 4014 %} 4015 4016 ins_pipe(ialu_reg_mem); 4017 %} 4018 4019 // Load Unsigned Byte (8 bit UNsigned) 4020 instruct loadUB(rRegI dst, memory mem) 4021 %{ 4022 match(Set dst (LoadUB mem)); 4023 4024 ins_cost(125); 4025 format %{ "movzbl $dst, $mem\t# ubyte" %} 4026 4027 ins_encode %{ 4028 __ movzbl($dst$$Register, $mem$$Address); 4029 %} 4030 4031 ins_pipe(ialu_reg_mem); 4032 %} 4033 4034 // Load Unsigned Byte (8 bit UNsigned) into Long Register 4035 instruct loadUB2L(rRegL dst, memory mem) 4036 %{ 4037 match(Set dst (ConvI2L (LoadUB mem))); 4038 4039 ins_cost(125); 4040 format %{ "movzbq $dst, $mem\t# ubyte -> long" %} 4041 4042 ins_encode %{ 4043 __ movzbq($dst$$Register, $mem$$Address); 4044 %} 4045 4046 ins_pipe(ialu_reg_mem); 4047 %} 4048 4049 // Load Unsigned Byte (8 bit UNsigned) with 32-bit mask into Long Register 4050 instruct loadUB2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 4051 match(Set dst (ConvI2L (AndI (LoadUB mem) mask))); 4052 effect(KILL cr); 4053 4054 format %{ "movzbq $dst, $mem\t# ubyte & 32-bit mask -> long\n\t" 4055 "andl $dst, right_n_bits($mask, 8)" %} 4056 ins_encode %{ 4057 Register Rdst = $dst$$Register; 4058 __ movzbq(Rdst, $mem$$Address); 4059 __ andl(Rdst, $mask$$constant & right_n_bits(8)); 4060 %} 4061 ins_pipe(ialu_reg_mem); 4062 %} 4063 4064 // Load Short (16 bit signed) 4065 instruct loadS(rRegI dst, memory mem) 4066 %{ 4067 match(Set dst (LoadS mem)); 4068 4069 ins_cost(125); 4070 format %{ "movswl $dst, $mem\t# short" %} 4071 4072 ins_encode %{ 4073 __ movswl($dst$$Register, $mem$$Address); 4074 %} 4075 4076 ins_pipe(ialu_reg_mem); 4077 %} 4078 4079 // Load Short (16 bit signed) to Byte (8 bit signed) 4080 instruct loadS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4081 match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour)); 4082 4083 ins_cost(125); 4084 format %{ "movsbl $dst, $mem\t# short -> byte" %} 4085 ins_encode %{ 4086 __ movsbl($dst$$Register, $mem$$Address); 4087 %} 4088 ins_pipe(ialu_reg_mem); 4089 %} 4090 4091 // Load Short (16 bit signed) into Long Register 4092 instruct loadS2L(rRegL dst, memory mem) 4093 %{ 4094 match(Set dst (ConvI2L (LoadS mem))); 4095 4096 ins_cost(125); 4097 format %{ "movswq $dst, $mem\t# short -> long" %} 4098 4099 ins_encode %{ 4100 __ movswq($dst$$Register, $mem$$Address); 4101 %} 4102 4103 ins_pipe(ialu_reg_mem); 4104 %} 4105 4106 // Load Unsigned Short/Char (16 bit UNsigned) 4107 instruct loadUS(rRegI dst, memory mem) 4108 %{ 4109 match(Set dst (LoadUS mem)); 4110 4111 ins_cost(125); 4112 format %{ "movzwl $dst, $mem\t# ushort/char" %} 4113 4114 ins_encode %{ 4115 __ movzwl($dst$$Register, $mem$$Address); 4116 %} 4117 4118 ins_pipe(ialu_reg_mem); 4119 %} 4120 4121 // Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed) 4122 instruct loadUS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4123 match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour)); 4124 4125 ins_cost(125); 4126 format %{ "movsbl $dst, $mem\t# ushort -> byte" %} 4127 ins_encode %{ 4128 __ movsbl($dst$$Register, $mem$$Address); 4129 %} 4130 ins_pipe(ialu_reg_mem); 4131 %} 4132 4133 // Load Unsigned Short/Char (16 bit UNsigned) into Long Register 4134 instruct loadUS2L(rRegL dst, memory mem) 4135 %{ 4136 match(Set dst (ConvI2L (LoadUS mem))); 4137 4138 ins_cost(125); 4139 format %{ "movzwq $dst, $mem\t# ushort/char -> long" %} 4140 4141 ins_encode %{ 4142 __ movzwq($dst$$Register, $mem$$Address); 4143 %} 4144 4145 ins_pipe(ialu_reg_mem); 4146 %} 4147 4148 // Load Unsigned Short/Char (16 bit UNsigned) with mask 0xFF into Long Register 4149 instruct loadUS2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 4150 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 4151 4152 format %{ "movzbq $dst, $mem\t# ushort/char & 0xFF -> long" %} 4153 ins_encode %{ 4154 __ movzbq($dst$$Register, $mem$$Address); 4155 %} 4156 ins_pipe(ialu_reg_mem); 4157 %} 4158 4159 // Load Unsigned Short/Char (16 bit UNsigned) with 32-bit mask into Long Register 4160 instruct loadUS2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 4161 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 4162 effect(KILL cr); 4163 4164 format %{ "movzwq $dst, $mem\t# ushort/char & 32-bit mask -> long\n\t" 4165 "andl $dst, right_n_bits($mask, 16)" %} 4166 ins_encode %{ 4167 Register Rdst = $dst$$Register; 4168 __ movzwq(Rdst, $mem$$Address); 4169 __ andl(Rdst, $mask$$constant & right_n_bits(16)); 4170 %} 4171 ins_pipe(ialu_reg_mem); 4172 %} 4173 4174 // Load Integer 4175 instruct loadI(rRegI dst, memory mem) 4176 %{ 4177 match(Set dst (LoadI mem)); 4178 4179 ins_cost(125); 4180 format %{ "movl $dst, $mem\t# int" %} 4181 4182 ins_encode %{ 4183 __ movl($dst$$Register, $mem$$Address); 4184 %} 4185 4186 ins_pipe(ialu_reg_mem); 4187 %} 4188 4189 // Load Integer (32 bit signed) to Byte (8 bit signed) 4190 instruct loadI2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4191 match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour)); 4192 4193 ins_cost(125); 4194 format %{ "movsbl $dst, $mem\t# int -> byte" %} 4195 ins_encode %{ 4196 __ movsbl($dst$$Register, $mem$$Address); 4197 %} 4198 ins_pipe(ialu_reg_mem); 4199 %} 4200 4201 // Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned) 4202 instruct loadI2UB(rRegI dst, memory mem, immI_255 mask) %{ 4203 match(Set dst (AndI (LoadI mem) mask)); 4204 4205 ins_cost(125); 4206 format %{ "movzbl $dst, $mem\t# int -> ubyte" %} 4207 ins_encode %{ 4208 __ movzbl($dst$$Register, $mem$$Address); 4209 %} 4210 ins_pipe(ialu_reg_mem); 4211 %} 4212 4213 // Load Integer (32 bit signed) to Short (16 bit signed) 4214 instruct loadI2S(rRegI dst, memory mem, immI_16 sixteen) %{ 4215 match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen)); 4216 4217 ins_cost(125); 4218 format %{ "movswl $dst, $mem\t# int -> short" %} 4219 ins_encode %{ 4220 __ movswl($dst$$Register, $mem$$Address); 4221 %} 4222 ins_pipe(ialu_reg_mem); 4223 %} 4224 4225 // Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned) 4226 instruct loadI2US(rRegI dst, memory mem, immI_65535 mask) %{ 4227 match(Set dst (AndI (LoadI mem) mask)); 4228 4229 ins_cost(125); 4230 format %{ "movzwl $dst, $mem\t# int -> ushort/char" %} 4231 ins_encode %{ 4232 __ movzwl($dst$$Register, $mem$$Address); 4233 %} 4234 ins_pipe(ialu_reg_mem); 4235 %} 4236 4237 // Load Integer into Long Register 4238 instruct loadI2L(rRegL dst, memory mem) 4239 %{ 4240 match(Set dst (ConvI2L (LoadI mem))); 4241 4242 ins_cost(125); 4243 format %{ "movslq $dst, $mem\t# int -> long" %} 4244 4245 ins_encode %{ 4246 __ movslq($dst$$Register, $mem$$Address); 4247 %} 4248 4249 ins_pipe(ialu_reg_mem); 4250 %} 4251 4252 // Load Integer with mask 0xFF into Long Register 4253 instruct loadI2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 4254 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4255 4256 format %{ "movzbq $dst, $mem\t# int & 0xFF -> long" %} 4257 ins_encode %{ 4258 __ movzbq($dst$$Register, $mem$$Address); 4259 %} 4260 ins_pipe(ialu_reg_mem); 4261 %} 4262 4263 // Load Integer with mask 0xFFFF into Long Register 4264 instruct loadI2L_immI_65535(rRegL dst, memory mem, immI_65535 mask) %{ 4265 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4266 4267 format %{ "movzwq $dst, $mem\t# int & 0xFFFF -> long" %} 4268 ins_encode %{ 4269 __ movzwq($dst$$Register, $mem$$Address); 4270 %} 4271 ins_pipe(ialu_reg_mem); 4272 %} 4273 4274 // Load Integer with a 31-bit mask into Long Register 4275 instruct loadI2L_immU31(rRegL dst, memory mem, immU31 mask, rFlagsReg cr) %{ 4276 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4277 effect(KILL cr); 4278 4279 format %{ "movl $dst, $mem\t# int & 31-bit mask -> long\n\t" 4280 "andl $dst, $mask" %} 4281 ins_encode %{ 4282 Register Rdst = $dst$$Register; 4283 __ movl(Rdst, $mem$$Address); 4284 __ andl(Rdst, $mask$$constant); 4285 %} 4286 ins_pipe(ialu_reg_mem); 4287 %} 4288 4289 // Load Unsigned Integer into Long Register 4290 instruct loadUI2L(rRegL dst, memory mem, immL_32bits mask) 4291 %{ 4292 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 4293 4294 ins_cost(125); 4295 format %{ "movl $dst, $mem\t# uint -> long" %} 4296 4297 ins_encode %{ 4298 __ movl($dst$$Register, $mem$$Address); 4299 %} 4300 4301 ins_pipe(ialu_reg_mem); 4302 %} 4303 4304 // Load Long 4305 instruct loadL(rRegL dst, memory mem) 4306 %{ 4307 match(Set dst (LoadL mem)); 4308 4309 ins_cost(125); 4310 format %{ "movq $dst, $mem\t# long" %} 4311 4312 ins_encode %{ 4313 __ movq($dst$$Register, $mem$$Address); 4314 %} 4315 4316 ins_pipe(ialu_reg_mem); // XXX 4317 %} 4318 4319 // Load Range 4320 instruct loadRange(rRegI dst, memory mem) 4321 %{ 4322 match(Set dst (LoadRange mem)); 4323 4324 ins_cost(125); // XXX 4325 format %{ "movl $dst, $mem\t# range" %} 4326 ins_encode %{ 4327 __ movl($dst$$Register, $mem$$Address); 4328 %} 4329 ins_pipe(ialu_reg_mem); 4330 %} 4331 4332 // Load Pointer 4333 instruct loadP(rRegP dst, memory mem) 4334 %{ 4335 match(Set dst (LoadP mem)); 4336 predicate(n->as_Load()->barrier_data() == 0); 4337 4338 ins_cost(125); // XXX 4339 format %{ "movq $dst, $mem\t# ptr" %} 4340 ins_encode %{ 4341 __ movq($dst$$Register, $mem$$Address); 4342 %} 4343 ins_pipe(ialu_reg_mem); // XXX 4344 %} 4345 4346 // Load Compressed Pointer 4347 instruct loadN(rRegN dst, memory mem) 4348 %{ 4349 predicate(n->as_Load()->barrier_data() == 0); 4350 match(Set dst (LoadN mem)); 4351 4352 ins_cost(125); // XXX 4353 format %{ "movl $dst, $mem\t# compressed ptr" %} 4354 ins_encode %{ 4355 __ movl($dst$$Register, $mem$$Address); 4356 %} 4357 ins_pipe(ialu_reg_mem); // XXX 4358 %} 4359 4360 4361 // Load Klass Pointer 4362 instruct loadKlass(rRegP dst, memory mem) 4363 %{ 4364 match(Set dst (LoadKlass mem)); 4365 4366 ins_cost(125); // XXX 4367 format %{ "movq $dst, $mem\t# class" %} 4368 ins_encode %{ 4369 __ movq($dst$$Register, $mem$$Address); 4370 %} 4371 ins_pipe(ialu_reg_mem); // XXX 4372 %} 4373 4374 // Load narrow Klass Pointer 4375 instruct loadNKlass(rRegN dst, memory mem) 4376 %{ 4377 predicate(!UseCompactObjectHeaders); 4378 match(Set dst (LoadNKlass mem)); 4379 4380 ins_cost(125); // XXX 4381 format %{ "movl $dst, $mem\t# compressed klass ptr" %} 4382 ins_encode %{ 4383 __ movl($dst$$Register, $mem$$Address); 4384 %} 4385 ins_pipe(ialu_reg_mem); // XXX 4386 %} 4387 4388 instruct loadNKlassCompactHeaders(rRegN dst, memory mem, rFlagsReg cr) 4389 %{ 4390 predicate(UseCompactObjectHeaders); 4391 match(Set dst (LoadNKlass mem)); 4392 effect(KILL cr); 4393 ins_cost(125); 4394 format %{ 4395 "movl $dst, $mem\t# compressed klass ptr, shifted\n\t" 4396 "shrl $dst, markWord::klass_shift_at_offset" 4397 %} 4398 ins_encode %{ 4399 if (UseAPX) { 4400 __ eshrl($dst$$Register, $mem$$Address, markWord::klass_shift_at_offset, false); 4401 } 4402 else { 4403 __ movl($dst$$Register, $mem$$Address); 4404 __ shrl($dst$$Register, markWord::klass_shift_at_offset); 4405 } 4406 %} 4407 ins_pipe(ialu_reg_mem); 4408 %} 4409 4410 // Load Float 4411 instruct loadF(regF dst, memory mem) 4412 %{ 4413 match(Set dst (LoadF mem)); 4414 4415 ins_cost(145); // XXX 4416 format %{ "movss $dst, $mem\t# float" %} 4417 ins_encode %{ 4418 __ movflt($dst$$XMMRegister, $mem$$Address); 4419 %} 4420 ins_pipe(pipe_slow); // XXX 4421 %} 4422 4423 // Load Double 4424 instruct loadD_partial(regD dst, memory mem) 4425 %{ 4426 predicate(!UseXmmLoadAndClearUpper); 4427 match(Set dst (LoadD mem)); 4428 4429 ins_cost(145); // XXX 4430 format %{ "movlpd $dst, $mem\t# double" %} 4431 ins_encode %{ 4432 __ movdbl($dst$$XMMRegister, $mem$$Address); 4433 %} 4434 ins_pipe(pipe_slow); // XXX 4435 %} 4436 4437 instruct loadD(regD dst, memory mem) 4438 %{ 4439 predicate(UseXmmLoadAndClearUpper); 4440 match(Set dst (LoadD mem)); 4441 4442 ins_cost(145); // XXX 4443 format %{ "movsd $dst, $mem\t# double" %} 4444 ins_encode %{ 4445 __ movdbl($dst$$XMMRegister, $mem$$Address); 4446 %} 4447 ins_pipe(pipe_slow); // XXX 4448 %} 4449 4450 // max = java.lang.Math.max(float a, float b) 4451 instruct maxF_reg(legRegF dst, legRegF a, legRegF b, legRegF tmp, legRegF atmp, legRegF btmp) %{ 4452 predicate(UseAVX > 0 && !VLoopReductions::is_reduction(n)); 4453 match(Set dst (MaxF a b)); 4454 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 4455 format %{ "maxF $dst, $a, $b \t! using $tmp, $atmp and $btmp as TEMP" %} 4456 ins_encode %{ 4457 __ vminmax_fp(Op_MaxV, T_FLOAT, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, Assembler::AVX_128bit); 4458 %} 4459 ins_pipe( pipe_slow ); 4460 %} 4461 4462 instruct maxF_reduction_reg(legRegF dst, legRegF a, legRegF b, legRegF xtmp, rRegI rtmp, rFlagsReg cr) %{ 4463 predicate(UseAVX > 0 && VLoopReductions::is_reduction(n)); 4464 match(Set dst (MaxF a b)); 4465 effect(USE a, USE b, TEMP xtmp, TEMP rtmp, KILL cr); 4466 4467 format %{ "maxF_reduction $dst, $a, $b \t!using $xtmp and $rtmp as TEMP" %} 4468 ins_encode %{ 4469 emit_fp_min_max(masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xtmp$$XMMRegister, $rtmp$$Register, 4470 false /*min*/, true /*single*/); 4471 %} 4472 ins_pipe( pipe_slow ); 4473 %} 4474 4475 // max = java.lang.Math.max(double a, double b) 4476 instruct maxD_reg(legRegD dst, legRegD a, legRegD b, legRegD tmp, legRegD atmp, legRegD btmp) %{ 4477 predicate(UseAVX > 0 && !VLoopReductions::is_reduction(n)); 4478 match(Set dst (MaxD a b)); 4479 effect(USE a, USE b, TEMP atmp, TEMP btmp, TEMP tmp); 4480 format %{ "maxD $dst, $a, $b \t! using $tmp, $atmp and $btmp as TEMP" %} 4481 ins_encode %{ 4482 __ vminmax_fp(Op_MaxV, T_DOUBLE, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, Assembler::AVX_128bit); 4483 %} 4484 ins_pipe( pipe_slow ); 4485 %} 4486 4487 instruct maxD_reduction_reg(legRegD dst, legRegD a, legRegD b, legRegD xtmp, rRegL rtmp, rFlagsReg cr) %{ 4488 predicate(UseAVX > 0 && VLoopReductions::is_reduction(n)); 4489 match(Set dst (MaxD a b)); 4490 effect(USE a, USE b, TEMP xtmp, TEMP rtmp, KILL cr); 4491 4492 format %{ "maxD_reduction $dst, $a, $b \t! using $xtmp and $rtmp as TEMP" %} 4493 ins_encode %{ 4494 emit_fp_min_max(masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xtmp$$XMMRegister, $rtmp$$Register, 4495 false /*min*/, false /*single*/); 4496 %} 4497 ins_pipe( pipe_slow ); 4498 %} 4499 4500 // min = java.lang.Math.min(float a, float b) 4501 instruct minF_reg(legRegF dst, legRegF a, legRegF b, legRegF tmp, legRegF atmp, legRegF btmp) %{ 4502 predicate(UseAVX > 0 && !VLoopReductions::is_reduction(n)); 4503 match(Set dst (MinF a b)); 4504 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 4505 format %{ "minF $dst, $a, $b \t! using $tmp, $atmp and $btmp as TEMP" %} 4506 ins_encode %{ 4507 __ vminmax_fp(Op_MinV, T_FLOAT, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, Assembler::AVX_128bit); 4508 %} 4509 ins_pipe( pipe_slow ); 4510 %} 4511 4512 instruct minF_reduction_reg(legRegF dst, legRegF a, legRegF b, legRegF xtmp, rRegI rtmp, rFlagsReg cr) %{ 4513 predicate(UseAVX > 0 && VLoopReductions::is_reduction(n)); 4514 match(Set dst (MinF a b)); 4515 effect(USE a, USE b, TEMP xtmp, TEMP rtmp, KILL cr); 4516 4517 format %{ "minF_reduction $dst, $a, $b \t! using $xtmp and $rtmp as TEMP" %} 4518 ins_encode %{ 4519 emit_fp_min_max(masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xtmp$$XMMRegister, $rtmp$$Register, 4520 true /*min*/, true /*single*/); 4521 %} 4522 ins_pipe( pipe_slow ); 4523 %} 4524 4525 // min = java.lang.Math.min(double a, double b) 4526 instruct minD_reg(legRegD dst, legRegD a, legRegD b, legRegD tmp, legRegD atmp, legRegD btmp) %{ 4527 predicate(UseAVX > 0 && !VLoopReductions::is_reduction(n)); 4528 match(Set dst (MinD a b)); 4529 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 4530 format %{ "minD $dst, $a, $b \t! using $tmp, $atmp and $btmp as TEMP" %} 4531 ins_encode %{ 4532 __ vminmax_fp(Op_MinV, T_DOUBLE, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, Assembler::AVX_128bit); 4533 %} 4534 ins_pipe( pipe_slow ); 4535 %} 4536 4537 instruct minD_reduction_reg(legRegD dst, legRegD a, legRegD b, legRegD xtmp, rRegL rtmp, rFlagsReg cr) %{ 4538 predicate(UseAVX > 0 && VLoopReductions::is_reduction(n)); 4539 match(Set dst (MinD a b)); 4540 effect(USE a, USE b, TEMP xtmp, TEMP rtmp, KILL cr); 4541 4542 format %{ "maxD_reduction $dst, $a, $b \t! using $xtmp and $rtmp as TEMP" %} 4543 ins_encode %{ 4544 emit_fp_min_max(masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xtmp$$XMMRegister, $rtmp$$Register, 4545 true /*min*/, false /*single*/); 4546 %} 4547 ins_pipe( pipe_slow ); 4548 %} 4549 4550 // Load Effective Address 4551 instruct leaP8(rRegP dst, indOffset8 mem) 4552 %{ 4553 match(Set dst mem); 4554 4555 ins_cost(110); // XXX 4556 format %{ "leaq $dst, $mem\t# ptr 8" %} 4557 ins_encode %{ 4558 __ leaq($dst$$Register, $mem$$Address); 4559 %} 4560 ins_pipe(ialu_reg_reg_fat); 4561 %} 4562 4563 instruct leaP32(rRegP dst, indOffset32 mem) 4564 %{ 4565 match(Set dst mem); 4566 4567 ins_cost(110); 4568 format %{ "leaq $dst, $mem\t# ptr 32" %} 4569 ins_encode %{ 4570 __ leaq($dst$$Register, $mem$$Address); 4571 %} 4572 ins_pipe(ialu_reg_reg_fat); 4573 %} 4574 4575 instruct leaPIdxOff(rRegP dst, indIndexOffset mem) 4576 %{ 4577 match(Set dst mem); 4578 4579 ins_cost(110); 4580 format %{ "leaq $dst, $mem\t# ptr idxoff" %} 4581 ins_encode %{ 4582 __ leaq($dst$$Register, $mem$$Address); 4583 %} 4584 ins_pipe(ialu_reg_reg_fat); 4585 %} 4586 4587 instruct leaPIdxScale(rRegP dst, indIndexScale mem) 4588 %{ 4589 match(Set dst mem); 4590 4591 ins_cost(110); 4592 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 4593 ins_encode %{ 4594 __ leaq($dst$$Register, $mem$$Address); 4595 %} 4596 ins_pipe(ialu_reg_reg_fat); 4597 %} 4598 4599 instruct leaPPosIdxScale(rRegP dst, indPosIndexScale mem) 4600 %{ 4601 match(Set dst mem); 4602 4603 ins_cost(110); 4604 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 4605 ins_encode %{ 4606 __ leaq($dst$$Register, $mem$$Address); 4607 %} 4608 ins_pipe(ialu_reg_reg_fat); 4609 %} 4610 4611 instruct leaPIdxScaleOff(rRegP dst, indIndexScaleOffset mem) 4612 %{ 4613 match(Set dst mem); 4614 4615 ins_cost(110); 4616 format %{ "leaq $dst, $mem\t# ptr idxscaleoff" %} 4617 ins_encode %{ 4618 __ leaq($dst$$Register, $mem$$Address); 4619 %} 4620 ins_pipe(ialu_reg_reg_fat); 4621 %} 4622 4623 instruct leaPPosIdxOff(rRegP dst, indPosIndexOffset mem) 4624 %{ 4625 match(Set dst mem); 4626 4627 ins_cost(110); 4628 format %{ "leaq $dst, $mem\t# ptr posidxoff" %} 4629 ins_encode %{ 4630 __ leaq($dst$$Register, $mem$$Address); 4631 %} 4632 ins_pipe(ialu_reg_reg_fat); 4633 %} 4634 4635 instruct leaPPosIdxScaleOff(rRegP dst, indPosIndexScaleOffset mem) 4636 %{ 4637 match(Set dst mem); 4638 4639 ins_cost(110); 4640 format %{ "leaq $dst, $mem\t# ptr posidxscaleoff" %} 4641 ins_encode %{ 4642 __ leaq($dst$$Register, $mem$$Address); 4643 %} 4644 ins_pipe(ialu_reg_reg_fat); 4645 %} 4646 4647 // Load Effective Address which uses Narrow (32-bits) oop 4648 instruct leaPCompressedOopOffset(rRegP dst, indCompressedOopOffset mem) 4649 %{ 4650 predicate(UseCompressedOops && (CompressedOops::shift() != 0)); 4651 match(Set dst mem); 4652 4653 ins_cost(110); 4654 format %{ "leaq $dst, $mem\t# ptr compressedoopoff32" %} 4655 ins_encode %{ 4656 __ leaq($dst$$Register, $mem$$Address); 4657 %} 4658 ins_pipe(ialu_reg_reg_fat); 4659 %} 4660 4661 instruct leaP8Narrow(rRegP dst, indOffset8Narrow mem) 4662 %{ 4663 predicate(CompressedOops::shift() == 0); 4664 match(Set dst mem); 4665 4666 ins_cost(110); // XXX 4667 format %{ "leaq $dst, $mem\t# ptr off8narrow" %} 4668 ins_encode %{ 4669 __ leaq($dst$$Register, $mem$$Address); 4670 %} 4671 ins_pipe(ialu_reg_reg_fat); 4672 %} 4673 4674 instruct leaP32Narrow(rRegP dst, indOffset32Narrow mem) 4675 %{ 4676 predicate(CompressedOops::shift() == 0); 4677 match(Set dst mem); 4678 4679 ins_cost(110); 4680 format %{ "leaq $dst, $mem\t# ptr off32narrow" %} 4681 ins_encode %{ 4682 __ leaq($dst$$Register, $mem$$Address); 4683 %} 4684 ins_pipe(ialu_reg_reg_fat); 4685 %} 4686 4687 instruct leaPIdxOffNarrow(rRegP dst, indIndexOffsetNarrow mem) 4688 %{ 4689 predicate(CompressedOops::shift() == 0); 4690 match(Set dst mem); 4691 4692 ins_cost(110); 4693 format %{ "leaq $dst, $mem\t# ptr idxoffnarrow" %} 4694 ins_encode %{ 4695 __ leaq($dst$$Register, $mem$$Address); 4696 %} 4697 ins_pipe(ialu_reg_reg_fat); 4698 %} 4699 4700 instruct leaPIdxScaleNarrow(rRegP dst, indIndexScaleNarrow mem) 4701 %{ 4702 predicate(CompressedOops::shift() == 0); 4703 match(Set dst mem); 4704 4705 ins_cost(110); 4706 format %{ "leaq $dst, $mem\t# ptr idxscalenarrow" %} 4707 ins_encode %{ 4708 __ leaq($dst$$Register, $mem$$Address); 4709 %} 4710 ins_pipe(ialu_reg_reg_fat); 4711 %} 4712 4713 instruct leaPIdxScaleOffNarrow(rRegP dst, indIndexScaleOffsetNarrow mem) 4714 %{ 4715 predicate(CompressedOops::shift() == 0); 4716 match(Set dst mem); 4717 4718 ins_cost(110); 4719 format %{ "leaq $dst, $mem\t# ptr idxscaleoffnarrow" %} 4720 ins_encode %{ 4721 __ leaq($dst$$Register, $mem$$Address); 4722 %} 4723 ins_pipe(ialu_reg_reg_fat); 4724 %} 4725 4726 instruct leaPPosIdxOffNarrow(rRegP dst, indPosIndexOffsetNarrow mem) 4727 %{ 4728 predicate(CompressedOops::shift() == 0); 4729 match(Set dst mem); 4730 4731 ins_cost(110); 4732 format %{ "leaq $dst, $mem\t# ptr posidxoffnarrow" %} 4733 ins_encode %{ 4734 __ leaq($dst$$Register, $mem$$Address); 4735 %} 4736 ins_pipe(ialu_reg_reg_fat); 4737 %} 4738 4739 instruct leaPPosIdxScaleOffNarrow(rRegP dst, indPosIndexScaleOffsetNarrow mem) 4740 %{ 4741 predicate(CompressedOops::shift() == 0); 4742 match(Set dst mem); 4743 4744 ins_cost(110); 4745 format %{ "leaq $dst, $mem\t# ptr posidxscaleoffnarrow" %} 4746 ins_encode %{ 4747 __ leaq($dst$$Register, $mem$$Address); 4748 %} 4749 ins_pipe(ialu_reg_reg_fat); 4750 %} 4751 4752 instruct loadConI(rRegI dst, immI src) 4753 %{ 4754 match(Set dst src); 4755 4756 format %{ "movl $dst, $src\t# int" %} 4757 ins_encode %{ 4758 __ movl($dst$$Register, $src$$constant); 4759 %} 4760 ins_pipe(ialu_reg_fat); // XXX 4761 %} 4762 4763 instruct loadConI0(rRegI dst, immI_0 src, rFlagsReg cr) 4764 %{ 4765 match(Set dst src); 4766 effect(KILL cr); 4767 4768 ins_cost(50); 4769 format %{ "xorl $dst, $dst\t# int" %} 4770 ins_encode %{ 4771 __ xorl($dst$$Register, $dst$$Register); 4772 %} 4773 ins_pipe(ialu_reg); 4774 %} 4775 4776 instruct loadConL(rRegL dst, immL src) 4777 %{ 4778 match(Set dst src); 4779 4780 ins_cost(150); 4781 format %{ "movq $dst, $src\t# long" %} 4782 ins_encode %{ 4783 __ mov64($dst$$Register, $src$$constant); 4784 %} 4785 ins_pipe(ialu_reg); 4786 %} 4787 4788 instruct loadConL0(rRegL dst, immL0 src, rFlagsReg cr) 4789 %{ 4790 match(Set dst src); 4791 effect(KILL cr); 4792 4793 ins_cost(50); 4794 format %{ "xorl $dst, $dst\t# long" %} 4795 ins_encode %{ 4796 __ xorl($dst$$Register, $dst$$Register); 4797 %} 4798 ins_pipe(ialu_reg); // XXX 4799 %} 4800 4801 instruct loadConUL32(rRegL dst, immUL32 src) 4802 %{ 4803 match(Set dst src); 4804 4805 ins_cost(60); 4806 format %{ "movl $dst, $src\t# long (unsigned 32-bit)" %} 4807 ins_encode %{ 4808 __ movl($dst$$Register, $src$$constant); 4809 %} 4810 ins_pipe(ialu_reg); 4811 %} 4812 4813 instruct loadConL32(rRegL dst, immL32 src) 4814 %{ 4815 match(Set dst src); 4816 4817 ins_cost(70); 4818 format %{ "movq $dst, $src\t# long (32-bit)" %} 4819 ins_encode %{ 4820 __ movq($dst$$Register, $src$$constant); 4821 %} 4822 ins_pipe(ialu_reg); 4823 %} 4824 4825 instruct loadConP(rRegP dst, immP con) %{ 4826 match(Set dst con); 4827 4828 format %{ "movq $dst, $con\t# ptr" %} 4829 ins_encode %{ 4830 __ mov64($dst$$Register, $con$$constant, $con->constant_reloc(), RELOC_IMM64); 4831 %} 4832 ins_pipe(ialu_reg_fat); // XXX 4833 %} 4834 4835 instruct loadConP0(rRegP dst, immP0 src, rFlagsReg cr) 4836 %{ 4837 match(Set dst src); 4838 effect(KILL cr); 4839 4840 ins_cost(50); 4841 format %{ "xorl $dst, $dst\t# ptr" %} 4842 ins_encode %{ 4843 __ xorl($dst$$Register, $dst$$Register); 4844 %} 4845 ins_pipe(ialu_reg); 4846 %} 4847 4848 instruct loadConP31(rRegP dst, immP31 src, rFlagsReg cr) 4849 %{ 4850 match(Set dst src); 4851 effect(KILL cr); 4852 4853 ins_cost(60); 4854 format %{ "movl $dst, $src\t# ptr (positive 32-bit)" %} 4855 ins_encode %{ 4856 __ movl($dst$$Register, $src$$constant); 4857 %} 4858 ins_pipe(ialu_reg); 4859 %} 4860 4861 instruct loadConF(regF dst, immF con) %{ 4862 match(Set dst con); 4863 ins_cost(125); 4864 format %{ "movss $dst, [$constantaddress]\t# load from constant table: float=$con" %} 4865 ins_encode %{ 4866 __ movflt($dst$$XMMRegister, $constantaddress($con)); 4867 %} 4868 ins_pipe(pipe_slow); 4869 %} 4870 4871 instruct loadConH(regF dst, immH con) %{ 4872 match(Set dst con); 4873 ins_cost(125); 4874 format %{ "movss $dst, [$constantaddress]\t# load from constant table: halffloat=$con" %} 4875 ins_encode %{ 4876 __ movflt($dst$$XMMRegister, $constantaddress($con)); 4877 %} 4878 ins_pipe(pipe_slow); 4879 %} 4880 4881 instruct loadConN0(rRegN dst, immN0 src, rFlagsReg cr) %{ 4882 match(Set dst src); 4883 effect(KILL cr); 4884 format %{ "xorq $dst, $src\t# compressed null pointer" %} 4885 ins_encode %{ 4886 __ xorq($dst$$Register, $dst$$Register); 4887 %} 4888 ins_pipe(ialu_reg); 4889 %} 4890 4891 instruct loadConN(rRegN dst, immN src) %{ 4892 match(Set dst src); 4893 4894 ins_cost(125); 4895 format %{ "movl $dst, $src\t# compressed ptr" %} 4896 ins_encode %{ 4897 address con = (address)$src$$constant; 4898 if (con == nullptr) { 4899 ShouldNotReachHere(); 4900 } else { 4901 __ set_narrow_oop($dst$$Register, (jobject)$src$$constant); 4902 } 4903 %} 4904 ins_pipe(ialu_reg_fat); // XXX 4905 %} 4906 4907 instruct loadConNKlass(rRegN dst, immNKlass src) %{ 4908 match(Set dst src); 4909 4910 ins_cost(125); 4911 format %{ "movl $dst, $src\t# compressed klass ptr" %} 4912 ins_encode %{ 4913 address con = (address)$src$$constant; 4914 if (con == nullptr) { 4915 ShouldNotReachHere(); 4916 } else { 4917 __ set_narrow_klass($dst$$Register, (Klass*)$src$$constant); 4918 } 4919 %} 4920 ins_pipe(ialu_reg_fat); // XXX 4921 %} 4922 4923 instruct loadConF0(regF dst, immF0 src) 4924 %{ 4925 match(Set dst src); 4926 ins_cost(100); 4927 4928 format %{ "xorps $dst, $dst\t# float 0.0" %} 4929 ins_encode %{ 4930 __ xorps($dst$$XMMRegister, $dst$$XMMRegister); 4931 %} 4932 ins_pipe(pipe_slow); 4933 %} 4934 4935 // Use the same format since predicate() can not be used here. 4936 instruct loadConD(regD dst, immD con) %{ 4937 match(Set dst con); 4938 ins_cost(125); 4939 format %{ "movsd $dst, [$constantaddress]\t# load from constant table: double=$con" %} 4940 ins_encode %{ 4941 __ movdbl($dst$$XMMRegister, $constantaddress($con)); 4942 %} 4943 ins_pipe(pipe_slow); 4944 %} 4945 4946 instruct loadConD0(regD dst, immD0 src) 4947 %{ 4948 match(Set dst src); 4949 ins_cost(100); 4950 4951 format %{ "xorpd $dst, $dst\t# double 0.0" %} 4952 ins_encode %{ 4953 __ xorpd($dst$$XMMRegister, $dst$$XMMRegister); 4954 %} 4955 ins_pipe(pipe_slow); 4956 %} 4957 4958 instruct loadSSI(rRegI dst, stackSlotI src) 4959 %{ 4960 match(Set dst src); 4961 4962 ins_cost(125); 4963 format %{ "movl $dst, $src\t# int stk" %} 4964 ins_encode %{ 4965 __ movl($dst$$Register, $src$$Address); 4966 %} 4967 ins_pipe(ialu_reg_mem); 4968 %} 4969 4970 instruct loadSSL(rRegL dst, stackSlotL src) 4971 %{ 4972 match(Set dst src); 4973 4974 ins_cost(125); 4975 format %{ "movq $dst, $src\t# long stk" %} 4976 ins_encode %{ 4977 __ movq($dst$$Register, $src$$Address); 4978 %} 4979 ins_pipe(ialu_reg_mem); 4980 %} 4981 4982 instruct loadSSP(rRegP dst, stackSlotP src) 4983 %{ 4984 match(Set dst src); 4985 4986 ins_cost(125); 4987 format %{ "movq $dst, $src\t# ptr stk" %} 4988 ins_encode %{ 4989 __ movq($dst$$Register, $src$$Address); 4990 %} 4991 ins_pipe(ialu_reg_mem); 4992 %} 4993 4994 instruct loadSSF(regF dst, stackSlotF src) 4995 %{ 4996 match(Set dst src); 4997 4998 ins_cost(125); 4999 format %{ "movss $dst, $src\t# float stk" %} 5000 ins_encode %{ 5001 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 5002 %} 5003 ins_pipe(pipe_slow); // XXX 5004 %} 5005 5006 // Use the same format since predicate() can not be used here. 5007 instruct loadSSD(regD dst, stackSlotD src) 5008 %{ 5009 match(Set dst src); 5010 5011 ins_cost(125); 5012 format %{ "movsd $dst, $src\t# double stk" %} 5013 ins_encode %{ 5014 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 5015 %} 5016 ins_pipe(pipe_slow); // XXX 5017 %} 5018 5019 // Prefetch instructions for allocation. 5020 // Must be safe to execute with invalid address (cannot fault). 5021 5022 instruct prefetchAlloc( memory mem ) %{ 5023 predicate(AllocatePrefetchInstr==3); 5024 match(PrefetchAllocation mem); 5025 ins_cost(125); 5026 5027 format %{ "PREFETCHW $mem\t# Prefetch allocation into level 1 cache and mark modified" %} 5028 ins_encode %{ 5029 __ prefetchw($mem$$Address); 5030 %} 5031 ins_pipe(ialu_mem); 5032 %} 5033 5034 instruct prefetchAllocNTA( memory mem ) %{ 5035 predicate(AllocatePrefetchInstr==0); 5036 match(PrefetchAllocation mem); 5037 ins_cost(125); 5038 5039 format %{ "PREFETCHNTA $mem\t# Prefetch allocation to non-temporal cache for write" %} 5040 ins_encode %{ 5041 __ prefetchnta($mem$$Address); 5042 %} 5043 ins_pipe(ialu_mem); 5044 %} 5045 5046 instruct prefetchAllocT0( memory mem ) %{ 5047 predicate(AllocatePrefetchInstr==1); 5048 match(PrefetchAllocation mem); 5049 ins_cost(125); 5050 5051 format %{ "PREFETCHT0 $mem\t# Prefetch allocation to level 1 and 2 caches for write" %} 5052 ins_encode %{ 5053 __ prefetcht0($mem$$Address); 5054 %} 5055 ins_pipe(ialu_mem); 5056 %} 5057 5058 instruct prefetchAllocT2( memory mem ) %{ 5059 predicate(AllocatePrefetchInstr==2); 5060 match(PrefetchAllocation mem); 5061 ins_cost(125); 5062 5063 format %{ "PREFETCHT2 $mem\t# Prefetch allocation to level 2 cache for write" %} 5064 ins_encode %{ 5065 __ prefetcht2($mem$$Address); 5066 %} 5067 ins_pipe(ialu_mem); 5068 %} 5069 5070 //----------Store Instructions------------------------------------------------- 5071 5072 // Store Byte 5073 instruct storeB(memory mem, rRegI src) 5074 %{ 5075 match(Set mem (StoreB mem src)); 5076 5077 ins_cost(125); // XXX 5078 format %{ "movb $mem, $src\t# byte" %} 5079 ins_encode %{ 5080 __ movb($mem$$Address, $src$$Register); 5081 %} 5082 ins_pipe(ialu_mem_reg); 5083 %} 5084 5085 // Store Char/Short 5086 instruct storeC(memory mem, rRegI src) 5087 %{ 5088 match(Set mem (StoreC mem src)); 5089 5090 ins_cost(125); // XXX 5091 format %{ "movw $mem, $src\t# char/short" %} 5092 ins_encode %{ 5093 __ movw($mem$$Address, $src$$Register); 5094 %} 5095 ins_pipe(ialu_mem_reg); 5096 %} 5097 5098 // Store Integer 5099 instruct storeI(memory mem, rRegI src) 5100 %{ 5101 match(Set mem (StoreI mem src)); 5102 5103 ins_cost(125); // XXX 5104 format %{ "movl $mem, $src\t# int" %} 5105 ins_encode %{ 5106 __ movl($mem$$Address, $src$$Register); 5107 %} 5108 ins_pipe(ialu_mem_reg); 5109 %} 5110 5111 // Store Long 5112 instruct storeL(memory mem, rRegL src) 5113 %{ 5114 match(Set mem (StoreL mem src)); 5115 5116 ins_cost(125); // XXX 5117 format %{ "movq $mem, $src\t# long" %} 5118 ins_encode %{ 5119 __ movq($mem$$Address, $src$$Register); 5120 %} 5121 ins_pipe(ialu_mem_reg); // XXX 5122 %} 5123 5124 // Store Pointer 5125 instruct storeP(memory mem, any_RegP src) 5126 %{ 5127 predicate(n->as_Store()->barrier_data() == 0); 5128 match(Set mem (StoreP mem src)); 5129 5130 ins_cost(125); // XXX 5131 format %{ "movq $mem, $src\t# ptr" %} 5132 ins_encode %{ 5133 __ movq($mem$$Address, $src$$Register); 5134 %} 5135 ins_pipe(ialu_mem_reg); 5136 %} 5137 5138 instruct storeImmP0(memory mem, immP0 zero) 5139 %{ 5140 predicate(UseCompressedOops && (CompressedOops::base() == nullptr) && n->as_Store()->barrier_data() == 0); 5141 match(Set mem (StoreP mem zero)); 5142 5143 ins_cost(125); // XXX 5144 format %{ "movq $mem, R12\t# ptr (R12_heapbase==0)" %} 5145 ins_encode %{ 5146 __ movq($mem$$Address, r12); 5147 %} 5148 ins_pipe(ialu_mem_reg); 5149 %} 5150 5151 // Store Null Pointer, mark word, or other simple pointer constant. 5152 instruct storeImmP(memory mem, immP31 src) 5153 %{ 5154 predicate(n->as_Store()->barrier_data() == 0); 5155 match(Set mem (StoreP mem src)); 5156 5157 ins_cost(150); // XXX 5158 format %{ "movq $mem, $src\t# ptr" %} 5159 ins_encode %{ 5160 __ movq($mem$$Address, $src$$constant); 5161 %} 5162 ins_pipe(ialu_mem_imm); 5163 %} 5164 5165 // Store Compressed Pointer 5166 instruct storeN(memory mem, rRegN src) 5167 %{ 5168 predicate(n->as_Store()->barrier_data() == 0); 5169 match(Set mem (StoreN mem src)); 5170 5171 ins_cost(125); // XXX 5172 format %{ "movl $mem, $src\t# compressed ptr" %} 5173 ins_encode %{ 5174 __ movl($mem$$Address, $src$$Register); 5175 %} 5176 ins_pipe(ialu_mem_reg); 5177 %} 5178 5179 instruct storeNKlass(memory mem, rRegN src) 5180 %{ 5181 match(Set mem (StoreNKlass mem src)); 5182 5183 ins_cost(125); // XXX 5184 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5185 ins_encode %{ 5186 __ movl($mem$$Address, $src$$Register); 5187 %} 5188 ins_pipe(ialu_mem_reg); 5189 %} 5190 5191 instruct storeImmN0(memory mem, immN0 zero) 5192 %{ 5193 predicate(CompressedOops::base() == nullptr && n->as_Store()->barrier_data() == 0); 5194 match(Set mem (StoreN mem zero)); 5195 5196 ins_cost(125); // XXX 5197 format %{ "movl $mem, R12\t# compressed ptr (R12_heapbase==0)" %} 5198 ins_encode %{ 5199 __ movl($mem$$Address, r12); 5200 %} 5201 ins_pipe(ialu_mem_reg); 5202 %} 5203 5204 instruct storeImmN(memory mem, immN src) 5205 %{ 5206 predicate(n->as_Store()->barrier_data() == 0); 5207 match(Set mem (StoreN mem src)); 5208 5209 ins_cost(150); // XXX 5210 format %{ "movl $mem, $src\t# compressed ptr" %} 5211 ins_encode %{ 5212 address con = (address)$src$$constant; 5213 if (con == nullptr) { 5214 __ movl($mem$$Address, 0); 5215 } else { 5216 __ set_narrow_oop($mem$$Address, (jobject)$src$$constant); 5217 } 5218 %} 5219 ins_pipe(ialu_mem_imm); 5220 %} 5221 5222 instruct storeImmNKlass(memory mem, immNKlass src) 5223 %{ 5224 match(Set mem (StoreNKlass mem src)); 5225 5226 ins_cost(150); // XXX 5227 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5228 ins_encode %{ 5229 __ set_narrow_klass($mem$$Address, (Klass*)$src$$constant); 5230 %} 5231 ins_pipe(ialu_mem_imm); 5232 %} 5233 5234 // Store Integer Immediate 5235 instruct storeImmI0(memory mem, immI_0 zero) 5236 %{ 5237 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5238 match(Set mem (StoreI mem zero)); 5239 5240 ins_cost(125); // XXX 5241 format %{ "movl $mem, R12\t# int (R12_heapbase==0)" %} 5242 ins_encode %{ 5243 __ movl($mem$$Address, r12); 5244 %} 5245 ins_pipe(ialu_mem_reg); 5246 %} 5247 5248 instruct storeImmI(memory mem, immI src) 5249 %{ 5250 match(Set mem (StoreI mem src)); 5251 5252 ins_cost(150); 5253 format %{ "movl $mem, $src\t# int" %} 5254 ins_encode %{ 5255 __ movl($mem$$Address, $src$$constant); 5256 %} 5257 ins_pipe(ialu_mem_imm); 5258 %} 5259 5260 // Store Long Immediate 5261 instruct storeImmL0(memory mem, immL0 zero) 5262 %{ 5263 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5264 match(Set mem (StoreL mem zero)); 5265 5266 ins_cost(125); // XXX 5267 format %{ "movq $mem, R12\t# long (R12_heapbase==0)" %} 5268 ins_encode %{ 5269 __ movq($mem$$Address, r12); 5270 %} 5271 ins_pipe(ialu_mem_reg); 5272 %} 5273 5274 instruct storeImmL(memory mem, immL32 src) 5275 %{ 5276 match(Set mem (StoreL mem src)); 5277 5278 ins_cost(150); 5279 format %{ "movq $mem, $src\t# long" %} 5280 ins_encode %{ 5281 __ movq($mem$$Address, $src$$constant); 5282 %} 5283 ins_pipe(ialu_mem_imm); 5284 %} 5285 5286 // Store Short/Char Immediate 5287 instruct storeImmC0(memory mem, immI_0 zero) 5288 %{ 5289 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5290 match(Set mem (StoreC mem zero)); 5291 5292 ins_cost(125); // XXX 5293 format %{ "movw $mem, R12\t# short/char (R12_heapbase==0)" %} 5294 ins_encode %{ 5295 __ movw($mem$$Address, r12); 5296 %} 5297 ins_pipe(ialu_mem_reg); 5298 %} 5299 5300 instruct storeImmI16(memory mem, immI16 src) 5301 %{ 5302 predicate(UseStoreImmI16); 5303 match(Set mem (StoreC mem src)); 5304 5305 ins_cost(150); 5306 format %{ "movw $mem, $src\t# short/char" %} 5307 ins_encode %{ 5308 __ movw($mem$$Address, $src$$constant); 5309 %} 5310 ins_pipe(ialu_mem_imm); 5311 %} 5312 5313 // Store Byte Immediate 5314 instruct storeImmB0(memory mem, immI_0 zero) 5315 %{ 5316 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5317 match(Set mem (StoreB mem zero)); 5318 5319 ins_cost(125); // XXX 5320 format %{ "movb $mem, R12\t# short/char (R12_heapbase==0)" %} 5321 ins_encode %{ 5322 __ movb($mem$$Address, r12); 5323 %} 5324 ins_pipe(ialu_mem_reg); 5325 %} 5326 5327 instruct storeImmB(memory mem, immI8 src) 5328 %{ 5329 match(Set mem (StoreB mem src)); 5330 5331 ins_cost(150); // XXX 5332 format %{ "movb $mem, $src\t# byte" %} 5333 ins_encode %{ 5334 __ movb($mem$$Address, $src$$constant); 5335 %} 5336 ins_pipe(ialu_mem_imm); 5337 %} 5338 5339 // Store Float 5340 instruct storeF(memory mem, regF src) 5341 %{ 5342 match(Set mem (StoreF mem src)); 5343 5344 ins_cost(95); // XXX 5345 format %{ "movss $mem, $src\t# float" %} 5346 ins_encode %{ 5347 __ movflt($mem$$Address, $src$$XMMRegister); 5348 %} 5349 ins_pipe(pipe_slow); // XXX 5350 %} 5351 5352 // Store immediate Float value (it is faster than store from XMM register) 5353 instruct storeF0(memory mem, immF0 zero) 5354 %{ 5355 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5356 match(Set mem (StoreF mem zero)); 5357 5358 ins_cost(25); // XXX 5359 format %{ "movl $mem, R12\t# float 0. (R12_heapbase==0)" %} 5360 ins_encode %{ 5361 __ movl($mem$$Address, r12); 5362 %} 5363 ins_pipe(ialu_mem_reg); 5364 %} 5365 5366 instruct storeF_imm(memory mem, immF src) 5367 %{ 5368 match(Set mem (StoreF mem src)); 5369 5370 ins_cost(50); 5371 format %{ "movl $mem, $src\t# float" %} 5372 ins_encode %{ 5373 __ movl($mem$$Address, jint_cast($src$$constant)); 5374 %} 5375 ins_pipe(ialu_mem_imm); 5376 %} 5377 5378 // Store Double 5379 instruct storeD(memory mem, regD src) 5380 %{ 5381 match(Set mem (StoreD mem src)); 5382 5383 ins_cost(95); // XXX 5384 format %{ "movsd $mem, $src\t# double" %} 5385 ins_encode %{ 5386 __ movdbl($mem$$Address, $src$$XMMRegister); 5387 %} 5388 ins_pipe(pipe_slow); // XXX 5389 %} 5390 5391 // Store immediate double 0.0 (it is faster than store from XMM register) 5392 instruct storeD0_imm(memory mem, immD0 src) 5393 %{ 5394 predicate(!UseCompressedOops || (CompressedOops::base() != nullptr)); 5395 match(Set mem (StoreD mem src)); 5396 5397 ins_cost(50); 5398 format %{ "movq $mem, $src\t# double 0." %} 5399 ins_encode %{ 5400 __ movq($mem$$Address, $src$$constant); 5401 %} 5402 ins_pipe(ialu_mem_imm); 5403 %} 5404 5405 instruct storeD0(memory mem, immD0 zero) 5406 %{ 5407 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5408 match(Set mem (StoreD mem zero)); 5409 5410 ins_cost(25); // XXX 5411 format %{ "movq $mem, R12\t# double 0. (R12_heapbase==0)" %} 5412 ins_encode %{ 5413 __ movq($mem$$Address, r12); 5414 %} 5415 ins_pipe(ialu_mem_reg); 5416 %} 5417 5418 instruct storeSSI(stackSlotI dst, rRegI src) 5419 %{ 5420 match(Set dst src); 5421 5422 ins_cost(100); 5423 format %{ "movl $dst, $src\t# int stk" %} 5424 ins_encode %{ 5425 __ movl($dst$$Address, $src$$Register); 5426 %} 5427 ins_pipe( ialu_mem_reg ); 5428 %} 5429 5430 instruct storeSSL(stackSlotL dst, rRegL src) 5431 %{ 5432 match(Set dst src); 5433 5434 ins_cost(100); 5435 format %{ "movq $dst, $src\t# long stk" %} 5436 ins_encode %{ 5437 __ movq($dst$$Address, $src$$Register); 5438 %} 5439 ins_pipe(ialu_mem_reg); 5440 %} 5441 5442 instruct storeSSP(stackSlotP dst, rRegP src) 5443 %{ 5444 match(Set dst src); 5445 5446 ins_cost(100); 5447 format %{ "movq $dst, $src\t# ptr stk" %} 5448 ins_encode %{ 5449 __ movq($dst$$Address, $src$$Register); 5450 %} 5451 ins_pipe(ialu_mem_reg); 5452 %} 5453 5454 instruct storeSSF(stackSlotF dst, regF src) 5455 %{ 5456 match(Set dst src); 5457 5458 ins_cost(95); // XXX 5459 format %{ "movss $dst, $src\t# float stk" %} 5460 ins_encode %{ 5461 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 5462 %} 5463 ins_pipe(pipe_slow); // XXX 5464 %} 5465 5466 instruct storeSSD(stackSlotD dst, regD src) 5467 %{ 5468 match(Set dst src); 5469 5470 ins_cost(95); // XXX 5471 format %{ "movsd $dst, $src\t# double stk" %} 5472 ins_encode %{ 5473 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 5474 %} 5475 ins_pipe(pipe_slow); // XXX 5476 %} 5477 5478 instruct cacheWB(indirect addr) 5479 %{ 5480 predicate(VM_Version::supports_data_cache_line_flush()); 5481 match(CacheWB addr); 5482 5483 ins_cost(100); 5484 format %{"cache wb $addr" %} 5485 ins_encode %{ 5486 assert($addr->index_position() < 0, "should be"); 5487 assert($addr$$disp == 0, "should be"); 5488 __ cache_wb(Address($addr$$base$$Register, 0)); 5489 %} 5490 ins_pipe(pipe_slow); // XXX 5491 %} 5492 5493 instruct cacheWBPreSync() 5494 %{ 5495 predicate(VM_Version::supports_data_cache_line_flush()); 5496 match(CacheWBPreSync); 5497 5498 ins_cost(100); 5499 format %{"cache wb presync" %} 5500 ins_encode %{ 5501 __ cache_wbsync(true); 5502 %} 5503 ins_pipe(pipe_slow); // XXX 5504 %} 5505 5506 instruct cacheWBPostSync() 5507 %{ 5508 predicate(VM_Version::supports_data_cache_line_flush()); 5509 match(CacheWBPostSync); 5510 5511 ins_cost(100); 5512 format %{"cache wb postsync" %} 5513 ins_encode %{ 5514 __ cache_wbsync(false); 5515 %} 5516 ins_pipe(pipe_slow); // XXX 5517 %} 5518 5519 //----------BSWAP Instructions------------------------------------------------- 5520 instruct bytes_reverse_int(rRegI dst) %{ 5521 match(Set dst (ReverseBytesI dst)); 5522 5523 format %{ "bswapl $dst" %} 5524 ins_encode %{ 5525 __ bswapl($dst$$Register); 5526 %} 5527 ins_pipe( ialu_reg ); 5528 %} 5529 5530 instruct bytes_reverse_long(rRegL dst) %{ 5531 match(Set dst (ReverseBytesL dst)); 5532 5533 format %{ "bswapq $dst" %} 5534 ins_encode %{ 5535 __ bswapq($dst$$Register); 5536 %} 5537 ins_pipe( ialu_reg); 5538 %} 5539 5540 instruct bytes_reverse_unsigned_short(rRegI dst, rFlagsReg cr) %{ 5541 match(Set dst (ReverseBytesUS dst)); 5542 effect(KILL cr); 5543 5544 format %{ "bswapl $dst\n\t" 5545 "shrl $dst,16\n\t" %} 5546 ins_encode %{ 5547 __ bswapl($dst$$Register); 5548 __ shrl($dst$$Register, 16); 5549 %} 5550 ins_pipe( ialu_reg ); 5551 %} 5552 5553 instruct bytes_reverse_short(rRegI dst, rFlagsReg cr) %{ 5554 match(Set dst (ReverseBytesS dst)); 5555 effect(KILL cr); 5556 5557 format %{ "bswapl $dst\n\t" 5558 "sar $dst,16\n\t" %} 5559 ins_encode %{ 5560 __ bswapl($dst$$Register); 5561 __ sarl($dst$$Register, 16); 5562 %} 5563 ins_pipe( ialu_reg ); 5564 %} 5565 5566 //---------- Zeros Count Instructions ------------------------------------------ 5567 5568 instruct countLeadingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 5569 predicate(UseCountLeadingZerosInstruction); 5570 match(Set dst (CountLeadingZerosI src)); 5571 effect(KILL cr); 5572 5573 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 5574 ins_encode %{ 5575 __ lzcntl($dst$$Register, $src$$Register); 5576 %} 5577 ins_pipe(ialu_reg); 5578 %} 5579 5580 instruct countLeadingZerosI_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5581 predicate(UseCountLeadingZerosInstruction); 5582 match(Set dst (CountLeadingZerosI (LoadI src))); 5583 effect(KILL cr); 5584 ins_cost(175); 5585 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 5586 ins_encode %{ 5587 __ lzcntl($dst$$Register, $src$$Address); 5588 %} 5589 ins_pipe(ialu_reg_mem); 5590 %} 5591 5592 instruct countLeadingZerosI_bsr(rRegI dst, rRegI src, rFlagsReg cr) %{ 5593 predicate(!UseCountLeadingZerosInstruction); 5594 match(Set dst (CountLeadingZerosI src)); 5595 effect(KILL cr); 5596 5597 format %{ "bsrl $dst, $src\t# count leading zeros (int)\n\t" 5598 "jnz skip\n\t" 5599 "movl $dst, -1\n" 5600 "skip:\n\t" 5601 "negl $dst\n\t" 5602 "addl $dst, 31" %} 5603 ins_encode %{ 5604 Register Rdst = $dst$$Register; 5605 Register Rsrc = $src$$Register; 5606 Label skip; 5607 __ bsrl(Rdst, Rsrc); 5608 __ jccb(Assembler::notZero, skip); 5609 __ movl(Rdst, -1); 5610 __ bind(skip); 5611 __ negl(Rdst); 5612 __ addl(Rdst, BitsPerInt - 1); 5613 %} 5614 ins_pipe(ialu_reg); 5615 %} 5616 5617 instruct countLeadingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 5618 predicate(UseCountLeadingZerosInstruction); 5619 match(Set dst (CountLeadingZerosL src)); 5620 effect(KILL cr); 5621 5622 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 5623 ins_encode %{ 5624 __ lzcntq($dst$$Register, $src$$Register); 5625 %} 5626 ins_pipe(ialu_reg); 5627 %} 5628 5629 instruct countLeadingZerosL_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5630 predicate(UseCountLeadingZerosInstruction); 5631 match(Set dst (CountLeadingZerosL (LoadL src))); 5632 effect(KILL cr); 5633 ins_cost(175); 5634 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 5635 ins_encode %{ 5636 __ lzcntq($dst$$Register, $src$$Address); 5637 %} 5638 ins_pipe(ialu_reg_mem); 5639 %} 5640 5641 instruct countLeadingZerosL_bsr(rRegI dst, rRegL src, rFlagsReg cr) %{ 5642 predicate(!UseCountLeadingZerosInstruction); 5643 match(Set dst (CountLeadingZerosL src)); 5644 effect(KILL cr); 5645 5646 format %{ "bsrq $dst, $src\t# count leading zeros (long)\n\t" 5647 "jnz skip\n\t" 5648 "movl $dst, -1\n" 5649 "skip:\n\t" 5650 "negl $dst\n\t" 5651 "addl $dst, 63" %} 5652 ins_encode %{ 5653 Register Rdst = $dst$$Register; 5654 Register Rsrc = $src$$Register; 5655 Label skip; 5656 __ bsrq(Rdst, Rsrc); 5657 __ jccb(Assembler::notZero, skip); 5658 __ movl(Rdst, -1); 5659 __ bind(skip); 5660 __ negl(Rdst); 5661 __ addl(Rdst, BitsPerLong - 1); 5662 %} 5663 ins_pipe(ialu_reg); 5664 %} 5665 5666 instruct countTrailingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 5667 predicate(UseCountTrailingZerosInstruction); 5668 match(Set dst (CountTrailingZerosI src)); 5669 effect(KILL cr); 5670 5671 format %{ "tzcntl $dst, $src\t# count trailing zeros (int)" %} 5672 ins_encode %{ 5673 __ tzcntl($dst$$Register, $src$$Register); 5674 %} 5675 ins_pipe(ialu_reg); 5676 %} 5677 5678 instruct countTrailingZerosI_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5679 predicate(UseCountTrailingZerosInstruction); 5680 match(Set dst (CountTrailingZerosI (LoadI src))); 5681 effect(KILL cr); 5682 ins_cost(175); 5683 format %{ "tzcntl $dst, $src\t# count trailing zeros (int)" %} 5684 ins_encode %{ 5685 __ tzcntl($dst$$Register, $src$$Address); 5686 %} 5687 ins_pipe(ialu_reg_mem); 5688 %} 5689 5690 instruct countTrailingZerosI_bsf(rRegI dst, rRegI src, rFlagsReg cr) %{ 5691 predicate(!UseCountTrailingZerosInstruction); 5692 match(Set dst (CountTrailingZerosI src)); 5693 effect(KILL cr); 5694 5695 format %{ "bsfl $dst, $src\t# count trailing zeros (int)\n\t" 5696 "jnz done\n\t" 5697 "movl $dst, 32\n" 5698 "done:" %} 5699 ins_encode %{ 5700 Register Rdst = $dst$$Register; 5701 Label done; 5702 __ bsfl(Rdst, $src$$Register); 5703 __ jccb(Assembler::notZero, done); 5704 __ movl(Rdst, BitsPerInt); 5705 __ bind(done); 5706 %} 5707 ins_pipe(ialu_reg); 5708 %} 5709 5710 instruct countTrailingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 5711 predicate(UseCountTrailingZerosInstruction); 5712 match(Set dst (CountTrailingZerosL src)); 5713 effect(KILL cr); 5714 5715 format %{ "tzcntq $dst, $src\t# count trailing zeros (long)" %} 5716 ins_encode %{ 5717 __ tzcntq($dst$$Register, $src$$Register); 5718 %} 5719 ins_pipe(ialu_reg); 5720 %} 5721 5722 instruct countTrailingZerosL_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5723 predicate(UseCountTrailingZerosInstruction); 5724 match(Set dst (CountTrailingZerosL (LoadL src))); 5725 effect(KILL cr); 5726 ins_cost(175); 5727 format %{ "tzcntq $dst, $src\t# count trailing zeros (long)" %} 5728 ins_encode %{ 5729 __ tzcntq($dst$$Register, $src$$Address); 5730 %} 5731 ins_pipe(ialu_reg_mem); 5732 %} 5733 5734 instruct countTrailingZerosL_bsf(rRegI dst, rRegL src, rFlagsReg cr) %{ 5735 predicate(!UseCountTrailingZerosInstruction); 5736 match(Set dst (CountTrailingZerosL src)); 5737 effect(KILL cr); 5738 5739 format %{ "bsfq $dst, $src\t# count trailing zeros (long)\n\t" 5740 "jnz done\n\t" 5741 "movl $dst, 64\n" 5742 "done:" %} 5743 ins_encode %{ 5744 Register Rdst = $dst$$Register; 5745 Label done; 5746 __ bsfq(Rdst, $src$$Register); 5747 __ jccb(Assembler::notZero, done); 5748 __ movl(Rdst, BitsPerLong); 5749 __ bind(done); 5750 %} 5751 ins_pipe(ialu_reg); 5752 %} 5753 5754 //--------------- Reverse Operation Instructions ---------------- 5755 instruct bytes_reversebit_int(rRegI dst, rRegI src, rRegI rtmp, rFlagsReg cr) %{ 5756 predicate(!VM_Version::supports_gfni()); 5757 match(Set dst (ReverseI src)); 5758 effect(TEMP dst, TEMP rtmp, KILL cr); 5759 format %{ "reverse_int $dst $src\t! using $rtmp as TEMP" %} 5760 ins_encode %{ 5761 __ reverseI($dst$$Register, $src$$Register, xnoreg, xnoreg, $rtmp$$Register); 5762 %} 5763 ins_pipe( ialu_reg ); 5764 %} 5765 5766 instruct bytes_reversebit_int_gfni(rRegI dst, rRegI src, vlRegF xtmp1, vlRegF xtmp2, rRegL rtmp, rFlagsReg cr) %{ 5767 predicate(VM_Version::supports_gfni()); 5768 match(Set dst (ReverseI src)); 5769 effect(TEMP dst, TEMP xtmp1, TEMP xtmp2, TEMP rtmp, KILL cr); 5770 format %{ "reverse_int $dst $src\t! using $rtmp, $xtmp1 and $xtmp2 as TEMP" %} 5771 ins_encode %{ 5772 __ reverseI($dst$$Register, $src$$Register, $xtmp1$$XMMRegister, $xtmp2$$XMMRegister, $rtmp$$Register); 5773 %} 5774 ins_pipe( ialu_reg ); 5775 %} 5776 5777 instruct bytes_reversebit_long(rRegL dst, rRegL src, rRegL rtmp1, rRegL rtmp2, rFlagsReg cr) %{ 5778 predicate(!VM_Version::supports_gfni()); 5779 match(Set dst (ReverseL src)); 5780 effect(TEMP dst, TEMP rtmp1, TEMP rtmp2, KILL cr); 5781 format %{ "reverse_long $dst $src\t! using $rtmp1 and $rtmp2 as TEMP" %} 5782 ins_encode %{ 5783 __ reverseL($dst$$Register, $src$$Register, xnoreg, xnoreg, $rtmp1$$Register, $rtmp2$$Register); 5784 %} 5785 ins_pipe( ialu_reg ); 5786 %} 5787 5788 instruct bytes_reversebit_long_gfni(rRegL dst, rRegL src, vlRegD xtmp1, vlRegD xtmp2, rRegL rtmp, rFlagsReg cr) %{ 5789 predicate(VM_Version::supports_gfni()); 5790 match(Set dst (ReverseL src)); 5791 effect(TEMP dst, TEMP xtmp1, TEMP xtmp2, TEMP rtmp, KILL cr); 5792 format %{ "reverse_long $dst $src\t! using $rtmp, $xtmp1 and $xtmp2 as TEMP" %} 5793 ins_encode %{ 5794 __ reverseL($dst$$Register, $src$$Register, $xtmp1$$XMMRegister, $xtmp2$$XMMRegister, $rtmp$$Register, noreg); 5795 %} 5796 ins_pipe( ialu_reg ); 5797 %} 5798 5799 //---------- Population Count Instructions ------------------------------------- 5800 5801 instruct popCountI(rRegI dst, rRegI src, rFlagsReg cr) %{ 5802 predicate(UsePopCountInstruction); 5803 match(Set dst (PopCountI src)); 5804 effect(KILL cr); 5805 5806 format %{ "popcnt $dst, $src" %} 5807 ins_encode %{ 5808 __ popcntl($dst$$Register, $src$$Register); 5809 %} 5810 ins_pipe(ialu_reg); 5811 %} 5812 5813 instruct popCountI_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 5814 predicate(UsePopCountInstruction); 5815 match(Set dst (PopCountI (LoadI mem))); 5816 effect(KILL cr); 5817 5818 format %{ "popcnt $dst, $mem" %} 5819 ins_encode %{ 5820 __ popcntl($dst$$Register, $mem$$Address); 5821 %} 5822 ins_pipe(ialu_reg); 5823 %} 5824 5825 // Note: Long.bitCount(long) returns an int. 5826 instruct popCountL(rRegI dst, rRegL src, rFlagsReg cr) %{ 5827 predicate(UsePopCountInstruction); 5828 match(Set dst (PopCountL src)); 5829 effect(KILL cr); 5830 5831 format %{ "popcnt $dst, $src" %} 5832 ins_encode %{ 5833 __ popcntq($dst$$Register, $src$$Register); 5834 %} 5835 ins_pipe(ialu_reg); 5836 %} 5837 5838 // Note: Long.bitCount(long) returns an int. 5839 instruct popCountL_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 5840 predicate(UsePopCountInstruction); 5841 match(Set dst (PopCountL (LoadL mem))); 5842 effect(KILL cr); 5843 5844 format %{ "popcnt $dst, $mem" %} 5845 ins_encode %{ 5846 __ popcntq($dst$$Register, $mem$$Address); 5847 %} 5848 ins_pipe(ialu_reg); 5849 %} 5850 5851 5852 //----------MemBar Instructions----------------------------------------------- 5853 // Memory barrier flavors 5854 5855 instruct membar_acquire() 5856 %{ 5857 match(MemBarAcquire); 5858 match(LoadFence); 5859 ins_cost(0); 5860 5861 size(0); 5862 format %{ "MEMBAR-acquire ! (empty encoding)" %} 5863 ins_encode(); 5864 ins_pipe(empty); 5865 %} 5866 5867 instruct membar_acquire_lock() 5868 %{ 5869 match(MemBarAcquireLock); 5870 ins_cost(0); 5871 5872 size(0); 5873 format %{ "MEMBAR-acquire (prior CMPXCHG in FastLock so empty encoding)" %} 5874 ins_encode(); 5875 ins_pipe(empty); 5876 %} 5877 5878 instruct membar_release() 5879 %{ 5880 match(MemBarRelease); 5881 match(StoreFence); 5882 ins_cost(0); 5883 5884 size(0); 5885 format %{ "MEMBAR-release ! (empty encoding)" %} 5886 ins_encode(); 5887 ins_pipe(empty); 5888 %} 5889 5890 instruct membar_release_lock() 5891 %{ 5892 match(MemBarReleaseLock); 5893 ins_cost(0); 5894 5895 size(0); 5896 format %{ "MEMBAR-release (a FastUnlock follows so empty encoding)" %} 5897 ins_encode(); 5898 ins_pipe(empty); 5899 %} 5900 5901 instruct membar_volatile(rFlagsReg cr) %{ 5902 match(MemBarVolatile); 5903 effect(KILL cr); 5904 ins_cost(400); 5905 5906 format %{ 5907 $$template 5908 $$emit$$"lock addl [rsp + #0], 0\t! membar_volatile" 5909 %} 5910 ins_encode %{ 5911 __ membar(Assembler::StoreLoad); 5912 %} 5913 ins_pipe(pipe_slow); 5914 %} 5915 5916 instruct unnecessary_membar_volatile() 5917 %{ 5918 match(MemBarVolatile); 5919 predicate(Matcher::post_store_load_barrier(n)); 5920 ins_cost(0); 5921 5922 size(0); 5923 format %{ "MEMBAR-volatile (unnecessary so empty encoding)" %} 5924 ins_encode(); 5925 ins_pipe(empty); 5926 %} 5927 5928 instruct membar_storestore() %{ 5929 match(MemBarStoreStore); 5930 match(StoreStoreFence); 5931 ins_cost(0); 5932 5933 size(0); 5934 format %{ "MEMBAR-storestore (empty encoding)" %} 5935 ins_encode( ); 5936 ins_pipe(empty); 5937 %} 5938 5939 //----------Move Instructions-------------------------------------------------- 5940 5941 instruct castX2P(rRegP dst, rRegL src) 5942 %{ 5943 match(Set dst (CastX2P src)); 5944 5945 format %{ "movq $dst, $src\t# long->ptr" %} 5946 ins_encode %{ 5947 if ($dst$$reg != $src$$reg) { 5948 __ movptr($dst$$Register, $src$$Register); 5949 } 5950 %} 5951 ins_pipe(ialu_reg_reg); // XXX 5952 %} 5953 5954 instruct castP2X(rRegL dst, rRegP src) 5955 %{ 5956 match(Set dst (CastP2X src)); 5957 5958 format %{ "movq $dst, $src\t# ptr -> long" %} 5959 ins_encode %{ 5960 if ($dst$$reg != $src$$reg) { 5961 __ movptr($dst$$Register, $src$$Register); 5962 } 5963 %} 5964 ins_pipe(ialu_reg_reg); // XXX 5965 %} 5966 5967 // Convert oop into int for vectors alignment masking 5968 instruct convP2I(rRegI dst, rRegP src) 5969 %{ 5970 match(Set dst (ConvL2I (CastP2X src))); 5971 5972 format %{ "movl $dst, $src\t# ptr -> int" %} 5973 ins_encode %{ 5974 __ movl($dst$$Register, $src$$Register); 5975 %} 5976 ins_pipe(ialu_reg_reg); // XXX 5977 %} 5978 5979 // Convert compressed oop into int for vectors alignment masking 5980 // in case of 32bit oops (heap < 4Gb). 5981 instruct convN2I(rRegI dst, rRegN src) 5982 %{ 5983 predicate(CompressedOops::shift() == 0); 5984 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 5985 5986 format %{ "movl $dst, $src\t# compressed ptr -> int" %} 5987 ins_encode %{ 5988 __ movl($dst$$Register, $src$$Register); 5989 %} 5990 ins_pipe(ialu_reg_reg); // XXX 5991 %} 5992 5993 // Convert oop pointer into compressed form 5994 instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{ 5995 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 5996 match(Set dst (EncodeP src)); 5997 effect(KILL cr); 5998 format %{ "encode_heap_oop $dst,$src" %} 5999 ins_encode %{ 6000 Register s = $src$$Register; 6001 Register d = $dst$$Register; 6002 if (s != d) { 6003 __ movq(d, s); 6004 } 6005 __ encode_heap_oop(d); 6006 %} 6007 ins_pipe(ialu_reg_long); 6008 %} 6009 6010 instruct encodeHeapOop_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6011 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 6012 match(Set dst (EncodeP src)); 6013 effect(KILL cr); 6014 format %{ "encode_heap_oop_not_null $dst,$src" %} 6015 ins_encode %{ 6016 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 6017 %} 6018 ins_pipe(ialu_reg_long); 6019 %} 6020 6021 instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{ 6022 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 6023 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 6024 match(Set dst (DecodeN src)); 6025 effect(KILL cr); 6026 format %{ "decode_heap_oop $dst,$src" %} 6027 ins_encode %{ 6028 Register s = $src$$Register; 6029 Register d = $dst$$Register; 6030 if (s != d) { 6031 __ movq(d, s); 6032 } 6033 __ decode_heap_oop(d); 6034 %} 6035 ins_pipe(ialu_reg_long); 6036 %} 6037 6038 instruct decodeHeapOop_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6039 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 6040 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 6041 match(Set dst (DecodeN src)); 6042 effect(KILL cr); 6043 format %{ "decode_heap_oop_not_null $dst,$src" %} 6044 ins_encode %{ 6045 Register s = $src$$Register; 6046 Register d = $dst$$Register; 6047 if (s != d) { 6048 __ decode_heap_oop_not_null(d, s); 6049 } else { 6050 __ decode_heap_oop_not_null(d); 6051 } 6052 %} 6053 ins_pipe(ialu_reg_long); 6054 %} 6055 6056 instruct encodeKlass_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6057 match(Set dst (EncodePKlass src)); 6058 effect(TEMP dst, KILL cr); 6059 format %{ "encode_and_move_klass_not_null $dst,$src" %} 6060 ins_encode %{ 6061 __ encode_and_move_klass_not_null($dst$$Register, $src$$Register); 6062 %} 6063 ins_pipe(ialu_reg_long); 6064 %} 6065 6066 instruct decodeKlass_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6067 match(Set dst (DecodeNKlass src)); 6068 effect(TEMP dst, KILL cr); 6069 format %{ "decode_and_move_klass_not_null $dst,$src" %} 6070 ins_encode %{ 6071 __ decode_and_move_klass_not_null($dst$$Register, $src$$Register); 6072 %} 6073 ins_pipe(ialu_reg_long); 6074 %} 6075 6076 //----------Conditional Move--------------------------------------------------- 6077 // Jump 6078 // dummy instruction for generating temp registers 6079 instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{ 6080 match(Jump (LShiftL switch_val shift)); 6081 ins_cost(350); 6082 predicate(false); 6083 effect(TEMP dest); 6084 6085 format %{ "leaq $dest, [$constantaddress]\n\t" 6086 "jmp [$dest + $switch_val << $shift]\n\t" %} 6087 ins_encode %{ 6088 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6089 // to do that and the compiler is using that register as one it can allocate. 6090 // So we build it all by hand. 6091 // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant); 6092 // ArrayAddress dispatch(table, index); 6093 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant); 6094 __ lea($dest$$Register, $constantaddress); 6095 __ jmp(dispatch); 6096 %} 6097 ins_pipe(pipe_jmp); 6098 %} 6099 6100 instruct jumpXtnd_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{ 6101 match(Jump (AddL (LShiftL switch_val shift) offset)); 6102 ins_cost(350); 6103 effect(TEMP dest); 6104 6105 format %{ "leaq $dest, [$constantaddress]\n\t" 6106 "jmp [$dest + $switch_val << $shift + $offset]\n\t" %} 6107 ins_encode %{ 6108 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6109 // to do that and the compiler is using that register as one it can allocate. 6110 // So we build it all by hand. 6111 // Address index(noreg, switch_reg, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6112 // ArrayAddress dispatch(table, index); 6113 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6114 __ lea($dest$$Register, $constantaddress); 6115 __ jmp(dispatch); 6116 %} 6117 ins_pipe(pipe_jmp); 6118 %} 6119 6120 instruct jumpXtnd(rRegL switch_val, rRegI dest) %{ 6121 match(Jump switch_val); 6122 ins_cost(350); 6123 effect(TEMP dest); 6124 6125 format %{ "leaq $dest, [$constantaddress]\n\t" 6126 "jmp [$dest + $switch_val]\n\t" %} 6127 ins_encode %{ 6128 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6129 // to do that and the compiler is using that register as one it can allocate. 6130 // So we build it all by hand. 6131 // Address index(noreg, switch_reg, Address::times_1); 6132 // ArrayAddress dispatch(table, index); 6133 Address dispatch($dest$$Register, $switch_val$$Register, Address::times_1); 6134 __ lea($dest$$Register, $constantaddress); 6135 __ jmp(dispatch); 6136 %} 6137 ins_pipe(pipe_jmp); 6138 %} 6139 6140 // Conditional move 6141 instruct cmovI_imm_01(rRegI dst, immI_1 src, rFlagsReg cr, cmpOp cop) 6142 %{ 6143 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_int() == 0); 6144 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6145 6146 ins_cost(100); // XXX 6147 format %{ "setbn$cop $dst\t# signed, int" %} 6148 ins_encode %{ 6149 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6150 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6151 %} 6152 ins_pipe(ialu_reg); 6153 %} 6154 6155 instruct cmovI_reg(rRegI dst, rRegI src, rFlagsReg cr, cmpOp cop) 6156 %{ 6157 predicate(!UseAPX); 6158 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6159 6160 ins_cost(200); // XXX 6161 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6162 ins_encode %{ 6163 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6164 %} 6165 ins_pipe(pipe_cmov_reg); 6166 %} 6167 6168 instruct cmovI_reg_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr, cmpOp cop) 6169 %{ 6170 predicate(UseAPX); 6171 match(Set dst (CMoveI (Binary cop cr) (Binary src1 src2))); 6172 6173 ins_cost(200); 6174 format %{ "ecmovl$cop $dst, $src1, $src2\t# signed, int ndd" %} 6175 ins_encode %{ 6176 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6177 %} 6178 ins_pipe(pipe_cmov_reg); 6179 %} 6180 6181 instruct cmovI_imm_01U(rRegI dst, immI_1 src, rFlagsRegU cr, cmpOpU cop) 6182 %{ 6183 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_int() == 0); 6184 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6185 6186 ins_cost(100); // XXX 6187 format %{ "setbn$cop $dst\t# unsigned, int" %} 6188 ins_encode %{ 6189 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6190 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6191 %} 6192 ins_pipe(ialu_reg); 6193 %} 6194 6195 instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{ 6196 predicate(!UseAPX); 6197 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6198 6199 ins_cost(200); // XXX 6200 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6201 ins_encode %{ 6202 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6203 %} 6204 ins_pipe(pipe_cmov_reg); 6205 %} 6206 6207 instruct cmovI_regU_ndd(rRegI dst, cmpOpU cop, rFlagsRegU cr, rRegI src1, rRegI src2) %{ 6208 predicate(UseAPX); 6209 match(Set dst (CMoveI (Binary cop cr) (Binary src1 src2))); 6210 6211 ins_cost(200); 6212 format %{ "ecmovl$cop $dst, $src1, $src2\t# unsigned, int ndd" %} 6213 ins_encode %{ 6214 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6215 %} 6216 ins_pipe(pipe_cmov_reg); 6217 %} 6218 6219 instruct cmovI_imm_01UCF(rRegI dst, immI_1 src, rFlagsRegUCF cr, cmpOpUCF cop) 6220 %{ 6221 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_int() == 0); 6222 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6223 6224 ins_cost(100); // XXX 6225 format %{ "setbn$cop $dst\t# unsigned, int" %} 6226 ins_encode %{ 6227 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6228 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6229 %} 6230 ins_pipe(ialu_reg); 6231 %} 6232 6233 instruct cmovI_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6234 predicate(!UseAPX); 6235 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6236 ins_cost(200); 6237 expand %{ 6238 cmovI_regU(cop, cr, dst, src); 6239 %} 6240 %} 6241 6242 instruct cmovI_regUCF_ndd(rRegI dst, cmpOpUCF cop, rFlagsRegUCF cr, rRegI src1, rRegI src2) %{ 6243 predicate(UseAPX); 6244 match(Set dst (CMoveI (Binary cop cr) (Binary src1 src2))); 6245 ins_cost(200); 6246 format %{ "ecmovl$cop $dst, $src1, $src2\t# unsigned, int ndd" %} 6247 ins_encode %{ 6248 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6249 %} 6250 ins_pipe(pipe_cmov_reg); 6251 %} 6252 6253 instruct cmovI_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6254 predicate(!UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6255 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6256 6257 ins_cost(200); // XXX 6258 format %{ "cmovpl $dst, $src\n\t" 6259 "cmovnel $dst, $src" %} 6260 ins_encode %{ 6261 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6262 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6263 %} 6264 ins_pipe(pipe_cmov_reg); 6265 %} 6266 6267 instruct cmovI_regUCF2_ne_ndd(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegI dst, rRegI src1, rRegI src2) %{ 6268 predicate(UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6269 match(Set dst (CMoveI (Binary cop cr) (Binary src1 src2))); 6270 6271 ins_cost(200); 6272 format %{ "ecmovpl $dst, $src1, $src2\n\t" 6273 "ecmovnel $dst, $src1, $src2" %} 6274 ins_encode %{ 6275 __ ecmovl(Assembler::parity, $dst$$Register, $src1$$Register, $src2$$Register); 6276 __ ecmovl(Assembler::notEqual, $dst$$Register, $src1$$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 6287 ins_cost(200); // XXX 6288 format %{ "cmovpl $dst, $src\n\t" 6289 "cmovnel $dst, $src" %} 6290 ins_encode %{ 6291 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6292 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6293 %} 6294 ins_pipe(pipe_cmov_reg); 6295 %} 6296 6297 // We need this special handling for only eq / neq comparison since NaN == NaN is false, 6298 // and parity flag bit is set if any of the operand is a NaN. 6299 instruct cmovI_regUCF2_eq_ndd(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegI dst, rRegI src1, rRegI src2) %{ 6300 predicate(UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6301 match(Set dst (CMoveI (Binary cop cr) (Binary src1 src2))); 6302 6303 ins_cost(200); 6304 format %{ "ecmovpl $dst, $src1, $src2\n\t" 6305 "ecmovnel $dst, $src1, $src2" %} 6306 ins_encode %{ 6307 __ ecmovl(Assembler::parity, $dst$$Register, $src1$$Register, $src2$$Register); 6308 __ ecmovl(Assembler::notEqual, $dst$$Register, $src1$$Register, $src2$$Register); 6309 %} 6310 ins_pipe(pipe_cmov_reg); 6311 %} 6312 6313 // Conditional move 6314 instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{ 6315 predicate(!UseAPX); 6316 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6317 6318 ins_cost(250); // XXX 6319 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6320 ins_encode %{ 6321 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6322 %} 6323 ins_pipe(pipe_cmov_mem); 6324 %} 6325 6326 // Conditional move 6327 instruct cmovI_rReg_rReg_mem_ndd(rRegI dst, cmpOp cop, rFlagsReg cr, rRegI src1, memory src2) 6328 %{ 6329 predicate(UseAPX); 6330 match(Set dst (CMoveI (Binary cop cr) (Binary src1 (LoadI src2)))); 6331 6332 ins_cost(250); 6333 format %{ "ecmovl$cop $dst, $src1, $src2\t# signed, int ndd" %} 6334 ins_encode %{ 6335 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Address); 6336 %} 6337 ins_pipe(pipe_cmov_mem); 6338 %} 6339 6340 // Conditional move 6341 instruct cmovI_memU(cmpOpU cop, rFlagsRegU cr, rRegI dst, memory src) 6342 %{ 6343 predicate(!UseAPX); 6344 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6345 6346 ins_cost(250); // XXX 6347 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6348 ins_encode %{ 6349 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6350 %} 6351 ins_pipe(pipe_cmov_mem); 6352 %} 6353 6354 instruct cmovI_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, memory src) %{ 6355 predicate(!UseAPX); 6356 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6357 ins_cost(250); 6358 expand %{ 6359 cmovI_memU(cop, cr, dst, src); 6360 %} 6361 %} 6362 6363 instruct cmovI_rReg_rReg_memU_ndd(rRegI dst, cmpOpU cop, rFlagsRegU cr, rRegI src1, memory src2) 6364 %{ 6365 predicate(UseAPX); 6366 match(Set dst (CMoveI (Binary cop cr) (Binary src1 (LoadI src2)))); 6367 6368 ins_cost(250); 6369 format %{ "ecmovl$cop $dst, $src1, $src2\t# unsigned, int ndd" %} 6370 ins_encode %{ 6371 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Address); 6372 %} 6373 ins_pipe(pipe_cmov_mem); 6374 %} 6375 6376 instruct cmovI_rReg_rReg_memUCF_ndd(rRegI dst, cmpOpUCF cop, rFlagsRegUCF cr, rRegI src1, memory src2) 6377 %{ 6378 predicate(UseAPX); 6379 match(Set dst (CMoveI (Binary cop cr) (Binary src1 (LoadI src2)))); 6380 ins_cost(250); 6381 format %{ "ecmovl$cop $dst, $src1, $src2\t# unsigned, int ndd" %} 6382 ins_encode %{ 6383 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Address); 6384 %} 6385 ins_pipe(pipe_cmov_mem); 6386 %} 6387 6388 // Conditional move 6389 instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop) 6390 %{ 6391 predicate(!UseAPX); 6392 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6393 6394 ins_cost(200); // XXX 6395 format %{ "cmovl$cop $dst, $src\t# signed, compressed ptr" %} 6396 ins_encode %{ 6397 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6398 %} 6399 ins_pipe(pipe_cmov_reg); 6400 %} 6401 6402 // Conditional move ndd 6403 instruct cmovN_reg_ndd(rRegN dst, rRegN src1, rRegN src2, rFlagsReg cr, cmpOp cop) 6404 %{ 6405 predicate(UseAPX); 6406 match(Set dst (CMoveN (Binary cop cr) (Binary src1 src2))); 6407 6408 ins_cost(200); 6409 format %{ "ecmovl$cop $dst, $src1, $src2\t# signed, compressed ptr ndd" %} 6410 ins_encode %{ 6411 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6412 %} 6413 ins_pipe(pipe_cmov_reg); 6414 %} 6415 6416 // Conditional move 6417 instruct cmovN_regU(cmpOpU cop, rFlagsRegU cr, rRegN dst, rRegN src) 6418 %{ 6419 predicate(!UseAPX); 6420 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6421 6422 ins_cost(200); // XXX 6423 format %{ "cmovl$cop $dst, $src\t# unsigned, compressed ptr" %} 6424 ins_encode %{ 6425 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6426 %} 6427 ins_pipe(pipe_cmov_reg); 6428 %} 6429 6430 instruct cmovN_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6431 predicate(!UseAPX); 6432 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6433 ins_cost(200); 6434 expand %{ 6435 cmovN_regU(cop, cr, dst, src); 6436 %} 6437 %} 6438 6439 // Conditional move ndd 6440 instruct cmovN_regU_ndd(rRegN dst, cmpOpU cop, rFlagsRegU cr, rRegN src1, rRegN src2) 6441 %{ 6442 predicate(UseAPX); 6443 match(Set dst (CMoveN (Binary cop cr) (Binary src1 src2))); 6444 6445 ins_cost(200); 6446 format %{ "ecmovl$cop $dst, $src1, $src2\t# unsigned, compressed ptr ndd" %} 6447 ins_encode %{ 6448 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6449 %} 6450 ins_pipe(pipe_cmov_reg); 6451 %} 6452 6453 instruct cmovN_regUCF_ndd(rRegN dst, cmpOpUCF cop, rFlagsRegUCF cr, rRegN src1, rRegN src2) %{ 6454 predicate(UseAPX); 6455 match(Set dst (CMoveN (Binary cop cr) (Binary src1 src2))); 6456 ins_cost(200); 6457 format %{ "ecmovl$cop $dst, $src1, $src2\t# unsigned, compressed ptr ndd" %} 6458 ins_encode %{ 6459 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6460 %} 6461 ins_pipe(pipe_cmov_reg); 6462 %} 6463 6464 instruct cmovN_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6465 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6466 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6467 6468 ins_cost(200); // XXX 6469 format %{ "cmovpl $dst, $src\n\t" 6470 "cmovnel $dst, $src" %} 6471 ins_encode %{ 6472 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6473 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6474 %} 6475 ins_pipe(pipe_cmov_reg); 6476 %} 6477 6478 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6479 // inputs of the CMove 6480 instruct cmovN_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6481 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6482 match(Set dst (CMoveN (Binary cop cr) (Binary src dst))); 6483 6484 ins_cost(200); // XXX 6485 format %{ "cmovpl $dst, $src\n\t" 6486 "cmovnel $dst, $src" %} 6487 ins_encode %{ 6488 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6489 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6490 %} 6491 ins_pipe(pipe_cmov_reg); 6492 %} 6493 6494 // Conditional move 6495 instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop) 6496 %{ 6497 predicate(!UseAPX); 6498 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6499 6500 ins_cost(200); // XXX 6501 format %{ "cmovq$cop $dst, $src\t# signed, ptr" %} 6502 ins_encode %{ 6503 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6504 %} 6505 ins_pipe(pipe_cmov_reg); // XXX 6506 %} 6507 6508 // Conditional move ndd 6509 instruct cmovP_reg_ndd(rRegP dst, rRegP src1, rRegP src2, rFlagsReg cr, cmpOp cop) 6510 %{ 6511 predicate(UseAPX); 6512 match(Set dst (CMoveP (Binary cop cr) (Binary src1 src2))); 6513 6514 ins_cost(200); 6515 format %{ "ecmovq$cop $dst, $src1, $src2\t# signed, ptr ndd" %} 6516 ins_encode %{ 6517 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6518 %} 6519 ins_pipe(pipe_cmov_reg); 6520 %} 6521 6522 // Conditional move 6523 instruct cmovP_regU(cmpOpU cop, rFlagsRegU cr, rRegP dst, rRegP src) 6524 %{ 6525 predicate(!UseAPX); 6526 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6527 6528 ins_cost(200); // XXX 6529 format %{ "cmovq$cop $dst, $src\t# unsigned, ptr" %} 6530 ins_encode %{ 6531 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6532 %} 6533 ins_pipe(pipe_cmov_reg); // XXX 6534 %} 6535 6536 // Conditional move ndd 6537 instruct cmovP_regU_ndd(rRegP dst, cmpOpU cop, rFlagsRegU cr, rRegP src1, rRegP src2) 6538 %{ 6539 predicate(UseAPX); 6540 match(Set dst (CMoveP (Binary cop cr) (Binary src1 src2))); 6541 6542 ins_cost(200); 6543 format %{ "ecmovq$cop $dst, $src1, $src2\t# unsigned, ptr ndd" %} 6544 ins_encode %{ 6545 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6546 %} 6547 ins_pipe(pipe_cmov_reg); 6548 %} 6549 6550 instruct cmovP_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6551 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6552 ins_cost(200); 6553 expand %{ 6554 cmovP_regU(cop, cr, dst, src); 6555 %} 6556 %} 6557 6558 instruct cmovP_regUCF_ndd(rRegP dst, cmpOpUCF cop, rFlagsRegUCF cr, rRegP src1, rRegP src2) %{ 6559 match(Set dst (CMoveP (Binary cop cr) (Binary src1 src2))); 6560 ins_cost(200); 6561 format %{ "ecmovq$cop $dst, $src1, $src2\t# unsigned, ptr ndd" %} 6562 ins_encode %{ 6563 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6564 %} 6565 ins_pipe(pipe_cmov_reg); 6566 %} 6567 6568 instruct cmovP_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6569 predicate(!UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6570 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6571 6572 ins_cost(200); // XXX 6573 format %{ "cmovpq $dst, $src\n\t" 6574 "cmovneq $dst, $src" %} 6575 ins_encode %{ 6576 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6577 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6578 %} 6579 ins_pipe(pipe_cmov_reg); 6580 %} 6581 6582 instruct cmovP_regUCF2_ne_ndd(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegP dst, rRegP src1, rRegP src2) %{ 6583 predicate(UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6584 match(Set dst (CMoveP (Binary cop cr) (Binary src1 src2))); 6585 6586 ins_cost(200); 6587 format %{ "ecmovpq $dst, $src1, $src2\n\t" 6588 "ecmovneq $dst, $src1, $src2" %} 6589 ins_encode %{ 6590 __ ecmovq(Assembler::parity, $dst$$Register, $src1$$Register, $src2$$Register); 6591 __ ecmovq(Assembler::notEqual, $dst$$Register, $src1$$Register, $src2$$Register); 6592 %} 6593 ins_pipe(pipe_cmov_reg); 6594 %} 6595 6596 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6597 // inputs of the CMove 6598 instruct cmovP_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6599 predicate(!UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6600 match(Set dst (CMoveP (Binary cop cr) (Binary src dst))); 6601 6602 ins_cost(200); // XXX 6603 format %{ "cmovpq $dst, $src\n\t" 6604 "cmovneq $dst, $src" %} 6605 ins_encode %{ 6606 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6607 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6608 %} 6609 ins_pipe(pipe_cmov_reg); 6610 %} 6611 6612 instruct cmovP_regUCF2_eq_ndd(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegP dst, rRegP src1, rRegP src2) %{ 6613 predicate(UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6614 match(Set dst (CMoveP (Binary cop cr) (Binary src1 src2))); 6615 6616 ins_cost(200); 6617 format %{ "ecmovpq $dst, $src1, $src2\n\t" 6618 "ecmovneq $dst, $src1, $src2" %} 6619 ins_encode %{ 6620 __ ecmovq(Assembler::parity, $dst$$Register, $src1$$Register, $src2$$Register); 6621 __ ecmovq(Assembler::notEqual, $dst$$Register, $src1$$Register, $src2$$Register); 6622 %} 6623 ins_pipe(pipe_cmov_reg); 6624 %} 6625 6626 instruct cmovL_imm_01(rRegL dst, immL1 src, rFlagsReg cr, cmpOp cop) 6627 %{ 6628 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_long() == 0); 6629 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6630 6631 ins_cost(100); // XXX 6632 format %{ "setbn$cop $dst\t# signed, long" %} 6633 ins_encode %{ 6634 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6635 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6636 %} 6637 ins_pipe(ialu_reg); 6638 %} 6639 6640 instruct cmovL_reg(cmpOp cop, rFlagsReg cr, rRegL dst, rRegL src) 6641 %{ 6642 predicate(!UseAPX); 6643 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6644 6645 ins_cost(200); // XXX 6646 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6647 ins_encode %{ 6648 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6649 %} 6650 ins_pipe(pipe_cmov_reg); // XXX 6651 %} 6652 6653 instruct cmovL_reg_ndd(rRegL dst, cmpOp cop, rFlagsReg cr, rRegL src1, rRegL src2) 6654 %{ 6655 predicate(UseAPX); 6656 match(Set dst (CMoveL (Binary cop cr) (Binary src1 src2))); 6657 6658 ins_cost(200); 6659 format %{ "ecmovq$cop $dst, $src1, $src2\t# signed, long ndd" %} 6660 ins_encode %{ 6661 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6662 %} 6663 ins_pipe(pipe_cmov_reg); 6664 %} 6665 6666 instruct cmovL_mem(cmpOp cop, rFlagsReg cr, rRegL dst, memory src) 6667 %{ 6668 predicate(!UseAPX); 6669 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6670 6671 ins_cost(200); // XXX 6672 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6673 ins_encode %{ 6674 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6675 %} 6676 ins_pipe(pipe_cmov_mem); // XXX 6677 %} 6678 6679 instruct cmovL_rReg_rReg_mem_ndd(rRegL dst, cmpOp cop, rFlagsReg cr, rRegL src1, memory src2) 6680 %{ 6681 predicate(UseAPX); 6682 match(Set dst (CMoveL (Binary cop cr) (Binary src1 (LoadL src2)))); 6683 6684 ins_cost(200); 6685 format %{ "ecmovq$cop $dst, $src1, $src2\t# signed, long ndd" %} 6686 ins_encode %{ 6687 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Address); 6688 %} 6689 ins_pipe(pipe_cmov_mem); 6690 %} 6691 6692 instruct cmovL_imm_01U(rRegL dst, immL1 src, rFlagsRegU cr, cmpOpU cop) 6693 %{ 6694 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_long() == 0); 6695 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6696 6697 ins_cost(100); // XXX 6698 format %{ "setbn$cop $dst\t# unsigned, long" %} 6699 ins_encode %{ 6700 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6701 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6702 %} 6703 ins_pipe(ialu_reg); 6704 %} 6705 6706 instruct cmovL_regU(cmpOpU cop, rFlagsRegU cr, rRegL dst, rRegL src) 6707 %{ 6708 predicate(!UseAPX); 6709 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6710 6711 ins_cost(200); // XXX 6712 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 6713 ins_encode %{ 6714 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6715 %} 6716 ins_pipe(pipe_cmov_reg); // XXX 6717 %} 6718 6719 instruct cmovL_regU_ndd(rRegL dst, cmpOpU cop, rFlagsRegU cr, rRegL src1, rRegL src2) 6720 %{ 6721 predicate(UseAPX); 6722 match(Set dst (CMoveL (Binary cop cr) (Binary src1 src2))); 6723 6724 ins_cost(200); 6725 format %{ "ecmovq$cop $dst, $src1, $src2\t# unsigned, long ndd" %} 6726 ins_encode %{ 6727 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6728 %} 6729 ins_pipe(pipe_cmov_reg); 6730 %} 6731 6732 instruct cmovL_imm_01UCF(rRegL dst, immL1 src, rFlagsRegUCF cr, cmpOpUCF cop) 6733 %{ 6734 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_long() == 0); 6735 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6736 6737 ins_cost(100); // XXX 6738 format %{ "setbn$cop $dst\t# unsigned, long" %} 6739 ins_encode %{ 6740 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6741 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6742 %} 6743 ins_pipe(ialu_reg); 6744 %} 6745 6746 instruct cmovL_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6747 predicate(!UseAPX); 6748 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6749 ins_cost(200); 6750 expand %{ 6751 cmovL_regU(cop, cr, dst, src); 6752 %} 6753 %} 6754 6755 instruct cmovL_regUCF_ndd(rRegL dst, cmpOpUCF cop, rFlagsRegUCF cr, rRegL src1, rRegL src2) 6756 %{ 6757 predicate(UseAPX); 6758 match(Set dst (CMoveL (Binary cop cr) (Binary src1 src2))); 6759 ins_cost(200); 6760 format %{ "ecmovq$cop $dst, $src1, $src2\t# unsigned, long ndd" %} 6761 ins_encode %{ 6762 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6763 %} 6764 ins_pipe(pipe_cmov_reg); 6765 %} 6766 6767 instruct cmovL_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6768 predicate(!UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6769 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6770 6771 ins_cost(200); // XXX 6772 format %{ "cmovpq $dst, $src\n\t" 6773 "cmovneq $dst, $src" %} 6774 ins_encode %{ 6775 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6776 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6777 %} 6778 ins_pipe(pipe_cmov_reg); 6779 %} 6780 6781 instruct cmovL_regUCF2_ne_ndd(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegL dst, rRegL src1, rRegL src2) %{ 6782 predicate(UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6783 match(Set dst (CMoveL (Binary cop cr) (Binary src1 src2))); 6784 6785 ins_cost(200); 6786 format %{ "ecmovpq $dst, $src1, $src2\n\t" 6787 "ecmovneq $dst, $src1, $src2" %} 6788 ins_encode %{ 6789 __ ecmovq(Assembler::parity, $dst$$Register, $src1$$Register, $src2$$Register); 6790 __ ecmovq(Assembler::notEqual, $dst$$Register, $src1$$Register, $src2$$Register); 6791 %} 6792 ins_pipe(pipe_cmov_reg); 6793 %} 6794 6795 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6796 // inputs of the CMove 6797 instruct cmovL_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6798 predicate(!UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6799 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6800 6801 ins_cost(200); // XXX 6802 format %{ "cmovpq $dst, $src\n\t" 6803 "cmovneq $dst, $src" %} 6804 ins_encode %{ 6805 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6806 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6807 %} 6808 ins_pipe(pipe_cmov_reg); 6809 %} 6810 6811 instruct cmovL_regUCF2_eq_ndd(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegL dst, rRegL src1, rRegL src2) %{ 6812 predicate(UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6813 match(Set dst (CMoveL (Binary cop cr) (Binary src1 src2))); 6814 6815 ins_cost(200); 6816 format %{ "ecmovpq $dst, $src1, $src2\n\t" 6817 "ecmovneq $dst, $src1, $src2" %} 6818 ins_encode %{ 6819 __ ecmovq(Assembler::parity, $dst$$Register, $src1$$Register, $src2$$Register); 6820 __ ecmovq(Assembler::notEqual, $dst$$Register, $src1$$Register, $src2$$Register); 6821 %} 6822 ins_pipe(pipe_cmov_reg); 6823 %} 6824 6825 instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src) 6826 %{ 6827 predicate(!UseAPX); 6828 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6829 6830 ins_cost(200); // XXX 6831 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 6832 ins_encode %{ 6833 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6834 %} 6835 ins_pipe(pipe_cmov_mem); // XXX 6836 %} 6837 6838 instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{ 6839 predicate(!UseAPX); 6840 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6841 ins_cost(200); 6842 expand %{ 6843 cmovL_memU(cop, cr, dst, src); 6844 %} 6845 %} 6846 6847 instruct cmovL_rReg_rReg_memU_ndd(rRegL dst, cmpOpU cop, rFlagsRegU cr, rRegL src1, memory src2) 6848 %{ 6849 predicate(UseAPX); 6850 match(Set dst (CMoveL (Binary cop cr) (Binary src1 (LoadL src2)))); 6851 6852 ins_cost(200); 6853 format %{ "ecmovq$cop $dst, $src1, $src2\t# unsigned, long ndd" %} 6854 ins_encode %{ 6855 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Address); 6856 %} 6857 ins_pipe(pipe_cmov_mem); 6858 %} 6859 6860 instruct cmovL_rReg_rReg_memUCF_ndd(rRegL dst, cmpOpUCF cop, rFlagsRegUCF cr, rRegL src1, memory src2) 6861 %{ 6862 predicate(UseAPX); 6863 match(Set dst (CMoveL (Binary cop cr) (Binary src1 (LoadL src2)))); 6864 ins_cost(200); 6865 format %{ "ecmovq$cop $dst, $src1, $src2\t# unsigned, long ndd" %} 6866 ins_encode %{ 6867 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Address); 6868 %} 6869 ins_pipe(pipe_cmov_mem); 6870 %} 6871 6872 instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src) 6873 %{ 6874 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6875 6876 ins_cost(200); // XXX 6877 format %{ "jn$cop skip\t# signed cmove float\n\t" 6878 "movss $dst, $src\n" 6879 "skip:" %} 6880 ins_encode %{ 6881 Label Lskip; 6882 // Invert sense of branch from sense of CMOV 6883 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6884 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 6885 __ bind(Lskip); 6886 %} 6887 ins_pipe(pipe_slow); 6888 %} 6889 6890 instruct cmovF_regU(cmpOpU cop, rFlagsRegU cr, regF dst, regF src) 6891 %{ 6892 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6893 6894 ins_cost(200); // XXX 6895 format %{ "jn$cop skip\t# unsigned cmove float\n\t" 6896 "movss $dst, $src\n" 6897 "skip:" %} 6898 ins_encode %{ 6899 Label Lskip; 6900 // Invert sense of branch from sense of CMOV 6901 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6902 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 6903 __ bind(Lskip); 6904 %} 6905 ins_pipe(pipe_slow); 6906 %} 6907 6908 instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{ 6909 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6910 ins_cost(200); 6911 expand %{ 6912 cmovF_regU(cop, cr, dst, src); 6913 %} 6914 %} 6915 6916 instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src) 6917 %{ 6918 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6919 6920 ins_cost(200); // XXX 6921 format %{ "jn$cop skip\t# signed cmove double\n\t" 6922 "movsd $dst, $src\n" 6923 "skip:" %} 6924 ins_encode %{ 6925 Label Lskip; 6926 // Invert sense of branch from sense of CMOV 6927 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6928 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 6929 __ bind(Lskip); 6930 %} 6931 ins_pipe(pipe_slow); 6932 %} 6933 6934 instruct cmovD_regU(cmpOpU cop, rFlagsRegU cr, regD dst, regD src) 6935 %{ 6936 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6937 6938 ins_cost(200); // XXX 6939 format %{ "jn$cop skip\t# unsigned cmove double\n\t" 6940 "movsd $dst, $src\n" 6941 "skip:" %} 6942 ins_encode %{ 6943 Label Lskip; 6944 // Invert sense of branch from sense of CMOV 6945 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6946 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 6947 __ bind(Lskip); 6948 %} 6949 ins_pipe(pipe_slow); 6950 %} 6951 6952 instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{ 6953 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6954 ins_cost(200); 6955 expand %{ 6956 cmovD_regU(cop, cr, dst, src); 6957 %} 6958 %} 6959 6960 //----------Arithmetic Instructions-------------------------------------------- 6961 //----------Addition Instructions---------------------------------------------- 6962 6963 instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 6964 %{ 6965 predicate(!UseAPX); 6966 match(Set dst (AddI dst src)); 6967 effect(KILL cr); 6968 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 6969 format %{ "addl $dst, $src\t# int" %} 6970 ins_encode %{ 6971 __ addl($dst$$Register, $src$$Register); 6972 %} 6973 ins_pipe(ialu_reg_reg); 6974 %} 6975 6976 instruct addI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr) 6977 %{ 6978 predicate(UseAPX); 6979 match(Set dst (AddI src1 src2)); 6980 effect(KILL cr); 6981 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 6982 6983 format %{ "eaddl $dst, $src1, $src2\t# int ndd" %} 6984 ins_encode %{ 6985 __ eaddl($dst$$Register, $src1$$Register, $src2$$Register, false); 6986 %} 6987 ins_pipe(ialu_reg_reg); 6988 %} 6989 6990 instruct addI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 6991 %{ 6992 predicate(!UseAPX); 6993 match(Set dst (AddI dst src)); 6994 effect(KILL cr); 6995 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); 6996 6997 format %{ "addl $dst, $src\t# int" %} 6998 ins_encode %{ 6999 __ addl($dst$$Register, $src$$constant); 7000 %} 7001 ins_pipe( ialu_reg ); 7002 %} 7003 7004 instruct addI_rReg_rReg_imm_ndd(rRegI dst, rRegI src1, immI src2, rFlagsReg cr) 7005 %{ 7006 predicate(UseAPX); 7007 match(Set dst (AddI src1 src2)); 7008 effect(KILL cr); 7009 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); 7010 7011 format %{ "eaddl $dst, $src1, $src2\t# int ndd" %} 7012 ins_encode %{ 7013 __ eaddl($dst$$Register, $src1$$Register, $src2$$constant, false); 7014 %} 7015 ins_pipe( ialu_reg ); 7016 %} 7017 7018 instruct addI_rReg_mem_imm_ndd(rRegI dst, memory src1, immI src2, rFlagsReg cr) 7019 %{ 7020 predicate(UseAPX); 7021 match(Set dst (AddI (LoadI src1) src2)); 7022 effect(KILL cr); 7023 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); 7024 7025 format %{ "eaddl $dst, $src1, $src2\t# int ndd" %} 7026 ins_encode %{ 7027 __ eaddl($dst$$Register, $src1$$Address, $src2$$constant, false); 7028 %} 7029 ins_pipe( ialu_reg ); 7030 %} 7031 7032 instruct addI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 7033 %{ 7034 predicate(!UseAPX); 7035 match(Set dst (AddI dst (LoadI src))); 7036 effect(KILL cr); 7037 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); 7038 7039 ins_cost(150); // XXX 7040 format %{ "addl $dst, $src\t# int" %} 7041 ins_encode %{ 7042 __ addl($dst$$Register, $src$$Address); 7043 %} 7044 ins_pipe(ialu_reg_mem); 7045 %} 7046 7047 instruct addI_rReg_mem_rReg_ndd(rRegI dst, memory src1, rRegI src2, rFlagsReg cr) 7048 %{ 7049 predicate(UseAPX); 7050 match(Set dst (AddI (LoadI src1) src2)); 7051 effect(KILL cr); 7052 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); 7053 7054 ins_cost(150); 7055 format %{ "eaddl $dst, $src1, $src2\t# int ndd" %} 7056 ins_encode %{ 7057 __ eaddl($dst$$Register, $src1$$Address, $src2$$Register, false); 7058 %} 7059 ins_pipe(ialu_reg_mem); 7060 %} 7061 7062 instruct addI_rReg_rReg_mem_ndd(rRegI dst, rRegI src1, memory src2, rFlagsReg cr) 7063 %{ 7064 predicate(UseAPX); 7065 match(Set dst (AddI src1 (LoadI src2))); 7066 effect(KILL cr); 7067 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); 7068 7069 ins_cost(150); 7070 format %{ "eaddl $dst, $src1, $src2\t# int ndd" %} 7071 ins_encode %{ 7072 __ eaddl($dst$$Register, $src1$$Register, $src2$$Address, false); 7073 %} 7074 ins_pipe(ialu_reg_mem); 7075 %} 7076 7077 instruct addI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 7078 %{ 7079 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7080 effect(KILL cr); 7081 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); 7082 7083 ins_cost(150); // XXX 7084 format %{ "addl $dst, $src\t# int" %} 7085 ins_encode %{ 7086 __ addl($dst$$Address, $src$$Register); 7087 %} 7088 ins_pipe(ialu_mem_reg); 7089 %} 7090 7091 instruct addI_mem_imm(memory dst, immI src, rFlagsReg cr) 7092 %{ 7093 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7094 effect(KILL cr); 7095 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); 7096 7097 7098 ins_cost(125); // XXX 7099 format %{ "addl $dst, $src\t# int" %} 7100 ins_encode %{ 7101 __ addl($dst$$Address, $src$$constant); 7102 %} 7103 ins_pipe(ialu_mem_imm); 7104 %} 7105 7106 instruct incI_rReg(rRegI dst, immI_1 src, rFlagsReg cr) 7107 %{ 7108 predicate(!UseAPX && UseIncDec); 7109 match(Set dst (AddI dst src)); 7110 effect(KILL cr); 7111 7112 format %{ "incl $dst\t# int" %} 7113 ins_encode %{ 7114 __ incrementl($dst$$Register); 7115 %} 7116 ins_pipe(ialu_reg); 7117 %} 7118 7119 instruct incI_rReg_ndd(rRegI dst, rRegI src, immI_1 val, rFlagsReg cr) 7120 %{ 7121 predicate(UseAPX && UseIncDec); 7122 match(Set dst (AddI src val)); 7123 effect(KILL cr); 7124 7125 format %{ "eincl $dst, $src\t# int ndd" %} 7126 ins_encode %{ 7127 __ eincl($dst$$Register, $src$$Register, false); 7128 %} 7129 ins_pipe(ialu_reg); 7130 %} 7131 7132 instruct incI_rReg_mem_ndd(rRegI dst, memory src, immI_1 val, rFlagsReg cr) 7133 %{ 7134 predicate(UseAPX && UseIncDec); 7135 match(Set dst (AddI (LoadI src) val)); 7136 effect(KILL cr); 7137 7138 format %{ "eincl $dst, $src\t# int ndd" %} 7139 ins_encode %{ 7140 __ eincl($dst$$Register, $src$$Address, false); 7141 %} 7142 ins_pipe(ialu_reg); 7143 %} 7144 7145 instruct incI_mem(memory dst, immI_1 src, rFlagsReg cr) 7146 %{ 7147 predicate(UseIncDec); 7148 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7149 effect(KILL cr); 7150 7151 ins_cost(125); // XXX 7152 format %{ "incl $dst\t# int" %} 7153 ins_encode %{ 7154 __ incrementl($dst$$Address); 7155 %} 7156 ins_pipe(ialu_mem_imm); 7157 %} 7158 7159 // XXX why does that use AddI 7160 instruct decI_rReg(rRegI dst, immI_M1 src, rFlagsReg cr) 7161 %{ 7162 predicate(!UseAPX && UseIncDec); 7163 match(Set dst (AddI dst src)); 7164 effect(KILL cr); 7165 7166 format %{ "decl $dst\t# int" %} 7167 ins_encode %{ 7168 __ decrementl($dst$$Register); 7169 %} 7170 ins_pipe(ialu_reg); 7171 %} 7172 7173 instruct decI_rReg_ndd(rRegI dst, rRegI src, immI_M1 val, rFlagsReg cr) 7174 %{ 7175 predicate(UseAPX && UseIncDec); 7176 match(Set dst (AddI src val)); 7177 effect(KILL cr); 7178 7179 format %{ "edecl $dst, $src\t# int ndd" %} 7180 ins_encode %{ 7181 __ edecl($dst$$Register, $src$$Register, false); 7182 %} 7183 ins_pipe(ialu_reg); 7184 %} 7185 7186 instruct decI_rReg_mem_ndd(rRegI dst, memory src, immI_M1 val, rFlagsReg cr) 7187 %{ 7188 predicate(UseAPX && UseIncDec); 7189 match(Set dst (AddI (LoadI src) val)); 7190 effect(KILL cr); 7191 7192 format %{ "edecl $dst, $src\t# int ndd" %} 7193 ins_encode %{ 7194 __ edecl($dst$$Register, $src$$Address, false); 7195 %} 7196 ins_pipe(ialu_reg); 7197 %} 7198 7199 // XXX why does that use AddI 7200 instruct decI_mem(memory dst, immI_M1 src, rFlagsReg cr) 7201 %{ 7202 predicate(UseIncDec); 7203 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7204 effect(KILL cr); 7205 7206 ins_cost(125); // XXX 7207 format %{ "decl $dst\t# int" %} 7208 ins_encode %{ 7209 __ decrementl($dst$$Address); 7210 %} 7211 ins_pipe(ialu_mem_imm); 7212 %} 7213 7214 instruct leaI_rReg_immI2_immI(rRegI dst, rRegI index, immI2 scale, immI disp) 7215 %{ 7216 predicate(VM_Version::supports_fast_2op_lea()); 7217 match(Set dst (AddI (LShiftI index scale) disp)); 7218 7219 format %{ "leal $dst, [$index << $scale + $disp]\t# int" %} 7220 ins_encode %{ 7221 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 7222 __ leal($dst$$Register, Address(noreg, $index$$Register, scale, $disp$$constant)); 7223 %} 7224 ins_pipe(ialu_reg_reg); 7225 %} 7226 7227 instruct leaI_rReg_rReg_immI(rRegI dst, rRegI base, rRegI index, immI disp) 7228 %{ 7229 predicate(VM_Version::supports_fast_3op_lea()); 7230 match(Set dst (AddI (AddI base index) disp)); 7231 7232 format %{ "leal $dst, [$base + $index + $disp]\t# int" %} 7233 ins_encode %{ 7234 __ leal($dst$$Register, Address($base$$Register, $index$$Register, Address::times_1, $disp$$constant)); 7235 %} 7236 ins_pipe(ialu_reg_reg); 7237 %} 7238 7239 instruct leaI_rReg_rReg_immI2(rRegI dst, no_rbp_r13_RegI base, rRegI index, immI2 scale) 7240 %{ 7241 predicate(VM_Version::supports_fast_2op_lea()); 7242 match(Set dst (AddI base (LShiftI index scale))); 7243 7244 format %{ "leal $dst, [$base + $index << $scale]\t# int" %} 7245 ins_encode %{ 7246 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 7247 __ leal($dst$$Register, Address($base$$Register, $index$$Register, scale)); 7248 %} 7249 ins_pipe(ialu_reg_reg); 7250 %} 7251 7252 instruct leaI_rReg_rReg_immI2_immI(rRegI dst, rRegI base, rRegI index, immI2 scale, immI disp) 7253 %{ 7254 predicate(VM_Version::supports_fast_3op_lea()); 7255 match(Set dst (AddI (AddI base (LShiftI index scale)) disp)); 7256 7257 format %{ "leal $dst, [$base + $index << $scale + $disp]\t# int" %} 7258 ins_encode %{ 7259 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 7260 __ leal($dst$$Register, Address($base$$Register, $index$$Register, scale, $disp$$constant)); 7261 %} 7262 ins_pipe(ialu_reg_reg); 7263 %} 7264 7265 instruct addL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7266 %{ 7267 predicate(!UseAPX); 7268 match(Set dst (AddL dst src)); 7269 effect(KILL cr); 7270 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); 7271 7272 format %{ "addq $dst, $src\t# long" %} 7273 ins_encode %{ 7274 __ addq($dst$$Register, $src$$Register); 7275 %} 7276 ins_pipe(ialu_reg_reg); 7277 %} 7278 7279 instruct addL_rReg_ndd(rRegL dst, rRegL src1, rRegL src2, rFlagsReg cr) 7280 %{ 7281 predicate(UseAPX); 7282 match(Set dst (AddL src1 src2)); 7283 effect(KILL cr); 7284 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); 7285 7286 format %{ "eaddq $dst, $src1, $src2\t# long ndd" %} 7287 ins_encode %{ 7288 __ eaddq($dst$$Register, $src1$$Register, $src2$$Register, false); 7289 %} 7290 ins_pipe(ialu_reg_reg); 7291 %} 7292 7293 instruct addL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 7294 %{ 7295 predicate(!UseAPX); 7296 match(Set dst (AddL dst src)); 7297 effect(KILL cr); 7298 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); 7299 7300 format %{ "addq $dst, $src\t# long" %} 7301 ins_encode %{ 7302 __ addq($dst$$Register, $src$$constant); 7303 %} 7304 ins_pipe( ialu_reg ); 7305 %} 7306 7307 instruct addL_rReg_rReg_imm_ndd(rRegL dst, rRegL src1, immL32 src2, rFlagsReg cr) 7308 %{ 7309 predicate(UseAPX); 7310 match(Set dst (AddL src1 src2)); 7311 effect(KILL cr); 7312 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); 7313 7314 format %{ "eaddq $dst, $src1, $src2\t# long ndd" %} 7315 ins_encode %{ 7316 __ eaddq($dst$$Register, $src1$$Register, $src2$$constant, false); 7317 %} 7318 ins_pipe( ialu_reg ); 7319 %} 7320 7321 instruct addL_rReg_mem_imm_ndd(rRegL dst, memory src1, immL32 src2, rFlagsReg cr) 7322 %{ 7323 predicate(UseAPX); 7324 match(Set dst (AddL (LoadL src1) src2)); 7325 effect(KILL cr); 7326 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); 7327 7328 format %{ "eaddq $dst, $src1, $src2\t# long ndd" %} 7329 ins_encode %{ 7330 __ eaddq($dst$$Register, $src1$$Address, $src2$$constant, false); 7331 %} 7332 ins_pipe( ialu_reg ); 7333 %} 7334 7335 instruct addL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 7336 %{ 7337 predicate(!UseAPX); 7338 match(Set dst (AddL dst (LoadL src))); 7339 effect(KILL cr); 7340 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); 7341 7342 ins_cost(150); // XXX 7343 format %{ "addq $dst, $src\t# long" %} 7344 ins_encode %{ 7345 __ addq($dst$$Register, $src$$Address); 7346 %} 7347 ins_pipe(ialu_reg_mem); 7348 %} 7349 7350 instruct addL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr) 7351 %{ 7352 predicate(UseAPX); 7353 match(Set dst (AddL src1 (LoadL src2))); 7354 effect(KILL cr); 7355 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); 7356 7357 ins_cost(150); 7358 format %{ "eaddq $dst, $src1, $src2\t# long ndd" %} 7359 ins_encode %{ 7360 __ eaddq($dst$$Register, $src1$$Register, $src2$$Address, false); 7361 %} 7362 ins_pipe(ialu_reg_mem); 7363 %} 7364 7365 instruct addL_rReg_mem_rReg_ndd(rRegL dst, memory src1, rRegL src2, rFlagsReg cr) 7366 %{ 7367 predicate(UseAPX); 7368 match(Set dst (AddL (LoadL src1) src2)); 7369 effect(KILL cr); 7370 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); 7371 7372 ins_cost(150); 7373 format %{ "eaddq $dst, $src1, $src2\t# long ndd" %} 7374 ins_encode %{ 7375 __ eaddq($dst$$Register, $src1$$Address, $src2$$Register, false); 7376 %} 7377 ins_pipe(ialu_reg_mem); 7378 %} 7379 7380 instruct addL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 7381 %{ 7382 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7383 effect(KILL cr); 7384 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); 7385 7386 ins_cost(150); // XXX 7387 format %{ "addq $dst, $src\t# long" %} 7388 ins_encode %{ 7389 __ addq($dst$$Address, $src$$Register); 7390 %} 7391 ins_pipe(ialu_mem_reg); 7392 %} 7393 7394 instruct addL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 7395 %{ 7396 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7397 effect(KILL cr); 7398 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); 7399 7400 ins_cost(125); // XXX 7401 format %{ "addq $dst, $src\t# long" %} 7402 ins_encode %{ 7403 __ addq($dst$$Address, $src$$constant); 7404 %} 7405 ins_pipe(ialu_mem_imm); 7406 %} 7407 7408 instruct incL_rReg(rRegL dst, immL1 src, rFlagsReg cr) 7409 %{ 7410 predicate(!UseAPX && UseIncDec); 7411 match(Set dst (AddL dst src)); 7412 effect(KILL cr); 7413 7414 format %{ "incq $dst\t# long" %} 7415 ins_encode %{ 7416 __ incrementq($dst$$Register); 7417 %} 7418 ins_pipe(ialu_reg); 7419 %} 7420 7421 instruct incL_rReg_ndd(rRegL dst, rRegI src, immL1 val, rFlagsReg cr) 7422 %{ 7423 predicate(UseAPX && UseIncDec); 7424 match(Set dst (AddL src val)); 7425 effect(KILL cr); 7426 7427 format %{ "eincq $dst, $src\t# long ndd" %} 7428 ins_encode %{ 7429 __ eincq($dst$$Register, $src$$Register, false); 7430 %} 7431 ins_pipe(ialu_reg); 7432 %} 7433 7434 instruct incL_rReg_mem_ndd(rRegL dst, memory src, immL1 val, rFlagsReg cr) 7435 %{ 7436 predicate(UseAPX && UseIncDec); 7437 match(Set dst (AddL (LoadL src) val)); 7438 effect(KILL cr); 7439 7440 format %{ "eincq $dst, $src\t# long ndd" %} 7441 ins_encode %{ 7442 __ eincq($dst$$Register, $src$$Address, false); 7443 %} 7444 ins_pipe(ialu_reg); 7445 %} 7446 7447 instruct incL_mem(memory dst, immL1 src, rFlagsReg cr) 7448 %{ 7449 predicate(UseIncDec); 7450 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7451 effect(KILL cr); 7452 7453 ins_cost(125); // XXX 7454 format %{ "incq $dst\t# long" %} 7455 ins_encode %{ 7456 __ incrementq($dst$$Address); 7457 %} 7458 ins_pipe(ialu_mem_imm); 7459 %} 7460 7461 // XXX why does that use AddL 7462 instruct decL_rReg(rRegL dst, immL_M1 src, rFlagsReg cr) 7463 %{ 7464 predicate(!UseAPX && UseIncDec); 7465 match(Set dst (AddL dst src)); 7466 effect(KILL cr); 7467 7468 format %{ "decq $dst\t# long" %} 7469 ins_encode %{ 7470 __ decrementq($dst$$Register); 7471 %} 7472 ins_pipe(ialu_reg); 7473 %} 7474 7475 instruct decL_rReg_ndd(rRegL dst, rRegL src, immL_M1 val, rFlagsReg cr) 7476 %{ 7477 predicate(UseAPX && UseIncDec); 7478 match(Set dst (AddL src val)); 7479 effect(KILL cr); 7480 7481 format %{ "edecq $dst, $src\t# long ndd" %} 7482 ins_encode %{ 7483 __ edecq($dst$$Register, $src$$Register, false); 7484 %} 7485 ins_pipe(ialu_reg); 7486 %} 7487 7488 instruct decL_rReg_mem_ndd(rRegL dst, memory src, immL_M1 val, rFlagsReg cr) 7489 %{ 7490 predicate(UseAPX && UseIncDec); 7491 match(Set dst (AddL (LoadL src) val)); 7492 effect(KILL cr); 7493 7494 format %{ "edecq $dst, $src\t# long ndd" %} 7495 ins_encode %{ 7496 __ edecq($dst$$Register, $src$$Address, false); 7497 %} 7498 ins_pipe(ialu_reg); 7499 %} 7500 7501 // XXX why does that use AddL 7502 instruct decL_mem(memory dst, immL_M1 src, rFlagsReg cr) 7503 %{ 7504 predicate(UseIncDec); 7505 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7506 effect(KILL cr); 7507 7508 ins_cost(125); // XXX 7509 format %{ "decq $dst\t# long" %} 7510 ins_encode %{ 7511 __ decrementq($dst$$Address); 7512 %} 7513 ins_pipe(ialu_mem_imm); 7514 %} 7515 7516 instruct leaL_rReg_immI2_immL32(rRegL dst, rRegL index, immI2 scale, immL32 disp) 7517 %{ 7518 predicate(VM_Version::supports_fast_2op_lea()); 7519 match(Set dst (AddL (LShiftL index scale) disp)); 7520 7521 format %{ "leaq $dst, [$index << $scale + $disp]\t# long" %} 7522 ins_encode %{ 7523 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 7524 __ leaq($dst$$Register, Address(noreg, $index$$Register, scale, $disp$$constant)); 7525 %} 7526 ins_pipe(ialu_reg_reg); 7527 %} 7528 7529 instruct leaL_rReg_rReg_immL32(rRegL dst, rRegL base, rRegL index, immL32 disp) 7530 %{ 7531 predicate(VM_Version::supports_fast_3op_lea()); 7532 match(Set dst (AddL (AddL base index) disp)); 7533 7534 format %{ "leaq $dst, [$base + $index + $disp]\t# long" %} 7535 ins_encode %{ 7536 __ leaq($dst$$Register, Address($base$$Register, $index$$Register, Address::times_1, $disp$$constant)); 7537 %} 7538 ins_pipe(ialu_reg_reg); 7539 %} 7540 7541 instruct leaL_rReg_rReg_immI2(rRegL dst, no_rbp_r13_RegL base, rRegL index, immI2 scale) 7542 %{ 7543 predicate(VM_Version::supports_fast_2op_lea()); 7544 match(Set dst (AddL base (LShiftL index scale))); 7545 7546 format %{ "leaq $dst, [$base + $index << $scale]\t# long" %} 7547 ins_encode %{ 7548 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 7549 __ leaq($dst$$Register, Address($base$$Register, $index$$Register, scale)); 7550 %} 7551 ins_pipe(ialu_reg_reg); 7552 %} 7553 7554 instruct leaL_rReg_rReg_immI2_immL32(rRegL dst, rRegL base, rRegL index, immI2 scale, immL32 disp) 7555 %{ 7556 predicate(VM_Version::supports_fast_3op_lea()); 7557 match(Set dst (AddL (AddL base (LShiftL index scale)) disp)); 7558 7559 format %{ "leaq $dst, [$base + $index << $scale + $disp]\t# long" %} 7560 ins_encode %{ 7561 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 7562 __ leaq($dst$$Register, Address($base$$Register, $index$$Register, scale, $disp$$constant)); 7563 %} 7564 ins_pipe(ialu_reg_reg); 7565 %} 7566 7567 instruct addP_rReg(rRegP dst, rRegL src, rFlagsReg cr) 7568 %{ 7569 match(Set dst (AddP dst src)); 7570 effect(KILL cr); 7571 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); 7572 7573 format %{ "addq $dst, $src\t# ptr" %} 7574 ins_encode %{ 7575 __ addq($dst$$Register, $src$$Register); 7576 %} 7577 ins_pipe(ialu_reg_reg); 7578 %} 7579 7580 instruct addP_rReg_imm(rRegP dst, immL32 src, rFlagsReg cr) 7581 %{ 7582 match(Set dst (AddP dst src)); 7583 effect(KILL cr); 7584 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); 7585 7586 format %{ "addq $dst, $src\t# ptr" %} 7587 ins_encode %{ 7588 __ addq($dst$$Register, $src$$constant); 7589 %} 7590 ins_pipe( ialu_reg ); 7591 %} 7592 7593 // XXX addP mem ops ???? 7594 7595 instruct checkCastPP(rRegP dst) 7596 %{ 7597 match(Set dst (CheckCastPP dst)); 7598 7599 size(0); 7600 format %{ "# checkcastPP of $dst" %} 7601 ins_encode(/* empty encoding */); 7602 ins_pipe(empty); 7603 %} 7604 7605 instruct castPP(rRegP dst) 7606 %{ 7607 match(Set dst (CastPP dst)); 7608 7609 size(0); 7610 format %{ "# castPP of $dst" %} 7611 ins_encode(/* empty encoding */); 7612 ins_pipe(empty); 7613 %} 7614 7615 instruct castII(rRegI dst) 7616 %{ 7617 predicate(VerifyConstraintCasts == 0); 7618 match(Set dst (CastII dst)); 7619 7620 size(0); 7621 format %{ "# castII of $dst" %} 7622 ins_encode(/* empty encoding */); 7623 ins_cost(0); 7624 ins_pipe(empty); 7625 %} 7626 7627 instruct castII_checked(rRegI dst, rFlagsReg cr) 7628 %{ 7629 predicate(VerifyConstraintCasts > 0); 7630 match(Set dst (CastII dst)); 7631 7632 effect(KILL cr); 7633 format %{ "# cast_checked_II $dst" %} 7634 ins_encode %{ 7635 __ verify_int_in_range(_idx, bottom_type()->is_int(), $dst$$Register); 7636 %} 7637 ins_pipe(pipe_slow); 7638 %} 7639 7640 instruct castLL(rRegL dst) 7641 %{ 7642 predicate(VerifyConstraintCasts == 0); 7643 match(Set dst (CastLL dst)); 7644 7645 size(0); 7646 format %{ "# castLL of $dst" %} 7647 ins_encode(/* empty encoding */); 7648 ins_cost(0); 7649 ins_pipe(empty); 7650 %} 7651 7652 instruct castLL_checked_L32(rRegL dst, rFlagsReg cr) 7653 %{ 7654 predicate(VerifyConstraintCasts > 0 && castLL_is_imm32(n)); 7655 match(Set dst (CastLL dst)); 7656 7657 effect(KILL cr); 7658 format %{ "# cast_checked_LL $dst" %} 7659 ins_encode %{ 7660 __ verify_long_in_range(_idx, bottom_type()->is_long(), $dst$$Register, noreg); 7661 %} 7662 ins_pipe(pipe_slow); 7663 %} 7664 7665 instruct castLL_checked(rRegL dst, rRegL tmp, rFlagsReg cr) 7666 %{ 7667 predicate(VerifyConstraintCasts > 0 && !castLL_is_imm32(n)); 7668 match(Set dst (CastLL dst)); 7669 7670 effect(KILL cr, TEMP tmp); 7671 format %{ "# cast_checked_LL $dst\tusing $tmp as TEMP" %} 7672 ins_encode %{ 7673 __ verify_long_in_range(_idx, bottom_type()->is_long(), $dst$$Register, $tmp$$Register); 7674 %} 7675 ins_pipe(pipe_slow); 7676 %} 7677 7678 instruct castFF(regF dst) 7679 %{ 7680 match(Set dst (CastFF dst)); 7681 7682 size(0); 7683 format %{ "# castFF of $dst" %} 7684 ins_encode(/* empty encoding */); 7685 ins_cost(0); 7686 ins_pipe(empty); 7687 %} 7688 7689 instruct castHH(regF dst) 7690 %{ 7691 match(Set dst (CastHH dst)); 7692 7693 size(0); 7694 format %{ "# castHH of $dst" %} 7695 ins_encode(/* empty encoding */); 7696 ins_cost(0); 7697 ins_pipe(empty); 7698 %} 7699 7700 instruct castDD(regD dst) 7701 %{ 7702 match(Set dst (CastDD dst)); 7703 7704 size(0); 7705 format %{ "# castDD of $dst" %} 7706 ins_encode(/* empty encoding */); 7707 ins_cost(0); 7708 ins_pipe(empty); 7709 %} 7710 7711 // XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them 7712 instruct compareAndSwapP(rRegI res, 7713 memory mem_ptr, 7714 rax_RegP oldval, rRegP newval, 7715 rFlagsReg cr) 7716 %{ 7717 predicate(n->as_LoadStore()->barrier_data() == 0); 7718 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); 7719 match(Set res (WeakCompareAndSwapP mem_ptr (Binary oldval newval))); 7720 effect(KILL cr, KILL oldval); 7721 7722 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7723 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7724 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7725 ins_encode %{ 7726 __ lock(); 7727 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7728 __ setcc(Assembler::equal, $res$$Register); 7729 %} 7730 ins_pipe( pipe_cmpxchg ); 7731 %} 7732 7733 instruct compareAndSwapL(rRegI res, 7734 memory mem_ptr, 7735 rax_RegL oldval, rRegL newval, 7736 rFlagsReg cr) 7737 %{ 7738 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval))); 7739 match(Set res (WeakCompareAndSwapL mem_ptr (Binary oldval newval))); 7740 effect(KILL cr, KILL oldval); 7741 7742 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7743 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7744 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7745 ins_encode %{ 7746 __ lock(); 7747 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7748 __ setcc(Assembler::equal, $res$$Register); 7749 %} 7750 ins_pipe( pipe_cmpxchg ); 7751 %} 7752 7753 instruct compareAndSwapI(rRegI res, 7754 memory mem_ptr, 7755 rax_RegI oldval, rRegI newval, 7756 rFlagsReg cr) 7757 %{ 7758 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval))); 7759 match(Set res (WeakCompareAndSwapI mem_ptr (Binary oldval newval))); 7760 effect(KILL cr, KILL oldval); 7761 7762 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7763 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7764 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7765 ins_encode %{ 7766 __ lock(); 7767 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7768 __ setcc(Assembler::equal, $res$$Register); 7769 %} 7770 ins_pipe( pipe_cmpxchg ); 7771 %} 7772 7773 instruct compareAndSwapB(rRegI res, 7774 memory mem_ptr, 7775 rax_RegI oldval, rRegI newval, 7776 rFlagsReg cr) 7777 %{ 7778 match(Set res (CompareAndSwapB mem_ptr (Binary oldval newval))); 7779 match(Set res (WeakCompareAndSwapB mem_ptr (Binary oldval newval))); 7780 effect(KILL cr, KILL oldval); 7781 7782 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7783 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7784 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7785 ins_encode %{ 7786 __ lock(); 7787 __ cmpxchgb($newval$$Register, $mem_ptr$$Address); 7788 __ setcc(Assembler::equal, $res$$Register); 7789 %} 7790 ins_pipe( pipe_cmpxchg ); 7791 %} 7792 7793 instruct compareAndSwapS(rRegI res, 7794 memory mem_ptr, 7795 rax_RegI oldval, rRegI newval, 7796 rFlagsReg cr) 7797 %{ 7798 match(Set res (CompareAndSwapS mem_ptr (Binary oldval newval))); 7799 match(Set res (WeakCompareAndSwapS mem_ptr (Binary oldval newval))); 7800 effect(KILL cr, KILL oldval); 7801 7802 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7803 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7804 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7805 ins_encode %{ 7806 __ lock(); 7807 __ cmpxchgw($newval$$Register, $mem_ptr$$Address); 7808 __ setcc(Assembler::equal, $res$$Register); 7809 %} 7810 ins_pipe( pipe_cmpxchg ); 7811 %} 7812 7813 instruct compareAndSwapN(rRegI res, 7814 memory mem_ptr, 7815 rax_RegN oldval, rRegN newval, 7816 rFlagsReg cr) %{ 7817 predicate(n->as_LoadStore()->barrier_data() == 0); 7818 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval))); 7819 match(Set res (WeakCompareAndSwapN mem_ptr (Binary oldval newval))); 7820 effect(KILL cr, KILL oldval); 7821 7822 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7823 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7824 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7825 ins_encode %{ 7826 __ lock(); 7827 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7828 __ setcc(Assembler::equal, $res$$Register); 7829 %} 7830 ins_pipe( pipe_cmpxchg ); 7831 %} 7832 7833 instruct compareAndExchangeB( 7834 memory mem_ptr, 7835 rax_RegI oldval, rRegI newval, 7836 rFlagsReg cr) 7837 %{ 7838 match(Set oldval (CompareAndExchangeB mem_ptr (Binary oldval newval))); 7839 effect(KILL cr); 7840 7841 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7842 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7843 ins_encode %{ 7844 __ lock(); 7845 __ cmpxchgb($newval$$Register, $mem_ptr$$Address); 7846 %} 7847 ins_pipe( pipe_cmpxchg ); 7848 %} 7849 7850 instruct compareAndExchangeS( 7851 memory mem_ptr, 7852 rax_RegI oldval, rRegI newval, 7853 rFlagsReg cr) 7854 %{ 7855 match(Set oldval (CompareAndExchangeS mem_ptr (Binary oldval newval))); 7856 effect(KILL cr); 7857 7858 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7859 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7860 ins_encode %{ 7861 __ lock(); 7862 __ cmpxchgw($newval$$Register, $mem_ptr$$Address); 7863 %} 7864 ins_pipe( pipe_cmpxchg ); 7865 %} 7866 7867 instruct compareAndExchangeI( 7868 memory mem_ptr, 7869 rax_RegI oldval, rRegI newval, 7870 rFlagsReg cr) 7871 %{ 7872 match(Set oldval (CompareAndExchangeI mem_ptr (Binary oldval newval))); 7873 effect(KILL cr); 7874 7875 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7876 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7877 ins_encode %{ 7878 __ lock(); 7879 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7880 %} 7881 ins_pipe( pipe_cmpxchg ); 7882 %} 7883 7884 instruct compareAndExchangeL( 7885 memory mem_ptr, 7886 rax_RegL oldval, rRegL newval, 7887 rFlagsReg cr) 7888 %{ 7889 match(Set oldval (CompareAndExchangeL mem_ptr (Binary oldval newval))); 7890 effect(KILL cr); 7891 7892 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7893 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7894 ins_encode %{ 7895 __ lock(); 7896 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7897 %} 7898 ins_pipe( pipe_cmpxchg ); 7899 %} 7900 7901 instruct compareAndExchangeN( 7902 memory mem_ptr, 7903 rax_RegN oldval, rRegN newval, 7904 rFlagsReg cr) %{ 7905 predicate(n->as_LoadStore()->barrier_data() == 0); 7906 match(Set oldval (CompareAndExchangeN mem_ptr (Binary oldval newval))); 7907 effect(KILL cr); 7908 7909 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7910 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7911 ins_encode %{ 7912 __ lock(); 7913 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7914 %} 7915 ins_pipe( pipe_cmpxchg ); 7916 %} 7917 7918 instruct compareAndExchangeP( 7919 memory mem_ptr, 7920 rax_RegP oldval, rRegP newval, 7921 rFlagsReg cr) 7922 %{ 7923 predicate(n->as_LoadStore()->barrier_data() == 0); 7924 match(Set oldval (CompareAndExchangeP mem_ptr (Binary oldval newval))); 7925 effect(KILL cr); 7926 7927 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7928 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7929 ins_encode %{ 7930 __ lock(); 7931 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7932 %} 7933 ins_pipe( pipe_cmpxchg ); 7934 %} 7935 7936 instruct xaddB_reg_no_res(memory mem, Universe dummy, rRegI add, rFlagsReg cr) %{ 7937 predicate(n->as_LoadStore()->result_not_used()); 7938 match(Set dummy (GetAndAddB mem add)); 7939 effect(KILL cr); 7940 format %{ "addb_lock $mem, $add" %} 7941 ins_encode %{ 7942 __ lock(); 7943 __ addb($mem$$Address, $add$$Register); 7944 %} 7945 ins_pipe(pipe_cmpxchg); 7946 %} 7947 7948 instruct xaddB_imm_no_res(memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7949 predicate(n->as_LoadStore()->result_not_used()); 7950 match(Set dummy (GetAndAddB mem add)); 7951 effect(KILL cr); 7952 format %{ "addb_lock $mem, $add" %} 7953 ins_encode %{ 7954 __ lock(); 7955 __ addb($mem$$Address, $add$$constant); 7956 %} 7957 ins_pipe(pipe_cmpxchg); 7958 %} 7959 7960 instruct xaddB(memory mem, rRegI newval, rFlagsReg cr) %{ 7961 predicate(!n->as_LoadStore()->result_not_used()); 7962 match(Set newval (GetAndAddB mem newval)); 7963 effect(KILL cr); 7964 format %{ "xaddb_lock $mem, $newval" %} 7965 ins_encode %{ 7966 __ lock(); 7967 __ xaddb($mem$$Address, $newval$$Register); 7968 %} 7969 ins_pipe(pipe_cmpxchg); 7970 %} 7971 7972 instruct xaddS_reg_no_res(memory mem, Universe dummy, rRegI add, rFlagsReg cr) %{ 7973 predicate(n->as_LoadStore()->result_not_used()); 7974 match(Set dummy (GetAndAddS mem add)); 7975 effect(KILL cr); 7976 format %{ "addw_lock $mem, $add" %} 7977 ins_encode %{ 7978 __ lock(); 7979 __ addw($mem$$Address, $add$$Register); 7980 %} 7981 ins_pipe(pipe_cmpxchg); 7982 %} 7983 7984 instruct xaddS_imm_no_res(memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7985 predicate(UseStoreImmI16 && n->as_LoadStore()->result_not_used()); 7986 match(Set dummy (GetAndAddS mem add)); 7987 effect(KILL cr); 7988 format %{ "addw_lock $mem, $add" %} 7989 ins_encode %{ 7990 __ lock(); 7991 __ addw($mem$$Address, $add$$constant); 7992 %} 7993 ins_pipe(pipe_cmpxchg); 7994 %} 7995 7996 instruct xaddS(memory mem, rRegI newval, rFlagsReg cr) %{ 7997 predicate(!n->as_LoadStore()->result_not_used()); 7998 match(Set newval (GetAndAddS mem newval)); 7999 effect(KILL cr); 8000 format %{ "xaddw_lock $mem, $newval" %} 8001 ins_encode %{ 8002 __ lock(); 8003 __ xaddw($mem$$Address, $newval$$Register); 8004 %} 8005 ins_pipe(pipe_cmpxchg); 8006 %} 8007 8008 instruct xaddI_reg_no_res(memory mem, Universe dummy, rRegI add, rFlagsReg cr) %{ 8009 predicate(n->as_LoadStore()->result_not_used()); 8010 match(Set dummy (GetAndAddI mem add)); 8011 effect(KILL cr); 8012 format %{ "addl_lock $mem, $add" %} 8013 ins_encode %{ 8014 __ lock(); 8015 __ addl($mem$$Address, $add$$Register); 8016 %} 8017 ins_pipe(pipe_cmpxchg); 8018 %} 8019 8020 instruct xaddI_imm_no_res(memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 8021 predicate(n->as_LoadStore()->result_not_used()); 8022 match(Set dummy (GetAndAddI mem add)); 8023 effect(KILL cr); 8024 format %{ "addl_lock $mem, $add" %} 8025 ins_encode %{ 8026 __ lock(); 8027 __ addl($mem$$Address, $add$$constant); 8028 %} 8029 ins_pipe(pipe_cmpxchg); 8030 %} 8031 8032 instruct xaddI(memory mem, rRegI newval, rFlagsReg cr) %{ 8033 predicate(!n->as_LoadStore()->result_not_used()); 8034 match(Set newval (GetAndAddI mem newval)); 8035 effect(KILL cr); 8036 format %{ "xaddl_lock $mem, $newval" %} 8037 ins_encode %{ 8038 __ lock(); 8039 __ xaddl($mem$$Address, $newval$$Register); 8040 %} 8041 ins_pipe(pipe_cmpxchg); 8042 %} 8043 8044 instruct xaddL_reg_no_res(memory mem, Universe dummy, rRegL add, rFlagsReg cr) %{ 8045 predicate(n->as_LoadStore()->result_not_used()); 8046 match(Set dummy (GetAndAddL mem add)); 8047 effect(KILL cr); 8048 format %{ "addq_lock $mem, $add" %} 8049 ins_encode %{ 8050 __ lock(); 8051 __ addq($mem$$Address, $add$$Register); 8052 %} 8053 ins_pipe(pipe_cmpxchg); 8054 %} 8055 8056 instruct xaddL_imm_no_res(memory mem, Universe dummy, immL32 add, rFlagsReg cr) %{ 8057 predicate(n->as_LoadStore()->result_not_used()); 8058 match(Set dummy (GetAndAddL mem add)); 8059 effect(KILL cr); 8060 format %{ "addq_lock $mem, $add" %} 8061 ins_encode %{ 8062 __ lock(); 8063 __ addq($mem$$Address, $add$$constant); 8064 %} 8065 ins_pipe(pipe_cmpxchg); 8066 %} 8067 8068 instruct xaddL(memory mem, rRegL newval, rFlagsReg cr) %{ 8069 predicate(!n->as_LoadStore()->result_not_used()); 8070 match(Set newval (GetAndAddL mem newval)); 8071 effect(KILL cr); 8072 format %{ "xaddq_lock $mem, $newval" %} 8073 ins_encode %{ 8074 __ lock(); 8075 __ xaddq($mem$$Address, $newval$$Register); 8076 %} 8077 ins_pipe(pipe_cmpxchg); 8078 %} 8079 8080 instruct xchgB( memory mem, rRegI newval) %{ 8081 match(Set newval (GetAndSetB mem newval)); 8082 format %{ "XCHGB $newval,[$mem]" %} 8083 ins_encode %{ 8084 __ xchgb($newval$$Register, $mem$$Address); 8085 %} 8086 ins_pipe( pipe_cmpxchg ); 8087 %} 8088 8089 instruct xchgS( memory mem, rRegI newval) %{ 8090 match(Set newval (GetAndSetS mem newval)); 8091 format %{ "XCHGW $newval,[$mem]" %} 8092 ins_encode %{ 8093 __ xchgw($newval$$Register, $mem$$Address); 8094 %} 8095 ins_pipe( pipe_cmpxchg ); 8096 %} 8097 8098 instruct xchgI( memory mem, rRegI newval) %{ 8099 match(Set newval (GetAndSetI mem newval)); 8100 format %{ "XCHGL $newval,[$mem]" %} 8101 ins_encode %{ 8102 __ xchgl($newval$$Register, $mem$$Address); 8103 %} 8104 ins_pipe( pipe_cmpxchg ); 8105 %} 8106 8107 instruct xchgL( memory mem, rRegL newval) %{ 8108 match(Set newval (GetAndSetL mem newval)); 8109 format %{ "XCHGL $newval,[$mem]" %} 8110 ins_encode %{ 8111 __ xchgq($newval$$Register, $mem$$Address); 8112 %} 8113 ins_pipe( pipe_cmpxchg ); 8114 %} 8115 8116 instruct xchgP( memory mem, rRegP newval) %{ 8117 match(Set newval (GetAndSetP mem newval)); 8118 predicate(n->as_LoadStore()->barrier_data() == 0); 8119 format %{ "XCHGQ $newval,[$mem]" %} 8120 ins_encode %{ 8121 __ xchgq($newval$$Register, $mem$$Address); 8122 %} 8123 ins_pipe( pipe_cmpxchg ); 8124 %} 8125 8126 instruct xchgN( memory mem, rRegN newval) %{ 8127 predicate(n->as_LoadStore()->barrier_data() == 0); 8128 match(Set newval (GetAndSetN mem newval)); 8129 format %{ "XCHGL $newval,$mem]" %} 8130 ins_encode %{ 8131 __ xchgl($newval$$Register, $mem$$Address); 8132 %} 8133 ins_pipe( pipe_cmpxchg ); 8134 %} 8135 8136 //----------Abs Instructions------------------------------------------- 8137 8138 // Integer Absolute Instructions 8139 instruct absI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8140 %{ 8141 match(Set dst (AbsI src)); 8142 effect(TEMP dst, KILL cr); 8143 format %{ "xorl $dst, $dst\t# abs int\n\t" 8144 "subl $dst, $src\n\t" 8145 "cmovll $dst, $src" %} 8146 ins_encode %{ 8147 __ xorl($dst$$Register, $dst$$Register); 8148 __ subl($dst$$Register, $src$$Register); 8149 __ cmovl(Assembler::less, $dst$$Register, $src$$Register); 8150 %} 8151 8152 ins_pipe(ialu_reg_reg); 8153 %} 8154 8155 // Long Absolute Instructions 8156 instruct absL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 8157 %{ 8158 match(Set dst (AbsL src)); 8159 effect(TEMP dst, KILL cr); 8160 format %{ "xorl $dst, $dst\t# abs long\n\t" 8161 "subq $dst, $src\n\t" 8162 "cmovlq $dst, $src" %} 8163 ins_encode %{ 8164 __ xorl($dst$$Register, $dst$$Register); 8165 __ subq($dst$$Register, $src$$Register); 8166 __ cmovq(Assembler::less, $dst$$Register, $src$$Register); 8167 %} 8168 8169 ins_pipe(ialu_reg_reg); 8170 %} 8171 8172 //----------Subtraction Instructions------------------------------------------- 8173 8174 // Integer Subtraction Instructions 8175 instruct subI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8176 %{ 8177 predicate(!UseAPX); 8178 match(Set dst (SubI dst src)); 8179 effect(KILL cr); 8180 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); 8181 8182 format %{ "subl $dst, $src\t# int" %} 8183 ins_encode %{ 8184 __ subl($dst$$Register, $src$$Register); 8185 %} 8186 ins_pipe(ialu_reg_reg); 8187 %} 8188 8189 instruct subI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr) 8190 %{ 8191 predicate(UseAPX); 8192 match(Set dst (SubI src1 src2)); 8193 effect(KILL cr); 8194 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); 8195 8196 format %{ "esubl $dst, $src1, $src2\t# int ndd" %} 8197 ins_encode %{ 8198 __ esubl($dst$$Register, $src1$$Register, $src2$$Register, false); 8199 %} 8200 ins_pipe(ialu_reg_reg); 8201 %} 8202 8203 instruct subI_rReg_rReg_imm_ndd(rRegI dst, rRegI src1, immI src2, rFlagsReg cr) 8204 %{ 8205 predicate(UseAPX); 8206 match(Set dst (SubI src1 src2)); 8207 effect(KILL cr); 8208 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); 8209 8210 format %{ "esubl $dst, $src1, $src2\t# int ndd" %} 8211 ins_encode %{ 8212 __ esubl($dst$$Register, $src1$$Register, $src2$$constant, false); 8213 %} 8214 ins_pipe(ialu_reg_reg); 8215 %} 8216 8217 instruct subI_rReg_mem_imm_ndd(rRegI dst, memory src1, immI src2, rFlagsReg cr) 8218 %{ 8219 predicate(UseAPX); 8220 match(Set dst (SubI (LoadI src1) src2)); 8221 effect(KILL cr); 8222 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); 8223 8224 format %{ "esubl $dst, $src1, $src2\t# int ndd" %} 8225 ins_encode %{ 8226 __ esubl($dst$$Register, $src1$$Address, $src2$$constant, false); 8227 %} 8228 ins_pipe(ialu_reg_reg); 8229 %} 8230 8231 instruct subI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 8232 %{ 8233 predicate(!UseAPX); 8234 match(Set dst (SubI dst (LoadI src))); 8235 effect(KILL cr); 8236 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); 8237 8238 ins_cost(150); 8239 format %{ "subl $dst, $src\t# int" %} 8240 ins_encode %{ 8241 __ subl($dst$$Register, $src$$Address); 8242 %} 8243 ins_pipe(ialu_reg_mem); 8244 %} 8245 8246 instruct subI_rReg_rReg_mem_ndd(rRegI dst, rRegI src1, memory src2, rFlagsReg cr) 8247 %{ 8248 predicate(UseAPX); 8249 match(Set dst (SubI src1 (LoadI src2))); 8250 effect(KILL cr); 8251 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); 8252 8253 ins_cost(150); 8254 format %{ "esubl $dst, $src1, $src2\t# int ndd" %} 8255 ins_encode %{ 8256 __ esubl($dst$$Register, $src1$$Register, $src2$$Address, false); 8257 %} 8258 ins_pipe(ialu_reg_mem); 8259 %} 8260 8261 instruct subI_rReg_mem_rReg_ndd(rRegI dst, memory src1, rRegI src2, rFlagsReg cr) 8262 %{ 8263 predicate(UseAPX); 8264 match(Set dst (SubI (LoadI src1) src2)); 8265 effect(KILL cr); 8266 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); 8267 8268 ins_cost(150); 8269 format %{ "esubl $dst, $src1, $src2\t# int ndd" %} 8270 ins_encode %{ 8271 __ esubl($dst$$Register, $src1$$Address, $src2$$Register, false); 8272 %} 8273 ins_pipe(ialu_reg_mem); 8274 %} 8275 8276 instruct subI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 8277 %{ 8278 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 8279 effect(KILL cr); 8280 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); 8281 8282 ins_cost(150); 8283 format %{ "subl $dst, $src\t# int" %} 8284 ins_encode %{ 8285 __ subl($dst$$Address, $src$$Register); 8286 %} 8287 ins_pipe(ialu_mem_reg); 8288 %} 8289 8290 instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 8291 %{ 8292 predicate(!UseAPX); 8293 match(Set dst (SubL dst src)); 8294 effect(KILL cr); 8295 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); 8296 8297 format %{ "subq $dst, $src\t# long" %} 8298 ins_encode %{ 8299 __ subq($dst$$Register, $src$$Register); 8300 %} 8301 ins_pipe(ialu_reg_reg); 8302 %} 8303 8304 instruct subL_rReg_ndd(rRegL dst, rRegL src1, rRegL src2, rFlagsReg cr) 8305 %{ 8306 predicate(UseAPX); 8307 match(Set dst (SubL src1 src2)); 8308 effect(KILL cr); 8309 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); 8310 8311 format %{ "esubq $dst, $src1, $src2\t# long ndd" %} 8312 ins_encode %{ 8313 __ esubq($dst$$Register, $src1$$Register, $src2$$Register, false); 8314 %} 8315 ins_pipe(ialu_reg_reg); 8316 %} 8317 8318 instruct subL_rReg_rReg_imm_ndd(rRegL dst, rRegL src1, immL32 src2, rFlagsReg cr) 8319 %{ 8320 predicate(UseAPX); 8321 match(Set dst (SubL src1 src2)); 8322 effect(KILL cr); 8323 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); 8324 8325 format %{ "esubq $dst, $src1, $src2\t# long ndd" %} 8326 ins_encode %{ 8327 __ esubq($dst$$Register, $src1$$Register, $src2$$constant, false); 8328 %} 8329 ins_pipe(ialu_reg_reg); 8330 %} 8331 8332 instruct subL_rReg_mem_imm_ndd(rRegL dst, memory src1, immL32 src2, rFlagsReg cr) 8333 %{ 8334 predicate(UseAPX); 8335 match(Set dst (SubL (LoadL src1) src2)); 8336 effect(KILL cr); 8337 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); 8338 8339 format %{ "esubq $dst, $src1, $src2\t# long ndd" %} 8340 ins_encode %{ 8341 __ esubq($dst$$Register, $src1$$Address, $src2$$constant, false); 8342 %} 8343 ins_pipe(ialu_reg_reg); 8344 %} 8345 8346 instruct subL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 8347 %{ 8348 predicate(!UseAPX); 8349 match(Set dst (SubL dst (LoadL src))); 8350 effect(KILL cr); 8351 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); 8352 8353 ins_cost(150); 8354 format %{ "subq $dst, $src\t# long" %} 8355 ins_encode %{ 8356 __ subq($dst$$Register, $src$$Address); 8357 %} 8358 ins_pipe(ialu_reg_mem); 8359 %} 8360 8361 instruct subL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr) 8362 %{ 8363 predicate(UseAPX); 8364 match(Set dst (SubL src1 (LoadL src2))); 8365 effect(KILL cr); 8366 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); 8367 8368 ins_cost(150); 8369 format %{ "esubq $dst, $src1, $src2\t# long ndd" %} 8370 ins_encode %{ 8371 __ esubq($dst$$Register, $src1$$Register, $src2$$Address, false); 8372 %} 8373 ins_pipe(ialu_reg_mem); 8374 %} 8375 8376 instruct subL_rReg_mem_rReg_ndd(rRegL dst, memory src1, rRegL src2, rFlagsReg cr) 8377 %{ 8378 predicate(UseAPX); 8379 match(Set dst (SubL (LoadL src1) src2)); 8380 effect(KILL cr); 8381 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); 8382 8383 ins_cost(150); 8384 format %{ "esubq $dst, $src1, $src2\t# long ndd" %} 8385 ins_encode %{ 8386 __ esubq($dst$$Register, $src1$$Address, $src2$$Register, false); 8387 %} 8388 ins_pipe(ialu_reg_mem); 8389 %} 8390 8391 instruct subL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 8392 %{ 8393 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 8394 effect(KILL cr); 8395 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); 8396 8397 ins_cost(150); 8398 format %{ "subq $dst, $src\t# long" %} 8399 ins_encode %{ 8400 __ subq($dst$$Address, $src$$Register); 8401 %} 8402 ins_pipe(ialu_mem_reg); 8403 %} 8404 8405 // Subtract from a pointer 8406 // XXX hmpf??? 8407 instruct subP_rReg(rRegP dst, rRegI src, immI_0 zero, rFlagsReg cr) 8408 %{ 8409 match(Set dst (AddP dst (SubI zero src))); 8410 effect(KILL cr); 8411 8412 format %{ "subq $dst, $src\t# ptr - int" %} 8413 ins_encode %{ 8414 __ subq($dst$$Register, $src$$Register); 8415 %} 8416 ins_pipe(ialu_reg_reg); 8417 %} 8418 8419 instruct negI_rReg(rRegI dst, immI_0 zero, rFlagsReg cr) 8420 %{ 8421 predicate(!UseAPX); 8422 match(Set dst (SubI zero dst)); 8423 effect(KILL cr); 8424 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8425 8426 format %{ "negl $dst\t# int" %} 8427 ins_encode %{ 8428 __ negl($dst$$Register); 8429 %} 8430 ins_pipe(ialu_reg); 8431 %} 8432 8433 instruct negI_rReg_ndd(rRegI dst, rRegI src, immI_0 zero, rFlagsReg cr) 8434 %{ 8435 predicate(UseAPX); 8436 match(Set dst (SubI zero src)); 8437 effect(KILL cr); 8438 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8439 8440 format %{ "enegl $dst, $src\t# int ndd" %} 8441 ins_encode %{ 8442 __ enegl($dst$$Register, $src$$Register, false); 8443 %} 8444 ins_pipe(ialu_reg); 8445 %} 8446 8447 instruct negI_rReg_2(rRegI dst, rFlagsReg cr) 8448 %{ 8449 predicate(!UseAPX); 8450 match(Set dst (NegI dst)); 8451 effect(KILL cr); 8452 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8453 8454 format %{ "negl $dst\t# int" %} 8455 ins_encode %{ 8456 __ negl($dst$$Register); 8457 %} 8458 ins_pipe(ialu_reg); 8459 %} 8460 8461 instruct negI_rReg_2_ndd(rRegI dst, rRegI src, rFlagsReg cr) 8462 %{ 8463 predicate(UseAPX); 8464 match(Set dst (NegI src)); 8465 effect(KILL cr); 8466 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8467 8468 format %{ "enegl $dst, $src\t# int ndd" %} 8469 ins_encode %{ 8470 __ enegl($dst$$Register, $src$$Register, false); 8471 %} 8472 ins_pipe(ialu_reg); 8473 %} 8474 8475 instruct negI_mem(memory dst, immI_0 zero, rFlagsReg cr) 8476 %{ 8477 match(Set dst (StoreI dst (SubI zero (LoadI dst)))); 8478 effect(KILL cr); 8479 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8480 8481 format %{ "negl $dst\t# int" %} 8482 ins_encode %{ 8483 __ negl($dst$$Address); 8484 %} 8485 ins_pipe(ialu_reg); 8486 %} 8487 8488 instruct negL_rReg(rRegL dst, immL0 zero, rFlagsReg cr) 8489 %{ 8490 predicate(!UseAPX); 8491 match(Set dst (SubL zero dst)); 8492 effect(KILL cr); 8493 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8494 8495 format %{ "negq $dst\t# long" %} 8496 ins_encode %{ 8497 __ negq($dst$$Register); 8498 %} 8499 ins_pipe(ialu_reg); 8500 %} 8501 8502 instruct negL_rReg_ndd(rRegL dst, rRegL src, immL0 zero, rFlagsReg cr) 8503 %{ 8504 predicate(UseAPX); 8505 match(Set dst (SubL zero src)); 8506 effect(KILL cr); 8507 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8508 8509 format %{ "enegq $dst, $src\t# long ndd" %} 8510 ins_encode %{ 8511 __ enegq($dst$$Register, $src$$Register, false); 8512 %} 8513 ins_pipe(ialu_reg); 8514 %} 8515 8516 instruct negL_rReg_2(rRegL dst, rFlagsReg cr) 8517 %{ 8518 predicate(!UseAPX); 8519 match(Set dst (NegL dst)); 8520 effect(KILL cr); 8521 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8522 8523 format %{ "negq $dst\t# int" %} 8524 ins_encode %{ 8525 __ negq($dst$$Register); 8526 %} 8527 ins_pipe(ialu_reg); 8528 %} 8529 8530 instruct negL_rReg_2_ndd(rRegL dst, rRegL src, rFlagsReg cr) 8531 %{ 8532 predicate(UseAPX); 8533 match(Set dst (NegL src)); 8534 effect(KILL cr); 8535 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8536 8537 format %{ "enegq $dst, $src\t# long ndd" %} 8538 ins_encode %{ 8539 __ enegq($dst$$Register, $src$$Register, false); 8540 %} 8541 ins_pipe(ialu_reg); 8542 %} 8543 8544 instruct negL_mem(memory dst, immL0 zero, rFlagsReg cr) 8545 %{ 8546 match(Set dst (StoreL dst (SubL zero (LoadL dst)))); 8547 effect(KILL cr); 8548 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8549 8550 format %{ "negq $dst\t# long" %} 8551 ins_encode %{ 8552 __ negq($dst$$Address); 8553 %} 8554 ins_pipe(ialu_reg); 8555 %} 8556 8557 //----------Multiplication/Division Instructions------------------------------- 8558 // Integer Multiplication Instructions 8559 // Multiply Register 8560 8561 instruct mulI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8562 %{ 8563 predicate(!UseAPX); 8564 match(Set dst (MulI dst src)); 8565 effect(KILL cr); 8566 8567 ins_cost(300); 8568 format %{ "imull $dst, $src\t# int" %} 8569 ins_encode %{ 8570 __ imull($dst$$Register, $src$$Register); 8571 %} 8572 ins_pipe(ialu_reg_reg_alu0); 8573 %} 8574 8575 instruct mulI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr) 8576 %{ 8577 predicate(UseAPX); 8578 match(Set dst (MulI src1 src2)); 8579 effect(KILL cr); 8580 8581 ins_cost(300); 8582 format %{ "eimull $dst, $src1, $src2\t# int ndd" %} 8583 ins_encode %{ 8584 __ eimull($dst$$Register, $src1$$Register, $src2$$Register, false); 8585 %} 8586 ins_pipe(ialu_reg_reg_alu0); 8587 %} 8588 8589 instruct mulI_rReg_imm(rRegI dst, rRegI src, immI imm, rFlagsReg cr) 8590 %{ 8591 predicate(!UseAPX); 8592 match(Set dst (MulI src imm)); 8593 effect(KILL cr); 8594 8595 ins_cost(300); 8596 format %{ "imull $dst, $src, $imm\t# int" %} 8597 ins_encode %{ 8598 __ imull($dst$$Register, $src$$Register, $imm$$constant); 8599 %} 8600 ins_pipe(ialu_reg_reg_alu0); 8601 %} 8602 8603 instruct mulI_rReg_rReg_imm_ndd(rRegI dst, rRegI src1, immI src2, rFlagsReg cr) 8604 %{ 8605 predicate(UseAPX); 8606 match(Set dst (MulI src1 src2)); 8607 effect(KILL cr); 8608 8609 ins_cost(300); 8610 format %{ "eimull $dst, $src1, $src2\t# int ndd" %} 8611 ins_encode %{ 8612 __ eimull($dst$$Register, $src1$$Register, $src2$$constant, false); 8613 %} 8614 ins_pipe(ialu_reg_reg_alu0); 8615 %} 8616 8617 instruct mulI_mem(rRegI dst, memory src, rFlagsReg cr) 8618 %{ 8619 predicate(!UseAPX); 8620 match(Set dst (MulI dst (LoadI src))); 8621 effect(KILL cr); 8622 8623 ins_cost(350); 8624 format %{ "imull $dst, $src\t# int" %} 8625 ins_encode %{ 8626 __ imull($dst$$Register, $src$$Address); 8627 %} 8628 ins_pipe(ialu_reg_mem_alu0); 8629 %} 8630 8631 instruct mulI_rReg_rReg_mem_ndd(rRegI dst, rRegI src1, memory src2, rFlagsReg cr) 8632 %{ 8633 predicate(UseAPX); 8634 match(Set dst (MulI src1 (LoadI src2))); 8635 effect(KILL cr); 8636 8637 ins_cost(350); 8638 format %{ "eimull $dst, $src1, $src2\t# int ndd" %} 8639 ins_encode %{ 8640 __ eimull($dst$$Register, $src1$$Register, $src2$$Address, false); 8641 %} 8642 ins_pipe(ialu_reg_mem_alu0); 8643 %} 8644 8645 instruct mulI_mem_imm(rRegI dst, memory src, immI imm, rFlagsReg cr) 8646 %{ 8647 predicate(!UseAPX); 8648 match(Set dst (MulI (LoadI src) imm)); 8649 effect(KILL cr); 8650 8651 ins_cost(300); 8652 format %{ "imull $dst, $src, $imm\t# int" %} 8653 ins_encode %{ 8654 __ imull($dst$$Register, $src$$Address, $imm$$constant); 8655 %} 8656 ins_pipe(ialu_reg_mem_alu0); 8657 %} 8658 8659 instruct mulI_rReg_mem_imm(rRegI dst, memory src1, immI src2, rFlagsReg cr) 8660 %{ 8661 predicate(UseAPX); 8662 match(Set dst (MulI (LoadI src1) src2)); 8663 effect(KILL cr); 8664 8665 ins_cost(300); 8666 format %{ "eimull $dst, $src1, $src2\t# int ndd" %} 8667 ins_encode %{ 8668 __ eimull($dst$$Register, $src1$$Address, $src2$$constant, false); 8669 %} 8670 ins_pipe(ialu_reg_mem_alu0); 8671 %} 8672 8673 instruct mulAddS2I_rReg(rRegI dst, rRegI src1, rRegI src2, rRegI src3, rFlagsReg cr) 8674 %{ 8675 match(Set dst (MulAddS2I (Binary dst src1) (Binary src2 src3))); 8676 effect(KILL cr, KILL src2); 8677 8678 expand %{ mulI_rReg(dst, src1, cr); 8679 mulI_rReg(src2, src3, cr); 8680 addI_rReg(dst, src2, cr); %} 8681 %} 8682 8683 instruct mulL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 8684 %{ 8685 predicate(!UseAPX); 8686 match(Set dst (MulL dst src)); 8687 effect(KILL cr); 8688 8689 ins_cost(300); 8690 format %{ "imulq $dst, $src\t# long" %} 8691 ins_encode %{ 8692 __ imulq($dst$$Register, $src$$Register); 8693 %} 8694 ins_pipe(ialu_reg_reg_alu0); 8695 %} 8696 8697 instruct mulL_rReg_ndd(rRegL dst, rRegL src1, rRegL src2, rFlagsReg cr) 8698 %{ 8699 predicate(UseAPX); 8700 match(Set dst (MulL src1 src2)); 8701 effect(KILL cr); 8702 8703 ins_cost(300); 8704 format %{ "eimulq $dst, $src1, $src2\t# long ndd" %} 8705 ins_encode %{ 8706 __ eimulq($dst$$Register, $src1$$Register, $src2$$Register, false); 8707 %} 8708 ins_pipe(ialu_reg_reg_alu0); 8709 %} 8710 8711 instruct mulL_rReg_imm(rRegL dst, rRegL src, immL32 imm, rFlagsReg cr) 8712 %{ 8713 predicate(!UseAPX); 8714 match(Set dst (MulL src imm)); 8715 effect(KILL cr); 8716 8717 ins_cost(300); 8718 format %{ "imulq $dst, $src, $imm\t# long" %} 8719 ins_encode %{ 8720 __ imulq($dst$$Register, $src$$Register, $imm$$constant); 8721 %} 8722 ins_pipe(ialu_reg_reg_alu0); 8723 %} 8724 8725 instruct mulL_rReg_rReg_imm_ndd(rRegL dst, rRegL src1, immL32 src2, rFlagsReg cr) 8726 %{ 8727 predicate(UseAPX); 8728 match(Set dst (MulL src1 src2)); 8729 effect(KILL cr); 8730 8731 ins_cost(300); 8732 format %{ "eimulq $dst, $src1, $src2\t# long ndd" %} 8733 ins_encode %{ 8734 __ eimulq($dst$$Register, $src1$$Register, $src2$$constant, false); 8735 %} 8736 ins_pipe(ialu_reg_reg_alu0); 8737 %} 8738 8739 instruct mulL_mem(rRegL dst, memory src, rFlagsReg cr) 8740 %{ 8741 predicate(!UseAPX); 8742 match(Set dst (MulL dst (LoadL src))); 8743 effect(KILL cr); 8744 8745 ins_cost(350); 8746 format %{ "imulq $dst, $src\t# long" %} 8747 ins_encode %{ 8748 __ imulq($dst$$Register, $src$$Address); 8749 %} 8750 ins_pipe(ialu_reg_mem_alu0); 8751 %} 8752 8753 instruct mulL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr) 8754 %{ 8755 predicate(UseAPX); 8756 match(Set dst (MulL src1 (LoadL src2))); 8757 effect(KILL cr); 8758 8759 ins_cost(350); 8760 format %{ "eimulq $dst, $src1, $src2 \t# long" %} 8761 ins_encode %{ 8762 __ eimulq($dst$$Register, $src1$$Register, $src2$$Address, false); 8763 %} 8764 ins_pipe(ialu_reg_mem_alu0); 8765 %} 8766 8767 instruct mulL_mem_imm(rRegL dst, memory src, immL32 imm, rFlagsReg cr) 8768 %{ 8769 predicate(!UseAPX); 8770 match(Set dst (MulL (LoadL src) imm)); 8771 effect(KILL cr); 8772 8773 ins_cost(300); 8774 format %{ "imulq $dst, $src, $imm\t# long" %} 8775 ins_encode %{ 8776 __ imulq($dst$$Register, $src$$Address, $imm$$constant); 8777 %} 8778 ins_pipe(ialu_reg_mem_alu0); 8779 %} 8780 8781 instruct mulL_rReg_mem_imm_ndd(rRegL dst, memory src1, immL32 src2, rFlagsReg cr) 8782 %{ 8783 predicate(UseAPX); 8784 match(Set dst (MulL (LoadL src1) src2)); 8785 effect(KILL cr); 8786 8787 ins_cost(300); 8788 format %{ "eimulq $dst, $src1, $src2\t# long ndd" %} 8789 ins_encode %{ 8790 __ eimulq($dst$$Register, $src1$$Address, $src2$$constant, false); 8791 %} 8792 ins_pipe(ialu_reg_mem_alu0); 8793 %} 8794 8795 instruct mulHiL_rReg(rdx_RegL dst, rRegL src, rax_RegL rax, rFlagsReg cr) 8796 %{ 8797 match(Set dst (MulHiL src rax)); 8798 effect(USE_KILL rax, KILL cr); 8799 8800 ins_cost(300); 8801 format %{ "imulq RDX:RAX, RAX, $src\t# mulhi" %} 8802 ins_encode %{ 8803 __ imulq($src$$Register); 8804 %} 8805 ins_pipe(ialu_reg_reg_alu0); 8806 %} 8807 8808 instruct umulHiL_rReg(rdx_RegL dst, rRegL src, rax_RegL rax, rFlagsReg cr) 8809 %{ 8810 match(Set dst (UMulHiL src rax)); 8811 effect(USE_KILL rax, KILL cr); 8812 8813 ins_cost(300); 8814 format %{ "mulq RDX:RAX, RAX, $src\t# umulhi" %} 8815 ins_encode %{ 8816 __ mulq($src$$Register); 8817 %} 8818 ins_pipe(ialu_reg_reg_alu0); 8819 %} 8820 8821 instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 8822 rFlagsReg cr) 8823 %{ 8824 match(Set rax (DivI rax div)); 8825 effect(KILL rdx, KILL cr); 8826 8827 ins_cost(30*100+10*100); // XXX 8828 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 8829 "jne,s normal\n\t" 8830 "xorl rdx, rdx\n\t" 8831 "cmpl $div, -1\n\t" 8832 "je,s done\n" 8833 "normal: cdql\n\t" 8834 "idivl $div\n" 8835 "done:" %} 8836 ins_encode(cdql_enc(div)); 8837 ins_pipe(ialu_reg_reg_alu0); 8838 %} 8839 8840 instruct divL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 8841 rFlagsReg cr) 8842 %{ 8843 match(Set rax (DivL rax div)); 8844 effect(KILL rdx, KILL cr); 8845 8846 ins_cost(30*100+10*100); // XXX 8847 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 8848 "cmpq rax, rdx\n\t" 8849 "jne,s normal\n\t" 8850 "xorl rdx, rdx\n\t" 8851 "cmpq $div, -1\n\t" 8852 "je,s done\n" 8853 "normal: cdqq\n\t" 8854 "idivq $div\n" 8855 "done:" %} 8856 ins_encode(cdqq_enc(div)); 8857 ins_pipe(ialu_reg_reg_alu0); 8858 %} 8859 8860 instruct udivI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, rFlagsReg cr) 8861 %{ 8862 match(Set rax (UDivI rax div)); 8863 effect(KILL rdx, KILL cr); 8864 8865 ins_cost(300); 8866 format %{ "udivl $rax,$rax,$div\t# UDivI\n" %} 8867 ins_encode %{ 8868 __ udivI($rax$$Register, $div$$Register, $rdx$$Register); 8869 %} 8870 ins_pipe(ialu_reg_reg_alu0); 8871 %} 8872 8873 instruct udivL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, rFlagsReg cr) 8874 %{ 8875 match(Set rax (UDivL rax div)); 8876 effect(KILL rdx, KILL cr); 8877 8878 ins_cost(300); 8879 format %{ "udivq $rax,$rax,$div\t# UDivL\n" %} 8880 ins_encode %{ 8881 __ udivL($rax$$Register, $div$$Register, $rdx$$Register); 8882 %} 8883 ins_pipe(ialu_reg_reg_alu0); 8884 %} 8885 8886 // Integer DIVMOD with Register, both quotient and mod results 8887 instruct divModI_rReg_divmod(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 8888 rFlagsReg cr) 8889 %{ 8890 match(DivModI rax div); 8891 effect(KILL cr); 8892 8893 ins_cost(30*100+10*100); // XXX 8894 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 8895 "jne,s normal\n\t" 8896 "xorl rdx, rdx\n\t" 8897 "cmpl $div, -1\n\t" 8898 "je,s done\n" 8899 "normal: cdql\n\t" 8900 "idivl $div\n" 8901 "done:" %} 8902 ins_encode(cdql_enc(div)); 8903 ins_pipe(pipe_slow); 8904 %} 8905 8906 // Long DIVMOD with Register, both quotient and mod results 8907 instruct divModL_rReg_divmod(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 8908 rFlagsReg cr) 8909 %{ 8910 match(DivModL rax div); 8911 effect(KILL cr); 8912 8913 ins_cost(30*100+10*100); // XXX 8914 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 8915 "cmpq rax, rdx\n\t" 8916 "jne,s normal\n\t" 8917 "xorl rdx, rdx\n\t" 8918 "cmpq $div, -1\n\t" 8919 "je,s done\n" 8920 "normal: cdqq\n\t" 8921 "idivq $div\n" 8922 "done:" %} 8923 ins_encode(cdqq_enc(div)); 8924 ins_pipe(pipe_slow); 8925 %} 8926 8927 // Unsigned integer DIVMOD with Register, both quotient and mod results 8928 instruct udivModI_rReg_divmod(rax_RegI rax, no_rax_rdx_RegI tmp, rdx_RegI rdx, 8929 no_rax_rdx_RegI div, rFlagsReg cr) 8930 %{ 8931 match(UDivModI rax div); 8932 effect(TEMP tmp, KILL cr); 8933 8934 ins_cost(300); 8935 format %{ "udivl $rax,$rax,$div\t# begin UDivModI\n\t" 8936 "umodl $rdx,$rax,$div\t! using $tmp as TEMP # end UDivModI\n" 8937 %} 8938 ins_encode %{ 8939 __ udivmodI($rax$$Register, $div$$Register, $rdx$$Register, $tmp$$Register); 8940 %} 8941 ins_pipe(pipe_slow); 8942 %} 8943 8944 // Unsigned long DIVMOD with Register, both quotient and mod results 8945 instruct udivModL_rReg_divmod(rax_RegL rax, no_rax_rdx_RegL tmp, rdx_RegL rdx, 8946 no_rax_rdx_RegL div, rFlagsReg cr) 8947 %{ 8948 match(UDivModL rax div); 8949 effect(TEMP tmp, KILL cr); 8950 8951 ins_cost(300); 8952 format %{ "udivq $rax,$rax,$div\t# begin UDivModL\n\t" 8953 "umodq $rdx,$rax,$div\t! using $tmp as TEMP # end UDivModL\n" 8954 %} 8955 ins_encode %{ 8956 __ udivmodL($rax$$Register, $div$$Register, $rdx$$Register, $tmp$$Register); 8957 %} 8958 ins_pipe(pipe_slow); 8959 %} 8960 8961 instruct modI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, 8962 rFlagsReg cr) 8963 %{ 8964 match(Set rdx (ModI rax div)); 8965 effect(KILL rax, KILL cr); 8966 8967 ins_cost(300); // XXX 8968 format %{ "cmpl rax, 0x80000000\t# irem\n\t" 8969 "jne,s normal\n\t" 8970 "xorl rdx, rdx\n\t" 8971 "cmpl $div, -1\n\t" 8972 "je,s done\n" 8973 "normal: cdql\n\t" 8974 "idivl $div\n" 8975 "done:" %} 8976 ins_encode(cdql_enc(div)); 8977 ins_pipe(ialu_reg_reg_alu0); 8978 %} 8979 8980 instruct modL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, 8981 rFlagsReg cr) 8982 %{ 8983 match(Set rdx (ModL rax div)); 8984 effect(KILL rax, KILL cr); 8985 8986 ins_cost(300); // XXX 8987 format %{ "movq rdx, 0x8000000000000000\t# lrem\n\t" 8988 "cmpq rax, rdx\n\t" 8989 "jne,s normal\n\t" 8990 "xorl rdx, rdx\n\t" 8991 "cmpq $div, -1\n\t" 8992 "je,s done\n" 8993 "normal: cdqq\n\t" 8994 "idivq $div\n" 8995 "done:" %} 8996 ins_encode(cdqq_enc(div)); 8997 ins_pipe(ialu_reg_reg_alu0); 8998 %} 8999 9000 instruct umodI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, rFlagsReg cr) 9001 %{ 9002 match(Set rdx (UModI rax div)); 9003 effect(KILL rax, KILL cr); 9004 9005 ins_cost(300); 9006 format %{ "umodl $rdx,$rax,$div\t# UModI\n" %} 9007 ins_encode %{ 9008 __ umodI($rax$$Register, $div$$Register, $rdx$$Register); 9009 %} 9010 ins_pipe(ialu_reg_reg_alu0); 9011 %} 9012 9013 instruct umodL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, rFlagsReg cr) 9014 %{ 9015 match(Set rdx (UModL rax div)); 9016 effect(KILL rax, KILL cr); 9017 9018 ins_cost(300); 9019 format %{ "umodq $rdx,$rax,$div\t# UModL\n" %} 9020 ins_encode %{ 9021 __ umodL($rax$$Register, $div$$Register, $rdx$$Register); 9022 %} 9023 ins_pipe(ialu_reg_reg_alu0); 9024 %} 9025 9026 // Integer Shift Instructions 9027 // Shift Left by one, two, three 9028 instruct salI_rReg_immI2(rRegI dst, immI2 shift, rFlagsReg cr) 9029 %{ 9030 predicate(!UseAPX); 9031 match(Set dst (LShiftI dst shift)); 9032 effect(KILL cr); 9033 9034 format %{ "sall $dst, $shift" %} 9035 ins_encode %{ 9036 __ sall($dst$$Register, $shift$$constant); 9037 %} 9038 ins_pipe(ialu_reg); 9039 %} 9040 9041 // Shift Left by one, two, three 9042 instruct salI_rReg_immI2_ndd(rRegI dst, rRegI src, immI2 shift, rFlagsReg cr) 9043 %{ 9044 predicate(UseAPX); 9045 match(Set dst (LShiftI src shift)); 9046 effect(KILL cr); 9047 9048 format %{ "esall $dst, $src, $shift\t# int(ndd)" %} 9049 ins_encode %{ 9050 __ esall($dst$$Register, $src$$Register, $shift$$constant, false); 9051 %} 9052 ins_pipe(ialu_reg); 9053 %} 9054 9055 // Shift Left by 8-bit immediate 9056 instruct salI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 9057 %{ 9058 predicate(!UseAPX); 9059 match(Set dst (LShiftI dst shift)); 9060 effect(KILL cr); 9061 9062 format %{ "sall $dst, $shift" %} 9063 ins_encode %{ 9064 __ sall($dst$$Register, $shift$$constant); 9065 %} 9066 ins_pipe(ialu_reg); 9067 %} 9068 9069 // Shift Left by 8-bit immediate 9070 instruct salI_rReg_imm_ndd(rRegI dst, rRegI src, immI8 shift, rFlagsReg cr) 9071 %{ 9072 predicate(UseAPX); 9073 match(Set dst (LShiftI src shift)); 9074 effect(KILL cr); 9075 9076 format %{ "esall $dst, $src, $shift\t# int (ndd)" %} 9077 ins_encode %{ 9078 __ esall($dst$$Register, $src$$Register, $shift$$constant, false); 9079 %} 9080 ins_pipe(ialu_reg); 9081 %} 9082 9083 instruct salI_rReg_mem_imm_ndd(rRegI dst, memory src, immI8 shift, rFlagsReg cr) 9084 %{ 9085 predicate(UseAPX); 9086 match(Set dst (LShiftI (LoadI src) shift)); 9087 effect(KILL cr); 9088 9089 format %{ "esall $dst, $src, $shift\t# int (ndd)" %} 9090 ins_encode %{ 9091 __ esall($dst$$Register, $src$$Address, $shift$$constant, false); 9092 %} 9093 ins_pipe(ialu_reg); 9094 %} 9095 9096 // Shift Left by 8-bit immediate 9097 instruct salI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 9098 %{ 9099 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 9100 effect(KILL cr); 9101 9102 format %{ "sall $dst, $shift" %} 9103 ins_encode %{ 9104 __ sall($dst$$Address, $shift$$constant); 9105 %} 9106 ins_pipe(ialu_mem_imm); 9107 %} 9108 9109 // Shift Left by variable 9110 instruct salI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 9111 %{ 9112 predicate(!VM_Version::supports_bmi2()); 9113 match(Set dst (LShiftI dst shift)); 9114 effect(KILL cr); 9115 9116 format %{ "sall $dst, $shift" %} 9117 ins_encode %{ 9118 __ sall($dst$$Register); 9119 %} 9120 ins_pipe(ialu_reg_reg); 9121 %} 9122 9123 // Shift Left by variable 9124 instruct salI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 9125 %{ 9126 predicate(!VM_Version::supports_bmi2()); 9127 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 9128 effect(KILL cr); 9129 9130 format %{ "sall $dst, $shift" %} 9131 ins_encode %{ 9132 __ sall($dst$$Address); 9133 %} 9134 ins_pipe(ialu_mem_reg); 9135 %} 9136 9137 instruct salI_rReg_rReg(rRegI dst, rRegI src, rRegI shift) 9138 %{ 9139 predicate(VM_Version::supports_bmi2()); 9140 match(Set dst (LShiftI src shift)); 9141 9142 format %{ "shlxl $dst, $src, $shift" %} 9143 ins_encode %{ 9144 __ shlxl($dst$$Register, $src$$Register, $shift$$Register); 9145 %} 9146 ins_pipe(ialu_reg_reg); 9147 %} 9148 9149 instruct salI_mem_rReg(rRegI dst, memory src, rRegI shift) 9150 %{ 9151 predicate(VM_Version::supports_bmi2()); 9152 match(Set dst (LShiftI (LoadI src) shift)); 9153 ins_cost(175); 9154 format %{ "shlxl $dst, $src, $shift" %} 9155 ins_encode %{ 9156 __ shlxl($dst$$Register, $src$$Address, $shift$$Register); 9157 %} 9158 ins_pipe(ialu_reg_mem); 9159 %} 9160 9161 // Arithmetic Shift Right by 8-bit immediate 9162 instruct sarI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 9163 %{ 9164 predicate(!UseAPX); 9165 match(Set dst (RShiftI dst shift)); 9166 effect(KILL cr); 9167 9168 format %{ "sarl $dst, $shift" %} 9169 ins_encode %{ 9170 __ sarl($dst$$Register, $shift$$constant); 9171 %} 9172 ins_pipe(ialu_mem_imm); 9173 %} 9174 9175 // Arithmetic Shift Right by 8-bit immediate 9176 instruct sarI_rReg_imm_ndd(rRegI dst, rRegI src, immI8 shift, rFlagsReg cr) 9177 %{ 9178 predicate(UseAPX); 9179 match(Set dst (RShiftI src shift)); 9180 effect(KILL cr); 9181 9182 format %{ "esarl $dst, $src, $shift\t# int (ndd)" %} 9183 ins_encode %{ 9184 __ esarl($dst$$Register, $src$$Register, $shift$$constant, false); 9185 %} 9186 ins_pipe(ialu_mem_imm); 9187 %} 9188 9189 instruct sarI_rReg_mem_imm_ndd(rRegI dst, memory src, immI8 shift, rFlagsReg cr) 9190 %{ 9191 predicate(UseAPX); 9192 match(Set dst (RShiftI (LoadI src) shift)); 9193 effect(KILL cr); 9194 9195 format %{ "esarl $dst, $src, $shift\t# int (ndd)" %} 9196 ins_encode %{ 9197 __ esarl($dst$$Register, $src$$Address, $shift$$constant, false); 9198 %} 9199 ins_pipe(ialu_mem_imm); 9200 %} 9201 9202 // Arithmetic Shift Right by 8-bit immediate 9203 instruct sarI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 9204 %{ 9205 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 9206 effect(KILL cr); 9207 9208 format %{ "sarl $dst, $shift" %} 9209 ins_encode %{ 9210 __ sarl($dst$$Address, $shift$$constant); 9211 %} 9212 ins_pipe(ialu_mem_imm); 9213 %} 9214 9215 // Arithmetic Shift Right by variable 9216 instruct sarI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 9217 %{ 9218 predicate(!VM_Version::supports_bmi2()); 9219 match(Set dst (RShiftI dst shift)); 9220 effect(KILL cr); 9221 9222 format %{ "sarl $dst, $shift" %} 9223 ins_encode %{ 9224 __ sarl($dst$$Register); 9225 %} 9226 ins_pipe(ialu_reg_reg); 9227 %} 9228 9229 // Arithmetic Shift Right by variable 9230 instruct sarI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 9231 %{ 9232 predicate(!VM_Version::supports_bmi2()); 9233 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 9234 effect(KILL cr); 9235 9236 format %{ "sarl $dst, $shift" %} 9237 ins_encode %{ 9238 __ sarl($dst$$Address); 9239 %} 9240 ins_pipe(ialu_mem_reg); 9241 %} 9242 9243 instruct sarI_rReg_rReg(rRegI dst, rRegI src, rRegI shift) 9244 %{ 9245 predicate(VM_Version::supports_bmi2()); 9246 match(Set dst (RShiftI src shift)); 9247 9248 format %{ "sarxl $dst, $src, $shift" %} 9249 ins_encode %{ 9250 __ sarxl($dst$$Register, $src$$Register, $shift$$Register); 9251 %} 9252 ins_pipe(ialu_reg_reg); 9253 %} 9254 9255 instruct sarI_mem_rReg(rRegI dst, memory src, rRegI shift) 9256 %{ 9257 predicate(VM_Version::supports_bmi2()); 9258 match(Set dst (RShiftI (LoadI src) shift)); 9259 ins_cost(175); 9260 format %{ "sarxl $dst, $src, $shift" %} 9261 ins_encode %{ 9262 __ sarxl($dst$$Register, $src$$Address, $shift$$Register); 9263 %} 9264 ins_pipe(ialu_reg_mem); 9265 %} 9266 9267 // Logical Shift Right by 8-bit immediate 9268 instruct shrI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 9269 %{ 9270 predicate(!UseAPX); 9271 match(Set dst (URShiftI dst shift)); 9272 effect(KILL cr); 9273 9274 format %{ "shrl $dst, $shift" %} 9275 ins_encode %{ 9276 __ shrl($dst$$Register, $shift$$constant); 9277 %} 9278 ins_pipe(ialu_reg); 9279 %} 9280 9281 // Logical Shift Right by 8-bit immediate 9282 instruct shrI_rReg_imm_ndd(rRegI dst, rRegI src, immI8 shift, rFlagsReg cr) 9283 %{ 9284 predicate(UseAPX); 9285 match(Set dst (URShiftI src shift)); 9286 effect(KILL cr); 9287 9288 format %{ "eshrl $dst, $src, $shift\t # int (ndd)" %} 9289 ins_encode %{ 9290 __ eshrl($dst$$Register, $src$$Register, $shift$$constant, false); 9291 %} 9292 ins_pipe(ialu_reg); 9293 %} 9294 9295 instruct shrI_rReg_mem_imm_ndd(rRegI dst, memory src, immI8 shift, rFlagsReg cr) 9296 %{ 9297 predicate(UseAPX); 9298 match(Set dst (URShiftI (LoadI src) shift)); 9299 effect(KILL cr); 9300 9301 format %{ "eshrl $dst, $src, $shift\t # int (ndd)" %} 9302 ins_encode %{ 9303 __ eshrl($dst$$Register, $src$$Address, $shift$$constant, false); 9304 %} 9305 ins_pipe(ialu_reg); 9306 %} 9307 9308 // Logical Shift Right by 8-bit immediate 9309 instruct shrI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 9310 %{ 9311 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 9312 effect(KILL cr); 9313 9314 format %{ "shrl $dst, $shift" %} 9315 ins_encode %{ 9316 __ shrl($dst$$Address, $shift$$constant); 9317 %} 9318 ins_pipe(ialu_mem_imm); 9319 %} 9320 9321 // Logical Shift Right by variable 9322 instruct shrI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 9323 %{ 9324 predicate(!VM_Version::supports_bmi2()); 9325 match(Set dst (URShiftI dst shift)); 9326 effect(KILL cr); 9327 9328 format %{ "shrl $dst, $shift" %} 9329 ins_encode %{ 9330 __ shrl($dst$$Register); 9331 %} 9332 ins_pipe(ialu_reg_reg); 9333 %} 9334 9335 // Logical Shift Right by variable 9336 instruct shrI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 9337 %{ 9338 predicate(!VM_Version::supports_bmi2()); 9339 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 9340 effect(KILL cr); 9341 9342 format %{ "shrl $dst, $shift" %} 9343 ins_encode %{ 9344 __ shrl($dst$$Address); 9345 %} 9346 ins_pipe(ialu_mem_reg); 9347 %} 9348 9349 instruct shrI_rReg_rReg(rRegI dst, rRegI src, rRegI shift) 9350 %{ 9351 predicate(VM_Version::supports_bmi2()); 9352 match(Set dst (URShiftI src shift)); 9353 9354 format %{ "shrxl $dst, $src, $shift" %} 9355 ins_encode %{ 9356 __ shrxl($dst$$Register, $src$$Register, $shift$$Register); 9357 %} 9358 ins_pipe(ialu_reg_reg); 9359 %} 9360 9361 instruct shrI_mem_rReg(rRegI dst, memory src, rRegI shift) 9362 %{ 9363 predicate(VM_Version::supports_bmi2()); 9364 match(Set dst (URShiftI (LoadI src) shift)); 9365 ins_cost(175); 9366 format %{ "shrxl $dst, $src, $shift" %} 9367 ins_encode %{ 9368 __ shrxl($dst$$Register, $src$$Address, $shift$$Register); 9369 %} 9370 ins_pipe(ialu_reg_mem); 9371 %} 9372 9373 // Long Shift Instructions 9374 // Shift Left by one, two, three 9375 instruct salL_rReg_immI2(rRegL dst, immI2 shift, rFlagsReg cr) 9376 %{ 9377 predicate(!UseAPX); 9378 match(Set dst (LShiftL dst shift)); 9379 effect(KILL cr); 9380 9381 format %{ "salq $dst, $shift" %} 9382 ins_encode %{ 9383 __ salq($dst$$Register, $shift$$constant); 9384 %} 9385 ins_pipe(ialu_reg); 9386 %} 9387 9388 // Shift Left by one, two, three 9389 instruct salL_rReg_immI2_ndd(rRegL dst, rRegL src, immI2 shift, rFlagsReg cr) 9390 %{ 9391 predicate(UseAPX); 9392 match(Set dst (LShiftL src shift)); 9393 effect(KILL cr); 9394 9395 format %{ "esalq $dst, $src, $shift\t# long (ndd)" %} 9396 ins_encode %{ 9397 __ esalq($dst$$Register, $src$$Register, $shift$$constant, false); 9398 %} 9399 ins_pipe(ialu_reg); 9400 %} 9401 9402 // Shift Left by 8-bit immediate 9403 instruct salL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 9404 %{ 9405 predicate(!UseAPX); 9406 match(Set dst (LShiftL dst shift)); 9407 effect(KILL cr); 9408 9409 format %{ "salq $dst, $shift" %} 9410 ins_encode %{ 9411 __ salq($dst$$Register, $shift$$constant); 9412 %} 9413 ins_pipe(ialu_reg); 9414 %} 9415 9416 // Shift Left by 8-bit immediate 9417 instruct salL_rReg_imm_ndd(rRegL dst, rRegL src, immI8 shift, rFlagsReg cr) 9418 %{ 9419 predicate(UseAPX); 9420 match(Set dst (LShiftL src shift)); 9421 effect(KILL cr); 9422 9423 format %{ "esalq $dst, $src, $shift\t# long (ndd)" %} 9424 ins_encode %{ 9425 __ esalq($dst$$Register, $src$$Register, $shift$$constant, false); 9426 %} 9427 ins_pipe(ialu_reg); 9428 %} 9429 9430 instruct salL_rReg_mem_imm_ndd(rRegL dst, memory src, immI8 shift, rFlagsReg cr) 9431 %{ 9432 predicate(UseAPX); 9433 match(Set dst (LShiftL (LoadL src) shift)); 9434 effect(KILL cr); 9435 9436 format %{ "esalq $dst, $src, $shift\t# long (ndd)" %} 9437 ins_encode %{ 9438 __ esalq($dst$$Register, $src$$Address, $shift$$constant, false); 9439 %} 9440 ins_pipe(ialu_reg); 9441 %} 9442 9443 // Shift Left by 8-bit immediate 9444 instruct salL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 9445 %{ 9446 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 9447 effect(KILL cr); 9448 9449 format %{ "salq $dst, $shift" %} 9450 ins_encode %{ 9451 __ salq($dst$$Address, $shift$$constant); 9452 %} 9453 ins_pipe(ialu_mem_imm); 9454 %} 9455 9456 // Shift Left by variable 9457 instruct salL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 9458 %{ 9459 predicate(!VM_Version::supports_bmi2()); 9460 match(Set dst (LShiftL dst shift)); 9461 effect(KILL cr); 9462 9463 format %{ "salq $dst, $shift" %} 9464 ins_encode %{ 9465 __ salq($dst$$Register); 9466 %} 9467 ins_pipe(ialu_reg_reg); 9468 %} 9469 9470 // Shift Left by variable 9471 instruct salL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 9472 %{ 9473 predicate(!VM_Version::supports_bmi2()); 9474 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 9475 effect(KILL cr); 9476 9477 format %{ "salq $dst, $shift" %} 9478 ins_encode %{ 9479 __ salq($dst$$Address); 9480 %} 9481 ins_pipe(ialu_mem_reg); 9482 %} 9483 9484 instruct salL_rReg_rReg(rRegL dst, rRegL src, rRegI shift) 9485 %{ 9486 predicate(VM_Version::supports_bmi2()); 9487 match(Set dst (LShiftL src shift)); 9488 9489 format %{ "shlxq $dst, $src, $shift" %} 9490 ins_encode %{ 9491 __ shlxq($dst$$Register, $src$$Register, $shift$$Register); 9492 %} 9493 ins_pipe(ialu_reg_reg); 9494 %} 9495 9496 instruct salL_mem_rReg(rRegL dst, memory src, rRegI shift) 9497 %{ 9498 predicate(VM_Version::supports_bmi2()); 9499 match(Set dst (LShiftL (LoadL src) shift)); 9500 ins_cost(175); 9501 format %{ "shlxq $dst, $src, $shift" %} 9502 ins_encode %{ 9503 __ shlxq($dst$$Register, $src$$Address, $shift$$Register); 9504 %} 9505 ins_pipe(ialu_reg_mem); 9506 %} 9507 9508 // Arithmetic Shift Right by 8-bit immediate 9509 instruct sarL_rReg_imm(rRegL dst, immI shift, rFlagsReg cr) 9510 %{ 9511 predicate(!UseAPX); 9512 match(Set dst (RShiftL dst shift)); 9513 effect(KILL cr); 9514 9515 format %{ "sarq $dst, $shift" %} 9516 ins_encode %{ 9517 __ sarq($dst$$Register, (unsigned char)($shift$$constant & 0x3F)); 9518 %} 9519 ins_pipe(ialu_mem_imm); 9520 %} 9521 9522 // Arithmetic Shift Right by 8-bit immediate 9523 instruct sarL_rReg_imm_ndd(rRegL dst, rRegL src, immI shift, rFlagsReg cr) 9524 %{ 9525 predicate(UseAPX); 9526 match(Set dst (RShiftL src shift)); 9527 effect(KILL cr); 9528 9529 format %{ "esarq $dst, $src, $shift\t# long (ndd)" %} 9530 ins_encode %{ 9531 __ esarq($dst$$Register, $src$$Register, (unsigned char)($shift$$constant & 0x3F), false); 9532 %} 9533 ins_pipe(ialu_mem_imm); 9534 %} 9535 9536 instruct sarL_rReg_mem_imm_ndd(rRegL dst, memory src, immI shift, rFlagsReg cr) 9537 %{ 9538 predicate(UseAPX); 9539 match(Set dst (RShiftL (LoadL src) shift)); 9540 effect(KILL cr); 9541 9542 format %{ "esarq $dst, $src, $shift\t# long (ndd)" %} 9543 ins_encode %{ 9544 __ esarq($dst$$Register, $src$$Address, (unsigned char)($shift$$constant & 0x3F), false); 9545 %} 9546 ins_pipe(ialu_mem_imm); 9547 %} 9548 9549 // Arithmetic Shift Right by 8-bit immediate 9550 instruct sarL_mem_imm(memory dst, immI shift, rFlagsReg cr) 9551 %{ 9552 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 9553 effect(KILL cr); 9554 9555 format %{ "sarq $dst, $shift" %} 9556 ins_encode %{ 9557 __ sarq($dst$$Address, (unsigned char)($shift$$constant & 0x3F)); 9558 %} 9559 ins_pipe(ialu_mem_imm); 9560 %} 9561 9562 // Arithmetic Shift Right by variable 9563 instruct sarL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 9564 %{ 9565 predicate(!VM_Version::supports_bmi2()); 9566 match(Set dst (RShiftL dst shift)); 9567 effect(KILL cr); 9568 9569 format %{ "sarq $dst, $shift" %} 9570 ins_encode %{ 9571 __ sarq($dst$$Register); 9572 %} 9573 ins_pipe(ialu_reg_reg); 9574 %} 9575 9576 // Arithmetic Shift Right by variable 9577 instruct sarL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 9578 %{ 9579 predicate(!VM_Version::supports_bmi2()); 9580 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 9581 effect(KILL cr); 9582 9583 format %{ "sarq $dst, $shift" %} 9584 ins_encode %{ 9585 __ sarq($dst$$Address); 9586 %} 9587 ins_pipe(ialu_mem_reg); 9588 %} 9589 9590 instruct sarL_rReg_rReg(rRegL dst, rRegL src, rRegI shift) 9591 %{ 9592 predicate(VM_Version::supports_bmi2()); 9593 match(Set dst (RShiftL src shift)); 9594 9595 format %{ "sarxq $dst, $src, $shift" %} 9596 ins_encode %{ 9597 __ sarxq($dst$$Register, $src$$Register, $shift$$Register); 9598 %} 9599 ins_pipe(ialu_reg_reg); 9600 %} 9601 9602 instruct sarL_mem_rReg(rRegL dst, memory src, rRegI shift) 9603 %{ 9604 predicate(VM_Version::supports_bmi2()); 9605 match(Set dst (RShiftL (LoadL src) shift)); 9606 ins_cost(175); 9607 format %{ "sarxq $dst, $src, $shift" %} 9608 ins_encode %{ 9609 __ sarxq($dst$$Register, $src$$Address, $shift$$Register); 9610 %} 9611 ins_pipe(ialu_reg_mem); 9612 %} 9613 9614 // Logical Shift Right by 8-bit immediate 9615 instruct shrL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 9616 %{ 9617 predicate(!UseAPX); 9618 match(Set dst (URShiftL dst shift)); 9619 effect(KILL cr); 9620 9621 format %{ "shrq $dst, $shift" %} 9622 ins_encode %{ 9623 __ shrq($dst$$Register, $shift$$constant); 9624 %} 9625 ins_pipe(ialu_reg); 9626 %} 9627 9628 // Logical Shift Right by 8-bit immediate 9629 instruct shrL_rReg_imm_ndd(rRegL dst, rRegL src, immI8 shift, rFlagsReg cr) 9630 %{ 9631 predicate(UseAPX); 9632 match(Set dst (URShiftL src shift)); 9633 effect(KILL cr); 9634 9635 format %{ "eshrq $dst, $src, $shift\t# long (ndd)" %} 9636 ins_encode %{ 9637 __ eshrq($dst$$Register, $src$$Register, $shift$$constant, false); 9638 %} 9639 ins_pipe(ialu_reg); 9640 %} 9641 9642 instruct shrL_rReg_mem_imm_ndd(rRegL dst, memory src, immI8 shift, rFlagsReg cr) 9643 %{ 9644 predicate(UseAPX); 9645 match(Set dst (URShiftL (LoadL src) shift)); 9646 effect(KILL cr); 9647 9648 format %{ "eshrq $dst, $src, $shift\t# long (ndd)" %} 9649 ins_encode %{ 9650 __ eshrq($dst$$Register, $src$$Address, $shift$$constant, false); 9651 %} 9652 ins_pipe(ialu_reg); 9653 %} 9654 9655 // Logical Shift Right by 8-bit immediate 9656 instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 9657 %{ 9658 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 9659 effect(KILL cr); 9660 9661 format %{ "shrq $dst, $shift" %} 9662 ins_encode %{ 9663 __ shrq($dst$$Address, $shift$$constant); 9664 %} 9665 ins_pipe(ialu_mem_imm); 9666 %} 9667 9668 // Logical Shift Right by variable 9669 instruct shrL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 9670 %{ 9671 predicate(!VM_Version::supports_bmi2()); 9672 match(Set dst (URShiftL dst shift)); 9673 effect(KILL cr); 9674 9675 format %{ "shrq $dst, $shift" %} 9676 ins_encode %{ 9677 __ shrq($dst$$Register); 9678 %} 9679 ins_pipe(ialu_reg_reg); 9680 %} 9681 9682 // Logical Shift Right by variable 9683 instruct shrL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 9684 %{ 9685 predicate(!VM_Version::supports_bmi2()); 9686 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 9687 effect(KILL cr); 9688 9689 format %{ "shrq $dst, $shift" %} 9690 ins_encode %{ 9691 __ shrq($dst$$Address); 9692 %} 9693 ins_pipe(ialu_mem_reg); 9694 %} 9695 9696 instruct shrL_rReg_rReg(rRegL dst, rRegL src, rRegI shift) 9697 %{ 9698 predicate(VM_Version::supports_bmi2()); 9699 match(Set dst (URShiftL src shift)); 9700 9701 format %{ "shrxq $dst, $src, $shift" %} 9702 ins_encode %{ 9703 __ shrxq($dst$$Register, $src$$Register, $shift$$Register); 9704 %} 9705 ins_pipe(ialu_reg_reg); 9706 %} 9707 9708 instruct shrL_mem_rReg(rRegL dst, memory src, rRegI shift) 9709 %{ 9710 predicate(VM_Version::supports_bmi2()); 9711 match(Set dst (URShiftL (LoadL src) shift)); 9712 ins_cost(175); 9713 format %{ "shrxq $dst, $src, $shift" %} 9714 ins_encode %{ 9715 __ shrxq($dst$$Register, $src$$Address, $shift$$Register); 9716 %} 9717 ins_pipe(ialu_reg_mem); 9718 %} 9719 9720 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24. 9721 // This idiom is used by the compiler for the i2b bytecode. 9722 instruct i2b(rRegI dst, rRegI src, immI_24 twentyfour) 9723 %{ 9724 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour)); 9725 9726 format %{ "movsbl $dst, $src\t# i2b" %} 9727 ins_encode %{ 9728 __ movsbl($dst$$Register, $src$$Register); 9729 %} 9730 ins_pipe(ialu_reg_reg); 9731 %} 9732 9733 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16. 9734 // This idiom is used by the compiler the i2s bytecode. 9735 instruct i2s(rRegI dst, rRegI src, immI_16 sixteen) 9736 %{ 9737 match(Set dst (RShiftI (LShiftI src sixteen) sixteen)); 9738 9739 format %{ "movswl $dst, $src\t# i2s" %} 9740 ins_encode %{ 9741 __ movswl($dst$$Register, $src$$Register); 9742 %} 9743 ins_pipe(ialu_reg_reg); 9744 %} 9745 9746 // ROL/ROR instructions 9747 9748 // Rotate left by constant. 9749 instruct rolI_immI8_legacy(rRegI dst, immI8 shift, rFlagsReg cr) 9750 %{ 9751 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 9752 match(Set dst (RotateLeft dst shift)); 9753 effect(KILL cr); 9754 format %{ "roll $dst, $shift" %} 9755 ins_encode %{ 9756 __ roll($dst$$Register, $shift$$constant); 9757 %} 9758 ins_pipe(ialu_reg); 9759 %} 9760 9761 instruct rolI_immI8(rRegI dst, rRegI src, immI8 shift) 9762 %{ 9763 predicate(!UseAPX && VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 9764 match(Set dst (RotateLeft src shift)); 9765 format %{ "rolxl $dst, $src, $shift" %} 9766 ins_encode %{ 9767 int shift = 32 - ($shift$$constant & 31); 9768 __ rorxl($dst$$Register, $src$$Register, shift); 9769 %} 9770 ins_pipe(ialu_reg_reg); 9771 %} 9772 9773 instruct rolI_mem_immI8(rRegI dst, memory src, immI8 shift) 9774 %{ 9775 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 9776 match(Set dst (RotateLeft (LoadI src) shift)); 9777 ins_cost(175); 9778 format %{ "rolxl $dst, $src, $shift" %} 9779 ins_encode %{ 9780 int shift = 32 - ($shift$$constant & 31); 9781 __ rorxl($dst$$Register, $src$$Address, shift); 9782 %} 9783 ins_pipe(ialu_reg_mem); 9784 %} 9785 9786 // Rotate Left by variable 9787 instruct rolI_rReg_Var(rRegI dst, rcx_RegI shift, rFlagsReg cr) 9788 %{ 9789 predicate(!UseAPX && n->bottom_type()->basic_type() == T_INT); 9790 match(Set dst (RotateLeft dst shift)); 9791 effect(KILL cr); 9792 format %{ "roll $dst, $shift" %} 9793 ins_encode %{ 9794 __ roll($dst$$Register); 9795 %} 9796 ins_pipe(ialu_reg_reg); 9797 %} 9798 9799 // Rotate Left by variable 9800 instruct rolI_rReg_Var_ndd(rRegI dst, rRegI src, rcx_RegI shift, rFlagsReg cr) 9801 %{ 9802 predicate(UseAPX && n->bottom_type()->basic_type() == T_INT); 9803 match(Set dst (RotateLeft src shift)); 9804 effect(KILL cr); 9805 9806 format %{ "eroll $dst, $src, $shift\t# rotate left (int ndd)" %} 9807 ins_encode %{ 9808 __ eroll($dst$$Register, $src$$Register, false); 9809 %} 9810 ins_pipe(ialu_reg_reg); 9811 %} 9812 9813 // Rotate Right by constant. 9814 instruct rorI_immI8_legacy(rRegI dst, immI8 shift, rFlagsReg cr) 9815 %{ 9816 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 9817 match(Set dst (RotateRight dst shift)); 9818 effect(KILL cr); 9819 format %{ "rorl $dst, $shift" %} 9820 ins_encode %{ 9821 __ rorl($dst$$Register, $shift$$constant); 9822 %} 9823 ins_pipe(ialu_reg); 9824 %} 9825 9826 // Rotate Right by constant. 9827 instruct rorI_immI8(rRegI dst, rRegI src, immI8 shift) 9828 %{ 9829 predicate(!UseAPX && VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 9830 match(Set dst (RotateRight src shift)); 9831 format %{ "rorxl $dst, $src, $shift" %} 9832 ins_encode %{ 9833 __ rorxl($dst$$Register, $src$$Register, $shift$$constant); 9834 %} 9835 ins_pipe(ialu_reg_reg); 9836 %} 9837 9838 instruct rorI_mem_immI8(rRegI dst, memory src, immI8 shift) 9839 %{ 9840 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 9841 match(Set dst (RotateRight (LoadI src) shift)); 9842 ins_cost(175); 9843 format %{ "rorxl $dst, $src, $shift" %} 9844 ins_encode %{ 9845 __ rorxl($dst$$Register, $src$$Address, $shift$$constant); 9846 %} 9847 ins_pipe(ialu_reg_mem); 9848 %} 9849 9850 // Rotate Right by variable 9851 instruct rorI_rReg_Var(rRegI dst, rcx_RegI shift, rFlagsReg cr) 9852 %{ 9853 predicate(!UseAPX && n->bottom_type()->basic_type() == T_INT); 9854 match(Set dst (RotateRight dst shift)); 9855 effect(KILL cr); 9856 format %{ "rorl $dst, $shift" %} 9857 ins_encode %{ 9858 __ rorl($dst$$Register); 9859 %} 9860 ins_pipe(ialu_reg_reg); 9861 %} 9862 9863 // Rotate Right by variable 9864 instruct rorI_rReg_Var_ndd(rRegI dst, rRegI src, rcx_RegI shift, rFlagsReg cr) 9865 %{ 9866 predicate(UseAPX && n->bottom_type()->basic_type() == T_INT); 9867 match(Set dst (RotateRight src shift)); 9868 effect(KILL cr); 9869 9870 format %{ "erorl $dst, $src, $shift\t# rotate right(int ndd)" %} 9871 ins_encode %{ 9872 __ erorl($dst$$Register, $src$$Register, false); 9873 %} 9874 ins_pipe(ialu_reg_reg); 9875 %} 9876 9877 // Rotate Left by constant. 9878 instruct rolL_immI8_legacy(rRegL dst, immI8 shift, rFlagsReg cr) 9879 %{ 9880 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 9881 match(Set dst (RotateLeft dst shift)); 9882 effect(KILL cr); 9883 format %{ "rolq $dst, $shift" %} 9884 ins_encode %{ 9885 __ rolq($dst$$Register, $shift$$constant); 9886 %} 9887 ins_pipe(ialu_reg); 9888 %} 9889 9890 instruct rolL_immI8(rRegL dst, rRegL src, immI8 shift) 9891 %{ 9892 predicate(!UseAPX && VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 9893 match(Set dst (RotateLeft src shift)); 9894 format %{ "rolxq $dst, $src, $shift" %} 9895 ins_encode %{ 9896 int shift = 64 - ($shift$$constant & 63); 9897 __ rorxq($dst$$Register, $src$$Register, shift); 9898 %} 9899 ins_pipe(ialu_reg_reg); 9900 %} 9901 9902 instruct rolL_mem_immI8(rRegL dst, memory src, immI8 shift) 9903 %{ 9904 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 9905 match(Set dst (RotateLeft (LoadL src) shift)); 9906 ins_cost(175); 9907 format %{ "rolxq $dst, $src, $shift" %} 9908 ins_encode %{ 9909 int shift = 64 - ($shift$$constant & 63); 9910 __ rorxq($dst$$Register, $src$$Address, shift); 9911 %} 9912 ins_pipe(ialu_reg_mem); 9913 %} 9914 9915 // Rotate Left by variable 9916 instruct rolL_rReg_Var(rRegL dst, rcx_RegI shift, rFlagsReg cr) 9917 %{ 9918 predicate(!UseAPX && n->bottom_type()->basic_type() == T_LONG); 9919 match(Set dst (RotateLeft dst shift)); 9920 effect(KILL cr); 9921 format %{ "rolq $dst, $shift" %} 9922 ins_encode %{ 9923 __ rolq($dst$$Register); 9924 %} 9925 ins_pipe(ialu_reg_reg); 9926 %} 9927 9928 // Rotate Left by variable 9929 instruct rolL_rReg_Var_ndd(rRegL dst, rRegL src, rcx_RegI shift, rFlagsReg cr) 9930 %{ 9931 predicate(UseAPX && n->bottom_type()->basic_type() == T_LONG); 9932 match(Set dst (RotateLeft src shift)); 9933 effect(KILL cr); 9934 9935 format %{ "erolq $dst, $src, $shift\t# rotate left(long ndd)" %} 9936 ins_encode %{ 9937 __ erolq($dst$$Register, $src$$Register, false); 9938 %} 9939 ins_pipe(ialu_reg_reg); 9940 %} 9941 9942 // Rotate Right by constant. 9943 instruct rorL_immI8_legacy(rRegL dst, immI8 shift, rFlagsReg cr) 9944 %{ 9945 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 9946 match(Set dst (RotateRight dst shift)); 9947 effect(KILL cr); 9948 format %{ "rorq $dst, $shift" %} 9949 ins_encode %{ 9950 __ rorq($dst$$Register, $shift$$constant); 9951 %} 9952 ins_pipe(ialu_reg); 9953 %} 9954 9955 // Rotate Right by constant 9956 instruct rorL_immI8(rRegL dst, rRegL src, immI8 shift) 9957 %{ 9958 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 9959 match(Set dst (RotateRight src shift)); 9960 format %{ "rorxq $dst, $src, $shift" %} 9961 ins_encode %{ 9962 __ rorxq($dst$$Register, $src$$Register, $shift$$constant); 9963 %} 9964 ins_pipe(ialu_reg_reg); 9965 %} 9966 9967 instruct rorL_mem_immI8(rRegL dst, memory src, immI8 shift) 9968 %{ 9969 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 9970 match(Set dst (RotateRight (LoadL src) shift)); 9971 ins_cost(175); 9972 format %{ "rorxq $dst, $src, $shift" %} 9973 ins_encode %{ 9974 __ rorxq($dst$$Register, $src$$Address, $shift$$constant); 9975 %} 9976 ins_pipe(ialu_reg_mem); 9977 %} 9978 9979 // Rotate Right by variable 9980 instruct rorL_rReg_Var(rRegL dst, rcx_RegI shift, rFlagsReg cr) 9981 %{ 9982 predicate(!UseAPX && n->bottom_type()->basic_type() == T_LONG); 9983 match(Set dst (RotateRight dst shift)); 9984 effect(KILL cr); 9985 format %{ "rorq $dst, $shift" %} 9986 ins_encode %{ 9987 __ rorq($dst$$Register); 9988 %} 9989 ins_pipe(ialu_reg_reg); 9990 %} 9991 9992 // Rotate Right by variable 9993 instruct rorL_rReg_Var_ndd(rRegL dst, rRegL src, rcx_RegI shift, rFlagsReg cr) 9994 %{ 9995 predicate(UseAPX && n->bottom_type()->basic_type() == T_LONG); 9996 match(Set dst (RotateRight src shift)); 9997 effect(KILL cr); 9998 9999 format %{ "erorq $dst, $src, $shift\t# rotate right(long ndd)" %} 10000 ins_encode %{ 10001 __ erorq($dst$$Register, $src$$Register, false); 10002 %} 10003 ins_pipe(ialu_reg_reg); 10004 %} 10005 10006 //----------------------------- CompressBits/ExpandBits ------------------------ 10007 10008 instruct compressBitsL_reg(rRegL dst, rRegL src, rRegL mask) %{ 10009 predicate(n->bottom_type()->isa_long()); 10010 match(Set dst (CompressBits src mask)); 10011 format %{ "pextq $dst, $src, $mask\t! parallel bit extract" %} 10012 ins_encode %{ 10013 __ pextq($dst$$Register, $src$$Register, $mask$$Register); 10014 %} 10015 ins_pipe( pipe_slow ); 10016 %} 10017 10018 instruct expandBitsL_reg(rRegL dst, rRegL src, rRegL mask) %{ 10019 predicate(n->bottom_type()->isa_long()); 10020 match(Set dst (ExpandBits src mask)); 10021 format %{ "pdepq $dst, $src, $mask\t! parallel bit deposit" %} 10022 ins_encode %{ 10023 __ pdepq($dst$$Register, $src$$Register, $mask$$Register); 10024 %} 10025 ins_pipe( pipe_slow ); 10026 %} 10027 10028 instruct compressBitsL_mem(rRegL dst, rRegL src, memory mask) %{ 10029 predicate(n->bottom_type()->isa_long()); 10030 match(Set dst (CompressBits src (LoadL mask))); 10031 format %{ "pextq $dst, $src, $mask\t! parallel bit extract" %} 10032 ins_encode %{ 10033 __ pextq($dst$$Register, $src$$Register, $mask$$Address); 10034 %} 10035 ins_pipe( pipe_slow ); 10036 %} 10037 10038 instruct expandBitsL_mem(rRegL dst, rRegL src, memory mask) %{ 10039 predicate(n->bottom_type()->isa_long()); 10040 match(Set dst (ExpandBits src (LoadL mask))); 10041 format %{ "pdepq $dst, $src, $mask\t! parallel bit deposit" %} 10042 ins_encode %{ 10043 __ pdepq($dst$$Register, $src$$Register, $mask$$Address); 10044 %} 10045 ins_pipe( pipe_slow ); 10046 %} 10047 10048 10049 // Logical Instructions 10050 10051 // Integer Logical Instructions 10052 10053 // And Instructions 10054 // And Register with Register 10055 instruct andI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 10056 %{ 10057 predicate(!UseAPX); 10058 match(Set dst (AndI dst src)); 10059 effect(KILL cr); 10060 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10061 10062 format %{ "andl $dst, $src\t# int" %} 10063 ins_encode %{ 10064 __ andl($dst$$Register, $src$$Register); 10065 %} 10066 ins_pipe(ialu_reg_reg); 10067 %} 10068 10069 // And Register with Register using New Data Destination (NDD) 10070 instruct andI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr) 10071 %{ 10072 predicate(UseAPX); 10073 match(Set dst (AndI src1 src2)); 10074 effect(KILL cr); 10075 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10076 10077 format %{ "eandl $dst, $src1, $src2\t# int ndd" %} 10078 ins_encode %{ 10079 __ eandl($dst$$Register, $src1$$Register, $src2$$Register, false); 10080 10081 %} 10082 ins_pipe(ialu_reg_reg); 10083 %} 10084 10085 // And Register with Immediate 255 10086 instruct andI_rReg_imm255(rRegI dst, rRegI src, immI_255 mask) 10087 %{ 10088 match(Set dst (AndI src mask)); 10089 10090 format %{ "movzbl $dst, $src\t# int & 0xFF" %} 10091 ins_encode %{ 10092 __ movzbl($dst$$Register, $src$$Register); 10093 %} 10094 ins_pipe(ialu_reg); 10095 %} 10096 10097 // And Register with Immediate 255 and promote to long 10098 instruct andI2L_rReg_imm255(rRegL dst, rRegI src, immI_255 mask) 10099 %{ 10100 match(Set dst (ConvI2L (AndI src mask))); 10101 10102 format %{ "movzbl $dst, $src\t# int & 0xFF -> long" %} 10103 ins_encode %{ 10104 __ movzbl($dst$$Register, $src$$Register); 10105 %} 10106 ins_pipe(ialu_reg); 10107 %} 10108 10109 // And Register with Immediate 65535 10110 instruct andI_rReg_imm65535(rRegI dst, rRegI src, immI_65535 mask) 10111 %{ 10112 match(Set dst (AndI src mask)); 10113 10114 format %{ "movzwl $dst, $src\t# int & 0xFFFF" %} 10115 ins_encode %{ 10116 __ movzwl($dst$$Register, $src$$Register); 10117 %} 10118 ins_pipe(ialu_reg); 10119 %} 10120 10121 // And Register with Immediate 65535 and promote to long 10122 instruct andI2L_rReg_imm65535(rRegL dst, rRegI src, immI_65535 mask) 10123 %{ 10124 match(Set dst (ConvI2L (AndI src mask))); 10125 10126 format %{ "movzwl $dst, $src\t# int & 0xFFFF -> long" %} 10127 ins_encode %{ 10128 __ movzwl($dst$$Register, $src$$Register); 10129 %} 10130 ins_pipe(ialu_reg); 10131 %} 10132 10133 // Can skip int2long conversions after AND with small bitmask 10134 instruct convI2LAndI_reg_immIbitmask(rRegL dst, rRegI src, immI_Pow2M1 mask, rRegI tmp, rFlagsReg cr) 10135 %{ 10136 predicate(VM_Version::supports_bmi2()); 10137 ins_cost(125); 10138 effect(TEMP tmp, KILL cr); 10139 match(Set dst (ConvI2L (AndI src mask))); 10140 format %{ "bzhiq $dst, $src, $mask \t# using $tmp as TEMP, int & immI_Pow2M1 -> long" %} 10141 ins_encode %{ 10142 __ movl($tmp$$Register, exact_log2($mask$$constant + 1)); 10143 __ bzhiq($dst$$Register, $src$$Register, $tmp$$Register); 10144 %} 10145 ins_pipe(ialu_reg_reg); 10146 %} 10147 10148 // And Register with Immediate 10149 instruct andI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 10150 %{ 10151 predicate(!UseAPX); 10152 match(Set dst (AndI dst src)); 10153 effect(KILL cr); 10154 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10155 10156 format %{ "andl $dst, $src\t# int" %} 10157 ins_encode %{ 10158 __ andl($dst$$Register, $src$$constant); 10159 %} 10160 ins_pipe(ialu_reg); 10161 %} 10162 10163 instruct andI_rReg_rReg_imm_ndd(rRegI dst, rRegI src1, immI src2, rFlagsReg cr) 10164 %{ 10165 predicate(UseAPX); 10166 match(Set dst (AndI src1 src2)); 10167 effect(KILL cr); 10168 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10169 10170 format %{ "eandl $dst, $src1, $src2\t# int ndd" %} 10171 ins_encode %{ 10172 __ eandl($dst$$Register, $src1$$Register, $src2$$constant, false); 10173 %} 10174 ins_pipe(ialu_reg); 10175 %} 10176 10177 instruct andI_rReg_mem_imm_ndd(rRegI dst, memory src1, immI src2, rFlagsReg cr) 10178 %{ 10179 predicate(UseAPX); 10180 match(Set dst (AndI (LoadI src1) src2)); 10181 effect(KILL cr); 10182 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10183 10184 format %{ "eandl $dst, $src1, $src2\t# int ndd" %} 10185 ins_encode %{ 10186 __ eandl($dst$$Register, $src1$$Address, $src2$$constant, false); 10187 %} 10188 ins_pipe(ialu_reg); 10189 %} 10190 10191 // And Register with Memory 10192 instruct andI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 10193 %{ 10194 predicate(!UseAPX); 10195 match(Set dst (AndI dst (LoadI src))); 10196 effect(KILL cr); 10197 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10198 10199 ins_cost(150); 10200 format %{ "andl $dst, $src\t# int" %} 10201 ins_encode %{ 10202 __ andl($dst$$Register, $src$$Address); 10203 %} 10204 ins_pipe(ialu_reg_mem); 10205 %} 10206 10207 instruct andI_rReg_rReg_mem_ndd(rRegI dst, rRegI src1, memory src2, rFlagsReg cr) 10208 %{ 10209 predicate(UseAPX); 10210 match(Set dst (AndI src1 (LoadI src2))); 10211 effect(KILL cr); 10212 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10213 10214 ins_cost(150); 10215 format %{ "eandl $dst, $src1, $src2\t# int ndd" %} 10216 ins_encode %{ 10217 __ eandl($dst$$Register, $src1$$Register, $src2$$Address, false); 10218 %} 10219 ins_pipe(ialu_reg_mem); 10220 %} 10221 10222 // And Memory with Register 10223 instruct andB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 10224 %{ 10225 match(Set dst (StoreB dst (AndI (LoadB dst) src))); 10226 effect(KILL cr); 10227 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10228 10229 ins_cost(150); 10230 format %{ "andb $dst, $src\t# byte" %} 10231 ins_encode %{ 10232 __ andb($dst$$Address, $src$$Register); 10233 %} 10234 ins_pipe(ialu_mem_reg); 10235 %} 10236 10237 instruct andI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 10238 %{ 10239 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 10240 effect(KILL cr); 10241 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10242 10243 ins_cost(150); 10244 format %{ "andl $dst, $src\t# int" %} 10245 ins_encode %{ 10246 __ andl($dst$$Address, $src$$Register); 10247 %} 10248 ins_pipe(ialu_mem_reg); 10249 %} 10250 10251 // And Memory with Immediate 10252 instruct andI_mem_imm(memory dst, immI src, rFlagsReg cr) 10253 %{ 10254 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 10255 effect(KILL cr); 10256 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10257 10258 ins_cost(125); 10259 format %{ "andl $dst, $src\t# int" %} 10260 ins_encode %{ 10261 __ andl($dst$$Address, $src$$constant); 10262 %} 10263 ins_pipe(ialu_mem_imm); 10264 %} 10265 10266 // BMI1 instructions 10267 instruct andnI_rReg_rReg_mem(rRegI dst, rRegI src1, memory src2, immI_M1 minus_1, rFlagsReg cr) %{ 10268 match(Set dst (AndI (XorI src1 minus_1) (LoadI src2))); 10269 predicate(UseBMI1Instructions); 10270 effect(KILL cr); 10271 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10272 10273 ins_cost(125); 10274 format %{ "andnl $dst, $src1, $src2" %} 10275 10276 ins_encode %{ 10277 __ andnl($dst$$Register, $src1$$Register, $src2$$Address); 10278 %} 10279 ins_pipe(ialu_reg_mem); 10280 %} 10281 10282 instruct andnI_rReg_rReg_rReg(rRegI dst, rRegI src1, rRegI src2, immI_M1 minus_1, rFlagsReg cr) %{ 10283 match(Set dst (AndI (XorI src1 minus_1) src2)); 10284 predicate(UseBMI1Instructions); 10285 effect(KILL cr); 10286 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10287 10288 format %{ "andnl $dst, $src1, $src2" %} 10289 10290 ins_encode %{ 10291 __ andnl($dst$$Register, $src1$$Register, $src2$$Register); 10292 %} 10293 ins_pipe(ialu_reg); 10294 %} 10295 10296 instruct blsiI_rReg_rReg(rRegI dst, rRegI src, immI_0 imm_zero, rFlagsReg cr) %{ 10297 match(Set dst (AndI (SubI imm_zero src) src)); 10298 predicate(UseBMI1Instructions); 10299 effect(KILL cr); 10300 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 10301 10302 format %{ "blsil $dst, $src" %} 10303 10304 ins_encode %{ 10305 __ blsil($dst$$Register, $src$$Register); 10306 %} 10307 ins_pipe(ialu_reg); 10308 %} 10309 10310 instruct blsiI_rReg_mem(rRegI dst, memory src, immI_0 imm_zero, rFlagsReg cr) %{ 10311 match(Set dst (AndI (SubI imm_zero (LoadI src) ) (LoadI src) )); 10312 predicate(UseBMI1Instructions); 10313 effect(KILL cr); 10314 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 10315 10316 ins_cost(125); 10317 format %{ "blsil $dst, $src" %} 10318 10319 ins_encode %{ 10320 __ blsil($dst$$Register, $src$$Address); 10321 %} 10322 ins_pipe(ialu_reg_mem); 10323 %} 10324 10325 instruct blsmskI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 10326 %{ 10327 match(Set dst (XorI (AddI (LoadI src) minus_1) (LoadI src) ) ); 10328 predicate(UseBMI1Instructions); 10329 effect(KILL cr); 10330 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 10331 10332 ins_cost(125); 10333 format %{ "blsmskl $dst, $src" %} 10334 10335 ins_encode %{ 10336 __ blsmskl($dst$$Register, $src$$Address); 10337 %} 10338 ins_pipe(ialu_reg_mem); 10339 %} 10340 10341 instruct blsmskI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 10342 %{ 10343 match(Set dst (XorI (AddI src minus_1) src)); 10344 predicate(UseBMI1Instructions); 10345 effect(KILL cr); 10346 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 10347 10348 format %{ "blsmskl $dst, $src" %} 10349 10350 ins_encode %{ 10351 __ blsmskl($dst$$Register, $src$$Register); 10352 %} 10353 10354 ins_pipe(ialu_reg); 10355 %} 10356 10357 instruct blsrI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 10358 %{ 10359 match(Set dst (AndI (AddI src minus_1) src) ); 10360 predicate(UseBMI1Instructions); 10361 effect(KILL cr); 10362 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 10363 10364 format %{ "blsrl $dst, $src" %} 10365 10366 ins_encode %{ 10367 __ blsrl($dst$$Register, $src$$Register); 10368 %} 10369 10370 ins_pipe(ialu_reg_mem); 10371 %} 10372 10373 instruct blsrI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 10374 %{ 10375 match(Set dst (AndI (AddI (LoadI src) minus_1) (LoadI src) ) ); 10376 predicate(UseBMI1Instructions); 10377 effect(KILL cr); 10378 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 10379 10380 ins_cost(125); 10381 format %{ "blsrl $dst, $src" %} 10382 10383 ins_encode %{ 10384 __ blsrl($dst$$Register, $src$$Address); 10385 %} 10386 10387 ins_pipe(ialu_reg); 10388 %} 10389 10390 // Or Instructions 10391 // Or Register with Register 10392 instruct orI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 10393 %{ 10394 predicate(!UseAPX); 10395 match(Set dst (OrI dst src)); 10396 effect(KILL cr); 10397 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10398 10399 format %{ "orl $dst, $src\t# int" %} 10400 ins_encode %{ 10401 __ orl($dst$$Register, $src$$Register); 10402 %} 10403 ins_pipe(ialu_reg_reg); 10404 %} 10405 10406 // Or Register with Register using New Data Destination (NDD) 10407 instruct orI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr) 10408 %{ 10409 predicate(UseAPX); 10410 match(Set dst (OrI src1 src2)); 10411 effect(KILL cr); 10412 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10413 10414 format %{ "eorl $dst, $src1, $src2\t# int ndd" %} 10415 ins_encode %{ 10416 __ eorl($dst$$Register, $src1$$Register, $src2$$Register, false); 10417 %} 10418 ins_pipe(ialu_reg_reg); 10419 %} 10420 10421 // Or Register with Immediate 10422 instruct orI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 10423 %{ 10424 predicate(!UseAPX); 10425 match(Set dst (OrI dst src)); 10426 effect(KILL cr); 10427 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10428 10429 format %{ "orl $dst, $src\t# int" %} 10430 ins_encode %{ 10431 __ orl($dst$$Register, $src$$constant); 10432 %} 10433 ins_pipe(ialu_reg); 10434 %} 10435 10436 instruct orI_rReg_rReg_imm_ndd(rRegI dst, rRegI src1, immI src2, rFlagsReg cr) 10437 %{ 10438 predicate(UseAPX); 10439 match(Set dst (OrI src1 src2)); 10440 effect(KILL cr); 10441 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10442 10443 format %{ "eorl $dst, $src1, $src2\t# int ndd" %} 10444 ins_encode %{ 10445 __ eorl($dst$$Register, $src1$$Register, $src2$$constant, false); 10446 %} 10447 ins_pipe(ialu_reg); 10448 %} 10449 10450 instruct orI_rReg_imm_rReg_ndd(rRegI dst, immI src1, rRegI src2, rFlagsReg cr) 10451 %{ 10452 predicate(UseAPX); 10453 match(Set dst (OrI src1 src2)); 10454 effect(KILL cr); 10455 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10456 10457 format %{ "eorl $dst, $src2, $src1\t# int ndd" %} 10458 ins_encode %{ 10459 __ eorl($dst$$Register, $src2$$Register, $src1$$constant, false); 10460 %} 10461 ins_pipe(ialu_reg); 10462 %} 10463 10464 instruct orI_rReg_mem_imm_ndd(rRegI dst, memory src1, immI src2, rFlagsReg cr) 10465 %{ 10466 predicate(UseAPX); 10467 match(Set dst (OrI (LoadI src1) src2)); 10468 effect(KILL cr); 10469 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10470 10471 format %{ "eorl $dst, $src1, $src2\t# int ndd" %} 10472 ins_encode %{ 10473 __ eorl($dst$$Register, $src1$$Address, $src2$$constant, false); 10474 %} 10475 ins_pipe(ialu_reg); 10476 %} 10477 10478 // Or Register with Memory 10479 instruct orI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 10480 %{ 10481 predicate(!UseAPX); 10482 match(Set dst (OrI dst (LoadI src))); 10483 effect(KILL cr); 10484 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10485 10486 ins_cost(150); 10487 format %{ "orl $dst, $src\t# int" %} 10488 ins_encode %{ 10489 __ orl($dst$$Register, $src$$Address); 10490 %} 10491 ins_pipe(ialu_reg_mem); 10492 %} 10493 10494 instruct orI_rReg_rReg_mem_ndd(rRegI dst, rRegI src1, memory src2, rFlagsReg cr) 10495 %{ 10496 predicate(UseAPX); 10497 match(Set dst (OrI src1 (LoadI src2))); 10498 effect(KILL cr); 10499 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10500 10501 ins_cost(150); 10502 format %{ "eorl $dst, $src1, $src2\t# int ndd" %} 10503 ins_encode %{ 10504 __ eorl($dst$$Register, $src1$$Register, $src2$$Address, false); 10505 %} 10506 ins_pipe(ialu_reg_mem); 10507 %} 10508 10509 // Or Memory with Register 10510 instruct orB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 10511 %{ 10512 match(Set dst (StoreB dst (OrI (LoadB dst) src))); 10513 effect(KILL cr); 10514 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10515 10516 ins_cost(150); 10517 format %{ "orb $dst, $src\t# byte" %} 10518 ins_encode %{ 10519 __ orb($dst$$Address, $src$$Register); 10520 %} 10521 ins_pipe(ialu_mem_reg); 10522 %} 10523 10524 instruct orI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 10525 %{ 10526 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 10527 effect(KILL cr); 10528 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10529 10530 ins_cost(150); 10531 format %{ "orl $dst, $src\t# int" %} 10532 ins_encode %{ 10533 __ orl($dst$$Address, $src$$Register); 10534 %} 10535 ins_pipe(ialu_mem_reg); 10536 %} 10537 10538 // Or Memory with Immediate 10539 instruct orI_mem_imm(memory dst, immI src, rFlagsReg cr) 10540 %{ 10541 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 10542 effect(KILL cr); 10543 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10544 10545 ins_cost(125); 10546 format %{ "orl $dst, $src\t# int" %} 10547 ins_encode %{ 10548 __ orl($dst$$Address, $src$$constant); 10549 %} 10550 ins_pipe(ialu_mem_imm); 10551 %} 10552 10553 // Xor Instructions 10554 // Xor Register with Register 10555 instruct xorI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 10556 %{ 10557 predicate(!UseAPX); 10558 match(Set dst (XorI dst src)); 10559 effect(KILL cr); 10560 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10561 10562 format %{ "xorl $dst, $src\t# int" %} 10563 ins_encode %{ 10564 __ xorl($dst$$Register, $src$$Register); 10565 %} 10566 ins_pipe(ialu_reg_reg); 10567 %} 10568 10569 // Xor Register with Register using New Data Destination (NDD) 10570 instruct xorI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr) 10571 %{ 10572 predicate(UseAPX); 10573 match(Set dst (XorI src1 src2)); 10574 effect(KILL cr); 10575 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10576 10577 format %{ "exorl $dst, $src1, $src2\t# int ndd" %} 10578 ins_encode %{ 10579 __ exorl($dst$$Register, $src1$$Register, $src2$$Register, false); 10580 %} 10581 ins_pipe(ialu_reg_reg); 10582 %} 10583 10584 // Xor Register with Immediate -1 10585 instruct xorI_rReg_im1(rRegI dst, immI_M1 imm) 10586 %{ 10587 predicate(!UseAPX); 10588 match(Set dst (XorI dst imm)); 10589 10590 format %{ "notl $dst" %} 10591 ins_encode %{ 10592 __ notl($dst$$Register); 10593 %} 10594 ins_pipe(ialu_reg); 10595 %} 10596 10597 instruct xorI_rReg_im1_ndd(rRegI dst, rRegI src, immI_M1 imm) 10598 %{ 10599 match(Set dst (XorI src imm)); 10600 predicate(UseAPX); 10601 10602 format %{ "enotl $dst, $src" %} 10603 ins_encode %{ 10604 __ enotl($dst$$Register, $src$$Register); 10605 %} 10606 ins_pipe(ialu_reg); 10607 %} 10608 10609 // Xor Register with Immediate 10610 instruct xorI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 10611 %{ 10612 predicate(!UseAPX); 10613 match(Set dst (XorI dst src)); 10614 effect(KILL cr); 10615 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10616 10617 format %{ "xorl $dst, $src\t# int" %} 10618 ins_encode %{ 10619 __ xorl($dst$$Register, $src$$constant); 10620 %} 10621 ins_pipe(ialu_reg); 10622 %} 10623 10624 instruct xorI_rReg_rReg_imm_ndd(rRegI dst, rRegI src1, immI src2, rFlagsReg cr) 10625 %{ 10626 predicate(UseAPX); 10627 match(Set dst (XorI src1 src2)); 10628 effect(KILL cr); 10629 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10630 10631 format %{ "exorl $dst, $src1, $src2\t# int ndd" %} 10632 ins_encode %{ 10633 __ exorl($dst$$Register, $src1$$Register, $src2$$constant, false); 10634 %} 10635 ins_pipe(ialu_reg); 10636 %} 10637 10638 // Xor Memory with Immediate 10639 instruct xorI_rReg_mem_imm_ndd(rRegI dst, memory src1, immI src2, rFlagsReg cr) 10640 %{ 10641 predicate(UseAPX); 10642 match(Set dst (XorI (LoadI src1) src2)); 10643 effect(KILL cr); 10644 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10645 10646 format %{ "exorl $dst, $src1, $src2\t# int ndd" %} 10647 ins_encode %{ 10648 __ exorl($dst$$Register, $src1$$Address, $src2$$constant, false); 10649 %} 10650 ins_pipe(ialu_reg); 10651 %} 10652 10653 // Xor Register with Memory 10654 instruct xorI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 10655 %{ 10656 predicate(!UseAPX); 10657 match(Set dst (XorI dst (LoadI src))); 10658 effect(KILL cr); 10659 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10660 10661 ins_cost(150); 10662 format %{ "xorl $dst, $src\t# int" %} 10663 ins_encode %{ 10664 __ xorl($dst$$Register, $src$$Address); 10665 %} 10666 ins_pipe(ialu_reg_mem); 10667 %} 10668 10669 instruct xorI_rReg_rReg_mem_ndd(rRegI dst, rRegI src1, memory src2, rFlagsReg cr) 10670 %{ 10671 predicate(UseAPX); 10672 match(Set dst (XorI src1 (LoadI src2))); 10673 effect(KILL cr); 10674 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10675 10676 ins_cost(150); 10677 format %{ "exorl $dst, $src1, $src2\t# int ndd" %} 10678 ins_encode %{ 10679 __ exorl($dst$$Register, $src1$$Register, $src2$$Address, false); 10680 %} 10681 ins_pipe(ialu_reg_mem); 10682 %} 10683 10684 instruct xorI_rReg_mem_rReg_ndd(rRegI dst, memory src1, rRegI src2, rFlagsReg cr) 10685 %{ 10686 predicate(UseAPX); 10687 match(Set dst (XorI (LoadI src1) src2)); 10688 effect(KILL cr); 10689 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10690 10691 ins_cost(150); 10692 format %{ "exorl $dst, $src1, $src2\t# int ndd" %} 10693 ins_encode %{ 10694 __ exorl($dst$$Register, $src1$$Address, $src2$$Register, false); 10695 %} 10696 ins_pipe(ialu_reg_mem); 10697 %} 10698 10699 // Xor Memory with Register 10700 instruct xorB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 10701 %{ 10702 match(Set dst (StoreB dst (XorI (LoadB dst) src))); 10703 effect(KILL cr); 10704 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10705 10706 ins_cost(150); 10707 format %{ "xorb $dst, $src\t# byte" %} 10708 ins_encode %{ 10709 __ xorb($dst$$Address, $src$$Register); 10710 %} 10711 ins_pipe(ialu_mem_reg); 10712 %} 10713 10714 instruct xorI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 10715 %{ 10716 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 10717 effect(KILL cr); 10718 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10719 10720 ins_cost(150); 10721 format %{ "xorl $dst, $src\t# int" %} 10722 ins_encode %{ 10723 __ xorl($dst$$Address, $src$$Register); 10724 %} 10725 ins_pipe(ialu_mem_reg); 10726 %} 10727 10728 // Xor Memory with Immediate 10729 instruct xorI_mem_imm(memory dst, immI src, rFlagsReg cr) 10730 %{ 10731 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 10732 effect(KILL cr); 10733 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10734 10735 ins_cost(125); 10736 format %{ "xorl $dst, $src\t# int" %} 10737 ins_encode %{ 10738 __ xorl($dst$$Address, $src$$constant); 10739 %} 10740 ins_pipe(ialu_mem_imm); 10741 %} 10742 10743 10744 // Long Logical Instructions 10745 10746 // And Instructions 10747 // And Register with Register 10748 instruct andL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 10749 %{ 10750 predicate(!UseAPX); 10751 match(Set dst (AndL dst src)); 10752 effect(KILL cr); 10753 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10754 10755 format %{ "andq $dst, $src\t# long" %} 10756 ins_encode %{ 10757 __ andq($dst$$Register, $src$$Register); 10758 %} 10759 ins_pipe(ialu_reg_reg); 10760 %} 10761 10762 // And Register with Register using New Data Destination (NDD) 10763 instruct andL_rReg_ndd(rRegL dst, rRegL src1, rRegL src2, rFlagsReg cr) 10764 %{ 10765 predicate(UseAPX); 10766 match(Set dst (AndL src1 src2)); 10767 effect(KILL cr); 10768 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10769 10770 format %{ "eandq $dst, $src1, $src2\t# long ndd" %} 10771 ins_encode %{ 10772 __ eandq($dst$$Register, $src1$$Register, $src2$$Register, false); 10773 10774 %} 10775 ins_pipe(ialu_reg_reg); 10776 %} 10777 10778 // And Register with Immediate 255 10779 instruct andL_rReg_imm255(rRegL dst, rRegL src, immL_255 mask) 10780 %{ 10781 match(Set dst (AndL src mask)); 10782 10783 format %{ "movzbl $dst, $src\t# long & 0xFF" %} 10784 ins_encode %{ 10785 // movzbl zeroes out the upper 32-bit and does not need REX.W 10786 __ movzbl($dst$$Register, $src$$Register); 10787 %} 10788 ins_pipe(ialu_reg); 10789 %} 10790 10791 // And Register with Immediate 65535 10792 instruct andL_rReg_imm65535(rRegL dst, rRegL src, immL_65535 mask) 10793 %{ 10794 match(Set dst (AndL src mask)); 10795 10796 format %{ "movzwl $dst, $src\t# long & 0xFFFF" %} 10797 ins_encode %{ 10798 // movzwl zeroes out the upper 32-bit and does not need REX.W 10799 __ movzwl($dst$$Register, $src$$Register); 10800 %} 10801 ins_pipe(ialu_reg); 10802 %} 10803 10804 // And Register with Immediate 10805 instruct andL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 10806 %{ 10807 predicate(!UseAPX); 10808 match(Set dst (AndL dst src)); 10809 effect(KILL cr); 10810 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10811 10812 format %{ "andq $dst, $src\t# long" %} 10813 ins_encode %{ 10814 __ andq($dst$$Register, $src$$constant); 10815 %} 10816 ins_pipe(ialu_reg); 10817 %} 10818 10819 instruct andL_rReg_rReg_imm_ndd(rRegL dst, rRegL src1, immL32 src2, rFlagsReg cr) 10820 %{ 10821 predicate(UseAPX); 10822 match(Set dst (AndL src1 src2)); 10823 effect(KILL cr); 10824 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10825 10826 format %{ "eandq $dst, $src1, $src2\t# long ndd" %} 10827 ins_encode %{ 10828 __ eandq($dst$$Register, $src1$$Register, $src2$$constant, false); 10829 %} 10830 ins_pipe(ialu_reg); 10831 %} 10832 10833 instruct andL_rReg_mem_imm_ndd(rRegL dst, memory src1, immL32 src2, rFlagsReg cr) 10834 %{ 10835 predicate(UseAPX); 10836 match(Set dst (AndL (LoadL src1) src2)); 10837 effect(KILL cr); 10838 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10839 10840 format %{ "eandq $dst, $src1, $src2\t# long ndd" %} 10841 ins_encode %{ 10842 __ eandq($dst$$Register, $src1$$Address, $src2$$constant, false); 10843 %} 10844 ins_pipe(ialu_reg); 10845 %} 10846 10847 // And Register with Memory 10848 instruct andL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 10849 %{ 10850 predicate(!UseAPX); 10851 match(Set dst (AndL dst (LoadL src))); 10852 effect(KILL cr); 10853 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10854 10855 ins_cost(150); 10856 format %{ "andq $dst, $src\t# long" %} 10857 ins_encode %{ 10858 __ andq($dst$$Register, $src$$Address); 10859 %} 10860 ins_pipe(ialu_reg_mem); 10861 %} 10862 10863 instruct andL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr) 10864 %{ 10865 predicate(UseAPX); 10866 match(Set dst (AndL src1 (LoadL src2))); 10867 effect(KILL cr); 10868 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10869 10870 ins_cost(150); 10871 format %{ "eandq $dst, $src1, $src2\t# long ndd" %} 10872 ins_encode %{ 10873 __ eandq($dst$$Register, $src1$$Register, $src2$$Address, false); 10874 %} 10875 ins_pipe(ialu_reg_mem); 10876 %} 10877 10878 instruct andL_rReg_mem_rReg_ndd(rRegL dst, memory src1, rRegL src2, rFlagsReg cr) 10879 %{ 10880 predicate(UseAPX); 10881 match(Set dst (AndL (LoadL src1) src2)); 10882 effect(KILL cr); 10883 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10884 10885 ins_cost(150); 10886 format %{ "eandq $dst, $src1, $src2\t# long ndd" %} 10887 ins_encode %{ 10888 __ eandq($dst$$Register, $src1$$Address, $src2$$Register, false); 10889 %} 10890 ins_pipe(ialu_reg_mem); 10891 %} 10892 10893 // And Memory with Register 10894 instruct andL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 10895 %{ 10896 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 10897 effect(KILL cr); 10898 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10899 10900 ins_cost(150); 10901 format %{ "andq $dst, $src\t# long" %} 10902 ins_encode %{ 10903 __ andq($dst$$Address, $src$$Register); 10904 %} 10905 ins_pipe(ialu_mem_reg); 10906 %} 10907 10908 // And Memory with Immediate 10909 instruct andL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 10910 %{ 10911 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 10912 effect(KILL cr); 10913 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10914 10915 ins_cost(125); 10916 format %{ "andq $dst, $src\t# long" %} 10917 ins_encode %{ 10918 __ andq($dst$$Address, $src$$constant); 10919 %} 10920 ins_pipe(ialu_mem_imm); 10921 %} 10922 10923 instruct btrL_mem_imm(memory dst, immL_NotPow2 con, rFlagsReg cr) 10924 %{ 10925 // con should be a pure 64-bit immediate given that not(con) is a power of 2 10926 // because AND/OR works well enough for 8/32-bit values. 10927 predicate(log2i_graceful(~n->in(3)->in(2)->get_long()) > 30); 10928 10929 match(Set dst (StoreL dst (AndL (LoadL dst) con))); 10930 effect(KILL cr); 10931 10932 ins_cost(125); 10933 format %{ "btrq $dst, log2(not($con))\t# long" %} 10934 ins_encode %{ 10935 __ btrq($dst$$Address, log2i_exact((julong)~$con$$constant)); 10936 %} 10937 ins_pipe(ialu_mem_imm); 10938 %} 10939 10940 // BMI1 instructions 10941 instruct andnL_rReg_rReg_mem(rRegL dst, rRegL src1, memory src2, immL_M1 minus_1, rFlagsReg cr) %{ 10942 match(Set dst (AndL (XorL src1 minus_1) (LoadL src2))); 10943 predicate(UseBMI1Instructions); 10944 effect(KILL cr); 10945 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10946 10947 ins_cost(125); 10948 format %{ "andnq $dst, $src1, $src2" %} 10949 10950 ins_encode %{ 10951 __ andnq($dst$$Register, $src1$$Register, $src2$$Address); 10952 %} 10953 ins_pipe(ialu_reg_mem); 10954 %} 10955 10956 instruct andnL_rReg_rReg_rReg(rRegL dst, rRegL src1, rRegL src2, immL_M1 minus_1, rFlagsReg cr) %{ 10957 match(Set dst (AndL (XorL src1 minus_1) src2)); 10958 predicate(UseBMI1Instructions); 10959 effect(KILL cr); 10960 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10961 10962 format %{ "andnq $dst, $src1, $src2" %} 10963 10964 ins_encode %{ 10965 __ andnq($dst$$Register, $src1$$Register, $src2$$Register); 10966 %} 10967 ins_pipe(ialu_reg_mem); 10968 %} 10969 10970 instruct blsiL_rReg_rReg(rRegL dst, rRegL src, immL0 imm_zero, rFlagsReg cr) %{ 10971 match(Set dst (AndL (SubL imm_zero src) src)); 10972 predicate(UseBMI1Instructions); 10973 effect(KILL cr); 10974 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 10975 10976 format %{ "blsiq $dst, $src" %} 10977 10978 ins_encode %{ 10979 __ blsiq($dst$$Register, $src$$Register); 10980 %} 10981 ins_pipe(ialu_reg); 10982 %} 10983 10984 instruct blsiL_rReg_mem(rRegL dst, memory src, immL0 imm_zero, rFlagsReg cr) %{ 10985 match(Set dst (AndL (SubL imm_zero (LoadL src) ) (LoadL src) )); 10986 predicate(UseBMI1Instructions); 10987 effect(KILL cr); 10988 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 10989 10990 ins_cost(125); 10991 format %{ "blsiq $dst, $src" %} 10992 10993 ins_encode %{ 10994 __ blsiq($dst$$Register, $src$$Address); 10995 %} 10996 ins_pipe(ialu_reg_mem); 10997 %} 10998 10999 instruct blsmskL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 11000 %{ 11001 match(Set dst (XorL (AddL (LoadL src) minus_1) (LoadL src) ) ); 11002 predicate(UseBMI1Instructions); 11003 effect(KILL cr); 11004 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 11005 11006 ins_cost(125); 11007 format %{ "blsmskq $dst, $src" %} 11008 11009 ins_encode %{ 11010 __ blsmskq($dst$$Register, $src$$Address); 11011 %} 11012 ins_pipe(ialu_reg_mem); 11013 %} 11014 11015 instruct blsmskL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 11016 %{ 11017 match(Set dst (XorL (AddL src minus_1) src)); 11018 predicate(UseBMI1Instructions); 11019 effect(KILL cr); 11020 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 11021 11022 format %{ "blsmskq $dst, $src" %} 11023 11024 ins_encode %{ 11025 __ blsmskq($dst$$Register, $src$$Register); 11026 %} 11027 11028 ins_pipe(ialu_reg); 11029 %} 11030 11031 instruct blsrL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 11032 %{ 11033 match(Set dst (AndL (AddL src minus_1) src) ); 11034 predicate(UseBMI1Instructions); 11035 effect(KILL cr); 11036 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 11037 11038 format %{ "blsrq $dst, $src" %} 11039 11040 ins_encode %{ 11041 __ blsrq($dst$$Register, $src$$Register); 11042 %} 11043 11044 ins_pipe(ialu_reg); 11045 %} 11046 11047 instruct blsrL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 11048 %{ 11049 match(Set dst (AndL (AddL (LoadL src) minus_1) (LoadL src)) ); 11050 predicate(UseBMI1Instructions); 11051 effect(KILL cr); 11052 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 11053 11054 ins_cost(125); 11055 format %{ "blsrq $dst, $src" %} 11056 11057 ins_encode %{ 11058 __ blsrq($dst$$Register, $src$$Address); 11059 %} 11060 11061 ins_pipe(ialu_reg); 11062 %} 11063 11064 // Or Instructions 11065 // Or Register with Register 11066 instruct orL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 11067 %{ 11068 predicate(!UseAPX); 11069 match(Set dst (OrL dst src)); 11070 effect(KILL cr); 11071 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11072 11073 format %{ "orq $dst, $src\t# long" %} 11074 ins_encode %{ 11075 __ orq($dst$$Register, $src$$Register); 11076 %} 11077 ins_pipe(ialu_reg_reg); 11078 %} 11079 11080 // Or Register with Register using New Data Destination (NDD) 11081 instruct orL_rReg_ndd(rRegL dst, rRegL src1, rRegL src2, rFlagsReg cr) 11082 %{ 11083 predicate(UseAPX); 11084 match(Set dst (OrL src1 src2)); 11085 effect(KILL cr); 11086 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11087 11088 format %{ "eorq $dst, $src1, $src2\t# long ndd" %} 11089 ins_encode %{ 11090 __ eorq($dst$$Register, $src1$$Register, $src2$$Register, false); 11091 11092 %} 11093 ins_pipe(ialu_reg_reg); 11094 %} 11095 11096 // Use any_RegP to match R15 (TLS register) without spilling. 11097 instruct orL_rReg_castP2X(rRegL dst, any_RegP src, rFlagsReg cr) %{ 11098 match(Set dst (OrL dst (CastP2X src))); 11099 effect(KILL cr); 11100 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11101 11102 format %{ "orq $dst, $src\t# long" %} 11103 ins_encode %{ 11104 __ orq($dst$$Register, $src$$Register); 11105 %} 11106 ins_pipe(ialu_reg_reg); 11107 %} 11108 11109 instruct orL_rReg_castP2X_ndd(rRegL dst, any_RegP src1, any_RegP src2, rFlagsReg cr) %{ 11110 match(Set dst (OrL src1 (CastP2X src2))); 11111 effect(KILL cr); 11112 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11113 11114 format %{ "eorq $dst, $src1, $src2\t# long ndd" %} 11115 ins_encode %{ 11116 __ eorq($dst$$Register, $src1$$Register, $src2$$Register, false); 11117 %} 11118 ins_pipe(ialu_reg_reg); 11119 %} 11120 11121 // Or Register with Immediate 11122 instruct orL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 11123 %{ 11124 predicate(!UseAPX); 11125 match(Set dst (OrL dst src)); 11126 effect(KILL cr); 11127 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11128 11129 format %{ "orq $dst, $src\t# long" %} 11130 ins_encode %{ 11131 __ orq($dst$$Register, $src$$constant); 11132 %} 11133 ins_pipe(ialu_reg); 11134 %} 11135 11136 instruct orL_rReg_rReg_imm_ndd(rRegL dst, rRegL src1, immL32 src2, rFlagsReg cr) 11137 %{ 11138 predicate(UseAPX); 11139 match(Set dst (OrL src1 src2)); 11140 effect(KILL cr); 11141 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11142 11143 format %{ "eorq $dst, $src1, $src2\t# long ndd" %} 11144 ins_encode %{ 11145 __ eorq($dst$$Register, $src1$$Register, $src2$$constant, false); 11146 %} 11147 ins_pipe(ialu_reg); 11148 %} 11149 11150 instruct orL_rReg_imm_rReg_ndd(rRegL dst, immL32 src1, rRegL src2, rFlagsReg cr) 11151 %{ 11152 predicate(UseAPX); 11153 match(Set dst (OrL src1 src2)); 11154 effect(KILL cr); 11155 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11156 11157 format %{ "eorq $dst, $src2, $src1\t# long ndd" %} 11158 ins_encode %{ 11159 __ eorq($dst$$Register, $src2$$Register, $src1$$constant, false); 11160 %} 11161 ins_pipe(ialu_reg); 11162 %} 11163 11164 // Or Memory with Immediate 11165 instruct orL_rReg_mem_imm_ndd(rRegL dst, memory src1, immL32 src2, rFlagsReg cr) 11166 %{ 11167 predicate(UseAPX); 11168 match(Set dst (OrL (LoadL src1) src2)); 11169 effect(KILL cr); 11170 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11171 11172 format %{ "eorq $dst, $src1, $src2\t# long ndd" %} 11173 ins_encode %{ 11174 __ eorq($dst$$Register, $src1$$Address, $src2$$constant, false); 11175 %} 11176 ins_pipe(ialu_reg); 11177 %} 11178 11179 // Or Register with Memory 11180 instruct orL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 11181 %{ 11182 predicate(!UseAPX); 11183 match(Set dst (OrL dst (LoadL src))); 11184 effect(KILL cr); 11185 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11186 11187 ins_cost(150); 11188 format %{ "orq $dst, $src\t# long" %} 11189 ins_encode %{ 11190 __ orq($dst$$Register, $src$$Address); 11191 %} 11192 ins_pipe(ialu_reg_mem); 11193 %} 11194 11195 instruct orL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr) 11196 %{ 11197 predicate(UseAPX); 11198 match(Set dst (OrL src1 (LoadL src2))); 11199 effect(KILL cr); 11200 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11201 11202 ins_cost(150); 11203 format %{ "eorq $dst, $src1, $src2\t# long ndd" %} 11204 ins_encode %{ 11205 __ eorq($dst$$Register, $src1$$Register, $src2$$Address, false); 11206 %} 11207 ins_pipe(ialu_reg_mem); 11208 %} 11209 11210 // Or Memory with Register 11211 instruct orL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 11212 %{ 11213 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 11214 effect(KILL cr); 11215 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11216 11217 ins_cost(150); 11218 format %{ "orq $dst, $src\t# long" %} 11219 ins_encode %{ 11220 __ orq($dst$$Address, $src$$Register); 11221 %} 11222 ins_pipe(ialu_mem_reg); 11223 %} 11224 11225 // Or Memory with Immediate 11226 instruct orL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 11227 %{ 11228 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 11229 effect(KILL cr); 11230 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11231 11232 ins_cost(125); 11233 format %{ "orq $dst, $src\t# long" %} 11234 ins_encode %{ 11235 __ orq($dst$$Address, $src$$constant); 11236 %} 11237 ins_pipe(ialu_mem_imm); 11238 %} 11239 11240 instruct btsL_mem_imm(memory dst, immL_Pow2 con, rFlagsReg cr) 11241 %{ 11242 // con should be a pure 64-bit power of 2 immediate 11243 // because AND/OR works well enough for 8/32-bit values. 11244 predicate(log2i_graceful(n->in(3)->in(2)->get_long()) > 31); 11245 11246 match(Set dst (StoreL dst (OrL (LoadL dst) con))); 11247 effect(KILL cr); 11248 11249 ins_cost(125); 11250 format %{ "btsq $dst, log2($con)\t# long" %} 11251 ins_encode %{ 11252 __ btsq($dst$$Address, log2i_exact((julong)$con$$constant)); 11253 %} 11254 ins_pipe(ialu_mem_imm); 11255 %} 11256 11257 // Xor Instructions 11258 // Xor Register with Register 11259 instruct xorL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 11260 %{ 11261 predicate(!UseAPX); 11262 match(Set dst (XorL dst src)); 11263 effect(KILL cr); 11264 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11265 11266 format %{ "xorq $dst, $src\t# long" %} 11267 ins_encode %{ 11268 __ xorq($dst$$Register, $src$$Register); 11269 %} 11270 ins_pipe(ialu_reg_reg); 11271 %} 11272 11273 // Xor Register with Register using New Data Destination (NDD) 11274 instruct xorL_rReg_ndd(rRegL dst, rRegL src1, rRegL src2, rFlagsReg cr) 11275 %{ 11276 predicate(UseAPX); 11277 match(Set dst (XorL src1 src2)); 11278 effect(KILL cr); 11279 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11280 11281 format %{ "exorq $dst, $src1, $src2\t# long ndd" %} 11282 ins_encode %{ 11283 __ exorq($dst$$Register, $src1$$Register, $src2$$Register, false); 11284 %} 11285 ins_pipe(ialu_reg_reg); 11286 %} 11287 11288 // Xor Register with Immediate -1 11289 instruct xorL_rReg_im1(rRegL dst, immL_M1 imm) 11290 %{ 11291 predicate(!UseAPX); 11292 match(Set dst (XorL dst imm)); 11293 11294 format %{ "notq $dst" %} 11295 ins_encode %{ 11296 __ notq($dst$$Register); 11297 %} 11298 ins_pipe(ialu_reg); 11299 %} 11300 11301 instruct xorL_rReg_im1_ndd(rRegL dst,rRegL src, immL_M1 imm) 11302 %{ 11303 predicate(UseAPX); 11304 match(Set dst (XorL src imm)); 11305 11306 format %{ "enotq $dst, $src" %} 11307 ins_encode %{ 11308 __ enotq($dst$$Register, $src$$Register); 11309 %} 11310 ins_pipe(ialu_reg); 11311 %} 11312 11313 // Xor Register with Immediate 11314 instruct xorL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 11315 %{ 11316 predicate(!UseAPX); 11317 match(Set dst (XorL dst src)); 11318 effect(KILL cr); 11319 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11320 11321 format %{ "xorq $dst, $src\t# long" %} 11322 ins_encode %{ 11323 __ xorq($dst$$Register, $src$$constant); 11324 %} 11325 ins_pipe(ialu_reg); 11326 %} 11327 11328 instruct xorL_rReg_rReg_imm(rRegL dst, rRegL src1, immL32 src2, rFlagsReg cr) 11329 %{ 11330 predicate(UseAPX); 11331 match(Set dst (XorL src1 src2)); 11332 effect(KILL cr); 11333 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11334 11335 format %{ "exorq $dst, $src1, $src2\t# long ndd" %} 11336 ins_encode %{ 11337 __ exorq($dst$$Register, $src1$$Register, $src2$$constant, false); 11338 %} 11339 ins_pipe(ialu_reg); 11340 %} 11341 11342 // Xor Memory with Immediate 11343 instruct xorL_rReg_mem_imm(rRegL dst, memory src1, immL32 src2, rFlagsReg cr) 11344 %{ 11345 predicate(UseAPX); 11346 match(Set dst (XorL (LoadL src1) src2)); 11347 effect(KILL cr); 11348 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11349 11350 format %{ "exorq $dst, $src1, $src2\t# long ndd" %} 11351 ins_encode %{ 11352 __ exorq($dst$$Register, $src1$$Address, $src2$$constant, false); 11353 %} 11354 ins_pipe(ialu_reg); 11355 %} 11356 11357 // Xor Register with Memory 11358 instruct xorL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 11359 %{ 11360 predicate(!UseAPX); 11361 match(Set dst (XorL dst (LoadL src))); 11362 effect(KILL cr); 11363 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11364 11365 ins_cost(150); 11366 format %{ "xorq $dst, $src\t# long" %} 11367 ins_encode %{ 11368 __ xorq($dst$$Register, $src$$Address); 11369 %} 11370 ins_pipe(ialu_reg_mem); 11371 %} 11372 11373 instruct xorL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr) 11374 %{ 11375 predicate(UseAPX); 11376 match(Set dst (XorL src1 (LoadL src2))); 11377 effect(KILL cr); 11378 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11379 11380 ins_cost(150); 11381 format %{ "exorq $dst, $src1, $src2\t# long ndd" %} 11382 ins_encode %{ 11383 __ exorq($dst$$Register, $src1$$Register, $src2$$Address, false); 11384 %} 11385 ins_pipe(ialu_reg_mem); 11386 %} 11387 11388 instruct xorL_rReg_mem_rReg_ndd(rRegL dst, memory src1, rRegL src2, rFlagsReg cr) 11389 %{ 11390 predicate(UseAPX); 11391 match(Set dst (XorL (LoadL src1) src2)); 11392 effect(KILL cr); 11393 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11394 11395 ins_cost(150); 11396 format %{ "exorq $dst, $src1, $src2\t# long ndd" %} 11397 ins_encode %{ 11398 __ exorq($dst$$Register, $src1$$Address, $src2$$Register, false); 11399 %} 11400 ins_pipe(ialu_reg_mem); 11401 %} 11402 11403 // Xor Memory with Register 11404 instruct xorL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 11405 %{ 11406 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 11407 effect(KILL cr); 11408 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11409 11410 ins_cost(150); 11411 format %{ "xorq $dst, $src\t# long" %} 11412 ins_encode %{ 11413 __ xorq($dst$$Address, $src$$Register); 11414 %} 11415 ins_pipe(ialu_mem_reg); 11416 %} 11417 11418 // Xor Memory with Immediate 11419 instruct xorL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 11420 %{ 11421 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 11422 effect(KILL cr); 11423 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11424 11425 ins_cost(125); 11426 format %{ "xorq $dst, $src\t# long" %} 11427 ins_encode %{ 11428 __ xorq($dst$$Address, $src$$constant); 11429 %} 11430 ins_pipe(ialu_mem_imm); 11431 %} 11432 11433 instruct cmpLTMask(rRegI dst, rRegI p, rRegI q, rFlagsReg cr) 11434 %{ 11435 match(Set dst (CmpLTMask p q)); 11436 effect(KILL cr); 11437 11438 ins_cost(400); 11439 format %{ "cmpl $p, $q\t# cmpLTMask\n\t" 11440 "setcc $dst \t# emits setlt + movzbl or setzul for APX" 11441 "negl $dst" %} 11442 ins_encode %{ 11443 __ cmpl($p$$Register, $q$$Register); 11444 __ setcc(Assembler::less, $dst$$Register); 11445 __ negl($dst$$Register); 11446 %} 11447 ins_pipe(pipe_slow); 11448 %} 11449 11450 instruct cmpLTMask0(rRegI dst, immI_0 zero, rFlagsReg cr) 11451 %{ 11452 match(Set dst (CmpLTMask dst zero)); 11453 effect(KILL cr); 11454 11455 ins_cost(100); 11456 format %{ "sarl $dst, #31\t# cmpLTMask0" %} 11457 ins_encode %{ 11458 __ sarl($dst$$Register, 31); 11459 %} 11460 ins_pipe(ialu_reg); 11461 %} 11462 11463 /* Better to save a register than avoid a branch */ 11464 instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 11465 %{ 11466 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q))); 11467 effect(KILL cr); 11468 ins_cost(300); 11469 format %{ "subl $p,$q\t# cadd_cmpLTMask\n\t" 11470 "jge done\n\t" 11471 "addl $p,$y\n" 11472 "done: " %} 11473 ins_encode %{ 11474 Register Rp = $p$$Register; 11475 Register Rq = $q$$Register; 11476 Register Ry = $y$$Register; 11477 Label done; 11478 __ subl(Rp, Rq); 11479 __ jccb(Assembler::greaterEqual, done); 11480 __ addl(Rp, Ry); 11481 __ bind(done); 11482 %} 11483 ins_pipe(pipe_cmplt); 11484 %} 11485 11486 /* Better to save a register than avoid a branch */ 11487 instruct and_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 11488 %{ 11489 match(Set y (AndI (CmpLTMask p q) y)); 11490 effect(KILL cr); 11491 11492 ins_cost(300); 11493 11494 format %{ "cmpl $p, $q\t# and_cmpLTMask\n\t" 11495 "jlt done\n\t" 11496 "xorl $y, $y\n" 11497 "done: " %} 11498 ins_encode %{ 11499 Register Rp = $p$$Register; 11500 Register Rq = $q$$Register; 11501 Register Ry = $y$$Register; 11502 Label done; 11503 __ cmpl(Rp, Rq); 11504 __ jccb(Assembler::less, done); 11505 __ xorl(Ry, Ry); 11506 __ bind(done); 11507 %} 11508 ins_pipe(pipe_cmplt); 11509 %} 11510 11511 11512 //---------- FP Instructions------------------------------------------------ 11513 11514 // Really expensive, avoid 11515 instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2) 11516 %{ 11517 match(Set cr (CmpF src1 src2)); 11518 11519 ins_cost(500); 11520 format %{ "ucomiss $src1, $src2\n\t" 11521 "jnp,s exit\n\t" 11522 "pushfq\t# saw NaN, set CF\n\t" 11523 "andq [rsp], #0xffffff2b\n\t" 11524 "popfq\n" 11525 "exit:" %} 11526 ins_encode %{ 11527 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 11528 emit_cmpfp_fixup(masm); 11529 %} 11530 ins_pipe(pipe_slow); 11531 %} 11532 11533 instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{ 11534 match(Set cr (CmpF src1 src2)); 11535 11536 ins_cost(100); 11537 format %{ "ucomiss $src1, $src2" %} 11538 ins_encode %{ 11539 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 11540 %} 11541 ins_pipe(pipe_slow); 11542 %} 11543 11544 instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{ 11545 match(Set cr (CmpF src1 (LoadF src2))); 11546 11547 ins_cost(100); 11548 format %{ "ucomiss $src1, $src2" %} 11549 ins_encode %{ 11550 __ ucomiss($src1$$XMMRegister, $src2$$Address); 11551 %} 11552 ins_pipe(pipe_slow); 11553 %} 11554 11555 instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src, immF con) %{ 11556 match(Set cr (CmpF src con)); 11557 ins_cost(100); 11558 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con" %} 11559 ins_encode %{ 11560 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 11561 %} 11562 ins_pipe(pipe_slow); 11563 %} 11564 11565 // Really expensive, avoid 11566 instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2) 11567 %{ 11568 match(Set cr (CmpD src1 src2)); 11569 11570 ins_cost(500); 11571 format %{ "ucomisd $src1, $src2\n\t" 11572 "jnp,s exit\n\t" 11573 "pushfq\t# saw NaN, set CF\n\t" 11574 "andq [rsp], #0xffffff2b\n\t" 11575 "popfq\n" 11576 "exit:" %} 11577 ins_encode %{ 11578 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 11579 emit_cmpfp_fixup(masm); 11580 %} 11581 ins_pipe(pipe_slow); 11582 %} 11583 11584 instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{ 11585 match(Set cr (CmpD src1 src2)); 11586 11587 ins_cost(100); 11588 format %{ "ucomisd $src1, $src2 test" %} 11589 ins_encode %{ 11590 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 11591 %} 11592 ins_pipe(pipe_slow); 11593 %} 11594 11595 instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{ 11596 match(Set cr (CmpD src1 (LoadD src2))); 11597 11598 ins_cost(100); 11599 format %{ "ucomisd $src1, $src2" %} 11600 ins_encode %{ 11601 __ ucomisd($src1$$XMMRegister, $src2$$Address); 11602 %} 11603 ins_pipe(pipe_slow); 11604 %} 11605 11606 instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src, immD con) %{ 11607 match(Set cr (CmpD src con)); 11608 ins_cost(100); 11609 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con" %} 11610 ins_encode %{ 11611 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 11612 %} 11613 ins_pipe(pipe_slow); 11614 %} 11615 11616 // Compare into -1,0,1 11617 instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr) 11618 %{ 11619 match(Set dst (CmpF3 src1 src2)); 11620 effect(KILL cr); 11621 11622 ins_cost(275); 11623 format %{ "ucomiss $src1, $src2\n\t" 11624 "movl $dst, #-1\n\t" 11625 "jp,s done\n\t" 11626 "jb,s done\n\t" 11627 "setne $dst\n\t" 11628 "movzbl $dst, $dst\n" 11629 "done:" %} 11630 ins_encode %{ 11631 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 11632 emit_cmpfp3(masm, $dst$$Register); 11633 %} 11634 ins_pipe(pipe_slow); 11635 %} 11636 11637 // Compare into -1,0,1 11638 instruct cmpF_mem(rRegI dst, regF src1, memory src2, rFlagsReg cr) 11639 %{ 11640 match(Set dst (CmpF3 src1 (LoadF src2))); 11641 effect(KILL cr); 11642 11643 ins_cost(275); 11644 format %{ "ucomiss $src1, $src2\n\t" 11645 "movl $dst, #-1\n\t" 11646 "jp,s done\n\t" 11647 "jb,s done\n\t" 11648 "setne $dst\n\t" 11649 "movzbl $dst, $dst\n" 11650 "done:" %} 11651 ins_encode %{ 11652 __ ucomiss($src1$$XMMRegister, $src2$$Address); 11653 emit_cmpfp3(masm, $dst$$Register); 11654 %} 11655 ins_pipe(pipe_slow); 11656 %} 11657 11658 // Compare into -1,0,1 11659 instruct cmpF_imm(rRegI dst, regF src, immF con, rFlagsReg cr) %{ 11660 match(Set dst (CmpF3 src con)); 11661 effect(KILL cr); 11662 11663 ins_cost(275); 11664 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 11665 "movl $dst, #-1\n\t" 11666 "jp,s done\n\t" 11667 "jb,s done\n\t" 11668 "setne $dst\n\t" 11669 "movzbl $dst, $dst\n" 11670 "done:" %} 11671 ins_encode %{ 11672 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 11673 emit_cmpfp3(masm, $dst$$Register); 11674 %} 11675 ins_pipe(pipe_slow); 11676 %} 11677 11678 // Compare into -1,0,1 11679 instruct cmpD_reg(rRegI dst, regD src1, regD src2, rFlagsReg cr) 11680 %{ 11681 match(Set dst (CmpD3 src1 src2)); 11682 effect(KILL cr); 11683 11684 ins_cost(275); 11685 format %{ "ucomisd $src1, $src2\n\t" 11686 "movl $dst, #-1\n\t" 11687 "jp,s done\n\t" 11688 "jb,s done\n\t" 11689 "setne $dst\n\t" 11690 "movzbl $dst, $dst\n" 11691 "done:" %} 11692 ins_encode %{ 11693 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 11694 emit_cmpfp3(masm, $dst$$Register); 11695 %} 11696 ins_pipe(pipe_slow); 11697 %} 11698 11699 // Compare into -1,0,1 11700 instruct cmpD_mem(rRegI dst, regD src1, memory src2, rFlagsReg cr) 11701 %{ 11702 match(Set dst (CmpD3 src1 (LoadD src2))); 11703 effect(KILL cr); 11704 11705 ins_cost(275); 11706 format %{ "ucomisd $src1, $src2\n\t" 11707 "movl $dst, #-1\n\t" 11708 "jp,s done\n\t" 11709 "jb,s done\n\t" 11710 "setne $dst\n\t" 11711 "movzbl $dst, $dst\n" 11712 "done:" %} 11713 ins_encode %{ 11714 __ ucomisd($src1$$XMMRegister, $src2$$Address); 11715 emit_cmpfp3(masm, $dst$$Register); 11716 %} 11717 ins_pipe(pipe_slow); 11718 %} 11719 11720 // Compare into -1,0,1 11721 instruct cmpD_imm(rRegI dst, regD src, immD con, rFlagsReg cr) %{ 11722 match(Set dst (CmpD3 src con)); 11723 effect(KILL cr); 11724 11725 ins_cost(275); 11726 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 11727 "movl $dst, #-1\n\t" 11728 "jp,s done\n\t" 11729 "jb,s done\n\t" 11730 "setne $dst\n\t" 11731 "movzbl $dst, $dst\n" 11732 "done:" %} 11733 ins_encode %{ 11734 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 11735 emit_cmpfp3(masm, $dst$$Register); 11736 %} 11737 ins_pipe(pipe_slow); 11738 %} 11739 11740 //----------Arithmetic Conversion Instructions--------------------------------- 11741 11742 instruct convF2D_reg_reg(regD dst, regF src) 11743 %{ 11744 match(Set dst (ConvF2D src)); 11745 11746 format %{ "cvtss2sd $dst, $src" %} 11747 ins_encode %{ 11748 __ cvtss2sd ($dst$$XMMRegister, $src$$XMMRegister); 11749 %} 11750 ins_pipe(pipe_slow); // XXX 11751 %} 11752 11753 instruct convF2D_reg_mem(regD dst, memory src) 11754 %{ 11755 predicate(UseAVX == 0); 11756 match(Set dst (ConvF2D (LoadF src))); 11757 11758 format %{ "cvtss2sd $dst, $src" %} 11759 ins_encode %{ 11760 __ cvtss2sd ($dst$$XMMRegister, $src$$Address); 11761 %} 11762 ins_pipe(pipe_slow); // XXX 11763 %} 11764 11765 instruct convD2F_reg_reg(regF dst, regD src) 11766 %{ 11767 match(Set dst (ConvD2F src)); 11768 11769 format %{ "cvtsd2ss $dst, $src" %} 11770 ins_encode %{ 11771 __ cvtsd2ss ($dst$$XMMRegister, $src$$XMMRegister); 11772 %} 11773 ins_pipe(pipe_slow); // XXX 11774 %} 11775 11776 instruct convD2F_reg_mem(regF dst, memory src) 11777 %{ 11778 predicate(UseAVX == 0); 11779 match(Set dst (ConvD2F (LoadD src))); 11780 11781 format %{ "cvtsd2ss $dst, $src" %} 11782 ins_encode %{ 11783 __ cvtsd2ss ($dst$$XMMRegister, $src$$Address); 11784 %} 11785 ins_pipe(pipe_slow); // XXX 11786 %} 11787 11788 // XXX do mem variants 11789 instruct convF2I_reg_reg(rRegI dst, regF src, rFlagsReg cr) 11790 %{ 11791 match(Set dst (ConvF2I src)); 11792 effect(KILL cr); 11793 format %{ "convert_f2i $dst, $src" %} 11794 ins_encode %{ 11795 __ convertF2I(T_INT, T_FLOAT, $dst$$Register, $src$$XMMRegister); 11796 %} 11797 ins_pipe(pipe_slow); 11798 %} 11799 11800 instruct convF2L_reg_reg(rRegL dst, regF src, rFlagsReg cr) 11801 %{ 11802 match(Set dst (ConvF2L src)); 11803 effect(KILL cr); 11804 format %{ "convert_f2l $dst, $src"%} 11805 ins_encode %{ 11806 __ convertF2I(T_LONG, T_FLOAT, $dst$$Register, $src$$XMMRegister); 11807 %} 11808 ins_pipe(pipe_slow); 11809 %} 11810 11811 instruct convD2I_reg_reg(rRegI dst, regD src, rFlagsReg cr) 11812 %{ 11813 match(Set dst (ConvD2I src)); 11814 effect(KILL cr); 11815 format %{ "convert_d2i $dst, $src"%} 11816 ins_encode %{ 11817 __ convertF2I(T_INT, T_DOUBLE, $dst$$Register, $src$$XMMRegister); 11818 %} 11819 ins_pipe(pipe_slow); 11820 %} 11821 11822 instruct convD2L_reg_reg(rRegL dst, regD src, rFlagsReg cr) 11823 %{ 11824 match(Set dst (ConvD2L src)); 11825 effect(KILL cr); 11826 format %{ "convert_d2l $dst, $src"%} 11827 ins_encode %{ 11828 __ convertF2I(T_LONG, T_DOUBLE, $dst$$Register, $src$$XMMRegister); 11829 %} 11830 ins_pipe(pipe_slow); 11831 %} 11832 11833 instruct round_double_reg(rRegL dst, regD src, rRegL rtmp, rcx_RegL rcx, rFlagsReg cr) 11834 %{ 11835 match(Set dst (RoundD src)); 11836 effect(TEMP dst, TEMP rtmp, TEMP rcx, KILL cr); 11837 format %{ "round_double $dst,$src \t! using $rtmp and $rcx as TEMP"%} 11838 ins_encode %{ 11839 __ round_double($dst$$Register, $src$$XMMRegister, $rtmp$$Register, $rcx$$Register); 11840 %} 11841 ins_pipe(pipe_slow); 11842 %} 11843 11844 instruct round_float_reg(rRegI dst, regF src, rRegL rtmp, rcx_RegL rcx, rFlagsReg cr) 11845 %{ 11846 match(Set dst (RoundF src)); 11847 effect(TEMP dst, TEMP rtmp, TEMP rcx, KILL cr); 11848 format %{ "round_float $dst,$src" %} 11849 ins_encode %{ 11850 __ round_float($dst$$Register, $src$$XMMRegister, $rtmp$$Register, $rcx$$Register); 11851 %} 11852 ins_pipe(pipe_slow); 11853 %} 11854 11855 instruct convI2F_reg_reg(vlRegF dst, rRegI src) 11856 %{ 11857 predicate(!UseXmmI2F); 11858 match(Set dst (ConvI2F src)); 11859 11860 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 11861 ins_encode %{ 11862 if (UseAVX > 0) { 11863 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 11864 } 11865 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Register); 11866 %} 11867 ins_pipe(pipe_slow); // XXX 11868 %} 11869 11870 instruct convI2F_reg_mem(regF dst, memory src) 11871 %{ 11872 predicate(UseAVX == 0); 11873 match(Set dst (ConvI2F (LoadI src))); 11874 11875 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 11876 ins_encode %{ 11877 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Address); 11878 %} 11879 ins_pipe(pipe_slow); // XXX 11880 %} 11881 11882 instruct convI2D_reg_reg(vlRegD dst, rRegI src) 11883 %{ 11884 predicate(!UseXmmI2D); 11885 match(Set dst (ConvI2D src)); 11886 11887 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 11888 ins_encode %{ 11889 if (UseAVX > 0) { 11890 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 11891 } 11892 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Register); 11893 %} 11894 ins_pipe(pipe_slow); // XXX 11895 %} 11896 11897 instruct convI2D_reg_mem(regD dst, memory src) 11898 %{ 11899 predicate(UseAVX == 0); 11900 match(Set dst (ConvI2D (LoadI src))); 11901 11902 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 11903 ins_encode %{ 11904 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Address); 11905 %} 11906 ins_pipe(pipe_slow); // XXX 11907 %} 11908 11909 instruct convXI2F_reg(regF dst, rRegI src) 11910 %{ 11911 predicate(UseXmmI2F); 11912 match(Set dst (ConvI2F src)); 11913 11914 format %{ "movdl $dst, $src\n\t" 11915 "cvtdq2psl $dst, $dst\t# i2f" %} 11916 ins_encode %{ 11917 __ movdl($dst$$XMMRegister, $src$$Register); 11918 __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister); 11919 %} 11920 ins_pipe(pipe_slow); // XXX 11921 %} 11922 11923 instruct convXI2D_reg(regD dst, rRegI src) 11924 %{ 11925 predicate(UseXmmI2D); 11926 match(Set dst (ConvI2D src)); 11927 11928 format %{ "movdl $dst, $src\n\t" 11929 "cvtdq2pdl $dst, $dst\t# i2d" %} 11930 ins_encode %{ 11931 __ movdl($dst$$XMMRegister, $src$$Register); 11932 __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister); 11933 %} 11934 ins_pipe(pipe_slow); // XXX 11935 %} 11936 11937 instruct convL2F_reg_reg(vlRegF dst, rRegL src) 11938 %{ 11939 match(Set dst (ConvL2F src)); 11940 11941 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 11942 ins_encode %{ 11943 if (UseAVX > 0) { 11944 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 11945 } 11946 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Register); 11947 %} 11948 ins_pipe(pipe_slow); // XXX 11949 %} 11950 11951 instruct convL2F_reg_mem(regF dst, memory src) 11952 %{ 11953 predicate(UseAVX == 0); 11954 match(Set dst (ConvL2F (LoadL src))); 11955 11956 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 11957 ins_encode %{ 11958 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Address); 11959 %} 11960 ins_pipe(pipe_slow); // XXX 11961 %} 11962 11963 instruct convL2D_reg_reg(vlRegD dst, rRegL src) 11964 %{ 11965 match(Set dst (ConvL2D src)); 11966 11967 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 11968 ins_encode %{ 11969 if (UseAVX > 0) { 11970 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 11971 } 11972 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Register); 11973 %} 11974 ins_pipe(pipe_slow); // XXX 11975 %} 11976 11977 instruct convL2D_reg_mem(regD dst, memory src) 11978 %{ 11979 predicate(UseAVX == 0); 11980 match(Set dst (ConvL2D (LoadL src))); 11981 11982 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 11983 ins_encode %{ 11984 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Address); 11985 %} 11986 ins_pipe(pipe_slow); // XXX 11987 %} 11988 11989 instruct convI2L_reg_reg(rRegL dst, rRegI src) 11990 %{ 11991 match(Set dst (ConvI2L src)); 11992 11993 ins_cost(125); 11994 format %{ "movslq $dst, $src\t# i2l" %} 11995 ins_encode %{ 11996 __ movslq($dst$$Register, $src$$Register); 11997 %} 11998 ins_pipe(ialu_reg_reg); 11999 %} 12000 12001 // Zero-extend convert int to long 12002 instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask) 12003 %{ 12004 match(Set dst (AndL (ConvI2L src) mask)); 12005 12006 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 12007 ins_encode %{ 12008 if ($dst$$reg != $src$$reg) { 12009 __ movl($dst$$Register, $src$$Register); 12010 } 12011 %} 12012 ins_pipe(ialu_reg_reg); 12013 %} 12014 12015 // Zero-extend convert int to long 12016 instruct convI2L_reg_mem_zex(rRegL dst, memory src, immL_32bits mask) 12017 %{ 12018 match(Set dst (AndL (ConvI2L (LoadI src)) mask)); 12019 12020 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 12021 ins_encode %{ 12022 __ movl($dst$$Register, $src$$Address); 12023 %} 12024 ins_pipe(ialu_reg_mem); 12025 %} 12026 12027 instruct zerox_long_reg_reg(rRegL dst, rRegL src, immL_32bits mask) 12028 %{ 12029 match(Set dst (AndL src mask)); 12030 12031 format %{ "movl $dst, $src\t# zero-extend long" %} 12032 ins_encode %{ 12033 __ movl($dst$$Register, $src$$Register); 12034 %} 12035 ins_pipe(ialu_reg_reg); 12036 %} 12037 12038 instruct convL2I_reg_reg(rRegI dst, rRegL src) 12039 %{ 12040 match(Set dst (ConvL2I src)); 12041 12042 format %{ "movl $dst, $src\t# l2i" %} 12043 ins_encode %{ 12044 __ movl($dst$$Register, $src$$Register); 12045 %} 12046 ins_pipe(ialu_reg_reg); 12047 %} 12048 12049 12050 instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{ 12051 match(Set dst (MoveF2I src)); 12052 effect(DEF dst, USE src); 12053 12054 ins_cost(125); 12055 format %{ "movl $dst, $src\t# MoveF2I_stack_reg" %} 12056 ins_encode %{ 12057 __ movl($dst$$Register, Address(rsp, $src$$disp)); 12058 %} 12059 ins_pipe(ialu_reg_mem); 12060 %} 12061 12062 instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{ 12063 match(Set dst (MoveI2F src)); 12064 effect(DEF dst, USE src); 12065 12066 ins_cost(125); 12067 format %{ "movss $dst, $src\t# MoveI2F_stack_reg" %} 12068 ins_encode %{ 12069 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 12070 %} 12071 ins_pipe(pipe_slow); 12072 %} 12073 12074 instruct MoveD2L_stack_reg(rRegL dst, stackSlotD src) %{ 12075 match(Set dst (MoveD2L src)); 12076 effect(DEF dst, USE src); 12077 12078 ins_cost(125); 12079 format %{ "movq $dst, $src\t# MoveD2L_stack_reg" %} 12080 ins_encode %{ 12081 __ movq($dst$$Register, Address(rsp, $src$$disp)); 12082 %} 12083 ins_pipe(ialu_reg_mem); 12084 %} 12085 12086 instruct MoveL2D_stack_reg_partial(regD dst, stackSlotL src) %{ 12087 predicate(!UseXmmLoadAndClearUpper); 12088 match(Set dst (MoveL2D src)); 12089 effect(DEF dst, USE src); 12090 12091 ins_cost(125); 12092 format %{ "movlpd $dst, $src\t# MoveL2D_stack_reg" %} 12093 ins_encode %{ 12094 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 12095 %} 12096 ins_pipe(pipe_slow); 12097 %} 12098 12099 instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{ 12100 predicate(UseXmmLoadAndClearUpper); 12101 match(Set dst (MoveL2D src)); 12102 effect(DEF dst, USE src); 12103 12104 ins_cost(125); 12105 format %{ "movsd $dst, $src\t# MoveL2D_stack_reg" %} 12106 ins_encode %{ 12107 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 12108 %} 12109 ins_pipe(pipe_slow); 12110 %} 12111 12112 12113 instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{ 12114 match(Set dst (MoveF2I src)); 12115 effect(DEF dst, USE src); 12116 12117 ins_cost(95); // XXX 12118 format %{ "movss $dst, $src\t# MoveF2I_reg_stack" %} 12119 ins_encode %{ 12120 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 12121 %} 12122 ins_pipe(pipe_slow); 12123 %} 12124 12125 instruct MoveI2F_reg_stack(stackSlotF dst, rRegI src) %{ 12126 match(Set dst (MoveI2F src)); 12127 effect(DEF dst, USE src); 12128 12129 ins_cost(100); 12130 format %{ "movl $dst, $src\t# MoveI2F_reg_stack" %} 12131 ins_encode %{ 12132 __ movl(Address(rsp, $dst$$disp), $src$$Register); 12133 %} 12134 ins_pipe( ialu_mem_reg ); 12135 %} 12136 12137 instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{ 12138 match(Set dst (MoveD2L src)); 12139 effect(DEF dst, USE src); 12140 12141 ins_cost(95); // XXX 12142 format %{ "movsd $dst, $src\t# MoveL2D_reg_stack" %} 12143 ins_encode %{ 12144 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 12145 %} 12146 ins_pipe(pipe_slow); 12147 %} 12148 12149 instruct MoveL2D_reg_stack(stackSlotD dst, rRegL src) %{ 12150 match(Set dst (MoveL2D src)); 12151 effect(DEF dst, USE src); 12152 12153 ins_cost(100); 12154 format %{ "movq $dst, $src\t# MoveL2D_reg_stack" %} 12155 ins_encode %{ 12156 __ movq(Address(rsp, $dst$$disp), $src$$Register); 12157 %} 12158 ins_pipe(ialu_mem_reg); 12159 %} 12160 12161 instruct MoveF2I_reg_reg(rRegI dst, regF src) %{ 12162 match(Set dst (MoveF2I src)); 12163 effect(DEF dst, USE src); 12164 ins_cost(85); 12165 format %{ "movd $dst,$src\t# MoveF2I" %} 12166 ins_encode %{ 12167 __ movdl($dst$$Register, $src$$XMMRegister); 12168 %} 12169 ins_pipe( pipe_slow ); 12170 %} 12171 12172 instruct MoveD2L_reg_reg(rRegL dst, regD src) %{ 12173 match(Set dst (MoveD2L src)); 12174 effect(DEF dst, USE src); 12175 ins_cost(85); 12176 format %{ "movd $dst,$src\t# MoveD2L" %} 12177 ins_encode %{ 12178 __ movdq($dst$$Register, $src$$XMMRegister); 12179 %} 12180 ins_pipe( pipe_slow ); 12181 %} 12182 12183 instruct MoveI2F_reg_reg(regF dst, rRegI src) %{ 12184 match(Set dst (MoveI2F src)); 12185 effect(DEF dst, USE src); 12186 ins_cost(100); 12187 format %{ "movd $dst,$src\t# MoveI2F" %} 12188 ins_encode %{ 12189 __ movdl($dst$$XMMRegister, $src$$Register); 12190 %} 12191 ins_pipe( pipe_slow ); 12192 %} 12193 12194 instruct MoveL2D_reg_reg(regD dst, rRegL src) %{ 12195 match(Set dst (MoveL2D src)); 12196 effect(DEF dst, USE src); 12197 ins_cost(100); 12198 format %{ "movd $dst,$src\t# MoveL2D" %} 12199 ins_encode %{ 12200 __ movdq($dst$$XMMRegister, $src$$Register); 12201 %} 12202 ins_pipe( pipe_slow ); 12203 %} 12204 12205 // Fast clearing of an array 12206 // Small non-constant lenght ClearArray for non-AVX512 targets. 12207 instruct rep_stos(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegI zero, 12208 Universe dummy, rFlagsReg cr) 12209 %{ 12210 predicate(!((ClearArrayNode*)n)->is_large() && (UseAVX <= 2)); 12211 match(Set dummy (ClearArray cnt base)); 12212 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL zero, KILL cr); 12213 12214 format %{ $$template 12215 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 12216 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 12217 $$emit$$"jg LARGE\n\t" 12218 $$emit$$"dec rcx\n\t" 12219 $$emit$$"js DONE\t# Zero length\n\t" 12220 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 12221 $$emit$$"dec rcx\n\t" 12222 $$emit$$"jge LOOP\n\t" 12223 $$emit$$"jmp DONE\n\t" 12224 $$emit$$"# LARGE:\n\t" 12225 if (UseFastStosb) { 12226 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 12227 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--\n\t" 12228 } else if (UseXMMForObjInit) { 12229 $$emit$$"mov rdi,rax\n\t" 12230 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 12231 $$emit$$"jmpq L_zero_64_bytes\n\t" 12232 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 12233 $$emit$$"vmovdqu ymm0,(rax)\n\t" 12234 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 12235 $$emit$$"add 0x40,rax\n\t" 12236 $$emit$$"# L_zero_64_bytes:\n\t" 12237 $$emit$$"sub 0x8,rcx\n\t" 12238 $$emit$$"jge L_loop\n\t" 12239 $$emit$$"add 0x4,rcx\n\t" 12240 $$emit$$"jl L_tail\n\t" 12241 $$emit$$"vmovdqu ymm0,(rax)\n\t" 12242 $$emit$$"add 0x20,rax\n\t" 12243 $$emit$$"sub 0x4,rcx\n\t" 12244 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 12245 $$emit$$"add 0x4,rcx\n\t" 12246 $$emit$$"jle L_end\n\t" 12247 $$emit$$"dec rcx\n\t" 12248 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 12249 $$emit$$"vmovq xmm0,(rax)\n\t" 12250 $$emit$$"add 0x8,rax\n\t" 12251 $$emit$$"dec rcx\n\t" 12252 $$emit$$"jge L_sloop\n\t" 12253 $$emit$$"# L_end:\n\t" 12254 } else { 12255 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 12256 } 12257 $$emit$$"# DONE" 12258 %} 12259 ins_encode %{ 12260 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 12261 $tmp$$XMMRegister, false, knoreg); 12262 %} 12263 ins_pipe(pipe_slow); 12264 %} 12265 12266 // Small non-constant length ClearArray for AVX512 targets. 12267 instruct rep_stos_evex(rcx_RegL cnt, rdi_RegP base, legRegD tmp, kReg ktmp, rax_RegI zero, 12268 Universe dummy, rFlagsReg cr) 12269 %{ 12270 predicate(!((ClearArrayNode*)n)->is_large() && (UseAVX > 2)); 12271 match(Set dummy (ClearArray cnt base)); 12272 ins_cost(125); 12273 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, TEMP ktmp, KILL zero, KILL cr); 12274 12275 format %{ $$template 12276 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 12277 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 12278 $$emit$$"jg LARGE\n\t" 12279 $$emit$$"dec rcx\n\t" 12280 $$emit$$"js DONE\t# Zero length\n\t" 12281 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 12282 $$emit$$"dec rcx\n\t" 12283 $$emit$$"jge LOOP\n\t" 12284 $$emit$$"jmp DONE\n\t" 12285 $$emit$$"# LARGE:\n\t" 12286 if (UseFastStosb) { 12287 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 12288 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--\n\t" 12289 } else if (UseXMMForObjInit) { 12290 $$emit$$"mov rdi,rax\n\t" 12291 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 12292 $$emit$$"jmpq L_zero_64_bytes\n\t" 12293 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 12294 $$emit$$"vmovdqu ymm0,(rax)\n\t" 12295 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 12296 $$emit$$"add 0x40,rax\n\t" 12297 $$emit$$"# L_zero_64_bytes:\n\t" 12298 $$emit$$"sub 0x8,rcx\n\t" 12299 $$emit$$"jge L_loop\n\t" 12300 $$emit$$"add 0x4,rcx\n\t" 12301 $$emit$$"jl L_tail\n\t" 12302 $$emit$$"vmovdqu ymm0,(rax)\n\t" 12303 $$emit$$"add 0x20,rax\n\t" 12304 $$emit$$"sub 0x4,rcx\n\t" 12305 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 12306 $$emit$$"add 0x4,rcx\n\t" 12307 $$emit$$"jle L_end\n\t" 12308 $$emit$$"dec rcx\n\t" 12309 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 12310 $$emit$$"vmovq xmm0,(rax)\n\t" 12311 $$emit$$"add 0x8,rax\n\t" 12312 $$emit$$"dec rcx\n\t" 12313 $$emit$$"jge L_sloop\n\t" 12314 $$emit$$"# L_end:\n\t" 12315 } else { 12316 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 12317 } 12318 $$emit$$"# DONE" 12319 %} 12320 ins_encode %{ 12321 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 12322 $tmp$$XMMRegister, false, $ktmp$$KRegister); 12323 %} 12324 ins_pipe(pipe_slow); 12325 %} 12326 12327 // Large non-constant length ClearArray for non-AVX512 targets. 12328 instruct rep_stos_large(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegI zero, 12329 Universe dummy, rFlagsReg cr) 12330 %{ 12331 predicate((UseAVX <=2) && ((ClearArrayNode*)n)->is_large()); 12332 match(Set dummy (ClearArray cnt base)); 12333 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL zero, KILL cr); 12334 12335 format %{ $$template 12336 if (UseFastStosb) { 12337 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 12338 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 12339 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--" 12340 } else if (UseXMMForObjInit) { 12341 $$emit$$"mov rdi,rax\t# ClearArray:\n\t" 12342 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 12343 $$emit$$"jmpq L_zero_64_bytes\n\t" 12344 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 12345 $$emit$$"vmovdqu ymm0,(rax)\n\t" 12346 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 12347 $$emit$$"add 0x40,rax\n\t" 12348 $$emit$$"# L_zero_64_bytes:\n\t" 12349 $$emit$$"sub 0x8,rcx\n\t" 12350 $$emit$$"jge L_loop\n\t" 12351 $$emit$$"add 0x4,rcx\n\t" 12352 $$emit$$"jl L_tail\n\t" 12353 $$emit$$"vmovdqu ymm0,(rax)\n\t" 12354 $$emit$$"add 0x20,rax\n\t" 12355 $$emit$$"sub 0x4,rcx\n\t" 12356 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 12357 $$emit$$"add 0x4,rcx\n\t" 12358 $$emit$$"jle L_end\n\t" 12359 $$emit$$"dec rcx\n\t" 12360 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 12361 $$emit$$"vmovq xmm0,(rax)\n\t" 12362 $$emit$$"add 0x8,rax\n\t" 12363 $$emit$$"dec rcx\n\t" 12364 $$emit$$"jge L_sloop\n\t" 12365 $$emit$$"# L_end:\n\t" 12366 } else { 12367 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 12368 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 12369 } 12370 %} 12371 ins_encode %{ 12372 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 12373 $tmp$$XMMRegister, true, knoreg); 12374 %} 12375 ins_pipe(pipe_slow); 12376 %} 12377 12378 // Large non-constant length ClearArray for AVX512 targets. 12379 instruct rep_stos_large_evex(rcx_RegL cnt, rdi_RegP base, legRegD tmp, kReg ktmp, rax_RegI zero, 12380 Universe dummy, rFlagsReg cr) 12381 %{ 12382 predicate((UseAVX > 2) && ((ClearArrayNode*)n)->is_large()); 12383 match(Set dummy (ClearArray cnt base)); 12384 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, TEMP ktmp, KILL zero, KILL cr); 12385 12386 format %{ $$template 12387 if (UseFastStosb) { 12388 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 12389 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 12390 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--" 12391 } else if (UseXMMForObjInit) { 12392 $$emit$$"mov rdi,rax\t# ClearArray:\n\t" 12393 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 12394 $$emit$$"jmpq L_zero_64_bytes\n\t" 12395 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 12396 $$emit$$"vmovdqu ymm0,(rax)\n\t" 12397 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 12398 $$emit$$"add 0x40,rax\n\t" 12399 $$emit$$"# L_zero_64_bytes:\n\t" 12400 $$emit$$"sub 0x8,rcx\n\t" 12401 $$emit$$"jge L_loop\n\t" 12402 $$emit$$"add 0x4,rcx\n\t" 12403 $$emit$$"jl L_tail\n\t" 12404 $$emit$$"vmovdqu ymm0,(rax)\n\t" 12405 $$emit$$"add 0x20,rax\n\t" 12406 $$emit$$"sub 0x4,rcx\n\t" 12407 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 12408 $$emit$$"add 0x4,rcx\n\t" 12409 $$emit$$"jle L_end\n\t" 12410 $$emit$$"dec rcx\n\t" 12411 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 12412 $$emit$$"vmovq xmm0,(rax)\n\t" 12413 $$emit$$"add 0x8,rax\n\t" 12414 $$emit$$"dec rcx\n\t" 12415 $$emit$$"jge L_sloop\n\t" 12416 $$emit$$"# L_end:\n\t" 12417 } else { 12418 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 12419 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 12420 } 12421 %} 12422 ins_encode %{ 12423 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 12424 $tmp$$XMMRegister, true, $ktmp$$KRegister); 12425 %} 12426 ins_pipe(pipe_slow); 12427 %} 12428 12429 // Small constant length ClearArray for AVX512 targets. 12430 instruct rep_stos_im(immL cnt, rRegP base, regD tmp, rRegI zero, kReg ktmp, Universe dummy, rFlagsReg cr) 12431 %{ 12432 predicate(!((ClearArrayNode*)n)->is_large() && (MaxVectorSize >= 32) && VM_Version::supports_avx512vl()); 12433 match(Set dummy (ClearArray cnt base)); 12434 ins_cost(100); 12435 effect(TEMP tmp, TEMP zero, TEMP ktmp, KILL cr); 12436 format %{ "clear_mem_imm $base , $cnt \n\t" %} 12437 ins_encode %{ 12438 __ clear_mem($base$$Register, $cnt$$constant, $zero$$Register, $tmp$$XMMRegister, $ktmp$$KRegister); 12439 %} 12440 ins_pipe(pipe_slow); 12441 %} 12442 12443 instruct string_compareL(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 12444 rax_RegI result, legRegD tmp1, rFlagsReg cr) 12445 %{ 12446 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 12447 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12448 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 12449 12450 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 12451 ins_encode %{ 12452 __ string_compare($str1$$Register, $str2$$Register, 12453 $cnt1$$Register, $cnt2$$Register, $result$$Register, 12454 $tmp1$$XMMRegister, StrIntrinsicNode::LL, knoreg); 12455 %} 12456 ins_pipe( pipe_slow ); 12457 %} 12458 12459 instruct string_compareL_evex(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 12460 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 12461 %{ 12462 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 12463 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12464 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 12465 12466 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 12467 ins_encode %{ 12468 __ string_compare($str1$$Register, $str2$$Register, 12469 $cnt1$$Register, $cnt2$$Register, $result$$Register, 12470 $tmp1$$XMMRegister, StrIntrinsicNode::LL, $ktmp$$KRegister); 12471 %} 12472 ins_pipe( pipe_slow ); 12473 %} 12474 12475 instruct string_compareU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 12476 rax_RegI result, legRegD tmp1, rFlagsReg cr) 12477 %{ 12478 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 12479 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12480 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 12481 12482 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 12483 ins_encode %{ 12484 __ string_compare($str1$$Register, $str2$$Register, 12485 $cnt1$$Register, $cnt2$$Register, $result$$Register, 12486 $tmp1$$XMMRegister, StrIntrinsicNode::UU, knoreg); 12487 %} 12488 ins_pipe( pipe_slow ); 12489 %} 12490 12491 instruct string_compareU_evex(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 12492 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 12493 %{ 12494 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 12495 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12496 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 12497 12498 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 12499 ins_encode %{ 12500 __ string_compare($str1$$Register, $str2$$Register, 12501 $cnt1$$Register, $cnt2$$Register, $result$$Register, 12502 $tmp1$$XMMRegister, StrIntrinsicNode::UU, $ktmp$$KRegister); 12503 %} 12504 ins_pipe( pipe_slow ); 12505 %} 12506 12507 instruct string_compareLU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 12508 rax_RegI result, legRegD tmp1, rFlagsReg cr) 12509 %{ 12510 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 12511 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12512 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 12513 12514 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 12515 ins_encode %{ 12516 __ string_compare($str1$$Register, $str2$$Register, 12517 $cnt1$$Register, $cnt2$$Register, $result$$Register, 12518 $tmp1$$XMMRegister, StrIntrinsicNode::LU, knoreg); 12519 %} 12520 ins_pipe( pipe_slow ); 12521 %} 12522 12523 instruct string_compareLU_evex(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 12524 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 12525 %{ 12526 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 12527 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12528 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 12529 12530 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 12531 ins_encode %{ 12532 __ string_compare($str1$$Register, $str2$$Register, 12533 $cnt1$$Register, $cnt2$$Register, $result$$Register, 12534 $tmp1$$XMMRegister, StrIntrinsicNode::LU, $ktmp$$KRegister); 12535 %} 12536 ins_pipe( pipe_slow ); 12537 %} 12538 12539 instruct string_compareUL(rsi_RegP str1, rdx_RegI cnt1, rdi_RegP str2, rcx_RegI cnt2, 12540 rax_RegI result, legRegD tmp1, rFlagsReg cr) 12541 %{ 12542 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 12543 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12544 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 12545 12546 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 12547 ins_encode %{ 12548 __ string_compare($str2$$Register, $str1$$Register, 12549 $cnt2$$Register, $cnt1$$Register, $result$$Register, 12550 $tmp1$$XMMRegister, StrIntrinsicNode::UL, knoreg); 12551 %} 12552 ins_pipe( pipe_slow ); 12553 %} 12554 12555 instruct string_compareUL_evex(rsi_RegP str1, rdx_RegI cnt1, rdi_RegP str2, rcx_RegI cnt2, 12556 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 12557 %{ 12558 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 12559 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12560 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 12561 12562 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 12563 ins_encode %{ 12564 __ string_compare($str2$$Register, $str1$$Register, 12565 $cnt2$$Register, $cnt1$$Register, $result$$Register, 12566 $tmp1$$XMMRegister, StrIntrinsicNode::UL, $ktmp$$KRegister); 12567 %} 12568 ins_pipe( pipe_slow ); 12569 %} 12570 12571 // fast search of substring with known size. 12572 instruct string_indexof_conL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 12573 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 12574 %{ 12575 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 12576 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 12577 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 12578 12579 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %} 12580 ins_encode %{ 12581 int icnt2 = (int)$int_cnt2$$constant; 12582 if (icnt2 >= 16) { 12583 // IndexOf for constant substrings with size >= 16 elements 12584 // which don't need to be loaded through stack. 12585 __ string_indexofC8($str1$$Register, $str2$$Register, 12586 $cnt1$$Register, $cnt2$$Register, 12587 icnt2, $result$$Register, 12588 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 12589 } else { 12590 // Small strings are loaded through stack if they cross page boundary. 12591 __ string_indexof($str1$$Register, $str2$$Register, 12592 $cnt1$$Register, $cnt2$$Register, 12593 icnt2, $result$$Register, 12594 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 12595 } 12596 %} 12597 ins_pipe( pipe_slow ); 12598 %} 12599 12600 // fast search of substring with known size. 12601 instruct string_indexof_conU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 12602 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 12603 %{ 12604 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 12605 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 12606 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 12607 12608 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %} 12609 ins_encode %{ 12610 int icnt2 = (int)$int_cnt2$$constant; 12611 if (icnt2 >= 8) { 12612 // IndexOf for constant substrings with size >= 8 elements 12613 // which don't need to be loaded through stack. 12614 __ string_indexofC8($str1$$Register, $str2$$Register, 12615 $cnt1$$Register, $cnt2$$Register, 12616 icnt2, $result$$Register, 12617 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 12618 } else { 12619 // Small strings are loaded through stack if they cross page boundary. 12620 __ string_indexof($str1$$Register, $str2$$Register, 12621 $cnt1$$Register, $cnt2$$Register, 12622 icnt2, $result$$Register, 12623 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 12624 } 12625 %} 12626 ins_pipe( pipe_slow ); 12627 %} 12628 12629 // fast search of substring with known size. 12630 instruct string_indexof_conUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 12631 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 12632 %{ 12633 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 12634 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 12635 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 12636 12637 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %} 12638 ins_encode %{ 12639 int icnt2 = (int)$int_cnt2$$constant; 12640 if (icnt2 >= 8) { 12641 // IndexOf for constant substrings with size >= 8 elements 12642 // which don't need to be loaded through stack. 12643 __ string_indexofC8($str1$$Register, $str2$$Register, 12644 $cnt1$$Register, $cnt2$$Register, 12645 icnt2, $result$$Register, 12646 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 12647 } else { 12648 // Small strings are loaded through stack if they cross page boundary. 12649 __ string_indexof($str1$$Register, $str2$$Register, 12650 $cnt1$$Register, $cnt2$$Register, 12651 icnt2, $result$$Register, 12652 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 12653 } 12654 %} 12655 ins_pipe( pipe_slow ); 12656 %} 12657 12658 instruct string_indexofL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 12659 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr) 12660 %{ 12661 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 12662 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 12663 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 12664 12665 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 12666 ins_encode %{ 12667 __ string_indexof($str1$$Register, $str2$$Register, 12668 $cnt1$$Register, $cnt2$$Register, 12669 (-1), $result$$Register, 12670 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 12671 %} 12672 ins_pipe( pipe_slow ); 12673 %} 12674 12675 instruct string_indexofU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 12676 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr) 12677 %{ 12678 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 12679 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 12680 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 12681 12682 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 12683 ins_encode %{ 12684 __ string_indexof($str1$$Register, $str2$$Register, 12685 $cnt1$$Register, $cnt2$$Register, 12686 (-1), $result$$Register, 12687 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 12688 %} 12689 ins_pipe( pipe_slow ); 12690 %} 12691 12692 instruct string_indexofUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 12693 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr) 12694 %{ 12695 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 12696 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 12697 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 12698 12699 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 12700 ins_encode %{ 12701 __ string_indexof($str1$$Register, $str2$$Register, 12702 $cnt1$$Register, $cnt2$$Register, 12703 (-1), $result$$Register, 12704 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 12705 %} 12706 ins_pipe( pipe_slow ); 12707 %} 12708 12709 instruct string_indexof_char(rdi_RegP str1, rdx_RegI cnt1, rax_RegI ch, 12710 rbx_RegI result, legRegD tmp_vec1, legRegD tmp_vec2, legRegD tmp_vec3, rcx_RegI tmp, rFlagsReg cr) 12711 %{ 12712 predicate(UseSSE42Intrinsics && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::U)); 12713 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 12714 effect(TEMP tmp_vec1, TEMP tmp_vec2, TEMP tmp_vec3, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP tmp, KILL cr); 12715 format %{ "StringUTF16 IndexOf char[] $str1,$cnt1,$ch -> $result // KILL all" %} 12716 ins_encode %{ 12717 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register, 12718 $tmp_vec1$$XMMRegister, $tmp_vec2$$XMMRegister, $tmp_vec3$$XMMRegister, $tmp$$Register); 12719 %} 12720 ins_pipe( pipe_slow ); 12721 %} 12722 12723 instruct stringL_indexof_char(rdi_RegP str1, rdx_RegI cnt1, rax_RegI ch, 12724 rbx_RegI result, legRegD tmp_vec1, legRegD tmp_vec2, legRegD tmp_vec3, rcx_RegI tmp, rFlagsReg cr) 12725 %{ 12726 predicate(UseSSE42Intrinsics && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::L)); 12727 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 12728 effect(TEMP tmp_vec1, TEMP tmp_vec2, TEMP tmp_vec3, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP tmp, KILL cr); 12729 format %{ "StringLatin1 IndexOf char[] $str1,$cnt1,$ch -> $result // KILL all" %} 12730 ins_encode %{ 12731 __ stringL_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register, 12732 $tmp_vec1$$XMMRegister, $tmp_vec2$$XMMRegister, $tmp_vec3$$XMMRegister, $tmp$$Register); 12733 %} 12734 ins_pipe( pipe_slow ); 12735 %} 12736 12737 // fast string equals 12738 instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 12739 legRegD tmp1, legRegD tmp2, rbx_RegI tmp3, rFlagsReg cr) 12740 %{ 12741 predicate(!VM_Version::supports_avx512vlbw()); 12742 match(Set result (StrEquals (Binary str1 str2) cnt)); 12743 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 12744 12745 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 12746 ins_encode %{ 12747 __ arrays_equals(false, $str1$$Register, $str2$$Register, 12748 $cnt$$Register, $result$$Register, $tmp3$$Register, 12749 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, knoreg); 12750 %} 12751 ins_pipe( pipe_slow ); 12752 %} 12753 12754 instruct string_equals_evex(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 12755 legRegD tmp1, legRegD tmp2, kReg ktmp, rbx_RegI tmp3, rFlagsReg cr) 12756 %{ 12757 predicate(VM_Version::supports_avx512vlbw()); 12758 match(Set result (StrEquals (Binary str1 str2) cnt)); 12759 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 12760 12761 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 12762 ins_encode %{ 12763 __ arrays_equals(false, $str1$$Register, $str2$$Register, 12764 $cnt$$Register, $result$$Register, $tmp3$$Register, 12765 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, $ktmp$$KRegister); 12766 %} 12767 ins_pipe( pipe_slow ); 12768 %} 12769 12770 // fast array equals 12771 instruct array_equalsB(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 12772 legRegD tmp1, legRegD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 12773 %{ 12774 predicate(!VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 12775 match(Set result (AryEq ary1 ary2)); 12776 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 12777 12778 format %{ "Array Equals byte[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 12779 ins_encode %{ 12780 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 12781 $tmp3$$Register, $result$$Register, $tmp4$$Register, 12782 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, knoreg); 12783 %} 12784 ins_pipe( pipe_slow ); 12785 %} 12786 12787 instruct array_equalsB_evex(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 12788 legRegD tmp1, legRegD tmp2, kReg ktmp, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 12789 %{ 12790 predicate(VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 12791 match(Set result (AryEq ary1 ary2)); 12792 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 12793 12794 format %{ "Array Equals byte[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 12795 ins_encode %{ 12796 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 12797 $tmp3$$Register, $result$$Register, $tmp4$$Register, 12798 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, $ktmp$$KRegister); 12799 %} 12800 ins_pipe( pipe_slow ); 12801 %} 12802 12803 instruct array_equalsC(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 12804 legRegD tmp1, legRegD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 12805 %{ 12806 predicate(!VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 12807 match(Set result (AryEq ary1 ary2)); 12808 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 12809 12810 format %{ "Array Equals char[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 12811 ins_encode %{ 12812 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 12813 $tmp3$$Register, $result$$Register, $tmp4$$Register, 12814 $tmp1$$XMMRegister, $tmp2$$XMMRegister, true /* char */, knoreg); 12815 %} 12816 ins_pipe( pipe_slow ); 12817 %} 12818 12819 instruct array_equalsC_evex(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 12820 legRegD tmp1, legRegD tmp2, kReg ktmp, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 12821 %{ 12822 predicate(VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 12823 match(Set result (AryEq ary1 ary2)); 12824 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 12825 12826 format %{ "Array Equals char[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 12827 ins_encode %{ 12828 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 12829 $tmp3$$Register, $result$$Register, $tmp4$$Register, 12830 $tmp1$$XMMRegister, $tmp2$$XMMRegister, true /* char */, $ktmp$$KRegister); 12831 %} 12832 ins_pipe( pipe_slow ); 12833 %} 12834 12835 instruct arrays_hashcode(rdi_RegP ary1, rdx_RegI cnt1, rbx_RegI result, immU8 basic_type, 12836 legRegD tmp_vec1, legRegD tmp_vec2, legRegD tmp_vec3, legRegD tmp_vec4, 12837 legRegD tmp_vec5, legRegD tmp_vec6, legRegD tmp_vec7, legRegD tmp_vec8, 12838 legRegD tmp_vec9, legRegD tmp_vec10, legRegD tmp_vec11, legRegD tmp_vec12, 12839 legRegD tmp_vec13, rRegI tmp1, rRegI tmp2, rRegI tmp3, rFlagsReg cr) 12840 %{ 12841 predicate(UseAVX >= 2); 12842 match(Set result (VectorizedHashCode (Binary ary1 cnt1) (Binary result basic_type))); 12843 effect(TEMP tmp_vec1, TEMP tmp_vec2, TEMP tmp_vec3, TEMP tmp_vec4, TEMP tmp_vec5, TEMP tmp_vec6, 12844 TEMP tmp_vec7, TEMP tmp_vec8, TEMP tmp_vec9, TEMP tmp_vec10, TEMP tmp_vec11, TEMP tmp_vec12, 12845 TEMP tmp_vec13, TEMP tmp1, TEMP tmp2, TEMP tmp3, USE_KILL ary1, USE_KILL cnt1, 12846 USE basic_type, KILL cr); 12847 12848 format %{ "Array HashCode array[] $ary1,$cnt1,$result,$basic_type -> $result // KILL all" %} 12849 ins_encode %{ 12850 __ arrays_hashcode($ary1$$Register, $cnt1$$Register, $result$$Register, 12851 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 12852 $tmp_vec1$$XMMRegister, $tmp_vec2$$XMMRegister, $tmp_vec3$$XMMRegister, 12853 $tmp_vec4$$XMMRegister, $tmp_vec5$$XMMRegister, $tmp_vec6$$XMMRegister, 12854 $tmp_vec7$$XMMRegister, $tmp_vec8$$XMMRegister, $tmp_vec9$$XMMRegister, 12855 $tmp_vec10$$XMMRegister, $tmp_vec11$$XMMRegister, $tmp_vec12$$XMMRegister, 12856 $tmp_vec13$$XMMRegister, (BasicType)$basic_type$$constant); 12857 %} 12858 ins_pipe( pipe_slow ); 12859 %} 12860 12861 instruct count_positives(rsi_RegP ary1, rcx_RegI len, rax_RegI result, 12862 legRegD tmp1, legRegD tmp2, rbx_RegI tmp3, rFlagsReg cr,) 12863 %{ 12864 predicate(!VM_Version::supports_avx512vlbw() || !VM_Version::supports_bmi2()); 12865 match(Set result (CountPositives ary1 len)); 12866 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr); 12867 12868 format %{ "countPositives byte[] $ary1,$len -> $result // KILL $tmp1, $tmp2, $tmp3" %} 12869 ins_encode %{ 12870 __ count_positives($ary1$$Register, $len$$Register, 12871 $result$$Register, $tmp3$$Register, 12872 $tmp1$$XMMRegister, $tmp2$$XMMRegister, knoreg, knoreg); 12873 %} 12874 ins_pipe( pipe_slow ); 12875 %} 12876 12877 instruct count_positives_evex(rsi_RegP ary1, rcx_RegI len, rax_RegI result, 12878 legRegD tmp1, legRegD tmp2, kReg ktmp1, kReg ktmp2, rbx_RegI tmp3, rFlagsReg cr,) 12879 %{ 12880 predicate(VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2()); 12881 match(Set result (CountPositives ary1 len)); 12882 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp1, TEMP ktmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr); 12883 12884 format %{ "countPositives byte[] $ary1,$len -> $result // KILL $tmp1, $tmp2, $tmp3" %} 12885 ins_encode %{ 12886 __ count_positives($ary1$$Register, $len$$Register, 12887 $result$$Register, $tmp3$$Register, 12888 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $ktmp1$$KRegister, $ktmp2$$KRegister); 12889 %} 12890 ins_pipe( pipe_slow ); 12891 %} 12892 12893 // fast char[] to byte[] compression 12894 instruct string_compress(rsi_RegP src, rdi_RegP dst, rdx_RegI len, legRegD tmp1, legRegD tmp2, legRegD tmp3, 12895 legRegD tmp4, rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 12896 predicate(!VM_Version::supports_avx512vlbw() || !VM_Version::supports_bmi2()); 12897 match(Set result (StrCompressedCopy src (Binary dst len))); 12898 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, 12899 USE_KILL len, KILL tmp5, KILL cr); 12900 12901 format %{ "String Compress $src,$dst -> $result // KILL RAX, RCX, RDX" %} 12902 ins_encode %{ 12903 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 12904 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 12905 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, 12906 knoreg, knoreg); 12907 %} 12908 ins_pipe( pipe_slow ); 12909 %} 12910 12911 instruct string_compress_evex(rsi_RegP src, rdi_RegP dst, rdx_RegI len, legRegD tmp1, legRegD tmp2, legRegD tmp3, 12912 legRegD tmp4, kReg ktmp1, kReg ktmp2, rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 12913 predicate(VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2()); 12914 match(Set result (StrCompressedCopy src (Binary dst len))); 12915 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP ktmp1, TEMP ktmp2, USE_KILL src, USE_KILL dst, 12916 USE_KILL len, KILL tmp5, KILL cr); 12917 12918 format %{ "String Compress $src,$dst -> $result // KILL RAX, RCX, RDX" %} 12919 ins_encode %{ 12920 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 12921 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 12922 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, 12923 $ktmp1$$KRegister, $ktmp2$$KRegister); 12924 %} 12925 ins_pipe( pipe_slow ); 12926 %} 12927 // fast byte[] to char[] inflation 12928 instruct string_inflate(Universe dummy, rsi_RegP src, rdi_RegP dst, rdx_RegI len, 12929 legRegD tmp1, rcx_RegI tmp2, rFlagsReg cr) %{ 12930 predicate(!VM_Version::supports_avx512vlbw() || !VM_Version::supports_bmi2()); 12931 match(Set dummy (StrInflatedCopy src (Binary dst len))); 12932 effect(TEMP tmp1, TEMP tmp2, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 12933 12934 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 12935 ins_encode %{ 12936 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 12937 $tmp1$$XMMRegister, $tmp2$$Register, knoreg); 12938 %} 12939 ins_pipe( pipe_slow ); 12940 %} 12941 12942 instruct string_inflate_evex(Universe dummy, rsi_RegP src, rdi_RegP dst, rdx_RegI len, 12943 legRegD tmp1, kReg ktmp, rcx_RegI tmp2, rFlagsReg cr) %{ 12944 predicate(VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2()); 12945 match(Set dummy (StrInflatedCopy src (Binary dst len))); 12946 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 12947 12948 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 12949 ins_encode %{ 12950 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 12951 $tmp1$$XMMRegister, $tmp2$$Register, $ktmp$$KRegister); 12952 %} 12953 ins_pipe( pipe_slow ); 12954 %} 12955 12956 // encode char[] to byte[] in ISO_8859_1 12957 instruct encode_iso_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len, 12958 legRegD tmp1, legRegD tmp2, legRegD tmp3, legRegD tmp4, 12959 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 12960 predicate(!((EncodeISOArrayNode*)n)->is_ascii()); 12961 match(Set result (EncodeISOArray src (Binary dst len))); 12962 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 12963 12964 format %{ "Encode iso array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %} 12965 ins_encode %{ 12966 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 12967 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 12968 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, false); 12969 %} 12970 ins_pipe( pipe_slow ); 12971 %} 12972 12973 // encode char[] to byte[] in ASCII 12974 instruct encode_ascii_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len, 12975 legRegD tmp1, legRegD tmp2, legRegD tmp3, legRegD tmp4, 12976 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 12977 predicate(((EncodeISOArrayNode*)n)->is_ascii()); 12978 match(Set result (EncodeISOArray src (Binary dst len))); 12979 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 12980 12981 format %{ "Encode ascii array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %} 12982 ins_encode %{ 12983 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 12984 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 12985 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, true); 12986 %} 12987 ins_pipe( pipe_slow ); 12988 %} 12989 12990 //----------Overflow Math Instructions----------------------------------------- 12991 12992 instruct overflowAddI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 12993 %{ 12994 match(Set cr (OverflowAddI op1 op2)); 12995 effect(DEF cr, USE_KILL op1, USE op2); 12996 12997 format %{ "addl $op1, $op2\t# overflow check int" %} 12998 12999 ins_encode %{ 13000 __ addl($op1$$Register, $op2$$Register); 13001 %} 13002 ins_pipe(ialu_reg_reg); 13003 %} 13004 13005 instruct overflowAddI_rReg_imm(rFlagsReg cr, rax_RegI op1, immI op2) 13006 %{ 13007 match(Set cr (OverflowAddI op1 op2)); 13008 effect(DEF cr, USE_KILL op1, USE op2); 13009 13010 format %{ "addl $op1, $op2\t# overflow check int" %} 13011 13012 ins_encode %{ 13013 __ addl($op1$$Register, $op2$$constant); 13014 %} 13015 ins_pipe(ialu_reg_reg); 13016 %} 13017 13018 instruct overflowAddL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 13019 %{ 13020 match(Set cr (OverflowAddL op1 op2)); 13021 effect(DEF cr, USE_KILL op1, USE op2); 13022 13023 format %{ "addq $op1, $op2\t# overflow check long" %} 13024 ins_encode %{ 13025 __ addq($op1$$Register, $op2$$Register); 13026 %} 13027 ins_pipe(ialu_reg_reg); 13028 %} 13029 13030 instruct overflowAddL_rReg_imm(rFlagsReg cr, rax_RegL op1, immL32 op2) 13031 %{ 13032 match(Set cr (OverflowAddL op1 op2)); 13033 effect(DEF cr, USE_KILL op1, USE op2); 13034 13035 format %{ "addq $op1, $op2\t# overflow check long" %} 13036 ins_encode %{ 13037 __ addq($op1$$Register, $op2$$constant); 13038 %} 13039 ins_pipe(ialu_reg_reg); 13040 %} 13041 13042 instruct overflowSubI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 13043 %{ 13044 match(Set cr (OverflowSubI op1 op2)); 13045 13046 format %{ "cmpl $op1, $op2\t# overflow check int" %} 13047 ins_encode %{ 13048 __ cmpl($op1$$Register, $op2$$Register); 13049 %} 13050 ins_pipe(ialu_reg_reg); 13051 %} 13052 13053 instruct overflowSubI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 13054 %{ 13055 match(Set cr (OverflowSubI op1 op2)); 13056 13057 format %{ "cmpl $op1, $op2\t# overflow check int" %} 13058 ins_encode %{ 13059 __ cmpl($op1$$Register, $op2$$constant); 13060 %} 13061 ins_pipe(ialu_reg_reg); 13062 %} 13063 13064 instruct overflowSubL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 13065 %{ 13066 match(Set cr (OverflowSubL op1 op2)); 13067 13068 format %{ "cmpq $op1, $op2\t# overflow check long" %} 13069 ins_encode %{ 13070 __ cmpq($op1$$Register, $op2$$Register); 13071 %} 13072 ins_pipe(ialu_reg_reg); 13073 %} 13074 13075 instruct overflowSubL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 13076 %{ 13077 match(Set cr (OverflowSubL op1 op2)); 13078 13079 format %{ "cmpq $op1, $op2\t# overflow check long" %} 13080 ins_encode %{ 13081 __ cmpq($op1$$Register, $op2$$constant); 13082 %} 13083 ins_pipe(ialu_reg_reg); 13084 %} 13085 13086 instruct overflowNegI_rReg(rFlagsReg cr, immI_0 zero, rax_RegI op2) 13087 %{ 13088 match(Set cr (OverflowSubI zero op2)); 13089 effect(DEF cr, USE_KILL op2); 13090 13091 format %{ "negl $op2\t# overflow check int" %} 13092 ins_encode %{ 13093 __ negl($op2$$Register); 13094 %} 13095 ins_pipe(ialu_reg_reg); 13096 %} 13097 13098 instruct overflowNegL_rReg(rFlagsReg cr, immL0 zero, rax_RegL op2) 13099 %{ 13100 match(Set cr (OverflowSubL zero op2)); 13101 effect(DEF cr, USE_KILL op2); 13102 13103 format %{ "negq $op2\t# overflow check long" %} 13104 ins_encode %{ 13105 __ negq($op2$$Register); 13106 %} 13107 ins_pipe(ialu_reg_reg); 13108 %} 13109 13110 instruct overflowMulI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 13111 %{ 13112 match(Set cr (OverflowMulI op1 op2)); 13113 effect(DEF cr, USE_KILL op1, USE op2); 13114 13115 format %{ "imull $op1, $op2\t# overflow check int" %} 13116 ins_encode %{ 13117 __ imull($op1$$Register, $op2$$Register); 13118 %} 13119 ins_pipe(ialu_reg_reg_alu0); 13120 %} 13121 13122 instruct overflowMulI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2, rRegI tmp) 13123 %{ 13124 match(Set cr (OverflowMulI op1 op2)); 13125 effect(DEF cr, TEMP tmp, USE op1, USE op2); 13126 13127 format %{ "imull $tmp, $op1, $op2\t# overflow check int" %} 13128 ins_encode %{ 13129 __ imull($tmp$$Register, $op1$$Register, $op2$$constant); 13130 %} 13131 ins_pipe(ialu_reg_reg_alu0); 13132 %} 13133 13134 instruct overflowMulL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 13135 %{ 13136 match(Set cr (OverflowMulL op1 op2)); 13137 effect(DEF cr, USE_KILL op1, USE op2); 13138 13139 format %{ "imulq $op1, $op2\t# overflow check long" %} 13140 ins_encode %{ 13141 __ imulq($op1$$Register, $op2$$Register); 13142 %} 13143 ins_pipe(ialu_reg_reg_alu0); 13144 %} 13145 13146 instruct overflowMulL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2, rRegL tmp) 13147 %{ 13148 match(Set cr (OverflowMulL op1 op2)); 13149 effect(DEF cr, TEMP tmp, USE op1, USE op2); 13150 13151 format %{ "imulq $tmp, $op1, $op2\t# overflow check long" %} 13152 ins_encode %{ 13153 __ imulq($tmp$$Register, $op1$$Register, $op2$$constant); 13154 %} 13155 ins_pipe(ialu_reg_reg_alu0); 13156 %} 13157 13158 13159 //----------Control Flow Instructions------------------------------------------ 13160 // Signed compare Instructions 13161 13162 // XXX more variants!! 13163 instruct compI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 13164 %{ 13165 match(Set cr (CmpI op1 op2)); 13166 effect(DEF cr, USE op1, USE op2); 13167 13168 format %{ "cmpl $op1, $op2" %} 13169 ins_encode %{ 13170 __ cmpl($op1$$Register, $op2$$Register); 13171 %} 13172 ins_pipe(ialu_cr_reg_reg); 13173 %} 13174 13175 instruct compI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 13176 %{ 13177 match(Set cr (CmpI op1 op2)); 13178 13179 format %{ "cmpl $op1, $op2" %} 13180 ins_encode %{ 13181 __ cmpl($op1$$Register, $op2$$constant); 13182 %} 13183 ins_pipe(ialu_cr_reg_imm); 13184 %} 13185 13186 instruct compI_rReg_mem(rFlagsReg cr, rRegI op1, memory op2) 13187 %{ 13188 match(Set cr (CmpI op1 (LoadI op2))); 13189 13190 ins_cost(500); // XXX 13191 format %{ "cmpl $op1, $op2" %} 13192 ins_encode %{ 13193 __ cmpl($op1$$Register, $op2$$Address); 13194 %} 13195 ins_pipe(ialu_cr_reg_mem); 13196 %} 13197 13198 instruct testI_reg(rFlagsReg cr, rRegI src, immI_0 zero) 13199 %{ 13200 match(Set cr (CmpI src zero)); 13201 13202 format %{ "testl $src, $src" %} 13203 ins_encode %{ 13204 __ testl($src$$Register, $src$$Register); 13205 %} 13206 ins_pipe(ialu_cr_reg_imm); 13207 %} 13208 13209 instruct testI_reg_imm(rFlagsReg cr, rRegI src, immI con, immI_0 zero) 13210 %{ 13211 match(Set cr (CmpI (AndI src con) zero)); 13212 13213 format %{ "testl $src, $con" %} 13214 ins_encode %{ 13215 __ testl($src$$Register, $con$$constant); 13216 %} 13217 ins_pipe(ialu_cr_reg_imm); 13218 %} 13219 13220 instruct testI_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2, immI_0 zero) 13221 %{ 13222 match(Set cr (CmpI (AndI src1 src2) zero)); 13223 13224 format %{ "testl $src1, $src2" %} 13225 ins_encode %{ 13226 __ testl($src1$$Register, $src2$$Register); 13227 %} 13228 ins_pipe(ialu_cr_reg_imm); 13229 %} 13230 13231 instruct testI_reg_mem(rFlagsReg cr, rRegI src, memory mem, immI_0 zero) 13232 %{ 13233 match(Set cr (CmpI (AndI src (LoadI mem)) zero)); 13234 13235 format %{ "testl $src, $mem" %} 13236 ins_encode %{ 13237 __ testl($src$$Register, $mem$$Address); 13238 %} 13239 ins_pipe(ialu_cr_reg_mem); 13240 %} 13241 13242 // Unsigned compare Instructions; really, same as signed except they 13243 // produce an rFlagsRegU instead of rFlagsReg. 13244 instruct compU_rReg(rFlagsRegU cr, rRegI op1, rRegI op2) 13245 %{ 13246 match(Set cr (CmpU op1 op2)); 13247 13248 format %{ "cmpl $op1, $op2\t# unsigned" %} 13249 ins_encode %{ 13250 __ cmpl($op1$$Register, $op2$$Register); 13251 %} 13252 ins_pipe(ialu_cr_reg_reg); 13253 %} 13254 13255 instruct compU_rReg_imm(rFlagsRegU cr, rRegI op1, immI op2) 13256 %{ 13257 match(Set cr (CmpU op1 op2)); 13258 13259 format %{ "cmpl $op1, $op2\t# unsigned" %} 13260 ins_encode %{ 13261 __ cmpl($op1$$Register, $op2$$constant); 13262 %} 13263 ins_pipe(ialu_cr_reg_imm); 13264 %} 13265 13266 instruct compU_rReg_mem(rFlagsRegU cr, rRegI op1, memory op2) 13267 %{ 13268 match(Set cr (CmpU op1 (LoadI op2))); 13269 13270 ins_cost(500); // XXX 13271 format %{ "cmpl $op1, $op2\t# unsigned" %} 13272 ins_encode %{ 13273 __ cmpl($op1$$Register, $op2$$Address); 13274 %} 13275 ins_pipe(ialu_cr_reg_mem); 13276 %} 13277 13278 instruct testU_reg(rFlagsRegU cr, rRegI src, immI_0 zero) 13279 %{ 13280 match(Set cr (CmpU src zero)); 13281 13282 format %{ "testl $src, $src\t# unsigned" %} 13283 ins_encode %{ 13284 __ testl($src$$Register, $src$$Register); 13285 %} 13286 ins_pipe(ialu_cr_reg_imm); 13287 %} 13288 13289 instruct compP_rReg(rFlagsRegU cr, rRegP op1, rRegP op2) 13290 %{ 13291 match(Set cr (CmpP op1 op2)); 13292 13293 format %{ "cmpq $op1, $op2\t# ptr" %} 13294 ins_encode %{ 13295 __ cmpq($op1$$Register, $op2$$Register); 13296 %} 13297 ins_pipe(ialu_cr_reg_reg); 13298 %} 13299 13300 instruct compP_rReg_mem(rFlagsRegU cr, rRegP op1, memory op2) 13301 %{ 13302 match(Set cr (CmpP op1 (LoadP op2))); 13303 predicate(n->in(2)->as_Load()->barrier_data() == 0); 13304 13305 ins_cost(500); // XXX 13306 format %{ "cmpq $op1, $op2\t# ptr" %} 13307 ins_encode %{ 13308 __ cmpq($op1$$Register, $op2$$Address); 13309 %} 13310 ins_pipe(ialu_cr_reg_mem); 13311 %} 13312 13313 // XXX this is generalized by compP_rReg_mem??? 13314 // Compare raw pointer (used in out-of-heap check). 13315 // Only works because non-oop pointers must be raw pointers 13316 // and raw pointers have no anti-dependencies. 13317 instruct compP_mem_rReg(rFlagsRegU cr, rRegP op1, memory op2) 13318 %{ 13319 predicate(n->in(2)->in(2)->bottom_type()->reloc() == relocInfo::none && 13320 n->in(2)->as_Load()->barrier_data() == 0); 13321 match(Set cr (CmpP op1 (LoadP op2))); 13322 13323 format %{ "cmpq $op1, $op2\t# raw ptr" %} 13324 ins_encode %{ 13325 __ cmpq($op1$$Register, $op2$$Address); 13326 %} 13327 ins_pipe(ialu_cr_reg_mem); 13328 %} 13329 13330 // This will generate a signed flags result. This should be OK since 13331 // any compare to a zero should be eq/neq. 13332 instruct testP_reg(rFlagsReg cr, rRegP src, immP0 zero) 13333 %{ 13334 match(Set cr (CmpP src zero)); 13335 13336 format %{ "testq $src, $src\t# ptr" %} 13337 ins_encode %{ 13338 __ testq($src$$Register, $src$$Register); 13339 %} 13340 ins_pipe(ialu_cr_reg_imm); 13341 %} 13342 13343 // This will generate a signed flags result. This should be OK since 13344 // any compare to a zero should be eq/neq. 13345 instruct testP_mem(rFlagsReg cr, memory op, immP0 zero) 13346 %{ 13347 predicate((!UseCompressedOops || (CompressedOops::base() != nullptr)) && 13348 n->in(1)->as_Load()->barrier_data() == 0); 13349 match(Set cr (CmpP (LoadP op) zero)); 13350 13351 ins_cost(500); // XXX 13352 format %{ "testq $op, 0xffffffffffffffff\t# ptr" %} 13353 ins_encode %{ 13354 __ testq($op$$Address, 0xFFFFFFFF); 13355 %} 13356 ins_pipe(ialu_cr_reg_imm); 13357 %} 13358 13359 instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero) 13360 %{ 13361 predicate(UseCompressedOops && (CompressedOops::base() == nullptr) && 13362 n->in(1)->as_Load()->barrier_data() == 0); 13363 match(Set cr (CmpP (LoadP mem) zero)); 13364 13365 format %{ "cmpq R12, $mem\t# ptr (R12_heapbase==0)" %} 13366 ins_encode %{ 13367 __ cmpq(r12, $mem$$Address); 13368 %} 13369 ins_pipe(ialu_cr_reg_mem); 13370 %} 13371 13372 instruct compN_rReg(rFlagsRegU cr, rRegN op1, rRegN op2) 13373 %{ 13374 match(Set cr (CmpN op1 op2)); 13375 13376 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 13377 ins_encode %{ __ cmpl($op1$$Register, $op2$$Register); %} 13378 ins_pipe(ialu_cr_reg_reg); 13379 %} 13380 13381 instruct compN_rReg_mem(rFlagsRegU cr, rRegN src, memory mem) 13382 %{ 13383 predicate(n->in(2)->as_Load()->barrier_data() == 0); 13384 match(Set cr (CmpN src (LoadN mem))); 13385 13386 format %{ "cmpl $src, $mem\t# compressed ptr" %} 13387 ins_encode %{ 13388 __ cmpl($src$$Register, $mem$$Address); 13389 %} 13390 ins_pipe(ialu_cr_reg_mem); 13391 %} 13392 13393 instruct compN_rReg_imm(rFlagsRegU cr, rRegN op1, immN op2) %{ 13394 match(Set cr (CmpN op1 op2)); 13395 13396 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 13397 ins_encode %{ 13398 __ cmp_narrow_oop($op1$$Register, (jobject)$op2$$constant); 13399 %} 13400 ins_pipe(ialu_cr_reg_imm); 13401 %} 13402 13403 instruct compN_mem_imm(rFlagsRegU cr, memory mem, immN src) 13404 %{ 13405 predicate(n->in(2)->as_Load()->barrier_data() == 0); 13406 match(Set cr (CmpN src (LoadN mem))); 13407 13408 format %{ "cmpl $mem, $src\t# compressed ptr" %} 13409 ins_encode %{ 13410 __ cmp_narrow_oop($mem$$Address, (jobject)$src$$constant); 13411 %} 13412 ins_pipe(ialu_cr_reg_mem); 13413 %} 13414 13415 instruct compN_rReg_imm_klass(rFlagsRegU cr, rRegN op1, immNKlass op2) %{ 13416 match(Set cr (CmpN op1 op2)); 13417 13418 format %{ "cmpl $op1, $op2\t# compressed klass ptr" %} 13419 ins_encode %{ 13420 __ cmp_narrow_klass($op1$$Register, (Klass*)$op2$$constant); 13421 %} 13422 ins_pipe(ialu_cr_reg_imm); 13423 %} 13424 13425 instruct compN_mem_imm_klass(rFlagsRegU cr, memory mem, immNKlass src) 13426 %{ 13427 predicate(!UseCompactObjectHeaders); 13428 match(Set cr (CmpN src (LoadNKlass mem))); 13429 13430 format %{ "cmpl $mem, $src\t# compressed klass ptr" %} 13431 ins_encode %{ 13432 __ cmp_narrow_klass($mem$$Address, (Klass*)$src$$constant); 13433 %} 13434 ins_pipe(ialu_cr_reg_mem); 13435 %} 13436 13437 instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{ 13438 match(Set cr (CmpN src zero)); 13439 13440 format %{ "testl $src, $src\t# compressed ptr" %} 13441 ins_encode %{ __ testl($src$$Register, $src$$Register); %} 13442 ins_pipe(ialu_cr_reg_imm); 13443 %} 13444 13445 instruct testN_mem(rFlagsReg cr, memory mem, immN0 zero) 13446 %{ 13447 predicate(CompressedOops::base() != nullptr && 13448 n->in(1)->as_Load()->barrier_data() == 0); 13449 match(Set cr (CmpN (LoadN mem) zero)); 13450 13451 ins_cost(500); // XXX 13452 format %{ "testl $mem, 0xffffffff\t# compressed ptr" %} 13453 ins_encode %{ 13454 __ cmpl($mem$$Address, (int)0xFFFFFFFF); 13455 %} 13456 ins_pipe(ialu_cr_reg_mem); 13457 %} 13458 13459 instruct testN_mem_reg0(rFlagsReg cr, memory mem, immN0 zero) 13460 %{ 13461 predicate(CompressedOops::base() == nullptr && 13462 n->in(1)->as_Load()->barrier_data() == 0); 13463 match(Set cr (CmpN (LoadN mem) zero)); 13464 13465 format %{ "cmpl R12, $mem\t# compressed ptr (R12_heapbase==0)" %} 13466 ins_encode %{ 13467 __ cmpl(r12, $mem$$Address); 13468 %} 13469 ins_pipe(ialu_cr_reg_mem); 13470 %} 13471 13472 // Yanked all unsigned pointer compare operations. 13473 // Pointer compares are done with CmpP which is already unsigned. 13474 13475 instruct compL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 13476 %{ 13477 match(Set cr (CmpL op1 op2)); 13478 13479 format %{ "cmpq $op1, $op2" %} 13480 ins_encode %{ 13481 __ cmpq($op1$$Register, $op2$$Register); 13482 %} 13483 ins_pipe(ialu_cr_reg_reg); 13484 %} 13485 13486 instruct compL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 13487 %{ 13488 match(Set cr (CmpL op1 op2)); 13489 13490 format %{ "cmpq $op1, $op2" %} 13491 ins_encode %{ 13492 __ cmpq($op1$$Register, $op2$$constant); 13493 %} 13494 ins_pipe(ialu_cr_reg_imm); 13495 %} 13496 13497 instruct compL_rReg_mem(rFlagsReg cr, rRegL op1, memory op2) 13498 %{ 13499 match(Set cr (CmpL op1 (LoadL op2))); 13500 13501 format %{ "cmpq $op1, $op2" %} 13502 ins_encode %{ 13503 __ cmpq($op1$$Register, $op2$$Address); 13504 %} 13505 ins_pipe(ialu_cr_reg_mem); 13506 %} 13507 13508 instruct testL_reg(rFlagsReg cr, rRegL src, immL0 zero) 13509 %{ 13510 match(Set cr (CmpL src zero)); 13511 13512 format %{ "testq $src, $src" %} 13513 ins_encode %{ 13514 __ testq($src$$Register, $src$$Register); 13515 %} 13516 ins_pipe(ialu_cr_reg_imm); 13517 %} 13518 13519 instruct testL_reg_imm(rFlagsReg cr, rRegL src, immL32 con, immL0 zero) 13520 %{ 13521 match(Set cr (CmpL (AndL src con) zero)); 13522 13523 format %{ "testq $src, $con\t# long" %} 13524 ins_encode %{ 13525 __ testq($src$$Register, $con$$constant); 13526 %} 13527 ins_pipe(ialu_cr_reg_imm); 13528 %} 13529 13530 instruct testL_reg_reg(rFlagsReg cr, rRegL src1, rRegL src2, immL0 zero) 13531 %{ 13532 match(Set cr (CmpL (AndL src1 src2) zero)); 13533 13534 format %{ "testq $src1, $src2\t# long" %} 13535 ins_encode %{ 13536 __ testq($src1$$Register, $src2$$Register); 13537 %} 13538 ins_pipe(ialu_cr_reg_imm); 13539 %} 13540 13541 instruct testL_reg_mem(rFlagsReg cr, rRegL src, memory mem, immL0 zero) 13542 %{ 13543 match(Set cr (CmpL (AndL src (LoadL mem)) zero)); 13544 13545 format %{ "testq $src, $mem" %} 13546 ins_encode %{ 13547 __ testq($src$$Register, $mem$$Address); 13548 %} 13549 ins_pipe(ialu_cr_reg_mem); 13550 %} 13551 13552 instruct testL_reg_mem2(rFlagsReg cr, rRegP src, memory mem, immL0 zero) 13553 %{ 13554 match(Set cr (CmpL (AndL (CastP2X src) (LoadL mem)) zero)); 13555 13556 format %{ "testq $src, $mem" %} 13557 ins_encode %{ 13558 __ testq($src$$Register, $mem$$Address); 13559 %} 13560 ins_pipe(ialu_cr_reg_mem); 13561 %} 13562 13563 // Manifest a CmpU result in an integer register. Very painful. 13564 // This is the test to avoid. 13565 instruct cmpU3_reg_reg(rRegI dst, rRegI src1, rRegI src2, rFlagsReg flags) 13566 %{ 13567 match(Set dst (CmpU3 src1 src2)); 13568 effect(KILL flags); 13569 13570 ins_cost(275); // XXX 13571 format %{ "cmpl $src1, $src2\t# CmpL3\n\t" 13572 "movl $dst, -1\n\t" 13573 "jb,u done\n\t" 13574 "setcc $dst \t# emits setne + movzbl or setzune for APX" 13575 "done:" %} 13576 ins_encode %{ 13577 Label done; 13578 __ cmpl($src1$$Register, $src2$$Register); 13579 __ movl($dst$$Register, -1); 13580 __ jccb(Assembler::below, done); 13581 __ setcc(Assembler::notZero, $dst$$Register); 13582 __ bind(done); 13583 %} 13584 ins_pipe(pipe_slow); 13585 %} 13586 13587 // Manifest a CmpL result in an integer register. Very painful. 13588 // This is the test to avoid. 13589 instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 13590 %{ 13591 match(Set dst (CmpL3 src1 src2)); 13592 effect(KILL flags); 13593 13594 ins_cost(275); // XXX 13595 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 13596 "movl $dst, -1\n\t" 13597 "jl,s done\n\t" 13598 "setcc $dst \t# emits setne + movzbl or setzune for APX" 13599 "done:" %} 13600 ins_encode %{ 13601 Label done; 13602 __ cmpq($src1$$Register, $src2$$Register); 13603 __ movl($dst$$Register, -1); 13604 __ jccb(Assembler::less, done); 13605 __ setcc(Assembler::notZero, $dst$$Register); 13606 __ bind(done); 13607 %} 13608 ins_pipe(pipe_slow); 13609 %} 13610 13611 // Manifest a CmpUL result in an integer register. Very painful. 13612 // This is the test to avoid. 13613 instruct cmpUL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 13614 %{ 13615 match(Set dst (CmpUL3 src1 src2)); 13616 effect(KILL flags); 13617 13618 ins_cost(275); // XXX 13619 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 13620 "movl $dst, -1\n\t" 13621 "jb,u done\n\t" 13622 "setcc $dst \t# emits setne + movzbl or setzune for APX" 13623 "done:" %} 13624 ins_encode %{ 13625 Label done; 13626 __ cmpq($src1$$Register, $src2$$Register); 13627 __ movl($dst$$Register, -1); 13628 __ jccb(Assembler::below, done); 13629 __ setcc(Assembler::notZero, $dst$$Register); 13630 __ bind(done); 13631 %} 13632 ins_pipe(pipe_slow); 13633 %} 13634 13635 // Unsigned long compare Instructions; really, same as signed long except they 13636 // produce an rFlagsRegU instead of rFlagsReg. 13637 instruct compUL_rReg(rFlagsRegU cr, rRegL op1, rRegL op2) 13638 %{ 13639 match(Set cr (CmpUL op1 op2)); 13640 13641 format %{ "cmpq $op1, $op2\t# unsigned" %} 13642 ins_encode %{ 13643 __ cmpq($op1$$Register, $op2$$Register); 13644 %} 13645 ins_pipe(ialu_cr_reg_reg); 13646 %} 13647 13648 instruct compUL_rReg_imm(rFlagsRegU cr, rRegL op1, immL32 op2) 13649 %{ 13650 match(Set cr (CmpUL op1 op2)); 13651 13652 format %{ "cmpq $op1, $op2\t# unsigned" %} 13653 ins_encode %{ 13654 __ cmpq($op1$$Register, $op2$$constant); 13655 %} 13656 ins_pipe(ialu_cr_reg_imm); 13657 %} 13658 13659 instruct compUL_rReg_mem(rFlagsRegU cr, rRegL op1, memory op2) 13660 %{ 13661 match(Set cr (CmpUL op1 (LoadL op2))); 13662 13663 format %{ "cmpq $op1, $op2\t# unsigned" %} 13664 ins_encode %{ 13665 __ cmpq($op1$$Register, $op2$$Address); 13666 %} 13667 ins_pipe(ialu_cr_reg_mem); 13668 %} 13669 13670 instruct testUL_reg(rFlagsRegU cr, rRegL src, immL0 zero) 13671 %{ 13672 match(Set cr (CmpUL src zero)); 13673 13674 format %{ "testq $src, $src\t# unsigned" %} 13675 ins_encode %{ 13676 __ testq($src$$Register, $src$$Register); 13677 %} 13678 ins_pipe(ialu_cr_reg_imm); 13679 %} 13680 13681 instruct compB_mem_imm(rFlagsReg cr, memory mem, immI8 imm) 13682 %{ 13683 match(Set cr (CmpI (LoadB mem) imm)); 13684 13685 ins_cost(125); 13686 format %{ "cmpb $mem, $imm" %} 13687 ins_encode %{ __ cmpb($mem$$Address, $imm$$constant); %} 13688 ins_pipe(ialu_cr_reg_mem); 13689 %} 13690 13691 instruct testUB_mem_imm(rFlagsReg cr, memory mem, immU7 imm, immI_0 zero) 13692 %{ 13693 match(Set cr (CmpI (AndI (LoadUB mem) imm) zero)); 13694 13695 ins_cost(125); 13696 format %{ "testb $mem, $imm\t# ubyte" %} 13697 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %} 13698 ins_pipe(ialu_cr_reg_mem); 13699 %} 13700 13701 instruct testB_mem_imm(rFlagsReg cr, memory mem, immI8 imm, immI_0 zero) 13702 %{ 13703 match(Set cr (CmpI (AndI (LoadB mem) imm) zero)); 13704 13705 ins_cost(125); 13706 format %{ "testb $mem, $imm\t# byte" %} 13707 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %} 13708 ins_pipe(ialu_cr_reg_mem); 13709 %} 13710 13711 //----------Max and Min-------------------------------------------------------- 13712 // Min Instructions 13713 13714 instruct cmovI_reg_g(rRegI dst, rRegI src, rFlagsReg cr) 13715 %{ 13716 predicate(!UseAPX); 13717 effect(USE_DEF dst, USE src, USE cr); 13718 13719 format %{ "cmovlgt $dst, $src\t# min" %} 13720 ins_encode %{ 13721 __ cmovl(Assembler::greater, $dst$$Register, $src$$Register); 13722 %} 13723 ins_pipe(pipe_cmov_reg); 13724 %} 13725 13726 instruct cmovI_reg_g_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr) 13727 %{ 13728 predicate(UseAPX); 13729 effect(DEF dst, USE src1, USE src2, USE cr); 13730 13731 format %{ "ecmovlgt $dst, $src1, $src2\t# min ndd" %} 13732 ins_encode %{ 13733 __ ecmovl(Assembler::greater, $dst$$Register, $src1$$Register, $src2$$Register); 13734 %} 13735 ins_pipe(pipe_cmov_reg); 13736 %} 13737 13738 instruct minI_rReg(rRegI dst, rRegI src) 13739 %{ 13740 predicate(!UseAPX); 13741 match(Set dst (MinI dst src)); 13742 13743 ins_cost(200); 13744 expand %{ 13745 rFlagsReg cr; 13746 compI_rReg(cr, dst, src); 13747 cmovI_reg_g(dst, src, cr); 13748 %} 13749 %} 13750 13751 instruct minI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2) 13752 %{ 13753 predicate(UseAPX); 13754 match(Set dst (MinI src1 src2)); 13755 effect(DEF dst, USE src1, USE src2); 13756 13757 ins_cost(200); 13758 expand %{ 13759 rFlagsReg cr; 13760 compI_rReg(cr, src1, src2); 13761 cmovI_reg_g_ndd(dst, src1, src2, cr); 13762 %} 13763 %} 13764 13765 instruct cmovI_reg_l(rRegI dst, rRegI src, rFlagsReg cr) 13766 %{ 13767 predicate(!UseAPX); 13768 effect(USE_DEF dst, USE src, USE cr); 13769 13770 format %{ "cmovllt $dst, $src\t# max" %} 13771 ins_encode %{ 13772 __ cmovl(Assembler::less, $dst$$Register, $src$$Register); 13773 %} 13774 ins_pipe(pipe_cmov_reg); 13775 %} 13776 13777 instruct cmovI_reg_l_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr) 13778 %{ 13779 predicate(UseAPX); 13780 effect(DEF dst, USE src1, USE src2, USE cr); 13781 13782 format %{ "ecmovllt $dst, $src1, $src2\t# max ndd" %} 13783 ins_encode %{ 13784 __ ecmovl(Assembler::less, $dst$$Register, $src1$$Register, $src2$$Register); 13785 %} 13786 ins_pipe(pipe_cmov_reg); 13787 %} 13788 13789 instruct maxI_rReg(rRegI dst, rRegI src) 13790 %{ 13791 predicate(!UseAPX); 13792 match(Set dst (MaxI dst src)); 13793 13794 ins_cost(200); 13795 expand %{ 13796 rFlagsReg cr; 13797 compI_rReg(cr, dst, src); 13798 cmovI_reg_l(dst, src, cr); 13799 %} 13800 %} 13801 13802 instruct maxI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2) 13803 %{ 13804 predicate(UseAPX); 13805 match(Set dst (MaxI src1 src2)); 13806 effect(DEF dst, USE src1, USE src2); 13807 13808 ins_cost(200); 13809 expand %{ 13810 rFlagsReg cr; 13811 compI_rReg(cr, src1, src2); 13812 cmovI_reg_l_ndd(dst, src1, src2, cr); 13813 %} 13814 %} 13815 13816 // ============================================================================ 13817 // Branch Instructions 13818 13819 // Jump Direct - Label defines a relative address from JMP+1 13820 instruct jmpDir(label labl) 13821 %{ 13822 match(Goto); 13823 effect(USE labl); 13824 13825 ins_cost(300); 13826 format %{ "jmp $labl" %} 13827 size(5); 13828 ins_encode %{ 13829 Label* L = $labl$$label; 13830 __ jmp(*L, false); // Always long jump 13831 %} 13832 ins_pipe(pipe_jmp); 13833 %} 13834 13835 // Jump Direct Conditional - Label defines a relative address from Jcc+1 13836 instruct jmpCon(cmpOp cop, rFlagsReg cr, label labl) 13837 %{ 13838 match(If cop cr); 13839 effect(USE labl); 13840 13841 ins_cost(300); 13842 format %{ "j$cop $labl" %} 13843 size(6); 13844 ins_encode %{ 13845 Label* L = $labl$$label; 13846 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 13847 %} 13848 ins_pipe(pipe_jcc); 13849 %} 13850 13851 // Jump Direct Conditional - Label defines a relative address from Jcc+1 13852 instruct jmpLoopEnd(cmpOp cop, rFlagsReg cr, label labl) 13853 %{ 13854 match(CountedLoopEnd cop cr); 13855 effect(USE labl); 13856 13857 ins_cost(300); 13858 format %{ "j$cop $labl\t# loop end" %} 13859 size(6); 13860 ins_encode %{ 13861 Label* L = $labl$$label; 13862 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 13863 %} 13864 ins_pipe(pipe_jcc); 13865 %} 13866 13867 // Jump Direct Conditional - using unsigned comparison 13868 instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 13869 match(If cop cmp); 13870 effect(USE labl); 13871 13872 ins_cost(300); 13873 format %{ "j$cop,u $labl" %} 13874 size(6); 13875 ins_encode %{ 13876 Label* L = $labl$$label; 13877 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 13878 %} 13879 ins_pipe(pipe_jcc); 13880 %} 13881 13882 instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 13883 match(If cop cmp); 13884 effect(USE labl); 13885 13886 ins_cost(200); 13887 format %{ "j$cop,u $labl" %} 13888 size(6); 13889 ins_encode %{ 13890 Label* L = $labl$$label; 13891 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 13892 %} 13893 ins_pipe(pipe_jcc); 13894 %} 13895 13896 instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 13897 match(If cop cmp); 13898 effect(USE labl); 13899 13900 ins_cost(200); 13901 format %{ $$template 13902 if ($cop$$cmpcode == Assembler::notEqual) { 13903 $$emit$$"jp,u $labl\n\t" 13904 $$emit$$"j$cop,u $labl" 13905 } else { 13906 $$emit$$"jp,u done\n\t" 13907 $$emit$$"j$cop,u $labl\n\t" 13908 $$emit$$"done:" 13909 } 13910 %} 13911 ins_encode %{ 13912 Label* l = $labl$$label; 13913 if ($cop$$cmpcode == Assembler::notEqual) { 13914 __ jcc(Assembler::parity, *l, false); 13915 __ jcc(Assembler::notEqual, *l, false); 13916 } else if ($cop$$cmpcode == Assembler::equal) { 13917 Label done; 13918 __ jccb(Assembler::parity, done); 13919 __ jcc(Assembler::equal, *l, false); 13920 __ bind(done); 13921 } else { 13922 ShouldNotReachHere(); 13923 } 13924 %} 13925 ins_pipe(pipe_jcc); 13926 %} 13927 13928 // ============================================================================ 13929 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary 13930 // superklass array for an instance of the superklass. Set a hidden 13931 // internal cache on a hit (cache is checked with exposed code in 13932 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The 13933 // encoding ALSO sets flags. 13934 13935 instruct partialSubtypeCheck(rdi_RegP result, 13936 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 13937 rFlagsReg cr) 13938 %{ 13939 match(Set result (PartialSubtypeCheck sub super)); 13940 predicate(!UseSecondarySupersTable); 13941 effect(KILL rcx, KILL cr); 13942 13943 ins_cost(1100); // slightly larger than the next version 13944 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 13945 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 13946 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 13947 "repne scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t" 13948 "jne,s miss\t\t# Missed: rdi not-zero\n\t" 13949 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 13950 "xorq $result, $result\t\t Hit: rdi zero\n\t" 13951 "miss:\t" %} 13952 13953 ins_encode %{ 13954 Label miss; 13955 // NB: Callers may assume that, when $result is a valid register, 13956 // check_klass_subtype_slow_path_linear sets it to a nonzero 13957 // value. 13958 __ check_klass_subtype_slow_path_linear($sub$$Register, $super$$Register, 13959 $rcx$$Register, $result$$Register, 13960 nullptr, &miss, 13961 /*set_cond_codes:*/ true); 13962 __ xorptr($result$$Register, $result$$Register); 13963 __ bind(miss); 13964 %} 13965 13966 ins_pipe(pipe_slow); 13967 %} 13968 13969 // ============================================================================ 13970 // Two versions of hashtable-based partialSubtypeCheck, both used when 13971 // we need to search for a super class in the secondary supers array. 13972 // The first is used when we don't know _a priori_ the class being 13973 // searched for. The second, far more common, is used when we do know: 13974 // this is used for instanceof, checkcast, and any case where C2 can 13975 // determine it by constant propagation. 13976 13977 instruct partialSubtypeCheckVarSuper(rsi_RegP sub, rax_RegP super, rdi_RegP result, 13978 rdx_RegL temp1, rcx_RegL temp2, rbx_RegP temp3, r11_RegL temp4, 13979 rFlagsReg cr) 13980 %{ 13981 match(Set result (PartialSubtypeCheck sub super)); 13982 predicate(UseSecondarySupersTable); 13983 effect(KILL cr, TEMP temp1, TEMP temp2, TEMP temp3, TEMP temp4); 13984 13985 ins_cost(1000); 13986 format %{ "partialSubtypeCheck $result, $sub, $super" %} 13987 13988 ins_encode %{ 13989 __ lookup_secondary_supers_table_var($sub$$Register, $super$$Register, $temp1$$Register, $temp2$$Register, 13990 $temp3$$Register, $temp4$$Register, $result$$Register); 13991 %} 13992 13993 ins_pipe(pipe_slow); 13994 %} 13995 13996 instruct partialSubtypeCheckConstSuper(rsi_RegP sub, rax_RegP super_reg, immP super_con, rdi_RegP result, 13997 rdx_RegL temp1, rcx_RegL temp2, rbx_RegP temp3, r11_RegL temp4, 13998 rFlagsReg cr) 13999 %{ 14000 match(Set result (PartialSubtypeCheck sub (Binary super_reg super_con))); 14001 predicate(UseSecondarySupersTable); 14002 effect(KILL cr, TEMP temp1, TEMP temp2, TEMP temp3, TEMP temp4); 14003 14004 ins_cost(700); // smaller than the next version 14005 format %{ "partialSubtypeCheck $result, $sub, $super_reg, $super_con" %} 14006 14007 ins_encode %{ 14008 u1 super_klass_slot = ((Klass*)$super_con$$constant)->hash_slot(); 14009 if (InlineSecondarySupersTest) { 14010 __ lookup_secondary_supers_table_const($sub$$Register, $super_reg$$Register, $temp1$$Register, $temp2$$Register, 14011 $temp3$$Register, $temp4$$Register, $result$$Register, 14012 super_klass_slot); 14013 } else { 14014 __ call(RuntimeAddress(StubRoutines::lookup_secondary_supers_table_stub(super_klass_slot))); 14015 } 14016 %} 14017 14018 ins_pipe(pipe_slow); 14019 %} 14020 14021 // ============================================================================ 14022 // Branch Instructions -- short offset versions 14023 // 14024 // These instructions are used to replace jumps of a long offset (the default 14025 // match) with jumps of a shorter offset. These instructions are all tagged 14026 // with the ins_short_branch attribute, which causes the ADLC to suppress the 14027 // match rules in general matching. Instead, the ADLC generates a conversion 14028 // method in the MachNode which can be used to do in-place replacement of the 14029 // long variant with the shorter variant. The compiler will determine if a 14030 // branch can be taken by the is_short_branch_offset() predicate in the machine 14031 // specific code section of the file. 14032 14033 // Jump Direct - Label defines a relative address from JMP+1 14034 instruct jmpDir_short(label labl) %{ 14035 match(Goto); 14036 effect(USE labl); 14037 14038 ins_cost(300); 14039 format %{ "jmp,s $labl" %} 14040 size(2); 14041 ins_encode %{ 14042 Label* L = $labl$$label; 14043 __ jmpb(*L); 14044 %} 14045 ins_pipe(pipe_jmp); 14046 ins_short_branch(1); 14047 %} 14048 14049 // Jump Direct Conditional - Label defines a relative address from Jcc+1 14050 instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{ 14051 match(If cop cr); 14052 effect(USE labl); 14053 14054 ins_cost(300); 14055 format %{ "j$cop,s $labl" %} 14056 size(2); 14057 ins_encode %{ 14058 Label* L = $labl$$label; 14059 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 14060 %} 14061 ins_pipe(pipe_jcc); 14062 ins_short_branch(1); 14063 %} 14064 14065 // Jump Direct Conditional - Label defines a relative address from Jcc+1 14066 instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{ 14067 match(CountedLoopEnd cop cr); 14068 effect(USE labl); 14069 14070 ins_cost(300); 14071 format %{ "j$cop,s $labl\t# loop end" %} 14072 size(2); 14073 ins_encode %{ 14074 Label* L = $labl$$label; 14075 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 14076 %} 14077 ins_pipe(pipe_jcc); 14078 ins_short_branch(1); 14079 %} 14080 14081 // Jump Direct Conditional - using unsigned comparison 14082 instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 14083 match(If cop cmp); 14084 effect(USE labl); 14085 14086 ins_cost(300); 14087 format %{ "j$cop,us $labl" %} 14088 size(2); 14089 ins_encode %{ 14090 Label* L = $labl$$label; 14091 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 14092 %} 14093 ins_pipe(pipe_jcc); 14094 ins_short_branch(1); 14095 %} 14096 14097 instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 14098 match(If cop cmp); 14099 effect(USE labl); 14100 14101 ins_cost(300); 14102 format %{ "j$cop,us $labl" %} 14103 size(2); 14104 ins_encode %{ 14105 Label* L = $labl$$label; 14106 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 14107 %} 14108 ins_pipe(pipe_jcc); 14109 ins_short_branch(1); 14110 %} 14111 14112 instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 14113 match(If cop cmp); 14114 effect(USE labl); 14115 14116 ins_cost(300); 14117 format %{ $$template 14118 if ($cop$$cmpcode == Assembler::notEqual) { 14119 $$emit$$"jp,u,s $labl\n\t" 14120 $$emit$$"j$cop,u,s $labl" 14121 } else { 14122 $$emit$$"jp,u,s done\n\t" 14123 $$emit$$"j$cop,u,s $labl\n\t" 14124 $$emit$$"done:" 14125 } 14126 %} 14127 size(4); 14128 ins_encode %{ 14129 Label* l = $labl$$label; 14130 if ($cop$$cmpcode == Assembler::notEqual) { 14131 __ jccb(Assembler::parity, *l); 14132 __ jccb(Assembler::notEqual, *l); 14133 } else if ($cop$$cmpcode == Assembler::equal) { 14134 Label done; 14135 __ jccb(Assembler::parity, done); 14136 __ jccb(Assembler::equal, *l); 14137 __ bind(done); 14138 } else { 14139 ShouldNotReachHere(); 14140 } 14141 %} 14142 ins_pipe(pipe_jcc); 14143 ins_short_branch(1); 14144 %} 14145 14146 // ============================================================================ 14147 // inlined locking and unlocking 14148 14149 instruct cmpFastLock(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr) %{ 14150 predicate(LockingMode != LM_LIGHTWEIGHT); 14151 match(Set cr (FastLock object box)); 14152 effect(TEMP tmp, TEMP scr, USE_KILL box); 14153 ins_cost(300); 14154 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr" %} 14155 ins_encode %{ 14156 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, 14157 $scr$$Register, noreg, noreg, r15_thread, nullptr); 14158 %} 14159 ins_pipe(pipe_slow); 14160 %} 14161 14162 instruct cmpFastUnlock(rFlagsReg cr, rRegP object, rax_RegP box, rRegP tmp) %{ 14163 predicate(LockingMode != LM_LIGHTWEIGHT); 14164 match(Set cr (FastUnlock object box)); 14165 effect(TEMP tmp, USE_KILL box); 14166 ins_cost(300); 14167 format %{ "fastunlock $object,$box\t! kills $box,$tmp" %} 14168 ins_encode %{ 14169 __ fast_unlock($object$$Register, $box$$Register, $tmp$$Register); 14170 %} 14171 ins_pipe(pipe_slow); 14172 %} 14173 14174 instruct cmpFastLockLightweight(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI rax_reg, rRegP tmp) %{ 14175 predicate(LockingMode == LM_LIGHTWEIGHT); 14176 match(Set cr (FastLock object box)); 14177 effect(TEMP rax_reg, TEMP tmp, USE_KILL box); 14178 ins_cost(300); 14179 format %{ "fastlock $object,$box\t! kills $box,$rax_reg,$tmp" %} 14180 ins_encode %{ 14181 __ fast_lock_lightweight($object$$Register, $box$$Register, $rax_reg$$Register, $tmp$$Register, r15_thread); 14182 %} 14183 ins_pipe(pipe_slow); 14184 %} 14185 14186 instruct cmpFastUnlockLightweight(rFlagsReg cr, rRegP object, rax_RegP rax_reg, rRegP tmp) %{ 14187 predicate(LockingMode == LM_LIGHTWEIGHT); 14188 match(Set cr (FastUnlock object rax_reg)); 14189 effect(TEMP tmp, USE_KILL rax_reg); 14190 ins_cost(300); 14191 format %{ "fastunlock $object,$rax_reg\t! kills $rax_reg,$tmp" %} 14192 ins_encode %{ 14193 __ fast_unlock_lightweight($object$$Register, $rax_reg$$Register, $tmp$$Register, r15_thread); 14194 %} 14195 ins_pipe(pipe_slow); 14196 %} 14197 14198 14199 // ============================================================================ 14200 // Safepoint Instructions 14201 instruct safePoint_poll_tls(rFlagsReg cr, rRegP poll) 14202 %{ 14203 match(SafePoint poll); 14204 effect(KILL cr, USE poll); 14205 14206 format %{ "testl rax, [$poll]\t" 14207 "# Safepoint: poll for GC" %} 14208 ins_cost(125); 14209 ins_encode %{ 14210 __ relocate(relocInfo::poll_type); 14211 address pre_pc = __ pc(); 14212 __ testl(rax, Address($poll$$Register, 0)); 14213 assert(nativeInstruction_at(pre_pc)->is_safepoint_poll(), "must emit test %%eax [reg]"); 14214 %} 14215 ins_pipe(ialu_reg_mem); 14216 %} 14217 14218 instruct mask_all_evexL(kReg dst, rRegL src) %{ 14219 match(Set dst (MaskAll src)); 14220 format %{ "mask_all_evexL $dst, $src \t! mask all operation" %} 14221 ins_encode %{ 14222 int mask_len = Matcher::vector_length(this); 14223 __ vector_maskall_operation($dst$$KRegister, $src$$Register, mask_len); 14224 %} 14225 ins_pipe( pipe_slow ); 14226 %} 14227 14228 instruct mask_all_evexI_GT32(kReg dst, rRegI src, rRegL tmp) %{ 14229 predicate(Matcher::vector_length(n) > 32); 14230 match(Set dst (MaskAll src)); 14231 effect(TEMP tmp); 14232 format %{ "mask_all_evexI_GT32 $dst, $src \t! using $tmp as TEMP" %} 14233 ins_encode %{ 14234 int mask_len = Matcher::vector_length(this); 14235 __ movslq($tmp$$Register, $src$$Register); 14236 __ vector_maskall_operation($dst$$KRegister, $tmp$$Register, mask_len); 14237 %} 14238 ins_pipe( pipe_slow ); 14239 %} 14240 14241 // ============================================================================ 14242 // Procedure Call/Return Instructions 14243 // Call Java Static Instruction 14244 // Note: If this code changes, the corresponding ret_addr_offset() and 14245 // compute_padding() functions will have to be adjusted. 14246 instruct CallStaticJavaDirect(method meth) %{ 14247 match(CallStaticJava); 14248 effect(USE meth); 14249 14250 ins_cost(300); 14251 format %{ "call,static " %} 14252 opcode(0xE8); /* E8 cd */ 14253 ins_encode(clear_avx, Java_Static_Call(meth), call_epilog); 14254 ins_pipe(pipe_slow); 14255 ins_alignment(4); 14256 %} 14257 14258 // Call Java Dynamic Instruction 14259 // Note: If this code changes, the corresponding ret_addr_offset() and 14260 // compute_padding() functions will have to be adjusted. 14261 instruct CallDynamicJavaDirect(method meth) 14262 %{ 14263 match(CallDynamicJava); 14264 effect(USE meth); 14265 14266 ins_cost(300); 14267 format %{ "movq rax, #Universe::non_oop_word()\n\t" 14268 "call,dynamic " %} 14269 ins_encode(clear_avx, Java_Dynamic_Call(meth), call_epilog); 14270 ins_pipe(pipe_slow); 14271 ins_alignment(4); 14272 %} 14273 14274 // Call Runtime Instruction 14275 instruct CallRuntimeDirect(method meth) 14276 %{ 14277 match(CallRuntime); 14278 effect(USE meth); 14279 14280 ins_cost(300); 14281 format %{ "call,runtime " %} 14282 ins_encode(clear_avx, Java_To_Runtime(meth)); 14283 ins_pipe(pipe_slow); 14284 %} 14285 14286 // Call runtime without safepoint 14287 instruct CallLeafDirect(method meth) 14288 %{ 14289 match(CallLeaf); 14290 effect(USE meth); 14291 14292 ins_cost(300); 14293 format %{ "call_leaf,runtime " %} 14294 ins_encode(clear_avx, Java_To_Runtime(meth)); 14295 ins_pipe(pipe_slow); 14296 %} 14297 14298 // Call runtime without safepoint and with vector arguments 14299 instruct CallLeafDirectVector(method meth) 14300 %{ 14301 match(CallLeafVector); 14302 effect(USE meth); 14303 14304 ins_cost(300); 14305 format %{ "call_leaf,vector " %} 14306 ins_encode(Java_To_Runtime(meth)); 14307 ins_pipe(pipe_slow); 14308 %} 14309 14310 // Call runtime without safepoint 14311 instruct CallLeafNoFPDirect(method meth) 14312 %{ 14313 match(CallLeafNoFP); 14314 effect(USE meth); 14315 14316 ins_cost(300); 14317 format %{ "call_leaf_nofp,runtime " %} 14318 ins_encode(clear_avx, Java_To_Runtime(meth)); 14319 ins_pipe(pipe_slow); 14320 %} 14321 14322 // Return Instruction 14323 // Remove the return address & jump to it. 14324 // Notice: We always emit a nop after a ret to make sure there is room 14325 // for safepoint patching 14326 instruct Ret() 14327 %{ 14328 match(Return); 14329 14330 format %{ "ret" %} 14331 ins_encode %{ 14332 __ ret(0); 14333 %} 14334 ins_pipe(pipe_jmp); 14335 %} 14336 14337 // Tail Call; Jump from runtime stub to Java code. 14338 // Also known as an 'interprocedural jump'. 14339 // Target of jump will eventually return to caller. 14340 // TailJump below removes the return address. 14341 // Don't use rbp for 'jump_target' because a MachEpilogNode has already been 14342 // emitted just above the TailCall which has reset rbp to the caller state. 14343 instruct TailCalljmpInd(no_rbp_RegP jump_target, rbx_RegP method_ptr) 14344 %{ 14345 match(TailCall jump_target method_ptr); 14346 14347 ins_cost(300); 14348 format %{ "jmp $jump_target\t# rbx holds method" %} 14349 ins_encode %{ 14350 __ jmp($jump_target$$Register); 14351 %} 14352 ins_pipe(pipe_jmp); 14353 %} 14354 14355 // Tail Jump; remove the return address; jump to target. 14356 // TailCall above leaves the return address around. 14357 instruct tailjmpInd(no_rbp_RegP jump_target, rax_RegP ex_oop) 14358 %{ 14359 match(TailJump jump_target ex_oop); 14360 14361 ins_cost(300); 14362 format %{ "popq rdx\t# pop return address\n\t" 14363 "jmp $jump_target" %} 14364 ins_encode %{ 14365 __ popq(as_Register(RDX_enc)); 14366 __ jmp($jump_target$$Register); 14367 %} 14368 ins_pipe(pipe_jmp); 14369 %} 14370 14371 // Forward exception. 14372 instruct ForwardExceptionjmp() 14373 %{ 14374 match(ForwardException); 14375 14376 format %{ "jmp forward_exception_stub" %} 14377 ins_encode %{ 14378 __ jump(RuntimeAddress(StubRoutines::forward_exception_entry()), noreg); 14379 %} 14380 ins_pipe(pipe_jmp); 14381 %} 14382 14383 // Create exception oop: created by stack-crawling runtime code. 14384 // Created exception is now available to this handler, and is setup 14385 // just prior to jumping to this handler. No code emitted. 14386 instruct CreateException(rax_RegP ex_oop) 14387 %{ 14388 match(Set ex_oop (CreateEx)); 14389 14390 size(0); 14391 // use the following format syntax 14392 format %{ "# exception oop is in rax; no code emitted" %} 14393 ins_encode(); 14394 ins_pipe(empty); 14395 %} 14396 14397 // Rethrow exception: 14398 // The exception oop will come in the first argument position. 14399 // Then JUMP (not call) to the rethrow stub code. 14400 instruct RethrowException() 14401 %{ 14402 match(Rethrow); 14403 14404 // use the following format syntax 14405 format %{ "jmp rethrow_stub" %} 14406 ins_encode %{ 14407 __ jump(RuntimeAddress(OptoRuntime::rethrow_stub()), noreg); 14408 %} 14409 ins_pipe(pipe_jmp); 14410 %} 14411 14412 // ============================================================================ 14413 // This name is KNOWN by the ADLC and cannot be changed. 14414 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type 14415 // for this guy. 14416 instruct tlsLoadP(r15_RegP dst) %{ 14417 match(Set dst (ThreadLocal)); 14418 effect(DEF dst); 14419 14420 size(0); 14421 format %{ "# TLS is in R15" %} 14422 ins_encode( /*empty encoding*/ ); 14423 ins_pipe(ialu_reg_reg); 14424 %} 14425 14426 14427 //----------PEEPHOLE RULES----------------------------------------------------- 14428 // These must follow all instruction definitions as they use the names 14429 // defined in the instructions definitions. 14430 // 14431 // peeppredicate ( rule_predicate ); 14432 // // the predicate unless which the peephole rule will be ignored 14433 // 14434 // peepmatch ( root_instr_name [preceding_instruction]* ); 14435 // 14436 // peepprocedure ( procedure_name ); 14437 // // provide a procedure name to perform the optimization, the procedure should 14438 // // reside in the architecture dependent peephole file, the method has the 14439 // // signature of MachNode* (Block*, int, PhaseRegAlloc*, (MachNode*)(*)(), int...) 14440 // // with the arguments being the basic block, the current node index inside the 14441 // // block, the register allocator, the functions upon invoked return a new node 14442 // // defined in peepreplace, and the rules of the nodes appearing in the 14443 // // corresponding peepmatch, the function return true if successful, else 14444 // // return false 14445 // 14446 // peepconstraint %{ 14447 // (instruction_number.operand_name relational_op instruction_number.operand_name 14448 // [, ...] ); 14449 // // instruction numbers are zero-based using left to right order in peepmatch 14450 // 14451 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 14452 // // provide an instruction_number.operand_name for each operand that appears 14453 // // in the replacement instruction's match rule 14454 // 14455 // ---------VM FLAGS--------------------------------------------------------- 14456 // 14457 // All peephole optimizations can be turned off using -XX:-OptoPeephole 14458 // 14459 // Each peephole rule is given an identifying number starting with zero and 14460 // increasing by one in the order seen by the parser. An individual peephole 14461 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 14462 // on the command-line. 14463 // 14464 // ---------CURRENT LIMITATIONS---------------------------------------------- 14465 // 14466 // Only transformations inside a basic block (do we need more for peephole) 14467 // 14468 // ---------EXAMPLE---------------------------------------------------------- 14469 // 14470 // // pertinent parts of existing instructions in architecture description 14471 // instruct movI(rRegI dst, rRegI src) 14472 // %{ 14473 // match(Set dst (CopyI src)); 14474 // %} 14475 // 14476 // instruct incI_rReg(rRegI dst, immI_1 src, rFlagsReg cr) 14477 // %{ 14478 // match(Set dst (AddI dst src)); 14479 // effect(KILL cr); 14480 // %} 14481 // 14482 // instruct leaI_rReg_immI(rRegI dst, immI_1 src) 14483 // %{ 14484 // match(Set dst (AddI dst src)); 14485 // %} 14486 // 14487 // 1. Simple replacement 14488 // - Only match adjacent instructions in same basic block 14489 // - Only equality constraints 14490 // - Only constraints between operands, not (0.dest_reg == RAX_enc) 14491 // - Only one replacement instruction 14492 // 14493 // // Change (inc mov) to lea 14494 // peephole %{ 14495 // // lea should only be emitted when beneficial 14496 // peeppredicate( VM_Version::supports_fast_2op_lea() ); 14497 // // increment preceded by register-register move 14498 // peepmatch ( incI_rReg movI ); 14499 // // require that the destination register of the increment 14500 // // match the destination register of the move 14501 // peepconstraint ( 0.dst == 1.dst ); 14502 // // construct a replacement instruction that sets 14503 // // the destination to ( move's source register + one ) 14504 // peepreplace ( leaI_rReg_immI( 0.dst 1.src 0.src ) ); 14505 // %} 14506 // 14507 // 2. Procedural replacement 14508 // - More flexible finding relevent nodes 14509 // - More flexible constraints 14510 // - More flexible transformations 14511 // - May utilise architecture-dependent API more effectively 14512 // - Currently only one replacement instruction due to adlc parsing capabilities 14513 // 14514 // // Change (inc mov) to lea 14515 // peephole %{ 14516 // // lea should only be emitted when beneficial 14517 // peeppredicate( VM_Version::supports_fast_2op_lea() ); 14518 // // the rule numbers of these nodes inside are passed into the function below 14519 // peepmatch ( incI_rReg movI ); 14520 // // the method that takes the responsibility of transformation 14521 // peepprocedure ( inc_mov_to_lea ); 14522 // // the replacement is a leaI_rReg_immI, a lambda upon invoked creating this 14523 // // node is passed into the function above 14524 // peepreplace ( leaI_rReg_immI() ); 14525 // %} 14526 14527 // These instructions is not matched by the matcher but used by the peephole 14528 instruct leaI_rReg_rReg_peep(rRegI dst, rRegI src1, rRegI src2) 14529 %{ 14530 predicate(false); 14531 match(Set dst (AddI src1 src2)); 14532 format %{ "leal $dst, [$src1 + $src2]" %} 14533 ins_encode %{ 14534 Register dst = $dst$$Register; 14535 Register src1 = $src1$$Register; 14536 Register src2 = $src2$$Register; 14537 if (src1 != rbp && src1 != r13) { 14538 __ leal(dst, Address(src1, src2, Address::times_1)); 14539 } else { 14540 assert(src2 != rbp && src2 != r13, ""); 14541 __ leal(dst, Address(src2, src1, Address::times_1)); 14542 } 14543 %} 14544 ins_pipe(ialu_reg_reg); 14545 %} 14546 14547 instruct leaI_rReg_immI_peep(rRegI dst, rRegI src1, immI src2) 14548 %{ 14549 predicate(false); 14550 match(Set dst (AddI src1 src2)); 14551 format %{ "leal $dst, [$src1 + $src2]" %} 14552 ins_encode %{ 14553 __ leal($dst$$Register, Address($src1$$Register, $src2$$constant)); 14554 %} 14555 ins_pipe(ialu_reg_reg); 14556 %} 14557 14558 instruct leaI_rReg_immI2_peep(rRegI dst, rRegI src, immI2 shift) 14559 %{ 14560 predicate(false); 14561 match(Set dst (LShiftI src shift)); 14562 format %{ "leal $dst, [$src << $shift]" %} 14563 ins_encode %{ 14564 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($shift$$constant); 14565 Register src = $src$$Register; 14566 if (scale == Address::times_2 && src != rbp && src != r13) { 14567 __ leal($dst$$Register, Address(src, src, Address::times_1)); 14568 } else { 14569 __ leal($dst$$Register, Address(noreg, src, scale)); 14570 } 14571 %} 14572 ins_pipe(ialu_reg_reg); 14573 %} 14574 14575 instruct leaL_rReg_rReg_peep(rRegL dst, rRegL src1, rRegL src2) 14576 %{ 14577 predicate(false); 14578 match(Set dst (AddL src1 src2)); 14579 format %{ "leaq $dst, [$src1 + $src2]" %} 14580 ins_encode %{ 14581 Register dst = $dst$$Register; 14582 Register src1 = $src1$$Register; 14583 Register src2 = $src2$$Register; 14584 if (src1 != rbp && src1 != r13) { 14585 __ leaq(dst, Address(src1, src2, Address::times_1)); 14586 } else { 14587 assert(src2 != rbp && src2 != r13, ""); 14588 __ leaq(dst, Address(src2, src1, Address::times_1)); 14589 } 14590 %} 14591 ins_pipe(ialu_reg_reg); 14592 %} 14593 14594 instruct leaL_rReg_immL32_peep(rRegL dst, rRegL src1, immL32 src2) 14595 %{ 14596 predicate(false); 14597 match(Set dst (AddL src1 src2)); 14598 format %{ "leaq $dst, [$src1 + $src2]" %} 14599 ins_encode %{ 14600 __ leaq($dst$$Register, Address($src1$$Register, $src2$$constant)); 14601 %} 14602 ins_pipe(ialu_reg_reg); 14603 %} 14604 14605 instruct leaL_rReg_immI2_peep(rRegL dst, rRegL src, immI2 shift) 14606 %{ 14607 predicate(false); 14608 match(Set dst (LShiftL src shift)); 14609 format %{ "leaq $dst, [$src << $shift]" %} 14610 ins_encode %{ 14611 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($shift$$constant); 14612 Register src = $src$$Register; 14613 if (scale == Address::times_2 && src != rbp && src != r13) { 14614 __ leaq($dst$$Register, Address(src, src, Address::times_1)); 14615 } else { 14616 __ leaq($dst$$Register, Address(noreg, src, scale)); 14617 } 14618 %} 14619 ins_pipe(ialu_reg_reg); 14620 %} 14621 14622 // These peephole rules replace mov + I pairs (where I is one of {add, inc, dec, 14623 // sal}) with lea instructions. The {add, sal} rules are beneficial in 14624 // processors with at least partial ALU support for lea 14625 // (supports_fast_2op_lea()), whereas the {inc, dec} rules are only generally 14626 // beneficial for processors with full ALU support 14627 // (VM_Version::supports_fast_3op_lea()) and Intel Cascade Lake. 14628 14629 peephole 14630 %{ 14631 peeppredicate(VM_Version::supports_fast_2op_lea()); 14632 peepmatch (addI_rReg); 14633 peepprocedure (lea_coalesce_reg); 14634 peepreplace (leaI_rReg_rReg_peep()); 14635 %} 14636 14637 peephole 14638 %{ 14639 peeppredicate(VM_Version::supports_fast_2op_lea()); 14640 peepmatch (addI_rReg_imm); 14641 peepprocedure (lea_coalesce_imm); 14642 peepreplace (leaI_rReg_immI_peep()); 14643 %} 14644 14645 peephole 14646 %{ 14647 peeppredicate(VM_Version::supports_fast_3op_lea() || 14648 VM_Version::is_intel_cascade_lake()); 14649 peepmatch (incI_rReg); 14650 peepprocedure (lea_coalesce_imm); 14651 peepreplace (leaI_rReg_immI_peep()); 14652 %} 14653 14654 peephole 14655 %{ 14656 peeppredicate(VM_Version::supports_fast_3op_lea() || 14657 VM_Version::is_intel_cascade_lake()); 14658 peepmatch (decI_rReg); 14659 peepprocedure (lea_coalesce_imm); 14660 peepreplace (leaI_rReg_immI_peep()); 14661 %} 14662 14663 peephole 14664 %{ 14665 peeppredicate(VM_Version::supports_fast_2op_lea()); 14666 peepmatch (salI_rReg_immI2); 14667 peepprocedure (lea_coalesce_imm); 14668 peepreplace (leaI_rReg_immI2_peep()); 14669 %} 14670 14671 peephole 14672 %{ 14673 peeppredicate(VM_Version::supports_fast_2op_lea()); 14674 peepmatch (addL_rReg); 14675 peepprocedure (lea_coalesce_reg); 14676 peepreplace (leaL_rReg_rReg_peep()); 14677 %} 14678 14679 peephole 14680 %{ 14681 peeppredicate(VM_Version::supports_fast_2op_lea()); 14682 peepmatch (addL_rReg_imm); 14683 peepprocedure (lea_coalesce_imm); 14684 peepreplace (leaL_rReg_immL32_peep()); 14685 %} 14686 14687 peephole 14688 %{ 14689 peeppredicate(VM_Version::supports_fast_3op_lea() || 14690 VM_Version::is_intel_cascade_lake()); 14691 peepmatch (incL_rReg); 14692 peepprocedure (lea_coalesce_imm); 14693 peepreplace (leaL_rReg_immL32_peep()); 14694 %} 14695 14696 peephole 14697 %{ 14698 peeppredicate(VM_Version::supports_fast_3op_lea() || 14699 VM_Version::is_intel_cascade_lake()); 14700 peepmatch (decL_rReg); 14701 peepprocedure (lea_coalesce_imm); 14702 peepreplace (leaL_rReg_immL32_peep()); 14703 %} 14704 14705 peephole 14706 %{ 14707 peeppredicate(VM_Version::supports_fast_2op_lea()); 14708 peepmatch (salL_rReg_immI2); 14709 peepprocedure (lea_coalesce_imm); 14710 peepreplace (leaL_rReg_immI2_peep()); 14711 %} 14712 14713 // These peephole rules matches instructions which set flags and are followed by a testI/L_reg 14714 // 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 14715 14716 //int variant 14717 peephole 14718 %{ 14719 peepmatch (testI_reg); 14720 peepprocedure (test_may_remove); 14721 %} 14722 14723 //long variant 14724 peephole 14725 %{ 14726 peepmatch (testL_reg); 14727 peepprocedure (test_may_remove); 14728 %} 14729 14730 14731 //----------SMARTSPILL RULES--------------------------------------------------- 14732 // These must follow all instruction definitions as they use the names 14733 // defined in the instructions definitions.