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 // List of nop instructions 3445 nops( MachNop ); 3446 %} 3447 3448 //----------RESOURCES---------------------------------------------------------- 3449 // Resources are the functional units available to the machine 3450 3451 // Generic P2/P3 pipeline 3452 // 3 decoders, only D0 handles big operands; a "bundle" is the limit of 3453 // 3 instructions decoded per cycle. 3454 // 2 load/store ops per cycle, 1 branch, 1 FPU, 3455 // 3 ALU op, only ALU0 handles mul instructions. 3456 resources( D0, D1, D2, DECODE = D0 | D1 | D2, 3457 MS0, MS1, MS2, MEM = MS0 | MS1 | MS2, 3458 BR, FPU, 3459 ALU0, ALU1, ALU2, ALU = ALU0 | ALU1 | ALU2); 3460 3461 //----------PIPELINE DESCRIPTION----------------------------------------------- 3462 // Pipeline Description specifies the stages in the machine's pipeline 3463 3464 // Generic P2/P3 pipeline 3465 pipe_desc(S0, S1, S2, S3, S4, S5); 3466 3467 //----------PIPELINE CLASSES--------------------------------------------------- 3468 // Pipeline Classes describe the stages in which input and output are 3469 // referenced by the hardware pipeline. 3470 3471 // Naming convention: ialu or fpu 3472 // Then: _reg 3473 // Then: _reg if there is a 2nd register 3474 // Then: _long if it's a pair of instructions implementing a long 3475 // Then: _fat if it requires the big decoder 3476 // Or: _mem if it requires the big decoder and a memory unit. 3477 3478 // Integer ALU reg operation 3479 pipe_class ialu_reg(rRegI dst) 3480 %{ 3481 single_instruction; 3482 dst : S4(write); 3483 dst : S3(read); 3484 DECODE : S0; // any decoder 3485 ALU : S3; // any alu 3486 %} 3487 3488 // Long ALU reg operation 3489 pipe_class ialu_reg_long(rRegL dst) 3490 %{ 3491 instruction_count(2); 3492 dst : S4(write); 3493 dst : S3(read); 3494 DECODE : S0(2); // any 2 decoders 3495 ALU : S3(2); // both alus 3496 %} 3497 3498 // Integer ALU reg operation using big decoder 3499 pipe_class ialu_reg_fat(rRegI dst) 3500 %{ 3501 single_instruction; 3502 dst : S4(write); 3503 dst : S3(read); 3504 D0 : S0; // big decoder only 3505 ALU : S3; // any alu 3506 %} 3507 3508 // Integer ALU reg-reg operation 3509 pipe_class ialu_reg_reg(rRegI dst, rRegI src) 3510 %{ 3511 single_instruction; 3512 dst : S4(write); 3513 src : S3(read); 3514 DECODE : S0; // any decoder 3515 ALU : S3; // any alu 3516 %} 3517 3518 // Integer ALU reg-reg operation 3519 pipe_class ialu_reg_reg_fat(rRegI dst, memory src) 3520 %{ 3521 single_instruction; 3522 dst : S4(write); 3523 src : S3(read); 3524 D0 : S0; // big decoder only 3525 ALU : S3; // any alu 3526 %} 3527 3528 // Integer ALU reg-mem operation 3529 pipe_class ialu_reg_mem(rRegI dst, memory mem) 3530 %{ 3531 single_instruction; 3532 dst : S5(write); 3533 mem : S3(read); 3534 D0 : S0; // big decoder only 3535 ALU : S4; // any alu 3536 MEM : S3; // any mem 3537 %} 3538 3539 // Integer mem operation (prefetch) 3540 pipe_class ialu_mem(memory mem) 3541 %{ 3542 single_instruction; 3543 mem : S3(read); 3544 D0 : S0; // big decoder only 3545 MEM : S3; // any mem 3546 %} 3547 3548 // Integer Store to Memory 3549 pipe_class ialu_mem_reg(memory mem, rRegI src) 3550 %{ 3551 single_instruction; 3552 mem : S3(read); 3553 src : S5(read); 3554 D0 : S0; // big decoder only 3555 ALU : S4; // any alu 3556 MEM : S3; 3557 %} 3558 3559 // // Long Store to Memory 3560 // pipe_class ialu_mem_long_reg(memory mem, rRegL src) 3561 // %{ 3562 // instruction_count(2); 3563 // mem : S3(read); 3564 // src : S5(read); 3565 // D0 : S0(2); // big decoder only; twice 3566 // ALU : S4(2); // any 2 alus 3567 // MEM : S3(2); // Both mems 3568 // %} 3569 3570 // Integer Store to Memory 3571 pipe_class ialu_mem_imm(memory mem) 3572 %{ 3573 single_instruction; 3574 mem : S3(read); 3575 D0 : S0; // big decoder only 3576 ALU : S4; // any alu 3577 MEM : S3; 3578 %} 3579 3580 // Integer ALU0 reg-reg operation 3581 pipe_class ialu_reg_reg_alu0(rRegI dst, rRegI src) 3582 %{ 3583 single_instruction; 3584 dst : S4(write); 3585 src : S3(read); 3586 D0 : S0; // Big decoder only 3587 ALU0 : S3; // only alu0 3588 %} 3589 3590 // Integer ALU0 reg-mem operation 3591 pipe_class ialu_reg_mem_alu0(rRegI dst, memory mem) 3592 %{ 3593 single_instruction; 3594 dst : S5(write); 3595 mem : S3(read); 3596 D0 : S0; // big decoder only 3597 ALU0 : S4; // ALU0 only 3598 MEM : S3; // any mem 3599 %} 3600 3601 // Integer ALU reg-reg operation 3602 pipe_class ialu_cr_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2) 3603 %{ 3604 single_instruction; 3605 cr : S4(write); 3606 src1 : S3(read); 3607 src2 : S3(read); 3608 DECODE : S0; // any decoder 3609 ALU : S3; // any alu 3610 %} 3611 3612 // Integer ALU reg-imm operation 3613 pipe_class ialu_cr_reg_imm(rFlagsReg cr, rRegI src1) 3614 %{ 3615 single_instruction; 3616 cr : S4(write); 3617 src1 : S3(read); 3618 DECODE : S0; // any decoder 3619 ALU : S3; // any alu 3620 %} 3621 3622 // Integer ALU reg-mem operation 3623 pipe_class ialu_cr_reg_mem(rFlagsReg cr, rRegI src1, memory src2) 3624 %{ 3625 single_instruction; 3626 cr : S4(write); 3627 src1 : S3(read); 3628 src2 : S3(read); 3629 D0 : S0; // big decoder only 3630 ALU : S4; // any alu 3631 MEM : S3; 3632 %} 3633 3634 // Conditional move reg-reg 3635 pipe_class pipe_cmplt( rRegI p, rRegI q, rRegI y) 3636 %{ 3637 instruction_count(4); 3638 y : S4(read); 3639 q : S3(read); 3640 p : S3(read); 3641 DECODE : S0(4); // any decoder 3642 %} 3643 3644 // Conditional move reg-reg 3645 pipe_class pipe_cmov_reg( rRegI dst, rRegI src, rFlagsReg cr) 3646 %{ 3647 single_instruction; 3648 dst : S4(write); 3649 src : S3(read); 3650 cr : S3(read); 3651 DECODE : S0; // any decoder 3652 %} 3653 3654 // Conditional move reg-mem 3655 pipe_class pipe_cmov_mem( rFlagsReg cr, rRegI dst, memory src) 3656 %{ 3657 single_instruction; 3658 dst : S4(write); 3659 src : S3(read); 3660 cr : S3(read); 3661 DECODE : S0; // any decoder 3662 MEM : S3; 3663 %} 3664 3665 // Conditional move reg-reg long 3666 pipe_class pipe_cmov_reg_long( rFlagsReg cr, rRegL dst, rRegL src) 3667 %{ 3668 single_instruction; 3669 dst : S4(write); 3670 src : S3(read); 3671 cr : S3(read); 3672 DECODE : S0(2); // any 2 decoders 3673 %} 3674 3675 // Float reg-reg operation 3676 pipe_class fpu_reg(regD dst) 3677 %{ 3678 instruction_count(2); 3679 dst : S3(read); 3680 DECODE : S0(2); // any 2 decoders 3681 FPU : S3; 3682 %} 3683 3684 // Float reg-reg operation 3685 pipe_class fpu_reg_reg(regD dst, regD src) 3686 %{ 3687 instruction_count(2); 3688 dst : S4(write); 3689 src : S3(read); 3690 DECODE : S0(2); // any 2 decoders 3691 FPU : S3; 3692 %} 3693 3694 // Float reg-reg operation 3695 pipe_class fpu_reg_reg_reg(regD dst, regD src1, regD src2) 3696 %{ 3697 instruction_count(3); 3698 dst : S4(write); 3699 src1 : S3(read); 3700 src2 : S3(read); 3701 DECODE : S0(3); // any 3 decoders 3702 FPU : S3(2); 3703 %} 3704 3705 // Float reg-reg operation 3706 pipe_class fpu_reg_reg_reg_reg(regD dst, regD src1, regD src2, regD src3) 3707 %{ 3708 instruction_count(4); 3709 dst : S4(write); 3710 src1 : S3(read); 3711 src2 : S3(read); 3712 src3 : S3(read); 3713 DECODE : S0(4); // any 3 decoders 3714 FPU : S3(2); 3715 %} 3716 3717 // Float reg-reg operation 3718 pipe_class fpu_reg_mem_reg_reg(regD dst, memory src1, regD src2, regD src3) 3719 %{ 3720 instruction_count(4); 3721 dst : S4(write); 3722 src1 : S3(read); 3723 src2 : S3(read); 3724 src3 : S3(read); 3725 DECODE : S1(3); // any 3 decoders 3726 D0 : S0; // Big decoder only 3727 FPU : S3(2); 3728 MEM : S3; 3729 %} 3730 3731 // Float reg-mem operation 3732 pipe_class fpu_reg_mem(regD dst, memory mem) 3733 %{ 3734 instruction_count(2); 3735 dst : S5(write); 3736 mem : S3(read); 3737 D0 : S0; // big decoder only 3738 DECODE : S1; // any decoder for FPU POP 3739 FPU : S4; 3740 MEM : S3; // any mem 3741 %} 3742 3743 // Float reg-mem operation 3744 pipe_class fpu_reg_reg_mem(regD dst, regD src1, memory mem) 3745 %{ 3746 instruction_count(3); 3747 dst : S5(write); 3748 src1 : S3(read); 3749 mem : S3(read); 3750 D0 : S0; // big decoder only 3751 DECODE : S1(2); // any decoder for FPU POP 3752 FPU : S4; 3753 MEM : S3; // any mem 3754 %} 3755 3756 // Float mem-reg operation 3757 pipe_class fpu_mem_reg(memory mem, regD src) 3758 %{ 3759 instruction_count(2); 3760 src : S5(read); 3761 mem : S3(read); 3762 DECODE : S0; // any decoder for FPU PUSH 3763 D0 : S1; // big decoder only 3764 FPU : S4; 3765 MEM : S3; // any mem 3766 %} 3767 3768 pipe_class fpu_mem_reg_reg(memory mem, regD src1, regD src2) 3769 %{ 3770 instruction_count(3); 3771 src1 : S3(read); 3772 src2 : S3(read); 3773 mem : S3(read); 3774 DECODE : S0(2); // any decoder for FPU PUSH 3775 D0 : S1; // big decoder only 3776 FPU : S4; 3777 MEM : S3; // any mem 3778 %} 3779 3780 pipe_class fpu_mem_reg_mem(memory mem, regD src1, memory src2) 3781 %{ 3782 instruction_count(3); 3783 src1 : S3(read); 3784 src2 : S3(read); 3785 mem : S4(read); 3786 DECODE : S0; // any decoder for FPU PUSH 3787 D0 : S0(2); // big decoder only 3788 FPU : S4; 3789 MEM : S3(2); // any mem 3790 %} 3791 3792 pipe_class fpu_mem_mem(memory dst, memory src1) 3793 %{ 3794 instruction_count(2); 3795 src1 : S3(read); 3796 dst : S4(read); 3797 D0 : S0(2); // big decoder only 3798 MEM : S3(2); // any mem 3799 %} 3800 3801 pipe_class fpu_mem_mem_mem(memory dst, memory src1, memory src2) 3802 %{ 3803 instruction_count(3); 3804 src1 : S3(read); 3805 src2 : S3(read); 3806 dst : S4(read); 3807 D0 : S0(3); // big decoder only 3808 FPU : S4; 3809 MEM : S3(3); // any mem 3810 %} 3811 3812 pipe_class fpu_mem_reg_con(memory mem, regD src1) 3813 %{ 3814 instruction_count(3); 3815 src1 : S4(read); 3816 mem : S4(read); 3817 DECODE : S0; // any decoder for FPU PUSH 3818 D0 : S0(2); // big decoder only 3819 FPU : S4; 3820 MEM : S3(2); // any mem 3821 %} 3822 3823 // Float load constant 3824 pipe_class fpu_reg_con(regD dst) 3825 %{ 3826 instruction_count(2); 3827 dst : S5(write); 3828 D0 : S0; // big decoder only for the load 3829 DECODE : S1; // any decoder for FPU POP 3830 FPU : S4; 3831 MEM : S3; // any mem 3832 %} 3833 3834 // Float load constant 3835 pipe_class fpu_reg_reg_con(regD dst, regD src) 3836 %{ 3837 instruction_count(3); 3838 dst : S5(write); 3839 src : S3(read); 3840 D0 : S0; // big decoder only for the load 3841 DECODE : S1(2); // any decoder for FPU POP 3842 FPU : S4; 3843 MEM : S3; // any mem 3844 %} 3845 3846 // UnConditional branch 3847 pipe_class pipe_jmp(label labl) 3848 %{ 3849 single_instruction; 3850 BR : S3; 3851 %} 3852 3853 // Conditional branch 3854 pipe_class pipe_jcc(cmpOp cmp, rFlagsReg cr, label labl) 3855 %{ 3856 single_instruction; 3857 cr : S1(read); 3858 BR : S3; 3859 %} 3860 3861 // Allocation idiom 3862 pipe_class pipe_cmpxchg(rRegP dst, rRegP heap_ptr) 3863 %{ 3864 instruction_count(1); force_serialization; 3865 fixed_latency(6); 3866 heap_ptr : S3(read); 3867 DECODE : S0(3); 3868 D0 : S2; 3869 MEM : S3; 3870 ALU : S3(2); 3871 dst : S5(write); 3872 BR : S5; 3873 %} 3874 3875 // Generic big/slow expanded idiom 3876 pipe_class pipe_slow() 3877 %{ 3878 instruction_count(10); multiple_bundles; force_serialization; 3879 fixed_latency(100); 3880 D0 : S0(2); 3881 MEM : S3(2); 3882 %} 3883 3884 // The real do-nothing guy 3885 pipe_class empty() 3886 %{ 3887 instruction_count(0); 3888 %} 3889 3890 // Define the class for the Nop node 3891 define 3892 %{ 3893 MachNop = empty; 3894 %} 3895 3896 %} 3897 3898 //----------INSTRUCTIONS------------------------------------------------------- 3899 // 3900 // match -- States which machine-independent subtree may be replaced 3901 // by this instruction. 3902 // ins_cost -- The estimated cost of this instruction is used by instruction 3903 // selection to identify a minimum cost tree of machine 3904 // instructions that matches a tree of machine-independent 3905 // instructions. 3906 // format -- A string providing the disassembly for this instruction. 3907 // The value of an instruction's operand may be inserted 3908 // by referring to it with a '$' prefix. 3909 // opcode -- Three instruction opcodes may be provided. These are referred 3910 // to within an encode class as $primary, $secondary, and $tertiary 3911 // rrspectively. The primary opcode is commonly used to 3912 // indicate the type of machine instruction, while secondary 3913 // and tertiary are often used for prefix options or addressing 3914 // modes. 3915 // ins_encode -- A list of encode classes with parameters. The encode class 3916 // name must have been defined in an 'enc_class' specification 3917 // in the encode section of the architecture description. 3918 3919 // Dummy reg-to-reg vector moves. Removed during post-selection cleanup. 3920 // Load Float 3921 instruct MoveF2VL(vlRegF dst, regF src) %{ 3922 match(Set dst src); 3923 format %{ "movss $dst,$src\t! load float (4 bytes)" %} 3924 ins_encode %{ 3925 ShouldNotReachHere(); 3926 %} 3927 ins_pipe( fpu_reg_reg ); 3928 %} 3929 3930 // Load Float 3931 instruct MoveF2LEG(legRegF dst, regF src) %{ 3932 match(Set dst src); 3933 format %{ "movss $dst,$src\t# if src != dst load float (4 bytes)" %} 3934 ins_encode %{ 3935 ShouldNotReachHere(); 3936 %} 3937 ins_pipe( fpu_reg_reg ); 3938 %} 3939 3940 // Load Float 3941 instruct MoveVL2F(regF dst, vlRegF src) %{ 3942 match(Set dst src); 3943 format %{ "movss $dst,$src\t! load float (4 bytes)" %} 3944 ins_encode %{ 3945 ShouldNotReachHere(); 3946 %} 3947 ins_pipe( fpu_reg_reg ); 3948 %} 3949 3950 // Load Float 3951 instruct MoveLEG2F(regF dst, legRegF src) %{ 3952 match(Set dst src); 3953 format %{ "movss $dst,$src\t# if src != dst load float (4 bytes)" %} 3954 ins_encode %{ 3955 ShouldNotReachHere(); 3956 %} 3957 ins_pipe( fpu_reg_reg ); 3958 %} 3959 3960 // Load Double 3961 instruct MoveD2VL(vlRegD dst, regD src) %{ 3962 match(Set dst src); 3963 format %{ "movsd $dst,$src\t! load double (8 bytes)" %} 3964 ins_encode %{ 3965 ShouldNotReachHere(); 3966 %} 3967 ins_pipe( fpu_reg_reg ); 3968 %} 3969 3970 // Load Double 3971 instruct MoveD2LEG(legRegD dst, regD src) %{ 3972 match(Set dst src); 3973 format %{ "movsd $dst,$src\t# if src != dst load double (8 bytes)" %} 3974 ins_encode %{ 3975 ShouldNotReachHere(); 3976 %} 3977 ins_pipe( fpu_reg_reg ); 3978 %} 3979 3980 // Load Double 3981 instruct MoveVL2D(regD dst, vlRegD src) %{ 3982 match(Set dst src); 3983 format %{ "movsd $dst,$src\t! load double (8 bytes)" %} 3984 ins_encode %{ 3985 ShouldNotReachHere(); 3986 %} 3987 ins_pipe( fpu_reg_reg ); 3988 %} 3989 3990 // Load Double 3991 instruct MoveLEG2D(regD dst, legRegD src) %{ 3992 match(Set dst src); 3993 format %{ "movsd $dst,$src\t# if src != dst load double (8 bytes)" %} 3994 ins_encode %{ 3995 ShouldNotReachHere(); 3996 %} 3997 ins_pipe( fpu_reg_reg ); 3998 %} 3999 4000 //----------Load/Store/Move Instructions--------------------------------------- 4001 //----------Load Instructions-------------------------------------------------- 4002 4003 // Load Byte (8 bit signed) 4004 instruct loadB(rRegI dst, memory mem) 4005 %{ 4006 match(Set dst (LoadB mem)); 4007 4008 ins_cost(125); 4009 format %{ "movsbl $dst, $mem\t# byte" %} 4010 4011 ins_encode %{ 4012 __ movsbl($dst$$Register, $mem$$Address); 4013 %} 4014 4015 ins_pipe(ialu_reg_mem); 4016 %} 4017 4018 // Load Byte (8 bit signed) into Long Register 4019 instruct loadB2L(rRegL dst, memory mem) 4020 %{ 4021 match(Set dst (ConvI2L (LoadB mem))); 4022 4023 ins_cost(125); 4024 format %{ "movsbq $dst, $mem\t# byte -> long" %} 4025 4026 ins_encode %{ 4027 __ movsbq($dst$$Register, $mem$$Address); 4028 %} 4029 4030 ins_pipe(ialu_reg_mem); 4031 %} 4032 4033 // Load Unsigned Byte (8 bit UNsigned) 4034 instruct loadUB(rRegI dst, memory mem) 4035 %{ 4036 match(Set dst (LoadUB mem)); 4037 4038 ins_cost(125); 4039 format %{ "movzbl $dst, $mem\t# ubyte" %} 4040 4041 ins_encode %{ 4042 __ movzbl($dst$$Register, $mem$$Address); 4043 %} 4044 4045 ins_pipe(ialu_reg_mem); 4046 %} 4047 4048 // Load Unsigned Byte (8 bit UNsigned) into Long Register 4049 instruct loadUB2L(rRegL dst, memory mem) 4050 %{ 4051 match(Set dst (ConvI2L (LoadUB mem))); 4052 4053 ins_cost(125); 4054 format %{ "movzbq $dst, $mem\t# ubyte -> long" %} 4055 4056 ins_encode %{ 4057 __ movzbq($dst$$Register, $mem$$Address); 4058 %} 4059 4060 ins_pipe(ialu_reg_mem); 4061 %} 4062 4063 // Load Unsigned Byte (8 bit UNsigned) with 32-bit mask into Long Register 4064 instruct loadUB2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 4065 match(Set dst (ConvI2L (AndI (LoadUB mem) mask))); 4066 effect(KILL cr); 4067 4068 format %{ "movzbq $dst, $mem\t# ubyte & 32-bit mask -> long\n\t" 4069 "andl $dst, right_n_bits($mask, 8)" %} 4070 ins_encode %{ 4071 Register Rdst = $dst$$Register; 4072 __ movzbq(Rdst, $mem$$Address); 4073 __ andl(Rdst, $mask$$constant & right_n_bits(8)); 4074 %} 4075 ins_pipe(ialu_reg_mem); 4076 %} 4077 4078 // Load Short (16 bit signed) 4079 instruct loadS(rRegI dst, memory mem) 4080 %{ 4081 match(Set dst (LoadS mem)); 4082 4083 ins_cost(125); 4084 format %{ "movswl $dst, $mem\t# short" %} 4085 4086 ins_encode %{ 4087 __ movswl($dst$$Register, $mem$$Address); 4088 %} 4089 4090 ins_pipe(ialu_reg_mem); 4091 %} 4092 4093 // Load Short (16 bit signed) to Byte (8 bit signed) 4094 instruct loadS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4095 match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour)); 4096 4097 ins_cost(125); 4098 format %{ "movsbl $dst, $mem\t# short -> byte" %} 4099 ins_encode %{ 4100 __ movsbl($dst$$Register, $mem$$Address); 4101 %} 4102 ins_pipe(ialu_reg_mem); 4103 %} 4104 4105 // Load Short (16 bit signed) into Long Register 4106 instruct loadS2L(rRegL dst, memory mem) 4107 %{ 4108 match(Set dst (ConvI2L (LoadS mem))); 4109 4110 ins_cost(125); 4111 format %{ "movswq $dst, $mem\t# short -> long" %} 4112 4113 ins_encode %{ 4114 __ movswq($dst$$Register, $mem$$Address); 4115 %} 4116 4117 ins_pipe(ialu_reg_mem); 4118 %} 4119 4120 // Load Unsigned Short/Char (16 bit UNsigned) 4121 instruct loadUS(rRegI dst, memory mem) 4122 %{ 4123 match(Set dst (LoadUS mem)); 4124 4125 ins_cost(125); 4126 format %{ "movzwl $dst, $mem\t# ushort/char" %} 4127 4128 ins_encode %{ 4129 __ movzwl($dst$$Register, $mem$$Address); 4130 %} 4131 4132 ins_pipe(ialu_reg_mem); 4133 %} 4134 4135 // Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed) 4136 instruct loadUS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4137 match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour)); 4138 4139 ins_cost(125); 4140 format %{ "movsbl $dst, $mem\t# ushort -> byte" %} 4141 ins_encode %{ 4142 __ movsbl($dst$$Register, $mem$$Address); 4143 %} 4144 ins_pipe(ialu_reg_mem); 4145 %} 4146 4147 // Load Unsigned Short/Char (16 bit UNsigned) into Long Register 4148 instruct loadUS2L(rRegL dst, memory mem) 4149 %{ 4150 match(Set dst (ConvI2L (LoadUS mem))); 4151 4152 ins_cost(125); 4153 format %{ "movzwq $dst, $mem\t# ushort/char -> long" %} 4154 4155 ins_encode %{ 4156 __ movzwq($dst$$Register, $mem$$Address); 4157 %} 4158 4159 ins_pipe(ialu_reg_mem); 4160 %} 4161 4162 // Load Unsigned Short/Char (16 bit UNsigned) with mask 0xFF into Long Register 4163 instruct loadUS2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 4164 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 4165 4166 format %{ "movzbq $dst, $mem\t# ushort/char & 0xFF -> long" %} 4167 ins_encode %{ 4168 __ movzbq($dst$$Register, $mem$$Address); 4169 %} 4170 ins_pipe(ialu_reg_mem); 4171 %} 4172 4173 // Load Unsigned Short/Char (16 bit UNsigned) with 32-bit mask into Long Register 4174 instruct loadUS2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 4175 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 4176 effect(KILL cr); 4177 4178 format %{ "movzwq $dst, $mem\t# ushort/char & 32-bit mask -> long\n\t" 4179 "andl $dst, right_n_bits($mask, 16)" %} 4180 ins_encode %{ 4181 Register Rdst = $dst$$Register; 4182 __ movzwq(Rdst, $mem$$Address); 4183 __ andl(Rdst, $mask$$constant & right_n_bits(16)); 4184 %} 4185 ins_pipe(ialu_reg_mem); 4186 %} 4187 4188 // Load Integer 4189 instruct loadI(rRegI dst, memory mem) 4190 %{ 4191 match(Set dst (LoadI mem)); 4192 4193 ins_cost(125); 4194 format %{ "movl $dst, $mem\t# int" %} 4195 4196 ins_encode %{ 4197 __ movl($dst$$Register, $mem$$Address); 4198 %} 4199 4200 ins_pipe(ialu_reg_mem); 4201 %} 4202 4203 // Load Integer (32 bit signed) to Byte (8 bit signed) 4204 instruct loadI2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4205 match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour)); 4206 4207 ins_cost(125); 4208 format %{ "movsbl $dst, $mem\t# int -> byte" %} 4209 ins_encode %{ 4210 __ movsbl($dst$$Register, $mem$$Address); 4211 %} 4212 ins_pipe(ialu_reg_mem); 4213 %} 4214 4215 // Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned) 4216 instruct loadI2UB(rRegI dst, memory mem, immI_255 mask) %{ 4217 match(Set dst (AndI (LoadI mem) mask)); 4218 4219 ins_cost(125); 4220 format %{ "movzbl $dst, $mem\t# int -> ubyte" %} 4221 ins_encode %{ 4222 __ movzbl($dst$$Register, $mem$$Address); 4223 %} 4224 ins_pipe(ialu_reg_mem); 4225 %} 4226 4227 // Load Integer (32 bit signed) to Short (16 bit signed) 4228 instruct loadI2S(rRegI dst, memory mem, immI_16 sixteen) %{ 4229 match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen)); 4230 4231 ins_cost(125); 4232 format %{ "movswl $dst, $mem\t# int -> short" %} 4233 ins_encode %{ 4234 __ movswl($dst$$Register, $mem$$Address); 4235 %} 4236 ins_pipe(ialu_reg_mem); 4237 %} 4238 4239 // Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned) 4240 instruct loadI2US(rRegI dst, memory mem, immI_65535 mask) %{ 4241 match(Set dst (AndI (LoadI mem) mask)); 4242 4243 ins_cost(125); 4244 format %{ "movzwl $dst, $mem\t# int -> ushort/char" %} 4245 ins_encode %{ 4246 __ movzwl($dst$$Register, $mem$$Address); 4247 %} 4248 ins_pipe(ialu_reg_mem); 4249 %} 4250 4251 // Load Integer into Long Register 4252 instruct loadI2L(rRegL dst, memory mem) 4253 %{ 4254 match(Set dst (ConvI2L (LoadI mem))); 4255 4256 ins_cost(125); 4257 format %{ "movslq $dst, $mem\t# int -> long" %} 4258 4259 ins_encode %{ 4260 __ movslq($dst$$Register, $mem$$Address); 4261 %} 4262 4263 ins_pipe(ialu_reg_mem); 4264 %} 4265 4266 // Load Integer with mask 0xFF into Long Register 4267 instruct loadI2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 4268 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4269 4270 format %{ "movzbq $dst, $mem\t# int & 0xFF -> long" %} 4271 ins_encode %{ 4272 __ movzbq($dst$$Register, $mem$$Address); 4273 %} 4274 ins_pipe(ialu_reg_mem); 4275 %} 4276 4277 // Load Integer with mask 0xFFFF into Long Register 4278 instruct loadI2L_immI_65535(rRegL dst, memory mem, immI_65535 mask) %{ 4279 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4280 4281 format %{ "movzwq $dst, $mem\t# int & 0xFFFF -> long" %} 4282 ins_encode %{ 4283 __ movzwq($dst$$Register, $mem$$Address); 4284 %} 4285 ins_pipe(ialu_reg_mem); 4286 %} 4287 4288 // Load Integer with a 31-bit mask into Long Register 4289 instruct loadI2L_immU31(rRegL dst, memory mem, immU31 mask, rFlagsReg cr) %{ 4290 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4291 effect(KILL cr); 4292 4293 format %{ "movl $dst, $mem\t# int & 31-bit mask -> long\n\t" 4294 "andl $dst, $mask" %} 4295 ins_encode %{ 4296 Register Rdst = $dst$$Register; 4297 __ movl(Rdst, $mem$$Address); 4298 __ andl(Rdst, $mask$$constant); 4299 %} 4300 ins_pipe(ialu_reg_mem); 4301 %} 4302 4303 // Load Unsigned Integer into Long Register 4304 instruct loadUI2L(rRegL dst, memory mem, immL_32bits mask) 4305 %{ 4306 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 4307 4308 ins_cost(125); 4309 format %{ "movl $dst, $mem\t# uint -> long" %} 4310 4311 ins_encode %{ 4312 __ movl($dst$$Register, $mem$$Address); 4313 %} 4314 4315 ins_pipe(ialu_reg_mem); 4316 %} 4317 4318 // Load Long 4319 instruct loadL(rRegL dst, memory mem) 4320 %{ 4321 match(Set dst (LoadL mem)); 4322 4323 ins_cost(125); 4324 format %{ "movq $dst, $mem\t# long" %} 4325 4326 ins_encode %{ 4327 __ movq($dst$$Register, $mem$$Address); 4328 %} 4329 4330 ins_pipe(ialu_reg_mem); // XXX 4331 %} 4332 4333 // Load Range 4334 instruct loadRange(rRegI dst, memory mem) 4335 %{ 4336 match(Set dst (LoadRange mem)); 4337 4338 ins_cost(125); // XXX 4339 format %{ "movl $dst, $mem\t# range" %} 4340 ins_encode %{ 4341 __ movl($dst$$Register, $mem$$Address); 4342 %} 4343 ins_pipe(ialu_reg_mem); 4344 %} 4345 4346 // Load Pointer 4347 instruct loadP(rRegP dst, memory mem) 4348 %{ 4349 match(Set dst (LoadP mem)); 4350 predicate(n->as_Load()->barrier_data() == 0); 4351 4352 ins_cost(125); // XXX 4353 format %{ "movq $dst, $mem\t# ptr" %} 4354 ins_encode %{ 4355 __ movq($dst$$Register, $mem$$Address); 4356 %} 4357 ins_pipe(ialu_reg_mem); // XXX 4358 %} 4359 4360 // Load Compressed Pointer 4361 instruct loadN(rRegN dst, memory mem) 4362 %{ 4363 predicate(n->as_Load()->barrier_data() == 0); 4364 match(Set dst (LoadN mem)); 4365 4366 ins_cost(125); // XXX 4367 format %{ "movl $dst, $mem\t# compressed ptr" %} 4368 ins_encode %{ 4369 __ movl($dst$$Register, $mem$$Address); 4370 %} 4371 ins_pipe(ialu_reg_mem); // XXX 4372 %} 4373 4374 4375 // Load Klass Pointer 4376 instruct loadKlass(rRegP dst, memory mem) 4377 %{ 4378 match(Set dst (LoadKlass mem)); 4379 4380 ins_cost(125); // XXX 4381 format %{ "movq $dst, $mem\t# class" %} 4382 ins_encode %{ 4383 __ movq($dst$$Register, $mem$$Address); 4384 %} 4385 ins_pipe(ialu_reg_mem); // XXX 4386 %} 4387 4388 // Load narrow Klass Pointer 4389 instruct loadNKlass(rRegN dst, memory mem) 4390 %{ 4391 predicate(!UseCompactObjectHeaders); 4392 match(Set dst (LoadNKlass mem)); 4393 4394 ins_cost(125); // XXX 4395 format %{ "movl $dst, $mem\t# compressed klass ptr" %} 4396 ins_encode %{ 4397 __ movl($dst$$Register, $mem$$Address); 4398 %} 4399 ins_pipe(ialu_reg_mem); // XXX 4400 %} 4401 4402 instruct loadNKlassCompactHeaders(rRegN dst, memory mem, rFlagsReg cr) 4403 %{ 4404 predicate(UseCompactObjectHeaders); 4405 match(Set dst (LoadNKlass mem)); 4406 effect(KILL cr); 4407 ins_cost(125); 4408 format %{ 4409 "movl $dst, $mem\t# compressed klass ptr, shifted\n\t" 4410 "shrl $dst, markWord::klass_shift_at_offset" 4411 %} 4412 ins_encode %{ 4413 if (UseAPX) { 4414 __ eshrl($dst$$Register, $mem$$Address, markWord::klass_shift_at_offset, false); 4415 } 4416 else { 4417 __ movl($dst$$Register, $mem$$Address); 4418 __ shrl($dst$$Register, markWord::klass_shift_at_offset); 4419 } 4420 %} 4421 ins_pipe(ialu_reg_mem); 4422 %} 4423 4424 // Load Float 4425 instruct loadF(regF dst, memory mem) 4426 %{ 4427 match(Set dst (LoadF mem)); 4428 4429 ins_cost(145); // XXX 4430 format %{ "movss $dst, $mem\t# float" %} 4431 ins_encode %{ 4432 __ movflt($dst$$XMMRegister, $mem$$Address); 4433 %} 4434 ins_pipe(pipe_slow); // XXX 4435 %} 4436 4437 // Load Double 4438 instruct loadD_partial(regD dst, memory mem) 4439 %{ 4440 predicate(!UseXmmLoadAndClearUpper); 4441 match(Set dst (LoadD mem)); 4442 4443 ins_cost(145); // XXX 4444 format %{ "movlpd $dst, $mem\t# double" %} 4445 ins_encode %{ 4446 __ movdbl($dst$$XMMRegister, $mem$$Address); 4447 %} 4448 ins_pipe(pipe_slow); // XXX 4449 %} 4450 4451 instruct loadD(regD dst, memory mem) 4452 %{ 4453 predicate(UseXmmLoadAndClearUpper); 4454 match(Set dst (LoadD mem)); 4455 4456 ins_cost(145); // XXX 4457 format %{ "movsd $dst, $mem\t# double" %} 4458 ins_encode %{ 4459 __ movdbl($dst$$XMMRegister, $mem$$Address); 4460 %} 4461 ins_pipe(pipe_slow); // XXX 4462 %} 4463 4464 instruct loadAOTRCAddress(rRegP dst, immAOTRuntimeConstantsAddress con) 4465 %{ 4466 match(Set dst con); 4467 4468 format %{ "leaq $dst, $con\t# AOT Runtime Constants Address" %} 4469 4470 ins_encode %{ 4471 __ load_aotrc_address($dst$$Register, (address)$con$$constant); 4472 %} 4473 4474 ins_pipe(ialu_reg_fat); 4475 %} 4476 4477 // max = java.lang.Math.max(float a, float b) 4478 instruct maxF_avx10_reg(regF dst, regF a, regF b) %{ 4479 predicate(VM_Version::supports_avx10_2()); 4480 match(Set dst (MaxF a b)); 4481 format %{ "maxF $dst, $a, $b" %} 4482 ins_encode %{ 4483 __ eminmaxss($dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, AVX10_MINMAX_MAX_COMPARE_SIGN); 4484 %} 4485 ins_pipe( pipe_slow ); 4486 %} 4487 4488 // max = java.lang.Math.max(float a, float b) 4489 instruct maxF_reg(legRegF dst, legRegF a, legRegF b, legRegF tmp, legRegF atmp, legRegF btmp) %{ 4490 predicate(!VM_Version::supports_avx10_2() && UseAVX > 0 && !VLoopReductions::is_reduction(n)); 4491 match(Set dst (MaxF a b)); 4492 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 4493 format %{ "maxF $dst, $a, $b \t! using $tmp, $atmp and $btmp as TEMP" %} 4494 ins_encode %{ 4495 __ vminmax_fp(Op_MaxV, T_FLOAT, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, Assembler::AVX_128bit); 4496 %} 4497 ins_pipe( pipe_slow ); 4498 %} 4499 4500 instruct maxF_reduction_reg(legRegF dst, legRegF a, legRegF b, legRegF xtmp, rRegI rtmp, rFlagsReg cr) %{ 4501 predicate(!VM_Version::supports_avx10_2() && UseAVX > 0 && VLoopReductions::is_reduction(n)); 4502 match(Set dst (MaxF a b)); 4503 effect(USE a, USE b, TEMP xtmp, TEMP rtmp, KILL cr); 4504 4505 format %{ "maxF_reduction $dst, $a, $b \t!using $xtmp and $rtmp as TEMP" %} 4506 ins_encode %{ 4507 emit_fp_min_max(masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xtmp$$XMMRegister, $rtmp$$Register, 4508 false /*min*/, true /*single*/); 4509 %} 4510 ins_pipe( pipe_slow ); 4511 %} 4512 4513 // max = java.lang.Math.max(double a, double b) 4514 instruct maxD_avx10_reg(regD dst, regD a, regD b) %{ 4515 predicate(VM_Version::supports_avx10_2()); 4516 match(Set dst (MaxD a b)); 4517 format %{ "maxD $dst, $a, $b" %} 4518 ins_encode %{ 4519 __ eminmaxsd($dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, AVX10_MINMAX_MAX_COMPARE_SIGN); 4520 %} 4521 ins_pipe( pipe_slow ); 4522 %} 4523 4524 // max = java.lang.Math.max(double a, double b) 4525 instruct maxD_reg(legRegD dst, legRegD a, legRegD b, legRegD tmp, legRegD atmp, legRegD btmp) %{ 4526 predicate(!VM_Version::supports_avx10_2() && UseAVX > 0 && !VLoopReductions::is_reduction(n)); 4527 match(Set dst (MaxD a b)); 4528 effect(USE a, USE b, TEMP atmp, TEMP btmp, TEMP tmp); 4529 format %{ "maxD $dst, $a, $b \t! using $tmp, $atmp and $btmp as TEMP" %} 4530 ins_encode %{ 4531 __ vminmax_fp(Op_MaxV, T_DOUBLE, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, Assembler::AVX_128bit); 4532 %} 4533 ins_pipe( pipe_slow ); 4534 %} 4535 4536 instruct maxD_reduction_reg(legRegD dst, legRegD a, legRegD b, legRegD xtmp, rRegL rtmp, rFlagsReg cr) %{ 4537 predicate(!VM_Version::supports_avx10_2() && UseAVX > 0 && VLoopReductions::is_reduction(n)); 4538 match(Set dst (MaxD a b)); 4539 effect(USE a, USE b, TEMP xtmp, TEMP rtmp, KILL cr); 4540 4541 format %{ "maxD_reduction $dst, $a, $b \t! using $xtmp and $rtmp as TEMP" %} 4542 ins_encode %{ 4543 emit_fp_min_max(masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xtmp$$XMMRegister, $rtmp$$Register, 4544 false /*min*/, false /*single*/); 4545 %} 4546 ins_pipe( pipe_slow ); 4547 %} 4548 4549 // max = java.lang.Math.min(float a, float b) 4550 instruct minF_avx10_reg(regF dst, regF a, regF b) %{ 4551 predicate(VM_Version::supports_avx10_2()); 4552 match(Set dst (MinF a b)); 4553 format %{ "minF $dst, $a, $b" %} 4554 ins_encode %{ 4555 __ eminmaxss($dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, AVX10_MINMAX_MIN_COMPARE_SIGN); 4556 %} 4557 ins_pipe( pipe_slow ); 4558 %} 4559 4560 // min = java.lang.Math.min(float a, float b) 4561 instruct minF_reg(legRegF dst, legRegF a, legRegF b, legRegF tmp, legRegF atmp, legRegF btmp) %{ 4562 predicate(!VM_Version::supports_avx10_2() && UseAVX > 0 && !VLoopReductions::is_reduction(n)); 4563 match(Set dst (MinF a b)); 4564 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 4565 format %{ "minF $dst, $a, $b \t! using $tmp, $atmp and $btmp as TEMP" %} 4566 ins_encode %{ 4567 __ vminmax_fp(Op_MinV, T_FLOAT, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, Assembler::AVX_128bit); 4568 %} 4569 ins_pipe( pipe_slow ); 4570 %} 4571 4572 instruct minF_reduction_reg(legRegF dst, legRegF a, legRegF b, legRegF xtmp, rRegI rtmp, rFlagsReg cr) %{ 4573 predicate(!VM_Version::supports_avx10_2() && UseAVX > 0 && VLoopReductions::is_reduction(n)); 4574 match(Set dst (MinF a b)); 4575 effect(USE a, USE b, TEMP xtmp, TEMP rtmp, KILL cr); 4576 4577 format %{ "minF_reduction $dst, $a, $b \t! using $xtmp and $rtmp as TEMP" %} 4578 ins_encode %{ 4579 emit_fp_min_max(masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xtmp$$XMMRegister, $rtmp$$Register, 4580 true /*min*/, true /*single*/); 4581 %} 4582 ins_pipe( pipe_slow ); 4583 %} 4584 4585 // max = java.lang.Math.min(double a, double b) 4586 instruct minD_avx10_reg(regD dst, regD a, regD b) %{ 4587 predicate(VM_Version::supports_avx10_2()); 4588 match(Set dst (MinD a b)); 4589 format %{ "minD $dst, $a, $b" %} 4590 ins_encode %{ 4591 __ eminmaxsd($dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, AVX10_MINMAX_MIN_COMPARE_SIGN); 4592 %} 4593 ins_pipe( pipe_slow ); 4594 %} 4595 4596 // min = java.lang.Math.min(double a, double b) 4597 instruct minD_reg(legRegD dst, legRegD a, legRegD b, legRegD tmp, legRegD atmp, legRegD btmp) %{ 4598 predicate(!VM_Version::supports_avx10_2() && UseAVX > 0 && !VLoopReductions::is_reduction(n)); 4599 match(Set dst (MinD a b)); 4600 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 4601 format %{ "minD $dst, $a, $b \t! using $tmp, $atmp and $btmp as TEMP" %} 4602 ins_encode %{ 4603 __ vminmax_fp(Op_MinV, T_DOUBLE, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, Assembler::AVX_128bit); 4604 %} 4605 ins_pipe( pipe_slow ); 4606 %} 4607 4608 instruct minD_reduction_reg(legRegD dst, legRegD a, legRegD b, legRegD xtmp, rRegL rtmp, rFlagsReg cr) %{ 4609 predicate(!VM_Version::supports_avx10_2() && UseAVX > 0 && VLoopReductions::is_reduction(n)); 4610 match(Set dst (MinD a b)); 4611 effect(USE a, USE b, TEMP xtmp, TEMP rtmp, KILL cr); 4612 4613 format %{ "maxD_reduction $dst, $a, $b \t! using $xtmp and $rtmp as TEMP" %} 4614 ins_encode %{ 4615 emit_fp_min_max(masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xtmp$$XMMRegister, $rtmp$$Register, 4616 true /*min*/, false /*single*/); 4617 %} 4618 ins_pipe( pipe_slow ); 4619 %} 4620 4621 // Load Effective Address 4622 instruct leaP8(rRegP dst, indOffset8 mem) 4623 %{ 4624 match(Set dst mem); 4625 4626 ins_cost(110); // XXX 4627 format %{ "leaq $dst, $mem\t# ptr 8" %} 4628 ins_encode %{ 4629 __ leaq($dst$$Register, $mem$$Address); 4630 %} 4631 ins_pipe(ialu_reg_reg_fat); 4632 %} 4633 4634 instruct leaP32(rRegP dst, indOffset32 mem) 4635 %{ 4636 match(Set dst mem); 4637 4638 ins_cost(110); 4639 format %{ "leaq $dst, $mem\t# ptr 32" %} 4640 ins_encode %{ 4641 __ leaq($dst$$Register, $mem$$Address); 4642 %} 4643 ins_pipe(ialu_reg_reg_fat); 4644 %} 4645 4646 instruct leaPIdxOff(rRegP dst, indIndexOffset mem) 4647 %{ 4648 match(Set dst mem); 4649 4650 ins_cost(110); 4651 format %{ "leaq $dst, $mem\t# ptr idxoff" %} 4652 ins_encode %{ 4653 __ leaq($dst$$Register, $mem$$Address); 4654 %} 4655 ins_pipe(ialu_reg_reg_fat); 4656 %} 4657 4658 instruct leaPIdxScale(rRegP dst, indIndexScale mem) 4659 %{ 4660 match(Set dst mem); 4661 4662 ins_cost(110); 4663 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 4664 ins_encode %{ 4665 __ leaq($dst$$Register, $mem$$Address); 4666 %} 4667 ins_pipe(ialu_reg_reg_fat); 4668 %} 4669 4670 instruct leaPPosIdxScale(rRegP dst, indPosIndexScale mem) 4671 %{ 4672 match(Set dst mem); 4673 4674 ins_cost(110); 4675 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 4676 ins_encode %{ 4677 __ leaq($dst$$Register, $mem$$Address); 4678 %} 4679 ins_pipe(ialu_reg_reg_fat); 4680 %} 4681 4682 instruct leaPIdxScaleOff(rRegP dst, indIndexScaleOffset mem) 4683 %{ 4684 match(Set dst mem); 4685 4686 ins_cost(110); 4687 format %{ "leaq $dst, $mem\t# ptr idxscaleoff" %} 4688 ins_encode %{ 4689 __ leaq($dst$$Register, $mem$$Address); 4690 %} 4691 ins_pipe(ialu_reg_reg_fat); 4692 %} 4693 4694 instruct leaPPosIdxOff(rRegP dst, indPosIndexOffset mem) 4695 %{ 4696 match(Set dst mem); 4697 4698 ins_cost(110); 4699 format %{ "leaq $dst, $mem\t# ptr posidxoff" %} 4700 ins_encode %{ 4701 __ leaq($dst$$Register, $mem$$Address); 4702 %} 4703 ins_pipe(ialu_reg_reg_fat); 4704 %} 4705 4706 instruct leaPPosIdxScaleOff(rRegP dst, indPosIndexScaleOffset mem) 4707 %{ 4708 match(Set dst mem); 4709 4710 ins_cost(110); 4711 format %{ "leaq $dst, $mem\t# ptr posidxscaleoff" %} 4712 ins_encode %{ 4713 __ leaq($dst$$Register, $mem$$Address); 4714 %} 4715 ins_pipe(ialu_reg_reg_fat); 4716 %} 4717 4718 // Load Effective Address which uses Narrow (32-bits) oop 4719 instruct leaPCompressedOopOffset(rRegP dst, indCompressedOopOffset mem) 4720 %{ 4721 predicate(UseCompressedOops && (CompressedOops::shift() != 0)); 4722 match(Set dst mem); 4723 4724 ins_cost(110); 4725 format %{ "leaq $dst, $mem\t# ptr compressedoopoff32" %} 4726 ins_encode %{ 4727 __ leaq($dst$$Register, $mem$$Address); 4728 %} 4729 ins_pipe(ialu_reg_reg_fat); 4730 %} 4731 4732 instruct leaP8Narrow(rRegP dst, indOffset8Narrow mem) 4733 %{ 4734 predicate(CompressedOops::shift() == 0); 4735 match(Set dst mem); 4736 4737 ins_cost(110); // XXX 4738 format %{ "leaq $dst, $mem\t# ptr off8narrow" %} 4739 ins_encode %{ 4740 __ leaq($dst$$Register, $mem$$Address); 4741 %} 4742 ins_pipe(ialu_reg_reg_fat); 4743 %} 4744 4745 instruct leaP32Narrow(rRegP dst, indOffset32Narrow mem) 4746 %{ 4747 predicate(CompressedOops::shift() == 0); 4748 match(Set dst mem); 4749 4750 ins_cost(110); 4751 format %{ "leaq $dst, $mem\t# ptr off32narrow" %} 4752 ins_encode %{ 4753 __ leaq($dst$$Register, $mem$$Address); 4754 %} 4755 ins_pipe(ialu_reg_reg_fat); 4756 %} 4757 4758 instruct leaPIdxOffNarrow(rRegP dst, indIndexOffsetNarrow mem) 4759 %{ 4760 predicate(CompressedOops::shift() == 0); 4761 match(Set dst mem); 4762 4763 ins_cost(110); 4764 format %{ "leaq $dst, $mem\t# ptr idxoffnarrow" %} 4765 ins_encode %{ 4766 __ leaq($dst$$Register, $mem$$Address); 4767 %} 4768 ins_pipe(ialu_reg_reg_fat); 4769 %} 4770 4771 instruct leaPIdxScaleNarrow(rRegP dst, indIndexScaleNarrow mem) 4772 %{ 4773 predicate(CompressedOops::shift() == 0); 4774 match(Set dst mem); 4775 4776 ins_cost(110); 4777 format %{ "leaq $dst, $mem\t# ptr idxscalenarrow" %} 4778 ins_encode %{ 4779 __ leaq($dst$$Register, $mem$$Address); 4780 %} 4781 ins_pipe(ialu_reg_reg_fat); 4782 %} 4783 4784 instruct leaPIdxScaleOffNarrow(rRegP dst, indIndexScaleOffsetNarrow mem) 4785 %{ 4786 predicate(CompressedOops::shift() == 0); 4787 match(Set dst mem); 4788 4789 ins_cost(110); 4790 format %{ "leaq $dst, $mem\t# ptr idxscaleoffnarrow" %} 4791 ins_encode %{ 4792 __ leaq($dst$$Register, $mem$$Address); 4793 %} 4794 ins_pipe(ialu_reg_reg_fat); 4795 %} 4796 4797 instruct leaPPosIdxOffNarrow(rRegP dst, indPosIndexOffsetNarrow mem) 4798 %{ 4799 predicate(CompressedOops::shift() == 0); 4800 match(Set dst mem); 4801 4802 ins_cost(110); 4803 format %{ "leaq $dst, $mem\t# ptr posidxoffnarrow" %} 4804 ins_encode %{ 4805 __ leaq($dst$$Register, $mem$$Address); 4806 %} 4807 ins_pipe(ialu_reg_reg_fat); 4808 %} 4809 4810 instruct leaPPosIdxScaleOffNarrow(rRegP dst, indPosIndexScaleOffsetNarrow mem) 4811 %{ 4812 predicate(CompressedOops::shift() == 0); 4813 match(Set dst mem); 4814 4815 ins_cost(110); 4816 format %{ "leaq $dst, $mem\t# ptr posidxscaleoffnarrow" %} 4817 ins_encode %{ 4818 __ leaq($dst$$Register, $mem$$Address); 4819 %} 4820 ins_pipe(ialu_reg_reg_fat); 4821 %} 4822 4823 instruct loadConI(rRegI dst, immI src) 4824 %{ 4825 match(Set dst src); 4826 4827 format %{ "movl $dst, $src\t# int" %} 4828 ins_encode %{ 4829 __ movl($dst$$Register, $src$$constant); 4830 %} 4831 ins_pipe(ialu_reg_fat); // XXX 4832 %} 4833 4834 instruct loadConI0(rRegI dst, immI_0 src, rFlagsReg cr) 4835 %{ 4836 match(Set dst src); 4837 effect(KILL cr); 4838 4839 ins_cost(50); 4840 format %{ "xorl $dst, $dst\t# int" %} 4841 ins_encode %{ 4842 __ xorl($dst$$Register, $dst$$Register); 4843 %} 4844 ins_pipe(ialu_reg); 4845 %} 4846 4847 instruct loadConL(rRegL dst, immL src) 4848 %{ 4849 match(Set dst src); 4850 4851 ins_cost(150); 4852 format %{ "movq $dst, $src\t# long" %} 4853 ins_encode %{ 4854 __ mov64($dst$$Register, $src$$constant); 4855 %} 4856 ins_pipe(ialu_reg); 4857 %} 4858 4859 instruct loadConL0(rRegL dst, immL0 src, rFlagsReg cr) 4860 %{ 4861 match(Set dst src); 4862 effect(KILL cr); 4863 4864 ins_cost(50); 4865 format %{ "xorl $dst, $dst\t# long" %} 4866 ins_encode %{ 4867 __ xorl($dst$$Register, $dst$$Register); 4868 %} 4869 ins_pipe(ialu_reg); // XXX 4870 %} 4871 4872 instruct loadConUL32(rRegL dst, immUL32 src) 4873 %{ 4874 match(Set dst src); 4875 4876 ins_cost(60); 4877 format %{ "movl $dst, $src\t# long (unsigned 32-bit)" %} 4878 ins_encode %{ 4879 __ movl($dst$$Register, $src$$constant); 4880 %} 4881 ins_pipe(ialu_reg); 4882 %} 4883 4884 instruct loadConL32(rRegL dst, immL32 src) 4885 %{ 4886 match(Set dst src); 4887 4888 ins_cost(70); 4889 format %{ "movq $dst, $src\t# long (32-bit)" %} 4890 ins_encode %{ 4891 __ movq($dst$$Register, $src$$constant); 4892 %} 4893 ins_pipe(ialu_reg); 4894 %} 4895 4896 instruct loadConP(rRegP dst, immP con) %{ 4897 match(Set dst con); 4898 4899 format %{ "movq $dst, $con\t# ptr" %} 4900 ins_encode %{ 4901 __ mov64($dst$$Register, $con$$constant, $con->constant_reloc(), RELOC_IMM64); 4902 %} 4903 ins_pipe(ialu_reg_fat); // XXX 4904 %} 4905 4906 instruct loadConP0(rRegP dst, immP0 src, rFlagsReg cr) 4907 %{ 4908 match(Set dst src); 4909 effect(KILL cr); 4910 4911 ins_cost(50); 4912 format %{ "xorl $dst, $dst\t# ptr" %} 4913 ins_encode %{ 4914 __ xorl($dst$$Register, $dst$$Register); 4915 %} 4916 ins_pipe(ialu_reg); 4917 %} 4918 4919 instruct loadConP31(rRegP dst, immP31 src, rFlagsReg cr) 4920 %{ 4921 match(Set dst src); 4922 effect(KILL cr); 4923 4924 ins_cost(60); 4925 format %{ "movl $dst, $src\t# ptr (positive 32-bit)" %} 4926 ins_encode %{ 4927 __ movl($dst$$Register, $src$$constant); 4928 %} 4929 ins_pipe(ialu_reg); 4930 %} 4931 4932 instruct loadConF(regF dst, immF con) %{ 4933 match(Set dst con); 4934 ins_cost(125); 4935 format %{ "movss $dst, [$constantaddress]\t# load from constant table: float=$con" %} 4936 ins_encode %{ 4937 __ movflt($dst$$XMMRegister, $constantaddress($con)); 4938 %} 4939 ins_pipe(pipe_slow); 4940 %} 4941 4942 instruct loadConH(regF dst, immH con) %{ 4943 match(Set dst con); 4944 ins_cost(125); 4945 format %{ "movss $dst, [$constantaddress]\t# load from constant table: halffloat=$con" %} 4946 ins_encode %{ 4947 __ movflt($dst$$XMMRegister, $constantaddress($con)); 4948 %} 4949 ins_pipe(pipe_slow); 4950 %} 4951 4952 instruct loadConN0(rRegN dst, immN0 src, rFlagsReg cr) %{ 4953 match(Set dst src); 4954 effect(KILL cr); 4955 format %{ "xorq $dst, $src\t# compressed null pointer" %} 4956 ins_encode %{ 4957 __ xorq($dst$$Register, $dst$$Register); 4958 %} 4959 ins_pipe(ialu_reg); 4960 %} 4961 4962 instruct loadConN(rRegN dst, immN src) %{ 4963 match(Set dst src); 4964 4965 ins_cost(125); 4966 format %{ "movl $dst, $src\t# compressed ptr" %} 4967 ins_encode %{ 4968 address con = (address)$src$$constant; 4969 if (con == nullptr) { 4970 ShouldNotReachHere(); 4971 } else { 4972 __ set_narrow_oop($dst$$Register, (jobject)$src$$constant); 4973 } 4974 %} 4975 ins_pipe(ialu_reg_fat); // XXX 4976 %} 4977 4978 instruct loadConNKlass(rRegN dst, immNKlass src) %{ 4979 match(Set dst src); 4980 4981 ins_cost(125); 4982 format %{ "movl $dst, $src\t# compressed klass ptr" %} 4983 ins_encode %{ 4984 address con = (address)$src$$constant; 4985 if (con == nullptr) { 4986 ShouldNotReachHere(); 4987 } else { 4988 __ set_narrow_klass($dst$$Register, (Klass*)$src$$constant); 4989 } 4990 %} 4991 ins_pipe(ialu_reg_fat); // XXX 4992 %} 4993 4994 instruct loadConF0(regF dst, immF0 src) 4995 %{ 4996 match(Set dst src); 4997 ins_cost(100); 4998 4999 format %{ "xorps $dst, $dst\t# float 0.0" %} 5000 ins_encode %{ 5001 __ xorps($dst$$XMMRegister, $dst$$XMMRegister); 5002 %} 5003 ins_pipe(pipe_slow); 5004 %} 5005 5006 // Use the same format since predicate() can not be used here. 5007 instruct loadConD(regD dst, immD con) %{ 5008 match(Set dst con); 5009 ins_cost(125); 5010 format %{ "movsd $dst, [$constantaddress]\t# load from constant table: double=$con" %} 5011 ins_encode %{ 5012 __ movdbl($dst$$XMMRegister, $constantaddress($con)); 5013 %} 5014 ins_pipe(pipe_slow); 5015 %} 5016 5017 instruct loadConD0(regD dst, immD0 src) 5018 %{ 5019 match(Set dst src); 5020 ins_cost(100); 5021 5022 format %{ "xorpd $dst, $dst\t# double 0.0" %} 5023 ins_encode %{ 5024 __ xorpd($dst$$XMMRegister, $dst$$XMMRegister); 5025 %} 5026 ins_pipe(pipe_slow); 5027 %} 5028 5029 instruct loadSSI(rRegI dst, stackSlotI src) 5030 %{ 5031 match(Set dst src); 5032 5033 ins_cost(125); 5034 format %{ "movl $dst, $src\t# int stk" %} 5035 ins_encode %{ 5036 __ movl($dst$$Register, $src$$Address); 5037 %} 5038 ins_pipe(ialu_reg_mem); 5039 %} 5040 5041 instruct loadSSL(rRegL dst, stackSlotL src) 5042 %{ 5043 match(Set dst src); 5044 5045 ins_cost(125); 5046 format %{ "movq $dst, $src\t# long stk" %} 5047 ins_encode %{ 5048 __ movq($dst$$Register, $src$$Address); 5049 %} 5050 ins_pipe(ialu_reg_mem); 5051 %} 5052 5053 instruct loadSSP(rRegP dst, stackSlotP src) 5054 %{ 5055 match(Set dst src); 5056 5057 ins_cost(125); 5058 format %{ "movq $dst, $src\t# ptr stk" %} 5059 ins_encode %{ 5060 __ movq($dst$$Register, $src$$Address); 5061 %} 5062 ins_pipe(ialu_reg_mem); 5063 %} 5064 5065 instruct loadSSF(regF dst, stackSlotF src) 5066 %{ 5067 match(Set dst src); 5068 5069 ins_cost(125); 5070 format %{ "movss $dst, $src\t# float stk" %} 5071 ins_encode %{ 5072 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 5073 %} 5074 ins_pipe(pipe_slow); // XXX 5075 %} 5076 5077 // Use the same format since predicate() can not be used here. 5078 instruct loadSSD(regD dst, stackSlotD src) 5079 %{ 5080 match(Set dst src); 5081 5082 ins_cost(125); 5083 format %{ "movsd $dst, $src\t# double stk" %} 5084 ins_encode %{ 5085 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 5086 %} 5087 ins_pipe(pipe_slow); // XXX 5088 %} 5089 5090 // Prefetch instructions for allocation. 5091 // Must be safe to execute with invalid address (cannot fault). 5092 5093 instruct prefetchAlloc( memory mem ) %{ 5094 predicate(AllocatePrefetchInstr==3); 5095 match(PrefetchAllocation mem); 5096 ins_cost(125); 5097 5098 format %{ "PREFETCHW $mem\t# Prefetch allocation into level 1 cache and mark modified" %} 5099 ins_encode %{ 5100 __ prefetchw($mem$$Address); 5101 %} 5102 ins_pipe(ialu_mem); 5103 %} 5104 5105 instruct prefetchAllocNTA( memory mem ) %{ 5106 predicate(AllocatePrefetchInstr==0); 5107 match(PrefetchAllocation mem); 5108 ins_cost(125); 5109 5110 format %{ "PREFETCHNTA $mem\t# Prefetch allocation to non-temporal cache for write" %} 5111 ins_encode %{ 5112 __ prefetchnta($mem$$Address); 5113 %} 5114 ins_pipe(ialu_mem); 5115 %} 5116 5117 instruct prefetchAllocT0( memory mem ) %{ 5118 predicate(AllocatePrefetchInstr==1); 5119 match(PrefetchAllocation mem); 5120 ins_cost(125); 5121 5122 format %{ "PREFETCHT0 $mem\t# Prefetch allocation to level 1 and 2 caches for write" %} 5123 ins_encode %{ 5124 __ prefetcht0($mem$$Address); 5125 %} 5126 ins_pipe(ialu_mem); 5127 %} 5128 5129 instruct prefetchAllocT2( memory mem ) %{ 5130 predicate(AllocatePrefetchInstr==2); 5131 match(PrefetchAllocation mem); 5132 ins_cost(125); 5133 5134 format %{ "PREFETCHT2 $mem\t# Prefetch allocation to level 2 cache for write" %} 5135 ins_encode %{ 5136 __ prefetcht2($mem$$Address); 5137 %} 5138 ins_pipe(ialu_mem); 5139 %} 5140 5141 //----------Store Instructions------------------------------------------------- 5142 5143 // Store Byte 5144 instruct storeB(memory mem, rRegI src) 5145 %{ 5146 match(Set mem (StoreB mem src)); 5147 5148 ins_cost(125); // XXX 5149 format %{ "movb $mem, $src\t# byte" %} 5150 ins_encode %{ 5151 __ movb($mem$$Address, $src$$Register); 5152 %} 5153 ins_pipe(ialu_mem_reg); 5154 %} 5155 5156 // Store Char/Short 5157 instruct storeC(memory mem, rRegI src) 5158 %{ 5159 match(Set mem (StoreC mem src)); 5160 5161 ins_cost(125); // XXX 5162 format %{ "movw $mem, $src\t# char/short" %} 5163 ins_encode %{ 5164 __ movw($mem$$Address, $src$$Register); 5165 %} 5166 ins_pipe(ialu_mem_reg); 5167 %} 5168 5169 // Store Integer 5170 instruct storeI(memory mem, rRegI src) 5171 %{ 5172 match(Set mem (StoreI mem src)); 5173 5174 ins_cost(125); // XXX 5175 format %{ "movl $mem, $src\t# int" %} 5176 ins_encode %{ 5177 __ movl($mem$$Address, $src$$Register); 5178 %} 5179 ins_pipe(ialu_mem_reg); 5180 %} 5181 5182 // Store Long 5183 instruct storeL(memory mem, rRegL src) 5184 %{ 5185 match(Set mem (StoreL mem src)); 5186 5187 ins_cost(125); // XXX 5188 format %{ "movq $mem, $src\t# long" %} 5189 ins_encode %{ 5190 __ movq($mem$$Address, $src$$Register); 5191 %} 5192 ins_pipe(ialu_mem_reg); // XXX 5193 %} 5194 5195 // Store Pointer 5196 instruct storeP(memory mem, any_RegP src) 5197 %{ 5198 predicate(n->as_Store()->barrier_data() == 0); 5199 match(Set mem (StoreP mem src)); 5200 5201 ins_cost(125); // XXX 5202 format %{ "movq $mem, $src\t# ptr" %} 5203 ins_encode %{ 5204 __ movq($mem$$Address, $src$$Register); 5205 %} 5206 ins_pipe(ialu_mem_reg); 5207 %} 5208 5209 instruct storeImmP0(memory mem, immP0 zero) 5210 %{ 5211 predicate(UseCompressedOops && (CompressedOops::base() == nullptr) && n->as_Store()->barrier_data() == 0); 5212 match(Set mem (StoreP mem zero)); 5213 5214 ins_cost(125); // XXX 5215 format %{ "movq $mem, R12\t# ptr (R12_heapbase==0)" %} 5216 ins_encode %{ 5217 __ movq($mem$$Address, r12); 5218 %} 5219 ins_pipe(ialu_mem_reg); 5220 %} 5221 5222 // Store Null Pointer, mark word, or other simple pointer constant. 5223 instruct storeImmP(memory mem, immP31 src) 5224 %{ 5225 predicate(n->as_Store()->barrier_data() == 0); 5226 match(Set mem (StoreP mem src)); 5227 5228 ins_cost(150); // XXX 5229 format %{ "movq $mem, $src\t# ptr" %} 5230 ins_encode %{ 5231 __ movq($mem$$Address, $src$$constant); 5232 %} 5233 ins_pipe(ialu_mem_imm); 5234 %} 5235 5236 // Store Compressed Pointer 5237 instruct storeN(memory mem, rRegN src) 5238 %{ 5239 predicate(n->as_Store()->barrier_data() == 0); 5240 match(Set mem (StoreN mem src)); 5241 5242 ins_cost(125); // XXX 5243 format %{ "movl $mem, $src\t# compressed ptr" %} 5244 ins_encode %{ 5245 __ movl($mem$$Address, $src$$Register); 5246 %} 5247 ins_pipe(ialu_mem_reg); 5248 %} 5249 5250 instruct storeNKlass(memory mem, rRegN src) 5251 %{ 5252 match(Set mem (StoreNKlass mem src)); 5253 5254 ins_cost(125); // XXX 5255 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5256 ins_encode %{ 5257 __ movl($mem$$Address, $src$$Register); 5258 %} 5259 ins_pipe(ialu_mem_reg); 5260 %} 5261 5262 instruct storeImmN0(memory mem, immN0 zero) 5263 %{ 5264 predicate(CompressedOops::base() == nullptr && n->as_Store()->barrier_data() == 0); 5265 match(Set mem (StoreN mem zero)); 5266 5267 ins_cost(125); // XXX 5268 format %{ "movl $mem, R12\t# compressed ptr (R12_heapbase==0)" %} 5269 ins_encode %{ 5270 __ movl($mem$$Address, r12); 5271 %} 5272 ins_pipe(ialu_mem_reg); 5273 %} 5274 5275 instruct storeImmN(memory mem, immN src) 5276 %{ 5277 predicate(n->as_Store()->barrier_data() == 0); 5278 match(Set mem (StoreN mem src)); 5279 5280 ins_cost(150); // XXX 5281 format %{ "movl $mem, $src\t# compressed ptr" %} 5282 ins_encode %{ 5283 address con = (address)$src$$constant; 5284 if (con == nullptr) { 5285 __ movl($mem$$Address, 0); 5286 } else { 5287 __ set_narrow_oop($mem$$Address, (jobject)$src$$constant); 5288 } 5289 %} 5290 ins_pipe(ialu_mem_imm); 5291 %} 5292 5293 instruct storeImmNKlass(memory mem, immNKlass src) 5294 %{ 5295 match(Set mem (StoreNKlass mem src)); 5296 5297 ins_cost(150); // XXX 5298 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5299 ins_encode %{ 5300 __ set_narrow_klass($mem$$Address, (Klass*)$src$$constant); 5301 %} 5302 ins_pipe(ialu_mem_imm); 5303 %} 5304 5305 // Store Integer Immediate 5306 instruct storeImmI0(memory mem, immI_0 zero) 5307 %{ 5308 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5309 match(Set mem (StoreI mem zero)); 5310 5311 ins_cost(125); // XXX 5312 format %{ "movl $mem, R12\t# int (R12_heapbase==0)" %} 5313 ins_encode %{ 5314 __ movl($mem$$Address, r12); 5315 %} 5316 ins_pipe(ialu_mem_reg); 5317 %} 5318 5319 instruct storeImmI(memory mem, immI src) 5320 %{ 5321 match(Set mem (StoreI mem src)); 5322 5323 ins_cost(150); 5324 format %{ "movl $mem, $src\t# int" %} 5325 ins_encode %{ 5326 __ movl($mem$$Address, $src$$constant); 5327 %} 5328 ins_pipe(ialu_mem_imm); 5329 %} 5330 5331 // Store Long Immediate 5332 instruct storeImmL0(memory mem, immL0 zero) 5333 %{ 5334 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5335 match(Set mem (StoreL mem zero)); 5336 5337 ins_cost(125); // XXX 5338 format %{ "movq $mem, R12\t# long (R12_heapbase==0)" %} 5339 ins_encode %{ 5340 __ movq($mem$$Address, r12); 5341 %} 5342 ins_pipe(ialu_mem_reg); 5343 %} 5344 5345 instruct storeImmL(memory mem, immL32 src) 5346 %{ 5347 match(Set mem (StoreL mem src)); 5348 5349 ins_cost(150); 5350 format %{ "movq $mem, $src\t# long" %} 5351 ins_encode %{ 5352 __ movq($mem$$Address, $src$$constant); 5353 %} 5354 ins_pipe(ialu_mem_imm); 5355 %} 5356 5357 // Store Short/Char Immediate 5358 instruct storeImmC0(memory mem, immI_0 zero) 5359 %{ 5360 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5361 match(Set mem (StoreC mem zero)); 5362 5363 ins_cost(125); // XXX 5364 format %{ "movw $mem, R12\t# short/char (R12_heapbase==0)" %} 5365 ins_encode %{ 5366 __ movw($mem$$Address, r12); 5367 %} 5368 ins_pipe(ialu_mem_reg); 5369 %} 5370 5371 instruct storeImmI16(memory mem, immI16 src) 5372 %{ 5373 predicate(UseStoreImmI16); 5374 match(Set mem (StoreC mem src)); 5375 5376 ins_cost(150); 5377 format %{ "movw $mem, $src\t# short/char" %} 5378 ins_encode %{ 5379 __ movw($mem$$Address, $src$$constant); 5380 %} 5381 ins_pipe(ialu_mem_imm); 5382 %} 5383 5384 // Store Byte Immediate 5385 instruct storeImmB0(memory mem, immI_0 zero) 5386 %{ 5387 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5388 match(Set mem (StoreB mem zero)); 5389 5390 ins_cost(125); // XXX 5391 format %{ "movb $mem, R12\t# short/char (R12_heapbase==0)" %} 5392 ins_encode %{ 5393 __ movb($mem$$Address, r12); 5394 %} 5395 ins_pipe(ialu_mem_reg); 5396 %} 5397 5398 instruct storeImmB(memory mem, immI8 src) 5399 %{ 5400 match(Set mem (StoreB mem src)); 5401 5402 ins_cost(150); // XXX 5403 format %{ "movb $mem, $src\t# byte" %} 5404 ins_encode %{ 5405 __ movb($mem$$Address, $src$$constant); 5406 %} 5407 ins_pipe(ialu_mem_imm); 5408 %} 5409 5410 // Store Float 5411 instruct storeF(memory mem, regF src) 5412 %{ 5413 match(Set mem (StoreF mem src)); 5414 5415 ins_cost(95); // XXX 5416 format %{ "movss $mem, $src\t# float" %} 5417 ins_encode %{ 5418 __ movflt($mem$$Address, $src$$XMMRegister); 5419 %} 5420 ins_pipe(pipe_slow); // XXX 5421 %} 5422 5423 // Store immediate Float value (it is faster than store from XMM register) 5424 instruct storeF0(memory mem, immF0 zero) 5425 %{ 5426 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5427 match(Set mem (StoreF mem zero)); 5428 5429 ins_cost(25); // XXX 5430 format %{ "movl $mem, R12\t# float 0. (R12_heapbase==0)" %} 5431 ins_encode %{ 5432 __ movl($mem$$Address, r12); 5433 %} 5434 ins_pipe(ialu_mem_reg); 5435 %} 5436 5437 instruct storeF_imm(memory mem, immF src) 5438 %{ 5439 match(Set mem (StoreF mem src)); 5440 5441 ins_cost(50); 5442 format %{ "movl $mem, $src\t# float" %} 5443 ins_encode %{ 5444 __ movl($mem$$Address, jint_cast($src$$constant)); 5445 %} 5446 ins_pipe(ialu_mem_imm); 5447 %} 5448 5449 // Store Double 5450 instruct storeD(memory mem, regD src) 5451 %{ 5452 match(Set mem (StoreD mem src)); 5453 5454 ins_cost(95); // XXX 5455 format %{ "movsd $mem, $src\t# double" %} 5456 ins_encode %{ 5457 __ movdbl($mem$$Address, $src$$XMMRegister); 5458 %} 5459 ins_pipe(pipe_slow); // XXX 5460 %} 5461 5462 // Store immediate double 0.0 (it is faster than store from XMM register) 5463 instruct storeD0_imm(memory mem, immD0 src) 5464 %{ 5465 predicate(!UseCompressedOops || (CompressedOops::base() != nullptr)); 5466 match(Set mem (StoreD mem src)); 5467 5468 ins_cost(50); 5469 format %{ "movq $mem, $src\t# double 0." %} 5470 ins_encode %{ 5471 __ movq($mem$$Address, $src$$constant); 5472 %} 5473 ins_pipe(ialu_mem_imm); 5474 %} 5475 5476 instruct storeD0(memory mem, immD0 zero) 5477 %{ 5478 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5479 match(Set mem (StoreD mem zero)); 5480 5481 ins_cost(25); // XXX 5482 format %{ "movq $mem, R12\t# double 0. (R12_heapbase==0)" %} 5483 ins_encode %{ 5484 __ movq($mem$$Address, r12); 5485 %} 5486 ins_pipe(ialu_mem_reg); 5487 %} 5488 5489 instruct storeSSI(stackSlotI dst, rRegI src) 5490 %{ 5491 match(Set dst src); 5492 5493 ins_cost(100); 5494 format %{ "movl $dst, $src\t# int stk" %} 5495 ins_encode %{ 5496 __ movl($dst$$Address, $src$$Register); 5497 %} 5498 ins_pipe( ialu_mem_reg ); 5499 %} 5500 5501 instruct storeSSL(stackSlotL dst, rRegL src) 5502 %{ 5503 match(Set dst src); 5504 5505 ins_cost(100); 5506 format %{ "movq $dst, $src\t# long stk" %} 5507 ins_encode %{ 5508 __ movq($dst$$Address, $src$$Register); 5509 %} 5510 ins_pipe(ialu_mem_reg); 5511 %} 5512 5513 instruct storeSSP(stackSlotP dst, rRegP src) 5514 %{ 5515 match(Set dst src); 5516 5517 ins_cost(100); 5518 format %{ "movq $dst, $src\t# ptr stk" %} 5519 ins_encode %{ 5520 __ movq($dst$$Address, $src$$Register); 5521 %} 5522 ins_pipe(ialu_mem_reg); 5523 %} 5524 5525 instruct storeSSF(stackSlotF dst, regF src) 5526 %{ 5527 match(Set dst src); 5528 5529 ins_cost(95); // XXX 5530 format %{ "movss $dst, $src\t# float stk" %} 5531 ins_encode %{ 5532 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 5533 %} 5534 ins_pipe(pipe_slow); // XXX 5535 %} 5536 5537 instruct storeSSD(stackSlotD dst, regD src) 5538 %{ 5539 match(Set dst src); 5540 5541 ins_cost(95); // XXX 5542 format %{ "movsd $dst, $src\t# double stk" %} 5543 ins_encode %{ 5544 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 5545 %} 5546 ins_pipe(pipe_slow); // XXX 5547 %} 5548 5549 instruct cacheWB(indirect addr) 5550 %{ 5551 predicate(VM_Version::supports_data_cache_line_flush()); 5552 match(CacheWB addr); 5553 5554 ins_cost(100); 5555 format %{"cache wb $addr" %} 5556 ins_encode %{ 5557 assert($addr->index_position() < 0, "should be"); 5558 assert($addr$$disp == 0, "should be"); 5559 __ cache_wb(Address($addr$$base$$Register, 0)); 5560 %} 5561 ins_pipe(pipe_slow); // XXX 5562 %} 5563 5564 instruct cacheWBPreSync() 5565 %{ 5566 predicate(VM_Version::supports_data_cache_line_flush()); 5567 match(CacheWBPreSync); 5568 5569 ins_cost(100); 5570 format %{"cache wb presync" %} 5571 ins_encode %{ 5572 __ cache_wbsync(true); 5573 %} 5574 ins_pipe(pipe_slow); // XXX 5575 %} 5576 5577 instruct cacheWBPostSync() 5578 %{ 5579 predicate(VM_Version::supports_data_cache_line_flush()); 5580 match(CacheWBPostSync); 5581 5582 ins_cost(100); 5583 format %{"cache wb postsync" %} 5584 ins_encode %{ 5585 __ cache_wbsync(false); 5586 %} 5587 ins_pipe(pipe_slow); // XXX 5588 %} 5589 5590 //----------BSWAP Instructions------------------------------------------------- 5591 instruct bytes_reverse_int(rRegI dst) %{ 5592 match(Set dst (ReverseBytesI dst)); 5593 5594 format %{ "bswapl $dst" %} 5595 ins_encode %{ 5596 __ bswapl($dst$$Register); 5597 %} 5598 ins_pipe( ialu_reg ); 5599 %} 5600 5601 instruct bytes_reverse_long(rRegL dst) %{ 5602 match(Set dst (ReverseBytesL dst)); 5603 5604 format %{ "bswapq $dst" %} 5605 ins_encode %{ 5606 __ bswapq($dst$$Register); 5607 %} 5608 ins_pipe( ialu_reg); 5609 %} 5610 5611 instruct bytes_reverse_unsigned_short(rRegI dst, rFlagsReg cr) %{ 5612 match(Set dst (ReverseBytesUS dst)); 5613 effect(KILL cr); 5614 5615 format %{ "bswapl $dst\n\t" 5616 "shrl $dst,16\n\t" %} 5617 ins_encode %{ 5618 __ bswapl($dst$$Register); 5619 __ shrl($dst$$Register, 16); 5620 %} 5621 ins_pipe( ialu_reg ); 5622 %} 5623 5624 instruct bytes_reverse_short(rRegI dst, rFlagsReg cr) %{ 5625 match(Set dst (ReverseBytesS dst)); 5626 effect(KILL cr); 5627 5628 format %{ "bswapl $dst\n\t" 5629 "sar $dst,16\n\t" %} 5630 ins_encode %{ 5631 __ bswapl($dst$$Register); 5632 __ sarl($dst$$Register, 16); 5633 %} 5634 ins_pipe( ialu_reg ); 5635 %} 5636 5637 //---------- Zeros Count Instructions ------------------------------------------ 5638 5639 instruct countLeadingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 5640 predicate(UseCountLeadingZerosInstruction); 5641 match(Set dst (CountLeadingZerosI src)); 5642 effect(KILL cr); 5643 5644 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 5645 ins_encode %{ 5646 __ lzcntl($dst$$Register, $src$$Register); 5647 %} 5648 ins_pipe(ialu_reg); 5649 %} 5650 5651 instruct countLeadingZerosI_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5652 predicate(UseCountLeadingZerosInstruction); 5653 match(Set dst (CountLeadingZerosI (LoadI src))); 5654 effect(KILL cr); 5655 ins_cost(175); 5656 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 5657 ins_encode %{ 5658 __ lzcntl($dst$$Register, $src$$Address); 5659 %} 5660 ins_pipe(ialu_reg_mem); 5661 %} 5662 5663 instruct countLeadingZerosI_bsr(rRegI dst, rRegI src, rFlagsReg cr) %{ 5664 predicate(!UseCountLeadingZerosInstruction); 5665 match(Set dst (CountLeadingZerosI src)); 5666 effect(KILL cr); 5667 5668 format %{ "bsrl $dst, $src\t# count leading zeros (int)\n\t" 5669 "jnz skip\n\t" 5670 "movl $dst, -1\n" 5671 "skip:\n\t" 5672 "negl $dst\n\t" 5673 "addl $dst, 31" %} 5674 ins_encode %{ 5675 Register Rdst = $dst$$Register; 5676 Register Rsrc = $src$$Register; 5677 Label skip; 5678 __ bsrl(Rdst, Rsrc); 5679 __ jccb(Assembler::notZero, skip); 5680 __ movl(Rdst, -1); 5681 __ bind(skip); 5682 __ negl(Rdst); 5683 __ addl(Rdst, BitsPerInt - 1); 5684 %} 5685 ins_pipe(ialu_reg); 5686 %} 5687 5688 instruct countLeadingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 5689 predicate(UseCountLeadingZerosInstruction); 5690 match(Set dst (CountLeadingZerosL src)); 5691 effect(KILL cr); 5692 5693 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 5694 ins_encode %{ 5695 __ lzcntq($dst$$Register, $src$$Register); 5696 %} 5697 ins_pipe(ialu_reg); 5698 %} 5699 5700 instruct countLeadingZerosL_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5701 predicate(UseCountLeadingZerosInstruction); 5702 match(Set dst (CountLeadingZerosL (LoadL src))); 5703 effect(KILL cr); 5704 ins_cost(175); 5705 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 5706 ins_encode %{ 5707 __ lzcntq($dst$$Register, $src$$Address); 5708 %} 5709 ins_pipe(ialu_reg_mem); 5710 %} 5711 5712 instruct countLeadingZerosL_bsr(rRegI dst, rRegL src, rFlagsReg cr) %{ 5713 predicate(!UseCountLeadingZerosInstruction); 5714 match(Set dst (CountLeadingZerosL src)); 5715 effect(KILL cr); 5716 5717 format %{ "bsrq $dst, $src\t# count leading zeros (long)\n\t" 5718 "jnz skip\n\t" 5719 "movl $dst, -1\n" 5720 "skip:\n\t" 5721 "negl $dst\n\t" 5722 "addl $dst, 63" %} 5723 ins_encode %{ 5724 Register Rdst = $dst$$Register; 5725 Register Rsrc = $src$$Register; 5726 Label skip; 5727 __ bsrq(Rdst, Rsrc); 5728 __ jccb(Assembler::notZero, skip); 5729 __ movl(Rdst, -1); 5730 __ bind(skip); 5731 __ negl(Rdst); 5732 __ addl(Rdst, BitsPerLong - 1); 5733 %} 5734 ins_pipe(ialu_reg); 5735 %} 5736 5737 instruct countTrailingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 5738 predicate(UseCountTrailingZerosInstruction); 5739 match(Set dst (CountTrailingZerosI src)); 5740 effect(KILL cr); 5741 5742 format %{ "tzcntl $dst, $src\t# count trailing zeros (int)" %} 5743 ins_encode %{ 5744 __ tzcntl($dst$$Register, $src$$Register); 5745 %} 5746 ins_pipe(ialu_reg); 5747 %} 5748 5749 instruct countTrailingZerosI_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5750 predicate(UseCountTrailingZerosInstruction); 5751 match(Set dst (CountTrailingZerosI (LoadI src))); 5752 effect(KILL cr); 5753 ins_cost(175); 5754 format %{ "tzcntl $dst, $src\t# count trailing zeros (int)" %} 5755 ins_encode %{ 5756 __ tzcntl($dst$$Register, $src$$Address); 5757 %} 5758 ins_pipe(ialu_reg_mem); 5759 %} 5760 5761 instruct countTrailingZerosI_bsf(rRegI dst, rRegI src, rFlagsReg cr) %{ 5762 predicate(!UseCountTrailingZerosInstruction); 5763 match(Set dst (CountTrailingZerosI src)); 5764 effect(KILL cr); 5765 5766 format %{ "bsfl $dst, $src\t# count trailing zeros (int)\n\t" 5767 "jnz done\n\t" 5768 "movl $dst, 32\n" 5769 "done:" %} 5770 ins_encode %{ 5771 Register Rdst = $dst$$Register; 5772 Label done; 5773 __ bsfl(Rdst, $src$$Register); 5774 __ jccb(Assembler::notZero, done); 5775 __ movl(Rdst, BitsPerInt); 5776 __ bind(done); 5777 %} 5778 ins_pipe(ialu_reg); 5779 %} 5780 5781 instruct countTrailingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 5782 predicate(UseCountTrailingZerosInstruction); 5783 match(Set dst (CountTrailingZerosL src)); 5784 effect(KILL cr); 5785 5786 format %{ "tzcntq $dst, $src\t# count trailing zeros (long)" %} 5787 ins_encode %{ 5788 __ tzcntq($dst$$Register, $src$$Register); 5789 %} 5790 ins_pipe(ialu_reg); 5791 %} 5792 5793 instruct countTrailingZerosL_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5794 predicate(UseCountTrailingZerosInstruction); 5795 match(Set dst (CountTrailingZerosL (LoadL src))); 5796 effect(KILL cr); 5797 ins_cost(175); 5798 format %{ "tzcntq $dst, $src\t# count trailing zeros (long)" %} 5799 ins_encode %{ 5800 __ tzcntq($dst$$Register, $src$$Address); 5801 %} 5802 ins_pipe(ialu_reg_mem); 5803 %} 5804 5805 instruct countTrailingZerosL_bsf(rRegI dst, rRegL src, rFlagsReg cr) %{ 5806 predicate(!UseCountTrailingZerosInstruction); 5807 match(Set dst (CountTrailingZerosL src)); 5808 effect(KILL cr); 5809 5810 format %{ "bsfq $dst, $src\t# count trailing zeros (long)\n\t" 5811 "jnz done\n\t" 5812 "movl $dst, 64\n" 5813 "done:" %} 5814 ins_encode %{ 5815 Register Rdst = $dst$$Register; 5816 Label done; 5817 __ bsfq(Rdst, $src$$Register); 5818 __ jccb(Assembler::notZero, done); 5819 __ movl(Rdst, BitsPerLong); 5820 __ bind(done); 5821 %} 5822 ins_pipe(ialu_reg); 5823 %} 5824 5825 //--------------- Reverse Operation Instructions ---------------- 5826 instruct bytes_reversebit_int(rRegI dst, rRegI src, rRegI rtmp, rFlagsReg cr) %{ 5827 predicate(!VM_Version::supports_gfni()); 5828 match(Set dst (ReverseI src)); 5829 effect(TEMP dst, TEMP rtmp, KILL cr); 5830 format %{ "reverse_int $dst $src\t! using $rtmp as TEMP" %} 5831 ins_encode %{ 5832 __ reverseI($dst$$Register, $src$$Register, xnoreg, xnoreg, $rtmp$$Register); 5833 %} 5834 ins_pipe( ialu_reg ); 5835 %} 5836 5837 instruct bytes_reversebit_int_gfni(rRegI dst, rRegI src, vlRegF xtmp1, vlRegF xtmp2, rRegL rtmp, rFlagsReg cr) %{ 5838 predicate(VM_Version::supports_gfni()); 5839 match(Set dst (ReverseI src)); 5840 effect(TEMP dst, TEMP xtmp1, TEMP xtmp2, TEMP rtmp, KILL cr); 5841 format %{ "reverse_int $dst $src\t! using $rtmp, $xtmp1 and $xtmp2 as TEMP" %} 5842 ins_encode %{ 5843 __ reverseI($dst$$Register, $src$$Register, $xtmp1$$XMMRegister, $xtmp2$$XMMRegister, $rtmp$$Register); 5844 %} 5845 ins_pipe( ialu_reg ); 5846 %} 5847 5848 instruct bytes_reversebit_long(rRegL dst, rRegL src, rRegL rtmp1, rRegL rtmp2, rFlagsReg cr) %{ 5849 predicate(!VM_Version::supports_gfni()); 5850 match(Set dst (ReverseL src)); 5851 effect(TEMP dst, TEMP rtmp1, TEMP rtmp2, KILL cr); 5852 format %{ "reverse_long $dst $src\t! using $rtmp1 and $rtmp2 as TEMP" %} 5853 ins_encode %{ 5854 __ reverseL($dst$$Register, $src$$Register, xnoreg, xnoreg, $rtmp1$$Register, $rtmp2$$Register); 5855 %} 5856 ins_pipe( ialu_reg ); 5857 %} 5858 5859 instruct bytes_reversebit_long_gfni(rRegL dst, rRegL src, vlRegD xtmp1, vlRegD xtmp2, rRegL rtmp, rFlagsReg cr) %{ 5860 predicate(VM_Version::supports_gfni()); 5861 match(Set dst (ReverseL src)); 5862 effect(TEMP dst, TEMP xtmp1, TEMP xtmp2, TEMP rtmp, KILL cr); 5863 format %{ "reverse_long $dst $src\t! using $rtmp, $xtmp1 and $xtmp2 as TEMP" %} 5864 ins_encode %{ 5865 __ reverseL($dst$$Register, $src$$Register, $xtmp1$$XMMRegister, $xtmp2$$XMMRegister, $rtmp$$Register, noreg); 5866 %} 5867 ins_pipe( ialu_reg ); 5868 %} 5869 5870 //---------- Population Count Instructions ------------------------------------- 5871 5872 instruct popCountI(rRegI dst, rRegI src, rFlagsReg cr) %{ 5873 predicate(UsePopCountInstruction); 5874 match(Set dst (PopCountI src)); 5875 effect(KILL cr); 5876 5877 format %{ "popcnt $dst, $src" %} 5878 ins_encode %{ 5879 __ popcntl($dst$$Register, $src$$Register); 5880 %} 5881 ins_pipe(ialu_reg); 5882 %} 5883 5884 instruct popCountI_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 5885 predicate(UsePopCountInstruction); 5886 match(Set dst (PopCountI (LoadI mem))); 5887 effect(KILL cr); 5888 5889 format %{ "popcnt $dst, $mem" %} 5890 ins_encode %{ 5891 __ popcntl($dst$$Register, $mem$$Address); 5892 %} 5893 ins_pipe(ialu_reg); 5894 %} 5895 5896 // Note: Long.bitCount(long) returns an int. 5897 instruct popCountL(rRegI dst, rRegL src, rFlagsReg cr) %{ 5898 predicate(UsePopCountInstruction); 5899 match(Set dst (PopCountL src)); 5900 effect(KILL cr); 5901 5902 format %{ "popcnt $dst, $src" %} 5903 ins_encode %{ 5904 __ popcntq($dst$$Register, $src$$Register); 5905 %} 5906 ins_pipe(ialu_reg); 5907 %} 5908 5909 // Note: Long.bitCount(long) returns an int. 5910 instruct popCountL_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 5911 predicate(UsePopCountInstruction); 5912 match(Set dst (PopCountL (LoadL mem))); 5913 effect(KILL cr); 5914 5915 format %{ "popcnt $dst, $mem" %} 5916 ins_encode %{ 5917 __ popcntq($dst$$Register, $mem$$Address); 5918 %} 5919 ins_pipe(ialu_reg); 5920 %} 5921 5922 5923 //----------MemBar Instructions----------------------------------------------- 5924 // Memory barrier flavors 5925 5926 instruct membar_acquire() 5927 %{ 5928 match(MemBarAcquire); 5929 match(LoadFence); 5930 ins_cost(0); 5931 5932 size(0); 5933 format %{ "MEMBAR-acquire ! (empty encoding)" %} 5934 ins_encode(); 5935 ins_pipe(empty); 5936 %} 5937 5938 instruct membar_acquire_lock() 5939 %{ 5940 match(MemBarAcquireLock); 5941 ins_cost(0); 5942 5943 size(0); 5944 format %{ "MEMBAR-acquire (prior CMPXCHG in FastLock so empty encoding)" %} 5945 ins_encode(); 5946 ins_pipe(empty); 5947 %} 5948 5949 instruct membar_release() 5950 %{ 5951 match(MemBarRelease); 5952 match(StoreFence); 5953 ins_cost(0); 5954 5955 size(0); 5956 format %{ "MEMBAR-release ! (empty encoding)" %} 5957 ins_encode(); 5958 ins_pipe(empty); 5959 %} 5960 5961 instruct membar_release_lock() 5962 %{ 5963 match(MemBarReleaseLock); 5964 ins_cost(0); 5965 5966 size(0); 5967 format %{ "MEMBAR-release (a FastUnlock follows so empty encoding)" %} 5968 ins_encode(); 5969 ins_pipe(empty); 5970 %} 5971 5972 instruct membar_volatile(rFlagsReg cr) %{ 5973 match(MemBarVolatile); 5974 effect(KILL cr); 5975 ins_cost(400); 5976 5977 format %{ 5978 $$template 5979 $$emit$$"lock addl [rsp + #0], 0\t! membar_volatile" 5980 %} 5981 ins_encode %{ 5982 __ membar(Assembler::StoreLoad); 5983 %} 5984 ins_pipe(pipe_slow); 5985 %} 5986 5987 instruct unnecessary_membar_volatile() 5988 %{ 5989 match(MemBarVolatile); 5990 predicate(Matcher::post_store_load_barrier(n)); 5991 ins_cost(0); 5992 5993 size(0); 5994 format %{ "MEMBAR-volatile (unnecessary so empty encoding)" %} 5995 ins_encode(); 5996 ins_pipe(empty); 5997 %} 5998 5999 instruct membar_storestore() %{ 6000 match(MemBarStoreStore); 6001 match(StoreStoreFence); 6002 ins_cost(0); 6003 6004 size(0); 6005 format %{ "MEMBAR-storestore (empty encoding)" %} 6006 ins_encode( ); 6007 ins_pipe(empty); 6008 %} 6009 6010 //----------Move Instructions-------------------------------------------------- 6011 6012 instruct castX2P(rRegP dst, rRegL src) 6013 %{ 6014 match(Set dst (CastX2P src)); 6015 6016 format %{ "movq $dst, $src\t# long->ptr" %} 6017 ins_encode %{ 6018 if ($dst$$reg != $src$$reg) { 6019 __ movptr($dst$$Register, $src$$Register); 6020 } 6021 %} 6022 ins_pipe(ialu_reg_reg); // XXX 6023 %} 6024 6025 instruct castP2X(rRegL dst, rRegP src) 6026 %{ 6027 match(Set dst (CastP2X src)); 6028 6029 format %{ "movq $dst, $src\t# ptr -> long" %} 6030 ins_encode %{ 6031 if ($dst$$reg != $src$$reg) { 6032 __ movptr($dst$$Register, $src$$Register); 6033 } 6034 %} 6035 ins_pipe(ialu_reg_reg); // XXX 6036 %} 6037 6038 // Convert oop into int for vectors alignment masking 6039 instruct convP2I(rRegI dst, rRegP src) 6040 %{ 6041 match(Set dst (ConvL2I (CastP2X src))); 6042 6043 format %{ "movl $dst, $src\t# ptr -> int" %} 6044 ins_encode %{ 6045 __ movl($dst$$Register, $src$$Register); 6046 %} 6047 ins_pipe(ialu_reg_reg); // XXX 6048 %} 6049 6050 // Convert compressed oop into int for vectors alignment masking 6051 // in case of 32bit oops (heap < 4Gb). 6052 instruct convN2I(rRegI dst, rRegN src) 6053 %{ 6054 predicate(CompressedOops::shift() == 0); 6055 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 6056 6057 format %{ "movl $dst, $src\t# compressed ptr -> int" %} 6058 ins_encode %{ 6059 __ movl($dst$$Register, $src$$Register); 6060 %} 6061 ins_pipe(ialu_reg_reg); // XXX 6062 %} 6063 6064 // Convert oop pointer into compressed form 6065 instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{ 6066 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 6067 match(Set dst (EncodeP src)); 6068 effect(KILL cr); 6069 format %{ "encode_heap_oop $dst,$src" %} 6070 ins_encode %{ 6071 Register s = $src$$Register; 6072 Register d = $dst$$Register; 6073 if (s != d) { 6074 __ movq(d, s); 6075 } 6076 __ encode_heap_oop(d); 6077 %} 6078 ins_pipe(ialu_reg_long); 6079 %} 6080 6081 instruct encodeHeapOop_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6082 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 6083 match(Set dst (EncodeP src)); 6084 effect(KILL cr); 6085 format %{ "encode_heap_oop_not_null $dst,$src" %} 6086 ins_encode %{ 6087 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 6088 %} 6089 ins_pipe(ialu_reg_long); 6090 %} 6091 6092 instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{ 6093 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 6094 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 6095 match(Set dst (DecodeN src)); 6096 effect(KILL cr); 6097 format %{ "decode_heap_oop $dst,$src" %} 6098 ins_encode %{ 6099 Register s = $src$$Register; 6100 Register d = $dst$$Register; 6101 if (s != d) { 6102 __ movq(d, s); 6103 } 6104 __ decode_heap_oop(d); 6105 %} 6106 ins_pipe(ialu_reg_long); 6107 %} 6108 6109 instruct decodeHeapOop_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6110 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 6111 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 6112 match(Set dst (DecodeN src)); 6113 effect(KILL cr); 6114 format %{ "decode_heap_oop_not_null $dst,$src" %} 6115 ins_encode %{ 6116 Register s = $src$$Register; 6117 Register d = $dst$$Register; 6118 if (s != d) { 6119 __ decode_heap_oop_not_null(d, s); 6120 } else { 6121 __ decode_heap_oop_not_null(d); 6122 } 6123 %} 6124 ins_pipe(ialu_reg_long); 6125 %} 6126 6127 instruct encodeKlass_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6128 match(Set dst (EncodePKlass src)); 6129 effect(TEMP dst, KILL cr); 6130 format %{ "encode_and_move_klass_not_null $dst,$src" %} 6131 ins_encode %{ 6132 __ encode_and_move_klass_not_null($dst$$Register, $src$$Register); 6133 %} 6134 ins_pipe(ialu_reg_long); 6135 %} 6136 6137 instruct decodeKlass_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6138 match(Set dst (DecodeNKlass src)); 6139 effect(TEMP dst, KILL cr); 6140 format %{ "decode_and_move_klass_not_null $dst,$src" %} 6141 ins_encode %{ 6142 __ decode_and_move_klass_not_null($dst$$Register, $src$$Register); 6143 %} 6144 ins_pipe(ialu_reg_long); 6145 %} 6146 6147 //----------Conditional Move--------------------------------------------------- 6148 // Jump 6149 // dummy instruction for generating temp registers 6150 instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{ 6151 match(Jump (LShiftL switch_val shift)); 6152 ins_cost(350); 6153 predicate(false); 6154 effect(TEMP dest); 6155 6156 format %{ "leaq $dest, [$constantaddress]\n\t" 6157 "jmp [$dest + $switch_val << $shift]\n\t" %} 6158 ins_encode %{ 6159 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6160 // to do that and the compiler is using that register as one it can allocate. 6161 // So we build it all by hand. 6162 // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant); 6163 // ArrayAddress dispatch(table, index); 6164 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant); 6165 __ lea($dest$$Register, $constantaddress); 6166 __ jmp(dispatch); 6167 %} 6168 ins_pipe(pipe_jmp); 6169 %} 6170 6171 instruct jumpXtnd_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{ 6172 match(Jump (AddL (LShiftL switch_val shift) offset)); 6173 ins_cost(350); 6174 effect(TEMP dest); 6175 6176 format %{ "leaq $dest, [$constantaddress]\n\t" 6177 "jmp [$dest + $switch_val << $shift + $offset]\n\t" %} 6178 ins_encode %{ 6179 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6180 // to do that and the compiler is using that register as one it can allocate. 6181 // So we build it all by hand. 6182 // Address index(noreg, switch_reg, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6183 // ArrayAddress dispatch(table, index); 6184 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6185 __ lea($dest$$Register, $constantaddress); 6186 __ jmp(dispatch); 6187 %} 6188 ins_pipe(pipe_jmp); 6189 %} 6190 6191 instruct jumpXtnd(rRegL switch_val, rRegI dest) %{ 6192 match(Jump switch_val); 6193 ins_cost(350); 6194 effect(TEMP dest); 6195 6196 format %{ "leaq $dest, [$constantaddress]\n\t" 6197 "jmp [$dest + $switch_val]\n\t" %} 6198 ins_encode %{ 6199 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6200 // to do that and the compiler is using that register as one it can allocate. 6201 // So we build it all by hand. 6202 // Address index(noreg, switch_reg, Address::times_1); 6203 // ArrayAddress dispatch(table, index); 6204 Address dispatch($dest$$Register, $switch_val$$Register, Address::times_1); 6205 __ lea($dest$$Register, $constantaddress); 6206 __ jmp(dispatch); 6207 %} 6208 ins_pipe(pipe_jmp); 6209 %} 6210 6211 // Conditional move 6212 instruct cmovI_imm_01(rRegI dst, immI_1 src, rFlagsReg cr, cmpOp cop) 6213 %{ 6214 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_int() == 0); 6215 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6216 6217 ins_cost(100); // XXX 6218 format %{ "setbn$cop $dst\t# signed, int" %} 6219 ins_encode %{ 6220 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6221 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6222 %} 6223 ins_pipe(ialu_reg); 6224 %} 6225 6226 instruct cmovI_reg(rRegI dst, rRegI src, rFlagsReg cr, cmpOp cop) 6227 %{ 6228 predicate(!UseAPX); 6229 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6230 6231 ins_cost(200); // XXX 6232 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6233 ins_encode %{ 6234 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6235 %} 6236 ins_pipe(pipe_cmov_reg); 6237 %} 6238 6239 instruct cmovI_reg_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr, cmpOp cop) 6240 %{ 6241 predicate(UseAPX); 6242 match(Set dst (CMoveI (Binary cop cr) (Binary src1 src2))); 6243 6244 ins_cost(200); 6245 format %{ "ecmovl$cop $dst, $src1, $src2\t# signed, int ndd" %} 6246 ins_encode %{ 6247 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6248 %} 6249 ins_pipe(pipe_cmov_reg); 6250 %} 6251 6252 instruct cmovI_imm_01U(rRegI dst, immI_1 src, rFlagsRegU cr, cmpOpU cop) 6253 %{ 6254 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_int() == 0); 6255 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6256 6257 ins_cost(100); // XXX 6258 format %{ "setbn$cop $dst\t# unsigned, int" %} 6259 ins_encode %{ 6260 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6261 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6262 %} 6263 ins_pipe(ialu_reg); 6264 %} 6265 6266 instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{ 6267 predicate(!UseAPX); 6268 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6269 6270 ins_cost(200); // XXX 6271 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6272 ins_encode %{ 6273 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6274 %} 6275 ins_pipe(pipe_cmov_reg); 6276 %} 6277 6278 instruct cmovI_regU_ndd(rRegI dst, cmpOpU cop, rFlagsRegU cr, rRegI src1, rRegI src2) %{ 6279 predicate(UseAPX); 6280 match(Set dst (CMoveI (Binary cop cr) (Binary src1 src2))); 6281 6282 ins_cost(200); 6283 format %{ "ecmovl$cop $dst, $src1, $src2\t# unsigned, int ndd" %} 6284 ins_encode %{ 6285 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6286 %} 6287 ins_pipe(pipe_cmov_reg); 6288 %} 6289 6290 instruct cmovI_imm_01UCF(rRegI dst, immI_1 src, rFlagsRegUCF cr, cmpOpUCF cop) 6291 %{ 6292 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_int() == 0); 6293 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6294 6295 ins_cost(100); // XXX 6296 format %{ "setbn$cop $dst\t# unsigned, int" %} 6297 ins_encode %{ 6298 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6299 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6300 %} 6301 ins_pipe(ialu_reg); 6302 %} 6303 6304 instruct cmovI_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6305 predicate(!UseAPX); 6306 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6307 ins_cost(200); 6308 expand %{ 6309 cmovI_regU(cop, cr, dst, src); 6310 %} 6311 %} 6312 6313 instruct cmovI_regUCF_ndd(rRegI dst, cmpOpUCF cop, rFlagsRegUCF cr, rRegI src1, rRegI src2) %{ 6314 predicate(UseAPX); 6315 match(Set dst (CMoveI (Binary cop cr) (Binary src1 src2))); 6316 ins_cost(200); 6317 format %{ "ecmovl$cop $dst, $src1, $src2\t# unsigned, int ndd" %} 6318 ins_encode %{ 6319 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6320 %} 6321 ins_pipe(pipe_cmov_reg); 6322 %} 6323 6324 instruct cmovI_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6325 predicate(!UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6326 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6327 6328 ins_cost(200); // XXX 6329 format %{ "cmovpl $dst, $src\n\t" 6330 "cmovnel $dst, $src" %} 6331 ins_encode %{ 6332 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6333 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6334 %} 6335 ins_pipe(pipe_cmov_reg); 6336 %} 6337 6338 instruct cmovI_regUCF2_ne_ndd(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegI dst, rRegI src1, rRegI src2) %{ 6339 predicate(UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6340 match(Set dst (CMoveI (Binary cop cr) (Binary src1 src2))); 6341 effect(TEMP dst); 6342 6343 ins_cost(200); 6344 format %{ "ecmovpl $dst, $src1, $src2\n\t" 6345 "cmovnel $dst, $src2" %} 6346 ins_encode %{ 6347 __ ecmovl(Assembler::parity, $dst$$Register, $src1$$Register, $src2$$Register); 6348 __ cmovl(Assembler::notEqual, $dst$$Register, $src2$$Register); 6349 %} 6350 ins_pipe(pipe_cmov_reg); 6351 %} 6352 6353 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6354 // inputs of the CMove 6355 instruct cmovI_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6356 predicate(!UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6357 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6358 effect(TEMP dst); 6359 6360 ins_cost(200); // XXX 6361 format %{ "cmovpl $dst, $src\n\t" 6362 "cmovnel $dst, $src" %} 6363 ins_encode %{ 6364 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6365 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6366 %} 6367 ins_pipe(pipe_cmov_reg); 6368 %} 6369 6370 // We need this special handling for only eq / neq comparison since NaN == NaN is false, 6371 // and parity flag bit is set if any of the operand is a NaN. 6372 instruct cmovI_regUCF2_eq_ndd(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegI dst, rRegI src1, rRegI src2) %{ 6373 predicate(UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6374 match(Set dst (CMoveI (Binary cop cr) (Binary src2 src1))); 6375 effect(TEMP dst); 6376 6377 ins_cost(200); 6378 format %{ "ecmovpl $dst, $src1, $src2\n\t" 6379 "cmovnel $dst, $src2" %} 6380 ins_encode %{ 6381 __ ecmovl(Assembler::parity, $dst$$Register, $src1$$Register, $src2$$Register); 6382 __ cmovl(Assembler::notEqual, $dst$$Register, $src2$$Register); 6383 %} 6384 ins_pipe(pipe_cmov_reg); 6385 %} 6386 6387 // Conditional move 6388 instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{ 6389 predicate(!UseAPX); 6390 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6391 6392 ins_cost(250); // XXX 6393 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6394 ins_encode %{ 6395 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6396 %} 6397 ins_pipe(pipe_cmov_mem); 6398 %} 6399 6400 // Conditional move 6401 instruct cmovI_rReg_rReg_mem_ndd(rRegI dst, cmpOp cop, rFlagsReg cr, rRegI src1, memory src2) 6402 %{ 6403 predicate(UseAPX); 6404 match(Set dst (CMoveI (Binary cop cr) (Binary src1 (LoadI src2)))); 6405 6406 ins_cost(250); 6407 format %{ "ecmovl$cop $dst, $src1, $src2\t# signed, int ndd" %} 6408 ins_encode %{ 6409 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Address); 6410 %} 6411 ins_pipe(pipe_cmov_mem); 6412 %} 6413 6414 // Conditional move 6415 instruct cmovI_memU(cmpOpU cop, rFlagsRegU cr, rRegI dst, memory src) 6416 %{ 6417 predicate(!UseAPX); 6418 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6419 6420 ins_cost(250); // XXX 6421 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6422 ins_encode %{ 6423 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6424 %} 6425 ins_pipe(pipe_cmov_mem); 6426 %} 6427 6428 instruct cmovI_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, memory src) %{ 6429 predicate(!UseAPX); 6430 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6431 ins_cost(250); 6432 expand %{ 6433 cmovI_memU(cop, cr, dst, src); 6434 %} 6435 %} 6436 6437 instruct cmovI_rReg_rReg_memU_ndd(rRegI dst, cmpOpU cop, rFlagsRegU cr, rRegI src1, memory src2) 6438 %{ 6439 predicate(UseAPX); 6440 match(Set dst (CMoveI (Binary cop cr) (Binary src1 (LoadI src2)))); 6441 6442 ins_cost(250); 6443 format %{ "ecmovl$cop $dst, $src1, $src2\t# unsigned, int ndd" %} 6444 ins_encode %{ 6445 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Address); 6446 %} 6447 ins_pipe(pipe_cmov_mem); 6448 %} 6449 6450 instruct cmovI_rReg_rReg_memUCF_ndd(rRegI dst, cmpOpUCF cop, rFlagsRegUCF cr, rRegI src1, memory src2) 6451 %{ 6452 predicate(UseAPX); 6453 match(Set dst (CMoveI (Binary cop cr) (Binary src1 (LoadI src2)))); 6454 ins_cost(250); 6455 format %{ "ecmovl$cop $dst, $src1, $src2\t# unsigned, int ndd" %} 6456 ins_encode %{ 6457 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Address); 6458 %} 6459 ins_pipe(pipe_cmov_mem); 6460 %} 6461 6462 // Conditional move 6463 instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop) 6464 %{ 6465 predicate(!UseAPX); 6466 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6467 6468 ins_cost(200); // XXX 6469 format %{ "cmovl$cop $dst, $src\t# signed, compressed ptr" %} 6470 ins_encode %{ 6471 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6472 %} 6473 ins_pipe(pipe_cmov_reg); 6474 %} 6475 6476 // Conditional move ndd 6477 instruct cmovN_reg_ndd(rRegN dst, rRegN src1, rRegN src2, rFlagsReg cr, cmpOp cop) 6478 %{ 6479 predicate(UseAPX); 6480 match(Set dst (CMoveN (Binary cop cr) (Binary src1 src2))); 6481 6482 ins_cost(200); 6483 format %{ "ecmovl$cop $dst, $src1, $src2\t# signed, compressed ptr ndd" %} 6484 ins_encode %{ 6485 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6486 %} 6487 ins_pipe(pipe_cmov_reg); 6488 %} 6489 6490 // Conditional move 6491 instruct cmovN_regU(cmpOpU cop, rFlagsRegU cr, rRegN dst, rRegN src) 6492 %{ 6493 predicate(!UseAPX); 6494 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6495 6496 ins_cost(200); // XXX 6497 format %{ "cmovl$cop $dst, $src\t# unsigned, compressed ptr" %} 6498 ins_encode %{ 6499 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6500 %} 6501 ins_pipe(pipe_cmov_reg); 6502 %} 6503 6504 instruct cmovN_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6505 predicate(!UseAPX); 6506 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6507 ins_cost(200); 6508 expand %{ 6509 cmovN_regU(cop, cr, dst, src); 6510 %} 6511 %} 6512 6513 // Conditional move ndd 6514 instruct cmovN_regU_ndd(rRegN dst, cmpOpU cop, rFlagsRegU cr, rRegN src1, rRegN src2) 6515 %{ 6516 predicate(UseAPX); 6517 match(Set dst (CMoveN (Binary cop cr) (Binary src1 src2))); 6518 6519 ins_cost(200); 6520 format %{ "ecmovl$cop $dst, $src1, $src2\t# unsigned, compressed ptr ndd" %} 6521 ins_encode %{ 6522 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6523 %} 6524 ins_pipe(pipe_cmov_reg); 6525 %} 6526 6527 instruct cmovN_regUCF_ndd(rRegN dst, cmpOpUCF cop, rFlagsRegUCF cr, rRegN src1, rRegN src2) %{ 6528 predicate(UseAPX); 6529 match(Set dst (CMoveN (Binary cop cr) (Binary src1 src2))); 6530 ins_cost(200); 6531 format %{ "ecmovl$cop $dst, $src1, $src2\t# unsigned, compressed ptr ndd" %} 6532 ins_encode %{ 6533 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6534 %} 6535 ins_pipe(pipe_cmov_reg); 6536 %} 6537 6538 instruct cmovN_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6539 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6540 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6541 6542 ins_cost(200); // XXX 6543 format %{ "cmovpl $dst, $src\n\t" 6544 "cmovnel $dst, $src" %} 6545 ins_encode %{ 6546 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6547 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6548 %} 6549 ins_pipe(pipe_cmov_reg); 6550 %} 6551 6552 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6553 // inputs of the CMove 6554 instruct cmovN_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6555 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6556 match(Set dst (CMoveN (Binary cop cr) (Binary src dst))); 6557 6558 ins_cost(200); // XXX 6559 format %{ "cmovpl $dst, $src\n\t" 6560 "cmovnel $dst, $src" %} 6561 ins_encode %{ 6562 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6563 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6564 %} 6565 ins_pipe(pipe_cmov_reg); 6566 %} 6567 6568 // Conditional move 6569 instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop) 6570 %{ 6571 predicate(!UseAPX); 6572 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6573 6574 ins_cost(200); // XXX 6575 format %{ "cmovq$cop $dst, $src\t# signed, ptr" %} 6576 ins_encode %{ 6577 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6578 %} 6579 ins_pipe(pipe_cmov_reg); // XXX 6580 %} 6581 6582 // Conditional move ndd 6583 instruct cmovP_reg_ndd(rRegP dst, rRegP src1, rRegP src2, rFlagsReg cr, cmpOp cop) 6584 %{ 6585 predicate(UseAPX); 6586 match(Set dst (CMoveP (Binary cop cr) (Binary src1 src2))); 6587 6588 ins_cost(200); 6589 format %{ "ecmovq$cop $dst, $src1, $src2\t# signed, ptr ndd" %} 6590 ins_encode %{ 6591 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6592 %} 6593 ins_pipe(pipe_cmov_reg); 6594 %} 6595 6596 // Conditional move 6597 instruct cmovP_regU(cmpOpU cop, rFlagsRegU cr, rRegP dst, rRegP src) 6598 %{ 6599 predicate(!UseAPX); 6600 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6601 6602 ins_cost(200); // XXX 6603 format %{ "cmovq$cop $dst, $src\t# unsigned, ptr" %} 6604 ins_encode %{ 6605 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6606 %} 6607 ins_pipe(pipe_cmov_reg); // XXX 6608 %} 6609 6610 // Conditional move ndd 6611 instruct cmovP_regU_ndd(rRegP dst, cmpOpU cop, rFlagsRegU cr, rRegP src1, rRegP src2) 6612 %{ 6613 predicate(UseAPX); 6614 match(Set dst (CMoveP (Binary cop cr) (Binary src1 src2))); 6615 6616 ins_cost(200); 6617 format %{ "ecmovq$cop $dst, $src1, $src2\t# unsigned, ptr ndd" %} 6618 ins_encode %{ 6619 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6620 %} 6621 ins_pipe(pipe_cmov_reg); 6622 %} 6623 6624 instruct cmovP_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6625 predicate(!UseAPX); 6626 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6627 ins_cost(200); 6628 expand %{ 6629 cmovP_regU(cop, cr, dst, src); 6630 %} 6631 %} 6632 6633 instruct cmovP_regUCF_ndd(rRegP dst, cmpOpUCF cop, rFlagsRegUCF cr, rRegP src1, rRegP src2) %{ 6634 predicate(UseAPX); 6635 match(Set dst (CMoveP (Binary cop cr) (Binary src1 src2))); 6636 ins_cost(200); 6637 format %{ "ecmovq$cop $dst, $src1, $src2\t# unsigned, ptr ndd" %} 6638 ins_encode %{ 6639 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6640 %} 6641 ins_pipe(pipe_cmov_reg); 6642 %} 6643 6644 instruct cmovP_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6645 predicate(!UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6646 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6647 6648 ins_cost(200); // XXX 6649 format %{ "cmovpq $dst, $src\n\t" 6650 "cmovneq $dst, $src" %} 6651 ins_encode %{ 6652 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6653 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6654 %} 6655 ins_pipe(pipe_cmov_reg); 6656 %} 6657 6658 instruct cmovP_regUCF2_ne_ndd(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegP dst, rRegP src1, rRegP src2) %{ 6659 predicate(UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6660 match(Set dst (CMoveP (Binary cop cr) (Binary src1 src2))); 6661 effect(TEMP dst); 6662 6663 ins_cost(200); 6664 format %{ "ecmovpq $dst, $src1, $src2\n\t" 6665 "cmovneq $dst, $src2" %} 6666 ins_encode %{ 6667 __ ecmovq(Assembler::parity, $dst$$Register, $src1$$Register, $src2$$Register); 6668 __ cmovq(Assembler::notEqual, $dst$$Register, $src2$$Register); 6669 %} 6670 ins_pipe(pipe_cmov_reg); 6671 %} 6672 6673 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6674 // inputs of the CMove 6675 instruct cmovP_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6676 predicate(!UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6677 match(Set dst (CMoveP (Binary cop cr) (Binary src dst))); 6678 6679 ins_cost(200); // XXX 6680 format %{ "cmovpq $dst, $src\n\t" 6681 "cmovneq $dst, $src" %} 6682 ins_encode %{ 6683 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6684 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6685 %} 6686 ins_pipe(pipe_cmov_reg); 6687 %} 6688 6689 instruct cmovP_regUCF2_eq_ndd(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegP dst, rRegP src1, rRegP src2) %{ 6690 predicate(UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6691 match(Set dst (CMoveP (Binary cop cr) (Binary src2 src1))); 6692 effect(TEMP dst); 6693 6694 ins_cost(200); 6695 format %{ "ecmovpq $dst, $src1, $src2\n\t" 6696 "cmovneq $dst, $src2" %} 6697 ins_encode %{ 6698 __ ecmovq(Assembler::parity, $dst$$Register, $src1$$Register, $src2$$Register); 6699 __ cmovq(Assembler::notEqual, $dst$$Register, $src2$$Register); 6700 %} 6701 ins_pipe(pipe_cmov_reg); 6702 %} 6703 6704 instruct cmovL_imm_01(rRegL dst, immL1 src, rFlagsReg cr, cmpOp cop) 6705 %{ 6706 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_long() == 0); 6707 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6708 6709 ins_cost(100); // XXX 6710 format %{ "setbn$cop $dst\t# signed, long" %} 6711 ins_encode %{ 6712 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6713 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6714 %} 6715 ins_pipe(ialu_reg); 6716 %} 6717 6718 instruct cmovL_reg(cmpOp cop, rFlagsReg cr, rRegL dst, rRegL src) 6719 %{ 6720 predicate(!UseAPX); 6721 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6722 6723 ins_cost(200); // XXX 6724 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6725 ins_encode %{ 6726 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6727 %} 6728 ins_pipe(pipe_cmov_reg); // XXX 6729 %} 6730 6731 instruct cmovL_reg_ndd(rRegL dst, cmpOp cop, rFlagsReg cr, rRegL src1, rRegL src2) 6732 %{ 6733 predicate(UseAPX); 6734 match(Set dst (CMoveL (Binary cop cr) (Binary src1 src2))); 6735 6736 ins_cost(200); 6737 format %{ "ecmovq$cop $dst, $src1, $src2\t# signed, long ndd" %} 6738 ins_encode %{ 6739 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6740 %} 6741 ins_pipe(pipe_cmov_reg); 6742 %} 6743 6744 instruct cmovL_mem(cmpOp cop, rFlagsReg cr, rRegL dst, memory src) 6745 %{ 6746 predicate(!UseAPX); 6747 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6748 6749 ins_cost(200); // XXX 6750 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6751 ins_encode %{ 6752 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6753 %} 6754 ins_pipe(pipe_cmov_mem); // XXX 6755 %} 6756 6757 instruct cmovL_rReg_rReg_mem_ndd(rRegL dst, cmpOp cop, rFlagsReg cr, rRegL src1, memory src2) 6758 %{ 6759 predicate(UseAPX); 6760 match(Set dst (CMoveL (Binary cop cr) (Binary src1 (LoadL src2)))); 6761 6762 ins_cost(200); 6763 format %{ "ecmovq$cop $dst, $src1, $src2\t# signed, long ndd" %} 6764 ins_encode %{ 6765 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Address); 6766 %} 6767 ins_pipe(pipe_cmov_mem); 6768 %} 6769 6770 instruct cmovL_imm_01U(rRegL dst, immL1 src, rFlagsRegU cr, cmpOpU cop) 6771 %{ 6772 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_long() == 0); 6773 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6774 6775 ins_cost(100); // XXX 6776 format %{ "setbn$cop $dst\t# unsigned, long" %} 6777 ins_encode %{ 6778 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6779 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6780 %} 6781 ins_pipe(ialu_reg); 6782 %} 6783 6784 instruct cmovL_regU(cmpOpU cop, rFlagsRegU cr, rRegL dst, rRegL src) 6785 %{ 6786 predicate(!UseAPX); 6787 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6788 6789 ins_cost(200); // XXX 6790 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 6791 ins_encode %{ 6792 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6793 %} 6794 ins_pipe(pipe_cmov_reg); // XXX 6795 %} 6796 6797 instruct cmovL_regU_ndd(rRegL dst, cmpOpU cop, rFlagsRegU cr, rRegL src1, rRegL src2) 6798 %{ 6799 predicate(UseAPX); 6800 match(Set dst (CMoveL (Binary cop cr) (Binary src1 src2))); 6801 6802 ins_cost(200); 6803 format %{ "ecmovq$cop $dst, $src1, $src2\t# unsigned, long ndd" %} 6804 ins_encode %{ 6805 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6806 %} 6807 ins_pipe(pipe_cmov_reg); 6808 %} 6809 6810 instruct cmovL_imm_01UCF(rRegL dst, immL1 src, rFlagsRegUCF cr, cmpOpUCF cop) 6811 %{ 6812 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_long() == 0); 6813 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6814 6815 ins_cost(100); // XXX 6816 format %{ "setbn$cop $dst\t# unsigned, long" %} 6817 ins_encode %{ 6818 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6819 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6820 %} 6821 ins_pipe(ialu_reg); 6822 %} 6823 6824 instruct cmovL_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6825 predicate(!UseAPX); 6826 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6827 ins_cost(200); 6828 expand %{ 6829 cmovL_regU(cop, cr, dst, src); 6830 %} 6831 %} 6832 6833 instruct cmovL_regUCF_ndd(rRegL dst, cmpOpUCF cop, rFlagsRegUCF cr, rRegL src1, rRegL src2) 6834 %{ 6835 predicate(UseAPX); 6836 match(Set dst (CMoveL (Binary cop cr) (Binary src1 src2))); 6837 ins_cost(200); 6838 format %{ "ecmovq$cop $dst, $src1, $src2\t# unsigned, long ndd" %} 6839 ins_encode %{ 6840 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6841 %} 6842 ins_pipe(pipe_cmov_reg); 6843 %} 6844 6845 instruct cmovL_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6846 predicate(!UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6847 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6848 6849 ins_cost(200); // XXX 6850 format %{ "cmovpq $dst, $src\n\t" 6851 "cmovneq $dst, $src" %} 6852 ins_encode %{ 6853 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6854 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6855 %} 6856 ins_pipe(pipe_cmov_reg); 6857 %} 6858 6859 instruct cmovL_regUCF2_ne_ndd(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegL dst, rRegL src1, rRegL src2) %{ 6860 predicate(UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6861 match(Set dst (CMoveL (Binary cop cr) (Binary src1 src2))); 6862 effect(TEMP dst); 6863 6864 ins_cost(200); 6865 format %{ "ecmovpq $dst, $src1, $src2\n\t" 6866 "cmovneq $dst, $src2" %} 6867 ins_encode %{ 6868 __ ecmovq(Assembler::parity, $dst$$Register, $src1$$Register, $src2$$Register); 6869 __ cmovq(Assembler::notEqual, $dst$$Register, $src2$$Register); 6870 %} 6871 ins_pipe(pipe_cmov_reg); 6872 %} 6873 6874 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6875 // inputs of the CMove 6876 instruct cmovL_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6877 predicate(!UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6878 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6879 6880 ins_cost(200); // XXX 6881 format %{ "cmovpq $dst, $src\n\t" 6882 "cmovneq $dst, $src" %} 6883 ins_encode %{ 6884 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6885 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6886 %} 6887 ins_pipe(pipe_cmov_reg); 6888 %} 6889 6890 instruct cmovL_regUCF2_eq_ndd(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegL dst, rRegL src1, rRegL src2) %{ 6891 predicate(UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6892 match(Set dst (CMoveL (Binary cop cr) (Binary src2 src1))); 6893 effect(TEMP dst); 6894 6895 ins_cost(200); 6896 format %{ "ecmovpq $dst, $src1, $src2\n\t" 6897 "cmovneq $dst, $src2" %} 6898 ins_encode %{ 6899 __ ecmovq(Assembler::parity, $dst$$Register, $src1$$Register, $src2$$Register); 6900 __ cmovq(Assembler::notEqual, $dst$$Register, $src2$$Register); 6901 %} 6902 ins_pipe(pipe_cmov_reg); 6903 %} 6904 6905 instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src) 6906 %{ 6907 predicate(!UseAPX); 6908 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6909 6910 ins_cost(200); // XXX 6911 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 6912 ins_encode %{ 6913 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6914 %} 6915 ins_pipe(pipe_cmov_mem); // XXX 6916 %} 6917 6918 instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{ 6919 predicate(!UseAPX); 6920 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6921 ins_cost(200); 6922 expand %{ 6923 cmovL_memU(cop, cr, dst, src); 6924 %} 6925 %} 6926 6927 instruct cmovL_rReg_rReg_memU_ndd(rRegL dst, cmpOpU cop, rFlagsRegU cr, rRegL src1, memory src2) 6928 %{ 6929 predicate(UseAPX); 6930 match(Set dst (CMoveL (Binary cop cr) (Binary src1 (LoadL src2)))); 6931 6932 ins_cost(200); 6933 format %{ "ecmovq$cop $dst, $src1, $src2\t# unsigned, long ndd" %} 6934 ins_encode %{ 6935 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Address); 6936 %} 6937 ins_pipe(pipe_cmov_mem); 6938 %} 6939 6940 instruct cmovL_rReg_rReg_memUCF_ndd(rRegL dst, cmpOpUCF cop, rFlagsRegUCF cr, rRegL src1, memory src2) 6941 %{ 6942 predicate(UseAPX); 6943 match(Set dst (CMoveL (Binary cop cr) (Binary src1 (LoadL src2)))); 6944 ins_cost(200); 6945 format %{ "ecmovq$cop $dst, $src1, $src2\t# unsigned, long ndd" %} 6946 ins_encode %{ 6947 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Address); 6948 %} 6949 ins_pipe(pipe_cmov_mem); 6950 %} 6951 6952 instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src) 6953 %{ 6954 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6955 6956 ins_cost(200); // XXX 6957 format %{ "jn$cop skip\t# signed cmove float\n\t" 6958 "movss $dst, $src\n" 6959 "skip:" %} 6960 ins_encode %{ 6961 Label Lskip; 6962 // Invert sense of branch from sense of CMOV 6963 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6964 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 6965 __ bind(Lskip); 6966 %} 6967 ins_pipe(pipe_slow); 6968 %} 6969 6970 instruct cmovF_regU(cmpOpU cop, rFlagsRegU cr, regF dst, regF src) 6971 %{ 6972 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6973 6974 ins_cost(200); // XXX 6975 format %{ "jn$cop skip\t# unsigned cmove float\n\t" 6976 "movss $dst, $src\n" 6977 "skip:" %} 6978 ins_encode %{ 6979 Label Lskip; 6980 // Invert sense of branch from sense of CMOV 6981 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6982 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 6983 __ bind(Lskip); 6984 %} 6985 ins_pipe(pipe_slow); 6986 %} 6987 6988 instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{ 6989 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6990 ins_cost(200); 6991 expand %{ 6992 cmovF_regU(cop, cr, dst, src); 6993 %} 6994 %} 6995 6996 instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src) 6997 %{ 6998 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6999 7000 ins_cost(200); // XXX 7001 format %{ "jn$cop skip\t# signed cmove double\n\t" 7002 "movsd $dst, $src\n" 7003 "skip:" %} 7004 ins_encode %{ 7005 Label Lskip; 7006 // Invert sense of branch from sense of CMOV 7007 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7008 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 7009 __ bind(Lskip); 7010 %} 7011 ins_pipe(pipe_slow); 7012 %} 7013 7014 instruct cmovD_regU(cmpOpU cop, rFlagsRegU cr, regD dst, regD src) 7015 %{ 7016 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7017 7018 ins_cost(200); // XXX 7019 format %{ "jn$cop skip\t# unsigned cmove double\n\t" 7020 "movsd $dst, $src\n" 7021 "skip:" %} 7022 ins_encode %{ 7023 Label Lskip; 7024 // Invert sense of branch from sense of CMOV 7025 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7026 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 7027 __ bind(Lskip); 7028 %} 7029 ins_pipe(pipe_slow); 7030 %} 7031 7032 instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{ 7033 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7034 ins_cost(200); 7035 expand %{ 7036 cmovD_regU(cop, cr, dst, src); 7037 %} 7038 %} 7039 7040 //----------Arithmetic Instructions-------------------------------------------- 7041 //----------Addition Instructions---------------------------------------------- 7042 7043 instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7044 %{ 7045 predicate(!UseAPX); 7046 match(Set dst (AddI dst src)); 7047 effect(KILL cr); 7048 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); 7049 format %{ "addl $dst, $src\t# int" %} 7050 ins_encode %{ 7051 __ addl($dst$$Register, $src$$Register); 7052 %} 7053 ins_pipe(ialu_reg_reg); 7054 %} 7055 7056 instruct addI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr) 7057 %{ 7058 predicate(UseAPX); 7059 match(Set dst (AddI src1 src2)); 7060 effect(KILL cr); 7061 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); 7062 7063 format %{ "eaddl $dst, $src1, $src2\t# int ndd" %} 7064 ins_encode %{ 7065 __ eaddl($dst$$Register, $src1$$Register, $src2$$Register, false); 7066 %} 7067 ins_pipe(ialu_reg_reg); 7068 %} 7069 7070 instruct addI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 7071 %{ 7072 predicate(!UseAPX); 7073 match(Set dst (AddI dst src)); 7074 effect(KILL cr); 7075 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 7076 7077 format %{ "addl $dst, $src\t# int" %} 7078 ins_encode %{ 7079 __ addl($dst$$Register, $src$$constant); 7080 %} 7081 ins_pipe( ialu_reg ); 7082 %} 7083 7084 instruct addI_rReg_rReg_imm_ndd(rRegI dst, rRegI src1, immI src2, rFlagsReg cr) 7085 %{ 7086 predicate(UseAPX); 7087 match(Set dst (AddI src1 src2)); 7088 effect(KILL cr); 7089 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 7090 7091 format %{ "eaddl $dst, $src1, $src2\t# int ndd" %} 7092 ins_encode %{ 7093 __ eaddl($dst$$Register, $src1$$Register, $src2$$constant, false); 7094 %} 7095 ins_pipe( ialu_reg ); 7096 %} 7097 7098 instruct addI_rReg_mem_imm_ndd(rRegI dst, memory src1, immI src2, rFlagsReg cr) 7099 %{ 7100 predicate(UseAPX); 7101 match(Set dst (AddI (LoadI src1) src2)); 7102 effect(KILL cr); 7103 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 7104 7105 format %{ "eaddl $dst, $src1, $src2\t# int ndd" %} 7106 ins_encode %{ 7107 __ eaddl($dst$$Register, $src1$$Address, $src2$$constant, false); 7108 %} 7109 ins_pipe( ialu_reg ); 7110 %} 7111 7112 instruct addI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 7113 %{ 7114 predicate(!UseAPX); 7115 match(Set dst (AddI dst (LoadI src))); 7116 effect(KILL cr); 7117 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); 7118 7119 ins_cost(150); // XXX 7120 format %{ "addl $dst, $src\t# int" %} 7121 ins_encode %{ 7122 __ addl($dst$$Register, $src$$Address); 7123 %} 7124 ins_pipe(ialu_reg_mem); 7125 %} 7126 7127 instruct addI_rReg_rReg_mem_ndd(rRegI dst, rRegI src1, memory src2, rFlagsReg cr) 7128 %{ 7129 predicate(UseAPX); 7130 match(Set dst (AddI src1 (LoadI src2))); 7131 effect(KILL cr); 7132 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 7133 7134 ins_cost(150); 7135 format %{ "eaddl $dst, $src1, $src2\t# int ndd" %} 7136 ins_encode %{ 7137 __ eaddl($dst$$Register, $src1$$Register, $src2$$Address, false); 7138 %} 7139 ins_pipe(ialu_reg_mem); 7140 %} 7141 7142 instruct addI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 7143 %{ 7144 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7145 effect(KILL cr); 7146 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 7147 7148 ins_cost(150); // XXX 7149 format %{ "addl $dst, $src\t# int" %} 7150 ins_encode %{ 7151 __ addl($dst$$Address, $src$$Register); 7152 %} 7153 ins_pipe(ialu_mem_reg); 7154 %} 7155 7156 instruct addI_mem_imm(memory dst, immI src, rFlagsReg cr) 7157 %{ 7158 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7159 effect(KILL cr); 7160 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); 7161 7162 7163 ins_cost(125); // XXX 7164 format %{ "addl $dst, $src\t# int" %} 7165 ins_encode %{ 7166 __ addl($dst$$Address, $src$$constant); 7167 %} 7168 ins_pipe(ialu_mem_imm); 7169 %} 7170 7171 instruct incI_rReg(rRegI dst, immI_1 src, rFlagsReg cr) 7172 %{ 7173 predicate(!UseAPX && UseIncDec); 7174 match(Set dst (AddI dst src)); 7175 effect(KILL cr); 7176 7177 format %{ "incl $dst\t# int" %} 7178 ins_encode %{ 7179 __ incrementl($dst$$Register); 7180 %} 7181 ins_pipe(ialu_reg); 7182 %} 7183 7184 instruct incI_rReg_ndd(rRegI dst, rRegI src, immI_1 val, rFlagsReg cr) 7185 %{ 7186 predicate(UseAPX && UseIncDec); 7187 match(Set dst (AddI src val)); 7188 effect(KILL cr); 7189 7190 format %{ "eincl $dst, $src\t# int ndd" %} 7191 ins_encode %{ 7192 __ eincl($dst$$Register, $src$$Register, false); 7193 %} 7194 ins_pipe(ialu_reg); 7195 %} 7196 7197 instruct incI_rReg_mem_ndd(rRegI dst, memory src, immI_1 val, rFlagsReg cr) 7198 %{ 7199 predicate(UseAPX && UseIncDec); 7200 match(Set dst (AddI (LoadI src) val)); 7201 effect(KILL cr); 7202 7203 format %{ "eincl $dst, $src\t# int ndd" %} 7204 ins_encode %{ 7205 __ eincl($dst$$Register, $src$$Address, false); 7206 %} 7207 ins_pipe(ialu_reg); 7208 %} 7209 7210 instruct incI_mem(memory dst, immI_1 src, rFlagsReg cr) 7211 %{ 7212 predicate(UseIncDec); 7213 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7214 effect(KILL cr); 7215 7216 ins_cost(125); // XXX 7217 format %{ "incl $dst\t# int" %} 7218 ins_encode %{ 7219 __ incrementl($dst$$Address); 7220 %} 7221 ins_pipe(ialu_mem_imm); 7222 %} 7223 7224 // XXX why does that use AddI 7225 instruct decI_rReg(rRegI dst, immI_M1 src, rFlagsReg cr) 7226 %{ 7227 predicate(!UseAPX && UseIncDec); 7228 match(Set dst (AddI dst src)); 7229 effect(KILL cr); 7230 7231 format %{ "decl $dst\t# int" %} 7232 ins_encode %{ 7233 __ decrementl($dst$$Register); 7234 %} 7235 ins_pipe(ialu_reg); 7236 %} 7237 7238 instruct decI_rReg_ndd(rRegI dst, rRegI src, immI_M1 val, rFlagsReg cr) 7239 %{ 7240 predicate(UseAPX && UseIncDec); 7241 match(Set dst (AddI src val)); 7242 effect(KILL cr); 7243 7244 format %{ "edecl $dst, $src\t# int ndd" %} 7245 ins_encode %{ 7246 __ edecl($dst$$Register, $src$$Register, false); 7247 %} 7248 ins_pipe(ialu_reg); 7249 %} 7250 7251 instruct decI_rReg_mem_ndd(rRegI dst, memory src, immI_M1 val, rFlagsReg cr) 7252 %{ 7253 predicate(UseAPX && UseIncDec); 7254 match(Set dst (AddI (LoadI src) val)); 7255 effect(KILL cr); 7256 7257 format %{ "edecl $dst, $src\t# int ndd" %} 7258 ins_encode %{ 7259 __ edecl($dst$$Register, $src$$Address, false); 7260 %} 7261 ins_pipe(ialu_reg); 7262 %} 7263 7264 // XXX why does that use AddI 7265 instruct decI_mem(memory dst, immI_M1 src, rFlagsReg cr) 7266 %{ 7267 predicate(UseIncDec); 7268 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7269 effect(KILL cr); 7270 7271 ins_cost(125); // XXX 7272 format %{ "decl $dst\t# int" %} 7273 ins_encode %{ 7274 __ decrementl($dst$$Address); 7275 %} 7276 ins_pipe(ialu_mem_imm); 7277 %} 7278 7279 instruct leaI_rReg_immI2_immI(rRegI dst, rRegI index, immI2 scale, immI disp) 7280 %{ 7281 predicate(VM_Version::supports_fast_2op_lea()); 7282 match(Set dst (AddI (LShiftI index scale) disp)); 7283 7284 format %{ "leal $dst, [$index << $scale + $disp]\t# int" %} 7285 ins_encode %{ 7286 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 7287 __ leal($dst$$Register, Address(noreg, $index$$Register, scale, $disp$$constant)); 7288 %} 7289 ins_pipe(ialu_reg_reg); 7290 %} 7291 7292 instruct leaI_rReg_rReg_immI(rRegI dst, rRegI base, rRegI index, immI disp) 7293 %{ 7294 predicate(VM_Version::supports_fast_3op_lea()); 7295 match(Set dst (AddI (AddI base index) disp)); 7296 7297 format %{ "leal $dst, [$base + $index + $disp]\t# int" %} 7298 ins_encode %{ 7299 __ leal($dst$$Register, Address($base$$Register, $index$$Register, Address::times_1, $disp$$constant)); 7300 %} 7301 ins_pipe(ialu_reg_reg); 7302 %} 7303 7304 instruct leaI_rReg_rReg_immI2(rRegI dst, no_rbp_r13_RegI base, rRegI index, immI2 scale) 7305 %{ 7306 predicate(VM_Version::supports_fast_2op_lea()); 7307 match(Set dst (AddI base (LShiftI index scale))); 7308 7309 format %{ "leal $dst, [$base + $index << $scale]\t# int" %} 7310 ins_encode %{ 7311 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 7312 __ leal($dst$$Register, Address($base$$Register, $index$$Register, scale)); 7313 %} 7314 ins_pipe(ialu_reg_reg); 7315 %} 7316 7317 instruct leaI_rReg_rReg_immI2_immI(rRegI dst, rRegI base, rRegI index, immI2 scale, immI disp) 7318 %{ 7319 predicate(VM_Version::supports_fast_3op_lea()); 7320 match(Set dst (AddI (AddI base (LShiftI index scale)) disp)); 7321 7322 format %{ "leal $dst, [$base + $index << $scale + $disp]\t# int" %} 7323 ins_encode %{ 7324 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 7325 __ leal($dst$$Register, Address($base$$Register, $index$$Register, scale, $disp$$constant)); 7326 %} 7327 ins_pipe(ialu_reg_reg); 7328 %} 7329 7330 instruct addL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7331 %{ 7332 predicate(!UseAPX); 7333 match(Set dst (AddL dst src)); 7334 effect(KILL cr); 7335 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 7336 7337 format %{ "addq $dst, $src\t# long" %} 7338 ins_encode %{ 7339 __ addq($dst$$Register, $src$$Register); 7340 %} 7341 ins_pipe(ialu_reg_reg); 7342 %} 7343 7344 instruct addL_rReg_ndd(rRegL dst, rRegL src1, rRegL src2, rFlagsReg cr) 7345 %{ 7346 predicate(UseAPX); 7347 match(Set dst (AddL src1 src2)); 7348 effect(KILL cr); 7349 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 7350 7351 format %{ "eaddq $dst, $src1, $src2\t# long ndd" %} 7352 ins_encode %{ 7353 __ eaddq($dst$$Register, $src1$$Register, $src2$$Register, false); 7354 %} 7355 ins_pipe(ialu_reg_reg); 7356 %} 7357 7358 instruct addL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 7359 %{ 7360 predicate(!UseAPX); 7361 match(Set dst (AddL dst src)); 7362 effect(KILL cr); 7363 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 7364 7365 format %{ "addq $dst, $src\t# long" %} 7366 ins_encode %{ 7367 __ addq($dst$$Register, $src$$constant); 7368 %} 7369 ins_pipe( ialu_reg ); 7370 %} 7371 7372 instruct addL_rReg_rReg_imm_ndd(rRegL dst, rRegL src1, immL32 src2, rFlagsReg cr) 7373 %{ 7374 predicate(UseAPX); 7375 match(Set dst (AddL src1 src2)); 7376 effect(KILL cr); 7377 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 7378 7379 format %{ "eaddq $dst, $src1, $src2\t# long ndd" %} 7380 ins_encode %{ 7381 __ eaddq($dst$$Register, $src1$$Register, $src2$$constant, false); 7382 %} 7383 ins_pipe( ialu_reg ); 7384 %} 7385 7386 instruct addL_rReg_mem_imm_ndd(rRegL dst, memory src1, immL32 src2, rFlagsReg cr) 7387 %{ 7388 predicate(UseAPX); 7389 match(Set dst (AddL (LoadL src1) src2)); 7390 effect(KILL cr); 7391 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 7392 7393 format %{ "eaddq $dst, $src1, $src2\t# long ndd" %} 7394 ins_encode %{ 7395 __ eaddq($dst$$Register, $src1$$Address, $src2$$constant, false); 7396 %} 7397 ins_pipe( ialu_reg ); 7398 %} 7399 7400 instruct addL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 7401 %{ 7402 predicate(!UseAPX); 7403 match(Set dst (AddL dst (LoadL src))); 7404 effect(KILL cr); 7405 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); 7406 7407 ins_cost(150); // XXX 7408 format %{ "addq $dst, $src\t# long" %} 7409 ins_encode %{ 7410 __ addq($dst$$Register, $src$$Address); 7411 %} 7412 ins_pipe(ialu_reg_mem); 7413 %} 7414 7415 instruct addL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr) 7416 %{ 7417 predicate(UseAPX); 7418 match(Set dst (AddL src1 (LoadL src2))); 7419 effect(KILL cr); 7420 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); 7421 7422 ins_cost(150); 7423 format %{ "eaddq $dst, $src1, $src2\t# long ndd" %} 7424 ins_encode %{ 7425 __ eaddq($dst$$Register, $src1$$Register, $src2$$Address, false); 7426 %} 7427 ins_pipe(ialu_reg_mem); 7428 %} 7429 7430 instruct addL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 7431 %{ 7432 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7433 effect(KILL cr); 7434 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); 7435 7436 ins_cost(150); // XXX 7437 format %{ "addq $dst, $src\t# long" %} 7438 ins_encode %{ 7439 __ addq($dst$$Address, $src$$Register); 7440 %} 7441 ins_pipe(ialu_mem_reg); 7442 %} 7443 7444 instruct addL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 7445 %{ 7446 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7447 effect(KILL cr); 7448 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); 7449 7450 ins_cost(125); // XXX 7451 format %{ "addq $dst, $src\t# long" %} 7452 ins_encode %{ 7453 __ addq($dst$$Address, $src$$constant); 7454 %} 7455 ins_pipe(ialu_mem_imm); 7456 %} 7457 7458 instruct incL_rReg(rRegL dst, immL1 src, rFlagsReg cr) 7459 %{ 7460 predicate(!UseAPX && UseIncDec); 7461 match(Set dst (AddL dst src)); 7462 effect(KILL cr); 7463 7464 format %{ "incq $dst\t# long" %} 7465 ins_encode %{ 7466 __ incrementq($dst$$Register); 7467 %} 7468 ins_pipe(ialu_reg); 7469 %} 7470 7471 instruct incL_rReg_ndd(rRegL dst, rRegI src, immL1 val, rFlagsReg cr) 7472 %{ 7473 predicate(UseAPX && UseIncDec); 7474 match(Set dst (AddL src val)); 7475 effect(KILL cr); 7476 7477 format %{ "eincq $dst, $src\t# long ndd" %} 7478 ins_encode %{ 7479 __ eincq($dst$$Register, $src$$Register, false); 7480 %} 7481 ins_pipe(ialu_reg); 7482 %} 7483 7484 instruct incL_rReg_mem_ndd(rRegL dst, memory src, immL1 val, rFlagsReg cr) 7485 %{ 7486 predicate(UseAPX && UseIncDec); 7487 match(Set dst (AddL (LoadL src) val)); 7488 effect(KILL cr); 7489 7490 format %{ "eincq $dst, $src\t# long ndd" %} 7491 ins_encode %{ 7492 __ eincq($dst$$Register, $src$$Address, false); 7493 %} 7494 ins_pipe(ialu_reg); 7495 %} 7496 7497 instruct incL_mem(memory dst, immL1 src, rFlagsReg cr) 7498 %{ 7499 predicate(UseIncDec); 7500 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7501 effect(KILL cr); 7502 7503 ins_cost(125); // XXX 7504 format %{ "incq $dst\t# long" %} 7505 ins_encode %{ 7506 __ incrementq($dst$$Address); 7507 %} 7508 ins_pipe(ialu_mem_imm); 7509 %} 7510 7511 // XXX why does that use AddL 7512 instruct decL_rReg(rRegL dst, immL_M1 src, rFlagsReg cr) 7513 %{ 7514 predicate(!UseAPX && UseIncDec); 7515 match(Set dst (AddL dst src)); 7516 effect(KILL cr); 7517 7518 format %{ "decq $dst\t# long" %} 7519 ins_encode %{ 7520 __ decrementq($dst$$Register); 7521 %} 7522 ins_pipe(ialu_reg); 7523 %} 7524 7525 instruct decL_rReg_ndd(rRegL dst, rRegL src, immL_M1 val, rFlagsReg cr) 7526 %{ 7527 predicate(UseAPX && UseIncDec); 7528 match(Set dst (AddL src val)); 7529 effect(KILL cr); 7530 7531 format %{ "edecq $dst, $src\t# long ndd" %} 7532 ins_encode %{ 7533 __ edecq($dst$$Register, $src$$Register, false); 7534 %} 7535 ins_pipe(ialu_reg); 7536 %} 7537 7538 instruct decL_rReg_mem_ndd(rRegL dst, memory src, immL_M1 val, rFlagsReg cr) 7539 %{ 7540 predicate(UseAPX && UseIncDec); 7541 match(Set dst (AddL (LoadL src) val)); 7542 effect(KILL cr); 7543 7544 format %{ "edecq $dst, $src\t# long ndd" %} 7545 ins_encode %{ 7546 __ edecq($dst$$Register, $src$$Address, false); 7547 %} 7548 ins_pipe(ialu_reg); 7549 %} 7550 7551 // XXX why does that use AddL 7552 instruct decL_mem(memory dst, immL_M1 src, rFlagsReg cr) 7553 %{ 7554 predicate(UseIncDec); 7555 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7556 effect(KILL cr); 7557 7558 ins_cost(125); // XXX 7559 format %{ "decq $dst\t# long" %} 7560 ins_encode %{ 7561 __ decrementq($dst$$Address); 7562 %} 7563 ins_pipe(ialu_mem_imm); 7564 %} 7565 7566 instruct leaL_rReg_immI2_immL32(rRegL dst, rRegL index, immI2 scale, immL32 disp) 7567 %{ 7568 predicate(VM_Version::supports_fast_2op_lea()); 7569 match(Set dst (AddL (LShiftL index scale) disp)); 7570 7571 format %{ "leaq $dst, [$index << $scale + $disp]\t# long" %} 7572 ins_encode %{ 7573 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 7574 __ leaq($dst$$Register, Address(noreg, $index$$Register, scale, $disp$$constant)); 7575 %} 7576 ins_pipe(ialu_reg_reg); 7577 %} 7578 7579 instruct leaL_rReg_rReg_immL32(rRegL dst, rRegL base, rRegL index, immL32 disp) 7580 %{ 7581 predicate(VM_Version::supports_fast_3op_lea()); 7582 match(Set dst (AddL (AddL base index) disp)); 7583 7584 format %{ "leaq $dst, [$base + $index + $disp]\t# long" %} 7585 ins_encode %{ 7586 __ leaq($dst$$Register, Address($base$$Register, $index$$Register, Address::times_1, $disp$$constant)); 7587 %} 7588 ins_pipe(ialu_reg_reg); 7589 %} 7590 7591 instruct leaL_rReg_rReg_immI2(rRegL dst, no_rbp_r13_RegL base, rRegL index, immI2 scale) 7592 %{ 7593 predicate(VM_Version::supports_fast_2op_lea()); 7594 match(Set dst (AddL base (LShiftL index scale))); 7595 7596 format %{ "leaq $dst, [$base + $index << $scale]\t# long" %} 7597 ins_encode %{ 7598 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 7599 __ leaq($dst$$Register, Address($base$$Register, $index$$Register, scale)); 7600 %} 7601 ins_pipe(ialu_reg_reg); 7602 %} 7603 7604 instruct leaL_rReg_rReg_immI2_immL32(rRegL dst, rRegL base, rRegL index, immI2 scale, immL32 disp) 7605 %{ 7606 predicate(VM_Version::supports_fast_3op_lea()); 7607 match(Set dst (AddL (AddL base (LShiftL index scale)) disp)); 7608 7609 format %{ "leaq $dst, [$base + $index << $scale + $disp]\t# long" %} 7610 ins_encode %{ 7611 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 7612 __ leaq($dst$$Register, Address($base$$Register, $index$$Register, scale, $disp$$constant)); 7613 %} 7614 ins_pipe(ialu_reg_reg); 7615 %} 7616 7617 instruct addP_rReg(rRegP dst, rRegL src, rFlagsReg cr) 7618 %{ 7619 match(Set dst (AddP dst src)); 7620 effect(KILL cr); 7621 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); 7622 7623 format %{ "addq $dst, $src\t# ptr" %} 7624 ins_encode %{ 7625 __ addq($dst$$Register, $src$$Register); 7626 %} 7627 ins_pipe(ialu_reg_reg); 7628 %} 7629 7630 instruct addP_rReg_imm(rRegP dst, immL32 src, rFlagsReg cr) 7631 %{ 7632 match(Set dst (AddP dst src)); 7633 effect(KILL cr); 7634 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); 7635 7636 format %{ "addq $dst, $src\t# ptr" %} 7637 ins_encode %{ 7638 __ addq($dst$$Register, $src$$constant); 7639 %} 7640 ins_pipe( ialu_reg ); 7641 %} 7642 7643 // XXX addP mem ops ???? 7644 7645 instruct checkCastPP(rRegP dst) 7646 %{ 7647 match(Set dst (CheckCastPP dst)); 7648 7649 size(0); 7650 format %{ "# checkcastPP of $dst" %} 7651 ins_encode(/* empty encoding */); 7652 ins_pipe(empty); 7653 %} 7654 7655 instruct castPP(rRegP dst) 7656 %{ 7657 match(Set dst (CastPP dst)); 7658 7659 size(0); 7660 format %{ "# castPP of $dst" %} 7661 ins_encode(/* empty encoding */); 7662 ins_pipe(empty); 7663 %} 7664 7665 instruct castII(rRegI dst) 7666 %{ 7667 predicate(VerifyConstraintCasts == 0); 7668 match(Set dst (CastII dst)); 7669 7670 size(0); 7671 format %{ "# castII of $dst" %} 7672 ins_encode(/* empty encoding */); 7673 ins_cost(0); 7674 ins_pipe(empty); 7675 %} 7676 7677 instruct castII_checked(rRegI dst, rFlagsReg cr) 7678 %{ 7679 predicate(VerifyConstraintCasts > 0); 7680 match(Set dst (CastII dst)); 7681 7682 effect(KILL cr); 7683 format %{ "# cast_checked_II $dst" %} 7684 ins_encode %{ 7685 __ verify_int_in_range(_idx, bottom_type()->is_int(), $dst$$Register); 7686 %} 7687 ins_pipe(pipe_slow); 7688 %} 7689 7690 instruct castLL(rRegL dst) 7691 %{ 7692 predicate(VerifyConstraintCasts == 0); 7693 match(Set dst (CastLL dst)); 7694 7695 size(0); 7696 format %{ "# castLL of $dst" %} 7697 ins_encode(/* empty encoding */); 7698 ins_cost(0); 7699 ins_pipe(empty); 7700 %} 7701 7702 instruct castLL_checked_L32(rRegL dst, rFlagsReg cr) 7703 %{ 7704 predicate(VerifyConstraintCasts > 0 && castLL_is_imm32(n)); 7705 match(Set dst (CastLL dst)); 7706 7707 effect(KILL cr); 7708 format %{ "# cast_checked_LL $dst" %} 7709 ins_encode %{ 7710 __ verify_long_in_range(_idx, bottom_type()->is_long(), $dst$$Register, noreg); 7711 %} 7712 ins_pipe(pipe_slow); 7713 %} 7714 7715 instruct castLL_checked(rRegL dst, rRegL tmp, rFlagsReg cr) 7716 %{ 7717 predicate(VerifyConstraintCasts > 0 && !castLL_is_imm32(n)); 7718 match(Set dst (CastLL dst)); 7719 7720 effect(KILL cr, TEMP tmp); 7721 format %{ "# cast_checked_LL $dst\tusing $tmp as TEMP" %} 7722 ins_encode %{ 7723 __ verify_long_in_range(_idx, bottom_type()->is_long(), $dst$$Register, $tmp$$Register); 7724 %} 7725 ins_pipe(pipe_slow); 7726 %} 7727 7728 instruct castFF(regF dst) 7729 %{ 7730 match(Set dst (CastFF dst)); 7731 7732 size(0); 7733 format %{ "# castFF of $dst" %} 7734 ins_encode(/* empty encoding */); 7735 ins_cost(0); 7736 ins_pipe(empty); 7737 %} 7738 7739 instruct castHH(regF dst) 7740 %{ 7741 match(Set dst (CastHH dst)); 7742 7743 size(0); 7744 format %{ "# castHH of $dst" %} 7745 ins_encode(/* empty encoding */); 7746 ins_cost(0); 7747 ins_pipe(empty); 7748 %} 7749 7750 instruct castDD(regD dst) 7751 %{ 7752 match(Set dst (CastDD dst)); 7753 7754 size(0); 7755 format %{ "# castDD of $dst" %} 7756 ins_encode(/* empty encoding */); 7757 ins_cost(0); 7758 ins_pipe(empty); 7759 %} 7760 7761 // XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them 7762 instruct compareAndSwapP(rRegI res, 7763 memory mem_ptr, 7764 rax_RegP oldval, rRegP newval, 7765 rFlagsReg cr) 7766 %{ 7767 predicate(n->as_LoadStore()->barrier_data() == 0); 7768 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); 7769 match(Set res (WeakCompareAndSwapP mem_ptr (Binary oldval newval))); 7770 effect(KILL cr, KILL oldval); 7771 7772 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7773 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7774 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7775 ins_encode %{ 7776 __ lock(); 7777 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7778 __ setcc(Assembler::equal, $res$$Register); 7779 %} 7780 ins_pipe( pipe_cmpxchg ); 7781 %} 7782 7783 instruct compareAndSwapL(rRegI res, 7784 memory mem_ptr, 7785 rax_RegL oldval, rRegL newval, 7786 rFlagsReg cr) 7787 %{ 7788 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval))); 7789 match(Set res (WeakCompareAndSwapL mem_ptr (Binary oldval newval))); 7790 effect(KILL cr, KILL oldval); 7791 7792 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7793 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7794 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7795 ins_encode %{ 7796 __ lock(); 7797 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7798 __ setcc(Assembler::equal, $res$$Register); 7799 %} 7800 ins_pipe( pipe_cmpxchg ); 7801 %} 7802 7803 instruct compareAndSwapI(rRegI res, 7804 memory mem_ptr, 7805 rax_RegI oldval, rRegI newval, 7806 rFlagsReg cr) 7807 %{ 7808 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval))); 7809 match(Set res (WeakCompareAndSwapI mem_ptr (Binary oldval newval))); 7810 effect(KILL cr, KILL oldval); 7811 7812 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7813 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7814 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7815 ins_encode %{ 7816 __ lock(); 7817 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7818 __ setcc(Assembler::equal, $res$$Register); 7819 %} 7820 ins_pipe( pipe_cmpxchg ); 7821 %} 7822 7823 instruct compareAndSwapB(rRegI res, 7824 memory mem_ptr, 7825 rax_RegI oldval, rRegI newval, 7826 rFlagsReg cr) 7827 %{ 7828 match(Set res (CompareAndSwapB mem_ptr (Binary oldval newval))); 7829 match(Set res (WeakCompareAndSwapB mem_ptr (Binary oldval newval))); 7830 effect(KILL cr, KILL oldval); 7831 7832 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7833 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7834 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7835 ins_encode %{ 7836 __ lock(); 7837 __ cmpxchgb($newval$$Register, $mem_ptr$$Address); 7838 __ setcc(Assembler::equal, $res$$Register); 7839 %} 7840 ins_pipe( pipe_cmpxchg ); 7841 %} 7842 7843 instruct compareAndSwapS(rRegI res, 7844 memory mem_ptr, 7845 rax_RegI oldval, rRegI newval, 7846 rFlagsReg cr) 7847 %{ 7848 match(Set res (CompareAndSwapS mem_ptr (Binary oldval newval))); 7849 match(Set res (WeakCompareAndSwapS mem_ptr (Binary oldval newval))); 7850 effect(KILL cr, KILL oldval); 7851 7852 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7853 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7854 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7855 ins_encode %{ 7856 __ lock(); 7857 __ cmpxchgw($newval$$Register, $mem_ptr$$Address); 7858 __ setcc(Assembler::equal, $res$$Register); 7859 %} 7860 ins_pipe( pipe_cmpxchg ); 7861 %} 7862 7863 instruct compareAndSwapN(rRegI res, 7864 memory mem_ptr, 7865 rax_RegN oldval, rRegN newval, 7866 rFlagsReg cr) %{ 7867 predicate(n->as_LoadStore()->barrier_data() == 0); 7868 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval))); 7869 match(Set res (WeakCompareAndSwapN mem_ptr (Binary oldval newval))); 7870 effect(KILL cr, KILL oldval); 7871 7872 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7873 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7874 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7875 ins_encode %{ 7876 __ lock(); 7877 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7878 __ setcc(Assembler::equal, $res$$Register); 7879 %} 7880 ins_pipe( pipe_cmpxchg ); 7881 %} 7882 7883 instruct compareAndExchangeB( 7884 memory mem_ptr, 7885 rax_RegI oldval, rRegI newval, 7886 rFlagsReg cr) 7887 %{ 7888 match(Set oldval (CompareAndExchangeB mem_ptr (Binary oldval newval))); 7889 effect(KILL cr); 7890 7891 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7892 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7893 ins_encode %{ 7894 __ lock(); 7895 __ cmpxchgb($newval$$Register, $mem_ptr$$Address); 7896 %} 7897 ins_pipe( pipe_cmpxchg ); 7898 %} 7899 7900 instruct compareAndExchangeS( 7901 memory mem_ptr, 7902 rax_RegI oldval, rRegI newval, 7903 rFlagsReg cr) 7904 %{ 7905 match(Set oldval (CompareAndExchangeS mem_ptr (Binary oldval newval))); 7906 effect(KILL cr); 7907 7908 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7909 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7910 ins_encode %{ 7911 __ lock(); 7912 __ cmpxchgw($newval$$Register, $mem_ptr$$Address); 7913 %} 7914 ins_pipe( pipe_cmpxchg ); 7915 %} 7916 7917 instruct compareAndExchangeI( 7918 memory mem_ptr, 7919 rax_RegI oldval, rRegI newval, 7920 rFlagsReg cr) 7921 %{ 7922 match(Set oldval (CompareAndExchangeI mem_ptr (Binary oldval newval))); 7923 effect(KILL cr); 7924 7925 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7926 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7927 ins_encode %{ 7928 __ lock(); 7929 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7930 %} 7931 ins_pipe( pipe_cmpxchg ); 7932 %} 7933 7934 instruct compareAndExchangeL( 7935 memory mem_ptr, 7936 rax_RegL oldval, rRegL newval, 7937 rFlagsReg cr) 7938 %{ 7939 match(Set oldval (CompareAndExchangeL mem_ptr (Binary oldval newval))); 7940 effect(KILL cr); 7941 7942 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7943 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7944 ins_encode %{ 7945 __ lock(); 7946 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7947 %} 7948 ins_pipe( pipe_cmpxchg ); 7949 %} 7950 7951 instruct compareAndExchangeN( 7952 memory mem_ptr, 7953 rax_RegN oldval, rRegN newval, 7954 rFlagsReg cr) %{ 7955 predicate(n->as_LoadStore()->barrier_data() == 0); 7956 match(Set oldval (CompareAndExchangeN mem_ptr (Binary oldval newval))); 7957 effect(KILL cr); 7958 7959 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7960 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7961 ins_encode %{ 7962 __ lock(); 7963 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7964 %} 7965 ins_pipe( pipe_cmpxchg ); 7966 %} 7967 7968 instruct compareAndExchangeP( 7969 memory mem_ptr, 7970 rax_RegP oldval, rRegP newval, 7971 rFlagsReg cr) 7972 %{ 7973 predicate(n->as_LoadStore()->barrier_data() == 0); 7974 match(Set oldval (CompareAndExchangeP mem_ptr (Binary oldval newval))); 7975 effect(KILL cr); 7976 7977 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7978 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7979 ins_encode %{ 7980 __ lock(); 7981 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7982 %} 7983 ins_pipe( pipe_cmpxchg ); 7984 %} 7985 7986 instruct xaddB_reg_no_res(memory mem, Universe dummy, rRegI add, rFlagsReg cr) %{ 7987 predicate(n->as_LoadStore()->result_not_used()); 7988 match(Set dummy (GetAndAddB mem add)); 7989 effect(KILL cr); 7990 format %{ "addb_lock $mem, $add" %} 7991 ins_encode %{ 7992 __ lock(); 7993 __ addb($mem$$Address, $add$$Register); 7994 %} 7995 ins_pipe(pipe_cmpxchg); 7996 %} 7997 7998 instruct xaddB_imm_no_res(memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7999 predicate(n->as_LoadStore()->result_not_used()); 8000 match(Set dummy (GetAndAddB mem add)); 8001 effect(KILL cr); 8002 format %{ "addb_lock $mem, $add" %} 8003 ins_encode %{ 8004 __ lock(); 8005 __ addb($mem$$Address, $add$$constant); 8006 %} 8007 ins_pipe(pipe_cmpxchg); 8008 %} 8009 8010 instruct xaddB(memory mem, rRegI newval, rFlagsReg cr) %{ 8011 predicate(!n->as_LoadStore()->result_not_used()); 8012 match(Set newval (GetAndAddB mem newval)); 8013 effect(KILL cr); 8014 format %{ "xaddb_lock $mem, $newval" %} 8015 ins_encode %{ 8016 __ lock(); 8017 __ xaddb($mem$$Address, $newval$$Register); 8018 %} 8019 ins_pipe(pipe_cmpxchg); 8020 %} 8021 8022 instruct xaddS_reg_no_res(memory mem, Universe dummy, rRegI add, rFlagsReg cr) %{ 8023 predicate(n->as_LoadStore()->result_not_used()); 8024 match(Set dummy (GetAndAddS mem add)); 8025 effect(KILL cr); 8026 format %{ "addw_lock $mem, $add" %} 8027 ins_encode %{ 8028 __ lock(); 8029 __ addw($mem$$Address, $add$$Register); 8030 %} 8031 ins_pipe(pipe_cmpxchg); 8032 %} 8033 8034 instruct xaddS_imm_no_res(memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 8035 predicate(UseStoreImmI16 && n->as_LoadStore()->result_not_used()); 8036 match(Set dummy (GetAndAddS mem add)); 8037 effect(KILL cr); 8038 format %{ "addw_lock $mem, $add" %} 8039 ins_encode %{ 8040 __ lock(); 8041 __ addw($mem$$Address, $add$$constant); 8042 %} 8043 ins_pipe(pipe_cmpxchg); 8044 %} 8045 8046 instruct xaddS(memory mem, rRegI newval, rFlagsReg cr) %{ 8047 predicate(!n->as_LoadStore()->result_not_used()); 8048 match(Set newval (GetAndAddS mem newval)); 8049 effect(KILL cr); 8050 format %{ "xaddw_lock $mem, $newval" %} 8051 ins_encode %{ 8052 __ lock(); 8053 __ xaddw($mem$$Address, $newval$$Register); 8054 %} 8055 ins_pipe(pipe_cmpxchg); 8056 %} 8057 8058 instruct xaddI_reg_no_res(memory mem, Universe dummy, rRegI add, rFlagsReg cr) %{ 8059 predicate(n->as_LoadStore()->result_not_used()); 8060 match(Set dummy (GetAndAddI mem add)); 8061 effect(KILL cr); 8062 format %{ "addl_lock $mem, $add" %} 8063 ins_encode %{ 8064 __ lock(); 8065 __ addl($mem$$Address, $add$$Register); 8066 %} 8067 ins_pipe(pipe_cmpxchg); 8068 %} 8069 8070 instruct xaddI_imm_no_res(memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 8071 predicate(n->as_LoadStore()->result_not_used()); 8072 match(Set dummy (GetAndAddI mem add)); 8073 effect(KILL cr); 8074 format %{ "addl_lock $mem, $add" %} 8075 ins_encode %{ 8076 __ lock(); 8077 __ addl($mem$$Address, $add$$constant); 8078 %} 8079 ins_pipe(pipe_cmpxchg); 8080 %} 8081 8082 instruct xaddI(memory mem, rRegI newval, rFlagsReg cr) %{ 8083 predicate(!n->as_LoadStore()->result_not_used()); 8084 match(Set newval (GetAndAddI mem newval)); 8085 effect(KILL cr); 8086 format %{ "xaddl_lock $mem, $newval" %} 8087 ins_encode %{ 8088 __ lock(); 8089 __ xaddl($mem$$Address, $newval$$Register); 8090 %} 8091 ins_pipe(pipe_cmpxchg); 8092 %} 8093 8094 instruct xaddL_reg_no_res(memory mem, Universe dummy, rRegL add, rFlagsReg cr) %{ 8095 predicate(n->as_LoadStore()->result_not_used()); 8096 match(Set dummy (GetAndAddL mem add)); 8097 effect(KILL cr); 8098 format %{ "addq_lock $mem, $add" %} 8099 ins_encode %{ 8100 __ lock(); 8101 __ addq($mem$$Address, $add$$Register); 8102 %} 8103 ins_pipe(pipe_cmpxchg); 8104 %} 8105 8106 instruct xaddL_imm_no_res(memory mem, Universe dummy, immL32 add, rFlagsReg cr) %{ 8107 predicate(n->as_LoadStore()->result_not_used()); 8108 match(Set dummy (GetAndAddL mem add)); 8109 effect(KILL cr); 8110 format %{ "addq_lock $mem, $add" %} 8111 ins_encode %{ 8112 __ lock(); 8113 __ addq($mem$$Address, $add$$constant); 8114 %} 8115 ins_pipe(pipe_cmpxchg); 8116 %} 8117 8118 instruct xaddL(memory mem, rRegL newval, rFlagsReg cr) %{ 8119 predicate(!n->as_LoadStore()->result_not_used()); 8120 match(Set newval (GetAndAddL mem newval)); 8121 effect(KILL cr); 8122 format %{ "xaddq_lock $mem, $newval" %} 8123 ins_encode %{ 8124 __ lock(); 8125 __ xaddq($mem$$Address, $newval$$Register); 8126 %} 8127 ins_pipe(pipe_cmpxchg); 8128 %} 8129 8130 instruct xchgB( memory mem, rRegI newval) %{ 8131 match(Set newval (GetAndSetB mem newval)); 8132 format %{ "XCHGB $newval,[$mem]" %} 8133 ins_encode %{ 8134 __ xchgb($newval$$Register, $mem$$Address); 8135 %} 8136 ins_pipe( pipe_cmpxchg ); 8137 %} 8138 8139 instruct xchgS( memory mem, rRegI newval) %{ 8140 match(Set newval (GetAndSetS mem newval)); 8141 format %{ "XCHGW $newval,[$mem]" %} 8142 ins_encode %{ 8143 __ xchgw($newval$$Register, $mem$$Address); 8144 %} 8145 ins_pipe( pipe_cmpxchg ); 8146 %} 8147 8148 instruct xchgI( memory mem, rRegI newval) %{ 8149 match(Set newval (GetAndSetI mem newval)); 8150 format %{ "XCHGL $newval,[$mem]" %} 8151 ins_encode %{ 8152 __ xchgl($newval$$Register, $mem$$Address); 8153 %} 8154 ins_pipe( pipe_cmpxchg ); 8155 %} 8156 8157 instruct xchgL( memory mem, rRegL newval) %{ 8158 match(Set newval (GetAndSetL mem newval)); 8159 format %{ "XCHGL $newval,[$mem]" %} 8160 ins_encode %{ 8161 __ xchgq($newval$$Register, $mem$$Address); 8162 %} 8163 ins_pipe( pipe_cmpxchg ); 8164 %} 8165 8166 instruct xchgP( memory mem, rRegP newval) %{ 8167 match(Set newval (GetAndSetP mem newval)); 8168 predicate(n->as_LoadStore()->barrier_data() == 0); 8169 format %{ "XCHGQ $newval,[$mem]" %} 8170 ins_encode %{ 8171 __ xchgq($newval$$Register, $mem$$Address); 8172 %} 8173 ins_pipe( pipe_cmpxchg ); 8174 %} 8175 8176 instruct xchgN( memory mem, rRegN newval) %{ 8177 predicate(n->as_LoadStore()->barrier_data() == 0); 8178 match(Set newval (GetAndSetN mem newval)); 8179 format %{ "XCHGL $newval,$mem]" %} 8180 ins_encode %{ 8181 __ xchgl($newval$$Register, $mem$$Address); 8182 %} 8183 ins_pipe( pipe_cmpxchg ); 8184 %} 8185 8186 //----------Abs Instructions------------------------------------------- 8187 8188 // Integer Absolute Instructions 8189 instruct absI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8190 %{ 8191 match(Set dst (AbsI src)); 8192 effect(TEMP dst, KILL cr); 8193 format %{ "xorl $dst, $dst\t# abs int\n\t" 8194 "subl $dst, $src\n\t" 8195 "cmovll $dst, $src" %} 8196 ins_encode %{ 8197 __ xorl($dst$$Register, $dst$$Register); 8198 __ subl($dst$$Register, $src$$Register); 8199 __ cmovl(Assembler::less, $dst$$Register, $src$$Register); 8200 %} 8201 8202 ins_pipe(ialu_reg_reg); 8203 %} 8204 8205 // Long Absolute Instructions 8206 instruct absL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 8207 %{ 8208 match(Set dst (AbsL src)); 8209 effect(TEMP dst, KILL cr); 8210 format %{ "xorl $dst, $dst\t# abs long\n\t" 8211 "subq $dst, $src\n\t" 8212 "cmovlq $dst, $src" %} 8213 ins_encode %{ 8214 __ xorl($dst$$Register, $dst$$Register); 8215 __ subq($dst$$Register, $src$$Register); 8216 __ cmovq(Assembler::less, $dst$$Register, $src$$Register); 8217 %} 8218 8219 ins_pipe(ialu_reg_reg); 8220 %} 8221 8222 //----------Subtraction Instructions------------------------------------------- 8223 8224 // Integer Subtraction Instructions 8225 instruct subI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8226 %{ 8227 predicate(!UseAPX); 8228 match(Set dst (SubI dst src)); 8229 effect(KILL cr); 8230 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 8231 8232 format %{ "subl $dst, $src\t# int" %} 8233 ins_encode %{ 8234 __ subl($dst$$Register, $src$$Register); 8235 %} 8236 ins_pipe(ialu_reg_reg); 8237 %} 8238 8239 instruct subI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr) 8240 %{ 8241 predicate(UseAPX); 8242 match(Set dst (SubI src1 src2)); 8243 effect(KILL cr); 8244 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 8245 8246 format %{ "esubl $dst, $src1, $src2\t# int ndd" %} 8247 ins_encode %{ 8248 __ esubl($dst$$Register, $src1$$Register, $src2$$Register, false); 8249 %} 8250 ins_pipe(ialu_reg_reg); 8251 %} 8252 8253 instruct subI_rReg_rReg_imm_ndd(rRegI dst, rRegI src1, immI src2, rFlagsReg cr) 8254 %{ 8255 predicate(UseAPX); 8256 match(Set dst (SubI src1 src2)); 8257 effect(KILL cr); 8258 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); 8259 8260 format %{ "esubl $dst, $src1, $src2\t# int ndd" %} 8261 ins_encode %{ 8262 __ esubl($dst$$Register, $src1$$Register, $src2$$constant, false); 8263 %} 8264 ins_pipe(ialu_reg_reg); 8265 %} 8266 8267 instruct subI_rReg_mem_imm_ndd(rRegI dst, memory src1, immI src2, rFlagsReg cr) 8268 %{ 8269 predicate(UseAPX); 8270 match(Set dst (SubI (LoadI src1) src2)); 8271 effect(KILL cr); 8272 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); 8273 8274 format %{ "esubl $dst, $src1, $src2\t# int ndd" %} 8275 ins_encode %{ 8276 __ esubl($dst$$Register, $src1$$Address, $src2$$constant, false); 8277 %} 8278 ins_pipe(ialu_reg_reg); 8279 %} 8280 8281 instruct subI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 8282 %{ 8283 predicate(!UseAPX); 8284 match(Set dst (SubI dst (LoadI src))); 8285 effect(KILL cr); 8286 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); 8287 8288 ins_cost(150); 8289 format %{ "subl $dst, $src\t# int" %} 8290 ins_encode %{ 8291 __ subl($dst$$Register, $src$$Address); 8292 %} 8293 ins_pipe(ialu_reg_mem); 8294 %} 8295 8296 instruct subI_rReg_rReg_mem_ndd(rRegI dst, rRegI src1, memory src2, rFlagsReg cr) 8297 %{ 8298 predicate(UseAPX); 8299 match(Set dst (SubI src1 (LoadI src2))); 8300 effect(KILL cr); 8301 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); 8302 8303 ins_cost(150); 8304 format %{ "esubl $dst, $src1, $src2\t# int ndd" %} 8305 ins_encode %{ 8306 __ esubl($dst$$Register, $src1$$Register, $src2$$Address, false); 8307 %} 8308 ins_pipe(ialu_reg_mem); 8309 %} 8310 8311 instruct subI_rReg_mem_rReg_ndd(rRegI dst, memory src1, rRegI src2, rFlagsReg cr) 8312 %{ 8313 predicate(UseAPX); 8314 match(Set dst (SubI (LoadI src1) src2)); 8315 effect(KILL cr); 8316 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); 8317 8318 ins_cost(150); 8319 format %{ "esubl $dst, $src1, $src2\t# int ndd" %} 8320 ins_encode %{ 8321 __ esubl($dst$$Register, $src1$$Address, $src2$$Register, false); 8322 %} 8323 ins_pipe(ialu_reg_mem); 8324 %} 8325 8326 instruct subI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 8327 %{ 8328 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 8329 effect(KILL cr); 8330 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); 8331 8332 ins_cost(150); 8333 format %{ "subl $dst, $src\t# int" %} 8334 ins_encode %{ 8335 __ subl($dst$$Address, $src$$Register); 8336 %} 8337 ins_pipe(ialu_mem_reg); 8338 %} 8339 8340 instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 8341 %{ 8342 predicate(!UseAPX); 8343 match(Set dst (SubL dst src)); 8344 effect(KILL cr); 8345 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 8346 8347 format %{ "subq $dst, $src\t# long" %} 8348 ins_encode %{ 8349 __ subq($dst$$Register, $src$$Register); 8350 %} 8351 ins_pipe(ialu_reg_reg); 8352 %} 8353 8354 instruct subL_rReg_ndd(rRegL dst, rRegL src1, rRegL src2, rFlagsReg cr) 8355 %{ 8356 predicate(UseAPX); 8357 match(Set dst (SubL src1 src2)); 8358 effect(KILL cr); 8359 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 8360 8361 format %{ "esubq $dst, $src1, $src2\t# long ndd" %} 8362 ins_encode %{ 8363 __ esubq($dst$$Register, $src1$$Register, $src2$$Register, false); 8364 %} 8365 ins_pipe(ialu_reg_reg); 8366 %} 8367 8368 instruct subL_rReg_rReg_imm_ndd(rRegL dst, rRegL src1, immL32 src2, rFlagsReg cr) 8369 %{ 8370 predicate(UseAPX); 8371 match(Set dst (SubL src1 src2)); 8372 effect(KILL cr); 8373 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); 8374 8375 format %{ "esubq $dst, $src1, $src2\t# long ndd" %} 8376 ins_encode %{ 8377 __ esubq($dst$$Register, $src1$$Register, $src2$$constant, false); 8378 %} 8379 ins_pipe(ialu_reg_reg); 8380 %} 8381 8382 instruct subL_rReg_mem_imm_ndd(rRegL dst, memory src1, immL32 src2, rFlagsReg cr) 8383 %{ 8384 predicate(UseAPX); 8385 match(Set dst (SubL (LoadL src1) src2)); 8386 effect(KILL cr); 8387 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); 8388 8389 format %{ "esubq $dst, $src1, $src2\t# long ndd" %} 8390 ins_encode %{ 8391 __ esubq($dst$$Register, $src1$$Address, $src2$$constant, false); 8392 %} 8393 ins_pipe(ialu_reg_reg); 8394 %} 8395 8396 instruct subL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 8397 %{ 8398 predicate(!UseAPX); 8399 match(Set dst (SubL dst (LoadL src))); 8400 effect(KILL cr); 8401 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); 8402 8403 ins_cost(150); 8404 format %{ "subq $dst, $src\t# long" %} 8405 ins_encode %{ 8406 __ subq($dst$$Register, $src$$Address); 8407 %} 8408 ins_pipe(ialu_reg_mem); 8409 %} 8410 8411 instruct subL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr) 8412 %{ 8413 predicate(UseAPX); 8414 match(Set dst (SubL src1 (LoadL src2))); 8415 effect(KILL cr); 8416 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); 8417 8418 ins_cost(150); 8419 format %{ "esubq $dst, $src1, $src2\t# long ndd" %} 8420 ins_encode %{ 8421 __ esubq($dst$$Register, $src1$$Register, $src2$$Address, false); 8422 %} 8423 ins_pipe(ialu_reg_mem); 8424 %} 8425 8426 instruct subL_rReg_mem_rReg_ndd(rRegL dst, memory src1, rRegL src2, rFlagsReg cr) 8427 %{ 8428 predicate(UseAPX); 8429 match(Set dst (SubL (LoadL src1) src2)); 8430 effect(KILL cr); 8431 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); 8432 8433 ins_cost(150); 8434 format %{ "esubq $dst, $src1, $src2\t# long ndd" %} 8435 ins_encode %{ 8436 __ esubq($dst$$Register, $src1$$Address, $src2$$Register, false); 8437 %} 8438 ins_pipe(ialu_reg_mem); 8439 %} 8440 8441 instruct subL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 8442 %{ 8443 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 8444 effect(KILL cr); 8445 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); 8446 8447 ins_cost(150); 8448 format %{ "subq $dst, $src\t# long" %} 8449 ins_encode %{ 8450 __ subq($dst$$Address, $src$$Register); 8451 %} 8452 ins_pipe(ialu_mem_reg); 8453 %} 8454 8455 // Subtract from a pointer 8456 // XXX hmpf??? 8457 instruct subP_rReg(rRegP dst, rRegI src, immI_0 zero, rFlagsReg cr) 8458 %{ 8459 match(Set dst (AddP dst (SubI zero src))); 8460 effect(KILL cr); 8461 8462 format %{ "subq $dst, $src\t# ptr - int" %} 8463 ins_encode %{ 8464 __ subq($dst$$Register, $src$$Register); 8465 %} 8466 ins_pipe(ialu_reg_reg); 8467 %} 8468 8469 instruct negI_rReg(rRegI dst, immI_0 zero, rFlagsReg cr) 8470 %{ 8471 predicate(!UseAPX); 8472 match(Set dst (SubI zero dst)); 8473 effect(KILL cr); 8474 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8475 8476 format %{ "negl $dst\t# int" %} 8477 ins_encode %{ 8478 __ negl($dst$$Register); 8479 %} 8480 ins_pipe(ialu_reg); 8481 %} 8482 8483 instruct negI_rReg_ndd(rRegI dst, rRegI src, immI_0 zero, rFlagsReg cr) 8484 %{ 8485 predicate(UseAPX); 8486 match(Set dst (SubI zero src)); 8487 effect(KILL cr); 8488 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8489 8490 format %{ "enegl $dst, $src\t# int ndd" %} 8491 ins_encode %{ 8492 __ enegl($dst$$Register, $src$$Register, false); 8493 %} 8494 ins_pipe(ialu_reg); 8495 %} 8496 8497 instruct negI_rReg_2(rRegI dst, rFlagsReg cr) 8498 %{ 8499 predicate(!UseAPX); 8500 match(Set dst (NegI dst)); 8501 effect(KILL cr); 8502 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8503 8504 format %{ "negl $dst\t# int" %} 8505 ins_encode %{ 8506 __ negl($dst$$Register); 8507 %} 8508 ins_pipe(ialu_reg); 8509 %} 8510 8511 instruct negI_rReg_2_ndd(rRegI dst, rRegI src, rFlagsReg cr) 8512 %{ 8513 predicate(UseAPX); 8514 match(Set dst (NegI src)); 8515 effect(KILL cr); 8516 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8517 8518 format %{ "enegl $dst, $src\t# int ndd" %} 8519 ins_encode %{ 8520 __ enegl($dst$$Register, $src$$Register, false); 8521 %} 8522 ins_pipe(ialu_reg); 8523 %} 8524 8525 instruct negI_mem(memory dst, immI_0 zero, rFlagsReg cr) 8526 %{ 8527 match(Set dst (StoreI dst (SubI zero (LoadI dst)))); 8528 effect(KILL cr); 8529 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8530 8531 format %{ "negl $dst\t# int" %} 8532 ins_encode %{ 8533 __ negl($dst$$Address); 8534 %} 8535 ins_pipe(ialu_reg); 8536 %} 8537 8538 instruct negL_rReg(rRegL dst, immL0 zero, rFlagsReg cr) 8539 %{ 8540 predicate(!UseAPX); 8541 match(Set dst (SubL zero dst)); 8542 effect(KILL cr); 8543 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8544 8545 format %{ "negq $dst\t# long" %} 8546 ins_encode %{ 8547 __ negq($dst$$Register); 8548 %} 8549 ins_pipe(ialu_reg); 8550 %} 8551 8552 instruct negL_rReg_ndd(rRegL dst, rRegL src, immL0 zero, rFlagsReg cr) 8553 %{ 8554 predicate(UseAPX); 8555 match(Set dst (SubL zero src)); 8556 effect(KILL cr); 8557 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8558 8559 format %{ "enegq $dst, $src\t# long ndd" %} 8560 ins_encode %{ 8561 __ enegq($dst$$Register, $src$$Register, false); 8562 %} 8563 ins_pipe(ialu_reg); 8564 %} 8565 8566 instruct negL_rReg_2(rRegL dst, rFlagsReg cr) 8567 %{ 8568 predicate(!UseAPX); 8569 match(Set dst (NegL dst)); 8570 effect(KILL cr); 8571 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8572 8573 format %{ "negq $dst\t# int" %} 8574 ins_encode %{ 8575 __ negq($dst$$Register); 8576 %} 8577 ins_pipe(ialu_reg); 8578 %} 8579 8580 instruct negL_rReg_2_ndd(rRegL dst, rRegL src, rFlagsReg cr) 8581 %{ 8582 predicate(UseAPX); 8583 match(Set dst (NegL src)); 8584 effect(KILL cr); 8585 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8586 8587 format %{ "enegq $dst, $src\t# long ndd" %} 8588 ins_encode %{ 8589 __ enegq($dst$$Register, $src$$Register, false); 8590 %} 8591 ins_pipe(ialu_reg); 8592 %} 8593 8594 instruct negL_mem(memory dst, immL0 zero, rFlagsReg cr) 8595 %{ 8596 match(Set dst (StoreL dst (SubL zero (LoadL dst)))); 8597 effect(KILL cr); 8598 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8599 8600 format %{ "negq $dst\t# long" %} 8601 ins_encode %{ 8602 __ negq($dst$$Address); 8603 %} 8604 ins_pipe(ialu_reg); 8605 %} 8606 8607 //----------Multiplication/Division Instructions------------------------------- 8608 // Integer Multiplication Instructions 8609 // Multiply Register 8610 8611 instruct mulI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8612 %{ 8613 predicate(!UseAPX); 8614 match(Set dst (MulI dst src)); 8615 effect(KILL cr); 8616 8617 ins_cost(300); 8618 format %{ "imull $dst, $src\t# int" %} 8619 ins_encode %{ 8620 __ imull($dst$$Register, $src$$Register); 8621 %} 8622 ins_pipe(ialu_reg_reg_alu0); 8623 %} 8624 8625 instruct mulI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr) 8626 %{ 8627 predicate(UseAPX); 8628 match(Set dst (MulI src1 src2)); 8629 effect(KILL cr); 8630 8631 ins_cost(300); 8632 format %{ "eimull $dst, $src1, $src2\t# int ndd" %} 8633 ins_encode %{ 8634 __ eimull($dst$$Register, $src1$$Register, $src2$$Register, false); 8635 %} 8636 ins_pipe(ialu_reg_reg_alu0); 8637 %} 8638 8639 instruct mulI_rReg_imm(rRegI dst, rRegI src, immI imm, rFlagsReg cr) 8640 %{ 8641 match(Set dst (MulI src imm)); 8642 effect(KILL cr); 8643 8644 ins_cost(300); 8645 format %{ "imull $dst, $src, $imm\t# int" %} 8646 ins_encode %{ 8647 __ imull($dst$$Register, $src$$Register, $imm$$constant); 8648 %} 8649 ins_pipe(ialu_reg_reg_alu0); 8650 %} 8651 8652 instruct mulI_mem(rRegI dst, memory src, rFlagsReg cr) 8653 %{ 8654 predicate(!UseAPX); 8655 match(Set dst (MulI dst (LoadI src))); 8656 effect(KILL cr); 8657 8658 ins_cost(350); 8659 format %{ "imull $dst, $src\t# int" %} 8660 ins_encode %{ 8661 __ imull($dst$$Register, $src$$Address); 8662 %} 8663 ins_pipe(ialu_reg_mem_alu0); 8664 %} 8665 8666 instruct mulI_rReg_rReg_mem_ndd(rRegI dst, rRegI src1, memory src2, rFlagsReg cr) 8667 %{ 8668 predicate(UseAPX); 8669 match(Set dst (MulI src1 (LoadI src2))); 8670 effect(KILL cr); 8671 8672 ins_cost(350); 8673 format %{ "eimull $dst, $src1, $src2\t# int ndd" %} 8674 ins_encode %{ 8675 __ eimull($dst$$Register, $src1$$Register, $src2$$Address, false); 8676 %} 8677 ins_pipe(ialu_reg_mem_alu0); 8678 %} 8679 8680 instruct mulI_mem_imm(rRegI dst, memory src, immI imm, rFlagsReg cr) 8681 %{ 8682 match(Set dst (MulI (LoadI src) imm)); 8683 effect(KILL cr); 8684 8685 ins_cost(300); 8686 format %{ "imull $dst, $src, $imm\t# int" %} 8687 ins_encode %{ 8688 __ imull($dst$$Register, $src$$Address, $imm$$constant); 8689 %} 8690 ins_pipe(ialu_reg_mem_alu0); 8691 %} 8692 8693 instruct mulAddS2I_rReg(rRegI dst, rRegI src1, rRegI src2, rRegI src3, rFlagsReg cr) 8694 %{ 8695 match(Set dst (MulAddS2I (Binary dst src1) (Binary src2 src3))); 8696 effect(KILL cr, KILL src2); 8697 8698 expand %{ mulI_rReg(dst, src1, cr); 8699 mulI_rReg(src2, src3, cr); 8700 addI_rReg(dst, src2, cr); %} 8701 %} 8702 8703 instruct mulL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 8704 %{ 8705 predicate(!UseAPX); 8706 match(Set dst (MulL dst src)); 8707 effect(KILL cr); 8708 8709 ins_cost(300); 8710 format %{ "imulq $dst, $src\t# long" %} 8711 ins_encode %{ 8712 __ imulq($dst$$Register, $src$$Register); 8713 %} 8714 ins_pipe(ialu_reg_reg_alu0); 8715 %} 8716 8717 instruct mulL_rReg_ndd(rRegL dst, rRegL src1, rRegL src2, rFlagsReg cr) 8718 %{ 8719 predicate(UseAPX); 8720 match(Set dst (MulL src1 src2)); 8721 effect(KILL cr); 8722 8723 ins_cost(300); 8724 format %{ "eimulq $dst, $src1, $src2\t# long ndd" %} 8725 ins_encode %{ 8726 __ eimulq($dst$$Register, $src1$$Register, $src2$$Register, false); 8727 %} 8728 ins_pipe(ialu_reg_reg_alu0); 8729 %} 8730 8731 instruct mulL_rReg_imm(rRegL dst, rRegL src, immL32 imm, rFlagsReg cr) 8732 %{ 8733 match(Set dst (MulL src imm)); 8734 effect(KILL cr); 8735 8736 ins_cost(300); 8737 format %{ "imulq $dst, $src, $imm\t# long" %} 8738 ins_encode %{ 8739 __ imulq($dst$$Register, $src$$Register, $imm$$constant); 8740 %} 8741 ins_pipe(ialu_reg_reg_alu0); 8742 %} 8743 8744 instruct mulL_mem(rRegL dst, memory src, rFlagsReg cr) 8745 %{ 8746 predicate(!UseAPX); 8747 match(Set dst (MulL dst (LoadL src))); 8748 effect(KILL cr); 8749 8750 ins_cost(350); 8751 format %{ "imulq $dst, $src\t# long" %} 8752 ins_encode %{ 8753 __ imulq($dst$$Register, $src$$Address); 8754 %} 8755 ins_pipe(ialu_reg_mem_alu0); 8756 %} 8757 8758 instruct mulL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr) 8759 %{ 8760 predicate(UseAPX); 8761 match(Set dst (MulL src1 (LoadL src2))); 8762 effect(KILL cr); 8763 8764 ins_cost(350); 8765 format %{ "eimulq $dst, $src1, $src2 \t# long" %} 8766 ins_encode %{ 8767 __ eimulq($dst$$Register, $src1$$Register, $src2$$Address, false); 8768 %} 8769 ins_pipe(ialu_reg_mem_alu0); 8770 %} 8771 8772 instruct mulL_mem_imm(rRegL dst, memory src, immL32 imm, rFlagsReg cr) 8773 %{ 8774 match(Set dst (MulL (LoadL src) imm)); 8775 effect(KILL cr); 8776 8777 ins_cost(300); 8778 format %{ "imulq $dst, $src, $imm\t# long" %} 8779 ins_encode %{ 8780 __ imulq($dst$$Register, $src$$Address, $imm$$constant); 8781 %} 8782 ins_pipe(ialu_reg_mem_alu0); 8783 %} 8784 8785 instruct mulHiL_rReg(rdx_RegL dst, rRegL src, rax_RegL rax, rFlagsReg cr) 8786 %{ 8787 match(Set dst (MulHiL src rax)); 8788 effect(USE_KILL rax, KILL cr); 8789 8790 ins_cost(300); 8791 format %{ "imulq RDX:RAX, RAX, $src\t# mulhi" %} 8792 ins_encode %{ 8793 __ imulq($src$$Register); 8794 %} 8795 ins_pipe(ialu_reg_reg_alu0); 8796 %} 8797 8798 instruct umulHiL_rReg(rdx_RegL dst, rRegL src, rax_RegL rax, rFlagsReg cr) 8799 %{ 8800 match(Set dst (UMulHiL src rax)); 8801 effect(USE_KILL rax, KILL cr); 8802 8803 ins_cost(300); 8804 format %{ "mulq RDX:RAX, RAX, $src\t# umulhi" %} 8805 ins_encode %{ 8806 __ mulq($src$$Register); 8807 %} 8808 ins_pipe(ialu_reg_reg_alu0); 8809 %} 8810 8811 instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 8812 rFlagsReg cr) 8813 %{ 8814 match(Set rax (DivI rax div)); 8815 effect(KILL rdx, KILL cr); 8816 8817 ins_cost(30*100+10*100); // XXX 8818 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 8819 "jne,s normal\n\t" 8820 "xorl rdx, rdx\n\t" 8821 "cmpl $div, -1\n\t" 8822 "je,s done\n" 8823 "normal: cdql\n\t" 8824 "idivl $div\n" 8825 "done:" %} 8826 ins_encode(cdql_enc(div)); 8827 ins_pipe(ialu_reg_reg_alu0); 8828 %} 8829 8830 instruct divL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 8831 rFlagsReg cr) 8832 %{ 8833 match(Set rax (DivL rax div)); 8834 effect(KILL rdx, KILL cr); 8835 8836 ins_cost(30*100+10*100); // XXX 8837 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 8838 "cmpq rax, rdx\n\t" 8839 "jne,s normal\n\t" 8840 "xorl rdx, rdx\n\t" 8841 "cmpq $div, -1\n\t" 8842 "je,s done\n" 8843 "normal: cdqq\n\t" 8844 "idivq $div\n" 8845 "done:" %} 8846 ins_encode(cdqq_enc(div)); 8847 ins_pipe(ialu_reg_reg_alu0); 8848 %} 8849 8850 instruct udivI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, rFlagsReg cr) 8851 %{ 8852 match(Set rax (UDivI rax div)); 8853 effect(KILL rdx, KILL cr); 8854 8855 ins_cost(300); 8856 format %{ "udivl $rax,$rax,$div\t# UDivI\n" %} 8857 ins_encode %{ 8858 __ udivI($rax$$Register, $div$$Register, $rdx$$Register); 8859 %} 8860 ins_pipe(ialu_reg_reg_alu0); 8861 %} 8862 8863 instruct udivL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, rFlagsReg cr) 8864 %{ 8865 match(Set rax (UDivL rax div)); 8866 effect(KILL rdx, KILL cr); 8867 8868 ins_cost(300); 8869 format %{ "udivq $rax,$rax,$div\t# UDivL\n" %} 8870 ins_encode %{ 8871 __ udivL($rax$$Register, $div$$Register, $rdx$$Register); 8872 %} 8873 ins_pipe(ialu_reg_reg_alu0); 8874 %} 8875 8876 // Integer DIVMOD with Register, both quotient and mod results 8877 instruct divModI_rReg_divmod(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 8878 rFlagsReg cr) 8879 %{ 8880 match(DivModI rax div); 8881 effect(KILL cr); 8882 8883 ins_cost(30*100+10*100); // XXX 8884 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 8885 "jne,s normal\n\t" 8886 "xorl rdx, rdx\n\t" 8887 "cmpl $div, -1\n\t" 8888 "je,s done\n" 8889 "normal: cdql\n\t" 8890 "idivl $div\n" 8891 "done:" %} 8892 ins_encode(cdql_enc(div)); 8893 ins_pipe(pipe_slow); 8894 %} 8895 8896 // Long DIVMOD with Register, both quotient and mod results 8897 instruct divModL_rReg_divmod(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 8898 rFlagsReg cr) 8899 %{ 8900 match(DivModL rax div); 8901 effect(KILL cr); 8902 8903 ins_cost(30*100+10*100); // XXX 8904 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 8905 "cmpq rax, rdx\n\t" 8906 "jne,s normal\n\t" 8907 "xorl rdx, rdx\n\t" 8908 "cmpq $div, -1\n\t" 8909 "je,s done\n" 8910 "normal: cdqq\n\t" 8911 "idivq $div\n" 8912 "done:" %} 8913 ins_encode(cdqq_enc(div)); 8914 ins_pipe(pipe_slow); 8915 %} 8916 8917 // Unsigned integer DIVMOD with Register, both quotient and mod results 8918 instruct udivModI_rReg_divmod(rax_RegI rax, no_rax_rdx_RegI tmp, rdx_RegI rdx, 8919 no_rax_rdx_RegI div, rFlagsReg cr) 8920 %{ 8921 match(UDivModI rax div); 8922 effect(TEMP tmp, KILL cr); 8923 8924 ins_cost(300); 8925 format %{ "udivl $rax,$rax,$div\t# begin UDivModI\n\t" 8926 "umodl $rdx,$rax,$div\t! using $tmp as TEMP # end UDivModI\n" 8927 %} 8928 ins_encode %{ 8929 __ udivmodI($rax$$Register, $div$$Register, $rdx$$Register, $tmp$$Register); 8930 %} 8931 ins_pipe(pipe_slow); 8932 %} 8933 8934 // Unsigned long DIVMOD with Register, both quotient and mod results 8935 instruct udivModL_rReg_divmod(rax_RegL rax, no_rax_rdx_RegL tmp, rdx_RegL rdx, 8936 no_rax_rdx_RegL div, rFlagsReg cr) 8937 %{ 8938 match(UDivModL rax div); 8939 effect(TEMP tmp, KILL cr); 8940 8941 ins_cost(300); 8942 format %{ "udivq $rax,$rax,$div\t# begin UDivModL\n\t" 8943 "umodq $rdx,$rax,$div\t! using $tmp as TEMP # end UDivModL\n" 8944 %} 8945 ins_encode %{ 8946 __ udivmodL($rax$$Register, $div$$Register, $rdx$$Register, $tmp$$Register); 8947 %} 8948 ins_pipe(pipe_slow); 8949 %} 8950 8951 instruct modI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, 8952 rFlagsReg cr) 8953 %{ 8954 match(Set rdx (ModI rax div)); 8955 effect(KILL rax, KILL cr); 8956 8957 ins_cost(300); // XXX 8958 format %{ "cmpl rax, 0x80000000\t# irem\n\t" 8959 "jne,s normal\n\t" 8960 "xorl rdx, rdx\n\t" 8961 "cmpl $div, -1\n\t" 8962 "je,s done\n" 8963 "normal: cdql\n\t" 8964 "idivl $div\n" 8965 "done:" %} 8966 ins_encode(cdql_enc(div)); 8967 ins_pipe(ialu_reg_reg_alu0); 8968 %} 8969 8970 instruct modL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, 8971 rFlagsReg cr) 8972 %{ 8973 match(Set rdx (ModL rax div)); 8974 effect(KILL rax, KILL cr); 8975 8976 ins_cost(300); // XXX 8977 format %{ "movq rdx, 0x8000000000000000\t# lrem\n\t" 8978 "cmpq rax, rdx\n\t" 8979 "jne,s normal\n\t" 8980 "xorl rdx, rdx\n\t" 8981 "cmpq $div, -1\n\t" 8982 "je,s done\n" 8983 "normal: cdqq\n\t" 8984 "idivq $div\n" 8985 "done:" %} 8986 ins_encode(cdqq_enc(div)); 8987 ins_pipe(ialu_reg_reg_alu0); 8988 %} 8989 8990 instruct umodI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, rFlagsReg cr) 8991 %{ 8992 match(Set rdx (UModI rax div)); 8993 effect(KILL rax, KILL cr); 8994 8995 ins_cost(300); 8996 format %{ "umodl $rdx,$rax,$div\t# UModI\n" %} 8997 ins_encode %{ 8998 __ umodI($rax$$Register, $div$$Register, $rdx$$Register); 8999 %} 9000 ins_pipe(ialu_reg_reg_alu0); 9001 %} 9002 9003 instruct umodL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, rFlagsReg cr) 9004 %{ 9005 match(Set rdx (UModL rax div)); 9006 effect(KILL rax, KILL cr); 9007 9008 ins_cost(300); 9009 format %{ "umodq $rdx,$rax,$div\t# UModL\n" %} 9010 ins_encode %{ 9011 __ umodL($rax$$Register, $div$$Register, $rdx$$Register); 9012 %} 9013 ins_pipe(ialu_reg_reg_alu0); 9014 %} 9015 9016 // Integer Shift Instructions 9017 // Shift Left by one, two, three 9018 instruct salI_rReg_immI2(rRegI dst, immI2 shift, rFlagsReg cr) 9019 %{ 9020 predicate(!UseAPX); 9021 match(Set dst (LShiftI dst shift)); 9022 effect(KILL cr); 9023 9024 format %{ "sall $dst, $shift" %} 9025 ins_encode %{ 9026 __ sall($dst$$Register, $shift$$constant); 9027 %} 9028 ins_pipe(ialu_reg); 9029 %} 9030 9031 // Shift Left by one, two, three 9032 instruct salI_rReg_immI2_ndd(rRegI dst, rRegI src, immI2 shift, rFlagsReg cr) 9033 %{ 9034 predicate(UseAPX); 9035 match(Set dst (LShiftI src shift)); 9036 effect(KILL cr); 9037 9038 format %{ "esall $dst, $src, $shift\t# int(ndd)" %} 9039 ins_encode %{ 9040 __ esall($dst$$Register, $src$$Register, $shift$$constant, false); 9041 %} 9042 ins_pipe(ialu_reg); 9043 %} 9044 9045 // Shift Left by 8-bit immediate 9046 instruct salI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 9047 %{ 9048 predicate(!UseAPX); 9049 match(Set dst (LShiftI dst shift)); 9050 effect(KILL cr); 9051 9052 format %{ "sall $dst, $shift" %} 9053 ins_encode %{ 9054 __ sall($dst$$Register, $shift$$constant); 9055 %} 9056 ins_pipe(ialu_reg); 9057 %} 9058 9059 // Shift Left by 8-bit immediate 9060 instruct salI_rReg_imm_ndd(rRegI dst, rRegI src, immI8 shift, rFlagsReg cr) 9061 %{ 9062 predicate(UseAPX); 9063 match(Set dst (LShiftI src shift)); 9064 effect(KILL cr); 9065 9066 format %{ "esall $dst, $src, $shift\t# int (ndd)" %} 9067 ins_encode %{ 9068 __ esall($dst$$Register, $src$$Register, $shift$$constant, false); 9069 %} 9070 ins_pipe(ialu_reg); 9071 %} 9072 9073 instruct salI_rReg_mem_imm_ndd(rRegI dst, memory src, immI8 shift, rFlagsReg cr) 9074 %{ 9075 predicate(UseAPX); 9076 match(Set dst (LShiftI (LoadI src) shift)); 9077 effect(KILL cr); 9078 9079 format %{ "esall $dst, $src, $shift\t# int (ndd)" %} 9080 ins_encode %{ 9081 __ esall($dst$$Register, $src$$Address, $shift$$constant, false); 9082 %} 9083 ins_pipe(ialu_reg); 9084 %} 9085 9086 // Shift Left by 8-bit immediate 9087 instruct salI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 9088 %{ 9089 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 9090 effect(KILL cr); 9091 9092 format %{ "sall $dst, $shift" %} 9093 ins_encode %{ 9094 __ sall($dst$$Address, $shift$$constant); 9095 %} 9096 ins_pipe(ialu_mem_imm); 9097 %} 9098 9099 // Shift Left by variable 9100 instruct salI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 9101 %{ 9102 predicate(!VM_Version::supports_bmi2()); 9103 match(Set dst (LShiftI dst shift)); 9104 effect(KILL cr); 9105 9106 format %{ "sall $dst, $shift" %} 9107 ins_encode %{ 9108 __ sall($dst$$Register); 9109 %} 9110 ins_pipe(ialu_reg_reg); 9111 %} 9112 9113 // Shift Left by variable 9114 instruct salI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 9115 %{ 9116 predicate(!VM_Version::supports_bmi2()); 9117 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 9118 effect(KILL cr); 9119 9120 format %{ "sall $dst, $shift" %} 9121 ins_encode %{ 9122 __ sall($dst$$Address); 9123 %} 9124 ins_pipe(ialu_mem_reg); 9125 %} 9126 9127 instruct salI_rReg_rReg(rRegI dst, rRegI src, rRegI shift) 9128 %{ 9129 predicate(VM_Version::supports_bmi2()); 9130 match(Set dst (LShiftI src shift)); 9131 9132 format %{ "shlxl $dst, $src, $shift" %} 9133 ins_encode %{ 9134 __ shlxl($dst$$Register, $src$$Register, $shift$$Register); 9135 %} 9136 ins_pipe(ialu_reg_reg); 9137 %} 9138 9139 instruct salI_mem_rReg(rRegI dst, memory src, rRegI shift) 9140 %{ 9141 predicate(VM_Version::supports_bmi2()); 9142 match(Set dst (LShiftI (LoadI src) shift)); 9143 ins_cost(175); 9144 format %{ "shlxl $dst, $src, $shift" %} 9145 ins_encode %{ 9146 __ shlxl($dst$$Register, $src$$Address, $shift$$Register); 9147 %} 9148 ins_pipe(ialu_reg_mem); 9149 %} 9150 9151 // Arithmetic Shift Right by 8-bit immediate 9152 instruct sarI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 9153 %{ 9154 predicate(!UseAPX); 9155 match(Set dst (RShiftI dst shift)); 9156 effect(KILL cr); 9157 9158 format %{ "sarl $dst, $shift" %} 9159 ins_encode %{ 9160 __ sarl($dst$$Register, $shift$$constant); 9161 %} 9162 ins_pipe(ialu_mem_imm); 9163 %} 9164 9165 // Arithmetic Shift Right by 8-bit immediate 9166 instruct sarI_rReg_imm_ndd(rRegI dst, rRegI src, immI8 shift, rFlagsReg cr) 9167 %{ 9168 predicate(UseAPX); 9169 match(Set dst (RShiftI src shift)); 9170 effect(KILL cr); 9171 9172 format %{ "esarl $dst, $src, $shift\t# int (ndd)" %} 9173 ins_encode %{ 9174 __ esarl($dst$$Register, $src$$Register, $shift$$constant, false); 9175 %} 9176 ins_pipe(ialu_mem_imm); 9177 %} 9178 9179 instruct sarI_rReg_mem_imm_ndd(rRegI dst, memory src, immI8 shift, rFlagsReg cr) 9180 %{ 9181 predicate(UseAPX); 9182 match(Set dst (RShiftI (LoadI src) shift)); 9183 effect(KILL cr); 9184 9185 format %{ "esarl $dst, $src, $shift\t# int (ndd)" %} 9186 ins_encode %{ 9187 __ esarl($dst$$Register, $src$$Address, $shift$$constant, false); 9188 %} 9189 ins_pipe(ialu_mem_imm); 9190 %} 9191 9192 // Arithmetic Shift Right by 8-bit immediate 9193 instruct sarI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 9194 %{ 9195 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 9196 effect(KILL cr); 9197 9198 format %{ "sarl $dst, $shift" %} 9199 ins_encode %{ 9200 __ sarl($dst$$Address, $shift$$constant); 9201 %} 9202 ins_pipe(ialu_mem_imm); 9203 %} 9204 9205 // Arithmetic Shift Right by variable 9206 instruct sarI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 9207 %{ 9208 predicate(!VM_Version::supports_bmi2()); 9209 match(Set dst (RShiftI dst shift)); 9210 effect(KILL cr); 9211 9212 format %{ "sarl $dst, $shift" %} 9213 ins_encode %{ 9214 __ sarl($dst$$Register); 9215 %} 9216 ins_pipe(ialu_reg_reg); 9217 %} 9218 9219 // Arithmetic Shift Right by variable 9220 instruct sarI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 9221 %{ 9222 predicate(!VM_Version::supports_bmi2()); 9223 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 9224 effect(KILL cr); 9225 9226 format %{ "sarl $dst, $shift" %} 9227 ins_encode %{ 9228 __ sarl($dst$$Address); 9229 %} 9230 ins_pipe(ialu_mem_reg); 9231 %} 9232 9233 instruct sarI_rReg_rReg(rRegI dst, rRegI src, rRegI shift) 9234 %{ 9235 predicate(VM_Version::supports_bmi2()); 9236 match(Set dst (RShiftI src shift)); 9237 9238 format %{ "sarxl $dst, $src, $shift" %} 9239 ins_encode %{ 9240 __ sarxl($dst$$Register, $src$$Register, $shift$$Register); 9241 %} 9242 ins_pipe(ialu_reg_reg); 9243 %} 9244 9245 instruct sarI_mem_rReg(rRegI dst, memory src, rRegI shift) 9246 %{ 9247 predicate(VM_Version::supports_bmi2()); 9248 match(Set dst (RShiftI (LoadI src) shift)); 9249 ins_cost(175); 9250 format %{ "sarxl $dst, $src, $shift" %} 9251 ins_encode %{ 9252 __ sarxl($dst$$Register, $src$$Address, $shift$$Register); 9253 %} 9254 ins_pipe(ialu_reg_mem); 9255 %} 9256 9257 // Logical Shift Right by 8-bit immediate 9258 instruct shrI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 9259 %{ 9260 predicate(!UseAPX); 9261 match(Set dst (URShiftI dst shift)); 9262 effect(KILL cr); 9263 9264 format %{ "shrl $dst, $shift" %} 9265 ins_encode %{ 9266 __ shrl($dst$$Register, $shift$$constant); 9267 %} 9268 ins_pipe(ialu_reg); 9269 %} 9270 9271 // Logical Shift Right by 8-bit immediate 9272 instruct shrI_rReg_imm_ndd(rRegI dst, rRegI src, immI8 shift, rFlagsReg cr) 9273 %{ 9274 predicate(UseAPX); 9275 match(Set dst (URShiftI src shift)); 9276 effect(KILL cr); 9277 9278 format %{ "eshrl $dst, $src, $shift\t # int (ndd)" %} 9279 ins_encode %{ 9280 __ eshrl($dst$$Register, $src$$Register, $shift$$constant, false); 9281 %} 9282 ins_pipe(ialu_reg); 9283 %} 9284 9285 instruct shrI_rReg_mem_imm_ndd(rRegI dst, memory src, immI8 shift, rFlagsReg cr) 9286 %{ 9287 predicate(UseAPX); 9288 match(Set dst (URShiftI (LoadI src) shift)); 9289 effect(KILL cr); 9290 9291 format %{ "eshrl $dst, $src, $shift\t # int (ndd)" %} 9292 ins_encode %{ 9293 __ eshrl($dst$$Register, $src$$Address, $shift$$constant, false); 9294 %} 9295 ins_pipe(ialu_reg); 9296 %} 9297 9298 // Logical Shift Right by 8-bit immediate 9299 instruct shrI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 9300 %{ 9301 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 9302 effect(KILL cr); 9303 9304 format %{ "shrl $dst, $shift" %} 9305 ins_encode %{ 9306 __ shrl($dst$$Address, $shift$$constant); 9307 %} 9308 ins_pipe(ialu_mem_imm); 9309 %} 9310 9311 // Logical Shift Right by variable 9312 instruct shrI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 9313 %{ 9314 predicate(!VM_Version::supports_bmi2()); 9315 match(Set dst (URShiftI dst shift)); 9316 effect(KILL cr); 9317 9318 format %{ "shrl $dst, $shift" %} 9319 ins_encode %{ 9320 __ shrl($dst$$Register); 9321 %} 9322 ins_pipe(ialu_reg_reg); 9323 %} 9324 9325 // Logical Shift Right by variable 9326 instruct shrI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 9327 %{ 9328 predicate(!VM_Version::supports_bmi2()); 9329 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 9330 effect(KILL cr); 9331 9332 format %{ "shrl $dst, $shift" %} 9333 ins_encode %{ 9334 __ shrl($dst$$Address); 9335 %} 9336 ins_pipe(ialu_mem_reg); 9337 %} 9338 9339 instruct shrI_rReg_rReg(rRegI dst, rRegI src, rRegI shift) 9340 %{ 9341 predicate(VM_Version::supports_bmi2()); 9342 match(Set dst (URShiftI src shift)); 9343 9344 format %{ "shrxl $dst, $src, $shift" %} 9345 ins_encode %{ 9346 __ shrxl($dst$$Register, $src$$Register, $shift$$Register); 9347 %} 9348 ins_pipe(ialu_reg_reg); 9349 %} 9350 9351 instruct shrI_mem_rReg(rRegI dst, memory src, rRegI shift) 9352 %{ 9353 predicate(VM_Version::supports_bmi2()); 9354 match(Set dst (URShiftI (LoadI src) shift)); 9355 ins_cost(175); 9356 format %{ "shrxl $dst, $src, $shift" %} 9357 ins_encode %{ 9358 __ shrxl($dst$$Register, $src$$Address, $shift$$Register); 9359 %} 9360 ins_pipe(ialu_reg_mem); 9361 %} 9362 9363 // Long Shift Instructions 9364 // Shift Left by one, two, three 9365 instruct salL_rReg_immI2(rRegL dst, immI2 shift, rFlagsReg cr) 9366 %{ 9367 predicate(!UseAPX); 9368 match(Set dst (LShiftL dst shift)); 9369 effect(KILL cr); 9370 9371 format %{ "salq $dst, $shift" %} 9372 ins_encode %{ 9373 __ salq($dst$$Register, $shift$$constant); 9374 %} 9375 ins_pipe(ialu_reg); 9376 %} 9377 9378 // Shift Left by one, two, three 9379 instruct salL_rReg_immI2_ndd(rRegL dst, rRegL src, immI2 shift, rFlagsReg cr) 9380 %{ 9381 predicate(UseAPX); 9382 match(Set dst (LShiftL src shift)); 9383 effect(KILL cr); 9384 9385 format %{ "esalq $dst, $src, $shift\t# long (ndd)" %} 9386 ins_encode %{ 9387 __ esalq($dst$$Register, $src$$Register, $shift$$constant, false); 9388 %} 9389 ins_pipe(ialu_reg); 9390 %} 9391 9392 // Shift Left by 8-bit immediate 9393 instruct salL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 9394 %{ 9395 predicate(!UseAPX); 9396 match(Set dst (LShiftL dst shift)); 9397 effect(KILL cr); 9398 9399 format %{ "salq $dst, $shift" %} 9400 ins_encode %{ 9401 __ salq($dst$$Register, $shift$$constant); 9402 %} 9403 ins_pipe(ialu_reg); 9404 %} 9405 9406 // Shift Left by 8-bit immediate 9407 instruct salL_rReg_imm_ndd(rRegL dst, rRegL src, immI8 shift, rFlagsReg cr) 9408 %{ 9409 predicate(UseAPX); 9410 match(Set dst (LShiftL src shift)); 9411 effect(KILL cr); 9412 9413 format %{ "esalq $dst, $src, $shift\t# long (ndd)" %} 9414 ins_encode %{ 9415 __ esalq($dst$$Register, $src$$Register, $shift$$constant, false); 9416 %} 9417 ins_pipe(ialu_reg); 9418 %} 9419 9420 instruct salL_rReg_mem_imm_ndd(rRegL dst, memory src, immI8 shift, rFlagsReg cr) 9421 %{ 9422 predicate(UseAPX); 9423 match(Set dst (LShiftL (LoadL src) shift)); 9424 effect(KILL cr); 9425 9426 format %{ "esalq $dst, $src, $shift\t# long (ndd)" %} 9427 ins_encode %{ 9428 __ esalq($dst$$Register, $src$$Address, $shift$$constant, false); 9429 %} 9430 ins_pipe(ialu_reg); 9431 %} 9432 9433 // Shift Left by 8-bit immediate 9434 instruct salL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 9435 %{ 9436 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 9437 effect(KILL cr); 9438 9439 format %{ "salq $dst, $shift" %} 9440 ins_encode %{ 9441 __ salq($dst$$Address, $shift$$constant); 9442 %} 9443 ins_pipe(ialu_mem_imm); 9444 %} 9445 9446 // Shift Left by variable 9447 instruct salL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 9448 %{ 9449 predicate(!VM_Version::supports_bmi2()); 9450 match(Set dst (LShiftL dst shift)); 9451 effect(KILL cr); 9452 9453 format %{ "salq $dst, $shift" %} 9454 ins_encode %{ 9455 __ salq($dst$$Register); 9456 %} 9457 ins_pipe(ialu_reg_reg); 9458 %} 9459 9460 // Shift Left by variable 9461 instruct salL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 9462 %{ 9463 predicate(!VM_Version::supports_bmi2()); 9464 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 9465 effect(KILL cr); 9466 9467 format %{ "salq $dst, $shift" %} 9468 ins_encode %{ 9469 __ salq($dst$$Address); 9470 %} 9471 ins_pipe(ialu_mem_reg); 9472 %} 9473 9474 instruct salL_rReg_rReg(rRegL dst, rRegL src, rRegI shift) 9475 %{ 9476 predicate(VM_Version::supports_bmi2()); 9477 match(Set dst (LShiftL src shift)); 9478 9479 format %{ "shlxq $dst, $src, $shift" %} 9480 ins_encode %{ 9481 __ shlxq($dst$$Register, $src$$Register, $shift$$Register); 9482 %} 9483 ins_pipe(ialu_reg_reg); 9484 %} 9485 9486 instruct salL_mem_rReg(rRegL dst, memory src, rRegI shift) 9487 %{ 9488 predicate(VM_Version::supports_bmi2()); 9489 match(Set dst (LShiftL (LoadL src) shift)); 9490 ins_cost(175); 9491 format %{ "shlxq $dst, $src, $shift" %} 9492 ins_encode %{ 9493 __ shlxq($dst$$Register, $src$$Address, $shift$$Register); 9494 %} 9495 ins_pipe(ialu_reg_mem); 9496 %} 9497 9498 // Arithmetic Shift Right by 8-bit immediate 9499 instruct sarL_rReg_imm(rRegL dst, immI shift, rFlagsReg cr) 9500 %{ 9501 predicate(!UseAPX); 9502 match(Set dst (RShiftL dst shift)); 9503 effect(KILL cr); 9504 9505 format %{ "sarq $dst, $shift" %} 9506 ins_encode %{ 9507 __ sarq($dst$$Register, (unsigned char)($shift$$constant & 0x3F)); 9508 %} 9509 ins_pipe(ialu_mem_imm); 9510 %} 9511 9512 // Arithmetic Shift Right by 8-bit immediate 9513 instruct sarL_rReg_imm_ndd(rRegL dst, rRegL src, immI shift, rFlagsReg cr) 9514 %{ 9515 predicate(UseAPX); 9516 match(Set dst (RShiftL src shift)); 9517 effect(KILL cr); 9518 9519 format %{ "esarq $dst, $src, $shift\t# long (ndd)" %} 9520 ins_encode %{ 9521 __ esarq($dst$$Register, $src$$Register, (unsigned char)($shift$$constant & 0x3F), false); 9522 %} 9523 ins_pipe(ialu_mem_imm); 9524 %} 9525 9526 instruct sarL_rReg_mem_imm_ndd(rRegL dst, memory src, immI shift, rFlagsReg cr) 9527 %{ 9528 predicate(UseAPX); 9529 match(Set dst (RShiftL (LoadL src) shift)); 9530 effect(KILL cr); 9531 9532 format %{ "esarq $dst, $src, $shift\t# long (ndd)" %} 9533 ins_encode %{ 9534 __ esarq($dst$$Register, $src$$Address, (unsigned char)($shift$$constant & 0x3F), false); 9535 %} 9536 ins_pipe(ialu_mem_imm); 9537 %} 9538 9539 // Arithmetic Shift Right by 8-bit immediate 9540 instruct sarL_mem_imm(memory dst, immI shift, rFlagsReg cr) 9541 %{ 9542 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 9543 effect(KILL cr); 9544 9545 format %{ "sarq $dst, $shift" %} 9546 ins_encode %{ 9547 __ sarq($dst$$Address, (unsigned char)($shift$$constant & 0x3F)); 9548 %} 9549 ins_pipe(ialu_mem_imm); 9550 %} 9551 9552 // Arithmetic Shift Right by variable 9553 instruct sarL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 9554 %{ 9555 predicate(!VM_Version::supports_bmi2()); 9556 match(Set dst (RShiftL dst shift)); 9557 effect(KILL cr); 9558 9559 format %{ "sarq $dst, $shift" %} 9560 ins_encode %{ 9561 __ sarq($dst$$Register); 9562 %} 9563 ins_pipe(ialu_reg_reg); 9564 %} 9565 9566 // Arithmetic Shift Right by variable 9567 instruct sarL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 9568 %{ 9569 predicate(!VM_Version::supports_bmi2()); 9570 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 9571 effect(KILL cr); 9572 9573 format %{ "sarq $dst, $shift" %} 9574 ins_encode %{ 9575 __ sarq($dst$$Address); 9576 %} 9577 ins_pipe(ialu_mem_reg); 9578 %} 9579 9580 instruct sarL_rReg_rReg(rRegL dst, rRegL src, rRegI shift) 9581 %{ 9582 predicate(VM_Version::supports_bmi2()); 9583 match(Set dst (RShiftL src shift)); 9584 9585 format %{ "sarxq $dst, $src, $shift" %} 9586 ins_encode %{ 9587 __ sarxq($dst$$Register, $src$$Register, $shift$$Register); 9588 %} 9589 ins_pipe(ialu_reg_reg); 9590 %} 9591 9592 instruct sarL_mem_rReg(rRegL dst, memory src, rRegI shift) 9593 %{ 9594 predicate(VM_Version::supports_bmi2()); 9595 match(Set dst (RShiftL (LoadL src) shift)); 9596 ins_cost(175); 9597 format %{ "sarxq $dst, $src, $shift" %} 9598 ins_encode %{ 9599 __ sarxq($dst$$Register, $src$$Address, $shift$$Register); 9600 %} 9601 ins_pipe(ialu_reg_mem); 9602 %} 9603 9604 // Logical Shift Right by 8-bit immediate 9605 instruct shrL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 9606 %{ 9607 predicate(!UseAPX); 9608 match(Set dst (URShiftL dst shift)); 9609 effect(KILL cr); 9610 9611 format %{ "shrq $dst, $shift" %} 9612 ins_encode %{ 9613 __ shrq($dst$$Register, $shift$$constant); 9614 %} 9615 ins_pipe(ialu_reg); 9616 %} 9617 9618 // Logical Shift Right by 8-bit immediate 9619 instruct shrL_rReg_imm_ndd(rRegL dst, rRegL src, immI8 shift, rFlagsReg cr) 9620 %{ 9621 predicate(UseAPX); 9622 match(Set dst (URShiftL src shift)); 9623 effect(KILL cr); 9624 9625 format %{ "eshrq $dst, $src, $shift\t# long (ndd)" %} 9626 ins_encode %{ 9627 __ eshrq($dst$$Register, $src$$Register, $shift$$constant, false); 9628 %} 9629 ins_pipe(ialu_reg); 9630 %} 9631 9632 instruct shrL_rReg_mem_imm_ndd(rRegL dst, memory src, immI8 shift, rFlagsReg cr) 9633 %{ 9634 predicate(UseAPX); 9635 match(Set dst (URShiftL (LoadL src) shift)); 9636 effect(KILL cr); 9637 9638 format %{ "eshrq $dst, $src, $shift\t# long (ndd)" %} 9639 ins_encode %{ 9640 __ eshrq($dst$$Register, $src$$Address, $shift$$constant, false); 9641 %} 9642 ins_pipe(ialu_reg); 9643 %} 9644 9645 // Logical Shift Right by 8-bit immediate 9646 instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 9647 %{ 9648 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 9649 effect(KILL cr); 9650 9651 format %{ "shrq $dst, $shift" %} 9652 ins_encode %{ 9653 __ shrq($dst$$Address, $shift$$constant); 9654 %} 9655 ins_pipe(ialu_mem_imm); 9656 %} 9657 9658 // Logical Shift Right by variable 9659 instruct shrL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 9660 %{ 9661 predicate(!VM_Version::supports_bmi2()); 9662 match(Set dst (URShiftL dst shift)); 9663 effect(KILL cr); 9664 9665 format %{ "shrq $dst, $shift" %} 9666 ins_encode %{ 9667 __ shrq($dst$$Register); 9668 %} 9669 ins_pipe(ialu_reg_reg); 9670 %} 9671 9672 // Logical Shift Right by variable 9673 instruct shrL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 9674 %{ 9675 predicate(!VM_Version::supports_bmi2()); 9676 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 9677 effect(KILL cr); 9678 9679 format %{ "shrq $dst, $shift" %} 9680 ins_encode %{ 9681 __ shrq($dst$$Address); 9682 %} 9683 ins_pipe(ialu_mem_reg); 9684 %} 9685 9686 instruct shrL_rReg_rReg(rRegL dst, rRegL src, rRegI shift) 9687 %{ 9688 predicate(VM_Version::supports_bmi2()); 9689 match(Set dst (URShiftL src shift)); 9690 9691 format %{ "shrxq $dst, $src, $shift" %} 9692 ins_encode %{ 9693 __ shrxq($dst$$Register, $src$$Register, $shift$$Register); 9694 %} 9695 ins_pipe(ialu_reg_reg); 9696 %} 9697 9698 instruct shrL_mem_rReg(rRegL dst, memory src, rRegI shift) 9699 %{ 9700 predicate(VM_Version::supports_bmi2()); 9701 match(Set dst (URShiftL (LoadL src) shift)); 9702 ins_cost(175); 9703 format %{ "shrxq $dst, $src, $shift" %} 9704 ins_encode %{ 9705 __ shrxq($dst$$Register, $src$$Address, $shift$$Register); 9706 %} 9707 ins_pipe(ialu_reg_mem); 9708 %} 9709 9710 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24. 9711 // This idiom is used by the compiler for the i2b bytecode. 9712 instruct i2b(rRegI dst, rRegI src, immI_24 twentyfour) 9713 %{ 9714 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour)); 9715 9716 format %{ "movsbl $dst, $src\t# i2b" %} 9717 ins_encode %{ 9718 __ movsbl($dst$$Register, $src$$Register); 9719 %} 9720 ins_pipe(ialu_reg_reg); 9721 %} 9722 9723 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16. 9724 // This idiom is used by the compiler the i2s bytecode. 9725 instruct i2s(rRegI dst, rRegI src, immI_16 sixteen) 9726 %{ 9727 match(Set dst (RShiftI (LShiftI src sixteen) sixteen)); 9728 9729 format %{ "movswl $dst, $src\t# i2s" %} 9730 ins_encode %{ 9731 __ movswl($dst$$Register, $src$$Register); 9732 %} 9733 ins_pipe(ialu_reg_reg); 9734 %} 9735 9736 // ROL/ROR instructions 9737 9738 // Rotate left by constant. 9739 instruct rolI_immI8_legacy(rRegI dst, immI8 shift, rFlagsReg cr) 9740 %{ 9741 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 9742 match(Set dst (RotateLeft dst shift)); 9743 effect(KILL cr); 9744 format %{ "roll $dst, $shift" %} 9745 ins_encode %{ 9746 __ roll($dst$$Register, $shift$$constant); 9747 %} 9748 ins_pipe(ialu_reg); 9749 %} 9750 9751 instruct rolI_immI8(rRegI dst, rRegI src, immI8 shift) 9752 %{ 9753 predicate(!UseAPX && VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 9754 match(Set dst (RotateLeft src shift)); 9755 format %{ "rolxl $dst, $src, $shift" %} 9756 ins_encode %{ 9757 int shift = 32 - ($shift$$constant & 31); 9758 __ rorxl($dst$$Register, $src$$Register, shift); 9759 %} 9760 ins_pipe(ialu_reg_reg); 9761 %} 9762 9763 instruct rolI_mem_immI8(rRegI dst, memory src, immI8 shift) 9764 %{ 9765 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 9766 match(Set dst (RotateLeft (LoadI src) shift)); 9767 ins_cost(175); 9768 format %{ "rolxl $dst, $src, $shift" %} 9769 ins_encode %{ 9770 int shift = 32 - ($shift$$constant & 31); 9771 __ rorxl($dst$$Register, $src$$Address, shift); 9772 %} 9773 ins_pipe(ialu_reg_mem); 9774 %} 9775 9776 // Rotate Left by variable 9777 instruct rolI_rReg_Var(rRegI dst, rcx_RegI shift, rFlagsReg cr) 9778 %{ 9779 predicate(!UseAPX && n->bottom_type()->basic_type() == T_INT); 9780 match(Set dst (RotateLeft dst shift)); 9781 effect(KILL cr); 9782 format %{ "roll $dst, $shift" %} 9783 ins_encode %{ 9784 __ roll($dst$$Register); 9785 %} 9786 ins_pipe(ialu_reg_reg); 9787 %} 9788 9789 // Rotate Left by variable 9790 instruct rolI_rReg_Var_ndd(rRegI dst, rRegI src, rcx_RegI shift, rFlagsReg cr) 9791 %{ 9792 predicate(UseAPX && n->bottom_type()->basic_type() == T_INT); 9793 match(Set dst (RotateLeft src shift)); 9794 effect(KILL cr); 9795 9796 format %{ "eroll $dst, $src, $shift\t# rotate left (int ndd)" %} 9797 ins_encode %{ 9798 __ eroll($dst$$Register, $src$$Register, false); 9799 %} 9800 ins_pipe(ialu_reg_reg); 9801 %} 9802 9803 // Rotate Right by constant. 9804 instruct rorI_immI8_legacy(rRegI dst, immI8 shift, rFlagsReg cr) 9805 %{ 9806 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 9807 match(Set dst (RotateRight dst shift)); 9808 effect(KILL cr); 9809 format %{ "rorl $dst, $shift" %} 9810 ins_encode %{ 9811 __ rorl($dst$$Register, $shift$$constant); 9812 %} 9813 ins_pipe(ialu_reg); 9814 %} 9815 9816 // Rotate Right by constant. 9817 instruct rorI_immI8(rRegI dst, rRegI src, immI8 shift) 9818 %{ 9819 predicate(!UseAPX && VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 9820 match(Set dst (RotateRight src shift)); 9821 format %{ "rorxl $dst, $src, $shift" %} 9822 ins_encode %{ 9823 __ rorxl($dst$$Register, $src$$Register, $shift$$constant); 9824 %} 9825 ins_pipe(ialu_reg_reg); 9826 %} 9827 9828 instruct rorI_mem_immI8(rRegI dst, memory src, immI8 shift) 9829 %{ 9830 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 9831 match(Set dst (RotateRight (LoadI src) shift)); 9832 ins_cost(175); 9833 format %{ "rorxl $dst, $src, $shift" %} 9834 ins_encode %{ 9835 __ rorxl($dst$$Register, $src$$Address, $shift$$constant); 9836 %} 9837 ins_pipe(ialu_reg_mem); 9838 %} 9839 9840 // Rotate Right by variable 9841 instruct rorI_rReg_Var(rRegI dst, rcx_RegI shift, rFlagsReg cr) 9842 %{ 9843 predicate(!UseAPX && n->bottom_type()->basic_type() == T_INT); 9844 match(Set dst (RotateRight dst shift)); 9845 effect(KILL cr); 9846 format %{ "rorl $dst, $shift" %} 9847 ins_encode %{ 9848 __ rorl($dst$$Register); 9849 %} 9850 ins_pipe(ialu_reg_reg); 9851 %} 9852 9853 // Rotate Right by variable 9854 instruct rorI_rReg_Var_ndd(rRegI dst, rRegI src, rcx_RegI shift, rFlagsReg cr) 9855 %{ 9856 predicate(UseAPX && n->bottom_type()->basic_type() == T_INT); 9857 match(Set dst (RotateRight src shift)); 9858 effect(KILL cr); 9859 9860 format %{ "erorl $dst, $src, $shift\t# rotate right(int ndd)" %} 9861 ins_encode %{ 9862 __ erorl($dst$$Register, $src$$Register, false); 9863 %} 9864 ins_pipe(ialu_reg_reg); 9865 %} 9866 9867 // Rotate Left by constant. 9868 instruct rolL_immI8_legacy(rRegL dst, immI8 shift, rFlagsReg cr) 9869 %{ 9870 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 9871 match(Set dst (RotateLeft dst shift)); 9872 effect(KILL cr); 9873 format %{ "rolq $dst, $shift" %} 9874 ins_encode %{ 9875 __ rolq($dst$$Register, $shift$$constant); 9876 %} 9877 ins_pipe(ialu_reg); 9878 %} 9879 9880 instruct rolL_immI8(rRegL dst, rRegL src, immI8 shift) 9881 %{ 9882 predicate(!UseAPX && VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 9883 match(Set dst (RotateLeft src shift)); 9884 format %{ "rolxq $dst, $src, $shift" %} 9885 ins_encode %{ 9886 int shift = 64 - ($shift$$constant & 63); 9887 __ rorxq($dst$$Register, $src$$Register, shift); 9888 %} 9889 ins_pipe(ialu_reg_reg); 9890 %} 9891 9892 instruct rolL_mem_immI8(rRegL dst, memory src, immI8 shift) 9893 %{ 9894 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 9895 match(Set dst (RotateLeft (LoadL src) shift)); 9896 ins_cost(175); 9897 format %{ "rolxq $dst, $src, $shift" %} 9898 ins_encode %{ 9899 int shift = 64 - ($shift$$constant & 63); 9900 __ rorxq($dst$$Register, $src$$Address, shift); 9901 %} 9902 ins_pipe(ialu_reg_mem); 9903 %} 9904 9905 // Rotate Left by variable 9906 instruct rolL_rReg_Var(rRegL dst, rcx_RegI shift, rFlagsReg cr) 9907 %{ 9908 predicate(!UseAPX && n->bottom_type()->basic_type() == T_LONG); 9909 match(Set dst (RotateLeft dst shift)); 9910 effect(KILL cr); 9911 format %{ "rolq $dst, $shift" %} 9912 ins_encode %{ 9913 __ rolq($dst$$Register); 9914 %} 9915 ins_pipe(ialu_reg_reg); 9916 %} 9917 9918 // Rotate Left by variable 9919 instruct rolL_rReg_Var_ndd(rRegL dst, rRegL src, rcx_RegI shift, rFlagsReg cr) 9920 %{ 9921 predicate(UseAPX && n->bottom_type()->basic_type() == T_LONG); 9922 match(Set dst (RotateLeft src shift)); 9923 effect(KILL cr); 9924 9925 format %{ "erolq $dst, $src, $shift\t# rotate left(long ndd)" %} 9926 ins_encode %{ 9927 __ erolq($dst$$Register, $src$$Register, false); 9928 %} 9929 ins_pipe(ialu_reg_reg); 9930 %} 9931 9932 // Rotate Right by constant. 9933 instruct rorL_immI8_legacy(rRegL dst, immI8 shift, rFlagsReg cr) 9934 %{ 9935 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 9936 match(Set dst (RotateRight dst shift)); 9937 effect(KILL cr); 9938 format %{ "rorq $dst, $shift" %} 9939 ins_encode %{ 9940 __ rorq($dst$$Register, $shift$$constant); 9941 %} 9942 ins_pipe(ialu_reg); 9943 %} 9944 9945 // Rotate Right by constant 9946 instruct rorL_immI8(rRegL dst, rRegL src, immI8 shift) 9947 %{ 9948 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 9949 match(Set dst (RotateRight src shift)); 9950 format %{ "rorxq $dst, $src, $shift" %} 9951 ins_encode %{ 9952 __ rorxq($dst$$Register, $src$$Register, $shift$$constant); 9953 %} 9954 ins_pipe(ialu_reg_reg); 9955 %} 9956 9957 instruct rorL_mem_immI8(rRegL dst, memory src, immI8 shift) 9958 %{ 9959 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 9960 match(Set dst (RotateRight (LoadL src) shift)); 9961 ins_cost(175); 9962 format %{ "rorxq $dst, $src, $shift" %} 9963 ins_encode %{ 9964 __ rorxq($dst$$Register, $src$$Address, $shift$$constant); 9965 %} 9966 ins_pipe(ialu_reg_mem); 9967 %} 9968 9969 // Rotate Right by variable 9970 instruct rorL_rReg_Var(rRegL dst, rcx_RegI shift, rFlagsReg cr) 9971 %{ 9972 predicate(!UseAPX && n->bottom_type()->basic_type() == T_LONG); 9973 match(Set dst (RotateRight dst shift)); 9974 effect(KILL cr); 9975 format %{ "rorq $dst, $shift" %} 9976 ins_encode %{ 9977 __ rorq($dst$$Register); 9978 %} 9979 ins_pipe(ialu_reg_reg); 9980 %} 9981 9982 // Rotate Right by variable 9983 instruct rorL_rReg_Var_ndd(rRegL dst, rRegL src, rcx_RegI shift, rFlagsReg cr) 9984 %{ 9985 predicate(UseAPX && n->bottom_type()->basic_type() == T_LONG); 9986 match(Set dst (RotateRight src shift)); 9987 effect(KILL cr); 9988 9989 format %{ "erorq $dst, $src, $shift\t# rotate right(long ndd)" %} 9990 ins_encode %{ 9991 __ erorq($dst$$Register, $src$$Register, false); 9992 %} 9993 ins_pipe(ialu_reg_reg); 9994 %} 9995 9996 //----------------------------- CompressBits/ExpandBits ------------------------ 9997 9998 instruct compressBitsL_reg(rRegL dst, rRegL src, rRegL mask) %{ 9999 predicate(n->bottom_type()->isa_long()); 10000 match(Set dst (CompressBits src mask)); 10001 format %{ "pextq $dst, $src, $mask\t! parallel bit extract" %} 10002 ins_encode %{ 10003 __ pextq($dst$$Register, $src$$Register, $mask$$Register); 10004 %} 10005 ins_pipe( pipe_slow ); 10006 %} 10007 10008 instruct expandBitsL_reg(rRegL dst, rRegL src, rRegL mask) %{ 10009 predicate(n->bottom_type()->isa_long()); 10010 match(Set dst (ExpandBits src mask)); 10011 format %{ "pdepq $dst, $src, $mask\t! parallel bit deposit" %} 10012 ins_encode %{ 10013 __ pdepq($dst$$Register, $src$$Register, $mask$$Register); 10014 %} 10015 ins_pipe( pipe_slow ); 10016 %} 10017 10018 instruct compressBitsL_mem(rRegL dst, rRegL src, memory mask) %{ 10019 predicate(n->bottom_type()->isa_long()); 10020 match(Set dst (CompressBits src (LoadL mask))); 10021 format %{ "pextq $dst, $src, $mask\t! parallel bit extract" %} 10022 ins_encode %{ 10023 __ pextq($dst$$Register, $src$$Register, $mask$$Address); 10024 %} 10025 ins_pipe( pipe_slow ); 10026 %} 10027 10028 instruct expandBitsL_mem(rRegL dst, rRegL src, memory mask) %{ 10029 predicate(n->bottom_type()->isa_long()); 10030 match(Set dst (ExpandBits src (LoadL mask))); 10031 format %{ "pdepq $dst, $src, $mask\t! parallel bit deposit" %} 10032 ins_encode %{ 10033 __ pdepq($dst$$Register, $src$$Register, $mask$$Address); 10034 %} 10035 ins_pipe( pipe_slow ); 10036 %} 10037 10038 10039 // Logical Instructions 10040 10041 // Integer Logical Instructions 10042 10043 // And Instructions 10044 // And Register with Register 10045 instruct andI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 10046 %{ 10047 predicate(!UseAPX); 10048 match(Set dst (AndI dst src)); 10049 effect(KILL cr); 10050 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10051 10052 format %{ "andl $dst, $src\t# int" %} 10053 ins_encode %{ 10054 __ andl($dst$$Register, $src$$Register); 10055 %} 10056 ins_pipe(ialu_reg_reg); 10057 %} 10058 10059 // And Register with Register using New Data Destination (NDD) 10060 instruct andI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr) 10061 %{ 10062 predicate(UseAPX); 10063 match(Set dst (AndI src1 src2)); 10064 effect(KILL cr); 10065 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10066 10067 format %{ "eandl $dst, $src1, $src2\t# int ndd" %} 10068 ins_encode %{ 10069 __ eandl($dst$$Register, $src1$$Register, $src2$$Register, false); 10070 10071 %} 10072 ins_pipe(ialu_reg_reg); 10073 %} 10074 10075 // And Register with Immediate 255 10076 instruct andI_rReg_imm255(rRegI dst, rRegI src, immI_255 mask) 10077 %{ 10078 match(Set dst (AndI src mask)); 10079 10080 format %{ "movzbl $dst, $src\t# int & 0xFF" %} 10081 ins_encode %{ 10082 __ movzbl($dst$$Register, $src$$Register); 10083 %} 10084 ins_pipe(ialu_reg); 10085 %} 10086 10087 // And Register with Immediate 255 and promote to long 10088 instruct andI2L_rReg_imm255(rRegL dst, rRegI src, immI_255 mask) 10089 %{ 10090 match(Set dst (ConvI2L (AndI src mask))); 10091 10092 format %{ "movzbl $dst, $src\t# int & 0xFF -> long" %} 10093 ins_encode %{ 10094 __ movzbl($dst$$Register, $src$$Register); 10095 %} 10096 ins_pipe(ialu_reg); 10097 %} 10098 10099 // And Register with Immediate 65535 10100 instruct andI_rReg_imm65535(rRegI dst, rRegI src, immI_65535 mask) 10101 %{ 10102 match(Set dst (AndI src mask)); 10103 10104 format %{ "movzwl $dst, $src\t# int & 0xFFFF" %} 10105 ins_encode %{ 10106 __ movzwl($dst$$Register, $src$$Register); 10107 %} 10108 ins_pipe(ialu_reg); 10109 %} 10110 10111 // And Register with Immediate 65535 and promote to long 10112 instruct andI2L_rReg_imm65535(rRegL dst, rRegI src, immI_65535 mask) 10113 %{ 10114 match(Set dst (ConvI2L (AndI src mask))); 10115 10116 format %{ "movzwl $dst, $src\t# int & 0xFFFF -> long" %} 10117 ins_encode %{ 10118 __ movzwl($dst$$Register, $src$$Register); 10119 %} 10120 ins_pipe(ialu_reg); 10121 %} 10122 10123 // Can skip int2long conversions after AND with small bitmask 10124 instruct convI2LAndI_reg_immIbitmask(rRegL dst, rRegI src, immI_Pow2M1 mask, rRegI tmp, rFlagsReg cr) 10125 %{ 10126 predicate(VM_Version::supports_bmi2()); 10127 ins_cost(125); 10128 effect(TEMP tmp, KILL cr); 10129 match(Set dst (ConvI2L (AndI src mask))); 10130 format %{ "bzhiq $dst, $src, $mask \t# using $tmp as TEMP, int & immI_Pow2M1 -> long" %} 10131 ins_encode %{ 10132 __ movl($tmp$$Register, exact_log2($mask$$constant + 1)); 10133 __ bzhiq($dst$$Register, $src$$Register, $tmp$$Register); 10134 %} 10135 ins_pipe(ialu_reg_reg); 10136 %} 10137 10138 // And Register with Immediate 10139 instruct andI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 10140 %{ 10141 predicate(!UseAPX); 10142 match(Set dst (AndI dst src)); 10143 effect(KILL cr); 10144 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10145 10146 format %{ "andl $dst, $src\t# int" %} 10147 ins_encode %{ 10148 __ andl($dst$$Register, $src$$constant); 10149 %} 10150 ins_pipe(ialu_reg); 10151 %} 10152 10153 instruct andI_rReg_rReg_imm_ndd(rRegI dst, rRegI src1, immI src2, rFlagsReg cr) 10154 %{ 10155 predicate(UseAPX); 10156 match(Set dst (AndI src1 src2)); 10157 effect(KILL cr); 10158 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10159 10160 format %{ "eandl $dst, $src1, $src2\t# int ndd" %} 10161 ins_encode %{ 10162 __ eandl($dst$$Register, $src1$$Register, $src2$$constant, false); 10163 %} 10164 ins_pipe(ialu_reg); 10165 %} 10166 10167 instruct andI_rReg_mem_imm_ndd(rRegI dst, memory src1, immI src2, rFlagsReg cr) 10168 %{ 10169 predicate(UseAPX); 10170 match(Set dst (AndI (LoadI src1) src2)); 10171 effect(KILL cr); 10172 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10173 10174 format %{ "eandl $dst, $src1, $src2\t# int ndd" %} 10175 ins_encode %{ 10176 __ eandl($dst$$Register, $src1$$Address, $src2$$constant, false); 10177 %} 10178 ins_pipe(ialu_reg); 10179 %} 10180 10181 // And Register with Memory 10182 instruct andI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 10183 %{ 10184 predicate(!UseAPX); 10185 match(Set dst (AndI dst (LoadI src))); 10186 effect(KILL cr); 10187 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10188 10189 ins_cost(150); 10190 format %{ "andl $dst, $src\t# int" %} 10191 ins_encode %{ 10192 __ andl($dst$$Register, $src$$Address); 10193 %} 10194 ins_pipe(ialu_reg_mem); 10195 %} 10196 10197 instruct andI_rReg_rReg_mem_ndd(rRegI dst, rRegI src1, memory src2, rFlagsReg cr) 10198 %{ 10199 predicate(UseAPX); 10200 match(Set dst (AndI src1 (LoadI src2))); 10201 effect(KILL cr); 10202 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10203 10204 ins_cost(150); 10205 format %{ "eandl $dst, $src1, $src2\t# int ndd" %} 10206 ins_encode %{ 10207 __ eandl($dst$$Register, $src1$$Register, $src2$$Address, false); 10208 %} 10209 ins_pipe(ialu_reg_mem); 10210 %} 10211 10212 // And Memory with Register 10213 instruct andB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 10214 %{ 10215 match(Set dst (StoreB dst (AndI (LoadB dst) src))); 10216 effect(KILL cr); 10217 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10218 10219 ins_cost(150); 10220 format %{ "andb $dst, $src\t# byte" %} 10221 ins_encode %{ 10222 __ andb($dst$$Address, $src$$Register); 10223 %} 10224 ins_pipe(ialu_mem_reg); 10225 %} 10226 10227 instruct andI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 10228 %{ 10229 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 10230 effect(KILL cr); 10231 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10232 10233 ins_cost(150); 10234 format %{ "andl $dst, $src\t# int" %} 10235 ins_encode %{ 10236 __ andl($dst$$Address, $src$$Register); 10237 %} 10238 ins_pipe(ialu_mem_reg); 10239 %} 10240 10241 // And Memory with Immediate 10242 instruct andI_mem_imm(memory dst, immI src, rFlagsReg cr) 10243 %{ 10244 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 10245 effect(KILL cr); 10246 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10247 10248 ins_cost(125); 10249 format %{ "andl $dst, $src\t# int" %} 10250 ins_encode %{ 10251 __ andl($dst$$Address, $src$$constant); 10252 %} 10253 ins_pipe(ialu_mem_imm); 10254 %} 10255 10256 // BMI1 instructions 10257 instruct andnI_rReg_rReg_mem(rRegI dst, rRegI src1, memory src2, immI_M1 minus_1, rFlagsReg cr) %{ 10258 match(Set dst (AndI (XorI src1 minus_1) (LoadI src2))); 10259 predicate(UseBMI1Instructions); 10260 effect(KILL cr); 10261 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10262 10263 ins_cost(125); 10264 format %{ "andnl $dst, $src1, $src2" %} 10265 10266 ins_encode %{ 10267 __ andnl($dst$$Register, $src1$$Register, $src2$$Address); 10268 %} 10269 ins_pipe(ialu_reg_mem); 10270 %} 10271 10272 instruct andnI_rReg_rReg_rReg(rRegI dst, rRegI src1, rRegI src2, immI_M1 minus_1, rFlagsReg cr) %{ 10273 match(Set dst (AndI (XorI src1 minus_1) src2)); 10274 predicate(UseBMI1Instructions); 10275 effect(KILL cr); 10276 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10277 10278 format %{ "andnl $dst, $src1, $src2" %} 10279 10280 ins_encode %{ 10281 __ andnl($dst$$Register, $src1$$Register, $src2$$Register); 10282 %} 10283 ins_pipe(ialu_reg); 10284 %} 10285 10286 instruct blsiI_rReg_rReg(rRegI dst, rRegI src, immI_0 imm_zero, rFlagsReg cr) %{ 10287 match(Set dst (AndI (SubI imm_zero src) src)); 10288 predicate(UseBMI1Instructions); 10289 effect(KILL cr); 10290 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 10291 10292 format %{ "blsil $dst, $src" %} 10293 10294 ins_encode %{ 10295 __ blsil($dst$$Register, $src$$Register); 10296 %} 10297 ins_pipe(ialu_reg); 10298 %} 10299 10300 instruct blsiI_rReg_mem(rRegI dst, memory src, immI_0 imm_zero, rFlagsReg cr) %{ 10301 match(Set dst (AndI (SubI imm_zero (LoadI src) ) (LoadI src) )); 10302 predicate(UseBMI1Instructions); 10303 effect(KILL cr); 10304 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 10305 10306 ins_cost(125); 10307 format %{ "blsil $dst, $src" %} 10308 10309 ins_encode %{ 10310 __ blsil($dst$$Register, $src$$Address); 10311 %} 10312 ins_pipe(ialu_reg_mem); 10313 %} 10314 10315 instruct blsmskI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 10316 %{ 10317 match(Set dst (XorI (AddI (LoadI src) minus_1) (LoadI src) ) ); 10318 predicate(UseBMI1Instructions); 10319 effect(KILL cr); 10320 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 10321 10322 ins_cost(125); 10323 format %{ "blsmskl $dst, $src" %} 10324 10325 ins_encode %{ 10326 __ blsmskl($dst$$Register, $src$$Address); 10327 %} 10328 ins_pipe(ialu_reg_mem); 10329 %} 10330 10331 instruct blsmskI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 10332 %{ 10333 match(Set dst (XorI (AddI src minus_1) src)); 10334 predicate(UseBMI1Instructions); 10335 effect(KILL cr); 10336 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 10337 10338 format %{ "blsmskl $dst, $src" %} 10339 10340 ins_encode %{ 10341 __ blsmskl($dst$$Register, $src$$Register); 10342 %} 10343 10344 ins_pipe(ialu_reg); 10345 %} 10346 10347 instruct blsrI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 10348 %{ 10349 match(Set dst (AndI (AddI src minus_1) src) ); 10350 predicate(UseBMI1Instructions); 10351 effect(KILL cr); 10352 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 10353 10354 format %{ "blsrl $dst, $src" %} 10355 10356 ins_encode %{ 10357 __ blsrl($dst$$Register, $src$$Register); 10358 %} 10359 10360 ins_pipe(ialu_reg_mem); 10361 %} 10362 10363 instruct blsrI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 10364 %{ 10365 match(Set dst (AndI (AddI (LoadI src) minus_1) (LoadI src) ) ); 10366 predicate(UseBMI1Instructions); 10367 effect(KILL cr); 10368 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 10369 10370 ins_cost(125); 10371 format %{ "blsrl $dst, $src" %} 10372 10373 ins_encode %{ 10374 __ blsrl($dst$$Register, $src$$Address); 10375 %} 10376 10377 ins_pipe(ialu_reg); 10378 %} 10379 10380 // Or Instructions 10381 // Or Register with Register 10382 instruct orI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 10383 %{ 10384 predicate(!UseAPX); 10385 match(Set dst (OrI dst src)); 10386 effect(KILL cr); 10387 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10388 10389 format %{ "orl $dst, $src\t# int" %} 10390 ins_encode %{ 10391 __ orl($dst$$Register, $src$$Register); 10392 %} 10393 ins_pipe(ialu_reg_reg); 10394 %} 10395 10396 // Or Register with Register using New Data Destination (NDD) 10397 instruct orI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr) 10398 %{ 10399 predicate(UseAPX); 10400 match(Set dst (OrI src1 src2)); 10401 effect(KILL cr); 10402 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10403 10404 format %{ "eorl $dst, $src1, $src2\t# int ndd" %} 10405 ins_encode %{ 10406 __ eorl($dst$$Register, $src1$$Register, $src2$$Register, false); 10407 %} 10408 ins_pipe(ialu_reg_reg); 10409 %} 10410 10411 // Or Register with Immediate 10412 instruct orI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 10413 %{ 10414 predicate(!UseAPX); 10415 match(Set dst (OrI dst src)); 10416 effect(KILL cr); 10417 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10418 10419 format %{ "orl $dst, $src\t# int" %} 10420 ins_encode %{ 10421 __ orl($dst$$Register, $src$$constant); 10422 %} 10423 ins_pipe(ialu_reg); 10424 %} 10425 10426 instruct orI_rReg_rReg_imm_ndd(rRegI dst, rRegI src1, immI src2, rFlagsReg cr) 10427 %{ 10428 predicate(UseAPX); 10429 match(Set dst (OrI src1 src2)); 10430 effect(KILL cr); 10431 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10432 10433 format %{ "eorl $dst, $src1, $src2\t# int ndd" %} 10434 ins_encode %{ 10435 __ eorl($dst$$Register, $src1$$Register, $src2$$constant, false); 10436 %} 10437 ins_pipe(ialu_reg); 10438 %} 10439 10440 instruct orI_rReg_imm_rReg_ndd(rRegI dst, immI src1, rRegI src2, rFlagsReg cr) 10441 %{ 10442 predicate(UseAPX); 10443 match(Set dst (OrI src1 src2)); 10444 effect(KILL cr); 10445 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10446 10447 format %{ "eorl $dst, $src2, $src1\t# int ndd" %} 10448 ins_encode %{ 10449 __ eorl($dst$$Register, $src2$$Register, $src1$$constant, false); 10450 %} 10451 ins_pipe(ialu_reg); 10452 %} 10453 10454 instruct orI_rReg_mem_imm_ndd(rRegI dst, memory src1, immI src2, rFlagsReg cr) 10455 %{ 10456 predicate(UseAPX); 10457 match(Set dst (OrI (LoadI src1) src2)); 10458 effect(KILL cr); 10459 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10460 10461 format %{ "eorl $dst, $src1, $src2\t# int ndd" %} 10462 ins_encode %{ 10463 __ eorl($dst$$Register, $src1$$Address, $src2$$constant, false); 10464 %} 10465 ins_pipe(ialu_reg); 10466 %} 10467 10468 // Or Register with Memory 10469 instruct orI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 10470 %{ 10471 predicate(!UseAPX); 10472 match(Set dst (OrI dst (LoadI src))); 10473 effect(KILL cr); 10474 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10475 10476 ins_cost(150); 10477 format %{ "orl $dst, $src\t# int" %} 10478 ins_encode %{ 10479 __ orl($dst$$Register, $src$$Address); 10480 %} 10481 ins_pipe(ialu_reg_mem); 10482 %} 10483 10484 instruct orI_rReg_rReg_mem_ndd(rRegI dst, rRegI src1, memory src2, rFlagsReg cr) 10485 %{ 10486 predicate(UseAPX); 10487 match(Set dst (OrI src1 (LoadI src2))); 10488 effect(KILL cr); 10489 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10490 10491 ins_cost(150); 10492 format %{ "eorl $dst, $src1, $src2\t# int ndd" %} 10493 ins_encode %{ 10494 __ eorl($dst$$Register, $src1$$Register, $src2$$Address, false); 10495 %} 10496 ins_pipe(ialu_reg_mem); 10497 %} 10498 10499 // Or Memory with Register 10500 instruct orB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 10501 %{ 10502 match(Set dst (StoreB dst (OrI (LoadB dst) src))); 10503 effect(KILL cr); 10504 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10505 10506 ins_cost(150); 10507 format %{ "orb $dst, $src\t# byte" %} 10508 ins_encode %{ 10509 __ orb($dst$$Address, $src$$Register); 10510 %} 10511 ins_pipe(ialu_mem_reg); 10512 %} 10513 10514 instruct orI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 10515 %{ 10516 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 10517 effect(KILL cr); 10518 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10519 10520 ins_cost(150); 10521 format %{ "orl $dst, $src\t# int" %} 10522 ins_encode %{ 10523 __ orl($dst$$Address, $src$$Register); 10524 %} 10525 ins_pipe(ialu_mem_reg); 10526 %} 10527 10528 // Or Memory with Immediate 10529 instruct orI_mem_imm(memory dst, immI src, rFlagsReg cr) 10530 %{ 10531 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 10532 effect(KILL cr); 10533 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10534 10535 ins_cost(125); 10536 format %{ "orl $dst, $src\t# int" %} 10537 ins_encode %{ 10538 __ orl($dst$$Address, $src$$constant); 10539 %} 10540 ins_pipe(ialu_mem_imm); 10541 %} 10542 10543 // Xor Instructions 10544 // Xor Register with Register 10545 instruct xorI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 10546 %{ 10547 predicate(!UseAPX); 10548 match(Set dst (XorI dst src)); 10549 effect(KILL cr); 10550 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10551 10552 format %{ "xorl $dst, $src\t# int" %} 10553 ins_encode %{ 10554 __ xorl($dst$$Register, $src$$Register); 10555 %} 10556 ins_pipe(ialu_reg_reg); 10557 %} 10558 10559 // Xor Register with Register using New Data Destination (NDD) 10560 instruct xorI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr) 10561 %{ 10562 predicate(UseAPX); 10563 match(Set dst (XorI src1 src2)); 10564 effect(KILL cr); 10565 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10566 10567 format %{ "exorl $dst, $src1, $src2\t# int ndd" %} 10568 ins_encode %{ 10569 __ exorl($dst$$Register, $src1$$Register, $src2$$Register, false); 10570 %} 10571 ins_pipe(ialu_reg_reg); 10572 %} 10573 10574 // Xor Register with Immediate -1 10575 instruct xorI_rReg_im1(rRegI dst, immI_M1 imm) 10576 %{ 10577 predicate(!UseAPX); 10578 match(Set dst (XorI dst imm)); 10579 10580 format %{ "notl $dst" %} 10581 ins_encode %{ 10582 __ notl($dst$$Register); 10583 %} 10584 ins_pipe(ialu_reg); 10585 %} 10586 10587 instruct xorI_rReg_im1_ndd(rRegI dst, rRegI src, immI_M1 imm) 10588 %{ 10589 match(Set dst (XorI src imm)); 10590 predicate(UseAPX); 10591 10592 format %{ "enotl $dst, $src" %} 10593 ins_encode %{ 10594 __ enotl($dst$$Register, $src$$Register); 10595 %} 10596 ins_pipe(ialu_reg); 10597 %} 10598 10599 // Xor Register with Immediate 10600 instruct xorI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 10601 %{ 10602 // Strict predicate check to make selection of xorI_rReg_im1 cost agnostic if immI src is -1. 10603 predicate(!UseAPX && n->in(2)->bottom_type()->is_int()->get_con() != -1); 10604 match(Set dst (XorI dst src)); 10605 effect(KILL cr); 10606 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10607 10608 format %{ "xorl $dst, $src\t# int" %} 10609 ins_encode %{ 10610 __ xorl($dst$$Register, $src$$constant); 10611 %} 10612 ins_pipe(ialu_reg); 10613 %} 10614 10615 instruct xorI_rReg_rReg_imm_ndd(rRegI dst, rRegI src1, immI src2, rFlagsReg cr) 10616 %{ 10617 // Strict predicate check to make selection of xorI_rReg_im1_ndd cost agnostic if immI src2 is -1. 10618 predicate(UseAPX && n->in(2)->bottom_type()->is_int()->get_con() != -1); 10619 match(Set dst (XorI src1 src2)); 10620 effect(KILL cr); 10621 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10622 10623 format %{ "exorl $dst, $src1, $src2\t# int ndd" %} 10624 ins_encode %{ 10625 __ exorl($dst$$Register, $src1$$Register, $src2$$constant, false); 10626 %} 10627 ins_pipe(ialu_reg); 10628 %} 10629 10630 // Xor Memory with Immediate 10631 instruct xorI_rReg_mem_imm_ndd(rRegI dst, memory src1, immI src2, rFlagsReg cr) 10632 %{ 10633 predicate(UseAPX); 10634 match(Set dst (XorI (LoadI src1) src2)); 10635 effect(KILL cr); 10636 ins_cost(150); 10637 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10638 10639 format %{ "exorl $dst, $src1, $src2\t# int ndd" %} 10640 ins_encode %{ 10641 __ exorl($dst$$Register, $src1$$Address, $src2$$constant, false); 10642 %} 10643 ins_pipe(ialu_reg); 10644 %} 10645 10646 // Xor Register with Memory 10647 instruct xorI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 10648 %{ 10649 predicate(!UseAPX); 10650 match(Set dst (XorI dst (LoadI src))); 10651 effect(KILL cr); 10652 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10653 10654 ins_cost(150); 10655 format %{ "xorl $dst, $src\t# int" %} 10656 ins_encode %{ 10657 __ xorl($dst$$Register, $src$$Address); 10658 %} 10659 ins_pipe(ialu_reg_mem); 10660 %} 10661 10662 instruct xorI_rReg_rReg_mem_ndd(rRegI dst, rRegI src1, memory src2, rFlagsReg cr) 10663 %{ 10664 predicate(UseAPX); 10665 match(Set dst (XorI src1 (LoadI src2))); 10666 effect(KILL cr); 10667 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10668 10669 ins_cost(150); 10670 format %{ "exorl $dst, $src1, $src2\t# int ndd" %} 10671 ins_encode %{ 10672 __ exorl($dst$$Register, $src1$$Register, $src2$$Address, false); 10673 %} 10674 ins_pipe(ialu_reg_mem); 10675 %} 10676 10677 // Xor Memory with Register 10678 instruct xorB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 10679 %{ 10680 match(Set dst (StoreB dst (XorI (LoadB dst) src))); 10681 effect(KILL cr); 10682 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10683 10684 ins_cost(150); 10685 format %{ "xorb $dst, $src\t# byte" %} 10686 ins_encode %{ 10687 __ xorb($dst$$Address, $src$$Register); 10688 %} 10689 ins_pipe(ialu_mem_reg); 10690 %} 10691 10692 instruct xorI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 10693 %{ 10694 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 10695 effect(KILL cr); 10696 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10697 10698 ins_cost(150); 10699 format %{ "xorl $dst, $src\t# int" %} 10700 ins_encode %{ 10701 __ xorl($dst$$Address, $src$$Register); 10702 %} 10703 ins_pipe(ialu_mem_reg); 10704 %} 10705 10706 // Xor Memory with Immediate 10707 instruct xorI_mem_imm(memory dst, immI src, rFlagsReg cr) 10708 %{ 10709 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 10710 effect(KILL cr); 10711 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10712 10713 ins_cost(125); 10714 format %{ "xorl $dst, $src\t# int" %} 10715 ins_encode %{ 10716 __ xorl($dst$$Address, $src$$constant); 10717 %} 10718 ins_pipe(ialu_mem_imm); 10719 %} 10720 10721 10722 // Long Logical Instructions 10723 10724 // And Instructions 10725 // And Register with Register 10726 instruct andL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 10727 %{ 10728 predicate(!UseAPX); 10729 match(Set dst (AndL dst src)); 10730 effect(KILL cr); 10731 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10732 10733 format %{ "andq $dst, $src\t# long" %} 10734 ins_encode %{ 10735 __ andq($dst$$Register, $src$$Register); 10736 %} 10737 ins_pipe(ialu_reg_reg); 10738 %} 10739 10740 // And Register with Register using New Data Destination (NDD) 10741 instruct andL_rReg_ndd(rRegL dst, rRegL src1, rRegL src2, rFlagsReg cr) 10742 %{ 10743 predicate(UseAPX); 10744 match(Set dst (AndL src1 src2)); 10745 effect(KILL cr); 10746 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10747 10748 format %{ "eandq $dst, $src1, $src2\t# long ndd" %} 10749 ins_encode %{ 10750 __ eandq($dst$$Register, $src1$$Register, $src2$$Register, false); 10751 10752 %} 10753 ins_pipe(ialu_reg_reg); 10754 %} 10755 10756 // And Register with Immediate 255 10757 instruct andL_rReg_imm255(rRegL dst, rRegL src, immL_255 mask) 10758 %{ 10759 match(Set dst (AndL src mask)); 10760 10761 format %{ "movzbl $dst, $src\t# long & 0xFF" %} 10762 ins_encode %{ 10763 // movzbl zeroes out the upper 32-bit and does not need REX.W 10764 __ movzbl($dst$$Register, $src$$Register); 10765 %} 10766 ins_pipe(ialu_reg); 10767 %} 10768 10769 // And Register with Immediate 65535 10770 instruct andL_rReg_imm65535(rRegL dst, rRegL src, immL_65535 mask) 10771 %{ 10772 match(Set dst (AndL src mask)); 10773 10774 format %{ "movzwl $dst, $src\t# long & 0xFFFF" %} 10775 ins_encode %{ 10776 // movzwl zeroes out the upper 32-bit and does not need REX.W 10777 __ movzwl($dst$$Register, $src$$Register); 10778 %} 10779 ins_pipe(ialu_reg); 10780 %} 10781 10782 // And Register with Immediate 10783 instruct andL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 10784 %{ 10785 predicate(!UseAPX); 10786 match(Set dst (AndL dst src)); 10787 effect(KILL cr); 10788 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10789 10790 format %{ "andq $dst, $src\t# long" %} 10791 ins_encode %{ 10792 __ andq($dst$$Register, $src$$constant); 10793 %} 10794 ins_pipe(ialu_reg); 10795 %} 10796 10797 instruct andL_rReg_rReg_imm_ndd(rRegL dst, rRegL src1, immL32 src2, rFlagsReg cr) 10798 %{ 10799 predicate(UseAPX); 10800 match(Set dst (AndL src1 src2)); 10801 effect(KILL cr); 10802 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10803 10804 format %{ "eandq $dst, $src1, $src2\t# long ndd" %} 10805 ins_encode %{ 10806 __ eandq($dst$$Register, $src1$$Register, $src2$$constant, false); 10807 %} 10808 ins_pipe(ialu_reg); 10809 %} 10810 10811 instruct andL_rReg_mem_imm_ndd(rRegL dst, memory src1, immL32 src2, rFlagsReg cr) 10812 %{ 10813 predicate(UseAPX); 10814 match(Set dst (AndL (LoadL src1) src2)); 10815 effect(KILL cr); 10816 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10817 10818 format %{ "eandq $dst, $src1, $src2\t# long ndd" %} 10819 ins_encode %{ 10820 __ eandq($dst$$Register, $src1$$Address, $src2$$constant, false); 10821 %} 10822 ins_pipe(ialu_reg); 10823 %} 10824 10825 // And Register with Memory 10826 instruct andL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 10827 %{ 10828 predicate(!UseAPX); 10829 match(Set dst (AndL dst (LoadL src))); 10830 effect(KILL cr); 10831 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10832 10833 ins_cost(150); 10834 format %{ "andq $dst, $src\t# long" %} 10835 ins_encode %{ 10836 __ andq($dst$$Register, $src$$Address); 10837 %} 10838 ins_pipe(ialu_reg_mem); 10839 %} 10840 10841 instruct andL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr) 10842 %{ 10843 predicate(UseAPX); 10844 match(Set dst (AndL src1 (LoadL src2))); 10845 effect(KILL cr); 10846 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10847 10848 ins_cost(150); 10849 format %{ "eandq $dst, $src1, $src2\t# long ndd" %} 10850 ins_encode %{ 10851 __ eandq($dst$$Register, $src1$$Register, $src2$$Address, false); 10852 %} 10853 ins_pipe(ialu_reg_mem); 10854 %} 10855 10856 // And Memory with Register 10857 instruct andL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 10858 %{ 10859 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 10860 effect(KILL cr); 10861 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10862 10863 ins_cost(150); 10864 format %{ "andq $dst, $src\t# long" %} 10865 ins_encode %{ 10866 __ andq($dst$$Address, $src$$Register); 10867 %} 10868 ins_pipe(ialu_mem_reg); 10869 %} 10870 10871 // And Memory with Immediate 10872 instruct andL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 10873 %{ 10874 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 10875 effect(KILL cr); 10876 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10877 10878 ins_cost(125); 10879 format %{ "andq $dst, $src\t# long" %} 10880 ins_encode %{ 10881 __ andq($dst$$Address, $src$$constant); 10882 %} 10883 ins_pipe(ialu_mem_imm); 10884 %} 10885 10886 instruct btrL_mem_imm(memory dst, immL_NotPow2 con, rFlagsReg cr) 10887 %{ 10888 // con should be a pure 64-bit immediate given that not(con) is a power of 2 10889 // because AND/OR works well enough for 8/32-bit values. 10890 predicate(log2i_graceful(~n->in(3)->in(2)->get_long()) > 30); 10891 10892 match(Set dst (StoreL dst (AndL (LoadL dst) con))); 10893 effect(KILL cr); 10894 10895 ins_cost(125); 10896 format %{ "btrq $dst, log2(not($con))\t# long" %} 10897 ins_encode %{ 10898 __ btrq($dst$$Address, log2i_exact((julong)~$con$$constant)); 10899 %} 10900 ins_pipe(ialu_mem_imm); 10901 %} 10902 10903 // BMI1 instructions 10904 instruct andnL_rReg_rReg_mem(rRegL dst, rRegL src1, memory src2, immL_M1 minus_1, rFlagsReg cr) %{ 10905 match(Set dst (AndL (XorL src1 minus_1) (LoadL src2))); 10906 predicate(UseBMI1Instructions); 10907 effect(KILL cr); 10908 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10909 10910 ins_cost(125); 10911 format %{ "andnq $dst, $src1, $src2" %} 10912 10913 ins_encode %{ 10914 __ andnq($dst$$Register, $src1$$Register, $src2$$Address); 10915 %} 10916 ins_pipe(ialu_reg_mem); 10917 %} 10918 10919 instruct andnL_rReg_rReg_rReg(rRegL dst, rRegL src1, rRegL src2, immL_M1 minus_1, rFlagsReg cr) %{ 10920 match(Set dst (AndL (XorL src1 minus_1) src2)); 10921 predicate(UseBMI1Instructions); 10922 effect(KILL cr); 10923 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10924 10925 format %{ "andnq $dst, $src1, $src2" %} 10926 10927 ins_encode %{ 10928 __ andnq($dst$$Register, $src1$$Register, $src2$$Register); 10929 %} 10930 ins_pipe(ialu_reg_mem); 10931 %} 10932 10933 instruct blsiL_rReg_rReg(rRegL dst, rRegL src, immL0 imm_zero, rFlagsReg cr) %{ 10934 match(Set dst (AndL (SubL imm_zero src) src)); 10935 predicate(UseBMI1Instructions); 10936 effect(KILL cr); 10937 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 10938 10939 format %{ "blsiq $dst, $src" %} 10940 10941 ins_encode %{ 10942 __ blsiq($dst$$Register, $src$$Register); 10943 %} 10944 ins_pipe(ialu_reg); 10945 %} 10946 10947 instruct blsiL_rReg_mem(rRegL dst, memory src, immL0 imm_zero, rFlagsReg cr) %{ 10948 match(Set dst (AndL (SubL imm_zero (LoadL src) ) (LoadL src) )); 10949 predicate(UseBMI1Instructions); 10950 effect(KILL cr); 10951 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 10952 10953 ins_cost(125); 10954 format %{ "blsiq $dst, $src" %} 10955 10956 ins_encode %{ 10957 __ blsiq($dst$$Register, $src$$Address); 10958 %} 10959 ins_pipe(ialu_reg_mem); 10960 %} 10961 10962 instruct blsmskL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 10963 %{ 10964 match(Set dst (XorL (AddL (LoadL src) minus_1) (LoadL src) ) ); 10965 predicate(UseBMI1Instructions); 10966 effect(KILL cr); 10967 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 10968 10969 ins_cost(125); 10970 format %{ "blsmskq $dst, $src" %} 10971 10972 ins_encode %{ 10973 __ blsmskq($dst$$Register, $src$$Address); 10974 %} 10975 ins_pipe(ialu_reg_mem); 10976 %} 10977 10978 instruct blsmskL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 10979 %{ 10980 match(Set dst (XorL (AddL src minus_1) src)); 10981 predicate(UseBMI1Instructions); 10982 effect(KILL cr); 10983 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 10984 10985 format %{ "blsmskq $dst, $src" %} 10986 10987 ins_encode %{ 10988 __ blsmskq($dst$$Register, $src$$Register); 10989 %} 10990 10991 ins_pipe(ialu_reg); 10992 %} 10993 10994 instruct blsrL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 10995 %{ 10996 match(Set dst (AndL (AddL src minus_1) src) ); 10997 predicate(UseBMI1Instructions); 10998 effect(KILL cr); 10999 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 11000 11001 format %{ "blsrq $dst, $src" %} 11002 11003 ins_encode %{ 11004 __ blsrq($dst$$Register, $src$$Register); 11005 %} 11006 11007 ins_pipe(ialu_reg); 11008 %} 11009 11010 instruct blsrL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 11011 %{ 11012 match(Set dst (AndL (AddL (LoadL src) minus_1) (LoadL src)) ); 11013 predicate(UseBMI1Instructions); 11014 effect(KILL cr); 11015 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 11016 11017 ins_cost(125); 11018 format %{ "blsrq $dst, $src" %} 11019 11020 ins_encode %{ 11021 __ blsrq($dst$$Register, $src$$Address); 11022 %} 11023 11024 ins_pipe(ialu_reg); 11025 %} 11026 11027 // Or Instructions 11028 // Or Register with Register 11029 instruct orL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 11030 %{ 11031 predicate(!UseAPX); 11032 match(Set dst (OrL dst src)); 11033 effect(KILL cr); 11034 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11035 11036 format %{ "orq $dst, $src\t# long" %} 11037 ins_encode %{ 11038 __ orq($dst$$Register, $src$$Register); 11039 %} 11040 ins_pipe(ialu_reg_reg); 11041 %} 11042 11043 // Or Register with Register using New Data Destination (NDD) 11044 instruct orL_rReg_ndd(rRegL dst, rRegL src1, rRegL src2, rFlagsReg cr) 11045 %{ 11046 predicate(UseAPX); 11047 match(Set dst (OrL src1 src2)); 11048 effect(KILL cr); 11049 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11050 11051 format %{ "eorq $dst, $src1, $src2\t# long ndd" %} 11052 ins_encode %{ 11053 __ eorq($dst$$Register, $src1$$Register, $src2$$Register, false); 11054 11055 %} 11056 ins_pipe(ialu_reg_reg); 11057 %} 11058 11059 // Use any_RegP to match R15 (TLS register) without spilling. 11060 instruct orL_rReg_castP2X(rRegL dst, any_RegP src, rFlagsReg cr) %{ 11061 match(Set dst (OrL dst (CastP2X src))); 11062 effect(KILL cr); 11063 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11064 11065 format %{ "orq $dst, $src\t# long" %} 11066 ins_encode %{ 11067 __ orq($dst$$Register, $src$$Register); 11068 %} 11069 ins_pipe(ialu_reg_reg); 11070 %} 11071 11072 instruct orL_rReg_castP2X_ndd(rRegL dst, any_RegP src1, any_RegP src2, rFlagsReg cr) %{ 11073 match(Set dst (OrL src1 (CastP2X src2))); 11074 effect(KILL cr); 11075 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11076 11077 format %{ "eorq $dst, $src1, $src2\t# long ndd" %} 11078 ins_encode %{ 11079 __ eorq($dst$$Register, $src1$$Register, $src2$$Register, false); 11080 %} 11081 ins_pipe(ialu_reg_reg); 11082 %} 11083 11084 // Or Register with Immediate 11085 instruct orL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 11086 %{ 11087 predicate(!UseAPX); 11088 match(Set dst (OrL dst src)); 11089 effect(KILL cr); 11090 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11091 11092 format %{ "orq $dst, $src\t# long" %} 11093 ins_encode %{ 11094 __ orq($dst$$Register, $src$$constant); 11095 %} 11096 ins_pipe(ialu_reg); 11097 %} 11098 11099 instruct orL_rReg_rReg_imm_ndd(rRegL dst, rRegL src1, immL32 src2, rFlagsReg cr) 11100 %{ 11101 predicate(UseAPX); 11102 match(Set dst (OrL src1 src2)); 11103 effect(KILL cr); 11104 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11105 11106 format %{ "eorq $dst, $src1, $src2\t# long ndd" %} 11107 ins_encode %{ 11108 __ eorq($dst$$Register, $src1$$Register, $src2$$constant, false); 11109 %} 11110 ins_pipe(ialu_reg); 11111 %} 11112 11113 instruct orL_rReg_imm_rReg_ndd(rRegL dst, immL32 src1, rRegL src2, rFlagsReg cr) 11114 %{ 11115 predicate(UseAPX); 11116 match(Set dst (OrL src1 src2)); 11117 effect(KILL cr); 11118 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11119 11120 format %{ "eorq $dst, $src2, $src1\t# long ndd" %} 11121 ins_encode %{ 11122 __ eorq($dst$$Register, $src2$$Register, $src1$$constant, false); 11123 %} 11124 ins_pipe(ialu_reg); 11125 %} 11126 11127 // Or Memory with Immediate 11128 instruct orL_rReg_mem_imm_ndd(rRegL dst, memory src1, immL32 src2, rFlagsReg cr) 11129 %{ 11130 predicate(UseAPX); 11131 match(Set dst (OrL (LoadL src1) src2)); 11132 effect(KILL cr); 11133 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11134 11135 format %{ "eorq $dst, $src1, $src2\t# long ndd" %} 11136 ins_encode %{ 11137 __ eorq($dst$$Register, $src1$$Address, $src2$$constant, false); 11138 %} 11139 ins_pipe(ialu_reg); 11140 %} 11141 11142 // Or Register with Memory 11143 instruct orL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 11144 %{ 11145 predicate(!UseAPX); 11146 match(Set dst (OrL dst (LoadL src))); 11147 effect(KILL cr); 11148 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11149 11150 ins_cost(150); 11151 format %{ "orq $dst, $src\t# long" %} 11152 ins_encode %{ 11153 __ orq($dst$$Register, $src$$Address); 11154 %} 11155 ins_pipe(ialu_reg_mem); 11156 %} 11157 11158 instruct orL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr) 11159 %{ 11160 predicate(UseAPX); 11161 match(Set dst (OrL src1 (LoadL src2))); 11162 effect(KILL cr); 11163 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11164 11165 ins_cost(150); 11166 format %{ "eorq $dst, $src1, $src2\t# long ndd" %} 11167 ins_encode %{ 11168 __ eorq($dst$$Register, $src1$$Register, $src2$$Address, false); 11169 %} 11170 ins_pipe(ialu_reg_mem); 11171 %} 11172 11173 // Or Memory with Register 11174 instruct orL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 11175 %{ 11176 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 11177 effect(KILL cr); 11178 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11179 11180 ins_cost(150); 11181 format %{ "orq $dst, $src\t# long" %} 11182 ins_encode %{ 11183 __ orq($dst$$Address, $src$$Register); 11184 %} 11185 ins_pipe(ialu_mem_reg); 11186 %} 11187 11188 // Or Memory with Immediate 11189 instruct orL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 11190 %{ 11191 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 11192 effect(KILL cr); 11193 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11194 11195 ins_cost(125); 11196 format %{ "orq $dst, $src\t# long" %} 11197 ins_encode %{ 11198 __ orq($dst$$Address, $src$$constant); 11199 %} 11200 ins_pipe(ialu_mem_imm); 11201 %} 11202 11203 instruct btsL_mem_imm(memory dst, immL_Pow2 con, rFlagsReg cr) 11204 %{ 11205 // con should be a pure 64-bit power of 2 immediate 11206 // because AND/OR works well enough for 8/32-bit values. 11207 predicate(log2i_graceful(n->in(3)->in(2)->get_long()) > 31); 11208 11209 match(Set dst (StoreL dst (OrL (LoadL dst) con))); 11210 effect(KILL cr); 11211 11212 ins_cost(125); 11213 format %{ "btsq $dst, log2($con)\t# long" %} 11214 ins_encode %{ 11215 __ btsq($dst$$Address, log2i_exact((julong)$con$$constant)); 11216 %} 11217 ins_pipe(ialu_mem_imm); 11218 %} 11219 11220 // Xor Instructions 11221 // Xor Register with Register 11222 instruct xorL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 11223 %{ 11224 predicate(!UseAPX); 11225 match(Set dst (XorL dst src)); 11226 effect(KILL cr); 11227 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11228 11229 format %{ "xorq $dst, $src\t# long" %} 11230 ins_encode %{ 11231 __ xorq($dst$$Register, $src$$Register); 11232 %} 11233 ins_pipe(ialu_reg_reg); 11234 %} 11235 11236 // Xor Register with Register using New Data Destination (NDD) 11237 instruct xorL_rReg_ndd(rRegL dst, rRegL src1, rRegL src2, rFlagsReg cr) 11238 %{ 11239 predicate(UseAPX); 11240 match(Set dst (XorL src1 src2)); 11241 effect(KILL cr); 11242 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11243 11244 format %{ "exorq $dst, $src1, $src2\t# long ndd" %} 11245 ins_encode %{ 11246 __ exorq($dst$$Register, $src1$$Register, $src2$$Register, false); 11247 %} 11248 ins_pipe(ialu_reg_reg); 11249 %} 11250 11251 // Xor Register with Immediate -1 11252 instruct xorL_rReg_im1(rRegL dst, immL_M1 imm) 11253 %{ 11254 predicate(!UseAPX); 11255 match(Set dst (XorL dst imm)); 11256 11257 format %{ "notq $dst" %} 11258 ins_encode %{ 11259 __ notq($dst$$Register); 11260 %} 11261 ins_pipe(ialu_reg); 11262 %} 11263 11264 instruct xorL_rReg_im1_ndd(rRegL dst,rRegL src, immL_M1 imm) 11265 %{ 11266 predicate(UseAPX); 11267 match(Set dst (XorL src imm)); 11268 11269 format %{ "enotq $dst, $src" %} 11270 ins_encode %{ 11271 __ enotq($dst$$Register, $src$$Register); 11272 %} 11273 ins_pipe(ialu_reg); 11274 %} 11275 11276 // Xor Register with Immediate 11277 instruct xorL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 11278 %{ 11279 // Strict predicate check to make selection of xorL_rReg_im1 cost agnostic if immL32 src is -1. 11280 predicate(!UseAPX && n->in(2)->bottom_type()->is_long()->get_con() != -1L); 11281 match(Set dst (XorL dst src)); 11282 effect(KILL cr); 11283 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11284 11285 format %{ "xorq $dst, $src\t# long" %} 11286 ins_encode %{ 11287 __ xorq($dst$$Register, $src$$constant); 11288 %} 11289 ins_pipe(ialu_reg); 11290 %} 11291 11292 instruct xorL_rReg_rReg_imm(rRegL dst, rRegL src1, immL32 src2, rFlagsReg cr) 11293 %{ 11294 // Strict predicate check to make selection of xorL_rReg_im1_ndd cost agnostic if immL32 src2 is -1. 11295 predicate(UseAPX && n->in(2)->bottom_type()->is_long()->get_con() != -1L); 11296 match(Set dst (XorL src1 src2)); 11297 effect(KILL cr); 11298 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11299 11300 format %{ "exorq $dst, $src1, $src2\t# long ndd" %} 11301 ins_encode %{ 11302 __ exorq($dst$$Register, $src1$$Register, $src2$$constant, false); 11303 %} 11304 ins_pipe(ialu_reg); 11305 %} 11306 11307 // Xor Memory with Immediate 11308 instruct xorL_rReg_mem_imm(rRegL dst, memory src1, immL32 src2, rFlagsReg cr) 11309 %{ 11310 predicate(UseAPX); 11311 match(Set dst (XorL (LoadL src1) src2)); 11312 effect(KILL cr); 11313 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11314 ins_cost(150); 11315 11316 format %{ "exorq $dst, $src1, $src2\t# long ndd" %} 11317 ins_encode %{ 11318 __ exorq($dst$$Register, $src1$$Address, $src2$$constant, false); 11319 %} 11320 ins_pipe(ialu_reg); 11321 %} 11322 11323 // Xor Register with Memory 11324 instruct xorL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 11325 %{ 11326 predicate(!UseAPX); 11327 match(Set dst (XorL dst (LoadL src))); 11328 effect(KILL cr); 11329 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11330 11331 ins_cost(150); 11332 format %{ "xorq $dst, $src\t# long" %} 11333 ins_encode %{ 11334 __ xorq($dst$$Register, $src$$Address); 11335 %} 11336 ins_pipe(ialu_reg_mem); 11337 %} 11338 11339 instruct xorL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr) 11340 %{ 11341 predicate(UseAPX); 11342 match(Set dst (XorL src1 (LoadL src2))); 11343 effect(KILL cr); 11344 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11345 11346 ins_cost(150); 11347 format %{ "exorq $dst, $src1, $src2\t# long ndd" %} 11348 ins_encode %{ 11349 __ exorq($dst$$Register, $src1$$Register, $src2$$Address, false); 11350 %} 11351 ins_pipe(ialu_reg_mem); 11352 %} 11353 11354 // Xor Memory with Register 11355 instruct xorL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 11356 %{ 11357 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 11358 effect(KILL cr); 11359 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11360 11361 ins_cost(150); 11362 format %{ "xorq $dst, $src\t# long" %} 11363 ins_encode %{ 11364 __ xorq($dst$$Address, $src$$Register); 11365 %} 11366 ins_pipe(ialu_mem_reg); 11367 %} 11368 11369 // Xor Memory with Immediate 11370 instruct xorL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 11371 %{ 11372 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 11373 effect(KILL cr); 11374 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11375 11376 ins_cost(125); 11377 format %{ "xorq $dst, $src\t# long" %} 11378 ins_encode %{ 11379 __ xorq($dst$$Address, $src$$constant); 11380 %} 11381 ins_pipe(ialu_mem_imm); 11382 %} 11383 11384 instruct cmpLTMask(rRegI dst, rRegI p, rRegI q, rFlagsReg cr) 11385 %{ 11386 match(Set dst (CmpLTMask p q)); 11387 effect(KILL cr); 11388 11389 ins_cost(400); 11390 format %{ "cmpl $p, $q\t# cmpLTMask\n\t" 11391 "setcc $dst \t# emits setlt + movzbl or setzul for APX" 11392 "negl $dst" %} 11393 ins_encode %{ 11394 __ cmpl($p$$Register, $q$$Register); 11395 __ setcc(Assembler::less, $dst$$Register); 11396 __ negl($dst$$Register); 11397 %} 11398 ins_pipe(pipe_slow); 11399 %} 11400 11401 instruct cmpLTMask0(rRegI dst, immI_0 zero, rFlagsReg cr) 11402 %{ 11403 match(Set dst (CmpLTMask dst zero)); 11404 effect(KILL cr); 11405 11406 ins_cost(100); 11407 format %{ "sarl $dst, #31\t# cmpLTMask0" %} 11408 ins_encode %{ 11409 __ sarl($dst$$Register, 31); 11410 %} 11411 ins_pipe(ialu_reg); 11412 %} 11413 11414 /* Better to save a register than avoid a branch */ 11415 instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 11416 %{ 11417 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q))); 11418 effect(KILL cr); 11419 ins_cost(300); 11420 format %{ "subl $p,$q\t# cadd_cmpLTMask\n\t" 11421 "jge done\n\t" 11422 "addl $p,$y\n" 11423 "done: " %} 11424 ins_encode %{ 11425 Register Rp = $p$$Register; 11426 Register Rq = $q$$Register; 11427 Register Ry = $y$$Register; 11428 Label done; 11429 __ subl(Rp, Rq); 11430 __ jccb(Assembler::greaterEqual, done); 11431 __ addl(Rp, Ry); 11432 __ bind(done); 11433 %} 11434 ins_pipe(pipe_cmplt); 11435 %} 11436 11437 /* Better to save a register than avoid a branch */ 11438 instruct and_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 11439 %{ 11440 match(Set y (AndI (CmpLTMask p q) y)); 11441 effect(KILL cr); 11442 11443 ins_cost(300); 11444 11445 format %{ "cmpl $p, $q\t# and_cmpLTMask\n\t" 11446 "jlt done\n\t" 11447 "xorl $y, $y\n" 11448 "done: " %} 11449 ins_encode %{ 11450 Register Rp = $p$$Register; 11451 Register Rq = $q$$Register; 11452 Register Ry = $y$$Register; 11453 Label done; 11454 __ cmpl(Rp, Rq); 11455 __ jccb(Assembler::less, done); 11456 __ xorl(Ry, Ry); 11457 __ bind(done); 11458 %} 11459 ins_pipe(pipe_cmplt); 11460 %} 11461 11462 11463 //---------- FP Instructions------------------------------------------------ 11464 11465 // Really expensive, avoid 11466 instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2) 11467 %{ 11468 match(Set cr (CmpF src1 src2)); 11469 11470 ins_cost(500); 11471 format %{ "ucomiss $src1, $src2\n\t" 11472 "jnp,s exit\n\t" 11473 "pushfq\t# saw NaN, set CF\n\t" 11474 "andq [rsp], #0xffffff2b\n\t" 11475 "popfq\n" 11476 "exit:" %} 11477 ins_encode %{ 11478 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 11479 emit_cmpfp_fixup(masm); 11480 %} 11481 ins_pipe(pipe_slow); 11482 %} 11483 11484 instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{ 11485 match(Set cr (CmpF src1 src2)); 11486 11487 ins_cost(100); 11488 format %{ "ucomiss $src1, $src2" %} 11489 ins_encode %{ 11490 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 11491 %} 11492 ins_pipe(pipe_slow); 11493 %} 11494 11495 instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{ 11496 match(Set cr (CmpF src1 (LoadF src2))); 11497 11498 ins_cost(100); 11499 format %{ "ucomiss $src1, $src2" %} 11500 ins_encode %{ 11501 __ ucomiss($src1$$XMMRegister, $src2$$Address); 11502 %} 11503 ins_pipe(pipe_slow); 11504 %} 11505 11506 instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src, immF con) %{ 11507 match(Set cr (CmpF src con)); 11508 ins_cost(100); 11509 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con" %} 11510 ins_encode %{ 11511 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 11512 %} 11513 ins_pipe(pipe_slow); 11514 %} 11515 11516 // Really expensive, avoid 11517 instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2) 11518 %{ 11519 match(Set cr (CmpD src1 src2)); 11520 11521 ins_cost(500); 11522 format %{ "ucomisd $src1, $src2\n\t" 11523 "jnp,s exit\n\t" 11524 "pushfq\t# saw NaN, set CF\n\t" 11525 "andq [rsp], #0xffffff2b\n\t" 11526 "popfq\n" 11527 "exit:" %} 11528 ins_encode %{ 11529 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 11530 emit_cmpfp_fixup(masm); 11531 %} 11532 ins_pipe(pipe_slow); 11533 %} 11534 11535 instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{ 11536 match(Set cr (CmpD src1 src2)); 11537 11538 ins_cost(100); 11539 format %{ "ucomisd $src1, $src2 test" %} 11540 ins_encode %{ 11541 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 11542 %} 11543 ins_pipe(pipe_slow); 11544 %} 11545 11546 instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{ 11547 match(Set cr (CmpD src1 (LoadD src2))); 11548 11549 ins_cost(100); 11550 format %{ "ucomisd $src1, $src2" %} 11551 ins_encode %{ 11552 __ ucomisd($src1$$XMMRegister, $src2$$Address); 11553 %} 11554 ins_pipe(pipe_slow); 11555 %} 11556 11557 instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src, immD con) %{ 11558 match(Set cr (CmpD src con)); 11559 ins_cost(100); 11560 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con" %} 11561 ins_encode %{ 11562 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 11563 %} 11564 ins_pipe(pipe_slow); 11565 %} 11566 11567 // Compare into -1,0,1 11568 instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr) 11569 %{ 11570 match(Set dst (CmpF3 src1 src2)); 11571 effect(KILL cr); 11572 11573 ins_cost(275); 11574 format %{ "ucomiss $src1, $src2\n\t" 11575 "movl $dst, #-1\n\t" 11576 "jp,s done\n\t" 11577 "jb,s done\n\t" 11578 "setne $dst\n\t" 11579 "movzbl $dst, $dst\n" 11580 "done:" %} 11581 ins_encode %{ 11582 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 11583 emit_cmpfp3(masm, $dst$$Register); 11584 %} 11585 ins_pipe(pipe_slow); 11586 %} 11587 11588 // Compare into -1,0,1 11589 instruct cmpF_mem(rRegI dst, regF src1, memory src2, rFlagsReg cr) 11590 %{ 11591 match(Set dst (CmpF3 src1 (LoadF src2))); 11592 effect(KILL cr); 11593 11594 ins_cost(275); 11595 format %{ "ucomiss $src1, $src2\n\t" 11596 "movl $dst, #-1\n\t" 11597 "jp,s done\n\t" 11598 "jb,s done\n\t" 11599 "setne $dst\n\t" 11600 "movzbl $dst, $dst\n" 11601 "done:" %} 11602 ins_encode %{ 11603 __ ucomiss($src1$$XMMRegister, $src2$$Address); 11604 emit_cmpfp3(masm, $dst$$Register); 11605 %} 11606 ins_pipe(pipe_slow); 11607 %} 11608 11609 // Compare into -1,0,1 11610 instruct cmpF_imm(rRegI dst, regF src, immF con, rFlagsReg cr) %{ 11611 match(Set dst (CmpF3 src con)); 11612 effect(KILL cr); 11613 11614 ins_cost(275); 11615 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 11616 "movl $dst, #-1\n\t" 11617 "jp,s done\n\t" 11618 "jb,s done\n\t" 11619 "setne $dst\n\t" 11620 "movzbl $dst, $dst\n" 11621 "done:" %} 11622 ins_encode %{ 11623 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 11624 emit_cmpfp3(masm, $dst$$Register); 11625 %} 11626 ins_pipe(pipe_slow); 11627 %} 11628 11629 // Compare into -1,0,1 11630 instruct cmpD_reg(rRegI dst, regD src1, regD src2, rFlagsReg cr) 11631 %{ 11632 match(Set dst (CmpD3 src1 src2)); 11633 effect(KILL cr); 11634 11635 ins_cost(275); 11636 format %{ "ucomisd $src1, $src2\n\t" 11637 "movl $dst, #-1\n\t" 11638 "jp,s done\n\t" 11639 "jb,s done\n\t" 11640 "setne $dst\n\t" 11641 "movzbl $dst, $dst\n" 11642 "done:" %} 11643 ins_encode %{ 11644 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 11645 emit_cmpfp3(masm, $dst$$Register); 11646 %} 11647 ins_pipe(pipe_slow); 11648 %} 11649 11650 // Compare into -1,0,1 11651 instruct cmpD_mem(rRegI dst, regD src1, memory src2, rFlagsReg cr) 11652 %{ 11653 match(Set dst (CmpD3 src1 (LoadD src2))); 11654 effect(KILL cr); 11655 11656 ins_cost(275); 11657 format %{ "ucomisd $src1, $src2\n\t" 11658 "movl $dst, #-1\n\t" 11659 "jp,s done\n\t" 11660 "jb,s done\n\t" 11661 "setne $dst\n\t" 11662 "movzbl $dst, $dst\n" 11663 "done:" %} 11664 ins_encode %{ 11665 __ ucomisd($src1$$XMMRegister, $src2$$Address); 11666 emit_cmpfp3(masm, $dst$$Register); 11667 %} 11668 ins_pipe(pipe_slow); 11669 %} 11670 11671 // Compare into -1,0,1 11672 instruct cmpD_imm(rRegI dst, regD src, immD con, rFlagsReg cr) %{ 11673 match(Set dst (CmpD3 src con)); 11674 effect(KILL cr); 11675 11676 ins_cost(275); 11677 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 11678 "movl $dst, #-1\n\t" 11679 "jp,s done\n\t" 11680 "jb,s done\n\t" 11681 "setne $dst\n\t" 11682 "movzbl $dst, $dst\n" 11683 "done:" %} 11684 ins_encode %{ 11685 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 11686 emit_cmpfp3(masm, $dst$$Register); 11687 %} 11688 ins_pipe(pipe_slow); 11689 %} 11690 11691 //----------Arithmetic Conversion Instructions--------------------------------- 11692 11693 instruct convF2D_reg_reg(regD dst, regF src) 11694 %{ 11695 match(Set dst (ConvF2D src)); 11696 11697 format %{ "cvtss2sd $dst, $src" %} 11698 ins_encode %{ 11699 __ cvtss2sd ($dst$$XMMRegister, $src$$XMMRegister); 11700 %} 11701 ins_pipe(pipe_slow); // XXX 11702 %} 11703 11704 instruct convF2D_reg_mem(regD dst, memory src) 11705 %{ 11706 predicate(UseAVX == 0); 11707 match(Set dst (ConvF2D (LoadF src))); 11708 11709 format %{ "cvtss2sd $dst, $src" %} 11710 ins_encode %{ 11711 __ cvtss2sd ($dst$$XMMRegister, $src$$Address); 11712 %} 11713 ins_pipe(pipe_slow); // XXX 11714 %} 11715 11716 instruct convD2F_reg_reg(regF dst, regD src) 11717 %{ 11718 match(Set dst (ConvD2F src)); 11719 11720 format %{ "cvtsd2ss $dst, $src" %} 11721 ins_encode %{ 11722 __ cvtsd2ss ($dst$$XMMRegister, $src$$XMMRegister); 11723 %} 11724 ins_pipe(pipe_slow); // XXX 11725 %} 11726 11727 instruct convD2F_reg_mem(regF dst, memory src) 11728 %{ 11729 predicate(UseAVX == 0); 11730 match(Set dst (ConvD2F (LoadD src))); 11731 11732 format %{ "cvtsd2ss $dst, $src" %} 11733 ins_encode %{ 11734 __ cvtsd2ss ($dst$$XMMRegister, $src$$Address); 11735 %} 11736 ins_pipe(pipe_slow); // XXX 11737 %} 11738 11739 // XXX do mem variants 11740 instruct convF2I_reg_reg(rRegI dst, regF src, rFlagsReg cr) 11741 %{ 11742 match(Set dst (ConvF2I src)); 11743 effect(KILL cr); 11744 format %{ "convert_f2i $dst, $src" %} 11745 ins_encode %{ 11746 __ convertF2I(T_INT, T_FLOAT, $dst$$Register, $src$$XMMRegister); 11747 %} 11748 ins_pipe(pipe_slow); 11749 %} 11750 11751 instruct convF2L_reg_reg(rRegL dst, regF src, rFlagsReg cr) 11752 %{ 11753 match(Set dst (ConvF2L src)); 11754 effect(KILL cr); 11755 format %{ "convert_f2l $dst, $src"%} 11756 ins_encode %{ 11757 __ convertF2I(T_LONG, T_FLOAT, $dst$$Register, $src$$XMMRegister); 11758 %} 11759 ins_pipe(pipe_slow); 11760 %} 11761 11762 instruct convD2I_reg_reg(rRegI dst, regD src, rFlagsReg cr) 11763 %{ 11764 match(Set dst (ConvD2I src)); 11765 effect(KILL cr); 11766 format %{ "convert_d2i $dst, $src"%} 11767 ins_encode %{ 11768 __ convertF2I(T_INT, T_DOUBLE, $dst$$Register, $src$$XMMRegister); 11769 %} 11770 ins_pipe(pipe_slow); 11771 %} 11772 11773 instruct convD2L_reg_reg(rRegL dst, regD src, rFlagsReg cr) 11774 %{ 11775 match(Set dst (ConvD2L src)); 11776 effect(KILL cr); 11777 format %{ "convert_d2l $dst, $src"%} 11778 ins_encode %{ 11779 __ convertF2I(T_LONG, T_DOUBLE, $dst$$Register, $src$$XMMRegister); 11780 %} 11781 ins_pipe(pipe_slow); 11782 %} 11783 11784 instruct round_double_reg(rRegL dst, regD src, rRegL rtmp, rcx_RegL rcx, rFlagsReg cr) 11785 %{ 11786 match(Set dst (RoundD src)); 11787 effect(TEMP dst, TEMP rtmp, TEMP rcx, KILL cr); 11788 format %{ "round_double $dst,$src \t! using $rtmp and $rcx as TEMP"%} 11789 ins_encode %{ 11790 __ round_double($dst$$Register, $src$$XMMRegister, $rtmp$$Register, $rcx$$Register); 11791 %} 11792 ins_pipe(pipe_slow); 11793 %} 11794 11795 instruct round_float_reg(rRegI dst, regF src, rRegL rtmp, rcx_RegL rcx, rFlagsReg cr) 11796 %{ 11797 match(Set dst (RoundF src)); 11798 effect(TEMP dst, TEMP rtmp, TEMP rcx, KILL cr); 11799 format %{ "round_float $dst,$src" %} 11800 ins_encode %{ 11801 __ round_float($dst$$Register, $src$$XMMRegister, $rtmp$$Register, $rcx$$Register); 11802 %} 11803 ins_pipe(pipe_slow); 11804 %} 11805 11806 instruct convI2F_reg_reg(vlRegF dst, rRegI src) 11807 %{ 11808 predicate(!UseXmmI2F); 11809 match(Set dst (ConvI2F src)); 11810 11811 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 11812 ins_encode %{ 11813 if (UseAVX > 0) { 11814 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 11815 } 11816 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Register); 11817 %} 11818 ins_pipe(pipe_slow); // XXX 11819 %} 11820 11821 instruct convI2F_reg_mem(regF dst, memory src) 11822 %{ 11823 predicate(UseAVX == 0); 11824 match(Set dst (ConvI2F (LoadI src))); 11825 11826 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 11827 ins_encode %{ 11828 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Address); 11829 %} 11830 ins_pipe(pipe_slow); // XXX 11831 %} 11832 11833 instruct convI2D_reg_reg(vlRegD dst, rRegI src) 11834 %{ 11835 predicate(!UseXmmI2D); 11836 match(Set dst (ConvI2D src)); 11837 11838 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 11839 ins_encode %{ 11840 if (UseAVX > 0) { 11841 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 11842 } 11843 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Register); 11844 %} 11845 ins_pipe(pipe_slow); // XXX 11846 %} 11847 11848 instruct convI2D_reg_mem(regD dst, memory src) 11849 %{ 11850 predicate(UseAVX == 0); 11851 match(Set dst (ConvI2D (LoadI src))); 11852 11853 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 11854 ins_encode %{ 11855 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Address); 11856 %} 11857 ins_pipe(pipe_slow); // XXX 11858 %} 11859 11860 instruct convXI2F_reg(regF dst, rRegI src) 11861 %{ 11862 predicate(UseXmmI2F); 11863 match(Set dst (ConvI2F src)); 11864 11865 format %{ "movdl $dst, $src\n\t" 11866 "cvtdq2psl $dst, $dst\t# i2f" %} 11867 ins_encode %{ 11868 __ movdl($dst$$XMMRegister, $src$$Register); 11869 __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister); 11870 %} 11871 ins_pipe(pipe_slow); // XXX 11872 %} 11873 11874 instruct convXI2D_reg(regD dst, rRegI src) 11875 %{ 11876 predicate(UseXmmI2D); 11877 match(Set dst (ConvI2D src)); 11878 11879 format %{ "movdl $dst, $src\n\t" 11880 "cvtdq2pdl $dst, $dst\t# i2d" %} 11881 ins_encode %{ 11882 __ movdl($dst$$XMMRegister, $src$$Register); 11883 __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister); 11884 %} 11885 ins_pipe(pipe_slow); // XXX 11886 %} 11887 11888 instruct convL2F_reg_reg(vlRegF dst, rRegL src) 11889 %{ 11890 match(Set dst (ConvL2F src)); 11891 11892 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 11893 ins_encode %{ 11894 if (UseAVX > 0) { 11895 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 11896 } 11897 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Register); 11898 %} 11899 ins_pipe(pipe_slow); // XXX 11900 %} 11901 11902 instruct convL2F_reg_mem(regF dst, memory src) 11903 %{ 11904 predicate(UseAVX == 0); 11905 match(Set dst (ConvL2F (LoadL src))); 11906 11907 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 11908 ins_encode %{ 11909 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Address); 11910 %} 11911 ins_pipe(pipe_slow); // XXX 11912 %} 11913 11914 instruct convL2D_reg_reg(vlRegD dst, rRegL src) 11915 %{ 11916 match(Set dst (ConvL2D src)); 11917 11918 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 11919 ins_encode %{ 11920 if (UseAVX > 0) { 11921 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 11922 } 11923 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Register); 11924 %} 11925 ins_pipe(pipe_slow); // XXX 11926 %} 11927 11928 instruct convL2D_reg_mem(regD dst, memory src) 11929 %{ 11930 predicate(UseAVX == 0); 11931 match(Set dst (ConvL2D (LoadL src))); 11932 11933 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 11934 ins_encode %{ 11935 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Address); 11936 %} 11937 ins_pipe(pipe_slow); // XXX 11938 %} 11939 11940 instruct convI2L_reg_reg(rRegL dst, rRegI src) 11941 %{ 11942 match(Set dst (ConvI2L src)); 11943 11944 ins_cost(125); 11945 format %{ "movslq $dst, $src\t# i2l" %} 11946 ins_encode %{ 11947 __ movslq($dst$$Register, $src$$Register); 11948 %} 11949 ins_pipe(ialu_reg_reg); 11950 %} 11951 11952 // Zero-extend convert int to long 11953 instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask) 11954 %{ 11955 match(Set dst (AndL (ConvI2L src) mask)); 11956 11957 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 11958 ins_encode %{ 11959 if ($dst$$reg != $src$$reg) { 11960 __ movl($dst$$Register, $src$$Register); 11961 } 11962 %} 11963 ins_pipe(ialu_reg_reg); 11964 %} 11965 11966 // Zero-extend convert int to long 11967 instruct convI2L_reg_mem_zex(rRegL dst, memory src, immL_32bits mask) 11968 %{ 11969 match(Set dst (AndL (ConvI2L (LoadI src)) mask)); 11970 11971 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 11972 ins_encode %{ 11973 __ movl($dst$$Register, $src$$Address); 11974 %} 11975 ins_pipe(ialu_reg_mem); 11976 %} 11977 11978 instruct zerox_long_reg_reg(rRegL dst, rRegL src, immL_32bits mask) 11979 %{ 11980 match(Set dst (AndL src mask)); 11981 11982 format %{ "movl $dst, $src\t# zero-extend long" %} 11983 ins_encode %{ 11984 __ movl($dst$$Register, $src$$Register); 11985 %} 11986 ins_pipe(ialu_reg_reg); 11987 %} 11988 11989 instruct convL2I_reg_reg(rRegI dst, rRegL src) 11990 %{ 11991 match(Set dst (ConvL2I src)); 11992 11993 format %{ "movl $dst, $src\t# l2i" %} 11994 ins_encode %{ 11995 __ movl($dst$$Register, $src$$Register); 11996 %} 11997 ins_pipe(ialu_reg_reg); 11998 %} 11999 12000 12001 instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{ 12002 match(Set dst (MoveF2I src)); 12003 effect(DEF dst, USE src); 12004 12005 ins_cost(125); 12006 format %{ "movl $dst, $src\t# MoveF2I_stack_reg" %} 12007 ins_encode %{ 12008 __ movl($dst$$Register, Address(rsp, $src$$disp)); 12009 %} 12010 ins_pipe(ialu_reg_mem); 12011 %} 12012 12013 instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{ 12014 match(Set dst (MoveI2F src)); 12015 effect(DEF dst, USE src); 12016 12017 ins_cost(125); 12018 format %{ "movss $dst, $src\t# MoveI2F_stack_reg" %} 12019 ins_encode %{ 12020 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 12021 %} 12022 ins_pipe(pipe_slow); 12023 %} 12024 12025 instruct MoveD2L_stack_reg(rRegL dst, stackSlotD src) %{ 12026 match(Set dst (MoveD2L src)); 12027 effect(DEF dst, USE src); 12028 12029 ins_cost(125); 12030 format %{ "movq $dst, $src\t# MoveD2L_stack_reg" %} 12031 ins_encode %{ 12032 __ movq($dst$$Register, Address(rsp, $src$$disp)); 12033 %} 12034 ins_pipe(ialu_reg_mem); 12035 %} 12036 12037 instruct MoveL2D_stack_reg_partial(regD dst, stackSlotL src) %{ 12038 predicate(!UseXmmLoadAndClearUpper); 12039 match(Set dst (MoveL2D src)); 12040 effect(DEF dst, USE src); 12041 12042 ins_cost(125); 12043 format %{ "movlpd $dst, $src\t# MoveL2D_stack_reg" %} 12044 ins_encode %{ 12045 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 12046 %} 12047 ins_pipe(pipe_slow); 12048 %} 12049 12050 instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{ 12051 predicate(UseXmmLoadAndClearUpper); 12052 match(Set dst (MoveL2D src)); 12053 effect(DEF dst, USE src); 12054 12055 ins_cost(125); 12056 format %{ "movsd $dst, $src\t# MoveL2D_stack_reg" %} 12057 ins_encode %{ 12058 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 12059 %} 12060 ins_pipe(pipe_slow); 12061 %} 12062 12063 12064 instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{ 12065 match(Set dst (MoveF2I src)); 12066 effect(DEF dst, USE src); 12067 12068 ins_cost(95); // XXX 12069 format %{ "movss $dst, $src\t# MoveF2I_reg_stack" %} 12070 ins_encode %{ 12071 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 12072 %} 12073 ins_pipe(pipe_slow); 12074 %} 12075 12076 instruct MoveI2F_reg_stack(stackSlotF dst, rRegI src) %{ 12077 match(Set dst (MoveI2F src)); 12078 effect(DEF dst, USE src); 12079 12080 ins_cost(100); 12081 format %{ "movl $dst, $src\t# MoveI2F_reg_stack" %} 12082 ins_encode %{ 12083 __ movl(Address(rsp, $dst$$disp), $src$$Register); 12084 %} 12085 ins_pipe( ialu_mem_reg ); 12086 %} 12087 12088 instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{ 12089 match(Set dst (MoveD2L src)); 12090 effect(DEF dst, USE src); 12091 12092 ins_cost(95); // XXX 12093 format %{ "movsd $dst, $src\t# MoveL2D_reg_stack" %} 12094 ins_encode %{ 12095 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 12096 %} 12097 ins_pipe(pipe_slow); 12098 %} 12099 12100 instruct MoveL2D_reg_stack(stackSlotD dst, rRegL src) %{ 12101 match(Set dst (MoveL2D src)); 12102 effect(DEF dst, USE src); 12103 12104 ins_cost(100); 12105 format %{ "movq $dst, $src\t# MoveL2D_reg_stack" %} 12106 ins_encode %{ 12107 __ movq(Address(rsp, $dst$$disp), $src$$Register); 12108 %} 12109 ins_pipe(ialu_mem_reg); 12110 %} 12111 12112 instruct MoveF2I_reg_reg(rRegI dst, regF src) %{ 12113 match(Set dst (MoveF2I src)); 12114 effect(DEF dst, USE src); 12115 ins_cost(85); 12116 format %{ "movd $dst,$src\t# MoveF2I" %} 12117 ins_encode %{ 12118 __ movdl($dst$$Register, $src$$XMMRegister); 12119 %} 12120 ins_pipe( pipe_slow ); 12121 %} 12122 12123 instruct MoveD2L_reg_reg(rRegL dst, regD src) %{ 12124 match(Set dst (MoveD2L src)); 12125 effect(DEF dst, USE src); 12126 ins_cost(85); 12127 format %{ "movd $dst,$src\t# MoveD2L" %} 12128 ins_encode %{ 12129 __ movdq($dst$$Register, $src$$XMMRegister); 12130 %} 12131 ins_pipe( pipe_slow ); 12132 %} 12133 12134 instruct MoveI2F_reg_reg(regF dst, rRegI src) %{ 12135 match(Set dst (MoveI2F src)); 12136 effect(DEF dst, USE src); 12137 ins_cost(100); 12138 format %{ "movd $dst,$src\t# MoveI2F" %} 12139 ins_encode %{ 12140 __ movdl($dst$$XMMRegister, $src$$Register); 12141 %} 12142 ins_pipe( pipe_slow ); 12143 %} 12144 12145 instruct MoveL2D_reg_reg(regD dst, rRegL src) %{ 12146 match(Set dst (MoveL2D src)); 12147 effect(DEF dst, USE src); 12148 ins_cost(100); 12149 format %{ "movd $dst,$src\t# MoveL2D" %} 12150 ins_encode %{ 12151 __ movdq($dst$$XMMRegister, $src$$Register); 12152 %} 12153 ins_pipe( pipe_slow ); 12154 %} 12155 12156 // Fast clearing of an array 12157 // Small non-constant lenght ClearArray for non-AVX512 targets. 12158 instruct rep_stos(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegI zero, 12159 Universe dummy, rFlagsReg cr) 12160 %{ 12161 predicate(!((ClearArrayNode*)n)->is_large() && (UseAVX <= 2)); 12162 match(Set dummy (ClearArray cnt base)); 12163 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL zero, KILL cr); 12164 12165 format %{ $$template 12166 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 12167 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 12168 $$emit$$"jg LARGE\n\t" 12169 $$emit$$"dec rcx\n\t" 12170 $$emit$$"js DONE\t# Zero length\n\t" 12171 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 12172 $$emit$$"dec rcx\n\t" 12173 $$emit$$"jge LOOP\n\t" 12174 $$emit$$"jmp DONE\n\t" 12175 $$emit$$"# LARGE:\n\t" 12176 if (UseFastStosb) { 12177 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 12178 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--\n\t" 12179 } else if (UseXMMForObjInit) { 12180 $$emit$$"mov rdi,rax\n\t" 12181 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 12182 $$emit$$"jmpq L_zero_64_bytes\n\t" 12183 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 12184 $$emit$$"vmovdqu ymm0,(rax)\n\t" 12185 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 12186 $$emit$$"add 0x40,rax\n\t" 12187 $$emit$$"# L_zero_64_bytes:\n\t" 12188 $$emit$$"sub 0x8,rcx\n\t" 12189 $$emit$$"jge L_loop\n\t" 12190 $$emit$$"add 0x4,rcx\n\t" 12191 $$emit$$"jl L_tail\n\t" 12192 $$emit$$"vmovdqu ymm0,(rax)\n\t" 12193 $$emit$$"add 0x20,rax\n\t" 12194 $$emit$$"sub 0x4,rcx\n\t" 12195 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 12196 $$emit$$"add 0x4,rcx\n\t" 12197 $$emit$$"jle L_end\n\t" 12198 $$emit$$"dec rcx\n\t" 12199 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 12200 $$emit$$"vmovq xmm0,(rax)\n\t" 12201 $$emit$$"add 0x8,rax\n\t" 12202 $$emit$$"dec rcx\n\t" 12203 $$emit$$"jge L_sloop\n\t" 12204 $$emit$$"# L_end:\n\t" 12205 } else { 12206 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 12207 } 12208 $$emit$$"# DONE" 12209 %} 12210 ins_encode %{ 12211 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 12212 $tmp$$XMMRegister, false, knoreg); 12213 %} 12214 ins_pipe(pipe_slow); 12215 %} 12216 12217 // Small non-constant length ClearArray for AVX512 targets. 12218 instruct rep_stos_evex(rcx_RegL cnt, rdi_RegP base, legRegD tmp, kReg ktmp, rax_RegI zero, 12219 Universe dummy, rFlagsReg cr) 12220 %{ 12221 predicate(!((ClearArrayNode*)n)->is_large() && (UseAVX > 2)); 12222 match(Set dummy (ClearArray cnt base)); 12223 ins_cost(125); 12224 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, TEMP ktmp, KILL zero, KILL cr); 12225 12226 format %{ $$template 12227 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 12228 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 12229 $$emit$$"jg LARGE\n\t" 12230 $$emit$$"dec rcx\n\t" 12231 $$emit$$"js DONE\t# Zero length\n\t" 12232 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 12233 $$emit$$"dec rcx\n\t" 12234 $$emit$$"jge LOOP\n\t" 12235 $$emit$$"jmp DONE\n\t" 12236 $$emit$$"# LARGE:\n\t" 12237 if (UseFastStosb) { 12238 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 12239 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--\n\t" 12240 } else if (UseXMMForObjInit) { 12241 $$emit$$"mov rdi,rax\n\t" 12242 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 12243 $$emit$$"jmpq L_zero_64_bytes\n\t" 12244 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 12245 $$emit$$"vmovdqu ymm0,(rax)\n\t" 12246 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 12247 $$emit$$"add 0x40,rax\n\t" 12248 $$emit$$"# L_zero_64_bytes:\n\t" 12249 $$emit$$"sub 0x8,rcx\n\t" 12250 $$emit$$"jge L_loop\n\t" 12251 $$emit$$"add 0x4,rcx\n\t" 12252 $$emit$$"jl L_tail\n\t" 12253 $$emit$$"vmovdqu ymm0,(rax)\n\t" 12254 $$emit$$"add 0x20,rax\n\t" 12255 $$emit$$"sub 0x4,rcx\n\t" 12256 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 12257 $$emit$$"add 0x4,rcx\n\t" 12258 $$emit$$"jle L_end\n\t" 12259 $$emit$$"dec rcx\n\t" 12260 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 12261 $$emit$$"vmovq xmm0,(rax)\n\t" 12262 $$emit$$"add 0x8,rax\n\t" 12263 $$emit$$"dec rcx\n\t" 12264 $$emit$$"jge L_sloop\n\t" 12265 $$emit$$"# L_end:\n\t" 12266 } else { 12267 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 12268 } 12269 $$emit$$"# DONE" 12270 %} 12271 ins_encode %{ 12272 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 12273 $tmp$$XMMRegister, false, $ktmp$$KRegister); 12274 %} 12275 ins_pipe(pipe_slow); 12276 %} 12277 12278 // Large non-constant length ClearArray for non-AVX512 targets. 12279 instruct rep_stos_large(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegI zero, 12280 Universe dummy, rFlagsReg cr) 12281 %{ 12282 predicate((UseAVX <=2) && ((ClearArrayNode*)n)->is_large()); 12283 match(Set dummy (ClearArray cnt base)); 12284 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL zero, KILL cr); 12285 12286 format %{ $$template 12287 if (UseFastStosb) { 12288 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 12289 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 12290 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--" 12291 } else if (UseXMMForObjInit) { 12292 $$emit$$"mov rdi,rax\t# ClearArray:\n\t" 12293 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 12294 $$emit$$"jmpq L_zero_64_bytes\n\t" 12295 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 12296 $$emit$$"vmovdqu ymm0,(rax)\n\t" 12297 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 12298 $$emit$$"add 0x40,rax\n\t" 12299 $$emit$$"# L_zero_64_bytes:\n\t" 12300 $$emit$$"sub 0x8,rcx\n\t" 12301 $$emit$$"jge L_loop\n\t" 12302 $$emit$$"add 0x4,rcx\n\t" 12303 $$emit$$"jl L_tail\n\t" 12304 $$emit$$"vmovdqu ymm0,(rax)\n\t" 12305 $$emit$$"add 0x20,rax\n\t" 12306 $$emit$$"sub 0x4,rcx\n\t" 12307 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 12308 $$emit$$"add 0x4,rcx\n\t" 12309 $$emit$$"jle L_end\n\t" 12310 $$emit$$"dec rcx\n\t" 12311 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 12312 $$emit$$"vmovq xmm0,(rax)\n\t" 12313 $$emit$$"add 0x8,rax\n\t" 12314 $$emit$$"dec rcx\n\t" 12315 $$emit$$"jge L_sloop\n\t" 12316 $$emit$$"# L_end:\n\t" 12317 } else { 12318 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 12319 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 12320 } 12321 %} 12322 ins_encode %{ 12323 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 12324 $tmp$$XMMRegister, true, knoreg); 12325 %} 12326 ins_pipe(pipe_slow); 12327 %} 12328 12329 // Large non-constant length ClearArray for AVX512 targets. 12330 instruct rep_stos_large_evex(rcx_RegL cnt, rdi_RegP base, legRegD tmp, kReg ktmp, rax_RegI zero, 12331 Universe dummy, rFlagsReg cr) 12332 %{ 12333 predicate((UseAVX > 2) && ((ClearArrayNode*)n)->is_large()); 12334 match(Set dummy (ClearArray cnt base)); 12335 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, TEMP ktmp, KILL zero, KILL cr); 12336 12337 format %{ $$template 12338 if (UseFastStosb) { 12339 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 12340 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 12341 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--" 12342 } else if (UseXMMForObjInit) { 12343 $$emit$$"mov rdi,rax\t# ClearArray:\n\t" 12344 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 12345 $$emit$$"jmpq L_zero_64_bytes\n\t" 12346 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 12347 $$emit$$"vmovdqu ymm0,(rax)\n\t" 12348 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 12349 $$emit$$"add 0x40,rax\n\t" 12350 $$emit$$"# L_zero_64_bytes:\n\t" 12351 $$emit$$"sub 0x8,rcx\n\t" 12352 $$emit$$"jge L_loop\n\t" 12353 $$emit$$"add 0x4,rcx\n\t" 12354 $$emit$$"jl L_tail\n\t" 12355 $$emit$$"vmovdqu ymm0,(rax)\n\t" 12356 $$emit$$"add 0x20,rax\n\t" 12357 $$emit$$"sub 0x4,rcx\n\t" 12358 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 12359 $$emit$$"add 0x4,rcx\n\t" 12360 $$emit$$"jle L_end\n\t" 12361 $$emit$$"dec rcx\n\t" 12362 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 12363 $$emit$$"vmovq xmm0,(rax)\n\t" 12364 $$emit$$"add 0x8,rax\n\t" 12365 $$emit$$"dec rcx\n\t" 12366 $$emit$$"jge L_sloop\n\t" 12367 $$emit$$"# L_end:\n\t" 12368 } else { 12369 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 12370 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 12371 } 12372 %} 12373 ins_encode %{ 12374 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 12375 $tmp$$XMMRegister, true, $ktmp$$KRegister); 12376 %} 12377 ins_pipe(pipe_slow); 12378 %} 12379 12380 // Small constant length ClearArray for AVX512 targets. 12381 instruct rep_stos_im(immL cnt, rRegP base, regD tmp, rRegI zero, kReg ktmp, Universe dummy, rFlagsReg cr) 12382 %{ 12383 predicate(!((ClearArrayNode*)n)->is_large() && (MaxVectorSize >= 32) && VM_Version::supports_avx512vl()); 12384 match(Set dummy (ClearArray cnt base)); 12385 ins_cost(100); 12386 effect(TEMP tmp, TEMP zero, TEMP ktmp, KILL cr); 12387 format %{ "clear_mem_imm $base , $cnt \n\t" %} 12388 ins_encode %{ 12389 __ clear_mem($base$$Register, $cnt$$constant, $zero$$Register, $tmp$$XMMRegister, $ktmp$$KRegister); 12390 %} 12391 ins_pipe(pipe_slow); 12392 %} 12393 12394 instruct string_compareL(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 12395 rax_RegI result, legRegD tmp1, rFlagsReg cr) 12396 %{ 12397 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 12398 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12399 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 12400 12401 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 12402 ins_encode %{ 12403 __ string_compare($str1$$Register, $str2$$Register, 12404 $cnt1$$Register, $cnt2$$Register, $result$$Register, 12405 $tmp1$$XMMRegister, StrIntrinsicNode::LL, knoreg); 12406 %} 12407 ins_pipe( pipe_slow ); 12408 %} 12409 12410 instruct string_compareL_evex(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 12411 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 12412 %{ 12413 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 12414 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12415 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 12416 12417 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 12418 ins_encode %{ 12419 __ string_compare($str1$$Register, $str2$$Register, 12420 $cnt1$$Register, $cnt2$$Register, $result$$Register, 12421 $tmp1$$XMMRegister, StrIntrinsicNode::LL, $ktmp$$KRegister); 12422 %} 12423 ins_pipe( pipe_slow ); 12424 %} 12425 12426 instruct string_compareU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 12427 rax_RegI result, legRegD tmp1, rFlagsReg cr) 12428 %{ 12429 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 12430 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12431 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 12432 12433 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 12434 ins_encode %{ 12435 __ string_compare($str1$$Register, $str2$$Register, 12436 $cnt1$$Register, $cnt2$$Register, $result$$Register, 12437 $tmp1$$XMMRegister, StrIntrinsicNode::UU, knoreg); 12438 %} 12439 ins_pipe( pipe_slow ); 12440 %} 12441 12442 instruct string_compareU_evex(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 12443 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 12444 %{ 12445 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 12446 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12447 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 12448 12449 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 12450 ins_encode %{ 12451 __ string_compare($str1$$Register, $str2$$Register, 12452 $cnt1$$Register, $cnt2$$Register, $result$$Register, 12453 $tmp1$$XMMRegister, StrIntrinsicNode::UU, $ktmp$$KRegister); 12454 %} 12455 ins_pipe( pipe_slow ); 12456 %} 12457 12458 instruct string_compareLU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 12459 rax_RegI result, legRegD tmp1, rFlagsReg cr) 12460 %{ 12461 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 12462 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12463 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 12464 12465 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 12466 ins_encode %{ 12467 __ string_compare($str1$$Register, $str2$$Register, 12468 $cnt1$$Register, $cnt2$$Register, $result$$Register, 12469 $tmp1$$XMMRegister, StrIntrinsicNode::LU, knoreg); 12470 %} 12471 ins_pipe( pipe_slow ); 12472 %} 12473 12474 instruct string_compareLU_evex(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 12475 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 12476 %{ 12477 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 12478 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12479 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 12480 12481 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 12482 ins_encode %{ 12483 __ string_compare($str1$$Register, $str2$$Register, 12484 $cnt1$$Register, $cnt2$$Register, $result$$Register, 12485 $tmp1$$XMMRegister, StrIntrinsicNode::LU, $ktmp$$KRegister); 12486 %} 12487 ins_pipe( pipe_slow ); 12488 %} 12489 12490 instruct string_compareUL(rsi_RegP str1, rdx_RegI cnt1, rdi_RegP str2, rcx_RegI cnt2, 12491 rax_RegI result, legRegD tmp1, rFlagsReg cr) 12492 %{ 12493 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 12494 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12495 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 12496 12497 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 12498 ins_encode %{ 12499 __ string_compare($str2$$Register, $str1$$Register, 12500 $cnt2$$Register, $cnt1$$Register, $result$$Register, 12501 $tmp1$$XMMRegister, StrIntrinsicNode::UL, knoreg); 12502 %} 12503 ins_pipe( pipe_slow ); 12504 %} 12505 12506 instruct string_compareUL_evex(rsi_RegP str1, rdx_RegI cnt1, rdi_RegP str2, rcx_RegI cnt2, 12507 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 12508 %{ 12509 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 12510 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12511 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 12512 12513 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 12514 ins_encode %{ 12515 __ string_compare($str2$$Register, $str1$$Register, 12516 $cnt2$$Register, $cnt1$$Register, $result$$Register, 12517 $tmp1$$XMMRegister, StrIntrinsicNode::UL, $ktmp$$KRegister); 12518 %} 12519 ins_pipe( pipe_slow ); 12520 %} 12521 12522 // fast search of substring with known size. 12523 instruct string_indexof_conL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 12524 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 12525 %{ 12526 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 12527 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 12528 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 12529 12530 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %} 12531 ins_encode %{ 12532 int icnt2 = (int)$int_cnt2$$constant; 12533 if (icnt2 >= 16) { 12534 // IndexOf for constant substrings with size >= 16 elements 12535 // which don't need to be loaded through stack. 12536 __ string_indexofC8($str1$$Register, $str2$$Register, 12537 $cnt1$$Register, $cnt2$$Register, 12538 icnt2, $result$$Register, 12539 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 12540 } else { 12541 // Small strings are loaded through stack if they cross page boundary. 12542 __ string_indexof($str1$$Register, $str2$$Register, 12543 $cnt1$$Register, $cnt2$$Register, 12544 icnt2, $result$$Register, 12545 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 12546 } 12547 %} 12548 ins_pipe( pipe_slow ); 12549 %} 12550 12551 // fast search of substring with known size. 12552 instruct string_indexof_conU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 12553 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 12554 %{ 12555 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 12556 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 12557 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 12558 12559 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %} 12560 ins_encode %{ 12561 int icnt2 = (int)$int_cnt2$$constant; 12562 if (icnt2 >= 8) { 12563 // IndexOf for constant substrings with size >= 8 elements 12564 // which don't need to be loaded through stack. 12565 __ string_indexofC8($str1$$Register, $str2$$Register, 12566 $cnt1$$Register, $cnt2$$Register, 12567 icnt2, $result$$Register, 12568 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 12569 } else { 12570 // Small strings are loaded through stack if they cross page boundary. 12571 __ string_indexof($str1$$Register, $str2$$Register, 12572 $cnt1$$Register, $cnt2$$Register, 12573 icnt2, $result$$Register, 12574 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 12575 } 12576 %} 12577 ins_pipe( pipe_slow ); 12578 %} 12579 12580 // fast search of substring with known size. 12581 instruct string_indexof_conUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 12582 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 12583 %{ 12584 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 12585 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 12586 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 12587 12588 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %} 12589 ins_encode %{ 12590 int icnt2 = (int)$int_cnt2$$constant; 12591 if (icnt2 >= 8) { 12592 // IndexOf for constant substrings with size >= 8 elements 12593 // which don't need to be loaded through stack. 12594 __ string_indexofC8($str1$$Register, $str2$$Register, 12595 $cnt1$$Register, $cnt2$$Register, 12596 icnt2, $result$$Register, 12597 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 12598 } else { 12599 // Small strings are loaded through stack if they cross page boundary. 12600 __ string_indexof($str1$$Register, $str2$$Register, 12601 $cnt1$$Register, $cnt2$$Register, 12602 icnt2, $result$$Register, 12603 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 12604 } 12605 %} 12606 ins_pipe( pipe_slow ); 12607 %} 12608 12609 instruct string_indexofL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 12610 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr) 12611 %{ 12612 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 12613 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 12614 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 12615 12616 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 12617 ins_encode %{ 12618 __ string_indexof($str1$$Register, $str2$$Register, 12619 $cnt1$$Register, $cnt2$$Register, 12620 (-1), $result$$Register, 12621 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 12622 %} 12623 ins_pipe( pipe_slow ); 12624 %} 12625 12626 instruct string_indexofU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 12627 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr) 12628 %{ 12629 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 12630 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 12631 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 12632 12633 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 12634 ins_encode %{ 12635 __ string_indexof($str1$$Register, $str2$$Register, 12636 $cnt1$$Register, $cnt2$$Register, 12637 (-1), $result$$Register, 12638 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 12639 %} 12640 ins_pipe( pipe_slow ); 12641 %} 12642 12643 instruct string_indexofUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 12644 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr) 12645 %{ 12646 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 12647 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 12648 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 12649 12650 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 12651 ins_encode %{ 12652 __ string_indexof($str1$$Register, $str2$$Register, 12653 $cnt1$$Register, $cnt2$$Register, 12654 (-1), $result$$Register, 12655 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 12656 %} 12657 ins_pipe( pipe_slow ); 12658 %} 12659 12660 instruct string_indexof_char(rdi_RegP str1, rdx_RegI cnt1, rax_RegI ch, 12661 rbx_RegI result, legRegD tmp_vec1, legRegD tmp_vec2, legRegD tmp_vec3, rcx_RegI tmp, rFlagsReg cr) 12662 %{ 12663 predicate(UseSSE42Intrinsics && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::U)); 12664 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 12665 effect(TEMP tmp_vec1, TEMP tmp_vec2, TEMP tmp_vec3, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP tmp, KILL cr); 12666 format %{ "StringUTF16 IndexOf char[] $str1,$cnt1,$ch -> $result // KILL all" %} 12667 ins_encode %{ 12668 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register, 12669 $tmp_vec1$$XMMRegister, $tmp_vec2$$XMMRegister, $tmp_vec3$$XMMRegister, $tmp$$Register); 12670 %} 12671 ins_pipe( pipe_slow ); 12672 %} 12673 12674 instruct stringL_indexof_char(rdi_RegP str1, rdx_RegI cnt1, rax_RegI ch, 12675 rbx_RegI result, legRegD tmp_vec1, legRegD tmp_vec2, legRegD tmp_vec3, rcx_RegI tmp, rFlagsReg cr) 12676 %{ 12677 predicate(UseSSE42Intrinsics && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::L)); 12678 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 12679 effect(TEMP tmp_vec1, TEMP tmp_vec2, TEMP tmp_vec3, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP tmp, KILL cr); 12680 format %{ "StringLatin1 IndexOf char[] $str1,$cnt1,$ch -> $result // KILL all" %} 12681 ins_encode %{ 12682 __ stringL_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register, 12683 $tmp_vec1$$XMMRegister, $tmp_vec2$$XMMRegister, $tmp_vec3$$XMMRegister, $tmp$$Register); 12684 %} 12685 ins_pipe( pipe_slow ); 12686 %} 12687 12688 // fast string equals 12689 instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 12690 legRegD tmp1, legRegD tmp2, rbx_RegI tmp3, rFlagsReg cr) 12691 %{ 12692 predicate(!VM_Version::supports_avx512vlbw()); 12693 match(Set result (StrEquals (Binary str1 str2) cnt)); 12694 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 12695 12696 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 12697 ins_encode %{ 12698 __ arrays_equals(false, $str1$$Register, $str2$$Register, 12699 $cnt$$Register, $result$$Register, $tmp3$$Register, 12700 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, knoreg); 12701 %} 12702 ins_pipe( pipe_slow ); 12703 %} 12704 12705 instruct string_equals_evex(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 12706 legRegD tmp1, legRegD tmp2, kReg ktmp, rbx_RegI tmp3, rFlagsReg cr) 12707 %{ 12708 predicate(VM_Version::supports_avx512vlbw()); 12709 match(Set result (StrEquals (Binary str1 str2) cnt)); 12710 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 12711 12712 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 12713 ins_encode %{ 12714 __ arrays_equals(false, $str1$$Register, $str2$$Register, 12715 $cnt$$Register, $result$$Register, $tmp3$$Register, 12716 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, $ktmp$$KRegister); 12717 %} 12718 ins_pipe( pipe_slow ); 12719 %} 12720 12721 // fast array equals 12722 instruct array_equalsB(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 12723 legRegD tmp1, legRegD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 12724 %{ 12725 predicate(!VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 12726 match(Set result (AryEq ary1 ary2)); 12727 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 12728 12729 format %{ "Array Equals byte[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 12730 ins_encode %{ 12731 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 12732 $tmp3$$Register, $result$$Register, $tmp4$$Register, 12733 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, knoreg); 12734 %} 12735 ins_pipe( pipe_slow ); 12736 %} 12737 12738 instruct array_equalsB_evex(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 12739 legRegD tmp1, legRegD tmp2, kReg ktmp, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 12740 %{ 12741 predicate(VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 12742 match(Set result (AryEq ary1 ary2)); 12743 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 12744 12745 format %{ "Array Equals byte[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 12746 ins_encode %{ 12747 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 12748 $tmp3$$Register, $result$$Register, $tmp4$$Register, 12749 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, $ktmp$$KRegister); 12750 %} 12751 ins_pipe( pipe_slow ); 12752 %} 12753 12754 instruct array_equalsC(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 12755 legRegD tmp1, legRegD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 12756 %{ 12757 predicate(!VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 12758 match(Set result (AryEq ary1 ary2)); 12759 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 12760 12761 format %{ "Array Equals char[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 12762 ins_encode %{ 12763 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 12764 $tmp3$$Register, $result$$Register, $tmp4$$Register, 12765 $tmp1$$XMMRegister, $tmp2$$XMMRegister, true /* char */, knoreg); 12766 %} 12767 ins_pipe( pipe_slow ); 12768 %} 12769 12770 instruct array_equalsC_evex(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 12771 legRegD tmp1, legRegD tmp2, kReg ktmp, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 12772 %{ 12773 predicate(VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 12774 match(Set result (AryEq ary1 ary2)); 12775 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 12776 12777 format %{ "Array Equals char[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 12778 ins_encode %{ 12779 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 12780 $tmp3$$Register, $result$$Register, $tmp4$$Register, 12781 $tmp1$$XMMRegister, $tmp2$$XMMRegister, true /* char */, $ktmp$$KRegister); 12782 %} 12783 ins_pipe( pipe_slow ); 12784 %} 12785 12786 instruct arrays_hashcode(rdi_RegP ary1, rdx_RegI cnt1, rbx_RegI result, immU8 basic_type, 12787 legRegD tmp_vec1, legRegD tmp_vec2, legRegD tmp_vec3, legRegD tmp_vec4, 12788 legRegD tmp_vec5, legRegD tmp_vec6, legRegD tmp_vec7, legRegD tmp_vec8, 12789 legRegD tmp_vec9, legRegD tmp_vec10, legRegD tmp_vec11, legRegD tmp_vec12, 12790 legRegD tmp_vec13, rRegI tmp1, rRegI tmp2, rRegI tmp3, rFlagsReg cr) 12791 %{ 12792 predicate(UseAVX >= 2); 12793 match(Set result (VectorizedHashCode (Binary ary1 cnt1) (Binary result basic_type))); 12794 effect(TEMP tmp_vec1, TEMP tmp_vec2, TEMP tmp_vec3, TEMP tmp_vec4, TEMP tmp_vec5, TEMP tmp_vec6, 12795 TEMP tmp_vec7, TEMP tmp_vec8, TEMP tmp_vec9, TEMP tmp_vec10, TEMP tmp_vec11, TEMP tmp_vec12, 12796 TEMP tmp_vec13, TEMP tmp1, TEMP tmp2, TEMP tmp3, USE_KILL ary1, USE_KILL cnt1, 12797 USE basic_type, KILL cr); 12798 12799 format %{ "Array HashCode array[] $ary1,$cnt1,$result,$basic_type -> $result // KILL all" %} 12800 ins_encode %{ 12801 __ arrays_hashcode($ary1$$Register, $cnt1$$Register, $result$$Register, 12802 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 12803 $tmp_vec1$$XMMRegister, $tmp_vec2$$XMMRegister, $tmp_vec3$$XMMRegister, 12804 $tmp_vec4$$XMMRegister, $tmp_vec5$$XMMRegister, $tmp_vec6$$XMMRegister, 12805 $tmp_vec7$$XMMRegister, $tmp_vec8$$XMMRegister, $tmp_vec9$$XMMRegister, 12806 $tmp_vec10$$XMMRegister, $tmp_vec11$$XMMRegister, $tmp_vec12$$XMMRegister, 12807 $tmp_vec13$$XMMRegister, (BasicType)$basic_type$$constant); 12808 %} 12809 ins_pipe( pipe_slow ); 12810 %} 12811 12812 instruct count_positives(rsi_RegP ary1, rcx_RegI len, rax_RegI result, 12813 legRegD tmp1, legRegD tmp2, rbx_RegI tmp3, rFlagsReg cr,) 12814 %{ 12815 predicate(!VM_Version::supports_avx512vlbw() || !VM_Version::supports_bmi2()); 12816 match(Set result (CountPositives ary1 len)); 12817 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr); 12818 12819 format %{ "countPositives byte[] $ary1,$len -> $result // KILL $tmp1, $tmp2, $tmp3" %} 12820 ins_encode %{ 12821 __ count_positives($ary1$$Register, $len$$Register, 12822 $result$$Register, $tmp3$$Register, 12823 $tmp1$$XMMRegister, $tmp2$$XMMRegister, knoreg, knoreg); 12824 %} 12825 ins_pipe( pipe_slow ); 12826 %} 12827 12828 instruct count_positives_evex(rsi_RegP ary1, rcx_RegI len, rax_RegI result, 12829 legRegD tmp1, legRegD tmp2, kReg ktmp1, kReg ktmp2, rbx_RegI tmp3, rFlagsReg cr,) 12830 %{ 12831 predicate(VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2()); 12832 match(Set result (CountPositives ary1 len)); 12833 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp1, TEMP ktmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr); 12834 12835 format %{ "countPositives byte[] $ary1,$len -> $result // KILL $tmp1, $tmp2, $tmp3" %} 12836 ins_encode %{ 12837 __ count_positives($ary1$$Register, $len$$Register, 12838 $result$$Register, $tmp3$$Register, 12839 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $ktmp1$$KRegister, $ktmp2$$KRegister); 12840 %} 12841 ins_pipe( pipe_slow ); 12842 %} 12843 12844 // fast char[] to byte[] compression 12845 instruct string_compress(rsi_RegP src, rdi_RegP dst, rdx_RegI len, legRegD tmp1, legRegD tmp2, legRegD tmp3, 12846 legRegD tmp4, rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 12847 predicate(!VM_Version::supports_avx512vlbw() || !VM_Version::supports_bmi2()); 12848 match(Set result (StrCompressedCopy src (Binary dst len))); 12849 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, 12850 USE_KILL len, KILL tmp5, KILL cr); 12851 12852 format %{ "String Compress $src,$dst -> $result // KILL RAX, RCX, RDX" %} 12853 ins_encode %{ 12854 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 12855 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 12856 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, 12857 knoreg, knoreg); 12858 %} 12859 ins_pipe( pipe_slow ); 12860 %} 12861 12862 instruct string_compress_evex(rsi_RegP src, rdi_RegP dst, rdx_RegI len, legRegD tmp1, legRegD tmp2, legRegD tmp3, 12863 legRegD tmp4, kReg ktmp1, kReg ktmp2, rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 12864 predicate(VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2()); 12865 match(Set result (StrCompressedCopy src (Binary dst len))); 12866 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP ktmp1, TEMP ktmp2, USE_KILL src, USE_KILL dst, 12867 USE_KILL len, KILL tmp5, KILL cr); 12868 12869 format %{ "String Compress $src,$dst -> $result // KILL RAX, RCX, RDX" %} 12870 ins_encode %{ 12871 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 12872 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 12873 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, 12874 $ktmp1$$KRegister, $ktmp2$$KRegister); 12875 %} 12876 ins_pipe( pipe_slow ); 12877 %} 12878 // fast byte[] to char[] inflation 12879 instruct string_inflate(Universe dummy, rsi_RegP src, rdi_RegP dst, rdx_RegI len, 12880 legRegD tmp1, rcx_RegI tmp2, rFlagsReg cr) %{ 12881 predicate(!VM_Version::supports_avx512vlbw() || !VM_Version::supports_bmi2()); 12882 match(Set dummy (StrInflatedCopy src (Binary dst len))); 12883 effect(TEMP tmp1, TEMP tmp2, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 12884 12885 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 12886 ins_encode %{ 12887 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 12888 $tmp1$$XMMRegister, $tmp2$$Register, knoreg); 12889 %} 12890 ins_pipe( pipe_slow ); 12891 %} 12892 12893 instruct string_inflate_evex(Universe dummy, rsi_RegP src, rdi_RegP dst, rdx_RegI len, 12894 legRegD tmp1, kReg ktmp, rcx_RegI tmp2, rFlagsReg cr) %{ 12895 predicate(VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2()); 12896 match(Set dummy (StrInflatedCopy src (Binary dst len))); 12897 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 12898 12899 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 12900 ins_encode %{ 12901 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 12902 $tmp1$$XMMRegister, $tmp2$$Register, $ktmp$$KRegister); 12903 %} 12904 ins_pipe( pipe_slow ); 12905 %} 12906 12907 // encode char[] to byte[] in ISO_8859_1 12908 instruct encode_iso_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len, 12909 legRegD tmp1, legRegD tmp2, legRegD tmp3, legRegD tmp4, 12910 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 12911 predicate(!((EncodeISOArrayNode*)n)->is_ascii()); 12912 match(Set result (EncodeISOArray src (Binary dst len))); 12913 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 12914 12915 format %{ "Encode iso array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %} 12916 ins_encode %{ 12917 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 12918 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 12919 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, false); 12920 %} 12921 ins_pipe( pipe_slow ); 12922 %} 12923 12924 // encode char[] to byte[] in ASCII 12925 instruct encode_ascii_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len, 12926 legRegD tmp1, legRegD tmp2, legRegD tmp3, legRegD tmp4, 12927 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 12928 predicate(((EncodeISOArrayNode*)n)->is_ascii()); 12929 match(Set result (EncodeISOArray src (Binary dst len))); 12930 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 12931 12932 format %{ "Encode ascii array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %} 12933 ins_encode %{ 12934 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 12935 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 12936 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, true); 12937 %} 12938 ins_pipe( pipe_slow ); 12939 %} 12940 12941 //----------Overflow Math Instructions----------------------------------------- 12942 12943 instruct overflowAddI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 12944 %{ 12945 match(Set cr (OverflowAddI op1 op2)); 12946 effect(DEF cr, USE_KILL op1, USE op2); 12947 12948 format %{ "addl $op1, $op2\t# overflow check int" %} 12949 12950 ins_encode %{ 12951 __ addl($op1$$Register, $op2$$Register); 12952 %} 12953 ins_pipe(ialu_reg_reg); 12954 %} 12955 12956 instruct overflowAddI_rReg_imm(rFlagsReg cr, rax_RegI op1, immI op2) 12957 %{ 12958 match(Set cr (OverflowAddI op1 op2)); 12959 effect(DEF cr, USE_KILL op1, USE op2); 12960 12961 format %{ "addl $op1, $op2\t# overflow check int" %} 12962 12963 ins_encode %{ 12964 __ addl($op1$$Register, $op2$$constant); 12965 %} 12966 ins_pipe(ialu_reg_reg); 12967 %} 12968 12969 instruct overflowAddL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 12970 %{ 12971 match(Set cr (OverflowAddL op1 op2)); 12972 effect(DEF cr, USE_KILL op1, USE op2); 12973 12974 format %{ "addq $op1, $op2\t# overflow check long" %} 12975 ins_encode %{ 12976 __ addq($op1$$Register, $op2$$Register); 12977 %} 12978 ins_pipe(ialu_reg_reg); 12979 %} 12980 12981 instruct overflowAddL_rReg_imm(rFlagsReg cr, rax_RegL op1, immL32 op2) 12982 %{ 12983 match(Set cr (OverflowAddL op1 op2)); 12984 effect(DEF cr, USE_KILL op1, USE op2); 12985 12986 format %{ "addq $op1, $op2\t# overflow check long" %} 12987 ins_encode %{ 12988 __ addq($op1$$Register, $op2$$constant); 12989 %} 12990 ins_pipe(ialu_reg_reg); 12991 %} 12992 12993 instruct overflowSubI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 12994 %{ 12995 match(Set cr (OverflowSubI op1 op2)); 12996 12997 format %{ "cmpl $op1, $op2\t# overflow check int" %} 12998 ins_encode %{ 12999 __ cmpl($op1$$Register, $op2$$Register); 13000 %} 13001 ins_pipe(ialu_reg_reg); 13002 %} 13003 13004 instruct overflowSubI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 13005 %{ 13006 match(Set cr (OverflowSubI op1 op2)); 13007 13008 format %{ "cmpl $op1, $op2\t# overflow check int" %} 13009 ins_encode %{ 13010 __ cmpl($op1$$Register, $op2$$constant); 13011 %} 13012 ins_pipe(ialu_reg_reg); 13013 %} 13014 13015 instruct overflowSubL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 13016 %{ 13017 match(Set cr (OverflowSubL op1 op2)); 13018 13019 format %{ "cmpq $op1, $op2\t# overflow check long" %} 13020 ins_encode %{ 13021 __ cmpq($op1$$Register, $op2$$Register); 13022 %} 13023 ins_pipe(ialu_reg_reg); 13024 %} 13025 13026 instruct overflowSubL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 13027 %{ 13028 match(Set cr (OverflowSubL op1 op2)); 13029 13030 format %{ "cmpq $op1, $op2\t# overflow check long" %} 13031 ins_encode %{ 13032 __ cmpq($op1$$Register, $op2$$constant); 13033 %} 13034 ins_pipe(ialu_reg_reg); 13035 %} 13036 13037 instruct overflowNegI_rReg(rFlagsReg cr, immI_0 zero, rax_RegI op2) 13038 %{ 13039 match(Set cr (OverflowSubI zero op2)); 13040 effect(DEF cr, USE_KILL op2); 13041 13042 format %{ "negl $op2\t# overflow check int" %} 13043 ins_encode %{ 13044 __ negl($op2$$Register); 13045 %} 13046 ins_pipe(ialu_reg_reg); 13047 %} 13048 13049 instruct overflowNegL_rReg(rFlagsReg cr, immL0 zero, rax_RegL op2) 13050 %{ 13051 match(Set cr (OverflowSubL zero op2)); 13052 effect(DEF cr, USE_KILL op2); 13053 13054 format %{ "negq $op2\t# overflow check long" %} 13055 ins_encode %{ 13056 __ negq($op2$$Register); 13057 %} 13058 ins_pipe(ialu_reg_reg); 13059 %} 13060 13061 instruct overflowMulI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 13062 %{ 13063 match(Set cr (OverflowMulI op1 op2)); 13064 effect(DEF cr, USE_KILL op1, USE op2); 13065 13066 format %{ "imull $op1, $op2\t# overflow check int" %} 13067 ins_encode %{ 13068 __ imull($op1$$Register, $op2$$Register); 13069 %} 13070 ins_pipe(ialu_reg_reg_alu0); 13071 %} 13072 13073 instruct overflowMulI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2, rRegI tmp) 13074 %{ 13075 match(Set cr (OverflowMulI op1 op2)); 13076 effect(DEF cr, TEMP tmp, USE op1, USE op2); 13077 13078 format %{ "imull $tmp, $op1, $op2\t# overflow check int" %} 13079 ins_encode %{ 13080 __ imull($tmp$$Register, $op1$$Register, $op2$$constant); 13081 %} 13082 ins_pipe(ialu_reg_reg_alu0); 13083 %} 13084 13085 instruct overflowMulL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 13086 %{ 13087 match(Set cr (OverflowMulL op1 op2)); 13088 effect(DEF cr, USE_KILL op1, USE op2); 13089 13090 format %{ "imulq $op1, $op2\t# overflow check long" %} 13091 ins_encode %{ 13092 __ imulq($op1$$Register, $op2$$Register); 13093 %} 13094 ins_pipe(ialu_reg_reg_alu0); 13095 %} 13096 13097 instruct overflowMulL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2, rRegL tmp) 13098 %{ 13099 match(Set cr (OverflowMulL op1 op2)); 13100 effect(DEF cr, TEMP tmp, USE op1, USE op2); 13101 13102 format %{ "imulq $tmp, $op1, $op2\t# overflow check long" %} 13103 ins_encode %{ 13104 __ imulq($tmp$$Register, $op1$$Register, $op2$$constant); 13105 %} 13106 ins_pipe(ialu_reg_reg_alu0); 13107 %} 13108 13109 13110 //----------Control Flow Instructions------------------------------------------ 13111 // Signed compare Instructions 13112 13113 // XXX more variants!! 13114 instruct compI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 13115 %{ 13116 match(Set cr (CmpI op1 op2)); 13117 effect(DEF cr, USE op1, USE op2); 13118 13119 format %{ "cmpl $op1, $op2" %} 13120 ins_encode %{ 13121 __ cmpl($op1$$Register, $op2$$Register); 13122 %} 13123 ins_pipe(ialu_cr_reg_reg); 13124 %} 13125 13126 instruct compI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 13127 %{ 13128 match(Set cr (CmpI op1 op2)); 13129 13130 format %{ "cmpl $op1, $op2" %} 13131 ins_encode %{ 13132 __ cmpl($op1$$Register, $op2$$constant); 13133 %} 13134 ins_pipe(ialu_cr_reg_imm); 13135 %} 13136 13137 instruct compI_rReg_mem(rFlagsReg cr, rRegI op1, memory op2) 13138 %{ 13139 match(Set cr (CmpI op1 (LoadI op2))); 13140 13141 ins_cost(500); // XXX 13142 format %{ "cmpl $op1, $op2" %} 13143 ins_encode %{ 13144 __ cmpl($op1$$Register, $op2$$Address); 13145 %} 13146 ins_pipe(ialu_cr_reg_mem); 13147 %} 13148 13149 instruct testI_reg(rFlagsReg cr, rRegI src, immI_0 zero) 13150 %{ 13151 match(Set cr (CmpI src zero)); 13152 13153 format %{ "testl $src, $src" %} 13154 ins_encode %{ 13155 __ testl($src$$Register, $src$$Register); 13156 %} 13157 ins_pipe(ialu_cr_reg_imm); 13158 %} 13159 13160 instruct testI_reg_imm(rFlagsReg cr, rRegI src, immI con, immI_0 zero) 13161 %{ 13162 match(Set cr (CmpI (AndI src con) zero)); 13163 13164 format %{ "testl $src, $con" %} 13165 ins_encode %{ 13166 __ testl($src$$Register, $con$$constant); 13167 %} 13168 ins_pipe(ialu_cr_reg_imm); 13169 %} 13170 13171 instruct testI_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2, immI_0 zero) 13172 %{ 13173 match(Set cr (CmpI (AndI src1 src2) zero)); 13174 13175 format %{ "testl $src1, $src2" %} 13176 ins_encode %{ 13177 __ testl($src1$$Register, $src2$$Register); 13178 %} 13179 ins_pipe(ialu_cr_reg_imm); 13180 %} 13181 13182 instruct testI_reg_mem(rFlagsReg cr, rRegI src, memory mem, immI_0 zero) 13183 %{ 13184 match(Set cr (CmpI (AndI src (LoadI mem)) zero)); 13185 13186 format %{ "testl $src, $mem" %} 13187 ins_encode %{ 13188 __ testl($src$$Register, $mem$$Address); 13189 %} 13190 ins_pipe(ialu_cr_reg_mem); 13191 %} 13192 13193 // Unsigned compare Instructions; really, same as signed except they 13194 // produce an rFlagsRegU instead of rFlagsReg. 13195 instruct compU_rReg(rFlagsRegU cr, rRegI op1, rRegI op2) 13196 %{ 13197 match(Set cr (CmpU op1 op2)); 13198 13199 format %{ "cmpl $op1, $op2\t# unsigned" %} 13200 ins_encode %{ 13201 __ cmpl($op1$$Register, $op2$$Register); 13202 %} 13203 ins_pipe(ialu_cr_reg_reg); 13204 %} 13205 13206 instruct compU_rReg_imm(rFlagsRegU cr, rRegI op1, immI op2) 13207 %{ 13208 match(Set cr (CmpU op1 op2)); 13209 13210 format %{ "cmpl $op1, $op2\t# unsigned" %} 13211 ins_encode %{ 13212 __ cmpl($op1$$Register, $op2$$constant); 13213 %} 13214 ins_pipe(ialu_cr_reg_imm); 13215 %} 13216 13217 instruct compU_rReg_mem(rFlagsRegU cr, rRegI op1, memory op2) 13218 %{ 13219 match(Set cr (CmpU op1 (LoadI op2))); 13220 13221 ins_cost(500); // XXX 13222 format %{ "cmpl $op1, $op2\t# unsigned" %} 13223 ins_encode %{ 13224 __ cmpl($op1$$Register, $op2$$Address); 13225 %} 13226 ins_pipe(ialu_cr_reg_mem); 13227 %} 13228 13229 instruct testU_reg(rFlagsRegU cr, rRegI src, immI_0 zero) 13230 %{ 13231 match(Set cr (CmpU src zero)); 13232 13233 format %{ "testl $src, $src\t# unsigned" %} 13234 ins_encode %{ 13235 __ testl($src$$Register, $src$$Register); 13236 %} 13237 ins_pipe(ialu_cr_reg_imm); 13238 %} 13239 13240 instruct compP_rReg(rFlagsRegU cr, rRegP op1, rRegP op2) 13241 %{ 13242 match(Set cr (CmpP op1 op2)); 13243 13244 format %{ "cmpq $op1, $op2\t# ptr" %} 13245 ins_encode %{ 13246 __ cmpq($op1$$Register, $op2$$Register); 13247 %} 13248 ins_pipe(ialu_cr_reg_reg); 13249 %} 13250 13251 instruct compP_rReg_mem(rFlagsRegU cr, rRegP op1, memory op2) 13252 %{ 13253 match(Set cr (CmpP op1 (LoadP op2))); 13254 predicate(n->in(2)->as_Load()->barrier_data() == 0); 13255 13256 ins_cost(500); // XXX 13257 format %{ "cmpq $op1, $op2\t# ptr" %} 13258 ins_encode %{ 13259 __ cmpq($op1$$Register, $op2$$Address); 13260 %} 13261 ins_pipe(ialu_cr_reg_mem); 13262 %} 13263 13264 // XXX this is generalized by compP_rReg_mem??? 13265 // Compare raw pointer (used in out-of-heap check). 13266 // Only works because non-oop pointers must be raw pointers 13267 // and raw pointers have no anti-dependencies. 13268 instruct compP_mem_rReg(rFlagsRegU cr, rRegP op1, memory op2) 13269 %{ 13270 predicate(n->in(2)->in(2)->bottom_type()->reloc() == relocInfo::none && 13271 n->in(2)->as_Load()->barrier_data() == 0); 13272 match(Set cr (CmpP op1 (LoadP op2))); 13273 13274 format %{ "cmpq $op1, $op2\t# raw ptr" %} 13275 ins_encode %{ 13276 __ cmpq($op1$$Register, $op2$$Address); 13277 %} 13278 ins_pipe(ialu_cr_reg_mem); 13279 %} 13280 13281 // This will generate a signed flags result. This should be OK since 13282 // any compare to a zero should be eq/neq. 13283 instruct testP_reg(rFlagsReg cr, rRegP src, immP0 zero) 13284 %{ 13285 match(Set cr (CmpP src zero)); 13286 13287 format %{ "testq $src, $src\t# ptr" %} 13288 ins_encode %{ 13289 __ testq($src$$Register, $src$$Register); 13290 %} 13291 ins_pipe(ialu_cr_reg_imm); 13292 %} 13293 13294 // This will generate a signed flags result. This should be OK since 13295 // any compare to a zero should be eq/neq. 13296 instruct testP_mem(rFlagsReg cr, memory op, immP0 zero) 13297 %{ 13298 predicate((!UseCompressedOops || (CompressedOops::base() != nullptr)) && 13299 n->in(1)->as_Load()->barrier_data() == 0); 13300 match(Set cr (CmpP (LoadP op) zero)); 13301 13302 ins_cost(500); // XXX 13303 format %{ "testq $op, 0xffffffffffffffff\t# ptr" %} 13304 ins_encode %{ 13305 __ testq($op$$Address, 0xFFFFFFFF); 13306 %} 13307 ins_pipe(ialu_cr_reg_imm); 13308 %} 13309 13310 instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero) 13311 %{ 13312 predicate(UseCompressedOops && (CompressedOops::base() == nullptr) && 13313 n->in(1)->as_Load()->barrier_data() == 0); 13314 match(Set cr (CmpP (LoadP mem) zero)); 13315 13316 format %{ "cmpq R12, $mem\t# ptr (R12_heapbase==0)" %} 13317 ins_encode %{ 13318 __ cmpq(r12, $mem$$Address); 13319 %} 13320 ins_pipe(ialu_cr_reg_mem); 13321 %} 13322 13323 instruct compN_rReg(rFlagsRegU cr, rRegN op1, rRegN op2) 13324 %{ 13325 match(Set cr (CmpN op1 op2)); 13326 13327 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 13328 ins_encode %{ __ cmpl($op1$$Register, $op2$$Register); %} 13329 ins_pipe(ialu_cr_reg_reg); 13330 %} 13331 13332 instruct compN_rReg_mem(rFlagsRegU cr, rRegN src, memory mem) 13333 %{ 13334 predicate(n->in(2)->as_Load()->barrier_data() == 0); 13335 match(Set cr (CmpN src (LoadN mem))); 13336 13337 format %{ "cmpl $src, $mem\t# compressed ptr" %} 13338 ins_encode %{ 13339 __ cmpl($src$$Register, $mem$$Address); 13340 %} 13341 ins_pipe(ialu_cr_reg_mem); 13342 %} 13343 13344 instruct compN_rReg_imm(rFlagsRegU cr, rRegN op1, immN op2) %{ 13345 match(Set cr (CmpN op1 op2)); 13346 13347 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 13348 ins_encode %{ 13349 __ cmp_narrow_oop($op1$$Register, (jobject)$op2$$constant); 13350 %} 13351 ins_pipe(ialu_cr_reg_imm); 13352 %} 13353 13354 instruct compN_mem_imm(rFlagsRegU cr, memory mem, immN src) 13355 %{ 13356 predicate(n->in(2)->as_Load()->barrier_data() == 0); 13357 match(Set cr (CmpN src (LoadN mem))); 13358 13359 format %{ "cmpl $mem, $src\t# compressed ptr" %} 13360 ins_encode %{ 13361 __ cmp_narrow_oop($mem$$Address, (jobject)$src$$constant); 13362 %} 13363 ins_pipe(ialu_cr_reg_mem); 13364 %} 13365 13366 instruct compN_rReg_imm_klass(rFlagsRegU cr, rRegN op1, immNKlass op2) %{ 13367 match(Set cr (CmpN op1 op2)); 13368 13369 format %{ "cmpl $op1, $op2\t# compressed klass ptr" %} 13370 ins_encode %{ 13371 __ cmp_narrow_klass($op1$$Register, (Klass*)$op2$$constant); 13372 %} 13373 ins_pipe(ialu_cr_reg_imm); 13374 %} 13375 13376 instruct compN_mem_imm_klass(rFlagsRegU cr, memory mem, immNKlass src) 13377 %{ 13378 predicate(!UseCompactObjectHeaders); 13379 match(Set cr (CmpN src (LoadNKlass mem))); 13380 13381 format %{ "cmpl $mem, $src\t# compressed klass ptr" %} 13382 ins_encode %{ 13383 __ cmp_narrow_klass($mem$$Address, (Klass*)$src$$constant); 13384 %} 13385 ins_pipe(ialu_cr_reg_mem); 13386 %} 13387 13388 instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{ 13389 match(Set cr (CmpN src zero)); 13390 13391 format %{ "testl $src, $src\t# compressed ptr" %} 13392 ins_encode %{ __ testl($src$$Register, $src$$Register); %} 13393 ins_pipe(ialu_cr_reg_imm); 13394 %} 13395 13396 instruct testN_mem(rFlagsReg cr, memory mem, immN0 zero) 13397 %{ 13398 predicate(CompressedOops::base() != nullptr && 13399 n->in(1)->as_Load()->barrier_data() == 0); 13400 match(Set cr (CmpN (LoadN mem) zero)); 13401 13402 ins_cost(500); // XXX 13403 format %{ "testl $mem, 0xffffffff\t# compressed ptr" %} 13404 ins_encode %{ 13405 __ cmpl($mem$$Address, (int)0xFFFFFFFF); 13406 %} 13407 ins_pipe(ialu_cr_reg_mem); 13408 %} 13409 13410 instruct testN_mem_reg0(rFlagsReg cr, memory mem, immN0 zero) 13411 %{ 13412 predicate(CompressedOops::base() == nullptr && 13413 n->in(1)->as_Load()->barrier_data() == 0); 13414 match(Set cr (CmpN (LoadN mem) zero)); 13415 13416 format %{ "cmpl R12, $mem\t# compressed ptr (R12_heapbase==0)" %} 13417 ins_encode %{ 13418 __ cmpl(r12, $mem$$Address); 13419 %} 13420 ins_pipe(ialu_cr_reg_mem); 13421 %} 13422 13423 // Yanked all unsigned pointer compare operations. 13424 // Pointer compares are done with CmpP which is already unsigned. 13425 13426 instruct compL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 13427 %{ 13428 match(Set cr (CmpL op1 op2)); 13429 13430 format %{ "cmpq $op1, $op2" %} 13431 ins_encode %{ 13432 __ cmpq($op1$$Register, $op2$$Register); 13433 %} 13434 ins_pipe(ialu_cr_reg_reg); 13435 %} 13436 13437 instruct compL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 13438 %{ 13439 match(Set cr (CmpL op1 op2)); 13440 13441 format %{ "cmpq $op1, $op2" %} 13442 ins_encode %{ 13443 __ cmpq($op1$$Register, $op2$$constant); 13444 %} 13445 ins_pipe(ialu_cr_reg_imm); 13446 %} 13447 13448 instruct compL_rReg_mem(rFlagsReg cr, rRegL op1, memory op2) 13449 %{ 13450 match(Set cr (CmpL op1 (LoadL op2))); 13451 13452 format %{ "cmpq $op1, $op2" %} 13453 ins_encode %{ 13454 __ cmpq($op1$$Register, $op2$$Address); 13455 %} 13456 ins_pipe(ialu_cr_reg_mem); 13457 %} 13458 13459 instruct testL_reg(rFlagsReg cr, rRegL src, immL0 zero) 13460 %{ 13461 match(Set cr (CmpL src zero)); 13462 13463 format %{ "testq $src, $src" %} 13464 ins_encode %{ 13465 __ testq($src$$Register, $src$$Register); 13466 %} 13467 ins_pipe(ialu_cr_reg_imm); 13468 %} 13469 13470 instruct testL_reg_imm(rFlagsReg cr, rRegL src, immL32 con, immL0 zero) 13471 %{ 13472 match(Set cr (CmpL (AndL src con) zero)); 13473 13474 format %{ "testq $src, $con\t# long" %} 13475 ins_encode %{ 13476 __ testq($src$$Register, $con$$constant); 13477 %} 13478 ins_pipe(ialu_cr_reg_imm); 13479 %} 13480 13481 instruct testL_reg_reg(rFlagsReg cr, rRegL src1, rRegL src2, immL0 zero) 13482 %{ 13483 match(Set cr (CmpL (AndL src1 src2) zero)); 13484 13485 format %{ "testq $src1, $src2\t# long" %} 13486 ins_encode %{ 13487 __ testq($src1$$Register, $src2$$Register); 13488 %} 13489 ins_pipe(ialu_cr_reg_imm); 13490 %} 13491 13492 instruct testL_reg_mem(rFlagsReg cr, rRegL src, memory mem, immL0 zero) 13493 %{ 13494 match(Set cr (CmpL (AndL src (LoadL mem)) zero)); 13495 13496 format %{ "testq $src, $mem" %} 13497 ins_encode %{ 13498 __ testq($src$$Register, $mem$$Address); 13499 %} 13500 ins_pipe(ialu_cr_reg_mem); 13501 %} 13502 13503 instruct testL_reg_mem2(rFlagsReg cr, rRegP src, memory mem, immL0 zero) 13504 %{ 13505 match(Set cr (CmpL (AndL (CastP2X src) (LoadL mem)) zero)); 13506 13507 format %{ "testq $src, $mem" %} 13508 ins_encode %{ 13509 __ testq($src$$Register, $mem$$Address); 13510 %} 13511 ins_pipe(ialu_cr_reg_mem); 13512 %} 13513 13514 // Manifest a CmpU result in an integer register. Very painful. 13515 // This is the test to avoid. 13516 instruct cmpU3_reg_reg(rRegI dst, rRegI src1, rRegI src2, rFlagsReg flags) 13517 %{ 13518 match(Set dst (CmpU3 src1 src2)); 13519 effect(KILL flags); 13520 13521 ins_cost(275); // XXX 13522 format %{ "cmpl $src1, $src2\t# CmpL3\n\t" 13523 "movl $dst, -1\n\t" 13524 "jb,u done\n\t" 13525 "setcc $dst \t# emits setne + movzbl or setzune for APX" 13526 "done:" %} 13527 ins_encode %{ 13528 Label done; 13529 __ cmpl($src1$$Register, $src2$$Register); 13530 __ movl($dst$$Register, -1); 13531 __ jccb(Assembler::below, done); 13532 __ setcc(Assembler::notZero, $dst$$Register); 13533 __ bind(done); 13534 %} 13535 ins_pipe(pipe_slow); 13536 %} 13537 13538 // Manifest a CmpL result in an integer register. Very painful. 13539 // This is the test to avoid. 13540 instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 13541 %{ 13542 match(Set dst (CmpL3 src1 src2)); 13543 effect(KILL flags); 13544 13545 ins_cost(275); // XXX 13546 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 13547 "movl $dst, -1\n\t" 13548 "jl,s done\n\t" 13549 "setcc $dst \t# emits setne + movzbl or setzune for APX" 13550 "done:" %} 13551 ins_encode %{ 13552 Label done; 13553 __ cmpq($src1$$Register, $src2$$Register); 13554 __ movl($dst$$Register, -1); 13555 __ jccb(Assembler::less, done); 13556 __ setcc(Assembler::notZero, $dst$$Register); 13557 __ bind(done); 13558 %} 13559 ins_pipe(pipe_slow); 13560 %} 13561 13562 // Manifest a CmpUL result in an integer register. Very painful. 13563 // This is the test to avoid. 13564 instruct cmpUL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 13565 %{ 13566 match(Set dst (CmpUL3 src1 src2)); 13567 effect(KILL flags); 13568 13569 ins_cost(275); // XXX 13570 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 13571 "movl $dst, -1\n\t" 13572 "jb,u done\n\t" 13573 "setcc $dst \t# emits setne + movzbl or setzune for APX" 13574 "done:" %} 13575 ins_encode %{ 13576 Label done; 13577 __ cmpq($src1$$Register, $src2$$Register); 13578 __ movl($dst$$Register, -1); 13579 __ jccb(Assembler::below, done); 13580 __ setcc(Assembler::notZero, $dst$$Register); 13581 __ bind(done); 13582 %} 13583 ins_pipe(pipe_slow); 13584 %} 13585 13586 // Unsigned long compare Instructions; really, same as signed long except they 13587 // produce an rFlagsRegU instead of rFlagsReg. 13588 instruct compUL_rReg(rFlagsRegU cr, rRegL op1, rRegL op2) 13589 %{ 13590 match(Set cr (CmpUL op1 op2)); 13591 13592 format %{ "cmpq $op1, $op2\t# unsigned" %} 13593 ins_encode %{ 13594 __ cmpq($op1$$Register, $op2$$Register); 13595 %} 13596 ins_pipe(ialu_cr_reg_reg); 13597 %} 13598 13599 instruct compUL_rReg_imm(rFlagsRegU cr, rRegL op1, immL32 op2) 13600 %{ 13601 match(Set cr (CmpUL op1 op2)); 13602 13603 format %{ "cmpq $op1, $op2\t# unsigned" %} 13604 ins_encode %{ 13605 __ cmpq($op1$$Register, $op2$$constant); 13606 %} 13607 ins_pipe(ialu_cr_reg_imm); 13608 %} 13609 13610 instruct compUL_rReg_mem(rFlagsRegU cr, rRegL op1, memory op2) 13611 %{ 13612 match(Set cr (CmpUL op1 (LoadL op2))); 13613 13614 format %{ "cmpq $op1, $op2\t# unsigned" %} 13615 ins_encode %{ 13616 __ cmpq($op1$$Register, $op2$$Address); 13617 %} 13618 ins_pipe(ialu_cr_reg_mem); 13619 %} 13620 13621 instruct testUL_reg(rFlagsRegU cr, rRegL src, immL0 zero) 13622 %{ 13623 match(Set cr (CmpUL src zero)); 13624 13625 format %{ "testq $src, $src\t# unsigned" %} 13626 ins_encode %{ 13627 __ testq($src$$Register, $src$$Register); 13628 %} 13629 ins_pipe(ialu_cr_reg_imm); 13630 %} 13631 13632 instruct compB_mem_imm(rFlagsReg cr, memory mem, immI8 imm) 13633 %{ 13634 match(Set cr (CmpI (LoadB mem) imm)); 13635 13636 ins_cost(125); 13637 format %{ "cmpb $mem, $imm" %} 13638 ins_encode %{ __ cmpb($mem$$Address, $imm$$constant); %} 13639 ins_pipe(ialu_cr_reg_mem); 13640 %} 13641 13642 instruct testUB_mem_imm(rFlagsReg cr, memory mem, immU7 imm, immI_0 zero) 13643 %{ 13644 match(Set cr (CmpI (AndI (LoadUB mem) imm) zero)); 13645 13646 ins_cost(125); 13647 format %{ "testb $mem, $imm\t# ubyte" %} 13648 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %} 13649 ins_pipe(ialu_cr_reg_mem); 13650 %} 13651 13652 instruct testB_mem_imm(rFlagsReg cr, memory mem, immI8 imm, immI_0 zero) 13653 %{ 13654 match(Set cr (CmpI (AndI (LoadB mem) imm) zero)); 13655 13656 ins_cost(125); 13657 format %{ "testb $mem, $imm\t# byte" %} 13658 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %} 13659 ins_pipe(ialu_cr_reg_mem); 13660 %} 13661 13662 //----------Max and Min-------------------------------------------------------- 13663 // Min Instructions 13664 13665 instruct cmovI_reg_g(rRegI dst, rRegI src, rFlagsReg cr) 13666 %{ 13667 predicate(!UseAPX); 13668 effect(USE_DEF dst, USE src, USE cr); 13669 13670 format %{ "cmovlgt $dst, $src\t# min" %} 13671 ins_encode %{ 13672 __ cmovl(Assembler::greater, $dst$$Register, $src$$Register); 13673 %} 13674 ins_pipe(pipe_cmov_reg); 13675 %} 13676 13677 instruct cmovI_reg_g_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr) 13678 %{ 13679 predicate(UseAPX); 13680 effect(DEF dst, USE src1, USE src2, USE cr); 13681 13682 format %{ "ecmovlgt $dst, $src1, $src2\t# min ndd" %} 13683 ins_encode %{ 13684 __ ecmovl(Assembler::greater, $dst$$Register, $src1$$Register, $src2$$Register); 13685 %} 13686 ins_pipe(pipe_cmov_reg); 13687 %} 13688 13689 instruct minI_rReg(rRegI dst, rRegI src) 13690 %{ 13691 predicate(!UseAPX); 13692 match(Set dst (MinI dst src)); 13693 13694 ins_cost(200); 13695 expand %{ 13696 rFlagsReg cr; 13697 compI_rReg(cr, dst, src); 13698 cmovI_reg_g(dst, src, cr); 13699 %} 13700 %} 13701 13702 instruct minI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2) 13703 %{ 13704 predicate(UseAPX); 13705 match(Set dst (MinI src1 src2)); 13706 effect(DEF dst, USE src1, USE src2); 13707 13708 ins_cost(200); 13709 expand %{ 13710 rFlagsReg cr; 13711 compI_rReg(cr, src1, src2); 13712 cmovI_reg_g_ndd(dst, src1, src2, cr); 13713 %} 13714 %} 13715 13716 instruct cmovI_reg_l(rRegI dst, rRegI src, rFlagsReg cr) 13717 %{ 13718 predicate(!UseAPX); 13719 effect(USE_DEF dst, USE src, USE cr); 13720 13721 format %{ "cmovllt $dst, $src\t# max" %} 13722 ins_encode %{ 13723 __ cmovl(Assembler::less, $dst$$Register, $src$$Register); 13724 %} 13725 ins_pipe(pipe_cmov_reg); 13726 %} 13727 13728 instruct cmovI_reg_l_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr) 13729 %{ 13730 predicate(UseAPX); 13731 effect(DEF dst, USE src1, USE src2, USE cr); 13732 13733 format %{ "ecmovllt $dst, $src1, $src2\t# max ndd" %} 13734 ins_encode %{ 13735 __ ecmovl(Assembler::less, $dst$$Register, $src1$$Register, $src2$$Register); 13736 %} 13737 ins_pipe(pipe_cmov_reg); 13738 %} 13739 13740 instruct maxI_rReg(rRegI dst, rRegI src) 13741 %{ 13742 predicate(!UseAPX); 13743 match(Set dst (MaxI dst src)); 13744 13745 ins_cost(200); 13746 expand %{ 13747 rFlagsReg cr; 13748 compI_rReg(cr, dst, src); 13749 cmovI_reg_l(dst, src, cr); 13750 %} 13751 %} 13752 13753 instruct maxI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2) 13754 %{ 13755 predicate(UseAPX); 13756 match(Set dst (MaxI src1 src2)); 13757 effect(DEF dst, USE src1, USE src2); 13758 13759 ins_cost(200); 13760 expand %{ 13761 rFlagsReg cr; 13762 compI_rReg(cr, src1, src2); 13763 cmovI_reg_l_ndd(dst, src1, src2, cr); 13764 %} 13765 %} 13766 13767 // ============================================================================ 13768 // Branch Instructions 13769 13770 // Jump Direct - Label defines a relative address from JMP+1 13771 instruct jmpDir(label labl) 13772 %{ 13773 match(Goto); 13774 effect(USE labl); 13775 13776 ins_cost(300); 13777 format %{ "jmp $labl" %} 13778 size(5); 13779 ins_encode %{ 13780 Label* L = $labl$$label; 13781 __ jmp(*L, false); // Always long jump 13782 %} 13783 ins_pipe(pipe_jmp); 13784 %} 13785 13786 // Jump Direct Conditional - Label defines a relative address from Jcc+1 13787 instruct jmpCon(cmpOp cop, rFlagsReg cr, label labl) 13788 %{ 13789 match(If cop cr); 13790 effect(USE labl); 13791 13792 ins_cost(300); 13793 format %{ "j$cop $labl" %} 13794 size(6); 13795 ins_encode %{ 13796 Label* L = $labl$$label; 13797 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 13798 %} 13799 ins_pipe(pipe_jcc); 13800 %} 13801 13802 // Jump Direct Conditional - Label defines a relative address from Jcc+1 13803 instruct jmpLoopEnd(cmpOp cop, rFlagsReg cr, label labl) 13804 %{ 13805 match(CountedLoopEnd cop cr); 13806 effect(USE labl); 13807 13808 ins_cost(300); 13809 format %{ "j$cop $labl\t# loop end" %} 13810 size(6); 13811 ins_encode %{ 13812 Label* L = $labl$$label; 13813 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 13814 %} 13815 ins_pipe(pipe_jcc); 13816 %} 13817 13818 // Jump Direct Conditional - using unsigned comparison 13819 instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 13820 match(If cop cmp); 13821 effect(USE labl); 13822 13823 ins_cost(300); 13824 format %{ "j$cop,u $labl" %} 13825 size(6); 13826 ins_encode %{ 13827 Label* L = $labl$$label; 13828 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 13829 %} 13830 ins_pipe(pipe_jcc); 13831 %} 13832 13833 instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 13834 match(If cop cmp); 13835 effect(USE labl); 13836 13837 ins_cost(200); 13838 format %{ "j$cop,u $labl" %} 13839 size(6); 13840 ins_encode %{ 13841 Label* L = $labl$$label; 13842 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 13843 %} 13844 ins_pipe(pipe_jcc); 13845 %} 13846 13847 instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 13848 match(If cop cmp); 13849 effect(USE labl); 13850 13851 ins_cost(200); 13852 format %{ $$template 13853 if ($cop$$cmpcode == Assembler::notEqual) { 13854 $$emit$$"jp,u $labl\n\t" 13855 $$emit$$"j$cop,u $labl" 13856 } else { 13857 $$emit$$"jp,u done\n\t" 13858 $$emit$$"j$cop,u $labl\n\t" 13859 $$emit$$"done:" 13860 } 13861 %} 13862 ins_encode %{ 13863 Label* l = $labl$$label; 13864 if ($cop$$cmpcode == Assembler::notEqual) { 13865 __ jcc(Assembler::parity, *l, false); 13866 __ jcc(Assembler::notEqual, *l, false); 13867 } else if ($cop$$cmpcode == Assembler::equal) { 13868 Label done; 13869 __ jccb(Assembler::parity, done); 13870 __ jcc(Assembler::equal, *l, false); 13871 __ bind(done); 13872 } else { 13873 ShouldNotReachHere(); 13874 } 13875 %} 13876 ins_pipe(pipe_jcc); 13877 %} 13878 13879 // ============================================================================ 13880 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary 13881 // superklass array for an instance of the superklass. Set a hidden 13882 // internal cache on a hit (cache is checked with exposed code in 13883 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The 13884 // encoding ALSO sets flags. 13885 13886 instruct partialSubtypeCheck(rdi_RegP result, 13887 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 13888 rFlagsReg cr) 13889 %{ 13890 match(Set result (PartialSubtypeCheck sub super)); 13891 predicate(!UseSecondarySupersTable); 13892 effect(KILL rcx, KILL cr); 13893 13894 ins_cost(1100); // slightly larger than the next version 13895 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 13896 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 13897 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 13898 "repne scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t" 13899 "jne,s miss\t\t# Missed: rdi not-zero\n\t" 13900 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 13901 "xorq $result, $result\t\t Hit: rdi zero\n\t" 13902 "miss:\t" %} 13903 13904 ins_encode %{ 13905 Label miss; 13906 // NB: Callers may assume that, when $result is a valid register, 13907 // check_klass_subtype_slow_path_linear sets it to a nonzero 13908 // value. 13909 __ check_klass_subtype_slow_path_linear($sub$$Register, $super$$Register, 13910 $rcx$$Register, $result$$Register, 13911 nullptr, &miss, 13912 /*set_cond_codes:*/ true); 13913 __ xorptr($result$$Register, $result$$Register); 13914 __ bind(miss); 13915 %} 13916 13917 ins_pipe(pipe_slow); 13918 %} 13919 13920 // ============================================================================ 13921 // Two versions of hashtable-based partialSubtypeCheck, both used when 13922 // we need to search for a super class in the secondary supers array. 13923 // The first is used when we don't know _a priori_ the class being 13924 // searched for. The second, far more common, is used when we do know: 13925 // this is used for instanceof, checkcast, and any case where C2 can 13926 // determine it by constant propagation. 13927 13928 instruct partialSubtypeCheckVarSuper(rsi_RegP sub, rax_RegP super, rdi_RegP result, 13929 rdx_RegL temp1, rcx_RegL temp2, rbx_RegP temp3, r11_RegL temp4, 13930 rFlagsReg cr) 13931 %{ 13932 match(Set result (PartialSubtypeCheck sub super)); 13933 predicate(UseSecondarySupersTable); 13934 effect(KILL cr, TEMP temp1, TEMP temp2, TEMP temp3, TEMP temp4); 13935 13936 ins_cost(1000); 13937 format %{ "partialSubtypeCheck $result, $sub, $super" %} 13938 13939 ins_encode %{ 13940 __ lookup_secondary_supers_table_var($sub$$Register, $super$$Register, $temp1$$Register, $temp2$$Register, 13941 $temp3$$Register, $temp4$$Register, $result$$Register); 13942 %} 13943 13944 ins_pipe(pipe_slow); 13945 %} 13946 13947 instruct partialSubtypeCheckConstSuper(rsi_RegP sub, rax_RegP super_reg, immP super_con, rdi_RegP result, 13948 rdx_RegL temp1, rcx_RegL temp2, rbx_RegP temp3, r11_RegL temp4, 13949 rFlagsReg cr) 13950 %{ 13951 match(Set result (PartialSubtypeCheck sub (Binary super_reg super_con))); 13952 predicate(UseSecondarySupersTable); 13953 effect(KILL cr, TEMP temp1, TEMP temp2, TEMP temp3, TEMP temp4); 13954 13955 ins_cost(700); // smaller than the next version 13956 format %{ "partialSubtypeCheck $result, $sub, $super_reg, $super_con" %} 13957 13958 ins_encode %{ 13959 u1 super_klass_slot = ((Klass*)$super_con$$constant)->hash_slot(); 13960 if (InlineSecondarySupersTest) { 13961 __ lookup_secondary_supers_table_const($sub$$Register, $super_reg$$Register, $temp1$$Register, $temp2$$Register, 13962 $temp3$$Register, $temp4$$Register, $result$$Register, 13963 super_klass_slot); 13964 } else { 13965 __ call(RuntimeAddress(StubRoutines::lookup_secondary_supers_table_stub(super_klass_slot))); 13966 } 13967 %} 13968 13969 ins_pipe(pipe_slow); 13970 %} 13971 13972 // ============================================================================ 13973 // Branch Instructions -- short offset versions 13974 // 13975 // These instructions are used to replace jumps of a long offset (the default 13976 // match) with jumps of a shorter offset. These instructions are all tagged 13977 // with the ins_short_branch attribute, which causes the ADLC to suppress the 13978 // match rules in general matching. Instead, the ADLC generates a conversion 13979 // method in the MachNode which can be used to do in-place replacement of the 13980 // long variant with the shorter variant. The compiler will determine if a 13981 // branch can be taken by the is_short_branch_offset() predicate in the machine 13982 // specific code section of the file. 13983 13984 // Jump Direct - Label defines a relative address from JMP+1 13985 instruct jmpDir_short(label labl) %{ 13986 match(Goto); 13987 effect(USE labl); 13988 13989 ins_cost(300); 13990 format %{ "jmp,s $labl" %} 13991 size(2); 13992 ins_encode %{ 13993 Label* L = $labl$$label; 13994 __ jmpb(*L); 13995 %} 13996 ins_pipe(pipe_jmp); 13997 ins_short_branch(1); 13998 %} 13999 14000 // Jump Direct Conditional - Label defines a relative address from Jcc+1 14001 instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{ 14002 match(If cop cr); 14003 effect(USE labl); 14004 14005 ins_cost(300); 14006 format %{ "j$cop,s $labl" %} 14007 size(2); 14008 ins_encode %{ 14009 Label* L = $labl$$label; 14010 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 14011 %} 14012 ins_pipe(pipe_jcc); 14013 ins_short_branch(1); 14014 %} 14015 14016 // Jump Direct Conditional - Label defines a relative address from Jcc+1 14017 instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{ 14018 match(CountedLoopEnd cop cr); 14019 effect(USE labl); 14020 14021 ins_cost(300); 14022 format %{ "j$cop,s $labl\t# loop end" %} 14023 size(2); 14024 ins_encode %{ 14025 Label* L = $labl$$label; 14026 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 14027 %} 14028 ins_pipe(pipe_jcc); 14029 ins_short_branch(1); 14030 %} 14031 14032 // Jump Direct Conditional - using unsigned comparison 14033 instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 14034 match(If cop cmp); 14035 effect(USE labl); 14036 14037 ins_cost(300); 14038 format %{ "j$cop,us $labl" %} 14039 size(2); 14040 ins_encode %{ 14041 Label* L = $labl$$label; 14042 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 14043 %} 14044 ins_pipe(pipe_jcc); 14045 ins_short_branch(1); 14046 %} 14047 14048 instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 14049 match(If cop cmp); 14050 effect(USE labl); 14051 14052 ins_cost(300); 14053 format %{ "j$cop,us $labl" %} 14054 size(2); 14055 ins_encode %{ 14056 Label* L = $labl$$label; 14057 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 14058 %} 14059 ins_pipe(pipe_jcc); 14060 ins_short_branch(1); 14061 %} 14062 14063 instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 14064 match(If cop cmp); 14065 effect(USE labl); 14066 14067 ins_cost(300); 14068 format %{ $$template 14069 if ($cop$$cmpcode == Assembler::notEqual) { 14070 $$emit$$"jp,u,s $labl\n\t" 14071 $$emit$$"j$cop,u,s $labl" 14072 } else { 14073 $$emit$$"jp,u,s done\n\t" 14074 $$emit$$"j$cop,u,s $labl\n\t" 14075 $$emit$$"done:" 14076 } 14077 %} 14078 size(4); 14079 ins_encode %{ 14080 Label* l = $labl$$label; 14081 if ($cop$$cmpcode == Assembler::notEqual) { 14082 __ jccb(Assembler::parity, *l); 14083 __ jccb(Assembler::notEqual, *l); 14084 } else if ($cop$$cmpcode == Assembler::equal) { 14085 Label done; 14086 __ jccb(Assembler::parity, done); 14087 __ jccb(Assembler::equal, *l); 14088 __ bind(done); 14089 } else { 14090 ShouldNotReachHere(); 14091 } 14092 %} 14093 ins_pipe(pipe_jcc); 14094 ins_short_branch(1); 14095 %} 14096 14097 // ============================================================================ 14098 // inlined locking and unlocking 14099 14100 instruct cmpFastLockLightweight(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI rax_reg, rRegP tmp) %{ 14101 match(Set cr (FastLock object box)); 14102 effect(TEMP rax_reg, TEMP tmp, USE_KILL box); 14103 ins_cost(300); 14104 format %{ "fastlock $object,$box\t! kills $box,$rax_reg,$tmp" %} 14105 ins_encode %{ 14106 __ fast_lock_lightweight($object$$Register, $box$$Register, $rax_reg$$Register, $tmp$$Register, r15_thread); 14107 %} 14108 ins_pipe(pipe_slow); 14109 %} 14110 14111 instruct cmpFastUnlockLightweight(rFlagsReg cr, rRegP object, rax_RegP rax_reg, rRegP tmp) %{ 14112 match(Set cr (FastUnlock object rax_reg)); 14113 effect(TEMP tmp, USE_KILL rax_reg); 14114 ins_cost(300); 14115 format %{ "fastunlock $object,$rax_reg\t! kills $rax_reg,$tmp" %} 14116 ins_encode %{ 14117 __ fast_unlock_lightweight($object$$Register, $rax_reg$$Register, $tmp$$Register, r15_thread); 14118 %} 14119 ins_pipe(pipe_slow); 14120 %} 14121 14122 14123 // ============================================================================ 14124 // Safepoint Instructions 14125 instruct safePoint_poll_tls(rFlagsReg cr, rRegP poll) 14126 %{ 14127 match(SafePoint poll); 14128 effect(KILL cr, USE poll); 14129 14130 format %{ "testl rax, [$poll]\t" 14131 "# Safepoint: poll for GC" %} 14132 ins_cost(125); 14133 ins_encode %{ 14134 __ relocate(relocInfo::poll_type); 14135 address pre_pc = __ pc(); 14136 __ testl(rax, Address($poll$$Register, 0)); 14137 assert(nativeInstruction_at(pre_pc)->is_safepoint_poll(), "must emit test %%eax [reg]"); 14138 %} 14139 ins_pipe(ialu_reg_mem); 14140 %} 14141 14142 instruct mask_all_evexL(kReg dst, rRegL src) %{ 14143 match(Set dst (MaskAll src)); 14144 format %{ "mask_all_evexL $dst, $src \t! mask all operation" %} 14145 ins_encode %{ 14146 int mask_len = Matcher::vector_length(this); 14147 __ vector_maskall_operation($dst$$KRegister, $src$$Register, mask_len); 14148 %} 14149 ins_pipe( pipe_slow ); 14150 %} 14151 14152 instruct mask_all_evexI_GT32(kReg dst, rRegI src, rRegL tmp) %{ 14153 predicate(Matcher::vector_length(n) > 32); 14154 match(Set dst (MaskAll src)); 14155 effect(TEMP tmp); 14156 format %{ "mask_all_evexI_GT32 $dst, $src \t! using $tmp as TEMP" %} 14157 ins_encode %{ 14158 int mask_len = Matcher::vector_length(this); 14159 __ movslq($tmp$$Register, $src$$Register); 14160 __ vector_maskall_operation($dst$$KRegister, $tmp$$Register, mask_len); 14161 %} 14162 ins_pipe( pipe_slow ); 14163 %} 14164 14165 // ============================================================================ 14166 // Procedure Call/Return Instructions 14167 // Call Java Static Instruction 14168 // Note: If this code changes, the corresponding ret_addr_offset() and 14169 // compute_padding() functions will have to be adjusted. 14170 instruct CallStaticJavaDirect(method meth) %{ 14171 match(CallStaticJava); 14172 effect(USE meth); 14173 14174 ins_cost(300); 14175 format %{ "call,static " %} 14176 opcode(0xE8); /* E8 cd */ 14177 ins_encode(clear_avx, Java_Static_Call(meth), call_epilog); 14178 ins_pipe(pipe_slow); 14179 ins_alignment(4); 14180 %} 14181 14182 // Call Java Dynamic Instruction 14183 // Note: If this code changes, the corresponding ret_addr_offset() and 14184 // compute_padding() functions will have to be adjusted. 14185 instruct CallDynamicJavaDirect(method meth) 14186 %{ 14187 match(CallDynamicJava); 14188 effect(USE meth); 14189 14190 ins_cost(300); 14191 format %{ "movq rax, #Universe::non_oop_word()\n\t" 14192 "call,dynamic " %} 14193 ins_encode(clear_avx, Java_Dynamic_Call(meth), call_epilog); 14194 ins_pipe(pipe_slow); 14195 ins_alignment(4); 14196 %} 14197 14198 // Call Runtime Instruction 14199 instruct CallRuntimeDirect(method meth) 14200 %{ 14201 match(CallRuntime); 14202 effect(USE meth); 14203 14204 ins_cost(300); 14205 format %{ "call,runtime " %} 14206 ins_encode(clear_avx, Java_To_Runtime(meth)); 14207 ins_pipe(pipe_slow); 14208 %} 14209 14210 // Call runtime without safepoint 14211 instruct CallLeafDirect(method meth) 14212 %{ 14213 match(CallLeaf); 14214 effect(USE meth); 14215 14216 ins_cost(300); 14217 format %{ "call_leaf,runtime " %} 14218 ins_encode(clear_avx, Java_To_Runtime(meth)); 14219 ins_pipe(pipe_slow); 14220 %} 14221 14222 // Call runtime without safepoint and with vector arguments 14223 instruct CallLeafDirectVector(method meth) 14224 %{ 14225 match(CallLeafVector); 14226 effect(USE meth); 14227 14228 ins_cost(300); 14229 format %{ "call_leaf,vector " %} 14230 ins_encode(Java_To_Runtime(meth)); 14231 ins_pipe(pipe_slow); 14232 %} 14233 14234 // Call runtime without safepoint 14235 instruct CallLeafNoFPDirect(method meth) 14236 %{ 14237 match(CallLeafNoFP); 14238 effect(USE meth); 14239 14240 ins_cost(300); 14241 format %{ "call_leaf_nofp,runtime " %} 14242 ins_encode(clear_avx, Java_To_Runtime(meth)); 14243 ins_pipe(pipe_slow); 14244 %} 14245 14246 // Return Instruction 14247 // Remove the return address & jump to it. 14248 // Notice: We always emit a nop after a ret to make sure there is room 14249 // for safepoint patching 14250 instruct Ret() 14251 %{ 14252 match(Return); 14253 14254 format %{ "ret" %} 14255 ins_encode %{ 14256 __ ret(0); 14257 %} 14258 ins_pipe(pipe_jmp); 14259 %} 14260 14261 // Tail Call; Jump from runtime stub to Java code. 14262 // Also known as an 'interprocedural jump'. 14263 // Target of jump will eventually return to caller. 14264 // TailJump below removes the return address. 14265 // Don't use rbp for 'jump_target' because a MachEpilogNode has already been 14266 // emitted just above the TailCall which has reset rbp to the caller state. 14267 instruct TailCalljmpInd(no_rbp_RegP jump_target, rbx_RegP method_ptr) 14268 %{ 14269 match(TailCall jump_target method_ptr); 14270 14271 ins_cost(300); 14272 format %{ "jmp $jump_target\t# rbx holds method" %} 14273 ins_encode %{ 14274 __ jmp($jump_target$$Register); 14275 %} 14276 ins_pipe(pipe_jmp); 14277 %} 14278 14279 // Tail Jump; remove the return address; jump to target. 14280 // TailCall above leaves the return address around. 14281 instruct tailjmpInd(no_rbp_RegP jump_target, rax_RegP ex_oop) 14282 %{ 14283 match(TailJump jump_target ex_oop); 14284 14285 ins_cost(300); 14286 format %{ "popq rdx\t# pop return address\n\t" 14287 "jmp $jump_target" %} 14288 ins_encode %{ 14289 __ popq(as_Register(RDX_enc)); 14290 __ jmp($jump_target$$Register); 14291 %} 14292 ins_pipe(pipe_jmp); 14293 %} 14294 14295 // Forward exception. 14296 instruct ForwardExceptionjmp() 14297 %{ 14298 match(ForwardException); 14299 14300 format %{ "jmp forward_exception_stub" %} 14301 ins_encode %{ 14302 __ jump(RuntimeAddress(StubRoutines::forward_exception_entry()), noreg); 14303 %} 14304 ins_pipe(pipe_jmp); 14305 %} 14306 14307 // Create exception oop: created by stack-crawling runtime code. 14308 // Created exception is now available to this handler, and is setup 14309 // just prior to jumping to this handler. No code emitted. 14310 instruct CreateException(rax_RegP ex_oop) 14311 %{ 14312 match(Set ex_oop (CreateEx)); 14313 14314 size(0); 14315 // use the following format syntax 14316 format %{ "# exception oop is in rax; no code emitted" %} 14317 ins_encode(); 14318 ins_pipe(empty); 14319 %} 14320 14321 // Rethrow exception: 14322 // The exception oop will come in the first argument position. 14323 // Then JUMP (not call) to the rethrow stub code. 14324 instruct RethrowException() 14325 %{ 14326 match(Rethrow); 14327 14328 // use the following format syntax 14329 format %{ "jmp rethrow_stub" %} 14330 ins_encode %{ 14331 __ jump(RuntimeAddress(OptoRuntime::rethrow_stub()), noreg); 14332 %} 14333 ins_pipe(pipe_jmp); 14334 %} 14335 14336 // ============================================================================ 14337 // This name is KNOWN by the ADLC and cannot be changed. 14338 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type 14339 // for this guy. 14340 instruct tlsLoadP(r15_RegP dst) %{ 14341 match(Set dst (ThreadLocal)); 14342 effect(DEF dst); 14343 14344 size(0); 14345 format %{ "# TLS is in R15" %} 14346 ins_encode( /*empty encoding*/ ); 14347 ins_pipe(ialu_reg_reg); 14348 %} 14349 14350 14351 //----------PEEPHOLE RULES----------------------------------------------------- 14352 // These must follow all instruction definitions as they use the names 14353 // defined in the instructions definitions. 14354 // 14355 // peeppredicate ( rule_predicate ); 14356 // // the predicate unless which the peephole rule will be ignored 14357 // 14358 // peepmatch ( root_instr_name [preceding_instruction]* ); 14359 // 14360 // peepprocedure ( procedure_name ); 14361 // // provide a procedure name to perform the optimization, the procedure should 14362 // // reside in the architecture dependent peephole file, the method has the 14363 // // signature of MachNode* (Block*, int, PhaseRegAlloc*, (MachNode*)(*)(), int...) 14364 // // with the arguments being the basic block, the current node index inside the 14365 // // block, the register allocator, the functions upon invoked return a new node 14366 // // defined in peepreplace, and the rules of the nodes appearing in the 14367 // // corresponding peepmatch, the function return true if successful, else 14368 // // return false 14369 // 14370 // peepconstraint %{ 14371 // (instruction_number.operand_name relational_op instruction_number.operand_name 14372 // [, ...] ); 14373 // // instruction numbers are zero-based using left to right order in peepmatch 14374 // 14375 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 14376 // // provide an instruction_number.operand_name for each operand that appears 14377 // // in the replacement instruction's match rule 14378 // 14379 // ---------VM FLAGS--------------------------------------------------------- 14380 // 14381 // All peephole optimizations can be turned off using -XX:-OptoPeephole 14382 // 14383 // Each peephole rule is given an identifying number starting with zero and 14384 // increasing by one in the order seen by the parser. An individual peephole 14385 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 14386 // on the command-line. 14387 // 14388 // ---------CURRENT LIMITATIONS---------------------------------------------- 14389 // 14390 // Only transformations inside a basic block (do we need more for peephole) 14391 // 14392 // ---------EXAMPLE---------------------------------------------------------- 14393 // 14394 // // pertinent parts of existing instructions in architecture description 14395 // instruct movI(rRegI dst, rRegI src) 14396 // %{ 14397 // match(Set dst (CopyI src)); 14398 // %} 14399 // 14400 // instruct incI_rReg(rRegI dst, immI_1 src, rFlagsReg cr) 14401 // %{ 14402 // match(Set dst (AddI dst src)); 14403 // effect(KILL cr); 14404 // %} 14405 // 14406 // instruct leaI_rReg_immI(rRegI dst, immI_1 src) 14407 // %{ 14408 // match(Set dst (AddI dst src)); 14409 // %} 14410 // 14411 // 1. Simple replacement 14412 // - Only match adjacent instructions in same basic block 14413 // - Only equality constraints 14414 // - Only constraints between operands, not (0.dest_reg == RAX_enc) 14415 // - Only one replacement instruction 14416 // 14417 // // Change (inc mov) to lea 14418 // peephole %{ 14419 // // lea should only be emitted when beneficial 14420 // peeppredicate( VM_Version::supports_fast_2op_lea() ); 14421 // // increment preceded by register-register move 14422 // peepmatch ( incI_rReg movI ); 14423 // // require that the destination register of the increment 14424 // // match the destination register of the move 14425 // peepconstraint ( 0.dst == 1.dst ); 14426 // // construct a replacement instruction that sets 14427 // // the destination to ( move's source register + one ) 14428 // peepreplace ( leaI_rReg_immI( 0.dst 1.src 0.src ) ); 14429 // %} 14430 // 14431 // 2. Procedural replacement 14432 // - More flexible finding relevent nodes 14433 // - More flexible constraints 14434 // - More flexible transformations 14435 // - May utilise architecture-dependent API more effectively 14436 // - Currently only one replacement instruction due to adlc parsing capabilities 14437 // 14438 // // Change (inc mov) to lea 14439 // peephole %{ 14440 // // lea should only be emitted when beneficial 14441 // peeppredicate( VM_Version::supports_fast_2op_lea() ); 14442 // // the rule numbers of these nodes inside are passed into the function below 14443 // peepmatch ( incI_rReg movI ); 14444 // // the method that takes the responsibility of transformation 14445 // peepprocedure ( inc_mov_to_lea ); 14446 // // the replacement is a leaI_rReg_immI, a lambda upon invoked creating this 14447 // // node is passed into the function above 14448 // peepreplace ( leaI_rReg_immI() ); 14449 // %} 14450 14451 // These instructions is not matched by the matcher but used by the peephole 14452 instruct leaI_rReg_rReg_peep(rRegI dst, rRegI src1, rRegI src2) 14453 %{ 14454 predicate(false); 14455 match(Set dst (AddI src1 src2)); 14456 format %{ "leal $dst, [$src1 + $src2]" %} 14457 ins_encode %{ 14458 Register dst = $dst$$Register; 14459 Register src1 = $src1$$Register; 14460 Register src2 = $src2$$Register; 14461 if (src1 != rbp && src1 != r13) { 14462 __ leal(dst, Address(src1, src2, Address::times_1)); 14463 } else { 14464 assert(src2 != rbp && src2 != r13, ""); 14465 __ leal(dst, Address(src2, src1, Address::times_1)); 14466 } 14467 %} 14468 ins_pipe(ialu_reg_reg); 14469 %} 14470 14471 instruct leaI_rReg_immI_peep(rRegI dst, rRegI src1, immI src2) 14472 %{ 14473 predicate(false); 14474 match(Set dst (AddI src1 src2)); 14475 format %{ "leal $dst, [$src1 + $src2]" %} 14476 ins_encode %{ 14477 __ leal($dst$$Register, Address($src1$$Register, $src2$$constant)); 14478 %} 14479 ins_pipe(ialu_reg_reg); 14480 %} 14481 14482 instruct leaI_rReg_immI2_peep(rRegI dst, rRegI src, immI2 shift) 14483 %{ 14484 predicate(false); 14485 match(Set dst (LShiftI src shift)); 14486 format %{ "leal $dst, [$src << $shift]" %} 14487 ins_encode %{ 14488 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($shift$$constant); 14489 Register src = $src$$Register; 14490 if (scale == Address::times_2 && src != rbp && src != r13) { 14491 __ leal($dst$$Register, Address(src, src, Address::times_1)); 14492 } else { 14493 __ leal($dst$$Register, Address(noreg, src, scale)); 14494 } 14495 %} 14496 ins_pipe(ialu_reg_reg); 14497 %} 14498 14499 instruct leaL_rReg_rReg_peep(rRegL dst, rRegL src1, rRegL src2) 14500 %{ 14501 predicate(false); 14502 match(Set dst (AddL src1 src2)); 14503 format %{ "leaq $dst, [$src1 + $src2]" %} 14504 ins_encode %{ 14505 Register dst = $dst$$Register; 14506 Register src1 = $src1$$Register; 14507 Register src2 = $src2$$Register; 14508 if (src1 != rbp && src1 != r13) { 14509 __ leaq(dst, Address(src1, src2, Address::times_1)); 14510 } else { 14511 assert(src2 != rbp && src2 != r13, ""); 14512 __ leaq(dst, Address(src2, src1, Address::times_1)); 14513 } 14514 %} 14515 ins_pipe(ialu_reg_reg); 14516 %} 14517 14518 instruct leaL_rReg_immL32_peep(rRegL dst, rRegL src1, immL32 src2) 14519 %{ 14520 predicate(false); 14521 match(Set dst (AddL src1 src2)); 14522 format %{ "leaq $dst, [$src1 + $src2]" %} 14523 ins_encode %{ 14524 __ leaq($dst$$Register, Address($src1$$Register, $src2$$constant)); 14525 %} 14526 ins_pipe(ialu_reg_reg); 14527 %} 14528 14529 instruct leaL_rReg_immI2_peep(rRegL dst, rRegL src, immI2 shift) 14530 %{ 14531 predicate(false); 14532 match(Set dst (LShiftL src shift)); 14533 format %{ "leaq $dst, [$src << $shift]" %} 14534 ins_encode %{ 14535 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($shift$$constant); 14536 Register src = $src$$Register; 14537 if (scale == Address::times_2 && src != rbp && src != r13) { 14538 __ leaq($dst$$Register, Address(src, src, Address::times_1)); 14539 } else { 14540 __ leaq($dst$$Register, Address(noreg, src, scale)); 14541 } 14542 %} 14543 ins_pipe(ialu_reg_reg); 14544 %} 14545 14546 // These peephole rules replace mov + I pairs (where I is one of {add, inc, dec, 14547 // sal}) with lea instructions. The {add, sal} rules are beneficial in 14548 // processors with at least partial ALU support for lea 14549 // (supports_fast_2op_lea()), whereas the {inc, dec} rules are only generally 14550 // beneficial for processors with full ALU support 14551 // (VM_Version::supports_fast_3op_lea()) and Intel Cascade Lake. 14552 14553 peephole 14554 %{ 14555 peeppredicate(VM_Version::supports_fast_2op_lea()); 14556 peepmatch (addI_rReg); 14557 peepprocedure (lea_coalesce_reg); 14558 peepreplace (leaI_rReg_rReg_peep()); 14559 %} 14560 14561 peephole 14562 %{ 14563 peeppredicate(VM_Version::supports_fast_2op_lea()); 14564 peepmatch (addI_rReg_imm); 14565 peepprocedure (lea_coalesce_imm); 14566 peepreplace (leaI_rReg_immI_peep()); 14567 %} 14568 14569 peephole 14570 %{ 14571 peeppredicate(VM_Version::supports_fast_3op_lea() || 14572 VM_Version::is_intel_cascade_lake()); 14573 peepmatch (incI_rReg); 14574 peepprocedure (lea_coalesce_imm); 14575 peepreplace (leaI_rReg_immI_peep()); 14576 %} 14577 14578 peephole 14579 %{ 14580 peeppredicate(VM_Version::supports_fast_3op_lea() || 14581 VM_Version::is_intel_cascade_lake()); 14582 peepmatch (decI_rReg); 14583 peepprocedure (lea_coalesce_imm); 14584 peepreplace (leaI_rReg_immI_peep()); 14585 %} 14586 14587 peephole 14588 %{ 14589 peeppredicate(VM_Version::supports_fast_2op_lea()); 14590 peepmatch (salI_rReg_immI2); 14591 peepprocedure (lea_coalesce_imm); 14592 peepreplace (leaI_rReg_immI2_peep()); 14593 %} 14594 14595 peephole 14596 %{ 14597 peeppredicate(VM_Version::supports_fast_2op_lea()); 14598 peepmatch (addL_rReg); 14599 peepprocedure (lea_coalesce_reg); 14600 peepreplace (leaL_rReg_rReg_peep()); 14601 %} 14602 14603 peephole 14604 %{ 14605 peeppredicate(VM_Version::supports_fast_2op_lea()); 14606 peepmatch (addL_rReg_imm); 14607 peepprocedure (lea_coalesce_imm); 14608 peepreplace (leaL_rReg_immL32_peep()); 14609 %} 14610 14611 peephole 14612 %{ 14613 peeppredicate(VM_Version::supports_fast_3op_lea() || 14614 VM_Version::is_intel_cascade_lake()); 14615 peepmatch (incL_rReg); 14616 peepprocedure (lea_coalesce_imm); 14617 peepreplace (leaL_rReg_immL32_peep()); 14618 %} 14619 14620 peephole 14621 %{ 14622 peeppredicate(VM_Version::supports_fast_3op_lea() || 14623 VM_Version::is_intel_cascade_lake()); 14624 peepmatch (decL_rReg); 14625 peepprocedure (lea_coalesce_imm); 14626 peepreplace (leaL_rReg_immL32_peep()); 14627 %} 14628 14629 peephole 14630 %{ 14631 peeppredicate(VM_Version::supports_fast_2op_lea()); 14632 peepmatch (salL_rReg_immI2); 14633 peepprocedure (lea_coalesce_imm); 14634 peepreplace (leaL_rReg_immI2_peep()); 14635 %} 14636 14637 peephole 14638 %{ 14639 peepmatch (leaPCompressedOopOffset); 14640 peepprocedure (lea_remove_redundant); 14641 %} 14642 14643 peephole 14644 %{ 14645 peepmatch (leaP8Narrow); 14646 peepprocedure (lea_remove_redundant); 14647 %} 14648 14649 peephole 14650 %{ 14651 peepmatch (leaP32Narrow); 14652 peepprocedure (lea_remove_redundant); 14653 %} 14654 14655 // These peephole rules matches instructions which set flags and are followed by a testI/L_reg 14656 // 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 14657 14658 //int variant 14659 peephole 14660 %{ 14661 peepmatch (testI_reg); 14662 peepprocedure (test_may_remove); 14663 %} 14664 14665 //long variant 14666 peephole 14667 %{ 14668 peepmatch (testL_reg); 14669 peepprocedure (test_may_remove); 14670 %} 14671 14672 14673 //----------SMARTSPILL RULES--------------------------------------------------- 14674 // These must follow all instruction definitions as they use the names 14675 // defined in the instructions definitions.