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 extern RegMask _ANY_REG_mask; 442 extern RegMask _PTR_REG_mask; 443 extern RegMask _PTR_REG_NO_RBP_mask; 444 extern RegMask _PTR_NO_RAX_REG_mask; 445 extern RegMask _PTR_NO_RAX_RBX_REG_mask; 446 extern RegMask _LONG_REG_mask; 447 extern RegMask _LONG_NO_RAX_RDX_REG_mask; 448 extern RegMask _LONG_NO_RCX_REG_mask; 449 extern RegMask _LONG_NO_RBP_R13_REG_mask; 450 extern RegMask _INT_REG_mask; 451 extern RegMask _INT_NO_RAX_RDX_REG_mask; 452 extern RegMask _INT_NO_RCX_REG_mask; 453 extern RegMask _INT_NO_RBP_R13_REG_mask; 454 extern RegMask _FLOAT_REG_mask; 455 456 extern RegMask _STACK_OR_PTR_REG_mask; 457 extern RegMask _STACK_OR_LONG_REG_mask; 458 extern RegMask _STACK_OR_INT_REG_mask; 459 460 inline const RegMask& STACK_OR_PTR_REG_mask() { return _STACK_OR_PTR_REG_mask; } 461 inline const RegMask& STACK_OR_LONG_REG_mask() { return _STACK_OR_LONG_REG_mask; } 462 inline const RegMask& STACK_OR_INT_REG_mask() { return _STACK_OR_INT_REG_mask; } 463 464 %} 465 466 source %{ 467 #define RELOC_IMM64 Assembler::imm_operand 468 #define RELOC_DISP32 Assembler::disp32_operand 469 470 #define __ masm-> 471 472 RegMask _ANY_REG_mask; 473 RegMask _PTR_REG_mask; 474 RegMask _PTR_REG_NO_RBP_mask; 475 RegMask _PTR_NO_RAX_REG_mask; 476 RegMask _PTR_NO_RAX_RBX_REG_mask; 477 RegMask _LONG_REG_mask; 478 RegMask _LONG_NO_RAX_RDX_REG_mask; 479 RegMask _LONG_NO_RCX_REG_mask; 480 RegMask _LONG_NO_RBP_R13_REG_mask; 481 RegMask _INT_REG_mask; 482 RegMask _INT_NO_RAX_RDX_REG_mask; 483 RegMask _INT_NO_RCX_REG_mask; 484 RegMask _INT_NO_RBP_R13_REG_mask; 485 RegMask _FLOAT_REG_mask; 486 RegMask _STACK_OR_PTR_REG_mask; 487 RegMask _STACK_OR_LONG_REG_mask; 488 RegMask _STACK_OR_INT_REG_mask; 489 490 static bool need_r12_heapbase() { 491 return UseCompressedOops; 492 } 493 494 void reg_mask_init() { 495 constexpr Register egprs[] = {r16, r17, r18, r19, r20, r21, r22, r23, r24, r25, r26, r27, r28, r29, r30, r31}; 496 497 // _ALL_REG_mask is generated by adlc from the all_reg register class below. 498 // We derive a number of subsets from it. 499 _ANY_REG_mask = _ALL_REG_mask; 500 501 if (PreserveFramePointer) { 502 _ANY_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg())); 503 _ANY_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg()->next())); 504 } 505 if (need_r12_heapbase()) { 506 _ANY_REG_mask.Remove(OptoReg::as_OptoReg(r12->as_VMReg())); 507 _ANY_REG_mask.Remove(OptoReg::as_OptoReg(r12->as_VMReg()->next())); 508 } 509 510 _PTR_REG_mask = _ANY_REG_mask; 511 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(rsp->as_VMReg())); 512 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(rsp->as_VMReg()->next())); 513 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(r15->as_VMReg())); 514 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(r15->as_VMReg()->next())); 515 if (!UseAPX) { 516 for (uint i = 0; i < sizeof(egprs)/sizeof(Register); i++) { 517 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(egprs[i]->as_VMReg())); 518 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(egprs[i]->as_VMReg()->next())); 519 } 520 } 521 522 _STACK_OR_PTR_REG_mask = _PTR_REG_mask; 523 _STACK_OR_PTR_REG_mask.OR(STACK_OR_STACK_SLOTS_mask()); 524 525 _PTR_REG_NO_RBP_mask = _PTR_REG_mask; 526 _PTR_REG_NO_RBP_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg())); 527 _PTR_REG_NO_RBP_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg()->next())); 528 529 _PTR_NO_RAX_REG_mask = _PTR_REG_mask; 530 _PTR_NO_RAX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg())); 531 _PTR_NO_RAX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg()->next())); 532 533 _PTR_NO_RAX_RBX_REG_mask = _PTR_NO_RAX_REG_mask; 534 _PTR_NO_RAX_RBX_REG_mask.Remove(OptoReg::as_OptoReg(rbx->as_VMReg())); 535 _PTR_NO_RAX_RBX_REG_mask.Remove(OptoReg::as_OptoReg(rbx->as_VMReg()->next())); 536 537 538 _LONG_REG_mask = _PTR_REG_mask; 539 _STACK_OR_LONG_REG_mask = _LONG_REG_mask; 540 _STACK_OR_LONG_REG_mask.OR(STACK_OR_STACK_SLOTS_mask()); 541 542 _LONG_NO_RAX_RDX_REG_mask = _LONG_REG_mask; 543 _LONG_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg())); 544 _LONG_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg()->next())); 545 _LONG_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rdx->as_VMReg())); 546 _LONG_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rdx->as_VMReg()->next())); 547 548 _LONG_NO_RCX_REG_mask = _LONG_REG_mask; 549 _LONG_NO_RCX_REG_mask.Remove(OptoReg::as_OptoReg(rcx->as_VMReg())); 550 _LONG_NO_RCX_REG_mask.Remove(OptoReg::as_OptoReg(rcx->as_VMReg()->next())); 551 552 _LONG_NO_RBP_R13_REG_mask = _LONG_REG_mask; 553 _LONG_NO_RBP_R13_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg())); 554 _LONG_NO_RBP_R13_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg()->next())); 555 _LONG_NO_RBP_R13_REG_mask.Remove(OptoReg::as_OptoReg(r13->as_VMReg())); 556 _LONG_NO_RBP_R13_REG_mask.Remove(OptoReg::as_OptoReg(r13->as_VMReg()->next())); 557 558 _INT_REG_mask = _ALL_INT_REG_mask; 559 if (!UseAPX) { 560 for (uint i = 0; i < sizeof(egprs)/sizeof(Register); i++) { 561 _INT_REG_mask.Remove(OptoReg::as_OptoReg(egprs[i]->as_VMReg())); 562 } 563 } 564 565 if (PreserveFramePointer) { 566 _INT_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg())); 567 } 568 if (need_r12_heapbase()) { 569 _INT_REG_mask.Remove(OptoReg::as_OptoReg(r12->as_VMReg())); 570 } 571 572 _STACK_OR_INT_REG_mask = _INT_REG_mask; 573 _STACK_OR_INT_REG_mask.OR(STACK_OR_STACK_SLOTS_mask()); 574 575 _INT_NO_RAX_RDX_REG_mask = _INT_REG_mask; 576 _INT_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg())); 577 _INT_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rdx->as_VMReg())); 578 579 _INT_NO_RCX_REG_mask = _INT_REG_mask; 580 _INT_NO_RCX_REG_mask.Remove(OptoReg::as_OptoReg(rcx->as_VMReg())); 581 582 _INT_NO_RBP_R13_REG_mask = _INT_REG_mask; 583 _INT_NO_RBP_R13_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg())); 584 _INT_NO_RBP_R13_REG_mask.Remove(OptoReg::as_OptoReg(r13->as_VMReg())); 585 586 // _FLOAT_REG_LEGACY_mask/_FLOAT_REG_EVEX_mask is generated by adlc 587 // from the float_reg_legacy/float_reg_evex register class. 588 _FLOAT_REG_mask = VM_Version::supports_evex() ? _FLOAT_REG_EVEX_mask : _FLOAT_REG_LEGACY_mask; 589 } 590 591 static bool generate_vzeroupper(Compile* C) { 592 return (VM_Version::supports_vzeroupper() && (C->max_vector_size() > 16 || C->clear_upper_avx() == true)) ? true: false; // Generate vzeroupper 593 } 594 595 static int clear_avx_size() { 596 return generate_vzeroupper(Compile::current()) ? 3: 0; // vzeroupper 597 } 598 599 // !!!!! Special hack to get all types of calls to specify the byte offset 600 // from the start of the call to the point where the return address 601 // will point. 602 int MachCallStaticJavaNode::ret_addr_offset() 603 { 604 int offset = 5; // 5 bytes from start of call to where return address points 605 offset += clear_avx_size(); 606 return offset; 607 } 608 609 int MachCallDynamicJavaNode::ret_addr_offset() 610 { 611 int offset = 15; // 15 bytes from start of call to where return address points 612 offset += clear_avx_size(); 613 return offset; 614 } 615 616 int MachCallRuntimeNode::ret_addr_offset() { 617 int offset = 13; // movq r10,#addr; callq (r10) 618 if (this->ideal_Opcode() != Op_CallLeafVector) { 619 offset += clear_avx_size(); 620 } 621 return offset; 622 } 623 // 624 // Compute padding required for nodes which need alignment 625 // 626 627 // The address of the call instruction needs to be 4-byte aligned to 628 // ensure that it does not span a cache line so that it can be patched. 629 int CallStaticJavaDirectNode::compute_padding(int current_offset) const 630 { 631 current_offset += clear_avx_size(); // skip vzeroupper 632 current_offset += 1; // skip call opcode byte 633 return align_up(current_offset, alignment_required()) - current_offset; 634 } 635 636 // The address of the call instruction needs to be 4-byte aligned to 637 // ensure that it does not span a cache line so that it can be patched. 638 int CallDynamicJavaDirectNode::compute_padding(int current_offset) const 639 { 640 current_offset += clear_avx_size(); // skip vzeroupper 641 current_offset += 11; // skip movq instruction + call opcode byte 642 return align_up(current_offset, alignment_required()) - current_offset; 643 } 644 645 // This could be in MacroAssembler but it's fairly C2 specific 646 static void emit_cmpfp_fixup(MacroAssembler* masm) { 647 Label exit; 648 __ jccb(Assembler::noParity, exit); 649 __ pushf(); 650 // 651 // comiss/ucomiss instructions set ZF,PF,CF flags and 652 // zero OF,AF,SF for NaN values. 653 // Fixup flags by zeroing ZF,PF so that compare of NaN 654 // values returns 'less than' result (CF is set). 655 // Leave the rest of flags unchanged. 656 // 657 // 7 6 5 4 3 2 1 0 658 // |S|Z|r|A|r|P|r|C| (r - reserved bit) 659 // 0 0 1 0 1 0 1 1 (0x2B) 660 // 661 __ andq(Address(rsp, 0), 0xffffff2b); 662 __ popf(); 663 __ bind(exit); 664 } 665 666 static void emit_cmpfp3(MacroAssembler* masm, Register dst) { 667 Label done; 668 __ movl(dst, -1); 669 __ jcc(Assembler::parity, done); 670 __ jcc(Assembler::below, done); 671 __ setcc(Assembler::notEqual, dst); 672 __ bind(done); 673 } 674 675 // Math.min() # Math.max() 676 // -------------------------- 677 // ucomis[s/d] # 678 // ja -> b # a 679 // jp -> NaN # NaN 680 // jb -> a # b 681 // je # 682 // |-jz -> a | b # a & b 683 // | -> a # 684 static void emit_fp_min_max(MacroAssembler* masm, XMMRegister dst, 685 XMMRegister a, XMMRegister b, 686 XMMRegister xmmt, Register rt, 687 bool min, bool single) { 688 689 Label nan, zero, below, above, done; 690 691 if (single) 692 __ ucomiss(a, b); 693 else 694 __ ucomisd(a, b); 695 696 if (dst->encoding() != (min ? b : a)->encoding()) 697 __ jccb(Assembler::above, above); // CF=0 & ZF=0 698 else 699 __ jccb(Assembler::above, done); 700 701 __ jccb(Assembler::parity, nan); // PF=1 702 __ jccb(Assembler::below, below); // CF=1 703 704 // equal 705 __ vpxor(xmmt, xmmt, xmmt, Assembler::AVX_128bit); 706 if (single) { 707 __ ucomiss(a, xmmt); 708 __ jccb(Assembler::equal, zero); 709 710 __ movflt(dst, a); 711 __ jmp(done); 712 } 713 else { 714 __ ucomisd(a, xmmt); 715 __ jccb(Assembler::equal, zero); 716 717 __ movdbl(dst, a); 718 __ jmp(done); 719 } 720 721 __ bind(zero); 722 if (min) 723 __ vpor(dst, a, b, Assembler::AVX_128bit); 724 else 725 __ vpand(dst, a, b, Assembler::AVX_128bit); 726 727 __ jmp(done); 728 729 __ bind(above); 730 if (single) 731 __ movflt(dst, min ? b : a); 732 else 733 __ movdbl(dst, min ? b : a); 734 735 __ jmp(done); 736 737 __ bind(nan); 738 if (single) { 739 __ movl(rt, 0x7fc00000); // Float.NaN 740 __ movdl(dst, rt); 741 } 742 else { 743 __ mov64(rt, 0x7ff8000000000000L); // Double.NaN 744 __ movdq(dst, rt); 745 } 746 __ jmp(done); 747 748 __ bind(below); 749 if (single) 750 __ movflt(dst, min ? a : b); 751 else 752 __ movdbl(dst, min ? a : b); 753 754 __ bind(done); 755 } 756 757 //============================================================================= 758 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; 759 760 int ConstantTable::calculate_table_base_offset() const { 761 return 0; // absolute addressing, no offset 762 } 763 764 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; } 765 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 766 ShouldNotReachHere(); 767 } 768 769 void MachConstantBaseNode::emit(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const { 770 // Empty encoding 771 } 772 773 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 774 return 0; 775 } 776 777 #ifndef PRODUCT 778 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 779 st->print("# MachConstantBaseNode (empty encoding)"); 780 } 781 #endif 782 783 784 //============================================================================= 785 #ifndef PRODUCT 786 void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 787 Compile* C = ra_->C; 788 789 int framesize = C->output()->frame_size_in_bytes(); 790 int bangsize = C->output()->bang_size_in_bytes(); 791 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 792 // Remove wordSize for return addr which is already pushed. 793 framesize -= wordSize; 794 795 if (C->output()->need_stack_bang(bangsize)) { 796 framesize -= wordSize; 797 st->print("# stack bang (%d bytes)", bangsize); 798 st->print("\n\t"); 799 st->print("pushq rbp\t# Save rbp"); 800 if (PreserveFramePointer) { 801 st->print("\n\t"); 802 st->print("movq rbp, rsp\t# Save the caller's SP into rbp"); 803 } 804 if (framesize) { 805 st->print("\n\t"); 806 st->print("subq rsp, #%d\t# Create frame",framesize); 807 } 808 } else { 809 st->print("subq rsp, #%d\t# Create frame",framesize); 810 st->print("\n\t"); 811 framesize -= wordSize; 812 st->print("movq [rsp + #%d], rbp\t# Save rbp",framesize); 813 if (PreserveFramePointer) { 814 st->print("\n\t"); 815 st->print("movq rbp, rsp\t# Save the caller's SP into rbp"); 816 if (framesize > 0) { 817 st->print("\n\t"); 818 st->print("addq rbp, #%d", framesize); 819 } 820 } 821 } 822 823 if (VerifyStackAtCalls) { 824 st->print("\n\t"); 825 framesize -= wordSize; 826 st->print("movq [rsp + #%d], 0xbadb100d\t# Majik cookie for stack depth check",framesize); 827 #ifdef ASSERT 828 st->print("\n\t"); 829 st->print("# stack alignment check"); 830 #endif 831 } 832 if (C->stub_function() != nullptr) { 833 st->print("\n\t"); 834 st->print("cmpl [r15_thread + #disarmed_guard_value_offset], #disarmed_guard_value\t"); 835 st->print("\n\t"); 836 st->print("je fast_entry\t"); 837 st->print("\n\t"); 838 st->print("call #nmethod_entry_barrier_stub\t"); 839 st->print("\n\tfast_entry:"); 840 } 841 st->cr(); 842 } 843 #endif 844 845 void MachPrologNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const { 846 Compile* C = ra_->C; 847 848 int framesize = C->output()->frame_size_in_bytes(); 849 int bangsize = C->output()->bang_size_in_bytes(); 850 851 if (C->clinit_barrier_on_entry()) { 852 assert(VM_Version::supports_fast_class_init_checks(), "sanity"); 853 assert(!C->method()->holder()->is_not_initialized() || C->do_clinit_barriers(), "initialization should have been started"); 854 855 Label L_skip_barrier; 856 Register klass = rscratch1; 857 858 __ mov_metadata(klass, C->method()->holder()->constant_encoding()); 859 __ clinit_barrier(klass, &L_skip_barrier /*L_fast_path*/); 860 861 __ jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub())); // slow path 862 863 __ bind(L_skip_barrier); 864 } 865 866 __ verified_entry(framesize, C->output()->need_stack_bang(bangsize)?bangsize:0, false, C->stub_function() != nullptr); 867 868 C->output()->set_frame_complete(__ offset()); 869 870 if (C->has_mach_constant_base_node()) { 871 // NOTE: We set the table base offset here because users might be 872 // emitted before MachConstantBaseNode. 873 ConstantTable& constant_table = C->output()->constant_table(); 874 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset()); 875 } 876 } 877 878 uint MachPrologNode::size(PhaseRegAlloc* ra_) const 879 { 880 return MachNode::size(ra_); // too many variables; just compute it 881 // the hard way 882 } 883 884 int MachPrologNode::reloc() const 885 { 886 return 0; // a large enough number 887 } 888 889 //============================================================================= 890 #ifndef PRODUCT 891 void MachEpilogNode::format(PhaseRegAlloc* ra_, outputStream* st) const 892 { 893 Compile* C = ra_->C; 894 if (generate_vzeroupper(C)) { 895 st->print("vzeroupper"); 896 st->cr(); st->print("\t"); 897 } 898 899 int framesize = C->output()->frame_size_in_bytes(); 900 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 901 // Remove word for return adr already pushed 902 // and RBP 903 framesize -= 2*wordSize; 904 905 if (framesize) { 906 st->print_cr("addq rsp, %d\t# Destroy frame", framesize); 907 st->print("\t"); 908 } 909 910 st->print_cr("popq rbp"); 911 if (do_polling() && C->is_method_compilation()) { 912 st->print("\t"); 913 st->print_cr("cmpq rsp, poll_offset[r15_thread] \n\t" 914 "ja #safepoint_stub\t" 915 "# Safepoint: poll for GC"); 916 } 917 } 918 #endif 919 920 void MachEpilogNode::emit(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const 921 { 922 Compile* C = ra_->C; 923 924 if (generate_vzeroupper(C)) { 925 // Clear upper bits of YMM registers when current compiled code uses 926 // wide vectors to avoid AVX <-> SSE transition penalty during call. 927 __ vzeroupper(); 928 } 929 930 int framesize = C->output()->frame_size_in_bytes(); 931 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 932 // Remove word for return adr already pushed 933 // and RBP 934 framesize -= 2*wordSize; 935 936 // Note that VerifyStackAtCalls' Majik cookie does not change the frame size popped here 937 938 if (framesize) { 939 __ addq(rsp, framesize); 940 } 941 942 __ popq(rbp); 943 944 if (StackReservedPages > 0 && C->has_reserved_stack_access()) { 945 __ reserved_stack_check(); 946 } 947 948 if (do_polling() && C->is_method_compilation()) { 949 Label dummy_label; 950 Label* code_stub = &dummy_label; 951 if (!C->output()->in_scratch_emit_size()) { 952 C2SafepointPollStub* stub = new (C->comp_arena()) C2SafepointPollStub(__ offset()); 953 C->output()->add_stub(stub); 954 code_stub = &stub->entry(); 955 } 956 __ relocate(relocInfo::poll_return_type); 957 __ safepoint_poll(*code_stub, true /* at_return */, true /* in_nmethod */); 958 } 959 } 960 961 uint MachEpilogNode::size(PhaseRegAlloc* ra_) const 962 { 963 return MachNode::size(ra_); // too many variables; just compute it 964 // the hard way 965 } 966 967 int MachEpilogNode::reloc() const 968 { 969 return 2; // a large enough number 970 } 971 972 const Pipeline* MachEpilogNode::pipeline() const 973 { 974 return MachNode::pipeline_class(); 975 } 976 977 //============================================================================= 978 979 enum RC { 980 rc_bad, 981 rc_int, 982 rc_kreg, 983 rc_float, 984 rc_stack 985 }; 986 987 static enum RC rc_class(OptoReg::Name reg) 988 { 989 if( !OptoReg::is_valid(reg) ) return rc_bad; 990 991 if (OptoReg::is_stack(reg)) return rc_stack; 992 993 VMReg r = OptoReg::as_VMReg(reg); 994 995 if (r->is_Register()) return rc_int; 996 997 if (r->is_KRegister()) return rc_kreg; 998 999 assert(r->is_XMMRegister(), "must be"); 1000 return rc_float; 1001 } 1002 1003 // Next two methods are shared by 32- and 64-bit VM. They are defined in x86.ad. 1004 static void vec_mov_helper(C2_MacroAssembler *masm, int src_lo, int dst_lo, 1005 int src_hi, int dst_hi, uint ireg, outputStream* st); 1006 1007 void vec_spill_helper(C2_MacroAssembler *masm, bool is_load, 1008 int stack_offset, int reg, uint ireg, outputStream* st); 1009 1010 static void vec_stack_to_stack_helper(C2_MacroAssembler *masm, int src_offset, 1011 int dst_offset, uint ireg, outputStream* st) { 1012 if (masm) { 1013 switch (ireg) { 1014 case Op_VecS: 1015 __ movq(Address(rsp, -8), rax); 1016 __ movl(rax, Address(rsp, src_offset)); 1017 __ movl(Address(rsp, dst_offset), rax); 1018 __ movq(rax, Address(rsp, -8)); 1019 break; 1020 case Op_VecD: 1021 __ pushq(Address(rsp, src_offset)); 1022 __ popq (Address(rsp, dst_offset)); 1023 break; 1024 case Op_VecX: 1025 __ pushq(Address(rsp, src_offset)); 1026 __ popq (Address(rsp, dst_offset)); 1027 __ pushq(Address(rsp, src_offset+8)); 1028 __ popq (Address(rsp, dst_offset+8)); 1029 break; 1030 case Op_VecY: 1031 __ vmovdqu(Address(rsp, -32), xmm0); 1032 __ vmovdqu(xmm0, Address(rsp, src_offset)); 1033 __ vmovdqu(Address(rsp, dst_offset), xmm0); 1034 __ vmovdqu(xmm0, Address(rsp, -32)); 1035 break; 1036 case Op_VecZ: 1037 __ evmovdquq(Address(rsp, -64), xmm0, 2); 1038 __ evmovdquq(xmm0, Address(rsp, src_offset), 2); 1039 __ evmovdquq(Address(rsp, dst_offset), xmm0, 2); 1040 __ evmovdquq(xmm0, Address(rsp, -64), 2); 1041 break; 1042 default: 1043 ShouldNotReachHere(); 1044 } 1045 #ifndef PRODUCT 1046 } else { 1047 switch (ireg) { 1048 case Op_VecS: 1049 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1050 "movl rax, [rsp + #%d]\n\t" 1051 "movl [rsp + #%d], rax\n\t" 1052 "movq rax, [rsp - #8]", 1053 src_offset, dst_offset); 1054 break; 1055 case Op_VecD: 1056 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1057 "popq [rsp + #%d]", 1058 src_offset, dst_offset); 1059 break; 1060 case Op_VecX: 1061 st->print("pushq [rsp + #%d]\t# 128-bit mem-mem spill\n\t" 1062 "popq [rsp + #%d]\n\t" 1063 "pushq [rsp + #%d]\n\t" 1064 "popq [rsp + #%d]", 1065 src_offset, dst_offset, src_offset+8, dst_offset+8); 1066 break; 1067 case Op_VecY: 1068 st->print("vmovdqu [rsp - #32], xmm0\t# 256-bit mem-mem spill\n\t" 1069 "vmovdqu xmm0, [rsp + #%d]\n\t" 1070 "vmovdqu [rsp + #%d], xmm0\n\t" 1071 "vmovdqu xmm0, [rsp - #32]", 1072 src_offset, dst_offset); 1073 break; 1074 case Op_VecZ: 1075 st->print("vmovdqu [rsp - #64], xmm0\t# 512-bit mem-mem spill\n\t" 1076 "vmovdqu xmm0, [rsp + #%d]\n\t" 1077 "vmovdqu [rsp + #%d], xmm0\n\t" 1078 "vmovdqu xmm0, [rsp - #64]", 1079 src_offset, dst_offset); 1080 break; 1081 default: 1082 ShouldNotReachHere(); 1083 } 1084 #endif 1085 } 1086 } 1087 1088 uint MachSpillCopyNode::implementation(C2_MacroAssembler* masm, 1089 PhaseRegAlloc* ra_, 1090 bool do_size, 1091 outputStream* st) const { 1092 assert(masm != nullptr || st != nullptr, "sanity"); 1093 // Get registers to move 1094 OptoReg::Name src_second = ra_->get_reg_second(in(1)); 1095 OptoReg::Name src_first = ra_->get_reg_first(in(1)); 1096 OptoReg::Name dst_second = ra_->get_reg_second(this); 1097 OptoReg::Name dst_first = ra_->get_reg_first(this); 1098 1099 enum RC src_second_rc = rc_class(src_second); 1100 enum RC src_first_rc = rc_class(src_first); 1101 enum RC dst_second_rc = rc_class(dst_second); 1102 enum RC dst_first_rc = rc_class(dst_first); 1103 1104 assert(OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), 1105 "must move at least 1 register" ); 1106 1107 if (src_first == dst_first && src_second == dst_second) { 1108 // Self copy, no move 1109 return 0; 1110 } 1111 if (bottom_type()->isa_vect() != nullptr && bottom_type()->isa_vectmask() == nullptr) { 1112 uint ireg = ideal_reg(); 1113 assert((src_first_rc != rc_int && dst_first_rc != rc_int), "sanity"); 1114 assert((ireg == Op_VecS || ireg == Op_VecD || ireg == Op_VecX || ireg == Op_VecY || ireg == Op_VecZ ), "sanity"); 1115 if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) { 1116 // mem -> mem 1117 int src_offset = ra_->reg2offset(src_first); 1118 int dst_offset = ra_->reg2offset(dst_first); 1119 vec_stack_to_stack_helper(masm, src_offset, dst_offset, ireg, st); 1120 } else if (src_first_rc == rc_float && dst_first_rc == rc_float ) { 1121 vec_mov_helper(masm, src_first, dst_first, src_second, dst_second, ireg, st); 1122 } else if (src_first_rc == rc_float && dst_first_rc == rc_stack ) { 1123 int stack_offset = ra_->reg2offset(dst_first); 1124 vec_spill_helper(masm, false, stack_offset, src_first, ireg, st); 1125 } else if (src_first_rc == rc_stack && dst_first_rc == rc_float ) { 1126 int stack_offset = ra_->reg2offset(src_first); 1127 vec_spill_helper(masm, true, stack_offset, dst_first, ireg, st); 1128 } else { 1129 ShouldNotReachHere(); 1130 } 1131 return 0; 1132 } 1133 if (src_first_rc == rc_stack) { 1134 // mem -> 1135 if (dst_first_rc == rc_stack) { 1136 // mem -> mem 1137 assert(src_second != dst_first, "overlap"); 1138 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1139 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1140 // 64-bit 1141 int src_offset = ra_->reg2offset(src_first); 1142 int dst_offset = ra_->reg2offset(dst_first); 1143 if (masm) { 1144 __ pushq(Address(rsp, src_offset)); 1145 __ popq (Address(rsp, dst_offset)); 1146 #ifndef PRODUCT 1147 } else { 1148 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1149 "popq [rsp + #%d]", 1150 src_offset, dst_offset); 1151 #endif 1152 } 1153 } else { 1154 // 32-bit 1155 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1156 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1157 // No pushl/popl, so: 1158 int src_offset = ra_->reg2offset(src_first); 1159 int dst_offset = ra_->reg2offset(dst_first); 1160 if (masm) { 1161 __ movq(Address(rsp, -8), rax); 1162 __ movl(rax, Address(rsp, src_offset)); 1163 __ movl(Address(rsp, dst_offset), rax); 1164 __ movq(rax, Address(rsp, -8)); 1165 #ifndef PRODUCT 1166 } else { 1167 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1168 "movl rax, [rsp + #%d]\n\t" 1169 "movl [rsp + #%d], rax\n\t" 1170 "movq rax, [rsp - #8]", 1171 src_offset, dst_offset); 1172 #endif 1173 } 1174 } 1175 return 0; 1176 } else if (dst_first_rc == rc_int) { 1177 // mem -> gpr 1178 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1179 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1180 // 64-bit 1181 int offset = ra_->reg2offset(src_first); 1182 if (masm) { 1183 __ movq(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1184 #ifndef PRODUCT 1185 } else { 1186 st->print("movq %s, [rsp + #%d]\t# spill", 1187 Matcher::regName[dst_first], 1188 offset); 1189 #endif 1190 } 1191 } else { 1192 // 32-bit 1193 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1194 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1195 int offset = ra_->reg2offset(src_first); 1196 if (masm) { 1197 __ movl(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1198 #ifndef PRODUCT 1199 } else { 1200 st->print("movl %s, [rsp + #%d]\t# spill", 1201 Matcher::regName[dst_first], 1202 offset); 1203 #endif 1204 } 1205 } 1206 return 0; 1207 } else if (dst_first_rc == rc_float) { 1208 // mem-> xmm 1209 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1210 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1211 // 64-bit 1212 int offset = ra_->reg2offset(src_first); 1213 if (masm) { 1214 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1215 #ifndef PRODUCT 1216 } else { 1217 st->print("%s %s, [rsp + #%d]\t# spill", 1218 UseXmmLoadAndClearUpper ? "movsd " : "movlpd", 1219 Matcher::regName[dst_first], 1220 offset); 1221 #endif 1222 } 1223 } else { 1224 // 32-bit 1225 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1226 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1227 int offset = ra_->reg2offset(src_first); 1228 if (masm) { 1229 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1230 #ifndef PRODUCT 1231 } else { 1232 st->print("movss %s, [rsp + #%d]\t# spill", 1233 Matcher::regName[dst_first], 1234 offset); 1235 #endif 1236 } 1237 } 1238 return 0; 1239 } else if (dst_first_rc == rc_kreg) { 1240 // mem -> kreg 1241 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1242 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1243 // 64-bit 1244 int offset = ra_->reg2offset(src_first); 1245 if (masm) { 1246 __ kmov(as_KRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1247 #ifndef PRODUCT 1248 } else { 1249 st->print("kmovq %s, [rsp + #%d]\t# spill", 1250 Matcher::regName[dst_first], 1251 offset); 1252 #endif 1253 } 1254 } 1255 return 0; 1256 } 1257 } else if (src_first_rc == rc_int) { 1258 // gpr -> 1259 if (dst_first_rc == rc_stack) { 1260 // gpr -> mem 1261 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1262 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1263 // 64-bit 1264 int offset = ra_->reg2offset(dst_first); 1265 if (masm) { 1266 __ movq(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1267 #ifndef PRODUCT 1268 } else { 1269 st->print("movq [rsp + #%d], %s\t# spill", 1270 offset, 1271 Matcher::regName[src_first]); 1272 #endif 1273 } 1274 } else { 1275 // 32-bit 1276 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1277 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1278 int offset = ra_->reg2offset(dst_first); 1279 if (masm) { 1280 __ movl(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1281 #ifndef PRODUCT 1282 } else { 1283 st->print("movl [rsp + #%d], %s\t# spill", 1284 offset, 1285 Matcher::regName[src_first]); 1286 #endif 1287 } 1288 } 1289 return 0; 1290 } else if (dst_first_rc == rc_int) { 1291 // gpr -> gpr 1292 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1293 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1294 // 64-bit 1295 if (masm) { 1296 __ movq(as_Register(Matcher::_regEncode[dst_first]), 1297 as_Register(Matcher::_regEncode[src_first])); 1298 #ifndef PRODUCT 1299 } else { 1300 st->print("movq %s, %s\t# spill", 1301 Matcher::regName[dst_first], 1302 Matcher::regName[src_first]); 1303 #endif 1304 } 1305 return 0; 1306 } else { 1307 // 32-bit 1308 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1309 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1310 if (masm) { 1311 __ movl(as_Register(Matcher::_regEncode[dst_first]), 1312 as_Register(Matcher::_regEncode[src_first])); 1313 #ifndef PRODUCT 1314 } else { 1315 st->print("movl %s, %s\t# spill", 1316 Matcher::regName[dst_first], 1317 Matcher::regName[src_first]); 1318 #endif 1319 } 1320 return 0; 1321 } 1322 } else if (dst_first_rc == rc_float) { 1323 // gpr -> xmm 1324 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1325 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1326 // 64-bit 1327 if (masm) { 1328 __ movdq( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1329 #ifndef PRODUCT 1330 } else { 1331 st->print("movdq %s, %s\t# spill", 1332 Matcher::regName[dst_first], 1333 Matcher::regName[src_first]); 1334 #endif 1335 } 1336 } else { 1337 // 32-bit 1338 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1339 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1340 if (masm) { 1341 __ movdl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1342 #ifndef PRODUCT 1343 } else { 1344 st->print("movdl %s, %s\t# spill", 1345 Matcher::regName[dst_first], 1346 Matcher::regName[src_first]); 1347 #endif 1348 } 1349 } 1350 return 0; 1351 } else if (dst_first_rc == rc_kreg) { 1352 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1353 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1354 // 64-bit 1355 if (masm) { 1356 __ kmov(as_KRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1357 #ifndef PRODUCT 1358 } else { 1359 st->print("kmovq %s, %s\t# spill", 1360 Matcher::regName[dst_first], 1361 Matcher::regName[src_first]); 1362 #endif 1363 } 1364 } 1365 Unimplemented(); 1366 return 0; 1367 } 1368 } else if (src_first_rc == rc_float) { 1369 // xmm -> 1370 if (dst_first_rc == rc_stack) { 1371 // xmm -> mem 1372 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1373 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1374 // 64-bit 1375 int offset = ra_->reg2offset(dst_first); 1376 if (masm) { 1377 __ movdbl( Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1378 #ifndef PRODUCT 1379 } else { 1380 st->print("movsd [rsp + #%d], %s\t# spill", 1381 offset, 1382 Matcher::regName[src_first]); 1383 #endif 1384 } 1385 } else { 1386 // 32-bit 1387 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1388 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1389 int offset = ra_->reg2offset(dst_first); 1390 if (masm) { 1391 __ movflt(Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1392 #ifndef PRODUCT 1393 } else { 1394 st->print("movss [rsp + #%d], %s\t# spill", 1395 offset, 1396 Matcher::regName[src_first]); 1397 #endif 1398 } 1399 } 1400 return 0; 1401 } else if (dst_first_rc == rc_int) { 1402 // xmm -> gpr 1403 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1404 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1405 // 64-bit 1406 if (masm) { 1407 __ movdq( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1408 #ifndef PRODUCT 1409 } else { 1410 st->print("movdq %s, %s\t# spill", 1411 Matcher::regName[dst_first], 1412 Matcher::regName[src_first]); 1413 #endif 1414 } 1415 } else { 1416 // 32-bit 1417 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1418 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1419 if (masm) { 1420 __ movdl( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1421 #ifndef PRODUCT 1422 } else { 1423 st->print("movdl %s, %s\t# spill", 1424 Matcher::regName[dst_first], 1425 Matcher::regName[src_first]); 1426 #endif 1427 } 1428 } 1429 return 0; 1430 } else if (dst_first_rc == rc_float) { 1431 // xmm -> xmm 1432 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1433 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1434 // 64-bit 1435 if (masm) { 1436 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1437 #ifndef PRODUCT 1438 } else { 1439 st->print("%s %s, %s\t# spill", 1440 UseXmmRegToRegMoveAll ? "movapd" : "movsd ", 1441 Matcher::regName[dst_first], 1442 Matcher::regName[src_first]); 1443 #endif 1444 } 1445 } else { 1446 // 32-bit 1447 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1448 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1449 if (masm) { 1450 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1451 #ifndef PRODUCT 1452 } else { 1453 st->print("%s %s, %s\t# spill", 1454 UseXmmRegToRegMoveAll ? "movaps" : "movss ", 1455 Matcher::regName[dst_first], 1456 Matcher::regName[src_first]); 1457 #endif 1458 } 1459 } 1460 return 0; 1461 } else if (dst_first_rc == rc_kreg) { 1462 assert(false, "Illegal spilling"); 1463 return 0; 1464 } 1465 } else if (src_first_rc == rc_kreg) { 1466 if (dst_first_rc == rc_stack) { 1467 // mem -> kreg 1468 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1469 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1470 // 64-bit 1471 int offset = ra_->reg2offset(dst_first); 1472 if (masm) { 1473 __ kmov(Address(rsp, offset), as_KRegister(Matcher::_regEncode[src_first])); 1474 #ifndef PRODUCT 1475 } else { 1476 st->print("kmovq [rsp + #%d] , %s\t# spill", 1477 offset, 1478 Matcher::regName[src_first]); 1479 #endif 1480 } 1481 } 1482 return 0; 1483 } else if (dst_first_rc == rc_int) { 1484 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1485 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1486 // 64-bit 1487 if (masm) { 1488 __ kmov(as_Register(Matcher::_regEncode[dst_first]), as_KRegister(Matcher::_regEncode[src_first])); 1489 #ifndef PRODUCT 1490 } else { 1491 st->print("kmovq %s, %s\t# spill", 1492 Matcher::regName[dst_first], 1493 Matcher::regName[src_first]); 1494 #endif 1495 } 1496 } 1497 Unimplemented(); 1498 return 0; 1499 } else if (dst_first_rc == rc_kreg) { 1500 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1501 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1502 // 64-bit 1503 if (masm) { 1504 __ kmov(as_KRegister(Matcher::_regEncode[dst_first]), as_KRegister(Matcher::_regEncode[src_first])); 1505 #ifndef PRODUCT 1506 } else { 1507 st->print("kmovq %s, %s\t# spill", 1508 Matcher::regName[dst_first], 1509 Matcher::regName[src_first]); 1510 #endif 1511 } 1512 } 1513 return 0; 1514 } else if (dst_first_rc == rc_float) { 1515 assert(false, "Illegal spill"); 1516 return 0; 1517 } 1518 } 1519 1520 assert(0," foo "); 1521 Unimplemented(); 1522 return 0; 1523 } 1524 1525 #ifndef PRODUCT 1526 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream* st) const { 1527 implementation(nullptr, ra_, false, st); 1528 } 1529 #endif 1530 1531 void MachSpillCopyNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const { 1532 implementation(masm, ra_, false, nullptr); 1533 } 1534 1535 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1536 return MachNode::size(ra_); 1537 } 1538 1539 //============================================================================= 1540 #ifndef PRODUCT 1541 void BoxLockNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1542 { 1543 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1544 int reg = ra_->get_reg_first(this); 1545 st->print("leaq %s, [rsp + #%d]\t# box lock", 1546 Matcher::regName[reg], offset); 1547 } 1548 #endif 1549 1550 void BoxLockNode::emit(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const 1551 { 1552 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1553 int reg = ra_->get_encode(this); 1554 1555 __ lea(as_Register(reg), Address(rsp, offset)); 1556 } 1557 1558 uint BoxLockNode::size(PhaseRegAlloc *ra_) const 1559 { 1560 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1561 if (ra_->get_encode(this) > 15) { 1562 return (offset < 0x80) ? 6 : 9; // REX2 1563 } else { 1564 return (offset < 0x80) ? 5 : 8; // REX 1565 } 1566 } 1567 1568 //============================================================================= 1569 #ifndef PRODUCT 1570 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1571 { 1572 if (UseCompressedClassPointers) { 1573 st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1574 st->print_cr("\tcmpl rscratch1, [rax + CompiledICData::speculated_klass_offset()]\t # Inline cache check"); 1575 } else { 1576 st->print_cr("movq rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1577 st->print_cr("\tcmpq rscratch1, [rax + CompiledICData::speculated_klass_offset()]\t # Inline cache check"); 1578 } 1579 st->print_cr("\tjne SharedRuntime::_ic_miss_stub"); 1580 } 1581 #endif 1582 1583 void MachUEPNode::emit(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const 1584 { 1585 __ ic_check(InteriorEntryAlignment); 1586 } 1587 1588 uint MachUEPNode::size(PhaseRegAlloc* ra_) const 1589 { 1590 return MachNode::size(ra_); // too many variables; just compute it 1591 // the hard way 1592 } 1593 1594 1595 //============================================================================= 1596 1597 bool Matcher::supports_vector_calling_convention(void) { 1598 return EnableVectorSupport; 1599 } 1600 1601 OptoRegPair Matcher::vector_return_value(uint ideal_reg) { 1602 assert(EnableVectorSupport, "sanity"); 1603 int lo = XMM0_num; 1604 int hi = XMM0b_num; 1605 if (ideal_reg == Op_VecX) hi = XMM0d_num; 1606 else if (ideal_reg == Op_VecY) hi = XMM0h_num; 1607 else if (ideal_reg == Op_VecZ) hi = XMM0p_num; 1608 return OptoRegPair(hi, lo); 1609 } 1610 1611 // Is this branch offset short enough that a short branch can be used? 1612 // 1613 // NOTE: If the platform does not provide any short branch variants, then 1614 // this method should return false for offset 0. 1615 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 1616 // The passed offset is relative to address of the branch. 1617 // On 86 a branch displacement is calculated relative to address 1618 // of a next instruction. 1619 offset -= br_size; 1620 1621 // the short version of jmpConUCF2 contains multiple branches, 1622 // making the reach slightly less 1623 if (rule == jmpConUCF2_rule) 1624 return (-126 <= offset && offset <= 125); 1625 return (-128 <= offset && offset <= 127); 1626 } 1627 1628 // Return whether or not this register is ever used as an argument. 1629 // This function is used on startup to build the trampoline stubs in 1630 // generateOptoStub. Registers not mentioned will be killed by the VM 1631 // call in the trampoline, and arguments in those registers not be 1632 // available to the callee. 1633 bool Matcher::can_be_java_arg(int reg) 1634 { 1635 return 1636 reg == RDI_num || reg == RDI_H_num || 1637 reg == RSI_num || reg == RSI_H_num || 1638 reg == RDX_num || reg == RDX_H_num || 1639 reg == RCX_num || reg == RCX_H_num || 1640 reg == R8_num || reg == R8_H_num || 1641 reg == R9_num || reg == R9_H_num || 1642 reg == R12_num || reg == R12_H_num || 1643 reg == XMM0_num || reg == XMM0b_num || 1644 reg == XMM1_num || reg == XMM1b_num || 1645 reg == XMM2_num || reg == XMM2b_num || 1646 reg == XMM3_num || reg == XMM3b_num || 1647 reg == XMM4_num || reg == XMM4b_num || 1648 reg == XMM5_num || reg == XMM5b_num || 1649 reg == XMM6_num || reg == XMM6b_num || 1650 reg == XMM7_num || reg == XMM7b_num; 1651 } 1652 1653 bool Matcher::is_spillable_arg(int reg) 1654 { 1655 return can_be_java_arg(reg); 1656 } 1657 1658 uint Matcher::int_pressure_limit() 1659 { 1660 return (INTPRESSURE == -1) ? _INT_REG_mask.Size() : INTPRESSURE; 1661 } 1662 1663 uint Matcher::float_pressure_limit() 1664 { 1665 // After experiment around with different values, the following default threshold 1666 // works best for LCM's register pressure scheduling on x64. 1667 uint dec_count = VM_Version::supports_evex() ? 4 : 2; 1668 uint default_float_pressure_threshold = _FLOAT_REG_mask.Size() - dec_count; 1669 return (FLOATPRESSURE == -1) ? default_float_pressure_threshold : FLOATPRESSURE; 1670 } 1671 1672 bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) { 1673 // In 64 bit mode a code which use multiply when 1674 // devisor is constant is faster than hardware 1675 // DIV instruction (it uses MulHiL). 1676 return false; 1677 } 1678 1679 // Register for DIVI projection of divmodI 1680 RegMask Matcher::divI_proj_mask() { 1681 return INT_RAX_REG_mask(); 1682 } 1683 1684 // Register for MODI projection of divmodI 1685 RegMask Matcher::modI_proj_mask() { 1686 return INT_RDX_REG_mask(); 1687 } 1688 1689 // Register for DIVL projection of divmodL 1690 RegMask Matcher::divL_proj_mask() { 1691 return LONG_RAX_REG_mask(); 1692 } 1693 1694 // Register for MODL projection of divmodL 1695 RegMask Matcher::modL_proj_mask() { 1696 return LONG_RDX_REG_mask(); 1697 } 1698 1699 // Register for saving SP into on method handle invokes. Not used on x86_64. 1700 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 1701 return NO_REG_mask(); 1702 } 1703 1704 %} 1705 1706 //----------ENCODING BLOCK----------------------------------------------------- 1707 // This block specifies the encoding classes used by the compiler to 1708 // output byte streams. Encoding classes are parameterized macros 1709 // used by Machine Instruction Nodes in order to generate the bit 1710 // encoding of the instruction. Operands specify their base encoding 1711 // interface with the interface keyword. There are currently 1712 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & 1713 // COND_INTER. REG_INTER causes an operand to generate a function 1714 // which returns its register number when queried. CONST_INTER causes 1715 // an operand to generate a function which returns the value of the 1716 // constant when queried. MEMORY_INTER causes an operand to generate 1717 // four functions which return the Base Register, the Index Register, 1718 // the Scale Value, and the Offset Value of the operand when queried. 1719 // COND_INTER causes an operand to generate six functions which return 1720 // the encoding code (ie - encoding bits for the instruction) 1721 // associated with each basic boolean condition for a conditional 1722 // instruction. 1723 // 1724 // Instructions specify two basic values for encoding. Again, a 1725 // function is available to check if the constant displacement is an 1726 // oop. They use the ins_encode keyword to specify their encoding 1727 // classes (which must be a sequence of enc_class names, and their 1728 // parameters, specified in the encoding block), and they use the 1729 // opcode keyword to specify, in order, their primary, secondary, and 1730 // tertiary opcode. Only the opcode sections which a particular 1731 // instruction needs for encoding need to be specified. 1732 encode %{ 1733 enc_class cdql_enc(no_rax_rdx_RegI div) 1734 %{ 1735 // Full implementation of Java idiv and irem; checks for 1736 // special case as described in JVM spec., p.243 & p.271. 1737 // 1738 // normal case special case 1739 // 1740 // input : rax: dividend min_int 1741 // reg: divisor -1 1742 // 1743 // output: rax: quotient (= rax idiv reg) min_int 1744 // rdx: remainder (= rax irem reg) 0 1745 // 1746 // Code sequnce: 1747 // 1748 // 0: 3d 00 00 00 80 cmp $0x80000000,%eax 1749 // 5: 75 07/08 jne e <normal> 1750 // 7: 33 d2 xor %edx,%edx 1751 // [div >= 8 -> offset + 1] 1752 // [REX_B] 1753 // 9: 83 f9 ff cmp $0xffffffffffffffff,$div 1754 // c: 74 03/04 je 11 <done> 1755 // 000000000000000e <normal>: 1756 // e: 99 cltd 1757 // [div >= 8 -> offset + 1] 1758 // [REX_B] 1759 // f: f7 f9 idiv $div 1760 // 0000000000000011 <done>: 1761 Label normal; 1762 Label done; 1763 1764 // cmp $0x80000000,%eax 1765 __ cmpl(as_Register(RAX_enc), 0x80000000); 1766 1767 // jne e <normal> 1768 __ jccb(Assembler::notEqual, normal); 1769 1770 // xor %edx,%edx 1771 __ xorl(as_Register(RDX_enc), as_Register(RDX_enc)); 1772 1773 // cmp $0xffffffffffffffff,%ecx 1774 __ cmpl($div$$Register, -1); 1775 1776 // je 11 <done> 1777 __ jccb(Assembler::equal, done); 1778 1779 // <normal> 1780 // cltd 1781 __ bind(normal); 1782 __ cdql(); 1783 1784 // idivl 1785 // <done> 1786 __ idivl($div$$Register); 1787 __ bind(done); 1788 %} 1789 1790 enc_class cdqq_enc(no_rax_rdx_RegL div) 1791 %{ 1792 // Full implementation of Java ldiv and lrem; checks for 1793 // special case as described in JVM spec., p.243 & p.271. 1794 // 1795 // normal case special case 1796 // 1797 // input : rax: dividend min_long 1798 // reg: divisor -1 1799 // 1800 // output: rax: quotient (= rax idiv reg) min_long 1801 // rdx: remainder (= rax irem reg) 0 1802 // 1803 // Code sequnce: 1804 // 1805 // 0: 48 ba 00 00 00 00 00 mov $0x8000000000000000,%rdx 1806 // 7: 00 00 80 1807 // a: 48 39 d0 cmp %rdx,%rax 1808 // d: 75 08 jne 17 <normal> 1809 // f: 33 d2 xor %edx,%edx 1810 // 11: 48 83 f9 ff cmp $0xffffffffffffffff,$div 1811 // 15: 74 05 je 1c <done> 1812 // 0000000000000017 <normal>: 1813 // 17: 48 99 cqto 1814 // 19: 48 f7 f9 idiv $div 1815 // 000000000000001c <done>: 1816 Label normal; 1817 Label done; 1818 1819 // mov $0x8000000000000000,%rdx 1820 __ mov64(as_Register(RDX_enc), 0x8000000000000000); 1821 1822 // cmp %rdx,%rax 1823 __ cmpq(as_Register(RAX_enc), as_Register(RDX_enc)); 1824 1825 // jne 17 <normal> 1826 __ jccb(Assembler::notEqual, normal); 1827 1828 // xor %edx,%edx 1829 __ xorl(as_Register(RDX_enc), as_Register(RDX_enc)); 1830 1831 // cmp $0xffffffffffffffff,$div 1832 __ cmpq($div$$Register, -1); 1833 1834 // je 1e <done> 1835 __ jccb(Assembler::equal, done); 1836 1837 // <normal> 1838 // cqto 1839 __ bind(normal); 1840 __ cdqq(); 1841 1842 // idivq (note: must be emitted by the user of this rule) 1843 // <done> 1844 __ idivq($div$$Register); 1845 __ bind(done); 1846 %} 1847 1848 enc_class clear_avx %{ 1849 DEBUG_ONLY(int off0 = __ offset()); 1850 if (generate_vzeroupper(Compile::current())) { 1851 // Clear upper bits of YMM registers to avoid AVX <-> SSE transition penalty 1852 // Clear upper bits of YMM registers when current compiled code uses 1853 // wide vectors to avoid AVX <-> SSE transition penalty during call. 1854 __ vzeroupper(); 1855 } 1856 DEBUG_ONLY(int off1 = __ offset()); 1857 assert(off1 - off0 == clear_avx_size(), "correct size prediction"); 1858 %} 1859 1860 enc_class Java_To_Runtime(method meth) %{ 1861 __ lea(r10, RuntimeAddress((address)$meth$$method)); 1862 __ call(r10); 1863 __ post_call_nop(); 1864 %} 1865 1866 enc_class Java_Static_Call(method meth) 1867 %{ 1868 // JAVA STATIC CALL 1869 // CALL to fixup routine. Fixup routine uses ScopeDesc info to 1870 // determine who we intended to call. 1871 if (!_method) { 1872 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, $meth$$method))); 1873 } else if (_method->intrinsic_id() == vmIntrinsicID::_ensureMaterializedForStackWalk) { 1874 // The NOP here is purely to ensure that eliding a call to 1875 // JVM_EnsureMaterializedForStackWalk doesn't change the code size. 1876 __ addr_nop_5(); 1877 __ block_comment("call JVM_EnsureMaterializedForStackWalk (elided)"); 1878 } else { 1879 int method_index = resolved_method_index(masm); 1880 RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 1881 : static_call_Relocation::spec(method_index); 1882 address mark = __ pc(); 1883 int call_offset = __ offset(); 1884 __ call(AddressLiteral(CAST_FROM_FN_PTR(address, $meth$$method), rspec)); 1885 if (CodeBuffer::supports_shared_stubs() && _method->can_be_statically_bound()) { 1886 // Calls of the same statically bound method can share 1887 // a stub to the interpreter. 1888 __ code()->shared_stub_to_interp_for(_method, call_offset); 1889 } else { 1890 // Emit stubs for static call. 1891 address stub = CompiledDirectCall::emit_to_interp_stub(masm, mark); 1892 __ clear_inst_mark(); 1893 if (stub == nullptr) { 1894 ciEnv::current()->record_failure("CodeCache is full"); 1895 return; 1896 } 1897 } 1898 } 1899 __ post_call_nop(); 1900 %} 1901 1902 enc_class Java_Dynamic_Call(method meth) %{ 1903 __ ic_call((address)$meth$$method, resolved_method_index(masm)); 1904 __ post_call_nop(); 1905 %} 1906 1907 %} 1908 1909 1910 1911 //----------FRAME-------------------------------------------------------------- 1912 // Definition of frame structure and management information. 1913 // 1914 // S T A C K L A Y O U T Allocators stack-slot number 1915 // | (to get allocators register number 1916 // G Owned by | | v add OptoReg::stack0()) 1917 // r CALLER | | 1918 // o | +--------+ pad to even-align allocators stack-slot 1919 // w V | pad0 | numbers; owned by CALLER 1920 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned 1921 // h ^ | in | 5 1922 // | | args | 4 Holes in incoming args owned by SELF 1923 // | | | | 3 1924 // | | +--------+ 1925 // V | | old out| Empty on Intel, window on Sparc 1926 // | old |preserve| Must be even aligned. 1927 // | SP-+--------+----> Matcher::_old_SP, even aligned 1928 // | | in | 3 area for Intel ret address 1929 // Owned by |preserve| Empty on Sparc. 1930 // SELF +--------+ 1931 // | | pad2 | 2 pad to align old SP 1932 // | +--------+ 1 1933 // | | locks | 0 1934 // | +--------+----> OptoReg::stack0(), even aligned 1935 // | | pad1 | 11 pad to align new SP 1936 // | +--------+ 1937 // | | | 10 1938 // | | spills | 9 spills 1939 // V | | 8 (pad0 slot for callee) 1940 // -----------+--------+----> Matcher::_out_arg_limit, unaligned 1941 // ^ | out | 7 1942 // | | args | 6 Holes in outgoing args owned by CALLEE 1943 // Owned by +--------+ 1944 // CALLEE | new out| 6 Empty on Intel, window on Sparc 1945 // | new |preserve| Must be even-aligned. 1946 // | SP-+--------+----> Matcher::_new_SP, even aligned 1947 // | | | 1948 // 1949 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 1950 // known from SELF's arguments and the Java calling convention. 1951 // Region 6-7 is determined per call site. 1952 // Note 2: If the calling convention leaves holes in the incoming argument 1953 // area, those holes are owned by SELF. Holes in the outgoing area 1954 // are owned by the CALLEE. Holes should not be necessary in the 1955 // incoming area, as the Java calling convention is completely under 1956 // the control of the AD file. Doubles can be sorted and packed to 1957 // avoid holes. Holes in the outgoing arguments may be necessary for 1958 // varargs C calling conventions. 1959 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 1960 // even aligned with pad0 as needed. 1961 // Region 6 is even aligned. Region 6-7 is NOT even aligned; 1962 // region 6-11 is even aligned; it may be padded out more so that 1963 // the region from SP to FP meets the minimum stack alignment. 1964 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 1965 // alignment. Region 11, pad1, may be dynamically extended so that 1966 // SP meets the minimum alignment. 1967 1968 frame 1969 %{ 1970 // These three registers define part of the calling convention 1971 // between compiled code and the interpreter. 1972 inline_cache_reg(RAX); // Inline Cache Register 1973 1974 // Optional: name the operand used by cisc-spilling to access 1975 // [stack_pointer + offset] 1976 cisc_spilling_operand_name(indOffset32); 1977 1978 // Number of stack slots consumed by locking an object 1979 sync_stack_slots(2); 1980 1981 // Compiled code's Frame Pointer 1982 frame_pointer(RSP); 1983 1984 // Interpreter stores its frame pointer in a register which is 1985 // stored to the stack by I2CAdaptors. 1986 // I2CAdaptors convert from interpreted java to compiled java. 1987 interpreter_frame_pointer(RBP); 1988 1989 // Stack alignment requirement 1990 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 1991 1992 // Number of outgoing stack slots killed above the out_preserve_stack_slots 1993 // for calls to C. Supports the var-args backing area for register parms. 1994 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 1995 1996 // The after-PROLOG location of the return address. Location of 1997 // return address specifies a type (REG or STACK) and a number 1998 // representing the register number (i.e. - use a register name) or 1999 // stack slot. 2000 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 2001 // Otherwise, it is above the locks and verification slot and alignment word 2002 return_addr(STACK - 2 + 2003 align_up((Compile::current()->in_preserve_stack_slots() + 2004 Compile::current()->fixed_slots()), 2005 stack_alignment_in_slots())); 2006 2007 // Location of compiled Java return values. Same as C for now. 2008 return_value 2009 %{ 2010 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 2011 "only return normal values"); 2012 2013 static const int lo[Op_RegL + 1] = { 2014 0, 2015 0, 2016 RAX_num, // Op_RegN 2017 RAX_num, // Op_RegI 2018 RAX_num, // Op_RegP 2019 XMM0_num, // Op_RegF 2020 XMM0_num, // Op_RegD 2021 RAX_num // Op_RegL 2022 }; 2023 static const int hi[Op_RegL + 1] = { 2024 0, 2025 0, 2026 OptoReg::Bad, // Op_RegN 2027 OptoReg::Bad, // Op_RegI 2028 RAX_H_num, // Op_RegP 2029 OptoReg::Bad, // Op_RegF 2030 XMM0b_num, // Op_RegD 2031 RAX_H_num // Op_RegL 2032 }; 2033 // Excluded flags and vector registers. 2034 assert(ARRAY_SIZE(hi) == _last_machine_leaf - 8, "missing type"); 2035 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 2036 %} 2037 %} 2038 2039 //----------ATTRIBUTES--------------------------------------------------------- 2040 //----------Operand Attributes------------------------------------------------- 2041 op_attrib op_cost(0); // Required cost attribute 2042 2043 //----------Instruction Attributes--------------------------------------------- 2044 ins_attrib ins_cost(100); // Required cost attribute 2045 ins_attrib ins_size(8); // Required size attribute (in bits) 2046 ins_attrib ins_short_branch(0); // Required flag: is this instruction 2047 // a non-matching short branch variant 2048 // of some long branch? 2049 ins_attrib ins_alignment(1); // Required alignment attribute (must 2050 // be a power of 2) specifies the 2051 // alignment that some part of the 2052 // instruction (not necessarily the 2053 // start) requires. If > 1, a 2054 // compute_padding() function must be 2055 // provided for the instruction 2056 2057 // Whether this node is expanded during code emission into a sequence of 2058 // instructions and the first instruction can perform an implicit null check. 2059 ins_attrib ins_is_late_expanded_null_check_candidate(false); 2060 2061 //----------OPERANDS----------------------------------------------------------- 2062 // Operand definitions must precede instruction definitions for correct parsing 2063 // in the ADLC because operands constitute user defined types which are used in 2064 // instruction definitions. 2065 2066 //----------Simple Operands---------------------------------------------------- 2067 // Immediate Operands 2068 // Integer Immediate 2069 operand immI() 2070 %{ 2071 match(ConI); 2072 2073 op_cost(10); 2074 format %{ %} 2075 interface(CONST_INTER); 2076 %} 2077 2078 // Constant for test vs zero 2079 operand immI_0() 2080 %{ 2081 predicate(n->get_int() == 0); 2082 match(ConI); 2083 2084 op_cost(0); 2085 format %{ %} 2086 interface(CONST_INTER); 2087 %} 2088 2089 // Constant for increment 2090 operand immI_1() 2091 %{ 2092 predicate(n->get_int() == 1); 2093 match(ConI); 2094 2095 op_cost(0); 2096 format %{ %} 2097 interface(CONST_INTER); 2098 %} 2099 2100 // Constant for decrement 2101 operand immI_M1() 2102 %{ 2103 predicate(n->get_int() == -1); 2104 match(ConI); 2105 2106 op_cost(0); 2107 format %{ %} 2108 interface(CONST_INTER); 2109 %} 2110 2111 operand immI_2() 2112 %{ 2113 predicate(n->get_int() == 2); 2114 match(ConI); 2115 2116 op_cost(0); 2117 format %{ %} 2118 interface(CONST_INTER); 2119 %} 2120 2121 operand immI_4() 2122 %{ 2123 predicate(n->get_int() == 4); 2124 match(ConI); 2125 2126 op_cost(0); 2127 format %{ %} 2128 interface(CONST_INTER); 2129 %} 2130 2131 operand immI_8() 2132 %{ 2133 predicate(n->get_int() == 8); 2134 match(ConI); 2135 2136 op_cost(0); 2137 format %{ %} 2138 interface(CONST_INTER); 2139 %} 2140 2141 // Valid scale values for addressing modes 2142 operand immI2() 2143 %{ 2144 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 2145 match(ConI); 2146 2147 format %{ %} 2148 interface(CONST_INTER); 2149 %} 2150 2151 operand immU7() 2152 %{ 2153 predicate((0 <= n->get_int()) && (n->get_int() <= 0x7F)); 2154 match(ConI); 2155 2156 op_cost(5); 2157 format %{ %} 2158 interface(CONST_INTER); 2159 %} 2160 2161 operand immI8() 2162 %{ 2163 predicate((-0x80 <= n->get_int()) && (n->get_int() < 0x80)); 2164 match(ConI); 2165 2166 op_cost(5); 2167 format %{ %} 2168 interface(CONST_INTER); 2169 %} 2170 2171 operand immU8() 2172 %{ 2173 predicate((0 <= n->get_int()) && (n->get_int() <= 255)); 2174 match(ConI); 2175 2176 op_cost(5); 2177 format %{ %} 2178 interface(CONST_INTER); 2179 %} 2180 2181 operand immI16() 2182 %{ 2183 predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767)); 2184 match(ConI); 2185 2186 op_cost(10); 2187 format %{ %} 2188 interface(CONST_INTER); 2189 %} 2190 2191 // Int Immediate non-negative 2192 operand immU31() 2193 %{ 2194 predicate(n->get_int() >= 0); 2195 match(ConI); 2196 2197 op_cost(0); 2198 format %{ %} 2199 interface(CONST_INTER); 2200 %} 2201 2202 // Pointer Immediate 2203 operand immP() 2204 %{ 2205 match(ConP); 2206 2207 op_cost(10); 2208 format %{ %} 2209 interface(CONST_INTER); 2210 %} 2211 2212 // Null Pointer Immediate 2213 operand immP0() 2214 %{ 2215 predicate(n->get_ptr() == 0); 2216 match(ConP); 2217 2218 op_cost(5); 2219 format %{ %} 2220 interface(CONST_INTER); 2221 %} 2222 2223 // Pointer Immediate 2224 operand immN() %{ 2225 match(ConN); 2226 2227 op_cost(10); 2228 format %{ %} 2229 interface(CONST_INTER); 2230 %} 2231 2232 operand immNKlass() %{ 2233 match(ConNKlass); 2234 2235 op_cost(10); 2236 format %{ %} 2237 interface(CONST_INTER); 2238 %} 2239 2240 // Null Pointer Immediate 2241 operand immN0() %{ 2242 predicate(n->get_narrowcon() == 0); 2243 match(ConN); 2244 2245 op_cost(5); 2246 format %{ %} 2247 interface(CONST_INTER); 2248 %} 2249 2250 operand immP31() 2251 %{ 2252 predicate(n->as_Type()->type()->reloc() == relocInfo::none 2253 && (n->get_ptr() >> 31) == 0); 2254 match(ConP); 2255 2256 op_cost(5); 2257 format %{ %} 2258 interface(CONST_INTER); 2259 %} 2260 2261 2262 // Long Immediate 2263 operand immL() 2264 %{ 2265 match(ConL); 2266 2267 op_cost(20); 2268 format %{ %} 2269 interface(CONST_INTER); 2270 %} 2271 2272 // Long Immediate 8-bit 2273 operand immL8() 2274 %{ 2275 predicate(-0x80L <= n->get_long() && n->get_long() < 0x80L); 2276 match(ConL); 2277 2278 op_cost(5); 2279 format %{ %} 2280 interface(CONST_INTER); 2281 %} 2282 2283 // Long Immediate 32-bit unsigned 2284 operand immUL32() 2285 %{ 2286 predicate(n->get_long() == (unsigned int) (n->get_long())); 2287 match(ConL); 2288 2289 op_cost(10); 2290 format %{ %} 2291 interface(CONST_INTER); 2292 %} 2293 2294 // Long Immediate 32-bit signed 2295 operand immL32() 2296 %{ 2297 predicate(n->get_long() == (int) (n->get_long())); 2298 match(ConL); 2299 2300 op_cost(15); 2301 format %{ %} 2302 interface(CONST_INTER); 2303 %} 2304 2305 operand immL_Pow2() 2306 %{ 2307 predicate(is_power_of_2((julong)n->get_long())); 2308 match(ConL); 2309 2310 op_cost(15); 2311 format %{ %} 2312 interface(CONST_INTER); 2313 %} 2314 2315 operand immL_NotPow2() 2316 %{ 2317 predicate(is_power_of_2((julong)~n->get_long())); 2318 match(ConL); 2319 2320 op_cost(15); 2321 format %{ %} 2322 interface(CONST_INTER); 2323 %} 2324 2325 // Long Immediate zero 2326 operand immL0() 2327 %{ 2328 predicate(n->get_long() == 0L); 2329 match(ConL); 2330 2331 op_cost(10); 2332 format %{ %} 2333 interface(CONST_INTER); 2334 %} 2335 2336 // Constant for increment 2337 operand immL1() 2338 %{ 2339 predicate(n->get_long() == 1); 2340 match(ConL); 2341 2342 format %{ %} 2343 interface(CONST_INTER); 2344 %} 2345 2346 // Constant for decrement 2347 operand immL_M1() 2348 %{ 2349 predicate(n->get_long() == -1); 2350 match(ConL); 2351 2352 format %{ %} 2353 interface(CONST_INTER); 2354 %} 2355 2356 // Long Immediate: low 32-bit mask 2357 operand immL_32bits() 2358 %{ 2359 predicate(n->get_long() == 0xFFFFFFFFL); 2360 match(ConL); 2361 op_cost(20); 2362 2363 format %{ %} 2364 interface(CONST_INTER); 2365 %} 2366 2367 // Int Immediate: 2^n-1, positive 2368 operand immI_Pow2M1() 2369 %{ 2370 predicate((n->get_int() > 0) 2371 && is_power_of_2((juint)n->get_int() + 1)); 2372 match(ConI); 2373 2374 op_cost(20); 2375 format %{ %} 2376 interface(CONST_INTER); 2377 %} 2378 2379 // Float Immediate zero 2380 operand immF0() 2381 %{ 2382 predicate(jint_cast(n->getf()) == 0); 2383 match(ConF); 2384 2385 op_cost(5); 2386 format %{ %} 2387 interface(CONST_INTER); 2388 %} 2389 2390 // Float Immediate 2391 operand immF() 2392 %{ 2393 match(ConF); 2394 2395 op_cost(15); 2396 format %{ %} 2397 interface(CONST_INTER); 2398 %} 2399 2400 // Half Float Immediate 2401 operand immH() 2402 %{ 2403 match(ConH); 2404 2405 op_cost(15); 2406 format %{ %} 2407 interface(CONST_INTER); 2408 %} 2409 2410 // Double Immediate zero 2411 operand immD0() 2412 %{ 2413 predicate(jlong_cast(n->getd()) == 0); 2414 match(ConD); 2415 2416 op_cost(5); 2417 format %{ %} 2418 interface(CONST_INTER); 2419 %} 2420 2421 // Double Immediate 2422 operand immD() 2423 %{ 2424 match(ConD); 2425 2426 op_cost(15); 2427 format %{ %} 2428 interface(CONST_INTER); 2429 %} 2430 2431 // Immediates for special shifts (sign extend) 2432 2433 // Constants for increment 2434 operand immI_16() 2435 %{ 2436 predicate(n->get_int() == 16); 2437 match(ConI); 2438 2439 format %{ %} 2440 interface(CONST_INTER); 2441 %} 2442 2443 operand immI_24() 2444 %{ 2445 predicate(n->get_int() == 24); 2446 match(ConI); 2447 2448 format %{ %} 2449 interface(CONST_INTER); 2450 %} 2451 2452 // Constant for byte-wide masking 2453 operand immI_255() 2454 %{ 2455 predicate(n->get_int() == 255); 2456 match(ConI); 2457 2458 format %{ %} 2459 interface(CONST_INTER); 2460 %} 2461 2462 // Constant for short-wide masking 2463 operand immI_65535() 2464 %{ 2465 predicate(n->get_int() == 65535); 2466 match(ConI); 2467 2468 format %{ %} 2469 interface(CONST_INTER); 2470 %} 2471 2472 // Constant for byte-wide masking 2473 operand immL_255() 2474 %{ 2475 predicate(n->get_long() == 255); 2476 match(ConL); 2477 2478 format %{ %} 2479 interface(CONST_INTER); 2480 %} 2481 2482 // Constant for short-wide masking 2483 operand immL_65535() 2484 %{ 2485 predicate(n->get_long() == 65535); 2486 match(ConL); 2487 2488 format %{ %} 2489 interface(CONST_INTER); 2490 %} 2491 2492 // AOT Runtime Constants Address 2493 operand immAOTRuntimeConstantsAddress() 2494 %{ 2495 // Check if the address is in the range of AOT Runtime Constants 2496 predicate(AOTRuntimeConstants::contains((address)(n->get_ptr()))); 2497 match(ConP); 2498 2499 op_cost(0); 2500 format %{ %} 2501 interface(CONST_INTER); 2502 %} 2503 2504 operand kReg() 2505 %{ 2506 constraint(ALLOC_IN_RC(vectmask_reg)); 2507 match(RegVectMask); 2508 format %{%} 2509 interface(REG_INTER); 2510 %} 2511 2512 // Register Operands 2513 // Integer Register 2514 operand rRegI() 2515 %{ 2516 constraint(ALLOC_IN_RC(int_reg)); 2517 match(RegI); 2518 2519 match(rax_RegI); 2520 match(rbx_RegI); 2521 match(rcx_RegI); 2522 match(rdx_RegI); 2523 match(rdi_RegI); 2524 2525 format %{ %} 2526 interface(REG_INTER); 2527 %} 2528 2529 // Special Registers 2530 operand rax_RegI() 2531 %{ 2532 constraint(ALLOC_IN_RC(int_rax_reg)); 2533 match(RegI); 2534 match(rRegI); 2535 2536 format %{ "RAX" %} 2537 interface(REG_INTER); 2538 %} 2539 2540 // Special Registers 2541 operand rbx_RegI() 2542 %{ 2543 constraint(ALLOC_IN_RC(int_rbx_reg)); 2544 match(RegI); 2545 match(rRegI); 2546 2547 format %{ "RBX" %} 2548 interface(REG_INTER); 2549 %} 2550 2551 operand rcx_RegI() 2552 %{ 2553 constraint(ALLOC_IN_RC(int_rcx_reg)); 2554 match(RegI); 2555 match(rRegI); 2556 2557 format %{ "RCX" %} 2558 interface(REG_INTER); 2559 %} 2560 2561 operand rdx_RegI() 2562 %{ 2563 constraint(ALLOC_IN_RC(int_rdx_reg)); 2564 match(RegI); 2565 match(rRegI); 2566 2567 format %{ "RDX" %} 2568 interface(REG_INTER); 2569 %} 2570 2571 operand rdi_RegI() 2572 %{ 2573 constraint(ALLOC_IN_RC(int_rdi_reg)); 2574 match(RegI); 2575 match(rRegI); 2576 2577 format %{ "RDI" %} 2578 interface(REG_INTER); 2579 %} 2580 2581 operand no_rax_rdx_RegI() 2582 %{ 2583 constraint(ALLOC_IN_RC(int_no_rax_rdx_reg)); 2584 match(RegI); 2585 match(rbx_RegI); 2586 match(rcx_RegI); 2587 match(rdi_RegI); 2588 2589 format %{ %} 2590 interface(REG_INTER); 2591 %} 2592 2593 operand no_rbp_r13_RegI() 2594 %{ 2595 constraint(ALLOC_IN_RC(int_no_rbp_r13_reg)); 2596 match(RegI); 2597 match(rRegI); 2598 match(rax_RegI); 2599 match(rbx_RegI); 2600 match(rcx_RegI); 2601 match(rdx_RegI); 2602 match(rdi_RegI); 2603 2604 format %{ %} 2605 interface(REG_INTER); 2606 %} 2607 2608 // Pointer Register 2609 operand any_RegP() 2610 %{ 2611 constraint(ALLOC_IN_RC(any_reg)); 2612 match(RegP); 2613 match(rax_RegP); 2614 match(rbx_RegP); 2615 match(rdi_RegP); 2616 match(rsi_RegP); 2617 match(rbp_RegP); 2618 match(r15_RegP); 2619 match(rRegP); 2620 2621 format %{ %} 2622 interface(REG_INTER); 2623 %} 2624 2625 operand rRegP() 2626 %{ 2627 constraint(ALLOC_IN_RC(ptr_reg)); 2628 match(RegP); 2629 match(rax_RegP); 2630 match(rbx_RegP); 2631 match(rdi_RegP); 2632 match(rsi_RegP); 2633 match(rbp_RegP); // See Q&A below about 2634 match(r15_RegP); // r15_RegP and rbp_RegP. 2635 2636 format %{ %} 2637 interface(REG_INTER); 2638 %} 2639 2640 operand rRegN() %{ 2641 constraint(ALLOC_IN_RC(int_reg)); 2642 match(RegN); 2643 2644 format %{ %} 2645 interface(REG_INTER); 2646 %} 2647 2648 // Question: Why is r15_RegP (the read-only TLS register) a match for rRegP? 2649 // Answer: Operand match rules govern the DFA as it processes instruction inputs. 2650 // It's fine for an instruction input that expects rRegP to match a r15_RegP. 2651 // The output of an instruction is controlled by the allocator, which respects 2652 // register class masks, not match rules. Unless an instruction mentions 2653 // r15_RegP or any_RegP explicitly as its output, r15 will not be considered 2654 // by the allocator as an input. 2655 // The same logic applies to rbp_RegP being a match for rRegP: If PreserveFramePointer==true, 2656 // the RBP is used as a proper frame pointer and is not included in ptr_reg. As a 2657 // result, RBP is not included in the output of the instruction either. 2658 2659 // This operand is not allowed to use RBP even if 2660 // RBP is not used to hold the frame pointer. 2661 operand no_rbp_RegP() 2662 %{ 2663 constraint(ALLOC_IN_RC(ptr_reg_no_rbp)); 2664 match(RegP); 2665 match(rbx_RegP); 2666 match(rsi_RegP); 2667 match(rdi_RegP); 2668 2669 format %{ %} 2670 interface(REG_INTER); 2671 %} 2672 2673 // Special Registers 2674 // Return a pointer value 2675 operand rax_RegP() 2676 %{ 2677 constraint(ALLOC_IN_RC(ptr_rax_reg)); 2678 match(RegP); 2679 match(rRegP); 2680 2681 format %{ %} 2682 interface(REG_INTER); 2683 %} 2684 2685 // Special Registers 2686 // Return a compressed pointer value 2687 operand rax_RegN() 2688 %{ 2689 constraint(ALLOC_IN_RC(int_rax_reg)); 2690 match(RegN); 2691 match(rRegN); 2692 2693 format %{ %} 2694 interface(REG_INTER); 2695 %} 2696 2697 // Used in AtomicAdd 2698 operand rbx_RegP() 2699 %{ 2700 constraint(ALLOC_IN_RC(ptr_rbx_reg)); 2701 match(RegP); 2702 match(rRegP); 2703 2704 format %{ %} 2705 interface(REG_INTER); 2706 %} 2707 2708 operand rsi_RegP() 2709 %{ 2710 constraint(ALLOC_IN_RC(ptr_rsi_reg)); 2711 match(RegP); 2712 match(rRegP); 2713 2714 format %{ %} 2715 interface(REG_INTER); 2716 %} 2717 2718 operand rbp_RegP() 2719 %{ 2720 constraint(ALLOC_IN_RC(ptr_rbp_reg)); 2721 match(RegP); 2722 match(rRegP); 2723 2724 format %{ %} 2725 interface(REG_INTER); 2726 %} 2727 2728 // Used in rep stosq 2729 operand rdi_RegP() 2730 %{ 2731 constraint(ALLOC_IN_RC(ptr_rdi_reg)); 2732 match(RegP); 2733 match(rRegP); 2734 2735 format %{ %} 2736 interface(REG_INTER); 2737 %} 2738 2739 operand r15_RegP() 2740 %{ 2741 constraint(ALLOC_IN_RC(ptr_r15_reg)); 2742 match(RegP); 2743 match(rRegP); 2744 2745 format %{ %} 2746 interface(REG_INTER); 2747 %} 2748 2749 operand rRegL() 2750 %{ 2751 constraint(ALLOC_IN_RC(long_reg)); 2752 match(RegL); 2753 match(rax_RegL); 2754 match(rdx_RegL); 2755 2756 format %{ %} 2757 interface(REG_INTER); 2758 %} 2759 2760 // Special Registers 2761 operand no_rax_rdx_RegL() 2762 %{ 2763 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 2764 match(RegL); 2765 match(rRegL); 2766 2767 format %{ %} 2768 interface(REG_INTER); 2769 %} 2770 2771 operand rax_RegL() 2772 %{ 2773 constraint(ALLOC_IN_RC(long_rax_reg)); 2774 match(RegL); 2775 match(rRegL); 2776 2777 format %{ "RAX" %} 2778 interface(REG_INTER); 2779 %} 2780 2781 operand rcx_RegL() 2782 %{ 2783 constraint(ALLOC_IN_RC(long_rcx_reg)); 2784 match(RegL); 2785 match(rRegL); 2786 2787 format %{ %} 2788 interface(REG_INTER); 2789 %} 2790 2791 operand rdx_RegL() 2792 %{ 2793 constraint(ALLOC_IN_RC(long_rdx_reg)); 2794 match(RegL); 2795 match(rRegL); 2796 2797 format %{ %} 2798 interface(REG_INTER); 2799 %} 2800 2801 operand r11_RegL() 2802 %{ 2803 constraint(ALLOC_IN_RC(long_r11_reg)); 2804 match(RegL); 2805 match(rRegL); 2806 2807 format %{ %} 2808 interface(REG_INTER); 2809 %} 2810 2811 operand no_rbp_r13_RegL() 2812 %{ 2813 constraint(ALLOC_IN_RC(long_no_rbp_r13_reg)); 2814 match(RegL); 2815 match(rRegL); 2816 match(rax_RegL); 2817 match(rcx_RegL); 2818 match(rdx_RegL); 2819 2820 format %{ %} 2821 interface(REG_INTER); 2822 %} 2823 2824 // Flags register, used as output of compare instructions 2825 operand rFlagsReg() 2826 %{ 2827 constraint(ALLOC_IN_RC(int_flags)); 2828 match(RegFlags); 2829 2830 format %{ "RFLAGS" %} 2831 interface(REG_INTER); 2832 %} 2833 2834 // Flags register, used as output of FLOATING POINT compare instructions 2835 operand rFlagsRegU() 2836 %{ 2837 constraint(ALLOC_IN_RC(int_flags)); 2838 match(RegFlags); 2839 2840 format %{ "RFLAGS_U" %} 2841 interface(REG_INTER); 2842 %} 2843 2844 operand rFlagsRegUCF() %{ 2845 constraint(ALLOC_IN_RC(int_flags)); 2846 match(RegFlags); 2847 predicate(false); 2848 2849 format %{ "RFLAGS_U_CF" %} 2850 interface(REG_INTER); 2851 %} 2852 2853 // Float register operands 2854 operand regF() %{ 2855 constraint(ALLOC_IN_RC(float_reg)); 2856 match(RegF); 2857 2858 format %{ %} 2859 interface(REG_INTER); 2860 %} 2861 2862 // Float register operands 2863 operand legRegF() %{ 2864 constraint(ALLOC_IN_RC(float_reg_legacy)); 2865 match(RegF); 2866 2867 format %{ %} 2868 interface(REG_INTER); 2869 %} 2870 2871 // Float register operands 2872 operand vlRegF() %{ 2873 constraint(ALLOC_IN_RC(float_reg_vl)); 2874 match(RegF); 2875 2876 format %{ %} 2877 interface(REG_INTER); 2878 %} 2879 2880 // Double register operands 2881 operand regD() %{ 2882 constraint(ALLOC_IN_RC(double_reg)); 2883 match(RegD); 2884 2885 format %{ %} 2886 interface(REG_INTER); 2887 %} 2888 2889 // Double register operands 2890 operand legRegD() %{ 2891 constraint(ALLOC_IN_RC(double_reg_legacy)); 2892 match(RegD); 2893 2894 format %{ %} 2895 interface(REG_INTER); 2896 %} 2897 2898 // Double register operands 2899 operand vlRegD() %{ 2900 constraint(ALLOC_IN_RC(double_reg_vl)); 2901 match(RegD); 2902 2903 format %{ %} 2904 interface(REG_INTER); 2905 %} 2906 2907 //----------Memory Operands---------------------------------------------------- 2908 // Direct Memory Operand 2909 // operand direct(immP addr) 2910 // %{ 2911 // match(addr); 2912 2913 // format %{ "[$addr]" %} 2914 // interface(MEMORY_INTER) %{ 2915 // base(0xFFFFFFFF); 2916 // index(0x4); 2917 // scale(0x0); 2918 // disp($addr); 2919 // %} 2920 // %} 2921 2922 // Indirect Memory Operand 2923 operand indirect(any_RegP reg) 2924 %{ 2925 constraint(ALLOC_IN_RC(ptr_reg)); 2926 match(reg); 2927 2928 format %{ "[$reg]" %} 2929 interface(MEMORY_INTER) %{ 2930 base($reg); 2931 index(0x4); 2932 scale(0x0); 2933 disp(0x0); 2934 %} 2935 %} 2936 2937 // Indirect Memory Plus Short Offset Operand 2938 operand indOffset8(any_RegP reg, immL8 off) 2939 %{ 2940 constraint(ALLOC_IN_RC(ptr_reg)); 2941 match(AddP reg off); 2942 2943 format %{ "[$reg + $off (8-bit)]" %} 2944 interface(MEMORY_INTER) %{ 2945 base($reg); 2946 index(0x4); 2947 scale(0x0); 2948 disp($off); 2949 %} 2950 %} 2951 2952 // Indirect Memory Plus Long Offset Operand 2953 operand indOffset32(any_RegP reg, immL32 off) 2954 %{ 2955 constraint(ALLOC_IN_RC(ptr_reg)); 2956 match(AddP reg off); 2957 2958 format %{ "[$reg + $off (32-bit)]" %} 2959 interface(MEMORY_INTER) %{ 2960 base($reg); 2961 index(0x4); 2962 scale(0x0); 2963 disp($off); 2964 %} 2965 %} 2966 2967 // Indirect Memory Plus Index Register Plus Offset Operand 2968 operand indIndexOffset(any_RegP reg, rRegL lreg, immL32 off) 2969 %{ 2970 constraint(ALLOC_IN_RC(ptr_reg)); 2971 match(AddP (AddP reg lreg) off); 2972 2973 op_cost(10); 2974 format %{"[$reg + $off + $lreg]" %} 2975 interface(MEMORY_INTER) %{ 2976 base($reg); 2977 index($lreg); 2978 scale(0x0); 2979 disp($off); 2980 %} 2981 %} 2982 2983 // Indirect Memory Plus Index Register Plus Offset Operand 2984 operand indIndex(any_RegP reg, rRegL lreg) 2985 %{ 2986 constraint(ALLOC_IN_RC(ptr_reg)); 2987 match(AddP reg lreg); 2988 2989 op_cost(10); 2990 format %{"[$reg + $lreg]" %} 2991 interface(MEMORY_INTER) %{ 2992 base($reg); 2993 index($lreg); 2994 scale(0x0); 2995 disp(0x0); 2996 %} 2997 %} 2998 2999 // Indirect Memory Times Scale Plus Index Register 3000 operand indIndexScale(any_RegP reg, rRegL lreg, immI2 scale) 3001 %{ 3002 constraint(ALLOC_IN_RC(ptr_reg)); 3003 match(AddP reg (LShiftL lreg scale)); 3004 3005 op_cost(10); 3006 format %{"[$reg + $lreg << $scale]" %} 3007 interface(MEMORY_INTER) %{ 3008 base($reg); 3009 index($lreg); 3010 scale($scale); 3011 disp(0x0); 3012 %} 3013 %} 3014 3015 operand indPosIndexScale(any_RegP reg, rRegI idx, immI2 scale) 3016 %{ 3017 constraint(ALLOC_IN_RC(ptr_reg)); 3018 predicate(n->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3019 match(AddP reg (LShiftL (ConvI2L idx) scale)); 3020 3021 op_cost(10); 3022 format %{"[$reg + pos $idx << $scale]" %} 3023 interface(MEMORY_INTER) %{ 3024 base($reg); 3025 index($idx); 3026 scale($scale); 3027 disp(0x0); 3028 %} 3029 %} 3030 3031 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 3032 operand indIndexScaleOffset(any_RegP reg, immL32 off, rRegL lreg, immI2 scale) 3033 %{ 3034 constraint(ALLOC_IN_RC(ptr_reg)); 3035 match(AddP (AddP reg (LShiftL lreg scale)) off); 3036 3037 op_cost(10); 3038 format %{"[$reg + $off + $lreg << $scale]" %} 3039 interface(MEMORY_INTER) %{ 3040 base($reg); 3041 index($lreg); 3042 scale($scale); 3043 disp($off); 3044 %} 3045 %} 3046 3047 // Indirect Memory Plus Positive Index Register Plus Offset Operand 3048 operand indPosIndexOffset(any_RegP reg, immL32 off, rRegI idx) 3049 %{ 3050 constraint(ALLOC_IN_RC(ptr_reg)); 3051 predicate(n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 3052 match(AddP (AddP reg (ConvI2L idx)) off); 3053 3054 op_cost(10); 3055 format %{"[$reg + $off + $idx]" %} 3056 interface(MEMORY_INTER) %{ 3057 base($reg); 3058 index($idx); 3059 scale(0x0); 3060 disp($off); 3061 %} 3062 %} 3063 3064 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 3065 operand indPosIndexScaleOffset(any_RegP reg, immL32 off, rRegI idx, immI2 scale) 3066 %{ 3067 constraint(ALLOC_IN_RC(ptr_reg)); 3068 predicate(n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3069 match(AddP (AddP reg (LShiftL (ConvI2L idx) scale)) off); 3070 3071 op_cost(10); 3072 format %{"[$reg + $off + $idx << $scale]" %} 3073 interface(MEMORY_INTER) %{ 3074 base($reg); 3075 index($idx); 3076 scale($scale); 3077 disp($off); 3078 %} 3079 %} 3080 3081 // Indirect Narrow Oop Plus Offset Operand 3082 // Note: x86 architecture doesn't support "scale * index + offset" without a base 3083 // we can't free r12 even with CompressedOops::base() == nullptr. 3084 operand indCompressedOopOffset(rRegN reg, immL32 off) %{ 3085 predicate(UseCompressedOops && (CompressedOops::shift() == Address::times_8)); 3086 constraint(ALLOC_IN_RC(ptr_reg)); 3087 match(AddP (DecodeN reg) off); 3088 3089 op_cost(10); 3090 format %{"[R12 + $reg << 3 + $off] (compressed oop addressing)" %} 3091 interface(MEMORY_INTER) %{ 3092 base(0xc); // R12 3093 index($reg); 3094 scale(0x3); 3095 disp($off); 3096 %} 3097 %} 3098 3099 // Indirect Memory Operand 3100 operand indirectNarrow(rRegN reg) 3101 %{ 3102 predicate(CompressedOops::shift() == 0); 3103 constraint(ALLOC_IN_RC(ptr_reg)); 3104 match(DecodeN reg); 3105 3106 format %{ "[$reg]" %} 3107 interface(MEMORY_INTER) %{ 3108 base($reg); 3109 index(0x4); 3110 scale(0x0); 3111 disp(0x0); 3112 %} 3113 %} 3114 3115 // Indirect Memory Plus Short Offset Operand 3116 operand indOffset8Narrow(rRegN reg, immL8 off) 3117 %{ 3118 predicate(CompressedOops::shift() == 0); 3119 constraint(ALLOC_IN_RC(ptr_reg)); 3120 match(AddP (DecodeN reg) off); 3121 3122 format %{ "[$reg + $off (8-bit)]" %} 3123 interface(MEMORY_INTER) %{ 3124 base($reg); 3125 index(0x4); 3126 scale(0x0); 3127 disp($off); 3128 %} 3129 %} 3130 3131 // Indirect Memory Plus Long Offset Operand 3132 operand indOffset32Narrow(rRegN reg, immL32 off) 3133 %{ 3134 predicate(CompressedOops::shift() == 0); 3135 constraint(ALLOC_IN_RC(ptr_reg)); 3136 match(AddP (DecodeN reg) off); 3137 3138 format %{ "[$reg + $off (32-bit)]" %} 3139 interface(MEMORY_INTER) %{ 3140 base($reg); 3141 index(0x4); 3142 scale(0x0); 3143 disp($off); 3144 %} 3145 %} 3146 3147 // Indirect Memory Plus Index Register Plus Offset Operand 3148 operand indIndexOffsetNarrow(rRegN reg, rRegL lreg, immL32 off) 3149 %{ 3150 predicate(CompressedOops::shift() == 0); 3151 constraint(ALLOC_IN_RC(ptr_reg)); 3152 match(AddP (AddP (DecodeN reg) lreg) off); 3153 3154 op_cost(10); 3155 format %{"[$reg + $off + $lreg]" %} 3156 interface(MEMORY_INTER) %{ 3157 base($reg); 3158 index($lreg); 3159 scale(0x0); 3160 disp($off); 3161 %} 3162 %} 3163 3164 // Indirect Memory Plus Index Register Plus Offset Operand 3165 operand indIndexNarrow(rRegN reg, rRegL lreg) 3166 %{ 3167 predicate(CompressedOops::shift() == 0); 3168 constraint(ALLOC_IN_RC(ptr_reg)); 3169 match(AddP (DecodeN reg) lreg); 3170 3171 op_cost(10); 3172 format %{"[$reg + $lreg]" %} 3173 interface(MEMORY_INTER) %{ 3174 base($reg); 3175 index($lreg); 3176 scale(0x0); 3177 disp(0x0); 3178 %} 3179 %} 3180 3181 // Indirect Memory Times Scale Plus Index Register 3182 operand indIndexScaleNarrow(rRegN reg, rRegL lreg, immI2 scale) 3183 %{ 3184 predicate(CompressedOops::shift() == 0); 3185 constraint(ALLOC_IN_RC(ptr_reg)); 3186 match(AddP (DecodeN reg) (LShiftL lreg scale)); 3187 3188 op_cost(10); 3189 format %{"[$reg + $lreg << $scale]" %} 3190 interface(MEMORY_INTER) %{ 3191 base($reg); 3192 index($lreg); 3193 scale($scale); 3194 disp(0x0); 3195 %} 3196 %} 3197 3198 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 3199 operand indIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegL lreg, immI2 scale) 3200 %{ 3201 predicate(CompressedOops::shift() == 0); 3202 constraint(ALLOC_IN_RC(ptr_reg)); 3203 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off); 3204 3205 op_cost(10); 3206 format %{"[$reg + $off + $lreg << $scale]" %} 3207 interface(MEMORY_INTER) %{ 3208 base($reg); 3209 index($lreg); 3210 scale($scale); 3211 disp($off); 3212 %} 3213 %} 3214 3215 // Indirect Memory Times Plus Positive Index Register Plus Offset Operand 3216 operand indPosIndexOffsetNarrow(rRegN reg, immL32 off, rRegI idx) 3217 %{ 3218 constraint(ALLOC_IN_RC(ptr_reg)); 3219 predicate(CompressedOops::shift() == 0 && n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 3220 match(AddP (AddP (DecodeN reg) (ConvI2L idx)) off); 3221 3222 op_cost(10); 3223 format %{"[$reg + $off + $idx]" %} 3224 interface(MEMORY_INTER) %{ 3225 base($reg); 3226 index($idx); 3227 scale(0x0); 3228 disp($off); 3229 %} 3230 %} 3231 3232 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 3233 operand indPosIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegI idx, immI2 scale) 3234 %{ 3235 constraint(ALLOC_IN_RC(ptr_reg)); 3236 predicate(CompressedOops::shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3237 match(AddP (AddP (DecodeN reg) (LShiftL (ConvI2L idx) scale)) off); 3238 3239 op_cost(10); 3240 format %{"[$reg + $off + $idx << $scale]" %} 3241 interface(MEMORY_INTER) %{ 3242 base($reg); 3243 index($idx); 3244 scale($scale); 3245 disp($off); 3246 %} 3247 %} 3248 3249 //----------Special Memory Operands-------------------------------------------- 3250 // Stack Slot Operand - This operand is used for loading and storing temporary 3251 // values on the stack where a match requires a value to 3252 // flow through memory. 3253 operand stackSlotP(sRegP 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 stackSlotI(sRegI 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 stackSlotF(sRegF reg) 3282 %{ 3283 constraint(ALLOC_IN_RC(stack_slots)); 3284 // No match rule because this operand is only generated in matching 3285 3286 format %{ "[$reg]" %} 3287 interface(MEMORY_INTER) %{ 3288 base(0x4); // RSP 3289 index(0x4); // No Index 3290 scale(0x0); // No Scale 3291 disp($reg); // Stack Offset 3292 %} 3293 %} 3294 3295 operand stackSlotD(sRegD reg) 3296 %{ 3297 constraint(ALLOC_IN_RC(stack_slots)); 3298 // No match rule because this operand is only generated in matching 3299 3300 format %{ "[$reg]" %} 3301 interface(MEMORY_INTER) %{ 3302 base(0x4); // RSP 3303 index(0x4); // No Index 3304 scale(0x0); // No Scale 3305 disp($reg); // Stack Offset 3306 %} 3307 %} 3308 operand stackSlotL(sRegL reg) 3309 %{ 3310 constraint(ALLOC_IN_RC(stack_slots)); 3311 // No match rule because this operand is only generated in matching 3312 3313 format %{ "[$reg]" %} 3314 interface(MEMORY_INTER) %{ 3315 base(0x4); // RSP 3316 index(0x4); // No Index 3317 scale(0x0); // No Scale 3318 disp($reg); // Stack Offset 3319 %} 3320 %} 3321 3322 //----------Conditional Branch Operands---------------------------------------- 3323 // Comparison Op - This is the operation of the comparison, and is limited to 3324 // the following set of codes: 3325 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 3326 // 3327 // Other attributes of the comparison, such as unsignedness, are specified 3328 // by the comparison instruction that sets a condition code flags register. 3329 // That result is represented by a flags operand whose subtype is appropriate 3330 // to the unsignedness (etc.) of the comparison. 3331 // 3332 // Later, the instruction which matches both the Comparison Op (a Bool) and 3333 // the flags (produced by the Cmp) specifies the coding of the comparison op 3334 // by matching a specific subtype of Bool operand below, such as cmpOpU. 3335 3336 // Comparison Code 3337 operand cmpOp() 3338 %{ 3339 match(Bool); 3340 3341 format %{ "" %} 3342 interface(COND_INTER) %{ 3343 equal(0x4, "e"); 3344 not_equal(0x5, "ne"); 3345 less(0xC, "l"); 3346 greater_equal(0xD, "ge"); 3347 less_equal(0xE, "le"); 3348 greater(0xF, "g"); 3349 overflow(0x0, "o"); 3350 no_overflow(0x1, "no"); 3351 %} 3352 %} 3353 3354 // Comparison Code, unsigned compare. Used by FP also, with 3355 // C2 (unordered) turned into GT or LT already. The other bits 3356 // C0 and C3 are turned into Carry & Zero flags. 3357 operand cmpOpU() 3358 %{ 3359 match(Bool); 3360 3361 format %{ "" %} 3362 interface(COND_INTER) %{ 3363 equal(0x4, "e"); 3364 not_equal(0x5, "ne"); 3365 less(0x2, "b"); 3366 greater_equal(0x3, "ae"); 3367 less_equal(0x6, "be"); 3368 greater(0x7, "a"); 3369 overflow(0x0, "o"); 3370 no_overflow(0x1, "no"); 3371 %} 3372 %} 3373 3374 3375 // Floating comparisons that don't require any fixup for the unordered case, 3376 // If both inputs of the comparison are the same, ZF is always set so we 3377 // don't need to use cmpOpUCF2 for eq/ne 3378 operand cmpOpUCF() %{ 3379 match(Bool); 3380 predicate(n->as_Bool()->_test._test == BoolTest::lt || 3381 n->as_Bool()->_test._test == BoolTest::ge || 3382 n->as_Bool()->_test._test == BoolTest::le || 3383 n->as_Bool()->_test._test == BoolTest::gt || 3384 n->in(1)->in(1) == n->in(1)->in(2)); 3385 format %{ "" %} 3386 interface(COND_INTER) %{ 3387 equal(0xb, "np"); 3388 not_equal(0xa, "p"); 3389 less(0x2, "b"); 3390 greater_equal(0x3, "ae"); 3391 less_equal(0x6, "be"); 3392 greater(0x7, "a"); 3393 overflow(0x0, "o"); 3394 no_overflow(0x1, "no"); 3395 %} 3396 %} 3397 3398 3399 // Floating comparisons that can be fixed up with extra conditional jumps 3400 operand cmpOpUCF2() %{ 3401 match(Bool); 3402 predicate((n->as_Bool()->_test._test == BoolTest::ne || 3403 n->as_Bool()->_test._test == BoolTest::eq) && 3404 n->in(1)->in(1) != n->in(1)->in(2)); 3405 format %{ "" %} 3406 interface(COND_INTER) %{ 3407 equal(0x4, "e"); 3408 not_equal(0x5, "ne"); 3409 less(0x2, "b"); 3410 greater_equal(0x3, "ae"); 3411 less_equal(0x6, "be"); 3412 greater(0x7, "a"); 3413 overflow(0x0, "o"); 3414 no_overflow(0x1, "no"); 3415 %} 3416 %} 3417 3418 //----------OPERAND CLASSES---------------------------------------------------- 3419 // Operand Classes are groups of operands that are used as to simplify 3420 // instruction definitions by not requiring the AD writer to specify separate 3421 // instructions for every form of operand when the instruction accepts 3422 // multiple operand types with the same basic encoding and format. The classic 3423 // case of this is memory operands. 3424 3425 opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex, 3426 indIndexScale, indPosIndexScale, indIndexScaleOffset, indPosIndexOffset, indPosIndexScaleOffset, 3427 indCompressedOopOffset, 3428 indirectNarrow, indOffset8Narrow, indOffset32Narrow, 3429 indIndexOffsetNarrow, indIndexNarrow, indIndexScaleNarrow, 3430 indIndexScaleOffsetNarrow, indPosIndexOffsetNarrow, indPosIndexScaleOffsetNarrow); 3431 3432 //----------PIPELINE----------------------------------------------------------- 3433 // Rules which define the behavior of the target architectures pipeline. 3434 pipeline %{ 3435 3436 //----------ATTRIBUTES--------------------------------------------------------- 3437 attributes %{ 3438 variable_size_instructions; // Fixed size instructions 3439 max_instructions_per_bundle = 3; // Up to 3 instructions per bundle 3440 instruction_unit_size = 1; // An instruction is 1 bytes long 3441 instruction_fetch_unit_size = 16; // The processor fetches one line 3442 instruction_fetch_units = 1; // of 16 bytes 3443 %} 3444 3445 //----------RESOURCES---------------------------------------------------------- 3446 // Resources are the functional units available to the machine 3447 3448 // Generic P2/P3 pipeline 3449 // 3 decoders, only D0 handles big operands; a "bundle" is the limit of 3450 // 3 instructions decoded per cycle. 3451 // 2 load/store ops per cycle, 1 branch, 1 FPU, 3452 // 3 ALU op, only ALU0 handles mul instructions. 3453 resources( D0, D1, D2, DECODE = D0 | D1 | D2, 3454 MS0, MS1, MS2, MEM = MS0 | MS1 | MS2, 3455 BR, FPU, 3456 ALU0, ALU1, ALU2, ALU = ALU0 | ALU1 | ALU2); 3457 3458 //----------PIPELINE DESCRIPTION----------------------------------------------- 3459 // Pipeline Description specifies the stages in the machine's pipeline 3460 3461 // Generic P2/P3 pipeline 3462 pipe_desc(S0, S1, S2, S3, S4, S5); 3463 3464 //----------PIPELINE CLASSES--------------------------------------------------- 3465 // Pipeline Classes describe the stages in which input and output are 3466 // referenced by the hardware pipeline. 3467 3468 // Naming convention: ialu or fpu 3469 // Then: _reg 3470 // Then: _reg if there is a 2nd register 3471 // Then: _long if it's a pair of instructions implementing a long 3472 // Then: _fat if it requires the big decoder 3473 // Or: _mem if it requires the big decoder and a memory unit. 3474 3475 // Integer ALU reg operation 3476 pipe_class ialu_reg(rRegI dst) 3477 %{ 3478 single_instruction; 3479 dst : S4(write); 3480 dst : S3(read); 3481 DECODE : S0; // any decoder 3482 ALU : S3; // any alu 3483 %} 3484 3485 // Long ALU reg operation 3486 pipe_class ialu_reg_long(rRegL dst) 3487 %{ 3488 instruction_count(2); 3489 dst : S4(write); 3490 dst : S3(read); 3491 DECODE : S0(2); // any 2 decoders 3492 ALU : S3(2); // both alus 3493 %} 3494 3495 // Integer ALU reg operation using big decoder 3496 pipe_class ialu_reg_fat(rRegI dst) 3497 %{ 3498 single_instruction; 3499 dst : S4(write); 3500 dst : S3(read); 3501 D0 : S0; // big decoder only 3502 ALU : S3; // any alu 3503 %} 3504 3505 // Integer ALU reg-reg operation 3506 pipe_class ialu_reg_reg(rRegI dst, rRegI src) 3507 %{ 3508 single_instruction; 3509 dst : S4(write); 3510 src : S3(read); 3511 DECODE : S0; // any decoder 3512 ALU : S3; // any alu 3513 %} 3514 3515 // Integer ALU reg-reg operation 3516 pipe_class ialu_reg_reg_fat(rRegI dst, memory src) 3517 %{ 3518 single_instruction; 3519 dst : S4(write); 3520 src : S3(read); 3521 D0 : S0; // big decoder only 3522 ALU : S3; // any alu 3523 %} 3524 3525 // Integer ALU reg-mem operation 3526 pipe_class ialu_reg_mem(rRegI dst, memory mem) 3527 %{ 3528 single_instruction; 3529 dst : S5(write); 3530 mem : S3(read); 3531 D0 : S0; // big decoder only 3532 ALU : S4; // any alu 3533 MEM : S3; // any mem 3534 %} 3535 3536 // Integer mem operation (prefetch) 3537 pipe_class ialu_mem(memory mem) 3538 %{ 3539 single_instruction; 3540 mem : S3(read); 3541 D0 : S0; // big decoder only 3542 MEM : S3; // any mem 3543 %} 3544 3545 // Integer Store to Memory 3546 pipe_class ialu_mem_reg(memory mem, rRegI src) 3547 %{ 3548 single_instruction; 3549 mem : S3(read); 3550 src : S5(read); 3551 D0 : S0; // big decoder only 3552 ALU : S4; // any alu 3553 MEM : S3; 3554 %} 3555 3556 // // Long Store to Memory 3557 // pipe_class ialu_mem_long_reg(memory mem, rRegL src) 3558 // %{ 3559 // instruction_count(2); 3560 // mem : S3(read); 3561 // src : S5(read); 3562 // D0 : S0(2); // big decoder only; twice 3563 // ALU : S4(2); // any 2 alus 3564 // MEM : S3(2); // Both mems 3565 // %} 3566 3567 // Integer Store to Memory 3568 pipe_class ialu_mem_imm(memory mem) 3569 %{ 3570 single_instruction; 3571 mem : S3(read); 3572 D0 : S0; // big decoder only 3573 ALU : S4; // any alu 3574 MEM : S3; 3575 %} 3576 3577 // Integer ALU0 reg-reg operation 3578 pipe_class ialu_reg_reg_alu0(rRegI dst, rRegI src) 3579 %{ 3580 single_instruction; 3581 dst : S4(write); 3582 src : S3(read); 3583 D0 : S0; // Big decoder only 3584 ALU0 : S3; // only alu0 3585 %} 3586 3587 // Integer ALU0 reg-mem operation 3588 pipe_class ialu_reg_mem_alu0(rRegI dst, memory mem) 3589 %{ 3590 single_instruction; 3591 dst : S5(write); 3592 mem : S3(read); 3593 D0 : S0; // big decoder only 3594 ALU0 : S4; // ALU0 only 3595 MEM : S3; // any mem 3596 %} 3597 3598 // Integer ALU reg-reg operation 3599 pipe_class ialu_cr_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2) 3600 %{ 3601 single_instruction; 3602 cr : S4(write); 3603 src1 : S3(read); 3604 src2 : S3(read); 3605 DECODE : S0; // any decoder 3606 ALU : S3; // any alu 3607 %} 3608 3609 // Integer ALU reg-imm operation 3610 pipe_class ialu_cr_reg_imm(rFlagsReg cr, rRegI src1) 3611 %{ 3612 single_instruction; 3613 cr : S4(write); 3614 src1 : S3(read); 3615 DECODE : S0; // any decoder 3616 ALU : S3; // any alu 3617 %} 3618 3619 // Integer ALU reg-mem operation 3620 pipe_class ialu_cr_reg_mem(rFlagsReg cr, rRegI src1, memory src2) 3621 %{ 3622 single_instruction; 3623 cr : S4(write); 3624 src1 : S3(read); 3625 src2 : S3(read); 3626 D0 : S0; // big decoder only 3627 ALU : S4; // any alu 3628 MEM : S3; 3629 %} 3630 3631 // Conditional move reg-reg 3632 pipe_class pipe_cmplt( rRegI p, rRegI q, rRegI y) 3633 %{ 3634 instruction_count(4); 3635 y : S4(read); 3636 q : S3(read); 3637 p : S3(read); 3638 DECODE : S0(4); // any decoder 3639 %} 3640 3641 // Conditional move reg-reg 3642 pipe_class pipe_cmov_reg( rRegI dst, rRegI src, rFlagsReg cr) 3643 %{ 3644 single_instruction; 3645 dst : S4(write); 3646 src : S3(read); 3647 cr : S3(read); 3648 DECODE : S0; // any decoder 3649 %} 3650 3651 // Conditional move reg-mem 3652 pipe_class pipe_cmov_mem( rFlagsReg cr, rRegI dst, memory src) 3653 %{ 3654 single_instruction; 3655 dst : S4(write); 3656 src : S3(read); 3657 cr : S3(read); 3658 DECODE : S0; // any decoder 3659 MEM : S3; 3660 %} 3661 3662 // Conditional move reg-reg long 3663 pipe_class pipe_cmov_reg_long( rFlagsReg cr, rRegL dst, rRegL src) 3664 %{ 3665 single_instruction; 3666 dst : S4(write); 3667 src : S3(read); 3668 cr : S3(read); 3669 DECODE : S0(2); // any 2 decoders 3670 %} 3671 3672 // Float reg-reg operation 3673 pipe_class fpu_reg(regD dst) 3674 %{ 3675 instruction_count(2); 3676 dst : S3(read); 3677 DECODE : S0(2); // any 2 decoders 3678 FPU : S3; 3679 %} 3680 3681 // Float reg-reg operation 3682 pipe_class fpu_reg_reg(regD dst, regD src) 3683 %{ 3684 instruction_count(2); 3685 dst : S4(write); 3686 src : S3(read); 3687 DECODE : S0(2); // any 2 decoders 3688 FPU : S3; 3689 %} 3690 3691 // Float reg-reg operation 3692 pipe_class fpu_reg_reg_reg(regD dst, regD src1, regD src2) 3693 %{ 3694 instruction_count(3); 3695 dst : S4(write); 3696 src1 : S3(read); 3697 src2 : S3(read); 3698 DECODE : S0(3); // any 3 decoders 3699 FPU : S3(2); 3700 %} 3701 3702 // Float reg-reg operation 3703 pipe_class fpu_reg_reg_reg_reg(regD dst, regD src1, regD src2, regD src3) 3704 %{ 3705 instruction_count(4); 3706 dst : S4(write); 3707 src1 : S3(read); 3708 src2 : S3(read); 3709 src3 : S3(read); 3710 DECODE : S0(4); // any 3 decoders 3711 FPU : S3(2); 3712 %} 3713 3714 // Float reg-reg operation 3715 pipe_class fpu_reg_mem_reg_reg(regD dst, memory src1, regD src2, regD src3) 3716 %{ 3717 instruction_count(4); 3718 dst : S4(write); 3719 src1 : S3(read); 3720 src2 : S3(read); 3721 src3 : S3(read); 3722 DECODE : S1(3); // any 3 decoders 3723 D0 : S0; // Big decoder only 3724 FPU : S3(2); 3725 MEM : S3; 3726 %} 3727 3728 // Float reg-mem operation 3729 pipe_class fpu_reg_mem(regD dst, memory mem) 3730 %{ 3731 instruction_count(2); 3732 dst : S5(write); 3733 mem : S3(read); 3734 D0 : S0; // big decoder only 3735 DECODE : S1; // any decoder for FPU POP 3736 FPU : S4; 3737 MEM : S3; // any mem 3738 %} 3739 3740 // Float reg-mem operation 3741 pipe_class fpu_reg_reg_mem(regD dst, regD src1, memory mem) 3742 %{ 3743 instruction_count(3); 3744 dst : S5(write); 3745 src1 : S3(read); 3746 mem : S3(read); 3747 D0 : S0; // big decoder only 3748 DECODE : S1(2); // any decoder for FPU POP 3749 FPU : S4; 3750 MEM : S3; // any mem 3751 %} 3752 3753 // Float mem-reg operation 3754 pipe_class fpu_mem_reg(memory mem, regD src) 3755 %{ 3756 instruction_count(2); 3757 src : S5(read); 3758 mem : S3(read); 3759 DECODE : S0; // any decoder for FPU PUSH 3760 D0 : S1; // big decoder only 3761 FPU : S4; 3762 MEM : S3; // any mem 3763 %} 3764 3765 pipe_class fpu_mem_reg_reg(memory mem, regD src1, regD src2) 3766 %{ 3767 instruction_count(3); 3768 src1 : S3(read); 3769 src2 : S3(read); 3770 mem : S3(read); 3771 DECODE : S0(2); // any decoder for FPU PUSH 3772 D0 : S1; // big decoder only 3773 FPU : S4; 3774 MEM : S3; // any mem 3775 %} 3776 3777 pipe_class fpu_mem_reg_mem(memory mem, regD src1, memory src2) 3778 %{ 3779 instruction_count(3); 3780 src1 : S3(read); 3781 src2 : S3(read); 3782 mem : S4(read); 3783 DECODE : S0; // any decoder for FPU PUSH 3784 D0 : S0(2); // big decoder only 3785 FPU : S4; 3786 MEM : S3(2); // any mem 3787 %} 3788 3789 pipe_class fpu_mem_mem(memory dst, memory src1) 3790 %{ 3791 instruction_count(2); 3792 src1 : S3(read); 3793 dst : S4(read); 3794 D0 : S0(2); // big decoder only 3795 MEM : S3(2); // any mem 3796 %} 3797 3798 pipe_class fpu_mem_mem_mem(memory dst, memory src1, memory src2) 3799 %{ 3800 instruction_count(3); 3801 src1 : S3(read); 3802 src2 : S3(read); 3803 dst : S4(read); 3804 D0 : S0(3); // big decoder only 3805 FPU : S4; 3806 MEM : S3(3); // any mem 3807 %} 3808 3809 pipe_class fpu_mem_reg_con(memory mem, regD src1) 3810 %{ 3811 instruction_count(3); 3812 src1 : S4(read); 3813 mem : S4(read); 3814 DECODE : S0; // any decoder for FPU PUSH 3815 D0 : S0(2); // big decoder only 3816 FPU : S4; 3817 MEM : S3(2); // any mem 3818 %} 3819 3820 // Float load constant 3821 pipe_class fpu_reg_con(regD dst) 3822 %{ 3823 instruction_count(2); 3824 dst : S5(write); 3825 D0 : S0; // big decoder only for the load 3826 DECODE : S1; // any decoder for FPU POP 3827 FPU : S4; 3828 MEM : S3; // any mem 3829 %} 3830 3831 // Float load constant 3832 pipe_class fpu_reg_reg_con(regD dst, regD src) 3833 %{ 3834 instruction_count(3); 3835 dst : S5(write); 3836 src : S3(read); 3837 D0 : S0; // big decoder only for the load 3838 DECODE : S1(2); // any decoder for FPU POP 3839 FPU : S4; 3840 MEM : S3; // any mem 3841 %} 3842 3843 // UnConditional branch 3844 pipe_class pipe_jmp(label labl) 3845 %{ 3846 single_instruction; 3847 BR : S3; 3848 %} 3849 3850 // Conditional branch 3851 pipe_class pipe_jcc(cmpOp cmp, rFlagsReg cr, label labl) 3852 %{ 3853 single_instruction; 3854 cr : S1(read); 3855 BR : S3; 3856 %} 3857 3858 // Allocation idiom 3859 pipe_class pipe_cmpxchg(rRegP dst, rRegP heap_ptr) 3860 %{ 3861 instruction_count(1); force_serialization; 3862 fixed_latency(6); 3863 heap_ptr : S3(read); 3864 DECODE : S0(3); 3865 D0 : S2; 3866 MEM : S3; 3867 ALU : S3(2); 3868 dst : S5(write); 3869 BR : S5; 3870 %} 3871 3872 // Generic big/slow expanded idiom 3873 pipe_class pipe_slow() 3874 %{ 3875 instruction_count(10); multiple_bundles; force_serialization; 3876 fixed_latency(100); 3877 D0 : S0(2); 3878 MEM : S3(2); 3879 %} 3880 3881 // The real do-nothing guy 3882 pipe_class empty() 3883 %{ 3884 instruction_count(0); 3885 %} 3886 3887 // Define the class for the Nop node 3888 define 3889 %{ 3890 MachNop = empty; 3891 %} 3892 3893 %} 3894 3895 //----------INSTRUCTIONS------------------------------------------------------- 3896 // 3897 // match -- States which machine-independent subtree may be replaced 3898 // by this instruction. 3899 // ins_cost -- The estimated cost of this instruction is used by instruction 3900 // selection to identify a minimum cost tree of machine 3901 // instructions that matches a tree of machine-independent 3902 // instructions. 3903 // format -- A string providing the disassembly for this instruction. 3904 // The value of an instruction's operand may be inserted 3905 // by referring to it with a '$' prefix. 3906 // opcode -- Three instruction opcodes may be provided. These are referred 3907 // to within an encode class as $primary, $secondary, and $tertiary 3908 // rrspectively. The primary opcode is commonly used to 3909 // indicate the type of machine instruction, while secondary 3910 // and tertiary are often used for prefix options or addressing 3911 // modes. 3912 // ins_encode -- A list of encode classes with parameters. The encode class 3913 // name must have been defined in an 'enc_class' specification 3914 // in the encode section of the architecture description. 3915 3916 // Dummy reg-to-reg vector moves. Removed during post-selection cleanup. 3917 // Load Float 3918 instruct MoveF2VL(vlRegF dst, regF src) %{ 3919 match(Set dst src); 3920 format %{ "movss $dst,$src\t! load float (4 bytes)" %} 3921 ins_encode %{ 3922 ShouldNotReachHere(); 3923 %} 3924 ins_pipe( fpu_reg_reg ); 3925 %} 3926 3927 // Load Float 3928 instruct MoveF2LEG(legRegF dst, regF src) %{ 3929 match(Set dst src); 3930 format %{ "movss $dst,$src\t# if src != dst load float (4 bytes)" %} 3931 ins_encode %{ 3932 ShouldNotReachHere(); 3933 %} 3934 ins_pipe( fpu_reg_reg ); 3935 %} 3936 3937 // Load Float 3938 instruct MoveVL2F(regF dst, vlRegF src) %{ 3939 match(Set dst src); 3940 format %{ "movss $dst,$src\t! load float (4 bytes)" %} 3941 ins_encode %{ 3942 ShouldNotReachHere(); 3943 %} 3944 ins_pipe( fpu_reg_reg ); 3945 %} 3946 3947 // Load Float 3948 instruct MoveLEG2F(regF dst, legRegF src) %{ 3949 match(Set dst src); 3950 format %{ "movss $dst,$src\t# if src != dst load float (4 bytes)" %} 3951 ins_encode %{ 3952 ShouldNotReachHere(); 3953 %} 3954 ins_pipe( fpu_reg_reg ); 3955 %} 3956 3957 // Load Double 3958 instruct MoveD2VL(vlRegD dst, regD src) %{ 3959 match(Set dst src); 3960 format %{ "movsd $dst,$src\t! load double (8 bytes)" %} 3961 ins_encode %{ 3962 ShouldNotReachHere(); 3963 %} 3964 ins_pipe( fpu_reg_reg ); 3965 %} 3966 3967 // Load Double 3968 instruct MoveD2LEG(legRegD dst, regD src) %{ 3969 match(Set dst src); 3970 format %{ "movsd $dst,$src\t# if src != dst load double (8 bytes)" %} 3971 ins_encode %{ 3972 ShouldNotReachHere(); 3973 %} 3974 ins_pipe( fpu_reg_reg ); 3975 %} 3976 3977 // Load Double 3978 instruct MoveVL2D(regD dst, vlRegD src) %{ 3979 match(Set dst src); 3980 format %{ "movsd $dst,$src\t! load double (8 bytes)" %} 3981 ins_encode %{ 3982 ShouldNotReachHere(); 3983 %} 3984 ins_pipe( fpu_reg_reg ); 3985 %} 3986 3987 // Load Double 3988 instruct MoveLEG2D(regD dst, legRegD src) %{ 3989 match(Set dst src); 3990 format %{ "movsd $dst,$src\t# if src != dst load double (8 bytes)" %} 3991 ins_encode %{ 3992 ShouldNotReachHere(); 3993 %} 3994 ins_pipe( fpu_reg_reg ); 3995 %} 3996 3997 //----------Load/Store/Move Instructions--------------------------------------- 3998 //----------Load Instructions-------------------------------------------------- 3999 4000 // Load Byte (8 bit signed) 4001 instruct loadB(rRegI dst, memory mem) 4002 %{ 4003 match(Set dst (LoadB mem)); 4004 4005 ins_cost(125); 4006 format %{ "movsbl $dst, $mem\t# byte" %} 4007 4008 ins_encode %{ 4009 __ movsbl($dst$$Register, $mem$$Address); 4010 %} 4011 4012 ins_pipe(ialu_reg_mem); 4013 %} 4014 4015 // Load Byte (8 bit signed) into Long Register 4016 instruct loadB2L(rRegL dst, memory mem) 4017 %{ 4018 match(Set dst (ConvI2L (LoadB mem))); 4019 4020 ins_cost(125); 4021 format %{ "movsbq $dst, $mem\t# byte -> long" %} 4022 4023 ins_encode %{ 4024 __ movsbq($dst$$Register, $mem$$Address); 4025 %} 4026 4027 ins_pipe(ialu_reg_mem); 4028 %} 4029 4030 // Load Unsigned Byte (8 bit UNsigned) 4031 instruct loadUB(rRegI dst, memory mem) 4032 %{ 4033 match(Set dst (LoadUB mem)); 4034 4035 ins_cost(125); 4036 format %{ "movzbl $dst, $mem\t# ubyte" %} 4037 4038 ins_encode %{ 4039 __ movzbl($dst$$Register, $mem$$Address); 4040 %} 4041 4042 ins_pipe(ialu_reg_mem); 4043 %} 4044 4045 // Load Unsigned Byte (8 bit UNsigned) into Long Register 4046 instruct loadUB2L(rRegL dst, memory mem) 4047 %{ 4048 match(Set dst (ConvI2L (LoadUB mem))); 4049 4050 ins_cost(125); 4051 format %{ "movzbq $dst, $mem\t# ubyte -> long" %} 4052 4053 ins_encode %{ 4054 __ movzbq($dst$$Register, $mem$$Address); 4055 %} 4056 4057 ins_pipe(ialu_reg_mem); 4058 %} 4059 4060 // Load Unsigned Byte (8 bit UNsigned) with 32-bit mask into Long Register 4061 instruct loadUB2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 4062 match(Set dst (ConvI2L (AndI (LoadUB mem) mask))); 4063 effect(KILL cr); 4064 4065 format %{ "movzbq $dst, $mem\t# ubyte & 32-bit mask -> long\n\t" 4066 "andl $dst, right_n_bits($mask, 8)" %} 4067 ins_encode %{ 4068 Register Rdst = $dst$$Register; 4069 __ movzbq(Rdst, $mem$$Address); 4070 __ andl(Rdst, $mask$$constant & right_n_bits(8)); 4071 %} 4072 ins_pipe(ialu_reg_mem); 4073 %} 4074 4075 // Load Short (16 bit signed) 4076 instruct loadS(rRegI dst, memory mem) 4077 %{ 4078 match(Set dst (LoadS mem)); 4079 4080 ins_cost(125); 4081 format %{ "movswl $dst, $mem\t# short" %} 4082 4083 ins_encode %{ 4084 __ movswl($dst$$Register, $mem$$Address); 4085 %} 4086 4087 ins_pipe(ialu_reg_mem); 4088 %} 4089 4090 // Load Short (16 bit signed) to Byte (8 bit signed) 4091 instruct loadS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4092 match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour)); 4093 4094 ins_cost(125); 4095 format %{ "movsbl $dst, $mem\t# short -> byte" %} 4096 ins_encode %{ 4097 __ movsbl($dst$$Register, $mem$$Address); 4098 %} 4099 ins_pipe(ialu_reg_mem); 4100 %} 4101 4102 // Load Short (16 bit signed) into Long Register 4103 instruct loadS2L(rRegL dst, memory mem) 4104 %{ 4105 match(Set dst (ConvI2L (LoadS mem))); 4106 4107 ins_cost(125); 4108 format %{ "movswq $dst, $mem\t# short -> long" %} 4109 4110 ins_encode %{ 4111 __ movswq($dst$$Register, $mem$$Address); 4112 %} 4113 4114 ins_pipe(ialu_reg_mem); 4115 %} 4116 4117 // Load Unsigned Short/Char (16 bit UNsigned) 4118 instruct loadUS(rRegI dst, memory mem) 4119 %{ 4120 match(Set dst (LoadUS mem)); 4121 4122 ins_cost(125); 4123 format %{ "movzwl $dst, $mem\t# ushort/char" %} 4124 4125 ins_encode %{ 4126 __ movzwl($dst$$Register, $mem$$Address); 4127 %} 4128 4129 ins_pipe(ialu_reg_mem); 4130 %} 4131 4132 // Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed) 4133 instruct loadUS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4134 match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour)); 4135 4136 ins_cost(125); 4137 format %{ "movsbl $dst, $mem\t# ushort -> byte" %} 4138 ins_encode %{ 4139 __ movsbl($dst$$Register, $mem$$Address); 4140 %} 4141 ins_pipe(ialu_reg_mem); 4142 %} 4143 4144 // Load Unsigned Short/Char (16 bit UNsigned) into Long Register 4145 instruct loadUS2L(rRegL dst, memory mem) 4146 %{ 4147 match(Set dst (ConvI2L (LoadUS mem))); 4148 4149 ins_cost(125); 4150 format %{ "movzwq $dst, $mem\t# ushort/char -> long" %} 4151 4152 ins_encode %{ 4153 __ movzwq($dst$$Register, $mem$$Address); 4154 %} 4155 4156 ins_pipe(ialu_reg_mem); 4157 %} 4158 4159 // Load Unsigned Short/Char (16 bit UNsigned) with mask 0xFF into Long Register 4160 instruct loadUS2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 4161 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 4162 4163 format %{ "movzbq $dst, $mem\t# ushort/char & 0xFF -> long" %} 4164 ins_encode %{ 4165 __ movzbq($dst$$Register, $mem$$Address); 4166 %} 4167 ins_pipe(ialu_reg_mem); 4168 %} 4169 4170 // Load Unsigned Short/Char (16 bit UNsigned) with 32-bit mask into Long Register 4171 instruct loadUS2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 4172 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 4173 effect(KILL cr); 4174 4175 format %{ "movzwq $dst, $mem\t# ushort/char & 32-bit mask -> long\n\t" 4176 "andl $dst, right_n_bits($mask, 16)" %} 4177 ins_encode %{ 4178 Register Rdst = $dst$$Register; 4179 __ movzwq(Rdst, $mem$$Address); 4180 __ andl(Rdst, $mask$$constant & right_n_bits(16)); 4181 %} 4182 ins_pipe(ialu_reg_mem); 4183 %} 4184 4185 // Load Integer 4186 instruct loadI(rRegI dst, memory mem) 4187 %{ 4188 match(Set dst (LoadI mem)); 4189 4190 ins_cost(125); 4191 format %{ "movl $dst, $mem\t# int" %} 4192 4193 ins_encode %{ 4194 __ movl($dst$$Register, $mem$$Address); 4195 %} 4196 4197 ins_pipe(ialu_reg_mem); 4198 %} 4199 4200 // Load Integer (32 bit signed) to Byte (8 bit signed) 4201 instruct loadI2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4202 match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour)); 4203 4204 ins_cost(125); 4205 format %{ "movsbl $dst, $mem\t# int -> byte" %} 4206 ins_encode %{ 4207 __ movsbl($dst$$Register, $mem$$Address); 4208 %} 4209 ins_pipe(ialu_reg_mem); 4210 %} 4211 4212 // Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned) 4213 instruct loadI2UB(rRegI dst, memory mem, immI_255 mask) %{ 4214 match(Set dst (AndI (LoadI mem) mask)); 4215 4216 ins_cost(125); 4217 format %{ "movzbl $dst, $mem\t# int -> ubyte" %} 4218 ins_encode %{ 4219 __ movzbl($dst$$Register, $mem$$Address); 4220 %} 4221 ins_pipe(ialu_reg_mem); 4222 %} 4223 4224 // Load Integer (32 bit signed) to Short (16 bit signed) 4225 instruct loadI2S(rRegI dst, memory mem, immI_16 sixteen) %{ 4226 match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen)); 4227 4228 ins_cost(125); 4229 format %{ "movswl $dst, $mem\t# int -> short" %} 4230 ins_encode %{ 4231 __ movswl($dst$$Register, $mem$$Address); 4232 %} 4233 ins_pipe(ialu_reg_mem); 4234 %} 4235 4236 // Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned) 4237 instruct loadI2US(rRegI dst, memory mem, immI_65535 mask) %{ 4238 match(Set dst (AndI (LoadI mem) mask)); 4239 4240 ins_cost(125); 4241 format %{ "movzwl $dst, $mem\t# int -> ushort/char" %} 4242 ins_encode %{ 4243 __ movzwl($dst$$Register, $mem$$Address); 4244 %} 4245 ins_pipe(ialu_reg_mem); 4246 %} 4247 4248 // Load Integer into Long Register 4249 instruct loadI2L(rRegL dst, memory mem) 4250 %{ 4251 match(Set dst (ConvI2L (LoadI mem))); 4252 4253 ins_cost(125); 4254 format %{ "movslq $dst, $mem\t# int -> long" %} 4255 4256 ins_encode %{ 4257 __ movslq($dst$$Register, $mem$$Address); 4258 %} 4259 4260 ins_pipe(ialu_reg_mem); 4261 %} 4262 4263 // Load Integer with mask 0xFF into Long Register 4264 instruct loadI2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 4265 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4266 4267 format %{ "movzbq $dst, $mem\t# int & 0xFF -> long" %} 4268 ins_encode %{ 4269 __ movzbq($dst$$Register, $mem$$Address); 4270 %} 4271 ins_pipe(ialu_reg_mem); 4272 %} 4273 4274 // Load Integer with mask 0xFFFF into Long Register 4275 instruct loadI2L_immI_65535(rRegL dst, memory mem, immI_65535 mask) %{ 4276 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4277 4278 format %{ "movzwq $dst, $mem\t# int & 0xFFFF -> long" %} 4279 ins_encode %{ 4280 __ movzwq($dst$$Register, $mem$$Address); 4281 %} 4282 ins_pipe(ialu_reg_mem); 4283 %} 4284 4285 // Load Integer with a 31-bit mask into Long Register 4286 instruct loadI2L_immU31(rRegL dst, memory mem, immU31 mask, rFlagsReg cr) %{ 4287 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4288 effect(KILL cr); 4289 4290 format %{ "movl $dst, $mem\t# int & 31-bit mask -> long\n\t" 4291 "andl $dst, $mask" %} 4292 ins_encode %{ 4293 Register Rdst = $dst$$Register; 4294 __ movl(Rdst, $mem$$Address); 4295 __ andl(Rdst, $mask$$constant); 4296 %} 4297 ins_pipe(ialu_reg_mem); 4298 %} 4299 4300 // Load Unsigned Integer into Long Register 4301 instruct loadUI2L(rRegL dst, memory mem, immL_32bits mask) 4302 %{ 4303 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 4304 4305 ins_cost(125); 4306 format %{ "movl $dst, $mem\t# uint -> long" %} 4307 4308 ins_encode %{ 4309 __ movl($dst$$Register, $mem$$Address); 4310 %} 4311 4312 ins_pipe(ialu_reg_mem); 4313 %} 4314 4315 // Load Long 4316 instruct loadL(rRegL dst, memory mem) 4317 %{ 4318 match(Set dst (LoadL mem)); 4319 4320 ins_cost(125); 4321 format %{ "movq $dst, $mem\t# long" %} 4322 4323 ins_encode %{ 4324 __ movq($dst$$Register, $mem$$Address); 4325 %} 4326 4327 ins_pipe(ialu_reg_mem); // XXX 4328 %} 4329 4330 // Load Range 4331 instruct loadRange(rRegI dst, memory mem) 4332 %{ 4333 match(Set dst (LoadRange mem)); 4334 4335 ins_cost(125); // XXX 4336 format %{ "movl $dst, $mem\t# range" %} 4337 ins_encode %{ 4338 __ movl($dst$$Register, $mem$$Address); 4339 %} 4340 ins_pipe(ialu_reg_mem); 4341 %} 4342 4343 // Load Pointer 4344 instruct loadP(rRegP dst, memory mem) 4345 %{ 4346 match(Set dst (LoadP mem)); 4347 predicate(n->as_Load()->barrier_data() == 0); 4348 4349 ins_cost(125); // XXX 4350 format %{ "movq $dst, $mem\t# ptr" %} 4351 ins_encode %{ 4352 __ movq($dst$$Register, $mem$$Address); 4353 %} 4354 ins_pipe(ialu_reg_mem); // XXX 4355 %} 4356 4357 // Load Compressed Pointer 4358 instruct loadN(rRegN dst, memory mem) 4359 %{ 4360 predicate(n->as_Load()->barrier_data() == 0); 4361 match(Set dst (LoadN mem)); 4362 4363 ins_cost(125); // XXX 4364 format %{ "movl $dst, $mem\t# compressed ptr" %} 4365 ins_encode %{ 4366 __ movl($dst$$Register, $mem$$Address); 4367 %} 4368 ins_pipe(ialu_reg_mem); // XXX 4369 %} 4370 4371 4372 // Load Klass Pointer 4373 instruct loadKlass(rRegP dst, memory mem) 4374 %{ 4375 match(Set dst (LoadKlass mem)); 4376 4377 ins_cost(125); // XXX 4378 format %{ "movq $dst, $mem\t# class" %} 4379 ins_encode %{ 4380 __ movq($dst$$Register, $mem$$Address); 4381 %} 4382 ins_pipe(ialu_reg_mem); // XXX 4383 %} 4384 4385 // Load narrow Klass Pointer 4386 instruct loadNKlass(rRegN dst, memory mem) 4387 %{ 4388 predicate(!UseCompactObjectHeaders); 4389 match(Set dst (LoadNKlass mem)); 4390 4391 ins_cost(125); // XXX 4392 format %{ "movl $dst, $mem\t# compressed klass ptr" %} 4393 ins_encode %{ 4394 __ movl($dst$$Register, $mem$$Address); 4395 %} 4396 ins_pipe(ialu_reg_mem); // XXX 4397 %} 4398 4399 instruct loadNKlassCompactHeaders(rRegN dst, memory mem, rFlagsReg cr) 4400 %{ 4401 predicate(UseCompactObjectHeaders); 4402 match(Set dst (LoadNKlass mem)); 4403 effect(KILL cr); 4404 ins_cost(125); 4405 format %{ 4406 "movl $dst, $mem\t# compressed klass ptr, shifted\n\t" 4407 "shrl $dst, markWord::klass_shift_at_offset" 4408 %} 4409 ins_encode %{ 4410 if (UseAPX) { 4411 __ eshrl($dst$$Register, $mem$$Address, markWord::klass_shift_at_offset, false); 4412 } 4413 else { 4414 __ movl($dst$$Register, $mem$$Address); 4415 __ shrl($dst$$Register, markWord::klass_shift_at_offset); 4416 } 4417 %} 4418 ins_pipe(ialu_reg_mem); 4419 %} 4420 4421 // Load Float 4422 instruct loadF(regF dst, memory mem) 4423 %{ 4424 match(Set dst (LoadF mem)); 4425 4426 ins_cost(145); // XXX 4427 format %{ "movss $dst, $mem\t# float" %} 4428 ins_encode %{ 4429 __ movflt($dst$$XMMRegister, $mem$$Address); 4430 %} 4431 ins_pipe(pipe_slow); // XXX 4432 %} 4433 4434 // Load Double 4435 instruct loadD_partial(regD dst, memory mem) 4436 %{ 4437 predicate(!UseXmmLoadAndClearUpper); 4438 match(Set dst (LoadD mem)); 4439 4440 ins_cost(145); // XXX 4441 format %{ "movlpd $dst, $mem\t# double" %} 4442 ins_encode %{ 4443 __ movdbl($dst$$XMMRegister, $mem$$Address); 4444 %} 4445 ins_pipe(pipe_slow); // XXX 4446 %} 4447 4448 instruct loadD(regD dst, memory mem) 4449 %{ 4450 predicate(UseXmmLoadAndClearUpper); 4451 match(Set dst (LoadD mem)); 4452 4453 ins_cost(145); // XXX 4454 format %{ "movsd $dst, $mem\t# double" %} 4455 ins_encode %{ 4456 __ movdbl($dst$$XMMRegister, $mem$$Address); 4457 %} 4458 ins_pipe(pipe_slow); // XXX 4459 %} 4460 4461 instruct loadAOTRCAddress(rRegP dst, immAOTRuntimeConstantsAddress con) 4462 %{ 4463 match(Set dst con); 4464 4465 format %{ "leaq $dst, $con\t# AOT Runtime Constants Address" %} 4466 4467 ins_encode %{ 4468 __ load_aotrc_address($dst$$Register, (address)$con$$constant); 4469 %} 4470 4471 ins_pipe(ialu_reg_fat); 4472 %} 4473 4474 // max = java.lang.Math.max(float a, float b) 4475 instruct maxF_avx10_reg(regF dst, regF a, regF b) %{ 4476 predicate(VM_Version::supports_avx10_2()); 4477 match(Set dst (MaxF a b)); 4478 format %{ "maxF $dst, $a, $b" %} 4479 ins_encode %{ 4480 __ eminmaxss($dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, AVX10_MINMAX_MAX_COMPARE_SIGN); 4481 %} 4482 ins_pipe( pipe_slow ); 4483 %} 4484 4485 // max = java.lang.Math.max(float a, float b) 4486 instruct maxF_reg(legRegF dst, legRegF a, legRegF b, legRegF tmp, legRegF atmp, legRegF btmp) %{ 4487 predicate(!VM_Version::supports_avx10_2() && UseAVX > 0 && !VLoopReductions::is_reduction(n)); 4488 match(Set dst (MaxF a b)); 4489 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 4490 format %{ "maxF $dst, $a, $b \t! using $tmp, $atmp and $btmp as TEMP" %} 4491 ins_encode %{ 4492 __ vminmax_fp(Op_MaxV, T_FLOAT, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, Assembler::AVX_128bit); 4493 %} 4494 ins_pipe( pipe_slow ); 4495 %} 4496 4497 instruct maxF_reduction_reg(legRegF dst, legRegF a, legRegF b, legRegF xtmp, rRegI rtmp, rFlagsReg cr) %{ 4498 predicate(!VM_Version::supports_avx10_2() && UseAVX > 0 && VLoopReductions::is_reduction(n)); 4499 match(Set dst (MaxF a b)); 4500 effect(USE a, USE b, TEMP xtmp, TEMP rtmp, KILL cr); 4501 4502 format %{ "maxF_reduction $dst, $a, $b \t!using $xtmp and $rtmp as TEMP" %} 4503 ins_encode %{ 4504 emit_fp_min_max(masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xtmp$$XMMRegister, $rtmp$$Register, 4505 false /*min*/, true /*single*/); 4506 %} 4507 ins_pipe( pipe_slow ); 4508 %} 4509 4510 // max = java.lang.Math.max(double a, double b) 4511 instruct maxD_avx10_reg(regD dst, regD a, regD b) %{ 4512 predicate(VM_Version::supports_avx10_2()); 4513 match(Set dst (MaxD a b)); 4514 format %{ "maxD $dst, $a, $b" %} 4515 ins_encode %{ 4516 __ eminmaxsd($dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, AVX10_MINMAX_MAX_COMPARE_SIGN); 4517 %} 4518 ins_pipe( pipe_slow ); 4519 %} 4520 4521 // max = java.lang.Math.max(double a, double b) 4522 instruct maxD_reg(legRegD dst, legRegD a, legRegD b, legRegD tmp, legRegD atmp, legRegD btmp) %{ 4523 predicate(!VM_Version::supports_avx10_2() && UseAVX > 0 && !VLoopReductions::is_reduction(n)); 4524 match(Set dst (MaxD a b)); 4525 effect(USE a, USE b, TEMP atmp, TEMP btmp, TEMP tmp); 4526 format %{ "maxD $dst, $a, $b \t! using $tmp, $atmp and $btmp as TEMP" %} 4527 ins_encode %{ 4528 __ vminmax_fp(Op_MaxV, T_DOUBLE, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, Assembler::AVX_128bit); 4529 %} 4530 ins_pipe( pipe_slow ); 4531 %} 4532 4533 instruct maxD_reduction_reg(legRegD dst, legRegD a, legRegD b, legRegD xtmp, rRegL rtmp, rFlagsReg cr) %{ 4534 predicate(!VM_Version::supports_avx10_2() && UseAVX > 0 && VLoopReductions::is_reduction(n)); 4535 match(Set dst (MaxD a b)); 4536 effect(USE a, USE b, TEMP xtmp, TEMP rtmp, KILL cr); 4537 4538 format %{ "maxD_reduction $dst, $a, $b \t! using $xtmp and $rtmp as TEMP" %} 4539 ins_encode %{ 4540 emit_fp_min_max(masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xtmp$$XMMRegister, $rtmp$$Register, 4541 false /*min*/, false /*single*/); 4542 %} 4543 ins_pipe( pipe_slow ); 4544 %} 4545 4546 // max = java.lang.Math.min(float a, float b) 4547 instruct minF_avx10_reg(regF dst, regF a, regF b) %{ 4548 predicate(VM_Version::supports_avx10_2()); 4549 match(Set dst (MinF a b)); 4550 format %{ "minF $dst, $a, $b" %} 4551 ins_encode %{ 4552 __ eminmaxss($dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, AVX10_MINMAX_MIN_COMPARE_SIGN); 4553 %} 4554 ins_pipe( pipe_slow ); 4555 %} 4556 4557 // min = java.lang.Math.min(float a, float b) 4558 instruct minF_reg(legRegF dst, legRegF a, legRegF b, legRegF tmp, legRegF atmp, legRegF btmp) %{ 4559 predicate(!VM_Version::supports_avx10_2() && UseAVX > 0 && !VLoopReductions::is_reduction(n)); 4560 match(Set dst (MinF a b)); 4561 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 4562 format %{ "minF $dst, $a, $b \t! using $tmp, $atmp and $btmp as TEMP" %} 4563 ins_encode %{ 4564 __ vminmax_fp(Op_MinV, T_FLOAT, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, Assembler::AVX_128bit); 4565 %} 4566 ins_pipe( pipe_slow ); 4567 %} 4568 4569 instruct minF_reduction_reg(legRegF dst, legRegF a, legRegF b, legRegF xtmp, rRegI rtmp, rFlagsReg cr) %{ 4570 predicate(!VM_Version::supports_avx10_2() && UseAVX > 0 && VLoopReductions::is_reduction(n)); 4571 match(Set dst (MinF a b)); 4572 effect(USE a, USE b, TEMP xtmp, TEMP rtmp, KILL cr); 4573 4574 format %{ "minF_reduction $dst, $a, $b \t! using $xtmp and $rtmp as TEMP" %} 4575 ins_encode %{ 4576 emit_fp_min_max(masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xtmp$$XMMRegister, $rtmp$$Register, 4577 true /*min*/, true /*single*/); 4578 %} 4579 ins_pipe( pipe_slow ); 4580 %} 4581 4582 // max = java.lang.Math.min(double a, double b) 4583 instruct minD_avx10_reg(regD dst, regD a, regD b) %{ 4584 predicate(VM_Version::supports_avx10_2()); 4585 match(Set dst (MinD a b)); 4586 format %{ "minD $dst, $a, $b" %} 4587 ins_encode %{ 4588 __ eminmaxsd($dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, AVX10_MINMAX_MIN_COMPARE_SIGN); 4589 %} 4590 ins_pipe( pipe_slow ); 4591 %} 4592 4593 // min = java.lang.Math.min(double a, double b) 4594 instruct minD_reg(legRegD dst, legRegD a, legRegD b, legRegD tmp, legRegD atmp, legRegD btmp) %{ 4595 predicate(!VM_Version::supports_avx10_2() && UseAVX > 0 && !VLoopReductions::is_reduction(n)); 4596 match(Set dst (MinD a b)); 4597 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 4598 format %{ "minD $dst, $a, $b \t! using $tmp, $atmp and $btmp as TEMP" %} 4599 ins_encode %{ 4600 __ vminmax_fp(Op_MinV, T_DOUBLE, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, Assembler::AVX_128bit); 4601 %} 4602 ins_pipe( pipe_slow ); 4603 %} 4604 4605 instruct minD_reduction_reg(legRegD dst, legRegD a, legRegD b, legRegD xtmp, rRegL rtmp, rFlagsReg cr) %{ 4606 predicate(!VM_Version::supports_avx10_2() && UseAVX > 0 && VLoopReductions::is_reduction(n)); 4607 match(Set dst (MinD a b)); 4608 effect(USE a, USE b, TEMP xtmp, TEMP rtmp, KILL cr); 4609 4610 format %{ "maxD_reduction $dst, $a, $b \t! using $xtmp and $rtmp as TEMP" %} 4611 ins_encode %{ 4612 emit_fp_min_max(masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xtmp$$XMMRegister, $rtmp$$Register, 4613 true /*min*/, false /*single*/); 4614 %} 4615 ins_pipe( pipe_slow ); 4616 %} 4617 4618 // Load Effective Address 4619 instruct leaP8(rRegP dst, indOffset8 mem) 4620 %{ 4621 match(Set dst mem); 4622 4623 ins_cost(110); // XXX 4624 format %{ "leaq $dst, $mem\t# ptr 8" %} 4625 ins_encode %{ 4626 __ leaq($dst$$Register, $mem$$Address); 4627 %} 4628 ins_pipe(ialu_reg_reg_fat); 4629 %} 4630 4631 instruct leaP32(rRegP dst, indOffset32 mem) 4632 %{ 4633 match(Set dst mem); 4634 4635 ins_cost(110); 4636 format %{ "leaq $dst, $mem\t# ptr 32" %} 4637 ins_encode %{ 4638 __ leaq($dst$$Register, $mem$$Address); 4639 %} 4640 ins_pipe(ialu_reg_reg_fat); 4641 %} 4642 4643 instruct leaPIdxOff(rRegP dst, indIndexOffset mem) 4644 %{ 4645 match(Set dst mem); 4646 4647 ins_cost(110); 4648 format %{ "leaq $dst, $mem\t# ptr idxoff" %} 4649 ins_encode %{ 4650 __ leaq($dst$$Register, $mem$$Address); 4651 %} 4652 ins_pipe(ialu_reg_reg_fat); 4653 %} 4654 4655 instruct leaPIdxScale(rRegP dst, indIndexScale mem) 4656 %{ 4657 match(Set dst mem); 4658 4659 ins_cost(110); 4660 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 4661 ins_encode %{ 4662 __ leaq($dst$$Register, $mem$$Address); 4663 %} 4664 ins_pipe(ialu_reg_reg_fat); 4665 %} 4666 4667 instruct leaPPosIdxScale(rRegP dst, indPosIndexScale mem) 4668 %{ 4669 match(Set dst mem); 4670 4671 ins_cost(110); 4672 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 4673 ins_encode %{ 4674 __ leaq($dst$$Register, $mem$$Address); 4675 %} 4676 ins_pipe(ialu_reg_reg_fat); 4677 %} 4678 4679 instruct leaPIdxScaleOff(rRegP dst, indIndexScaleOffset mem) 4680 %{ 4681 match(Set dst mem); 4682 4683 ins_cost(110); 4684 format %{ "leaq $dst, $mem\t# ptr idxscaleoff" %} 4685 ins_encode %{ 4686 __ leaq($dst$$Register, $mem$$Address); 4687 %} 4688 ins_pipe(ialu_reg_reg_fat); 4689 %} 4690 4691 instruct leaPPosIdxOff(rRegP dst, indPosIndexOffset mem) 4692 %{ 4693 match(Set dst mem); 4694 4695 ins_cost(110); 4696 format %{ "leaq $dst, $mem\t# ptr posidxoff" %} 4697 ins_encode %{ 4698 __ leaq($dst$$Register, $mem$$Address); 4699 %} 4700 ins_pipe(ialu_reg_reg_fat); 4701 %} 4702 4703 instruct leaPPosIdxScaleOff(rRegP dst, indPosIndexScaleOffset mem) 4704 %{ 4705 match(Set dst mem); 4706 4707 ins_cost(110); 4708 format %{ "leaq $dst, $mem\t# ptr posidxscaleoff" %} 4709 ins_encode %{ 4710 __ leaq($dst$$Register, $mem$$Address); 4711 %} 4712 ins_pipe(ialu_reg_reg_fat); 4713 %} 4714 4715 // Load Effective Address which uses Narrow (32-bits) oop 4716 instruct leaPCompressedOopOffset(rRegP dst, indCompressedOopOffset mem) 4717 %{ 4718 predicate(UseCompressedOops && (CompressedOops::shift() != 0)); 4719 match(Set dst mem); 4720 4721 ins_cost(110); 4722 format %{ "leaq $dst, $mem\t# ptr compressedoopoff32" %} 4723 ins_encode %{ 4724 __ leaq($dst$$Register, $mem$$Address); 4725 %} 4726 ins_pipe(ialu_reg_reg_fat); 4727 %} 4728 4729 instruct leaP8Narrow(rRegP dst, indOffset8Narrow mem) 4730 %{ 4731 predicate(CompressedOops::shift() == 0); 4732 match(Set dst mem); 4733 4734 ins_cost(110); // XXX 4735 format %{ "leaq $dst, $mem\t# ptr off8narrow" %} 4736 ins_encode %{ 4737 __ leaq($dst$$Register, $mem$$Address); 4738 %} 4739 ins_pipe(ialu_reg_reg_fat); 4740 %} 4741 4742 instruct leaP32Narrow(rRegP dst, indOffset32Narrow mem) 4743 %{ 4744 predicate(CompressedOops::shift() == 0); 4745 match(Set dst mem); 4746 4747 ins_cost(110); 4748 format %{ "leaq $dst, $mem\t# ptr off32narrow" %} 4749 ins_encode %{ 4750 __ leaq($dst$$Register, $mem$$Address); 4751 %} 4752 ins_pipe(ialu_reg_reg_fat); 4753 %} 4754 4755 instruct leaPIdxOffNarrow(rRegP dst, indIndexOffsetNarrow mem) 4756 %{ 4757 predicate(CompressedOops::shift() == 0); 4758 match(Set dst mem); 4759 4760 ins_cost(110); 4761 format %{ "leaq $dst, $mem\t# ptr idxoffnarrow" %} 4762 ins_encode %{ 4763 __ leaq($dst$$Register, $mem$$Address); 4764 %} 4765 ins_pipe(ialu_reg_reg_fat); 4766 %} 4767 4768 instruct leaPIdxScaleNarrow(rRegP dst, indIndexScaleNarrow mem) 4769 %{ 4770 predicate(CompressedOops::shift() == 0); 4771 match(Set dst mem); 4772 4773 ins_cost(110); 4774 format %{ "leaq $dst, $mem\t# ptr idxscalenarrow" %} 4775 ins_encode %{ 4776 __ leaq($dst$$Register, $mem$$Address); 4777 %} 4778 ins_pipe(ialu_reg_reg_fat); 4779 %} 4780 4781 instruct leaPIdxScaleOffNarrow(rRegP dst, indIndexScaleOffsetNarrow mem) 4782 %{ 4783 predicate(CompressedOops::shift() == 0); 4784 match(Set dst mem); 4785 4786 ins_cost(110); 4787 format %{ "leaq $dst, $mem\t# ptr idxscaleoffnarrow" %} 4788 ins_encode %{ 4789 __ leaq($dst$$Register, $mem$$Address); 4790 %} 4791 ins_pipe(ialu_reg_reg_fat); 4792 %} 4793 4794 instruct leaPPosIdxOffNarrow(rRegP dst, indPosIndexOffsetNarrow mem) 4795 %{ 4796 predicate(CompressedOops::shift() == 0); 4797 match(Set dst mem); 4798 4799 ins_cost(110); 4800 format %{ "leaq $dst, $mem\t# ptr posidxoffnarrow" %} 4801 ins_encode %{ 4802 __ leaq($dst$$Register, $mem$$Address); 4803 %} 4804 ins_pipe(ialu_reg_reg_fat); 4805 %} 4806 4807 instruct leaPPosIdxScaleOffNarrow(rRegP dst, indPosIndexScaleOffsetNarrow mem) 4808 %{ 4809 predicate(CompressedOops::shift() == 0); 4810 match(Set dst mem); 4811 4812 ins_cost(110); 4813 format %{ "leaq $dst, $mem\t# ptr posidxscaleoffnarrow" %} 4814 ins_encode %{ 4815 __ leaq($dst$$Register, $mem$$Address); 4816 %} 4817 ins_pipe(ialu_reg_reg_fat); 4818 %} 4819 4820 instruct loadConI(rRegI dst, immI src) 4821 %{ 4822 match(Set dst src); 4823 4824 format %{ "movl $dst, $src\t# int" %} 4825 ins_encode %{ 4826 __ movl($dst$$Register, $src$$constant); 4827 %} 4828 ins_pipe(ialu_reg_fat); // XXX 4829 %} 4830 4831 instruct loadConI0(rRegI dst, immI_0 src, rFlagsReg cr) 4832 %{ 4833 match(Set dst src); 4834 effect(KILL cr); 4835 4836 ins_cost(50); 4837 format %{ "xorl $dst, $dst\t# int" %} 4838 ins_encode %{ 4839 __ xorl($dst$$Register, $dst$$Register); 4840 %} 4841 ins_pipe(ialu_reg); 4842 %} 4843 4844 instruct loadConL(rRegL dst, immL src) 4845 %{ 4846 match(Set dst src); 4847 4848 ins_cost(150); 4849 format %{ "movq $dst, $src\t# long" %} 4850 ins_encode %{ 4851 __ mov64($dst$$Register, $src$$constant); 4852 %} 4853 ins_pipe(ialu_reg); 4854 %} 4855 4856 instruct loadConL0(rRegL dst, immL0 src, rFlagsReg cr) 4857 %{ 4858 match(Set dst src); 4859 effect(KILL cr); 4860 4861 ins_cost(50); 4862 format %{ "xorl $dst, $dst\t# long" %} 4863 ins_encode %{ 4864 __ xorl($dst$$Register, $dst$$Register); 4865 %} 4866 ins_pipe(ialu_reg); // XXX 4867 %} 4868 4869 instruct loadConUL32(rRegL dst, immUL32 src) 4870 %{ 4871 match(Set dst src); 4872 4873 ins_cost(60); 4874 format %{ "movl $dst, $src\t# long (unsigned 32-bit)" %} 4875 ins_encode %{ 4876 __ movl($dst$$Register, $src$$constant); 4877 %} 4878 ins_pipe(ialu_reg); 4879 %} 4880 4881 instruct loadConL32(rRegL dst, immL32 src) 4882 %{ 4883 match(Set dst src); 4884 4885 ins_cost(70); 4886 format %{ "movq $dst, $src\t# long (32-bit)" %} 4887 ins_encode %{ 4888 __ movq($dst$$Register, $src$$constant); 4889 %} 4890 ins_pipe(ialu_reg); 4891 %} 4892 4893 instruct loadConP(rRegP dst, immP con) %{ 4894 match(Set dst con); 4895 4896 format %{ "movq $dst, $con\t# ptr" %} 4897 ins_encode %{ 4898 __ mov64($dst$$Register, $con$$constant, $con->constant_reloc(), RELOC_IMM64); 4899 %} 4900 ins_pipe(ialu_reg_fat); // XXX 4901 %} 4902 4903 instruct loadConP0(rRegP dst, immP0 src, rFlagsReg cr) 4904 %{ 4905 match(Set dst src); 4906 effect(KILL cr); 4907 4908 ins_cost(50); 4909 format %{ "xorl $dst, $dst\t# ptr" %} 4910 ins_encode %{ 4911 __ xorl($dst$$Register, $dst$$Register); 4912 %} 4913 ins_pipe(ialu_reg); 4914 %} 4915 4916 instruct loadConP31(rRegP dst, immP31 src, rFlagsReg cr) 4917 %{ 4918 match(Set dst src); 4919 effect(KILL cr); 4920 4921 ins_cost(60); 4922 format %{ "movl $dst, $src\t# ptr (positive 32-bit)" %} 4923 ins_encode %{ 4924 __ movl($dst$$Register, $src$$constant); 4925 %} 4926 ins_pipe(ialu_reg); 4927 %} 4928 4929 instruct loadConF(regF dst, immF con) %{ 4930 match(Set dst con); 4931 ins_cost(125); 4932 format %{ "movss $dst, [$constantaddress]\t# load from constant table: float=$con" %} 4933 ins_encode %{ 4934 __ movflt($dst$$XMMRegister, $constantaddress($con)); 4935 %} 4936 ins_pipe(pipe_slow); 4937 %} 4938 4939 instruct loadConH(regF dst, immH con) %{ 4940 match(Set dst con); 4941 ins_cost(125); 4942 format %{ "movss $dst, [$constantaddress]\t# load from constant table: halffloat=$con" %} 4943 ins_encode %{ 4944 __ movflt($dst$$XMMRegister, $constantaddress($con)); 4945 %} 4946 ins_pipe(pipe_slow); 4947 %} 4948 4949 instruct loadConN0(rRegN dst, immN0 src, rFlagsReg cr) %{ 4950 match(Set dst src); 4951 effect(KILL cr); 4952 format %{ "xorq $dst, $src\t# compressed null pointer" %} 4953 ins_encode %{ 4954 __ xorq($dst$$Register, $dst$$Register); 4955 %} 4956 ins_pipe(ialu_reg); 4957 %} 4958 4959 instruct loadConN(rRegN dst, immN src) %{ 4960 match(Set dst src); 4961 4962 ins_cost(125); 4963 format %{ "movl $dst, $src\t# compressed ptr" %} 4964 ins_encode %{ 4965 address con = (address)$src$$constant; 4966 if (con == nullptr) { 4967 ShouldNotReachHere(); 4968 } else { 4969 __ set_narrow_oop($dst$$Register, (jobject)$src$$constant); 4970 } 4971 %} 4972 ins_pipe(ialu_reg_fat); // XXX 4973 %} 4974 4975 instruct loadConNKlass(rRegN dst, immNKlass src) %{ 4976 match(Set dst src); 4977 4978 ins_cost(125); 4979 format %{ "movl $dst, $src\t# compressed klass ptr" %} 4980 ins_encode %{ 4981 address con = (address)$src$$constant; 4982 if (con == nullptr) { 4983 ShouldNotReachHere(); 4984 } else { 4985 __ set_narrow_klass($dst$$Register, (Klass*)$src$$constant); 4986 } 4987 %} 4988 ins_pipe(ialu_reg_fat); // XXX 4989 %} 4990 4991 instruct loadConF0(regF dst, immF0 src) 4992 %{ 4993 match(Set dst src); 4994 ins_cost(100); 4995 4996 format %{ "xorps $dst, $dst\t# float 0.0" %} 4997 ins_encode %{ 4998 __ xorps($dst$$XMMRegister, $dst$$XMMRegister); 4999 %} 5000 ins_pipe(pipe_slow); 5001 %} 5002 5003 // Use the same format since predicate() can not be used here. 5004 instruct loadConD(regD dst, immD con) %{ 5005 match(Set dst con); 5006 ins_cost(125); 5007 format %{ "movsd $dst, [$constantaddress]\t# load from constant table: double=$con" %} 5008 ins_encode %{ 5009 __ movdbl($dst$$XMMRegister, $constantaddress($con)); 5010 %} 5011 ins_pipe(pipe_slow); 5012 %} 5013 5014 instruct loadConD0(regD dst, immD0 src) 5015 %{ 5016 match(Set dst src); 5017 ins_cost(100); 5018 5019 format %{ "xorpd $dst, $dst\t# double 0.0" %} 5020 ins_encode %{ 5021 __ xorpd($dst$$XMMRegister, $dst$$XMMRegister); 5022 %} 5023 ins_pipe(pipe_slow); 5024 %} 5025 5026 instruct loadSSI(rRegI dst, stackSlotI src) 5027 %{ 5028 match(Set dst src); 5029 5030 ins_cost(125); 5031 format %{ "movl $dst, $src\t# int stk" %} 5032 ins_encode %{ 5033 __ movl($dst$$Register, $src$$Address); 5034 %} 5035 ins_pipe(ialu_reg_mem); 5036 %} 5037 5038 instruct loadSSL(rRegL dst, stackSlotL src) 5039 %{ 5040 match(Set dst src); 5041 5042 ins_cost(125); 5043 format %{ "movq $dst, $src\t# long stk" %} 5044 ins_encode %{ 5045 __ movq($dst$$Register, $src$$Address); 5046 %} 5047 ins_pipe(ialu_reg_mem); 5048 %} 5049 5050 instruct loadSSP(rRegP dst, stackSlotP src) 5051 %{ 5052 match(Set dst src); 5053 5054 ins_cost(125); 5055 format %{ "movq $dst, $src\t# ptr stk" %} 5056 ins_encode %{ 5057 __ movq($dst$$Register, $src$$Address); 5058 %} 5059 ins_pipe(ialu_reg_mem); 5060 %} 5061 5062 instruct loadSSF(regF dst, stackSlotF src) 5063 %{ 5064 match(Set dst src); 5065 5066 ins_cost(125); 5067 format %{ "movss $dst, $src\t# float stk" %} 5068 ins_encode %{ 5069 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 5070 %} 5071 ins_pipe(pipe_slow); // XXX 5072 %} 5073 5074 // Use the same format since predicate() can not be used here. 5075 instruct loadSSD(regD dst, stackSlotD src) 5076 %{ 5077 match(Set dst src); 5078 5079 ins_cost(125); 5080 format %{ "movsd $dst, $src\t# double stk" %} 5081 ins_encode %{ 5082 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 5083 %} 5084 ins_pipe(pipe_slow); // XXX 5085 %} 5086 5087 // Prefetch instructions for allocation. 5088 // Must be safe to execute with invalid address (cannot fault). 5089 5090 instruct prefetchAlloc( memory mem ) %{ 5091 predicate(AllocatePrefetchInstr==3); 5092 match(PrefetchAllocation mem); 5093 ins_cost(125); 5094 5095 format %{ "PREFETCHW $mem\t# Prefetch allocation into level 1 cache and mark modified" %} 5096 ins_encode %{ 5097 __ prefetchw($mem$$Address); 5098 %} 5099 ins_pipe(ialu_mem); 5100 %} 5101 5102 instruct prefetchAllocNTA( memory mem ) %{ 5103 predicate(AllocatePrefetchInstr==0); 5104 match(PrefetchAllocation mem); 5105 ins_cost(125); 5106 5107 format %{ "PREFETCHNTA $mem\t# Prefetch allocation to non-temporal cache for write" %} 5108 ins_encode %{ 5109 __ prefetchnta($mem$$Address); 5110 %} 5111 ins_pipe(ialu_mem); 5112 %} 5113 5114 instruct prefetchAllocT0( memory mem ) %{ 5115 predicate(AllocatePrefetchInstr==1); 5116 match(PrefetchAllocation mem); 5117 ins_cost(125); 5118 5119 format %{ "PREFETCHT0 $mem\t# Prefetch allocation to level 1 and 2 caches for write" %} 5120 ins_encode %{ 5121 __ prefetcht0($mem$$Address); 5122 %} 5123 ins_pipe(ialu_mem); 5124 %} 5125 5126 instruct prefetchAllocT2( memory mem ) %{ 5127 predicate(AllocatePrefetchInstr==2); 5128 match(PrefetchAllocation mem); 5129 ins_cost(125); 5130 5131 format %{ "PREFETCHT2 $mem\t# Prefetch allocation to level 2 cache for write" %} 5132 ins_encode %{ 5133 __ prefetcht2($mem$$Address); 5134 %} 5135 ins_pipe(ialu_mem); 5136 %} 5137 5138 //----------Store Instructions------------------------------------------------- 5139 5140 // Store Byte 5141 instruct storeB(memory mem, rRegI src) 5142 %{ 5143 match(Set mem (StoreB mem src)); 5144 5145 ins_cost(125); // XXX 5146 format %{ "movb $mem, $src\t# byte" %} 5147 ins_encode %{ 5148 __ movb($mem$$Address, $src$$Register); 5149 %} 5150 ins_pipe(ialu_mem_reg); 5151 %} 5152 5153 // Store Char/Short 5154 instruct storeC(memory mem, rRegI src) 5155 %{ 5156 match(Set mem (StoreC mem src)); 5157 5158 ins_cost(125); // XXX 5159 format %{ "movw $mem, $src\t# char/short" %} 5160 ins_encode %{ 5161 __ movw($mem$$Address, $src$$Register); 5162 %} 5163 ins_pipe(ialu_mem_reg); 5164 %} 5165 5166 // Store Integer 5167 instruct storeI(memory mem, rRegI src) 5168 %{ 5169 match(Set mem (StoreI mem src)); 5170 5171 ins_cost(125); // XXX 5172 format %{ "movl $mem, $src\t# int" %} 5173 ins_encode %{ 5174 __ movl($mem$$Address, $src$$Register); 5175 %} 5176 ins_pipe(ialu_mem_reg); 5177 %} 5178 5179 // Store Long 5180 instruct storeL(memory mem, rRegL src) 5181 %{ 5182 match(Set mem (StoreL mem src)); 5183 5184 ins_cost(125); // XXX 5185 format %{ "movq $mem, $src\t# long" %} 5186 ins_encode %{ 5187 __ movq($mem$$Address, $src$$Register); 5188 %} 5189 ins_pipe(ialu_mem_reg); // XXX 5190 %} 5191 5192 // Store Pointer 5193 instruct storeP(memory mem, any_RegP src) 5194 %{ 5195 predicate(n->as_Store()->barrier_data() == 0); 5196 match(Set mem (StoreP mem src)); 5197 5198 ins_cost(125); // XXX 5199 format %{ "movq $mem, $src\t# ptr" %} 5200 ins_encode %{ 5201 __ movq($mem$$Address, $src$$Register); 5202 %} 5203 ins_pipe(ialu_mem_reg); 5204 %} 5205 5206 instruct storeImmP0(memory mem, immP0 zero) 5207 %{ 5208 predicate(UseCompressedOops && (CompressedOops::base() == nullptr) && n->as_Store()->barrier_data() == 0); 5209 match(Set mem (StoreP mem zero)); 5210 5211 ins_cost(125); // XXX 5212 format %{ "movq $mem, R12\t# ptr (R12_heapbase==0)" %} 5213 ins_encode %{ 5214 __ movq($mem$$Address, r12); 5215 %} 5216 ins_pipe(ialu_mem_reg); 5217 %} 5218 5219 // Store Null Pointer, mark word, or other simple pointer constant. 5220 instruct storeImmP(memory mem, immP31 src) 5221 %{ 5222 predicate(n->as_Store()->barrier_data() == 0); 5223 match(Set mem (StoreP mem src)); 5224 5225 ins_cost(150); // XXX 5226 format %{ "movq $mem, $src\t# ptr" %} 5227 ins_encode %{ 5228 __ movq($mem$$Address, $src$$constant); 5229 %} 5230 ins_pipe(ialu_mem_imm); 5231 %} 5232 5233 // Store Compressed Pointer 5234 instruct storeN(memory mem, rRegN src) 5235 %{ 5236 predicate(n->as_Store()->barrier_data() == 0); 5237 match(Set mem (StoreN mem src)); 5238 5239 ins_cost(125); // XXX 5240 format %{ "movl $mem, $src\t# compressed ptr" %} 5241 ins_encode %{ 5242 __ movl($mem$$Address, $src$$Register); 5243 %} 5244 ins_pipe(ialu_mem_reg); 5245 %} 5246 5247 instruct storeNKlass(memory mem, rRegN src) 5248 %{ 5249 match(Set mem (StoreNKlass mem src)); 5250 5251 ins_cost(125); // XXX 5252 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5253 ins_encode %{ 5254 __ movl($mem$$Address, $src$$Register); 5255 %} 5256 ins_pipe(ialu_mem_reg); 5257 %} 5258 5259 instruct storeImmN0(memory mem, immN0 zero) 5260 %{ 5261 predicate(CompressedOops::base() == nullptr && n->as_Store()->barrier_data() == 0); 5262 match(Set mem (StoreN mem zero)); 5263 5264 ins_cost(125); // XXX 5265 format %{ "movl $mem, R12\t# compressed ptr (R12_heapbase==0)" %} 5266 ins_encode %{ 5267 __ movl($mem$$Address, r12); 5268 %} 5269 ins_pipe(ialu_mem_reg); 5270 %} 5271 5272 instruct storeImmN(memory mem, immN src) 5273 %{ 5274 predicate(n->as_Store()->barrier_data() == 0); 5275 match(Set mem (StoreN mem src)); 5276 5277 ins_cost(150); // XXX 5278 format %{ "movl $mem, $src\t# compressed ptr" %} 5279 ins_encode %{ 5280 address con = (address)$src$$constant; 5281 if (con == nullptr) { 5282 __ movl($mem$$Address, 0); 5283 } else { 5284 __ set_narrow_oop($mem$$Address, (jobject)$src$$constant); 5285 } 5286 %} 5287 ins_pipe(ialu_mem_imm); 5288 %} 5289 5290 instruct storeImmNKlass(memory mem, immNKlass src) 5291 %{ 5292 match(Set mem (StoreNKlass mem src)); 5293 5294 ins_cost(150); // XXX 5295 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5296 ins_encode %{ 5297 __ set_narrow_klass($mem$$Address, (Klass*)$src$$constant); 5298 %} 5299 ins_pipe(ialu_mem_imm); 5300 %} 5301 5302 // Store Integer Immediate 5303 instruct storeImmI0(memory mem, immI_0 zero) 5304 %{ 5305 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5306 match(Set mem (StoreI mem zero)); 5307 5308 ins_cost(125); // XXX 5309 format %{ "movl $mem, R12\t# int (R12_heapbase==0)" %} 5310 ins_encode %{ 5311 __ movl($mem$$Address, r12); 5312 %} 5313 ins_pipe(ialu_mem_reg); 5314 %} 5315 5316 instruct storeImmI(memory mem, immI src) 5317 %{ 5318 match(Set mem (StoreI mem src)); 5319 5320 ins_cost(150); 5321 format %{ "movl $mem, $src\t# int" %} 5322 ins_encode %{ 5323 __ movl($mem$$Address, $src$$constant); 5324 %} 5325 ins_pipe(ialu_mem_imm); 5326 %} 5327 5328 // Store Long Immediate 5329 instruct storeImmL0(memory mem, immL0 zero) 5330 %{ 5331 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5332 match(Set mem (StoreL mem zero)); 5333 5334 ins_cost(125); // XXX 5335 format %{ "movq $mem, R12\t# long (R12_heapbase==0)" %} 5336 ins_encode %{ 5337 __ movq($mem$$Address, r12); 5338 %} 5339 ins_pipe(ialu_mem_reg); 5340 %} 5341 5342 instruct storeImmL(memory mem, immL32 src) 5343 %{ 5344 match(Set mem (StoreL mem src)); 5345 5346 ins_cost(150); 5347 format %{ "movq $mem, $src\t# long" %} 5348 ins_encode %{ 5349 __ movq($mem$$Address, $src$$constant); 5350 %} 5351 ins_pipe(ialu_mem_imm); 5352 %} 5353 5354 // Store Short/Char Immediate 5355 instruct storeImmC0(memory mem, immI_0 zero) 5356 %{ 5357 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5358 match(Set mem (StoreC mem zero)); 5359 5360 ins_cost(125); // XXX 5361 format %{ "movw $mem, R12\t# short/char (R12_heapbase==0)" %} 5362 ins_encode %{ 5363 __ movw($mem$$Address, r12); 5364 %} 5365 ins_pipe(ialu_mem_reg); 5366 %} 5367 5368 instruct storeImmI16(memory mem, immI16 src) 5369 %{ 5370 predicate(UseStoreImmI16); 5371 match(Set mem (StoreC mem src)); 5372 5373 ins_cost(150); 5374 format %{ "movw $mem, $src\t# short/char" %} 5375 ins_encode %{ 5376 __ movw($mem$$Address, $src$$constant); 5377 %} 5378 ins_pipe(ialu_mem_imm); 5379 %} 5380 5381 // Store Byte Immediate 5382 instruct storeImmB0(memory mem, immI_0 zero) 5383 %{ 5384 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5385 match(Set mem (StoreB mem zero)); 5386 5387 ins_cost(125); // XXX 5388 format %{ "movb $mem, R12\t# short/char (R12_heapbase==0)" %} 5389 ins_encode %{ 5390 __ movb($mem$$Address, r12); 5391 %} 5392 ins_pipe(ialu_mem_reg); 5393 %} 5394 5395 instruct storeImmB(memory mem, immI8 src) 5396 %{ 5397 match(Set mem (StoreB mem src)); 5398 5399 ins_cost(150); // XXX 5400 format %{ "movb $mem, $src\t# byte" %} 5401 ins_encode %{ 5402 __ movb($mem$$Address, $src$$constant); 5403 %} 5404 ins_pipe(ialu_mem_imm); 5405 %} 5406 5407 // Store Float 5408 instruct storeF(memory mem, regF src) 5409 %{ 5410 match(Set mem (StoreF mem src)); 5411 5412 ins_cost(95); // XXX 5413 format %{ "movss $mem, $src\t# float" %} 5414 ins_encode %{ 5415 __ movflt($mem$$Address, $src$$XMMRegister); 5416 %} 5417 ins_pipe(pipe_slow); // XXX 5418 %} 5419 5420 // Store immediate Float value (it is faster than store from XMM register) 5421 instruct storeF0(memory mem, immF0 zero) 5422 %{ 5423 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5424 match(Set mem (StoreF mem zero)); 5425 5426 ins_cost(25); // XXX 5427 format %{ "movl $mem, R12\t# float 0. (R12_heapbase==0)" %} 5428 ins_encode %{ 5429 __ movl($mem$$Address, r12); 5430 %} 5431 ins_pipe(ialu_mem_reg); 5432 %} 5433 5434 instruct storeF_imm(memory mem, immF src) 5435 %{ 5436 match(Set mem (StoreF mem src)); 5437 5438 ins_cost(50); 5439 format %{ "movl $mem, $src\t# float" %} 5440 ins_encode %{ 5441 __ movl($mem$$Address, jint_cast($src$$constant)); 5442 %} 5443 ins_pipe(ialu_mem_imm); 5444 %} 5445 5446 // Store Double 5447 instruct storeD(memory mem, regD src) 5448 %{ 5449 match(Set mem (StoreD mem src)); 5450 5451 ins_cost(95); // XXX 5452 format %{ "movsd $mem, $src\t# double" %} 5453 ins_encode %{ 5454 __ movdbl($mem$$Address, $src$$XMMRegister); 5455 %} 5456 ins_pipe(pipe_slow); // XXX 5457 %} 5458 5459 // Store immediate double 0.0 (it is faster than store from XMM register) 5460 instruct storeD0_imm(memory mem, immD0 src) 5461 %{ 5462 predicate(!UseCompressedOops || (CompressedOops::base() != nullptr)); 5463 match(Set mem (StoreD mem src)); 5464 5465 ins_cost(50); 5466 format %{ "movq $mem, $src\t# double 0." %} 5467 ins_encode %{ 5468 __ movq($mem$$Address, $src$$constant); 5469 %} 5470 ins_pipe(ialu_mem_imm); 5471 %} 5472 5473 instruct storeD0(memory mem, immD0 zero) 5474 %{ 5475 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5476 match(Set mem (StoreD mem zero)); 5477 5478 ins_cost(25); // XXX 5479 format %{ "movq $mem, R12\t# double 0. (R12_heapbase==0)" %} 5480 ins_encode %{ 5481 __ movq($mem$$Address, r12); 5482 %} 5483 ins_pipe(ialu_mem_reg); 5484 %} 5485 5486 instruct storeSSI(stackSlotI dst, rRegI src) 5487 %{ 5488 match(Set dst src); 5489 5490 ins_cost(100); 5491 format %{ "movl $dst, $src\t# int stk" %} 5492 ins_encode %{ 5493 __ movl($dst$$Address, $src$$Register); 5494 %} 5495 ins_pipe( ialu_mem_reg ); 5496 %} 5497 5498 instruct storeSSL(stackSlotL dst, rRegL src) 5499 %{ 5500 match(Set dst src); 5501 5502 ins_cost(100); 5503 format %{ "movq $dst, $src\t# long stk" %} 5504 ins_encode %{ 5505 __ movq($dst$$Address, $src$$Register); 5506 %} 5507 ins_pipe(ialu_mem_reg); 5508 %} 5509 5510 instruct storeSSP(stackSlotP dst, rRegP src) 5511 %{ 5512 match(Set dst src); 5513 5514 ins_cost(100); 5515 format %{ "movq $dst, $src\t# ptr stk" %} 5516 ins_encode %{ 5517 __ movq($dst$$Address, $src$$Register); 5518 %} 5519 ins_pipe(ialu_mem_reg); 5520 %} 5521 5522 instruct storeSSF(stackSlotF dst, regF src) 5523 %{ 5524 match(Set dst src); 5525 5526 ins_cost(95); // XXX 5527 format %{ "movss $dst, $src\t# float stk" %} 5528 ins_encode %{ 5529 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 5530 %} 5531 ins_pipe(pipe_slow); // XXX 5532 %} 5533 5534 instruct storeSSD(stackSlotD dst, regD src) 5535 %{ 5536 match(Set dst src); 5537 5538 ins_cost(95); // XXX 5539 format %{ "movsd $dst, $src\t# double stk" %} 5540 ins_encode %{ 5541 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 5542 %} 5543 ins_pipe(pipe_slow); // XXX 5544 %} 5545 5546 instruct cacheWB(indirect addr) 5547 %{ 5548 predicate(VM_Version::supports_data_cache_line_flush()); 5549 match(CacheWB addr); 5550 5551 ins_cost(100); 5552 format %{"cache wb $addr" %} 5553 ins_encode %{ 5554 assert($addr->index_position() < 0, "should be"); 5555 assert($addr$$disp == 0, "should be"); 5556 __ cache_wb(Address($addr$$base$$Register, 0)); 5557 %} 5558 ins_pipe(pipe_slow); // XXX 5559 %} 5560 5561 instruct cacheWBPreSync() 5562 %{ 5563 predicate(VM_Version::supports_data_cache_line_flush()); 5564 match(CacheWBPreSync); 5565 5566 ins_cost(100); 5567 format %{"cache wb presync" %} 5568 ins_encode %{ 5569 __ cache_wbsync(true); 5570 %} 5571 ins_pipe(pipe_slow); // XXX 5572 %} 5573 5574 instruct cacheWBPostSync() 5575 %{ 5576 predicate(VM_Version::supports_data_cache_line_flush()); 5577 match(CacheWBPostSync); 5578 5579 ins_cost(100); 5580 format %{"cache wb postsync" %} 5581 ins_encode %{ 5582 __ cache_wbsync(false); 5583 %} 5584 ins_pipe(pipe_slow); // XXX 5585 %} 5586 5587 //----------BSWAP Instructions------------------------------------------------- 5588 instruct bytes_reverse_int(rRegI dst) %{ 5589 match(Set dst (ReverseBytesI dst)); 5590 5591 format %{ "bswapl $dst" %} 5592 ins_encode %{ 5593 __ bswapl($dst$$Register); 5594 %} 5595 ins_pipe( ialu_reg ); 5596 %} 5597 5598 instruct bytes_reverse_long(rRegL dst) %{ 5599 match(Set dst (ReverseBytesL dst)); 5600 5601 format %{ "bswapq $dst" %} 5602 ins_encode %{ 5603 __ bswapq($dst$$Register); 5604 %} 5605 ins_pipe( ialu_reg); 5606 %} 5607 5608 instruct bytes_reverse_unsigned_short(rRegI dst, rFlagsReg cr) %{ 5609 match(Set dst (ReverseBytesUS dst)); 5610 effect(KILL cr); 5611 5612 format %{ "bswapl $dst\n\t" 5613 "shrl $dst,16\n\t" %} 5614 ins_encode %{ 5615 __ bswapl($dst$$Register); 5616 __ shrl($dst$$Register, 16); 5617 %} 5618 ins_pipe( ialu_reg ); 5619 %} 5620 5621 instruct bytes_reverse_short(rRegI dst, rFlagsReg cr) %{ 5622 match(Set dst (ReverseBytesS dst)); 5623 effect(KILL cr); 5624 5625 format %{ "bswapl $dst\n\t" 5626 "sar $dst,16\n\t" %} 5627 ins_encode %{ 5628 __ bswapl($dst$$Register); 5629 __ sarl($dst$$Register, 16); 5630 %} 5631 ins_pipe( ialu_reg ); 5632 %} 5633 5634 //---------- Zeros Count Instructions ------------------------------------------ 5635 5636 instruct countLeadingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 5637 predicate(UseCountLeadingZerosInstruction); 5638 match(Set dst (CountLeadingZerosI src)); 5639 effect(KILL cr); 5640 5641 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 5642 ins_encode %{ 5643 __ lzcntl($dst$$Register, $src$$Register); 5644 %} 5645 ins_pipe(ialu_reg); 5646 %} 5647 5648 instruct countLeadingZerosI_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5649 predicate(UseCountLeadingZerosInstruction); 5650 match(Set dst (CountLeadingZerosI (LoadI src))); 5651 effect(KILL cr); 5652 ins_cost(175); 5653 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 5654 ins_encode %{ 5655 __ lzcntl($dst$$Register, $src$$Address); 5656 %} 5657 ins_pipe(ialu_reg_mem); 5658 %} 5659 5660 instruct countLeadingZerosI_bsr(rRegI dst, rRegI src, rFlagsReg cr) %{ 5661 predicate(!UseCountLeadingZerosInstruction); 5662 match(Set dst (CountLeadingZerosI src)); 5663 effect(KILL cr); 5664 5665 format %{ "bsrl $dst, $src\t# count leading zeros (int)\n\t" 5666 "jnz skip\n\t" 5667 "movl $dst, -1\n" 5668 "skip:\n\t" 5669 "negl $dst\n\t" 5670 "addl $dst, 31" %} 5671 ins_encode %{ 5672 Register Rdst = $dst$$Register; 5673 Register Rsrc = $src$$Register; 5674 Label skip; 5675 __ bsrl(Rdst, Rsrc); 5676 __ jccb(Assembler::notZero, skip); 5677 __ movl(Rdst, -1); 5678 __ bind(skip); 5679 __ negl(Rdst); 5680 __ addl(Rdst, BitsPerInt - 1); 5681 %} 5682 ins_pipe(ialu_reg); 5683 %} 5684 5685 instruct countLeadingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 5686 predicate(UseCountLeadingZerosInstruction); 5687 match(Set dst (CountLeadingZerosL src)); 5688 effect(KILL cr); 5689 5690 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 5691 ins_encode %{ 5692 __ lzcntq($dst$$Register, $src$$Register); 5693 %} 5694 ins_pipe(ialu_reg); 5695 %} 5696 5697 instruct countLeadingZerosL_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5698 predicate(UseCountLeadingZerosInstruction); 5699 match(Set dst (CountLeadingZerosL (LoadL src))); 5700 effect(KILL cr); 5701 ins_cost(175); 5702 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 5703 ins_encode %{ 5704 __ lzcntq($dst$$Register, $src$$Address); 5705 %} 5706 ins_pipe(ialu_reg_mem); 5707 %} 5708 5709 instruct countLeadingZerosL_bsr(rRegI dst, rRegL src, rFlagsReg cr) %{ 5710 predicate(!UseCountLeadingZerosInstruction); 5711 match(Set dst (CountLeadingZerosL src)); 5712 effect(KILL cr); 5713 5714 format %{ "bsrq $dst, $src\t# count leading zeros (long)\n\t" 5715 "jnz skip\n\t" 5716 "movl $dst, -1\n" 5717 "skip:\n\t" 5718 "negl $dst\n\t" 5719 "addl $dst, 63" %} 5720 ins_encode %{ 5721 Register Rdst = $dst$$Register; 5722 Register Rsrc = $src$$Register; 5723 Label skip; 5724 __ bsrq(Rdst, Rsrc); 5725 __ jccb(Assembler::notZero, skip); 5726 __ movl(Rdst, -1); 5727 __ bind(skip); 5728 __ negl(Rdst); 5729 __ addl(Rdst, BitsPerLong - 1); 5730 %} 5731 ins_pipe(ialu_reg); 5732 %} 5733 5734 instruct countTrailingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 5735 predicate(UseCountTrailingZerosInstruction); 5736 match(Set dst (CountTrailingZerosI src)); 5737 effect(KILL cr); 5738 5739 format %{ "tzcntl $dst, $src\t# count trailing zeros (int)" %} 5740 ins_encode %{ 5741 __ tzcntl($dst$$Register, $src$$Register); 5742 %} 5743 ins_pipe(ialu_reg); 5744 %} 5745 5746 instruct countTrailingZerosI_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5747 predicate(UseCountTrailingZerosInstruction); 5748 match(Set dst (CountTrailingZerosI (LoadI src))); 5749 effect(KILL cr); 5750 ins_cost(175); 5751 format %{ "tzcntl $dst, $src\t# count trailing zeros (int)" %} 5752 ins_encode %{ 5753 __ tzcntl($dst$$Register, $src$$Address); 5754 %} 5755 ins_pipe(ialu_reg_mem); 5756 %} 5757 5758 instruct countTrailingZerosI_bsf(rRegI dst, rRegI src, rFlagsReg cr) %{ 5759 predicate(!UseCountTrailingZerosInstruction); 5760 match(Set dst (CountTrailingZerosI src)); 5761 effect(KILL cr); 5762 5763 format %{ "bsfl $dst, $src\t# count trailing zeros (int)\n\t" 5764 "jnz done\n\t" 5765 "movl $dst, 32\n" 5766 "done:" %} 5767 ins_encode %{ 5768 Register Rdst = $dst$$Register; 5769 Label done; 5770 __ bsfl(Rdst, $src$$Register); 5771 __ jccb(Assembler::notZero, done); 5772 __ movl(Rdst, BitsPerInt); 5773 __ bind(done); 5774 %} 5775 ins_pipe(ialu_reg); 5776 %} 5777 5778 instruct countTrailingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 5779 predicate(UseCountTrailingZerosInstruction); 5780 match(Set dst (CountTrailingZerosL src)); 5781 effect(KILL cr); 5782 5783 format %{ "tzcntq $dst, $src\t# count trailing zeros (long)" %} 5784 ins_encode %{ 5785 __ tzcntq($dst$$Register, $src$$Register); 5786 %} 5787 ins_pipe(ialu_reg); 5788 %} 5789 5790 instruct countTrailingZerosL_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5791 predicate(UseCountTrailingZerosInstruction); 5792 match(Set dst (CountTrailingZerosL (LoadL src))); 5793 effect(KILL cr); 5794 ins_cost(175); 5795 format %{ "tzcntq $dst, $src\t# count trailing zeros (long)" %} 5796 ins_encode %{ 5797 __ tzcntq($dst$$Register, $src$$Address); 5798 %} 5799 ins_pipe(ialu_reg_mem); 5800 %} 5801 5802 instruct countTrailingZerosL_bsf(rRegI dst, rRegL src, rFlagsReg cr) %{ 5803 predicate(!UseCountTrailingZerosInstruction); 5804 match(Set dst (CountTrailingZerosL src)); 5805 effect(KILL cr); 5806 5807 format %{ "bsfq $dst, $src\t# count trailing zeros (long)\n\t" 5808 "jnz done\n\t" 5809 "movl $dst, 64\n" 5810 "done:" %} 5811 ins_encode %{ 5812 Register Rdst = $dst$$Register; 5813 Label done; 5814 __ bsfq(Rdst, $src$$Register); 5815 __ jccb(Assembler::notZero, done); 5816 __ movl(Rdst, BitsPerLong); 5817 __ bind(done); 5818 %} 5819 ins_pipe(ialu_reg); 5820 %} 5821 5822 //--------------- Reverse Operation Instructions ---------------- 5823 instruct bytes_reversebit_int(rRegI dst, rRegI src, rRegI rtmp, rFlagsReg cr) %{ 5824 predicate(!VM_Version::supports_gfni()); 5825 match(Set dst (ReverseI src)); 5826 effect(TEMP dst, TEMP rtmp, KILL cr); 5827 format %{ "reverse_int $dst $src\t! using $rtmp as TEMP" %} 5828 ins_encode %{ 5829 __ reverseI($dst$$Register, $src$$Register, xnoreg, xnoreg, $rtmp$$Register); 5830 %} 5831 ins_pipe( ialu_reg ); 5832 %} 5833 5834 instruct bytes_reversebit_int_gfni(rRegI dst, rRegI src, vlRegF xtmp1, vlRegF xtmp2, rRegL rtmp, rFlagsReg cr) %{ 5835 predicate(VM_Version::supports_gfni()); 5836 match(Set dst (ReverseI src)); 5837 effect(TEMP dst, TEMP xtmp1, TEMP xtmp2, TEMP rtmp, KILL cr); 5838 format %{ "reverse_int $dst $src\t! using $rtmp, $xtmp1 and $xtmp2 as TEMP" %} 5839 ins_encode %{ 5840 __ reverseI($dst$$Register, $src$$Register, $xtmp1$$XMMRegister, $xtmp2$$XMMRegister, $rtmp$$Register); 5841 %} 5842 ins_pipe( ialu_reg ); 5843 %} 5844 5845 instruct bytes_reversebit_long(rRegL dst, rRegL src, rRegL rtmp1, rRegL rtmp2, rFlagsReg cr) %{ 5846 predicate(!VM_Version::supports_gfni()); 5847 match(Set dst (ReverseL src)); 5848 effect(TEMP dst, TEMP rtmp1, TEMP rtmp2, KILL cr); 5849 format %{ "reverse_long $dst $src\t! using $rtmp1 and $rtmp2 as TEMP" %} 5850 ins_encode %{ 5851 __ reverseL($dst$$Register, $src$$Register, xnoreg, xnoreg, $rtmp1$$Register, $rtmp2$$Register); 5852 %} 5853 ins_pipe( ialu_reg ); 5854 %} 5855 5856 instruct bytes_reversebit_long_gfni(rRegL dst, rRegL src, vlRegD xtmp1, vlRegD xtmp2, rRegL rtmp, rFlagsReg cr) %{ 5857 predicate(VM_Version::supports_gfni()); 5858 match(Set dst (ReverseL src)); 5859 effect(TEMP dst, TEMP xtmp1, TEMP xtmp2, TEMP rtmp, KILL cr); 5860 format %{ "reverse_long $dst $src\t! using $rtmp, $xtmp1 and $xtmp2 as TEMP" %} 5861 ins_encode %{ 5862 __ reverseL($dst$$Register, $src$$Register, $xtmp1$$XMMRegister, $xtmp2$$XMMRegister, $rtmp$$Register, noreg); 5863 %} 5864 ins_pipe( ialu_reg ); 5865 %} 5866 5867 //---------- Population Count Instructions ------------------------------------- 5868 5869 instruct popCountI(rRegI dst, rRegI src, rFlagsReg cr) %{ 5870 predicate(UsePopCountInstruction); 5871 match(Set dst (PopCountI src)); 5872 effect(KILL cr); 5873 5874 format %{ "popcnt $dst, $src" %} 5875 ins_encode %{ 5876 __ popcntl($dst$$Register, $src$$Register); 5877 %} 5878 ins_pipe(ialu_reg); 5879 %} 5880 5881 instruct popCountI_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 5882 predicate(UsePopCountInstruction); 5883 match(Set dst (PopCountI (LoadI mem))); 5884 effect(KILL cr); 5885 5886 format %{ "popcnt $dst, $mem" %} 5887 ins_encode %{ 5888 __ popcntl($dst$$Register, $mem$$Address); 5889 %} 5890 ins_pipe(ialu_reg); 5891 %} 5892 5893 // Note: Long.bitCount(long) returns an int. 5894 instruct popCountL(rRegI dst, rRegL src, rFlagsReg cr) %{ 5895 predicate(UsePopCountInstruction); 5896 match(Set dst (PopCountL src)); 5897 effect(KILL cr); 5898 5899 format %{ "popcnt $dst, $src" %} 5900 ins_encode %{ 5901 __ popcntq($dst$$Register, $src$$Register); 5902 %} 5903 ins_pipe(ialu_reg); 5904 %} 5905 5906 // Note: Long.bitCount(long) returns an int. 5907 instruct popCountL_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 5908 predicate(UsePopCountInstruction); 5909 match(Set dst (PopCountL (LoadL mem))); 5910 effect(KILL cr); 5911 5912 format %{ "popcnt $dst, $mem" %} 5913 ins_encode %{ 5914 __ popcntq($dst$$Register, $mem$$Address); 5915 %} 5916 ins_pipe(ialu_reg); 5917 %} 5918 5919 5920 //----------MemBar Instructions----------------------------------------------- 5921 // Memory barrier flavors 5922 5923 instruct membar_acquire() 5924 %{ 5925 match(MemBarAcquire); 5926 match(LoadFence); 5927 ins_cost(0); 5928 5929 size(0); 5930 format %{ "MEMBAR-acquire ! (empty encoding)" %} 5931 ins_encode(); 5932 ins_pipe(empty); 5933 %} 5934 5935 instruct membar_acquire_lock() 5936 %{ 5937 match(MemBarAcquireLock); 5938 ins_cost(0); 5939 5940 size(0); 5941 format %{ "MEMBAR-acquire (prior CMPXCHG in FastLock so empty encoding)" %} 5942 ins_encode(); 5943 ins_pipe(empty); 5944 %} 5945 5946 instruct membar_release() 5947 %{ 5948 match(MemBarRelease); 5949 match(StoreFence); 5950 ins_cost(0); 5951 5952 size(0); 5953 format %{ "MEMBAR-release ! (empty encoding)" %} 5954 ins_encode(); 5955 ins_pipe(empty); 5956 %} 5957 5958 instruct membar_release_lock() 5959 %{ 5960 match(MemBarReleaseLock); 5961 ins_cost(0); 5962 5963 size(0); 5964 format %{ "MEMBAR-release (a FastUnlock follows so empty encoding)" %} 5965 ins_encode(); 5966 ins_pipe(empty); 5967 %} 5968 5969 instruct membar_volatile(rFlagsReg cr) %{ 5970 match(MemBarVolatile); 5971 effect(KILL cr); 5972 ins_cost(400); 5973 5974 format %{ 5975 $$template 5976 $$emit$$"lock addl [rsp + #0], 0\t! membar_volatile" 5977 %} 5978 ins_encode %{ 5979 __ membar(Assembler::StoreLoad); 5980 %} 5981 ins_pipe(pipe_slow); 5982 %} 5983 5984 instruct unnecessary_membar_volatile() 5985 %{ 5986 match(MemBarVolatile); 5987 predicate(Matcher::post_store_load_barrier(n)); 5988 ins_cost(0); 5989 5990 size(0); 5991 format %{ "MEMBAR-volatile (unnecessary so empty encoding)" %} 5992 ins_encode(); 5993 ins_pipe(empty); 5994 %} 5995 5996 instruct membar_storestore() %{ 5997 match(MemBarStoreStore); 5998 match(StoreStoreFence); 5999 ins_cost(0); 6000 6001 size(0); 6002 format %{ "MEMBAR-storestore (empty encoding)" %} 6003 ins_encode( ); 6004 ins_pipe(empty); 6005 %} 6006 6007 //----------Move Instructions-------------------------------------------------- 6008 6009 instruct castX2P(rRegP dst, rRegL src) 6010 %{ 6011 match(Set dst (CastX2P src)); 6012 6013 format %{ "movq $dst, $src\t# long->ptr" %} 6014 ins_encode %{ 6015 if ($dst$$reg != $src$$reg) { 6016 __ movptr($dst$$Register, $src$$Register); 6017 } 6018 %} 6019 ins_pipe(ialu_reg_reg); // XXX 6020 %} 6021 6022 instruct castP2X(rRegL dst, rRegP src) 6023 %{ 6024 match(Set dst (CastP2X src)); 6025 6026 format %{ "movq $dst, $src\t# ptr -> long" %} 6027 ins_encode %{ 6028 if ($dst$$reg != $src$$reg) { 6029 __ movptr($dst$$Register, $src$$Register); 6030 } 6031 %} 6032 ins_pipe(ialu_reg_reg); // XXX 6033 %} 6034 6035 // Convert oop into int for vectors alignment masking 6036 instruct convP2I(rRegI dst, rRegP src) 6037 %{ 6038 match(Set dst (ConvL2I (CastP2X src))); 6039 6040 format %{ "movl $dst, $src\t# ptr -> int" %} 6041 ins_encode %{ 6042 __ movl($dst$$Register, $src$$Register); 6043 %} 6044 ins_pipe(ialu_reg_reg); // XXX 6045 %} 6046 6047 // Convert compressed oop into int for vectors alignment masking 6048 // in case of 32bit oops (heap < 4Gb). 6049 instruct convN2I(rRegI dst, rRegN src) 6050 %{ 6051 predicate(CompressedOops::shift() == 0); 6052 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 6053 6054 format %{ "movl $dst, $src\t# compressed ptr -> int" %} 6055 ins_encode %{ 6056 __ movl($dst$$Register, $src$$Register); 6057 %} 6058 ins_pipe(ialu_reg_reg); // XXX 6059 %} 6060 6061 // Convert oop pointer into compressed form 6062 instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{ 6063 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 6064 match(Set dst (EncodeP src)); 6065 effect(KILL cr); 6066 format %{ "encode_heap_oop $dst,$src" %} 6067 ins_encode %{ 6068 Register s = $src$$Register; 6069 Register d = $dst$$Register; 6070 if (s != d) { 6071 __ movq(d, s); 6072 } 6073 __ encode_heap_oop(d); 6074 %} 6075 ins_pipe(ialu_reg_long); 6076 %} 6077 6078 instruct encodeHeapOop_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6079 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 6080 match(Set dst (EncodeP src)); 6081 effect(KILL cr); 6082 format %{ "encode_heap_oop_not_null $dst,$src" %} 6083 ins_encode %{ 6084 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 6085 %} 6086 ins_pipe(ialu_reg_long); 6087 %} 6088 6089 instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{ 6090 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 6091 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 6092 match(Set dst (DecodeN src)); 6093 effect(KILL cr); 6094 format %{ "decode_heap_oop $dst,$src" %} 6095 ins_encode %{ 6096 Register s = $src$$Register; 6097 Register d = $dst$$Register; 6098 if (s != d) { 6099 __ movq(d, s); 6100 } 6101 __ decode_heap_oop(d); 6102 %} 6103 ins_pipe(ialu_reg_long); 6104 %} 6105 6106 instruct decodeHeapOop_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6107 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 6108 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 6109 match(Set dst (DecodeN src)); 6110 effect(KILL cr); 6111 format %{ "decode_heap_oop_not_null $dst,$src" %} 6112 ins_encode %{ 6113 Register s = $src$$Register; 6114 Register d = $dst$$Register; 6115 if (s != d) { 6116 __ decode_heap_oop_not_null(d, s); 6117 } else { 6118 __ decode_heap_oop_not_null(d); 6119 } 6120 %} 6121 ins_pipe(ialu_reg_long); 6122 %} 6123 6124 instruct encodeKlass_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6125 match(Set dst (EncodePKlass src)); 6126 effect(TEMP dst, KILL cr); 6127 format %{ "encode_and_move_klass_not_null $dst,$src" %} 6128 ins_encode %{ 6129 __ encode_and_move_klass_not_null($dst$$Register, $src$$Register); 6130 %} 6131 ins_pipe(ialu_reg_long); 6132 %} 6133 6134 instruct decodeKlass_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6135 match(Set dst (DecodeNKlass src)); 6136 effect(TEMP dst, KILL cr); 6137 format %{ "decode_and_move_klass_not_null $dst,$src" %} 6138 ins_encode %{ 6139 __ decode_and_move_klass_not_null($dst$$Register, $src$$Register); 6140 %} 6141 ins_pipe(ialu_reg_long); 6142 %} 6143 6144 //----------Conditional Move--------------------------------------------------- 6145 // Jump 6146 // dummy instruction for generating temp registers 6147 instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{ 6148 match(Jump (LShiftL switch_val shift)); 6149 ins_cost(350); 6150 predicate(false); 6151 effect(TEMP dest); 6152 6153 format %{ "leaq $dest, [$constantaddress]\n\t" 6154 "jmp [$dest + $switch_val << $shift]\n\t" %} 6155 ins_encode %{ 6156 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6157 // to do that and the compiler is using that register as one it can allocate. 6158 // So we build it all by hand. 6159 // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant); 6160 // ArrayAddress dispatch(table, index); 6161 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant); 6162 __ lea($dest$$Register, $constantaddress); 6163 __ jmp(dispatch); 6164 %} 6165 ins_pipe(pipe_jmp); 6166 %} 6167 6168 instruct jumpXtnd_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{ 6169 match(Jump (AddL (LShiftL switch_val shift) offset)); 6170 ins_cost(350); 6171 effect(TEMP dest); 6172 6173 format %{ "leaq $dest, [$constantaddress]\n\t" 6174 "jmp [$dest + $switch_val << $shift + $offset]\n\t" %} 6175 ins_encode %{ 6176 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6177 // to do that and the compiler is using that register as one it can allocate. 6178 // So we build it all by hand. 6179 // Address index(noreg, switch_reg, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6180 // ArrayAddress dispatch(table, index); 6181 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6182 __ lea($dest$$Register, $constantaddress); 6183 __ jmp(dispatch); 6184 %} 6185 ins_pipe(pipe_jmp); 6186 %} 6187 6188 instruct jumpXtnd(rRegL switch_val, rRegI dest) %{ 6189 match(Jump switch_val); 6190 ins_cost(350); 6191 effect(TEMP dest); 6192 6193 format %{ "leaq $dest, [$constantaddress]\n\t" 6194 "jmp [$dest + $switch_val]\n\t" %} 6195 ins_encode %{ 6196 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6197 // to do that and the compiler is using that register as one it can allocate. 6198 // So we build it all by hand. 6199 // Address index(noreg, switch_reg, Address::times_1); 6200 // ArrayAddress dispatch(table, index); 6201 Address dispatch($dest$$Register, $switch_val$$Register, Address::times_1); 6202 __ lea($dest$$Register, $constantaddress); 6203 __ jmp(dispatch); 6204 %} 6205 ins_pipe(pipe_jmp); 6206 %} 6207 6208 // Conditional move 6209 instruct cmovI_imm_01(rRegI dst, immI_1 src, rFlagsReg cr, cmpOp cop) 6210 %{ 6211 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_int() == 0); 6212 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6213 6214 ins_cost(100); // XXX 6215 format %{ "setbn$cop $dst\t# signed, int" %} 6216 ins_encode %{ 6217 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6218 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6219 %} 6220 ins_pipe(ialu_reg); 6221 %} 6222 6223 instruct cmovI_reg(rRegI dst, rRegI src, rFlagsReg cr, cmpOp cop) 6224 %{ 6225 predicate(!UseAPX); 6226 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6227 6228 ins_cost(200); // XXX 6229 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6230 ins_encode %{ 6231 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6232 %} 6233 ins_pipe(pipe_cmov_reg); 6234 %} 6235 6236 instruct cmovI_reg_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr, cmpOp cop) 6237 %{ 6238 predicate(UseAPX); 6239 match(Set dst (CMoveI (Binary cop cr) (Binary src1 src2))); 6240 6241 ins_cost(200); 6242 format %{ "ecmovl$cop $dst, $src1, $src2\t# signed, int ndd" %} 6243 ins_encode %{ 6244 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6245 %} 6246 ins_pipe(pipe_cmov_reg); 6247 %} 6248 6249 instruct cmovI_imm_01U(rRegI dst, immI_1 src, rFlagsRegU cr, cmpOpU cop) 6250 %{ 6251 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_int() == 0); 6252 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6253 6254 ins_cost(100); // XXX 6255 format %{ "setbn$cop $dst\t# unsigned, int" %} 6256 ins_encode %{ 6257 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6258 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6259 %} 6260 ins_pipe(ialu_reg); 6261 %} 6262 6263 instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{ 6264 predicate(!UseAPX); 6265 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6266 6267 ins_cost(200); // XXX 6268 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6269 ins_encode %{ 6270 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6271 %} 6272 ins_pipe(pipe_cmov_reg); 6273 %} 6274 6275 instruct cmovI_regU_ndd(rRegI dst, cmpOpU cop, rFlagsRegU cr, rRegI src1, rRegI src2) %{ 6276 predicate(UseAPX); 6277 match(Set dst (CMoveI (Binary cop cr) (Binary src1 src2))); 6278 6279 ins_cost(200); 6280 format %{ "ecmovl$cop $dst, $src1, $src2\t# unsigned, int ndd" %} 6281 ins_encode %{ 6282 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6283 %} 6284 ins_pipe(pipe_cmov_reg); 6285 %} 6286 6287 instruct cmovI_imm_01UCF(rRegI dst, immI_1 src, rFlagsRegUCF cr, cmpOpUCF cop) 6288 %{ 6289 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_int() == 0); 6290 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6291 6292 ins_cost(100); // XXX 6293 format %{ "setbn$cop $dst\t# unsigned, int" %} 6294 ins_encode %{ 6295 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6296 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6297 %} 6298 ins_pipe(ialu_reg); 6299 %} 6300 6301 instruct cmovI_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6302 predicate(!UseAPX); 6303 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6304 ins_cost(200); 6305 expand %{ 6306 cmovI_regU(cop, cr, dst, src); 6307 %} 6308 %} 6309 6310 instruct cmovI_regUCF_ndd(rRegI dst, cmpOpUCF cop, rFlagsRegUCF cr, rRegI src1, rRegI src2) %{ 6311 predicate(UseAPX); 6312 match(Set dst (CMoveI (Binary cop cr) (Binary src1 src2))); 6313 ins_cost(200); 6314 format %{ "ecmovl$cop $dst, $src1, $src2\t# unsigned, int ndd" %} 6315 ins_encode %{ 6316 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6317 %} 6318 ins_pipe(pipe_cmov_reg); 6319 %} 6320 6321 instruct cmovI_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6322 predicate(!UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6323 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6324 6325 ins_cost(200); // XXX 6326 format %{ "cmovpl $dst, $src\n\t" 6327 "cmovnel $dst, $src" %} 6328 ins_encode %{ 6329 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6330 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6331 %} 6332 ins_pipe(pipe_cmov_reg); 6333 %} 6334 6335 instruct cmovI_regUCF2_ne_ndd(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegI dst, rRegI src1, rRegI src2) %{ 6336 predicate(UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6337 match(Set dst (CMoveI (Binary cop cr) (Binary src1 src2))); 6338 effect(TEMP dst); 6339 6340 ins_cost(200); 6341 format %{ "ecmovpl $dst, $src1, $src2\n\t" 6342 "cmovnel $dst, $src2" %} 6343 ins_encode %{ 6344 __ ecmovl(Assembler::parity, $dst$$Register, $src1$$Register, $src2$$Register); 6345 __ cmovl(Assembler::notEqual, $dst$$Register, $src2$$Register); 6346 %} 6347 ins_pipe(pipe_cmov_reg); 6348 %} 6349 6350 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6351 // inputs of the CMove 6352 instruct cmovI_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6353 predicate(!UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6354 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6355 effect(TEMP dst); 6356 6357 ins_cost(200); // XXX 6358 format %{ "cmovpl $dst, $src\n\t" 6359 "cmovnel $dst, $src" %} 6360 ins_encode %{ 6361 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6362 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6363 %} 6364 ins_pipe(pipe_cmov_reg); 6365 %} 6366 6367 // We need this special handling for only eq / neq comparison since NaN == NaN is false, 6368 // and parity flag bit is set if any of the operand is a NaN. 6369 instruct cmovI_regUCF2_eq_ndd(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegI dst, rRegI src1, rRegI src2) %{ 6370 predicate(UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6371 match(Set dst (CMoveI (Binary cop cr) (Binary src2 src1))); 6372 effect(TEMP dst); 6373 6374 ins_cost(200); 6375 format %{ "ecmovpl $dst, $src1, $src2\n\t" 6376 "cmovnel $dst, $src2" %} 6377 ins_encode %{ 6378 __ ecmovl(Assembler::parity, $dst$$Register, $src1$$Register, $src2$$Register); 6379 __ cmovl(Assembler::notEqual, $dst$$Register, $src2$$Register); 6380 %} 6381 ins_pipe(pipe_cmov_reg); 6382 %} 6383 6384 // Conditional move 6385 instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{ 6386 predicate(!UseAPX); 6387 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6388 6389 ins_cost(250); // XXX 6390 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6391 ins_encode %{ 6392 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6393 %} 6394 ins_pipe(pipe_cmov_mem); 6395 %} 6396 6397 // Conditional move 6398 instruct cmovI_rReg_rReg_mem_ndd(rRegI dst, cmpOp cop, rFlagsReg cr, rRegI src1, memory src2) 6399 %{ 6400 predicate(UseAPX); 6401 match(Set dst (CMoveI (Binary cop cr) (Binary src1 (LoadI src2)))); 6402 6403 ins_cost(250); 6404 format %{ "ecmovl$cop $dst, $src1, $src2\t# signed, int ndd" %} 6405 ins_encode %{ 6406 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Address); 6407 %} 6408 ins_pipe(pipe_cmov_mem); 6409 %} 6410 6411 // Conditional move 6412 instruct cmovI_memU(cmpOpU cop, rFlagsRegU cr, rRegI dst, memory src) 6413 %{ 6414 predicate(!UseAPX); 6415 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6416 6417 ins_cost(250); // XXX 6418 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6419 ins_encode %{ 6420 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6421 %} 6422 ins_pipe(pipe_cmov_mem); 6423 %} 6424 6425 instruct cmovI_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, memory src) %{ 6426 predicate(!UseAPX); 6427 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6428 ins_cost(250); 6429 expand %{ 6430 cmovI_memU(cop, cr, dst, src); 6431 %} 6432 %} 6433 6434 instruct cmovI_rReg_rReg_memU_ndd(rRegI dst, cmpOpU cop, rFlagsRegU cr, rRegI src1, memory src2) 6435 %{ 6436 predicate(UseAPX); 6437 match(Set dst (CMoveI (Binary cop cr) (Binary src1 (LoadI src2)))); 6438 6439 ins_cost(250); 6440 format %{ "ecmovl$cop $dst, $src1, $src2\t# unsigned, int ndd" %} 6441 ins_encode %{ 6442 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Address); 6443 %} 6444 ins_pipe(pipe_cmov_mem); 6445 %} 6446 6447 instruct cmovI_rReg_rReg_memUCF_ndd(rRegI dst, cmpOpUCF cop, rFlagsRegUCF cr, rRegI src1, memory src2) 6448 %{ 6449 predicate(UseAPX); 6450 match(Set dst (CMoveI (Binary cop cr) (Binary src1 (LoadI src2)))); 6451 ins_cost(250); 6452 format %{ "ecmovl$cop $dst, $src1, $src2\t# unsigned, int ndd" %} 6453 ins_encode %{ 6454 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Address); 6455 %} 6456 ins_pipe(pipe_cmov_mem); 6457 %} 6458 6459 // Conditional move 6460 instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop) 6461 %{ 6462 predicate(!UseAPX); 6463 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6464 6465 ins_cost(200); // XXX 6466 format %{ "cmovl$cop $dst, $src\t# signed, compressed ptr" %} 6467 ins_encode %{ 6468 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6469 %} 6470 ins_pipe(pipe_cmov_reg); 6471 %} 6472 6473 // Conditional move ndd 6474 instruct cmovN_reg_ndd(rRegN dst, rRegN src1, rRegN src2, rFlagsReg cr, cmpOp cop) 6475 %{ 6476 predicate(UseAPX); 6477 match(Set dst (CMoveN (Binary cop cr) (Binary src1 src2))); 6478 6479 ins_cost(200); 6480 format %{ "ecmovl$cop $dst, $src1, $src2\t# signed, compressed ptr ndd" %} 6481 ins_encode %{ 6482 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6483 %} 6484 ins_pipe(pipe_cmov_reg); 6485 %} 6486 6487 // Conditional move 6488 instruct cmovN_regU(cmpOpU cop, rFlagsRegU cr, rRegN dst, rRegN src) 6489 %{ 6490 predicate(!UseAPX); 6491 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6492 6493 ins_cost(200); // XXX 6494 format %{ "cmovl$cop $dst, $src\t# unsigned, compressed ptr" %} 6495 ins_encode %{ 6496 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6497 %} 6498 ins_pipe(pipe_cmov_reg); 6499 %} 6500 6501 instruct cmovN_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6502 predicate(!UseAPX); 6503 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6504 ins_cost(200); 6505 expand %{ 6506 cmovN_regU(cop, cr, dst, src); 6507 %} 6508 %} 6509 6510 // Conditional move ndd 6511 instruct cmovN_regU_ndd(rRegN dst, cmpOpU cop, rFlagsRegU cr, rRegN src1, rRegN src2) 6512 %{ 6513 predicate(UseAPX); 6514 match(Set dst (CMoveN (Binary cop cr) (Binary src1 src2))); 6515 6516 ins_cost(200); 6517 format %{ "ecmovl$cop $dst, $src1, $src2\t# unsigned, compressed ptr ndd" %} 6518 ins_encode %{ 6519 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6520 %} 6521 ins_pipe(pipe_cmov_reg); 6522 %} 6523 6524 instruct cmovN_regUCF_ndd(rRegN dst, cmpOpUCF cop, rFlagsRegUCF cr, rRegN src1, rRegN src2) %{ 6525 predicate(UseAPX); 6526 match(Set dst (CMoveN (Binary cop cr) (Binary src1 src2))); 6527 ins_cost(200); 6528 format %{ "ecmovl$cop $dst, $src1, $src2\t# unsigned, compressed ptr ndd" %} 6529 ins_encode %{ 6530 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6531 %} 6532 ins_pipe(pipe_cmov_reg); 6533 %} 6534 6535 instruct cmovN_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6536 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6537 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6538 6539 ins_cost(200); // XXX 6540 format %{ "cmovpl $dst, $src\n\t" 6541 "cmovnel $dst, $src" %} 6542 ins_encode %{ 6543 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6544 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6545 %} 6546 ins_pipe(pipe_cmov_reg); 6547 %} 6548 6549 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6550 // inputs of the CMove 6551 instruct cmovN_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6552 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6553 match(Set dst (CMoveN (Binary cop cr) (Binary src dst))); 6554 6555 ins_cost(200); // XXX 6556 format %{ "cmovpl $dst, $src\n\t" 6557 "cmovnel $dst, $src" %} 6558 ins_encode %{ 6559 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6560 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6561 %} 6562 ins_pipe(pipe_cmov_reg); 6563 %} 6564 6565 // Conditional move 6566 instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop) 6567 %{ 6568 predicate(!UseAPX); 6569 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6570 6571 ins_cost(200); // XXX 6572 format %{ "cmovq$cop $dst, $src\t# signed, ptr" %} 6573 ins_encode %{ 6574 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6575 %} 6576 ins_pipe(pipe_cmov_reg); // XXX 6577 %} 6578 6579 // Conditional move ndd 6580 instruct cmovP_reg_ndd(rRegP dst, rRegP src1, rRegP src2, rFlagsReg cr, cmpOp cop) 6581 %{ 6582 predicate(UseAPX); 6583 match(Set dst (CMoveP (Binary cop cr) (Binary src1 src2))); 6584 6585 ins_cost(200); 6586 format %{ "ecmovq$cop $dst, $src1, $src2\t# signed, ptr ndd" %} 6587 ins_encode %{ 6588 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6589 %} 6590 ins_pipe(pipe_cmov_reg); 6591 %} 6592 6593 // Conditional move 6594 instruct cmovP_regU(cmpOpU cop, rFlagsRegU cr, rRegP dst, rRegP src) 6595 %{ 6596 predicate(!UseAPX); 6597 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6598 6599 ins_cost(200); // XXX 6600 format %{ "cmovq$cop $dst, $src\t# unsigned, ptr" %} 6601 ins_encode %{ 6602 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6603 %} 6604 ins_pipe(pipe_cmov_reg); // XXX 6605 %} 6606 6607 // Conditional move ndd 6608 instruct cmovP_regU_ndd(rRegP dst, cmpOpU cop, rFlagsRegU cr, rRegP src1, rRegP src2) 6609 %{ 6610 predicate(UseAPX); 6611 match(Set dst (CMoveP (Binary cop cr) (Binary src1 src2))); 6612 6613 ins_cost(200); 6614 format %{ "ecmovq$cop $dst, $src1, $src2\t# unsigned, ptr ndd" %} 6615 ins_encode %{ 6616 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6617 %} 6618 ins_pipe(pipe_cmov_reg); 6619 %} 6620 6621 instruct cmovP_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6622 predicate(!UseAPX); 6623 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6624 ins_cost(200); 6625 expand %{ 6626 cmovP_regU(cop, cr, dst, src); 6627 %} 6628 %} 6629 6630 instruct cmovP_regUCF_ndd(rRegP dst, cmpOpUCF cop, rFlagsRegUCF cr, rRegP src1, rRegP src2) %{ 6631 predicate(UseAPX); 6632 match(Set dst (CMoveP (Binary cop cr) (Binary src1 src2))); 6633 ins_cost(200); 6634 format %{ "ecmovq$cop $dst, $src1, $src2\t# unsigned, ptr ndd" %} 6635 ins_encode %{ 6636 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6637 %} 6638 ins_pipe(pipe_cmov_reg); 6639 %} 6640 6641 instruct cmovP_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6642 predicate(!UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6643 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6644 6645 ins_cost(200); // XXX 6646 format %{ "cmovpq $dst, $src\n\t" 6647 "cmovneq $dst, $src" %} 6648 ins_encode %{ 6649 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6650 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6651 %} 6652 ins_pipe(pipe_cmov_reg); 6653 %} 6654 6655 instruct cmovP_regUCF2_ne_ndd(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegP dst, rRegP src1, rRegP src2) %{ 6656 predicate(UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6657 match(Set dst (CMoveP (Binary cop cr) (Binary src1 src2))); 6658 effect(TEMP dst); 6659 6660 ins_cost(200); 6661 format %{ "ecmovpq $dst, $src1, $src2\n\t" 6662 "cmovneq $dst, $src2" %} 6663 ins_encode %{ 6664 __ ecmovq(Assembler::parity, $dst$$Register, $src1$$Register, $src2$$Register); 6665 __ cmovq(Assembler::notEqual, $dst$$Register, $src2$$Register); 6666 %} 6667 ins_pipe(pipe_cmov_reg); 6668 %} 6669 6670 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6671 // inputs of the CMove 6672 instruct cmovP_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6673 predicate(!UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6674 match(Set dst (CMoveP (Binary cop cr) (Binary src dst))); 6675 6676 ins_cost(200); // XXX 6677 format %{ "cmovpq $dst, $src\n\t" 6678 "cmovneq $dst, $src" %} 6679 ins_encode %{ 6680 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6681 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6682 %} 6683 ins_pipe(pipe_cmov_reg); 6684 %} 6685 6686 instruct cmovP_regUCF2_eq_ndd(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegP dst, rRegP src1, rRegP src2) %{ 6687 predicate(UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6688 match(Set dst (CMoveP (Binary cop cr) (Binary src2 src1))); 6689 effect(TEMP dst); 6690 6691 ins_cost(200); 6692 format %{ "ecmovpq $dst, $src1, $src2\n\t" 6693 "cmovneq $dst, $src2" %} 6694 ins_encode %{ 6695 __ ecmovq(Assembler::parity, $dst$$Register, $src1$$Register, $src2$$Register); 6696 __ cmovq(Assembler::notEqual, $dst$$Register, $src2$$Register); 6697 %} 6698 ins_pipe(pipe_cmov_reg); 6699 %} 6700 6701 instruct cmovL_imm_01(rRegL dst, immL1 src, rFlagsReg cr, cmpOp cop) 6702 %{ 6703 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_long() == 0); 6704 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6705 6706 ins_cost(100); // XXX 6707 format %{ "setbn$cop $dst\t# signed, long" %} 6708 ins_encode %{ 6709 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6710 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6711 %} 6712 ins_pipe(ialu_reg); 6713 %} 6714 6715 instruct cmovL_reg(cmpOp cop, rFlagsReg cr, rRegL dst, rRegL src) 6716 %{ 6717 predicate(!UseAPX); 6718 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6719 6720 ins_cost(200); // XXX 6721 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6722 ins_encode %{ 6723 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6724 %} 6725 ins_pipe(pipe_cmov_reg); // XXX 6726 %} 6727 6728 instruct cmovL_reg_ndd(rRegL dst, cmpOp cop, rFlagsReg cr, rRegL src1, rRegL src2) 6729 %{ 6730 predicate(UseAPX); 6731 match(Set dst (CMoveL (Binary cop cr) (Binary src1 src2))); 6732 6733 ins_cost(200); 6734 format %{ "ecmovq$cop $dst, $src1, $src2\t# signed, long ndd" %} 6735 ins_encode %{ 6736 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6737 %} 6738 ins_pipe(pipe_cmov_reg); 6739 %} 6740 6741 instruct cmovL_mem(cmpOp cop, rFlagsReg cr, rRegL dst, memory src) 6742 %{ 6743 predicate(!UseAPX); 6744 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6745 6746 ins_cost(200); // XXX 6747 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6748 ins_encode %{ 6749 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6750 %} 6751 ins_pipe(pipe_cmov_mem); // XXX 6752 %} 6753 6754 instruct cmovL_rReg_rReg_mem_ndd(rRegL dst, cmpOp cop, rFlagsReg cr, rRegL src1, memory src2) 6755 %{ 6756 predicate(UseAPX); 6757 match(Set dst (CMoveL (Binary cop cr) (Binary src1 (LoadL src2)))); 6758 6759 ins_cost(200); 6760 format %{ "ecmovq$cop $dst, $src1, $src2\t# signed, long ndd" %} 6761 ins_encode %{ 6762 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Address); 6763 %} 6764 ins_pipe(pipe_cmov_mem); 6765 %} 6766 6767 instruct cmovL_imm_01U(rRegL dst, immL1 src, rFlagsRegU cr, cmpOpU cop) 6768 %{ 6769 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_long() == 0); 6770 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6771 6772 ins_cost(100); // XXX 6773 format %{ "setbn$cop $dst\t# unsigned, long" %} 6774 ins_encode %{ 6775 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6776 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6777 %} 6778 ins_pipe(ialu_reg); 6779 %} 6780 6781 instruct cmovL_regU(cmpOpU cop, rFlagsRegU cr, rRegL dst, rRegL src) 6782 %{ 6783 predicate(!UseAPX); 6784 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6785 6786 ins_cost(200); // XXX 6787 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 6788 ins_encode %{ 6789 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6790 %} 6791 ins_pipe(pipe_cmov_reg); // XXX 6792 %} 6793 6794 instruct cmovL_regU_ndd(rRegL dst, cmpOpU cop, rFlagsRegU cr, rRegL src1, rRegL src2) 6795 %{ 6796 predicate(UseAPX); 6797 match(Set dst (CMoveL (Binary cop cr) (Binary src1 src2))); 6798 6799 ins_cost(200); 6800 format %{ "ecmovq$cop $dst, $src1, $src2\t# unsigned, long ndd" %} 6801 ins_encode %{ 6802 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6803 %} 6804 ins_pipe(pipe_cmov_reg); 6805 %} 6806 6807 instruct cmovL_imm_01UCF(rRegL dst, immL1 src, rFlagsRegUCF cr, cmpOpUCF cop) 6808 %{ 6809 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_long() == 0); 6810 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6811 6812 ins_cost(100); // XXX 6813 format %{ "setbn$cop $dst\t# unsigned, long" %} 6814 ins_encode %{ 6815 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6816 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6817 %} 6818 ins_pipe(ialu_reg); 6819 %} 6820 6821 instruct cmovL_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6822 predicate(!UseAPX); 6823 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6824 ins_cost(200); 6825 expand %{ 6826 cmovL_regU(cop, cr, dst, src); 6827 %} 6828 %} 6829 6830 instruct cmovL_regUCF_ndd(rRegL dst, cmpOpUCF cop, rFlagsRegUCF cr, rRegL src1, rRegL src2) 6831 %{ 6832 predicate(UseAPX); 6833 match(Set dst (CMoveL (Binary cop cr) (Binary src1 src2))); 6834 ins_cost(200); 6835 format %{ "ecmovq$cop $dst, $src1, $src2\t# unsigned, long ndd" %} 6836 ins_encode %{ 6837 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6838 %} 6839 ins_pipe(pipe_cmov_reg); 6840 %} 6841 6842 instruct cmovL_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6843 predicate(!UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6844 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6845 6846 ins_cost(200); // XXX 6847 format %{ "cmovpq $dst, $src\n\t" 6848 "cmovneq $dst, $src" %} 6849 ins_encode %{ 6850 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6851 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6852 %} 6853 ins_pipe(pipe_cmov_reg); 6854 %} 6855 6856 instruct cmovL_regUCF2_ne_ndd(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegL dst, rRegL src1, rRegL src2) %{ 6857 predicate(UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6858 match(Set dst (CMoveL (Binary cop cr) (Binary src1 src2))); 6859 effect(TEMP dst); 6860 6861 ins_cost(200); 6862 format %{ "ecmovpq $dst, $src1, $src2\n\t" 6863 "cmovneq $dst, $src2" %} 6864 ins_encode %{ 6865 __ ecmovq(Assembler::parity, $dst$$Register, $src1$$Register, $src2$$Register); 6866 __ cmovq(Assembler::notEqual, $dst$$Register, $src2$$Register); 6867 %} 6868 ins_pipe(pipe_cmov_reg); 6869 %} 6870 6871 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6872 // inputs of the CMove 6873 instruct cmovL_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6874 predicate(!UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6875 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6876 6877 ins_cost(200); // XXX 6878 format %{ "cmovpq $dst, $src\n\t" 6879 "cmovneq $dst, $src" %} 6880 ins_encode %{ 6881 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6882 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6883 %} 6884 ins_pipe(pipe_cmov_reg); 6885 %} 6886 6887 instruct cmovL_regUCF2_eq_ndd(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegL dst, rRegL src1, rRegL src2) %{ 6888 predicate(UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6889 match(Set dst (CMoveL (Binary cop cr) (Binary src2 src1))); 6890 effect(TEMP dst); 6891 6892 ins_cost(200); 6893 format %{ "ecmovpq $dst, $src1, $src2\n\t" 6894 "cmovneq $dst, $src2" %} 6895 ins_encode %{ 6896 __ ecmovq(Assembler::parity, $dst$$Register, $src1$$Register, $src2$$Register); 6897 __ cmovq(Assembler::notEqual, $dst$$Register, $src2$$Register); 6898 %} 6899 ins_pipe(pipe_cmov_reg); 6900 %} 6901 6902 instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src) 6903 %{ 6904 predicate(!UseAPX); 6905 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6906 6907 ins_cost(200); // XXX 6908 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 6909 ins_encode %{ 6910 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6911 %} 6912 ins_pipe(pipe_cmov_mem); // XXX 6913 %} 6914 6915 instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{ 6916 predicate(!UseAPX); 6917 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6918 ins_cost(200); 6919 expand %{ 6920 cmovL_memU(cop, cr, dst, src); 6921 %} 6922 %} 6923 6924 instruct cmovL_rReg_rReg_memU_ndd(rRegL dst, cmpOpU cop, rFlagsRegU cr, rRegL src1, memory src2) 6925 %{ 6926 predicate(UseAPX); 6927 match(Set dst (CMoveL (Binary cop cr) (Binary src1 (LoadL src2)))); 6928 6929 ins_cost(200); 6930 format %{ "ecmovq$cop $dst, $src1, $src2\t# unsigned, long ndd" %} 6931 ins_encode %{ 6932 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Address); 6933 %} 6934 ins_pipe(pipe_cmov_mem); 6935 %} 6936 6937 instruct cmovL_rReg_rReg_memUCF_ndd(rRegL dst, cmpOpUCF cop, rFlagsRegUCF cr, rRegL src1, memory src2) 6938 %{ 6939 predicate(UseAPX); 6940 match(Set dst (CMoveL (Binary cop cr) (Binary src1 (LoadL src2)))); 6941 ins_cost(200); 6942 format %{ "ecmovq$cop $dst, $src1, $src2\t# unsigned, long ndd" %} 6943 ins_encode %{ 6944 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Address); 6945 %} 6946 ins_pipe(pipe_cmov_mem); 6947 %} 6948 6949 instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src) 6950 %{ 6951 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6952 6953 ins_cost(200); // XXX 6954 format %{ "jn$cop skip\t# signed cmove float\n\t" 6955 "movss $dst, $src\n" 6956 "skip:" %} 6957 ins_encode %{ 6958 Label Lskip; 6959 // Invert sense of branch from sense of CMOV 6960 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6961 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 6962 __ bind(Lskip); 6963 %} 6964 ins_pipe(pipe_slow); 6965 %} 6966 6967 instruct cmovF_regU(cmpOpU cop, rFlagsRegU cr, regF dst, regF src) 6968 %{ 6969 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6970 6971 ins_cost(200); // XXX 6972 format %{ "jn$cop skip\t# unsigned cmove float\n\t" 6973 "movss $dst, $src\n" 6974 "skip:" %} 6975 ins_encode %{ 6976 Label Lskip; 6977 // Invert sense of branch from sense of CMOV 6978 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6979 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 6980 __ bind(Lskip); 6981 %} 6982 ins_pipe(pipe_slow); 6983 %} 6984 6985 instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{ 6986 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6987 ins_cost(200); 6988 expand %{ 6989 cmovF_regU(cop, cr, dst, src); 6990 %} 6991 %} 6992 6993 instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src) 6994 %{ 6995 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6996 6997 ins_cost(200); // XXX 6998 format %{ "jn$cop skip\t# signed cmove double\n\t" 6999 "movsd $dst, $src\n" 7000 "skip:" %} 7001 ins_encode %{ 7002 Label Lskip; 7003 // Invert sense of branch from sense of CMOV 7004 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7005 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 7006 __ bind(Lskip); 7007 %} 7008 ins_pipe(pipe_slow); 7009 %} 7010 7011 instruct cmovD_regU(cmpOpU cop, rFlagsRegU cr, regD dst, regD src) 7012 %{ 7013 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7014 7015 ins_cost(200); // XXX 7016 format %{ "jn$cop skip\t# unsigned cmove double\n\t" 7017 "movsd $dst, $src\n" 7018 "skip:" %} 7019 ins_encode %{ 7020 Label Lskip; 7021 // Invert sense of branch from sense of CMOV 7022 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7023 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 7024 __ bind(Lskip); 7025 %} 7026 ins_pipe(pipe_slow); 7027 %} 7028 7029 instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{ 7030 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7031 ins_cost(200); 7032 expand %{ 7033 cmovD_regU(cop, cr, dst, src); 7034 %} 7035 %} 7036 7037 //----------Arithmetic Instructions-------------------------------------------- 7038 //----------Addition Instructions---------------------------------------------- 7039 7040 instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7041 %{ 7042 predicate(!UseAPX); 7043 match(Set dst (AddI dst src)); 7044 effect(KILL cr); 7045 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 7046 format %{ "addl $dst, $src\t# int" %} 7047 ins_encode %{ 7048 __ addl($dst$$Register, $src$$Register); 7049 %} 7050 ins_pipe(ialu_reg_reg); 7051 %} 7052 7053 instruct addI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr) 7054 %{ 7055 predicate(UseAPX); 7056 match(Set dst (AddI src1 src2)); 7057 effect(KILL cr); 7058 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); 7059 7060 format %{ "eaddl $dst, $src1, $src2\t# int ndd" %} 7061 ins_encode %{ 7062 __ eaddl($dst$$Register, $src1$$Register, $src2$$Register, false); 7063 %} 7064 ins_pipe(ialu_reg_reg); 7065 %} 7066 7067 instruct addI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 7068 %{ 7069 predicate(!UseAPX); 7070 match(Set dst (AddI dst src)); 7071 effect(KILL cr); 7072 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 7073 7074 format %{ "addl $dst, $src\t# int" %} 7075 ins_encode %{ 7076 __ addl($dst$$Register, $src$$constant); 7077 %} 7078 ins_pipe( ialu_reg ); 7079 %} 7080 7081 instruct addI_rReg_rReg_imm_ndd(rRegI dst, rRegI src1, immI src2, rFlagsReg cr) 7082 %{ 7083 predicate(UseAPX); 7084 match(Set dst (AddI src1 src2)); 7085 effect(KILL cr); 7086 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); 7087 7088 format %{ "eaddl $dst, $src1, $src2\t# int ndd" %} 7089 ins_encode %{ 7090 __ eaddl($dst$$Register, $src1$$Register, $src2$$constant, false); 7091 %} 7092 ins_pipe( ialu_reg ); 7093 %} 7094 7095 instruct addI_rReg_mem_imm_ndd(rRegI dst, memory src1, immI src2, rFlagsReg cr) 7096 %{ 7097 predicate(UseAPX); 7098 match(Set dst (AddI (LoadI src1) src2)); 7099 effect(KILL cr); 7100 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); 7101 7102 format %{ "eaddl $dst, $src1, $src2\t# int ndd" %} 7103 ins_encode %{ 7104 __ eaddl($dst$$Register, $src1$$Address, $src2$$constant, false); 7105 %} 7106 ins_pipe( ialu_reg ); 7107 %} 7108 7109 instruct addI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 7110 %{ 7111 predicate(!UseAPX); 7112 match(Set dst (AddI dst (LoadI src))); 7113 effect(KILL cr); 7114 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); 7115 7116 ins_cost(150); // XXX 7117 format %{ "addl $dst, $src\t# int" %} 7118 ins_encode %{ 7119 __ addl($dst$$Register, $src$$Address); 7120 %} 7121 ins_pipe(ialu_reg_mem); 7122 %} 7123 7124 instruct addI_rReg_rReg_mem_ndd(rRegI dst, rRegI src1, memory src2, rFlagsReg cr) 7125 %{ 7126 predicate(UseAPX); 7127 match(Set dst (AddI src1 (LoadI src2))); 7128 effect(KILL cr); 7129 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); 7130 7131 ins_cost(150); 7132 format %{ "eaddl $dst, $src1, $src2\t# int ndd" %} 7133 ins_encode %{ 7134 __ eaddl($dst$$Register, $src1$$Register, $src2$$Address, false); 7135 %} 7136 ins_pipe(ialu_reg_mem); 7137 %} 7138 7139 instruct addI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 7140 %{ 7141 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7142 effect(KILL cr); 7143 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); 7144 7145 ins_cost(150); // XXX 7146 format %{ "addl $dst, $src\t# int" %} 7147 ins_encode %{ 7148 __ addl($dst$$Address, $src$$Register); 7149 %} 7150 ins_pipe(ialu_mem_reg); 7151 %} 7152 7153 instruct addI_mem_imm(memory dst, immI src, rFlagsReg cr) 7154 %{ 7155 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7156 effect(KILL cr); 7157 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); 7158 7159 7160 ins_cost(125); // XXX 7161 format %{ "addl $dst, $src\t# int" %} 7162 ins_encode %{ 7163 __ addl($dst$$Address, $src$$constant); 7164 %} 7165 ins_pipe(ialu_mem_imm); 7166 %} 7167 7168 instruct incI_rReg(rRegI dst, immI_1 src, rFlagsReg cr) 7169 %{ 7170 predicate(!UseAPX && UseIncDec); 7171 match(Set dst (AddI dst src)); 7172 effect(KILL cr); 7173 7174 format %{ "incl $dst\t# int" %} 7175 ins_encode %{ 7176 __ incrementl($dst$$Register); 7177 %} 7178 ins_pipe(ialu_reg); 7179 %} 7180 7181 instruct incI_rReg_ndd(rRegI dst, rRegI src, immI_1 val, rFlagsReg cr) 7182 %{ 7183 predicate(UseAPX && UseIncDec); 7184 match(Set dst (AddI src val)); 7185 effect(KILL cr); 7186 7187 format %{ "eincl $dst, $src\t# int ndd" %} 7188 ins_encode %{ 7189 __ eincl($dst$$Register, $src$$Register, false); 7190 %} 7191 ins_pipe(ialu_reg); 7192 %} 7193 7194 instruct incI_rReg_mem_ndd(rRegI dst, memory src, immI_1 val, rFlagsReg cr) 7195 %{ 7196 predicate(UseAPX && UseIncDec); 7197 match(Set dst (AddI (LoadI src) val)); 7198 effect(KILL cr); 7199 7200 format %{ "eincl $dst, $src\t# int ndd" %} 7201 ins_encode %{ 7202 __ eincl($dst$$Register, $src$$Address, false); 7203 %} 7204 ins_pipe(ialu_reg); 7205 %} 7206 7207 instruct incI_mem(memory dst, immI_1 src, rFlagsReg cr) 7208 %{ 7209 predicate(UseIncDec); 7210 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7211 effect(KILL cr); 7212 7213 ins_cost(125); // XXX 7214 format %{ "incl $dst\t# int" %} 7215 ins_encode %{ 7216 __ incrementl($dst$$Address); 7217 %} 7218 ins_pipe(ialu_mem_imm); 7219 %} 7220 7221 // XXX why does that use AddI 7222 instruct decI_rReg(rRegI dst, immI_M1 src, rFlagsReg cr) 7223 %{ 7224 predicate(!UseAPX && UseIncDec); 7225 match(Set dst (AddI dst src)); 7226 effect(KILL cr); 7227 7228 format %{ "decl $dst\t# int" %} 7229 ins_encode %{ 7230 __ decrementl($dst$$Register); 7231 %} 7232 ins_pipe(ialu_reg); 7233 %} 7234 7235 instruct decI_rReg_ndd(rRegI dst, rRegI src, immI_M1 val, rFlagsReg cr) 7236 %{ 7237 predicate(UseAPX && UseIncDec); 7238 match(Set dst (AddI src val)); 7239 effect(KILL cr); 7240 7241 format %{ "edecl $dst, $src\t# int ndd" %} 7242 ins_encode %{ 7243 __ edecl($dst$$Register, $src$$Register, false); 7244 %} 7245 ins_pipe(ialu_reg); 7246 %} 7247 7248 instruct decI_rReg_mem_ndd(rRegI dst, memory src, immI_M1 val, rFlagsReg cr) 7249 %{ 7250 predicate(UseAPX && UseIncDec); 7251 match(Set dst (AddI (LoadI src) val)); 7252 effect(KILL cr); 7253 7254 format %{ "edecl $dst, $src\t# int ndd" %} 7255 ins_encode %{ 7256 __ edecl($dst$$Register, $src$$Address, false); 7257 %} 7258 ins_pipe(ialu_reg); 7259 %} 7260 7261 // XXX why does that use AddI 7262 instruct decI_mem(memory dst, immI_M1 src, rFlagsReg cr) 7263 %{ 7264 predicate(UseIncDec); 7265 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7266 effect(KILL cr); 7267 7268 ins_cost(125); // XXX 7269 format %{ "decl $dst\t# int" %} 7270 ins_encode %{ 7271 __ decrementl($dst$$Address); 7272 %} 7273 ins_pipe(ialu_mem_imm); 7274 %} 7275 7276 instruct leaI_rReg_immI2_immI(rRegI dst, rRegI index, immI2 scale, immI disp) 7277 %{ 7278 predicate(VM_Version::supports_fast_2op_lea()); 7279 match(Set dst (AddI (LShiftI index scale) disp)); 7280 7281 format %{ "leal $dst, [$index << $scale + $disp]\t# int" %} 7282 ins_encode %{ 7283 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 7284 __ leal($dst$$Register, Address(noreg, $index$$Register, scale, $disp$$constant)); 7285 %} 7286 ins_pipe(ialu_reg_reg); 7287 %} 7288 7289 instruct leaI_rReg_rReg_immI(rRegI dst, rRegI base, rRegI index, immI disp) 7290 %{ 7291 predicate(VM_Version::supports_fast_3op_lea()); 7292 match(Set dst (AddI (AddI base index) disp)); 7293 7294 format %{ "leal $dst, [$base + $index + $disp]\t# int" %} 7295 ins_encode %{ 7296 __ leal($dst$$Register, Address($base$$Register, $index$$Register, Address::times_1, $disp$$constant)); 7297 %} 7298 ins_pipe(ialu_reg_reg); 7299 %} 7300 7301 instruct leaI_rReg_rReg_immI2(rRegI dst, no_rbp_r13_RegI base, rRegI index, immI2 scale) 7302 %{ 7303 predicate(VM_Version::supports_fast_2op_lea()); 7304 match(Set dst (AddI base (LShiftI index scale))); 7305 7306 format %{ "leal $dst, [$base + $index << $scale]\t# int" %} 7307 ins_encode %{ 7308 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 7309 __ leal($dst$$Register, Address($base$$Register, $index$$Register, scale)); 7310 %} 7311 ins_pipe(ialu_reg_reg); 7312 %} 7313 7314 instruct leaI_rReg_rReg_immI2_immI(rRegI dst, rRegI base, rRegI index, immI2 scale, immI disp) 7315 %{ 7316 predicate(VM_Version::supports_fast_3op_lea()); 7317 match(Set dst (AddI (AddI base (LShiftI index scale)) disp)); 7318 7319 format %{ "leal $dst, [$base + $index << $scale + $disp]\t# int" %} 7320 ins_encode %{ 7321 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 7322 __ leal($dst$$Register, Address($base$$Register, $index$$Register, scale, $disp$$constant)); 7323 %} 7324 ins_pipe(ialu_reg_reg); 7325 %} 7326 7327 instruct addL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7328 %{ 7329 predicate(!UseAPX); 7330 match(Set dst (AddL dst src)); 7331 effect(KILL cr); 7332 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 7333 7334 format %{ "addq $dst, $src\t# long" %} 7335 ins_encode %{ 7336 __ addq($dst$$Register, $src$$Register); 7337 %} 7338 ins_pipe(ialu_reg_reg); 7339 %} 7340 7341 instruct addL_rReg_ndd(rRegL dst, rRegL src1, rRegL src2, rFlagsReg cr) 7342 %{ 7343 predicate(UseAPX); 7344 match(Set dst (AddL src1 src2)); 7345 effect(KILL cr); 7346 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 7347 7348 format %{ "eaddq $dst, $src1, $src2\t# long ndd" %} 7349 ins_encode %{ 7350 __ eaddq($dst$$Register, $src1$$Register, $src2$$Register, false); 7351 %} 7352 ins_pipe(ialu_reg_reg); 7353 %} 7354 7355 instruct addL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 7356 %{ 7357 predicate(!UseAPX); 7358 match(Set dst (AddL dst src)); 7359 effect(KILL cr); 7360 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 7361 7362 format %{ "addq $dst, $src\t# long" %} 7363 ins_encode %{ 7364 __ addq($dst$$Register, $src$$constant); 7365 %} 7366 ins_pipe( ialu_reg ); 7367 %} 7368 7369 instruct addL_rReg_rReg_imm_ndd(rRegL dst, rRegL src1, immL32 src2, rFlagsReg cr) 7370 %{ 7371 predicate(UseAPX); 7372 match(Set dst (AddL src1 src2)); 7373 effect(KILL cr); 7374 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); 7375 7376 format %{ "eaddq $dst, $src1, $src2\t# long ndd" %} 7377 ins_encode %{ 7378 __ eaddq($dst$$Register, $src1$$Register, $src2$$constant, false); 7379 %} 7380 ins_pipe( ialu_reg ); 7381 %} 7382 7383 instruct addL_rReg_mem_imm_ndd(rRegL dst, memory src1, immL32 src2, rFlagsReg cr) 7384 %{ 7385 predicate(UseAPX); 7386 match(Set dst (AddL (LoadL src1) src2)); 7387 effect(KILL cr); 7388 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); 7389 7390 format %{ "eaddq $dst, $src1, $src2\t# long ndd" %} 7391 ins_encode %{ 7392 __ eaddq($dst$$Register, $src1$$Address, $src2$$constant, false); 7393 %} 7394 ins_pipe( ialu_reg ); 7395 %} 7396 7397 instruct addL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 7398 %{ 7399 predicate(!UseAPX); 7400 match(Set dst (AddL dst (LoadL src))); 7401 effect(KILL cr); 7402 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); 7403 7404 ins_cost(150); // XXX 7405 format %{ "addq $dst, $src\t# long" %} 7406 ins_encode %{ 7407 __ addq($dst$$Register, $src$$Address); 7408 %} 7409 ins_pipe(ialu_reg_mem); 7410 %} 7411 7412 instruct addL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr) 7413 %{ 7414 predicate(UseAPX); 7415 match(Set dst (AddL src1 (LoadL src2))); 7416 effect(KILL cr); 7417 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); 7418 7419 ins_cost(150); 7420 format %{ "eaddq $dst, $src1, $src2\t# long ndd" %} 7421 ins_encode %{ 7422 __ eaddq($dst$$Register, $src1$$Register, $src2$$Address, false); 7423 %} 7424 ins_pipe(ialu_reg_mem); 7425 %} 7426 7427 instruct addL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 7428 %{ 7429 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7430 effect(KILL cr); 7431 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); 7432 7433 ins_cost(150); // XXX 7434 format %{ "addq $dst, $src\t# long" %} 7435 ins_encode %{ 7436 __ addq($dst$$Address, $src$$Register); 7437 %} 7438 ins_pipe(ialu_mem_reg); 7439 %} 7440 7441 instruct addL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 7442 %{ 7443 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7444 effect(KILL cr); 7445 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); 7446 7447 ins_cost(125); // XXX 7448 format %{ "addq $dst, $src\t# long" %} 7449 ins_encode %{ 7450 __ addq($dst$$Address, $src$$constant); 7451 %} 7452 ins_pipe(ialu_mem_imm); 7453 %} 7454 7455 instruct incL_rReg(rRegL dst, immL1 src, rFlagsReg cr) 7456 %{ 7457 predicate(!UseAPX && UseIncDec); 7458 match(Set dst (AddL dst src)); 7459 effect(KILL cr); 7460 7461 format %{ "incq $dst\t# long" %} 7462 ins_encode %{ 7463 __ incrementq($dst$$Register); 7464 %} 7465 ins_pipe(ialu_reg); 7466 %} 7467 7468 instruct incL_rReg_ndd(rRegL dst, rRegI src, immL1 val, rFlagsReg cr) 7469 %{ 7470 predicate(UseAPX && UseIncDec); 7471 match(Set dst (AddL src val)); 7472 effect(KILL cr); 7473 7474 format %{ "eincq $dst, $src\t# long ndd" %} 7475 ins_encode %{ 7476 __ eincq($dst$$Register, $src$$Register, false); 7477 %} 7478 ins_pipe(ialu_reg); 7479 %} 7480 7481 instruct incL_rReg_mem_ndd(rRegL dst, memory src, immL1 val, rFlagsReg cr) 7482 %{ 7483 predicate(UseAPX && UseIncDec); 7484 match(Set dst (AddL (LoadL src) val)); 7485 effect(KILL cr); 7486 7487 format %{ "eincq $dst, $src\t# long ndd" %} 7488 ins_encode %{ 7489 __ eincq($dst$$Register, $src$$Address, false); 7490 %} 7491 ins_pipe(ialu_reg); 7492 %} 7493 7494 instruct incL_mem(memory dst, immL1 src, rFlagsReg cr) 7495 %{ 7496 predicate(UseIncDec); 7497 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7498 effect(KILL cr); 7499 7500 ins_cost(125); // XXX 7501 format %{ "incq $dst\t# long" %} 7502 ins_encode %{ 7503 __ incrementq($dst$$Address); 7504 %} 7505 ins_pipe(ialu_mem_imm); 7506 %} 7507 7508 // XXX why does that use AddL 7509 instruct decL_rReg(rRegL dst, immL_M1 src, rFlagsReg cr) 7510 %{ 7511 predicate(!UseAPX && UseIncDec); 7512 match(Set dst (AddL dst src)); 7513 effect(KILL cr); 7514 7515 format %{ "decq $dst\t# long" %} 7516 ins_encode %{ 7517 __ decrementq($dst$$Register); 7518 %} 7519 ins_pipe(ialu_reg); 7520 %} 7521 7522 instruct decL_rReg_ndd(rRegL dst, rRegL src, immL_M1 val, rFlagsReg cr) 7523 %{ 7524 predicate(UseAPX && UseIncDec); 7525 match(Set dst (AddL src val)); 7526 effect(KILL cr); 7527 7528 format %{ "edecq $dst, $src\t# long ndd" %} 7529 ins_encode %{ 7530 __ edecq($dst$$Register, $src$$Register, false); 7531 %} 7532 ins_pipe(ialu_reg); 7533 %} 7534 7535 instruct decL_rReg_mem_ndd(rRegL dst, memory src, immL_M1 val, rFlagsReg cr) 7536 %{ 7537 predicate(UseAPX && UseIncDec); 7538 match(Set dst (AddL (LoadL src) val)); 7539 effect(KILL cr); 7540 7541 format %{ "edecq $dst, $src\t# long ndd" %} 7542 ins_encode %{ 7543 __ edecq($dst$$Register, $src$$Address, false); 7544 %} 7545 ins_pipe(ialu_reg); 7546 %} 7547 7548 // XXX why does that use AddL 7549 instruct decL_mem(memory dst, immL_M1 src, rFlagsReg cr) 7550 %{ 7551 predicate(UseIncDec); 7552 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7553 effect(KILL cr); 7554 7555 ins_cost(125); // XXX 7556 format %{ "decq $dst\t# long" %} 7557 ins_encode %{ 7558 __ decrementq($dst$$Address); 7559 %} 7560 ins_pipe(ialu_mem_imm); 7561 %} 7562 7563 instruct leaL_rReg_immI2_immL32(rRegL dst, rRegL index, immI2 scale, immL32 disp) 7564 %{ 7565 predicate(VM_Version::supports_fast_2op_lea()); 7566 match(Set dst (AddL (LShiftL index scale) disp)); 7567 7568 format %{ "leaq $dst, [$index << $scale + $disp]\t# long" %} 7569 ins_encode %{ 7570 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 7571 __ leaq($dst$$Register, Address(noreg, $index$$Register, scale, $disp$$constant)); 7572 %} 7573 ins_pipe(ialu_reg_reg); 7574 %} 7575 7576 instruct leaL_rReg_rReg_immL32(rRegL dst, rRegL base, rRegL index, immL32 disp) 7577 %{ 7578 predicate(VM_Version::supports_fast_3op_lea()); 7579 match(Set dst (AddL (AddL base index) disp)); 7580 7581 format %{ "leaq $dst, [$base + $index + $disp]\t# long" %} 7582 ins_encode %{ 7583 __ leaq($dst$$Register, Address($base$$Register, $index$$Register, Address::times_1, $disp$$constant)); 7584 %} 7585 ins_pipe(ialu_reg_reg); 7586 %} 7587 7588 instruct leaL_rReg_rReg_immI2(rRegL dst, no_rbp_r13_RegL base, rRegL index, immI2 scale) 7589 %{ 7590 predicate(VM_Version::supports_fast_2op_lea()); 7591 match(Set dst (AddL base (LShiftL index scale))); 7592 7593 format %{ "leaq $dst, [$base + $index << $scale]\t# long" %} 7594 ins_encode %{ 7595 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 7596 __ leaq($dst$$Register, Address($base$$Register, $index$$Register, scale)); 7597 %} 7598 ins_pipe(ialu_reg_reg); 7599 %} 7600 7601 instruct leaL_rReg_rReg_immI2_immL32(rRegL dst, rRegL base, rRegL index, immI2 scale, immL32 disp) 7602 %{ 7603 predicate(VM_Version::supports_fast_3op_lea()); 7604 match(Set dst (AddL (AddL base (LShiftL index scale)) disp)); 7605 7606 format %{ "leaq $dst, [$base + $index << $scale + $disp]\t# long" %} 7607 ins_encode %{ 7608 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 7609 __ leaq($dst$$Register, Address($base$$Register, $index$$Register, scale, $disp$$constant)); 7610 %} 7611 ins_pipe(ialu_reg_reg); 7612 %} 7613 7614 instruct addP_rReg(rRegP dst, rRegL src, rFlagsReg cr) 7615 %{ 7616 match(Set dst (AddP dst src)); 7617 effect(KILL cr); 7618 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); 7619 7620 format %{ "addq $dst, $src\t# ptr" %} 7621 ins_encode %{ 7622 __ addq($dst$$Register, $src$$Register); 7623 %} 7624 ins_pipe(ialu_reg_reg); 7625 %} 7626 7627 instruct addP_rReg_imm(rRegP dst, immL32 src, rFlagsReg cr) 7628 %{ 7629 match(Set dst (AddP dst src)); 7630 effect(KILL cr); 7631 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); 7632 7633 format %{ "addq $dst, $src\t# ptr" %} 7634 ins_encode %{ 7635 __ addq($dst$$Register, $src$$constant); 7636 %} 7637 ins_pipe( ialu_reg ); 7638 %} 7639 7640 // XXX addP mem ops ???? 7641 7642 instruct checkCastPP(rRegP dst) 7643 %{ 7644 match(Set dst (CheckCastPP dst)); 7645 7646 size(0); 7647 format %{ "# checkcastPP of $dst" %} 7648 ins_encode(/* empty encoding */); 7649 ins_pipe(empty); 7650 %} 7651 7652 instruct castPP(rRegP dst) 7653 %{ 7654 match(Set dst (CastPP dst)); 7655 7656 size(0); 7657 format %{ "# castPP of $dst" %} 7658 ins_encode(/* empty encoding */); 7659 ins_pipe(empty); 7660 %} 7661 7662 instruct castII(rRegI dst) 7663 %{ 7664 predicate(VerifyConstraintCasts == 0); 7665 match(Set dst (CastII dst)); 7666 7667 size(0); 7668 format %{ "# castII of $dst" %} 7669 ins_encode(/* empty encoding */); 7670 ins_cost(0); 7671 ins_pipe(empty); 7672 %} 7673 7674 instruct castII_checked(rRegI dst, rFlagsReg cr) 7675 %{ 7676 predicate(VerifyConstraintCasts > 0); 7677 match(Set dst (CastII dst)); 7678 7679 effect(KILL cr); 7680 format %{ "# cast_checked_II $dst" %} 7681 ins_encode %{ 7682 __ verify_int_in_range(_idx, bottom_type()->is_int(), $dst$$Register); 7683 %} 7684 ins_pipe(pipe_slow); 7685 %} 7686 7687 instruct castLL(rRegL dst) 7688 %{ 7689 predicate(VerifyConstraintCasts == 0); 7690 match(Set dst (CastLL dst)); 7691 7692 size(0); 7693 format %{ "# castLL of $dst" %} 7694 ins_encode(/* empty encoding */); 7695 ins_cost(0); 7696 ins_pipe(empty); 7697 %} 7698 7699 instruct castLL_checked_L32(rRegL dst, rFlagsReg cr) 7700 %{ 7701 predicate(VerifyConstraintCasts > 0 && castLL_is_imm32(n)); 7702 match(Set dst (CastLL dst)); 7703 7704 effect(KILL cr); 7705 format %{ "# cast_checked_LL $dst" %} 7706 ins_encode %{ 7707 __ verify_long_in_range(_idx, bottom_type()->is_long(), $dst$$Register, noreg); 7708 %} 7709 ins_pipe(pipe_slow); 7710 %} 7711 7712 instruct castLL_checked(rRegL dst, rRegL tmp, rFlagsReg cr) 7713 %{ 7714 predicate(VerifyConstraintCasts > 0 && !castLL_is_imm32(n)); 7715 match(Set dst (CastLL dst)); 7716 7717 effect(KILL cr, TEMP tmp); 7718 format %{ "# cast_checked_LL $dst\tusing $tmp as TEMP" %} 7719 ins_encode %{ 7720 __ verify_long_in_range(_idx, bottom_type()->is_long(), $dst$$Register, $tmp$$Register); 7721 %} 7722 ins_pipe(pipe_slow); 7723 %} 7724 7725 instruct castFF(regF dst) 7726 %{ 7727 match(Set dst (CastFF dst)); 7728 7729 size(0); 7730 format %{ "# castFF of $dst" %} 7731 ins_encode(/* empty encoding */); 7732 ins_cost(0); 7733 ins_pipe(empty); 7734 %} 7735 7736 instruct castHH(regF dst) 7737 %{ 7738 match(Set dst (CastHH dst)); 7739 7740 size(0); 7741 format %{ "# castHH of $dst" %} 7742 ins_encode(/* empty encoding */); 7743 ins_cost(0); 7744 ins_pipe(empty); 7745 %} 7746 7747 instruct castDD(regD dst) 7748 %{ 7749 match(Set dst (CastDD dst)); 7750 7751 size(0); 7752 format %{ "# castDD of $dst" %} 7753 ins_encode(/* empty encoding */); 7754 ins_cost(0); 7755 ins_pipe(empty); 7756 %} 7757 7758 // XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them 7759 instruct compareAndSwapP(rRegI res, 7760 memory mem_ptr, 7761 rax_RegP oldval, rRegP newval, 7762 rFlagsReg cr) 7763 %{ 7764 predicate(n->as_LoadStore()->barrier_data() == 0); 7765 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); 7766 match(Set res (WeakCompareAndSwapP mem_ptr (Binary oldval newval))); 7767 effect(KILL cr, KILL oldval); 7768 7769 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7770 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7771 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7772 ins_encode %{ 7773 __ lock(); 7774 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7775 __ setcc(Assembler::equal, $res$$Register); 7776 %} 7777 ins_pipe( pipe_cmpxchg ); 7778 %} 7779 7780 instruct compareAndSwapL(rRegI res, 7781 memory mem_ptr, 7782 rax_RegL oldval, rRegL newval, 7783 rFlagsReg cr) 7784 %{ 7785 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval))); 7786 match(Set res (WeakCompareAndSwapL mem_ptr (Binary oldval newval))); 7787 effect(KILL cr, KILL oldval); 7788 7789 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7790 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7791 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7792 ins_encode %{ 7793 __ lock(); 7794 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7795 __ setcc(Assembler::equal, $res$$Register); 7796 %} 7797 ins_pipe( pipe_cmpxchg ); 7798 %} 7799 7800 instruct compareAndSwapI(rRegI res, 7801 memory mem_ptr, 7802 rax_RegI oldval, rRegI newval, 7803 rFlagsReg cr) 7804 %{ 7805 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval))); 7806 match(Set res (WeakCompareAndSwapI mem_ptr (Binary oldval newval))); 7807 effect(KILL cr, KILL oldval); 7808 7809 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7810 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7811 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7812 ins_encode %{ 7813 __ lock(); 7814 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7815 __ setcc(Assembler::equal, $res$$Register); 7816 %} 7817 ins_pipe( pipe_cmpxchg ); 7818 %} 7819 7820 instruct compareAndSwapB(rRegI res, 7821 memory mem_ptr, 7822 rax_RegI oldval, rRegI newval, 7823 rFlagsReg cr) 7824 %{ 7825 match(Set res (CompareAndSwapB mem_ptr (Binary oldval newval))); 7826 match(Set res (WeakCompareAndSwapB mem_ptr (Binary oldval newval))); 7827 effect(KILL cr, KILL oldval); 7828 7829 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7830 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7831 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7832 ins_encode %{ 7833 __ lock(); 7834 __ cmpxchgb($newval$$Register, $mem_ptr$$Address); 7835 __ setcc(Assembler::equal, $res$$Register); 7836 %} 7837 ins_pipe( pipe_cmpxchg ); 7838 %} 7839 7840 instruct compareAndSwapS(rRegI res, 7841 memory mem_ptr, 7842 rax_RegI oldval, rRegI newval, 7843 rFlagsReg cr) 7844 %{ 7845 match(Set res (CompareAndSwapS mem_ptr (Binary oldval newval))); 7846 match(Set res (WeakCompareAndSwapS mem_ptr (Binary oldval newval))); 7847 effect(KILL cr, KILL oldval); 7848 7849 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7850 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7851 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7852 ins_encode %{ 7853 __ lock(); 7854 __ cmpxchgw($newval$$Register, $mem_ptr$$Address); 7855 __ setcc(Assembler::equal, $res$$Register); 7856 %} 7857 ins_pipe( pipe_cmpxchg ); 7858 %} 7859 7860 instruct compareAndSwapN(rRegI res, 7861 memory mem_ptr, 7862 rax_RegN oldval, rRegN newval, 7863 rFlagsReg cr) %{ 7864 predicate(n->as_LoadStore()->barrier_data() == 0); 7865 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval))); 7866 match(Set res (WeakCompareAndSwapN mem_ptr (Binary oldval newval))); 7867 effect(KILL cr, KILL oldval); 7868 7869 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7870 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7871 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7872 ins_encode %{ 7873 __ lock(); 7874 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7875 __ setcc(Assembler::equal, $res$$Register); 7876 %} 7877 ins_pipe( pipe_cmpxchg ); 7878 %} 7879 7880 instruct compareAndExchangeB( 7881 memory mem_ptr, 7882 rax_RegI oldval, rRegI newval, 7883 rFlagsReg cr) 7884 %{ 7885 match(Set oldval (CompareAndExchangeB mem_ptr (Binary oldval newval))); 7886 effect(KILL cr); 7887 7888 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7889 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7890 ins_encode %{ 7891 __ lock(); 7892 __ cmpxchgb($newval$$Register, $mem_ptr$$Address); 7893 %} 7894 ins_pipe( pipe_cmpxchg ); 7895 %} 7896 7897 instruct compareAndExchangeS( 7898 memory mem_ptr, 7899 rax_RegI oldval, rRegI newval, 7900 rFlagsReg cr) 7901 %{ 7902 match(Set oldval (CompareAndExchangeS mem_ptr (Binary oldval newval))); 7903 effect(KILL cr); 7904 7905 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7906 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7907 ins_encode %{ 7908 __ lock(); 7909 __ cmpxchgw($newval$$Register, $mem_ptr$$Address); 7910 %} 7911 ins_pipe( pipe_cmpxchg ); 7912 %} 7913 7914 instruct compareAndExchangeI( 7915 memory mem_ptr, 7916 rax_RegI oldval, rRegI newval, 7917 rFlagsReg cr) 7918 %{ 7919 match(Set oldval (CompareAndExchangeI mem_ptr (Binary oldval newval))); 7920 effect(KILL cr); 7921 7922 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7923 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7924 ins_encode %{ 7925 __ lock(); 7926 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7927 %} 7928 ins_pipe( pipe_cmpxchg ); 7929 %} 7930 7931 instruct compareAndExchangeL( 7932 memory mem_ptr, 7933 rax_RegL oldval, rRegL newval, 7934 rFlagsReg cr) 7935 %{ 7936 match(Set oldval (CompareAndExchangeL mem_ptr (Binary oldval newval))); 7937 effect(KILL cr); 7938 7939 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7940 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7941 ins_encode %{ 7942 __ lock(); 7943 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7944 %} 7945 ins_pipe( pipe_cmpxchg ); 7946 %} 7947 7948 instruct compareAndExchangeN( 7949 memory mem_ptr, 7950 rax_RegN oldval, rRegN newval, 7951 rFlagsReg cr) %{ 7952 predicate(n->as_LoadStore()->barrier_data() == 0); 7953 match(Set oldval (CompareAndExchangeN mem_ptr (Binary oldval newval))); 7954 effect(KILL cr); 7955 7956 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7957 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7958 ins_encode %{ 7959 __ lock(); 7960 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7961 %} 7962 ins_pipe( pipe_cmpxchg ); 7963 %} 7964 7965 instruct compareAndExchangeP( 7966 memory mem_ptr, 7967 rax_RegP oldval, rRegP newval, 7968 rFlagsReg cr) 7969 %{ 7970 predicate(n->as_LoadStore()->barrier_data() == 0); 7971 match(Set oldval (CompareAndExchangeP mem_ptr (Binary oldval newval))); 7972 effect(KILL cr); 7973 7974 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7975 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7976 ins_encode %{ 7977 __ lock(); 7978 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7979 %} 7980 ins_pipe( pipe_cmpxchg ); 7981 %} 7982 7983 instruct xaddB_reg_no_res(memory mem, Universe dummy, rRegI add, rFlagsReg cr) %{ 7984 predicate(n->as_LoadStore()->result_not_used()); 7985 match(Set dummy (GetAndAddB mem add)); 7986 effect(KILL cr); 7987 format %{ "addb_lock $mem, $add" %} 7988 ins_encode %{ 7989 __ lock(); 7990 __ addb($mem$$Address, $add$$Register); 7991 %} 7992 ins_pipe(pipe_cmpxchg); 7993 %} 7994 7995 instruct xaddB_imm_no_res(memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7996 predicate(n->as_LoadStore()->result_not_used()); 7997 match(Set dummy (GetAndAddB mem add)); 7998 effect(KILL cr); 7999 format %{ "addb_lock $mem, $add" %} 8000 ins_encode %{ 8001 __ lock(); 8002 __ addb($mem$$Address, $add$$constant); 8003 %} 8004 ins_pipe(pipe_cmpxchg); 8005 %} 8006 8007 instruct xaddB(memory mem, rRegI newval, rFlagsReg cr) %{ 8008 predicate(!n->as_LoadStore()->result_not_used()); 8009 match(Set newval (GetAndAddB mem newval)); 8010 effect(KILL cr); 8011 format %{ "xaddb_lock $mem, $newval" %} 8012 ins_encode %{ 8013 __ lock(); 8014 __ xaddb($mem$$Address, $newval$$Register); 8015 %} 8016 ins_pipe(pipe_cmpxchg); 8017 %} 8018 8019 instruct xaddS_reg_no_res(memory mem, Universe dummy, rRegI add, rFlagsReg cr) %{ 8020 predicate(n->as_LoadStore()->result_not_used()); 8021 match(Set dummy (GetAndAddS mem add)); 8022 effect(KILL cr); 8023 format %{ "addw_lock $mem, $add" %} 8024 ins_encode %{ 8025 __ lock(); 8026 __ addw($mem$$Address, $add$$Register); 8027 %} 8028 ins_pipe(pipe_cmpxchg); 8029 %} 8030 8031 instruct xaddS_imm_no_res(memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 8032 predicate(UseStoreImmI16 && n->as_LoadStore()->result_not_used()); 8033 match(Set dummy (GetAndAddS mem add)); 8034 effect(KILL cr); 8035 format %{ "addw_lock $mem, $add" %} 8036 ins_encode %{ 8037 __ lock(); 8038 __ addw($mem$$Address, $add$$constant); 8039 %} 8040 ins_pipe(pipe_cmpxchg); 8041 %} 8042 8043 instruct xaddS(memory mem, rRegI newval, rFlagsReg cr) %{ 8044 predicate(!n->as_LoadStore()->result_not_used()); 8045 match(Set newval (GetAndAddS mem newval)); 8046 effect(KILL cr); 8047 format %{ "xaddw_lock $mem, $newval" %} 8048 ins_encode %{ 8049 __ lock(); 8050 __ xaddw($mem$$Address, $newval$$Register); 8051 %} 8052 ins_pipe(pipe_cmpxchg); 8053 %} 8054 8055 instruct xaddI_reg_no_res(memory mem, Universe dummy, rRegI add, rFlagsReg cr) %{ 8056 predicate(n->as_LoadStore()->result_not_used()); 8057 match(Set dummy (GetAndAddI mem add)); 8058 effect(KILL cr); 8059 format %{ "addl_lock $mem, $add" %} 8060 ins_encode %{ 8061 __ lock(); 8062 __ addl($mem$$Address, $add$$Register); 8063 %} 8064 ins_pipe(pipe_cmpxchg); 8065 %} 8066 8067 instruct xaddI_imm_no_res(memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 8068 predicate(n->as_LoadStore()->result_not_used()); 8069 match(Set dummy (GetAndAddI mem add)); 8070 effect(KILL cr); 8071 format %{ "addl_lock $mem, $add" %} 8072 ins_encode %{ 8073 __ lock(); 8074 __ addl($mem$$Address, $add$$constant); 8075 %} 8076 ins_pipe(pipe_cmpxchg); 8077 %} 8078 8079 instruct xaddI(memory mem, rRegI newval, rFlagsReg cr) %{ 8080 predicate(!n->as_LoadStore()->result_not_used()); 8081 match(Set newval (GetAndAddI mem newval)); 8082 effect(KILL cr); 8083 format %{ "xaddl_lock $mem, $newval" %} 8084 ins_encode %{ 8085 __ lock(); 8086 __ xaddl($mem$$Address, $newval$$Register); 8087 %} 8088 ins_pipe(pipe_cmpxchg); 8089 %} 8090 8091 instruct xaddL_reg_no_res(memory mem, Universe dummy, rRegL add, rFlagsReg cr) %{ 8092 predicate(n->as_LoadStore()->result_not_used()); 8093 match(Set dummy (GetAndAddL mem add)); 8094 effect(KILL cr); 8095 format %{ "addq_lock $mem, $add" %} 8096 ins_encode %{ 8097 __ lock(); 8098 __ addq($mem$$Address, $add$$Register); 8099 %} 8100 ins_pipe(pipe_cmpxchg); 8101 %} 8102 8103 instruct xaddL_imm_no_res(memory mem, Universe dummy, immL32 add, rFlagsReg cr) %{ 8104 predicate(n->as_LoadStore()->result_not_used()); 8105 match(Set dummy (GetAndAddL mem add)); 8106 effect(KILL cr); 8107 format %{ "addq_lock $mem, $add" %} 8108 ins_encode %{ 8109 __ lock(); 8110 __ addq($mem$$Address, $add$$constant); 8111 %} 8112 ins_pipe(pipe_cmpxchg); 8113 %} 8114 8115 instruct xaddL(memory mem, rRegL newval, rFlagsReg cr) %{ 8116 predicate(!n->as_LoadStore()->result_not_used()); 8117 match(Set newval (GetAndAddL mem newval)); 8118 effect(KILL cr); 8119 format %{ "xaddq_lock $mem, $newval" %} 8120 ins_encode %{ 8121 __ lock(); 8122 __ xaddq($mem$$Address, $newval$$Register); 8123 %} 8124 ins_pipe(pipe_cmpxchg); 8125 %} 8126 8127 instruct xchgB( memory mem, rRegI newval) %{ 8128 match(Set newval (GetAndSetB mem newval)); 8129 format %{ "XCHGB $newval,[$mem]" %} 8130 ins_encode %{ 8131 __ xchgb($newval$$Register, $mem$$Address); 8132 %} 8133 ins_pipe( pipe_cmpxchg ); 8134 %} 8135 8136 instruct xchgS( memory mem, rRegI newval) %{ 8137 match(Set newval (GetAndSetS mem newval)); 8138 format %{ "XCHGW $newval,[$mem]" %} 8139 ins_encode %{ 8140 __ xchgw($newval$$Register, $mem$$Address); 8141 %} 8142 ins_pipe( pipe_cmpxchg ); 8143 %} 8144 8145 instruct xchgI( memory mem, rRegI newval) %{ 8146 match(Set newval (GetAndSetI mem newval)); 8147 format %{ "XCHGL $newval,[$mem]" %} 8148 ins_encode %{ 8149 __ xchgl($newval$$Register, $mem$$Address); 8150 %} 8151 ins_pipe( pipe_cmpxchg ); 8152 %} 8153 8154 instruct xchgL( memory mem, rRegL newval) %{ 8155 match(Set newval (GetAndSetL mem newval)); 8156 format %{ "XCHGL $newval,[$mem]" %} 8157 ins_encode %{ 8158 __ xchgq($newval$$Register, $mem$$Address); 8159 %} 8160 ins_pipe( pipe_cmpxchg ); 8161 %} 8162 8163 instruct xchgP( memory mem, rRegP newval) %{ 8164 match(Set newval (GetAndSetP mem newval)); 8165 predicate(n->as_LoadStore()->barrier_data() == 0); 8166 format %{ "XCHGQ $newval,[$mem]" %} 8167 ins_encode %{ 8168 __ xchgq($newval$$Register, $mem$$Address); 8169 %} 8170 ins_pipe( pipe_cmpxchg ); 8171 %} 8172 8173 instruct xchgN( memory mem, rRegN newval) %{ 8174 predicate(n->as_LoadStore()->barrier_data() == 0); 8175 match(Set newval (GetAndSetN mem newval)); 8176 format %{ "XCHGL $newval,$mem]" %} 8177 ins_encode %{ 8178 __ xchgl($newval$$Register, $mem$$Address); 8179 %} 8180 ins_pipe( pipe_cmpxchg ); 8181 %} 8182 8183 //----------Abs Instructions------------------------------------------- 8184 8185 // Integer Absolute Instructions 8186 instruct absI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8187 %{ 8188 match(Set dst (AbsI src)); 8189 effect(TEMP dst, KILL cr); 8190 format %{ "xorl $dst, $dst\t# abs int\n\t" 8191 "subl $dst, $src\n\t" 8192 "cmovll $dst, $src" %} 8193 ins_encode %{ 8194 __ xorl($dst$$Register, $dst$$Register); 8195 __ subl($dst$$Register, $src$$Register); 8196 __ cmovl(Assembler::less, $dst$$Register, $src$$Register); 8197 %} 8198 8199 ins_pipe(ialu_reg_reg); 8200 %} 8201 8202 // Long Absolute Instructions 8203 instruct absL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 8204 %{ 8205 match(Set dst (AbsL src)); 8206 effect(TEMP dst, KILL cr); 8207 format %{ "xorl $dst, $dst\t# abs long\n\t" 8208 "subq $dst, $src\n\t" 8209 "cmovlq $dst, $src" %} 8210 ins_encode %{ 8211 __ xorl($dst$$Register, $dst$$Register); 8212 __ subq($dst$$Register, $src$$Register); 8213 __ cmovq(Assembler::less, $dst$$Register, $src$$Register); 8214 %} 8215 8216 ins_pipe(ialu_reg_reg); 8217 %} 8218 8219 //----------Subtraction Instructions------------------------------------------- 8220 8221 // Integer Subtraction Instructions 8222 instruct subI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8223 %{ 8224 predicate(!UseAPX); 8225 match(Set dst (SubI dst src)); 8226 effect(KILL cr); 8227 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); 8228 8229 format %{ "subl $dst, $src\t# int" %} 8230 ins_encode %{ 8231 __ subl($dst$$Register, $src$$Register); 8232 %} 8233 ins_pipe(ialu_reg_reg); 8234 %} 8235 8236 instruct subI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr) 8237 %{ 8238 predicate(UseAPX); 8239 match(Set dst (SubI src1 src2)); 8240 effect(KILL cr); 8241 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); 8242 8243 format %{ "esubl $dst, $src1, $src2\t# int ndd" %} 8244 ins_encode %{ 8245 __ esubl($dst$$Register, $src1$$Register, $src2$$Register, false); 8246 %} 8247 ins_pipe(ialu_reg_reg); 8248 %} 8249 8250 instruct subI_rReg_rReg_imm_ndd(rRegI dst, rRegI src1, immI src2, rFlagsReg cr) 8251 %{ 8252 predicate(UseAPX); 8253 match(Set dst (SubI src1 src2)); 8254 effect(KILL cr); 8255 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); 8256 8257 format %{ "esubl $dst, $src1, $src2\t# int ndd" %} 8258 ins_encode %{ 8259 __ esubl($dst$$Register, $src1$$Register, $src2$$constant, false); 8260 %} 8261 ins_pipe(ialu_reg_reg); 8262 %} 8263 8264 instruct subI_rReg_mem_imm_ndd(rRegI dst, memory src1, immI src2, rFlagsReg cr) 8265 %{ 8266 predicate(UseAPX); 8267 match(Set dst (SubI (LoadI src1) src2)); 8268 effect(KILL cr); 8269 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); 8270 8271 format %{ "esubl $dst, $src1, $src2\t# int ndd" %} 8272 ins_encode %{ 8273 __ esubl($dst$$Register, $src1$$Address, $src2$$constant, false); 8274 %} 8275 ins_pipe(ialu_reg_reg); 8276 %} 8277 8278 instruct subI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 8279 %{ 8280 predicate(!UseAPX); 8281 match(Set dst (SubI dst (LoadI src))); 8282 effect(KILL cr); 8283 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); 8284 8285 ins_cost(150); 8286 format %{ "subl $dst, $src\t# int" %} 8287 ins_encode %{ 8288 __ subl($dst$$Register, $src$$Address); 8289 %} 8290 ins_pipe(ialu_reg_mem); 8291 %} 8292 8293 instruct subI_rReg_rReg_mem_ndd(rRegI dst, rRegI src1, memory src2, rFlagsReg cr) 8294 %{ 8295 predicate(UseAPX); 8296 match(Set dst (SubI src1 (LoadI src2))); 8297 effect(KILL cr); 8298 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); 8299 8300 ins_cost(150); 8301 format %{ "esubl $dst, $src1, $src2\t# int ndd" %} 8302 ins_encode %{ 8303 __ esubl($dst$$Register, $src1$$Register, $src2$$Address, false); 8304 %} 8305 ins_pipe(ialu_reg_mem); 8306 %} 8307 8308 instruct subI_rReg_mem_rReg_ndd(rRegI dst, memory src1, rRegI src2, rFlagsReg cr) 8309 %{ 8310 predicate(UseAPX); 8311 match(Set dst (SubI (LoadI src1) src2)); 8312 effect(KILL cr); 8313 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 8314 8315 ins_cost(150); 8316 format %{ "esubl $dst, $src1, $src2\t# int ndd" %} 8317 ins_encode %{ 8318 __ esubl($dst$$Register, $src1$$Address, $src2$$Register, false); 8319 %} 8320 ins_pipe(ialu_reg_mem); 8321 %} 8322 8323 instruct subI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 8324 %{ 8325 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 8326 effect(KILL cr); 8327 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); 8328 8329 ins_cost(150); 8330 format %{ "subl $dst, $src\t# int" %} 8331 ins_encode %{ 8332 __ subl($dst$$Address, $src$$Register); 8333 %} 8334 ins_pipe(ialu_mem_reg); 8335 %} 8336 8337 instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 8338 %{ 8339 predicate(!UseAPX); 8340 match(Set dst (SubL dst src)); 8341 effect(KILL cr); 8342 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); 8343 8344 format %{ "subq $dst, $src\t# long" %} 8345 ins_encode %{ 8346 __ subq($dst$$Register, $src$$Register); 8347 %} 8348 ins_pipe(ialu_reg_reg); 8349 %} 8350 8351 instruct subL_rReg_ndd(rRegL dst, rRegL src1, rRegL src2, rFlagsReg cr) 8352 %{ 8353 predicate(UseAPX); 8354 match(Set dst (SubL src1 src2)); 8355 effect(KILL cr); 8356 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); 8357 8358 format %{ "esubq $dst, $src1, $src2\t# long ndd" %} 8359 ins_encode %{ 8360 __ esubq($dst$$Register, $src1$$Register, $src2$$Register, false); 8361 %} 8362 ins_pipe(ialu_reg_reg); 8363 %} 8364 8365 instruct subL_rReg_rReg_imm_ndd(rRegL dst, rRegL src1, immL32 src2, rFlagsReg cr) 8366 %{ 8367 predicate(UseAPX); 8368 match(Set dst (SubL src1 src2)); 8369 effect(KILL cr); 8370 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); 8371 8372 format %{ "esubq $dst, $src1, $src2\t# long ndd" %} 8373 ins_encode %{ 8374 __ esubq($dst$$Register, $src1$$Register, $src2$$constant, false); 8375 %} 8376 ins_pipe(ialu_reg_reg); 8377 %} 8378 8379 instruct subL_rReg_mem_imm_ndd(rRegL dst, memory src1, immL32 src2, rFlagsReg cr) 8380 %{ 8381 predicate(UseAPX); 8382 match(Set dst (SubL (LoadL src1) src2)); 8383 effect(KILL cr); 8384 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); 8385 8386 format %{ "esubq $dst, $src1, $src2\t# long ndd" %} 8387 ins_encode %{ 8388 __ esubq($dst$$Register, $src1$$Address, $src2$$constant, false); 8389 %} 8390 ins_pipe(ialu_reg_reg); 8391 %} 8392 8393 instruct subL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 8394 %{ 8395 predicate(!UseAPX); 8396 match(Set dst (SubL dst (LoadL src))); 8397 effect(KILL cr); 8398 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); 8399 8400 ins_cost(150); 8401 format %{ "subq $dst, $src\t# long" %} 8402 ins_encode %{ 8403 __ subq($dst$$Register, $src$$Address); 8404 %} 8405 ins_pipe(ialu_reg_mem); 8406 %} 8407 8408 instruct subL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr) 8409 %{ 8410 predicate(UseAPX); 8411 match(Set dst (SubL src1 (LoadL src2))); 8412 effect(KILL cr); 8413 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); 8414 8415 ins_cost(150); 8416 format %{ "esubq $dst, $src1, $src2\t# long ndd" %} 8417 ins_encode %{ 8418 __ esubq($dst$$Register, $src1$$Register, $src2$$Address, false); 8419 %} 8420 ins_pipe(ialu_reg_mem); 8421 %} 8422 8423 instruct subL_rReg_mem_rReg_ndd(rRegL dst, memory src1, rRegL src2, rFlagsReg cr) 8424 %{ 8425 predicate(UseAPX); 8426 match(Set dst (SubL (LoadL src1) src2)); 8427 effect(KILL cr); 8428 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 8429 8430 ins_cost(150); 8431 format %{ "esubq $dst, $src1, $src2\t# long ndd" %} 8432 ins_encode %{ 8433 __ esubq($dst$$Register, $src1$$Address, $src2$$Register, false); 8434 %} 8435 ins_pipe(ialu_reg_mem); 8436 %} 8437 8438 instruct subL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 8439 %{ 8440 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 8441 effect(KILL cr); 8442 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); 8443 8444 ins_cost(150); 8445 format %{ "subq $dst, $src\t# long" %} 8446 ins_encode %{ 8447 __ subq($dst$$Address, $src$$Register); 8448 %} 8449 ins_pipe(ialu_mem_reg); 8450 %} 8451 8452 // Subtract from a pointer 8453 // XXX hmpf??? 8454 instruct subP_rReg(rRegP dst, rRegI src, immI_0 zero, rFlagsReg cr) 8455 %{ 8456 match(Set dst (AddP dst (SubI zero src))); 8457 effect(KILL cr); 8458 8459 format %{ "subq $dst, $src\t# ptr - int" %} 8460 ins_encode %{ 8461 __ subq($dst$$Register, $src$$Register); 8462 %} 8463 ins_pipe(ialu_reg_reg); 8464 %} 8465 8466 instruct negI_rReg(rRegI dst, immI_0 zero, rFlagsReg cr) 8467 %{ 8468 predicate(!UseAPX); 8469 match(Set dst (SubI zero dst)); 8470 effect(KILL cr); 8471 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8472 8473 format %{ "negl $dst\t# int" %} 8474 ins_encode %{ 8475 __ negl($dst$$Register); 8476 %} 8477 ins_pipe(ialu_reg); 8478 %} 8479 8480 instruct negI_rReg_ndd(rRegI dst, rRegI src, immI_0 zero, rFlagsReg cr) 8481 %{ 8482 predicate(UseAPX); 8483 match(Set dst (SubI zero src)); 8484 effect(KILL cr); 8485 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8486 8487 format %{ "enegl $dst, $src\t# int ndd" %} 8488 ins_encode %{ 8489 __ enegl($dst$$Register, $src$$Register, false); 8490 %} 8491 ins_pipe(ialu_reg); 8492 %} 8493 8494 instruct negI_rReg_2(rRegI dst, rFlagsReg cr) 8495 %{ 8496 predicate(!UseAPX); 8497 match(Set dst (NegI dst)); 8498 effect(KILL cr); 8499 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8500 8501 format %{ "negl $dst\t# int" %} 8502 ins_encode %{ 8503 __ negl($dst$$Register); 8504 %} 8505 ins_pipe(ialu_reg); 8506 %} 8507 8508 instruct negI_rReg_2_ndd(rRegI dst, rRegI src, rFlagsReg cr) 8509 %{ 8510 predicate(UseAPX); 8511 match(Set dst (NegI src)); 8512 effect(KILL cr); 8513 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8514 8515 format %{ "enegl $dst, $src\t# int ndd" %} 8516 ins_encode %{ 8517 __ enegl($dst$$Register, $src$$Register, false); 8518 %} 8519 ins_pipe(ialu_reg); 8520 %} 8521 8522 instruct negI_mem(memory dst, immI_0 zero, rFlagsReg cr) 8523 %{ 8524 match(Set dst (StoreI dst (SubI zero (LoadI dst)))); 8525 effect(KILL cr); 8526 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8527 8528 format %{ "negl $dst\t# int" %} 8529 ins_encode %{ 8530 __ negl($dst$$Address); 8531 %} 8532 ins_pipe(ialu_reg); 8533 %} 8534 8535 instruct negL_rReg(rRegL dst, immL0 zero, rFlagsReg cr) 8536 %{ 8537 predicate(!UseAPX); 8538 match(Set dst (SubL zero dst)); 8539 effect(KILL cr); 8540 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8541 8542 format %{ "negq $dst\t# long" %} 8543 ins_encode %{ 8544 __ negq($dst$$Register); 8545 %} 8546 ins_pipe(ialu_reg); 8547 %} 8548 8549 instruct negL_rReg_ndd(rRegL dst, rRegL src, immL0 zero, rFlagsReg cr) 8550 %{ 8551 predicate(UseAPX); 8552 match(Set dst (SubL zero src)); 8553 effect(KILL cr); 8554 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8555 8556 format %{ "enegq $dst, $src\t# long ndd" %} 8557 ins_encode %{ 8558 __ enegq($dst$$Register, $src$$Register, false); 8559 %} 8560 ins_pipe(ialu_reg); 8561 %} 8562 8563 instruct negL_rReg_2(rRegL dst, rFlagsReg cr) 8564 %{ 8565 predicate(!UseAPX); 8566 match(Set dst (NegL dst)); 8567 effect(KILL cr); 8568 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8569 8570 format %{ "negq $dst\t# int" %} 8571 ins_encode %{ 8572 __ negq($dst$$Register); 8573 %} 8574 ins_pipe(ialu_reg); 8575 %} 8576 8577 instruct negL_rReg_2_ndd(rRegL dst, rRegL src, rFlagsReg cr) 8578 %{ 8579 predicate(UseAPX); 8580 match(Set dst (NegL src)); 8581 effect(KILL cr); 8582 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8583 8584 format %{ "enegq $dst, $src\t# long ndd" %} 8585 ins_encode %{ 8586 __ enegq($dst$$Register, $src$$Register, false); 8587 %} 8588 ins_pipe(ialu_reg); 8589 %} 8590 8591 instruct negL_mem(memory dst, immL0 zero, rFlagsReg cr) 8592 %{ 8593 match(Set dst (StoreL dst (SubL zero (LoadL dst)))); 8594 effect(KILL cr); 8595 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8596 8597 format %{ "negq $dst\t# long" %} 8598 ins_encode %{ 8599 __ negq($dst$$Address); 8600 %} 8601 ins_pipe(ialu_reg); 8602 %} 8603 8604 //----------Multiplication/Division Instructions------------------------------- 8605 // Integer Multiplication Instructions 8606 // Multiply Register 8607 8608 instruct mulI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8609 %{ 8610 predicate(!UseAPX); 8611 match(Set dst (MulI dst src)); 8612 effect(KILL cr); 8613 8614 ins_cost(300); 8615 format %{ "imull $dst, $src\t# int" %} 8616 ins_encode %{ 8617 __ imull($dst$$Register, $src$$Register); 8618 %} 8619 ins_pipe(ialu_reg_reg_alu0); 8620 %} 8621 8622 instruct mulI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr) 8623 %{ 8624 predicate(UseAPX); 8625 match(Set dst (MulI src1 src2)); 8626 effect(KILL cr); 8627 8628 ins_cost(300); 8629 format %{ "eimull $dst, $src1, $src2\t# int ndd" %} 8630 ins_encode %{ 8631 __ eimull($dst$$Register, $src1$$Register, $src2$$Register, false); 8632 %} 8633 ins_pipe(ialu_reg_reg_alu0); 8634 %} 8635 8636 instruct mulI_rReg_imm(rRegI dst, rRegI src, immI imm, rFlagsReg cr) 8637 %{ 8638 match(Set dst (MulI src imm)); 8639 effect(KILL cr); 8640 8641 ins_cost(300); 8642 format %{ "imull $dst, $src, $imm\t# int" %} 8643 ins_encode %{ 8644 __ imull($dst$$Register, $src$$Register, $imm$$constant); 8645 %} 8646 ins_pipe(ialu_reg_reg_alu0); 8647 %} 8648 8649 instruct mulI_mem(rRegI dst, memory src, rFlagsReg cr) 8650 %{ 8651 predicate(!UseAPX); 8652 match(Set dst (MulI dst (LoadI src))); 8653 effect(KILL cr); 8654 8655 ins_cost(350); 8656 format %{ "imull $dst, $src\t# int" %} 8657 ins_encode %{ 8658 __ imull($dst$$Register, $src$$Address); 8659 %} 8660 ins_pipe(ialu_reg_mem_alu0); 8661 %} 8662 8663 instruct mulI_rReg_rReg_mem_ndd(rRegI dst, rRegI src1, memory src2, rFlagsReg cr) 8664 %{ 8665 predicate(UseAPX); 8666 match(Set dst (MulI src1 (LoadI src2))); 8667 effect(KILL cr); 8668 8669 ins_cost(350); 8670 format %{ "eimull $dst, $src1, $src2\t# int ndd" %} 8671 ins_encode %{ 8672 __ eimull($dst$$Register, $src1$$Register, $src2$$Address, false); 8673 %} 8674 ins_pipe(ialu_reg_mem_alu0); 8675 %} 8676 8677 instruct mulI_mem_imm(rRegI dst, memory src, immI imm, rFlagsReg cr) 8678 %{ 8679 match(Set dst (MulI (LoadI src) imm)); 8680 effect(KILL cr); 8681 8682 ins_cost(300); 8683 format %{ "imull $dst, $src, $imm\t# int" %} 8684 ins_encode %{ 8685 __ imull($dst$$Register, $src$$Address, $imm$$constant); 8686 %} 8687 ins_pipe(ialu_reg_mem_alu0); 8688 %} 8689 8690 instruct mulAddS2I_rReg(rRegI dst, rRegI src1, rRegI src2, rRegI src3, rFlagsReg cr) 8691 %{ 8692 match(Set dst (MulAddS2I (Binary dst src1) (Binary src2 src3))); 8693 effect(KILL cr, KILL src2); 8694 8695 expand %{ mulI_rReg(dst, src1, cr); 8696 mulI_rReg(src2, src3, cr); 8697 addI_rReg(dst, src2, cr); %} 8698 %} 8699 8700 instruct mulL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 8701 %{ 8702 predicate(!UseAPX); 8703 match(Set dst (MulL dst src)); 8704 effect(KILL cr); 8705 8706 ins_cost(300); 8707 format %{ "imulq $dst, $src\t# long" %} 8708 ins_encode %{ 8709 __ imulq($dst$$Register, $src$$Register); 8710 %} 8711 ins_pipe(ialu_reg_reg_alu0); 8712 %} 8713 8714 instruct mulL_rReg_ndd(rRegL dst, rRegL src1, rRegL src2, rFlagsReg cr) 8715 %{ 8716 predicate(UseAPX); 8717 match(Set dst (MulL src1 src2)); 8718 effect(KILL cr); 8719 8720 ins_cost(300); 8721 format %{ "eimulq $dst, $src1, $src2\t# long ndd" %} 8722 ins_encode %{ 8723 __ eimulq($dst$$Register, $src1$$Register, $src2$$Register, false); 8724 %} 8725 ins_pipe(ialu_reg_reg_alu0); 8726 %} 8727 8728 instruct mulL_rReg_imm(rRegL dst, rRegL src, immL32 imm, rFlagsReg cr) 8729 %{ 8730 match(Set dst (MulL src imm)); 8731 effect(KILL cr); 8732 8733 ins_cost(300); 8734 format %{ "imulq $dst, $src, $imm\t# long" %} 8735 ins_encode %{ 8736 __ imulq($dst$$Register, $src$$Register, $imm$$constant); 8737 %} 8738 ins_pipe(ialu_reg_reg_alu0); 8739 %} 8740 8741 instruct mulL_mem(rRegL dst, memory src, rFlagsReg cr) 8742 %{ 8743 predicate(!UseAPX); 8744 match(Set dst (MulL dst (LoadL src))); 8745 effect(KILL cr); 8746 8747 ins_cost(350); 8748 format %{ "imulq $dst, $src\t# long" %} 8749 ins_encode %{ 8750 __ imulq($dst$$Register, $src$$Address); 8751 %} 8752 ins_pipe(ialu_reg_mem_alu0); 8753 %} 8754 8755 instruct mulL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr) 8756 %{ 8757 predicate(UseAPX); 8758 match(Set dst (MulL src1 (LoadL src2))); 8759 effect(KILL cr); 8760 8761 ins_cost(350); 8762 format %{ "eimulq $dst, $src1, $src2 \t# long" %} 8763 ins_encode %{ 8764 __ eimulq($dst$$Register, $src1$$Register, $src2$$Address, false); 8765 %} 8766 ins_pipe(ialu_reg_mem_alu0); 8767 %} 8768 8769 instruct mulL_mem_imm(rRegL dst, memory src, immL32 imm, rFlagsReg cr) 8770 %{ 8771 match(Set dst (MulL (LoadL src) imm)); 8772 effect(KILL cr); 8773 8774 ins_cost(300); 8775 format %{ "imulq $dst, $src, $imm\t# long" %} 8776 ins_encode %{ 8777 __ imulq($dst$$Register, $src$$Address, $imm$$constant); 8778 %} 8779 ins_pipe(ialu_reg_mem_alu0); 8780 %} 8781 8782 instruct mulHiL_rReg(rdx_RegL dst, rRegL src, rax_RegL rax, rFlagsReg cr) 8783 %{ 8784 match(Set dst (MulHiL src rax)); 8785 effect(USE_KILL rax, KILL cr); 8786 8787 ins_cost(300); 8788 format %{ "imulq RDX:RAX, RAX, $src\t# mulhi" %} 8789 ins_encode %{ 8790 __ imulq($src$$Register); 8791 %} 8792 ins_pipe(ialu_reg_reg_alu0); 8793 %} 8794 8795 instruct umulHiL_rReg(rdx_RegL dst, rRegL src, rax_RegL rax, rFlagsReg cr) 8796 %{ 8797 match(Set dst (UMulHiL src rax)); 8798 effect(USE_KILL rax, KILL cr); 8799 8800 ins_cost(300); 8801 format %{ "mulq RDX:RAX, RAX, $src\t# umulhi" %} 8802 ins_encode %{ 8803 __ mulq($src$$Register); 8804 %} 8805 ins_pipe(ialu_reg_reg_alu0); 8806 %} 8807 8808 instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 8809 rFlagsReg cr) 8810 %{ 8811 match(Set rax (DivI rax div)); 8812 effect(KILL rdx, KILL cr); 8813 8814 ins_cost(30*100+10*100); // XXX 8815 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 8816 "jne,s normal\n\t" 8817 "xorl rdx, rdx\n\t" 8818 "cmpl $div, -1\n\t" 8819 "je,s done\n" 8820 "normal: cdql\n\t" 8821 "idivl $div\n" 8822 "done:" %} 8823 ins_encode(cdql_enc(div)); 8824 ins_pipe(ialu_reg_reg_alu0); 8825 %} 8826 8827 instruct divL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 8828 rFlagsReg cr) 8829 %{ 8830 match(Set rax (DivL rax div)); 8831 effect(KILL rdx, KILL cr); 8832 8833 ins_cost(30*100+10*100); // XXX 8834 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 8835 "cmpq rax, rdx\n\t" 8836 "jne,s normal\n\t" 8837 "xorl rdx, rdx\n\t" 8838 "cmpq $div, -1\n\t" 8839 "je,s done\n" 8840 "normal: cdqq\n\t" 8841 "idivq $div\n" 8842 "done:" %} 8843 ins_encode(cdqq_enc(div)); 8844 ins_pipe(ialu_reg_reg_alu0); 8845 %} 8846 8847 instruct udivI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, rFlagsReg cr) 8848 %{ 8849 match(Set rax (UDivI rax div)); 8850 effect(KILL rdx, KILL cr); 8851 8852 ins_cost(300); 8853 format %{ "udivl $rax,$rax,$div\t# UDivI\n" %} 8854 ins_encode %{ 8855 __ udivI($rax$$Register, $div$$Register, $rdx$$Register); 8856 %} 8857 ins_pipe(ialu_reg_reg_alu0); 8858 %} 8859 8860 instruct udivL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, rFlagsReg cr) 8861 %{ 8862 match(Set rax (UDivL rax div)); 8863 effect(KILL rdx, KILL cr); 8864 8865 ins_cost(300); 8866 format %{ "udivq $rax,$rax,$div\t# UDivL\n" %} 8867 ins_encode %{ 8868 __ udivL($rax$$Register, $div$$Register, $rdx$$Register); 8869 %} 8870 ins_pipe(ialu_reg_reg_alu0); 8871 %} 8872 8873 // Integer DIVMOD with Register, both quotient and mod results 8874 instruct divModI_rReg_divmod(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 8875 rFlagsReg cr) 8876 %{ 8877 match(DivModI rax div); 8878 effect(KILL cr); 8879 8880 ins_cost(30*100+10*100); // XXX 8881 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 8882 "jne,s normal\n\t" 8883 "xorl rdx, rdx\n\t" 8884 "cmpl $div, -1\n\t" 8885 "je,s done\n" 8886 "normal: cdql\n\t" 8887 "idivl $div\n" 8888 "done:" %} 8889 ins_encode(cdql_enc(div)); 8890 ins_pipe(pipe_slow); 8891 %} 8892 8893 // Long DIVMOD with Register, both quotient and mod results 8894 instruct divModL_rReg_divmod(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 8895 rFlagsReg cr) 8896 %{ 8897 match(DivModL rax div); 8898 effect(KILL cr); 8899 8900 ins_cost(30*100+10*100); // XXX 8901 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 8902 "cmpq rax, rdx\n\t" 8903 "jne,s normal\n\t" 8904 "xorl rdx, rdx\n\t" 8905 "cmpq $div, -1\n\t" 8906 "je,s done\n" 8907 "normal: cdqq\n\t" 8908 "idivq $div\n" 8909 "done:" %} 8910 ins_encode(cdqq_enc(div)); 8911 ins_pipe(pipe_slow); 8912 %} 8913 8914 // Unsigned integer DIVMOD with Register, both quotient and mod results 8915 instruct udivModI_rReg_divmod(rax_RegI rax, no_rax_rdx_RegI tmp, rdx_RegI rdx, 8916 no_rax_rdx_RegI div, rFlagsReg cr) 8917 %{ 8918 match(UDivModI rax div); 8919 effect(TEMP tmp, KILL cr); 8920 8921 ins_cost(300); 8922 format %{ "udivl $rax,$rax,$div\t# begin UDivModI\n\t" 8923 "umodl $rdx,$rax,$div\t! using $tmp as TEMP # end UDivModI\n" 8924 %} 8925 ins_encode %{ 8926 __ udivmodI($rax$$Register, $div$$Register, $rdx$$Register, $tmp$$Register); 8927 %} 8928 ins_pipe(pipe_slow); 8929 %} 8930 8931 // Unsigned long DIVMOD with Register, both quotient and mod results 8932 instruct udivModL_rReg_divmod(rax_RegL rax, no_rax_rdx_RegL tmp, rdx_RegL rdx, 8933 no_rax_rdx_RegL div, rFlagsReg cr) 8934 %{ 8935 match(UDivModL rax div); 8936 effect(TEMP tmp, KILL cr); 8937 8938 ins_cost(300); 8939 format %{ "udivq $rax,$rax,$div\t# begin UDivModL\n\t" 8940 "umodq $rdx,$rax,$div\t! using $tmp as TEMP # end UDivModL\n" 8941 %} 8942 ins_encode %{ 8943 __ udivmodL($rax$$Register, $div$$Register, $rdx$$Register, $tmp$$Register); 8944 %} 8945 ins_pipe(pipe_slow); 8946 %} 8947 8948 instruct modI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, 8949 rFlagsReg cr) 8950 %{ 8951 match(Set rdx (ModI rax div)); 8952 effect(KILL rax, KILL cr); 8953 8954 ins_cost(300); // XXX 8955 format %{ "cmpl rax, 0x80000000\t# irem\n\t" 8956 "jne,s normal\n\t" 8957 "xorl rdx, rdx\n\t" 8958 "cmpl $div, -1\n\t" 8959 "je,s done\n" 8960 "normal: cdql\n\t" 8961 "idivl $div\n" 8962 "done:" %} 8963 ins_encode(cdql_enc(div)); 8964 ins_pipe(ialu_reg_reg_alu0); 8965 %} 8966 8967 instruct modL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, 8968 rFlagsReg cr) 8969 %{ 8970 match(Set rdx (ModL rax div)); 8971 effect(KILL rax, KILL cr); 8972 8973 ins_cost(300); // XXX 8974 format %{ "movq rdx, 0x8000000000000000\t# lrem\n\t" 8975 "cmpq rax, rdx\n\t" 8976 "jne,s normal\n\t" 8977 "xorl rdx, rdx\n\t" 8978 "cmpq $div, -1\n\t" 8979 "je,s done\n" 8980 "normal: cdqq\n\t" 8981 "idivq $div\n" 8982 "done:" %} 8983 ins_encode(cdqq_enc(div)); 8984 ins_pipe(ialu_reg_reg_alu0); 8985 %} 8986 8987 instruct umodI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, rFlagsReg cr) 8988 %{ 8989 match(Set rdx (UModI rax div)); 8990 effect(KILL rax, KILL cr); 8991 8992 ins_cost(300); 8993 format %{ "umodl $rdx,$rax,$div\t# UModI\n" %} 8994 ins_encode %{ 8995 __ umodI($rax$$Register, $div$$Register, $rdx$$Register); 8996 %} 8997 ins_pipe(ialu_reg_reg_alu0); 8998 %} 8999 9000 instruct umodL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, rFlagsReg cr) 9001 %{ 9002 match(Set rdx (UModL rax div)); 9003 effect(KILL rax, KILL cr); 9004 9005 ins_cost(300); 9006 format %{ "umodq $rdx,$rax,$div\t# UModL\n" %} 9007 ins_encode %{ 9008 __ umodL($rax$$Register, $div$$Register, $rdx$$Register); 9009 %} 9010 ins_pipe(ialu_reg_reg_alu0); 9011 %} 9012 9013 // Integer Shift Instructions 9014 // Shift Left by one, two, three 9015 instruct salI_rReg_immI2(rRegI dst, immI2 shift, rFlagsReg cr) 9016 %{ 9017 predicate(!UseAPX); 9018 match(Set dst (LShiftI dst shift)); 9019 effect(KILL cr); 9020 9021 format %{ "sall $dst, $shift" %} 9022 ins_encode %{ 9023 __ sall($dst$$Register, $shift$$constant); 9024 %} 9025 ins_pipe(ialu_reg); 9026 %} 9027 9028 // Shift Left by one, two, three 9029 instruct salI_rReg_immI2_ndd(rRegI dst, rRegI src, immI2 shift, rFlagsReg cr) 9030 %{ 9031 predicate(UseAPX); 9032 match(Set dst (LShiftI src shift)); 9033 effect(KILL cr); 9034 9035 format %{ "esall $dst, $src, $shift\t# int(ndd)" %} 9036 ins_encode %{ 9037 __ esall($dst$$Register, $src$$Register, $shift$$constant, false); 9038 %} 9039 ins_pipe(ialu_reg); 9040 %} 9041 9042 // Shift Left by 8-bit immediate 9043 instruct salI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 9044 %{ 9045 predicate(!UseAPX); 9046 match(Set dst (LShiftI dst shift)); 9047 effect(KILL cr); 9048 9049 format %{ "sall $dst, $shift" %} 9050 ins_encode %{ 9051 __ sall($dst$$Register, $shift$$constant); 9052 %} 9053 ins_pipe(ialu_reg); 9054 %} 9055 9056 // Shift Left by 8-bit immediate 9057 instruct salI_rReg_imm_ndd(rRegI dst, rRegI src, immI8 shift, rFlagsReg cr) 9058 %{ 9059 predicate(UseAPX); 9060 match(Set dst (LShiftI src shift)); 9061 effect(KILL cr); 9062 9063 format %{ "esall $dst, $src, $shift\t# int (ndd)" %} 9064 ins_encode %{ 9065 __ esall($dst$$Register, $src$$Register, $shift$$constant, false); 9066 %} 9067 ins_pipe(ialu_reg); 9068 %} 9069 9070 instruct salI_rReg_mem_imm_ndd(rRegI dst, memory src, immI8 shift, rFlagsReg cr) 9071 %{ 9072 predicate(UseAPX); 9073 match(Set dst (LShiftI (LoadI src) shift)); 9074 effect(KILL cr); 9075 9076 format %{ "esall $dst, $src, $shift\t# int (ndd)" %} 9077 ins_encode %{ 9078 __ esall($dst$$Register, $src$$Address, $shift$$constant, false); 9079 %} 9080 ins_pipe(ialu_reg); 9081 %} 9082 9083 // Shift Left by 8-bit immediate 9084 instruct salI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 9085 %{ 9086 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 9087 effect(KILL cr); 9088 9089 format %{ "sall $dst, $shift" %} 9090 ins_encode %{ 9091 __ sall($dst$$Address, $shift$$constant); 9092 %} 9093 ins_pipe(ialu_mem_imm); 9094 %} 9095 9096 // Shift Left by variable 9097 instruct salI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 9098 %{ 9099 predicate(!VM_Version::supports_bmi2()); 9100 match(Set dst (LShiftI dst shift)); 9101 effect(KILL cr); 9102 9103 format %{ "sall $dst, $shift" %} 9104 ins_encode %{ 9105 __ sall($dst$$Register); 9106 %} 9107 ins_pipe(ialu_reg_reg); 9108 %} 9109 9110 // Shift Left by variable 9111 instruct salI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 9112 %{ 9113 predicate(!VM_Version::supports_bmi2()); 9114 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 9115 effect(KILL cr); 9116 9117 format %{ "sall $dst, $shift" %} 9118 ins_encode %{ 9119 __ sall($dst$$Address); 9120 %} 9121 ins_pipe(ialu_mem_reg); 9122 %} 9123 9124 instruct salI_rReg_rReg(rRegI dst, rRegI src, rRegI shift) 9125 %{ 9126 predicate(VM_Version::supports_bmi2()); 9127 match(Set dst (LShiftI src shift)); 9128 9129 format %{ "shlxl $dst, $src, $shift" %} 9130 ins_encode %{ 9131 __ shlxl($dst$$Register, $src$$Register, $shift$$Register); 9132 %} 9133 ins_pipe(ialu_reg_reg); 9134 %} 9135 9136 instruct salI_mem_rReg(rRegI dst, memory src, rRegI shift) 9137 %{ 9138 predicate(VM_Version::supports_bmi2()); 9139 match(Set dst (LShiftI (LoadI src) shift)); 9140 ins_cost(175); 9141 format %{ "shlxl $dst, $src, $shift" %} 9142 ins_encode %{ 9143 __ shlxl($dst$$Register, $src$$Address, $shift$$Register); 9144 %} 9145 ins_pipe(ialu_reg_mem); 9146 %} 9147 9148 // Arithmetic Shift Right by 8-bit immediate 9149 instruct sarI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 9150 %{ 9151 predicate(!UseAPX); 9152 match(Set dst (RShiftI dst shift)); 9153 effect(KILL cr); 9154 9155 format %{ "sarl $dst, $shift" %} 9156 ins_encode %{ 9157 __ sarl($dst$$Register, $shift$$constant); 9158 %} 9159 ins_pipe(ialu_mem_imm); 9160 %} 9161 9162 // Arithmetic Shift Right by 8-bit immediate 9163 instruct sarI_rReg_imm_ndd(rRegI dst, rRegI src, immI8 shift, rFlagsReg cr) 9164 %{ 9165 predicate(UseAPX); 9166 match(Set dst (RShiftI src shift)); 9167 effect(KILL cr); 9168 9169 format %{ "esarl $dst, $src, $shift\t# int (ndd)" %} 9170 ins_encode %{ 9171 __ esarl($dst$$Register, $src$$Register, $shift$$constant, false); 9172 %} 9173 ins_pipe(ialu_mem_imm); 9174 %} 9175 9176 instruct sarI_rReg_mem_imm_ndd(rRegI dst, memory src, immI8 shift, rFlagsReg cr) 9177 %{ 9178 predicate(UseAPX); 9179 match(Set dst (RShiftI (LoadI src) shift)); 9180 effect(KILL cr); 9181 9182 format %{ "esarl $dst, $src, $shift\t# int (ndd)" %} 9183 ins_encode %{ 9184 __ esarl($dst$$Register, $src$$Address, $shift$$constant, false); 9185 %} 9186 ins_pipe(ialu_mem_imm); 9187 %} 9188 9189 // Arithmetic Shift Right by 8-bit immediate 9190 instruct sarI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 9191 %{ 9192 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 9193 effect(KILL cr); 9194 9195 format %{ "sarl $dst, $shift" %} 9196 ins_encode %{ 9197 __ sarl($dst$$Address, $shift$$constant); 9198 %} 9199 ins_pipe(ialu_mem_imm); 9200 %} 9201 9202 // Arithmetic Shift Right by variable 9203 instruct sarI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 9204 %{ 9205 predicate(!VM_Version::supports_bmi2()); 9206 match(Set dst (RShiftI dst shift)); 9207 effect(KILL cr); 9208 9209 format %{ "sarl $dst, $shift" %} 9210 ins_encode %{ 9211 __ sarl($dst$$Register); 9212 %} 9213 ins_pipe(ialu_reg_reg); 9214 %} 9215 9216 // Arithmetic Shift Right by variable 9217 instruct sarI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 9218 %{ 9219 predicate(!VM_Version::supports_bmi2()); 9220 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 9221 effect(KILL cr); 9222 9223 format %{ "sarl $dst, $shift" %} 9224 ins_encode %{ 9225 __ sarl($dst$$Address); 9226 %} 9227 ins_pipe(ialu_mem_reg); 9228 %} 9229 9230 instruct sarI_rReg_rReg(rRegI dst, rRegI src, rRegI shift) 9231 %{ 9232 predicate(VM_Version::supports_bmi2()); 9233 match(Set dst (RShiftI src shift)); 9234 9235 format %{ "sarxl $dst, $src, $shift" %} 9236 ins_encode %{ 9237 __ sarxl($dst$$Register, $src$$Register, $shift$$Register); 9238 %} 9239 ins_pipe(ialu_reg_reg); 9240 %} 9241 9242 instruct sarI_mem_rReg(rRegI dst, memory src, rRegI shift) 9243 %{ 9244 predicate(VM_Version::supports_bmi2()); 9245 match(Set dst (RShiftI (LoadI src) shift)); 9246 ins_cost(175); 9247 format %{ "sarxl $dst, $src, $shift" %} 9248 ins_encode %{ 9249 __ sarxl($dst$$Register, $src$$Address, $shift$$Register); 9250 %} 9251 ins_pipe(ialu_reg_mem); 9252 %} 9253 9254 // Logical Shift Right by 8-bit immediate 9255 instruct shrI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 9256 %{ 9257 predicate(!UseAPX); 9258 match(Set dst (URShiftI dst shift)); 9259 effect(KILL cr); 9260 9261 format %{ "shrl $dst, $shift" %} 9262 ins_encode %{ 9263 __ shrl($dst$$Register, $shift$$constant); 9264 %} 9265 ins_pipe(ialu_reg); 9266 %} 9267 9268 // Logical Shift Right by 8-bit immediate 9269 instruct shrI_rReg_imm_ndd(rRegI dst, rRegI src, immI8 shift, rFlagsReg cr) 9270 %{ 9271 predicate(UseAPX); 9272 match(Set dst (URShiftI src shift)); 9273 effect(KILL cr); 9274 9275 format %{ "eshrl $dst, $src, $shift\t # int (ndd)" %} 9276 ins_encode %{ 9277 __ eshrl($dst$$Register, $src$$Register, $shift$$constant, false); 9278 %} 9279 ins_pipe(ialu_reg); 9280 %} 9281 9282 instruct shrI_rReg_mem_imm_ndd(rRegI dst, memory src, immI8 shift, rFlagsReg cr) 9283 %{ 9284 predicate(UseAPX); 9285 match(Set dst (URShiftI (LoadI src) shift)); 9286 effect(KILL cr); 9287 9288 format %{ "eshrl $dst, $src, $shift\t # int (ndd)" %} 9289 ins_encode %{ 9290 __ eshrl($dst$$Register, $src$$Address, $shift$$constant, false); 9291 %} 9292 ins_pipe(ialu_reg); 9293 %} 9294 9295 // Logical Shift Right by 8-bit immediate 9296 instruct shrI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 9297 %{ 9298 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 9299 effect(KILL cr); 9300 9301 format %{ "shrl $dst, $shift" %} 9302 ins_encode %{ 9303 __ shrl($dst$$Address, $shift$$constant); 9304 %} 9305 ins_pipe(ialu_mem_imm); 9306 %} 9307 9308 // Logical Shift Right by variable 9309 instruct shrI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 9310 %{ 9311 predicate(!VM_Version::supports_bmi2()); 9312 match(Set dst (URShiftI dst shift)); 9313 effect(KILL cr); 9314 9315 format %{ "shrl $dst, $shift" %} 9316 ins_encode %{ 9317 __ shrl($dst$$Register); 9318 %} 9319 ins_pipe(ialu_reg_reg); 9320 %} 9321 9322 // Logical Shift Right by variable 9323 instruct shrI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 9324 %{ 9325 predicate(!VM_Version::supports_bmi2()); 9326 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 9327 effect(KILL cr); 9328 9329 format %{ "shrl $dst, $shift" %} 9330 ins_encode %{ 9331 __ shrl($dst$$Address); 9332 %} 9333 ins_pipe(ialu_mem_reg); 9334 %} 9335 9336 instruct shrI_rReg_rReg(rRegI dst, rRegI src, rRegI shift) 9337 %{ 9338 predicate(VM_Version::supports_bmi2()); 9339 match(Set dst (URShiftI src shift)); 9340 9341 format %{ "shrxl $dst, $src, $shift" %} 9342 ins_encode %{ 9343 __ shrxl($dst$$Register, $src$$Register, $shift$$Register); 9344 %} 9345 ins_pipe(ialu_reg_reg); 9346 %} 9347 9348 instruct shrI_mem_rReg(rRegI dst, memory src, rRegI shift) 9349 %{ 9350 predicate(VM_Version::supports_bmi2()); 9351 match(Set dst (URShiftI (LoadI src) shift)); 9352 ins_cost(175); 9353 format %{ "shrxl $dst, $src, $shift" %} 9354 ins_encode %{ 9355 __ shrxl($dst$$Register, $src$$Address, $shift$$Register); 9356 %} 9357 ins_pipe(ialu_reg_mem); 9358 %} 9359 9360 // Long Shift Instructions 9361 // Shift Left by one, two, three 9362 instruct salL_rReg_immI2(rRegL dst, immI2 shift, rFlagsReg cr) 9363 %{ 9364 predicate(!UseAPX); 9365 match(Set dst (LShiftL dst shift)); 9366 effect(KILL cr); 9367 9368 format %{ "salq $dst, $shift" %} 9369 ins_encode %{ 9370 __ salq($dst$$Register, $shift$$constant); 9371 %} 9372 ins_pipe(ialu_reg); 9373 %} 9374 9375 // Shift Left by one, two, three 9376 instruct salL_rReg_immI2_ndd(rRegL dst, rRegL src, immI2 shift, rFlagsReg cr) 9377 %{ 9378 predicate(UseAPX); 9379 match(Set dst (LShiftL src shift)); 9380 effect(KILL cr); 9381 9382 format %{ "esalq $dst, $src, $shift\t# long (ndd)" %} 9383 ins_encode %{ 9384 __ esalq($dst$$Register, $src$$Register, $shift$$constant, false); 9385 %} 9386 ins_pipe(ialu_reg); 9387 %} 9388 9389 // Shift Left by 8-bit immediate 9390 instruct salL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 9391 %{ 9392 predicate(!UseAPX); 9393 match(Set dst (LShiftL dst shift)); 9394 effect(KILL cr); 9395 9396 format %{ "salq $dst, $shift" %} 9397 ins_encode %{ 9398 __ salq($dst$$Register, $shift$$constant); 9399 %} 9400 ins_pipe(ialu_reg); 9401 %} 9402 9403 // Shift Left by 8-bit immediate 9404 instruct salL_rReg_imm_ndd(rRegL dst, rRegL src, immI8 shift, rFlagsReg cr) 9405 %{ 9406 predicate(UseAPX); 9407 match(Set dst (LShiftL src shift)); 9408 effect(KILL cr); 9409 9410 format %{ "esalq $dst, $src, $shift\t# long (ndd)" %} 9411 ins_encode %{ 9412 __ esalq($dst$$Register, $src$$Register, $shift$$constant, false); 9413 %} 9414 ins_pipe(ialu_reg); 9415 %} 9416 9417 instruct salL_rReg_mem_imm_ndd(rRegL dst, memory src, immI8 shift, rFlagsReg cr) 9418 %{ 9419 predicate(UseAPX); 9420 match(Set dst (LShiftL (LoadL src) shift)); 9421 effect(KILL cr); 9422 9423 format %{ "esalq $dst, $src, $shift\t# long (ndd)" %} 9424 ins_encode %{ 9425 __ esalq($dst$$Register, $src$$Address, $shift$$constant, false); 9426 %} 9427 ins_pipe(ialu_reg); 9428 %} 9429 9430 // Shift Left by 8-bit immediate 9431 instruct salL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 9432 %{ 9433 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 9434 effect(KILL cr); 9435 9436 format %{ "salq $dst, $shift" %} 9437 ins_encode %{ 9438 __ salq($dst$$Address, $shift$$constant); 9439 %} 9440 ins_pipe(ialu_mem_imm); 9441 %} 9442 9443 // Shift Left by variable 9444 instruct salL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 9445 %{ 9446 predicate(!VM_Version::supports_bmi2()); 9447 match(Set dst (LShiftL dst shift)); 9448 effect(KILL cr); 9449 9450 format %{ "salq $dst, $shift" %} 9451 ins_encode %{ 9452 __ salq($dst$$Register); 9453 %} 9454 ins_pipe(ialu_reg_reg); 9455 %} 9456 9457 // Shift Left by variable 9458 instruct salL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 9459 %{ 9460 predicate(!VM_Version::supports_bmi2()); 9461 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 9462 effect(KILL cr); 9463 9464 format %{ "salq $dst, $shift" %} 9465 ins_encode %{ 9466 __ salq($dst$$Address); 9467 %} 9468 ins_pipe(ialu_mem_reg); 9469 %} 9470 9471 instruct salL_rReg_rReg(rRegL dst, rRegL src, rRegI shift) 9472 %{ 9473 predicate(VM_Version::supports_bmi2()); 9474 match(Set dst (LShiftL src shift)); 9475 9476 format %{ "shlxq $dst, $src, $shift" %} 9477 ins_encode %{ 9478 __ shlxq($dst$$Register, $src$$Register, $shift$$Register); 9479 %} 9480 ins_pipe(ialu_reg_reg); 9481 %} 9482 9483 instruct salL_mem_rReg(rRegL dst, memory src, rRegI shift) 9484 %{ 9485 predicate(VM_Version::supports_bmi2()); 9486 match(Set dst (LShiftL (LoadL src) shift)); 9487 ins_cost(175); 9488 format %{ "shlxq $dst, $src, $shift" %} 9489 ins_encode %{ 9490 __ shlxq($dst$$Register, $src$$Address, $shift$$Register); 9491 %} 9492 ins_pipe(ialu_reg_mem); 9493 %} 9494 9495 // Arithmetic Shift Right by 8-bit immediate 9496 instruct sarL_rReg_imm(rRegL dst, immI shift, rFlagsReg cr) 9497 %{ 9498 predicate(!UseAPX); 9499 match(Set dst (RShiftL dst shift)); 9500 effect(KILL cr); 9501 9502 format %{ "sarq $dst, $shift" %} 9503 ins_encode %{ 9504 __ sarq($dst$$Register, (unsigned char)($shift$$constant & 0x3F)); 9505 %} 9506 ins_pipe(ialu_mem_imm); 9507 %} 9508 9509 // Arithmetic Shift Right by 8-bit immediate 9510 instruct sarL_rReg_imm_ndd(rRegL dst, rRegL src, immI shift, rFlagsReg cr) 9511 %{ 9512 predicate(UseAPX); 9513 match(Set dst (RShiftL src shift)); 9514 effect(KILL cr); 9515 9516 format %{ "esarq $dst, $src, $shift\t# long (ndd)" %} 9517 ins_encode %{ 9518 __ esarq($dst$$Register, $src$$Register, (unsigned char)($shift$$constant & 0x3F), false); 9519 %} 9520 ins_pipe(ialu_mem_imm); 9521 %} 9522 9523 instruct sarL_rReg_mem_imm_ndd(rRegL dst, memory src, immI shift, rFlagsReg cr) 9524 %{ 9525 predicate(UseAPX); 9526 match(Set dst (RShiftL (LoadL src) shift)); 9527 effect(KILL cr); 9528 9529 format %{ "esarq $dst, $src, $shift\t# long (ndd)" %} 9530 ins_encode %{ 9531 __ esarq($dst$$Register, $src$$Address, (unsigned char)($shift$$constant & 0x3F), false); 9532 %} 9533 ins_pipe(ialu_mem_imm); 9534 %} 9535 9536 // Arithmetic Shift Right by 8-bit immediate 9537 instruct sarL_mem_imm(memory dst, immI shift, rFlagsReg cr) 9538 %{ 9539 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 9540 effect(KILL cr); 9541 9542 format %{ "sarq $dst, $shift" %} 9543 ins_encode %{ 9544 __ sarq($dst$$Address, (unsigned char)($shift$$constant & 0x3F)); 9545 %} 9546 ins_pipe(ialu_mem_imm); 9547 %} 9548 9549 // Arithmetic Shift Right by variable 9550 instruct sarL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 9551 %{ 9552 predicate(!VM_Version::supports_bmi2()); 9553 match(Set dst (RShiftL dst shift)); 9554 effect(KILL cr); 9555 9556 format %{ "sarq $dst, $shift" %} 9557 ins_encode %{ 9558 __ sarq($dst$$Register); 9559 %} 9560 ins_pipe(ialu_reg_reg); 9561 %} 9562 9563 // Arithmetic Shift Right by variable 9564 instruct sarL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 9565 %{ 9566 predicate(!VM_Version::supports_bmi2()); 9567 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 9568 effect(KILL cr); 9569 9570 format %{ "sarq $dst, $shift" %} 9571 ins_encode %{ 9572 __ sarq($dst$$Address); 9573 %} 9574 ins_pipe(ialu_mem_reg); 9575 %} 9576 9577 instruct sarL_rReg_rReg(rRegL dst, rRegL src, rRegI shift) 9578 %{ 9579 predicate(VM_Version::supports_bmi2()); 9580 match(Set dst (RShiftL src shift)); 9581 9582 format %{ "sarxq $dst, $src, $shift" %} 9583 ins_encode %{ 9584 __ sarxq($dst$$Register, $src$$Register, $shift$$Register); 9585 %} 9586 ins_pipe(ialu_reg_reg); 9587 %} 9588 9589 instruct sarL_mem_rReg(rRegL dst, memory src, rRegI shift) 9590 %{ 9591 predicate(VM_Version::supports_bmi2()); 9592 match(Set dst (RShiftL (LoadL src) shift)); 9593 ins_cost(175); 9594 format %{ "sarxq $dst, $src, $shift" %} 9595 ins_encode %{ 9596 __ sarxq($dst$$Register, $src$$Address, $shift$$Register); 9597 %} 9598 ins_pipe(ialu_reg_mem); 9599 %} 9600 9601 // Logical Shift Right by 8-bit immediate 9602 instruct shrL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 9603 %{ 9604 predicate(!UseAPX); 9605 match(Set dst (URShiftL dst shift)); 9606 effect(KILL cr); 9607 9608 format %{ "shrq $dst, $shift" %} 9609 ins_encode %{ 9610 __ shrq($dst$$Register, $shift$$constant); 9611 %} 9612 ins_pipe(ialu_reg); 9613 %} 9614 9615 // Logical Shift Right by 8-bit immediate 9616 instruct shrL_rReg_imm_ndd(rRegL dst, rRegL src, immI8 shift, rFlagsReg cr) 9617 %{ 9618 predicate(UseAPX); 9619 match(Set dst (URShiftL src shift)); 9620 effect(KILL cr); 9621 9622 format %{ "eshrq $dst, $src, $shift\t# long (ndd)" %} 9623 ins_encode %{ 9624 __ eshrq($dst$$Register, $src$$Register, $shift$$constant, false); 9625 %} 9626 ins_pipe(ialu_reg); 9627 %} 9628 9629 instruct shrL_rReg_mem_imm_ndd(rRegL dst, memory src, immI8 shift, rFlagsReg cr) 9630 %{ 9631 predicate(UseAPX); 9632 match(Set dst (URShiftL (LoadL src) shift)); 9633 effect(KILL cr); 9634 9635 format %{ "eshrq $dst, $src, $shift\t# long (ndd)" %} 9636 ins_encode %{ 9637 __ eshrq($dst$$Register, $src$$Address, $shift$$constant, false); 9638 %} 9639 ins_pipe(ialu_reg); 9640 %} 9641 9642 // Logical Shift Right by 8-bit immediate 9643 instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 9644 %{ 9645 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 9646 effect(KILL cr); 9647 9648 format %{ "shrq $dst, $shift" %} 9649 ins_encode %{ 9650 __ shrq($dst$$Address, $shift$$constant); 9651 %} 9652 ins_pipe(ialu_mem_imm); 9653 %} 9654 9655 // Logical Shift Right by variable 9656 instruct shrL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 9657 %{ 9658 predicate(!VM_Version::supports_bmi2()); 9659 match(Set dst (URShiftL dst shift)); 9660 effect(KILL cr); 9661 9662 format %{ "shrq $dst, $shift" %} 9663 ins_encode %{ 9664 __ shrq($dst$$Register); 9665 %} 9666 ins_pipe(ialu_reg_reg); 9667 %} 9668 9669 // Logical Shift Right by variable 9670 instruct shrL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 9671 %{ 9672 predicate(!VM_Version::supports_bmi2()); 9673 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 9674 effect(KILL cr); 9675 9676 format %{ "shrq $dst, $shift" %} 9677 ins_encode %{ 9678 __ shrq($dst$$Address); 9679 %} 9680 ins_pipe(ialu_mem_reg); 9681 %} 9682 9683 instruct shrL_rReg_rReg(rRegL dst, rRegL src, rRegI shift) 9684 %{ 9685 predicate(VM_Version::supports_bmi2()); 9686 match(Set dst (URShiftL src shift)); 9687 9688 format %{ "shrxq $dst, $src, $shift" %} 9689 ins_encode %{ 9690 __ shrxq($dst$$Register, $src$$Register, $shift$$Register); 9691 %} 9692 ins_pipe(ialu_reg_reg); 9693 %} 9694 9695 instruct shrL_mem_rReg(rRegL dst, memory src, rRegI shift) 9696 %{ 9697 predicate(VM_Version::supports_bmi2()); 9698 match(Set dst (URShiftL (LoadL src) shift)); 9699 ins_cost(175); 9700 format %{ "shrxq $dst, $src, $shift" %} 9701 ins_encode %{ 9702 __ shrxq($dst$$Register, $src$$Address, $shift$$Register); 9703 %} 9704 ins_pipe(ialu_reg_mem); 9705 %} 9706 9707 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24. 9708 // This idiom is used by the compiler for the i2b bytecode. 9709 instruct i2b(rRegI dst, rRegI src, immI_24 twentyfour) 9710 %{ 9711 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour)); 9712 9713 format %{ "movsbl $dst, $src\t# i2b" %} 9714 ins_encode %{ 9715 __ movsbl($dst$$Register, $src$$Register); 9716 %} 9717 ins_pipe(ialu_reg_reg); 9718 %} 9719 9720 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16. 9721 // This idiom is used by the compiler the i2s bytecode. 9722 instruct i2s(rRegI dst, rRegI src, immI_16 sixteen) 9723 %{ 9724 match(Set dst (RShiftI (LShiftI src sixteen) sixteen)); 9725 9726 format %{ "movswl $dst, $src\t# i2s" %} 9727 ins_encode %{ 9728 __ movswl($dst$$Register, $src$$Register); 9729 %} 9730 ins_pipe(ialu_reg_reg); 9731 %} 9732 9733 // ROL/ROR instructions 9734 9735 // Rotate left by constant. 9736 instruct rolI_immI8_legacy(rRegI dst, immI8 shift, rFlagsReg cr) 9737 %{ 9738 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 9739 match(Set dst (RotateLeft dst shift)); 9740 effect(KILL cr); 9741 format %{ "roll $dst, $shift" %} 9742 ins_encode %{ 9743 __ roll($dst$$Register, $shift$$constant); 9744 %} 9745 ins_pipe(ialu_reg); 9746 %} 9747 9748 instruct rolI_immI8(rRegI dst, rRegI src, immI8 shift) 9749 %{ 9750 predicate(!UseAPX && VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 9751 match(Set dst (RotateLeft src shift)); 9752 format %{ "rolxl $dst, $src, $shift" %} 9753 ins_encode %{ 9754 int shift = 32 - ($shift$$constant & 31); 9755 __ rorxl($dst$$Register, $src$$Register, shift); 9756 %} 9757 ins_pipe(ialu_reg_reg); 9758 %} 9759 9760 instruct rolI_mem_immI8(rRegI dst, memory src, immI8 shift) 9761 %{ 9762 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 9763 match(Set dst (RotateLeft (LoadI src) shift)); 9764 ins_cost(175); 9765 format %{ "rolxl $dst, $src, $shift" %} 9766 ins_encode %{ 9767 int shift = 32 - ($shift$$constant & 31); 9768 __ rorxl($dst$$Register, $src$$Address, shift); 9769 %} 9770 ins_pipe(ialu_reg_mem); 9771 %} 9772 9773 // Rotate Left by variable 9774 instruct rolI_rReg_Var(rRegI dst, rcx_RegI shift, rFlagsReg cr) 9775 %{ 9776 predicate(!UseAPX && n->bottom_type()->basic_type() == T_INT); 9777 match(Set dst (RotateLeft dst shift)); 9778 effect(KILL cr); 9779 format %{ "roll $dst, $shift" %} 9780 ins_encode %{ 9781 __ roll($dst$$Register); 9782 %} 9783 ins_pipe(ialu_reg_reg); 9784 %} 9785 9786 // Rotate Left by variable 9787 instruct rolI_rReg_Var_ndd(rRegI dst, rRegI src, rcx_RegI shift, rFlagsReg cr) 9788 %{ 9789 predicate(UseAPX && n->bottom_type()->basic_type() == T_INT); 9790 match(Set dst (RotateLeft src shift)); 9791 effect(KILL cr); 9792 9793 format %{ "eroll $dst, $src, $shift\t# rotate left (int ndd)" %} 9794 ins_encode %{ 9795 __ eroll($dst$$Register, $src$$Register, false); 9796 %} 9797 ins_pipe(ialu_reg_reg); 9798 %} 9799 9800 // Rotate Right by constant. 9801 instruct rorI_immI8_legacy(rRegI dst, immI8 shift, rFlagsReg cr) 9802 %{ 9803 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 9804 match(Set dst (RotateRight dst shift)); 9805 effect(KILL cr); 9806 format %{ "rorl $dst, $shift" %} 9807 ins_encode %{ 9808 __ rorl($dst$$Register, $shift$$constant); 9809 %} 9810 ins_pipe(ialu_reg); 9811 %} 9812 9813 // Rotate Right by constant. 9814 instruct rorI_immI8(rRegI dst, rRegI src, immI8 shift) 9815 %{ 9816 predicate(!UseAPX && VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 9817 match(Set dst (RotateRight src shift)); 9818 format %{ "rorxl $dst, $src, $shift" %} 9819 ins_encode %{ 9820 __ rorxl($dst$$Register, $src$$Register, $shift$$constant); 9821 %} 9822 ins_pipe(ialu_reg_reg); 9823 %} 9824 9825 instruct rorI_mem_immI8(rRegI dst, memory src, immI8 shift) 9826 %{ 9827 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 9828 match(Set dst (RotateRight (LoadI src) shift)); 9829 ins_cost(175); 9830 format %{ "rorxl $dst, $src, $shift" %} 9831 ins_encode %{ 9832 __ rorxl($dst$$Register, $src$$Address, $shift$$constant); 9833 %} 9834 ins_pipe(ialu_reg_mem); 9835 %} 9836 9837 // Rotate Right by variable 9838 instruct rorI_rReg_Var(rRegI dst, rcx_RegI shift, rFlagsReg cr) 9839 %{ 9840 predicate(!UseAPX && n->bottom_type()->basic_type() == T_INT); 9841 match(Set dst (RotateRight dst shift)); 9842 effect(KILL cr); 9843 format %{ "rorl $dst, $shift" %} 9844 ins_encode %{ 9845 __ rorl($dst$$Register); 9846 %} 9847 ins_pipe(ialu_reg_reg); 9848 %} 9849 9850 // Rotate Right by variable 9851 instruct rorI_rReg_Var_ndd(rRegI dst, rRegI src, rcx_RegI shift, rFlagsReg cr) 9852 %{ 9853 predicate(UseAPX && n->bottom_type()->basic_type() == T_INT); 9854 match(Set dst (RotateRight src shift)); 9855 effect(KILL cr); 9856 9857 format %{ "erorl $dst, $src, $shift\t# rotate right(int ndd)" %} 9858 ins_encode %{ 9859 __ erorl($dst$$Register, $src$$Register, false); 9860 %} 9861 ins_pipe(ialu_reg_reg); 9862 %} 9863 9864 // Rotate Left by constant. 9865 instruct rolL_immI8_legacy(rRegL dst, immI8 shift, rFlagsReg cr) 9866 %{ 9867 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 9868 match(Set dst (RotateLeft dst shift)); 9869 effect(KILL cr); 9870 format %{ "rolq $dst, $shift" %} 9871 ins_encode %{ 9872 __ rolq($dst$$Register, $shift$$constant); 9873 %} 9874 ins_pipe(ialu_reg); 9875 %} 9876 9877 instruct rolL_immI8(rRegL dst, rRegL src, immI8 shift) 9878 %{ 9879 predicate(!UseAPX && VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 9880 match(Set dst (RotateLeft src shift)); 9881 format %{ "rolxq $dst, $src, $shift" %} 9882 ins_encode %{ 9883 int shift = 64 - ($shift$$constant & 63); 9884 __ rorxq($dst$$Register, $src$$Register, shift); 9885 %} 9886 ins_pipe(ialu_reg_reg); 9887 %} 9888 9889 instruct rolL_mem_immI8(rRegL dst, memory src, immI8 shift) 9890 %{ 9891 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 9892 match(Set dst (RotateLeft (LoadL src) shift)); 9893 ins_cost(175); 9894 format %{ "rolxq $dst, $src, $shift" %} 9895 ins_encode %{ 9896 int shift = 64 - ($shift$$constant & 63); 9897 __ rorxq($dst$$Register, $src$$Address, shift); 9898 %} 9899 ins_pipe(ialu_reg_mem); 9900 %} 9901 9902 // Rotate Left by variable 9903 instruct rolL_rReg_Var(rRegL dst, rcx_RegI shift, rFlagsReg cr) 9904 %{ 9905 predicate(!UseAPX && n->bottom_type()->basic_type() == T_LONG); 9906 match(Set dst (RotateLeft dst shift)); 9907 effect(KILL cr); 9908 format %{ "rolq $dst, $shift" %} 9909 ins_encode %{ 9910 __ rolq($dst$$Register); 9911 %} 9912 ins_pipe(ialu_reg_reg); 9913 %} 9914 9915 // Rotate Left by variable 9916 instruct rolL_rReg_Var_ndd(rRegL dst, rRegL src, rcx_RegI shift, rFlagsReg cr) 9917 %{ 9918 predicate(UseAPX && n->bottom_type()->basic_type() == T_LONG); 9919 match(Set dst (RotateLeft src shift)); 9920 effect(KILL cr); 9921 9922 format %{ "erolq $dst, $src, $shift\t# rotate left(long ndd)" %} 9923 ins_encode %{ 9924 __ erolq($dst$$Register, $src$$Register, false); 9925 %} 9926 ins_pipe(ialu_reg_reg); 9927 %} 9928 9929 // Rotate Right by constant. 9930 instruct rorL_immI8_legacy(rRegL dst, immI8 shift, rFlagsReg cr) 9931 %{ 9932 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 9933 match(Set dst (RotateRight dst shift)); 9934 effect(KILL cr); 9935 format %{ "rorq $dst, $shift" %} 9936 ins_encode %{ 9937 __ rorq($dst$$Register, $shift$$constant); 9938 %} 9939 ins_pipe(ialu_reg); 9940 %} 9941 9942 // Rotate Right by constant 9943 instruct rorL_immI8(rRegL dst, rRegL src, immI8 shift) 9944 %{ 9945 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 9946 match(Set dst (RotateRight src shift)); 9947 format %{ "rorxq $dst, $src, $shift" %} 9948 ins_encode %{ 9949 __ rorxq($dst$$Register, $src$$Register, $shift$$constant); 9950 %} 9951 ins_pipe(ialu_reg_reg); 9952 %} 9953 9954 instruct rorL_mem_immI8(rRegL dst, memory src, immI8 shift) 9955 %{ 9956 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 9957 match(Set dst (RotateRight (LoadL src) shift)); 9958 ins_cost(175); 9959 format %{ "rorxq $dst, $src, $shift" %} 9960 ins_encode %{ 9961 __ rorxq($dst$$Register, $src$$Address, $shift$$constant); 9962 %} 9963 ins_pipe(ialu_reg_mem); 9964 %} 9965 9966 // Rotate Right by variable 9967 instruct rorL_rReg_Var(rRegL dst, rcx_RegI shift, rFlagsReg cr) 9968 %{ 9969 predicate(!UseAPX && n->bottom_type()->basic_type() == T_LONG); 9970 match(Set dst (RotateRight dst shift)); 9971 effect(KILL cr); 9972 format %{ "rorq $dst, $shift" %} 9973 ins_encode %{ 9974 __ rorq($dst$$Register); 9975 %} 9976 ins_pipe(ialu_reg_reg); 9977 %} 9978 9979 // Rotate Right by variable 9980 instruct rorL_rReg_Var_ndd(rRegL dst, rRegL src, rcx_RegI shift, rFlagsReg cr) 9981 %{ 9982 predicate(UseAPX && n->bottom_type()->basic_type() == T_LONG); 9983 match(Set dst (RotateRight src shift)); 9984 effect(KILL cr); 9985 9986 format %{ "erorq $dst, $src, $shift\t# rotate right(long ndd)" %} 9987 ins_encode %{ 9988 __ erorq($dst$$Register, $src$$Register, false); 9989 %} 9990 ins_pipe(ialu_reg_reg); 9991 %} 9992 9993 //----------------------------- CompressBits/ExpandBits ------------------------ 9994 9995 instruct compressBitsL_reg(rRegL dst, rRegL src, rRegL mask) %{ 9996 predicate(n->bottom_type()->isa_long()); 9997 match(Set dst (CompressBits src mask)); 9998 format %{ "pextq $dst, $src, $mask\t! parallel bit extract" %} 9999 ins_encode %{ 10000 __ pextq($dst$$Register, $src$$Register, $mask$$Register); 10001 %} 10002 ins_pipe( pipe_slow ); 10003 %} 10004 10005 instruct expandBitsL_reg(rRegL dst, rRegL src, rRegL mask) %{ 10006 predicate(n->bottom_type()->isa_long()); 10007 match(Set dst (ExpandBits src mask)); 10008 format %{ "pdepq $dst, $src, $mask\t! parallel bit deposit" %} 10009 ins_encode %{ 10010 __ pdepq($dst$$Register, $src$$Register, $mask$$Register); 10011 %} 10012 ins_pipe( pipe_slow ); 10013 %} 10014 10015 instruct compressBitsL_mem(rRegL dst, rRegL src, memory mask) %{ 10016 predicate(n->bottom_type()->isa_long()); 10017 match(Set dst (CompressBits src (LoadL mask))); 10018 format %{ "pextq $dst, $src, $mask\t! parallel bit extract" %} 10019 ins_encode %{ 10020 __ pextq($dst$$Register, $src$$Register, $mask$$Address); 10021 %} 10022 ins_pipe( pipe_slow ); 10023 %} 10024 10025 instruct expandBitsL_mem(rRegL dst, rRegL src, memory mask) %{ 10026 predicate(n->bottom_type()->isa_long()); 10027 match(Set dst (ExpandBits src (LoadL mask))); 10028 format %{ "pdepq $dst, $src, $mask\t! parallel bit deposit" %} 10029 ins_encode %{ 10030 __ pdepq($dst$$Register, $src$$Register, $mask$$Address); 10031 %} 10032 ins_pipe( pipe_slow ); 10033 %} 10034 10035 10036 // Logical Instructions 10037 10038 // Integer Logical Instructions 10039 10040 // And Instructions 10041 // And Register with Register 10042 instruct andI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 10043 %{ 10044 predicate(!UseAPX); 10045 match(Set dst (AndI dst src)); 10046 effect(KILL cr); 10047 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10048 10049 format %{ "andl $dst, $src\t# int" %} 10050 ins_encode %{ 10051 __ andl($dst$$Register, $src$$Register); 10052 %} 10053 ins_pipe(ialu_reg_reg); 10054 %} 10055 10056 // And Register with Register using New Data Destination (NDD) 10057 instruct andI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr) 10058 %{ 10059 predicate(UseAPX); 10060 match(Set dst (AndI src1 src2)); 10061 effect(KILL cr); 10062 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10063 10064 format %{ "eandl $dst, $src1, $src2\t# int ndd" %} 10065 ins_encode %{ 10066 __ eandl($dst$$Register, $src1$$Register, $src2$$Register, false); 10067 10068 %} 10069 ins_pipe(ialu_reg_reg); 10070 %} 10071 10072 // And Register with Immediate 255 10073 instruct andI_rReg_imm255(rRegI dst, rRegI src, immI_255 mask) 10074 %{ 10075 match(Set dst (AndI src mask)); 10076 10077 format %{ "movzbl $dst, $src\t# int & 0xFF" %} 10078 ins_encode %{ 10079 __ movzbl($dst$$Register, $src$$Register); 10080 %} 10081 ins_pipe(ialu_reg); 10082 %} 10083 10084 // And Register with Immediate 255 and promote to long 10085 instruct andI2L_rReg_imm255(rRegL dst, rRegI src, immI_255 mask) 10086 %{ 10087 match(Set dst (ConvI2L (AndI src mask))); 10088 10089 format %{ "movzbl $dst, $src\t# int & 0xFF -> long" %} 10090 ins_encode %{ 10091 __ movzbl($dst$$Register, $src$$Register); 10092 %} 10093 ins_pipe(ialu_reg); 10094 %} 10095 10096 // And Register with Immediate 65535 10097 instruct andI_rReg_imm65535(rRegI dst, rRegI src, immI_65535 mask) 10098 %{ 10099 match(Set dst (AndI src mask)); 10100 10101 format %{ "movzwl $dst, $src\t# int & 0xFFFF" %} 10102 ins_encode %{ 10103 __ movzwl($dst$$Register, $src$$Register); 10104 %} 10105 ins_pipe(ialu_reg); 10106 %} 10107 10108 // And Register with Immediate 65535 and promote to long 10109 instruct andI2L_rReg_imm65535(rRegL dst, rRegI src, immI_65535 mask) 10110 %{ 10111 match(Set dst (ConvI2L (AndI src mask))); 10112 10113 format %{ "movzwl $dst, $src\t# int & 0xFFFF -> long" %} 10114 ins_encode %{ 10115 __ movzwl($dst$$Register, $src$$Register); 10116 %} 10117 ins_pipe(ialu_reg); 10118 %} 10119 10120 // Can skip int2long conversions after AND with small bitmask 10121 instruct convI2LAndI_reg_immIbitmask(rRegL dst, rRegI src, immI_Pow2M1 mask, rRegI tmp, rFlagsReg cr) 10122 %{ 10123 predicate(VM_Version::supports_bmi2()); 10124 ins_cost(125); 10125 effect(TEMP tmp, KILL cr); 10126 match(Set dst (ConvI2L (AndI src mask))); 10127 format %{ "bzhiq $dst, $src, $mask \t# using $tmp as TEMP, int & immI_Pow2M1 -> long" %} 10128 ins_encode %{ 10129 __ movl($tmp$$Register, exact_log2($mask$$constant + 1)); 10130 __ bzhiq($dst$$Register, $src$$Register, $tmp$$Register); 10131 %} 10132 ins_pipe(ialu_reg_reg); 10133 %} 10134 10135 // And Register with Immediate 10136 instruct andI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 10137 %{ 10138 predicate(!UseAPX); 10139 match(Set dst (AndI dst src)); 10140 effect(KILL cr); 10141 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10142 10143 format %{ "andl $dst, $src\t# int" %} 10144 ins_encode %{ 10145 __ andl($dst$$Register, $src$$constant); 10146 %} 10147 ins_pipe(ialu_reg); 10148 %} 10149 10150 instruct andI_rReg_rReg_imm_ndd(rRegI dst, rRegI src1, immI src2, rFlagsReg cr) 10151 %{ 10152 predicate(UseAPX); 10153 match(Set dst (AndI src1 src2)); 10154 effect(KILL cr); 10155 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10156 10157 format %{ "eandl $dst, $src1, $src2\t# int ndd" %} 10158 ins_encode %{ 10159 __ eandl($dst$$Register, $src1$$Register, $src2$$constant, false); 10160 %} 10161 ins_pipe(ialu_reg); 10162 %} 10163 10164 instruct andI_rReg_mem_imm_ndd(rRegI dst, memory src1, immI src2, rFlagsReg cr) 10165 %{ 10166 predicate(UseAPX); 10167 match(Set dst (AndI (LoadI src1) src2)); 10168 effect(KILL cr); 10169 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10170 10171 format %{ "eandl $dst, $src1, $src2\t# int ndd" %} 10172 ins_encode %{ 10173 __ eandl($dst$$Register, $src1$$Address, $src2$$constant, false); 10174 %} 10175 ins_pipe(ialu_reg); 10176 %} 10177 10178 // And Register with Memory 10179 instruct andI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 10180 %{ 10181 predicate(!UseAPX); 10182 match(Set dst (AndI dst (LoadI src))); 10183 effect(KILL cr); 10184 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10185 10186 ins_cost(150); 10187 format %{ "andl $dst, $src\t# int" %} 10188 ins_encode %{ 10189 __ andl($dst$$Register, $src$$Address); 10190 %} 10191 ins_pipe(ialu_reg_mem); 10192 %} 10193 10194 instruct andI_rReg_rReg_mem_ndd(rRegI dst, rRegI src1, memory src2, rFlagsReg cr) 10195 %{ 10196 predicate(UseAPX); 10197 match(Set dst (AndI src1 (LoadI src2))); 10198 effect(KILL cr); 10199 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10200 10201 ins_cost(150); 10202 format %{ "eandl $dst, $src1, $src2\t# int ndd" %} 10203 ins_encode %{ 10204 __ eandl($dst$$Register, $src1$$Register, $src2$$Address, false); 10205 %} 10206 ins_pipe(ialu_reg_mem); 10207 %} 10208 10209 // And Memory with Register 10210 instruct andB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 10211 %{ 10212 match(Set dst (StoreB dst (AndI (LoadB dst) src))); 10213 effect(KILL cr); 10214 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10215 10216 ins_cost(150); 10217 format %{ "andb $dst, $src\t# byte" %} 10218 ins_encode %{ 10219 __ andb($dst$$Address, $src$$Register); 10220 %} 10221 ins_pipe(ialu_mem_reg); 10222 %} 10223 10224 instruct andI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 10225 %{ 10226 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 10227 effect(KILL cr); 10228 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10229 10230 ins_cost(150); 10231 format %{ "andl $dst, $src\t# int" %} 10232 ins_encode %{ 10233 __ andl($dst$$Address, $src$$Register); 10234 %} 10235 ins_pipe(ialu_mem_reg); 10236 %} 10237 10238 // And Memory with Immediate 10239 instruct andI_mem_imm(memory dst, immI src, rFlagsReg cr) 10240 %{ 10241 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 10242 effect(KILL cr); 10243 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10244 10245 ins_cost(125); 10246 format %{ "andl $dst, $src\t# int" %} 10247 ins_encode %{ 10248 __ andl($dst$$Address, $src$$constant); 10249 %} 10250 ins_pipe(ialu_mem_imm); 10251 %} 10252 10253 // BMI1 instructions 10254 instruct andnI_rReg_rReg_mem(rRegI dst, rRegI src1, memory src2, immI_M1 minus_1, rFlagsReg cr) %{ 10255 match(Set dst (AndI (XorI src1 minus_1) (LoadI src2))); 10256 predicate(UseBMI1Instructions); 10257 effect(KILL cr); 10258 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10259 10260 ins_cost(125); 10261 format %{ "andnl $dst, $src1, $src2" %} 10262 10263 ins_encode %{ 10264 __ andnl($dst$$Register, $src1$$Register, $src2$$Address); 10265 %} 10266 ins_pipe(ialu_reg_mem); 10267 %} 10268 10269 instruct andnI_rReg_rReg_rReg(rRegI dst, rRegI src1, rRegI src2, immI_M1 minus_1, rFlagsReg cr) %{ 10270 match(Set dst (AndI (XorI src1 minus_1) src2)); 10271 predicate(UseBMI1Instructions); 10272 effect(KILL cr); 10273 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10274 10275 format %{ "andnl $dst, $src1, $src2" %} 10276 10277 ins_encode %{ 10278 __ andnl($dst$$Register, $src1$$Register, $src2$$Register); 10279 %} 10280 ins_pipe(ialu_reg); 10281 %} 10282 10283 instruct blsiI_rReg_rReg(rRegI dst, rRegI src, immI_0 imm_zero, rFlagsReg cr) %{ 10284 match(Set dst (AndI (SubI imm_zero src) src)); 10285 predicate(UseBMI1Instructions); 10286 effect(KILL cr); 10287 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 10288 10289 format %{ "blsil $dst, $src" %} 10290 10291 ins_encode %{ 10292 __ blsil($dst$$Register, $src$$Register); 10293 %} 10294 ins_pipe(ialu_reg); 10295 %} 10296 10297 instruct blsiI_rReg_mem(rRegI dst, memory src, immI_0 imm_zero, rFlagsReg cr) %{ 10298 match(Set dst (AndI (SubI imm_zero (LoadI src) ) (LoadI src) )); 10299 predicate(UseBMI1Instructions); 10300 effect(KILL cr); 10301 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 10302 10303 ins_cost(125); 10304 format %{ "blsil $dst, $src" %} 10305 10306 ins_encode %{ 10307 __ blsil($dst$$Register, $src$$Address); 10308 %} 10309 ins_pipe(ialu_reg_mem); 10310 %} 10311 10312 instruct blsmskI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 10313 %{ 10314 match(Set dst (XorI (AddI (LoadI src) minus_1) (LoadI src) ) ); 10315 predicate(UseBMI1Instructions); 10316 effect(KILL cr); 10317 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 10318 10319 ins_cost(125); 10320 format %{ "blsmskl $dst, $src" %} 10321 10322 ins_encode %{ 10323 __ blsmskl($dst$$Register, $src$$Address); 10324 %} 10325 ins_pipe(ialu_reg_mem); 10326 %} 10327 10328 instruct blsmskI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 10329 %{ 10330 match(Set dst (XorI (AddI src minus_1) src)); 10331 predicate(UseBMI1Instructions); 10332 effect(KILL cr); 10333 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 10334 10335 format %{ "blsmskl $dst, $src" %} 10336 10337 ins_encode %{ 10338 __ blsmskl($dst$$Register, $src$$Register); 10339 %} 10340 10341 ins_pipe(ialu_reg); 10342 %} 10343 10344 instruct blsrI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 10345 %{ 10346 match(Set dst (AndI (AddI src minus_1) src) ); 10347 predicate(UseBMI1Instructions); 10348 effect(KILL cr); 10349 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 10350 10351 format %{ "blsrl $dst, $src" %} 10352 10353 ins_encode %{ 10354 __ blsrl($dst$$Register, $src$$Register); 10355 %} 10356 10357 ins_pipe(ialu_reg_mem); 10358 %} 10359 10360 instruct blsrI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 10361 %{ 10362 match(Set dst (AndI (AddI (LoadI src) minus_1) (LoadI src) ) ); 10363 predicate(UseBMI1Instructions); 10364 effect(KILL cr); 10365 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 10366 10367 ins_cost(125); 10368 format %{ "blsrl $dst, $src" %} 10369 10370 ins_encode %{ 10371 __ blsrl($dst$$Register, $src$$Address); 10372 %} 10373 10374 ins_pipe(ialu_reg); 10375 %} 10376 10377 // Or Instructions 10378 // Or Register with Register 10379 instruct orI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 10380 %{ 10381 predicate(!UseAPX); 10382 match(Set dst (OrI dst src)); 10383 effect(KILL cr); 10384 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10385 10386 format %{ "orl $dst, $src\t# int" %} 10387 ins_encode %{ 10388 __ orl($dst$$Register, $src$$Register); 10389 %} 10390 ins_pipe(ialu_reg_reg); 10391 %} 10392 10393 // Or Register with Register using New Data Destination (NDD) 10394 instruct orI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr) 10395 %{ 10396 predicate(UseAPX); 10397 match(Set dst (OrI src1 src2)); 10398 effect(KILL cr); 10399 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10400 10401 format %{ "eorl $dst, $src1, $src2\t# int ndd" %} 10402 ins_encode %{ 10403 __ eorl($dst$$Register, $src1$$Register, $src2$$Register, false); 10404 %} 10405 ins_pipe(ialu_reg_reg); 10406 %} 10407 10408 // Or Register with Immediate 10409 instruct orI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 10410 %{ 10411 predicate(!UseAPX); 10412 match(Set dst (OrI dst src)); 10413 effect(KILL cr); 10414 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10415 10416 format %{ "orl $dst, $src\t# int" %} 10417 ins_encode %{ 10418 __ orl($dst$$Register, $src$$constant); 10419 %} 10420 ins_pipe(ialu_reg); 10421 %} 10422 10423 instruct orI_rReg_rReg_imm_ndd(rRegI dst, rRegI src1, immI src2, rFlagsReg cr) 10424 %{ 10425 predicate(UseAPX); 10426 match(Set dst (OrI src1 src2)); 10427 effect(KILL cr); 10428 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10429 10430 format %{ "eorl $dst, $src1, $src2\t# int ndd" %} 10431 ins_encode %{ 10432 __ eorl($dst$$Register, $src1$$Register, $src2$$constant, false); 10433 %} 10434 ins_pipe(ialu_reg); 10435 %} 10436 10437 instruct orI_rReg_imm_rReg_ndd(rRegI dst, immI src1, rRegI src2, rFlagsReg cr) 10438 %{ 10439 predicate(UseAPX); 10440 match(Set dst (OrI src1 src2)); 10441 effect(KILL cr); 10442 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10443 10444 format %{ "eorl $dst, $src2, $src1\t# int ndd" %} 10445 ins_encode %{ 10446 __ eorl($dst$$Register, $src2$$Register, $src1$$constant, false); 10447 %} 10448 ins_pipe(ialu_reg); 10449 %} 10450 10451 instruct orI_rReg_mem_imm_ndd(rRegI dst, memory src1, immI src2, rFlagsReg cr) 10452 %{ 10453 predicate(UseAPX); 10454 match(Set dst (OrI (LoadI src1) src2)); 10455 effect(KILL cr); 10456 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10457 10458 format %{ "eorl $dst, $src1, $src2\t# int ndd" %} 10459 ins_encode %{ 10460 __ eorl($dst$$Register, $src1$$Address, $src2$$constant, false); 10461 %} 10462 ins_pipe(ialu_reg); 10463 %} 10464 10465 // Or Register with Memory 10466 instruct orI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 10467 %{ 10468 predicate(!UseAPX); 10469 match(Set dst (OrI dst (LoadI src))); 10470 effect(KILL cr); 10471 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10472 10473 ins_cost(150); 10474 format %{ "orl $dst, $src\t# int" %} 10475 ins_encode %{ 10476 __ orl($dst$$Register, $src$$Address); 10477 %} 10478 ins_pipe(ialu_reg_mem); 10479 %} 10480 10481 instruct orI_rReg_rReg_mem_ndd(rRegI dst, rRegI src1, memory src2, rFlagsReg cr) 10482 %{ 10483 predicate(UseAPX); 10484 match(Set dst (OrI src1 (LoadI src2))); 10485 effect(KILL cr); 10486 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10487 10488 ins_cost(150); 10489 format %{ "eorl $dst, $src1, $src2\t# int ndd" %} 10490 ins_encode %{ 10491 __ eorl($dst$$Register, $src1$$Register, $src2$$Address, false); 10492 %} 10493 ins_pipe(ialu_reg_mem); 10494 %} 10495 10496 // Or Memory with Register 10497 instruct orB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 10498 %{ 10499 match(Set dst (StoreB dst (OrI (LoadB dst) src))); 10500 effect(KILL cr); 10501 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10502 10503 ins_cost(150); 10504 format %{ "orb $dst, $src\t# byte" %} 10505 ins_encode %{ 10506 __ orb($dst$$Address, $src$$Register); 10507 %} 10508 ins_pipe(ialu_mem_reg); 10509 %} 10510 10511 instruct orI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 10512 %{ 10513 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 10514 effect(KILL cr); 10515 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10516 10517 ins_cost(150); 10518 format %{ "orl $dst, $src\t# int" %} 10519 ins_encode %{ 10520 __ orl($dst$$Address, $src$$Register); 10521 %} 10522 ins_pipe(ialu_mem_reg); 10523 %} 10524 10525 // Or Memory with Immediate 10526 instruct orI_mem_imm(memory dst, immI src, rFlagsReg cr) 10527 %{ 10528 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 10529 effect(KILL cr); 10530 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10531 10532 ins_cost(125); 10533 format %{ "orl $dst, $src\t# int" %} 10534 ins_encode %{ 10535 __ orl($dst$$Address, $src$$constant); 10536 %} 10537 ins_pipe(ialu_mem_imm); 10538 %} 10539 10540 // Xor Instructions 10541 // Xor Register with Register 10542 instruct xorI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 10543 %{ 10544 predicate(!UseAPX); 10545 match(Set dst (XorI dst src)); 10546 effect(KILL cr); 10547 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10548 10549 format %{ "xorl $dst, $src\t# int" %} 10550 ins_encode %{ 10551 __ xorl($dst$$Register, $src$$Register); 10552 %} 10553 ins_pipe(ialu_reg_reg); 10554 %} 10555 10556 // Xor Register with Register using New Data Destination (NDD) 10557 instruct xorI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr) 10558 %{ 10559 predicate(UseAPX); 10560 match(Set dst (XorI src1 src2)); 10561 effect(KILL cr); 10562 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10563 10564 format %{ "exorl $dst, $src1, $src2\t# int ndd" %} 10565 ins_encode %{ 10566 __ exorl($dst$$Register, $src1$$Register, $src2$$Register, false); 10567 %} 10568 ins_pipe(ialu_reg_reg); 10569 %} 10570 10571 // Xor Register with Immediate -1 10572 instruct xorI_rReg_im1(rRegI dst, immI_M1 imm) 10573 %{ 10574 predicate(!UseAPX); 10575 match(Set dst (XorI dst imm)); 10576 10577 format %{ "notl $dst" %} 10578 ins_encode %{ 10579 __ notl($dst$$Register); 10580 %} 10581 ins_pipe(ialu_reg); 10582 %} 10583 10584 instruct xorI_rReg_im1_ndd(rRegI dst, rRegI src, immI_M1 imm) 10585 %{ 10586 match(Set dst (XorI src imm)); 10587 predicate(UseAPX); 10588 10589 format %{ "enotl $dst, $src" %} 10590 ins_encode %{ 10591 __ enotl($dst$$Register, $src$$Register); 10592 %} 10593 ins_pipe(ialu_reg); 10594 %} 10595 10596 // Xor Register with Immediate 10597 instruct xorI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 10598 %{ 10599 // Strict predicate check to make selection of xorI_rReg_im1 cost agnostic if immI src is -1. 10600 predicate(!UseAPX && n->in(2)->bottom_type()->is_int()->get_con() != -1); 10601 match(Set dst (XorI dst src)); 10602 effect(KILL cr); 10603 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10604 10605 format %{ "xorl $dst, $src\t# int" %} 10606 ins_encode %{ 10607 __ xorl($dst$$Register, $src$$constant); 10608 %} 10609 ins_pipe(ialu_reg); 10610 %} 10611 10612 instruct xorI_rReg_rReg_imm_ndd(rRegI dst, rRegI src1, immI src2, rFlagsReg cr) 10613 %{ 10614 // Strict predicate check to make selection of xorI_rReg_im1_ndd cost agnostic if immI src2 is -1. 10615 predicate(UseAPX && n->in(2)->bottom_type()->is_int()->get_con() != -1); 10616 match(Set dst (XorI src1 src2)); 10617 effect(KILL cr); 10618 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10619 10620 format %{ "exorl $dst, $src1, $src2\t# int ndd" %} 10621 ins_encode %{ 10622 __ exorl($dst$$Register, $src1$$Register, $src2$$constant, false); 10623 %} 10624 ins_pipe(ialu_reg); 10625 %} 10626 10627 // Xor Memory with Immediate 10628 instruct xorI_rReg_mem_imm_ndd(rRegI dst, memory src1, immI src2, rFlagsReg cr) 10629 %{ 10630 predicate(UseAPX); 10631 match(Set dst (XorI (LoadI src1) src2)); 10632 effect(KILL cr); 10633 ins_cost(150); 10634 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10635 10636 format %{ "exorl $dst, $src1, $src2\t# int ndd" %} 10637 ins_encode %{ 10638 __ exorl($dst$$Register, $src1$$Address, $src2$$constant, false); 10639 %} 10640 ins_pipe(ialu_reg); 10641 %} 10642 10643 // Xor Register with Memory 10644 instruct xorI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 10645 %{ 10646 predicate(!UseAPX); 10647 match(Set dst (XorI dst (LoadI src))); 10648 effect(KILL cr); 10649 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10650 10651 ins_cost(150); 10652 format %{ "xorl $dst, $src\t# int" %} 10653 ins_encode %{ 10654 __ xorl($dst$$Register, $src$$Address); 10655 %} 10656 ins_pipe(ialu_reg_mem); 10657 %} 10658 10659 instruct xorI_rReg_rReg_mem_ndd(rRegI dst, rRegI src1, memory src2, rFlagsReg cr) 10660 %{ 10661 predicate(UseAPX); 10662 match(Set dst (XorI src1 (LoadI src2))); 10663 effect(KILL cr); 10664 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10665 10666 ins_cost(150); 10667 format %{ "exorl $dst, $src1, $src2\t# int ndd" %} 10668 ins_encode %{ 10669 __ exorl($dst$$Register, $src1$$Register, $src2$$Address, false); 10670 %} 10671 ins_pipe(ialu_reg_mem); 10672 %} 10673 10674 // Xor Memory with Register 10675 instruct xorB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 10676 %{ 10677 match(Set dst (StoreB dst (XorI (LoadB dst) src))); 10678 effect(KILL cr); 10679 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10680 10681 ins_cost(150); 10682 format %{ "xorb $dst, $src\t# byte" %} 10683 ins_encode %{ 10684 __ xorb($dst$$Address, $src$$Register); 10685 %} 10686 ins_pipe(ialu_mem_reg); 10687 %} 10688 10689 instruct xorI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 10690 %{ 10691 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 10692 effect(KILL cr); 10693 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10694 10695 ins_cost(150); 10696 format %{ "xorl $dst, $src\t# int" %} 10697 ins_encode %{ 10698 __ xorl($dst$$Address, $src$$Register); 10699 %} 10700 ins_pipe(ialu_mem_reg); 10701 %} 10702 10703 // Xor Memory with Immediate 10704 instruct xorI_mem_imm(memory dst, immI src, rFlagsReg cr) 10705 %{ 10706 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 10707 effect(KILL cr); 10708 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10709 10710 ins_cost(125); 10711 format %{ "xorl $dst, $src\t# int" %} 10712 ins_encode %{ 10713 __ xorl($dst$$Address, $src$$constant); 10714 %} 10715 ins_pipe(ialu_mem_imm); 10716 %} 10717 10718 10719 // Long Logical Instructions 10720 10721 // And Instructions 10722 // And Register with Register 10723 instruct andL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 10724 %{ 10725 predicate(!UseAPX); 10726 match(Set dst (AndL dst src)); 10727 effect(KILL cr); 10728 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10729 10730 format %{ "andq $dst, $src\t# long" %} 10731 ins_encode %{ 10732 __ andq($dst$$Register, $src$$Register); 10733 %} 10734 ins_pipe(ialu_reg_reg); 10735 %} 10736 10737 // And Register with Register using New Data Destination (NDD) 10738 instruct andL_rReg_ndd(rRegL dst, rRegL src1, rRegL src2, rFlagsReg cr) 10739 %{ 10740 predicate(UseAPX); 10741 match(Set dst (AndL src1 src2)); 10742 effect(KILL cr); 10743 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10744 10745 format %{ "eandq $dst, $src1, $src2\t# long ndd" %} 10746 ins_encode %{ 10747 __ eandq($dst$$Register, $src1$$Register, $src2$$Register, false); 10748 10749 %} 10750 ins_pipe(ialu_reg_reg); 10751 %} 10752 10753 // And Register with Immediate 255 10754 instruct andL_rReg_imm255(rRegL dst, rRegL src, immL_255 mask) 10755 %{ 10756 match(Set dst (AndL src mask)); 10757 10758 format %{ "movzbl $dst, $src\t# long & 0xFF" %} 10759 ins_encode %{ 10760 // movzbl zeroes out the upper 32-bit and does not need REX.W 10761 __ movzbl($dst$$Register, $src$$Register); 10762 %} 10763 ins_pipe(ialu_reg); 10764 %} 10765 10766 // And Register with Immediate 65535 10767 instruct andL_rReg_imm65535(rRegL dst, rRegL src, immL_65535 mask) 10768 %{ 10769 match(Set dst (AndL src mask)); 10770 10771 format %{ "movzwl $dst, $src\t# long & 0xFFFF" %} 10772 ins_encode %{ 10773 // movzwl zeroes out the upper 32-bit and does not need REX.W 10774 __ movzwl($dst$$Register, $src$$Register); 10775 %} 10776 ins_pipe(ialu_reg); 10777 %} 10778 10779 // And Register with Immediate 10780 instruct andL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 10781 %{ 10782 predicate(!UseAPX); 10783 match(Set dst (AndL dst src)); 10784 effect(KILL cr); 10785 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10786 10787 format %{ "andq $dst, $src\t# long" %} 10788 ins_encode %{ 10789 __ andq($dst$$Register, $src$$constant); 10790 %} 10791 ins_pipe(ialu_reg); 10792 %} 10793 10794 instruct andL_rReg_rReg_imm_ndd(rRegL dst, rRegL src1, immL32 src2, rFlagsReg cr) 10795 %{ 10796 predicate(UseAPX); 10797 match(Set dst (AndL src1 src2)); 10798 effect(KILL cr); 10799 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10800 10801 format %{ "eandq $dst, $src1, $src2\t# long ndd" %} 10802 ins_encode %{ 10803 __ eandq($dst$$Register, $src1$$Register, $src2$$constant, false); 10804 %} 10805 ins_pipe(ialu_reg); 10806 %} 10807 10808 instruct andL_rReg_mem_imm_ndd(rRegL dst, memory src1, immL32 src2, rFlagsReg cr) 10809 %{ 10810 predicate(UseAPX); 10811 match(Set dst (AndL (LoadL src1) src2)); 10812 effect(KILL cr); 10813 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10814 10815 format %{ "eandq $dst, $src1, $src2\t# long ndd" %} 10816 ins_encode %{ 10817 __ eandq($dst$$Register, $src1$$Address, $src2$$constant, false); 10818 %} 10819 ins_pipe(ialu_reg); 10820 %} 10821 10822 // And Register with Memory 10823 instruct andL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 10824 %{ 10825 predicate(!UseAPX); 10826 match(Set dst (AndL dst (LoadL src))); 10827 effect(KILL cr); 10828 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10829 10830 ins_cost(150); 10831 format %{ "andq $dst, $src\t# long" %} 10832 ins_encode %{ 10833 __ andq($dst$$Register, $src$$Address); 10834 %} 10835 ins_pipe(ialu_reg_mem); 10836 %} 10837 10838 instruct andL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr) 10839 %{ 10840 predicate(UseAPX); 10841 match(Set dst (AndL src1 (LoadL src2))); 10842 effect(KILL cr); 10843 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10844 10845 ins_cost(150); 10846 format %{ "eandq $dst, $src1, $src2\t# long ndd" %} 10847 ins_encode %{ 10848 __ eandq($dst$$Register, $src1$$Register, $src2$$Address, false); 10849 %} 10850 ins_pipe(ialu_reg_mem); 10851 %} 10852 10853 // And Memory with Register 10854 instruct andL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 10855 %{ 10856 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 10857 effect(KILL cr); 10858 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10859 10860 ins_cost(150); 10861 format %{ "andq $dst, $src\t# long" %} 10862 ins_encode %{ 10863 __ andq($dst$$Address, $src$$Register); 10864 %} 10865 ins_pipe(ialu_mem_reg); 10866 %} 10867 10868 // And Memory with Immediate 10869 instruct andL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 10870 %{ 10871 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 10872 effect(KILL cr); 10873 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10874 10875 ins_cost(125); 10876 format %{ "andq $dst, $src\t# long" %} 10877 ins_encode %{ 10878 __ andq($dst$$Address, $src$$constant); 10879 %} 10880 ins_pipe(ialu_mem_imm); 10881 %} 10882 10883 instruct btrL_mem_imm(memory dst, immL_NotPow2 con, rFlagsReg cr) 10884 %{ 10885 // con should be a pure 64-bit immediate given that not(con) is a power of 2 10886 // because AND/OR works well enough for 8/32-bit values. 10887 predicate(log2i_graceful(~n->in(3)->in(2)->get_long()) > 30); 10888 10889 match(Set dst (StoreL dst (AndL (LoadL dst) con))); 10890 effect(KILL cr); 10891 10892 ins_cost(125); 10893 format %{ "btrq $dst, log2(not($con))\t# long" %} 10894 ins_encode %{ 10895 __ btrq($dst$$Address, log2i_exact((julong)~$con$$constant)); 10896 %} 10897 ins_pipe(ialu_mem_imm); 10898 %} 10899 10900 // BMI1 instructions 10901 instruct andnL_rReg_rReg_mem(rRegL dst, rRegL src1, memory src2, immL_M1 minus_1, rFlagsReg cr) %{ 10902 match(Set dst (AndL (XorL src1 minus_1) (LoadL src2))); 10903 predicate(UseBMI1Instructions); 10904 effect(KILL cr); 10905 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10906 10907 ins_cost(125); 10908 format %{ "andnq $dst, $src1, $src2" %} 10909 10910 ins_encode %{ 10911 __ andnq($dst$$Register, $src1$$Register, $src2$$Address); 10912 %} 10913 ins_pipe(ialu_reg_mem); 10914 %} 10915 10916 instruct andnL_rReg_rReg_rReg(rRegL dst, rRegL src1, rRegL src2, immL_M1 minus_1, rFlagsReg cr) %{ 10917 match(Set dst (AndL (XorL src1 minus_1) src2)); 10918 predicate(UseBMI1Instructions); 10919 effect(KILL cr); 10920 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10921 10922 format %{ "andnq $dst, $src1, $src2" %} 10923 10924 ins_encode %{ 10925 __ andnq($dst$$Register, $src1$$Register, $src2$$Register); 10926 %} 10927 ins_pipe(ialu_reg_mem); 10928 %} 10929 10930 instruct blsiL_rReg_rReg(rRegL dst, rRegL src, immL0 imm_zero, rFlagsReg cr) %{ 10931 match(Set dst (AndL (SubL imm_zero src) src)); 10932 predicate(UseBMI1Instructions); 10933 effect(KILL cr); 10934 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 10935 10936 format %{ "blsiq $dst, $src" %} 10937 10938 ins_encode %{ 10939 __ blsiq($dst$$Register, $src$$Register); 10940 %} 10941 ins_pipe(ialu_reg); 10942 %} 10943 10944 instruct blsiL_rReg_mem(rRegL dst, memory src, immL0 imm_zero, rFlagsReg cr) %{ 10945 match(Set dst (AndL (SubL imm_zero (LoadL src) ) (LoadL src) )); 10946 predicate(UseBMI1Instructions); 10947 effect(KILL cr); 10948 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 10949 10950 ins_cost(125); 10951 format %{ "blsiq $dst, $src" %} 10952 10953 ins_encode %{ 10954 __ blsiq($dst$$Register, $src$$Address); 10955 %} 10956 ins_pipe(ialu_reg_mem); 10957 %} 10958 10959 instruct blsmskL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 10960 %{ 10961 match(Set dst (XorL (AddL (LoadL src) minus_1) (LoadL src) ) ); 10962 predicate(UseBMI1Instructions); 10963 effect(KILL cr); 10964 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 10965 10966 ins_cost(125); 10967 format %{ "blsmskq $dst, $src" %} 10968 10969 ins_encode %{ 10970 __ blsmskq($dst$$Register, $src$$Address); 10971 %} 10972 ins_pipe(ialu_reg_mem); 10973 %} 10974 10975 instruct blsmskL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 10976 %{ 10977 match(Set dst (XorL (AddL src minus_1) src)); 10978 predicate(UseBMI1Instructions); 10979 effect(KILL cr); 10980 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 10981 10982 format %{ "blsmskq $dst, $src" %} 10983 10984 ins_encode %{ 10985 __ blsmskq($dst$$Register, $src$$Register); 10986 %} 10987 10988 ins_pipe(ialu_reg); 10989 %} 10990 10991 instruct blsrL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 10992 %{ 10993 match(Set dst (AndL (AddL src minus_1) src) ); 10994 predicate(UseBMI1Instructions); 10995 effect(KILL cr); 10996 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 10997 10998 format %{ "blsrq $dst, $src" %} 10999 11000 ins_encode %{ 11001 __ blsrq($dst$$Register, $src$$Register); 11002 %} 11003 11004 ins_pipe(ialu_reg); 11005 %} 11006 11007 instruct blsrL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 11008 %{ 11009 match(Set dst (AndL (AddL (LoadL src) minus_1) (LoadL src)) ); 11010 predicate(UseBMI1Instructions); 11011 effect(KILL cr); 11012 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 11013 11014 ins_cost(125); 11015 format %{ "blsrq $dst, $src" %} 11016 11017 ins_encode %{ 11018 __ blsrq($dst$$Register, $src$$Address); 11019 %} 11020 11021 ins_pipe(ialu_reg); 11022 %} 11023 11024 // Or Instructions 11025 // Or Register with Register 11026 instruct orL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 11027 %{ 11028 predicate(!UseAPX); 11029 match(Set dst (OrL dst src)); 11030 effect(KILL cr); 11031 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11032 11033 format %{ "orq $dst, $src\t# long" %} 11034 ins_encode %{ 11035 __ orq($dst$$Register, $src$$Register); 11036 %} 11037 ins_pipe(ialu_reg_reg); 11038 %} 11039 11040 // Or Register with Register using New Data Destination (NDD) 11041 instruct orL_rReg_ndd(rRegL dst, rRegL src1, rRegL src2, rFlagsReg cr) 11042 %{ 11043 predicate(UseAPX); 11044 match(Set dst (OrL src1 src2)); 11045 effect(KILL cr); 11046 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11047 11048 format %{ "eorq $dst, $src1, $src2\t# long ndd" %} 11049 ins_encode %{ 11050 __ eorq($dst$$Register, $src1$$Register, $src2$$Register, false); 11051 11052 %} 11053 ins_pipe(ialu_reg_reg); 11054 %} 11055 11056 // Use any_RegP to match R15 (TLS register) without spilling. 11057 instruct orL_rReg_castP2X(rRegL dst, any_RegP src, rFlagsReg cr) %{ 11058 match(Set dst (OrL dst (CastP2X src))); 11059 effect(KILL cr); 11060 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11061 11062 format %{ "orq $dst, $src\t# long" %} 11063 ins_encode %{ 11064 __ orq($dst$$Register, $src$$Register); 11065 %} 11066 ins_pipe(ialu_reg_reg); 11067 %} 11068 11069 instruct orL_rReg_castP2X_ndd(rRegL dst, any_RegP src1, any_RegP src2, rFlagsReg cr) %{ 11070 match(Set dst (OrL src1 (CastP2X src2))); 11071 effect(KILL cr); 11072 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11073 11074 format %{ "eorq $dst, $src1, $src2\t# long ndd" %} 11075 ins_encode %{ 11076 __ eorq($dst$$Register, $src1$$Register, $src2$$Register, false); 11077 %} 11078 ins_pipe(ialu_reg_reg); 11079 %} 11080 11081 // Or Register with Immediate 11082 instruct orL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 11083 %{ 11084 predicate(!UseAPX); 11085 match(Set dst (OrL dst src)); 11086 effect(KILL cr); 11087 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11088 11089 format %{ "orq $dst, $src\t# long" %} 11090 ins_encode %{ 11091 __ orq($dst$$Register, $src$$constant); 11092 %} 11093 ins_pipe(ialu_reg); 11094 %} 11095 11096 instruct orL_rReg_rReg_imm_ndd(rRegL dst, rRegL src1, immL32 src2, rFlagsReg cr) 11097 %{ 11098 predicate(UseAPX); 11099 match(Set dst (OrL src1 src2)); 11100 effect(KILL cr); 11101 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11102 11103 format %{ "eorq $dst, $src1, $src2\t# long ndd" %} 11104 ins_encode %{ 11105 __ eorq($dst$$Register, $src1$$Register, $src2$$constant, false); 11106 %} 11107 ins_pipe(ialu_reg); 11108 %} 11109 11110 instruct orL_rReg_imm_rReg_ndd(rRegL dst, immL32 src1, rRegL src2, rFlagsReg cr) 11111 %{ 11112 predicate(UseAPX); 11113 match(Set dst (OrL src1 src2)); 11114 effect(KILL cr); 11115 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11116 11117 format %{ "eorq $dst, $src2, $src1\t# long ndd" %} 11118 ins_encode %{ 11119 __ eorq($dst$$Register, $src2$$Register, $src1$$constant, false); 11120 %} 11121 ins_pipe(ialu_reg); 11122 %} 11123 11124 // Or Memory with Immediate 11125 instruct orL_rReg_mem_imm_ndd(rRegL dst, memory src1, immL32 src2, rFlagsReg cr) 11126 %{ 11127 predicate(UseAPX); 11128 match(Set dst (OrL (LoadL src1) src2)); 11129 effect(KILL cr); 11130 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11131 11132 format %{ "eorq $dst, $src1, $src2\t# long ndd" %} 11133 ins_encode %{ 11134 __ eorq($dst$$Register, $src1$$Address, $src2$$constant, false); 11135 %} 11136 ins_pipe(ialu_reg); 11137 %} 11138 11139 // Or Register with Memory 11140 instruct orL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 11141 %{ 11142 predicate(!UseAPX); 11143 match(Set dst (OrL dst (LoadL src))); 11144 effect(KILL cr); 11145 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11146 11147 ins_cost(150); 11148 format %{ "orq $dst, $src\t# long" %} 11149 ins_encode %{ 11150 __ orq($dst$$Register, $src$$Address); 11151 %} 11152 ins_pipe(ialu_reg_mem); 11153 %} 11154 11155 instruct orL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr) 11156 %{ 11157 predicate(UseAPX); 11158 match(Set dst (OrL src1 (LoadL src2))); 11159 effect(KILL cr); 11160 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11161 11162 ins_cost(150); 11163 format %{ "eorq $dst, $src1, $src2\t# long ndd" %} 11164 ins_encode %{ 11165 __ eorq($dst$$Register, $src1$$Register, $src2$$Address, false); 11166 %} 11167 ins_pipe(ialu_reg_mem); 11168 %} 11169 11170 // Or Memory with Register 11171 instruct orL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 11172 %{ 11173 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 11174 effect(KILL cr); 11175 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11176 11177 ins_cost(150); 11178 format %{ "orq $dst, $src\t# long" %} 11179 ins_encode %{ 11180 __ orq($dst$$Address, $src$$Register); 11181 %} 11182 ins_pipe(ialu_mem_reg); 11183 %} 11184 11185 // Or Memory with Immediate 11186 instruct orL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 11187 %{ 11188 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 11189 effect(KILL cr); 11190 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11191 11192 ins_cost(125); 11193 format %{ "orq $dst, $src\t# long" %} 11194 ins_encode %{ 11195 __ orq($dst$$Address, $src$$constant); 11196 %} 11197 ins_pipe(ialu_mem_imm); 11198 %} 11199 11200 instruct btsL_mem_imm(memory dst, immL_Pow2 con, rFlagsReg cr) 11201 %{ 11202 // con should be a pure 64-bit power of 2 immediate 11203 // because AND/OR works well enough for 8/32-bit values. 11204 predicate(log2i_graceful(n->in(3)->in(2)->get_long()) > 31); 11205 11206 match(Set dst (StoreL dst (OrL (LoadL dst) con))); 11207 effect(KILL cr); 11208 11209 ins_cost(125); 11210 format %{ "btsq $dst, log2($con)\t# long" %} 11211 ins_encode %{ 11212 __ btsq($dst$$Address, log2i_exact((julong)$con$$constant)); 11213 %} 11214 ins_pipe(ialu_mem_imm); 11215 %} 11216 11217 // Xor Instructions 11218 // Xor Register with Register 11219 instruct xorL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 11220 %{ 11221 predicate(!UseAPX); 11222 match(Set dst (XorL dst src)); 11223 effect(KILL cr); 11224 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11225 11226 format %{ "xorq $dst, $src\t# long" %} 11227 ins_encode %{ 11228 __ xorq($dst$$Register, $src$$Register); 11229 %} 11230 ins_pipe(ialu_reg_reg); 11231 %} 11232 11233 // Xor Register with Register using New Data Destination (NDD) 11234 instruct xorL_rReg_ndd(rRegL dst, rRegL src1, rRegL src2, rFlagsReg cr) 11235 %{ 11236 predicate(UseAPX); 11237 match(Set dst (XorL src1 src2)); 11238 effect(KILL cr); 11239 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11240 11241 format %{ "exorq $dst, $src1, $src2\t# long ndd" %} 11242 ins_encode %{ 11243 __ exorq($dst$$Register, $src1$$Register, $src2$$Register, false); 11244 %} 11245 ins_pipe(ialu_reg_reg); 11246 %} 11247 11248 // Xor Register with Immediate -1 11249 instruct xorL_rReg_im1(rRegL dst, immL_M1 imm) 11250 %{ 11251 predicate(!UseAPX); 11252 match(Set dst (XorL dst imm)); 11253 11254 format %{ "notq $dst" %} 11255 ins_encode %{ 11256 __ notq($dst$$Register); 11257 %} 11258 ins_pipe(ialu_reg); 11259 %} 11260 11261 instruct xorL_rReg_im1_ndd(rRegL dst,rRegL src, immL_M1 imm) 11262 %{ 11263 predicate(UseAPX); 11264 match(Set dst (XorL src imm)); 11265 11266 format %{ "enotq $dst, $src" %} 11267 ins_encode %{ 11268 __ enotq($dst$$Register, $src$$Register); 11269 %} 11270 ins_pipe(ialu_reg); 11271 %} 11272 11273 // Xor Register with Immediate 11274 instruct xorL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 11275 %{ 11276 // Strict predicate check to make selection of xorL_rReg_im1 cost agnostic if immL32 src is -1. 11277 predicate(!UseAPX && n->in(2)->bottom_type()->is_long()->get_con() != -1L); 11278 match(Set dst (XorL dst src)); 11279 effect(KILL cr); 11280 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11281 11282 format %{ "xorq $dst, $src\t# long" %} 11283 ins_encode %{ 11284 __ xorq($dst$$Register, $src$$constant); 11285 %} 11286 ins_pipe(ialu_reg); 11287 %} 11288 11289 instruct xorL_rReg_rReg_imm(rRegL dst, rRegL src1, immL32 src2, rFlagsReg cr) 11290 %{ 11291 // Strict predicate check to make selection of xorL_rReg_im1_ndd cost agnostic if immL32 src2 is -1. 11292 predicate(UseAPX && n->in(2)->bottom_type()->is_long()->get_con() != -1L); 11293 match(Set dst (XorL src1 src2)); 11294 effect(KILL cr); 11295 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11296 11297 format %{ "exorq $dst, $src1, $src2\t# long ndd" %} 11298 ins_encode %{ 11299 __ exorq($dst$$Register, $src1$$Register, $src2$$constant, false); 11300 %} 11301 ins_pipe(ialu_reg); 11302 %} 11303 11304 // Xor Memory with Immediate 11305 instruct xorL_rReg_mem_imm(rRegL dst, memory src1, immL32 src2, rFlagsReg cr) 11306 %{ 11307 predicate(UseAPX); 11308 match(Set dst (XorL (LoadL src1) src2)); 11309 effect(KILL cr); 11310 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11311 ins_cost(150); 11312 11313 format %{ "exorq $dst, $src1, $src2\t# long ndd" %} 11314 ins_encode %{ 11315 __ exorq($dst$$Register, $src1$$Address, $src2$$constant, false); 11316 %} 11317 ins_pipe(ialu_reg); 11318 %} 11319 11320 // Xor Register with Memory 11321 instruct xorL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 11322 %{ 11323 predicate(!UseAPX); 11324 match(Set dst (XorL dst (LoadL src))); 11325 effect(KILL cr); 11326 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11327 11328 ins_cost(150); 11329 format %{ "xorq $dst, $src\t# long" %} 11330 ins_encode %{ 11331 __ xorq($dst$$Register, $src$$Address); 11332 %} 11333 ins_pipe(ialu_reg_mem); 11334 %} 11335 11336 instruct xorL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr) 11337 %{ 11338 predicate(UseAPX); 11339 match(Set dst (XorL src1 (LoadL src2))); 11340 effect(KILL cr); 11341 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11342 11343 ins_cost(150); 11344 format %{ "exorq $dst, $src1, $src2\t# long ndd" %} 11345 ins_encode %{ 11346 __ exorq($dst$$Register, $src1$$Register, $src2$$Address, false); 11347 %} 11348 ins_pipe(ialu_reg_mem); 11349 %} 11350 11351 // Xor Memory with Register 11352 instruct xorL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 11353 %{ 11354 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 11355 effect(KILL cr); 11356 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11357 11358 ins_cost(150); 11359 format %{ "xorq $dst, $src\t# long" %} 11360 ins_encode %{ 11361 __ xorq($dst$$Address, $src$$Register); 11362 %} 11363 ins_pipe(ialu_mem_reg); 11364 %} 11365 11366 // Xor Memory with Immediate 11367 instruct xorL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 11368 %{ 11369 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 11370 effect(KILL cr); 11371 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11372 11373 ins_cost(125); 11374 format %{ "xorq $dst, $src\t# long" %} 11375 ins_encode %{ 11376 __ xorq($dst$$Address, $src$$constant); 11377 %} 11378 ins_pipe(ialu_mem_imm); 11379 %} 11380 11381 instruct cmpLTMask(rRegI dst, rRegI p, rRegI q, rFlagsReg cr) 11382 %{ 11383 match(Set dst (CmpLTMask p q)); 11384 effect(KILL cr); 11385 11386 ins_cost(400); 11387 format %{ "cmpl $p, $q\t# cmpLTMask\n\t" 11388 "setcc $dst \t# emits setlt + movzbl or setzul for APX" 11389 "negl $dst" %} 11390 ins_encode %{ 11391 __ cmpl($p$$Register, $q$$Register); 11392 __ setcc(Assembler::less, $dst$$Register); 11393 __ negl($dst$$Register); 11394 %} 11395 ins_pipe(pipe_slow); 11396 %} 11397 11398 instruct cmpLTMask0(rRegI dst, immI_0 zero, rFlagsReg cr) 11399 %{ 11400 match(Set dst (CmpLTMask dst zero)); 11401 effect(KILL cr); 11402 11403 ins_cost(100); 11404 format %{ "sarl $dst, #31\t# cmpLTMask0" %} 11405 ins_encode %{ 11406 __ sarl($dst$$Register, 31); 11407 %} 11408 ins_pipe(ialu_reg); 11409 %} 11410 11411 /* Better to save a register than avoid a branch */ 11412 instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 11413 %{ 11414 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q))); 11415 effect(KILL cr); 11416 ins_cost(300); 11417 format %{ "subl $p,$q\t# cadd_cmpLTMask\n\t" 11418 "jge done\n\t" 11419 "addl $p,$y\n" 11420 "done: " %} 11421 ins_encode %{ 11422 Register Rp = $p$$Register; 11423 Register Rq = $q$$Register; 11424 Register Ry = $y$$Register; 11425 Label done; 11426 __ subl(Rp, Rq); 11427 __ jccb(Assembler::greaterEqual, done); 11428 __ addl(Rp, Ry); 11429 __ bind(done); 11430 %} 11431 ins_pipe(pipe_cmplt); 11432 %} 11433 11434 /* Better to save a register than avoid a branch */ 11435 instruct and_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 11436 %{ 11437 match(Set y (AndI (CmpLTMask p q) y)); 11438 effect(KILL cr); 11439 11440 ins_cost(300); 11441 11442 format %{ "cmpl $p, $q\t# and_cmpLTMask\n\t" 11443 "jlt done\n\t" 11444 "xorl $y, $y\n" 11445 "done: " %} 11446 ins_encode %{ 11447 Register Rp = $p$$Register; 11448 Register Rq = $q$$Register; 11449 Register Ry = $y$$Register; 11450 Label done; 11451 __ cmpl(Rp, Rq); 11452 __ jccb(Assembler::less, done); 11453 __ xorl(Ry, Ry); 11454 __ bind(done); 11455 %} 11456 ins_pipe(pipe_cmplt); 11457 %} 11458 11459 11460 //---------- FP Instructions------------------------------------------------ 11461 11462 // Really expensive, avoid 11463 instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2) 11464 %{ 11465 match(Set cr (CmpF src1 src2)); 11466 11467 ins_cost(500); 11468 format %{ "ucomiss $src1, $src2\n\t" 11469 "jnp,s exit\n\t" 11470 "pushfq\t# saw NaN, set CF\n\t" 11471 "andq [rsp], #0xffffff2b\n\t" 11472 "popfq\n" 11473 "exit:" %} 11474 ins_encode %{ 11475 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 11476 emit_cmpfp_fixup(masm); 11477 %} 11478 ins_pipe(pipe_slow); 11479 %} 11480 11481 instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{ 11482 match(Set cr (CmpF src1 src2)); 11483 11484 ins_cost(100); 11485 format %{ "ucomiss $src1, $src2" %} 11486 ins_encode %{ 11487 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 11488 %} 11489 ins_pipe(pipe_slow); 11490 %} 11491 11492 instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{ 11493 match(Set cr (CmpF src1 (LoadF src2))); 11494 11495 ins_cost(100); 11496 format %{ "ucomiss $src1, $src2" %} 11497 ins_encode %{ 11498 __ ucomiss($src1$$XMMRegister, $src2$$Address); 11499 %} 11500 ins_pipe(pipe_slow); 11501 %} 11502 11503 instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src, immF con) %{ 11504 match(Set cr (CmpF src con)); 11505 ins_cost(100); 11506 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con" %} 11507 ins_encode %{ 11508 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 11509 %} 11510 ins_pipe(pipe_slow); 11511 %} 11512 11513 // Really expensive, avoid 11514 instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2) 11515 %{ 11516 match(Set cr (CmpD src1 src2)); 11517 11518 ins_cost(500); 11519 format %{ "ucomisd $src1, $src2\n\t" 11520 "jnp,s exit\n\t" 11521 "pushfq\t# saw NaN, set CF\n\t" 11522 "andq [rsp], #0xffffff2b\n\t" 11523 "popfq\n" 11524 "exit:" %} 11525 ins_encode %{ 11526 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 11527 emit_cmpfp_fixup(masm); 11528 %} 11529 ins_pipe(pipe_slow); 11530 %} 11531 11532 instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{ 11533 match(Set cr (CmpD src1 src2)); 11534 11535 ins_cost(100); 11536 format %{ "ucomisd $src1, $src2 test" %} 11537 ins_encode %{ 11538 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 11539 %} 11540 ins_pipe(pipe_slow); 11541 %} 11542 11543 instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{ 11544 match(Set cr (CmpD src1 (LoadD src2))); 11545 11546 ins_cost(100); 11547 format %{ "ucomisd $src1, $src2" %} 11548 ins_encode %{ 11549 __ ucomisd($src1$$XMMRegister, $src2$$Address); 11550 %} 11551 ins_pipe(pipe_slow); 11552 %} 11553 11554 instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src, immD con) %{ 11555 match(Set cr (CmpD src con)); 11556 ins_cost(100); 11557 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con" %} 11558 ins_encode %{ 11559 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 11560 %} 11561 ins_pipe(pipe_slow); 11562 %} 11563 11564 // Compare into -1,0,1 11565 instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr) 11566 %{ 11567 match(Set dst (CmpF3 src1 src2)); 11568 effect(KILL cr); 11569 11570 ins_cost(275); 11571 format %{ "ucomiss $src1, $src2\n\t" 11572 "movl $dst, #-1\n\t" 11573 "jp,s done\n\t" 11574 "jb,s done\n\t" 11575 "setne $dst\n\t" 11576 "movzbl $dst, $dst\n" 11577 "done:" %} 11578 ins_encode %{ 11579 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 11580 emit_cmpfp3(masm, $dst$$Register); 11581 %} 11582 ins_pipe(pipe_slow); 11583 %} 11584 11585 // Compare into -1,0,1 11586 instruct cmpF_mem(rRegI dst, regF src1, memory src2, rFlagsReg cr) 11587 %{ 11588 match(Set dst (CmpF3 src1 (LoadF src2))); 11589 effect(KILL cr); 11590 11591 ins_cost(275); 11592 format %{ "ucomiss $src1, $src2\n\t" 11593 "movl $dst, #-1\n\t" 11594 "jp,s done\n\t" 11595 "jb,s done\n\t" 11596 "setne $dst\n\t" 11597 "movzbl $dst, $dst\n" 11598 "done:" %} 11599 ins_encode %{ 11600 __ ucomiss($src1$$XMMRegister, $src2$$Address); 11601 emit_cmpfp3(masm, $dst$$Register); 11602 %} 11603 ins_pipe(pipe_slow); 11604 %} 11605 11606 // Compare into -1,0,1 11607 instruct cmpF_imm(rRegI dst, regF src, immF con, rFlagsReg cr) %{ 11608 match(Set dst (CmpF3 src con)); 11609 effect(KILL cr); 11610 11611 ins_cost(275); 11612 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 11613 "movl $dst, #-1\n\t" 11614 "jp,s done\n\t" 11615 "jb,s done\n\t" 11616 "setne $dst\n\t" 11617 "movzbl $dst, $dst\n" 11618 "done:" %} 11619 ins_encode %{ 11620 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 11621 emit_cmpfp3(masm, $dst$$Register); 11622 %} 11623 ins_pipe(pipe_slow); 11624 %} 11625 11626 // Compare into -1,0,1 11627 instruct cmpD_reg(rRegI dst, regD src1, regD src2, rFlagsReg cr) 11628 %{ 11629 match(Set dst (CmpD3 src1 src2)); 11630 effect(KILL cr); 11631 11632 ins_cost(275); 11633 format %{ "ucomisd $src1, $src2\n\t" 11634 "movl $dst, #-1\n\t" 11635 "jp,s done\n\t" 11636 "jb,s done\n\t" 11637 "setne $dst\n\t" 11638 "movzbl $dst, $dst\n" 11639 "done:" %} 11640 ins_encode %{ 11641 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 11642 emit_cmpfp3(masm, $dst$$Register); 11643 %} 11644 ins_pipe(pipe_slow); 11645 %} 11646 11647 // Compare into -1,0,1 11648 instruct cmpD_mem(rRegI dst, regD src1, memory src2, rFlagsReg cr) 11649 %{ 11650 match(Set dst (CmpD3 src1 (LoadD src2))); 11651 effect(KILL cr); 11652 11653 ins_cost(275); 11654 format %{ "ucomisd $src1, $src2\n\t" 11655 "movl $dst, #-1\n\t" 11656 "jp,s done\n\t" 11657 "jb,s done\n\t" 11658 "setne $dst\n\t" 11659 "movzbl $dst, $dst\n" 11660 "done:" %} 11661 ins_encode %{ 11662 __ ucomisd($src1$$XMMRegister, $src2$$Address); 11663 emit_cmpfp3(masm, $dst$$Register); 11664 %} 11665 ins_pipe(pipe_slow); 11666 %} 11667 11668 // Compare into -1,0,1 11669 instruct cmpD_imm(rRegI dst, regD src, immD con, rFlagsReg cr) %{ 11670 match(Set dst (CmpD3 src con)); 11671 effect(KILL cr); 11672 11673 ins_cost(275); 11674 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 11675 "movl $dst, #-1\n\t" 11676 "jp,s done\n\t" 11677 "jb,s done\n\t" 11678 "setne $dst\n\t" 11679 "movzbl $dst, $dst\n" 11680 "done:" %} 11681 ins_encode %{ 11682 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 11683 emit_cmpfp3(masm, $dst$$Register); 11684 %} 11685 ins_pipe(pipe_slow); 11686 %} 11687 11688 //----------Arithmetic Conversion Instructions--------------------------------- 11689 11690 instruct convF2D_reg_reg(regD dst, regF src) 11691 %{ 11692 match(Set dst (ConvF2D src)); 11693 11694 format %{ "cvtss2sd $dst, $src" %} 11695 ins_encode %{ 11696 __ cvtss2sd ($dst$$XMMRegister, $src$$XMMRegister); 11697 %} 11698 ins_pipe(pipe_slow); // XXX 11699 %} 11700 11701 instruct convF2D_reg_mem(regD dst, memory src) 11702 %{ 11703 predicate(UseAVX == 0); 11704 match(Set dst (ConvF2D (LoadF src))); 11705 11706 format %{ "cvtss2sd $dst, $src" %} 11707 ins_encode %{ 11708 __ cvtss2sd ($dst$$XMMRegister, $src$$Address); 11709 %} 11710 ins_pipe(pipe_slow); // XXX 11711 %} 11712 11713 instruct convD2F_reg_reg(regF dst, regD src) 11714 %{ 11715 match(Set dst (ConvD2F src)); 11716 11717 format %{ "cvtsd2ss $dst, $src" %} 11718 ins_encode %{ 11719 __ cvtsd2ss ($dst$$XMMRegister, $src$$XMMRegister); 11720 %} 11721 ins_pipe(pipe_slow); // XXX 11722 %} 11723 11724 instruct convD2F_reg_mem(regF dst, memory src) 11725 %{ 11726 predicate(UseAVX == 0); 11727 match(Set dst (ConvD2F (LoadD src))); 11728 11729 format %{ "cvtsd2ss $dst, $src" %} 11730 ins_encode %{ 11731 __ cvtsd2ss ($dst$$XMMRegister, $src$$Address); 11732 %} 11733 ins_pipe(pipe_slow); // XXX 11734 %} 11735 11736 // XXX do mem variants 11737 instruct convF2I_reg_reg(rRegI dst, regF src, rFlagsReg cr) 11738 %{ 11739 match(Set dst (ConvF2I src)); 11740 effect(KILL cr); 11741 format %{ "convert_f2i $dst, $src" %} 11742 ins_encode %{ 11743 __ convertF2I(T_INT, T_FLOAT, $dst$$Register, $src$$XMMRegister); 11744 %} 11745 ins_pipe(pipe_slow); 11746 %} 11747 11748 instruct convF2L_reg_reg(rRegL dst, regF src, rFlagsReg cr) 11749 %{ 11750 match(Set dst (ConvF2L src)); 11751 effect(KILL cr); 11752 format %{ "convert_f2l $dst, $src"%} 11753 ins_encode %{ 11754 __ convertF2I(T_LONG, T_FLOAT, $dst$$Register, $src$$XMMRegister); 11755 %} 11756 ins_pipe(pipe_slow); 11757 %} 11758 11759 instruct convD2I_reg_reg(rRegI dst, regD src, rFlagsReg cr) 11760 %{ 11761 match(Set dst (ConvD2I src)); 11762 effect(KILL cr); 11763 format %{ "convert_d2i $dst, $src"%} 11764 ins_encode %{ 11765 __ convertF2I(T_INT, T_DOUBLE, $dst$$Register, $src$$XMMRegister); 11766 %} 11767 ins_pipe(pipe_slow); 11768 %} 11769 11770 instruct convD2L_reg_reg(rRegL dst, regD src, rFlagsReg cr) 11771 %{ 11772 match(Set dst (ConvD2L src)); 11773 effect(KILL cr); 11774 format %{ "convert_d2l $dst, $src"%} 11775 ins_encode %{ 11776 __ convertF2I(T_LONG, T_DOUBLE, $dst$$Register, $src$$XMMRegister); 11777 %} 11778 ins_pipe(pipe_slow); 11779 %} 11780 11781 instruct round_double_reg(rRegL dst, regD src, rRegL rtmp, rcx_RegL rcx, rFlagsReg cr) 11782 %{ 11783 match(Set dst (RoundD src)); 11784 effect(TEMP dst, TEMP rtmp, TEMP rcx, KILL cr); 11785 format %{ "round_double $dst,$src \t! using $rtmp and $rcx as TEMP"%} 11786 ins_encode %{ 11787 __ round_double($dst$$Register, $src$$XMMRegister, $rtmp$$Register, $rcx$$Register); 11788 %} 11789 ins_pipe(pipe_slow); 11790 %} 11791 11792 instruct round_float_reg(rRegI dst, regF src, rRegL rtmp, rcx_RegL rcx, rFlagsReg cr) 11793 %{ 11794 match(Set dst (RoundF src)); 11795 effect(TEMP dst, TEMP rtmp, TEMP rcx, KILL cr); 11796 format %{ "round_float $dst,$src" %} 11797 ins_encode %{ 11798 __ round_float($dst$$Register, $src$$XMMRegister, $rtmp$$Register, $rcx$$Register); 11799 %} 11800 ins_pipe(pipe_slow); 11801 %} 11802 11803 instruct convI2F_reg_reg(vlRegF dst, rRegI src) 11804 %{ 11805 predicate(!UseXmmI2F); 11806 match(Set dst (ConvI2F src)); 11807 11808 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 11809 ins_encode %{ 11810 if (UseAVX > 0) { 11811 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 11812 } 11813 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Register); 11814 %} 11815 ins_pipe(pipe_slow); // XXX 11816 %} 11817 11818 instruct convI2F_reg_mem(regF dst, memory src) 11819 %{ 11820 predicate(UseAVX == 0); 11821 match(Set dst (ConvI2F (LoadI src))); 11822 11823 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 11824 ins_encode %{ 11825 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Address); 11826 %} 11827 ins_pipe(pipe_slow); // XXX 11828 %} 11829 11830 instruct convI2D_reg_reg(vlRegD dst, rRegI src) 11831 %{ 11832 predicate(!UseXmmI2D); 11833 match(Set dst (ConvI2D src)); 11834 11835 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 11836 ins_encode %{ 11837 if (UseAVX > 0) { 11838 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 11839 } 11840 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Register); 11841 %} 11842 ins_pipe(pipe_slow); // XXX 11843 %} 11844 11845 instruct convI2D_reg_mem(regD dst, memory src) 11846 %{ 11847 predicate(UseAVX == 0); 11848 match(Set dst (ConvI2D (LoadI src))); 11849 11850 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 11851 ins_encode %{ 11852 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Address); 11853 %} 11854 ins_pipe(pipe_slow); // XXX 11855 %} 11856 11857 instruct convXI2F_reg(regF dst, rRegI src) 11858 %{ 11859 predicate(UseXmmI2F); 11860 match(Set dst (ConvI2F src)); 11861 11862 format %{ "movdl $dst, $src\n\t" 11863 "cvtdq2psl $dst, $dst\t# i2f" %} 11864 ins_encode %{ 11865 __ movdl($dst$$XMMRegister, $src$$Register); 11866 __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister); 11867 %} 11868 ins_pipe(pipe_slow); // XXX 11869 %} 11870 11871 instruct convXI2D_reg(regD dst, rRegI src) 11872 %{ 11873 predicate(UseXmmI2D); 11874 match(Set dst (ConvI2D src)); 11875 11876 format %{ "movdl $dst, $src\n\t" 11877 "cvtdq2pdl $dst, $dst\t# i2d" %} 11878 ins_encode %{ 11879 __ movdl($dst$$XMMRegister, $src$$Register); 11880 __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister); 11881 %} 11882 ins_pipe(pipe_slow); // XXX 11883 %} 11884 11885 instruct convL2F_reg_reg(vlRegF dst, rRegL src) 11886 %{ 11887 match(Set dst (ConvL2F src)); 11888 11889 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 11890 ins_encode %{ 11891 if (UseAVX > 0) { 11892 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 11893 } 11894 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Register); 11895 %} 11896 ins_pipe(pipe_slow); // XXX 11897 %} 11898 11899 instruct convL2F_reg_mem(regF dst, memory src) 11900 %{ 11901 predicate(UseAVX == 0); 11902 match(Set dst (ConvL2F (LoadL src))); 11903 11904 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 11905 ins_encode %{ 11906 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Address); 11907 %} 11908 ins_pipe(pipe_slow); // XXX 11909 %} 11910 11911 instruct convL2D_reg_reg(vlRegD dst, rRegL src) 11912 %{ 11913 match(Set dst (ConvL2D src)); 11914 11915 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 11916 ins_encode %{ 11917 if (UseAVX > 0) { 11918 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 11919 } 11920 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Register); 11921 %} 11922 ins_pipe(pipe_slow); // XXX 11923 %} 11924 11925 instruct convL2D_reg_mem(regD dst, memory src) 11926 %{ 11927 predicate(UseAVX == 0); 11928 match(Set dst (ConvL2D (LoadL src))); 11929 11930 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 11931 ins_encode %{ 11932 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Address); 11933 %} 11934 ins_pipe(pipe_slow); // XXX 11935 %} 11936 11937 instruct convI2L_reg_reg(rRegL dst, rRegI src) 11938 %{ 11939 match(Set dst (ConvI2L src)); 11940 11941 ins_cost(125); 11942 format %{ "movslq $dst, $src\t# i2l" %} 11943 ins_encode %{ 11944 __ movslq($dst$$Register, $src$$Register); 11945 %} 11946 ins_pipe(ialu_reg_reg); 11947 %} 11948 11949 // Zero-extend convert int to long 11950 instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask) 11951 %{ 11952 match(Set dst (AndL (ConvI2L src) mask)); 11953 11954 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 11955 ins_encode %{ 11956 if ($dst$$reg != $src$$reg) { 11957 __ movl($dst$$Register, $src$$Register); 11958 } 11959 %} 11960 ins_pipe(ialu_reg_reg); 11961 %} 11962 11963 // Zero-extend convert int to long 11964 instruct convI2L_reg_mem_zex(rRegL dst, memory src, immL_32bits mask) 11965 %{ 11966 match(Set dst (AndL (ConvI2L (LoadI src)) mask)); 11967 11968 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 11969 ins_encode %{ 11970 __ movl($dst$$Register, $src$$Address); 11971 %} 11972 ins_pipe(ialu_reg_mem); 11973 %} 11974 11975 instruct zerox_long_reg_reg(rRegL dst, rRegL src, immL_32bits mask) 11976 %{ 11977 match(Set dst (AndL src mask)); 11978 11979 format %{ "movl $dst, $src\t# zero-extend long" %} 11980 ins_encode %{ 11981 __ movl($dst$$Register, $src$$Register); 11982 %} 11983 ins_pipe(ialu_reg_reg); 11984 %} 11985 11986 instruct convL2I_reg_reg(rRegI dst, rRegL src) 11987 %{ 11988 match(Set dst (ConvL2I src)); 11989 11990 format %{ "movl $dst, $src\t# l2i" %} 11991 ins_encode %{ 11992 __ movl($dst$$Register, $src$$Register); 11993 %} 11994 ins_pipe(ialu_reg_reg); 11995 %} 11996 11997 11998 instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{ 11999 match(Set dst (MoveF2I src)); 12000 effect(DEF dst, USE src); 12001 12002 ins_cost(125); 12003 format %{ "movl $dst, $src\t# MoveF2I_stack_reg" %} 12004 ins_encode %{ 12005 __ movl($dst$$Register, Address(rsp, $src$$disp)); 12006 %} 12007 ins_pipe(ialu_reg_mem); 12008 %} 12009 12010 instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{ 12011 match(Set dst (MoveI2F src)); 12012 effect(DEF dst, USE src); 12013 12014 ins_cost(125); 12015 format %{ "movss $dst, $src\t# MoveI2F_stack_reg" %} 12016 ins_encode %{ 12017 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 12018 %} 12019 ins_pipe(pipe_slow); 12020 %} 12021 12022 instruct MoveD2L_stack_reg(rRegL dst, stackSlotD src) %{ 12023 match(Set dst (MoveD2L src)); 12024 effect(DEF dst, USE src); 12025 12026 ins_cost(125); 12027 format %{ "movq $dst, $src\t# MoveD2L_stack_reg" %} 12028 ins_encode %{ 12029 __ movq($dst$$Register, Address(rsp, $src$$disp)); 12030 %} 12031 ins_pipe(ialu_reg_mem); 12032 %} 12033 12034 instruct MoveL2D_stack_reg_partial(regD dst, stackSlotL src) %{ 12035 predicate(!UseXmmLoadAndClearUpper); 12036 match(Set dst (MoveL2D src)); 12037 effect(DEF dst, USE src); 12038 12039 ins_cost(125); 12040 format %{ "movlpd $dst, $src\t# MoveL2D_stack_reg" %} 12041 ins_encode %{ 12042 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 12043 %} 12044 ins_pipe(pipe_slow); 12045 %} 12046 12047 instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{ 12048 predicate(UseXmmLoadAndClearUpper); 12049 match(Set dst (MoveL2D src)); 12050 effect(DEF dst, USE src); 12051 12052 ins_cost(125); 12053 format %{ "movsd $dst, $src\t# MoveL2D_stack_reg" %} 12054 ins_encode %{ 12055 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 12056 %} 12057 ins_pipe(pipe_slow); 12058 %} 12059 12060 12061 instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{ 12062 match(Set dst (MoveF2I src)); 12063 effect(DEF dst, USE src); 12064 12065 ins_cost(95); // XXX 12066 format %{ "movss $dst, $src\t# MoveF2I_reg_stack" %} 12067 ins_encode %{ 12068 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 12069 %} 12070 ins_pipe(pipe_slow); 12071 %} 12072 12073 instruct MoveI2F_reg_stack(stackSlotF dst, rRegI src) %{ 12074 match(Set dst (MoveI2F src)); 12075 effect(DEF dst, USE src); 12076 12077 ins_cost(100); 12078 format %{ "movl $dst, $src\t# MoveI2F_reg_stack" %} 12079 ins_encode %{ 12080 __ movl(Address(rsp, $dst$$disp), $src$$Register); 12081 %} 12082 ins_pipe( ialu_mem_reg ); 12083 %} 12084 12085 instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{ 12086 match(Set dst (MoveD2L src)); 12087 effect(DEF dst, USE src); 12088 12089 ins_cost(95); // XXX 12090 format %{ "movsd $dst, $src\t# MoveL2D_reg_stack" %} 12091 ins_encode %{ 12092 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 12093 %} 12094 ins_pipe(pipe_slow); 12095 %} 12096 12097 instruct MoveL2D_reg_stack(stackSlotD dst, rRegL src) %{ 12098 match(Set dst (MoveL2D src)); 12099 effect(DEF dst, USE src); 12100 12101 ins_cost(100); 12102 format %{ "movq $dst, $src\t# MoveL2D_reg_stack" %} 12103 ins_encode %{ 12104 __ movq(Address(rsp, $dst$$disp), $src$$Register); 12105 %} 12106 ins_pipe(ialu_mem_reg); 12107 %} 12108 12109 instruct MoveF2I_reg_reg(rRegI dst, regF src) %{ 12110 match(Set dst (MoveF2I src)); 12111 effect(DEF dst, USE src); 12112 ins_cost(85); 12113 format %{ "movd $dst,$src\t# MoveF2I" %} 12114 ins_encode %{ 12115 __ movdl($dst$$Register, $src$$XMMRegister); 12116 %} 12117 ins_pipe( pipe_slow ); 12118 %} 12119 12120 instruct MoveD2L_reg_reg(rRegL dst, regD src) %{ 12121 match(Set dst (MoveD2L src)); 12122 effect(DEF dst, USE src); 12123 ins_cost(85); 12124 format %{ "movd $dst,$src\t# MoveD2L" %} 12125 ins_encode %{ 12126 __ movdq($dst$$Register, $src$$XMMRegister); 12127 %} 12128 ins_pipe( pipe_slow ); 12129 %} 12130 12131 instruct MoveI2F_reg_reg(regF dst, rRegI src) %{ 12132 match(Set dst (MoveI2F src)); 12133 effect(DEF dst, USE src); 12134 ins_cost(100); 12135 format %{ "movd $dst,$src\t# MoveI2F" %} 12136 ins_encode %{ 12137 __ movdl($dst$$XMMRegister, $src$$Register); 12138 %} 12139 ins_pipe( pipe_slow ); 12140 %} 12141 12142 instruct MoveL2D_reg_reg(regD dst, rRegL src) %{ 12143 match(Set dst (MoveL2D src)); 12144 effect(DEF dst, USE src); 12145 ins_cost(100); 12146 format %{ "movd $dst,$src\t# MoveL2D" %} 12147 ins_encode %{ 12148 __ movdq($dst$$XMMRegister, $src$$Register); 12149 %} 12150 ins_pipe( pipe_slow ); 12151 %} 12152 12153 // Fast clearing of an array 12154 // Small non-constant lenght ClearArray for non-AVX512 targets. 12155 instruct rep_stos(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegI zero, 12156 Universe dummy, rFlagsReg cr) 12157 %{ 12158 predicate(!((ClearArrayNode*)n)->is_large() && (UseAVX <= 2)); 12159 match(Set dummy (ClearArray cnt base)); 12160 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL zero, KILL cr); 12161 12162 format %{ $$template 12163 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 12164 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 12165 $$emit$$"jg LARGE\n\t" 12166 $$emit$$"dec rcx\n\t" 12167 $$emit$$"js DONE\t# Zero length\n\t" 12168 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 12169 $$emit$$"dec rcx\n\t" 12170 $$emit$$"jge LOOP\n\t" 12171 $$emit$$"jmp DONE\n\t" 12172 $$emit$$"# LARGE:\n\t" 12173 if (UseFastStosb) { 12174 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 12175 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--\n\t" 12176 } else if (UseXMMForObjInit) { 12177 $$emit$$"mov rdi,rax\n\t" 12178 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 12179 $$emit$$"jmpq L_zero_64_bytes\n\t" 12180 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 12181 $$emit$$"vmovdqu ymm0,(rax)\n\t" 12182 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 12183 $$emit$$"add 0x40,rax\n\t" 12184 $$emit$$"# L_zero_64_bytes:\n\t" 12185 $$emit$$"sub 0x8,rcx\n\t" 12186 $$emit$$"jge L_loop\n\t" 12187 $$emit$$"add 0x4,rcx\n\t" 12188 $$emit$$"jl L_tail\n\t" 12189 $$emit$$"vmovdqu ymm0,(rax)\n\t" 12190 $$emit$$"add 0x20,rax\n\t" 12191 $$emit$$"sub 0x4,rcx\n\t" 12192 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 12193 $$emit$$"add 0x4,rcx\n\t" 12194 $$emit$$"jle L_end\n\t" 12195 $$emit$$"dec rcx\n\t" 12196 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 12197 $$emit$$"vmovq xmm0,(rax)\n\t" 12198 $$emit$$"add 0x8,rax\n\t" 12199 $$emit$$"dec rcx\n\t" 12200 $$emit$$"jge L_sloop\n\t" 12201 $$emit$$"# L_end:\n\t" 12202 } else { 12203 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 12204 } 12205 $$emit$$"# DONE" 12206 %} 12207 ins_encode %{ 12208 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 12209 $tmp$$XMMRegister, false, knoreg); 12210 %} 12211 ins_pipe(pipe_slow); 12212 %} 12213 12214 // Small non-constant length ClearArray for AVX512 targets. 12215 instruct rep_stos_evex(rcx_RegL cnt, rdi_RegP base, legRegD tmp, kReg ktmp, rax_RegI zero, 12216 Universe dummy, rFlagsReg cr) 12217 %{ 12218 predicate(!((ClearArrayNode*)n)->is_large() && (UseAVX > 2)); 12219 match(Set dummy (ClearArray cnt base)); 12220 ins_cost(125); 12221 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, TEMP ktmp, KILL zero, KILL cr); 12222 12223 format %{ $$template 12224 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 12225 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 12226 $$emit$$"jg LARGE\n\t" 12227 $$emit$$"dec rcx\n\t" 12228 $$emit$$"js DONE\t# Zero length\n\t" 12229 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 12230 $$emit$$"dec rcx\n\t" 12231 $$emit$$"jge LOOP\n\t" 12232 $$emit$$"jmp DONE\n\t" 12233 $$emit$$"# LARGE:\n\t" 12234 if (UseFastStosb) { 12235 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 12236 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--\n\t" 12237 } else if (UseXMMForObjInit) { 12238 $$emit$$"mov rdi,rax\n\t" 12239 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 12240 $$emit$$"jmpq L_zero_64_bytes\n\t" 12241 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 12242 $$emit$$"vmovdqu ymm0,(rax)\n\t" 12243 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 12244 $$emit$$"add 0x40,rax\n\t" 12245 $$emit$$"# L_zero_64_bytes:\n\t" 12246 $$emit$$"sub 0x8,rcx\n\t" 12247 $$emit$$"jge L_loop\n\t" 12248 $$emit$$"add 0x4,rcx\n\t" 12249 $$emit$$"jl L_tail\n\t" 12250 $$emit$$"vmovdqu ymm0,(rax)\n\t" 12251 $$emit$$"add 0x20,rax\n\t" 12252 $$emit$$"sub 0x4,rcx\n\t" 12253 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 12254 $$emit$$"add 0x4,rcx\n\t" 12255 $$emit$$"jle L_end\n\t" 12256 $$emit$$"dec rcx\n\t" 12257 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 12258 $$emit$$"vmovq xmm0,(rax)\n\t" 12259 $$emit$$"add 0x8,rax\n\t" 12260 $$emit$$"dec rcx\n\t" 12261 $$emit$$"jge L_sloop\n\t" 12262 $$emit$$"# L_end:\n\t" 12263 } else { 12264 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 12265 } 12266 $$emit$$"# DONE" 12267 %} 12268 ins_encode %{ 12269 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 12270 $tmp$$XMMRegister, false, $ktmp$$KRegister); 12271 %} 12272 ins_pipe(pipe_slow); 12273 %} 12274 12275 // Large non-constant length ClearArray for non-AVX512 targets. 12276 instruct rep_stos_large(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegI zero, 12277 Universe dummy, rFlagsReg cr) 12278 %{ 12279 predicate((UseAVX <=2) && ((ClearArrayNode*)n)->is_large()); 12280 match(Set dummy (ClearArray cnt base)); 12281 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL zero, KILL cr); 12282 12283 format %{ $$template 12284 if (UseFastStosb) { 12285 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 12286 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 12287 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--" 12288 } else if (UseXMMForObjInit) { 12289 $$emit$$"mov rdi,rax\t# ClearArray:\n\t" 12290 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 12291 $$emit$$"jmpq L_zero_64_bytes\n\t" 12292 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 12293 $$emit$$"vmovdqu ymm0,(rax)\n\t" 12294 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 12295 $$emit$$"add 0x40,rax\n\t" 12296 $$emit$$"# L_zero_64_bytes:\n\t" 12297 $$emit$$"sub 0x8,rcx\n\t" 12298 $$emit$$"jge L_loop\n\t" 12299 $$emit$$"add 0x4,rcx\n\t" 12300 $$emit$$"jl L_tail\n\t" 12301 $$emit$$"vmovdqu ymm0,(rax)\n\t" 12302 $$emit$$"add 0x20,rax\n\t" 12303 $$emit$$"sub 0x4,rcx\n\t" 12304 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 12305 $$emit$$"add 0x4,rcx\n\t" 12306 $$emit$$"jle L_end\n\t" 12307 $$emit$$"dec rcx\n\t" 12308 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 12309 $$emit$$"vmovq xmm0,(rax)\n\t" 12310 $$emit$$"add 0x8,rax\n\t" 12311 $$emit$$"dec rcx\n\t" 12312 $$emit$$"jge L_sloop\n\t" 12313 $$emit$$"# L_end:\n\t" 12314 } else { 12315 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 12316 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 12317 } 12318 %} 12319 ins_encode %{ 12320 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 12321 $tmp$$XMMRegister, true, knoreg); 12322 %} 12323 ins_pipe(pipe_slow); 12324 %} 12325 12326 // Large non-constant length ClearArray for AVX512 targets. 12327 instruct rep_stos_large_evex(rcx_RegL cnt, rdi_RegP base, legRegD tmp, kReg ktmp, rax_RegI zero, 12328 Universe dummy, rFlagsReg cr) 12329 %{ 12330 predicate((UseAVX > 2) && ((ClearArrayNode*)n)->is_large()); 12331 match(Set dummy (ClearArray cnt base)); 12332 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, TEMP ktmp, KILL zero, KILL cr); 12333 12334 format %{ $$template 12335 if (UseFastStosb) { 12336 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 12337 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 12338 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--" 12339 } else if (UseXMMForObjInit) { 12340 $$emit$$"mov rdi,rax\t# ClearArray:\n\t" 12341 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 12342 $$emit$$"jmpq L_zero_64_bytes\n\t" 12343 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 12344 $$emit$$"vmovdqu ymm0,(rax)\n\t" 12345 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 12346 $$emit$$"add 0x40,rax\n\t" 12347 $$emit$$"# L_zero_64_bytes:\n\t" 12348 $$emit$$"sub 0x8,rcx\n\t" 12349 $$emit$$"jge L_loop\n\t" 12350 $$emit$$"add 0x4,rcx\n\t" 12351 $$emit$$"jl L_tail\n\t" 12352 $$emit$$"vmovdqu ymm0,(rax)\n\t" 12353 $$emit$$"add 0x20,rax\n\t" 12354 $$emit$$"sub 0x4,rcx\n\t" 12355 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 12356 $$emit$$"add 0x4,rcx\n\t" 12357 $$emit$$"jle L_end\n\t" 12358 $$emit$$"dec rcx\n\t" 12359 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 12360 $$emit$$"vmovq xmm0,(rax)\n\t" 12361 $$emit$$"add 0x8,rax\n\t" 12362 $$emit$$"dec rcx\n\t" 12363 $$emit$$"jge L_sloop\n\t" 12364 $$emit$$"# L_end:\n\t" 12365 } else { 12366 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 12367 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 12368 } 12369 %} 12370 ins_encode %{ 12371 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 12372 $tmp$$XMMRegister, true, $ktmp$$KRegister); 12373 %} 12374 ins_pipe(pipe_slow); 12375 %} 12376 12377 // Small constant length ClearArray for AVX512 targets. 12378 instruct rep_stos_im(immL cnt, rRegP base, regD tmp, rRegI zero, kReg ktmp, Universe dummy, rFlagsReg cr) 12379 %{ 12380 predicate(!((ClearArrayNode*)n)->is_large() && (MaxVectorSize >= 32) && VM_Version::supports_avx512vl()); 12381 match(Set dummy (ClearArray cnt base)); 12382 ins_cost(100); 12383 effect(TEMP tmp, TEMP zero, TEMP ktmp, KILL cr); 12384 format %{ "clear_mem_imm $base , $cnt \n\t" %} 12385 ins_encode %{ 12386 __ clear_mem($base$$Register, $cnt$$constant, $zero$$Register, $tmp$$XMMRegister, $ktmp$$KRegister); 12387 %} 12388 ins_pipe(pipe_slow); 12389 %} 12390 12391 instruct string_compareL(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 12392 rax_RegI result, legRegD tmp1, rFlagsReg cr) 12393 %{ 12394 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 12395 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12396 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 12397 12398 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 12399 ins_encode %{ 12400 __ string_compare($str1$$Register, $str2$$Register, 12401 $cnt1$$Register, $cnt2$$Register, $result$$Register, 12402 $tmp1$$XMMRegister, StrIntrinsicNode::LL, knoreg); 12403 %} 12404 ins_pipe( pipe_slow ); 12405 %} 12406 12407 instruct string_compareL_evex(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 12408 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 12409 %{ 12410 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 12411 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12412 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 12413 12414 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 12415 ins_encode %{ 12416 __ string_compare($str1$$Register, $str2$$Register, 12417 $cnt1$$Register, $cnt2$$Register, $result$$Register, 12418 $tmp1$$XMMRegister, StrIntrinsicNode::LL, $ktmp$$KRegister); 12419 %} 12420 ins_pipe( pipe_slow ); 12421 %} 12422 12423 instruct string_compareU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 12424 rax_RegI result, legRegD tmp1, rFlagsReg cr) 12425 %{ 12426 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 12427 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12428 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 12429 12430 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 12431 ins_encode %{ 12432 __ string_compare($str1$$Register, $str2$$Register, 12433 $cnt1$$Register, $cnt2$$Register, $result$$Register, 12434 $tmp1$$XMMRegister, StrIntrinsicNode::UU, knoreg); 12435 %} 12436 ins_pipe( pipe_slow ); 12437 %} 12438 12439 instruct string_compareU_evex(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 12440 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 12441 %{ 12442 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 12443 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12444 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 12445 12446 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 12447 ins_encode %{ 12448 __ string_compare($str1$$Register, $str2$$Register, 12449 $cnt1$$Register, $cnt2$$Register, $result$$Register, 12450 $tmp1$$XMMRegister, StrIntrinsicNode::UU, $ktmp$$KRegister); 12451 %} 12452 ins_pipe( pipe_slow ); 12453 %} 12454 12455 instruct string_compareLU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 12456 rax_RegI result, legRegD tmp1, rFlagsReg cr) 12457 %{ 12458 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 12459 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12460 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 12461 12462 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 12463 ins_encode %{ 12464 __ string_compare($str1$$Register, $str2$$Register, 12465 $cnt1$$Register, $cnt2$$Register, $result$$Register, 12466 $tmp1$$XMMRegister, StrIntrinsicNode::LU, knoreg); 12467 %} 12468 ins_pipe( pipe_slow ); 12469 %} 12470 12471 instruct string_compareLU_evex(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 12472 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 12473 %{ 12474 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 12475 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12476 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 12477 12478 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 12479 ins_encode %{ 12480 __ string_compare($str1$$Register, $str2$$Register, 12481 $cnt1$$Register, $cnt2$$Register, $result$$Register, 12482 $tmp1$$XMMRegister, StrIntrinsicNode::LU, $ktmp$$KRegister); 12483 %} 12484 ins_pipe( pipe_slow ); 12485 %} 12486 12487 instruct string_compareUL(rsi_RegP str1, rdx_RegI cnt1, rdi_RegP str2, rcx_RegI cnt2, 12488 rax_RegI result, legRegD tmp1, rFlagsReg cr) 12489 %{ 12490 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 12491 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12492 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 12493 12494 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 12495 ins_encode %{ 12496 __ string_compare($str2$$Register, $str1$$Register, 12497 $cnt2$$Register, $cnt1$$Register, $result$$Register, 12498 $tmp1$$XMMRegister, StrIntrinsicNode::UL, knoreg); 12499 %} 12500 ins_pipe( pipe_slow ); 12501 %} 12502 12503 instruct string_compareUL_evex(rsi_RegP str1, rdx_RegI cnt1, rdi_RegP str2, rcx_RegI cnt2, 12504 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 12505 %{ 12506 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 12507 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12508 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 12509 12510 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 12511 ins_encode %{ 12512 __ string_compare($str2$$Register, $str1$$Register, 12513 $cnt2$$Register, $cnt1$$Register, $result$$Register, 12514 $tmp1$$XMMRegister, StrIntrinsicNode::UL, $ktmp$$KRegister); 12515 %} 12516 ins_pipe( pipe_slow ); 12517 %} 12518 12519 // fast search of substring with known size. 12520 instruct string_indexof_conL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 12521 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 12522 %{ 12523 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 12524 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 12525 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 12526 12527 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %} 12528 ins_encode %{ 12529 int icnt2 = (int)$int_cnt2$$constant; 12530 if (icnt2 >= 16) { 12531 // IndexOf for constant substrings with size >= 16 elements 12532 // which don't need to be loaded through stack. 12533 __ string_indexofC8($str1$$Register, $str2$$Register, 12534 $cnt1$$Register, $cnt2$$Register, 12535 icnt2, $result$$Register, 12536 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 12537 } else { 12538 // Small strings are loaded through stack if they cross page boundary. 12539 __ string_indexof($str1$$Register, $str2$$Register, 12540 $cnt1$$Register, $cnt2$$Register, 12541 icnt2, $result$$Register, 12542 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 12543 } 12544 %} 12545 ins_pipe( pipe_slow ); 12546 %} 12547 12548 // fast search of substring with known size. 12549 instruct string_indexof_conU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 12550 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 12551 %{ 12552 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 12553 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 12554 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 12555 12556 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %} 12557 ins_encode %{ 12558 int icnt2 = (int)$int_cnt2$$constant; 12559 if (icnt2 >= 8) { 12560 // IndexOf for constant substrings with size >= 8 elements 12561 // which don't need to be loaded through stack. 12562 __ string_indexofC8($str1$$Register, $str2$$Register, 12563 $cnt1$$Register, $cnt2$$Register, 12564 icnt2, $result$$Register, 12565 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 12566 } else { 12567 // Small strings are loaded through stack if they cross page boundary. 12568 __ string_indexof($str1$$Register, $str2$$Register, 12569 $cnt1$$Register, $cnt2$$Register, 12570 icnt2, $result$$Register, 12571 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 12572 } 12573 %} 12574 ins_pipe( pipe_slow ); 12575 %} 12576 12577 // fast search of substring with known size. 12578 instruct string_indexof_conUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 12579 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 12580 %{ 12581 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 12582 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 12583 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 12584 12585 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %} 12586 ins_encode %{ 12587 int icnt2 = (int)$int_cnt2$$constant; 12588 if (icnt2 >= 8) { 12589 // IndexOf for constant substrings with size >= 8 elements 12590 // which don't need to be loaded through stack. 12591 __ string_indexofC8($str1$$Register, $str2$$Register, 12592 $cnt1$$Register, $cnt2$$Register, 12593 icnt2, $result$$Register, 12594 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 12595 } else { 12596 // Small strings are loaded through stack if they cross page boundary. 12597 __ string_indexof($str1$$Register, $str2$$Register, 12598 $cnt1$$Register, $cnt2$$Register, 12599 icnt2, $result$$Register, 12600 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 12601 } 12602 %} 12603 ins_pipe( pipe_slow ); 12604 %} 12605 12606 instruct string_indexofL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 12607 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr) 12608 %{ 12609 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 12610 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 12611 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 12612 12613 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 12614 ins_encode %{ 12615 __ string_indexof($str1$$Register, $str2$$Register, 12616 $cnt1$$Register, $cnt2$$Register, 12617 (-1), $result$$Register, 12618 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 12619 %} 12620 ins_pipe( pipe_slow ); 12621 %} 12622 12623 instruct string_indexofU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 12624 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr) 12625 %{ 12626 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 12627 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 12628 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 12629 12630 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 12631 ins_encode %{ 12632 __ string_indexof($str1$$Register, $str2$$Register, 12633 $cnt1$$Register, $cnt2$$Register, 12634 (-1), $result$$Register, 12635 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 12636 %} 12637 ins_pipe( pipe_slow ); 12638 %} 12639 12640 instruct string_indexofUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 12641 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr) 12642 %{ 12643 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 12644 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 12645 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 12646 12647 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 12648 ins_encode %{ 12649 __ string_indexof($str1$$Register, $str2$$Register, 12650 $cnt1$$Register, $cnt2$$Register, 12651 (-1), $result$$Register, 12652 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 12653 %} 12654 ins_pipe( pipe_slow ); 12655 %} 12656 12657 instruct string_indexof_char(rdi_RegP str1, rdx_RegI cnt1, rax_RegI ch, 12658 rbx_RegI result, legRegD tmp_vec1, legRegD tmp_vec2, legRegD tmp_vec3, rcx_RegI tmp, rFlagsReg cr) 12659 %{ 12660 predicate(UseSSE42Intrinsics && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::U)); 12661 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 12662 effect(TEMP tmp_vec1, TEMP tmp_vec2, TEMP tmp_vec3, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP tmp, KILL cr); 12663 format %{ "StringUTF16 IndexOf char[] $str1,$cnt1,$ch -> $result // KILL all" %} 12664 ins_encode %{ 12665 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register, 12666 $tmp_vec1$$XMMRegister, $tmp_vec2$$XMMRegister, $tmp_vec3$$XMMRegister, $tmp$$Register); 12667 %} 12668 ins_pipe( pipe_slow ); 12669 %} 12670 12671 instruct stringL_indexof_char(rdi_RegP str1, rdx_RegI cnt1, rax_RegI ch, 12672 rbx_RegI result, legRegD tmp_vec1, legRegD tmp_vec2, legRegD tmp_vec3, rcx_RegI tmp, rFlagsReg cr) 12673 %{ 12674 predicate(UseSSE42Intrinsics && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::L)); 12675 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 12676 effect(TEMP tmp_vec1, TEMP tmp_vec2, TEMP tmp_vec3, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP tmp, KILL cr); 12677 format %{ "StringLatin1 IndexOf char[] $str1,$cnt1,$ch -> $result // KILL all" %} 12678 ins_encode %{ 12679 __ stringL_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register, 12680 $tmp_vec1$$XMMRegister, $tmp_vec2$$XMMRegister, $tmp_vec3$$XMMRegister, $tmp$$Register); 12681 %} 12682 ins_pipe( pipe_slow ); 12683 %} 12684 12685 // fast string equals 12686 instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 12687 legRegD tmp1, legRegD tmp2, rbx_RegI tmp3, rFlagsReg cr) 12688 %{ 12689 predicate(!VM_Version::supports_avx512vlbw()); 12690 match(Set result (StrEquals (Binary str1 str2) cnt)); 12691 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 12692 12693 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 12694 ins_encode %{ 12695 __ arrays_equals(false, $str1$$Register, $str2$$Register, 12696 $cnt$$Register, $result$$Register, $tmp3$$Register, 12697 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, knoreg); 12698 %} 12699 ins_pipe( pipe_slow ); 12700 %} 12701 12702 instruct string_equals_evex(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 12703 legRegD tmp1, legRegD tmp2, kReg ktmp, rbx_RegI tmp3, rFlagsReg cr) 12704 %{ 12705 predicate(VM_Version::supports_avx512vlbw()); 12706 match(Set result (StrEquals (Binary str1 str2) cnt)); 12707 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 12708 12709 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 12710 ins_encode %{ 12711 __ arrays_equals(false, $str1$$Register, $str2$$Register, 12712 $cnt$$Register, $result$$Register, $tmp3$$Register, 12713 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, $ktmp$$KRegister); 12714 %} 12715 ins_pipe( pipe_slow ); 12716 %} 12717 12718 // fast array equals 12719 instruct array_equalsB(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 12720 legRegD tmp1, legRegD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 12721 %{ 12722 predicate(!VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 12723 match(Set result (AryEq ary1 ary2)); 12724 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 12725 12726 format %{ "Array Equals byte[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 12727 ins_encode %{ 12728 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 12729 $tmp3$$Register, $result$$Register, $tmp4$$Register, 12730 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, knoreg); 12731 %} 12732 ins_pipe( pipe_slow ); 12733 %} 12734 12735 instruct array_equalsB_evex(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 12736 legRegD tmp1, legRegD tmp2, kReg ktmp, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 12737 %{ 12738 predicate(VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 12739 match(Set result (AryEq ary1 ary2)); 12740 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 12741 12742 format %{ "Array Equals byte[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 12743 ins_encode %{ 12744 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 12745 $tmp3$$Register, $result$$Register, $tmp4$$Register, 12746 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, $ktmp$$KRegister); 12747 %} 12748 ins_pipe( pipe_slow ); 12749 %} 12750 12751 instruct array_equalsC(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 12752 legRegD tmp1, legRegD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 12753 %{ 12754 predicate(!VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 12755 match(Set result (AryEq ary1 ary2)); 12756 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 12757 12758 format %{ "Array Equals char[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 12759 ins_encode %{ 12760 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 12761 $tmp3$$Register, $result$$Register, $tmp4$$Register, 12762 $tmp1$$XMMRegister, $tmp2$$XMMRegister, true /* char */, knoreg); 12763 %} 12764 ins_pipe( pipe_slow ); 12765 %} 12766 12767 instruct array_equalsC_evex(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 12768 legRegD tmp1, legRegD tmp2, kReg ktmp, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 12769 %{ 12770 predicate(VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 12771 match(Set result (AryEq ary1 ary2)); 12772 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 12773 12774 format %{ "Array Equals char[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 12775 ins_encode %{ 12776 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 12777 $tmp3$$Register, $result$$Register, $tmp4$$Register, 12778 $tmp1$$XMMRegister, $tmp2$$XMMRegister, true /* char */, $ktmp$$KRegister); 12779 %} 12780 ins_pipe( pipe_slow ); 12781 %} 12782 12783 instruct arrays_hashcode(rdi_RegP ary1, rdx_RegI cnt1, rbx_RegI result, immU8 basic_type, 12784 legRegD tmp_vec1, legRegD tmp_vec2, legRegD tmp_vec3, legRegD tmp_vec4, 12785 legRegD tmp_vec5, legRegD tmp_vec6, legRegD tmp_vec7, legRegD tmp_vec8, 12786 legRegD tmp_vec9, legRegD tmp_vec10, legRegD tmp_vec11, legRegD tmp_vec12, 12787 legRegD tmp_vec13, rRegI tmp1, rRegI tmp2, rRegI tmp3, rFlagsReg cr) 12788 %{ 12789 predicate(UseAVX >= 2); 12790 match(Set result (VectorizedHashCode (Binary ary1 cnt1) (Binary result basic_type))); 12791 effect(TEMP tmp_vec1, TEMP tmp_vec2, TEMP tmp_vec3, TEMP tmp_vec4, TEMP tmp_vec5, TEMP tmp_vec6, 12792 TEMP tmp_vec7, TEMP tmp_vec8, TEMP tmp_vec9, TEMP tmp_vec10, TEMP tmp_vec11, TEMP tmp_vec12, 12793 TEMP tmp_vec13, TEMP tmp1, TEMP tmp2, TEMP tmp3, USE_KILL ary1, USE_KILL cnt1, 12794 USE basic_type, KILL cr); 12795 12796 format %{ "Array HashCode array[] $ary1,$cnt1,$result,$basic_type -> $result // KILL all" %} 12797 ins_encode %{ 12798 __ arrays_hashcode($ary1$$Register, $cnt1$$Register, $result$$Register, 12799 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 12800 $tmp_vec1$$XMMRegister, $tmp_vec2$$XMMRegister, $tmp_vec3$$XMMRegister, 12801 $tmp_vec4$$XMMRegister, $tmp_vec5$$XMMRegister, $tmp_vec6$$XMMRegister, 12802 $tmp_vec7$$XMMRegister, $tmp_vec8$$XMMRegister, $tmp_vec9$$XMMRegister, 12803 $tmp_vec10$$XMMRegister, $tmp_vec11$$XMMRegister, $tmp_vec12$$XMMRegister, 12804 $tmp_vec13$$XMMRegister, (BasicType)$basic_type$$constant); 12805 %} 12806 ins_pipe( pipe_slow ); 12807 %} 12808 12809 instruct count_positives(rsi_RegP ary1, rcx_RegI len, rax_RegI result, 12810 legRegD tmp1, legRegD tmp2, rbx_RegI tmp3, rFlagsReg cr,) 12811 %{ 12812 predicate(!VM_Version::supports_avx512vlbw() || !VM_Version::supports_bmi2()); 12813 match(Set result (CountPositives ary1 len)); 12814 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr); 12815 12816 format %{ "countPositives byte[] $ary1,$len -> $result // KILL $tmp1, $tmp2, $tmp3" %} 12817 ins_encode %{ 12818 __ count_positives($ary1$$Register, $len$$Register, 12819 $result$$Register, $tmp3$$Register, 12820 $tmp1$$XMMRegister, $tmp2$$XMMRegister, knoreg, knoreg); 12821 %} 12822 ins_pipe( pipe_slow ); 12823 %} 12824 12825 instruct count_positives_evex(rsi_RegP ary1, rcx_RegI len, rax_RegI result, 12826 legRegD tmp1, legRegD tmp2, kReg ktmp1, kReg ktmp2, rbx_RegI tmp3, rFlagsReg cr,) 12827 %{ 12828 predicate(VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2()); 12829 match(Set result (CountPositives ary1 len)); 12830 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp1, TEMP ktmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr); 12831 12832 format %{ "countPositives byte[] $ary1,$len -> $result // KILL $tmp1, $tmp2, $tmp3" %} 12833 ins_encode %{ 12834 __ count_positives($ary1$$Register, $len$$Register, 12835 $result$$Register, $tmp3$$Register, 12836 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $ktmp1$$KRegister, $ktmp2$$KRegister); 12837 %} 12838 ins_pipe( pipe_slow ); 12839 %} 12840 12841 // fast char[] to byte[] compression 12842 instruct string_compress(rsi_RegP src, rdi_RegP dst, rdx_RegI len, legRegD tmp1, legRegD tmp2, legRegD tmp3, 12843 legRegD tmp4, rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 12844 predicate(!VM_Version::supports_avx512vlbw() || !VM_Version::supports_bmi2()); 12845 match(Set result (StrCompressedCopy src (Binary dst len))); 12846 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, 12847 USE_KILL len, KILL tmp5, KILL cr); 12848 12849 format %{ "String Compress $src,$dst -> $result // KILL RAX, RCX, RDX" %} 12850 ins_encode %{ 12851 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 12852 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 12853 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, 12854 knoreg, knoreg); 12855 %} 12856 ins_pipe( pipe_slow ); 12857 %} 12858 12859 instruct string_compress_evex(rsi_RegP src, rdi_RegP dst, rdx_RegI len, legRegD tmp1, legRegD tmp2, legRegD tmp3, 12860 legRegD tmp4, kReg ktmp1, kReg ktmp2, rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 12861 predicate(VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2()); 12862 match(Set result (StrCompressedCopy src (Binary dst len))); 12863 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP ktmp1, TEMP ktmp2, USE_KILL src, USE_KILL dst, 12864 USE_KILL len, KILL tmp5, KILL cr); 12865 12866 format %{ "String Compress $src,$dst -> $result // KILL RAX, RCX, RDX" %} 12867 ins_encode %{ 12868 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 12869 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 12870 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, 12871 $ktmp1$$KRegister, $ktmp2$$KRegister); 12872 %} 12873 ins_pipe( pipe_slow ); 12874 %} 12875 // fast byte[] to char[] inflation 12876 instruct string_inflate(Universe dummy, rsi_RegP src, rdi_RegP dst, rdx_RegI len, 12877 legRegD tmp1, rcx_RegI tmp2, rFlagsReg cr) %{ 12878 predicate(!VM_Version::supports_avx512vlbw() || !VM_Version::supports_bmi2()); 12879 match(Set dummy (StrInflatedCopy src (Binary dst len))); 12880 effect(TEMP tmp1, TEMP tmp2, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 12881 12882 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 12883 ins_encode %{ 12884 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 12885 $tmp1$$XMMRegister, $tmp2$$Register, knoreg); 12886 %} 12887 ins_pipe( pipe_slow ); 12888 %} 12889 12890 instruct string_inflate_evex(Universe dummy, rsi_RegP src, rdi_RegP dst, rdx_RegI len, 12891 legRegD tmp1, kReg ktmp, rcx_RegI tmp2, rFlagsReg cr) %{ 12892 predicate(VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2()); 12893 match(Set dummy (StrInflatedCopy src (Binary dst len))); 12894 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 12895 12896 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 12897 ins_encode %{ 12898 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 12899 $tmp1$$XMMRegister, $tmp2$$Register, $ktmp$$KRegister); 12900 %} 12901 ins_pipe( pipe_slow ); 12902 %} 12903 12904 // encode char[] to byte[] in ISO_8859_1 12905 instruct encode_iso_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len, 12906 legRegD tmp1, legRegD tmp2, legRegD tmp3, legRegD tmp4, 12907 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 12908 predicate(!((EncodeISOArrayNode*)n)->is_ascii()); 12909 match(Set result (EncodeISOArray src (Binary dst len))); 12910 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 12911 12912 format %{ "Encode iso array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %} 12913 ins_encode %{ 12914 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 12915 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 12916 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, false); 12917 %} 12918 ins_pipe( pipe_slow ); 12919 %} 12920 12921 // encode char[] to byte[] in ASCII 12922 instruct encode_ascii_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len, 12923 legRegD tmp1, legRegD tmp2, legRegD tmp3, legRegD tmp4, 12924 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 12925 predicate(((EncodeISOArrayNode*)n)->is_ascii()); 12926 match(Set result (EncodeISOArray src (Binary dst len))); 12927 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 12928 12929 format %{ "Encode ascii array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %} 12930 ins_encode %{ 12931 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 12932 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 12933 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, true); 12934 %} 12935 ins_pipe( pipe_slow ); 12936 %} 12937 12938 //----------Overflow Math Instructions----------------------------------------- 12939 12940 instruct overflowAddI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 12941 %{ 12942 match(Set cr (OverflowAddI op1 op2)); 12943 effect(DEF cr, USE_KILL op1, USE op2); 12944 12945 format %{ "addl $op1, $op2\t# overflow check int" %} 12946 12947 ins_encode %{ 12948 __ addl($op1$$Register, $op2$$Register); 12949 %} 12950 ins_pipe(ialu_reg_reg); 12951 %} 12952 12953 instruct overflowAddI_rReg_imm(rFlagsReg cr, rax_RegI op1, immI op2) 12954 %{ 12955 match(Set cr (OverflowAddI op1 op2)); 12956 effect(DEF cr, USE_KILL op1, USE op2); 12957 12958 format %{ "addl $op1, $op2\t# overflow check int" %} 12959 12960 ins_encode %{ 12961 __ addl($op1$$Register, $op2$$constant); 12962 %} 12963 ins_pipe(ialu_reg_reg); 12964 %} 12965 12966 instruct overflowAddL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 12967 %{ 12968 match(Set cr (OverflowAddL op1 op2)); 12969 effect(DEF cr, USE_KILL op1, USE op2); 12970 12971 format %{ "addq $op1, $op2\t# overflow check long" %} 12972 ins_encode %{ 12973 __ addq($op1$$Register, $op2$$Register); 12974 %} 12975 ins_pipe(ialu_reg_reg); 12976 %} 12977 12978 instruct overflowAddL_rReg_imm(rFlagsReg cr, rax_RegL op1, immL32 op2) 12979 %{ 12980 match(Set cr (OverflowAddL op1 op2)); 12981 effect(DEF cr, USE_KILL op1, USE op2); 12982 12983 format %{ "addq $op1, $op2\t# overflow check long" %} 12984 ins_encode %{ 12985 __ addq($op1$$Register, $op2$$constant); 12986 %} 12987 ins_pipe(ialu_reg_reg); 12988 %} 12989 12990 instruct overflowSubI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 12991 %{ 12992 match(Set cr (OverflowSubI op1 op2)); 12993 12994 format %{ "cmpl $op1, $op2\t# overflow check int" %} 12995 ins_encode %{ 12996 __ cmpl($op1$$Register, $op2$$Register); 12997 %} 12998 ins_pipe(ialu_reg_reg); 12999 %} 13000 13001 instruct overflowSubI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 13002 %{ 13003 match(Set cr (OverflowSubI op1 op2)); 13004 13005 format %{ "cmpl $op1, $op2\t# overflow check int" %} 13006 ins_encode %{ 13007 __ cmpl($op1$$Register, $op2$$constant); 13008 %} 13009 ins_pipe(ialu_reg_reg); 13010 %} 13011 13012 instruct overflowSubL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 13013 %{ 13014 match(Set cr (OverflowSubL op1 op2)); 13015 13016 format %{ "cmpq $op1, $op2\t# overflow check long" %} 13017 ins_encode %{ 13018 __ cmpq($op1$$Register, $op2$$Register); 13019 %} 13020 ins_pipe(ialu_reg_reg); 13021 %} 13022 13023 instruct overflowSubL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 13024 %{ 13025 match(Set cr (OverflowSubL op1 op2)); 13026 13027 format %{ "cmpq $op1, $op2\t# overflow check long" %} 13028 ins_encode %{ 13029 __ cmpq($op1$$Register, $op2$$constant); 13030 %} 13031 ins_pipe(ialu_reg_reg); 13032 %} 13033 13034 instruct overflowNegI_rReg(rFlagsReg cr, immI_0 zero, rax_RegI op2) 13035 %{ 13036 match(Set cr (OverflowSubI zero op2)); 13037 effect(DEF cr, USE_KILL op2); 13038 13039 format %{ "negl $op2\t# overflow check int" %} 13040 ins_encode %{ 13041 __ negl($op2$$Register); 13042 %} 13043 ins_pipe(ialu_reg_reg); 13044 %} 13045 13046 instruct overflowNegL_rReg(rFlagsReg cr, immL0 zero, rax_RegL op2) 13047 %{ 13048 match(Set cr (OverflowSubL zero op2)); 13049 effect(DEF cr, USE_KILL op2); 13050 13051 format %{ "negq $op2\t# overflow check long" %} 13052 ins_encode %{ 13053 __ negq($op2$$Register); 13054 %} 13055 ins_pipe(ialu_reg_reg); 13056 %} 13057 13058 instruct overflowMulI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 13059 %{ 13060 match(Set cr (OverflowMulI op1 op2)); 13061 effect(DEF cr, USE_KILL op1, USE op2); 13062 13063 format %{ "imull $op1, $op2\t# overflow check int" %} 13064 ins_encode %{ 13065 __ imull($op1$$Register, $op2$$Register); 13066 %} 13067 ins_pipe(ialu_reg_reg_alu0); 13068 %} 13069 13070 instruct overflowMulI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2, rRegI tmp) 13071 %{ 13072 match(Set cr (OverflowMulI op1 op2)); 13073 effect(DEF cr, TEMP tmp, USE op1, USE op2); 13074 13075 format %{ "imull $tmp, $op1, $op2\t# overflow check int" %} 13076 ins_encode %{ 13077 __ imull($tmp$$Register, $op1$$Register, $op2$$constant); 13078 %} 13079 ins_pipe(ialu_reg_reg_alu0); 13080 %} 13081 13082 instruct overflowMulL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 13083 %{ 13084 match(Set cr (OverflowMulL op1 op2)); 13085 effect(DEF cr, USE_KILL op1, USE op2); 13086 13087 format %{ "imulq $op1, $op2\t# overflow check long" %} 13088 ins_encode %{ 13089 __ imulq($op1$$Register, $op2$$Register); 13090 %} 13091 ins_pipe(ialu_reg_reg_alu0); 13092 %} 13093 13094 instruct overflowMulL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2, rRegL tmp) 13095 %{ 13096 match(Set cr (OverflowMulL op1 op2)); 13097 effect(DEF cr, TEMP tmp, USE op1, USE op2); 13098 13099 format %{ "imulq $tmp, $op1, $op2\t# overflow check long" %} 13100 ins_encode %{ 13101 __ imulq($tmp$$Register, $op1$$Register, $op2$$constant); 13102 %} 13103 ins_pipe(ialu_reg_reg_alu0); 13104 %} 13105 13106 13107 //----------Control Flow Instructions------------------------------------------ 13108 // Signed compare Instructions 13109 13110 // XXX more variants!! 13111 instruct compI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 13112 %{ 13113 match(Set cr (CmpI op1 op2)); 13114 effect(DEF cr, USE op1, USE op2); 13115 13116 format %{ "cmpl $op1, $op2" %} 13117 ins_encode %{ 13118 __ cmpl($op1$$Register, $op2$$Register); 13119 %} 13120 ins_pipe(ialu_cr_reg_reg); 13121 %} 13122 13123 instruct compI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 13124 %{ 13125 match(Set cr (CmpI op1 op2)); 13126 13127 format %{ "cmpl $op1, $op2" %} 13128 ins_encode %{ 13129 __ cmpl($op1$$Register, $op2$$constant); 13130 %} 13131 ins_pipe(ialu_cr_reg_imm); 13132 %} 13133 13134 instruct compI_rReg_mem(rFlagsReg cr, rRegI op1, memory op2) 13135 %{ 13136 match(Set cr (CmpI op1 (LoadI op2))); 13137 13138 ins_cost(500); // XXX 13139 format %{ "cmpl $op1, $op2" %} 13140 ins_encode %{ 13141 __ cmpl($op1$$Register, $op2$$Address); 13142 %} 13143 ins_pipe(ialu_cr_reg_mem); 13144 %} 13145 13146 instruct testI_reg(rFlagsReg cr, rRegI src, immI_0 zero) 13147 %{ 13148 match(Set cr (CmpI src zero)); 13149 13150 format %{ "testl $src, $src" %} 13151 ins_encode %{ 13152 __ testl($src$$Register, $src$$Register); 13153 %} 13154 ins_pipe(ialu_cr_reg_imm); 13155 %} 13156 13157 instruct testI_reg_imm(rFlagsReg cr, rRegI src, immI con, immI_0 zero) 13158 %{ 13159 match(Set cr (CmpI (AndI src con) zero)); 13160 13161 format %{ "testl $src, $con" %} 13162 ins_encode %{ 13163 __ testl($src$$Register, $con$$constant); 13164 %} 13165 ins_pipe(ialu_cr_reg_imm); 13166 %} 13167 13168 instruct testI_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2, immI_0 zero) 13169 %{ 13170 match(Set cr (CmpI (AndI src1 src2) zero)); 13171 13172 format %{ "testl $src1, $src2" %} 13173 ins_encode %{ 13174 __ testl($src1$$Register, $src2$$Register); 13175 %} 13176 ins_pipe(ialu_cr_reg_imm); 13177 %} 13178 13179 instruct testI_reg_mem(rFlagsReg cr, rRegI src, memory mem, immI_0 zero) 13180 %{ 13181 match(Set cr (CmpI (AndI src (LoadI mem)) zero)); 13182 13183 format %{ "testl $src, $mem" %} 13184 ins_encode %{ 13185 __ testl($src$$Register, $mem$$Address); 13186 %} 13187 ins_pipe(ialu_cr_reg_mem); 13188 %} 13189 13190 // Unsigned compare Instructions; really, same as signed except they 13191 // produce an rFlagsRegU instead of rFlagsReg. 13192 instruct compU_rReg(rFlagsRegU cr, rRegI op1, rRegI op2) 13193 %{ 13194 match(Set cr (CmpU op1 op2)); 13195 13196 format %{ "cmpl $op1, $op2\t# unsigned" %} 13197 ins_encode %{ 13198 __ cmpl($op1$$Register, $op2$$Register); 13199 %} 13200 ins_pipe(ialu_cr_reg_reg); 13201 %} 13202 13203 instruct compU_rReg_imm(rFlagsRegU cr, rRegI op1, immI op2) 13204 %{ 13205 match(Set cr (CmpU op1 op2)); 13206 13207 format %{ "cmpl $op1, $op2\t# unsigned" %} 13208 ins_encode %{ 13209 __ cmpl($op1$$Register, $op2$$constant); 13210 %} 13211 ins_pipe(ialu_cr_reg_imm); 13212 %} 13213 13214 instruct compU_rReg_mem(rFlagsRegU cr, rRegI op1, memory op2) 13215 %{ 13216 match(Set cr (CmpU op1 (LoadI op2))); 13217 13218 ins_cost(500); // XXX 13219 format %{ "cmpl $op1, $op2\t# unsigned" %} 13220 ins_encode %{ 13221 __ cmpl($op1$$Register, $op2$$Address); 13222 %} 13223 ins_pipe(ialu_cr_reg_mem); 13224 %} 13225 13226 instruct testU_reg(rFlagsRegU cr, rRegI src, immI_0 zero) 13227 %{ 13228 match(Set cr (CmpU src zero)); 13229 13230 format %{ "testl $src, $src\t# unsigned" %} 13231 ins_encode %{ 13232 __ testl($src$$Register, $src$$Register); 13233 %} 13234 ins_pipe(ialu_cr_reg_imm); 13235 %} 13236 13237 instruct compP_rReg(rFlagsRegU cr, rRegP op1, rRegP op2) 13238 %{ 13239 match(Set cr (CmpP op1 op2)); 13240 13241 format %{ "cmpq $op1, $op2\t# ptr" %} 13242 ins_encode %{ 13243 __ cmpq($op1$$Register, $op2$$Register); 13244 %} 13245 ins_pipe(ialu_cr_reg_reg); 13246 %} 13247 13248 instruct compP_rReg_mem(rFlagsRegU cr, rRegP op1, memory op2) 13249 %{ 13250 match(Set cr (CmpP op1 (LoadP op2))); 13251 predicate(n->in(2)->as_Load()->barrier_data() == 0); 13252 13253 ins_cost(500); // XXX 13254 format %{ "cmpq $op1, $op2\t# ptr" %} 13255 ins_encode %{ 13256 __ cmpq($op1$$Register, $op2$$Address); 13257 %} 13258 ins_pipe(ialu_cr_reg_mem); 13259 %} 13260 13261 // XXX this is generalized by compP_rReg_mem??? 13262 // Compare raw pointer (used in out-of-heap check). 13263 // Only works because non-oop pointers must be raw pointers 13264 // and raw pointers have no anti-dependencies. 13265 instruct compP_mem_rReg(rFlagsRegU cr, rRegP op1, memory op2) 13266 %{ 13267 predicate(n->in(2)->in(2)->bottom_type()->reloc() == relocInfo::none && 13268 n->in(2)->as_Load()->barrier_data() == 0); 13269 match(Set cr (CmpP op1 (LoadP op2))); 13270 13271 format %{ "cmpq $op1, $op2\t# raw ptr" %} 13272 ins_encode %{ 13273 __ cmpq($op1$$Register, $op2$$Address); 13274 %} 13275 ins_pipe(ialu_cr_reg_mem); 13276 %} 13277 13278 // This will generate a signed flags result. This should be OK since 13279 // any compare to a zero should be eq/neq. 13280 instruct testP_reg(rFlagsReg cr, rRegP src, immP0 zero) 13281 %{ 13282 match(Set cr (CmpP src zero)); 13283 13284 format %{ "testq $src, $src\t# ptr" %} 13285 ins_encode %{ 13286 __ testq($src$$Register, $src$$Register); 13287 %} 13288 ins_pipe(ialu_cr_reg_imm); 13289 %} 13290 13291 // This will generate a signed flags result. This should be OK since 13292 // any compare to a zero should be eq/neq. 13293 instruct testP_mem(rFlagsReg cr, memory op, immP0 zero) 13294 %{ 13295 predicate((!UseCompressedOops || (CompressedOops::base() != nullptr)) && 13296 n->in(1)->as_Load()->barrier_data() == 0); 13297 match(Set cr (CmpP (LoadP op) zero)); 13298 13299 ins_cost(500); // XXX 13300 format %{ "testq $op, 0xffffffffffffffff\t# ptr" %} 13301 ins_encode %{ 13302 __ testq($op$$Address, 0xFFFFFFFF); 13303 %} 13304 ins_pipe(ialu_cr_reg_imm); 13305 %} 13306 13307 instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero) 13308 %{ 13309 predicate(UseCompressedOops && (CompressedOops::base() == nullptr) && 13310 n->in(1)->as_Load()->barrier_data() == 0); 13311 match(Set cr (CmpP (LoadP mem) zero)); 13312 13313 format %{ "cmpq R12, $mem\t# ptr (R12_heapbase==0)" %} 13314 ins_encode %{ 13315 __ cmpq(r12, $mem$$Address); 13316 %} 13317 ins_pipe(ialu_cr_reg_mem); 13318 %} 13319 13320 instruct compN_rReg(rFlagsRegU cr, rRegN op1, rRegN op2) 13321 %{ 13322 match(Set cr (CmpN op1 op2)); 13323 13324 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 13325 ins_encode %{ __ cmpl($op1$$Register, $op2$$Register); %} 13326 ins_pipe(ialu_cr_reg_reg); 13327 %} 13328 13329 instruct compN_rReg_mem(rFlagsRegU cr, rRegN src, memory mem) 13330 %{ 13331 predicate(n->in(2)->as_Load()->barrier_data() == 0); 13332 match(Set cr (CmpN src (LoadN mem))); 13333 13334 format %{ "cmpl $src, $mem\t# compressed ptr" %} 13335 ins_encode %{ 13336 __ cmpl($src$$Register, $mem$$Address); 13337 %} 13338 ins_pipe(ialu_cr_reg_mem); 13339 %} 13340 13341 instruct compN_rReg_imm(rFlagsRegU cr, rRegN op1, immN op2) %{ 13342 match(Set cr (CmpN op1 op2)); 13343 13344 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 13345 ins_encode %{ 13346 __ cmp_narrow_oop($op1$$Register, (jobject)$op2$$constant); 13347 %} 13348 ins_pipe(ialu_cr_reg_imm); 13349 %} 13350 13351 instruct compN_mem_imm(rFlagsRegU cr, memory mem, immN src) 13352 %{ 13353 predicate(n->in(2)->as_Load()->barrier_data() == 0); 13354 match(Set cr (CmpN src (LoadN mem))); 13355 13356 format %{ "cmpl $mem, $src\t# compressed ptr" %} 13357 ins_encode %{ 13358 __ cmp_narrow_oop($mem$$Address, (jobject)$src$$constant); 13359 %} 13360 ins_pipe(ialu_cr_reg_mem); 13361 %} 13362 13363 instruct compN_rReg_imm_klass(rFlagsRegU cr, rRegN op1, immNKlass op2) %{ 13364 match(Set cr (CmpN op1 op2)); 13365 13366 format %{ "cmpl $op1, $op2\t# compressed klass ptr" %} 13367 ins_encode %{ 13368 __ cmp_narrow_klass($op1$$Register, (Klass*)$op2$$constant); 13369 %} 13370 ins_pipe(ialu_cr_reg_imm); 13371 %} 13372 13373 instruct compN_mem_imm_klass(rFlagsRegU cr, memory mem, immNKlass src) 13374 %{ 13375 predicate(!UseCompactObjectHeaders); 13376 match(Set cr (CmpN src (LoadNKlass mem))); 13377 13378 format %{ "cmpl $mem, $src\t# compressed klass ptr" %} 13379 ins_encode %{ 13380 __ cmp_narrow_klass($mem$$Address, (Klass*)$src$$constant); 13381 %} 13382 ins_pipe(ialu_cr_reg_mem); 13383 %} 13384 13385 instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{ 13386 match(Set cr (CmpN src zero)); 13387 13388 format %{ "testl $src, $src\t# compressed ptr" %} 13389 ins_encode %{ __ testl($src$$Register, $src$$Register); %} 13390 ins_pipe(ialu_cr_reg_imm); 13391 %} 13392 13393 instruct testN_mem(rFlagsReg cr, memory mem, immN0 zero) 13394 %{ 13395 predicate(CompressedOops::base() != nullptr && 13396 n->in(1)->as_Load()->barrier_data() == 0); 13397 match(Set cr (CmpN (LoadN mem) zero)); 13398 13399 ins_cost(500); // XXX 13400 format %{ "testl $mem, 0xffffffff\t# compressed ptr" %} 13401 ins_encode %{ 13402 __ cmpl($mem$$Address, (int)0xFFFFFFFF); 13403 %} 13404 ins_pipe(ialu_cr_reg_mem); 13405 %} 13406 13407 instruct testN_mem_reg0(rFlagsReg cr, memory mem, immN0 zero) 13408 %{ 13409 predicate(CompressedOops::base() == nullptr && 13410 n->in(1)->as_Load()->barrier_data() == 0); 13411 match(Set cr (CmpN (LoadN mem) zero)); 13412 13413 format %{ "cmpl R12, $mem\t# compressed ptr (R12_heapbase==0)" %} 13414 ins_encode %{ 13415 __ cmpl(r12, $mem$$Address); 13416 %} 13417 ins_pipe(ialu_cr_reg_mem); 13418 %} 13419 13420 // Yanked all unsigned pointer compare operations. 13421 // Pointer compares are done with CmpP which is already unsigned. 13422 13423 instruct compL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 13424 %{ 13425 match(Set cr (CmpL op1 op2)); 13426 13427 format %{ "cmpq $op1, $op2" %} 13428 ins_encode %{ 13429 __ cmpq($op1$$Register, $op2$$Register); 13430 %} 13431 ins_pipe(ialu_cr_reg_reg); 13432 %} 13433 13434 instruct compL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 13435 %{ 13436 match(Set cr (CmpL op1 op2)); 13437 13438 format %{ "cmpq $op1, $op2" %} 13439 ins_encode %{ 13440 __ cmpq($op1$$Register, $op2$$constant); 13441 %} 13442 ins_pipe(ialu_cr_reg_imm); 13443 %} 13444 13445 instruct compL_rReg_mem(rFlagsReg cr, rRegL op1, memory op2) 13446 %{ 13447 match(Set cr (CmpL op1 (LoadL op2))); 13448 13449 format %{ "cmpq $op1, $op2" %} 13450 ins_encode %{ 13451 __ cmpq($op1$$Register, $op2$$Address); 13452 %} 13453 ins_pipe(ialu_cr_reg_mem); 13454 %} 13455 13456 instruct testL_reg(rFlagsReg cr, rRegL src, immL0 zero) 13457 %{ 13458 match(Set cr (CmpL src zero)); 13459 13460 format %{ "testq $src, $src" %} 13461 ins_encode %{ 13462 __ testq($src$$Register, $src$$Register); 13463 %} 13464 ins_pipe(ialu_cr_reg_imm); 13465 %} 13466 13467 instruct testL_reg_imm(rFlagsReg cr, rRegL src, immL32 con, immL0 zero) 13468 %{ 13469 match(Set cr (CmpL (AndL src con) zero)); 13470 13471 format %{ "testq $src, $con\t# long" %} 13472 ins_encode %{ 13473 __ testq($src$$Register, $con$$constant); 13474 %} 13475 ins_pipe(ialu_cr_reg_imm); 13476 %} 13477 13478 instruct testL_reg_reg(rFlagsReg cr, rRegL src1, rRegL src2, immL0 zero) 13479 %{ 13480 match(Set cr (CmpL (AndL src1 src2) zero)); 13481 13482 format %{ "testq $src1, $src2\t# long" %} 13483 ins_encode %{ 13484 __ testq($src1$$Register, $src2$$Register); 13485 %} 13486 ins_pipe(ialu_cr_reg_imm); 13487 %} 13488 13489 instruct testL_reg_mem(rFlagsReg cr, rRegL src, memory mem, immL0 zero) 13490 %{ 13491 match(Set cr (CmpL (AndL src (LoadL mem)) zero)); 13492 13493 format %{ "testq $src, $mem" %} 13494 ins_encode %{ 13495 __ testq($src$$Register, $mem$$Address); 13496 %} 13497 ins_pipe(ialu_cr_reg_mem); 13498 %} 13499 13500 instruct testL_reg_mem2(rFlagsReg cr, rRegP src, memory mem, immL0 zero) 13501 %{ 13502 match(Set cr (CmpL (AndL (CastP2X src) (LoadL mem)) zero)); 13503 13504 format %{ "testq $src, $mem" %} 13505 ins_encode %{ 13506 __ testq($src$$Register, $mem$$Address); 13507 %} 13508 ins_pipe(ialu_cr_reg_mem); 13509 %} 13510 13511 // Manifest a CmpU result in an integer register. Very painful. 13512 // This is the test to avoid. 13513 instruct cmpU3_reg_reg(rRegI dst, rRegI src1, rRegI src2, rFlagsReg flags) 13514 %{ 13515 match(Set dst (CmpU3 src1 src2)); 13516 effect(KILL flags); 13517 13518 ins_cost(275); // XXX 13519 format %{ "cmpl $src1, $src2\t# CmpL3\n\t" 13520 "movl $dst, -1\n\t" 13521 "jb,u done\n\t" 13522 "setcc $dst \t# emits setne + movzbl or setzune for APX" 13523 "done:" %} 13524 ins_encode %{ 13525 Label done; 13526 __ cmpl($src1$$Register, $src2$$Register); 13527 __ movl($dst$$Register, -1); 13528 __ jccb(Assembler::below, done); 13529 __ setcc(Assembler::notZero, $dst$$Register); 13530 __ bind(done); 13531 %} 13532 ins_pipe(pipe_slow); 13533 %} 13534 13535 // Manifest a CmpL result in an integer register. Very painful. 13536 // This is the test to avoid. 13537 instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 13538 %{ 13539 match(Set dst (CmpL3 src1 src2)); 13540 effect(KILL flags); 13541 13542 ins_cost(275); // XXX 13543 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 13544 "movl $dst, -1\n\t" 13545 "jl,s done\n\t" 13546 "setcc $dst \t# emits setne + movzbl or setzune for APX" 13547 "done:" %} 13548 ins_encode %{ 13549 Label done; 13550 __ cmpq($src1$$Register, $src2$$Register); 13551 __ movl($dst$$Register, -1); 13552 __ jccb(Assembler::less, done); 13553 __ setcc(Assembler::notZero, $dst$$Register); 13554 __ bind(done); 13555 %} 13556 ins_pipe(pipe_slow); 13557 %} 13558 13559 // Manifest a CmpUL result in an integer register. Very painful. 13560 // This is the test to avoid. 13561 instruct cmpUL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 13562 %{ 13563 match(Set dst (CmpUL3 src1 src2)); 13564 effect(KILL flags); 13565 13566 ins_cost(275); // XXX 13567 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 13568 "movl $dst, -1\n\t" 13569 "jb,u done\n\t" 13570 "setcc $dst \t# emits setne + movzbl or setzune for APX" 13571 "done:" %} 13572 ins_encode %{ 13573 Label done; 13574 __ cmpq($src1$$Register, $src2$$Register); 13575 __ movl($dst$$Register, -1); 13576 __ jccb(Assembler::below, done); 13577 __ setcc(Assembler::notZero, $dst$$Register); 13578 __ bind(done); 13579 %} 13580 ins_pipe(pipe_slow); 13581 %} 13582 13583 // Unsigned long compare Instructions; really, same as signed long except they 13584 // produce an rFlagsRegU instead of rFlagsReg. 13585 instruct compUL_rReg(rFlagsRegU cr, rRegL op1, rRegL op2) 13586 %{ 13587 match(Set cr (CmpUL op1 op2)); 13588 13589 format %{ "cmpq $op1, $op2\t# unsigned" %} 13590 ins_encode %{ 13591 __ cmpq($op1$$Register, $op2$$Register); 13592 %} 13593 ins_pipe(ialu_cr_reg_reg); 13594 %} 13595 13596 instruct compUL_rReg_imm(rFlagsRegU cr, rRegL op1, immL32 op2) 13597 %{ 13598 match(Set cr (CmpUL op1 op2)); 13599 13600 format %{ "cmpq $op1, $op2\t# unsigned" %} 13601 ins_encode %{ 13602 __ cmpq($op1$$Register, $op2$$constant); 13603 %} 13604 ins_pipe(ialu_cr_reg_imm); 13605 %} 13606 13607 instruct compUL_rReg_mem(rFlagsRegU cr, rRegL op1, memory op2) 13608 %{ 13609 match(Set cr (CmpUL op1 (LoadL op2))); 13610 13611 format %{ "cmpq $op1, $op2\t# unsigned" %} 13612 ins_encode %{ 13613 __ cmpq($op1$$Register, $op2$$Address); 13614 %} 13615 ins_pipe(ialu_cr_reg_mem); 13616 %} 13617 13618 instruct testUL_reg(rFlagsRegU cr, rRegL src, immL0 zero) 13619 %{ 13620 match(Set cr (CmpUL src zero)); 13621 13622 format %{ "testq $src, $src\t# unsigned" %} 13623 ins_encode %{ 13624 __ testq($src$$Register, $src$$Register); 13625 %} 13626 ins_pipe(ialu_cr_reg_imm); 13627 %} 13628 13629 instruct compB_mem_imm(rFlagsReg cr, memory mem, immI8 imm) 13630 %{ 13631 match(Set cr (CmpI (LoadB mem) imm)); 13632 13633 ins_cost(125); 13634 format %{ "cmpb $mem, $imm" %} 13635 ins_encode %{ __ cmpb($mem$$Address, $imm$$constant); %} 13636 ins_pipe(ialu_cr_reg_mem); 13637 %} 13638 13639 instruct testUB_mem_imm(rFlagsReg cr, memory mem, immU7 imm, immI_0 zero) 13640 %{ 13641 match(Set cr (CmpI (AndI (LoadUB mem) imm) zero)); 13642 13643 ins_cost(125); 13644 format %{ "testb $mem, $imm\t# ubyte" %} 13645 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %} 13646 ins_pipe(ialu_cr_reg_mem); 13647 %} 13648 13649 instruct testB_mem_imm(rFlagsReg cr, memory mem, immI8 imm, immI_0 zero) 13650 %{ 13651 match(Set cr (CmpI (AndI (LoadB mem) imm) zero)); 13652 13653 ins_cost(125); 13654 format %{ "testb $mem, $imm\t# byte" %} 13655 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %} 13656 ins_pipe(ialu_cr_reg_mem); 13657 %} 13658 13659 //----------Max and Min-------------------------------------------------------- 13660 // Min Instructions 13661 13662 instruct cmovI_reg_g(rRegI dst, rRegI src, rFlagsReg cr) 13663 %{ 13664 predicate(!UseAPX); 13665 effect(USE_DEF dst, USE src, USE cr); 13666 13667 format %{ "cmovlgt $dst, $src\t# min" %} 13668 ins_encode %{ 13669 __ cmovl(Assembler::greater, $dst$$Register, $src$$Register); 13670 %} 13671 ins_pipe(pipe_cmov_reg); 13672 %} 13673 13674 instruct cmovI_reg_g_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr) 13675 %{ 13676 predicate(UseAPX); 13677 effect(DEF dst, USE src1, USE src2, USE cr); 13678 13679 format %{ "ecmovlgt $dst, $src1, $src2\t# min ndd" %} 13680 ins_encode %{ 13681 __ ecmovl(Assembler::greater, $dst$$Register, $src1$$Register, $src2$$Register); 13682 %} 13683 ins_pipe(pipe_cmov_reg); 13684 %} 13685 13686 instruct minI_rReg(rRegI dst, rRegI src) 13687 %{ 13688 predicate(!UseAPX); 13689 match(Set dst (MinI dst src)); 13690 13691 ins_cost(200); 13692 expand %{ 13693 rFlagsReg cr; 13694 compI_rReg(cr, dst, src); 13695 cmovI_reg_g(dst, src, cr); 13696 %} 13697 %} 13698 13699 instruct minI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2) 13700 %{ 13701 predicate(UseAPX); 13702 match(Set dst (MinI src1 src2)); 13703 effect(DEF dst, USE src1, USE src2); 13704 13705 ins_cost(200); 13706 expand %{ 13707 rFlagsReg cr; 13708 compI_rReg(cr, src1, src2); 13709 cmovI_reg_g_ndd(dst, src1, src2, cr); 13710 %} 13711 %} 13712 13713 instruct cmovI_reg_l(rRegI dst, rRegI src, rFlagsReg cr) 13714 %{ 13715 predicate(!UseAPX); 13716 effect(USE_DEF dst, USE src, USE cr); 13717 13718 format %{ "cmovllt $dst, $src\t# max" %} 13719 ins_encode %{ 13720 __ cmovl(Assembler::less, $dst$$Register, $src$$Register); 13721 %} 13722 ins_pipe(pipe_cmov_reg); 13723 %} 13724 13725 instruct cmovI_reg_l_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr) 13726 %{ 13727 predicate(UseAPX); 13728 effect(DEF dst, USE src1, USE src2, USE cr); 13729 13730 format %{ "ecmovllt $dst, $src1, $src2\t# max ndd" %} 13731 ins_encode %{ 13732 __ ecmovl(Assembler::less, $dst$$Register, $src1$$Register, $src2$$Register); 13733 %} 13734 ins_pipe(pipe_cmov_reg); 13735 %} 13736 13737 instruct maxI_rReg(rRegI dst, rRegI src) 13738 %{ 13739 predicate(!UseAPX); 13740 match(Set dst (MaxI dst src)); 13741 13742 ins_cost(200); 13743 expand %{ 13744 rFlagsReg cr; 13745 compI_rReg(cr, dst, src); 13746 cmovI_reg_l(dst, src, cr); 13747 %} 13748 %} 13749 13750 instruct maxI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2) 13751 %{ 13752 predicate(UseAPX); 13753 match(Set dst (MaxI src1 src2)); 13754 effect(DEF dst, USE src1, USE src2); 13755 13756 ins_cost(200); 13757 expand %{ 13758 rFlagsReg cr; 13759 compI_rReg(cr, src1, src2); 13760 cmovI_reg_l_ndd(dst, src1, src2, cr); 13761 %} 13762 %} 13763 13764 // ============================================================================ 13765 // Branch Instructions 13766 13767 // Jump Direct - Label defines a relative address from JMP+1 13768 instruct jmpDir(label labl) 13769 %{ 13770 match(Goto); 13771 effect(USE labl); 13772 13773 ins_cost(300); 13774 format %{ "jmp $labl" %} 13775 size(5); 13776 ins_encode %{ 13777 Label* L = $labl$$label; 13778 __ jmp(*L, false); // Always long jump 13779 %} 13780 ins_pipe(pipe_jmp); 13781 %} 13782 13783 // Jump Direct Conditional - Label defines a relative address from Jcc+1 13784 instruct jmpCon(cmpOp cop, rFlagsReg cr, label labl) 13785 %{ 13786 match(If cop cr); 13787 effect(USE labl); 13788 13789 ins_cost(300); 13790 format %{ "j$cop $labl" %} 13791 size(6); 13792 ins_encode %{ 13793 Label* L = $labl$$label; 13794 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 13795 %} 13796 ins_pipe(pipe_jcc); 13797 %} 13798 13799 // Jump Direct Conditional - Label defines a relative address from Jcc+1 13800 instruct jmpLoopEnd(cmpOp cop, rFlagsReg cr, label labl) 13801 %{ 13802 match(CountedLoopEnd cop cr); 13803 effect(USE labl); 13804 13805 ins_cost(300); 13806 format %{ "j$cop $labl\t# loop end" %} 13807 size(6); 13808 ins_encode %{ 13809 Label* L = $labl$$label; 13810 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 13811 %} 13812 ins_pipe(pipe_jcc); 13813 %} 13814 13815 // Jump Direct Conditional - using unsigned comparison 13816 instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 13817 match(If cop cmp); 13818 effect(USE labl); 13819 13820 ins_cost(300); 13821 format %{ "j$cop,u $labl" %} 13822 size(6); 13823 ins_encode %{ 13824 Label* L = $labl$$label; 13825 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 13826 %} 13827 ins_pipe(pipe_jcc); 13828 %} 13829 13830 instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 13831 match(If cop cmp); 13832 effect(USE labl); 13833 13834 ins_cost(200); 13835 format %{ "j$cop,u $labl" %} 13836 size(6); 13837 ins_encode %{ 13838 Label* L = $labl$$label; 13839 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 13840 %} 13841 ins_pipe(pipe_jcc); 13842 %} 13843 13844 instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 13845 match(If cop cmp); 13846 effect(USE labl); 13847 13848 ins_cost(200); 13849 format %{ $$template 13850 if ($cop$$cmpcode == Assembler::notEqual) { 13851 $$emit$$"jp,u $labl\n\t" 13852 $$emit$$"j$cop,u $labl" 13853 } else { 13854 $$emit$$"jp,u done\n\t" 13855 $$emit$$"j$cop,u $labl\n\t" 13856 $$emit$$"done:" 13857 } 13858 %} 13859 ins_encode %{ 13860 Label* l = $labl$$label; 13861 if ($cop$$cmpcode == Assembler::notEqual) { 13862 __ jcc(Assembler::parity, *l, false); 13863 __ jcc(Assembler::notEqual, *l, false); 13864 } else if ($cop$$cmpcode == Assembler::equal) { 13865 Label done; 13866 __ jccb(Assembler::parity, done); 13867 __ jcc(Assembler::equal, *l, false); 13868 __ bind(done); 13869 } else { 13870 ShouldNotReachHere(); 13871 } 13872 %} 13873 ins_pipe(pipe_jcc); 13874 %} 13875 13876 // ============================================================================ 13877 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary 13878 // superklass array for an instance of the superklass. Set a hidden 13879 // internal cache on a hit (cache is checked with exposed code in 13880 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The 13881 // encoding ALSO sets flags. 13882 13883 instruct partialSubtypeCheck(rdi_RegP result, 13884 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 13885 rFlagsReg cr) 13886 %{ 13887 match(Set result (PartialSubtypeCheck sub super)); 13888 predicate(!UseSecondarySupersTable); 13889 effect(KILL rcx, KILL cr); 13890 13891 ins_cost(1100); // slightly larger than the next version 13892 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 13893 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 13894 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 13895 "repne scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t" 13896 "jne,s miss\t\t# Missed: rdi not-zero\n\t" 13897 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 13898 "xorq $result, $result\t\t Hit: rdi zero\n\t" 13899 "miss:\t" %} 13900 13901 ins_encode %{ 13902 Label miss; 13903 // NB: Callers may assume that, when $result is a valid register, 13904 // check_klass_subtype_slow_path_linear sets it to a nonzero 13905 // value. 13906 __ check_klass_subtype_slow_path_linear($sub$$Register, $super$$Register, 13907 $rcx$$Register, $result$$Register, 13908 nullptr, &miss, 13909 /*set_cond_codes:*/ true); 13910 __ xorptr($result$$Register, $result$$Register); 13911 __ bind(miss); 13912 %} 13913 13914 ins_pipe(pipe_slow); 13915 %} 13916 13917 // ============================================================================ 13918 // Two versions of hashtable-based partialSubtypeCheck, both used when 13919 // we need to search for a super class in the secondary supers array. 13920 // The first is used when we don't know _a priori_ the class being 13921 // searched for. The second, far more common, is used when we do know: 13922 // this is used for instanceof, checkcast, and any case where C2 can 13923 // determine it by constant propagation. 13924 13925 instruct partialSubtypeCheckVarSuper(rsi_RegP sub, rax_RegP super, rdi_RegP result, 13926 rdx_RegL temp1, rcx_RegL temp2, rbx_RegP temp3, r11_RegL temp4, 13927 rFlagsReg cr) 13928 %{ 13929 match(Set result (PartialSubtypeCheck sub super)); 13930 predicate(UseSecondarySupersTable); 13931 effect(KILL cr, TEMP temp1, TEMP temp2, TEMP temp3, TEMP temp4); 13932 13933 ins_cost(1000); 13934 format %{ "partialSubtypeCheck $result, $sub, $super" %} 13935 13936 ins_encode %{ 13937 __ lookup_secondary_supers_table_var($sub$$Register, $super$$Register, $temp1$$Register, $temp2$$Register, 13938 $temp3$$Register, $temp4$$Register, $result$$Register); 13939 %} 13940 13941 ins_pipe(pipe_slow); 13942 %} 13943 13944 instruct partialSubtypeCheckConstSuper(rsi_RegP sub, rax_RegP super_reg, immP super_con, rdi_RegP result, 13945 rdx_RegL temp1, rcx_RegL temp2, rbx_RegP temp3, r11_RegL temp4, 13946 rFlagsReg cr) 13947 %{ 13948 match(Set result (PartialSubtypeCheck sub (Binary super_reg super_con))); 13949 predicate(UseSecondarySupersTable); 13950 effect(KILL cr, TEMP temp1, TEMP temp2, TEMP temp3, TEMP temp4); 13951 13952 ins_cost(700); // smaller than the next version 13953 format %{ "partialSubtypeCheck $result, $sub, $super_reg, $super_con" %} 13954 13955 ins_encode %{ 13956 u1 super_klass_slot = ((Klass*)$super_con$$constant)->hash_slot(); 13957 if (InlineSecondarySupersTest) { 13958 __ lookup_secondary_supers_table_const($sub$$Register, $super_reg$$Register, $temp1$$Register, $temp2$$Register, 13959 $temp3$$Register, $temp4$$Register, $result$$Register, 13960 super_klass_slot); 13961 } else { 13962 __ call(RuntimeAddress(StubRoutines::lookup_secondary_supers_table_stub(super_klass_slot))); 13963 } 13964 %} 13965 13966 ins_pipe(pipe_slow); 13967 %} 13968 13969 // ============================================================================ 13970 // Branch Instructions -- short offset versions 13971 // 13972 // These instructions are used to replace jumps of a long offset (the default 13973 // match) with jumps of a shorter offset. These instructions are all tagged 13974 // with the ins_short_branch attribute, which causes the ADLC to suppress the 13975 // match rules in general matching. Instead, the ADLC generates a conversion 13976 // method in the MachNode which can be used to do in-place replacement of the 13977 // long variant with the shorter variant. The compiler will determine if a 13978 // branch can be taken by the is_short_branch_offset() predicate in the machine 13979 // specific code section of the file. 13980 13981 // Jump Direct - Label defines a relative address from JMP+1 13982 instruct jmpDir_short(label labl) %{ 13983 match(Goto); 13984 effect(USE labl); 13985 13986 ins_cost(300); 13987 format %{ "jmp,s $labl" %} 13988 size(2); 13989 ins_encode %{ 13990 Label* L = $labl$$label; 13991 __ jmpb(*L); 13992 %} 13993 ins_pipe(pipe_jmp); 13994 ins_short_branch(1); 13995 %} 13996 13997 // Jump Direct Conditional - Label defines a relative address from Jcc+1 13998 instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{ 13999 match(If cop cr); 14000 effect(USE labl); 14001 14002 ins_cost(300); 14003 format %{ "j$cop,s $labl" %} 14004 size(2); 14005 ins_encode %{ 14006 Label* L = $labl$$label; 14007 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 14008 %} 14009 ins_pipe(pipe_jcc); 14010 ins_short_branch(1); 14011 %} 14012 14013 // Jump Direct Conditional - Label defines a relative address from Jcc+1 14014 instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{ 14015 match(CountedLoopEnd cop cr); 14016 effect(USE labl); 14017 14018 ins_cost(300); 14019 format %{ "j$cop,s $labl\t# loop end" %} 14020 size(2); 14021 ins_encode %{ 14022 Label* L = $labl$$label; 14023 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 14024 %} 14025 ins_pipe(pipe_jcc); 14026 ins_short_branch(1); 14027 %} 14028 14029 // Jump Direct Conditional - using unsigned comparison 14030 instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 14031 match(If cop cmp); 14032 effect(USE labl); 14033 14034 ins_cost(300); 14035 format %{ "j$cop,us $labl" %} 14036 size(2); 14037 ins_encode %{ 14038 Label* L = $labl$$label; 14039 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 14040 %} 14041 ins_pipe(pipe_jcc); 14042 ins_short_branch(1); 14043 %} 14044 14045 instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 14046 match(If cop cmp); 14047 effect(USE labl); 14048 14049 ins_cost(300); 14050 format %{ "j$cop,us $labl" %} 14051 size(2); 14052 ins_encode %{ 14053 Label* L = $labl$$label; 14054 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 14055 %} 14056 ins_pipe(pipe_jcc); 14057 ins_short_branch(1); 14058 %} 14059 14060 instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 14061 match(If cop cmp); 14062 effect(USE labl); 14063 14064 ins_cost(300); 14065 format %{ $$template 14066 if ($cop$$cmpcode == Assembler::notEqual) { 14067 $$emit$$"jp,u,s $labl\n\t" 14068 $$emit$$"j$cop,u,s $labl" 14069 } else { 14070 $$emit$$"jp,u,s done\n\t" 14071 $$emit$$"j$cop,u,s $labl\n\t" 14072 $$emit$$"done:" 14073 } 14074 %} 14075 size(4); 14076 ins_encode %{ 14077 Label* l = $labl$$label; 14078 if ($cop$$cmpcode == Assembler::notEqual) { 14079 __ jccb(Assembler::parity, *l); 14080 __ jccb(Assembler::notEqual, *l); 14081 } else if ($cop$$cmpcode == Assembler::equal) { 14082 Label done; 14083 __ jccb(Assembler::parity, done); 14084 __ jccb(Assembler::equal, *l); 14085 __ bind(done); 14086 } else { 14087 ShouldNotReachHere(); 14088 } 14089 %} 14090 ins_pipe(pipe_jcc); 14091 ins_short_branch(1); 14092 %} 14093 14094 // ============================================================================ 14095 // inlined locking and unlocking 14096 14097 instruct cmpFastLockLightweight(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI rax_reg, rRegP tmp) %{ 14098 match(Set cr (FastLock object box)); 14099 effect(TEMP rax_reg, TEMP tmp, USE_KILL box); 14100 ins_cost(300); 14101 format %{ "fastlock $object,$box\t! kills $box,$rax_reg,$tmp" %} 14102 ins_encode %{ 14103 __ fast_lock_lightweight($object$$Register, $box$$Register, $rax_reg$$Register, $tmp$$Register, r15_thread); 14104 %} 14105 ins_pipe(pipe_slow); 14106 %} 14107 14108 instruct cmpFastUnlockLightweight(rFlagsReg cr, rRegP object, rax_RegP rax_reg, rRegP tmp) %{ 14109 match(Set cr (FastUnlock object rax_reg)); 14110 effect(TEMP tmp, USE_KILL rax_reg); 14111 ins_cost(300); 14112 format %{ "fastunlock $object,$rax_reg\t! kills $rax_reg,$tmp" %} 14113 ins_encode %{ 14114 __ fast_unlock_lightweight($object$$Register, $rax_reg$$Register, $tmp$$Register, r15_thread); 14115 %} 14116 ins_pipe(pipe_slow); 14117 %} 14118 14119 14120 // ============================================================================ 14121 // Safepoint Instructions 14122 instruct safePoint_poll_tls(rFlagsReg cr, rRegP poll) 14123 %{ 14124 match(SafePoint poll); 14125 effect(KILL cr, USE poll); 14126 14127 format %{ "testl rax, [$poll]\t" 14128 "# Safepoint: poll for GC" %} 14129 ins_cost(125); 14130 ins_encode %{ 14131 __ relocate(relocInfo::poll_type); 14132 address pre_pc = __ pc(); 14133 __ testl(rax, Address($poll$$Register, 0)); 14134 assert(nativeInstruction_at(pre_pc)->is_safepoint_poll(), "must emit test %%eax [reg]"); 14135 %} 14136 ins_pipe(ialu_reg_mem); 14137 %} 14138 14139 instruct mask_all_evexL(kReg dst, rRegL src) %{ 14140 match(Set dst (MaskAll src)); 14141 format %{ "mask_all_evexL $dst, $src \t! mask all operation" %} 14142 ins_encode %{ 14143 int mask_len = Matcher::vector_length(this); 14144 __ vector_maskall_operation($dst$$KRegister, $src$$Register, mask_len); 14145 %} 14146 ins_pipe( pipe_slow ); 14147 %} 14148 14149 instruct mask_all_evexI_GT32(kReg dst, rRegI src, rRegL tmp) %{ 14150 predicate(Matcher::vector_length(n) > 32); 14151 match(Set dst (MaskAll src)); 14152 effect(TEMP tmp); 14153 format %{ "mask_all_evexI_GT32 $dst, $src \t! using $tmp as TEMP" %} 14154 ins_encode %{ 14155 int mask_len = Matcher::vector_length(this); 14156 __ movslq($tmp$$Register, $src$$Register); 14157 __ vector_maskall_operation($dst$$KRegister, $tmp$$Register, mask_len); 14158 %} 14159 ins_pipe( pipe_slow ); 14160 %} 14161 14162 // ============================================================================ 14163 // Procedure Call/Return Instructions 14164 // Call Java Static Instruction 14165 // Note: If this code changes, the corresponding ret_addr_offset() and 14166 // compute_padding() functions will have to be adjusted. 14167 instruct CallStaticJavaDirect(method meth) %{ 14168 match(CallStaticJava); 14169 effect(USE meth); 14170 14171 ins_cost(300); 14172 format %{ "call,static " %} 14173 opcode(0xE8); /* E8 cd */ 14174 ins_encode(clear_avx, Java_Static_Call(meth), call_epilog); 14175 ins_pipe(pipe_slow); 14176 ins_alignment(4); 14177 %} 14178 14179 // Call Java Dynamic Instruction 14180 // Note: If this code changes, the corresponding ret_addr_offset() and 14181 // compute_padding() functions will have to be adjusted. 14182 instruct CallDynamicJavaDirect(method meth) 14183 %{ 14184 match(CallDynamicJava); 14185 effect(USE meth); 14186 14187 ins_cost(300); 14188 format %{ "movq rax, #Universe::non_oop_word()\n\t" 14189 "call,dynamic " %} 14190 ins_encode(clear_avx, Java_Dynamic_Call(meth), call_epilog); 14191 ins_pipe(pipe_slow); 14192 ins_alignment(4); 14193 %} 14194 14195 // Call Runtime Instruction 14196 instruct CallRuntimeDirect(method meth) 14197 %{ 14198 match(CallRuntime); 14199 effect(USE meth); 14200 14201 ins_cost(300); 14202 format %{ "call,runtime " %} 14203 ins_encode(clear_avx, Java_To_Runtime(meth)); 14204 ins_pipe(pipe_slow); 14205 %} 14206 14207 // Call runtime without safepoint 14208 instruct CallLeafDirect(method meth) 14209 %{ 14210 match(CallLeaf); 14211 effect(USE meth); 14212 14213 ins_cost(300); 14214 format %{ "call_leaf,runtime " %} 14215 ins_encode(clear_avx, Java_To_Runtime(meth)); 14216 ins_pipe(pipe_slow); 14217 %} 14218 14219 // Call runtime without safepoint and with vector arguments 14220 instruct CallLeafDirectVector(method meth) 14221 %{ 14222 match(CallLeafVector); 14223 effect(USE meth); 14224 14225 ins_cost(300); 14226 format %{ "call_leaf,vector " %} 14227 ins_encode(Java_To_Runtime(meth)); 14228 ins_pipe(pipe_slow); 14229 %} 14230 14231 // Call runtime without safepoint 14232 instruct CallLeafNoFPDirect(method meth) 14233 %{ 14234 match(CallLeafNoFP); 14235 effect(USE meth); 14236 14237 ins_cost(300); 14238 format %{ "call_leaf_nofp,runtime " %} 14239 ins_encode(clear_avx, Java_To_Runtime(meth)); 14240 ins_pipe(pipe_slow); 14241 %} 14242 14243 // Return Instruction 14244 // Remove the return address & jump to it. 14245 // Notice: We always emit a nop after a ret to make sure there is room 14246 // for safepoint patching 14247 instruct Ret() 14248 %{ 14249 match(Return); 14250 14251 format %{ "ret" %} 14252 ins_encode %{ 14253 __ ret(0); 14254 %} 14255 ins_pipe(pipe_jmp); 14256 %} 14257 14258 // Tail Call; Jump from runtime stub to Java code. 14259 // Also known as an 'interprocedural jump'. 14260 // Target of jump will eventually return to caller. 14261 // TailJump below removes the return address. 14262 // Don't use rbp for 'jump_target' because a MachEpilogNode has already been 14263 // emitted just above the TailCall which has reset rbp to the caller state. 14264 instruct TailCalljmpInd(no_rbp_RegP jump_target, rbx_RegP method_ptr) 14265 %{ 14266 match(TailCall jump_target method_ptr); 14267 14268 ins_cost(300); 14269 format %{ "jmp $jump_target\t# rbx holds method" %} 14270 ins_encode %{ 14271 __ jmp($jump_target$$Register); 14272 %} 14273 ins_pipe(pipe_jmp); 14274 %} 14275 14276 // Tail Jump; remove the return address; jump to target. 14277 // TailCall above leaves the return address around. 14278 instruct tailjmpInd(no_rbp_RegP jump_target, rax_RegP ex_oop) 14279 %{ 14280 match(TailJump jump_target ex_oop); 14281 14282 ins_cost(300); 14283 format %{ "popq rdx\t# pop return address\n\t" 14284 "jmp $jump_target" %} 14285 ins_encode %{ 14286 __ popq(as_Register(RDX_enc)); 14287 __ jmp($jump_target$$Register); 14288 %} 14289 ins_pipe(pipe_jmp); 14290 %} 14291 14292 // Forward exception. 14293 instruct ForwardExceptionjmp() 14294 %{ 14295 match(ForwardException); 14296 14297 format %{ "jmp forward_exception_stub" %} 14298 ins_encode %{ 14299 __ jump(RuntimeAddress(StubRoutines::forward_exception_entry()), noreg); 14300 %} 14301 ins_pipe(pipe_jmp); 14302 %} 14303 14304 // Create exception oop: created by stack-crawling runtime code. 14305 // Created exception is now available to this handler, and is setup 14306 // just prior to jumping to this handler. No code emitted. 14307 instruct CreateException(rax_RegP ex_oop) 14308 %{ 14309 match(Set ex_oop (CreateEx)); 14310 14311 size(0); 14312 // use the following format syntax 14313 format %{ "# exception oop is in rax; no code emitted" %} 14314 ins_encode(); 14315 ins_pipe(empty); 14316 %} 14317 14318 // Rethrow exception: 14319 // The exception oop will come in the first argument position. 14320 // Then JUMP (not call) to the rethrow stub code. 14321 instruct RethrowException() 14322 %{ 14323 match(Rethrow); 14324 14325 // use the following format syntax 14326 format %{ "jmp rethrow_stub" %} 14327 ins_encode %{ 14328 __ jump(RuntimeAddress(OptoRuntime::rethrow_stub()), noreg); 14329 %} 14330 ins_pipe(pipe_jmp); 14331 %} 14332 14333 // ============================================================================ 14334 // This name is KNOWN by the ADLC and cannot be changed. 14335 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type 14336 // for this guy. 14337 instruct tlsLoadP(r15_RegP dst) %{ 14338 match(Set dst (ThreadLocal)); 14339 effect(DEF dst); 14340 14341 size(0); 14342 format %{ "# TLS is in R15" %} 14343 ins_encode( /*empty encoding*/ ); 14344 ins_pipe(ialu_reg_reg); 14345 %} 14346 14347 14348 //----------PEEPHOLE RULES----------------------------------------------------- 14349 // These must follow all instruction definitions as they use the names 14350 // defined in the instructions definitions. 14351 // 14352 // peeppredicate ( rule_predicate ); 14353 // // the predicate unless which the peephole rule will be ignored 14354 // 14355 // peepmatch ( root_instr_name [preceding_instruction]* ); 14356 // 14357 // peepprocedure ( procedure_name ); 14358 // // provide a procedure name to perform the optimization, the procedure should 14359 // // reside in the architecture dependent peephole file, the method has the 14360 // // signature of MachNode* (Block*, int, PhaseRegAlloc*, (MachNode*)(*)(), int...) 14361 // // with the arguments being the basic block, the current node index inside the 14362 // // block, the register allocator, the functions upon invoked return a new node 14363 // // defined in peepreplace, and the rules of the nodes appearing in the 14364 // // corresponding peepmatch, the function return true if successful, else 14365 // // return false 14366 // 14367 // peepconstraint %{ 14368 // (instruction_number.operand_name relational_op instruction_number.operand_name 14369 // [, ...] ); 14370 // // instruction numbers are zero-based using left to right order in peepmatch 14371 // 14372 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 14373 // // provide an instruction_number.operand_name for each operand that appears 14374 // // in the replacement instruction's match rule 14375 // 14376 // ---------VM FLAGS--------------------------------------------------------- 14377 // 14378 // All peephole optimizations can be turned off using -XX:-OptoPeephole 14379 // 14380 // Each peephole rule is given an identifying number starting with zero and 14381 // increasing by one in the order seen by the parser. An individual peephole 14382 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 14383 // on the command-line. 14384 // 14385 // ---------CURRENT LIMITATIONS---------------------------------------------- 14386 // 14387 // Only transformations inside a basic block (do we need more for peephole) 14388 // 14389 // ---------EXAMPLE---------------------------------------------------------- 14390 // 14391 // // pertinent parts of existing instructions in architecture description 14392 // instruct movI(rRegI dst, rRegI src) 14393 // %{ 14394 // match(Set dst (CopyI src)); 14395 // %} 14396 // 14397 // instruct incI_rReg(rRegI dst, immI_1 src, rFlagsReg cr) 14398 // %{ 14399 // match(Set dst (AddI dst src)); 14400 // effect(KILL cr); 14401 // %} 14402 // 14403 // instruct leaI_rReg_immI(rRegI dst, immI_1 src) 14404 // %{ 14405 // match(Set dst (AddI dst src)); 14406 // %} 14407 // 14408 // 1. Simple replacement 14409 // - Only match adjacent instructions in same basic block 14410 // - Only equality constraints 14411 // - Only constraints between operands, not (0.dest_reg == RAX_enc) 14412 // - Only one replacement instruction 14413 // 14414 // // Change (inc mov) to lea 14415 // peephole %{ 14416 // // lea should only be emitted when beneficial 14417 // peeppredicate( VM_Version::supports_fast_2op_lea() ); 14418 // // increment preceded by register-register move 14419 // peepmatch ( incI_rReg movI ); 14420 // // require that the destination register of the increment 14421 // // match the destination register of the move 14422 // peepconstraint ( 0.dst == 1.dst ); 14423 // // construct a replacement instruction that sets 14424 // // the destination to ( move's source register + one ) 14425 // peepreplace ( leaI_rReg_immI( 0.dst 1.src 0.src ) ); 14426 // %} 14427 // 14428 // 2. Procedural replacement 14429 // - More flexible finding relevent nodes 14430 // - More flexible constraints 14431 // - More flexible transformations 14432 // - May utilise architecture-dependent API more effectively 14433 // - Currently only one replacement instruction due to adlc parsing capabilities 14434 // 14435 // // Change (inc mov) to lea 14436 // peephole %{ 14437 // // lea should only be emitted when beneficial 14438 // peeppredicate( VM_Version::supports_fast_2op_lea() ); 14439 // // the rule numbers of these nodes inside are passed into the function below 14440 // peepmatch ( incI_rReg movI ); 14441 // // the method that takes the responsibility of transformation 14442 // peepprocedure ( inc_mov_to_lea ); 14443 // // the replacement is a leaI_rReg_immI, a lambda upon invoked creating this 14444 // // node is passed into the function above 14445 // peepreplace ( leaI_rReg_immI() ); 14446 // %} 14447 14448 // These instructions is not matched by the matcher but used by the peephole 14449 instruct leaI_rReg_rReg_peep(rRegI dst, rRegI src1, rRegI src2) 14450 %{ 14451 predicate(false); 14452 match(Set dst (AddI src1 src2)); 14453 format %{ "leal $dst, [$src1 + $src2]" %} 14454 ins_encode %{ 14455 Register dst = $dst$$Register; 14456 Register src1 = $src1$$Register; 14457 Register src2 = $src2$$Register; 14458 if (src1 != rbp && src1 != r13) { 14459 __ leal(dst, Address(src1, src2, Address::times_1)); 14460 } else { 14461 assert(src2 != rbp && src2 != r13, ""); 14462 __ leal(dst, Address(src2, src1, Address::times_1)); 14463 } 14464 %} 14465 ins_pipe(ialu_reg_reg); 14466 %} 14467 14468 instruct leaI_rReg_immI_peep(rRegI dst, rRegI src1, immI src2) 14469 %{ 14470 predicate(false); 14471 match(Set dst (AddI src1 src2)); 14472 format %{ "leal $dst, [$src1 + $src2]" %} 14473 ins_encode %{ 14474 __ leal($dst$$Register, Address($src1$$Register, $src2$$constant)); 14475 %} 14476 ins_pipe(ialu_reg_reg); 14477 %} 14478 14479 instruct leaI_rReg_immI2_peep(rRegI dst, rRegI src, immI2 shift) 14480 %{ 14481 predicate(false); 14482 match(Set dst (LShiftI src shift)); 14483 format %{ "leal $dst, [$src << $shift]" %} 14484 ins_encode %{ 14485 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($shift$$constant); 14486 Register src = $src$$Register; 14487 if (scale == Address::times_2 && src != rbp && src != r13) { 14488 __ leal($dst$$Register, Address(src, src, Address::times_1)); 14489 } else { 14490 __ leal($dst$$Register, Address(noreg, src, scale)); 14491 } 14492 %} 14493 ins_pipe(ialu_reg_reg); 14494 %} 14495 14496 instruct leaL_rReg_rReg_peep(rRegL dst, rRegL src1, rRegL src2) 14497 %{ 14498 predicate(false); 14499 match(Set dst (AddL src1 src2)); 14500 format %{ "leaq $dst, [$src1 + $src2]" %} 14501 ins_encode %{ 14502 Register dst = $dst$$Register; 14503 Register src1 = $src1$$Register; 14504 Register src2 = $src2$$Register; 14505 if (src1 != rbp && src1 != r13) { 14506 __ leaq(dst, Address(src1, src2, Address::times_1)); 14507 } else { 14508 assert(src2 != rbp && src2 != r13, ""); 14509 __ leaq(dst, Address(src2, src1, Address::times_1)); 14510 } 14511 %} 14512 ins_pipe(ialu_reg_reg); 14513 %} 14514 14515 instruct leaL_rReg_immL32_peep(rRegL dst, rRegL src1, immL32 src2) 14516 %{ 14517 predicate(false); 14518 match(Set dst (AddL src1 src2)); 14519 format %{ "leaq $dst, [$src1 + $src2]" %} 14520 ins_encode %{ 14521 __ leaq($dst$$Register, Address($src1$$Register, $src2$$constant)); 14522 %} 14523 ins_pipe(ialu_reg_reg); 14524 %} 14525 14526 instruct leaL_rReg_immI2_peep(rRegL dst, rRegL src, immI2 shift) 14527 %{ 14528 predicate(false); 14529 match(Set dst (LShiftL src shift)); 14530 format %{ "leaq $dst, [$src << $shift]" %} 14531 ins_encode %{ 14532 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($shift$$constant); 14533 Register src = $src$$Register; 14534 if (scale == Address::times_2 && src != rbp && src != r13) { 14535 __ leaq($dst$$Register, Address(src, src, Address::times_1)); 14536 } else { 14537 __ leaq($dst$$Register, Address(noreg, src, scale)); 14538 } 14539 %} 14540 ins_pipe(ialu_reg_reg); 14541 %} 14542 14543 // These peephole rules replace mov + I pairs (where I is one of {add, inc, dec, 14544 // sal}) with lea instructions. The {add, sal} rules are beneficial in 14545 // processors with at least partial ALU support for lea 14546 // (supports_fast_2op_lea()), whereas the {inc, dec} rules are only generally 14547 // beneficial for processors with full ALU support 14548 // (VM_Version::supports_fast_3op_lea()) and Intel Cascade Lake. 14549 14550 peephole 14551 %{ 14552 peeppredicate(VM_Version::supports_fast_2op_lea()); 14553 peepmatch (addI_rReg); 14554 peepprocedure (lea_coalesce_reg); 14555 peepreplace (leaI_rReg_rReg_peep()); 14556 %} 14557 14558 peephole 14559 %{ 14560 peeppredicate(VM_Version::supports_fast_2op_lea()); 14561 peepmatch (addI_rReg_imm); 14562 peepprocedure (lea_coalesce_imm); 14563 peepreplace (leaI_rReg_immI_peep()); 14564 %} 14565 14566 peephole 14567 %{ 14568 peeppredicate(VM_Version::supports_fast_3op_lea() || 14569 VM_Version::is_intel_cascade_lake()); 14570 peepmatch (incI_rReg); 14571 peepprocedure (lea_coalesce_imm); 14572 peepreplace (leaI_rReg_immI_peep()); 14573 %} 14574 14575 peephole 14576 %{ 14577 peeppredicate(VM_Version::supports_fast_3op_lea() || 14578 VM_Version::is_intel_cascade_lake()); 14579 peepmatch (decI_rReg); 14580 peepprocedure (lea_coalesce_imm); 14581 peepreplace (leaI_rReg_immI_peep()); 14582 %} 14583 14584 peephole 14585 %{ 14586 peeppredicate(VM_Version::supports_fast_2op_lea()); 14587 peepmatch (salI_rReg_immI2); 14588 peepprocedure (lea_coalesce_imm); 14589 peepreplace (leaI_rReg_immI2_peep()); 14590 %} 14591 14592 peephole 14593 %{ 14594 peeppredicate(VM_Version::supports_fast_2op_lea()); 14595 peepmatch (addL_rReg); 14596 peepprocedure (lea_coalesce_reg); 14597 peepreplace (leaL_rReg_rReg_peep()); 14598 %} 14599 14600 peephole 14601 %{ 14602 peeppredicate(VM_Version::supports_fast_2op_lea()); 14603 peepmatch (addL_rReg_imm); 14604 peepprocedure (lea_coalesce_imm); 14605 peepreplace (leaL_rReg_immL32_peep()); 14606 %} 14607 14608 peephole 14609 %{ 14610 peeppredicate(VM_Version::supports_fast_3op_lea() || 14611 VM_Version::is_intel_cascade_lake()); 14612 peepmatch (incL_rReg); 14613 peepprocedure (lea_coalesce_imm); 14614 peepreplace (leaL_rReg_immL32_peep()); 14615 %} 14616 14617 peephole 14618 %{ 14619 peeppredicate(VM_Version::supports_fast_3op_lea() || 14620 VM_Version::is_intel_cascade_lake()); 14621 peepmatch (decL_rReg); 14622 peepprocedure (lea_coalesce_imm); 14623 peepreplace (leaL_rReg_immL32_peep()); 14624 %} 14625 14626 peephole 14627 %{ 14628 peeppredicate(VM_Version::supports_fast_2op_lea()); 14629 peepmatch (salL_rReg_immI2); 14630 peepprocedure (lea_coalesce_imm); 14631 peepreplace (leaL_rReg_immI2_peep()); 14632 %} 14633 14634 peephole 14635 %{ 14636 peepmatch (leaPCompressedOopOffset); 14637 peepprocedure (lea_remove_redundant); 14638 %} 14639 14640 peephole 14641 %{ 14642 peepmatch (leaP8Narrow); 14643 peepprocedure (lea_remove_redundant); 14644 %} 14645 14646 peephole 14647 %{ 14648 peepmatch (leaP32Narrow); 14649 peepprocedure (lea_remove_redundant); 14650 %} 14651 14652 // These peephole rules matches instructions which set flags and are followed by a testI/L_reg 14653 // 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 14654 14655 //int variant 14656 peephole 14657 %{ 14658 peepmatch (testI_reg); 14659 peepprocedure (test_may_remove); 14660 %} 14661 14662 //long variant 14663 peephole 14664 %{ 14665 peepmatch (testL_reg); 14666 peepprocedure (test_may_remove); 14667 %} 14668 14669 14670 //----------SMARTSPILL RULES--------------------------------------------------- 14671 // These must follow all instruction definitions as they use the names 14672 // defined in the instructions definitions.