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 //----------OPERANDS----------------------------------------------------------- 2058 // Operand definitions must precede instruction definitions for correct parsing 2059 // in the ADLC because operands constitute user defined types which are used in 2060 // instruction definitions. 2061 2062 //----------Simple Operands---------------------------------------------------- 2063 // Immediate Operands 2064 // Integer Immediate 2065 operand immI() 2066 %{ 2067 match(ConI); 2068 2069 op_cost(10); 2070 format %{ %} 2071 interface(CONST_INTER); 2072 %} 2073 2074 // Constant for test vs zero 2075 operand immI_0() 2076 %{ 2077 predicate(n->get_int() == 0); 2078 match(ConI); 2079 2080 op_cost(0); 2081 format %{ %} 2082 interface(CONST_INTER); 2083 %} 2084 2085 // Constant for increment 2086 operand immI_1() 2087 %{ 2088 predicate(n->get_int() == 1); 2089 match(ConI); 2090 2091 op_cost(0); 2092 format %{ %} 2093 interface(CONST_INTER); 2094 %} 2095 2096 // Constant for decrement 2097 operand immI_M1() 2098 %{ 2099 predicate(n->get_int() == -1); 2100 match(ConI); 2101 2102 op_cost(0); 2103 format %{ %} 2104 interface(CONST_INTER); 2105 %} 2106 2107 operand immI_2() 2108 %{ 2109 predicate(n->get_int() == 2); 2110 match(ConI); 2111 2112 op_cost(0); 2113 format %{ %} 2114 interface(CONST_INTER); 2115 %} 2116 2117 operand immI_4() 2118 %{ 2119 predicate(n->get_int() == 4); 2120 match(ConI); 2121 2122 op_cost(0); 2123 format %{ %} 2124 interface(CONST_INTER); 2125 %} 2126 2127 operand immI_8() 2128 %{ 2129 predicate(n->get_int() == 8); 2130 match(ConI); 2131 2132 op_cost(0); 2133 format %{ %} 2134 interface(CONST_INTER); 2135 %} 2136 2137 // Valid scale values for addressing modes 2138 operand immI2() 2139 %{ 2140 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 2141 match(ConI); 2142 2143 format %{ %} 2144 interface(CONST_INTER); 2145 %} 2146 2147 operand immU7() 2148 %{ 2149 predicate((0 <= n->get_int()) && (n->get_int() <= 0x7F)); 2150 match(ConI); 2151 2152 op_cost(5); 2153 format %{ %} 2154 interface(CONST_INTER); 2155 %} 2156 2157 operand immI8() 2158 %{ 2159 predicate((-0x80 <= n->get_int()) && (n->get_int() < 0x80)); 2160 match(ConI); 2161 2162 op_cost(5); 2163 format %{ %} 2164 interface(CONST_INTER); 2165 %} 2166 2167 operand immU8() 2168 %{ 2169 predicate((0 <= n->get_int()) && (n->get_int() <= 255)); 2170 match(ConI); 2171 2172 op_cost(5); 2173 format %{ %} 2174 interface(CONST_INTER); 2175 %} 2176 2177 operand immI16() 2178 %{ 2179 predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767)); 2180 match(ConI); 2181 2182 op_cost(10); 2183 format %{ %} 2184 interface(CONST_INTER); 2185 %} 2186 2187 // Int Immediate non-negative 2188 operand immU31() 2189 %{ 2190 predicate(n->get_int() >= 0); 2191 match(ConI); 2192 2193 op_cost(0); 2194 format %{ %} 2195 interface(CONST_INTER); 2196 %} 2197 2198 // Pointer Immediate 2199 operand immP() 2200 %{ 2201 match(ConP); 2202 2203 op_cost(10); 2204 format %{ %} 2205 interface(CONST_INTER); 2206 %} 2207 2208 // Null Pointer Immediate 2209 operand immP0() 2210 %{ 2211 predicate(n->get_ptr() == 0); 2212 match(ConP); 2213 2214 op_cost(5); 2215 format %{ %} 2216 interface(CONST_INTER); 2217 %} 2218 2219 // Pointer Immediate 2220 operand immN() %{ 2221 match(ConN); 2222 2223 op_cost(10); 2224 format %{ %} 2225 interface(CONST_INTER); 2226 %} 2227 2228 operand immNKlass() %{ 2229 match(ConNKlass); 2230 2231 op_cost(10); 2232 format %{ %} 2233 interface(CONST_INTER); 2234 %} 2235 2236 // Null Pointer Immediate 2237 operand immN0() %{ 2238 predicate(n->get_narrowcon() == 0); 2239 match(ConN); 2240 2241 op_cost(5); 2242 format %{ %} 2243 interface(CONST_INTER); 2244 %} 2245 2246 operand immP31() 2247 %{ 2248 predicate(n->as_Type()->type()->reloc() == relocInfo::none 2249 && (n->get_ptr() >> 31) == 0); 2250 match(ConP); 2251 2252 op_cost(5); 2253 format %{ %} 2254 interface(CONST_INTER); 2255 %} 2256 2257 2258 // Long Immediate 2259 operand immL() 2260 %{ 2261 match(ConL); 2262 2263 op_cost(20); 2264 format %{ %} 2265 interface(CONST_INTER); 2266 %} 2267 2268 // Long Immediate 8-bit 2269 operand immL8() 2270 %{ 2271 predicate(-0x80L <= n->get_long() && n->get_long() < 0x80L); 2272 match(ConL); 2273 2274 op_cost(5); 2275 format %{ %} 2276 interface(CONST_INTER); 2277 %} 2278 2279 // Long Immediate 32-bit unsigned 2280 operand immUL32() 2281 %{ 2282 predicate(n->get_long() == (unsigned int) (n->get_long())); 2283 match(ConL); 2284 2285 op_cost(10); 2286 format %{ %} 2287 interface(CONST_INTER); 2288 %} 2289 2290 // Long Immediate 32-bit signed 2291 operand immL32() 2292 %{ 2293 predicate(n->get_long() == (int) (n->get_long())); 2294 match(ConL); 2295 2296 op_cost(15); 2297 format %{ %} 2298 interface(CONST_INTER); 2299 %} 2300 2301 operand immL_Pow2() 2302 %{ 2303 predicate(is_power_of_2((julong)n->get_long())); 2304 match(ConL); 2305 2306 op_cost(15); 2307 format %{ %} 2308 interface(CONST_INTER); 2309 %} 2310 2311 operand immL_NotPow2() 2312 %{ 2313 predicate(is_power_of_2((julong)~n->get_long())); 2314 match(ConL); 2315 2316 op_cost(15); 2317 format %{ %} 2318 interface(CONST_INTER); 2319 %} 2320 2321 // Long Immediate zero 2322 operand immL0() 2323 %{ 2324 predicate(n->get_long() == 0L); 2325 match(ConL); 2326 2327 op_cost(10); 2328 format %{ %} 2329 interface(CONST_INTER); 2330 %} 2331 2332 // Constant for increment 2333 operand immL1() 2334 %{ 2335 predicate(n->get_long() == 1); 2336 match(ConL); 2337 2338 format %{ %} 2339 interface(CONST_INTER); 2340 %} 2341 2342 // Constant for decrement 2343 operand immL_M1() 2344 %{ 2345 predicate(n->get_long() == -1); 2346 match(ConL); 2347 2348 format %{ %} 2349 interface(CONST_INTER); 2350 %} 2351 2352 // Long Immediate: low 32-bit mask 2353 operand immL_32bits() 2354 %{ 2355 predicate(n->get_long() == 0xFFFFFFFFL); 2356 match(ConL); 2357 op_cost(20); 2358 2359 format %{ %} 2360 interface(CONST_INTER); 2361 %} 2362 2363 // Int Immediate: 2^n-1, positive 2364 operand immI_Pow2M1() 2365 %{ 2366 predicate((n->get_int() > 0) 2367 && is_power_of_2((juint)n->get_int() + 1)); 2368 match(ConI); 2369 2370 op_cost(20); 2371 format %{ %} 2372 interface(CONST_INTER); 2373 %} 2374 2375 // Float Immediate zero 2376 operand immF0() 2377 %{ 2378 predicate(jint_cast(n->getf()) == 0); 2379 match(ConF); 2380 2381 op_cost(5); 2382 format %{ %} 2383 interface(CONST_INTER); 2384 %} 2385 2386 // Float Immediate 2387 operand immF() 2388 %{ 2389 match(ConF); 2390 2391 op_cost(15); 2392 format %{ %} 2393 interface(CONST_INTER); 2394 %} 2395 2396 // Half Float Immediate 2397 operand immH() 2398 %{ 2399 match(ConH); 2400 2401 op_cost(15); 2402 format %{ %} 2403 interface(CONST_INTER); 2404 %} 2405 2406 // Double Immediate zero 2407 operand immD0() 2408 %{ 2409 predicate(jlong_cast(n->getd()) == 0); 2410 match(ConD); 2411 2412 op_cost(5); 2413 format %{ %} 2414 interface(CONST_INTER); 2415 %} 2416 2417 // Double Immediate 2418 operand immD() 2419 %{ 2420 match(ConD); 2421 2422 op_cost(15); 2423 format %{ %} 2424 interface(CONST_INTER); 2425 %} 2426 2427 // Immediates for special shifts (sign extend) 2428 2429 // Constants for increment 2430 operand immI_16() 2431 %{ 2432 predicate(n->get_int() == 16); 2433 match(ConI); 2434 2435 format %{ %} 2436 interface(CONST_INTER); 2437 %} 2438 2439 operand immI_24() 2440 %{ 2441 predicate(n->get_int() == 24); 2442 match(ConI); 2443 2444 format %{ %} 2445 interface(CONST_INTER); 2446 %} 2447 2448 // Constant for byte-wide masking 2449 operand immI_255() 2450 %{ 2451 predicate(n->get_int() == 255); 2452 match(ConI); 2453 2454 format %{ %} 2455 interface(CONST_INTER); 2456 %} 2457 2458 // Constant for short-wide masking 2459 operand immI_65535() 2460 %{ 2461 predicate(n->get_int() == 65535); 2462 match(ConI); 2463 2464 format %{ %} 2465 interface(CONST_INTER); 2466 %} 2467 2468 // Constant for byte-wide masking 2469 operand immL_255() 2470 %{ 2471 predicate(n->get_long() == 255); 2472 match(ConL); 2473 2474 format %{ %} 2475 interface(CONST_INTER); 2476 %} 2477 2478 // Constant for short-wide masking 2479 operand immL_65535() 2480 %{ 2481 predicate(n->get_long() == 65535); 2482 match(ConL); 2483 2484 format %{ %} 2485 interface(CONST_INTER); 2486 %} 2487 2488 // AOT Runtime Constants Address 2489 operand immAOTRuntimeConstantsAddress() 2490 %{ 2491 // Check if the address is in the range of AOT Runtime Constants 2492 predicate(AOTRuntimeConstants::contains((address)(n->get_ptr()))); 2493 match(ConP); 2494 2495 op_cost(0); 2496 format %{ %} 2497 interface(CONST_INTER); 2498 %} 2499 2500 operand kReg() 2501 %{ 2502 constraint(ALLOC_IN_RC(vectmask_reg)); 2503 match(RegVectMask); 2504 format %{%} 2505 interface(REG_INTER); 2506 %} 2507 2508 // Register Operands 2509 // Integer Register 2510 operand rRegI() 2511 %{ 2512 constraint(ALLOC_IN_RC(int_reg)); 2513 match(RegI); 2514 2515 match(rax_RegI); 2516 match(rbx_RegI); 2517 match(rcx_RegI); 2518 match(rdx_RegI); 2519 match(rdi_RegI); 2520 2521 format %{ %} 2522 interface(REG_INTER); 2523 %} 2524 2525 // Special Registers 2526 operand rax_RegI() 2527 %{ 2528 constraint(ALLOC_IN_RC(int_rax_reg)); 2529 match(RegI); 2530 match(rRegI); 2531 2532 format %{ "RAX" %} 2533 interface(REG_INTER); 2534 %} 2535 2536 // Special Registers 2537 operand rbx_RegI() 2538 %{ 2539 constraint(ALLOC_IN_RC(int_rbx_reg)); 2540 match(RegI); 2541 match(rRegI); 2542 2543 format %{ "RBX" %} 2544 interface(REG_INTER); 2545 %} 2546 2547 operand rcx_RegI() 2548 %{ 2549 constraint(ALLOC_IN_RC(int_rcx_reg)); 2550 match(RegI); 2551 match(rRegI); 2552 2553 format %{ "RCX" %} 2554 interface(REG_INTER); 2555 %} 2556 2557 operand rdx_RegI() 2558 %{ 2559 constraint(ALLOC_IN_RC(int_rdx_reg)); 2560 match(RegI); 2561 match(rRegI); 2562 2563 format %{ "RDX" %} 2564 interface(REG_INTER); 2565 %} 2566 2567 operand rdi_RegI() 2568 %{ 2569 constraint(ALLOC_IN_RC(int_rdi_reg)); 2570 match(RegI); 2571 match(rRegI); 2572 2573 format %{ "RDI" %} 2574 interface(REG_INTER); 2575 %} 2576 2577 operand no_rax_rdx_RegI() 2578 %{ 2579 constraint(ALLOC_IN_RC(int_no_rax_rdx_reg)); 2580 match(RegI); 2581 match(rbx_RegI); 2582 match(rcx_RegI); 2583 match(rdi_RegI); 2584 2585 format %{ %} 2586 interface(REG_INTER); 2587 %} 2588 2589 operand no_rbp_r13_RegI() 2590 %{ 2591 constraint(ALLOC_IN_RC(int_no_rbp_r13_reg)); 2592 match(RegI); 2593 match(rRegI); 2594 match(rax_RegI); 2595 match(rbx_RegI); 2596 match(rcx_RegI); 2597 match(rdx_RegI); 2598 match(rdi_RegI); 2599 2600 format %{ %} 2601 interface(REG_INTER); 2602 %} 2603 2604 // Pointer Register 2605 operand any_RegP() 2606 %{ 2607 constraint(ALLOC_IN_RC(any_reg)); 2608 match(RegP); 2609 match(rax_RegP); 2610 match(rbx_RegP); 2611 match(rdi_RegP); 2612 match(rsi_RegP); 2613 match(rbp_RegP); 2614 match(r15_RegP); 2615 match(rRegP); 2616 2617 format %{ %} 2618 interface(REG_INTER); 2619 %} 2620 2621 operand rRegP() 2622 %{ 2623 constraint(ALLOC_IN_RC(ptr_reg)); 2624 match(RegP); 2625 match(rax_RegP); 2626 match(rbx_RegP); 2627 match(rdi_RegP); 2628 match(rsi_RegP); 2629 match(rbp_RegP); // See Q&A below about 2630 match(r15_RegP); // r15_RegP and rbp_RegP. 2631 2632 format %{ %} 2633 interface(REG_INTER); 2634 %} 2635 2636 operand rRegN() %{ 2637 constraint(ALLOC_IN_RC(int_reg)); 2638 match(RegN); 2639 2640 format %{ %} 2641 interface(REG_INTER); 2642 %} 2643 2644 // Question: Why is r15_RegP (the read-only TLS register) a match for rRegP? 2645 // Answer: Operand match rules govern the DFA as it processes instruction inputs. 2646 // It's fine for an instruction input that expects rRegP to match a r15_RegP. 2647 // The output of an instruction is controlled by the allocator, which respects 2648 // register class masks, not match rules. Unless an instruction mentions 2649 // r15_RegP or any_RegP explicitly as its output, r15 will not be considered 2650 // by the allocator as an input. 2651 // The same logic applies to rbp_RegP being a match for rRegP: If PreserveFramePointer==true, 2652 // the RBP is used as a proper frame pointer and is not included in ptr_reg. As a 2653 // result, RBP is not included in the output of the instruction either. 2654 2655 // This operand is not allowed to use RBP even if 2656 // RBP is not used to hold the frame pointer. 2657 operand no_rbp_RegP() 2658 %{ 2659 constraint(ALLOC_IN_RC(ptr_reg_no_rbp)); 2660 match(RegP); 2661 match(rbx_RegP); 2662 match(rsi_RegP); 2663 match(rdi_RegP); 2664 2665 format %{ %} 2666 interface(REG_INTER); 2667 %} 2668 2669 // Special Registers 2670 // Return a pointer value 2671 operand rax_RegP() 2672 %{ 2673 constraint(ALLOC_IN_RC(ptr_rax_reg)); 2674 match(RegP); 2675 match(rRegP); 2676 2677 format %{ %} 2678 interface(REG_INTER); 2679 %} 2680 2681 // Special Registers 2682 // Return a compressed pointer value 2683 operand rax_RegN() 2684 %{ 2685 constraint(ALLOC_IN_RC(int_rax_reg)); 2686 match(RegN); 2687 match(rRegN); 2688 2689 format %{ %} 2690 interface(REG_INTER); 2691 %} 2692 2693 // Used in AtomicAdd 2694 operand rbx_RegP() 2695 %{ 2696 constraint(ALLOC_IN_RC(ptr_rbx_reg)); 2697 match(RegP); 2698 match(rRegP); 2699 2700 format %{ %} 2701 interface(REG_INTER); 2702 %} 2703 2704 operand rsi_RegP() 2705 %{ 2706 constraint(ALLOC_IN_RC(ptr_rsi_reg)); 2707 match(RegP); 2708 match(rRegP); 2709 2710 format %{ %} 2711 interface(REG_INTER); 2712 %} 2713 2714 operand rbp_RegP() 2715 %{ 2716 constraint(ALLOC_IN_RC(ptr_rbp_reg)); 2717 match(RegP); 2718 match(rRegP); 2719 2720 format %{ %} 2721 interface(REG_INTER); 2722 %} 2723 2724 // Used in rep stosq 2725 operand rdi_RegP() 2726 %{ 2727 constraint(ALLOC_IN_RC(ptr_rdi_reg)); 2728 match(RegP); 2729 match(rRegP); 2730 2731 format %{ %} 2732 interface(REG_INTER); 2733 %} 2734 2735 operand r15_RegP() 2736 %{ 2737 constraint(ALLOC_IN_RC(ptr_r15_reg)); 2738 match(RegP); 2739 match(rRegP); 2740 2741 format %{ %} 2742 interface(REG_INTER); 2743 %} 2744 2745 operand rRegL() 2746 %{ 2747 constraint(ALLOC_IN_RC(long_reg)); 2748 match(RegL); 2749 match(rax_RegL); 2750 match(rdx_RegL); 2751 2752 format %{ %} 2753 interface(REG_INTER); 2754 %} 2755 2756 // Special Registers 2757 operand no_rax_rdx_RegL() 2758 %{ 2759 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 2760 match(RegL); 2761 match(rRegL); 2762 2763 format %{ %} 2764 interface(REG_INTER); 2765 %} 2766 2767 operand rax_RegL() 2768 %{ 2769 constraint(ALLOC_IN_RC(long_rax_reg)); 2770 match(RegL); 2771 match(rRegL); 2772 2773 format %{ "RAX" %} 2774 interface(REG_INTER); 2775 %} 2776 2777 operand rcx_RegL() 2778 %{ 2779 constraint(ALLOC_IN_RC(long_rcx_reg)); 2780 match(RegL); 2781 match(rRegL); 2782 2783 format %{ %} 2784 interface(REG_INTER); 2785 %} 2786 2787 operand rdx_RegL() 2788 %{ 2789 constraint(ALLOC_IN_RC(long_rdx_reg)); 2790 match(RegL); 2791 match(rRegL); 2792 2793 format %{ %} 2794 interface(REG_INTER); 2795 %} 2796 2797 operand r11_RegL() 2798 %{ 2799 constraint(ALLOC_IN_RC(long_r11_reg)); 2800 match(RegL); 2801 match(rRegL); 2802 2803 format %{ %} 2804 interface(REG_INTER); 2805 %} 2806 2807 operand no_rbp_r13_RegL() 2808 %{ 2809 constraint(ALLOC_IN_RC(long_no_rbp_r13_reg)); 2810 match(RegL); 2811 match(rRegL); 2812 match(rax_RegL); 2813 match(rcx_RegL); 2814 match(rdx_RegL); 2815 2816 format %{ %} 2817 interface(REG_INTER); 2818 %} 2819 2820 // Flags register, used as output of compare instructions 2821 operand rFlagsReg() 2822 %{ 2823 constraint(ALLOC_IN_RC(int_flags)); 2824 match(RegFlags); 2825 2826 format %{ "RFLAGS" %} 2827 interface(REG_INTER); 2828 %} 2829 2830 // Flags register, used as output of FLOATING POINT compare instructions 2831 operand rFlagsRegU() 2832 %{ 2833 constraint(ALLOC_IN_RC(int_flags)); 2834 match(RegFlags); 2835 2836 format %{ "RFLAGS_U" %} 2837 interface(REG_INTER); 2838 %} 2839 2840 operand rFlagsRegUCF() %{ 2841 constraint(ALLOC_IN_RC(int_flags)); 2842 match(RegFlags); 2843 predicate(false); 2844 2845 format %{ "RFLAGS_U_CF" %} 2846 interface(REG_INTER); 2847 %} 2848 2849 // Float register operands 2850 operand regF() %{ 2851 constraint(ALLOC_IN_RC(float_reg)); 2852 match(RegF); 2853 2854 format %{ %} 2855 interface(REG_INTER); 2856 %} 2857 2858 // Float register operands 2859 operand legRegF() %{ 2860 constraint(ALLOC_IN_RC(float_reg_legacy)); 2861 match(RegF); 2862 2863 format %{ %} 2864 interface(REG_INTER); 2865 %} 2866 2867 // Float register operands 2868 operand vlRegF() %{ 2869 constraint(ALLOC_IN_RC(float_reg_vl)); 2870 match(RegF); 2871 2872 format %{ %} 2873 interface(REG_INTER); 2874 %} 2875 2876 // Double register operands 2877 operand regD() %{ 2878 constraint(ALLOC_IN_RC(double_reg)); 2879 match(RegD); 2880 2881 format %{ %} 2882 interface(REG_INTER); 2883 %} 2884 2885 // Double register operands 2886 operand legRegD() %{ 2887 constraint(ALLOC_IN_RC(double_reg_legacy)); 2888 match(RegD); 2889 2890 format %{ %} 2891 interface(REG_INTER); 2892 %} 2893 2894 // Double register operands 2895 operand vlRegD() %{ 2896 constraint(ALLOC_IN_RC(double_reg_vl)); 2897 match(RegD); 2898 2899 format %{ %} 2900 interface(REG_INTER); 2901 %} 2902 2903 //----------Memory Operands---------------------------------------------------- 2904 // Direct Memory Operand 2905 // operand direct(immP addr) 2906 // %{ 2907 // match(addr); 2908 2909 // format %{ "[$addr]" %} 2910 // interface(MEMORY_INTER) %{ 2911 // base(0xFFFFFFFF); 2912 // index(0x4); 2913 // scale(0x0); 2914 // disp($addr); 2915 // %} 2916 // %} 2917 2918 // Indirect Memory Operand 2919 operand indirect(any_RegP reg) 2920 %{ 2921 constraint(ALLOC_IN_RC(ptr_reg)); 2922 match(reg); 2923 2924 format %{ "[$reg]" %} 2925 interface(MEMORY_INTER) %{ 2926 base($reg); 2927 index(0x4); 2928 scale(0x0); 2929 disp(0x0); 2930 %} 2931 %} 2932 2933 // Indirect Memory Plus Short Offset Operand 2934 operand indOffset8(any_RegP reg, immL8 off) 2935 %{ 2936 constraint(ALLOC_IN_RC(ptr_reg)); 2937 match(AddP reg off); 2938 2939 format %{ "[$reg + $off (8-bit)]" %} 2940 interface(MEMORY_INTER) %{ 2941 base($reg); 2942 index(0x4); 2943 scale(0x0); 2944 disp($off); 2945 %} 2946 %} 2947 2948 // Indirect Memory Plus Long Offset Operand 2949 operand indOffset32(any_RegP reg, immL32 off) 2950 %{ 2951 constraint(ALLOC_IN_RC(ptr_reg)); 2952 match(AddP reg off); 2953 2954 format %{ "[$reg + $off (32-bit)]" %} 2955 interface(MEMORY_INTER) %{ 2956 base($reg); 2957 index(0x4); 2958 scale(0x0); 2959 disp($off); 2960 %} 2961 %} 2962 2963 // Indirect Memory Plus Index Register Plus Offset Operand 2964 operand indIndexOffset(any_RegP reg, rRegL lreg, immL32 off) 2965 %{ 2966 constraint(ALLOC_IN_RC(ptr_reg)); 2967 match(AddP (AddP reg lreg) off); 2968 2969 op_cost(10); 2970 format %{"[$reg + $off + $lreg]" %} 2971 interface(MEMORY_INTER) %{ 2972 base($reg); 2973 index($lreg); 2974 scale(0x0); 2975 disp($off); 2976 %} 2977 %} 2978 2979 // Indirect Memory Plus Index Register Plus Offset Operand 2980 operand indIndex(any_RegP reg, rRegL lreg) 2981 %{ 2982 constraint(ALLOC_IN_RC(ptr_reg)); 2983 match(AddP reg lreg); 2984 2985 op_cost(10); 2986 format %{"[$reg + $lreg]" %} 2987 interface(MEMORY_INTER) %{ 2988 base($reg); 2989 index($lreg); 2990 scale(0x0); 2991 disp(0x0); 2992 %} 2993 %} 2994 2995 // Indirect Memory Times Scale Plus Index Register 2996 operand indIndexScale(any_RegP reg, rRegL lreg, immI2 scale) 2997 %{ 2998 constraint(ALLOC_IN_RC(ptr_reg)); 2999 match(AddP reg (LShiftL lreg scale)); 3000 3001 op_cost(10); 3002 format %{"[$reg + $lreg << $scale]" %} 3003 interface(MEMORY_INTER) %{ 3004 base($reg); 3005 index($lreg); 3006 scale($scale); 3007 disp(0x0); 3008 %} 3009 %} 3010 3011 operand indPosIndexScale(any_RegP reg, rRegI idx, immI2 scale) 3012 %{ 3013 constraint(ALLOC_IN_RC(ptr_reg)); 3014 predicate(n->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3015 match(AddP reg (LShiftL (ConvI2L idx) scale)); 3016 3017 op_cost(10); 3018 format %{"[$reg + pos $idx << $scale]" %} 3019 interface(MEMORY_INTER) %{ 3020 base($reg); 3021 index($idx); 3022 scale($scale); 3023 disp(0x0); 3024 %} 3025 %} 3026 3027 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 3028 operand indIndexScaleOffset(any_RegP reg, immL32 off, rRegL lreg, immI2 scale) 3029 %{ 3030 constraint(ALLOC_IN_RC(ptr_reg)); 3031 match(AddP (AddP reg (LShiftL lreg scale)) off); 3032 3033 op_cost(10); 3034 format %{"[$reg + $off + $lreg << $scale]" %} 3035 interface(MEMORY_INTER) %{ 3036 base($reg); 3037 index($lreg); 3038 scale($scale); 3039 disp($off); 3040 %} 3041 %} 3042 3043 // Indirect Memory Plus Positive Index Register Plus Offset Operand 3044 operand indPosIndexOffset(any_RegP reg, immL32 off, rRegI idx) 3045 %{ 3046 constraint(ALLOC_IN_RC(ptr_reg)); 3047 predicate(n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 3048 match(AddP (AddP reg (ConvI2L idx)) off); 3049 3050 op_cost(10); 3051 format %{"[$reg + $off + $idx]" %} 3052 interface(MEMORY_INTER) %{ 3053 base($reg); 3054 index($idx); 3055 scale(0x0); 3056 disp($off); 3057 %} 3058 %} 3059 3060 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 3061 operand indPosIndexScaleOffset(any_RegP reg, immL32 off, rRegI idx, immI2 scale) 3062 %{ 3063 constraint(ALLOC_IN_RC(ptr_reg)); 3064 predicate(n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3065 match(AddP (AddP reg (LShiftL (ConvI2L idx) scale)) off); 3066 3067 op_cost(10); 3068 format %{"[$reg + $off + $idx << $scale]" %} 3069 interface(MEMORY_INTER) %{ 3070 base($reg); 3071 index($idx); 3072 scale($scale); 3073 disp($off); 3074 %} 3075 %} 3076 3077 // Indirect Narrow Oop Plus Offset Operand 3078 // Note: x86 architecture doesn't support "scale * index + offset" without a base 3079 // we can't free r12 even with CompressedOops::base() == nullptr. 3080 operand indCompressedOopOffset(rRegN reg, immL32 off) %{ 3081 predicate(UseCompressedOops && (CompressedOops::shift() == Address::times_8)); 3082 constraint(ALLOC_IN_RC(ptr_reg)); 3083 match(AddP (DecodeN reg) off); 3084 3085 op_cost(10); 3086 format %{"[R12 + $reg << 3 + $off] (compressed oop addressing)" %} 3087 interface(MEMORY_INTER) %{ 3088 base(0xc); // R12 3089 index($reg); 3090 scale(0x3); 3091 disp($off); 3092 %} 3093 %} 3094 3095 // Indirect Memory Operand 3096 operand indirectNarrow(rRegN reg) 3097 %{ 3098 predicate(CompressedOops::shift() == 0); 3099 constraint(ALLOC_IN_RC(ptr_reg)); 3100 match(DecodeN reg); 3101 3102 format %{ "[$reg]" %} 3103 interface(MEMORY_INTER) %{ 3104 base($reg); 3105 index(0x4); 3106 scale(0x0); 3107 disp(0x0); 3108 %} 3109 %} 3110 3111 // Indirect Memory Plus Short Offset Operand 3112 operand indOffset8Narrow(rRegN reg, immL8 off) 3113 %{ 3114 predicate(CompressedOops::shift() == 0); 3115 constraint(ALLOC_IN_RC(ptr_reg)); 3116 match(AddP (DecodeN reg) off); 3117 3118 format %{ "[$reg + $off (8-bit)]" %} 3119 interface(MEMORY_INTER) %{ 3120 base($reg); 3121 index(0x4); 3122 scale(0x0); 3123 disp($off); 3124 %} 3125 %} 3126 3127 // Indirect Memory Plus Long Offset Operand 3128 operand indOffset32Narrow(rRegN reg, immL32 off) 3129 %{ 3130 predicate(CompressedOops::shift() == 0); 3131 constraint(ALLOC_IN_RC(ptr_reg)); 3132 match(AddP (DecodeN reg) off); 3133 3134 format %{ "[$reg + $off (32-bit)]" %} 3135 interface(MEMORY_INTER) %{ 3136 base($reg); 3137 index(0x4); 3138 scale(0x0); 3139 disp($off); 3140 %} 3141 %} 3142 3143 // Indirect Memory Plus Index Register Plus Offset Operand 3144 operand indIndexOffsetNarrow(rRegN reg, rRegL lreg, immL32 off) 3145 %{ 3146 predicate(CompressedOops::shift() == 0); 3147 constraint(ALLOC_IN_RC(ptr_reg)); 3148 match(AddP (AddP (DecodeN reg) lreg) off); 3149 3150 op_cost(10); 3151 format %{"[$reg + $off + $lreg]" %} 3152 interface(MEMORY_INTER) %{ 3153 base($reg); 3154 index($lreg); 3155 scale(0x0); 3156 disp($off); 3157 %} 3158 %} 3159 3160 // Indirect Memory Plus Index Register Plus Offset Operand 3161 operand indIndexNarrow(rRegN reg, rRegL lreg) 3162 %{ 3163 predicate(CompressedOops::shift() == 0); 3164 constraint(ALLOC_IN_RC(ptr_reg)); 3165 match(AddP (DecodeN reg) lreg); 3166 3167 op_cost(10); 3168 format %{"[$reg + $lreg]" %} 3169 interface(MEMORY_INTER) %{ 3170 base($reg); 3171 index($lreg); 3172 scale(0x0); 3173 disp(0x0); 3174 %} 3175 %} 3176 3177 // Indirect Memory Times Scale Plus Index Register 3178 operand indIndexScaleNarrow(rRegN reg, rRegL lreg, immI2 scale) 3179 %{ 3180 predicate(CompressedOops::shift() == 0); 3181 constraint(ALLOC_IN_RC(ptr_reg)); 3182 match(AddP (DecodeN reg) (LShiftL lreg scale)); 3183 3184 op_cost(10); 3185 format %{"[$reg + $lreg << $scale]" %} 3186 interface(MEMORY_INTER) %{ 3187 base($reg); 3188 index($lreg); 3189 scale($scale); 3190 disp(0x0); 3191 %} 3192 %} 3193 3194 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 3195 operand indIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegL lreg, immI2 scale) 3196 %{ 3197 predicate(CompressedOops::shift() == 0); 3198 constraint(ALLOC_IN_RC(ptr_reg)); 3199 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off); 3200 3201 op_cost(10); 3202 format %{"[$reg + $off + $lreg << $scale]" %} 3203 interface(MEMORY_INTER) %{ 3204 base($reg); 3205 index($lreg); 3206 scale($scale); 3207 disp($off); 3208 %} 3209 %} 3210 3211 // Indirect Memory Times Plus Positive Index Register Plus Offset Operand 3212 operand indPosIndexOffsetNarrow(rRegN reg, immL32 off, rRegI idx) 3213 %{ 3214 constraint(ALLOC_IN_RC(ptr_reg)); 3215 predicate(CompressedOops::shift() == 0 && n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 3216 match(AddP (AddP (DecodeN reg) (ConvI2L idx)) off); 3217 3218 op_cost(10); 3219 format %{"[$reg + $off + $idx]" %} 3220 interface(MEMORY_INTER) %{ 3221 base($reg); 3222 index($idx); 3223 scale(0x0); 3224 disp($off); 3225 %} 3226 %} 3227 3228 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 3229 operand indPosIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegI idx, immI2 scale) 3230 %{ 3231 constraint(ALLOC_IN_RC(ptr_reg)); 3232 predicate(CompressedOops::shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3233 match(AddP (AddP (DecodeN reg) (LShiftL (ConvI2L idx) scale)) off); 3234 3235 op_cost(10); 3236 format %{"[$reg + $off + $idx << $scale]" %} 3237 interface(MEMORY_INTER) %{ 3238 base($reg); 3239 index($idx); 3240 scale($scale); 3241 disp($off); 3242 %} 3243 %} 3244 3245 //----------Special Memory Operands-------------------------------------------- 3246 // Stack Slot Operand - This operand is used for loading and storing temporary 3247 // values on the stack where a match requires a value to 3248 // flow through memory. 3249 operand stackSlotP(sRegP reg) 3250 %{ 3251 constraint(ALLOC_IN_RC(stack_slots)); 3252 // No match rule because this operand is only generated in matching 3253 3254 format %{ "[$reg]" %} 3255 interface(MEMORY_INTER) %{ 3256 base(0x4); // RSP 3257 index(0x4); // No Index 3258 scale(0x0); // No Scale 3259 disp($reg); // Stack Offset 3260 %} 3261 %} 3262 3263 operand stackSlotI(sRegI reg) 3264 %{ 3265 constraint(ALLOC_IN_RC(stack_slots)); 3266 // No match rule because this operand is only generated in matching 3267 3268 format %{ "[$reg]" %} 3269 interface(MEMORY_INTER) %{ 3270 base(0x4); // RSP 3271 index(0x4); // No Index 3272 scale(0x0); // No Scale 3273 disp($reg); // Stack Offset 3274 %} 3275 %} 3276 3277 operand stackSlotF(sRegF reg) 3278 %{ 3279 constraint(ALLOC_IN_RC(stack_slots)); 3280 // No match rule because this operand is only generated in matching 3281 3282 format %{ "[$reg]" %} 3283 interface(MEMORY_INTER) %{ 3284 base(0x4); // RSP 3285 index(0x4); // No Index 3286 scale(0x0); // No Scale 3287 disp($reg); // Stack Offset 3288 %} 3289 %} 3290 3291 operand stackSlotD(sRegD reg) 3292 %{ 3293 constraint(ALLOC_IN_RC(stack_slots)); 3294 // No match rule because this operand is only generated in matching 3295 3296 format %{ "[$reg]" %} 3297 interface(MEMORY_INTER) %{ 3298 base(0x4); // RSP 3299 index(0x4); // No Index 3300 scale(0x0); // No Scale 3301 disp($reg); // Stack Offset 3302 %} 3303 %} 3304 operand stackSlotL(sRegL reg) 3305 %{ 3306 constraint(ALLOC_IN_RC(stack_slots)); 3307 // No match rule because this operand is only generated in matching 3308 3309 format %{ "[$reg]" %} 3310 interface(MEMORY_INTER) %{ 3311 base(0x4); // RSP 3312 index(0x4); // No Index 3313 scale(0x0); // No Scale 3314 disp($reg); // Stack Offset 3315 %} 3316 %} 3317 3318 //----------Conditional Branch Operands---------------------------------------- 3319 // Comparison Op - This is the operation of the comparison, and is limited to 3320 // the following set of codes: 3321 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 3322 // 3323 // Other attributes of the comparison, such as unsignedness, are specified 3324 // by the comparison instruction that sets a condition code flags register. 3325 // That result is represented by a flags operand whose subtype is appropriate 3326 // to the unsignedness (etc.) of the comparison. 3327 // 3328 // Later, the instruction which matches both the Comparison Op (a Bool) and 3329 // the flags (produced by the Cmp) specifies the coding of the comparison op 3330 // by matching a specific subtype of Bool operand below, such as cmpOpU. 3331 3332 // Comparison Code 3333 operand cmpOp() 3334 %{ 3335 match(Bool); 3336 3337 format %{ "" %} 3338 interface(COND_INTER) %{ 3339 equal(0x4, "e"); 3340 not_equal(0x5, "ne"); 3341 less(0xC, "l"); 3342 greater_equal(0xD, "ge"); 3343 less_equal(0xE, "le"); 3344 greater(0xF, "g"); 3345 overflow(0x0, "o"); 3346 no_overflow(0x1, "no"); 3347 %} 3348 %} 3349 3350 // Comparison Code, unsigned compare. Used by FP also, with 3351 // C2 (unordered) turned into GT or LT already. The other bits 3352 // C0 and C3 are turned into Carry & Zero flags. 3353 operand cmpOpU() 3354 %{ 3355 match(Bool); 3356 3357 format %{ "" %} 3358 interface(COND_INTER) %{ 3359 equal(0x4, "e"); 3360 not_equal(0x5, "ne"); 3361 less(0x2, "b"); 3362 greater_equal(0x3, "ae"); 3363 less_equal(0x6, "be"); 3364 greater(0x7, "a"); 3365 overflow(0x0, "o"); 3366 no_overflow(0x1, "no"); 3367 %} 3368 %} 3369 3370 3371 // Floating comparisons that don't require any fixup for the unordered case, 3372 // If both inputs of the comparison are the same, ZF is always set so we 3373 // don't need to use cmpOpUCF2 for eq/ne 3374 operand cmpOpUCF() %{ 3375 match(Bool); 3376 predicate(n->as_Bool()->_test._test == BoolTest::lt || 3377 n->as_Bool()->_test._test == BoolTest::ge || 3378 n->as_Bool()->_test._test == BoolTest::le || 3379 n->as_Bool()->_test._test == BoolTest::gt || 3380 n->in(1)->in(1) == n->in(1)->in(2)); 3381 format %{ "" %} 3382 interface(COND_INTER) %{ 3383 equal(0xb, "np"); 3384 not_equal(0xa, "p"); 3385 less(0x2, "b"); 3386 greater_equal(0x3, "ae"); 3387 less_equal(0x6, "be"); 3388 greater(0x7, "a"); 3389 overflow(0x0, "o"); 3390 no_overflow(0x1, "no"); 3391 %} 3392 %} 3393 3394 3395 // Floating comparisons that can be fixed up with extra conditional jumps 3396 operand cmpOpUCF2() %{ 3397 match(Bool); 3398 predicate((n->as_Bool()->_test._test == BoolTest::ne || 3399 n->as_Bool()->_test._test == BoolTest::eq) && 3400 n->in(1)->in(1) != n->in(1)->in(2)); 3401 format %{ "" %} 3402 interface(COND_INTER) %{ 3403 equal(0x4, "e"); 3404 not_equal(0x5, "ne"); 3405 less(0x2, "b"); 3406 greater_equal(0x3, "ae"); 3407 less_equal(0x6, "be"); 3408 greater(0x7, "a"); 3409 overflow(0x0, "o"); 3410 no_overflow(0x1, "no"); 3411 %} 3412 %} 3413 3414 //----------OPERAND CLASSES---------------------------------------------------- 3415 // Operand Classes are groups of operands that are used as to simplify 3416 // instruction definitions by not requiring the AD writer to specify separate 3417 // instructions for every form of operand when the instruction accepts 3418 // multiple operand types with the same basic encoding and format. The classic 3419 // case of this is memory operands. 3420 3421 opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex, 3422 indIndexScale, indPosIndexScale, indIndexScaleOffset, indPosIndexOffset, indPosIndexScaleOffset, 3423 indCompressedOopOffset, 3424 indirectNarrow, indOffset8Narrow, indOffset32Narrow, 3425 indIndexOffsetNarrow, indIndexNarrow, indIndexScaleNarrow, 3426 indIndexScaleOffsetNarrow, indPosIndexOffsetNarrow, indPosIndexScaleOffsetNarrow); 3427 3428 //----------PIPELINE----------------------------------------------------------- 3429 // Rules which define the behavior of the target architectures pipeline. 3430 pipeline %{ 3431 3432 //----------ATTRIBUTES--------------------------------------------------------- 3433 attributes %{ 3434 variable_size_instructions; // Fixed size instructions 3435 max_instructions_per_bundle = 3; // Up to 3 instructions per bundle 3436 instruction_unit_size = 1; // An instruction is 1 bytes long 3437 instruction_fetch_unit_size = 16; // The processor fetches one line 3438 instruction_fetch_units = 1; // of 16 bytes 3439 3440 // List of nop instructions 3441 nops( MachNop ); 3442 %} 3443 3444 //----------RESOURCES---------------------------------------------------------- 3445 // Resources are the functional units available to the machine 3446 3447 // Generic P2/P3 pipeline 3448 // 3 decoders, only D0 handles big operands; a "bundle" is the limit of 3449 // 3 instructions decoded per cycle. 3450 // 2 load/store ops per cycle, 1 branch, 1 FPU, 3451 // 3 ALU op, only ALU0 handles mul instructions. 3452 resources( D0, D1, D2, DECODE = D0 | D1 | D2, 3453 MS0, MS1, MS2, MEM = MS0 | MS1 | MS2, 3454 BR, FPU, 3455 ALU0, ALU1, ALU2, ALU = ALU0 | ALU1 | ALU2); 3456 3457 //----------PIPELINE DESCRIPTION----------------------------------------------- 3458 // Pipeline Description specifies the stages in the machine's pipeline 3459 3460 // Generic P2/P3 pipeline 3461 pipe_desc(S0, S1, S2, S3, S4, S5); 3462 3463 //----------PIPELINE CLASSES--------------------------------------------------- 3464 // Pipeline Classes describe the stages in which input and output are 3465 // referenced by the hardware pipeline. 3466 3467 // Naming convention: ialu or fpu 3468 // Then: _reg 3469 // Then: _reg if there is a 2nd register 3470 // Then: _long if it's a pair of instructions implementing a long 3471 // Then: _fat if it requires the big decoder 3472 // Or: _mem if it requires the big decoder and a memory unit. 3473 3474 // Integer ALU reg operation 3475 pipe_class ialu_reg(rRegI dst) 3476 %{ 3477 single_instruction; 3478 dst : S4(write); 3479 dst : S3(read); 3480 DECODE : S0; // any decoder 3481 ALU : S3; // any alu 3482 %} 3483 3484 // Long ALU reg operation 3485 pipe_class ialu_reg_long(rRegL dst) 3486 %{ 3487 instruction_count(2); 3488 dst : S4(write); 3489 dst : S3(read); 3490 DECODE : S0(2); // any 2 decoders 3491 ALU : S3(2); // both alus 3492 %} 3493 3494 // Integer ALU reg operation using big decoder 3495 pipe_class ialu_reg_fat(rRegI dst) 3496 %{ 3497 single_instruction; 3498 dst : S4(write); 3499 dst : S3(read); 3500 D0 : S0; // big decoder only 3501 ALU : S3; // any alu 3502 %} 3503 3504 // Integer ALU reg-reg operation 3505 pipe_class ialu_reg_reg(rRegI dst, rRegI src) 3506 %{ 3507 single_instruction; 3508 dst : S4(write); 3509 src : S3(read); 3510 DECODE : S0; // any decoder 3511 ALU : S3; // any alu 3512 %} 3513 3514 // Integer ALU reg-reg operation 3515 pipe_class ialu_reg_reg_fat(rRegI dst, memory src) 3516 %{ 3517 single_instruction; 3518 dst : S4(write); 3519 src : S3(read); 3520 D0 : S0; // big decoder only 3521 ALU : S3; // any alu 3522 %} 3523 3524 // Integer ALU reg-mem operation 3525 pipe_class ialu_reg_mem(rRegI dst, memory mem) 3526 %{ 3527 single_instruction; 3528 dst : S5(write); 3529 mem : S3(read); 3530 D0 : S0; // big decoder only 3531 ALU : S4; // any alu 3532 MEM : S3; // any mem 3533 %} 3534 3535 // Integer mem operation (prefetch) 3536 pipe_class ialu_mem(memory mem) 3537 %{ 3538 single_instruction; 3539 mem : S3(read); 3540 D0 : S0; // big decoder only 3541 MEM : S3; // any mem 3542 %} 3543 3544 // Integer Store to Memory 3545 pipe_class ialu_mem_reg(memory mem, rRegI src) 3546 %{ 3547 single_instruction; 3548 mem : S3(read); 3549 src : S5(read); 3550 D0 : S0; // big decoder only 3551 ALU : S4; // any alu 3552 MEM : S3; 3553 %} 3554 3555 // // Long Store to Memory 3556 // pipe_class ialu_mem_long_reg(memory mem, rRegL src) 3557 // %{ 3558 // instruction_count(2); 3559 // mem : S3(read); 3560 // src : S5(read); 3561 // D0 : S0(2); // big decoder only; twice 3562 // ALU : S4(2); // any 2 alus 3563 // MEM : S3(2); // Both mems 3564 // %} 3565 3566 // Integer Store to Memory 3567 pipe_class ialu_mem_imm(memory mem) 3568 %{ 3569 single_instruction; 3570 mem : S3(read); 3571 D0 : S0; // big decoder only 3572 ALU : S4; // any alu 3573 MEM : S3; 3574 %} 3575 3576 // Integer ALU0 reg-reg operation 3577 pipe_class ialu_reg_reg_alu0(rRegI dst, rRegI src) 3578 %{ 3579 single_instruction; 3580 dst : S4(write); 3581 src : S3(read); 3582 D0 : S0; // Big decoder only 3583 ALU0 : S3; // only alu0 3584 %} 3585 3586 // Integer ALU0 reg-mem operation 3587 pipe_class ialu_reg_mem_alu0(rRegI dst, memory mem) 3588 %{ 3589 single_instruction; 3590 dst : S5(write); 3591 mem : S3(read); 3592 D0 : S0; // big decoder only 3593 ALU0 : S4; // ALU0 only 3594 MEM : S3; // any mem 3595 %} 3596 3597 // Integer ALU reg-reg operation 3598 pipe_class ialu_cr_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2) 3599 %{ 3600 single_instruction; 3601 cr : S4(write); 3602 src1 : S3(read); 3603 src2 : S3(read); 3604 DECODE : S0; // any decoder 3605 ALU : S3; // any alu 3606 %} 3607 3608 // Integer ALU reg-imm operation 3609 pipe_class ialu_cr_reg_imm(rFlagsReg cr, rRegI src1) 3610 %{ 3611 single_instruction; 3612 cr : S4(write); 3613 src1 : S3(read); 3614 DECODE : S0; // any decoder 3615 ALU : S3; // any alu 3616 %} 3617 3618 // Integer ALU reg-mem operation 3619 pipe_class ialu_cr_reg_mem(rFlagsReg cr, rRegI src1, memory src2) 3620 %{ 3621 single_instruction; 3622 cr : S4(write); 3623 src1 : S3(read); 3624 src2 : S3(read); 3625 D0 : S0; // big decoder only 3626 ALU : S4; // any alu 3627 MEM : S3; 3628 %} 3629 3630 // Conditional move reg-reg 3631 pipe_class pipe_cmplt( rRegI p, rRegI q, rRegI y) 3632 %{ 3633 instruction_count(4); 3634 y : S4(read); 3635 q : S3(read); 3636 p : S3(read); 3637 DECODE : S0(4); // any decoder 3638 %} 3639 3640 // Conditional move reg-reg 3641 pipe_class pipe_cmov_reg( rRegI dst, rRegI src, rFlagsReg cr) 3642 %{ 3643 single_instruction; 3644 dst : S4(write); 3645 src : S3(read); 3646 cr : S3(read); 3647 DECODE : S0; // any decoder 3648 %} 3649 3650 // Conditional move reg-mem 3651 pipe_class pipe_cmov_mem( rFlagsReg cr, rRegI dst, memory src) 3652 %{ 3653 single_instruction; 3654 dst : S4(write); 3655 src : S3(read); 3656 cr : S3(read); 3657 DECODE : S0; // any decoder 3658 MEM : S3; 3659 %} 3660 3661 // Conditional move reg-reg long 3662 pipe_class pipe_cmov_reg_long( rFlagsReg cr, rRegL dst, rRegL src) 3663 %{ 3664 single_instruction; 3665 dst : S4(write); 3666 src : S3(read); 3667 cr : S3(read); 3668 DECODE : S0(2); // any 2 decoders 3669 %} 3670 3671 // Float reg-reg operation 3672 pipe_class fpu_reg(regD dst) 3673 %{ 3674 instruction_count(2); 3675 dst : S3(read); 3676 DECODE : S0(2); // any 2 decoders 3677 FPU : S3; 3678 %} 3679 3680 // Float reg-reg operation 3681 pipe_class fpu_reg_reg(regD dst, regD src) 3682 %{ 3683 instruction_count(2); 3684 dst : S4(write); 3685 src : S3(read); 3686 DECODE : S0(2); // any 2 decoders 3687 FPU : S3; 3688 %} 3689 3690 // Float reg-reg operation 3691 pipe_class fpu_reg_reg_reg(regD dst, regD src1, regD src2) 3692 %{ 3693 instruction_count(3); 3694 dst : S4(write); 3695 src1 : S3(read); 3696 src2 : S3(read); 3697 DECODE : S0(3); // any 3 decoders 3698 FPU : S3(2); 3699 %} 3700 3701 // Float reg-reg operation 3702 pipe_class fpu_reg_reg_reg_reg(regD dst, regD src1, regD src2, regD src3) 3703 %{ 3704 instruction_count(4); 3705 dst : S4(write); 3706 src1 : S3(read); 3707 src2 : S3(read); 3708 src3 : S3(read); 3709 DECODE : S0(4); // any 3 decoders 3710 FPU : S3(2); 3711 %} 3712 3713 // Float reg-reg operation 3714 pipe_class fpu_reg_mem_reg_reg(regD dst, memory src1, regD src2, regD src3) 3715 %{ 3716 instruction_count(4); 3717 dst : S4(write); 3718 src1 : S3(read); 3719 src2 : S3(read); 3720 src3 : S3(read); 3721 DECODE : S1(3); // any 3 decoders 3722 D0 : S0; // Big decoder only 3723 FPU : S3(2); 3724 MEM : S3; 3725 %} 3726 3727 // Float reg-mem operation 3728 pipe_class fpu_reg_mem(regD dst, memory mem) 3729 %{ 3730 instruction_count(2); 3731 dst : S5(write); 3732 mem : S3(read); 3733 D0 : S0; // big decoder only 3734 DECODE : S1; // any decoder for FPU POP 3735 FPU : S4; 3736 MEM : S3; // any mem 3737 %} 3738 3739 // Float reg-mem operation 3740 pipe_class fpu_reg_reg_mem(regD dst, regD src1, memory mem) 3741 %{ 3742 instruction_count(3); 3743 dst : S5(write); 3744 src1 : S3(read); 3745 mem : S3(read); 3746 D0 : S0; // big decoder only 3747 DECODE : S1(2); // any decoder for FPU POP 3748 FPU : S4; 3749 MEM : S3; // any mem 3750 %} 3751 3752 // Float mem-reg operation 3753 pipe_class fpu_mem_reg(memory mem, regD src) 3754 %{ 3755 instruction_count(2); 3756 src : S5(read); 3757 mem : S3(read); 3758 DECODE : S0; // any decoder for FPU PUSH 3759 D0 : S1; // big decoder only 3760 FPU : S4; 3761 MEM : S3; // any mem 3762 %} 3763 3764 pipe_class fpu_mem_reg_reg(memory mem, regD src1, regD src2) 3765 %{ 3766 instruction_count(3); 3767 src1 : S3(read); 3768 src2 : S3(read); 3769 mem : S3(read); 3770 DECODE : S0(2); // any decoder for FPU PUSH 3771 D0 : S1; // big decoder only 3772 FPU : S4; 3773 MEM : S3; // any mem 3774 %} 3775 3776 pipe_class fpu_mem_reg_mem(memory mem, regD src1, memory src2) 3777 %{ 3778 instruction_count(3); 3779 src1 : S3(read); 3780 src2 : S3(read); 3781 mem : S4(read); 3782 DECODE : S0; // any decoder for FPU PUSH 3783 D0 : S0(2); // big decoder only 3784 FPU : S4; 3785 MEM : S3(2); // any mem 3786 %} 3787 3788 pipe_class fpu_mem_mem(memory dst, memory src1) 3789 %{ 3790 instruction_count(2); 3791 src1 : S3(read); 3792 dst : S4(read); 3793 D0 : S0(2); // big decoder only 3794 MEM : S3(2); // any mem 3795 %} 3796 3797 pipe_class fpu_mem_mem_mem(memory dst, memory src1, memory src2) 3798 %{ 3799 instruction_count(3); 3800 src1 : S3(read); 3801 src2 : S3(read); 3802 dst : S4(read); 3803 D0 : S0(3); // big decoder only 3804 FPU : S4; 3805 MEM : S3(3); // any mem 3806 %} 3807 3808 pipe_class fpu_mem_reg_con(memory mem, regD src1) 3809 %{ 3810 instruction_count(3); 3811 src1 : S4(read); 3812 mem : S4(read); 3813 DECODE : S0; // any decoder for FPU PUSH 3814 D0 : S0(2); // big decoder only 3815 FPU : S4; 3816 MEM : S3(2); // any mem 3817 %} 3818 3819 // Float load constant 3820 pipe_class fpu_reg_con(regD dst) 3821 %{ 3822 instruction_count(2); 3823 dst : S5(write); 3824 D0 : S0; // big decoder only for the load 3825 DECODE : S1; // any decoder for FPU POP 3826 FPU : S4; 3827 MEM : S3; // any mem 3828 %} 3829 3830 // Float load constant 3831 pipe_class fpu_reg_reg_con(regD dst, regD src) 3832 %{ 3833 instruction_count(3); 3834 dst : S5(write); 3835 src : S3(read); 3836 D0 : S0; // big decoder only for the load 3837 DECODE : S1(2); // any decoder for FPU POP 3838 FPU : S4; 3839 MEM : S3; // any mem 3840 %} 3841 3842 // UnConditional branch 3843 pipe_class pipe_jmp(label labl) 3844 %{ 3845 single_instruction; 3846 BR : S3; 3847 %} 3848 3849 // Conditional branch 3850 pipe_class pipe_jcc(cmpOp cmp, rFlagsReg cr, label labl) 3851 %{ 3852 single_instruction; 3853 cr : S1(read); 3854 BR : S3; 3855 %} 3856 3857 // Allocation idiom 3858 pipe_class pipe_cmpxchg(rRegP dst, rRegP heap_ptr) 3859 %{ 3860 instruction_count(1); force_serialization; 3861 fixed_latency(6); 3862 heap_ptr : S3(read); 3863 DECODE : S0(3); 3864 D0 : S2; 3865 MEM : S3; 3866 ALU : S3(2); 3867 dst : S5(write); 3868 BR : S5; 3869 %} 3870 3871 // Generic big/slow expanded idiom 3872 pipe_class pipe_slow() 3873 %{ 3874 instruction_count(10); multiple_bundles; force_serialization; 3875 fixed_latency(100); 3876 D0 : S0(2); 3877 MEM : S3(2); 3878 %} 3879 3880 // The real do-nothing guy 3881 pipe_class empty() 3882 %{ 3883 instruction_count(0); 3884 %} 3885 3886 // Define the class for the Nop node 3887 define 3888 %{ 3889 MachNop = empty; 3890 %} 3891 3892 %} 3893 3894 //----------INSTRUCTIONS------------------------------------------------------- 3895 // 3896 // match -- States which machine-independent subtree may be replaced 3897 // by this instruction. 3898 // ins_cost -- The estimated cost of this instruction is used by instruction 3899 // selection to identify a minimum cost tree of machine 3900 // instructions that matches a tree of machine-independent 3901 // instructions. 3902 // format -- A string providing the disassembly for this instruction. 3903 // The value of an instruction's operand may be inserted 3904 // by referring to it with a '$' prefix. 3905 // opcode -- Three instruction opcodes may be provided. These are referred 3906 // to within an encode class as $primary, $secondary, and $tertiary 3907 // rrspectively. The primary opcode is commonly used to 3908 // indicate the type of machine instruction, while secondary 3909 // and tertiary are often used for prefix options or addressing 3910 // modes. 3911 // ins_encode -- A list of encode classes with parameters. The encode class 3912 // name must have been defined in an 'enc_class' specification 3913 // in the encode section of the architecture description. 3914 3915 // Dummy reg-to-reg vector moves. Removed during post-selection cleanup. 3916 // Load Float 3917 instruct MoveF2VL(vlRegF dst, regF src) %{ 3918 match(Set dst src); 3919 format %{ "movss $dst,$src\t! load float (4 bytes)" %} 3920 ins_encode %{ 3921 ShouldNotReachHere(); 3922 %} 3923 ins_pipe( fpu_reg_reg ); 3924 %} 3925 3926 // Load Float 3927 instruct MoveF2LEG(legRegF dst, regF src) %{ 3928 match(Set dst src); 3929 format %{ "movss $dst,$src\t# if src != dst load float (4 bytes)" %} 3930 ins_encode %{ 3931 ShouldNotReachHere(); 3932 %} 3933 ins_pipe( fpu_reg_reg ); 3934 %} 3935 3936 // Load Float 3937 instruct MoveVL2F(regF dst, vlRegF src) %{ 3938 match(Set dst src); 3939 format %{ "movss $dst,$src\t! load float (4 bytes)" %} 3940 ins_encode %{ 3941 ShouldNotReachHere(); 3942 %} 3943 ins_pipe( fpu_reg_reg ); 3944 %} 3945 3946 // Load Float 3947 instruct MoveLEG2F(regF dst, legRegF src) %{ 3948 match(Set dst src); 3949 format %{ "movss $dst,$src\t# if src != dst load float (4 bytes)" %} 3950 ins_encode %{ 3951 ShouldNotReachHere(); 3952 %} 3953 ins_pipe( fpu_reg_reg ); 3954 %} 3955 3956 // Load Double 3957 instruct MoveD2VL(vlRegD dst, regD src) %{ 3958 match(Set dst src); 3959 format %{ "movsd $dst,$src\t! load double (8 bytes)" %} 3960 ins_encode %{ 3961 ShouldNotReachHere(); 3962 %} 3963 ins_pipe( fpu_reg_reg ); 3964 %} 3965 3966 // Load Double 3967 instruct MoveD2LEG(legRegD dst, regD src) %{ 3968 match(Set dst src); 3969 format %{ "movsd $dst,$src\t# if src != dst load double (8 bytes)" %} 3970 ins_encode %{ 3971 ShouldNotReachHere(); 3972 %} 3973 ins_pipe( fpu_reg_reg ); 3974 %} 3975 3976 // Load Double 3977 instruct MoveVL2D(regD dst, vlRegD src) %{ 3978 match(Set dst src); 3979 format %{ "movsd $dst,$src\t! load double (8 bytes)" %} 3980 ins_encode %{ 3981 ShouldNotReachHere(); 3982 %} 3983 ins_pipe( fpu_reg_reg ); 3984 %} 3985 3986 // Load Double 3987 instruct MoveLEG2D(regD dst, legRegD src) %{ 3988 match(Set dst src); 3989 format %{ "movsd $dst,$src\t# if src != dst load double (8 bytes)" %} 3990 ins_encode %{ 3991 ShouldNotReachHere(); 3992 %} 3993 ins_pipe( fpu_reg_reg ); 3994 %} 3995 3996 //----------Load/Store/Move Instructions--------------------------------------- 3997 //----------Load Instructions-------------------------------------------------- 3998 3999 // Load Byte (8 bit signed) 4000 instruct loadB(rRegI dst, memory mem) 4001 %{ 4002 match(Set dst (LoadB mem)); 4003 4004 ins_cost(125); 4005 format %{ "movsbl $dst, $mem\t# byte" %} 4006 4007 ins_encode %{ 4008 __ movsbl($dst$$Register, $mem$$Address); 4009 %} 4010 4011 ins_pipe(ialu_reg_mem); 4012 %} 4013 4014 // Load Byte (8 bit signed) into Long Register 4015 instruct loadB2L(rRegL dst, memory mem) 4016 %{ 4017 match(Set dst (ConvI2L (LoadB mem))); 4018 4019 ins_cost(125); 4020 format %{ "movsbq $dst, $mem\t# byte -> long" %} 4021 4022 ins_encode %{ 4023 __ movsbq($dst$$Register, $mem$$Address); 4024 %} 4025 4026 ins_pipe(ialu_reg_mem); 4027 %} 4028 4029 // Load Unsigned Byte (8 bit UNsigned) 4030 instruct loadUB(rRegI dst, memory mem) 4031 %{ 4032 match(Set dst (LoadUB mem)); 4033 4034 ins_cost(125); 4035 format %{ "movzbl $dst, $mem\t# ubyte" %} 4036 4037 ins_encode %{ 4038 __ movzbl($dst$$Register, $mem$$Address); 4039 %} 4040 4041 ins_pipe(ialu_reg_mem); 4042 %} 4043 4044 // Load Unsigned Byte (8 bit UNsigned) into Long Register 4045 instruct loadUB2L(rRegL dst, memory mem) 4046 %{ 4047 match(Set dst (ConvI2L (LoadUB mem))); 4048 4049 ins_cost(125); 4050 format %{ "movzbq $dst, $mem\t# ubyte -> long" %} 4051 4052 ins_encode %{ 4053 __ movzbq($dst$$Register, $mem$$Address); 4054 %} 4055 4056 ins_pipe(ialu_reg_mem); 4057 %} 4058 4059 // Load Unsigned Byte (8 bit UNsigned) with 32-bit mask into Long Register 4060 instruct loadUB2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 4061 match(Set dst (ConvI2L (AndI (LoadUB mem) mask))); 4062 effect(KILL cr); 4063 4064 format %{ "movzbq $dst, $mem\t# ubyte & 32-bit mask -> long\n\t" 4065 "andl $dst, right_n_bits($mask, 8)" %} 4066 ins_encode %{ 4067 Register Rdst = $dst$$Register; 4068 __ movzbq(Rdst, $mem$$Address); 4069 __ andl(Rdst, $mask$$constant & right_n_bits(8)); 4070 %} 4071 ins_pipe(ialu_reg_mem); 4072 %} 4073 4074 // Load Short (16 bit signed) 4075 instruct loadS(rRegI dst, memory mem) 4076 %{ 4077 match(Set dst (LoadS mem)); 4078 4079 ins_cost(125); 4080 format %{ "movswl $dst, $mem\t# short" %} 4081 4082 ins_encode %{ 4083 __ movswl($dst$$Register, $mem$$Address); 4084 %} 4085 4086 ins_pipe(ialu_reg_mem); 4087 %} 4088 4089 // Load Short (16 bit signed) to Byte (8 bit signed) 4090 instruct loadS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4091 match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour)); 4092 4093 ins_cost(125); 4094 format %{ "movsbl $dst, $mem\t# short -> byte" %} 4095 ins_encode %{ 4096 __ movsbl($dst$$Register, $mem$$Address); 4097 %} 4098 ins_pipe(ialu_reg_mem); 4099 %} 4100 4101 // Load Short (16 bit signed) into Long Register 4102 instruct loadS2L(rRegL dst, memory mem) 4103 %{ 4104 match(Set dst (ConvI2L (LoadS mem))); 4105 4106 ins_cost(125); 4107 format %{ "movswq $dst, $mem\t# short -> long" %} 4108 4109 ins_encode %{ 4110 __ movswq($dst$$Register, $mem$$Address); 4111 %} 4112 4113 ins_pipe(ialu_reg_mem); 4114 %} 4115 4116 // Load Unsigned Short/Char (16 bit UNsigned) 4117 instruct loadUS(rRegI dst, memory mem) 4118 %{ 4119 match(Set dst (LoadUS mem)); 4120 4121 ins_cost(125); 4122 format %{ "movzwl $dst, $mem\t# ushort/char" %} 4123 4124 ins_encode %{ 4125 __ movzwl($dst$$Register, $mem$$Address); 4126 %} 4127 4128 ins_pipe(ialu_reg_mem); 4129 %} 4130 4131 // Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed) 4132 instruct loadUS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4133 match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour)); 4134 4135 ins_cost(125); 4136 format %{ "movsbl $dst, $mem\t# ushort -> byte" %} 4137 ins_encode %{ 4138 __ movsbl($dst$$Register, $mem$$Address); 4139 %} 4140 ins_pipe(ialu_reg_mem); 4141 %} 4142 4143 // Load Unsigned Short/Char (16 bit UNsigned) into Long Register 4144 instruct loadUS2L(rRegL dst, memory mem) 4145 %{ 4146 match(Set dst (ConvI2L (LoadUS mem))); 4147 4148 ins_cost(125); 4149 format %{ "movzwq $dst, $mem\t# ushort/char -> long" %} 4150 4151 ins_encode %{ 4152 __ movzwq($dst$$Register, $mem$$Address); 4153 %} 4154 4155 ins_pipe(ialu_reg_mem); 4156 %} 4157 4158 // Load Unsigned Short/Char (16 bit UNsigned) with mask 0xFF into Long Register 4159 instruct loadUS2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 4160 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 4161 4162 format %{ "movzbq $dst, $mem\t# ushort/char & 0xFF -> long" %} 4163 ins_encode %{ 4164 __ movzbq($dst$$Register, $mem$$Address); 4165 %} 4166 ins_pipe(ialu_reg_mem); 4167 %} 4168 4169 // Load Unsigned Short/Char (16 bit UNsigned) with 32-bit mask into Long Register 4170 instruct loadUS2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 4171 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 4172 effect(KILL cr); 4173 4174 format %{ "movzwq $dst, $mem\t# ushort/char & 32-bit mask -> long\n\t" 4175 "andl $dst, right_n_bits($mask, 16)" %} 4176 ins_encode %{ 4177 Register Rdst = $dst$$Register; 4178 __ movzwq(Rdst, $mem$$Address); 4179 __ andl(Rdst, $mask$$constant & right_n_bits(16)); 4180 %} 4181 ins_pipe(ialu_reg_mem); 4182 %} 4183 4184 // Load Integer 4185 instruct loadI(rRegI dst, memory mem) 4186 %{ 4187 match(Set dst (LoadI mem)); 4188 4189 ins_cost(125); 4190 format %{ "movl $dst, $mem\t# int" %} 4191 4192 ins_encode %{ 4193 __ movl($dst$$Register, $mem$$Address); 4194 %} 4195 4196 ins_pipe(ialu_reg_mem); 4197 %} 4198 4199 // Load Integer (32 bit signed) to Byte (8 bit signed) 4200 instruct loadI2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4201 match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour)); 4202 4203 ins_cost(125); 4204 format %{ "movsbl $dst, $mem\t# int -> byte" %} 4205 ins_encode %{ 4206 __ movsbl($dst$$Register, $mem$$Address); 4207 %} 4208 ins_pipe(ialu_reg_mem); 4209 %} 4210 4211 // Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned) 4212 instruct loadI2UB(rRegI dst, memory mem, immI_255 mask) %{ 4213 match(Set dst (AndI (LoadI mem) mask)); 4214 4215 ins_cost(125); 4216 format %{ "movzbl $dst, $mem\t# int -> ubyte" %} 4217 ins_encode %{ 4218 __ movzbl($dst$$Register, $mem$$Address); 4219 %} 4220 ins_pipe(ialu_reg_mem); 4221 %} 4222 4223 // Load Integer (32 bit signed) to Short (16 bit signed) 4224 instruct loadI2S(rRegI dst, memory mem, immI_16 sixteen) %{ 4225 match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen)); 4226 4227 ins_cost(125); 4228 format %{ "movswl $dst, $mem\t# int -> short" %} 4229 ins_encode %{ 4230 __ movswl($dst$$Register, $mem$$Address); 4231 %} 4232 ins_pipe(ialu_reg_mem); 4233 %} 4234 4235 // Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned) 4236 instruct loadI2US(rRegI dst, memory mem, immI_65535 mask) %{ 4237 match(Set dst (AndI (LoadI mem) mask)); 4238 4239 ins_cost(125); 4240 format %{ "movzwl $dst, $mem\t# int -> ushort/char" %} 4241 ins_encode %{ 4242 __ movzwl($dst$$Register, $mem$$Address); 4243 %} 4244 ins_pipe(ialu_reg_mem); 4245 %} 4246 4247 // Load Integer into Long Register 4248 instruct loadI2L(rRegL dst, memory mem) 4249 %{ 4250 match(Set dst (ConvI2L (LoadI mem))); 4251 4252 ins_cost(125); 4253 format %{ "movslq $dst, $mem\t# int -> long" %} 4254 4255 ins_encode %{ 4256 __ movslq($dst$$Register, $mem$$Address); 4257 %} 4258 4259 ins_pipe(ialu_reg_mem); 4260 %} 4261 4262 // Load Integer with mask 0xFF into Long Register 4263 instruct loadI2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 4264 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4265 4266 format %{ "movzbq $dst, $mem\t# int & 0xFF -> long" %} 4267 ins_encode %{ 4268 __ movzbq($dst$$Register, $mem$$Address); 4269 %} 4270 ins_pipe(ialu_reg_mem); 4271 %} 4272 4273 // Load Integer with mask 0xFFFF into Long Register 4274 instruct loadI2L_immI_65535(rRegL dst, memory mem, immI_65535 mask) %{ 4275 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4276 4277 format %{ "movzwq $dst, $mem\t# int & 0xFFFF -> long" %} 4278 ins_encode %{ 4279 __ movzwq($dst$$Register, $mem$$Address); 4280 %} 4281 ins_pipe(ialu_reg_mem); 4282 %} 4283 4284 // Load Integer with a 31-bit mask into Long Register 4285 instruct loadI2L_immU31(rRegL dst, memory mem, immU31 mask, rFlagsReg cr) %{ 4286 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4287 effect(KILL cr); 4288 4289 format %{ "movl $dst, $mem\t# int & 31-bit mask -> long\n\t" 4290 "andl $dst, $mask" %} 4291 ins_encode %{ 4292 Register Rdst = $dst$$Register; 4293 __ movl(Rdst, $mem$$Address); 4294 __ andl(Rdst, $mask$$constant); 4295 %} 4296 ins_pipe(ialu_reg_mem); 4297 %} 4298 4299 // Load Unsigned Integer into Long Register 4300 instruct loadUI2L(rRegL dst, memory mem, immL_32bits mask) 4301 %{ 4302 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 4303 4304 ins_cost(125); 4305 format %{ "movl $dst, $mem\t# uint -> long" %} 4306 4307 ins_encode %{ 4308 __ movl($dst$$Register, $mem$$Address); 4309 %} 4310 4311 ins_pipe(ialu_reg_mem); 4312 %} 4313 4314 // Load Long 4315 instruct loadL(rRegL dst, memory mem) 4316 %{ 4317 match(Set dst (LoadL mem)); 4318 4319 ins_cost(125); 4320 format %{ "movq $dst, $mem\t# long" %} 4321 4322 ins_encode %{ 4323 __ movq($dst$$Register, $mem$$Address); 4324 %} 4325 4326 ins_pipe(ialu_reg_mem); // XXX 4327 %} 4328 4329 // Load Range 4330 instruct loadRange(rRegI dst, memory mem) 4331 %{ 4332 match(Set dst (LoadRange mem)); 4333 4334 ins_cost(125); // XXX 4335 format %{ "movl $dst, $mem\t# range" %} 4336 ins_encode %{ 4337 __ movl($dst$$Register, $mem$$Address); 4338 %} 4339 ins_pipe(ialu_reg_mem); 4340 %} 4341 4342 // Load Pointer 4343 instruct loadP(rRegP dst, memory mem) 4344 %{ 4345 match(Set dst (LoadP mem)); 4346 predicate(n->as_Load()->barrier_data() == 0); 4347 4348 ins_cost(125); // XXX 4349 format %{ "movq $dst, $mem\t# ptr" %} 4350 ins_encode %{ 4351 __ movq($dst$$Register, $mem$$Address); 4352 %} 4353 ins_pipe(ialu_reg_mem); // XXX 4354 %} 4355 4356 // Load Compressed Pointer 4357 instruct loadN(rRegN dst, memory mem) 4358 %{ 4359 predicate(n->as_Load()->barrier_data() == 0); 4360 match(Set dst (LoadN mem)); 4361 4362 ins_cost(125); // XXX 4363 format %{ "movl $dst, $mem\t# compressed ptr" %} 4364 ins_encode %{ 4365 __ movl($dst$$Register, $mem$$Address); 4366 %} 4367 ins_pipe(ialu_reg_mem); // XXX 4368 %} 4369 4370 4371 // Load Klass Pointer 4372 instruct loadKlass(rRegP dst, memory mem) 4373 %{ 4374 match(Set dst (LoadKlass mem)); 4375 4376 ins_cost(125); // XXX 4377 format %{ "movq $dst, $mem\t# class" %} 4378 ins_encode %{ 4379 __ movq($dst$$Register, $mem$$Address); 4380 %} 4381 ins_pipe(ialu_reg_mem); // XXX 4382 %} 4383 4384 // Load narrow Klass Pointer 4385 instruct loadNKlass(rRegN dst, memory mem) 4386 %{ 4387 predicate(!UseCompactObjectHeaders); 4388 match(Set dst (LoadNKlass mem)); 4389 4390 ins_cost(125); // XXX 4391 format %{ "movl $dst, $mem\t# compressed klass ptr" %} 4392 ins_encode %{ 4393 __ movl($dst$$Register, $mem$$Address); 4394 %} 4395 ins_pipe(ialu_reg_mem); // XXX 4396 %} 4397 4398 instruct loadNKlassCompactHeaders(rRegN dst, memory mem, rFlagsReg cr) 4399 %{ 4400 predicate(UseCompactObjectHeaders); 4401 match(Set dst (LoadNKlass mem)); 4402 effect(KILL cr); 4403 ins_cost(125); 4404 format %{ 4405 "movl $dst, $mem\t# compressed klass ptr, shifted\n\t" 4406 "shrl $dst, markWord::klass_shift_at_offset" 4407 %} 4408 ins_encode %{ 4409 if (UseAPX) { 4410 __ eshrl($dst$$Register, $mem$$Address, markWord::klass_shift_at_offset, false); 4411 } 4412 else { 4413 __ movl($dst$$Register, $mem$$Address); 4414 __ shrl($dst$$Register, markWord::klass_shift_at_offset); 4415 } 4416 %} 4417 ins_pipe(ialu_reg_mem); 4418 %} 4419 4420 // Load Float 4421 instruct loadF(regF dst, memory mem) 4422 %{ 4423 match(Set dst (LoadF mem)); 4424 4425 ins_cost(145); // XXX 4426 format %{ "movss $dst, $mem\t# float" %} 4427 ins_encode %{ 4428 __ movflt($dst$$XMMRegister, $mem$$Address); 4429 %} 4430 ins_pipe(pipe_slow); // XXX 4431 %} 4432 4433 // Load Double 4434 instruct loadD_partial(regD dst, memory mem) 4435 %{ 4436 predicate(!UseXmmLoadAndClearUpper); 4437 match(Set dst (LoadD mem)); 4438 4439 ins_cost(145); // XXX 4440 format %{ "movlpd $dst, $mem\t# double" %} 4441 ins_encode %{ 4442 __ movdbl($dst$$XMMRegister, $mem$$Address); 4443 %} 4444 ins_pipe(pipe_slow); // XXX 4445 %} 4446 4447 instruct loadD(regD dst, memory mem) 4448 %{ 4449 predicate(UseXmmLoadAndClearUpper); 4450 match(Set dst (LoadD mem)); 4451 4452 ins_cost(145); // XXX 4453 format %{ "movsd $dst, $mem\t# double" %} 4454 ins_encode %{ 4455 __ movdbl($dst$$XMMRegister, $mem$$Address); 4456 %} 4457 ins_pipe(pipe_slow); // XXX 4458 %} 4459 4460 instruct loadAOTRCAddress(rRegP dst, immAOTRuntimeConstantsAddress con) 4461 %{ 4462 match(Set dst con); 4463 4464 format %{ "leaq $dst, $con\t# AOT Runtime Constants Address" %} 4465 4466 ins_encode %{ 4467 __ load_aotrc_address($dst$$Register, (address)$con$$constant); 4468 %} 4469 4470 ins_pipe(ialu_reg_fat); 4471 %} 4472 4473 // max = java.lang.Math.max(float a, float b) 4474 instruct maxF_reg(legRegF dst, legRegF a, legRegF b, legRegF tmp, legRegF atmp, legRegF btmp) %{ 4475 predicate(UseAVX > 0 && !VLoopReductions::is_reduction(n)); 4476 match(Set dst (MaxF a b)); 4477 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 4478 format %{ "maxF $dst, $a, $b \t! using $tmp, $atmp and $btmp as TEMP" %} 4479 ins_encode %{ 4480 __ vminmax_fp(Op_MaxV, T_FLOAT, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, Assembler::AVX_128bit); 4481 %} 4482 ins_pipe( pipe_slow ); 4483 %} 4484 4485 instruct maxF_reduction_reg(legRegF dst, legRegF a, legRegF b, legRegF xtmp, rRegI rtmp, rFlagsReg cr) %{ 4486 predicate(UseAVX > 0 && VLoopReductions::is_reduction(n)); 4487 match(Set dst (MaxF a b)); 4488 effect(USE a, USE b, TEMP xtmp, TEMP rtmp, KILL cr); 4489 4490 format %{ "maxF_reduction $dst, $a, $b \t!using $xtmp and $rtmp as TEMP" %} 4491 ins_encode %{ 4492 emit_fp_min_max(masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xtmp$$XMMRegister, $rtmp$$Register, 4493 false /*min*/, true /*single*/); 4494 %} 4495 ins_pipe( pipe_slow ); 4496 %} 4497 4498 // max = java.lang.Math.max(double a, double b) 4499 instruct maxD_reg(legRegD dst, legRegD a, legRegD b, legRegD tmp, legRegD atmp, legRegD btmp) %{ 4500 predicate(UseAVX > 0 && !VLoopReductions::is_reduction(n)); 4501 match(Set dst (MaxD a b)); 4502 effect(USE a, USE b, TEMP atmp, TEMP btmp, TEMP tmp); 4503 format %{ "maxD $dst, $a, $b \t! using $tmp, $atmp and $btmp as TEMP" %} 4504 ins_encode %{ 4505 __ vminmax_fp(Op_MaxV, T_DOUBLE, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, Assembler::AVX_128bit); 4506 %} 4507 ins_pipe( pipe_slow ); 4508 %} 4509 4510 instruct maxD_reduction_reg(legRegD dst, legRegD a, legRegD b, legRegD xtmp, rRegL rtmp, rFlagsReg cr) %{ 4511 predicate(UseAVX > 0 && VLoopReductions::is_reduction(n)); 4512 match(Set dst (MaxD a b)); 4513 effect(USE a, USE b, TEMP xtmp, TEMP rtmp, KILL cr); 4514 4515 format %{ "maxD_reduction $dst, $a, $b \t! using $xtmp and $rtmp as TEMP" %} 4516 ins_encode %{ 4517 emit_fp_min_max(masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xtmp$$XMMRegister, $rtmp$$Register, 4518 false /*min*/, false /*single*/); 4519 %} 4520 ins_pipe( pipe_slow ); 4521 %} 4522 4523 // min = java.lang.Math.min(float a, float b) 4524 instruct minF_reg(legRegF dst, legRegF a, legRegF b, legRegF tmp, legRegF atmp, legRegF btmp) %{ 4525 predicate(UseAVX > 0 && !VLoopReductions::is_reduction(n)); 4526 match(Set dst (MinF a b)); 4527 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 4528 format %{ "minF $dst, $a, $b \t! using $tmp, $atmp and $btmp as TEMP" %} 4529 ins_encode %{ 4530 __ vminmax_fp(Op_MinV, T_FLOAT, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, Assembler::AVX_128bit); 4531 %} 4532 ins_pipe( pipe_slow ); 4533 %} 4534 4535 instruct minF_reduction_reg(legRegF dst, legRegF a, legRegF b, legRegF xtmp, rRegI rtmp, rFlagsReg cr) %{ 4536 predicate(UseAVX > 0 && VLoopReductions::is_reduction(n)); 4537 match(Set dst (MinF a b)); 4538 effect(USE a, USE b, TEMP xtmp, TEMP rtmp, KILL cr); 4539 4540 format %{ "minF_reduction $dst, $a, $b \t! using $xtmp and $rtmp as TEMP" %} 4541 ins_encode %{ 4542 emit_fp_min_max(masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xtmp$$XMMRegister, $rtmp$$Register, 4543 true /*min*/, true /*single*/); 4544 %} 4545 ins_pipe( pipe_slow ); 4546 %} 4547 4548 // min = java.lang.Math.min(double a, double b) 4549 instruct minD_reg(legRegD dst, legRegD a, legRegD b, legRegD tmp, legRegD atmp, legRegD btmp) %{ 4550 predicate(UseAVX > 0 && !VLoopReductions::is_reduction(n)); 4551 match(Set dst (MinD a b)); 4552 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 4553 format %{ "minD $dst, $a, $b \t! using $tmp, $atmp and $btmp as TEMP" %} 4554 ins_encode %{ 4555 __ vminmax_fp(Op_MinV, T_DOUBLE, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, Assembler::AVX_128bit); 4556 %} 4557 ins_pipe( pipe_slow ); 4558 %} 4559 4560 instruct minD_reduction_reg(legRegD dst, legRegD a, legRegD b, legRegD xtmp, rRegL rtmp, rFlagsReg cr) %{ 4561 predicate(UseAVX > 0 && VLoopReductions::is_reduction(n)); 4562 match(Set dst (MinD a b)); 4563 effect(USE a, USE b, TEMP xtmp, TEMP rtmp, KILL cr); 4564 4565 format %{ "maxD_reduction $dst, $a, $b \t! using $xtmp and $rtmp as TEMP" %} 4566 ins_encode %{ 4567 emit_fp_min_max(masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xtmp$$XMMRegister, $rtmp$$Register, 4568 true /*min*/, false /*single*/); 4569 %} 4570 ins_pipe( pipe_slow ); 4571 %} 4572 4573 // Load Effective Address 4574 instruct leaP8(rRegP dst, indOffset8 mem) 4575 %{ 4576 match(Set dst mem); 4577 4578 ins_cost(110); // XXX 4579 format %{ "leaq $dst, $mem\t# ptr 8" %} 4580 ins_encode %{ 4581 __ leaq($dst$$Register, $mem$$Address); 4582 %} 4583 ins_pipe(ialu_reg_reg_fat); 4584 %} 4585 4586 instruct leaP32(rRegP dst, indOffset32 mem) 4587 %{ 4588 match(Set dst mem); 4589 4590 ins_cost(110); 4591 format %{ "leaq $dst, $mem\t# ptr 32" %} 4592 ins_encode %{ 4593 __ leaq($dst$$Register, $mem$$Address); 4594 %} 4595 ins_pipe(ialu_reg_reg_fat); 4596 %} 4597 4598 instruct leaPIdxOff(rRegP dst, indIndexOffset mem) 4599 %{ 4600 match(Set dst mem); 4601 4602 ins_cost(110); 4603 format %{ "leaq $dst, $mem\t# ptr idxoff" %} 4604 ins_encode %{ 4605 __ leaq($dst$$Register, $mem$$Address); 4606 %} 4607 ins_pipe(ialu_reg_reg_fat); 4608 %} 4609 4610 instruct leaPIdxScale(rRegP dst, indIndexScale mem) 4611 %{ 4612 match(Set dst mem); 4613 4614 ins_cost(110); 4615 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 4616 ins_encode %{ 4617 __ leaq($dst$$Register, $mem$$Address); 4618 %} 4619 ins_pipe(ialu_reg_reg_fat); 4620 %} 4621 4622 instruct leaPPosIdxScale(rRegP dst, indPosIndexScale mem) 4623 %{ 4624 match(Set dst mem); 4625 4626 ins_cost(110); 4627 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 4628 ins_encode %{ 4629 __ leaq($dst$$Register, $mem$$Address); 4630 %} 4631 ins_pipe(ialu_reg_reg_fat); 4632 %} 4633 4634 instruct leaPIdxScaleOff(rRegP dst, indIndexScaleOffset mem) 4635 %{ 4636 match(Set dst mem); 4637 4638 ins_cost(110); 4639 format %{ "leaq $dst, $mem\t# ptr idxscaleoff" %} 4640 ins_encode %{ 4641 __ leaq($dst$$Register, $mem$$Address); 4642 %} 4643 ins_pipe(ialu_reg_reg_fat); 4644 %} 4645 4646 instruct leaPPosIdxOff(rRegP dst, indPosIndexOffset mem) 4647 %{ 4648 match(Set dst mem); 4649 4650 ins_cost(110); 4651 format %{ "leaq $dst, $mem\t# ptr posidxoff" %} 4652 ins_encode %{ 4653 __ leaq($dst$$Register, $mem$$Address); 4654 %} 4655 ins_pipe(ialu_reg_reg_fat); 4656 %} 4657 4658 instruct leaPPosIdxScaleOff(rRegP dst, indPosIndexScaleOffset mem) 4659 %{ 4660 match(Set dst mem); 4661 4662 ins_cost(110); 4663 format %{ "leaq $dst, $mem\t# ptr posidxscaleoff" %} 4664 ins_encode %{ 4665 __ leaq($dst$$Register, $mem$$Address); 4666 %} 4667 ins_pipe(ialu_reg_reg_fat); 4668 %} 4669 4670 // Load Effective Address which uses Narrow (32-bits) oop 4671 instruct leaPCompressedOopOffset(rRegP dst, indCompressedOopOffset mem) 4672 %{ 4673 predicate(UseCompressedOops && (CompressedOops::shift() != 0)); 4674 match(Set dst mem); 4675 4676 ins_cost(110); 4677 format %{ "leaq $dst, $mem\t# ptr compressedoopoff32" %} 4678 ins_encode %{ 4679 __ leaq($dst$$Register, $mem$$Address); 4680 %} 4681 ins_pipe(ialu_reg_reg_fat); 4682 %} 4683 4684 instruct leaP8Narrow(rRegP dst, indOffset8Narrow mem) 4685 %{ 4686 predicate(CompressedOops::shift() == 0); 4687 match(Set dst mem); 4688 4689 ins_cost(110); // XXX 4690 format %{ "leaq $dst, $mem\t# ptr off8narrow" %} 4691 ins_encode %{ 4692 __ leaq($dst$$Register, $mem$$Address); 4693 %} 4694 ins_pipe(ialu_reg_reg_fat); 4695 %} 4696 4697 instruct leaP32Narrow(rRegP dst, indOffset32Narrow mem) 4698 %{ 4699 predicate(CompressedOops::shift() == 0); 4700 match(Set dst mem); 4701 4702 ins_cost(110); 4703 format %{ "leaq $dst, $mem\t# ptr off32narrow" %} 4704 ins_encode %{ 4705 __ leaq($dst$$Register, $mem$$Address); 4706 %} 4707 ins_pipe(ialu_reg_reg_fat); 4708 %} 4709 4710 instruct leaPIdxOffNarrow(rRegP dst, indIndexOffsetNarrow mem) 4711 %{ 4712 predicate(CompressedOops::shift() == 0); 4713 match(Set dst mem); 4714 4715 ins_cost(110); 4716 format %{ "leaq $dst, $mem\t# ptr idxoffnarrow" %} 4717 ins_encode %{ 4718 __ leaq($dst$$Register, $mem$$Address); 4719 %} 4720 ins_pipe(ialu_reg_reg_fat); 4721 %} 4722 4723 instruct leaPIdxScaleNarrow(rRegP dst, indIndexScaleNarrow mem) 4724 %{ 4725 predicate(CompressedOops::shift() == 0); 4726 match(Set dst mem); 4727 4728 ins_cost(110); 4729 format %{ "leaq $dst, $mem\t# ptr idxscalenarrow" %} 4730 ins_encode %{ 4731 __ leaq($dst$$Register, $mem$$Address); 4732 %} 4733 ins_pipe(ialu_reg_reg_fat); 4734 %} 4735 4736 instruct leaPIdxScaleOffNarrow(rRegP dst, indIndexScaleOffsetNarrow mem) 4737 %{ 4738 predicate(CompressedOops::shift() == 0); 4739 match(Set dst mem); 4740 4741 ins_cost(110); 4742 format %{ "leaq $dst, $mem\t# ptr idxscaleoffnarrow" %} 4743 ins_encode %{ 4744 __ leaq($dst$$Register, $mem$$Address); 4745 %} 4746 ins_pipe(ialu_reg_reg_fat); 4747 %} 4748 4749 instruct leaPPosIdxOffNarrow(rRegP dst, indPosIndexOffsetNarrow mem) 4750 %{ 4751 predicate(CompressedOops::shift() == 0); 4752 match(Set dst mem); 4753 4754 ins_cost(110); 4755 format %{ "leaq $dst, $mem\t# ptr posidxoffnarrow" %} 4756 ins_encode %{ 4757 __ leaq($dst$$Register, $mem$$Address); 4758 %} 4759 ins_pipe(ialu_reg_reg_fat); 4760 %} 4761 4762 instruct leaPPosIdxScaleOffNarrow(rRegP dst, indPosIndexScaleOffsetNarrow mem) 4763 %{ 4764 predicate(CompressedOops::shift() == 0); 4765 match(Set dst mem); 4766 4767 ins_cost(110); 4768 format %{ "leaq $dst, $mem\t# ptr posidxscaleoffnarrow" %} 4769 ins_encode %{ 4770 __ leaq($dst$$Register, $mem$$Address); 4771 %} 4772 ins_pipe(ialu_reg_reg_fat); 4773 %} 4774 4775 instruct loadConI(rRegI dst, immI src) 4776 %{ 4777 match(Set dst src); 4778 4779 format %{ "movl $dst, $src\t# int" %} 4780 ins_encode %{ 4781 __ movl($dst$$Register, $src$$constant); 4782 %} 4783 ins_pipe(ialu_reg_fat); // XXX 4784 %} 4785 4786 instruct loadConI0(rRegI dst, immI_0 src, rFlagsReg cr) 4787 %{ 4788 match(Set dst src); 4789 effect(KILL cr); 4790 4791 ins_cost(50); 4792 format %{ "xorl $dst, $dst\t# int" %} 4793 ins_encode %{ 4794 __ xorl($dst$$Register, $dst$$Register); 4795 %} 4796 ins_pipe(ialu_reg); 4797 %} 4798 4799 instruct loadConL(rRegL dst, immL src) 4800 %{ 4801 match(Set dst src); 4802 4803 ins_cost(150); 4804 format %{ "movq $dst, $src\t# long" %} 4805 ins_encode %{ 4806 __ mov64($dst$$Register, $src$$constant); 4807 %} 4808 ins_pipe(ialu_reg); 4809 %} 4810 4811 instruct loadConL0(rRegL dst, immL0 src, rFlagsReg cr) 4812 %{ 4813 match(Set dst src); 4814 effect(KILL cr); 4815 4816 ins_cost(50); 4817 format %{ "xorl $dst, $dst\t# long" %} 4818 ins_encode %{ 4819 __ xorl($dst$$Register, $dst$$Register); 4820 %} 4821 ins_pipe(ialu_reg); // XXX 4822 %} 4823 4824 instruct loadConUL32(rRegL dst, immUL32 src) 4825 %{ 4826 match(Set dst src); 4827 4828 ins_cost(60); 4829 format %{ "movl $dst, $src\t# long (unsigned 32-bit)" %} 4830 ins_encode %{ 4831 __ movl($dst$$Register, $src$$constant); 4832 %} 4833 ins_pipe(ialu_reg); 4834 %} 4835 4836 instruct loadConL32(rRegL dst, immL32 src) 4837 %{ 4838 match(Set dst src); 4839 4840 ins_cost(70); 4841 format %{ "movq $dst, $src\t# long (32-bit)" %} 4842 ins_encode %{ 4843 __ movq($dst$$Register, $src$$constant); 4844 %} 4845 ins_pipe(ialu_reg); 4846 %} 4847 4848 instruct loadConP(rRegP dst, immP con) %{ 4849 match(Set dst con); 4850 4851 format %{ "movq $dst, $con\t# ptr" %} 4852 ins_encode %{ 4853 __ mov64($dst$$Register, $con$$constant, $con->constant_reloc(), RELOC_IMM64); 4854 %} 4855 ins_pipe(ialu_reg_fat); // XXX 4856 %} 4857 4858 instruct loadConP0(rRegP dst, immP0 src, rFlagsReg cr) 4859 %{ 4860 match(Set dst src); 4861 effect(KILL cr); 4862 4863 ins_cost(50); 4864 format %{ "xorl $dst, $dst\t# ptr" %} 4865 ins_encode %{ 4866 __ xorl($dst$$Register, $dst$$Register); 4867 %} 4868 ins_pipe(ialu_reg); 4869 %} 4870 4871 instruct loadConP31(rRegP dst, immP31 src, rFlagsReg cr) 4872 %{ 4873 match(Set dst src); 4874 effect(KILL cr); 4875 4876 ins_cost(60); 4877 format %{ "movl $dst, $src\t# ptr (positive 32-bit)" %} 4878 ins_encode %{ 4879 __ movl($dst$$Register, $src$$constant); 4880 %} 4881 ins_pipe(ialu_reg); 4882 %} 4883 4884 instruct loadConF(regF dst, immF con) %{ 4885 match(Set dst con); 4886 ins_cost(125); 4887 format %{ "movss $dst, [$constantaddress]\t# load from constant table: float=$con" %} 4888 ins_encode %{ 4889 __ movflt($dst$$XMMRegister, $constantaddress($con)); 4890 %} 4891 ins_pipe(pipe_slow); 4892 %} 4893 4894 instruct loadConH(regF dst, immH con) %{ 4895 match(Set dst con); 4896 ins_cost(125); 4897 format %{ "movss $dst, [$constantaddress]\t# load from constant table: halffloat=$con" %} 4898 ins_encode %{ 4899 __ movflt($dst$$XMMRegister, $constantaddress($con)); 4900 %} 4901 ins_pipe(pipe_slow); 4902 %} 4903 4904 instruct loadConN0(rRegN dst, immN0 src, rFlagsReg cr) %{ 4905 match(Set dst src); 4906 effect(KILL cr); 4907 format %{ "xorq $dst, $src\t# compressed null pointer" %} 4908 ins_encode %{ 4909 __ xorq($dst$$Register, $dst$$Register); 4910 %} 4911 ins_pipe(ialu_reg); 4912 %} 4913 4914 instruct loadConN(rRegN dst, immN src) %{ 4915 match(Set dst src); 4916 4917 ins_cost(125); 4918 format %{ "movl $dst, $src\t# compressed ptr" %} 4919 ins_encode %{ 4920 address con = (address)$src$$constant; 4921 if (con == nullptr) { 4922 ShouldNotReachHere(); 4923 } else { 4924 __ set_narrow_oop($dst$$Register, (jobject)$src$$constant); 4925 } 4926 %} 4927 ins_pipe(ialu_reg_fat); // XXX 4928 %} 4929 4930 instruct loadConNKlass(rRegN dst, immNKlass src) %{ 4931 match(Set dst src); 4932 4933 ins_cost(125); 4934 format %{ "movl $dst, $src\t# compressed klass ptr" %} 4935 ins_encode %{ 4936 address con = (address)$src$$constant; 4937 if (con == nullptr) { 4938 ShouldNotReachHere(); 4939 } else { 4940 __ set_narrow_klass($dst$$Register, (Klass*)$src$$constant); 4941 } 4942 %} 4943 ins_pipe(ialu_reg_fat); // XXX 4944 %} 4945 4946 instruct loadConF0(regF dst, immF0 src) 4947 %{ 4948 match(Set dst src); 4949 ins_cost(100); 4950 4951 format %{ "xorps $dst, $dst\t# float 0.0" %} 4952 ins_encode %{ 4953 __ xorps($dst$$XMMRegister, $dst$$XMMRegister); 4954 %} 4955 ins_pipe(pipe_slow); 4956 %} 4957 4958 // Use the same format since predicate() can not be used here. 4959 instruct loadConD(regD dst, immD con) %{ 4960 match(Set dst con); 4961 ins_cost(125); 4962 format %{ "movsd $dst, [$constantaddress]\t# load from constant table: double=$con" %} 4963 ins_encode %{ 4964 __ movdbl($dst$$XMMRegister, $constantaddress($con)); 4965 %} 4966 ins_pipe(pipe_slow); 4967 %} 4968 4969 instruct loadConD0(regD dst, immD0 src) 4970 %{ 4971 match(Set dst src); 4972 ins_cost(100); 4973 4974 format %{ "xorpd $dst, $dst\t# double 0.0" %} 4975 ins_encode %{ 4976 __ xorpd($dst$$XMMRegister, $dst$$XMMRegister); 4977 %} 4978 ins_pipe(pipe_slow); 4979 %} 4980 4981 instruct loadSSI(rRegI dst, stackSlotI src) 4982 %{ 4983 match(Set dst src); 4984 4985 ins_cost(125); 4986 format %{ "movl $dst, $src\t# int stk" %} 4987 ins_encode %{ 4988 __ movl($dst$$Register, $src$$Address); 4989 %} 4990 ins_pipe(ialu_reg_mem); 4991 %} 4992 4993 instruct loadSSL(rRegL dst, stackSlotL src) 4994 %{ 4995 match(Set dst src); 4996 4997 ins_cost(125); 4998 format %{ "movq $dst, $src\t# long stk" %} 4999 ins_encode %{ 5000 __ movq($dst$$Register, $src$$Address); 5001 %} 5002 ins_pipe(ialu_reg_mem); 5003 %} 5004 5005 instruct loadSSP(rRegP dst, stackSlotP src) 5006 %{ 5007 match(Set dst src); 5008 5009 ins_cost(125); 5010 format %{ "movq $dst, $src\t# ptr stk" %} 5011 ins_encode %{ 5012 __ movq($dst$$Register, $src$$Address); 5013 %} 5014 ins_pipe(ialu_reg_mem); 5015 %} 5016 5017 instruct loadSSF(regF dst, stackSlotF src) 5018 %{ 5019 match(Set dst src); 5020 5021 ins_cost(125); 5022 format %{ "movss $dst, $src\t# float stk" %} 5023 ins_encode %{ 5024 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 5025 %} 5026 ins_pipe(pipe_slow); // XXX 5027 %} 5028 5029 // Use the same format since predicate() can not be used here. 5030 instruct loadSSD(regD dst, stackSlotD src) 5031 %{ 5032 match(Set dst src); 5033 5034 ins_cost(125); 5035 format %{ "movsd $dst, $src\t# double stk" %} 5036 ins_encode %{ 5037 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 5038 %} 5039 ins_pipe(pipe_slow); // XXX 5040 %} 5041 5042 // Prefetch instructions for allocation. 5043 // Must be safe to execute with invalid address (cannot fault). 5044 5045 instruct prefetchAlloc( memory mem ) %{ 5046 predicate(AllocatePrefetchInstr==3); 5047 match(PrefetchAllocation mem); 5048 ins_cost(125); 5049 5050 format %{ "PREFETCHW $mem\t# Prefetch allocation into level 1 cache and mark modified" %} 5051 ins_encode %{ 5052 __ prefetchw($mem$$Address); 5053 %} 5054 ins_pipe(ialu_mem); 5055 %} 5056 5057 instruct prefetchAllocNTA( memory mem ) %{ 5058 predicate(AllocatePrefetchInstr==0); 5059 match(PrefetchAllocation mem); 5060 ins_cost(125); 5061 5062 format %{ "PREFETCHNTA $mem\t# Prefetch allocation to non-temporal cache for write" %} 5063 ins_encode %{ 5064 __ prefetchnta($mem$$Address); 5065 %} 5066 ins_pipe(ialu_mem); 5067 %} 5068 5069 instruct prefetchAllocT0( memory mem ) %{ 5070 predicate(AllocatePrefetchInstr==1); 5071 match(PrefetchAllocation mem); 5072 ins_cost(125); 5073 5074 format %{ "PREFETCHT0 $mem\t# Prefetch allocation to level 1 and 2 caches for write" %} 5075 ins_encode %{ 5076 __ prefetcht0($mem$$Address); 5077 %} 5078 ins_pipe(ialu_mem); 5079 %} 5080 5081 instruct prefetchAllocT2( memory mem ) %{ 5082 predicate(AllocatePrefetchInstr==2); 5083 match(PrefetchAllocation mem); 5084 ins_cost(125); 5085 5086 format %{ "PREFETCHT2 $mem\t# Prefetch allocation to level 2 cache for write" %} 5087 ins_encode %{ 5088 __ prefetcht2($mem$$Address); 5089 %} 5090 ins_pipe(ialu_mem); 5091 %} 5092 5093 //----------Store Instructions------------------------------------------------- 5094 5095 // Store Byte 5096 instruct storeB(memory mem, rRegI src) 5097 %{ 5098 match(Set mem (StoreB mem src)); 5099 5100 ins_cost(125); // XXX 5101 format %{ "movb $mem, $src\t# byte" %} 5102 ins_encode %{ 5103 __ movb($mem$$Address, $src$$Register); 5104 %} 5105 ins_pipe(ialu_mem_reg); 5106 %} 5107 5108 // Store Char/Short 5109 instruct storeC(memory mem, rRegI src) 5110 %{ 5111 match(Set mem (StoreC mem src)); 5112 5113 ins_cost(125); // XXX 5114 format %{ "movw $mem, $src\t# char/short" %} 5115 ins_encode %{ 5116 __ movw($mem$$Address, $src$$Register); 5117 %} 5118 ins_pipe(ialu_mem_reg); 5119 %} 5120 5121 // Store Integer 5122 instruct storeI(memory mem, rRegI src) 5123 %{ 5124 match(Set mem (StoreI mem src)); 5125 5126 ins_cost(125); // XXX 5127 format %{ "movl $mem, $src\t# int" %} 5128 ins_encode %{ 5129 __ movl($mem$$Address, $src$$Register); 5130 %} 5131 ins_pipe(ialu_mem_reg); 5132 %} 5133 5134 // Store Long 5135 instruct storeL(memory mem, rRegL src) 5136 %{ 5137 match(Set mem (StoreL mem src)); 5138 5139 ins_cost(125); // XXX 5140 format %{ "movq $mem, $src\t# long" %} 5141 ins_encode %{ 5142 __ movq($mem$$Address, $src$$Register); 5143 %} 5144 ins_pipe(ialu_mem_reg); // XXX 5145 %} 5146 5147 // Store Pointer 5148 instruct storeP(memory mem, any_RegP src) 5149 %{ 5150 predicate(n->as_Store()->barrier_data() == 0); 5151 match(Set mem (StoreP mem src)); 5152 5153 ins_cost(125); // XXX 5154 format %{ "movq $mem, $src\t# ptr" %} 5155 ins_encode %{ 5156 __ movq($mem$$Address, $src$$Register); 5157 %} 5158 ins_pipe(ialu_mem_reg); 5159 %} 5160 5161 instruct storeImmP0(memory mem, immP0 zero) 5162 %{ 5163 predicate(UseCompressedOops && (CompressedOops::base() == nullptr) && n->as_Store()->barrier_data() == 0); 5164 match(Set mem (StoreP mem zero)); 5165 5166 ins_cost(125); // XXX 5167 format %{ "movq $mem, R12\t# ptr (R12_heapbase==0)" %} 5168 ins_encode %{ 5169 __ movq($mem$$Address, r12); 5170 %} 5171 ins_pipe(ialu_mem_reg); 5172 %} 5173 5174 // Store Null Pointer, mark word, or other simple pointer constant. 5175 instruct storeImmP(memory mem, immP31 src) 5176 %{ 5177 predicate(n->as_Store()->barrier_data() == 0); 5178 match(Set mem (StoreP mem src)); 5179 5180 ins_cost(150); // XXX 5181 format %{ "movq $mem, $src\t# ptr" %} 5182 ins_encode %{ 5183 __ movq($mem$$Address, $src$$constant); 5184 %} 5185 ins_pipe(ialu_mem_imm); 5186 %} 5187 5188 // Store Compressed Pointer 5189 instruct storeN(memory mem, rRegN src) 5190 %{ 5191 predicate(n->as_Store()->barrier_data() == 0); 5192 match(Set mem (StoreN mem src)); 5193 5194 ins_cost(125); // XXX 5195 format %{ "movl $mem, $src\t# compressed ptr" %} 5196 ins_encode %{ 5197 __ movl($mem$$Address, $src$$Register); 5198 %} 5199 ins_pipe(ialu_mem_reg); 5200 %} 5201 5202 instruct storeNKlass(memory mem, rRegN src) 5203 %{ 5204 match(Set mem (StoreNKlass mem src)); 5205 5206 ins_cost(125); // XXX 5207 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5208 ins_encode %{ 5209 __ movl($mem$$Address, $src$$Register); 5210 %} 5211 ins_pipe(ialu_mem_reg); 5212 %} 5213 5214 instruct storeImmN0(memory mem, immN0 zero) 5215 %{ 5216 predicate(CompressedOops::base() == nullptr && n->as_Store()->barrier_data() == 0); 5217 match(Set mem (StoreN mem zero)); 5218 5219 ins_cost(125); // XXX 5220 format %{ "movl $mem, R12\t# compressed ptr (R12_heapbase==0)" %} 5221 ins_encode %{ 5222 __ movl($mem$$Address, r12); 5223 %} 5224 ins_pipe(ialu_mem_reg); 5225 %} 5226 5227 instruct storeImmN(memory mem, immN src) 5228 %{ 5229 predicate(n->as_Store()->barrier_data() == 0); 5230 match(Set mem (StoreN mem src)); 5231 5232 ins_cost(150); // XXX 5233 format %{ "movl $mem, $src\t# compressed ptr" %} 5234 ins_encode %{ 5235 address con = (address)$src$$constant; 5236 if (con == nullptr) { 5237 __ movl($mem$$Address, 0); 5238 } else { 5239 __ set_narrow_oop($mem$$Address, (jobject)$src$$constant); 5240 } 5241 %} 5242 ins_pipe(ialu_mem_imm); 5243 %} 5244 5245 instruct storeImmNKlass(memory mem, immNKlass src) 5246 %{ 5247 match(Set mem (StoreNKlass mem src)); 5248 5249 ins_cost(150); // XXX 5250 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5251 ins_encode %{ 5252 __ set_narrow_klass($mem$$Address, (Klass*)$src$$constant); 5253 %} 5254 ins_pipe(ialu_mem_imm); 5255 %} 5256 5257 // Store Integer Immediate 5258 instruct storeImmI0(memory mem, immI_0 zero) 5259 %{ 5260 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5261 match(Set mem (StoreI mem zero)); 5262 5263 ins_cost(125); // XXX 5264 format %{ "movl $mem, R12\t# int (R12_heapbase==0)" %} 5265 ins_encode %{ 5266 __ movl($mem$$Address, r12); 5267 %} 5268 ins_pipe(ialu_mem_reg); 5269 %} 5270 5271 instruct storeImmI(memory mem, immI src) 5272 %{ 5273 match(Set mem (StoreI mem src)); 5274 5275 ins_cost(150); 5276 format %{ "movl $mem, $src\t# int" %} 5277 ins_encode %{ 5278 __ movl($mem$$Address, $src$$constant); 5279 %} 5280 ins_pipe(ialu_mem_imm); 5281 %} 5282 5283 // Store Long Immediate 5284 instruct storeImmL0(memory mem, immL0 zero) 5285 %{ 5286 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5287 match(Set mem (StoreL mem zero)); 5288 5289 ins_cost(125); // XXX 5290 format %{ "movq $mem, R12\t# long (R12_heapbase==0)" %} 5291 ins_encode %{ 5292 __ movq($mem$$Address, r12); 5293 %} 5294 ins_pipe(ialu_mem_reg); 5295 %} 5296 5297 instruct storeImmL(memory mem, immL32 src) 5298 %{ 5299 match(Set mem (StoreL mem src)); 5300 5301 ins_cost(150); 5302 format %{ "movq $mem, $src\t# long" %} 5303 ins_encode %{ 5304 __ movq($mem$$Address, $src$$constant); 5305 %} 5306 ins_pipe(ialu_mem_imm); 5307 %} 5308 5309 // Store Short/Char Immediate 5310 instruct storeImmC0(memory mem, immI_0 zero) 5311 %{ 5312 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5313 match(Set mem (StoreC mem zero)); 5314 5315 ins_cost(125); // XXX 5316 format %{ "movw $mem, R12\t# short/char (R12_heapbase==0)" %} 5317 ins_encode %{ 5318 __ movw($mem$$Address, r12); 5319 %} 5320 ins_pipe(ialu_mem_reg); 5321 %} 5322 5323 instruct storeImmI16(memory mem, immI16 src) 5324 %{ 5325 predicate(UseStoreImmI16); 5326 match(Set mem (StoreC mem src)); 5327 5328 ins_cost(150); 5329 format %{ "movw $mem, $src\t# short/char" %} 5330 ins_encode %{ 5331 __ movw($mem$$Address, $src$$constant); 5332 %} 5333 ins_pipe(ialu_mem_imm); 5334 %} 5335 5336 // Store Byte Immediate 5337 instruct storeImmB0(memory mem, immI_0 zero) 5338 %{ 5339 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5340 match(Set mem (StoreB mem zero)); 5341 5342 ins_cost(125); // XXX 5343 format %{ "movb $mem, R12\t# short/char (R12_heapbase==0)" %} 5344 ins_encode %{ 5345 __ movb($mem$$Address, r12); 5346 %} 5347 ins_pipe(ialu_mem_reg); 5348 %} 5349 5350 instruct storeImmB(memory mem, immI8 src) 5351 %{ 5352 match(Set mem (StoreB mem src)); 5353 5354 ins_cost(150); // XXX 5355 format %{ "movb $mem, $src\t# byte" %} 5356 ins_encode %{ 5357 __ movb($mem$$Address, $src$$constant); 5358 %} 5359 ins_pipe(ialu_mem_imm); 5360 %} 5361 5362 // Store Float 5363 instruct storeF(memory mem, regF src) 5364 %{ 5365 match(Set mem (StoreF mem src)); 5366 5367 ins_cost(95); // XXX 5368 format %{ "movss $mem, $src\t# float" %} 5369 ins_encode %{ 5370 __ movflt($mem$$Address, $src$$XMMRegister); 5371 %} 5372 ins_pipe(pipe_slow); // XXX 5373 %} 5374 5375 // Store immediate Float value (it is faster than store from XMM register) 5376 instruct storeF0(memory mem, immF0 zero) 5377 %{ 5378 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5379 match(Set mem (StoreF mem zero)); 5380 5381 ins_cost(25); // XXX 5382 format %{ "movl $mem, R12\t# float 0. (R12_heapbase==0)" %} 5383 ins_encode %{ 5384 __ movl($mem$$Address, r12); 5385 %} 5386 ins_pipe(ialu_mem_reg); 5387 %} 5388 5389 instruct storeF_imm(memory mem, immF src) 5390 %{ 5391 match(Set mem (StoreF mem src)); 5392 5393 ins_cost(50); 5394 format %{ "movl $mem, $src\t# float" %} 5395 ins_encode %{ 5396 __ movl($mem$$Address, jint_cast($src$$constant)); 5397 %} 5398 ins_pipe(ialu_mem_imm); 5399 %} 5400 5401 // Store Double 5402 instruct storeD(memory mem, regD src) 5403 %{ 5404 match(Set mem (StoreD mem src)); 5405 5406 ins_cost(95); // XXX 5407 format %{ "movsd $mem, $src\t# double" %} 5408 ins_encode %{ 5409 __ movdbl($mem$$Address, $src$$XMMRegister); 5410 %} 5411 ins_pipe(pipe_slow); // XXX 5412 %} 5413 5414 // Store immediate double 0.0 (it is faster than store from XMM register) 5415 instruct storeD0_imm(memory mem, immD0 src) 5416 %{ 5417 predicate(!UseCompressedOops || (CompressedOops::base() != nullptr)); 5418 match(Set mem (StoreD mem src)); 5419 5420 ins_cost(50); 5421 format %{ "movq $mem, $src\t# double 0." %} 5422 ins_encode %{ 5423 __ movq($mem$$Address, $src$$constant); 5424 %} 5425 ins_pipe(ialu_mem_imm); 5426 %} 5427 5428 instruct storeD0(memory mem, immD0 zero) 5429 %{ 5430 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5431 match(Set mem (StoreD mem zero)); 5432 5433 ins_cost(25); // XXX 5434 format %{ "movq $mem, R12\t# double 0. (R12_heapbase==0)" %} 5435 ins_encode %{ 5436 __ movq($mem$$Address, r12); 5437 %} 5438 ins_pipe(ialu_mem_reg); 5439 %} 5440 5441 instruct storeSSI(stackSlotI dst, rRegI src) 5442 %{ 5443 match(Set dst src); 5444 5445 ins_cost(100); 5446 format %{ "movl $dst, $src\t# int stk" %} 5447 ins_encode %{ 5448 __ movl($dst$$Address, $src$$Register); 5449 %} 5450 ins_pipe( ialu_mem_reg ); 5451 %} 5452 5453 instruct storeSSL(stackSlotL dst, rRegL src) 5454 %{ 5455 match(Set dst src); 5456 5457 ins_cost(100); 5458 format %{ "movq $dst, $src\t# long stk" %} 5459 ins_encode %{ 5460 __ movq($dst$$Address, $src$$Register); 5461 %} 5462 ins_pipe(ialu_mem_reg); 5463 %} 5464 5465 instruct storeSSP(stackSlotP dst, rRegP src) 5466 %{ 5467 match(Set dst src); 5468 5469 ins_cost(100); 5470 format %{ "movq $dst, $src\t# ptr stk" %} 5471 ins_encode %{ 5472 __ movq($dst$$Address, $src$$Register); 5473 %} 5474 ins_pipe(ialu_mem_reg); 5475 %} 5476 5477 instruct storeSSF(stackSlotF dst, regF src) 5478 %{ 5479 match(Set dst src); 5480 5481 ins_cost(95); // XXX 5482 format %{ "movss $dst, $src\t# float stk" %} 5483 ins_encode %{ 5484 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 5485 %} 5486 ins_pipe(pipe_slow); // XXX 5487 %} 5488 5489 instruct storeSSD(stackSlotD dst, regD src) 5490 %{ 5491 match(Set dst src); 5492 5493 ins_cost(95); // XXX 5494 format %{ "movsd $dst, $src\t# double stk" %} 5495 ins_encode %{ 5496 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 5497 %} 5498 ins_pipe(pipe_slow); // XXX 5499 %} 5500 5501 instruct cacheWB(indirect addr) 5502 %{ 5503 predicate(VM_Version::supports_data_cache_line_flush()); 5504 match(CacheWB addr); 5505 5506 ins_cost(100); 5507 format %{"cache wb $addr" %} 5508 ins_encode %{ 5509 assert($addr->index_position() < 0, "should be"); 5510 assert($addr$$disp == 0, "should be"); 5511 __ cache_wb(Address($addr$$base$$Register, 0)); 5512 %} 5513 ins_pipe(pipe_slow); // XXX 5514 %} 5515 5516 instruct cacheWBPreSync() 5517 %{ 5518 predicate(VM_Version::supports_data_cache_line_flush()); 5519 match(CacheWBPreSync); 5520 5521 ins_cost(100); 5522 format %{"cache wb presync" %} 5523 ins_encode %{ 5524 __ cache_wbsync(true); 5525 %} 5526 ins_pipe(pipe_slow); // XXX 5527 %} 5528 5529 instruct cacheWBPostSync() 5530 %{ 5531 predicate(VM_Version::supports_data_cache_line_flush()); 5532 match(CacheWBPostSync); 5533 5534 ins_cost(100); 5535 format %{"cache wb postsync" %} 5536 ins_encode %{ 5537 __ cache_wbsync(false); 5538 %} 5539 ins_pipe(pipe_slow); // XXX 5540 %} 5541 5542 //----------BSWAP Instructions------------------------------------------------- 5543 instruct bytes_reverse_int(rRegI dst) %{ 5544 match(Set dst (ReverseBytesI dst)); 5545 5546 format %{ "bswapl $dst" %} 5547 ins_encode %{ 5548 __ bswapl($dst$$Register); 5549 %} 5550 ins_pipe( ialu_reg ); 5551 %} 5552 5553 instruct bytes_reverse_long(rRegL dst) %{ 5554 match(Set dst (ReverseBytesL dst)); 5555 5556 format %{ "bswapq $dst" %} 5557 ins_encode %{ 5558 __ bswapq($dst$$Register); 5559 %} 5560 ins_pipe( ialu_reg); 5561 %} 5562 5563 instruct bytes_reverse_unsigned_short(rRegI dst, rFlagsReg cr) %{ 5564 match(Set dst (ReverseBytesUS dst)); 5565 effect(KILL cr); 5566 5567 format %{ "bswapl $dst\n\t" 5568 "shrl $dst,16\n\t" %} 5569 ins_encode %{ 5570 __ bswapl($dst$$Register); 5571 __ shrl($dst$$Register, 16); 5572 %} 5573 ins_pipe( ialu_reg ); 5574 %} 5575 5576 instruct bytes_reverse_short(rRegI dst, rFlagsReg cr) %{ 5577 match(Set dst (ReverseBytesS dst)); 5578 effect(KILL cr); 5579 5580 format %{ "bswapl $dst\n\t" 5581 "sar $dst,16\n\t" %} 5582 ins_encode %{ 5583 __ bswapl($dst$$Register); 5584 __ sarl($dst$$Register, 16); 5585 %} 5586 ins_pipe( ialu_reg ); 5587 %} 5588 5589 //---------- Zeros Count Instructions ------------------------------------------ 5590 5591 instruct countLeadingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 5592 predicate(UseCountLeadingZerosInstruction); 5593 match(Set dst (CountLeadingZerosI src)); 5594 effect(KILL cr); 5595 5596 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 5597 ins_encode %{ 5598 __ lzcntl($dst$$Register, $src$$Register); 5599 %} 5600 ins_pipe(ialu_reg); 5601 %} 5602 5603 instruct countLeadingZerosI_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5604 predicate(UseCountLeadingZerosInstruction); 5605 match(Set dst (CountLeadingZerosI (LoadI src))); 5606 effect(KILL cr); 5607 ins_cost(175); 5608 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 5609 ins_encode %{ 5610 __ lzcntl($dst$$Register, $src$$Address); 5611 %} 5612 ins_pipe(ialu_reg_mem); 5613 %} 5614 5615 instruct countLeadingZerosI_bsr(rRegI dst, rRegI src, rFlagsReg cr) %{ 5616 predicate(!UseCountLeadingZerosInstruction); 5617 match(Set dst (CountLeadingZerosI src)); 5618 effect(KILL cr); 5619 5620 format %{ "bsrl $dst, $src\t# count leading zeros (int)\n\t" 5621 "jnz skip\n\t" 5622 "movl $dst, -1\n" 5623 "skip:\n\t" 5624 "negl $dst\n\t" 5625 "addl $dst, 31" %} 5626 ins_encode %{ 5627 Register Rdst = $dst$$Register; 5628 Register Rsrc = $src$$Register; 5629 Label skip; 5630 __ bsrl(Rdst, Rsrc); 5631 __ jccb(Assembler::notZero, skip); 5632 __ movl(Rdst, -1); 5633 __ bind(skip); 5634 __ negl(Rdst); 5635 __ addl(Rdst, BitsPerInt - 1); 5636 %} 5637 ins_pipe(ialu_reg); 5638 %} 5639 5640 instruct countLeadingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 5641 predicate(UseCountLeadingZerosInstruction); 5642 match(Set dst (CountLeadingZerosL src)); 5643 effect(KILL cr); 5644 5645 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 5646 ins_encode %{ 5647 __ lzcntq($dst$$Register, $src$$Register); 5648 %} 5649 ins_pipe(ialu_reg); 5650 %} 5651 5652 instruct countLeadingZerosL_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5653 predicate(UseCountLeadingZerosInstruction); 5654 match(Set dst (CountLeadingZerosL (LoadL src))); 5655 effect(KILL cr); 5656 ins_cost(175); 5657 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 5658 ins_encode %{ 5659 __ lzcntq($dst$$Register, $src$$Address); 5660 %} 5661 ins_pipe(ialu_reg_mem); 5662 %} 5663 5664 instruct countLeadingZerosL_bsr(rRegI dst, rRegL src, rFlagsReg cr) %{ 5665 predicate(!UseCountLeadingZerosInstruction); 5666 match(Set dst (CountLeadingZerosL src)); 5667 effect(KILL cr); 5668 5669 format %{ "bsrq $dst, $src\t# count leading zeros (long)\n\t" 5670 "jnz skip\n\t" 5671 "movl $dst, -1\n" 5672 "skip:\n\t" 5673 "negl $dst\n\t" 5674 "addl $dst, 63" %} 5675 ins_encode %{ 5676 Register Rdst = $dst$$Register; 5677 Register Rsrc = $src$$Register; 5678 Label skip; 5679 __ bsrq(Rdst, Rsrc); 5680 __ jccb(Assembler::notZero, skip); 5681 __ movl(Rdst, -1); 5682 __ bind(skip); 5683 __ negl(Rdst); 5684 __ addl(Rdst, BitsPerLong - 1); 5685 %} 5686 ins_pipe(ialu_reg); 5687 %} 5688 5689 instruct countTrailingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 5690 predicate(UseCountTrailingZerosInstruction); 5691 match(Set dst (CountTrailingZerosI src)); 5692 effect(KILL cr); 5693 5694 format %{ "tzcntl $dst, $src\t# count trailing zeros (int)" %} 5695 ins_encode %{ 5696 __ tzcntl($dst$$Register, $src$$Register); 5697 %} 5698 ins_pipe(ialu_reg); 5699 %} 5700 5701 instruct countTrailingZerosI_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5702 predicate(UseCountTrailingZerosInstruction); 5703 match(Set dst (CountTrailingZerosI (LoadI src))); 5704 effect(KILL cr); 5705 ins_cost(175); 5706 format %{ "tzcntl $dst, $src\t# count trailing zeros (int)" %} 5707 ins_encode %{ 5708 __ tzcntl($dst$$Register, $src$$Address); 5709 %} 5710 ins_pipe(ialu_reg_mem); 5711 %} 5712 5713 instruct countTrailingZerosI_bsf(rRegI dst, rRegI src, rFlagsReg cr) %{ 5714 predicate(!UseCountTrailingZerosInstruction); 5715 match(Set dst (CountTrailingZerosI src)); 5716 effect(KILL cr); 5717 5718 format %{ "bsfl $dst, $src\t# count trailing zeros (int)\n\t" 5719 "jnz done\n\t" 5720 "movl $dst, 32\n" 5721 "done:" %} 5722 ins_encode %{ 5723 Register Rdst = $dst$$Register; 5724 Label done; 5725 __ bsfl(Rdst, $src$$Register); 5726 __ jccb(Assembler::notZero, done); 5727 __ movl(Rdst, BitsPerInt); 5728 __ bind(done); 5729 %} 5730 ins_pipe(ialu_reg); 5731 %} 5732 5733 instruct countTrailingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 5734 predicate(UseCountTrailingZerosInstruction); 5735 match(Set dst (CountTrailingZerosL src)); 5736 effect(KILL cr); 5737 5738 format %{ "tzcntq $dst, $src\t# count trailing zeros (long)" %} 5739 ins_encode %{ 5740 __ tzcntq($dst$$Register, $src$$Register); 5741 %} 5742 ins_pipe(ialu_reg); 5743 %} 5744 5745 instruct countTrailingZerosL_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5746 predicate(UseCountTrailingZerosInstruction); 5747 match(Set dst (CountTrailingZerosL (LoadL src))); 5748 effect(KILL cr); 5749 ins_cost(175); 5750 format %{ "tzcntq $dst, $src\t# count trailing zeros (long)" %} 5751 ins_encode %{ 5752 __ tzcntq($dst$$Register, $src$$Address); 5753 %} 5754 ins_pipe(ialu_reg_mem); 5755 %} 5756 5757 instruct countTrailingZerosL_bsf(rRegI dst, rRegL src, rFlagsReg cr) %{ 5758 predicate(!UseCountTrailingZerosInstruction); 5759 match(Set dst (CountTrailingZerosL src)); 5760 effect(KILL cr); 5761 5762 format %{ "bsfq $dst, $src\t# count trailing zeros (long)\n\t" 5763 "jnz done\n\t" 5764 "movl $dst, 64\n" 5765 "done:" %} 5766 ins_encode %{ 5767 Register Rdst = $dst$$Register; 5768 Label done; 5769 __ bsfq(Rdst, $src$$Register); 5770 __ jccb(Assembler::notZero, done); 5771 __ movl(Rdst, BitsPerLong); 5772 __ bind(done); 5773 %} 5774 ins_pipe(ialu_reg); 5775 %} 5776 5777 //--------------- Reverse Operation Instructions ---------------- 5778 instruct bytes_reversebit_int(rRegI dst, rRegI src, rRegI rtmp, rFlagsReg cr) %{ 5779 predicate(!VM_Version::supports_gfni()); 5780 match(Set dst (ReverseI src)); 5781 effect(TEMP dst, TEMP rtmp, KILL cr); 5782 format %{ "reverse_int $dst $src\t! using $rtmp as TEMP" %} 5783 ins_encode %{ 5784 __ reverseI($dst$$Register, $src$$Register, xnoreg, xnoreg, $rtmp$$Register); 5785 %} 5786 ins_pipe( ialu_reg ); 5787 %} 5788 5789 instruct bytes_reversebit_int_gfni(rRegI dst, rRegI src, vlRegF xtmp1, vlRegF xtmp2, rRegL rtmp, rFlagsReg cr) %{ 5790 predicate(VM_Version::supports_gfni()); 5791 match(Set dst (ReverseI src)); 5792 effect(TEMP dst, TEMP xtmp1, TEMP xtmp2, TEMP rtmp, KILL cr); 5793 format %{ "reverse_int $dst $src\t! using $rtmp, $xtmp1 and $xtmp2 as TEMP" %} 5794 ins_encode %{ 5795 __ reverseI($dst$$Register, $src$$Register, $xtmp1$$XMMRegister, $xtmp2$$XMMRegister, $rtmp$$Register); 5796 %} 5797 ins_pipe( ialu_reg ); 5798 %} 5799 5800 instruct bytes_reversebit_long(rRegL dst, rRegL src, rRegL rtmp1, rRegL rtmp2, rFlagsReg cr) %{ 5801 predicate(!VM_Version::supports_gfni()); 5802 match(Set dst (ReverseL src)); 5803 effect(TEMP dst, TEMP rtmp1, TEMP rtmp2, KILL cr); 5804 format %{ "reverse_long $dst $src\t! using $rtmp1 and $rtmp2 as TEMP" %} 5805 ins_encode %{ 5806 __ reverseL($dst$$Register, $src$$Register, xnoreg, xnoreg, $rtmp1$$Register, $rtmp2$$Register); 5807 %} 5808 ins_pipe( ialu_reg ); 5809 %} 5810 5811 instruct bytes_reversebit_long_gfni(rRegL dst, rRegL src, vlRegD xtmp1, vlRegD xtmp2, rRegL rtmp, rFlagsReg cr) %{ 5812 predicate(VM_Version::supports_gfni()); 5813 match(Set dst (ReverseL src)); 5814 effect(TEMP dst, TEMP xtmp1, TEMP xtmp2, TEMP rtmp, KILL cr); 5815 format %{ "reverse_long $dst $src\t! using $rtmp, $xtmp1 and $xtmp2 as TEMP" %} 5816 ins_encode %{ 5817 __ reverseL($dst$$Register, $src$$Register, $xtmp1$$XMMRegister, $xtmp2$$XMMRegister, $rtmp$$Register, noreg); 5818 %} 5819 ins_pipe( ialu_reg ); 5820 %} 5821 5822 //---------- Population Count Instructions ------------------------------------- 5823 5824 instruct popCountI(rRegI dst, rRegI src, rFlagsReg cr) %{ 5825 predicate(UsePopCountInstruction); 5826 match(Set dst (PopCountI src)); 5827 effect(KILL cr); 5828 5829 format %{ "popcnt $dst, $src" %} 5830 ins_encode %{ 5831 __ popcntl($dst$$Register, $src$$Register); 5832 %} 5833 ins_pipe(ialu_reg); 5834 %} 5835 5836 instruct popCountI_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 5837 predicate(UsePopCountInstruction); 5838 match(Set dst (PopCountI (LoadI mem))); 5839 effect(KILL cr); 5840 5841 format %{ "popcnt $dst, $mem" %} 5842 ins_encode %{ 5843 __ popcntl($dst$$Register, $mem$$Address); 5844 %} 5845 ins_pipe(ialu_reg); 5846 %} 5847 5848 // Note: Long.bitCount(long) returns an int. 5849 instruct popCountL(rRegI dst, rRegL src, rFlagsReg cr) %{ 5850 predicate(UsePopCountInstruction); 5851 match(Set dst (PopCountL src)); 5852 effect(KILL cr); 5853 5854 format %{ "popcnt $dst, $src" %} 5855 ins_encode %{ 5856 __ popcntq($dst$$Register, $src$$Register); 5857 %} 5858 ins_pipe(ialu_reg); 5859 %} 5860 5861 // Note: Long.bitCount(long) returns an int. 5862 instruct popCountL_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 5863 predicate(UsePopCountInstruction); 5864 match(Set dst (PopCountL (LoadL mem))); 5865 effect(KILL cr); 5866 5867 format %{ "popcnt $dst, $mem" %} 5868 ins_encode %{ 5869 __ popcntq($dst$$Register, $mem$$Address); 5870 %} 5871 ins_pipe(ialu_reg); 5872 %} 5873 5874 5875 //----------MemBar Instructions----------------------------------------------- 5876 // Memory barrier flavors 5877 5878 instruct membar_acquire() 5879 %{ 5880 match(MemBarAcquire); 5881 match(LoadFence); 5882 ins_cost(0); 5883 5884 size(0); 5885 format %{ "MEMBAR-acquire ! (empty encoding)" %} 5886 ins_encode(); 5887 ins_pipe(empty); 5888 %} 5889 5890 instruct membar_acquire_lock() 5891 %{ 5892 match(MemBarAcquireLock); 5893 ins_cost(0); 5894 5895 size(0); 5896 format %{ "MEMBAR-acquire (prior CMPXCHG in FastLock so empty encoding)" %} 5897 ins_encode(); 5898 ins_pipe(empty); 5899 %} 5900 5901 instruct membar_release() 5902 %{ 5903 match(MemBarRelease); 5904 match(StoreFence); 5905 ins_cost(0); 5906 5907 size(0); 5908 format %{ "MEMBAR-release ! (empty encoding)" %} 5909 ins_encode(); 5910 ins_pipe(empty); 5911 %} 5912 5913 instruct membar_release_lock() 5914 %{ 5915 match(MemBarReleaseLock); 5916 ins_cost(0); 5917 5918 size(0); 5919 format %{ "MEMBAR-release (a FastUnlock follows so empty encoding)" %} 5920 ins_encode(); 5921 ins_pipe(empty); 5922 %} 5923 5924 instruct membar_volatile(rFlagsReg cr) %{ 5925 match(MemBarVolatile); 5926 effect(KILL cr); 5927 ins_cost(400); 5928 5929 format %{ 5930 $$template 5931 $$emit$$"lock addl [rsp + #0], 0\t! membar_volatile" 5932 %} 5933 ins_encode %{ 5934 __ membar(Assembler::StoreLoad); 5935 %} 5936 ins_pipe(pipe_slow); 5937 %} 5938 5939 instruct unnecessary_membar_volatile() 5940 %{ 5941 match(MemBarVolatile); 5942 predicate(Matcher::post_store_load_barrier(n)); 5943 ins_cost(0); 5944 5945 size(0); 5946 format %{ "MEMBAR-volatile (unnecessary so empty encoding)" %} 5947 ins_encode(); 5948 ins_pipe(empty); 5949 %} 5950 5951 instruct membar_storestore() %{ 5952 match(MemBarStoreStore); 5953 match(StoreStoreFence); 5954 ins_cost(0); 5955 5956 size(0); 5957 format %{ "MEMBAR-storestore (empty encoding)" %} 5958 ins_encode( ); 5959 ins_pipe(empty); 5960 %} 5961 5962 //----------Move Instructions-------------------------------------------------- 5963 5964 instruct castX2P(rRegP dst, rRegL src) 5965 %{ 5966 match(Set dst (CastX2P src)); 5967 5968 format %{ "movq $dst, $src\t# long->ptr" %} 5969 ins_encode %{ 5970 if ($dst$$reg != $src$$reg) { 5971 __ movptr($dst$$Register, $src$$Register); 5972 } 5973 %} 5974 ins_pipe(ialu_reg_reg); // XXX 5975 %} 5976 5977 instruct castP2X(rRegL dst, rRegP src) 5978 %{ 5979 match(Set dst (CastP2X src)); 5980 5981 format %{ "movq $dst, $src\t# ptr -> long" %} 5982 ins_encode %{ 5983 if ($dst$$reg != $src$$reg) { 5984 __ movptr($dst$$Register, $src$$Register); 5985 } 5986 %} 5987 ins_pipe(ialu_reg_reg); // XXX 5988 %} 5989 5990 // Convert oop into int for vectors alignment masking 5991 instruct convP2I(rRegI dst, rRegP src) 5992 %{ 5993 match(Set dst (ConvL2I (CastP2X src))); 5994 5995 format %{ "movl $dst, $src\t# ptr -> int" %} 5996 ins_encode %{ 5997 __ movl($dst$$Register, $src$$Register); 5998 %} 5999 ins_pipe(ialu_reg_reg); // XXX 6000 %} 6001 6002 // Convert compressed oop into int for vectors alignment masking 6003 // in case of 32bit oops (heap < 4Gb). 6004 instruct convN2I(rRegI dst, rRegN src) 6005 %{ 6006 predicate(CompressedOops::shift() == 0); 6007 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 6008 6009 format %{ "movl $dst, $src\t# compressed ptr -> int" %} 6010 ins_encode %{ 6011 __ movl($dst$$Register, $src$$Register); 6012 %} 6013 ins_pipe(ialu_reg_reg); // XXX 6014 %} 6015 6016 // Convert oop pointer into compressed form 6017 instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{ 6018 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 6019 match(Set dst (EncodeP src)); 6020 effect(KILL cr); 6021 format %{ "encode_heap_oop $dst,$src" %} 6022 ins_encode %{ 6023 Register s = $src$$Register; 6024 Register d = $dst$$Register; 6025 if (s != d) { 6026 __ movq(d, s); 6027 } 6028 __ encode_heap_oop(d); 6029 %} 6030 ins_pipe(ialu_reg_long); 6031 %} 6032 6033 instruct encodeHeapOop_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6034 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 6035 match(Set dst (EncodeP src)); 6036 effect(KILL cr); 6037 format %{ "encode_heap_oop_not_null $dst,$src" %} 6038 ins_encode %{ 6039 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 6040 %} 6041 ins_pipe(ialu_reg_long); 6042 %} 6043 6044 instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{ 6045 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 6046 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 6047 match(Set dst (DecodeN src)); 6048 effect(KILL cr); 6049 format %{ "decode_heap_oop $dst,$src" %} 6050 ins_encode %{ 6051 Register s = $src$$Register; 6052 Register d = $dst$$Register; 6053 if (s != d) { 6054 __ movq(d, s); 6055 } 6056 __ decode_heap_oop(d); 6057 %} 6058 ins_pipe(ialu_reg_long); 6059 %} 6060 6061 instruct decodeHeapOop_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6062 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 6063 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 6064 match(Set dst (DecodeN src)); 6065 effect(KILL cr); 6066 format %{ "decode_heap_oop_not_null $dst,$src" %} 6067 ins_encode %{ 6068 Register s = $src$$Register; 6069 Register d = $dst$$Register; 6070 if (s != d) { 6071 __ decode_heap_oop_not_null(d, s); 6072 } else { 6073 __ decode_heap_oop_not_null(d); 6074 } 6075 %} 6076 ins_pipe(ialu_reg_long); 6077 %} 6078 6079 instruct encodeKlass_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6080 match(Set dst (EncodePKlass src)); 6081 effect(TEMP dst, KILL cr); 6082 format %{ "encode_and_move_klass_not_null $dst,$src" %} 6083 ins_encode %{ 6084 __ encode_and_move_klass_not_null($dst$$Register, $src$$Register); 6085 %} 6086 ins_pipe(ialu_reg_long); 6087 %} 6088 6089 instruct decodeKlass_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6090 match(Set dst (DecodeNKlass src)); 6091 effect(TEMP dst, KILL cr); 6092 format %{ "decode_and_move_klass_not_null $dst,$src" %} 6093 ins_encode %{ 6094 __ decode_and_move_klass_not_null($dst$$Register, $src$$Register); 6095 %} 6096 ins_pipe(ialu_reg_long); 6097 %} 6098 6099 //----------Conditional Move--------------------------------------------------- 6100 // Jump 6101 // dummy instruction for generating temp registers 6102 instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{ 6103 match(Jump (LShiftL switch_val shift)); 6104 ins_cost(350); 6105 predicate(false); 6106 effect(TEMP dest); 6107 6108 format %{ "leaq $dest, [$constantaddress]\n\t" 6109 "jmp [$dest + $switch_val << $shift]\n\t" %} 6110 ins_encode %{ 6111 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6112 // to do that and the compiler is using that register as one it can allocate. 6113 // So we build it all by hand. 6114 // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant); 6115 // ArrayAddress dispatch(table, index); 6116 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant); 6117 __ lea($dest$$Register, $constantaddress); 6118 __ jmp(dispatch); 6119 %} 6120 ins_pipe(pipe_jmp); 6121 %} 6122 6123 instruct jumpXtnd_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{ 6124 match(Jump (AddL (LShiftL switch_val shift) offset)); 6125 ins_cost(350); 6126 effect(TEMP dest); 6127 6128 format %{ "leaq $dest, [$constantaddress]\n\t" 6129 "jmp [$dest + $switch_val << $shift + $offset]\n\t" %} 6130 ins_encode %{ 6131 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6132 // to do that and the compiler is using that register as one it can allocate. 6133 // So we build it all by hand. 6134 // Address index(noreg, switch_reg, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6135 // ArrayAddress dispatch(table, index); 6136 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6137 __ lea($dest$$Register, $constantaddress); 6138 __ jmp(dispatch); 6139 %} 6140 ins_pipe(pipe_jmp); 6141 %} 6142 6143 instruct jumpXtnd(rRegL switch_val, rRegI dest) %{ 6144 match(Jump switch_val); 6145 ins_cost(350); 6146 effect(TEMP dest); 6147 6148 format %{ "leaq $dest, [$constantaddress]\n\t" 6149 "jmp [$dest + $switch_val]\n\t" %} 6150 ins_encode %{ 6151 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6152 // to do that and the compiler is using that register as one it can allocate. 6153 // So we build it all by hand. 6154 // Address index(noreg, switch_reg, Address::times_1); 6155 // ArrayAddress dispatch(table, index); 6156 Address dispatch($dest$$Register, $switch_val$$Register, Address::times_1); 6157 __ lea($dest$$Register, $constantaddress); 6158 __ jmp(dispatch); 6159 %} 6160 ins_pipe(pipe_jmp); 6161 %} 6162 6163 // Conditional move 6164 instruct cmovI_imm_01(rRegI dst, immI_1 src, rFlagsReg cr, cmpOp cop) 6165 %{ 6166 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_int() == 0); 6167 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6168 6169 ins_cost(100); // XXX 6170 format %{ "setbn$cop $dst\t# signed, int" %} 6171 ins_encode %{ 6172 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6173 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6174 %} 6175 ins_pipe(ialu_reg); 6176 %} 6177 6178 instruct cmovI_reg(rRegI dst, rRegI src, rFlagsReg cr, cmpOp cop) 6179 %{ 6180 predicate(!UseAPX); 6181 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6182 6183 ins_cost(200); // XXX 6184 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6185 ins_encode %{ 6186 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6187 %} 6188 ins_pipe(pipe_cmov_reg); 6189 %} 6190 6191 instruct cmovI_reg_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr, cmpOp cop) 6192 %{ 6193 predicate(UseAPX); 6194 match(Set dst (CMoveI (Binary cop cr) (Binary src1 src2))); 6195 6196 ins_cost(200); 6197 format %{ "ecmovl$cop $dst, $src1, $src2\t# signed, int ndd" %} 6198 ins_encode %{ 6199 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6200 %} 6201 ins_pipe(pipe_cmov_reg); 6202 %} 6203 6204 instruct cmovI_imm_01U(rRegI dst, immI_1 src, rFlagsRegU cr, cmpOpU cop) 6205 %{ 6206 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_int() == 0); 6207 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6208 6209 ins_cost(100); // XXX 6210 format %{ "setbn$cop $dst\t# unsigned, int" %} 6211 ins_encode %{ 6212 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6213 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6214 %} 6215 ins_pipe(ialu_reg); 6216 %} 6217 6218 instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{ 6219 predicate(!UseAPX); 6220 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6221 6222 ins_cost(200); // XXX 6223 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6224 ins_encode %{ 6225 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6226 %} 6227 ins_pipe(pipe_cmov_reg); 6228 %} 6229 6230 instruct cmovI_regU_ndd(rRegI dst, cmpOpU cop, rFlagsRegU cr, rRegI src1, rRegI src2) %{ 6231 predicate(UseAPX); 6232 match(Set dst (CMoveI (Binary cop cr) (Binary src1 src2))); 6233 6234 ins_cost(200); 6235 format %{ "ecmovl$cop $dst, $src1, $src2\t# unsigned, int ndd" %} 6236 ins_encode %{ 6237 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6238 %} 6239 ins_pipe(pipe_cmov_reg); 6240 %} 6241 6242 instruct cmovI_imm_01UCF(rRegI dst, immI_1 src, rFlagsRegUCF cr, cmpOpUCF cop) 6243 %{ 6244 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_int() == 0); 6245 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6246 6247 ins_cost(100); // XXX 6248 format %{ "setbn$cop $dst\t# unsigned, int" %} 6249 ins_encode %{ 6250 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6251 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6252 %} 6253 ins_pipe(ialu_reg); 6254 %} 6255 6256 instruct cmovI_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6257 predicate(!UseAPX); 6258 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6259 ins_cost(200); 6260 expand %{ 6261 cmovI_regU(cop, cr, dst, src); 6262 %} 6263 %} 6264 6265 instruct cmovI_regUCF_ndd(rRegI dst, cmpOpUCF cop, rFlagsRegUCF cr, rRegI src1, rRegI src2) %{ 6266 predicate(UseAPX); 6267 match(Set dst (CMoveI (Binary cop cr) (Binary src1 src2))); 6268 ins_cost(200); 6269 format %{ "ecmovl$cop $dst, $src1, $src2\t# unsigned, int ndd" %} 6270 ins_encode %{ 6271 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6272 %} 6273 ins_pipe(pipe_cmov_reg); 6274 %} 6275 6276 instruct cmovI_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6277 predicate(!UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6278 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6279 6280 ins_cost(200); // XXX 6281 format %{ "cmovpl $dst, $src\n\t" 6282 "cmovnel $dst, $src" %} 6283 ins_encode %{ 6284 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6285 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6286 %} 6287 ins_pipe(pipe_cmov_reg); 6288 %} 6289 6290 instruct cmovI_regUCF2_ne_ndd(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegI dst, rRegI src1, rRegI src2) %{ 6291 predicate(UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6292 match(Set dst (CMoveI (Binary cop cr) (Binary src1 src2))); 6293 effect(TEMP dst); 6294 6295 ins_cost(200); 6296 format %{ "ecmovpl $dst, $src1, $src2\n\t" 6297 "cmovnel $dst, $src2" %} 6298 ins_encode %{ 6299 __ ecmovl(Assembler::parity, $dst$$Register, $src1$$Register, $src2$$Register); 6300 __ cmovl(Assembler::notEqual, $dst$$Register, $src2$$Register); 6301 %} 6302 ins_pipe(pipe_cmov_reg); 6303 %} 6304 6305 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6306 // inputs of the CMove 6307 instruct cmovI_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6308 predicate(!UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6309 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6310 effect(TEMP dst); 6311 6312 ins_cost(200); // XXX 6313 format %{ "cmovpl $dst, $src\n\t" 6314 "cmovnel $dst, $src" %} 6315 ins_encode %{ 6316 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6317 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6318 %} 6319 ins_pipe(pipe_cmov_reg); 6320 %} 6321 6322 // We need this special handling for only eq / neq comparison since NaN == NaN is false, 6323 // and parity flag bit is set if any of the operand is a NaN. 6324 instruct cmovI_regUCF2_eq_ndd(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegI dst, rRegI src1, rRegI src2) %{ 6325 predicate(UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6326 match(Set dst (CMoveI (Binary cop cr) (Binary src2 src1))); 6327 effect(TEMP dst); 6328 6329 ins_cost(200); 6330 format %{ "ecmovpl $dst, $src1, $src2\n\t" 6331 "cmovnel $dst, $src2" %} 6332 ins_encode %{ 6333 __ ecmovl(Assembler::parity, $dst$$Register, $src1$$Register, $src2$$Register); 6334 __ cmovl(Assembler::notEqual, $dst$$Register, $src2$$Register); 6335 %} 6336 ins_pipe(pipe_cmov_reg); 6337 %} 6338 6339 // Conditional move 6340 instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{ 6341 predicate(!UseAPX); 6342 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6343 6344 ins_cost(250); // XXX 6345 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6346 ins_encode %{ 6347 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6348 %} 6349 ins_pipe(pipe_cmov_mem); 6350 %} 6351 6352 // Conditional move 6353 instruct cmovI_rReg_rReg_mem_ndd(rRegI dst, cmpOp cop, rFlagsReg cr, rRegI src1, memory src2) 6354 %{ 6355 predicate(UseAPX); 6356 match(Set dst (CMoveI (Binary cop cr) (Binary src1 (LoadI src2)))); 6357 6358 ins_cost(250); 6359 format %{ "ecmovl$cop $dst, $src1, $src2\t# signed, int ndd" %} 6360 ins_encode %{ 6361 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Address); 6362 %} 6363 ins_pipe(pipe_cmov_mem); 6364 %} 6365 6366 // Conditional move 6367 instruct cmovI_memU(cmpOpU cop, rFlagsRegU cr, rRegI dst, memory src) 6368 %{ 6369 predicate(!UseAPX); 6370 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6371 6372 ins_cost(250); // XXX 6373 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6374 ins_encode %{ 6375 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6376 %} 6377 ins_pipe(pipe_cmov_mem); 6378 %} 6379 6380 instruct cmovI_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, memory src) %{ 6381 predicate(!UseAPX); 6382 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6383 ins_cost(250); 6384 expand %{ 6385 cmovI_memU(cop, cr, dst, src); 6386 %} 6387 %} 6388 6389 instruct cmovI_rReg_rReg_memU_ndd(rRegI dst, cmpOpU cop, rFlagsRegU cr, rRegI src1, memory src2) 6390 %{ 6391 predicate(UseAPX); 6392 match(Set dst (CMoveI (Binary cop cr) (Binary src1 (LoadI src2)))); 6393 6394 ins_cost(250); 6395 format %{ "ecmovl$cop $dst, $src1, $src2\t# unsigned, int ndd" %} 6396 ins_encode %{ 6397 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Address); 6398 %} 6399 ins_pipe(pipe_cmov_mem); 6400 %} 6401 6402 instruct cmovI_rReg_rReg_memUCF_ndd(rRegI dst, cmpOpUCF cop, rFlagsRegUCF cr, rRegI src1, memory src2) 6403 %{ 6404 predicate(UseAPX); 6405 match(Set dst (CMoveI (Binary cop cr) (Binary src1 (LoadI src2)))); 6406 ins_cost(250); 6407 format %{ "ecmovl$cop $dst, $src1, $src2\t# unsigned, 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 cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop) 6416 %{ 6417 predicate(!UseAPX); 6418 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6419 6420 ins_cost(200); // XXX 6421 format %{ "cmovl$cop $dst, $src\t# signed, compressed ptr" %} 6422 ins_encode %{ 6423 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6424 %} 6425 ins_pipe(pipe_cmov_reg); 6426 %} 6427 6428 // Conditional move ndd 6429 instruct cmovN_reg_ndd(rRegN dst, rRegN src1, rRegN src2, rFlagsReg cr, cmpOp cop) 6430 %{ 6431 predicate(UseAPX); 6432 match(Set dst (CMoveN (Binary cop cr) (Binary src1 src2))); 6433 6434 ins_cost(200); 6435 format %{ "ecmovl$cop $dst, $src1, $src2\t# signed, compressed ptr ndd" %} 6436 ins_encode %{ 6437 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6438 %} 6439 ins_pipe(pipe_cmov_reg); 6440 %} 6441 6442 // Conditional move 6443 instruct cmovN_regU(cmpOpU cop, rFlagsRegU cr, rRegN dst, rRegN src) 6444 %{ 6445 predicate(!UseAPX); 6446 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6447 6448 ins_cost(200); // XXX 6449 format %{ "cmovl$cop $dst, $src\t# unsigned, compressed ptr" %} 6450 ins_encode %{ 6451 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6452 %} 6453 ins_pipe(pipe_cmov_reg); 6454 %} 6455 6456 instruct cmovN_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6457 predicate(!UseAPX); 6458 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6459 ins_cost(200); 6460 expand %{ 6461 cmovN_regU(cop, cr, dst, src); 6462 %} 6463 %} 6464 6465 // Conditional move ndd 6466 instruct cmovN_regU_ndd(rRegN dst, cmpOpU cop, rFlagsRegU cr, rRegN src1, rRegN src2) 6467 %{ 6468 predicate(UseAPX); 6469 match(Set dst (CMoveN (Binary cop cr) (Binary src1 src2))); 6470 6471 ins_cost(200); 6472 format %{ "ecmovl$cop $dst, $src1, $src2\t# unsigned, compressed ptr ndd" %} 6473 ins_encode %{ 6474 __ ecmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6475 %} 6476 ins_pipe(pipe_cmov_reg); 6477 %} 6478 6479 instruct cmovN_regUCF_ndd(rRegN dst, cmpOpUCF cop, rFlagsRegUCF cr, rRegN src1, rRegN src2) %{ 6480 predicate(UseAPX); 6481 match(Set dst (CMoveN (Binary cop cr) (Binary src1 src2))); 6482 ins_cost(200); 6483 format %{ "ecmovl$cop $dst, $src1, $src2\t# unsigned, 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 instruct cmovN_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6491 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6492 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6493 6494 ins_cost(200); // XXX 6495 format %{ "cmovpl $dst, $src\n\t" 6496 "cmovnel $dst, $src" %} 6497 ins_encode %{ 6498 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6499 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6500 %} 6501 ins_pipe(pipe_cmov_reg); 6502 %} 6503 6504 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6505 // inputs of the CMove 6506 instruct cmovN_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6507 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6508 match(Set dst (CMoveN (Binary cop cr) (Binary src dst))); 6509 6510 ins_cost(200); // XXX 6511 format %{ "cmovpl $dst, $src\n\t" 6512 "cmovnel $dst, $src" %} 6513 ins_encode %{ 6514 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6515 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6516 %} 6517 ins_pipe(pipe_cmov_reg); 6518 %} 6519 6520 // Conditional move 6521 instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop) 6522 %{ 6523 predicate(!UseAPX); 6524 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6525 6526 ins_cost(200); // XXX 6527 format %{ "cmovq$cop $dst, $src\t# signed, ptr" %} 6528 ins_encode %{ 6529 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6530 %} 6531 ins_pipe(pipe_cmov_reg); // XXX 6532 %} 6533 6534 // Conditional move ndd 6535 instruct cmovP_reg_ndd(rRegP dst, rRegP src1, rRegP src2, rFlagsReg cr, cmpOp cop) 6536 %{ 6537 predicate(UseAPX); 6538 match(Set dst (CMoveP (Binary cop cr) (Binary src1 src2))); 6539 6540 ins_cost(200); 6541 format %{ "ecmovq$cop $dst, $src1, $src2\t# signed, ptr ndd" %} 6542 ins_encode %{ 6543 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6544 %} 6545 ins_pipe(pipe_cmov_reg); 6546 %} 6547 6548 // Conditional move 6549 instruct cmovP_regU(cmpOpU cop, rFlagsRegU cr, rRegP dst, rRegP src) 6550 %{ 6551 predicate(!UseAPX); 6552 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6553 6554 ins_cost(200); // XXX 6555 format %{ "cmovq$cop $dst, $src\t# unsigned, ptr" %} 6556 ins_encode %{ 6557 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6558 %} 6559 ins_pipe(pipe_cmov_reg); // XXX 6560 %} 6561 6562 // Conditional move ndd 6563 instruct cmovP_regU_ndd(rRegP dst, cmpOpU cop, rFlagsRegU cr, rRegP src1, rRegP src2) 6564 %{ 6565 predicate(UseAPX); 6566 match(Set dst (CMoveP (Binary cop cr) (Binary src1 src2))); 6567 6568 ins_cost(200); 6569 format %{ "ecmovq$cop $dst, $src1, $src2\t# unsigned, ptr ndd" %} 6570 ins_encode %{ 6571 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6572 %} 6573 ins_pipe(pipe_cmov_reg); 6574 %} 6575 6576 instruct cmovP_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6577 predicate(!UseAPX); 6578 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6579 ins_cost(200); 6580 expand %{ 6581 cmovP_regU(cop, cr, dst, src); 6582 %} 6583 %} 6584 6585 instruct cmovP_regUCF_ndd(rRegP dst, cmpOpUCF cop, rFlagsRegUCF cr, rRegP src1, rRegP src2) %{ 6586 predicate(UseAPX); 6587 match(Set dst (CMoveP (Binary cop cr) (Binary src1 src2))); 6588 ins_cost(200); 6589 format %{ "ecmovq$cop $dst, $src1, $src2\t# unsigned, 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 instruct cmovP_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6597 predicate(!UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6598 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6599 6600 ins_cost(200); // XXX 6601 format %{ "cmovpq $dst, $src\n\t" 6602 "cmovneq $dst, $src" %} 6603 ins_encode %{ 6604 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6605 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6606 %} 6607 ins_pipe(pipe_cmov_reg); 6608 %} 6609 6610 instruct cmovP_regUCF2_ne_ndd(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegP dst, rRegP src1, rRegP src2) %{ 6611 predicate(UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6612 match(Set dst (CMoveP (Binary cop cr) (Binary src1 src2))); 6613 effect(TEMP dst); 6614 6615 ins_cost(200); 6616 format %{ "ecmovpq $dst, $src1, $src2\n\t" 6617 "cmovneq $dst, $src2" %} 6618 ins_encode %{ 6619 __ ecmovq(Assembler::parity, $dst$$Register, $src1$$Register, $src2$$Register); 6620 __ cmovq(Assembler::notEqual, $dst$$Register, $src2$$Register); 6621 %} 6622 ins_pipe(pipe_cmov_reg); 6623 %} 6624 6625 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6626 // inputs of the CMove 6627 instruct cmovP_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6628 predicate(!UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6629 match(Set dst (CMoveP (Binary cop cr) (Binary src dst))); 6630 6631 ins_cost(200); // XXX 6632 format %{ "cmovpq $dst, $src\n\t" 6633 "cmovneq $dst, $src" %} 6634 ins_encode %{ 6635 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6636 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6637 %} 6638 ins_pipe(pipe_cmov_reg); 6639 %} 6640 6641 instruct cmovP_regUCF2_eq_ndd(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegP dst, rRegP src1, rRegP src2) %{ 6642 predicate(UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6643 match(Set dst (CMoveP (Binary cop cr) (Binary src2 src1))); 6644 effect(TEMP dst); 6645 6646 ins_cost(200); 6647 format %{ "ecmovpq $dst, $src1, $src2\n\t" 6648 "cmovneq $dst, $src2" %} 6649 ins_encode %{ 6650 __ ecmovq(Assembler::parity, $dst$$Register, $src1$$Register, $src2$$Register); 6651 __ cmovq(Assembler::notEqual, $dst$$Register, $src2$$Register); 6652 %} 6653 ins_pipe(pipe_cmov_reg); 6654 %} 6655 6656 instruct cmovL_imm_01(rRegL dst, immL1 src, rFlagsReg cr, cmpOp cop) 6657 %{ 6658 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_long() == 0); 6659 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6660 6661 ins_cost(100); // XXX 6662 format %{ "setbn$cop $dst\t# signed, long" %} 6663 ins_encode %{ 6664 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6665 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6666 %} 6667 ins_pipe(ialu_reg); 6668 %} 6669 6670 instruct cmovL_reg(cmpOp cop, rFlagsReg cr, rRegL dst, rRegL src) 6671 %{ 6672 predicate(!UseAPX); 6673 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6674 6675 ins_cost(200); // XXX 6676 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6677 ins_encode %{ 6678 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6679 %} 6680 ins_pipe(pipe_cmov_reg); // XXX 6681 %} 6682 6683 instruct cmovL_reg_ndd(rRegL dst, cmpOp cop, rFlagsReg cr, rRegL src1, rRegL src2) 6684 %{ 6685 predicate(UseAPX); 6686 match(Set dst (CMoveL (Binary cop cr) (Binary src1 src2))); 6687 6688 ins_cost(200); 6689 format %{ "ecmovq$cop $dst, $src1, $src2\t# signed, long ndd" %} 6690 ins_encode %{ 6691 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6692 %} 6693 ins_pipe(pipe_cmov_reg); 6694 %} 6695 6696 instruct cmovL_mem(cmpOp cop, rFlagsReg cr, rRegL dst, memory src) 6697 %{ 6698 predicate(!UseAPX); 6699 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6700 6701 ins_cost(200); // XXX 6702 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6703 ins_encode %{ 6704 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6705 %} 6706 ins_pipe(pipe_cmov_mem); // XXX 6707 %} 6708 6709 instruct cmovL_rReg_rReg_mem_ndd(rRegL dst, cmpOp cop, rFlagsReg cr, rRegL src1, memory src2) 6710 %{ 6711 predicate(UseAPX); 6712 match(Set dst (CMoveL (Binary cop cr) (Binary src1 (LoadL src2)))); 6713 6714 ins_cost(200); 6715 format %{ "ecmovq$cop $dst, $src1, $src2\t# signed, long ndd" %} 6716 ins_encode %{ 6717 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Address); 6718 %} 6719 ins_pipe(pipe_cmov_mem); 6720 %} 6721 6722 instruct cmovL_imm_01U(rRegL dst, immL1 src, rFlagsRegU cr, cmpOpU cop) 6723 %{ 6724 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_long() == 0); 6725 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6726 6727 ins_cost(100); // XXX 6728 format %{ "setbn$cop $dst\t# unsigned, long" %} 6729 ins_encode %{ 6730 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6731 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6732 %} 6733 ins_pipe(ialu_reg); 6734 %} 6735 6736 instruct cmovL_regU(cmpOpU cop, rFlagsRegU cr, rRegL dst, rRegL src) 6737 %{ 6738 predicate(!UseAPX); 6739 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6740 6741 ins_cost(200); // XXX 6742 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 6743 ins_encode %{ 6744 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6745 %} 6746 ins_pipe(pipe_cmov_reg); // XXX 6747 %} 6748 6749 instruct cmovL_regU_ndd(rRegL dst, cmpOpU cop, rFlagsRegU cr, rRegL src1, rRegL src2) 6750 %{ 6751 predicate(UseAPX); 6752 match(Set dst (CMoveL (Binary cop cr) (Binary src1 src2))); 6753 6754 ins_cost(200); 6755 format %{ "ecmovq$cop $dst, $src1, $src2\t# unsigned, long ndd" %} 6756 ins_encode %{ 6757 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6758 %} 6759 ins_pipe(pipe_cmov_reg); 6760 %} 6761 6762 instruct cmovL_imm_01UCF(rRegL dst, immL1 src, rFlagsRegUCF cr, cmpOpUCF cop) 6763 %{ 6764 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_long() == 0); 6765 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6766 6767 ins_cost(100); // XXX 6768 format %{ "setbn$cop $dst\t# unsigned, long" %} 6769 ins_encode %{ 6770 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6771 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6772 %} 6773 ins_pipe(ialu_reg); 6774 %} 6775 6776 instruct cmovL_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6777 predicate(!UseAPX); 6778 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6779 ins_cost(200); 6780 expand %{ 6781 cmovL_regU(cop, cr, dst, src); 6782 %} 6783 %} 6784 6785 instruct cmovL_regUCF_ndd(rRegL dst, cmpOpUCF cop, rFlagsRegUCF cr, rRegL src1, rRegL src2) 6786 %{ 6787 predicate(UseAPX); 6788 match(Set dst (CMoveL (Binary cop cr) (Binary src1 src2))); 6789 ins_cost(200); 6790 format %{ "ecmovq$cop $dst, $src1, $src2\t# unsigned, long ndd" %} 6791 ins_encode %{ 6792 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Register); 6793 %} 6794 ins_pipe(pipe_cmov_reg); 6795 %} 6796 6797 instruct cmovL_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6798 predicate(!UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6799 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6800 6801 ins_cost(200); // XXX 6802 format %{ "cmovpq $dst, $src\n\t" 6803 "cmovneq $dst, $src" %} 6804 ins_encode %{ 6805 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6806 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6807 %} 6808 ins_pipe(pipe_cmov_reg); 6809 %} 6810 6811 instruct cmovL_regUCF2_ne_ndd(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegL dst, rRegL src1, rRegL src2) %{ 6812 predicate(UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6813 match(Set dst (CMoveL (Binary cop cr) (Binary src1 src2))); 6814 effect(TEMP dst); 6815 6816 ins_cost(200); 6817 format %{ "ecmovpq $dst, $src1, $src2\n\t" 6818 "cmovneq $dst, $src2" %} 6819 ins_encode %{ 6820 __ ecmovq(Assembler::parity, $dst$$Register, $src1$$Register, $src2$$Register); 6821 __ cmovq(Assembler::notEqual, $dst$$Register, $src2$$Register); 6822 %} 6823 ins_pipe(pipe_cmov_reg); 6824 %} 6825 6826 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6827 // inputs of the CMove 6828 instruct cmovL_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6829 predicate(!UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6830 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6831 6832 ins_cost(200); // XXX 6833 format %{ "cmovpq $dst, $src\n\t" 6834 "cmovneq $dst, $src" %} 6835 ins_encode %{ 6836 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6837 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6838 %} 6839 ins_pipe(pipe_cmov_reg); 6840 %} 6841 6842 instruct cmovL_regUCF2_eq_ndd(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegL dst, rRegL src1, rRegL src2) %{ 6843 predicate(UseAPX && n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6844 match(Set dst (CMoveL (Binary cop cr) (Binary src2 src1))); 6845 effect(TEMP dst); 6846 6847 ins_cost(200); 6848 format %{ "ecmovpq $dst, $src1, $src2\n\t" 6849 "cmovneq $dst, $src2" %} 6850 ins_encode %{ 6851 __ ecmovq(Assembler::parity, $dst$$Register, $src1$$Register, $src2$$Register); 6852 __ cmovq(Assembler::notEqual, $dst$$Register, $src2$$Register); 6853 %} 6854 ins_pipe(pipe_cmov_reg); 6855 %} 6856 6857 instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src) 6858 %{ 6859 predicate(!UseAPX); 6860 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6861 6862 ins_cost(200); // XXX 6863 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 6864 ins_encode %{ 6865 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6866 %} 6867 ins_pipe(pipe_cmov_mem); // XXX 6868 %} 6869 6870 instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{ 6871 predicate(!UseAPX); 6872 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6873 ins_cost(200); 6874 expand %{ 6875 cmovL_memU(cop, cr, dst, src); 6876 %} 6877 %} 6878 6879 instruct cmovL_rReg_rReg_memU_ndd(rRegL dst, cmpOpU cop, rFlagsRegU cr, rRegL src1, memory src2) 6880 %{ 6881 predicate(UseAPX); 6882 match(Set dst (CMoveL (Binary cop cr) (Binary src1 (LoadL src2)))); 6883 6884 ins_cost(200); 6885 format %{ "ecmovq$cop $dst, $src1, $src2\t# unsigned, long ndd" %} 6886 ins_encode %{ 6887 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Address); 6888 %} 6889 ins_pipe(pipe_cmov_mem); 6890 %} 6891 6892 instruct cmovL_rReg_rReg_memUCF_ndd(rRegL dst, cmpOpUCF cop, rFlagsRegUCF cr, rRegL src1, memory src2) 6893 %{ 6894 predicate(UseAPX); 6895 match(Set dst (CMoveL (Binary cop cr) (Binary src1 (LoadL src2)))); 6896 ins_cost(200); 6897 format %{ "ecmovq$cop $dst, $src1, $src2\t# unsigned, long ndd" %} 6898 ins_encode %{ 6899 __ ecmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src1$$Register, $src2$$Address); 6900 %} 6901 ins_pipe(pipe_cmov_mem); 6902 %} 6903 6904 instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src) 6905 %{ 6906 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6907 6908 ins_cost(200); // XXX 6909 format %{ "jn$cop skip\t# signed cmove float\n\t" 6910 "movss $dst, $src\n" 6911 "skip:" %} 6912 ins_encode %{ 6913 Label Lskip; 6914 // Invert sense of branch from sense of CMOV 6915 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6916 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 6917 __ bind(Lskip); 6918 %} 6919 ins_pipe(pipe_slow); 6920 %} 6921 6922 instruct cmovF_regU(cmpOpU cop, rFlagsRegU cr, regF dst, regF src) 6923 %{ 6924 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6925 6926 ins_cost(200); // XXX 6927 format %{ "jn$cop skip\t# unsigned cmove float\n\t" 6928 "movss $dst, $src\n" 6929 "skip:" %} 6930 ins_encode %{ 6931 Label Lskip; 6932 // Invert sense of branch from sense of CMOV 6933 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6934 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 6935 __ bind(Lskip); 6936 %} 6937 ins_pipe(pipe_slow); 6938 %} 6939 6940 instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{ 6941 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6942 ins_cost(200); 6943 expand %{ 6944 cmovF_regU(cop, cr, dst, src); 6945 %} 6946 %} 6947 6948 instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src) 6949 %{ 6950 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6951 6952 ins_cost(200); // XXX 6953 format %{ "jn$cop skip\t# signed cmove double\n\t" 6954 "movsd $dst, $src\n" 6955 "skip:" %} 6956 ins_encode %{ 6957 Label Lskip; 6958 // Invert sense of branch from sense of CMOV 6959 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6960 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 6961 __ bind(Lskip); 6962 %} 6963 ins_pipe(pipe_slow); 6964 %} 6965 6966 instruct cmovD_regU(cmpOpU cop, rFlagsRegU cr, regD dst, regD src) 6967 %{ 6968 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6969 6970 ins_cost(200); // XXX 6971 format %{ "jn$cop skip\t# unsigned cmove double\n\t" 6972 "movsd $dst, $src\n" 6973 "skip:" %} 6974 ins_encode %{ 6975 Label Lskip; 6976 // Invert sense of branch from sense of CMOV 6977 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6978 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 6979 __ bind(Lskip); 6980 %} 6981 ins_pipe(pipe_slow); 6982 %} 6983 6984 instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{ 6985 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6986 ins_cost(200); 6987 expand %{ 6988 cmovD_regU(cop, cr, dst, src); 6989 %} 6990 %} 6991 6992 //----------Arithmetic Instructions-------------------------------------------- 6993 //----------Addition Instructions---------------------------------------------- 6994 6995 instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 6996 %{ 6997 predicate(!UseAPX); 6998 match(Set dst (AddI dst src)); 6999 effect(KILL cr); 7000 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); 7001 format %{ "addl $dst, $src\t# int" %} 7002 ins_encode %{ 7003 __ addl($dst$$Register, $src$$Register); 7004 %} 7005 ins_pipe(ialu_reg_reg); 7006 %} 7007 7008 instruct addI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr) 7009 %{ 7010 predicate(UseAPX); 7011 match(Set dst (AddI src1 src2)); 7012 effect(KILL cr); 7013 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); 7014 7015 format %{ "eaddl $dst, $src1, $src2\t# int ndd" %} 7016 ins_encode %{ 7017 __ eaddl($dst$$Register, $src1$$Register, $src2$$Register, false); 7018 %} 7019 ins_pipe(ialu_reg_reg); 7020 %} 7021 7022 instruct addI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 7023 %{ 7024 predicate(!UseAPX); 7025 match(Set dst (AddI dst src)); 7026 effect(KILL cr); 7027 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); 7028 7029 format %{ "addl $dst, $src\t# int" %} 7030 ins_encode %{ 7031 __ addl($dst$$Register, $src$$constant); 7032 %} 7033 ins_pipe( ialu_reg ); 7034 %} 7035 7036 instruct addI_rReg_rReg_imm_ndd(rRegI dst, rRegI src1, immI src2, rFlagsReg cr) 7037 %{ 7038 predicate(UseAPX); 7039 match(Set dst (AddI src1 src2)); 7040 effect(KILL cr); 7041 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); 7042 7043 format %{ "eaddl $dst, $src1, $src2\t# int ndd" %} 7044 ins_encode %{ 7045 __ eaddl($dst$$Register, $src1$$Register, $src2$$constant, false); 7046 %} 7047 ins_pipe( ialu_reg ); 7048 %} 7049 7050 instruct addI_rReg_mem_imm_ndd(rRegI dst, memory src1, immI src2, rFlagsReg cr) 7051 %{ 7052 predicate(UseAPX); 7053 match(Set dst (AddI (LoadI src1) src2)); 7054 effect(KILL cr); 7055 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); 7056 7057 format %{ "eaddl $dst, $src1, $src2\t# int ndd" %} 7058 ins_encode %{ 7059 __ eaddl($dst$$Register, $src1$$Address, $src2$$constant, false); 7060 %} 7061 ins_pipe( ialu_reg ); 7062 %} 7063 7064 instruct addI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 7065 %{ 7066 predicate(!UseAPX); 7067 match(Set dst (AddI dst (LoadI src))); 7068 effect(KILL cr); 7069 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); 7070 7071 ins_cost(150); // XXX 7072 format %{ "addl $dst, $src\t# int" %} 7073 ins_encode %{ 7074 __ addl($dst$$Register, $src$$Address); 7075 %} 7076 ins_pipe(ialu_reg_mem); 7077 %} 7078 7079 instruct addI_rReg_mem_rReg_ndd(rRegI dst, memory src1, rRegI src2, rFlagsReg cr) 7080 %{ 7081 predicate(UseAPX); 7082 match(Set dst (AddI (LoadI src1) src2)); 7083 effect(KILL cr); 7084 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); 7085 7086 ins_cost(150); 7087 format %{ "eaddl $dst, $src1, $src2\t# int ndd" %} 7088 ins_encode %{ 7089 __ eaddl($dst$$Register, $src1$$Address, $src2$$Register, false); 7090 %} 7091 ins_pipe(ialu_reg_mem); 7092 %} 7093 7094 instruct addI_rReg_rReg_mem_ndd(rRegI dst, rRegI src1, memory src2, rFlagsReg cr) 7095 %{ 7096 predicate(UseAPX); 7097 match(Set dst (AddI src1 (LoadI src2))); 7098 effect(KILL cr); 7099 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); 7100 7101 ins_cost(150); 7102 format %{ "eaddl $dst, $src1, $src2\t# int ndd" %} 7103 ins_encode %{ 7104 __ eaddl($dst$$Register, $src1$$Register, $src2$$Address, false); 7105 %} 7106 ins_pipe(ialu_reg_mem); 7107 %} 7108 7109 instruct addI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 7110 %{ 7111 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7112 effect(KILL cr); 7113 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); 7114 7115 ins_cost(150); // XXX 7116 format %{ "addl $dst, $src\t# int" %} 7117 ins_encode %{ 7118 __ addl($dst$$Address, $src$$Register); 7119 %} 7120 ins_pipe(ialu_mem_reg); 7121 %} 7122 7123 instruct addI_mem_imm(memory dst, immI src, rFlagsReg cr) 7124 %{ 7125 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7126 effect(KILL cr); 7127 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); 7128 7129 7130 ins_cost(125); // XXX 7131 format %{ "addl $dst, $src\t# int" %} 7132 ins_encode %{ 7133 __ addl($dst$$Address, $src$$constant); 7134 %} 7135 ins_pipe(ialu_mem_imm); 7136 %} 7137 7138 instruct incI_rReg(rRegI dst, immI_1 src, rFlagsReg cr) 7139 %{ 7140 predicate(!UseAPX && UseIncDec); 7141 match(Set dst (AddI dst src)); 7142 effect(KILL cr); 7143 7144 format %{ "incl $dst\t# int" %} 7145 ins_encode %{ 7146 __ incrementl($dst$$Register); 7147 %} 7148 ins_pipe(ialu_reg); 7149 %} 7150 7151 instruct incI_rReg_ndd(rRegI dst, rRegI src, immI_1 val, rFlagsReg cr) 7152 %{ 7153 predicate(UseAPX && UseIncDec); 7154 match(Set dst (AddI src val)); 7155 effect(KILL cr); 7156 7157 format %{ "eincl $dst, $src\t# int ndd" %} 7158 ins_encode %{ 7159 __ eincl($dst$$Register, $src$$Register, false); 7160 %} 7161 ins_pipe(ialu_reg); 7162 %} 7163 7164 instruct incI_rReg_mem_ndd(rRegI dst, memory src, immI_1 val, rFlagsReg cr) 7165 %{ 7166 predicate(UseAPX && UseIncDec); 7167 match(Set dst (AddI (LoadI src) val)); 7168 effect(KILL cr); 7169 7170 format %{ "eincl $dst, $src\t# int ndd" %} 7171 ins_encode %{ 7172 __ eincl($dst$$Register, $src$$Address, false); 7173 %} 7174 ins_pipe(ialu_reg); 7175 %} 7176 7177 instruct incI_mem(memory dst, immI_1 src, rFlagsReg cr) 7178 %{ 7179 predicate(UseIncDec); 7180 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7181 effect(KILL cr); 7182 7183 ins_cost(125); // XXX 7184 format %{ "incl $dst\t# int" %} 7185 ins_encode %{ 7186 __ incrementl($dst$$Address); 7187 %} 7188 ins_pipe(ialu_mem_imm); 7189 %} 7190 7191 // XXX why does that use AddI 7192 instruct decI_rReg(rRegI dst, immI_M1 src, rFlagsReg cr) 7193 %{ 7194 predicate(!UseAPX && UseIncDec); 7195 match(Set dst (AddI dst src)); 7196 effect(KILL cr); 7197 7198 format %{ "decl $dst\t# int" %} 7199 ins_encode %{ 7200 __ decrementl($dst$$Register); 7201 %} 7202 ins_pipe(ialu_reg); 7203 %} 7204 7205 instruct decI_rReg_ndd(rRegI dst, rRegI src, immI_M1 val, rFlagsReg cr) 7206 %{ 7207 predicate(UseAPX && UseIncDec); 7208 match(Set dst (AddI src val)); 7209 effect(KILL cr); 7210 7211 format %{ "edecl $dst, $src\t# int ndd" %} 7212 ins_encode %{ 7213 __ edecl($dst$$Register, $src$$Register, false); 7214 %} 7215 ins_pipe(ialu_reg); 7216 %} 7217 7218 instruct decI_rReg_mem_ndd(rRegI dst, memory src, immI_M1 val, rFlagsReg cr) 7219 %{ 7220 predicate(UseAPX && UseIncDec); 7221 match(Set dst (AddI (LoadI src) val)); 7222 effect(KILL cr); 7223 7224 format %{ "edecl $dst, $src\t# int ndd" %} 7225 ins_encode %{ 7226 __ edecl($dst$$Register, $src$$Address, false); 7227 %} 7228 ins_pipe(ialu_reg); 7229 %} 7230 7231 // XXX why does that use AddI 7232 instruct decI_mem(memory dst, immI_M1 src, rFlagsReg cr) 7233 %{ 7234 predicate(UseIncDec); 7235 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7236 effect(KILL cr); 7237 7238 ins_cost(125); // XXX 7239 format %{ "decl $dst\t# int" %} 7240 ins_encode %{ 7241 __ decrementl($dst$$Address); 7242 %} 7243 ins_pipe(ialu_mem_imm); 7244 %} 7245 7246 instruct leaI_rReg_immI2_immI(rRegI dst, rRegI index, immI2 scale, immI disp) 7247 %{ 7248 predicate(VM_Version::supports_fast_2op_lea()); 7249 match(Set dst (AddI (LShiftI index scale) disp)); 7250 7251 format %{ "leal $dst, [$index << $scale + $disp]\t# int" %} 7252 ins_encode %{ 7253 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 7254 __ leal($dst$$Register, Address(noreg, $index$$Register, scale, $disp$$constant)); 7255 %} 7256 ins_pipe(ialu_reg_reg); 7257 %} 7258 7259 instruct leaI_rReg_rReg_immI(rRegI dst, rRegI base, rRegI index, immI disp) 7260 %{ 7261 predicate(VM_Version::supports_fast_3op_lea()); 7262 match(Set dst (AddI (AddI base index) disp)); 7263 7264 format %{ "leal $dst, [$base + $index + $disp]\t# int" %} 7265 ins_encode %{ 7266 __ leal($dst$$Register, Address($base$$Register, $index$$Register, Address::times_1, $disp$$constant)); 7267 %} 7268 ins_pipe(ialu_reg_reg); 7269 %} 7270 7271 instruct leaI_rReg_rReg_immI2(rRegI dst, no_rbp_r13_RegI base, rRegI index, immI2 scale) 7272 %{ 7273 predicate(VM_Version::supports_fast_2op_lea()); 7274 match(Set dst (AddI base (LShiftI index scale))); 7275 7276 format %{ "leal $dst, [$base + $index << $scale]\t# int" %} 7277 ins_encode %{ 7278 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 7279 __ leal($dst$$Register, Address($base$$Register, $index$$Register, scale)); 7280 %} 7281 ins_pipe(ialu_reg_reg); 7282 %} 7283 7284 instruct leaI_rReg_rReg_immI2_immI(rRegI dst, rRegI base, rRegI index, immI2 scale, immI disp) 7285 %{ 7286 predicate(VM_Version::supports_fast_3op_lea()); 7287 match(Set dst (AddI (AddI base (LShiftI index scale)) disp)); 7288 7289 format %{ "leal $dst, [$base + $index << $scale + $disp]\t# int" %} 7290 ins_encode %{ 7291 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 7292 __ leal($dst$$Register, Address($base$$Register, $index$$Register, scale, $disp$$constant)); 7293 %} 7294 ins_pipe(ialu_reg_reg); 7295 %} 7296 7297 instruct addL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7298 %{ 7299 predicate(!UseAPX); 7300 match(Set dst (AddL dst src)); 7301 effect(KILL cr); 7302 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); 7303 7304 format %{ "addq $dst, $src\t# long" %} 7305 ins_encode %{ 7306 __ addq($dst$$Register, $src$$Register); 7307 %} 7308 ins_pipe(ialu_reg_reg); 7309 %} 7310 7311 instruct addL_rReg_ndd(rRegL dst, rRegL src1, rRegL src2, rFlagsReg cr) 7312 %{ 7313 predicate(UseAPX); 7314 match(Set dst (AddL src1 src2)); 7315 effect(KILL cr); 7316 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); 7317 7318 format %{ "eaddq $dst, $src1, $src2\t# long ndd" %} 7319 ins_encode %{ 7320 __ eaddq($dst$$Register, $src1$$Register, $src2$$Register, false); 7321 %} 7322 ins_pipe(ialu_reg_reg); 7323 %} 7324 7325 instruct addL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 7326 %{ 7327 predicate(!UseAPX); 7328 match(Set dst (AddL dst src)); 7329 effect(KILL cr); 7330 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); 7331 7332 format %{ "addq $dst, $src\t# long" %} 7333 ins_encode %{ 7334 __ addq($dst$$Register, $src$$constant); 7335 %} 7336 ins_pipe( ialu_reg ); 7337 %} 7338 7339 instruct addL_rReg_rReg_imm_ndd(rRegL dst, rRegL src1, immL32 src2, rFlagsReg cr) 7340 %{ 7341 predicate(UseAPX); 7342 match(Set dst (AddL src1 src2)); 7343 effect(KILL cr); 7344 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); 7345 7346 format %{ "eaddq $dst, $src1, $src2\t# long ndd" %} 7347 ins_encode %{ 7348 __ eaddq($dst$$Register, $src1$$Register, $src2$$constant, false); 7349 %} 7350 ins_pipe( ialu_reg ); 7351 %} 7352 7353 instruct addL_rReg_mem_imm_ndd(rRegL dst, memory src1, immL32 src2, rFlagsReg cr) 7354 %{ 7355 predicate(UseAPX); 7356 match(Set dst (AddL (LoadL src1) src2)); 7357 effect(KILL cr); 7358 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); 7359 7360 format %{ "eaddq $dst, $src1, $src2\t# long ndd" %} 7361 ins_encode %{ 7362 __ eaddq($dst$$Register, $src1$$Address, $src2$$constant, false); 7363 %} 7364 ins_pipe( ialu_reg ); 7365 %} 7366 7367 instruct addL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 7368 %{ 7369 predicate(!UseAPX); 7370 match(Set dst (AddL dst (LoadL src))); 7371 effect(KILL cr); 7372 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); 7373 7374 ins_cost(150); // XXX 7375 format %{ "addq $dst, $src\t# long" %} 7376 ins_encode %{ 7377 __ addq($dst$$Register, $src$$Address); 7378 %} 7379 ins_pipe(ialu_reg_mem); 7380 %} 7381 7382 instruct addL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr) 7383 %{ 7384 predicate(UseAPX); 7385 match(Set dst (AddL src1 (LoadL src2))); 7386 effect(KILL cr); 7387 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); 7388 7389 ins_cost(150); 7390 format %{ "eaddq $dst, $src1, $src2\t# long ndd" %} 7391 ins_encode %{ 7392 __ eaddq($dst$$Register, $src1$$Register, $src2$$Address, false); 7393 %} 7394 ins_pipe(ialu_reg_mem); 7395 %} 7396 7397 instruct addL_rReg_mem_rReg_ndd(rRegL dst, memory src1, rRegL src2, rFlagsReg cr) 7398 %{ 7399 predicate(UseAPX); 7400 match(Set dst (AddL (LoadL src1) src2)); 7401 effect(KILL cr); 7402 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 7403 7404 ins_cost(150); 7405 format %{ "eaddq $dst, $src1, $src2\t# long ndd" %} 7406 ins_encode %{ 7407 __ eaddq($dst$$Register, $src1$$Address, $src2$$Register, false); 7408 %} 7409 ins_pipe(ialu_reg_mem); 7410 %} 7411 7412 instruct addL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 7413 %{ 7414 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7415 effect(KILL cr); 7416 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); 7417 7418 ins_cost(150); // XXX 7419 format %{ "addq $dst, $src\t# long" %} 7420 ins_encode %{ 7421 __ addq($dst$$Address, $src$$Register); 7422 %} 7423 ins_pipe(ialu_mem_reg); 7424 %} 7425 7426 instruct addL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 7427 %{ 7428 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7429 effect(KILL cr); 7430 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); 7431 7432 ins_cost(125); // XXX 7433 format %{ "addq $dst, $src\t# long" %} 7434 ins_encode %{ 7435 __ addq($dst$$Address, $src$$constant); 7436 %} 7437 ins_pipe(ialu_mem_imm); 7438 %} 7439 7440 instruct incL_rReg(rRegL dst, immL1 src, rFlagsReg cr) 7441 %{ 7442 predicate(!UseAPX && UseIncDec); 7443 match(Set dst (AddL dst src)); 7444 effect(KILL cr); 7445 7446 format %{ "incq $dst\t# long" %} 7447 ins_encode %{ 7448 __ incrementq($dst$$Register); 7449 %} 7450 ins_pipe(ialu_reg); 7451 %} 7452 7453 instruct incL_rReg_ndd(rRegL dst, rRegI src, immL1 val, rFlagsReg cr) 7454 %{ 7455 predicate(UseAPX && UseIncDec); 7456 match(Set dst (AddL src val)); 7457 effect(KILL cr); 7458 7459 format %{ "eincq $dst, $src\t# long ndd" %} 7460 ins_encode %{ 7461 __ eincq($dst$$Register, $src$$Register, false); 7462 %} 7463 ins_pipe(ialu_reg); 7464 %} 7465 7466 instruct incL_rReg_mem_ndd(rRegL dst, memory src, immL1 val, rFlagsReg cr) 7467 %{ 7468 predicate(UseAPX && UseIncDec); 7469 match(Set dst (AddL (LoadL src) val)); 7470 effect(KILL cr); 7471 7472 format %{ "eincq $dst, $src\t# long ndd" %} 7473 ins_encode %{ 7474 __ eincq($dst$$Register, $src$$Address, false); 7475 %} 7476 ins_pipe(ialu_reg); 7477 %} 7478 7479 instruct incL_mem(memory dst, immL1 src, rFlagsReg cr) 7480 %{ 7481 predicate(UseIncDec); 7482 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7483 effect(KILL cr); 7484 7485 ins_cost(125); // XXX 7486 format %{ "incq $dst\t# long" %} 7487 ins_encode %{ 7488 __ incrementq($dst$$Address); 7489 %} 7490 ins_pipe(ialu_mem_imm); 7491 %} 7492 7493 // XXX why does that use AddL 7494 instruct decL_rReg(rRegL dst, immL_M1 src, rFlagsReg cr) 7495 %{ 7496 predicate(!UseAPX && UseIncDec); 7497 match(Set dst (AddL dst src)); 7498 effect(KILL cr); 7499 7500 format %{ "decq $dst\t# long" %} 7501 ins_encode %{ 7502 __ decrementq($dst$$Register); 7503 %} 7504 ins_pipe(ialu_reg); 7505 %} 7506 7507 instruct decL_rReg_ndd(rRegL dst, rRegL src, immL_M1 val, rFlagsReg cr) 7508 %{ 7509 predicate(UseAPX && UseIncDec); 7510 match(Set dst (AddL src val)); 7511 effect(KILL cr); 7512 7513 format %{ "edecq $dst, $src\t# long ndd" %} 7514 ins_encode %{ 7515 __ edecq($dst$$Register, $src$$Register, false); 7516 %} 7517 ins_pipe(ialu_reg); 7518 %} 7519 7520 instruct decL_rReg_mem_ndd(rRegL dst, memory src, immL_M1 val, rFlagsReg cr) 7521 %{ 7522 predicate(UseAPX && UseIncDec); 7523 match(Set dst (AddL (LoadL src) val)); 7524 effect(KILL cr); 7525 7526 format %{ "edecq $dst, $src\t# long ndd" %} 7527 ins_encode %{ 7528 __ edecq($dst$$Register, $src$$Address, false); 7529 %} 7530 ins_pipe(ialu_reg); 7531 %} 7532 7533 // XXX why does that use AddL 7534 instruct decL_mem(memory dst, immL_M1 src, rFlagsReg cr) 7535 %{ 7536 predicate(UseIncDec); 7537 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7538 effect(KILL cr); 7539 7540 ins_cost(125); // XXX 7541 format %{ "decq $dst\t# long" %} 7542 ins_encode %{ 7543 __ decrementq($dst$$Address); 7544 %} 7545 ins_pipe(ialu_mem_imm); 7546 %} 7547 7548 instruct leaL_rReg_immI2_immL32(rRegL dst, rRegL index, immI2 scale, immL32 disp) 7549 %{ 7550 predicate(VM_Version::supports_fast_2op_lea()); 7551 match(Set dst (AddL (LShiftL index scale) disp)); 7552 7553 format %{ "leaq $dst, [$index << $scale + $disp]\t# long" %} 7554 ins_encode %{ 7555 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 7556 __ leaq($dst$$Register, Address(noreg, $index$$Register, scale, $disp$$constant)); 7557 %} 7558 ins_pipe(ialu_reg_reg); 7559 %} 7560 7561 instruct leaL_rReg_rReg_immL32(rRegL dst, rRegL base, rRegL index, immL32 disp) 7562 %{ 7563 predicate(VM_Version::supports_fast_3op_lea()); 7564 match(Set dst (AddL (AddL base index) disp)); 7565 7566 format %{ "leaq $dst, [$base + $index + $disp]\t# long" %} 7567 ins_encode %{ 7568 __ leaq($dst$$Register, Address($base$$Register, $index$$Register, Address::times_1, $disp$$constant)); 7569 %} 7570 ins_pipe(ialu_reg_reg); 7571 %} 7572 7573 instruct leaL_rReg_rReg_immI2(rRegL dst, no_rbp_r13_RegL base, rRegL index, immI2 scale) 7574 %{ 7575 predicate(VM_Version::supports_fast_2op_lea()); 7576 match(Set dst (AddL base (LShiftL index scale))); 7577 7578 format %{ "leaq $dst, [$base + $index << $scale]\t# long" %} 7579 ins_encode %{ 7580 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 7581 __ leaq($dst$$Register, Address($base$$Register, $index$$Register, scale)); 7582 %} 7583 ins_pipe(ialu_reg_reg); 7584 %} 7585 7586 instruct leaL_rReg_rReg_immI2_immL32(rRegL dst, rRegL base, rRegL index, immI2 scale, immL32 disp) 7587 %{ 7588 predicate(VM_Version::supports_fast_3op_lea()); 7589 match(Set dst (AddL (AddL base (LShiftL index scale)) disp)); 7590 7591 format %{ "leaq $dst, [$base + $index << $scale + $disp]\t# long" %} 7592 ins_encode %{ 7593 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 7594 __ leaq($dst$$Register, Address($base$$Register, $index$$Register, scale, $disp$$constant)); 7595 %} 7596 ins_pipe(ialu_reg_reg); 7597 %} 7598 7599 instruct addP_rReg(rRegP dst, rRegL src, rFlagsReg cr) 7600 %{ 7601 match(Set dst (AddP dst src)); 7602 effect(KILL cr); 7603 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); 7604 7605 format %{ "addq $dst, $src\t# ptr" %} 7606 ins_encode %{ 7607 __ addq($dst$$Register, $src$$Register); 7608 %} 7609 ins_pipe(ialu_reg_reg); 7610 %} 7611 7612 instruct addP_rReg_imm(rRegP dst, immL32 src, rFlagsReg cr) 7613 %{ 7614 match(Set dst (AddP dst src)); 7615 effect(KILL cr); 7616 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); 7617 7618 format %{ "addq $dst, $src\t# ptr" %} 7619 ins_encode %{ 7620 __ addq($dst$$Register, $src$$constant); 7621 %} 7622 ins_pipe( ialu_reg ); 7623 %} 7624 7625 // XXX addP mem ops ???? 7626 7627 instruct checkCastPP(rRegP dst) 7628 %{ 7629 match(Set dst (CheckCastPP dst)); 7630 7631 size(0); 7632 format %{ "# checkcastPP of $dst" %} 7633 ins_encode(/* empty encoding */); 7634 ins_pipe(empty); 7635 %} 7636 7637 instruct castPP(rRegP dst) 7638 %{ 7639 match(Set dst (CastPP dst)); 7640 7641 size(0); 7642 format %{ "# castPP of $dst" %} 7643 ins_encode(/* empty encoding */); 7644 ins_pipe(empty); 7645 %} 7646 7647 instruct castII(rRegI dst) 7648 %{ 7649 predicate(VerifyConstraintCasts == 0); 7650 match(Set dst (CastII dst)); 7651 7652 size(0); 7653 format %{ "# castII of $dst" %} 7654 ins_encode(/* empty encoding */); 7655 ins_cost(0); 7656 ins_pipe(empty); 7657 %} 7658 7659 instruct castII_checked(rRegI dst, rFlagsReg cr) 7660 %{ 7661 predicate(VerifyConstraintCasts > 0); 7662 match(Set dst (CastII dst)); 7663 7664 effect(KILL cr); 7665 format %{ "# cast_checked_II $dst" %} 7666 ins_encode %{ 7667 __ verify_int_in_range(_idx, bottom_type()->is_int(), $dst$$Register); 7668 %} 7669 ins_pipe(pipe_slow); 7670 %} 7671 7672 instruct castLL(rRegL dst) 7673 %{ 7674 predicate(VerifyConstraintCasts == 0); 7675 match(Set dst (CastLL dst)); 7676 7677 size(0); 7678 format %{ "# castLL of $dst" %} 7679 ins_encode(/* empty encoding */); 7680 ins_cost(0); 7681 ins_pipe(empty); 7682 %} 7683 7684 instruct castLL_checked_L32(rRegL dst, rFlagsReg cr) 7685 %{ 7686 predicate(VerifyConstraintCasts > 0 && castLL_is_imm32(n)); 7687 match(Set dst (CastLL dst)); 7688 7689 effect(KILL cr); 7690 format %{ "# cast_checked_LL $dst" %} 7691 ins_encode %{ 7692 __ verify_long_in_range(_idx, bottom_type()->is_long(), $dst$$Register, noreg); 7693 %} 7694 ins_pipe(pipe_slow); 7695 %} 7696 7697 instruct castLL_checked(rRegL dst, rRegL tmp, rFlagsReg cr) 7698 %{ 7699 predicate(VerifyConstraintCasts > 0 && !castLL_is_imm32(n)); 7700 match(Set dst (CastLL dst)); 7701 7702 effect(KILL cr, TEMP tmp); 7703 format %{ "# cast_checked_LL $dst\tusing $tmp as TEMP" %} 7704 ins_encode %{ 7705 __ verify_long_in_range(_idx, bottom_type()->is_long(), $dst$$Register, $tmp$$Register); 7706 %} 7707 ins_pipe(pipe_slow); 7708 %} 7709 7710 instruct castFF(regF dst) 7711 %{ 7712 match(Set dst (CastFF dst)); 7713 7714 size(0); 7715 format %{ "# castFF of $dst" %} 7716 ins_encode(/* empty encoding */); 7717 ins_cost(0); 7718 ins_pipe(empty); 7719 %} 7720 7721 instruct castHH(regF dst) 7722 %{ 7723 match(Set dst (CastHH dst)); 7724 7725 size(0); 7726 format %{ "# castHH of $dst" %} 7727 ins_encode(/* empty encoding */); 7728 ins_cost(0); 7729 ins_pipe(empty); 7730 %} 7731 7732 instruct castDD(regD dst) 7733 %{ 7734 match(Set dst (CastDD dst)); 7735 7736 size(0); 7737 format %{ "# castDD of $dst" %} 7738 ins_encode(/* empty encoding */); 7739 ins_cost(0); 7740 ins_pipe(empty); 7741 %} 7742 7743 // XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them 7744 instruct compareAndSwapP(rRegI res, 7745 memory mem_ptr, 7746 rax_RegP oldval, rRegP newval, 7747 rFlagsReg cr) 7748 %{ 7749 predicate(n->as_LoadStore()->barrier_data() == 0); 7750 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); 7751 match(Set res (WeakCompareAndSwapP mem_ptr (Binary oldval newval))); 7752 effect(KILL cr, KILL oldval); 7753 7754 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7755 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7756 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7757 ins_encode %{ 7758 __ lock(); 7759 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7760 __ setcc(Assembler::equal, $res$$Register); 7761 %} 7762 ins_pipe( pipe_cmpxchg ); 7763 %} 7764 7765 instruct compareAndSwapL(rRegI res, 7766 memory mem_ptr, 7767 rax_RegL oldval, rRegL newval, 7768 rFlagsReg cr) 7769 %{ 7770 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval))); 7771 match(Set res (WeakCompareAndSwapL mem_ptr (Binary oldval newval))); 7772 effect(KILL cr, KILL oldval); 7773 7774 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7775 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7776 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7777 ins_encode %{ 7778 __ lock(); 7779 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7780 __ setcc(Assembler::equal, $res$$Register); 7781 %} 7782 ins_pipe( pipe_cmpxchg ); 7783 %} 7784 7785 instruct compareAndSwapI(rRegI res, 7786 memory mem_ptr, 7787 rax_RegI oldval, rRegI newval, 7788 rFlagsReg cr) 7789 %{ 7790 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval))); 7791 match(Set res (WeakCompareAndSwapI mem_ptr (Binary oldval newval))); 7792 effect(KILL cr, KILL oldval); 7793 7794 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7795 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7796 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7797 ins_encode %{ 7798 __ lock(); 7799 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7800 __ setcc(Assembler::equal, $res$$Register); 7801 %} 7802 ins_pipe( pipe_cmpxchg ); 7803 %} 7804 7805 instruct compareAndSwapB(rRegI res, 7806 memory mem_ptr, 7807 rax_RegI oldval, rRegI newval, 7808 rFlagsReg cr) 7809 %{ 7810 match(Set res (CompareAndSwapB mem_ptr (Binary oldval newval))); 7811 match(Set res (WeakCompareAndSwapB mem_ptr (Binary oldval newval))); 7812 effect(KILL cr, KILL oldval); 7813 7814 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7815 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7816 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7817 ins_encode %{ 7818 __ lock(); 7819 __ cmpxchgb($newval$$Register, $mem_ptr$$Address); 7820 __ setcc(Assembler::equal, $res$$Register); 7821 %} 7822 ins_pipe( pipe_cmpxchg ); 7823 %} 7824 7825 instruct compareAndSwapS(rRegI res, 7826 memory mem_ptr, 7827 rax_RegI oldval, rRegI newval, 7828 rFlagsReg cr) 7829 %{ 7830 match(Set res (CompareAndSwapS mem_ptr (Binary oldval newval))); 7831 match(Set res (WeakCompareAndSwapS mem_ptr (Binary oldval newval))); 7832 effect(KILL cr, KILL oldval); 7833 7834 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7835 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7836 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7837 ins_encode %{ 7838 __ lock(); 7839 __ cmpxchgw($newval$$Register, $mem_ptr$$Address); 7840 __ setcc(Assembler::equal, $res$$Register); 7841 %} 7842 ins_pipe( pipe_cmpxchg ); 7843 %} 7844 7845 instruct compareAndSwapN(rRegI res, 7846 memory mem_ptr, 7847 rax_RegN oldval, rRegN newval, 7848 rFlagsReg cr) %{ 7849 predicate(n->as_LoadStore()->barrier_data() == 0); 7850 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval))); 7851 match(Set res (WeakCompareAndSwapN mem_ptr (Binary oldval newval))); 7852 effect(KILL cr, KILL oldval); 7853 7854 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7855 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7856 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7857 ins_encode %{ 7858 __ lock(); 7859 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7860 __ setcc(Assembler::equal, $res$$Register); 7861 %} 7862 ins_pipe( pipe_cmpxchg ); 7863 %} 7864 7865 instruct compareAndExchangeB( 7866 memory mem_ptr, 7867 rax_RegI oldval, rRegI newval, 7868 rFlagsReg cr) 7869 %{ 7870 match(Set oldval (CompareAndExchangeB mem_ptr (Binary oldval newval))); 7871 effect(KILL cr); 7872 7873 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7874 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7875 ins_encode %{ 7876 __ lock(); 7877 __ cmpxchgb($newval$$Register, $mem_ptr$$Address); 7878 %} 7879 ins_pipe( pipe_cmpxchg ); 7880 %} 7881 7882 instruct compareAndExchangeS( 7883 memory mem_ptr, 7884 rax_RegI oldval, rRegI newval, 7885 rFlagsReg cr) 7886 %{ 7887 match(Set oldval (CompareAndExchangeS mem_ptr (Binary oldval newval))); 7888 effect(KILL cr); 7889 7890 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7891 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7892 ins_encode %{ 7893 __ lock(); 7894 __ cmpxchgw($newval$$Register, $mem_ptr$$Address); 7895 %} 7896 ins_pipe( pipe_cmpxchg ); 7897 %} 7898 7899 instruct compareAndExchangeI( 7900 memory mem_ptr, 7901 rax_RegI oldval, rRegI newval, 7902 rFlagsReg cr) 7903 %{ 7904 match(Set oldval (CompareAndExchangeI mem_ptr (Binary oldval newval))); 7905 effect(KILL cr); 7906 7907 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7908 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7909 ins_encode %{ 7910 __ lock(); 7911 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7912 %} 7913 ins_pipe( pipe_cmpxchg ); 7914 %} 7915 7916 instruct compareAndExchangeL( 7917 memory mem_ptr, 7918 rax_RegL oldval, rRegL newval, 7919 rFlagsReg cr) 7920 %{ 7921 match(Set oldval (CompareAndExchangeL mem_ptr (Binary oldval newval))); 7922 effect(KILL cr); 7923 7924 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7925 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7926 ins_encode %{ 7927 __ lock(); 7928 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7929 %} 7930 ins_pipe( pipe_cmpxchg ); 7931 %} 7932 7933 instruct compareAndExchangeN( 7934 memory mem_ptr, 7935 rax_RegN oldval, rRegN newval, 7936 rFlagsReg cr) %{ 7937 predicate(n->as_LoadStore()->barrier_data() == 0); 7938 match(Set oldval (CompareAndExchangeN mem_ptr (Binary oldval newval))); 7939 effect(KILL cr); 7940 7941 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7942 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7943 ins_encode %{ 7944 __ lock(); 7945 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7946 %} 7947 ins_pipe( pipe_cmpxchg ); 7948 %} 7949 7950 instruct compareAndExchangeP( 7951 memory mem_ptr, 7952 rax_RegP oldval, rRegP newval, 7953 rFlagsReg cr) 7954 %{ 7955 predicate(n->as_LoadStore()->barrier_data() == 0); 7956 match(Set oldval (CompareAndExchangeP mem_ptr (Binary oldval newval))); 7957 effect(KILL cr); 7958 7959 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7960 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7961 ins_encode %{ 7962 __ lock(); 7963 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7964 %} 7965 ins_pipe( pipe_cmpxchg ); 7966 %} 7967 7968 instruct xaddB_reg_no_res(memory mem, Universe dummy, rRegI add, rFlagsReg cr) %{ 7969 predicate(n->as_LoadStore()->result_not_used()); 7970 match(Set dummy (GetAndAddB mem add)); 7971 effect(KILL cr); 7972 format %{ "addb_lock $mem, $add" %} 7973 ins_encode %{ 7974 __ lock(); 7975 __ addb($mem$$Address, $add$$Register); 7976 %} 7977 ins_pipe(pipe_cmpxchg); 7978 %} 7979 7980 instruct xaddB_imm_no_res(memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7981 predicate(n->as_LoadStore()->result_not_used()); 7982 match(Set dummy (GetAndAddB mem add)); 7983 effect(KILL cr); 7984 format %{ "addb_lock $mem, $add" %} 7985 ins_encode %{ 7986 __ lock(); 7987 __ addb($mem$$Address, $add$$constant); 7988 %} 7989 ins_pipe(pipe_cmpxchg); 7990 %} 7991 7992 instruct xaddB(memory mem, rRegI newval, rFlagsReg cr) %{ 7993 predicate(!n->as_LoadStore()->result_not_used()); 7994 match(Set newval (GetAndAddB mem newval)); 7995 effect(KILL cr); 7996 format %{ "xaddb_lock $mem, $newval" %} 7997 ins_encode %{ 7998 __ lock(); 7999 __ xaddb($mem$$Address, $newval$$Register); 8000 %} 8001 ins_pipe(pipe_cmpxchg); 8002 %} 8003 8004 instruct xaddS_reg_no_res(memory mem, Universe dummy, rRegI add, rFlagsReg cr) %{ 8005 predicate(n->as_LoadStore()->result_not_used()); 8006 match(Set dummy (GetAndAddS mem add)); 8007 effect(KILL cr); 8008 format %{ "addw_lock $mem, $add" %} 8009 ins_encode %{ 8010 __ lock(); 8011 __ addw($mem$$Address, $add$$Register); 8012 %} 8013 ins_pipe(pipe_cmpxchg); 8014 %} 8015 8016 instruct xaddS_imm_no_res(memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 8017 predicate(UseStoreImmI16 && n->as_LoadStore()->result_not_used()); 8018 match(Set dummy (GetAndAddS mem add)); 8019 effect(KILL cr); 8020 format %{ "addw_lock $mem, $add" %} 8021 ins_encode %{ 8022 __ lock(); 8023 __ addw($mem$$Address, $add$$constant); 8024 %} 8025 ins_pipe(pipe_cmpxchg); 8026 %} 8027 8028 instruct xaddS(memory mem, rRegI newval, rFlagsReg cr) %{ 8029 predicate(!n->as_LoadStore()->result_not_used()); 8030 match(Set newval (GetAndAddS mem newval)); 8031 effect(KILL cr); 8032 format %{ "xaddw_lock $mem, $newval" %} 8033 ins_encode %{ 8034 __ lock(); 8035 __ xaddw($mem$$Address, $newval$$Register); 8036 %} 8037 ins_pipe(pipe_cmpxchg); 8038 %} 8039 8040 instruct xaddI_reg_no_res(memory mem, Universe dummy, rRegI add, rFlagsReg cr) %{ 8041 predicate(n->as_LoadStore()->result_not_used()); 8042 match(Set dummy (GetAndAddI mem add)); 8043 effect(KILL cr); 8044 format %{ "addl_lock $mem, $add" %} 8045 ins_encode %{ 8046 __ lock(); 8047 __ addl($mem$$Address, $add$$Register); 8048 %} 8049 ins_pipe(pipe_cmpxchg); 8050 %} 8051 8052 instruct xaddI_imm_no_res(memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 8053 predicate(n->as_LoadStore()->result_not_used()); 8054 match(Set dummy (GetAndAddI mem add)); 8055 effect(KILL cr); 8056 format %{ "addl_lock $mem, $add" %} 8057 ins_encode %{ 8058 __ lock(); 8059 __ addl($mem$$Address, $add$$constant); 8060 %} 8061 ins_pipe(pipe_cmpxchg); 8062 %} 8063 8064 instruct xaddI(memory mem, rRegI newval, rFlagsReg cr) %{ 8065 predicate(!n->as_LoadStore()->result_not_used()); 8066 match(Set newval (GetAndAddI mem newval)); 8067 effect(KILL cr); 8068 format %{ "xaddl_lock $mem, $newval" %} 8069 ins_encode %{ 8070 __ lock(); 8071 __ xaddl($mem$$Address, $newval$$Register); 8072 %} 8073 ins_pipe(pipe_cmpxchg); 8074 %} 8075 8076 instruct xaddL_reg_no_res(memory mem, Universe dummy, rRegL add, rFlagsReg cr) %{ 8077 predicate(n->as_LoadStore()->result_not_used()); 8078 match(Set dummy (GetAndAddL mem add)); 8079 effect(KILL cr); 8080 format %{ "addq_lock $mem, $add" %} 8081 ins_encode %{ 8082 __ lock(); 8083 __ addq($mem$$Address, $add$$Register); 8084 %} 8085 ins_pipe(pipe_cmpxchg); 8086 %} 8087 8088 instruct xaddL_imm_no_res(memory mem, Universe dummy, immL32 add, rFlagsReg cr) %{ 8089 predicate(n->as_LoadStore()->result_not_used()); 8090 match(Set dummy (GetAndAddL mem add)); 8091 effect(KILL cr); 8092 format %{ "addq_lock $mem, $add" %} 8093 ins_encode %{ 8094 __ lock(); 8095 __ addq($mem$$Address, $add$$constant); 8096 %} 8097 ins_pipe(pipe_cmpxchg); 8098 %} 8099 8100 instruct xaddL(memory mem, rRegL newval, rFlagsReg cr) %{ 8101 predicate(!n->as_LoadStore()->result_not_used()); 8102 match(Set newval (GetAndAddL mem newval)); 8103 effect(KILL cr); 8104 format %{ "xaddq_lock $mem, $newval" %} 8105 ins_encode %{ 8106 __ lock(); 8107 __ xaddq($mem$$Address, $newval$$Register); 8108 %} 8109 ins_pipe(pipe_cmpxchg); 8110 %} 8111 8112 instruct xchgB( memory mem, rRegI newval) %{ 8113 match(Set newval (GetAndSetB mem newval)); 8114 format %{ "XCHGB $newval,[$mem]" %} 8115 ins_encode %{ 8116 __ xchgb($newval$$Register, $mem$$Address); 8117 %} 8118 ins_pipe( pipe_cmpxchg ); 8119 %} 8120 8121 instruct xchgS( memory mem, rRegI newval) %{ 8122 match(Set newval (GetAndSetS mem newval)); 8123 format %{ "XCHGW $newval,[$mem]" %} 8124 ins_encode %{ 8125 __ xchgw($newval$$Register, $mem$$Address); 8126 %} 8127 ins_pipe( pipe_cmpxchg ); 8128 %} 8129 8130 instruct xchgI( memory mem, rRegI newval) %{ 8131 match(Set newval (GetAndSetI mem newval)); 8132 format %{ "XCHGL $newval,[$mem]" %} 8133 ins_encode %{ 8134 __ xchgl($newval$$Register, $mem$$Address); 8135 %} 8136 ins_pipe( pipe_cmpxchg ); 8137 %} 8138 8139 instruct xchgL( memory mem, rRegL newval) %{ 8140 match(Set newval (GetAndSetL mem newval)); 8141 format %{ "XCHGL $newval,[$mem]" %} 8142 ins_encode %{ 8143 __ xchgq($newval$$Register, $mem$$Address); 8144 %} 8145 ins_pipe( pipe_cmpxchg ); 8146 %} 8147 8148 instruct xchgP( memory mem, rRegP newval) %{ 8149 match(Set newval (GetAndSetP mem newval)); 8150 predicate(n->as_LoadStore()->barrier_data() == 0); 8151 format %{ "XCHGQ $newval,[$mem]" %} 8152 ins_encode %{ 8153 __ xchgq($newval$$Register, $mem$$Address); 8154 %} 8155 ins_pipe( pipe_cmpxchg ); 8156 %} 8157 8158 instruct xchgN( memory mem, rRegN newval) %{ 8159 predicate(n->as_LoadStore()->barrier_data() == 0); 8160 match(Set newval (GetAndSetN mem newval)); 8161 format %{ "XCHGL $newval,$mem]" %} 8162 ins_encode %{ 8163 __ xchgl($newval$$Register, $mem$$Address); 8164 %} 8165 ins_pipe( pipe_cmpxchg ); 8166 %} 8167 8168 //----------Abs Instructions------------------------------------------- 8169 8170 // Integer Absolute Instructions 8171 instruct absI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8172 %{ 8173 match(Set dst (AbsI src)); 8174 effect(TEMP dst, KILL cr); 8175 format %{ "xorl $dst, $dst\t# abs int\n\t" 8176 "subl $dst, $src\n\t" 8177 "cmovll $dst, $src" %} 8178 ins_encode %{ 8179 __ xorl($dst$$Register, $dst$$Register); 8180 __ subl($dst$$Register, $src$$Register); 8181 __ cmovl(Assembler::less, $dst$$Register, $src$$Register); 8182 %} 8183 8184 ins_pipe(ialu_reg_reg); 8185 %} 8186 8187 // Long Absolute Instructions 8188 instruct absL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 8189 %{ 8190 match(Set dst (AbsL src)); 8191 effect(TEMP dst, KILL cr); 8192 format %{ "xorl $dst, $dst\t# abs long\n\t" 8193 "subq $dst, $src\n\t" 8194 "cmovlq $dst, $src" %} 8195 ins_encode %{ 8196 __ xorl($dst$$Register, $dst$$Register); 8197 __ subq($dst$$Register, $src$$Register); 8198 __ cmovq(Assembler::less, $dst$$Register, $src$$Register); 8199 %} 8200 8201 ins_pipe(ialu_reg_reg); 8202 %} 8203 8204 //----------Subtraction Instructions------------------------------------------- 8205 8206 // Integer Subtraction Instructions 8207 instruct subI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8208 %{ 8209 predicate(!UseAPX); 8210 match(Set dst (SubI dst src)); 8211 effect(KILL cr); 8212 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); 8213 8214 format %{ "subl $dst, $src\t# int" %} 8215 ins_encode %{ 8216 __ subl($dst$$Register, $src$$Register); 8217 %} 8218 ins_pipe(ialu_reg_reg); 8219 %} 8220 8221 instruct subI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr) 8222 %{ 8223 predicate(UseAPX); 8224 match(Set dst (SubI src1 src2)); 8225 effect(KILL cr); 8226 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); 8227 8228 format %{ "esubl $dst, $src1, $src2\t# int ndd" %} 8229 ins_encode %{ 8230 __ esubl($dst$$Register, $src1$$Register, $src2$$Register, false); 8231 %} 8232 ins_pipe(ialu_reg_reg); 8233 %} 8234 8235 instruct subI_rReg_rReg_imm_ndd(rRegI dst, rRegI src1, immI src2, rFlagsReg cr) 8236 %{ 8237 predicate(UseAPX); 8238 match(Set dst (SubI src1 src2)); 8239 effect(KILL cr); 8240 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); 8241 8242 format %{ "esubl $dst, $src1, $src2\t# int ndd" %} 8243 ins_encode %{ 8244 __ esubl($dst$$Register, $src1$$Register, $src2$$constant, false); 8245 %} 8246 ins_pipe(ialu_reg_reg); 8247 %} 8248 8249 instruct subI_rReg_mem_imm_ndd(rRegI dst, memory src1, immI src2, rFlagsReg cr) 8250 %{ 8251 predicate(UseAPX); 8252 match(Set dst (SubI (LoadI src1) src2)); 8253 effect(KILL cr); 8254 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); 8255 8256 format %{ "esubl $dst, $src1, $src2\t# int ndd" %} 8257 ins_encode %{ 8258 __ esubl($dst$$Register, $src1$$Address, $src2$$constant, false); 8259 %} 8260 ins_pipe(ialu_reg_reg); 8261 %} 8262 8263 instruct subI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 8264 %{ 8265 predicate(!UseAPX); 8266 match(Set dst (SubI dst (LoadI src))); 8267 effect(KILL cr); 8268 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); 8269 8270 ins_cost(150); 8271 format %{ "subl $dst, $src\t# int" %} 8272 ins_encode %{ 8273 __ subl($dst$$Register, $src$$Address); 8274 %} 8275 ins_pipe(ialu_reg_mem); 8276 %} 8277 8278 instruct subI_rReg_rReg_mem_ndd(rRegI dst, rRegI src1, memory src2, rFlagsReg cr) 8279 %{ 8280 predicate(UseAPX); 8281 match(Set dst (SubI src1 (LoadI src2))); 8282 effect(KILL cr); 8283 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 8284 8285 ins_cost(150); 8286 format %{ "esubl $dst, $src1, $src2\t# int ndd" %} 8287 ins_encode %{ 8288 __ esubl($dst$$Register, $src1$$Register, $src2$$Address, false); 8289 %} 8290 ins_pipe(ialu_reg_mem); 8291 %} 8292 8293 instruct subI_rReg_mem_rReg_ndd(rRegI dst, memory src1, rRegI src2, rFlagsReg cr) 8294 %{ 8295 predicate(UseAPX); 8296 match(Set dst (SubI (LoadI src1) src2)); 8297 effect(KILL cr); 8298 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 8299 8300 ins_cost(150); 8301 format %{ "esubl $dst, $src1, $src2\t# int ndd" %} 8302 ins_encode %{ 8303 __ esubl($dst$$Register, $src1$$Address, $src2$$Register, false); 8304 %} 8305 ins_pipe(ialu_reg_mem); 8306 %} 8307 8308 instruct subI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 8309 %{ 8310 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 8311 effect(KILL cr); 8312 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); 8313 8314 ins_cost(150); 8315 format %{ "subl $dst, $src\t# int" %} 8316 ins_encode %{ 8317 __ subl($dst$$Address, $src$$Register); 8318 %} 8319 ins_pipe(ialu_mem_reg); 8320 %} 8321 8322 instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 8323 %{ 8324 predicate(!UseAPX); 8325 match(Set dst (SubL dst src)); 8326 effect(KILL cr); 8327 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 8328 8329 format %{ "subq $dst, $src\t# long" %} 8330 ins_encode %{ 8331 __ subq($dst$$Register, $src$$Register); 8332 %} 8333 ins_pipe(ialu_reg_reg); 8334 %} 8335 8336 instruct subL_rReg_ndd(rRegL dst, rRegL src1, rRegL src2, rFlagsReg cr) 8337 %{ 8338 predicate(UseAPX); 8339 match(Set dst (SubL src1 src2)); 8340 effect(KILL cr); 8341 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); 8342 8343 format %{ "esubq $dst, $src1, $src2\t# long ndd" %} 8344 ins_encode %{ 8345 __ esubq($dst$$Register, $src1$$Register, $src2$$Register, false); 8346 %} 8347 ins_pipe(ialu_reg_reg); 8348 %} 8349 8350 instruct subL_rReg_rReg_imm_ndd(rRegL dst, rRegL src1, immL32 src2, rFlagsReg cr) 8351 %{ 8352 predicate(UseAPX); 8353 match(Set dst (SubL src1 src2)); 8354 effect(KILL cr); 8355 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); 8356 8357 format %{ "esubq $dst, $src1, $src2\t# long ndd" %} 8358 ins_encode %{ 8359 __ esubq($dst$$Register, $src1$$Register, $src2$$constant, false); 8360 %} 8361 ins_pipe(ialu_reg_reg); 8362 %} 8363 8364 instruct subL_rReg_mem_imm_ndd(rRegL dst, memory src1, immL32 src2, rFlagsReg cr) 8365 %{ 8366 predicate(UseAPX); 8367 match(Set dst (SubL (LoadL src1) src2)); 8368 effect(KILL cr); 8369 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); 8370 8371 format %{ "esubq $dst, $src1, $src2\t# long ndd" %} 8372 ins_encode %{ 8373 __ esubq($dst$$Register, $src1$$Address, $src2$$constant, false); 8374 %} 8375 ins_pipe(ialu_reg_reg); 8376 %} 8377 8378 instruct subL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 8379 %{ 8380 predicate(!UseAPX); 8381 match(Set dst (SubL dst (LoadL src))); 8382 effect(KILL cr); 8383 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); 8384 8385 ins_cost(150); 8386 format %{ "subq $dst, $src\t# long" %} 8387 ins_encode %{ 8388 __ subq($dst$$Register, $src$$Address); 8389 %} 8390 ins_pipe(ialu_reg_mem); 8391 %} 8392 8393 instruct subL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr) 8394 %{ 8395 predicate(UseAPX); 8396 match(Set dst (SubL src1 (LoadL src2))); 8397 effect(KILL cr); 8398 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 8399 8400 ins_cost(150); 8401 format %{ "esubq $dst, $src1, $src2\t# long ndd" %} 8402 ins_encode %{ 8403 __ esubq($dst$$Register, $src1$$Register, $src2$$Address, false); 8404 %} 8405 ins_pipe(ialu_reg_mem); 8406 %} 8407 8408 instruct subL_rReg_mem_rReg_ndd(rRegL dst, memory src1, rRegL src2, rFlagsReg cr) 8409 %{ 8410 predicate(UseAPX); 8411 match(Set dst (SubL (LoadL src1) src2)); 8412 effect(KILL cr); 8413 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 8414 8415 ins_cost(150); 8416 format %{ "esubq $dst, $src1, $src2\t# long ndd" %} 8417 ins_encode %{ 8418 __ esubq($dst$$Register, $src1$$Address, $src2$$Register, false); 8419 %} 8420 ins_pipe(ialu_reg_mem); 8421 %} 8422 8423 instruct subL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 8424 %{ 8425 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 8426 effect(KILL cr); 8427 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); 8428 8429 ins_cost(150); 8430 format %{ "subq $dst, $src\t# long" %} 8431 ins_encode %{ 8432 __ subq($dst$$Address, $src$$Register); 8433 %} 8434 ins_pipe(ialu_mem_reg); 8435 %} 8436 8437 // Subtract from a pointer 8438 // XXX hmpf??? 8439 instruct subP_rReg(rRegP dst, rRegI src, immI_0 zero, rFlagsReg cr) 8440 %{ 8441 match(Set dst (AddP dst (SubI zero src))); 8442 effect(KILL cr); 8443 8444 format %{ "subq $dst, $src\t# ptr - int" %} 8445 ins_encode %{ 8446 __ subq($dst$$Register, $src$$Register); 8447 %} 8448 ins_pipe(ialu_reg_reg); 8449 %} 8450 8451 instruct negI_rReg(rRegI dst, immI_0 zero, rFlagsReg cr) 8452 %{ 8453 predicate(!UseAPX); 8454 match(Set dst (SubI zero dst)); 8455 effect(KILL cr); 8456 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8457 8458 format %{ "negl $dst\t# int" %} 8459 ins_encode %{ 8460 __ negl($dst$$Register); 8461 %} 8462 ins_pipe(ialu_reg); 8463 %} 8464 8465 instruct negI_rReg_ndd(rRegI dst, rRegI src, immI_0 zero, rFlagsReg cr) 8466 %{ 8467 predicate(UseAPX); 8468 match(Set dst (SubI zero src)); 8469 effect(KILL cr); 8470 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8471 8472 format %{ "enegl $dst, $src\t# int ndd" %} 8473 ins_encode %{ 8474 __ enegl($dst$$Register, $src$$Register, false); 8475 %} 8476 ins_pipe(ialu_reg); 8477 %} 8478 8479 instruct negI_rReg_2(rRegI dst, rFlagsReg cr) 8480 %{ 8481 predicate(!UseAPX); 8482 match(Set dst (NegI dst)); 8483 effect(KILL cr); 8484 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8485 8486 format %{ "negl $dst\t# int" %} 8487 ins_encode %{ 8488 __ negl($dst$$Register); 8489 %} 8490 ins_pipe(ialu_reg); 8491 %} 8492 8493 instruct negI_rReg_2_ndd(rRegI dst, rRegI src, rFlagsReg cr) 8494 %{ 8495 predicate(UseAPX); 8496 match(Set dst (NegI src)); 8497 effect(KILL cr); 8498 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8499 8500 format %{ "enegl $dst, $src\t# int ndd" %} 8501 ins_encode %{ 8502 __ enegl($dst$$Register, $src$$Register, false); 8503 %} 8504 ins_pipe(ialu_reg); 8505 %} 8506 8507 instruct negI_mem(memory dst, immI_0 zero, rFlagsReg cr) 8508 %{ 8509 match(Set dst (StoreI dst (SubI zero (LoadI dst)))); 8510 effect(KILL cr); 8511 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8512 8513 format %{ "negl $dst\t# int" %} 8514 ins_encode %{ 8515 __ negl($dst$$Address); 8516 %} 8517 ins_pipe(ialu_reg); 8518 %} 8519 8520 instruct negL_rReg(rRegL dst, immL0 zero, rFlagsReg cr) 8521 %{ 8522 predicate(!UseAPX); 8523 match(Set dst (SubL zero dst)); 8524 effect(KILL cr); 8525 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8526 8527 format %{ "negq $dst\t# long" %} 8528 ins_encode %{ 8529 __ negq($dst$$Register); 8530 %} 8531 ins_pipe(ialu_reg); 8532 %} 8533 8534 instruct negL_rReg_ndd(rRegL dst, rRegL src, immL0 zero, rFlagsReg cr) 8535 %{ 8536 predicate(UseAPX); 8537 match(Set dst (SubL zero src)); 8538 effect(KILL cr); 8539 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8540 8541 format %{ "enegq $dst, $src\t# long ndd" %} 8542 ins_encode %{ 8543 __ enegq($dst$$Register, $src$$Register, false); 8544 %} 8545 ins_pipe(ialu_reg); 8546 %} 8547 8548 instruct negL_rReg_2(rRegL dst, rFlagsReg cr) 8549 %{ 8550 predicate(!UseAPX); 8551 match(Set dst (NegL dst)); 8552 effect(KILL cr); 8553 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8554 8555 format %{ "negq $dst\t# int" %} 8556 ins_encode %{ 8557 __ negq($dst$$Register); 8558 %} 8559 ins_pipe(ialu_reg); 8560 %} 8561 8562 instruct negL_rReg_2_ndd(rRegL dst, rRegL src, rFlagsReg cr) 8563 %{ 8564 predicate(UseAPX); 8565 match(Set dst (NegL src)); 8566 effect(KILL cr); 8567 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8568 8569 format %{ "enegq $dst, $src\t# long ndd" %} 8570 ins_encode %{ 8571 __ enegq($dst$$Register, $src$$Register, false); 8572 %} 8573 ins_pipe(ialu_reg); 8574 %} 8575 8576 instruct negL_mem(memory dst, immL0 zero, rFlagsReg cr) 8577 %{ 8578 match(Set dst (StoreL dst (SubL zero (LoadL dst)))); 8579 effect(KILL cr); 8580 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 8581 8582 format %{ "negq $dst\t# long" %} 8583 ins_encode %{ 8584 __ negq($dst$$Address); 8585 %} 8586 ins_pipe(ialu_reg); 8587 %} 8588 8589 //----------Multiplication/Division Instructions------------------------------- 8590 // Integer Multiplication Instructions 8591 // Multiply Register 8592 8593 instruct mulI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8594 %{ 8595 predicate(!UseAPX); 8596 match(Set dst (MulI dst src)); 8597 effect(KILL cr); 8598 8599 ins_cost(300); 8600 format %{ "imull $dst, $src\t# int" %} 8601 ins_encode %{ 8602 __ imull($dst$$Register, $src$$Register); 8603 %} 8604 ins_pipe(ialu_reg_reg_alu0); 8605 %} 8606 8607 instruct mulI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr) 8608 %{ 8609 predicate(UseAPX); 8610 match(Set dst (MulI src1 src2)); 8611 effect(KILL cr); 8612 8613 ins_cost(300); 8614 format %{ "eimull $dst, $src1, $src2\t# int ndd" %} 8615 ins_encode %{ 8616 __ eimull($dst$$Register, $src1$$Register, $src2$$Register, false); 8617 %} 8618 ins_pipe(ialu_reg_reg_alu0); 8619 %} 8620 8621 instruct mulI_rReg_imm(rRegI dst, rRegI src, immI imm, rFlagsReg cr) 8622 %{ 8623 predicate(!UseAPX); 8624 match(Set dst (MulI src imm)); 8625 effect(KILL cr); 8626 8627 ins_cost(300); 8628 format %{ "imull $dst, $src, $imm\t# int" %} 8629 ins_encode %{ 8630 __ imull($dst$$Register, $src$$Register, $imm$$constant); 8631 %} 8632 ins_pipe(ialu_reg_reg_alu0); 8633 %} 8634 8635 instruct mulI_rReg_rReg_imm_ndd(rRegI dst, rRegI src1, immI src2, rFlagsReg cr) 8636 %{ 8637 predicate(UseAPX); 8638 match(Set dst (MulI src1 src2)); 8639 effect(KILL cr); 8640 8641 ins_cost(300); 8642 format %{ "eimull $dst, $src1, $src2\t# int ndd" %} 8643 ins_encode %{ 8644 __ eimull($dst$$Register, $src1$$Register, $src2$$constant, false); 8645 %} 8646 ins_pipe(ialu_reg_reg_alu0); 8647 %} 8648 8649 instruct mulI_mem(rRegI dst, memory src, rFlagsReg cr) 8650 %{ 8651 predicate(!UseAPX); 8652 match(Set dst (MulI dst (LoadI src))); 8653 effect(KILL cr); 8654 8655 ins_cost(350); 8656 format %{ "imull $dst, $src\t# int" %} 8657 ins_encode %{ 8658 __ imull($dst$$Register, $src$$Address); 8659 %} 8660 ins_pipe(ialu_reg_mem_alu0); 8661 %} 8662 8663 instruct mulI_rReg_rReg_mem_ndd(rRegI dst, rRegI src1, memory src2, rFlagsReg cr) 8664 %{ 8665 predicate(UseAPX); 8666 match(Set dst (MulI src1 (LoadI src2))); 8667 effect(KILL cr); 8668 8669 ins_cost(350); 8670 format %{ "eimull $dst, $src1, $src2\t# int ndd" %} 8671 ins_encode %{ 8672 __ eimull($dst$$Register, $src1$$Register, $src2$$Address, false); 8673 %} 8674 ins_pipe(ialu_reg_mem_alu0); 8675 %} 8676 8677 instruct mulI_mem_imm(rRegI dst, memory src, immI imm, rFlagsReg cr) 8678 %{ 8679 predicate(!UseAPX); 8680 match(Set dst (MulI (LoadI src) imm)); 8681 effect(KILL cr); 8682 8683 ins_cost(300); 8684 format %{ "imull $dst, $src, $imm\t# int" %} 8685 ins_encode %{ 8686 __ imull($dst$$Register, $src$$Address, $imm$$constant); 8687 %} 8688 ins_pipe(ialu_reg_mem_alu0); 8689 %} 8690 8691 instruct mulI_rReg_mem_imm(rRegI dst, memory src1, immI src2, rFlagsReg cr) 8692 %{ 8693 predicate(UseAPX); 8694 match(Set dst (MulI (LoadI src1) src2)); 8695 effect(KILL cr); 8696 8697 ins_cost(300); 8698 format %{ "eimull $dst, $src1, $src2\t# int ndd" %} 8699 ins_encode %{ 8700 __ eimull($dst$$Register, $src1$$Address, $src2$$constant, false); 8701 %} 8702 ins_pipe(ialu_reg_mem_alu0); 8703 %} 8704 8705 instruct mulAddS2I_rReg(rRegI dst, rRegI src1, rRegI src2, rRegI src3, rFlagsReg cr) 8706 %{ 8707 match(Set dst (MulAddS2I (Binary dst src1) (Binary src2 src3))); 8708 effect(KILL cr, KILL src2); 8709 8710 expand %{ mulI_rReg(dst, src1, cr); 8711 mulI_rReg(src2, src3, cr); 8712 addI_rReg(dst, src2, cr); %} 8713 %} 8714 8715 instruct mulL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 8716 %{ 8717 predicate(!UseAPX); 8718 match(Set dst (MulL dst src)); 8719 effect(KILL cr); 8720 8721 ins_cost(300); 8722 format %{ "imulq $dst, $src\t# long" %} 8723 ins_encode %{ 8724 __ imulq($dst$$Register, $src$$Register); 8725 %} 8726 ins_pipe(ialu_reg_reg_alu0); 8727 %} 8728 8729 instruct mulL_rReg_ndd(rRegL dst, rRegL src1, rRegL src2, rFlagsReg cr) 8730 %{ 8731 predicate(UseAPX); 8732 match(Set dst (MulL src1 src2)); 8733 effect(KILL cr); 8734 8735 ins_cost(300); 8736 format %{ "eimulq $dst, $src1, $src2\t# long ndd" %} 8737 ins_encode %{ 8738 __ eimulq($dst$$Register, $src1$$Register, $src2$$Register, false); 8739 %} 8740 ins_pipe(ialu_reg_reg_alu0); 8741 %} 8742 8743 instruct mulL_rReg_imm(rRegL dst, rRegL src, immL32 imm, rFlagsReg cr) 8744 %{ 8745 predicate(!UseAPX); 8746 match(Set dst (MulL src imm)); 8747 effect(KILL cr); 8748 8749 ins_cost(300); 8750 format %{ "imulq $dst, $src, $imm\t# long" %} 8751 ins_encode %{ 8752 __ imulq($dst$$Register, $src$$Register, $imm$$constant); 8753 %} 8754 ins_pipe(ialu_reg_reg_alu0); 8755 %} 8756 8757 instruct mulL_rReg_rReg_imm_ndd(rRegL dst, rRegL src1, immL32 src2, rFlagsReg cr) 8758 %{ 8759 predicate(UseAPX); 8760 match(Set dst (MulL src1 src2)); 8761 effect(KILL cr); 8762 8763 ins_cost(300); 8764 format %{ "eimulq $dst, $src1, $src2\t# long ndd" %} 8765 ins_encode %{ 8766 __ eimulq($dst$$Register, $src1$$Register, $src2$$constant, false); 8767 %} 8768 ins_pipe(ialu_reg_reg_alu0); 8769 %} 8770 8771 instruct mulL_mem(rRegL dst, memory src, rFlagsReg cr) 8772 %{ 8773 predicate(!UseAPX); 8774 match(Set dst (MulL dst (LoadL src))); 8775 effect(KILL cr); 8776 8777 ins_cost(350); 8778 format %{ "imulq $dst, $src\t# long" %} 8779 ins_encode %{ 8780 __ imulq($dst$$Register, $src$$Address); 8781 %} 8782 ins_pipe(ialu_reg_mem_alu0); 8783 %} 8784 8785 instruct mulL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr) 8786 %{ 8787 predicate(UseAPX); 8788 match(Set dst (MulL src1 (LoadL src2))); 8789 effect(KILL cr); 8790 8791 ins_cost(350); 8792 format %{ "eimulq $dst, $src1, $src2 \t# long" %} 8793 ins_encode %{ 8794 __ eimulq($dst$$Register, $src1$$Register, $src2$$Address, false); 8795 %} 8796 ins_pipe(ialu_reg_mem_alu0); 8797 %} 8798 8799 instruct mulL_mem_imm(rRegL dst, memory src, immL32 imm, rFlagsReg cr) 8800 %{ 8801 predicate(!UseAPX); 8802 match(Set dst (MulL (LoadL src) imm)); 8803 effect(KILL cr); 8804 8805 ins_cost(300); 8806 format %{ "imulq $dst, $src, $imm\t# long" %} 8807 ins_encode %{ 8808 __ imulq($dst$$Register, $src$$Address, $imm$$constant); 8809 %} 8810 ins_pipe(ialu_reg_mem_alu0); 8811 %} 8812 8813 instruct mulL_rReg_mem_imm_ndd(rRegL dst, memory src1, immL32 src2, rFlagsReg cr) 8814 %{ 8815 predicate(UseAPX); 8816 match(Set dst (MulL (LoadL src1) src2)); 8817 effect(KILL cr); 8818 8819 ins_cost(300); 8820 format %{ "eimulq $dst, $src1, $src2\t# long ndd" %} 8821 ins_encode %{ 8822 __ eimulq($dst$$Register, $src1$$Address, $src2$$constant, false); 8823 %} 8824 ins_pipe(ialu_reg_mem_alu0); 8825 %} 8826 8827 instruct mulHiL_rReg(rdx_RegL dst, rRegL src, rax_RegL rax, rFlagsReg cr) 8828 %{ 8829 match(Set dst (MulHiL src rax)); 8830 effect(USE_KILL rax, KILL cr); 8831 8832 ins_cost(300); 8833 format %{ "imulq RDX:RAX, RAX, $src\t# mulhi" %} 8834 ins_encode %{ 8835 __ imulq($src$$Register); 8836 %} 8837 ins_pipe(ialu_reg_reg_alu0); 8838 %} 8839 8840 instruct umulHiL_rReg(rdx_RegL dst, rRegL src, rax_RegL rax, rFlagsReg cr) 8841 %{ 8842 match(Set dst (UMulHiL src rax)); 8843 effect(USE_KILL rax, KILL cr); 8844 8845 ins_cost(300); 8846 format %{ "mulq RDX:RAX, RAX, $src\t# umulhi" %} 8847 ins_encode %{ 8848 __ mulq($src$$Register); 8849 %} 8850 ins_pipe(ialu_reg_reg_alu0); 8851 %} 8852 8853 instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 8854 rFlagsReg cr) 8855 %{ 8856 match(Set rax (DivI rax div)); 8857 effect(KILL rdx, KILL cr); 8858 8859 ins_cost(30*100+10*100); // XXX 8860 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 8861 "jne,s normal\n\t" 8862 "xorl rdx, rdx\n\t" 8863 "cmpl $div, -1\n\t" 8864 "je,s done\n" 8865 "normal: cdql\n\t" 8866 "idivl $div\n" 8867 "done:" %} 8868 ins_encode(cdql_enc(div)); 8869 ins_pipe(ialu_reg_reg_alu0); 8870 %} 8871 8872 instruct divL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 8873 rFlagsReg cr) 8874 %{ 8875 match(Set rax (DivL rax div)); 8876 effect(KILL rdx, KILL cr); 8877 8878 ins_cost(30*100+10*100); // XXX 8879 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 8880 "cmpq rax, rdx\n\t" 8881 "jne,s normal\n\t" 8882 "xorl rdx, rdx\n\t" 8883 "cmpq $div, -1\n\t" 8884 "je,s done\n" 8885 "normal: cdqq\n\t" 8886 "idivq $div\n" 8887 "done:" %} 8888 ins_encode(cdqq_enc(div)); 8889 ins_pipe(ialu_reg_reg_alu0); 8890 %} 8891 8892 instruct udivI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, rFlagsReg cr) 8893 %{ 8894 match(Set rax (UDivI rax div)); 8895 effect(KILL rdx, KILL cr); 8896 8897 ins_cost(300); 8898 format %{ "udivl $rax,$rax,$div\t# UDivI\n" %} 8899 ins_encode %{ 8900 __ udivI($rax$$Register, $div$$Register, $rdx$$Register); 8901 %} 8902 ins_pipe(ialu_reg_reg_alu0); 8903 %} 8904 8905 instruct udivL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, rFlagsReg cr) 8906 %{ 8907 match(Set rax (UDivL rax div)); 8908 effect(KILL rdx, KILL cr); 8909 8910 ins_cost(300); 8911 format %{ "udivq $rax,$rax,$div\t# UDivL\n" %} 8912 ins_encode %{ 8913 __ udivL($rax$$Register, $div$$Register, $rdx$$Register); 8914 %} 8915 ins_pipe(ialu_reg_reg_alu0); 8916 %} 8917 8918 // Integer DIVMOD with Register, both quotient and mod results 8919 instruct divModI_rReg_divmod(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 8920 rFlagsReg cr) 8921 %{ 8922 match(DivModI rax div); 8923 effect(KILL cr); 8924 8925 ins_cost(30*100+10*100); // XXX 8926 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 8927 "jne,s normal\n\t" 8928 "xorl rdx, rdx\n\t" 8929 "cmpl $div, -1\n\t" 8930 "je,s done\n" 8931 "normal: cdql\n\t" 8932 "idivl $div\n" 8933 "done:" %} 8934 ins_encode(cdql_enc(div)); 8935 ins_pipe(pipe_slow); 8936 %} 8937 8938 // Long DIVMOD with Register, both quotient and mod results 8939 instruct divModL_rReg_divmod(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 8940 rFlagsReg cr) 8941 %{ 8942 match(DivModL rax div); 8943 effect(KILL cr); 8944 8945 ins_cost(30*100+10*100); // XXX 8946 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 8947 "cmpq rax, rdx\n\t" 8948 "jne,s normal\n\t" 8949 "xorl rdx, rdx\n\t" 8950 "cmpq $div, -1\n\t" 8951 "je,s done\n" 8952 "normal: cdqq\n\t" 8953 "idivq $div\n" 8954 "done:" %} 8955 ins_encode(cdqq_enc(div)); 8956 ins_pipe(pipe_slow); 8957 %} 8958 8959 // Unsigned integer DIVMOD with Register, both quotient and mod results 8960 instruct udivModI_rReg_divmod(rax_RegI rax, no_rax_rdx_RegI tmp, rdx_RegI rdx, 8961 no_rax_rdx_RegI div, rFlagsReg cr) 8962 %{ 8963 match(UDivModI rax div); 8964 effect(TEMP tmp, KILL cr); 8965 8966 ins_cost(300); 8967 format %{ "udivl $rax,$rax,$div\t# begin UDivModI\n\t" 8968 "umodl $rdx,$rax,$div\t! using $tmp as TEMP # end UDivModI\n" 8969 %} 8970 ins_encode %{ 8971 __ udivmodI($rax$$Register, $div$$Register, $rdx$$Register, $tmp$$Register); 8972 %} 8973 ins_pipe(pipe_slow); 8974 %} 8975 8976 // Unsigned long DIVMOD with Register, both quotient and mod results 8977 instruct udivModL_rReg_divmod(rax_RegL rax, no_rax_rdx_RegL tmp, rdx_RegL rdx, 8978 no_rax_rdx_RegL div, rFlagsReg cr) 8979 %{ 8980 match(UDivModL rax div); 8981 effect(TEMP tmp, KILL cr); 8982 8983 ins_cost(300); 8984 format %{ "udivq $rax,$rax,$div\t# begin UDivModL\n\t" 8985 "umodq $rdx,$rax,$div\t! using $tmp as TEMP # end UDivModL\n" 8986 %} 8987 ins_encode %{ 8988 __ udivmodL($rax$$Register, $div$$Register, $rdx$$Register, $tmp$$Register); 8989 %} 8990 ins_pipe(pipe_slow); 8991 %} 8992 8993 instruct modI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, 8994 rFlagsReg cr) 8995 %{ 8996 match(Set rdx (ModI rax div)); 8997 effect(KILL rax, KILL cr); 8998 8999 ins_cost(300); // XXX 9000 format %{ "cmpl rax, 0x80000000\t# irem\n\t" 9001 "jne,s normal\n\t" 9002 "xorl rdx, rdx\n\t" 9003 "cmpl $div, -1\n\t" 9004 "je,s done\n" 9005 "normal: cdql\n\t" 9006 "idivl $div\n" 9007 "done:" %} 9008 ins_encode(cdql_enc(div)); 9009 ins_pipe(ialu_reg_reg_alu0); 9010 %} 9011 9012 instruct modL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, 9013 rFlagsReg cr) 9014 %{ 9015 match(Set rdx (ModL rax div)); 9016 effect(KILL rax, KILL cr); 9017 9018 ins_cost(300); // XXX 9019 format %{ "movq rdx, 0x8000000000000000\t# lrem\n\t" 9020 "cmpq rax, rdx\n\t" 9021 "jne,s normal\n\t" 9022 "xorl rdx, rdx\n\t" 9023 "cmpq $div, -1\n\t" 9024 "je,s done\n" 9025 "normal: cdqq\n\t" 9026 "idivq $div\n" 9027 "done:" %} 9028 ins_encode(cdqq_enc(div)); 9029 ins_pipe(ialu_reg_reg_alu0); 9030 %} 9031 9032 instruct umodI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, rFlagsReg cr) 9033 %{ 9034 match(Set rdx (UModI rax div)); 9035 effect(KILL rax, KILL cr); 9036 9037 ins_cost(300); 9038 format %{ "umodl $rdx,$rax,$div\t# UModI\n" %} 9039 ins_encode %{ 9040 __ umodI($rax$$Register, $div$$Register, $rdx$$Register); 9041 %} 9042 ins_pipe(ialu_reg_reg_alu0); 9043 %} 9044 9045 instruct umodL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, rFlagsReg cr) 9046 %{ 9047 match(Set rdx (UModL rax div)); 9048 effect(KILL rax, KILL cr); 9049 9050 ins_cost(300); 9051 format %{ "umodq $rdx,$rax,$div\t# UModL\n" %} 9052 ins_encode %{ 9053 __ umodL($rax$$Register, $div$$Register, $rdx$$Register); 9054 %} 9055 ins_pipe(ialu_reg_reg_alu0); 9056 %} 9057 9058 // Integer Shift Instructions 9059 // Shift Left by one, two, three 9060 instruct salI_rReg_immI2(rRegI dst, immI2 shift, rFlagsReg cr) 9061 %{ 9062 predicate(!UseAPX); 9063 match(Set dst (LShiftI dst shift)); 9064 effect(KILL cr); 9065 9066 format %{ "sall $dst, $shift" %} 9067 ins_encode %{ 9068 __ sall($dst$$Register, $shift$$constant); 9069 %} 9070 ins_pipe(ialu_reg); 9071 %} 9072 9073 // Shift Left by one, two, three 9074 instruct salI_rReg_immI2_ndd(rRegI dst, rRegI src, immI2 shift, rFlagsReg cr) 9075 %{ 9076 predicate(UseAPX); 9077 match(Set dst (LShiftI src shift)); 9078 effect(KILL cr); 9079 9080 format %{ "esall $dst, $src, $shift\t# int(ndd)" %} 9081 ins_encode %{ 9082 __ esall($dst$$Register, $src$$Register, $shift$$constant, false); 9083 %} 9084 ins_pipe(ialu_reg); 9085 %} 9086 9087 // Shift Left by 8-bit immediate 9088 instruct salI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 9089 %{ 9090 predicate(!UseAPX); 9091 match(Set dst (LShiftI dst shift)); 9092 effect(KILL cr); 9093 9094 format %{ "sall $dst, $shift" %} 9095 ins_encode %{ 9096 __ sall($dst$$Register, $shift$$constant); 9097 %} 9098 ins_pipe(ialu_reg); 9099 %} 9100 9101 // Shift Left by 8-bit immediate 9102 instruct salI_rReg_imm_ndd(rRegI dst, rRegI src, immI8 shift, rFlagsReg cr) 9103 %{ 9104 predicate(UseAPX); 9105 match(Set dst (LShiftI src shift)); 9106 effect(KILL cr); 9107 9108 format %{ "esall $dst, $src, $shift\t# int (ndd)" %} 9109 ins_encode %{ 9110 __ esall($dst$$Register, $src$$Register, $shift$$constant, false); 9111 %} 9112 ins_pipe(ialu_reg); 9113 %} 9114 9115 instruct salI_rReg_mem_imm_ndd(rRegI dst, memory src, immI8 shift, rFlagsReg cr) 9116 %{ 9117 predicate(UseAPX); 9118 match(Set dst (LShiftI (LoadI src) shift)); 9119 effect(KILL cr); 9120 9121 format %{ "esall $dst, $src, $shift\t# int (ndd)" %} 9122 ins_encode %{ 9123 __ esall($dst$$Register, $src$$Address, $shift$$constant, false); 9124 %} 9125 ins_pipe(ialu_reg); 9126 %} 9127 9128 // Shift Left by 8-bit immediate 9129 instruct salI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 9130 %{ 9131 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 9132 effect(KILL cr); 9133 9134 format %{ "sall $dst, $shift" %} 9135 ins_encode %{ 9136 __ sall($dst$$Address, $shift$$constant); 9137 %} 9138 ins_pipe(ialu_mem_imm); 9139 %} 9140 9141 // Shift Left by variable 9142 instruct salI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 9143 %{ 9144 predicate(!VM_Version::supports_bmi2()); 9145 match(Set dst (LShiftI dst shift)); 9146 effect(KILL cr); 9147 9148 format %{ "sall $dst, $shift" %} 9149 ins_encode %{ 9150 __ sall($dst$$Register); 9151 %} 9152 ins_pipe(ialu_reg_reg); 9153 %} 9154 9155 // Shift Left by variable 9156 instruct salI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 9157 %{ 9158 predicate(!VM_Version::supports_bmi2()); 9159 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 9160 effect(KILL cr); 9161 9162 format %{ "sall $dst, $shift" %} 9163 ins_encode %{ 9164 __ sall($dst$$Address); 9165 %} 9166 ins_pipe(ialu_mem_reg); 9167 %} 9168 9169 instruct salI_rReg_rReg(rRegI dst, rRegI src, rRegI shift) 9170 %{ 9171 predicate(VM_Version::supports_bmi2()); 9172 match(Set dst (LShiftI src shift)); 9173 9174 format %{ "shlxl $dst, $src, $shift" %} 9175 ins_encode %{ 9176 __ shlxl($dst$$Register, $src$$Register, $shift$$Register); 9177 %} 9178 ins_pipe(ialu_reg_reg); 9179 %} 9180 9181 instruct salI_mem_rReg(rRegI dst, memory src, rRegI shift) 9182 %{ 9183 predicate(VM_Version::supports_bmi2()); 9184 match(Set dst (LShiftI (LoadI src) shift)); 9185 ins_cost(175); 9186 format %{ "shlxl $dst, $src, $shift" %} 9187 ins_encode %{ 9188 __ shlxl($dst$$Register, $src$$Address, $shift$$Register); 9189 %} 9190 ins_pipe(ialu_reg_mem); 9191 %} 9192 9193 // Arithmetic Shift Right by 8-bit immediate 9194 instruct sarI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 9195 %{ 9196 predicate(!UseAPX); 9197 match(Set dst (RShiftI dst shift)); 9198 effect(KILL cr); 9199 9200 format %{ "sarl $dst, $shift" %} 9201 ins_encode %{ 9202 __ sarl($dst$$Register, $shift$$constant); 9203 %} 9204 ins_pipe(ialu_mem_imm); 9205 %} 9206 9207 // Arithmetic Shift Right by 8-bit immediate 9208 instruct sarI_rReg_imm_ndd(rRegI dst, rRegI src, immI8 shift, rFlagsReg cr) 9209 %{ 9210 predicate(UseAPX); 9211 match(Set dst (RShiftI src shift)); 9212 effect(KILL cr); 9213 9214 format %{ "esarl $dst, $src, $shift\t# int (ndd)" %} 9215 ins_encode %{ 9216 __ esarl($dst$$Register, $src$$Register, $shift$$constant, false); 9217 %} 9218 ins_pipe(ialu_mem_imm); 9219 %} 9220 9221 instruct sarI_rReg_mem_imm_ndd(rRegI dst, memory src, immI8 shift, rFlagsReg cr) 9222 %{ 9223 predicate(UseAPX); 9224 match(Set dst (RShiftI (LoadI src) shift)); 9225 effect(KILL cr); 9226 9227 format %{ "esarl $dst, $src, $shift\t# int (ndd)" %} 9228 ins_encode %{ 9229 __ esarl($dst$$Register, $src$$Address, $shift$$constant, false); 9230 %} 9231 ins_pipe(ialu_mem_imm); 9232 %} 9233 9234 // Arithmetic Shift Right by 8-bit immediate 9235 instruct sarI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 9236 %{ 9237 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 9238 effect(KILL cr); 9239 9240 format %{ "sarl $dst, $shift" %} 9241 ins_encode %{ 9242 __ sarl($dst$$Address, $shift$$constant); 9243 %} 9244 ins_pipe(ialu_mem_imm); 9245 %} 9246 9247 // Arithmetic Shift Right by variable 9248 instruct sarI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 9249 %{ 9250 predicate(!VM_Version::supports_bmi2()); 9251 match(Set dst (RShiftI dst shift)); 9252 effect(KILL cr); 9253 9254 format %{ "sarl $dst, $shift" %} 9255 ins_encode %{ 9256 __ sarl($dst$$Register); 9257 %} 9258 ins_pipe(ialu_reg_reg); 9259 %} 9260 9261 // Arithmetic Shift Right by variable 9262 instruct sarI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 9263 %{ 9264 predicate(!VM_Version::supports_bmi2()); 9265 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 9266 effect(KILL cr); 9267 9268 format %{ "sarl $dst, $shift" %} 9269 ins_encode %{ 9270 __ sarl($dst$$Address); 9271 %} 9272 ins_pipe(ialu_mem_reg); 9273 %} 9274 9275 instruct sarI_rReg_rReg(rRegI dst, rRegI src, rRegI shift) 9276 %{ 9277 predicate(VM_Version::supports_bmi2()); 9278 match(Set dst (RShiftI src shift)); 9279 9280 format %{ "sarxl $dst, $src, $shift" %} 9281 ins_encode %{ 9282 __ sarxl($dst$$Register, $src$$Register, $shift$$Register); 9283 %} 9284 ins_pipe(ialu_reg_reg); 9285 %} 9286 9287 instruct sarI_mem_rReg(rRegI dst, memory src, rRegI shift) 9288 %{ 9289 predicate(VM_Version::supports_bmi2()); 9290 match(Set dst (RShiftI (LoadI src) shift)); 9291 ins_cost(175); 9292 format %{ "sarxl $dst, $src, $shift" %} 9293 ins_encode %{ 9294 __ sarxl($dst$$Register, $src$$Address, $shift$$Register); 9295 %} 9296 ins_pipe(ialu_reg_mem); 9297 %} 9298 9299 // Logical Shift Right by 8-bit immediate 9300 instruct shrI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 9301 %{ 9302 predicate(!UseAPX); 9303 match(Set dst (URShiftI dst shift)); 9304 effect(KILL cr); 9305 9306 format %{ "shrl $dst, $shift" %} 9307 ins_encode %{ 9308 __ shrl($dst$$Register, $shift$$constant); 9309 %} 9310 ins_pipe(ialu_reg); 9311 %} 9312 9313 // Logical Shift Right by 8-bit immediate 9314 instruct shrI_rReg_imm_ndd(rRegI dst, rRegI src, immI8 shift, rFlagsReg cr) 9315 %{ 9316 predicate(UseAPX); 9317 match(Set dst (URShiftI src shift)); 9318 effect(KILL cr); 9319 9320 format %{ "eshrl $dst, $src, $shift\t # int (ndd)" %} 9321 ins_encode %{ 9322 __ eshrl($dst$$Register, $src$$Register, $shift$$constant, false); 9323 %} 9324 ins_pipe(ialu_reg); 9325 %} 9326 9327 instruct shrI_rReg_mem_imm_ndd(rRegI dst, memory src, immI8 shift, rFlagsReg cr) 9328 %{ 9329 predicate(UseAPX); 9330 match(Set dst (URShiftI (LoadI src) shift)); 9331 effect(KILL cr); 9332 9333 format %{ "eshrl $dst, $src, $shift\t # int (ndd)" %} 9334 ins_encode %{ 9335 __ eshrl($dst$$Register, $src$$Address, $shift$$constant, false); 9336 %} 9337 ins_pipe(ialu_reg); 9338 %} 9339 9340 // Logical Shift Right by 8-bit immediate 9341 instruct shrI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 9342 %{ 9343 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 9344 effect(KILL cr); 9345 9346 format %{ "shrl $dst, $shift" %} 9347 ins_encode %{ 9348 __ shrl($dst$$Address, $shift$$constant); 9349 %} 9350 ins_pipe(ialu_mem_imm); 9351 %} 9352 9353 // Logical Shift Right by variable 9354 instruct shrI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 9355 %{ 9356 predicate(!VM_Version::supports_bmi2()); 9357 match(Set dst (URShiftI dst shift)); 9358 effect(KILL cr); 9359 9360 format %{ "shrl $dst, $shift" %} 9361 ins_encode %{ 9362 __ shrl($dst$$Register); 9363 %} 9364 ins_pipe(ialu_reg_reg); 9365 %} 9366 9367 // Logical Shift Right by variable 9368 instruct shrI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 9369 %{ 9370 predicate(!VM_Version::supports_bmi2()); 9371 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 9372 effect(KILL cr); 9373 9374 format %{ "shrl $dst, $shift" %} 9375 ins_encode %{ 9376 __ shrl($dst$$Address); 9377 %} 9378 ins_pipe(ialu_mem_reg); 9379 %} 9380 9381 instruct shrI_rReg_rReg(rRegI dst, rRegI src, rRegI shift) 9382 %{ 9383 predicate(VM_Version::supports_bmi2()); 9384 match(Set dst (URShiftI src shift)); 9385 9386 format %{ "shrxl $dst, $src, $shift" %} 9387 ins_encode %{ 9388 __ shrxl($dst$$Register, $src$$Register, $shift$$Register); 9389 %} 9390 ins_pipe(ialu_reg_reg); 9391 %} 9392 9393 instruct shrI_mem_rReg(rRegI dst, memory src, rRegI shift) 9394 %{ 9395 predicate(VM_Version::supports_bmi2()); 9396 match(Set dst (URShiftI (LoadI src) shift)); 9397 ins_cost(175); 9398 format %{ "shrxl $dst, $src, $shift" %} 9399 ins_encode %{ 9400 __ shrxl($dst$$Register, $src$$Address, $shift$$Register); 9401 %} 9402 ins_pipe(ialu_reg_mem); 9403 %} 9404 9405 // Long Shift Instructions 9406 // Shift Left by one, two, three 9407 instruct salL_rReg_immI2(rRegL dst, immI2 shift, rFlagsReg cr) 9408 %{ 9409 predicate(!UseAPX); 9410 match(Set dst (LShiftL dst shift)); 9411 effect(KILL cr); 9412 9413 format %{ "salq $dst, $shift" %} 9414 ins_encode %{ 9415 __ salq($dst$$Register, $shift$$constant); 9416 %} 9417 ins_pipe(ialu_reg); 9418 %} 9419 9420 // Shift Left by one, two, three 9421 instruct salL_rReg_immI2_ndd(rRegL dst, rRegL src, immI2 shift, rFlagsReg cr) 9422 %{ 9423 predicate(UseAPX); 9424 match(Set dst (LShiftL src shift)); 9425 effect(KILL cr); 9426 9427 format %{ "esalq $dst, $src, $shift\t# long (ndd)" %} 9428 ins_encode %{ 9429 __ esalq($dst$$Register, $src$$Register, $shift$$constant, false); 9430 %} 9431 ins_pipe(ialu_reg); 9432 %} 9433 9434 // Shift Left by 8-bit immediate 9435 instruct salL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 9436 %{ 9437 predicate(!UseAPX); 9438 match(Set dst (LShiftL dst shift)); 9439 effect(KILL cr); 9440 9441 format %{ "salq $dst, $shift" %} 9442 ins_encode %{ 9443 __ salq($dst$$Register, $shift$$constant); 9444 %} 9445 ins_pipe(ialu_reg); 9446 %} 9447 9448 // Shift Left by 8-bit immediate 9449 instruct salL_rReg_imm_ndd(rRegL dst, rRegL src, immI8 shift, rFlagsReg cr) 9450 %{ 9451 predicate(UseAPX); 9452 match(Set dst (LShiftL src shift)); 9453 effect(KILL cr); 9454 9455 format %{ "esalq $dst, $src, $shift\t# long (ndd)" %} 9456 ins_encode %{ 9457 __ esalq($dst$$Register, $src$$Register, $shift$$constant, false); 9458 %} 9459 ins_pipe(ialu_reg); 9460 %} 9461 9462 instruct salL_rReg_mem_imm_ndd(rRegL dst, memory src, immI8 shift, rFlagsReg cr) 9463 %{ 9464 predicate(UseAPX); 9465 match(Set dst (LShiftL (LoadL src) shift)); 9466 effect(KILL cr); 9467 9468 format %{ "esalq $dst, $src, $shift\t# long (ndd)" %} 9469 ins_encode %{ 9470 __ esalq($dst$$Register, $src$$Address, $shift$$constant, false); 9471 %} 9472 ins_pipe(ialu_reg); 9473 %} 9474 9475 // Shift Left by 8-bit immediate 9476 instruct salL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 9477 %{ 9478 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 9479 effect(KILL cr); 9480 9481 format %{ "salq $dst, $shift" %} 9482 ins_encode %{ 9483 __ salq($dst$$Address, $shift$$constant); 9484 %} 9485 ins_pipe(ialu_mem_imm); 9486 %} 9487 9488 // Shift Left by variable 9489 instruct salL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 9490 %{ 9491 predicate(!VM_Version::supports_bmi2()); 9492 match(Set dst (LShiftL dst shift)); 9493 effect(KILL cr); 9494 9495 format %{ "salq $dst, $shift" %} 9496 ins_encode %{ 9497 __ salq($dst$$Register); 9498 %} 9499 ins_pipe(ialu_reg_reg); 9500 %} 9501 9502 // Shift Left by variable 9503 instruct salL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 9504 %{ 9505 predicate(!VM_Version::supports_bmi2()); 9506 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 9507 effect(KILL cr); 9508 9509 format %{ "salq $dst, $shift" %} 9510 ins_encode %{ 9511 __ salq($dst$$Address); 9512 %} 9513 ins_pipe(ialu_mem_reg); 9514 %} 9515 9516 instruct salL_rReg_rReg(rRegL dst, rRegL src, rRegI shift) 9517 %{ 9518 predicate(VM_Version::supports_bmi2()); 9519 match(Set dst (LShiftL src shift)); 9520 9521 format %{ "shlxq $dst, $src, $shift" %} 9522 ins_encode %{ 9523 __ shlxq($dst$$Register, $src$$Register, $shift$$Register); 9524 %} 9525 ins_pipe(ialu_reg_reg); 9526 %} 9527 9528 instruct salL_mem_rReg(rRegL dst, memory src, rRegI shift) 9529 %{ 9530 predicate(VM_Version::supports_bmi2()); 9531 match(Set dst (LShiftL (LoadL src) shift)); 9532 ins_cost(175); 9533 format %{ "shlxq $dst, $src, $shift" %} 9534 ins_encode %{ 9535 __ shlxq($dst$$Register, $src$$Address, $shift$$Register); 9536 %} 9537 ins_pipe(ialu_reg_mem); 9538 %} 9539 9540 // Arithmetic Shift Right by 8-bit immediate 9541 instruct sarL_rReg_imm(rRegL dst, immI shift, rFlagsReg cr) 9542 %{ 9543 predicate(!UseAPX); 9544 match(Set dst (RShiftL dst shift)); 9545 effect(KILL cr); 9546 9547 format %{ "sarq $dst, $shift" %} 9548 ins_encode %{ 9549 __ sarq($dst$$Register, (unsigned char)($shift$$constant & 0x3F)); 9550 %} 9551 ins_pipe(ialu_mem_imm); 9552 %} 9553 9554 // Arithmetic Shift Right by 8-bit immediate 9555 instruct sarL_rReg_imm_ndd(rRegL dst, rRegL src, immI shift, rFlagsReg cr) 9556 %{ 9557 predicate(UseAPX); 9558 match(Set dst (RShiftL src shift)); 9559 effect(KILL cr); 9560 9561 format %{ "esarq $dst, $src, $shift\t# long (ndd)" %} 9562 ins_encode %{ 9563 __ esarq($dst$$Register, $src$$Register, (unsigned char)($shift$$constant & 0x3F), false); 9564 %} 9565 ins_pipe(ialu_mem_imm); 9566 %} 9567 9568 instruct sarL_rReg_mem_imm_ndd(rRegL dst, memory src, immI shift, rFlagsReg cr) 9569 %{ 9570 predicate(UseAPX); 9571 match(Set dst (RShiftL (LoadL src) shift)); 9572 effect(KILL cr); 9573 9574 format %{ "esarq $dst, $src, $shift\t# long (ndd)" %} 9575 ins_encode %{ 9576 __ esarq($dst$$Register, $src$$Address, (unsigned char)($shift$$constant & 0x3F), false); 9577 %} 9578 ins_pipe(ialu_mem_imm); 9579 %} 9580 9581 // Arithmetic Shift Right by 8-bit immediate 9582 instruct sarL_mem_imm(memory dst, immI shift, rFlagsReg cr) 9583 %{ 9584 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 9585 effect(KILL cr); 9586 9587 format %{ "sarq $dst, $shift" %} 9588 ins_encode %{ 9589 __ sarq($dst$$Address, (unsigned char)($shift$$constant & 0x3F)); 9590 %} 9591 ins_pipe(ialu_mem_imm); 9592 %} 9593 9594 // Arithmetic Shift Right by variable 9595 instruct sarL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 9596 %{ 9597 predicate(!VM_Version::supports_bmi2()); 9598 match(Set dst (RShiftL dst shift)); 9599 effect(KILL cr); 9600 9601 format %{ "sarq $dst, $shift" %} 9602 ins_encode %{ 9603 __ sarq($dst$$Register); 9604 %} 9605 ins_pipe(ialu_reg_reg); 9606 %} 9607 9608 // Arithmetic Shift Right by variable 9609 instruct sarL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 9610 %{ 9611 predicate(!VM_Version::supports_bmi2()); 9612 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 9613 effect(KILL cr); 9614 9615 format %{ "sarq $dst, $shift" %} 9616 ins_encode %{ 9617 __ sarq($dst$$Address); 9618 %} 9619 ins_pipe(ialu_mem_reg); 9620 %} 9621 9622 instruct sarL_rReg_rReg(rRegL dst, rRegL src, rRegI shift) 9623 %{ 9624 predicate(VM_Version::supports_bmi2()); 9625 match(Set dst (RShiftL src shift)); 9626 9627 format %{ "sarxq $dst, $src, $shift" %} 9628 ins_encode %{ 9629 __ sarxq($dst$$Register, $src$$Register, $shift$$Register); 9630 %} 9631 ins_pipe(ialu_reg_reg); 9632 %} 9633 9634 instruct sarL_mem_rReg(rRegL dst, memory src, rRegI shift) 9635 %{ 9636 predicate(VM_Version::supports_bmi2()); 9637 match(Set dst (RShiftL (LoadL src) shift)); 9638 ins_cost(175); 9639 format %{ "sarxq $dst, $src, $shift" %} 9640 ins_encode %{ 9641 __ sarxq($dst$$Register, $src$$Address, $shift$$Register); 9642 %} 9643 ins_pipe(ialu_reg_mem); 9644 %} 9645 9646 // Logical Shift Right by 8-bit immediate 9647 instruct shrL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 9648 %{ 9649 predicate(!UseAPX); 9650 match(Set dst (URShiftL dst shift)); 9651 effect(KILL cr); 9652 9653 format %{ "shrq $dst, $shift" %} 9654 ins_encode %{ 9655 __ shrq($dst$$Register, $shift$$constant); 9656 %} 9657 ins_pipe(ialu_reg); 9658 %} 9659 9660 // Logical Shift Right by 8-bit immediate 9661 instruct shrL_rReg_imm_ndd(rRegL dst, rRegL src, immI8 shift, rFlagsReg cr) 9662 %{ 9663 predicate(UseAPX); 9664 match(Set dst (URShiftL src shift)); 9665 effect(KILL cr); 9666 9667 format %{ "eshrq $dst, $src, $shift\t# long (ndd)" %} 9668 ins_encode %{ 9669 __ eshrq($dst$$Register, $src$$Register, $shift$$constant, false); 9670 %} 9671 ins_pipe(ialu_reg); 9672 %} 9673 9674 instruct shrL_rReg_mem_imm_ndd(rRegL dst, memory src, immI8 shift, rFlagsReg cr) 9675 %{ 9676 predicate(UseAPX); 9677 match(Set dst (URShiftL (LoadL src) shift)); 9678 effect(KILL cr); 9679 9680 format %{ "eshrq $dst, $src, $shift\t# long (ndd)" %} 9681 ins_encode %{ 9682 __ eshrq($dst$$Register, $src$$Address, $shift$$constant, false); 9683 %} 9684 ins_pipe(ialu_reg); 9685 %} 9686 9687 // Logical Shift Right by 8-bit immediate 9688 instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 9689 %{ 9690 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 9691 effect(KILL cr); 9692 9693 format %{ "shrq $dst, $shift" %} 9694 ins_encode %{ 9695 __ shrq($dst$$Address, $shift$$constant); 9696 %} 9697 ins_pipe(ialu_mem_imm); 9698 %} 9699 9700 // Logical Shift Right by variable 9701 instruct shrL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 9702 %{ 9703 predicate(!VM_Version::supports_bmi2()); 9704 match(Set dst (URShiftL dst shift)); 9705 effect(KILL cr); 9706 9707 format %{ "shrq $dst, $shift" %} 9708 ins_encode %{ 9709 __ shrq($dst$$Register); 9710 %} 9711 ins_pipe(ialu_reg_reg); 9712 %} 9713 9714 // Logical Shift Right by variable 9715 instruct shrL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 9716 %{ 9717 predicate(!VM_Version::supports_bmi2()); 9718 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 9719 effect(KILL cr); 9720 9721 format %{ "shrq $dst, $shift" %} 9722 ins_encode %{ 9723 __ shrq($dst$$Address); 9724 %} 9725 ins_pipe(ialu_mem_reg); 9726 %} 9727 9728 instruct shrL_rReg_rReg(rRegL dst, rRegL src, rRegI shift) 9729 %{ 9730 predicate(VM_Version::supports_bmi2()); 9731 match(Set dst (URShiftL src shift)); 9732 9733 format %{ "shrxq $dst, $src, $shift" %} 9734 ins_encode %{ 9735 __ shrxq($dst$$Register, $src$$Register, $shift$$Register); 9736 %} 9737 ins_pipe(ialu_reg_reg); 9738 %} 9739 9740 instruct shrL_mem_rReg(rRegL dst, memory src, rRegI shift) 9741 %{ 9742 predicate(VM_Version::supports_bmi2()); 9743 match(Set dst (URShiftL (LoadL src) shift)); 9744 ins_cost(175); 9745 format %{ "shrxq $dst, $src, $shift" %} 9746 ins_encode %{ 9747 __ shrxq($dst$$Register, $src$$Address, $shift$$Register); 9748 %} 9749 ins_pipe(ialu_reg_mem); 9750 %} 9751 9752 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24. 9753 // This idiom is used by the compiler for the i2b bytecode. 9754 instruct i2b(rRegI dst, rRegI src, immI_24 twentyfour) 9755 %{ 9756 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour)); 9757 9758 format %{ "movsbl $dst, $src\t# i2b" %} 9759 ins_encode %{ 9760 __ movsbl($dst$$Register, $src$$Register); 9761 %} 9762 ins_pipe(ialu_reg_reg); 9763 %} 9764 9765 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16. 9766 // This idiom is used by the compiler the i2s bytecode. 9767 instruct i2s(rRegI dst, rRegI src, immI_16 sixteen) 9768 %{ 9769 match(Set dst (RShiftI (LShiftI src sixteen) sixteen)); 9770 9771 format %{ "movswl $dst, $src\t# i2s" %} 9772 ins_encode %{ 9773 __ movswl($dst$$Register, $src$$Register); 9774 %} 9775 ins_pipe(ialu_reg_reg); 9776 %} 9777 9778 // ROL/ROR instructions 9779 9780 // Rotate left by constant. 9781 instruct rolI_immI8_legacy(rRegI dst, immI8 shift, rFlagsReg cr) 9782 %{ 9783 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 9784 match(Set dst (RotateLeft dst shift)); 9785 effect(KILL cr); 9786 format %{ "roll $dst, $shift" %} 9787 ins_encode %{ 9788 __ roll($dst$$Register, $shift$$constant); 9789 %} 9790 ins_pipe(ialu_reg); 9791 %} 9792 9793 instruct rolI_immI8(rRegI dst, rRegI src, immI8 shift) 9794 %{ 9795 predicate(!UseAPX && VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 9796 match(Set dst (RotateLeft src shift)); 9797 format %{ "rolxl $dst, $src, $shift" %} 9798 ins_encode %{ 9799 int shift = 32 - ($shift$$constant & 31); 9800 __ rorxl($dst$$Register, $src$$Register, shift); 9801 %} 9802 ins_pipe(ialu_reg_reg); 9803 %} 9804 9805 instruct rolI_mem_immI8(rRegI dst, memory src, immI8 shift) 9806 %{ 9807 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 9808 match(Set dst (RotateLeft (LoadI src) shift)); 9809 ins_cost(175); 9810 format %{ "rolxl $dst, $src, $shift" %} 9811 ins_encode %{ 9812 int shift = 32 - ($shift$$constant & 31); 9813 __ rorxl($dst$$Register, $src$$Address, shift); 9814 %} 9815 ins_pipe(ialu_reg_mem); 9816 %} 9817 9818 // Rotate Left by variable 9819 instruct rolI_rReg_Var(rRegI dst, rcx_RegI shift, rFlagsReg cr) 9820 %{ 9821 predicate(!UseAPX && n->bottom_type()->basic_type() == T_INT); 9822 match(Set dst (RotateLeft dst shift)); 9823 effect(KILL cr); 9824 format %{ "roll $dst, $shift" %} 9825 ins_encode %{ 9826 __ roll($dst$$Register); 9827 %} 9828 ins_pipe(ialu_reg_reg); 9829 %} 9830 9831 // Rotate Left by variable 9832 instruct rolI_rReg_Var_ndd(rRegI dst, rRegI src, rcx_RegI shift, rFlagsReg cr) 9833 %{ 9834 predicate(UseAPX && n->bottom_type()->basic_type() == T_INT); 9835 match(Set dst (RotateLeft src shift)); 9836 effect(KILL cr); 9837 9838 format %{ "eroll $dst, $src, $shift\t# rotate left (int ndd)" %} 9839 ins_encode %{ 9840 __ eroll($dst$$Register, $src$$Register, false); 9841 %} 9842 ins_pipe(ialu_reg_reg); 9843 %} 9844 9845 // Rotate Right by constant. 9846 instruct rorI_immI8_legacy(rRegI dst, immI8 shift, rFlagsReg cr) 9847 %{ 9848 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 9849 match(Set dst (RotateRight dst shift)); 9850 effect(KILL cr); 9851 format %{ "rorl $dst, $shift" %} 9852 ins_encode %{ 9853 __ rorl($dst$$Register, $shift$$constant); 9854 %} 9855 ins_pipe(ialu_reg); 9856 %} 9857 9858 // Rotate Right by constant. 9859 instruct rorI_immI8(rRegI dst, rRegI src, immI8 shift) 9860 %{ 9861 predicate(!UseAPX && VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 9862 match(Set dst (RotateRight src shift)); 9863 format %{ "rorxl $dst, $src, $shift" %} 9864 ins_encode %{ 9865 __ rorxl($dst$$Register, $src$$Register, $shift$$constant); 9866 %} 9867 ins_pipe(ialu_reg_reg); 9868 %} 9869 9870 instruct rorI_mem_immI8(rRegI dst, memory src, immI8 shift) 9871 %{ 9872 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 9873 match(Set dst (RotateRight (LoadI src) shift)); 9874 ins_cost(175); 9875 format %{ "rorxl $dst, $src, $shift" %} 9876 ins_encode %{ 9877 __ rorxl($dst$$Register, $src$$Address, $shift$$constant); 9878 %} 9879 ins_pipe(ialu_reg_mem); 9880 %} 9881 9882 // Rotate Right by variable 9883 instruct rorI_rReg_Var(rRegI dst, rcx_RegI shift, rFlagsReg cr) 9884 %{ 9885 predicate(!UseAPX && n->bottom_type()->basic_type() == T_INT); 9886 match(Set dst (RotateRight dst shift)); 9887 effect(KILL cr); 9888 format %{ "rorl $dst, $shift" %} 9889 ins_encode %{ 9890 __ rorl($dst$$Register); 9891 %} 9892 ins_pipe(ialu_reg_reg); 9893 %} 9894 9895 // Rotate Right by variable 9896 instruct rorI_rReg_Var_ndd(rRegI dst, rRegI src, rcx_RegI shift, rFlagsReg cr) 9897 %{ 9898 predicate(UseAPX && n->bottom_type()->basic_type() == T_INT); 9899 match(Set dst (RotateRight src shift)); 9900 effect(KILL cr); 9901 9902 format %{ "erorl $dst, $src, $shift\t# rotate right(int ndd)" %} 9903 ins_encode %{ 9904 __ erorl($dst$$Register, $src$$Register, false); 9905 %} 9906 ins_pipe(ialu_reg_reg); 9907 %} 9908 9909 // Rotate Left by constant. 9910 instruct rolL_immI8_legacy(rRegL dst, immI8 shift, rFlagsReg cr) 9911 %{ 9912 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 9913 match(Set dst (RotateLeft dst shift)); 9914 effect(KILL cr); 9915 format %{ "rolq $dst, $shift" %} 9916 ins_encode %{ 9917 __ rolq($dst$$Register, $shift$$constant); 9918 %} 9919 ins_pipe(ialu_reg); 9920 %} 9921 9922 instruct rolL_immI8(rRegL dst, rRegL src, immI8 shift) 9923 %{ 9924 predicate(!UseAPX && VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 9925 match(Set dst (RotateLeft src shift)); 9926 format %{ "rolxq $dst, $src, $shift" %} 9927 ins_encode %{ 9928 int shift = 64 - ($shift$$constant & 63); 9929 __ rorxq($dst$$Register, $src$$Register, shift); 9930 %} 9931 ins_pipe(ialu_reg_reg); 9932 %} 9933 9934 instruct rolL_mem_immI8(rRegL dst, memory src, immI8 shift) 9935 %{ 9936 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 9937 match(Set dst (RotateLeft (LoadL src) shift)); 9938 ins_cost(175); 9939 format %{ "rolxq $dst, $src, $shift" %} 9940 ins_encode %{ 9941 int shift = 64 - ($shift$$constant & 63); 9942 __ rorxq($dst$$Register, $src$$Address, shift); 9943 %} 9944 ins_pipe(ialu_reg_mem); 9945 %} 9946 9947 // Rotate Left by variable 9948 instruct rolL_rReg_Var(rRegL dst, rcx_RegI shift, rFlagsReg cr) 9949 %{ 9950 predicate(!UseAPX && n->bottom_type()->basic_type() == T_LONG); 9951 match(Set dst (RotateLeft dst shift)); 9952 effect(KILL cr); 9953 format %{ "rolq $dst, $shift" %} 9954 ins_encode %{ 9955 __ rolq($dst$$Register); 9956 %} 9957 ins_pipe(ialu_reg_reg); 9958 %} 9959 9960 // Rotate Left by variable 9961 instruct rolL_rReg_Var_ndd(rRegL dst, rRegL src, rcx_RegI shift, rFlagsReg cr) 9962 %{ 9963 predicate(UseAPX && n->bottom_type()->basic_type() == T_LONG); 9964 match(Set dst (RotateLeft src shift)); 9965 effect(KILL cr); 9966 9967 format %{ "erolq $dst, $src, $shift\t# rotate left(long ndd)" %} 9968 ins_encode %{ 9969 __ erolq($dst$$Register, $src$$Register, false); 9970 %} 9971 ins_pipe(ialu_reg_reg); 9972 %} 9973 9974 // Rotate Right by constant. 9975 instruct rorL_immI8_legacy(rRegL dst, immI8 shift, rFlagsReg cr) 9976 %{ 9977 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 9978 match(Set dst (RotateRight dst shift)); 9979 effect(KILL cr); 9980 format %{ "rorq $dst, $shift" %} 9981 ins_encode %{ 9982 __ rorq($dst$$Register, $shift$$constant); 9983 %} 9984 ins_pipe(ialu_reg); 9985 %} 9986 9987 // Rotate Right by constant 9988 instruct rorL_immI8(rRegL dst, rRegL src, immI8 shift) 9989 %{ 9990 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 9991 match(Set dst (RotateRight src shift)); 9992 format %{ "rorxq $dst, $src, $shift" %} 9993 ins_encode %{ 9994 __ rorxq($dst$$Register, $src$$Register, $shift$$constant); 9995 %} 9996 ins_pipe(ialu_reg_reg); 9997 %} 9998 9999 instruct rorL_mem_immI8(rRegL dst, memory src, immI8 shift) 10000 %{ 10001 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 10002 match(Set dst (RotateRight (LoadL src) shift)); 10003 ins_cost(175); 10004 format %{ "rorxq $dst, $src, $shift" %} 10005 ins_encode %{ 10006 __ rorxq($dst$$Register, $src$$Address, $shift$$constant); 10007 %} 10008 ins_pipe(ialu_reg_mem); 10009 %} 10010 10011 // Rotate Right by variable 10012 instruct rorL_rReg_Var(rRegL dst, rcx_RegI shift, rFlagsReg cr) 10013 %{ 10014 predicate(!UseAPX && n->bottom_type()->basic_type() == T_LONG); 10015 match(Set dst (RotateRight dst shift)); 10016 effect(KILL cr); 10017 format %{ "rorq $dst, $shift" %} 10018 ins_encode %{ 10019 __ rorq($dst$$Register); 10020 %} 10021 ins_pipe(ialu_reg_reg); 10022 %} 10023 10024 // Rotate Right by variable 10025 instruct rorL_rReg_Var_ndd(rRegL dst, rRegL src, rcx_RegI shift, rFlagsReg cr) 10026 %{ 10027 predicate(UseAPX && n->bottom_type()->basic_type() == T_LONG); 10028 match(Set dst (RotateRight src shift)); 10029 effect(KILL cr); 10030 10031 format %{ "erorq $dst, $src, $shift\t# rotate right(long ndd)" %} 10032 ins_encode %{ 10033 __ erorq($dst$$Register, $src$$Register, false); 10034 %} 10035 ins_pipe(ialu_reg_reg); 10036 %} 10037 10038 //----------------------------- CompressBits/ExpandBits ------------------------ 10039 10040 instruct compressBitsL_reg(rRegL dst, rRegL src, rRegL mask) %{ 10041 predicate(n->bottom_type()->isa_long()); 10042 match(Set dst (CompressBits src mask)); 10043 format %{ "pextq $dst, $src, $mask\t! parallel bit extract" %} 10044 ins_encode %{ 10045 __ pextq($dst$$Register, $src$$Register, $mask$$Register); 10046 %} 10047 ins_pipe( pipe_slow ); 10048 %} 10049 10050 instruct expandBitsL_reg(rRegL dst, rRegL src, rRegL mask) %{ 10051 predicate(n->bottom_type()->isa_long()); 10052 match(Set dst (ExpandBits src mask)); 10053 format %{ "pdepq $dst, $src, $mask\t! parallel bit deposit" %} 10054 ins_encode %{ 10055 __ pdepq($dst$$Register, $src$$Register, $mask$$Register); 10056 %} 10057 ins_pipe( pipe_slow ); 10058 %} 10059 10060 instruct compressBitsL_mem(rRegL dst, rRegL src, memory mask) %{ 10061 predicate(n->bottom_type()->isa_long()); 10062 match(Set dst (CompressBits src (LoadL mask))); 10063 format %{ "pextq $dst, $src, $mask\t! parallel bit extract" %} 10064 ins_encode %{ 10065 __ pextq($dst$$Register, $src$$Register, $mask$$Address); 10066 %} 10067 ins_pipe( pipe_slow ); 10068 %} 10069 10070 instruct expandBitsL_mem(rRegL dst, rRegL src, memory mask) %{ 10071 predicate(n->bottom_type()->isa_long()); 10072 match(Set dst (ExpandBits src (LoadL mask))); 10073 format %{ "pdepq $dst, $src, $mask\t! parallel bit deposit" %} 10074 ins_encode %{ 10075 __ pdepq($dst$$Register, $src$$Register, $mask$$Address); 10076 %} 10077 ins_pipe( pipe_slow ); 10078 %} 10079 10080 10081 // Logical Instructions 10082 10083 // Integer Logical Instructions 10084 10085 // And Instructions 10086 // And Register with Register 10087 instruct andI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 10088 %{ 10089 predicate(!UseAPX); 10090 match(Set dst (AndI dst src)); 10091 effect(KILL cr); 10092 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10093 10094 format %{ "andl $dst, $src\t# int" %} 10095 ins_encode %{ 10096 __ andl($dst$$Register, $src$$Register); 10097 %} 10098 ins_pipe(ialu_reg_reg); 10099 %} 10100 10101 // And Register with Register using New Data Destination (NDD) 10102 instruct andI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr) 10103 %{ 10104 predicate(UseAPX); 10105 match(Set dst (AndI src1 src2)); 10106 effect(KILL cr); 10107 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10108 10109 format %{ "eandl $dst, $src1, $src2\t# int ndd" %} 10110 ins_encode %{ 10111 __ eandl($dst$$Register, $src1$$Register, $src2$$Register, false); 10112 10113 %} 10114 ins_pipe(ialu_reg_reg); 10115 %} 10116 10117 // And Register with Immediate 255 10118 instruct andI_rReg_imm255(rRegI dst, rRegI src, immI_255 mask) 10119 %{ 10120 match(Set dst (AndI src mask)); 10121 10122 format %{ "movzbl $dst, $src\t# int & 0xFF" %} 10123 ins_encode %{ 10124 __ movzbl($dst$$Register, $src$$Register); 10125 %} 10126 ins_pipe(ialu_reg); 10127 %} 10128 10129 // And Register with Immediate 255 and promote to long 10130 instruct andI2L_rReg_imm255(rRegL dst, rRegI src, immI_255 mask) 10131 %{ 10132 match(Set dst (ConvI2L (AndI src mask))); 10133 10134 format %{ "movzbl $dst, $src\t# int & 0xFF -> long" %} 10135 ins_encode %{ 10136 __ movzbl($dst$$Register, $src$$Register); 10137 %} 10138 ins_pipe(ialu_reg); 10139 %} 10140 10141 // And Register with Immediate 65535 10142 instruct andI_rReg_imm65535(rRegI dst, rRegI src, immI_65535 mask) 10143 %{ 10144 match(Set dst (AndI src mask)); 10145 10146 format %{ "movzwl $dst, $src\t# int & 0xFFFF" %} 10147 ins_encode %{ 10148 __ movzwl($dst$$Register, $src$$Register); 10149 %} 10150 ins_pipe(ialu_reg); 10151 %} 10152 10153 // And Register with Immediate 65535 and promote to long 10154 instruct andI2L_rReg_imm65535(rRegL dst, rRegI src, immI_65535 mask) 10155 %{ 10156 match(Set dst (ConvI2L (AndI src mask))); 10157 10158 format %{ "movzwl $dst, $src\t# int & 0xFFFF -> long" %} 10159 ins_encode %{ 10160 __ movzwl($dst$$Register, $src$$Register); 10161 %} 10162 ins_pipe(ialu_reg); 10163 %} 10164 10165 // Can skip int2long conversions after AND with small bitmask 10166 instruct convI2LAndI_reg_immIbitmask(rRegL dst, rRegI src, immI_Pow2M1 mask, rRegI tmp, rFlagsReg cr) 10167 %{ 10168 predicate(VM_Version::supports_bmi2()); 10169 ins_cost(125); 10170 effect(TEMP tmp, KILL cr); 10171 match(Set dst (ConvI2L (AndI src mask))); 10172 format %{ "bzhiq $dst, $src, $mask \t# using $tmp as TEMP, int & immI_Pow2M1 -> long" %} 10173 ins_encode %{ 10174 __ movl($tmp$$Register, exact_log2($mask$$constant + 1)); 10175 __ bzhiq($dst$$Register, $src$$Register, $tmp$$Register); 10176 %} 10177 ins_pipe(ialu_reg_reg); 10178 %} 10179 10180 // And Register with Immediate 10181 instruct andI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 10182 %{ 10183 predicate(!UseAPX); 10184 match(Set dst (AndI dst src)); 10185 effect(KILL cr); 10186 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10187 10188 format %{ "andl $dst, $src\t# int" %} 10189 ins_encode %{ 10190 __ andl($dst$$Register, $src$$constant); 10191 %} 10192 ins_pipe(ialu_reg); 10193 %} 10194 10195 instruct andI_rReg_rReg_imm_ndd(rRegI dst, rRegI src1, immI src2, rFlagsReg cr) 10196 %{ 10197 predicate(UseAPX); 10198 match(Set dst (AndI src1 src2)); 10199 effect(KILL cr); 10200 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10201 10202 format %{ "eandl $dst, $src1, $src2\t# int ndd" %} 10203 ins_encode %{ 10204 __ eandl($dst$$Register, $src1$$Register, $src2$$constant, false); 10205 %} 10206 ins_pipe(ialu_reg); 10207 %} 10208 10209 instruct andI_rReg_mem_imm_ndd(rRegI dst, memory src1, immI src2, rFlagsReg cr) 10210 %{ 10211 predicate(UseAPX); 10212 match(Set dst (AndI (LoadI src1) src2)); 10213 effect(KILL cr); 10214 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10215 10216 format %{ "eandl $dst, $src1, $src2\t# int ndd" %} 10217 ins_encode %{ 10218 __ eandl($dst$$Register, $src1$$Address, $src2$$constant, false); 10219 %} 10220 ins_pipe(ialu_reg); 10221 %} 10222 10223 // And Register with Memory 10224 instruct andI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 10225 %{ 10226 predicate(!UseAPX); 10227 match(Set dst (AndI dst (LoadI src))); 10228 effect(KILL cr); 10229 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10230 10231 ins_cost(150); 10232 format %{ "andl $dst, $src\t# int" %} 10233 ins_encode %{ 10234 __ andl($dst$$Register, $src$$Address); 10235 %} 10236 ins_pipe(ialu_reg_mem); 10237 %} 10238 10239 instruct andI_rReg_rReg_mem_ndd(rRegI dst, rRegI src1, memory src2, rFlagsReg cr) 10240 %{ 10241 predicate(UseAPX); 10242 match(Set dst (AndI src1 (LoadI src2))); 10243 effect(KILL cr); 10244 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10245 10246 ins_cost(150); 10247 format %{ "eandl $dst, $src1, $src2\t# int ndd" %} 10248 ins_encode %{ 10249 __ eandl($dst$$Register, $src1$$Register, $src2$$Address, false); 10250 %} 10251 ins_pipe(ialu_reg_mem); 10252 %} 10253 10254 // And Memory with Register 10255 instruct andB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 10256 %{ 10257 match(Set dst (StoreB dst (AndI (LoadB dst) src))); 10258 effect(KILL cr); 10259 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10260 10261 ins_cost(150); 10262 format %{ "andb $dst, $src\t# byte" %} 10263 ins_encode %{ 10264 __ andb($dst$$Address, $src$$Register); 10265 %} 10266 ins_pipe(ialu_mem_reg); 10267 %} 10268 10269 instruct andI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 10270 %{ 10271 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 10272 effect(KILL cr); 10273 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10274 10275 ins_cost(150); 10276 format %{ "andl $dst, $src\t# int" %} 10277 ins_encode %{ 10278 __ andl($dst$$Address, $src$$Register); 10279 %} 10280 ins_pipe(ialu_mem_reg); 10281 %} 10282 10283 // And Memory with Immediate 10284 instruct andI_mem_imm(memory dst, immI src, rFlagsReg cr) 10285 %{ 10286 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 10287 effect(KILL cr); 10288 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10289 10290 ins_cost(125); 10291 format %{ "andl $dst, $src\t# int" %} 10292 ins_encode %{ 10293 __ andl($dst$$Address, $src$$constant); 10294 %} 10295 ins_pipe(ialu_mem_imm); 10296 %} 10297 10298 // BMI1 instructions 10299 instruct andnI_rReg_rReg_mem(rRegI dst, rRegI src1, memory src2, immI_M1 minus_1, rFlagsReg cr) %{ 10300 match(Set dst (AndI (XorI src1 minus_1) (LoadI src2))); 10301 predicate(UseBMI1Instructions); 10302 effect(KILL cr); 10303 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10304 10305 ins_cost(125); 10306 format %{ "andnl $dst, $src1, $src2" %} 10307 10308 ins_encode %{ 10309 __ andnl($dst$$Register, $src1$$Register, $src2$$Address); 10310 %} 10311 ins_pipe(ialu_reg_mem); 10312 %} 10313 10314 instruct andnI_rReg_rReg_rReg(rRegI dst, rRegI src1, rRegI src2, immI_M1 minus_1, rFlagsReg cr) %{ 10315 match(Set dst (AndI (XorI src1 minus_1) src2)); 10316 predicate(UseBMI1Instructions); 10317 effect(KILL cr); 10318 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10319 10320 format %{ "andnl $dst, $src1, $src2" %} 10321 10322 ins_encode %{ 10323 __ andnl($dst$$Register, $src1$$Register, $src2$$Register); 10324 %} 10325 ins_pipe(ialu_reg); 10326 %} 10327 10328 instruct blsiI_rReg_rReg(rRegI dst, rRegI src, immI_0 imm_zero, rFlagsReg cr) %{ 10329 match(Set dst (AndI (SubI imm_zero src) src)); 10330 predicate(UseBMI1Instructions); 10331 effect(KILL cr); 10332 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 10333 10334 format %{ "blsil $dst, $src" %} 10335 10336 ins_encode %{ 10337 __ blsil($dst$$Register, $src$$Register); 10338 %} 10339 ins_pipe(ialu_reg); 10340 %} 10341 10342 instruct blsiI_rReg_mem(rRegI dst, memory src, immI_0 imm_zero, rFlagsReg cr) %{ 10343 match(Set dst (AndI (SubI imm_zero (LoadI src) ) (LoadI src) )); 10344 predicate(UseBMI1Instructions); 10345 effect(KILL cr); 10346 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 10347 10348 ins_cost(125); 10349 format %{ "blsil $dst, $src" %} 10350 10351 ins_encode %{ 10352 __ blsil($dst$$Register, $src$$Address); 10353 %} 10354 ins_pipe(ialu_reg_mem); 10355 %} 10356 10357 instruct blsmskI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 10358 %{ 10359 match(Set dst (XorI (AddI (LoadI src) minus_1) (LoadI src) ) ); 10360 predicate(UseBMI1Instructions); 10361 effect(KILL cr); 10362 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 10363 10364 ins_cost(125); 10365 format %{ "blsmskl $dst, $src" %} 10366 10367 ins_encode %{ 10368 __ blsmskl($dst$$Register, $src$$Address); 10369 %} 10370 ins_pipe(ialu_reg_mem); 10371 %} 10372 10373 instruct blsmskI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 10374 %{ 10375 match(Set dst (XorI (AddI src minus_1) src)); 10376 predicate(UseBMI1Instructions); 10377 effect(KILL cr); 10378 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 10379 10380 format %{ "blsmskl $dst, $src" %} 10381 10382 ins_encode %{ 10383 __ blsmskl($dst$$Register, $src$$Register); 10384 %} 10385 10386 ins_pipe(ialu_reg); 10387 %} 10388 10389 instruct blsrI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 10390 %{ 10391 match(Set dst (AndI (AddI src minus_1) src) ); 10392 predicate(UseBMI1Instructions); 10393 effect(KILL cr); 10394 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 10395 10396 format %{ "blsrl $dst, $src" %} 10397 10398 ins_encode %{ 10399 __ blsrl($dst$$Register, $src$$Register); 10400 %} 10401 10402 ins_pipe(ialu_reg_mem); 10403 %} 10404 10405 instruct blsrI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 10406 %{ 10407 match(Set dst (AndI (AddI (LoadI src) minus_1) (LoadI src) ) ); 10408 predicate(UseBMI1Instructions); 10409 effect(KILL cr); 10410 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 10411 10412 ins_cost(125); 10413 format %{ "blsrl $dst, $src" %} 10414 10415 ins_encode %{ 10416 __ blsrl($dst$$Register, $src$$Address); 10417 %} 10418 10419 ins_pipe(ialu_reg); 10420 %} 10421 10422 // Or Instructions 10423 // Or Register with Register 10424 instruct orI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 10425 %{ 10426 predicate(!UseAPX); 10427 match(Set dst (OrI dst src)); 10428 effect(KILL cr); 10429 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10430 10431 format %{ "orl $dst, $src\t# int" %} 10432 ins_encode %{ 10433 __ orl($dst$$Register, $src$$Register); 10434 %} 10435 ins_pipe(ialu_reg_reg); 10436 %} 10437 10438 // Or Register with Register using New Data Destination (NDD) 10439 instruct orI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr) 10440 %{ 10441 predicate(UseAPX); 10442 match(Set dst (OrI src1 src2)); 10443 effect(KILL cr); 10444 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10445 10446 format %{ "eorl $dst, $src1, $src2\t# int ndd" %} 10447 ins_encode %{ 10448 __ eorl($dst$$Register, $src1$$Register, $src2$$Register, false); 10449 %} 10450 ins_pipe(ialu_reg_reg); 10451 %} 10452 10453 // Or Register with Immediate 10454 instruct orI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 10455 %{ 10456 predicate(!UseAPX); 10457 match(Set dst (OrI dst src)); 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 %{ "orl $dst, $src\t# int" %} 10462 ins_encode %{ 10463 __ orl($dst$$Register, $src$$constant); 10464 %} 10465 ins_pipe(ialu_reg); 10466 %} 10467 10468 instruct orI_rReg_rReg_imm_ndd(rRegI dst, rRegI src1, immI src2, rFlagsReg cr) 10469 %{ 10470 predicate(UseAPX); 10471 match(Set dst (OrI src1 src2)); 10472 effect(KILL cr); 10473 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10474 10475 format %{ "eorl $dst, $src1, $src2\t# int ndd" %} 10476 ins_encode %{ 10477 __ eorl($dst$$Register, $src1$$Register, $src2$$constant, false); 10478 %} 10479 ins_pipe(ialu_reg); 10480 %} 10481 10482 instruct orI_rReg_imm_rReg_ndd(rRegI dst, immI src1, rRegI src2, rFlagsReg cr) 10483 %{ 10484 predicate(UseAPX); 10485 match(Set dst (OrI src1 src2)); 10486 effect(KILL cr); 10487 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10488 10489 format %{ "eorl $dst, $src2, $src1\t# int ndd" %} 10490 ins_encode %{ 10491 __ eorl($dst$$Register, $src2$$Register, $src1$$constant, false); 10492 %} 10493 ins_pipe(ialu_reg); 10494 %} 10495 10496 instruct orI_rReg_mem_imm_ndd(rRegI dst, memory src1, immI src2, rFlagsReg cr) 10497 %{ 10498 predicate(UseAPX); 10499 match(Set dst (OrI (LoadI src1) src2)); 10500 effect(KILL cr); 10501 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10502 10503 format %{ "eorl $dst, $src1, $src2\t# int ndd" %} 10504 ins_encode %{ 10505 __ eorl($dst$$Register, $src1$$Address, $src2$$constant, false); 10506 %} 10507 ins_pipe(ialu_reg); 10508 %} 10509 10510 // Or Register with Memory 10511 instruct orI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 10512 %{ 10513 predicate(!UseAPX); 10514 match(Set dst (OrI dst (LoadI src))); 10515 effect(KILL cr); 10516 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10517 10518 ins_cost(150); 10519 format %{ "orl $dst, $src\t# int" %} 10520 ins_encode %{ 10521 __ orl($dst$$Register, $src$$Address); 10522 %} 10523 ins_pipe(ialu_reg_mem); 10524 %} 10525 10526 instruct orI_rReg_rReg_mem_ndd(rRegI dst, rRegI src1, memory src2, rFlagsReg cr) 10527 %{ 10528 predicate(UseAPX); 10529 match(Set dst (OrI src1 (LoadI src2))); 10530 effect(KILL cr); 10531 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10532 10533 ins_cost(150); 10534 format %{ "eorl $dst, $src1, $src2\t# int ndd" %} 10535 ins_encode %{ 10536 __ eorl($dst$$Register, $src1$$Register, $src2$$Address, false); 10537 %} 10538 ins_pipe(ialu_reg_mem); 10539 %} 10540 10541 // Or Memory with Register 10542 instruct orB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 10543 %{ 10544 match(Set dst (StoreB dst (OrI (LoadB dst) src))); 10545 effect(KILL cr); 10546 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10547 10548 ins_cost(150); 10549 format %{ "orb $dst, $src\t# byte" %} 10550 ins_encode %{ 10551 __ orb($dst$$Address, $src$$Register); 10552 %} 10553 ins_pipe(ialu_mem_reg); 10554 %} 10555 10556 instruct orI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 10557 %{ 10558 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 10559 effect(KILL cr); 10560 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10561 10562 ins_cost(150); 10563 format %{ "orl $dst, $src\t# int" %} 10564 ins_encode %{ 10565 __ orl($dst$$Address, $src$$Register); 10566 %} 10567 ins_pipe(ialu_mem_reg); 10568 %} 10569 10570 // Or Memory with Immediate 10571 instruct orI_mem_imm(memory dst, immI src, rFlagsReg cr) 10572 %{ 10573 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 10574 effect(KILL cr); 10575 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10576 10577 ins_cost(125); 10578 format %{ "orl $dst, $src\t# int" %} 10579 ins_encode %{ 10580 __ orl($dst$$Address, $src$$constant); 10581 %} 10582 ins_pipe(ialu_mem_imm); 10583 %} 10584 10585 // Xor Instructions 10586 // Xor Register with Register 10587 instruct xorI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 10588 %{ 10589 predicate(!UseAPX); 10590 match(Set dst (XorI dst src)); 10591 effect(KILL cr); 10592 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10593 10594 format %{ "xorl $dst, $src\t# int" %} 10595 ins_encode %{ 10596 __ xorl($dst$$Register, $src$$Register); 10597 %} 10598 ins_pipe(ialu_reg_reg); 10599 %} 10600 10601 // Xor Register with Register using New Data Destination (NDD) 10602 instruct xorI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr) 10603 %{ 10604 predicate(UseAPX); 10605 match(Set dst (XorI src1 src2)); 10606 effect(KILL cr); 10607 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10608 10609 format %{ "exorl $dst, $src1, $src2\t# int ndd" %} 10610 ins_encode %{ 10611 __ exorl($dst$$Register, $src1$$Register, $src2$$Register, false); 10612 %} 10613 ins_pipe(ialu_reg_reg); 10614 %} 10615 10616 // Xor Register with Immediate -1 10617 instruct xorI_rReg_im1(rRegI dst, immI_M1 imm) 10618 %{ 10619 predicate(!UseAPX); 10620 match(Set dst (XorI dst imm)); 10621 10622 format %{ "notl $dst" %} 10623 ins_encode %{ 10624 __ notl($dst$$Register); 10625 %} 10626 ins_pipe(ialu_reg); 10627 %} 10628 10629 instruct xorI_rReg_im1_ndd(rRegI dst, rRegI src, immI_M1 imm) 10630 %{ 10631 match(Set dst (XorI src imm)); 10632 predicate(UseAPX); 10633 10634 format %{ "enotl $dst, $src" %} 10635 ins_encode %{ 10636 __ enotl($dst$$Register, $src$$Register); 10637 %} 10638 ins_pipe(ialu_reg); 10639 %} 10640 10641 // Xor Register with Immediate 10642 instruct xorI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 10643 %{ 10644 predicate(!UseAPX); 10645 match(Set dst (XorI dst src)); 10646 effect(KILL cr); 10647 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10648 10649 format %{ "xorl $dst, $src\t# int" %} 10650 ins_encode %{ 10651 __ xorl($dst$$Register, $src$$constant); 10652 %} 10653 ins_pipe(ialu_reg); 10654 %} 10655 10656 instruct xorI_rReg_rReg_imm_ndd(rRegI dst, rRegI src1, immI src2, rFlagsReg cr) 10657 %{ 10658 predicate(UseAPX); 10659 match(Set dst (XorI src1 src2)); 10660 effect(KILL cr); 10661 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10662 10663 format %{ "exorl $dst, $src1, $src2\t# int ndd" %} 10664 ins_encode %{ 10665 __ exorl($dst$$Register, $src1$$Register, $src2$$constant, false); 10666 %} 10667 ins_pipe(ialu_reg); 10668 %} 10669 10670 // Xor Memory with Immediate 10671 instruct xorI_rReg_mem_imm_ndd(rRegI dst, memory src1, immI src2, rFlagsReg cr) 10672 %{ 10673 predicate(UseAPX); 10674 match(Set dst (XorI (LoadI src1) src2)); 10675 effect(KILL cr); 10676 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10677 10678 format %{ "exorl $dst, $src1, $src2\t# int ndd" %} 10679 ins_encode %{ 10680 __ exorl($dst$$Register, $src1$$Address, $src2$$constant, false); 10681 %} 10682 ins_pipe(ialu_reg); 10683 %} 10684 10685 // Xor Register with Memory 10686 instruct xorI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 10687 %{ 10688 predicate(!UseAPX); 10689 match(Set dst (XorI dst (LoadI src))); 10690 effect(KILL cr); 10691 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10692 10693 ins_cost(150); 10694 format %{ "xorl $dst, $src\t# int" %} 10695 ins_encode %{ 10696 __ xorl($dst$$Register, $src$$Address); 10697 %} 10698 ins_pipe(ialu_reg_mem); 10699 %} 10700 10701 instruct xorI_rReg_rReg_mem_ndd(rRegI dst, rRegI src1, memory src2, rFlagsReg cr) 10702 %{ 10703 predicate(UseAPX); 10704 match(Set dst (XorI src1 (LoadI src2))); 10705 effect(KILL cr); 10706 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10707 10708 ins_cost(150); 10709 format %{ "exorl $dst, $src1, $src2\t# int ndd" %} 10710 ins_encode %{ 10711 __ exorl($dst$$Register, $src1$$Register, $src2$$Address, false); 10712 %} 10713 ins_pipe(ialu_reg_mem); 10714 %} 10715 10716 instruct xorI_rReg_mem_rReg_ndd(rRegI dst, memory src1, rRegI src2, rFlagsReg cr) 10717 %{ 10718 predicate(UseAPX); 10719 match(Set dst (XorI (LoadI src1) src2)); 10720 effect(KILL cr); 10721 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10722 10723 ins_cost(150); 10724 format %{ "exorl $dst, $src1, $src2\t# int ndd" %} 10725 ins_encode %{ 10726 __ exorl($dst$$Register, $src1$$Address, $src2$$Register, false); 10727 %} 10728 ins_pipe(ialu_reg_mem); 10729 %} 10730 10731 // Xor Memory with Register 10732 instruct xorB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 10733 %{ 10734 match(Set dst (StoreB dst (XorI (LoadB dst) src))); 10735 effect(KILL cr); 10736 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10737 10738 ins_cost(150); 10739 format %{ "xorb $dst, $src\t# byte" %} 10740 ins_encode %{ 10741 __ xorb($dst$$Address, $src$$Register); 10742 %} 10743 ins_pipe(ialu_mem_reg); 10744 %} 10745 10746 instruct xorI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 10747 %{ 10748 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 10749 effect(KILL cr); 10750 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10751 10752 ins_cost(150); 10753 format %{ "xorl $dst, $src\t# int" %} 10754 ins_encode %{ 10755 __ xorl($dst$$Address, $src$$Register); 10756 %} 10757 ins_pipe(ialu_mem_reg); 10758 %} 10759 10760 // Xor Memory with Immediate 10761 instruct xorI_mem_imm(memory dst, immI src, rFlagsReg cr) 10762 %{ 10763 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 10764 effect(KILL cr); 10765 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10766 10767 ins_cost(125); 10768 format %{ "xorl $dst, $src\t# int" %} 10769 ins_encode %{ 10770 __ xorl($dst$$Address, $src$$constant); 10771 %} 10772 ins_pipe(ialu_mem_imm); 10773 %} 10774 10775 10776 // Long Logical Instructions 10777 10778 // And Instructions 10779 // And Register with Register 10780 instruct andL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 10781 %{ 10782 predicate(!UseAPX); 10783 match(Set dst (AndL dst src)); 10784 effect(KILL cr); 10785 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10786 10787 format %{ "andq $dst, $src\t# long" %} 10788 ins_encode %{ 10789 __ andq($dst$$Register, $src$$Register); 10790 %} 10791 ins_pipe(ialu_reg_reg); 10792 %} 10793 10794 // And Register with Register using New Data Destination (NDD) 10795 instruct andL_rReg_ndd(rRegL dst, rRegL src1, rRegL src2, rFlagsReg cr) 10796 %{ 10797 predicate(UseAPX); 10798 match(Set dst (AndL src1 src2)); 10799 effect(KILL cr); 10800 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10801 10802 format %{ "eandq $dst, $src1, $src2\t# long ndd" %} 10803 ins_encode %{ 10804 __ eandq($dst$$Register, $src1$$Register, $src2$$Register, false); 10805 10806 %} 10807 ins_pipe(ialu_reg_reg); 10808 %} 10809 10810 // And Register with Immediate 255 10811 instruct andL_rReg_imm255(rRegL dst, rRegL src, immL_255 mask) 10812 %{ 10813 match(Set dst (AndL src mask)); 10814 10815 format %{ "movzbl $dst, $src\t# long & 0xFF" %} 10816 ins_encode %{ 10817 // movzbl zeroes out the upper 32-bit and does not need REX.W 10818 __ movzbl($dst$$Register, $src$$Register); 10819 %} 10820 ins_pipe(ialu_reg); 10821 %} 10822 10823 // And Register with Immediate 65535 10824 instruct andL_rReg_imm65535(rRegL dst, rRegL src, immL_65535 mask) 10825 %{ 10826 match(Set dst (AndL src mask)); 10827 10828 format %{ "movzwl $dst, $src\t# long & 0xFFFF" %} 10829 ins_encode %{ 10830 // movzwl zeroes out the upper 32-bit and does not need REX.W 10831 __ movzwl($dst$$Register, $src$$Register); 10832 %} 10833 ins_pipe(ialu_reg); 10834 %} 10835 10836 // And Register with Immediate 10837 instruct andL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 10838 %{ 10839 predicate(!UseAPX); 10840 match(Set dst (AndL dst src)); 10841 effect(KILL cr); 10842 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10843 10844 format %{ "andq $dst, $src\t# long" %} 10845 ins_encode %{ 10846 __ andq($dst$$Register, $src$$constant); 10847 %} 10848 ins_pipe(ialu_reg); 10849 %} 10850 10851 instruct andL_rReg_rReg_imm_ndd(rRegL dst, rRegL src1, immL32 src2, rFlagsReg cr) 10852 %{ 10853 predicate(UseAPX); 10854 match(Set dst (AndL src1 src2)); 10855 effect(KILL cr); 10856 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10857 10858 format %{ "eandq $dst, $src1, $src2\t# long ndd" %} 10859 ins_encode %{ 10860 __ eandq($dst$$Register, $src1$$Register, $src2$$constant, false); 10861 %} 10862 ins_pipe(ialu_reg); 10863 %} 10864 10865 instruct andL_rReg_mem_imm_ndd(rRegL dst, memory src1, immL32 src2, rFlagsReg cr) 10866 %{ 10867 predicate(UseAPX); 10868 match(Set dst (AndL (LoadL src1) src2)); 10869 effect(KILL cr); 10870 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10871 10872 format %{ "eandq $dst, $src1, $src2\t# long ndd" %} 10873 ins_encode %{ 10874 __ eandq($dst$$Register, $src1$$Address, $src2$$constant, false); 10875 %} 10876 ins_pipe(ialu_reg); 10877 %} 10878 10879 // And Register with Memory 10880 instruct andL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 10881 %{ 10882 predicate(!UseAPX); 10883 match(Set dst (AndL dst (LoadL src))); 10884 effect(KILL cr); 10885 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10886 10887 ins_cost(150); 10888 format %{ "andq $dst, $src\t# long" %} 10889 ins_encode %{ 10890 __ andq($dst$$Register, $src$$Address); 10891 %} 10892 ins_pipe(ialu_reg_mem); 10893 %} 10894 10895 instruct andL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr) 10896 %{ 10897 predicate(UseAPX); 10898 match(Set dst (AndL src1 (LoadL src2))); 10899 effect(KILL cr); 10900 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10901 10902 ins_cost(150); 10903 format %{ "eandq $dst, $src1, $src2\t# long ndd" %} 10904 ins_encode %{ 10905 __ eandq($dst$$Register, $src1$$Register, $src2$$Address, false); 10906 %} 10907 ins_pipe(ialu_reg_mem); 10908 %} 10909 10910 instruct andL_rReg_mem_rReg_ndd(rRegL dst, memory src1, rRegL src2, rFlagsReg cr) 10911 %{ 10912 predicate(UseAPX); 10913 match(Set dst (AndL (LoadL src1) src2)); 10914 effect(KILL cr); 10915 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10916 10917 ins_cost(150); 10918 format %{ "eandq $dst, $src1, $src2\t# long ndd" %} 10919 ins_encode %{ 10920 __ eandq($dst$$Register, $src1$$Address, $src2$$Register, false); 10921 %} 10922 ins_pipe(ialu_reg_mem); 10923 %} 10924 10925 // And Memory with Register 10926 instruct andL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 10927 %{ 10928 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 10929 effect(KILL cr); 10930 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10931 10932 ins_cost(150); 10933 format %{ "andq $dst, $src\t# long" %} 10934 ins_encode %{ 10935 __ andq($dst$$Address, $src$$Register); 10936 %} 10937 ins_pipe(ialu_mem_reg); 10938 %} 10939 10940 // And Memory with Immediate 10941 instruct andL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 10942 %{ 10943 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 10944 effect(KILL cr); 10945 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10946 10947 ins_cost(125); 10948 format %{ "andq $dst, $src\t# long" %} 10949 ins_encode %{ 10950 __ andq($dst$$Address, $src$$constant); 10951 %} 10952 ins_pipe(ialu_mem_imm); 10953 %} 10954 10955 instruct btrL_mem_imm(memory dst, immL_NotPow2 con, rFlagsReg cr) 10956 %{ 10957 // con should be a pure 64-bit immediate given that not(con) is a power of 2 10958 // because AND/OR works well enough for 8/32-bit values. 10959 predicate(log2i_graceful(~n->in(3)->in(2)->get_long()) > 30); 10960 10961 match(Set dst (StoreL dst (AndL (LoadL dst) con))); 10962 effect(KILL cr); 10963 10964 ins_cost(125); 10965 format %{ "btrq $dst, log2(not($con))\t# long" %} 10966 ins_encode %{ 10967 __ btrq($dst$$Address, log2i_exact((julong)~$con$$constant)); 10968 %} 10969 ins_pipe(ialu_mem_imm); 10970 %} 10971 10972 // BMI1 instructions 10973 instruct andnL_rReg_rReg_mem(rRegL dst, rRegL src1, memory src2, immL_M1 minus_1, rFlagsReg cr) %{ 10974 match(Set dst (AndL (XorL src1 minus_1) (LoadL src2))); 10975 predicate(UseBMI1Instructions); 10976 effect(KILL cr); 10977 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10978 10979 ins_cost(125); 10980 format %{ "andnq $dst, $src1, $src2" %} 10981 10982 ins_encode %{ 10983 __ andnq($dst$$Register, $src1$$Register, $src2$$Address); 10984 %} 10985 ins_pipe(ialu_reg_mem); 10986 %} 10987 10988 instruct andnL_rReg_rReg_rReg(rRegL dst, rRegL src1, rRegL src2, immL_M1 minus_1, rFlagsReg cr) %{ 10989 match(Set dst (AndL (XorL src1 minus_1) src2)); 10990 predicate(UseBMI1Instructions); 10991 effect(KILL cr); 10992 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 10993 10994 format %{ "andnq $dst, $src1, $src2" %} 10995 10996 ins_encode %{ 10997 __ andnq($dst$$Register, $src1$$Register, $src2$$Register); 10998 %} 10999 ins_pipe(ialu_reg_mem); 11000 %} 11001 11002 instruct blsiL_rReg_rReg(rRegL dst, rRegL src, immL0 imm_zero, rFlagsReg cr) %{ 11003 match(Set dst (AndL (SubL imm_zero src) src)); 11004 predicate(UseBMI1Instructions); 11005 effect(KILL cr); 11006 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 11007 11008 format %{ "blsiq $dst, $src" %} 11009 11010 ins_encode %{ 11011 __ blsiq($dst$$Register, $src$$Register); 11012 %} 11013 ins_pipe(ialu_reg); 11014 %} 11015 11016 instruct blsiL_rReg_mem(rRegL dst, memory src, immL0 imm_zero, rFlagsReg cr) %{ 11017 match(Set dst (AndL (SubL imm_zero (LoadL src) ) (LoadL src) )); 11018 predicate(UseBMI1Instructions); 11019 effect(KILL cr); 11020 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 11021 11022 ins_cost(125); 11023 format %{ "blsiq $dst, $src" %} 11024 11025 ins_encode %{ 11026 __ blsiq($dst$$Register, $src$$Address); 11027 %} 11028 ins_pipe(ialu_reg_mem); 11029 %} 11030 11031 instruct blsmskL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 11032 %{ 11033 match(Set dst (XorL (AddL (LoadL src) minus_1) (LoadL src) ) ); 11034 predicate(UseBMI1Instructions); 11035 effect(KILL cr); 11036 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 11037 11038 ins_cost(125); 11039 format %{ "blsmskq $dst, $src" %} 11040 11041 ins_encode %{ 11042 __ blsmskq($dst$$Register, $src$$Address); 11043 %} 11044 ins_pipe(ialu_reg_mem); 11045 %} 11046 11047 instruct blsmskL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 11048 %{ 11049 match(Set dst (XorL (AddL src minus_1) src)); 11050 predicate(UseBMI1Instructions); 11051 effect(KILL cr); 11052 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 11053 11054 format %{ "blsmskq $dst, $src" %} 11055 11056 ins_encode %{ 11057 __ blsmskq($dst$$Register, $src$$Register); 11058 %} 11059 11060 ins_pipe(ialu_reg); 11061 %} 11062 11063 instruct blsrL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 11064 %{ 11065 match(Set dst (AndL (AddL src minus_1) src) ); 11066 predicate(UseBMI1Instructions); 11067 effect(KILL cr); 11068 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 11069 11070 format %{ "blsrq $dst, $src" %} 11071 11072 ins_encode %{ 11073 __ blsrq($dst$$Register, $src$$Register); 11074 %} 11075 11076 ins_pipe(ialu_reg); 11077 %} 11078 11079 instruct blsrL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 11080 %{ 11081 match(Set dst (AndL (AddL (LoadL src) minus_1) (LoadL src)) ); 11082 predicate(UseBMI1Instructions); 11083 effect(KILL cr); 11084 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 11085 11086 ins_cost(125); 11087 format %{ "blsrq $dst, $src" %} 11088 11089 ins_encode %{ 11090 __ blsrq($dst$$Register, $src$$Address); 11091 %} 11092 11093 ins_pipe(ialu_reg); 11094 %} 11095 11096 // Or Instructions 11097 // Or Register with Register 11098 instruct orL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 11099 %{ 11100 predicate(!UseAPX); 11101 match(Set dst (OrL dst src)); 11102 effect(KILL cr); 11103 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11104 11105 format %{ "orq $dst, $src\t# long" %} 11106 ins_encode %{ 11107 __ orq($dst$$Register, $src$$Register); 11108 %} 11109 ins_pipe(ialu_reg_reg); 11110 %} 11111 11112 // Or Register with Register using New Data Destination (NDD) 11113 instruct orL_rReg_ndd(rRegL dst, rRegL 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, $src1, $src2\t# long ndd" %} 11121 ins_encode %{ 11122 __ eorq($dst$$Register, $src1$$Register, $src2$$Register, false); 11123 11124 %} 11125 ins_pipe(ialu_reg_reg); 11126 %} 11127 11128 // Use any_RegP to match R15 (TLS register) without spilling. 11129 instruct orL_rReg_castP2X(rRegL dst, any_RegP src, rFlagsReg cr) %{ 11130 match(Set dst (OrL dst (CastP2X src))); 11131 effect(KILL cr); 11132 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11133 11134 format %{ "orq $dst, $src\t# long" %} 11135 ins_encode %{ 11136 __ orq($dst$$Register, $src$$Register); 11137 %} 11138 ins_pipe(ialu_reg_reg); 11139 %} 11140 11141 instruct orL_rReg_castP2X_ndd(rRegL dst, any_RegP src1, any_RegP src2, rFlagsReg cr) %{ 11142 match(Set dst (OrL src1 (CastP2X src2))); 11143 effect(KILL cr); 11144 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11145 11146 format %{ "eorq $dst, $src1, $src2\t# long ndd" %} 11147 ins_encode %{ 11148 __ eorq($dst$$Register, $src1$$Register, $src2$$Register, false); 11149 %} 11150 ins_pipe(ialu_reg_reg); 11151 %} 11152 11153 // Or Register with Immediate 11154 instruct orL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 11155 %{ 11156 predicate(!UseAPX); 11157 match(Set dst (OrL dst src)); 11158 effect(KILL cr); 11159 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11160 11161 format %{ "orq $dst, $src\t# long" %} 11162 ins_encode %{ 11163 __ orq($dst$$Register, $src$$constant); 11164 %} 11165 ins_pipe(ialu_reg); 11166 %} 11167 11168 instruct orL_rReg_rReg_imm_ndd(rRegL dst, rRegL src1, immL32 src2, rFlagsReg cr) 11169 %{ 11170 predicate(UseAPX); 11171 match(Set dst (OrL src1 src2)); 11172 effect(KILL cr); 11173 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11174 11175 format %{ "eorq $dst, $src1, $src2\t# long ndd" %} 11176 ins_encode %{ 11177 __ eorq($dst$$Register, $src1$$Register, $src2$$constant, false); 11178 %} 11179 ins_pipe(ialu_reg); 11180 %} 11181 11182 instruct orL_rReg_imm_rReg_ndd(rRegL dst, immL32 src1, rRegL src2, rFlagsReg cr) 11183 %{ 11184 predicate(UseAPX); 11185 match(Set dst (OrL src1 src2)); 11186 effect(KILL cr); 11187 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11188 11189 format %{ "eorq $dst, $src2, $src1\t# long ndd" %} 11190 ins_encode %{ 11191 __ eorq($dst$$Register, $src2$$Register, $src1$$constant, false); 11192 %} 11193 ins_pipe(ialu_reg); 11194 %} 11195 11196 // Or Memory with Immediate 11197 instruct orL_rReg_mem_imm_ndd(rRegL dst, memory src1, immL32 src2, rFlagsReg cr) 11198 %{ 11199 predicate(UseAPX); 11200 match(Set dst (OrL (LoadL src1) src2)); 11201 effect(KILL cr); 11202 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11203 11204 format %{ "eorq $dst, $src1, $src2\t# long ndd" %} 11205 ins_encode %{ 11206 __ eorq($dst$$Register, $src1$$Address, $src2$$constant, false); 11207 %} 11208 ins_pipe(ialu_reg); 11209 %} 11210 11211 // Or Register with Memory 11212 instruct orL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 11213 %{ 11214 predicate(!UseAPX); 11215 match(Set dst (OrL dst (LoadL src))); 11216 effect(KILL cr); 11217 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11218 11219 ins_cost(150); 11220 format %{ "orq $dst, $src\t# long" %} 11221 ins_encode %{ 11222 __ orq($dst$$Register, $src$$Address); 11223 %} 11224 ins_pipe(ialu_reg_mem); 11225 %} 11226 11227 instruct orL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr) 11228 %{ 11229 predicate(UseAPX); 11230 match(Set dst (OrL src1 (LoadL src2))); 11231 effect(KILL cr); 11232 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11233 11234 ins_cost(150); 11235 format %{ "eorq $dst, $src1, $src2\t# long ndd" %} 11236 ins_encode %{ 11237 __ eorq($dst$$Register, $src1$$Register, $src2$$Address, false); 11238 %} 11239 ins_pipe(ialu_reg_mem); 11240 %} 11241 11242 // Or Memory with Register 11243 instruct orL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 11244 %{ 11245 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 11246 effect(KILL cr); 11247 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11248 11249 ins_cost(150); 11250 format %{ "orq $dst, $src\t# long" %} 11251 ins_encode %{ 11252 __ orq($dst$$Address, $src$$Register); 11253 %} 11254 ins_pipe(ialu_mem_reg); 11255 %} 11256 11257 // Or Memory with Immediate 11258 instruct orL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 11259 %{ 11260 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 11261 effect(KILL cr); 11262 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11263 11264 ins_cost(125); 11265 format %{ "orq $dst, $src\t# long" %} 11266 ins_encode %{ 11267 __ orq($dst$$Address, $src$$constant); 11268 %} 11269 ins_pipe(ialu_mem_imm); 11270 %} 11271 11272 instruct btsL_mem_imm(memory dst, immL_Pow2 con, rFlagsReg cr) 11273 %{ 11274 // con should be a pure 64-bit power of 2 immediate 11275 // because AND/OR works well enough for 8/32-bit values. 11276 predicate(log2i_graceful(n->in(3)->in(2)->get_long()) > 31); 11277 11278 match(Set dst (StoreL dst (OrL (LoadL dst) con))); 11279 effect(KILL cr); 11280 11281 ins_cost(125); 11282 format %{ "btsq $dst, log2($con)\t# long" %} 11283 ins_encode %{ 11284 __ btsq($dst$$Address, log2i_exact((julong)$con$$constant)); 11285 %} 11286 ins_pipe(ialu_mem_imm); 11287 %} 11288 11289 // Xor Instructions 11290 // Xor Register with Register 11291 instruct xorL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 11292 %{ 11293 predicate(!UseAPX); 11294 match(Set dst (XorL dst src)); 11295 effect(KILL cr); 11296 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11297 11298 format %{ "xorq $dst, $src\t# long" %} 11299 ins_encode %{ 11300 __ xorq($dst$$Register, $src$$Register); 11301 %} 11302 ins_pipe(ialu_reg_reg); 11303 %} 11304 11305 // Xor Register with Register using New Data Destination (NDD) 11306 instruct xorL_rReg_ndd(rRegL dst, rRegL src1, rRegL src2, rFlagsReg cr) 11307 %{ 11308 predicate(UseAPX); 11309 match(Set dst (XorL src1 src2)); 11310 effect(KILL cr); 11311 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11312 11313 format %{ "exorq $dst, $src1, $src2\t# long ndd" %} 11314 ins_encode %{ 11315 __ exorq($dst$$Register, $src1$$Register, $src2$$Register, false); 11316 %} 11317 ins_pipe(ialu_reg_reg); 11318 %} 11319 11320 // Xor Register with Immediate -1 11321 instruct xorL_rReg_im1(rRegL dst, immL_M1 imm) 11322 %{ 11323 predicate(!UseAPX); 11324 match(Set dst (XorL dst imm)); 11325 11326 format %{ "notq $dst" %} 11327 ins_encode %{ 11328 __ notq($dst$$Register); 11329 %} 11330 ins_pipe(ialu_reg); 11331 %} 11332 11333 instruct xorL_rReg_im1_ndd(rRegL dst,rRegL src, immL_M1 imm) 11334 %{ 11335 predicate(UseAPX); 11336 match(Set dst (XorL src imm)); 11337 11338 format %{ "enotq $dst, $src" %} 11339 ins_encode %{ 11340 __ enotq($dst$$Register, $src$$Register); 11341 %} 11342 ins_pipe(ialu_reg); 11343 %} 11344 11345 // Xor Register with Immediate 11346 instruct xorL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 11347 %{ 11348 predicate(!UseAPX); 11349 match(Set dst (XorL dst src)); 11350 effect(KILL cr); 11351 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11352 11353 format %{ "xorq $dst, $src\t# long" %} 11354 ins_encode %{ 11355 __ xorq($dst$$Register, $src$$constant); 11356 %} 11357 ins_pipe(ialu_reg); 11358 %} 11359 11360 instruct xorL_rReg_rReg_imm(rRegL dst, rRegL src1, immL32 src2, rFlagsReg cr) 11361 %{ 11362 predicate(UseAPX); 11363 match(Set dst (XorL src1 src2)); 11364 effect(KILL cr); 11365 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11366 11367 format %{ "exorq $dst, $src1, $src2\t# long ndd" %} 11368 ins_encode %{ 11369 __ exorq($dst$$Register, $src1$$Register, $src2$$constant, false); 11370 %} 11371 ins_pipe(ialu_reg); 11372 %} 11373 11374 // Xor Memory with Immediate 11375 instruct xorL_rReg_mem_imm(rRegL dst, memory src1, immL32 src2, rFlagsReg cr) 11376 %{ 11377 predicate(UseAPX); 11378 match(Set dst (XorL (LoadL src1) src2)); 11379 effect(KILL cr); 11380 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11381 11382 format %{ "exorq $dst, $src1, $src2\t# long ndd" %} 11383 ins_encode %{ 11384 __ exorq($dst$$Register, $src1$$Address, $src2$$constant, false); 11385 %} 11386 ins_pipe(ialu_reg); 11387 %} 11388 11389 // Xor Register with Memory 11390 instruct xorL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 11391 %{ 11392 predicate(!UseAPX); 11393 match(Set dst (XorL dst (LoadL src))); 11394 effect(KILL cr); 11395 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11396 11397 ins_cost(150); 11398 format %{ "xorq $dst, $src\t# long" %} 11399 ins_encode %{ 11400 __ xorq($dst$$Register, $src$$Address); 11401 %} 11402 ins_pipe(ialu_reg_mem); 11403 %} 11404 11405 instruct xorL_rReg_rReg_mem_ndd(rRegL dst, rRegL src1, memory src2, rFlagsReg cr) 11406 %{ 11407 predicate(UseAPX); 11408 match(Set dst (XorL src1 (LoadL src2))); 11409 effect(KILL cr); 11410 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11411 11412 ins_cost(150); 11413 format %{ "exorq $dst, $src1, $src2\t# long ndd" %} 11414 ins_encode %{ 11415 __ exorq($dst$$Register, $src1$$Register, $src2$$Address, false); 11416 %} 11417 ins_pipe(ialu_reg_mem); 11418 %} 11419 11420 instruct xorL_rReg_mem_rReg_ndd(rRegL dst, memory src1, rRegL src2, rFlagsReg cr) 11421 %{ 11422 predicate(UseAPX); 11423 match(Set dst (XorL (LoadL src1) src2)); 11424 effect(KILL cr); 11425 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11426 11427 ins_cost(150); 11428 format %{ "exorq $dst, $src1, $src2\t# long ndd" %} 11429 ins_encode %{ 11430 __ exorq($dst$$Register, $src1$$Address, $src2$$Register, false); 11431 %} 11432 ins_pipe(ialu_reg_mem); 11433 %} 11434 11435 // Xor Memory with Register 11436 instruct xorL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 11437 %{ 11438 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 11439 effect(KILL cr); 11440 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11441 11442 ins_cost(150); 11443 format %{ "xorq $dst, $src\t# long" %} 11444 ins_encode %{ 11445 __ xorq($dst$$Address, $src$$Register); 11446 %} 11447 ins_pipe(ialu_mem_reg); 11448 %} 11449 11450 // Xor Memory with Immediate 11451 instruct xorL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 11452 %{ 11453 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 11454 effect(KILL cr); 11455 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 11456 11457 ins_cost(125); 11458 format %{ "xorq $dst, $src\t# long" %} 11459 ins_encode %{ 11460 __ xorq($dst$$Address, $src$$constant); 11461 %} 11462 ins_pipe(ialu_mem_imm); 11463 %} 11464 11465 instruct cmpLTMask(rRegI dst, rRegI p, rRegI q, rFlagsReg cr) 11466 %{ 11467 match(Set dst (CmpLTMask p q)); 11468 effect(KILL cr); 11469 11470 ins_cost(400); 11471 format %{ "cmpl $p, $q\t# cmpLTMask\n\t" 11472 "setcc $dst \t# emits setlt + movzbl or setzul for APX" 11473 "negl $dst" %} 11474 ins_encode %{ 11475 __ cmpl($p$$Register, $q$$Register); 11476 __ setcc(Assembler::less, $dst$$Register); 11477 __ negl($dst$$Register); 11478 %} 11479 ins_pipe(pipe_slow); 11480 %} 11481 11482 instruct cmpLTMask0(rRegI dst, immI_0 zero, rFlagsReg cr) 11483 %{ 11484 match(Set dst (CmpLTMask dst zero)); 11485 effect(KILL cr); 11486 11487 ins_cost(100); 11488 format %{ "sarl $dst, #31\t# cmpLTMask0" %} 11489 ins_encode %{ 11490 __ sarl($dst$$Register, 31); 11491 %} 11492 ins_pipe(ialu_reg); 11493 %} 11494 11495 /* Better to save a register than avoid a branch */ 11496 instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 11497 %{ 11498 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q))); 11499 effect(KILL cr); 11500 ins_cost(300); 11501 format %{ "subl $p,$q\t# cadd_cmpLTMask\n\t" 11502 "jge done\n\t" 11503 "addl $p,$y\n" 11504 "done: " %} 11505 ins_encode %{ 11506 Register Rp = $p$$Register; 11507 Register Rq = $q$$Register; 11508 Register Ry = $y$$Register; 11509 Label done; 11510 __ subl(Rp, Rq); 11511 __ jccb(Assembler::greaterEqual, done); 11512 __ addl(Rp, Ry); 11513 __ bind(done); 11514 %} 11515 ins_pipe(pipe_cmplt); 11516 %} 11517 11518 /* Better to save a register than avoid a branch */ 11519 instruct and_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 11520 %{ 11521 match(Set y (AndI (CmpLTMask p q) y)); 11522 effect(KILL cr); 11523 11524 ins_cost(300); 11525 11526 format %{ "cmpl $p, $q\t# and_cmpLTMask\n\t" 11527 "jlt done\n\t" 11528 "xorl $y, $y\n" 11529 "done: " %} 11530 ins_encode %{ 11531 Register Rp = $p$$Register; 11532 Register Rq = $q$$Register; 11533 Register Ry = $y$$Register; 11534 Label done; 11535 __ cmpl(Rp, Rq); 11536 __ jccb(Assembler::less, done); 11537 __ xorl(Ry, Ry); 11538 __ bind(done); 11539 %} 11540 ins_pipe(pipe_cmplt); 11541 %} 11542 11543 11544 //---------- FP Instructions------------------------------------------------ 11545 11546 // Really expensive, avoid 11547 instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2) 11548 %{ 11549 match(Set cr (CmpF src1 src2)); 11550 11551 ins_cost(500); 11552 format %{ "ucomiss $src1, $src2\n\t" 11553 "jnp,s exit\n\t" 11554 "pushfq\t# saw NaN, set CF\n\t" 11555 "andq [rsp], #0xffffff2b\n\t" 11556 "popfq\n" 11557 "exit:" %} 11558 ins_encode %{ 11559 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 11560 emit_cmpfp_fixup(masm); 11561 %} 11562 ins_pipe(pipe_slow); 11563 %} 11564 11565 instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{ 11566 match(Set cr (CmpF src1 src2)); 11567 11568 ins_cost(100); 11569 format %{ "ucomiss $src1, $src2" %} 11570 ins_encode %{ 11571 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 11572 %} 11573 ins_pipe(pipe_slow); 11574 %} 11575 11576 instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{ 11577 match(Set cr (CmpF src1 (LoadF src2))); 11578 11579 ins_cost(100); 11580 format %{ "ucomiss $src1, $src2" %} 11581 ins_encode %{ 11582 __ ucomiss($src1$$XMMRegister, $src2$$Address); 11583 %} 11584 ins_pipe(pipe_slow); 11585 %} 11586 11587 instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src, immF con) %{ 11588 match(Set cr (CmpF src con)); 11589 ins_cost(100); 11590 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con" %} 11591 ins_encode %{ 11592 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 11593 %} 11594 ins_pipe(pipe_slow); 11595 %} 11596 11597 // Really expensive, avoid 11598 instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2) 11599 %{ 11600 match(Set cr (CmpD src1 src2)); 11601 11602 ins_cost(500); 11603 format %{ "ucomisd $src1, $src2\n\t" 11604 "jnp,s exit\n\t" 11605 "pushfq\t# saw NaN, set CF\n\t" 11606 "andq [rsp], #0xffffff2b\n\t" 11607 "popfq\n" 11608 "exit:" %} 11609 ins_encode %{ 11610 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 11611 emit_cmpfp_fixup(masm); 11612 %} 11613 ins_pipe(pipe_slow); 11614 %} 11615 11616 instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{ 11617 match(Set cr (CmpD src1 src2)); 11618 11619 ins_cost(100); 11620 format %{ "ucomisd $src1, $src2 test" %} 11621 ins_encode %{ 11622 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 11623 %} 11624 ins_pipe(pipe_slow); 11625 %} 11626 11627 instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{ 11628 match(Set cr (CmpD src1 (LoadD src2))); 11629 11630 ins_cost(100); 11631 format %{ "ucomisd $src1, $src2" %} 11632 ins_encode %{ 11633 __ ucomisd($src1$$XMMRegister, $src2$$Address); 11634 %} 11635 ins_pipe(pipe_slow); 11636 %} 11637 11638 instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src, immD con) %{ 11639 match(Set cr (CmpD src con)); 11640 ins_cost(100); 11641 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con" %} 11642 ins_encode %{ 11643 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 11644 %} 11645 ins_pipe(pipe_slow); 11646 %} 11647 11648 // Compare into -1,0,1 11649 instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr) 11650 %{ 11651 match(Set dst (CmpF3 src1 src2)); 11652 effect(KILL cr); 11653 11654 ins_cost(275); 11655 format %{ "ucomiss $src1, $src2\n\t" 11656 "movl $dst, #-1\n\t" 11657 "jp,s done\n\t" 11658 "jb,s done\n\t" 11659 "setne $dst\n\t" 11660 "movzbl $dst, $dst\n" 11661 "done:" %} 11662 ins_encode %{ 11663 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 11664 emit_cmpfp3(masm, $dst$$Register); 11665 %} 11666 ins_pipe(pipe_slow); 11667 %} 11668 11669 // Compare into -1,0,1 11670 instruct cmpF_mem(rRegI dst, regF src1, memory src2, rFlagsReg cr) 11671 %{ 11672 match(Set dst (CmpF3 src1 (LoadF src2))); 11673 effect(KILL cr); 11674 11675 ins_cost(275); 11676 format %{ "ucomiss $src1, $src2\n\t" 11677 "movl $dst, #-1\n\t" 11678 "jp,s done\n\t" 11679 "jb,s done\n\t" 11680 "setne $dst\n\t" 11681 "movzbl $dst, $dst\n" 11682 "done:" %} 11683 ins_encode %{ 11684 __ ucomiss($src1$$XMMRegister, $src2$$Address); 11685 emit_cmpfp3(masm, $dst$$Register); 11686 %} 11687 ins_pipe(pipe_slow); 11688 %} 11689 11690 // Compare into -1,0,1 11691 instruct cmpF_imm(rRegI dst, regF src, immF con, rFlagsReg cr) %{ 11692 match(Set dst (CmpF3 src con)); 11693 effect(KILL cr); 11694 11695 ins_cost(275); 11696 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 11697 "movl $dst, #-1\n\t" 11698 "jp,s done\n\t" 11699 "jb,s done\n\t" 11700 "setne $dst\n\t" 11701 "movzbl $dst, $dst\n" 11702 "done:" %} 11703 ins_encode %{ 11704 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 11705 emit_cmpfp3(masm, $dst$$Register); 11706 %} 11707 ins_pipe(pipe_slow); 11708 %} 11709 11710 // Compare into -1,0,1 11711 instruct cmpD_reg(rRegI dst, regD src1, regD src2, rFlagsReg cr) 11712 %{ 11713 match(Set dst (CmpD3 src1 src2)); 11714 effect(KILL cr); 11715 11716 ins_cost(275); 11717 format %{ "ucomisd $src1, $src2\n\t" 11718 "movl $dst, #-1\n\t" 11719 "jp,s done\n\t" 11720 "jb,s done\n\t" 11721 "setne $dst\n\t" 11722 "movzbl $dst, $dst\n" 11723 "done:" %} 11724 ins_encode %{ 11725 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 11726 emit_cmpfp3(masm, $dst$$Register); 11727 %} 11728 ins_pipe(pipe_slow); 11729 %} 11730 11731 // Compare into -1,0,1 11732 instruct cmpD_mem(rRegI dst, regD src1, memory src2, rFlagsReg cr) 11733 %{ 11734 match(Set dst (CmpD3 src1 (LoadD src2))); 11735 effect(KILL cr); 11736 11737 ins_cost(275); 11738 format %{ "ucomisd $src1, $src2\n\t" 11739 "movl $dst, #-1\n\t" 11740 "jp,s done\n\t" 11741 "jb,s done\n\t" 11742 "setne $dst\n\t" 11743 "movzbl $dst, $dst\n" 11744 "done:" %} 11745 ins_encode %{ 11746 __ ucomisd($src1$$XMMRegister, $src2$$Address); 11747 emit_cmpfp3(masm, $dst$$Register); 11748 %} 11749 ins_pipe(pipe_slow); 11750 %} 11751 11752 // Compare into -1,0,1 11753 instruct cmpD_imm(rRegI dst, regD src, immD con, rFlagsReg cr) %{ 11754 match(Set dst (CmpD3 src con)); 11755 effect(KILL cr); 11756 11757 ins_cost(275); 11758 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 11759 "movl $dst, #-1\n\t" 11760 "jp,s done\n\t" 11761 "jb,s done\n\t" 11762 "setne $dst\n\t" 11763 "movzbl $dst, $dst\n" 11764 "done:" %} 11765 ins_encode %{ 11766 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 11767 emit_cmpfp3(masm, $dst$$Register); 11768 %} 11769 ins_pipe(pipe_slow); 11770 %} 11771 11772 //----------Arithmetic Conversion Instructions--------------------------------- 11773 11774 instruct convF2D_reg_reg(regD dst, regF src) 11775 %{ 11776 match(Set dst (ConvF2D src)); 11777 11778 format %{ "cvtss2sd $dst, $src" %} 11779 ins_encode %{ 11780 __ cvtss2sd ($dst$$XMMRegister, $src$$XMMRegister); 11781 %} 11782 ins_pipe(pipe_slow); // XXX 11783 %} 11784 11785 instruct convF2D_reg_mem(regD dst, memory src) 11786 %{ 11787 predicate(UseAVX == 0); 11788 match(Set dst (ConvF2D (LoadF src))); 11789 11790 format %{ "cvtss2sd $dst, $src" %} 11791 ins_encode %{ 11792 __ cvtss2sd ($dst$$XMMRegister, $src$$Address); 11793 %} 11794 ins_pipe(pipe_slow); // XXX 11795 %} 11796 11797 instruct convD2F_reg_reg(regF dst, regD src) 11798 %{ 11799 match(Set dst (ConvD2F src)); 11800 11801 format %{ "cvtsd2ss $dst, $src" %} 11802 ins_encode %{ 11803 __ cvtsd2ss ($dst$$XMMRegister, $src$$XMMRegister); 11804 %} 11805 ins_pipe(pipe_slow); // XXX 11806 %} 11807 11808 instruct convD2F_reg_mem(regF dst, memory src) 11809 %{ 11810 predicate(UseAVX == 0); 11811 match(Set dst (ConvD2F (LoadD src))); 11812 11813 format %{ "cvtsd2ss $dst, $src" %} 11814 ins_encode %{ 11815 __ cvtsd2ss ($dst$$XMMRegister, $src$$Address); 11816 %} 11817 ins_pipe(pipe_slow); // XXX 11818 %} 11819 11820 // XXX do mem variants 11821 instruct convF2I_reg_reg(rRegI dst, regF src, rFlagsReg cr) 11822 %{ 11823 match(Set dst (ConvF2I src)); 11824 effect(KILL cr); 11825 format %{ "convert_f2i $dst, $src" %} 11826 ins_encode %{ 11827 __ convertF2I(T_INT, T_FLOAT, $dst$$Register, $src$$XMMRegister); 11828 %} 11829 ins_pipe(pipe_slow); 11830 %} 11831 11832 instruct convF2L_reg_reg(rRegL dst, regF src, rFlagsReg cr) 11833 %{ 11834 match(Set dst (ConvF2L src)); 11835 effect(KILL cr); 11836 format %{ "convert_f2l $dst, $src"%} 11837 ins_encode %{ 11838 __ convertF2I(T_LONG, T_FLOAT, $dst$$Register, $src$$XMMRegister); 11839 %} 11840 ins_pipe(pipe_slow); 11841 %} 11842 11843 instruct convD2I_reg_reg(rRegI dst, regD src, rFlagsReg cr) 11844 %{ 11845 match(Set dst (ConvD2I src)); 11846 effect(KILL cr); 11847 format %{ "convert_d2i $dst, $src"%} 11848 ins_encode %{ 11849 __ convertF2I(T_INT, T_DOUBLE, $dst$$Register, $src$$XMMRegister); 11850 %} 11851 ins_pipe(pipe_slow); 11852 %} 11853 11854 instruct convD2L_reg_reg(rRegL dst, regD src, rFlagsReg cr) 11855 %{ 11856 match(Set dst (ConvD2L src)); 11857 effect(KILL cr); 11858 format %{ "convert_d2l $dst, $src"%} 11859 ins_encode %{ 11860 __ convertF2I(T_LONG, T_DOUBLE, $dst$$Register, $src$$XMMRegister); 11861 %} 11862 ins_pipe(pipe_slow); 11863 %} 11864 11865 instruct round_double_reg(rRegL dst, regD src, rRegL rtmp, rcx_RegL rcx, rFlagsReg cr) 11866 %{ 11867 match(Set dst (RoundD src)); 11868 effect(TEMP dst, TEMP rtmp, TEMP rcx, KILL cr); 11869 format %{ "round_double $dst,$src \t! using $rtmp and $rcx as TEMP"%} 11870 ins_encode %{ 11871 __ round_double($dst$$Register, $src$$XMMRegister, $rtmp$$Register, $rcx$$Register); 11872 %} 11873 ins_pipe(pipe_slow); 11874 %} 11875 11876 instruct round_float_reg(rRegI dst, regF src, rRegL rtmp, rcx_RegL rcx, rFlagsReg cr) 11877 %{ 11878 match(Set dst (RoundF src)); 11879 effect(TEMP dst, TEMP rtmp, TEMP rcx, KILL cr); 11880 format %{ "round_float $dst,$src" %} 11881 ins_encode %{ 11882 __ round_float($dst$$Register, $src$$XMMRegister, $rtmp$$Register, $rcx$$Register); 11883 %} 11884 ins_pipe(pipe_slow); 11885 %} 11886 11887 instruct convI2F_reg_reg(vlRegF dst, rRegI src) 11888 %{ 11889 predicate(!UseXmmI2F); 11890 match(Set dst (ConvI2F src)); 11891 11892 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 11893 ins_encode %{ 11894 if (UseAVX > 0) { 11895 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 11896 } 11897 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Register); 11898 %} 11899 ins_pipe(pipe_slow); // XXX 11900 %} 11901 11902 instruct convI2F_reg_mem(regF dst, memory src) 11903 %{ 11904 predicate(UseAVX == 0); 11905 match(Set dst (ConvI2F (LoadI src))); 11906 11907 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 11908 ins_encode %{ 11909 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Address); 11910 %} 11911 ins_pipe(pipe_slow); // XXX 11912 %} 11913 11914 instruct convI2D_reg_reg(vlRegD dst, rRegI src) 11915 %{ 11916 predicate(!UseXmmI2D); 11917 match(Set dst (ConvI2D src)); 11918 11919 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 11920 ins_encode %{ 11921 if (UseAVX > 0) { 11922 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 11923 } 11924 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Register); 11925 %} 11926 ins_pipe(pipe_slow); // XXX 11927 %} 11928 11929 instruct convI2D_reg_mem(regD dst, memory src) 11930 %{ 11931 predicate(UseAVX == 0); 11932 match(Set dst (ConvI2D (LoadI src))); 11933 11934 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 11935 ins_encode %{ 11936 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Address); 11937 %} 11938 ins_pipe(pipe_slow); // XXX 11939 %} 11940 11941 instruct convXI2F_reg(regF dst, rRegI src) 11942 %{ 11943 predicate(UseXmmI2F); 11944 match(Set dst (ConvI2F src)); 11945 11946 format %{ "movdl $dst, $src\n\t" 11947 "cvtdq2psl $dst, $dst\t# i2f" %} 11948 ins_encode %{ 11949 __ movdl($dst$$XMMRegister, $src$$Register); 11950 __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister); 11951 %} 11952 ins_pipe(pipe_slow); // XXX 11953 %} 11954 11955 instruct convXI2D_reg(regD dst, rRegI src) 11956 %{ 11957 predicate(UseXmmI2D); 11958 match(Set dst (ConvI2D src)); 11959 11960 format %{ "movdl $dst, $src\n\t" 11961 "cvtdq2pdl $dst, $dst\t# i2d" %} 11962 ins_encode %{ 11963 __ movdl($dst$$XMMRegister, $src$$Register); 11964 __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister); 11965 %} 11966 ins_pipe(pipe_slow); // XXX 11967 %} 11968 11969 instruct convL2F_reg_reg(vlRegF dst, rRegL src) 11970 %{ 11971 match(Set dst (ConvL2F src)); 11972 11973 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 11974 ins_encode %{ 11975 if (UseAVX > 0) { 11976 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 11977 } 11978 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Register); 11979 %} 11980 ins_pipe(pipe_slow); // XXX 11981 %} 11982 11983 instruct convL2F_reg_mem(regF dst, memory src) 11984 %{ 11985 predicate(UseAVX == 0); 11986 match(Set dst (ConvL2F (LoadL src))); 11987 11988 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 11989 ins_encode %{ 11990 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Address); 11991 %} 11992 ins_pipe(pipe_slow); // XXX 11993 %} 11994 11995 instruct convL2D_reg_reg(vlRegD dst, rRegL src) 11996 %{ 11997 match(Set dst (ConvL2D src)); 11998 11999 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 12000 ins_encode %{ 12001 if (UseAVX > 0) { 12002 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 12003 } 12004 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Register); 12005 %} 12006 ins_pipe(pipe_slow); // XXX 12007 %} 12008 12009 instruct convL2D_reg_mem(regD dst, memory src) 12010 %{ 12011 predicate(UseAVX == 0); 12012 match(Set dst (ConvL2D (LoadL src))); 12013 12014 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 12015 ins_encode %{ 12016 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Address); 12017 %} 12018 ins_pipe(pipe_slow); // XXX 12019 %} 12020 12021 instruct convI2L_reg_reg(rRegL dst, rRegI src) 12022 %{ 12023 match(Set dst (ConvI2L src)); 12024 12025 ins_cost(125); 12026 format %{ "movslq $dst, $src\t# i2l" %} 12027 ins_encode %{ 12028 __ movslq($dst$$Register, $src$$Register); 12029 %} 12030 ins_pipe(ialu_reg_reg); 12031 %} 12032 12033 // Zero-extend convert int to long 12034 instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask) 12035 %{ 12036 match(Set dst (AndL (ConvI2L src) mask)); 12037 12038 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 12039 ins_encode %{ 12040 if ($dst$$reg != $src$$reg) { 12041 __ movl($dst$$Register, $src$$Register); 12042 } 12043 %} 12044 ins_pipe(ialu_reg_reg); 12045 %} 12046 12047 // Zero-extend convert int to long 12048 instruct convI2L_reg_mem_zex(rRegL dst, memory src, immL_32bits mask) 12049 %{ 12050 match(Set dst (AndL (ConvI2L (LoadI src)) mask)); 12051 12052 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 12053 ins_encode %{ 12054 __ movl($dst$$Register, $src$$Address); 12055 %} 12056 ins_pipe(ialu_reg_mem); 12057 %} 12058 12059 instruct zerox_long_reg_reg(rRegL dst, rRegL src, immL_32bits mask) 12060 %{ 12061 match(Set dst (AndL src mask)); 12062 12063 format %{ "movl $dst, $src\t# zero-extend long" %} 12064 ins_encode %{ 12065 __ movl($dst$$Register, $src$$Register); 12066 %} 12067 ins_pipe(ialu_reg_reg); 12068 %} 12069 12070 instruct convL2I_reg_reg(rRegI dst, rRegL src) 12071 %{ 12072 match(Set dst (ConvL2I src)); 12073 12074 format %{ "movl $dst, $src\t# l2i" %} 12075 ins_encode %{ 12076 __ movl($dst$$Register, $src$$Register); 12077 %} 12078 ins_pipe(ialu_reg_reg); 12079 %} 12080 12081 12082 instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{ 12083 match(Set dst (MoveF2I src)); 12084 effect(DEF dst, USE src); 12085 12086 ins_cost(125); 12087 format %{ "movl $dst, $src\t# MoveF2I_stack_reg" %} 12088 ins_encode %{ 12089 __ movl($dst$$Register, Address(rsp, $src$$disp)); 12090 %} 12091 ins_pipe(ialu_reg_mem); 12092 %} 12093 12094 instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{ 12095 match(Set dst (MoveI2F src)); 12096 effect(DEF dst, USE src); 12097 12098 ins_cost(125); 12099 format %{ "movss $dst, $src\t# MoveI2F_stack_reg" %} 12100 ins_encode %{ 12101 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 12102 %} 12103 ins_pipe(pipe_slow); 12104 %} 12105 12106 instruct MoveD2L_stack_reg(rRegL dst, stackSlotD src) %{ 12107 match(Set dst (MoveD2L src)); 12108 effect(DEF dst, USE src); 12109 12110 ins_cost(125); 12111 format %{ "movq $dst, $src\t# MoveD2L_stack_reg" %} 12112 ins_encode %{ 12113 __ movq($dst$$Register, Address(rsp, $src$$disp)); 12114 %} 12115 ins_pipe(ialu_reg_mem); 12116 %} 12117 12118 instruct MoveL2D_stack_reg_partial(regD dst, stackSlotL src) %{ 12119 predicate(!UseXmmLoadAndClearUpper); 12120 match(Set dst (MoveL2D src)); 12121 effect(DEF dst, USE src); 12122 12123 ins_cost(125); 12124 format %{ "movlpd $dst, $src\t# MoveL2D_stack_reg" %} 12125 ins_encode %{ 12126 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 12127 %} 12128 ins_pipe(pipe_slow); 12129 %} 12130 12131 instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{ 12132 predicate(UseXmmLoadAndClearUpper); 12133 match(Set dst (MoveL2D src)); 12134 effect(DEF dst, USE src); 12135 12136 ins_cost(125); 12137 format %{ "movsd $dst, $src\t# MoveL2D_stack_reg" %} 12138 ins_encode %{ 12139 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 12140 %} 12141 ins_pipe(pipe_slow); 12142 %} 12143 12144 12145 instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{ 12146 match(Set dst (MoveF2I src)); 12147 effect(DEF dst, USE src); 12148 12149 ins_cost(95); // XXX 12150 format %{ "movss $dst, $src\t# MoveF2I_reg_stack" %} 12151 ins_encode %{ 12152 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 12153 %} 12154 ins_pipe(pipe_slow); 12155 %} 12156 12157 instruct MoveI2F_reg_stack(stackSlotF dst, rRegI src) %{ 12158 match(Set dst (MoveI2F src)); 12159 effect(DEF dst, USE src); 12160 12161 ins_cost(100); 12162 format %{ "movl $dst, $src\t# MoveI2F_reg_stack" %} 12163 ins_encode %{ 12164 __ movl(Address(rsp, $dst$$disp), $src$$Register); 12165 %} 12166 ins_pipe( ialu_mem_reg ); 12167 %} 12168 12169 instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{ 12170 match(Set dst (MoveD2L src)); 12171 effect(DEF dst, USE src); 12172 12173 ins_cost(95); // XXX 12174 format %{ "movsd $dst, $src\t# MoveL2D_reg_stack" %} 12175 ins_encode %{ 12176 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 12177 %} 12178 ins_pipe(pipe_slow); 12179 %} 12180 12181 instruct MoveL2D_reg_stack(stackSlotD dst, rRegL src) %{ 12182 match(Set dst (MoveL2D src)); 12183 effect(DEF dst, USE src); 12184 12185 ins_cost(100); 12186 format %{ "movq $dst, $src\t# MoveL2D_reg_stack" %} 12187 ins_encode %{ 12188 __ movq(Address(rsp, $dst$$disp), $src$$Register); 12189 %} 12190 ins_pipe(ialu_mem_reg); 12191 %} 12192 12193 instruct MoveF2I_reg_reg(rRegI dst, regF src) %{ 12194 match(Set dst (MoveF2I src)); 12195 effect(DEF dst, USE src); 12196 ins_cost(85); 12197 format %{ "movd $dst,$src\t# MoveF2I" %} 12198 ins_encode %{ 12199 __ movdl($dst$$Register, $src$$XMMRegister); 12200 %} 12201 ins_pipe( pipe_slow ); 12202 %} 12203 12204 instruct MoveD2L_reg_reg(rRegL dst, regD src) %{ 12205 match(Set dst (MoveD2L src)); 12206 effect(DEF dst, USE src); 12207 ins_cost(85); 12208 format %{ "movd $dst,$src\t# MoveD2L" %} 12209 ins_encode %{ 12210 __ movdq($dst$$Register, $src$$XMMRegister); 12211 %} 12212 ins_pipe( pipe_slow ); 12213 %} 12214 12215 instruct MoveI2F_reg_reg(regF dst, rRegI src) %{ 12216 match(Set dst (MoveI2F src)); 12217 effect(DEF dst, USE src); 12218 ins_cost(100); 12219 format %{ "movd $dst,$src\t# MoveI2F" %} 12220 ins_encode %{ 12221 __ movdl($dst$$XMMRegister, $src$$Register); 12222 %} 12223 ins_pipe( pipe_slow ); 12224 %} 12225 12226 instruct MoveL2D_reg_reg(regD dst, rRegL src) %{ 12227 match(Set dst (MoveL2D src)); 12228 effect(DEF dst, USE src); 12229 ins_cost(100); 12230 format %{ "movd $dst,$src\t# MoveL2D" %} 12231 ins_encode %{ 12232 __ movdq($dst$$XMMRegister, $src$$Register); 12233 %} 12234 ins_pipe( pipe_slow ); 12235 %} 12236 12237 // Fast clearing of an array 12238 // Small non-constant lenght ClearArray for non-AVX512 targets. 12239 instruct rep_stos(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegI zero, 12240 Universe dummy, rFlagsReg cr) 12241 %{ 12242 predicate(!((ClearArrayNode*)n)->is_large() && (UseAVX <= 2)); 12243 match(Set dummy (ClearArray cnt base)); 12244 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL zero, KILL cr); 12245 12246 format %{ $$template 12247 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 12248 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 12249 $$emit$$"jg LARGE\n\t" 12250 $$emit$$"dec rcx\n\t" 12251 $$emit$$"js DONE\t# Zero length\n\t" 12252 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 12253 $$emit$$"dec rcx\n\t" 12254 $$emit$$"jge LOOP\n\t" 12255 $$emit$$"jmp DONE\n\t" 12256 $$emit$$"# LARGE:\n\t" 12257 if (UseFastStosb) { 12258 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 12259 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--\n\t" 12260 } else if (UseXMMForObjInit) { 12261 $$emit$$"mov rdi,rax\n\t" 12262 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 12263 $$emit$$"jmpq L_zero_64_bytes\n\t" 12264 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 12265 $$emit$$"vmovdqu ymm0,(rax)\n\t" 12266 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 12267 $$emit$$"add 0x40,rax\n\t" 12268 $$emit$$"# L_zero_64_bytes:\n\t" 12269 $$emit$$"sub 0x8,rcx\n\t" 12270 $$emit$$"jge L_loop\n\t" 12271 $$emit$$"add 0x4,rcx\n\t" 12272 $$emit$$"jl L_tail\n\t" 12273 $$emit$$"vmovdqu ymm0,(rax)\n\t" 12274 $$emit$$"add 0x20,rax\n\t" 12275 $$emit$$"sub 0x4,rcx\n\t" 12276 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 12277 $$emit$$"add 0x4,rcx\n\t" 12278 $$emit$$"jle L_end\n\t" 12279 $$emit$$"dec rcx\n\t" 12280 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 12281 $$emit$$"vmovq xmm0,(rax)\n\t" 12282 $$emit$$"add 0x8,rax\n\t" 12283 $$emit$$"dec rcx\n\t" 12284 $$emit$$"jge L_sloop\n\t" 12285 $$emit$$"# L_end:\n\t" 12286 } else { 12287 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 12288 } 12289 $$emit$$"# DONE" 12290 %} 12291 ins_encode %{ 12292 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 12293 $tmp$$XMMRegister, false, knoreg); 12294 %} 12295 ins_pipe(pipe_slow); 12296 %} 12297 12298 // Small non-constant length ClearArray for AVX512 targets. 12299 instruct rep_stos_evex(rcx_RegL cnt, rdi_RegP base, legRegD tmp, kReg ktmp, rax_RegI zero, 12300 Universe dummy, rFlagsReg cr) 12301 %{ 12302 predicate(!((ClearArrayNode*)n)->is_large() && (UseAVX > 2)); 12303 match(Set dummy (ClearArray cnt base)); 12304 ins_cost(125); 12305 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, TEMP ktmp, KILL zero, KILL cr); 12306 12307 format %{ $$template 12308 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 12309 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 12310 $$emit$$"jg LARGE\n\t" 12311 $$emit$$"dec rcx\n\t" 12312 $$emit$$"js DONE\t# Zero length\n\t" 12313 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 12314 $$emit$$"dec rcx\n\t" 12315 $$emit$$"jge LOOP\n\t" 12316 $$emit$$"jmp DONE\n\t" 12317 $$emit$$"# LARGE:\n\t" 12318 if (UseFastStosb) { 12319 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 12320 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--\n\t" 12321 } else if (UseXMMForObjInit) { 12322 $$emit$$"mov rdi,rax\n\t" 12323 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 12324 $$emit$$"jmpq L_zero_64_bytes\n\t" 12325 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 12326 $$emit$$"vmovdqu ymm0,(rax)\n\t" 12327 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 12328 $$emit$$"add 0x40,rax\n\t" 12329 $$emit$$"# L_zero_64_bytes:\n\t" 12330 $$emit$$"sub 0x8,rcx\n\t" 12331 $$emit$$"jge L_loop\n\t" 12332 $$emit$$"add 0x4,rcx\n\t" 12333 $$emit$$"jl L_tail\n\t" 12334 $$emit$$"vmovdqu ymm0,(rax)\n\t" 12335 $$emit$$"add 0x20,rax\n\t" 12336 $$emit$$"sub 0x4,rcx\n\t" 12337 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 12338 $$emit$$"add 0x4,rcx\n\t" 12339 $$emit$$"jle L_end\n\t" 12340 $$emit$$"dec rcx\n\t" 12341 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 12342 $$emit$$"vmovq xmm0,(rax)\n\t" 12343 $$emit$$"add 0x8,rax\n\t" 12344 $$emit$$"dec rcx\n\t" 12345 $$emit$$"jge L_sloop\n\t" 12346 $$emit$$"# L_end:\n\t" 12347 } else { 12348 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 12349 } 12350 $$emit$$"# DONE" 12351 %} 12352 ins_encode %{ 12353 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 12354 $tmp$$XMMRegister, false, $ktmp$$KRegister); 12355 %} 12356 ins_pipe(pipe_slow); 12357 %} 12358 12359 // Large non-constant length ClearArray for non-AVX512 targets. 12360 instruct rep_stos_large(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegI zero, 12361 Universe dummy, rFlagsReg cr) 12362 %{ 12363 predicate((UseAVX <=2) && ((ClearArrayNode*)n)->is_large()); 12364 match(Set dummy (ClearArray cnt base)); 12365 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL zero, KILL cr); 12366 12367 format %{ $$template 12368 if (UseFastStosb) { 12369 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 12370 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 12371 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--" 12372 } else if (UseXMMForObjInit) { 12373 $$emit$$"mov rdi,rax\t# ClearArray:\n\t" 12374 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 12375 $$emit$$"jmpq L_zero_64_bytes\n\t" 12376 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 12377 $$emit$$"vmovdqu ymm0,(rax)\n\t" 12378 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 12379 $$emit$$"add 0x40,rax\n\t" 12380 $$emit$$"# L_zero_64_bytes:\n\t" 12381 $$emit$$"sub 0x8,rcx\n\t" 12382 $$emit$$"jge L_loop\n\t" 12383 $$emit$$"add 0x4,rcx\n\t" 12384 $$emit$$"jl L_tail\n\t" 12385 $$emit$$"vmovdqu ymm0,(rax)\n\t" 12386 $$emit$$"add 0x20,rax\n\t" 12387 $$emit$$"sub 0x4,rcx\n\t" 12388 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 12389 $$emit$$"add 0x4,rcx\n\t" 12390 $$emit$$"jle L_end\n\t" 12391 $$emit$$"dec rcx\n\t" 12392 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 12393 $$emit$$"vmovq xmm0,(rax)\n\t" 12394 $$emit$$"add 0x8,rax\n\t" 12395 $$emit$$"dec rcx\n\t" 12396 $$emit$$"jge L_sloop\n\t" 12397 $$emit$$"# L_end:\n\t" 12398 } else { 12399 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 12400 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 12401 } 12402 %} 12403 ins_encode %{ 12404 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 12405 $tmp$$XMMRegister, true, knoreg); 12406 %} 12407 ins_pipe(pipe_slow); 12408 %} 12409 12410 // Large non-constant length ClearArray for AVX512 targets. 12411 instruct rep_stos_large_evex(rcx_RegL cnt, rdi_RegP base, legRegD tmp, kReg ktmp, rax_RegI zero, 12412 Universe dummy, rFlagsReg cr) 12413 %{ 12414 predicate((UseAVX > 2) && ((ClearArrayNode*)n)->is_large()); 12415 match(Set dummy (ClearArray cnt base)); 12416 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, TEMP ktmp, KILL zero, KILL cr); 12417 12418 format %{ $$template 12419 if (UseFastStosb) { 12420 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 12421 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 12422 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--" 12423 } else if (UseXMMForObjInit) { 12424 $$emit$$"mov rdi,rax\t# ClearArray:\n\t" 12425 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 12426 $$emit$$"jmpq L_zero_64_bytes\n\t" 12427 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 12428 $$emit$$"vmovdqu ymm0,(rax)\n\t" 12429 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 12430 $$emit$$"add 0x40,rax\n\t" 12431 $$emit$$"# L_zero_64_bytes:\n\t" 12432 $$emit$$"sub 0x8,rcx\n\t" 12433 $$emit$$"jge L_loop\n\t" 12434 $$emit$$"add 0x4,rcx\n\t" 12435 $$emit$$"jl L_tail\n\t" 12436 $$emit$$"vmovdqu ymm0,(rax)\n\t" 12437 $$emit$$"add 0x20,rax\n\t" 12438 $$emit$$"sub 0x4,rcx\n\t" 12439 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 12440 $$emit$$"add 0x4,rcx\n\t" 12441 $$emit$$"jle L_end\n\t" 12442 $$emit$$"dec rcx\n\t" 12443 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 12444 $$emit$$"vmovq xmm0,(rax)\n\t" 12445 $$emit$$"add 0x8,rax\n\t" 12446 $$emit$$"dec rcx\n\t" 12447 $$emit$$"jge L_sloop\n\t" 12448 $$emit$$"# L_end:\n\t" 12449 } else { 12450 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 12451 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 12452 } 12453 %} 12454 ins_encode %{ 12455 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 12456 $tmp$$XMMRegister, true, $ktmp$$KRegister); 12457 %} 12458 ins_pipe(pipe_slow); 12459 %} 12460 12461 // Small constant length ClearArray for AVX512 targets. 12462 instruct rep_stos_im(immL cnt, rRegP base, regD tmp, rRegI zero, kReg ktmp, Universe dummy, rFlagsReg cr) 12463 %{ 12464 predicate(!((ClearArrayNode*)n)->is_large() && (MaxVectorSize >= 32) && VM_Version::supports_avx512vl()); 12465 match(Set dummy (ClearArray cnt base)); 12466 ins_cost(100); 12467 effect(TEMP tmp, TEMP zero, TEMP ktmp, KILL cr); 12468 format %{ "clear_mem_imm $base , $cnt \n\t" %} 12469 ins_encode %{ 12470 __ clear_mem($base$$Register, $cnt$$constant, $zero$$Register, $tmp$$XMMRegister, $ktmp$$KRegister); 12471 %} 12472 ins_pipe(pipe_slow); 12473 %} 12474 12475 instruct string_compareL(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 12476 rax_RegI result, legRegD tmp1, rFlagsReg cr) 12477 %{ 12478 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 12479 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12480 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 12481 12482 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 12483 ins_encode %{ 12484 __ string_compare($str1$$Register, $str2$$Register, 12485 $cnt1$$Register, $cnt2$$Register, $result$$Register, 12486 $tmp1$$XMMRegister, StrIntrinsicNode::LL, knoreg); 12487 %} 12488 ins_pipe( pipe_slow ); 12489 %} 12490 12491 instruct string_compareL_evex(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 12492 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 12493 %{ 12494 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 12495 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12496 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 12497 12498 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 12499 ins_encode %{ 12500 __ string_compare($str1$$Register, $str2$$Register, 12501 $cnt1$$Register, $cnt2$$Register, $result$$Register, 12502 $tmp1$$XMMRegister, StrIntrinsicNode::LL, $ktmp$$KRegister); 12503 %} 12504 ins_pipe( pipe_slow ); 12505 %} 12506 12507 instruct string_compareU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 12508 rax_RegI result, legRegD tmp1, rFlagsReg cr) 12509 %{ 12510 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 12511 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12512 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 12513 12514 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 12515 ins_encode %{ 12516 __ string_compare($str1$$Register, $str2$$Register, 12517 $cnt1$$Register, $cnt2$$Register, $result$$Register, 12518 $tmp1$$XMMRegister, StrIntrinsicNode::UU, knoreg); 12519 %} 12520 ins_pipe( pipe_slow ); 12521 %} 12522 12523 instruct string_compareU_evex(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 12524 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 12525 %{ 12526 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 12527 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12528 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 12529 12530 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 12531 ins_encode %{ 12532 __ string_compare($str1$$Register, $str2$$Register, 12533 $cnt1$$Register, $cnt2$$Register, $result$$Register, 12534 $tmp1$$XMMRegister, StrIntrinsicNode::UU, $ktmp$$KRegister); 12535 %} 12536 ins_pipe( pipe_slow ); 12537 %} 12538 12539 instruct string_compareLU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 12540 rax_RegI result, legRegD tmp1, rFlagsReg cr) 12541 %{ 12542 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 12543 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12544 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 12545 12546 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 12547 ins_encode %{ 12548 __ string_compare($str1$$Register, $str2$$Register, 12549 $cnt1$$Register, $cnt2$$Register, $result$$Register, 12550 $tmp1$$XMMRegister, StrIntrinsicNode::LU, knoreg); 12551 %} 12552 ins_pipe( pipe_slow ); 12553 %} 12554 12555 instruct string_compareLU_evex(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 12556 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 12557 %{ 12558 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 12559 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12560 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 12561 12562 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 12563 ins_encode %{ 12564 __ string_compare($str1$$Register, $str2$$Register, 12565 $cnt1$$Register, $cnt2$$Register, $result$$Register, 12566 $tmp1$$XMMRegister, StrIntrinsicNode::LU, $ktmp$$KRegister); 12567 %} 12568 ins_pipe( pipe_slow ); 12569 %} 12570 12571 instruct string_compareUL(rsi_RegP str1, rdx_RegI cnt1, rdi_RegP str2, rcx_RegI cnt2, 12572 rax_RegI result, legRegD tmp1, rFlagsReg cr) 12573 %{ 12574 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 12575 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12576 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 12577 12578 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 12579 ins_encode %{ 12580 __ string_compare($str2$$Register, $str1$$Register, 12581 $cnt2$$Register, $cnt1$$Register, $result$$Register, 12582 $tmp1$$XMMRegister, StrIntrinsicNode::UL, knoreg); 12583 %} 12584 ins_pipe( pipe_slow ); 12585 %} 12586 12587 instruct string_compareUL_evex(rsi_RegP str1, rdx_RegI cnt1, rdi_RegP str2, rcx_RegI cnt2, 12588 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 12589 %{ 12590 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 12591 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12592 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 12593 12594 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 12595 ins_encode %{ 12596 __ string_compare($str2$$Register, $str1$$Register, 12597 $cnt2$$Register, $cnt1$$Register, $result$$Register, 12598 $tmp1$$XMMRegister, StrIntrinsicNode::UL, $ktmp$$KRegister); 12599 %} 12600 ins_pipe( pipe_slow ); 12601 %} 12602 12603 // fast search of substring with known size. 12604 instruct string_indexof_conL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 12605 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 12606 %{ 12607 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 12608 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 12609 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 12610 12611 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %} 12612 ins_encode %{ 12613 int icnt2 = (int)$int_cnt2$$constant; 12614 if (icnt2 >= 16) { 12615 // IndexOf for constant substrings with size >= 16 elements 12616 // which don't need to be loaded through stack. 12617 __ string_indexofC8($str1$$Register, $str2$$Register, 12618 $cnt1$$Register, $cnt2$$Register, 12619 icnt2, $result$$Register, 12620 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 12621 } else { 12622 // Small strings are loaded through stack if they cross page boundary. 12623 __ string_indexof($str1$$Register, $str2$$Register, 12624 $cnt1$$Register, $cnt2$$Register, 12625 icnt2, $result$$Register, 12626 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 12627 } 12628 %} 12629 ins_pipe( pipe_slow ); 12630 %} 12631 12632 // fast search of substring with known size. 12633 instruct string_indexof_conU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 12634 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 12635 %{ 12636 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 12637 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 12638 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 12639 12640 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %} 12641 ins_encode %{ 12642 int icnt2 = (int)$int_cnt2$$constant; 12643 if (icnt2 >= 8) { 12644 // IndexOf for constant substrings with size >= 8 elements 12645 // which don't need to be loaded through stack. 12646 __ string_indexofC8($str1$$Register, $str2$$Register, 12647 $cnt1$$Register, $cnt2$$Register, 12648 icnt2, $result$$Register, 12649 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 12650 } else { 12651 // Small strings are loaded through stack if they cross page boundary. 12652 __ string_indexof($str1$$Register, $str2$$Register, 12653 $cnt1$$Register, $cnt2$$Register, 12654 icnt2, $result$$Register, 12655 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 12656 } 12657 %} 12658 ins_pipe( pipe_slow ); 12659 %} 12660 12661 // fast search of substring with known size. 12662 instruct string_indexof_conUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 12663 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 12664 %{ 12665 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 12666 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 12667 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 12668 12669 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %} 12670 ins_encode %{ 12671 int icnt2 = (int)$int_cnt2$$constant; 12672 if (icnt2 >= 8) { 12673 // IndexOf for constant substrings with size >= 8 elements 12674 // which don't need to be loaded through stack. 12675 __ string_indexofC8($str1$$Register, $str2$$Register, 12676 $cnt1$$Register, $cnt2$$Register, 12677 icnt2, $result$$Register, 12678 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 12679 } else { 12680 // Small strings are loaded through stack if they cross page boundary. 12681 __ string_indexof($str1$$Register, $str2$$Register, 12682 $cnt1$$Register, $cnt2$$Register, 12683 icnt2, $result$$Register, 12684 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 12685 } 12686 %} 12687 ins_pipe( pipe_slow ); 12688 %} 12689 12690 instruct string_indexofL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 12691 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr) 12692 %{ 12693 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 12694 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 12695 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 12696 12697 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 12698 ins_encode %{ 12699 __ string_indexof($str1$$Register, $str2$$Register, 12700 $cnt1$$Register, $cnt2$$Register, 12701 (-1), $result$$Register, 12702 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 12703 %} 12704 ins_pipe( pipe_slow ); 12705 %} 12706 12707 instruct string_indexofU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 12708 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr) 12709 %{ 12710 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 12711 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 12712 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 12713 12714 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 12715 ins_encode %{ 12716 __ string_indexof($str1$$Register, $str2$$Register, 12717 $cnt1$$Register, $cnt2$$Register, 12718 (-1), $result$$Register, 12719 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 12720 %} 12721 ins_pipe( pipe_slow ); 12722 %} 12723 12724 instruct string_indexofUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 12725 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr) 12726 %{ 12727 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 12728 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 12729 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 12730 12731 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 12732 ins_encode %{ 12733 __ string_indexof($str1$$Register, $str2$$Register, 12734 $cnt1$$Register, $cnt2$$Register, 12735 (-1), $result$$Register, 12736 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 12737 %} 12738 ins_pipe( pipe_slow ); 12739 %} 12740 12741 instruct string_indexof_char(rdi_RegP str1, rdx_RegI cnt1, rax_RegI ch, 12742 rbx_RegI result, legRegD tmp_vec1, legRegD tmp_vec2, legRegD tmp_vec3, rcx_RegI tmp, rFlagsReg cr) 12743 %{ 12744 predicate(UseSSE42Intrinsics && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::U)); 12745 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 12746 effect(TEMP tmp_vec1, TEMP tmp_vec2, TEMP tmp_vec3, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP tmp, KILL cr); 12747 format %{ "StringUTF16 IndexOf char[] $str1,$cnt1,$ch -> $result // KILL all" %} 12748 ins_encode %{ 12749 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register, 12750 $tmp_vec1$$XMMRegister, $tmp_vec2$$XMMRegister, $tmp_vec3$$XMMRegister, $tmp$$Register); 12751 %} 12752 ins_pipe( pipe_slow ); 12753 %} 12754 12755 instruct stringL_indexof_char(rdi_RegP str1, rdx_RegI cnt1, rax_RegI ch, 12756 rbx_RegI result, legRegD tmp_vec1, legRegD tmp_vec2, legRegD tmp_vec3, rcx_RegI tmp, rFlagsReg cr) 12757 %{ 12758 predicate(UseSSE42Intrinsics && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::L)); 12759 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 12760 effect(TEMP tmp_vec1, TEMP tmp_vec2, TEMP tmp_vec3, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP tmp, KILL cr); 12761 format %{ "StringLatin1 IndexOf char[] $str1,$cnt1,$ch -> $result // KILL all" %} 12762 ins_encode %{ 12763 __ stringL_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register, 12764 $tmp_vec1$$XMMRegister, $tmp_vec2$$XMMRegister, $tmp_vec3$$XMMRegister, $tmp$$Register); 12765 %} 12766 ins_pipe( pipe_slow ); 12767 %} 12768 12769 // fast string equals 12770 instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 12771 legRegD tmp1, legRegD tmp2, rbx_RegI tmp3, rFlagsReg cr) 12772 %{ 12773 predicate(!VM_Version::supports_avx512vlbw()); 12774 match(Set result (StrEquals (Binary str1 str2) cnt)); 12775 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 12776 12777 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 12778 ins_encode %{ 12779 __ arrays_equals(false, $str1$$Register, $str2$$Register, 12780 $cnt$$Register, $result$$Register, $tmp3$$Register, 12781 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, knoreg); 12782 %} 12783 ins_pipe( pipe_slow ); 12784 %} 12785 12786 instruct string_equals_evex(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 12787 legRegD tmp1, legRegD tmp2, kReg ktmp, rbx_RegI tmp3, rFlagsReg cr) 12788 %{ 12789 predicate(VM_Version::supports_avx512vlbw()); 12790 match(Set result (StrEquals (Binary str1 str2) cnt)); 12791 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 12792 12793 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 12794 ins_encode %{ 12795 __ arrays_equals(false, $str1$$Register, $str2$$Register, 12796 $cnt$$Register, $result$$Register, $tmp3$$Register, 12797 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, $ktmp$$KRegister); 12798 %} 12799 ins_pipe( pipe_slow ); 12800 %} 12801 12802 // fast array equals 12803 instruct array_equalsB(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 12804 legRegD tmp1, legRegD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 12805 %{ 12806 predicate(!VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 12807 match(Set result (AryEq ary1 ary2)); 12808 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 12809 12810 format %{ "Array Equals byte[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 12811 ins_encode %{ 12812 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 12813 $tmp3$$Register, $result$$Register, $tmp4$$Register, 12814 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, knoreg); 12815 %} 12816 ins_pipe( pipe_slow ); 12817 %} 12818 12819 instruct array_equalsB_evex(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 12820 legRegD tmp1, legRegD tmp2, kReg ktmp, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 12821 %{ 12822 predicate(VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 12823 match(Set result (AryEq ary1 ary2)); 12824 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 12825 12826 format %{ "Array Equals byte[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 12827 ins_encode %{ 12828 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 12829 $tmp3$$Register, $result$$Register, $tmp4$$Register, 12830 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, $ktmp$$KRegister); 12831 %} 12832 ins_pipe( pipe_slow ); 12833 %} 12834 12835 instruct array_equalsC(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 12836 legRegD tmp1, legRegD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 12837 %{ 12838 predicate(!VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 12839 match(Set result (AryEq ary1 ary2)); 12840 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 12841 12842 format %{ "Array Equals char[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 12843 ins_encode %{ 12844 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 12845 $tmp3$$Register, $result$$Register, $tmp4$$Register, 12846 $tmp1$$XMMRegister, $tmp2$$XMMRegister, true /* char */, knoreg); 12847 %} 12848 ins_pipe( pipe_slow ); 12849 %} 12850 12851 instruct array_equalsC_evex(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 12852 legRegD tmp1, legRegD tmp2, kReg ktmp, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 12853 %{ 12854 predicate(VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 12855 match(Set result (AryEq ary1 ary2)); 12856 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 12857 12858 format %{ "Array Equals char[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 12859 ins_encode %{ 12860 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 12861 $tmp3$$Register, $result$$Register, $tmp4$$Register, 12862 $tmp1$$XMMRegister, $tmp2$$XMMRegister, true /* char */, $ktmp$$KRegister); 12863 %} 12864 ins_pipe( pipe_slow ); 12865 %} 12866 12867 instruct arrays_hashcode(rdi_RegP ary1, rdx_RegI cnt1, rbx_RegI result, immU8 basic_type, 12868 legRegD tmp_vec1, legRegD tmp_vec2, legRegD tmp_vec3, legRegD tmp_vec4, 12869 legRegD tmp_vec5, legRegD tmp_vec6, legRegD tmp_vec7, legRegD tmp_vec8, 12870 legRegD tmp_vec9, legRegD tmp_vec10, legRegD tmp_vec11, legRegD tmp_vec12, 12871 legRegD tmp_vec13, rRegI tmp1, rRegI tmp2, rRegI tmp3, rFlagsReg cr) 12872 %{ 12873 predicate(UseAVX >= 2); 12874 match(Set result (VectorizedHashCode (Binary ary1 cnt1) (Binary result basic_type))); 12875 effect(TEMP tmp_vec1, TEMP tmp_vec2, TEMP tmp_vec3, TEMP tmp_vec4, TEMP tmp_vec5, TEMP tmp_vec6, 12876 TEMP tmp_vec7, TEMP tmp_vec8, TEMP tmp_vec9, TEMP tmp_vec10, TEMP tmp_vec11, TEMP tmp_vec12, 12877 TEMP tmp_vec13, TEMP tmp1, TEMP tmp2, TEMP tmp3, USE_KILL ary1, USE_KILL cnt1, 12878 USE basic_type, KILL cr); 12879 12880 format %{ "Array HashCode array[] $ary1,$cnt1,$result,$basic_type -> $result // KILL all" %} 12881 ins_encode %{ 12882 __ arrays_hashcode($ary1$$Register, $cnt1$$Register, $result$$Register, 12883 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 12884 $tmp_vec1$$XMMRegister, $tmp_vec2$$XMMRegister, $tmp_vec3$$XMMRegister, 12885 $tmp_vec4$$XMMRegister, $tmp_vec5$$XMMRegister, $tmp_vec6$$XMMRegister, 12886 $tmp_vec7$$XMMRegister, $tmp_vec8$$XMMRegister, $tmp_vec9$$XMMRegister, 12887 $tmp_vec10$$XMMRegister, $tmp_vec11$$XMMRegister, $tmp_vec12$$XMMRegister, 12888 $tmp_vec13$$XMMRegister, (BasicType)$basic_type$$constant); 12889 %} 12890 ins_pipe( pipe_slow ); 12891 %} 12892 12893 instruct count_positives(rsi_RegP ary1, rcx_RegI len, rax_RegI result, 12894 legRegD tmp1, legRegD tmp2, rbx_RegI tmp3, rFlagsReg cr,) 12895 %{ 12896 predicate(!VM_Version::supports_avx512vlbw() || !VM_Version::supports_bmi2()); 12897 match(Set result (CountPositives ary1 len)); 12898 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr); 12899 12900 format %{ "countPositives byte[] $ary1,$len -> $result // KILL $tmp1, $tmp2, $tmp3" %} 12901 ins_encode %{ 12902 __ count_positives($ary1$$Register, $len$$Register, 12903 $result$$Register, $tmp3$$Register, 12904 $tmp1$$XMMRegister, $tmp2$$XMMRegister, knoreg, knoreg); 12905 %} 12906 ins_pipe( pipe_slow ); 12907 %} 12908 12909 instruct count_positives_evex(rsi_RegP ary1, rcx_RegI len, rax_RegI result, 12910 legRegD tmp1, legRegD tmp2, kReg ktmp1, kReg ktmp2, rbx_RegI tmp3, rFlagsReg cr,) 12911 %{ 12912 predicate(VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2()); 12913 match(Set result (CountPositives ary1 len)); 12914 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp1, TEMP ktmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr); 12915 12916 format %{ "countPositives byte[] $ary1,$len -> $result // KILL $tmp1, $tmp2, $tmp3" %} 12917 ins_encode %{ 12918 __ count_positives($ary1$$Register, $len$$Register, 12919 $result$$Register, $tmp3$$Register, 12920 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $ktmp1$$KRegister, $ktmp2$$KRegister); 12921 %} 12922 ins_pipe( pipe_slow ); 12923 %} 12924 12925 // fast char[] to byte[] compression 12926 instruct string_compress(rsi_RegP src, rdi_RegP dst, rdx_RegI len, legRegD tmp1, legRegD tmp2, legRegD tmp3, 12927 legRegD tmp4, rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 12928 predicate(!VM_Version::supports_avx512vlbw() || !VM_Version::supports_bmi2()); 12929 match(Set result (StrCompressedCopy src (Binary dst len))); 12930 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, 12931 USE_KILL len, KILL tmp5, KILL cr); 12932 12933 format %{ "String Compress $src,$dst -> $result // KILL RAX, RCX, RDX" %} 12934 ins_encode %{ 12935 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 12936 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 12937 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, 12938 knoreg, knoreg); 12939 %} 12940 ins_pipe( pipe_slow ); 12941 %} 12942 12943 instruct string_compress_evex(rsi_RegP src, rdi_RegP dst, rdx_RegI len, legRegD tmp1, legRegD tmp2, legRegD tmp3, 12944 legRegD tmp4, kReg ktmp1, kReg ktmp2, rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 12945 predicate(VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2()); 12946 match(Set result (StrCompressedCopy src (Binary dst len))); 12947 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP ktmp1, TEMP ktmp2, USE_KILL src, USE_KILL dst, 12948 USE_KILL len, KILL tmp5, KILL cr); 12949 12950 format %{ "String Compress $src,$dst -> $result // KILL RAX, RCX, RDX" %} 12951 ins_encode %{ 12952 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 12953 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 12954 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, 12955 $ktmp1$$KRegister, $ktmp2$$KRegister); 12956 %} 12957 ins_pipe( pipe_slow ); 12958 %} 12959 // fast byte[] to char[] inflation 12960 instruct string_inflate(Universe dummy, rsi_RegP src, rdi_RegP dst, rdx_RegI len, 12961 legRegD tmp1, rcx_RegI tmp2, rFlagsReg cr) %{ 12962 predicate(!VM_Version::supports_avx512vlbw() || !VM_Version::supports_bmi2()); 12963 match(Set dummy (StrInflatedCopy src (Binary dst len))); 12964 effect(TEMP tmp1, TEMP tmp2, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 12965 12966 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 12967 ins_encode %{ 12968 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 12969 $tmp1$$XMMRegister, $tmp2$$Register, knoreg); 12970 %} 12971 ins_pipe( pipe_slow ); 12972 %} 12973 12974 instruct string_inflate_evex(Universe dummy, rsi_RegP src, rdi_RegP dst, rdx_RegI len, 12975 legRegD tmp1, kReg ktmp, rcx_RegI tmp2, rFlagsReg cr) %{ 12976 predicate(VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2()); 12977 match(Set dummy (StrInflatedCopy src (Binary dst len))); 12978 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 12979 12980 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 12981 ins_encode %{ 12982 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 12983 $tmp1$$XMMRegister, $tmp2$$Register, $ktmp$$KRegister); 12984 %} 12985 ins_pipe( pipe_slow ); 12986 %} 12987 12988 // encode char[] to byte[] in ISO_8859_1 12989 instruct encode_iso_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len, 12990 legRegD tmp1, legRegD tmp2, legRegD tmp3, legRegD tmp4, 12991 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 12992 predicate(!((EncodeISOArrayNode*)n)->is_ascii()); 12993 match(Set result (EncodeISOArray src (Binary dst len))); 12994 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 12995 12996 format %{ "Encode iso array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %} 12997 ins_encode %{ 12998 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 12999 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 13000 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, false); 13001 %} 13002 ins_pipe( pipe_slow ); 13003 %} 13004 13005 // encode char[] to byte[] in ASCII 13006 instruct encode_ascii_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len, 13007 legRegD tmp1, legRegD tmp2, legRegD tmp3, legRegD tmp4, 13008 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 13009 predicate(((EncodeISOArrayNode*)n)->is_ascii()); 13010 match(Set result (EncodeISOArray src (Binary dst len))); 13011 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 13012 13013 format %{ "Encode ascii array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %} 13014 ins_encode %{ 13015 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 13016 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 13017 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, true); 13018 %} 13019 ins_pipe( pipe_slow ); 13020 %} 13021 13022 //----------Overflow Math Instructions----------------------------------------- 13023 13024 instruct overflowAddI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 13025 %{ 13026 match(Set cr (OverflowAddI op1 op2)); 13027 effect(DEF cr, USE_KILL op1, USE op2); 13028 13029 format %{ "addl $op1, $op2\t# overflow check int" %} 13030 13031 ins_encode %{ 13032 __ addl($op1$$Register, $op2$$Register); 13033 %} 13034 ins_pipe(ialu_reg_reg); 13035 %} 13036 13037 instruct overflowAddI_rReg_imm(rFlagsReg cr, rax_RegI op1, immI op2) 13038 %{ 13039 match(Set cr (OverflowAddI op1 op2)); 13040 effect(DEF cr, USE_KILL op1, USE op2); 13041 13042 format %{ "addl $op1, $op2\t# overflow check int" %} 13043 13044 ins_encode %{ 13045 __ addl($op1$$Register, $op2$$constant); 13046 %} 13047 ins_pipe(ialu_reg_reg); 13048 %} 13049 13050 instruct overflowAddL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 13051 %{ 13052 match(Set cr (OverflowAddL op1 op2)); 13053 effect(DEF cr, USE_KILL op1, USE op2); 13054 13055 format %{ "addq $op1, $op2\t# overflow check long" %} 13056 ins_encode %{ 13057 __ addq($op1$$Register, $op2$$Register); 13058 %} 13059 ins_pipe(ialu_reg_reg); 13060 %} 13061 13062 instruct overflowAddL_rReg_imm(rFlagsReg cr, rax_RegL op1, immL32 op2) 13063 %{ 13064 match(Set cr (OverflowAddL op1 op2)); 13065 effect(DEF cr, USE_KILL op1, USE op2); 13066 13067 format %{ "addq $op1, $op2\t# overflow check long" %} 13068 ins_encode %{ 13069 __ addq($op1$$Register, $op2$$constant); 13070 %} 13071 ins_pipe(ialu_reg_reg); 13072 %} 13073 13074 instruct overflowSubI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 13075 %{ 13076 match(Set cr (OverflowSubI op1 op2)); 13077 13078 format %{ "cmpl $op1, $op2\t# overflow check int" %} 13079 ins_encode %{ 13080 __ cmpl($op1$$Register, $op2$$Register); 13081 %} 13082 ins_pipe(ialu_reg_reg); 13083 %} 13084 13085 instruct overflowSubI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 13086 %{ 13087 match(Set cr (OverflowSubI op1 op2)); 13088 13089 format %{ "cmpl $op1, $op2\t# overflow check int" %} 13090 ins_encode %{ 13091 __ cmpl($op1$$Register, $op2$$constant); 13092 %} 13093 ins_pipe(ialu_reg_reg); 13094 %} 13095 13096 instruct overflowSubL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 13097 %{ 13098 match(Set cr (OverflowSubL op1 op2)); 13099 13100 format %{ "cmpq $op1, $op2\t# overflow check long" %} 13101 ins_encode %{ 13102 __ cmpq($op1$$Register, $op2$$Register); 13103 %} 13104 ins_pipe(ialu_reg_reg); 13105 %} 13106 13107 instruct overflowSubL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 13108 %{ 13109 match(Set cr (OverflowSubL op1 op2)); 13110 13111 format %{ "cmpq $op1, $op2\t# overflow check long" %} 13112 ins_encode %{ 13113 __ cmpq($op1$$Register, $op2$$constant); 13114 %} 13115 ins_pipe(ialu_reg_reg); 13116 %} 13117 13118 instruct overflowNegI_rReg(rFlagsReg cr, immI_0 zero, rax_RegI op2) 13119 %{ 13120 match(Set cr (OverflowSubI zero op2)); 13121 effect(DEF cr, USE_KILL op2); 13122 13123 format %{ "negl $op2\t# overflow check int" %} 13124 ins_encode %{ 13125 __ negl($op2$$Register); 13126 %} 13127 ins_pipe(ialu_reg_reg); 13128 %} 13129 13130 instruct overflowNegL_rReg(rFlagsReg cr, immL0 zero, rax_RegL op2) 13131 %{ 13132 match(Set cr (OverflowSubL zero op2)); 13133 effect(DEF cr, USE_KILL op2); 13134 13135 format %{ "negq $op2\t# overflow check long" %} 13136 ins_encode %{ 13137 __ negq($op2$$Register); 13138 %} 13139 ins_pipe(ialu_reg_reg); 13140 %} 13141 13142 instruct overflowMulI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 13143 %{ 13144 match(Set cr (OverflowMulI op1 op2)); 13145 effect(DEF cr, USE_KILL op1, USE op2); 13146 13147 format %{ "imull $op1, $op2\t# overflow check int" %} 13148 ins_encode %{ 13149 __ imull($op1$$Register, $op2$$Register); 13150 %} 13151 ins_pipe(ialu_reg_reg_alu0); 13152 %} 13153 13154 instruct overflowMulI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2, rRegI tmp) 13155 %{ 13156 match(Set cr (OverflowMulI op1 op2)); 13157 effect(DEF cr, TEMP tmp, USE op1, USE op2); 13158 13159 format %{ "imull $tmp, $op1, $op2\t# overflow check int" %} 13160 ins_encode %{ 13161 __ imull($tmp$$Register, $op1$$Register, $op2$$constant); 13162 %} 13163 ins_pipe(ialu_reg_reg_alu0); 13164 %} 13165 13166 instruct overflowMulL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 13167 %{ 13168 match(Set cr (OverflowMulL op1 op2)); 13169 effect(DEF cr, USE_KILL op1, USE op2); 13170 13171 format %{ "imulq $op1, $op2\t# overflow check long" %} 13172 ins_encode %{ 13173 __ imulq($op1$$Register, $op2$$Register); 13174 %} 13175 ins_pipe(ialu_reg_reg_alu0); 13176 %} 13177 13178 instruct overflowMulL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2, rRegL tmp) 13179 %{ 13180 match(Set cr (OverflowMulL op1 op2)); 13181 effect(DEF cr, TEMP tmp, USE op1, USE op2); 13182 13183 format %{ "imulq $tmp, $op1, $op2\t# overflow check long" %} 13184 ins_encode %{ 13185 __ imulq($tmp$$Register, $op1$$Register, $op2$$constant); 13186 %} 13187 ins_pipe(ialu_reg_reg_alu0); 13188 %} 13189 13190 13191 //----------Control Flow Instructions------------------------------------------ 13192 // Signed compare Instructions 13193 13194 // XXX more variants!! 13195 instruct compI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 13196 %{ 13197 match(Set cr (CmpI op1 op2)); 13198 effect(DEF cr, USE op1, USE op2); 13199 13200 format %{ "cmpl $op1, $op2" %} 13201 ins_encode %{ 13202 __ cmpl($op1$$Register, $op2$$Register); 13203 %} 13204 ins_pipe(ialu_cr_reg_reg); 13205 %} 13206 13207 instruct compI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 13208 %{ 13209 match(Set cr (CmpI op1 op2)); 13210 13211 format %{ "cmpl $op1, $op2" %} 13212 ins_encode %{ 13213 __ cmpl($op1$$Register, $op2$$constant); 13214 %} 13215 ins_pipe(ialu_cr_reg_imm); 13216 %} 13217 13218 instruct compI_rReg_mem(rFlagsReg cr, rRegI op1, memory op2) 13219 %{ 13220 match(Set cr (CmpI op1 (LoadI op2))); 13221 13222 ins_cost(500); // XXX 13223 format %{ "cmpl $op1, $op2" %} 13224 ins_encode %{ 13225 __ cmpl($op1$$Register, $op2$$Address); 13226 %} 13227 ins_pipe(ialu_cr_reg_mem); 13228 %} 13229 13230 instruct testI_reg(rFlagsReg cr, rRegI src, immI_0 zero) 13231 %{ 13232 match(Set cr (CmpI src zero)); 13233 13234 format %{ "testl $src, $src" %} 13235 ins_encode %{ 13236 __ testl($src$$Register, $src$$Register); 13237 %} 13238 ins_pipe(ialu_cr_reg_imm); 13239 %} 13240 13241 instruct testI_reg_imm(rFlagsReg cr, rRegI src, immI con, immI_0 zero) 13242 %{ 13243 match(Set cr (CmpI (AndI src con) zero)); 13244 13245 format %{ "testl $src, $con" %} 13246 ins_encode %{ 13247 __ testl($src$$Register, $con$$constant); 13248 %} 13249 ins_pipe(ialu_cr_reg_imm); 13250 %} 13251 13252 instruct testI_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2, immI_0 zero) 13253 %{ 13254 match(Set cr (CmpI (AndI src1 src2) zero)); 13255 13256 format %{ "testl $src1, $src2" %} 13257 ins_encode %{ 13258 __ testl($src1$$Register, $src2$$Register); 13259 %} 13260 ins_pipe(ialu_cr_reg_imm); 13261 %} 13262 13263 instruct testI_reg_mem(rFlagsReg cr, rRegI src, memory mem, immI_0 zero) 13264 %{ 13265 match(Set cr (CmpI (AndI src (LoadI mem)) zero)); 13266 13267 format %{ "testl $src, $mem" %} 13268 ins_encode %{ 13269 __ testl($src$$Register, $mem$$Address); 13270 %} 13271 ins_pipe(ialu_cr_reg_mem); 13272 %} 13273 13274 // Unsigned compare Instructions; really, same as signed except they 13275 // produce an rFlagsRegU instead of rFlagsReg. 13276 instruct compU_rReg(rFlagsRegU cr, rRegI op1, rRegI op2) 13277 %{ 13278 match(Set cr (CmpU op1 op2)); 13279 13280 format %{ "cmpl $op1, $op2\t# unsigned" %} 13281 ins_encode %{ 13282 __ cmpl($op1$$Register, $op2$$Register); 13283 %} 13284 ins_pipe(ialu_cr_reg_reg); 13285 %} 13286 13287 instruct compU_rReg_imm(rFlagsRegU cr, rRegI op1, immI op2) 13288 %{ 13289 match(Set cr (CmpU op1 op2)); 13290 13291 format %{ "cmpl $op1, $op2\t# unsigned" %} 13292 ins_encode %{ 13293 __ cmpl($op1$$Register, $op2$$constant); 13294 %} 13295 ins_pipe(ialu_cr_reg_imm); 13296 %} 13297 13298 instruct compU_rReg_mem(rFlagsRegU cr, rRegI op1, memory op2) 13299 %{ 13300 match(Set cr (CmpU op1 (LoadI op2))); 13301 13302 ins_cost(500); // XXX 13303 format %{ "cmpl $op1, $op2\t# unsigned" %} 13304 ins_encode %{ 13305 __ cmpl($op1$$Register, $op2$$Address); 13306 %} 13307 ins_pipe(ialu_cr_reg_mem); 13308 %} 13309 13310 instruct testU_reg(rFlagsRegU cr, rRegI src, immI_0 zero) 13311 %{ 13312 match(Set cr (CmpU src zero)); 13313 13314 format %{ "testl $src, $src\t# unsigned" %} 13315 ins_encode %{ 13316 __ testl($src$$Register, $src$$Register); 13317 %} 13318 ins_pipe(ialu_cr_reg_imm); 13319 %} 13320 13321 instruct compP_rReg(rFlagsRegU cr, rRegP op1, rRegP op2) 13322 %{ 13323 match(Set cr (CmpP op1 op2)); 13324 13325 format %{ "cmpq $op1, $op2\t# ptr" %} 13326 ins_encode %{ 13327 __ cmpq($op1$$Register, $op2$$Register); 13328 %} 13329 ins_pipe(ialu_cr_reg_reg); 13330 %} 13331 13332 instruct compP_rReg_mem(rFlagsRegU cr, rRegP op1, memory op2) 13333 %{ 13334 match(Set cr (CmpP op1 (LoadP op2))); 13335 predicate(n->in(2)->as_Load()->barrier_data() == 0); 13336 13337 ins_cost(500); // XXX 13338 format %{ "cmpq $op1, $op2\t# ptr" %} 13339 ins_encode %{ 13340 __ cmpq($op1$$Register, $op2$$Address); 13341 %} 13342 ins_pipe(ialu_cr_reg_mem); 13343 %} 13344 13345 // XXX this is generalized by compP_rReg_mem??? 13346 // Compare raw pointer (used in out-of-heap check). 13347 // Only works because non-oop pointers must be raw pointers 13348 // and raw pointers have no anti-dependencies. 13349 instruct compP_mem_rReg(rFlagsRegU cr, rRegP op1, memory op2) 13350 %{ 13351 predicate(n->in(2)->in(2)->bottom_type()->reloc() == relocInfo::none && 13352 n->in(2)->as_Load()->barrier_data() == 0); 13353 match(Set cr (CmpP op1 (LoadP op2))); 13354 13355 format %{ "cmpq $op1, $op2\t# raw ptr" %} 13356 ins_encode %{ 13357 __ cmpq($op1$$Register, $op2$$Address); 13358 %} 13359 ins_pipe(ialu_cr_reg_mem); 13360 %} 13361 13362 // This will generate a signed flags result. This should be OK since 13363 // any compare to a zero should be eq/neq. 13364 instruct testP_reg(rFlagsReg cr, rRegP src, immP0 zero) 13365 %{ 13366 match(Set cr (CmpP src zero)); 13367 13368 format %{ "testq $src, $src\t# ptr" %} 13369 ins_encode %{ 13370 __ testq($src$$Register, $src$$Register); 13371 %} 13372 ins_pipe(ialu_cr_reg_imm); 13373 %} 13374 13375 // This will generate a signed flags result. This should be OK since 13376 // any compare to a zero should be eq/neq. 13377 instruct testP_mem(rFlagsReg cr, memory op, immP0 zero) 13378 %{ 13379 predicate((!UseCompressedOops || (CompressedOops::base() != nullptr)) && 13380 n->in(1)->as_Load()->barrier_data() == 0); 13381 match(Set cr (CmpP (LoadP op) zero)); 13382 13383 ins_cost(500); // XXX 13384 format %{ "testq $op, 0xffffffffffffffff\t# ptr" %} 13385 ins_encode %{ 13386 __ testq($op$$Address, 0xFFFFFFFF); 13387 %} 13388 ins_pipe(ialu_cr_reg_imm); 13389 %} 13390 13391 instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero) 13392 %{ 13393 predicate(UseCompressedOops && (CompressedOops::base() == nullptr) && 13394 n->in(1)->as_Load()->barrier_data() == 0); 13395 match(Set cr (CmpP (LoadP mem) zero)); 13396 13397 format %{ "cmpq R12, $mem\t# ptr (R12_heapbase==0)" %} 13398 ins_encode %{ 13399 __ cmpq(r12, $mem$$Address); 13400 %} 13401 ins_pipe(ialu_cr_reg_mem); 13402 %} 13403 13404 instruct compN_rReg(rFlagsRegU cr, rRegN op1, rRegN op2) 13405 %{ 13406 match(Set cr (CmpN op1 op2)); 13407 13408 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 13409 ins_encode %{ __ cmpl($op1$$Register, $op2$$Register); %} 13410 ins_pipe(ialu_cr_reg_reg); 13411 %} 13412 13413 instruct compN_rReg_mem(rFlagsRegU cr, rRegN src, memory mem) 13414 %{ 13415 predicate(n->in(2)->as_Load()->barrier_data() == 0); 13416 match(Set cr (CmpN src (LoadN mem))); 13417 13418 format %{ "cmpl $src, $mem\t# compressed ptr" %} 13419 ins_encode %{ 13420 __ cmpl($src$$Register, $mem$$Address); 13421 %} 13422 ins_pipe(ialu_cr_reg_mem); 13423 %} 13424 13425 instruct compN_rReg_imm(rFlagsRegU cr, rRegN op1, immN op2) %{ 13426 match(Set cr (CmpN op1 op2)); 13427 13428 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 13429 ins_encode %{ 13430 __ cmp_narrow_oop($op1$$Register, (jobject)$op2$$constant); 13431 %} 13432 ins_pipe(ialu_cr_reg_imm); 13433 %} 13434 13435 instruct compN_mem_imm(rFlagsRegU cr, memory mem, immN src) 13436 %{ 13437 predicate(n->in(2)->as_Load()->barrier_data() == 0); 13438 match(Set cr (CmpN src (LoadN mem))); 13439 13440 format %{ "cmpl $mem, $src\t# compressed ptr" %} 13441 ins_encode %{ 13442 __ cmp_narrow_oop($mem$$Address, (jobject)$src$$constant); 13443 %} 13444 ins_pipe(ialu_cr_reg_mem); 13445 %} 13446 13447 instruct compN_rReg_imm_klass(rFlagsRegU cr, rRegN op1, immNKlass op2) %{ 13448 match(Set cr (CmpN op1 op2)); 13449 13450 format %{ "cmpl $op1, $op2\t# compressed klass ptr" %} 13451 ins_encode %{ 13452 __ cmp_narrow_klass($op1$$Register, (Klass*)$op2$$constant); 13453 %} 13454 ins_pipe(ialu_cr_reg_imm); 13455 %} 13456 13457 instruct compN_mem_imm_klass(rFlagsRegU cr, memory mem, immNKlass src) 13458 %{ 13459 predicate(!UseCompactObjectHeaders); 13460 match(Set cr (CmpN src (LoadNKlass mem))); 13461 13462 format %{ "cmpl $mem, $src\t# compressed klass ptr" %} 13463 ins_encode %{ 13464 __ cmp_narrow_klass($mem$$Address, (Klass*)$src$$constant); 13465 %} 13466 ins_pipe(ialu_cr_reg_mem); 13467 %} 13468 13469 instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{ 13470 match(Set cr (CmpN src zero)); 13471 13472 format %{ "testl $src, $src\t# compressed ptr" %} 13473 ins_encode %{ __ testl($src$$Register, $src$$Register); %} 13474 ins_pipe(ialu_cr_reg_imm); 13475 %} 13476 13477 instruct testN_mem(rFlagsReg cr, memory mem, immN0 zero) 13478 %{ 13479 predicate(CompressedOops::base() != nullptr && 13480 n->in(1)->as_Load()->barrier_data() == 0); 13481 match(Set cr (CmpN (LoadN mem) zero)); 13482 13483 ins_cost(500); // XXX 13484 format %{ "testl $mem, 0xffffffff\t# compressed ptr" %} 13485 ins_encode %{ 13486 __ cmpl($mem$$Address, (int)0xFFFFFFFF); 13487 %} 13488 ins_pipe(ialu_cr_reg_mem); 13489 %} 13490 13491 instruct testN_mem_reg0(rFlagsReg cr, memory mem, immN0 zero) 13492 %{ 13493 predicate(CompressedOops::base() == nullptr && 13494 n->in(1)->as_Load()->barrier_data() == 0); 13495 match(Set cr (CmpN (LoadN mem) zero)); 13496 13497 format %{ "cmpl R12, $mem\t# compressed ptr (R12_heapbase==0)" %} 13498 ins_encode %{ 13499 __ cmpl(r12, $mem$$Address); 13500 %} 13501 ins_pipe(ialu_cr_reg_mem); 13502 %} 13503 13504 // Yanked all unsigned pointer compare operations. 13505 // Pointer compares are done with CmpP which is already unsigned. 13506 13507 instruct compL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 13508 %{ 13509 match(Set cr (CmpL op1 op2)); 13510 13511 format %{ "cmpq $op1, $op2" %} 13512 ins_encode %{ 13513 __ cmpq($op1$$Register, $op2$$Register); 13514 %} 13515 ins_pipe(ialu_cr_reg_reg); 13516 %} 13517 13518 instruct compL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 13519 %{ 13520 match(Set cr (CmpL op1 op2)); 13521 13522 format %{ "cmpq $op1, $op2" %} 13523 ins_encode %{ 13524 __ cmpq($op1$$Register, $op2$$constant); 13525 %} 13526 ins_pipe(ialu_cr_reg_imm); 13527 %} 13528 13529 instruct compL_rReg_mem(rFlagsReg cr, rRegL op1, memory op2) 13530 %{ 13531 match(Set cr (CmpL op1 (LoadL op2))); 13532 13533 format %{ "cmpq $op1, $op2" %} 13534 ins_encode %{ 13535 __ cmpq($op1$$Register, $op2$$Address); 13536 %} 13537 ins_pipe(ialu_cr_reg_mem); 13538 %} 13539 13540 instruct testL_reg(rFlagsReg cr, rRegL src, immL0 zero) 13541 %{ 13542 match(Set cr (CmpL src zero)); 13543 13544 format %{ "testq $src, $src" %} 13545 ins_encode %{ 13546 __ testq($src$$Register, $src$$Register); 13547 %} 13548 ins_pipe(ialu_cr_reg_imm); 13549 %} 13550 13551 instruct testL_reg_imm(rFlagsReg cr, rRegL src, immL32 con, immL0 zero) 13552 %{ 13553 match(Set cr (CmpL (AndL src con) zero)); 13554 13555 format %{ "testq $src, $con\t# long" %} 13556 ins_encode %{ 13557 __ testq($src$$Register, $con$$constant); 13558 %} 13559 ins_pipe(ialu_cr_reg_imm); 13560 %} 13561 13562 instruct testL_reg_reg(rFlagsReg cr, rRegL src1, rRegL src2, immL0 zero) 13563 %{ 13564 match(Set cr (CmpL (AndL src1 src2) zero)); 13565 13566 format %{ "testq $src1, $src2\t# long" %} 13567 ins_encode %{ 13568 __ testq($src1$$Register, $src2$$Register); 13569 %} 13570 ins_pipe(ialu_cr_reg_imm); 13571 %} 13572 13573 instruct testL_reg_mem(rFlagsReg cr, rRegL src, memory mem, immL0 zero) 13574 %{ 13575 match(Set cr (CmpL (AndL src (LoadL mem)) zero)); 13576 13577 format %{ "testq $src, $mem" %} 13578 ins_encode %{ 13579 __ testq($src$$Register, $mem$$Address); 13580 %} 13581 ins_pipe(ialu_cr_reg_mem); 13582 %} 13583 13584 instruct testL_reg_mem2(rFlagsReg cr, rRegP src, memory mem, immL0 zero) 13585 %{ 13586 match(Set cr (CmpL (AndL (CastP2X src) (LoadL mem)) zero)); 13587 13588 format %{ "testq $src, $mem" %} 13589 ins_encode %{ 13590 __ testq($src$$Register, $mem$$Address); 13591 %} 13592 ins_pipe(ialu_cr_reg_mem); 13593 %} 13594 13595 // Manifest a CmpU result in an integer register. Very painful. 13596 // This is the test to avoid. 13597 instruct cmpU3_reg_reg(rRegI dst, rRegI src1, rRegI src2, rFlagsReg flags) 13598 %{ 13599 match(Set dst (CmpU3 src1 src2)); 13600 effect(KILL flags); 13601 13602 ins_cost(275); // XXX 13603 format %{ "cmpl $src1, $src2\t# CmpL3\n\t" 13604 "movl $dst, -1\n\t" 13605 "jb,u done\n\t" 13606 "setcc $dst \t# emits setne + movzbl or setzune for APX" 13607 "done:" %} 13608 ins_encode %{ 13609 Label done; 13610 __ cmpl($src1$$Register, $src2$$Register); 13611 __ movl($dst$$Register, -1); 13612 __ jccb(Assembler::below, done); 13613 __ setcc(Assembler::notZero, $dst$$Register); 13614 __ bind(done); 13615 %} 13616 ins_pipe(pipe_slow); 13617 %} 13618 13619 // Manifest a CmpL result in an integer register. Very painful. 13620 // This is the test to avoid. 13621 instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 13622 %{ 13623 match(Set dst (CmpL3 src1 src2)); 13624 effect(KILL flags); 13625 13626 ins_cost(275); // XXX 13627 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 13628 "movl $dst, -1\n\t" 13629 "jl,s done\n\t" 13630 "setcc $dst \t# emits setne + movzbl or setzune for APX" 13631 "done:" %} 13632 ins_encode %{ 13633 Label done; 13634 __ cmpq($src1$$Register, $src2$$Register); 13635 __ movl($dst$$Register, -1); 13636 __ jccb(Assembler::less, done); 13637 __ setcc(Assembler::notZero, $dst$$Register); 13638 __ bind(done); 13639 %} 13640 ins_pipe(pipe_slow); 13641 %} 13642 13643 // Manifest a CmpUL result in an integer register. Very painful. 13644 // This is the test to avoid. 13645 instruct cmpUL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 13646 %{ 13647 match(Set dst (CmpUL3 src1 src2)); 13648 effect(KILL flags); 13649 13650 ins_cost(275); // XXX 13651 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 13652 "movl $dst, -1\n\t" 13653 "jb,u done\n\t" 13654 "setcc $dst \t# emits setne + movzbl or setzune for APX" 13655 "done:" %} 13656 ins_encode %{ 13657 Label done; 13658 __ cmpq($src1$$Register, $src2$$Register); 13659 __ movl($dst$$Register, -1); 13660 __ jccb(Assembler::below, done); 13661 __ setcc(Assembler::notZero, $dst$$Register); 13662 __ bind(done); 13663 %} 13664 ins_pipe(pipe_slow); 13665 %} 13666 13667 // Unsigned long compare Instructions; really, same as signed long except they 13668 // produce an rFlagsRegU instead of rFlagsReg. 13669 instruct compUL_rReg(rFlagsRegU cr, rRegL op1, rRegL op2) 13670 %{ 13671 match(Set cr (CmpUL op1 op2)); 13672 13673 format %{ "cmpq $op1, $op2\t# unsigned" %} 13674 ins_encode %{ 13675 __ cmpq($op1$$Register, $op2$$Register); 13676 %} 13677 ins_pipe(ialu_cr_reg_reg); 13678 %} 13679 13680 instruct compUL_rReg_imm(rFlagsRegU cr, rRegL op1, immL32 op2) 13681 %{ 13682 match(Set cr (CmpUL op1 op2)); 13683 13684 format %{ "cmpq $op1, $op2\t# unsigned" %} 13685 ins_encode %{ 13686 __ cmpq($op1$$Register, $op2$$constant); 13687 %} 13688 ins_pipe(ialu_cr_reg_imm); 13689 %} 13690 13691 instruct compUL_rReg_mem(rFlagsRegU cr, rRegL op1, memory op2) 13692 %{ 13693 match(Set cr (CmpUL op1 (LoadL op2))); 13694 13695 format %{ "cmpq $op1, $op2\t# unsigned" %} 13696 ins_encode %{ 13697 __ cmpq($op1$$Register, $op2$$Address); 13698 %} 13699 ins_pipe(ialu_cr_reg_mem); 13700 %} 13701 13702 instruct testUL_reg(rFlagsRegU cr, rRegL src, immL0 zero) 13703 %{ 13704 match(Set cr (CmpUL src zero)); 13705 13706 format %{ "testq $src, $src\t# unsigned" %} 13707 ins_encode %{ 13708 __ testq($src$$Register, $src$$Register); 13709 %} 13710 ins_pipe(ialu_cr_reg_imm); 13711 %} 13712 13713 instruct compB_mem_imm(rFlagsReg cr, memory mem, immI8 imm) 13714 %{ 13715 match(Set cr (CmpI (LoadB mem) imm)); 13716 13717 ins_cost(125); 13718 format %{ "cmpb $mem, $imm" %} 13719 ins_encode %{ __ cmpb($mem$$Address, $imm$$constant); %} 13720 ins_pipe(ialu_cr_reg_mem); 13721 %} 13722 13723 instruct testUB_mem_imm(rFlagsReg cr, memory mem, immU7 imm, immI_0 zero) 13724 %{ 13725 match(Set cr (CmpI (AndI (LoadUB mem) imm) zero)); 13726 13727 ins_cost(125); 13728 format %{ "testb $mem, $imm\t# ubyte" %} 13729 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %} 13730 ins_pipe(ialu_cr_reg_mem); 13731 %} 13732 13733 instruct testB_mem_imm(rFlagsReg cr, memory mem, immI8 imm, immI_0 zero) 13734 %{ 13735 match(Set cr (CmpI (AndI (LoadB mem) imm) zero)); 13736 13737 ins_cost(125); 13738 format %{ "testb $mem, $imm\t# byte" %} 13739 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %} 13740 ins_pipe(ialu_cr_reg_mem); 13741 %} 13742 13743 //----------Max and Min-------------------------------------------------------- 13744 // Min Instructions 13745 13746 instruct cmovI_reg_g(rRegI dst, rRegI src, rFlagsReg cr) 13747 %{ 13748 predicate(!UseAPX); 13749 effect(USE_DEF dst, USE src, USE cr); 13750 13751 format %{ "cmovlgt $dst, $src\t# min" %} 13752 ins_encode %{ 13753 __ cmovl(Assembler::greater, $dst$$Register, $src$$Register); 13754 %} 13755 ins_pipe(pipe_cmov_reg); 13756 %} 13757 13758 instruct cmovI_reg_g_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr) 13759 %{ 13760 predicate(UseAPX); 13761 effect(DEF dst, USE src1, USE src2, USE cr); 13762 13763 format %{ "ecmovlgt $dst, $src1, $src2\t# min ndd" %} 13764 ins_encode %{ 13765 __ ecmovl(Assembler::greater, $dst$$Register, $src1$$Register, $src2$$Register); 13766 %} 13767 ins_pipe(pipe_cmov_reg); 13768 %} 13769 13770 instruct minI_rReg(rRegI dst, rRegI src) 13771 %{ 13772 predicate(!UseAPX); 13773 match(Set dst (MinI dst src)); 13774 13775 ins_cost(200); 13776 expand %{ 13777 rFlagsReg cr; 13778 compI_rReg(cr, dst, src); 13779 cmovI_reg_g(dst, src, cr); 13780 %} 13781 %} 13782 13783 instruct minI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2) 13784 %{ 13785 predicate(UseAPX); 13786 match(Set dst (MinI src1 src2)); 13787 effect(DEF dst, USE src1, USE src2); 13788 13789 ins_cost(200); 13790 expand %{ 13791 rFlagsReg cr; 13792 compI_rReg(cr, src1, src2); 13793 cmovI_reg_g_ndd(dst, src1, src2, cr); 13794 %} 13795 %} 13796 13797 instruct cmovI_reg_l(rRegI dst, rRegI src, rFlagsReg cr) 13798 %{ 13799 predicate(!UseAPX); 13800 effect(USE_DEF dst, USE src, USE cr); 13801 13802 format %{ "cmovllt $dst, $src\t# max" %} 13803 ins_encode %{ 13804 __ cmovl(Assembler::less, $dst$$Register, $src$$Register); 13805 %} 13806 ins_pipe(pipe_cmov_reg); 13807 %} 13808 13809 instruct cmovI_reg_l_ndd(rRegI dst, rRegI src1, rRegI src2, rFlagsReg cr) 13810 %{ 13811 predicate(UseAPX); 13812 effect(DEF dst, USE src1, USE src2, USE cr); 13813 13814 format %{ "ecmovllt $dst, $src1, $src2\t# max ndd" %} 13815 ins_encode %{ 13816 __ ecmovl(Assembler::less, $dst$$Register, $src1$$Register, $src2$$Register); 13817 %} 13818 ins_pipe(pipe_cmov_reg); 13819 %} 13820 13821 instruct maxI_rReg(rRegI dst, rRegI src) 13822 %{ 13823 predicate(!UseAPX); 13824 match(Set dst (MaxI dst src)); 13825 13826 ins_cost(200); 13827 expand %{ 13828 rFlagsReg cr; 13829 compI_rReg(cr, dst, src); 13830 cmovI_reg_l(dst, src, cr); 13831 %} 13832 %} 13833 13834 instruct maxI_rReg_ndd(rRegI dst, rRegI src1, rRegI src2) 13835 %{ 13836 predicate(UseAPX); 13837 match(Set dst (MaxI src1 src2)); 13838 effect(DEF dst, USE src1, USE src2); 13839 13840 ins_cost(200); 13841 expand %{ 13842 rFlagsReg cr; 13843 compI_rReg(cr, src1, src2); 13844 cmovI_reg_l_ndd(dst, src1, src2, cr); 13845 %} 13846 %} 13847 13848 // ============================================================================ 13849 // Branch Instructions 13850 13851 // Jump Direct - Label defines a relative address from JMP+1 13852 instruct jmpDir(label labl) 13853 %{ 13854 match(Goto); 13855 effect(USE labl); 13856 13857 ins_cost(300); 13858 format %{ "jmp $labl" %} 13859 size(5); 13860 ins_encode %{ 13861 Label* L = $labl$$label; 13862 __ jmp(*L, false); // Always long jump 13863 %} 13864 ins_pipe(pipe_jmp); 13865 %} 13866 13867 // Jump Direct Conditional - Label defines a relative address from Jcc+1 13868 instruct jmpCon(cmpOp cop, rFlagsReg cr, label labl) 13869 %{ 13870 match(If cop cr); 13871 effect(USE labl); 13872 13873 ins_cost(300); 13874 format %{ "j$cop $labl" %} 13875 size(6); 13876 ins_encode %{ 13877 Label* L = $labl$$label; 13878 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 13879 %} 13880 ins_pipe(pipe_jcc); 13881 %} 13882 13883 // Jump Direct Conditional - Label defines a relative address from Jcc+1 13884 instruct jmpLoopEnd(cmpOp cop, rFlagsReg cr, label labl) 13885 %{ 13886 match(CountedLoopEnd cop cr); 13887 effect(USE labl); 13888 13889 ins_cost(300); 13890 format %{ "j$cop $labl\t# loop end" %} 13891 size(6); 13892 ins_encode %{ 13893 Label* L = $labl$$label; 13894 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 13895 %} 13896 ins_pipe(pipe_jcc); 13897 %} 13898 13899 // Jump Direct Conditional - using unsigned comparison 13900 instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 13901 match(If cop cmp); 13902 effect(USE labl); 13903 13904 ins_cost(300); 13905 format %{ "j$cop,u $labl" %} 13906 size(6); 13907 ins_encode %{ 13908 Label* L = $labl$$label; 13909 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 13910 %} 13911 ins_pipe(pipe_jcc); 13912 %} 13913 13914 instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 13915 match(If cop cmp); 13916 effect(USE labl); 13917 13918 ins_cost(200); 13919 format %{ "j$cop,u $labl" %} 13920 size(6); 13921 ins_encode %{ 13922 Label* L = $labl$$label; 13923 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 13924 %} 13925 ins_pipe(pipe_jcc); 13926 %} 13927 13928 instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 13929 match(If cop cmp); 13930 effect(USE labl); 13931 13932 ins_cost(200); 13933 format %{ $$template 13934 if ($cop$$cmpcode == Assembler::notEqual) { 13935 $$emit$$"jp,u $labl\n\t" 13936 $$emit$$"j$cop,u $labl" 13937 } else { 13938 $$emit$$"jp,u done\n\t" 13939 $$emit$$"j$cop,u $labl\n\t" 13940 $$emit$$"done:" 13941 } 13942 %} 13943 ins_encode %{ 13944 Label* l = $labl$$label; 13945 if ($cop$$cmpcode == Assembler::notEqual) { 13946 __ jcc(Assembler::parity, *l, false); 13947 __ jcc(Assembler::notEqual, *l, false); 13948 } else if ($cop$$cmpcode == Assembler::equal) { 13949 Label done; 13950 __ jccb(Assembler::parity, done); 13951 __ jcc(Assembler::equal, *l, false); 13952 __ bind(done); 13953 } else { 13954 ShouldNotReachHere(); 13955 } 13956 %} 13957 ins_pipe(pipe_jcc); 13958 %} 13959 13960 // ============================================================================ 13961 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary 13962 // superklass array for an instance of the superklass. Set a hidden 13963 // internal cache on a hit (cache is checked with exposed code in 13964 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The 13965 // encoding ALSO sets flags. 13966 13967 instruct partialSubtypeCheck(rdi_RegP result, 13968 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 13969 rFlagsReg cr) 13970 %{ 13971 match(Set result (PartialSubtypeCheck sub super)); 13972 predicate(!UseSecondarySupersTable); 13973 effect(KILL rcx, KILL cr); 13974 13975 ins_cost(1100); // slightly larger than the next version 13976 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 13977 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 13978 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 13979 "repne scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t" 13980 "jne,s miss\t\t# Missed: rdi not-zero\n\t" 13981 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 13982 "xorq $result, $result\t\t Hit: rdi zero\n\t" 13983 "miss:\t" %} 13984 13985 ins_encode %{ 13986 Label miss; 13987 // NB: Callers may assume that, when $result is a valid register, 13988 // check_klass_subtype_slow_path_linear sets it to a nonzero 13989 // value. 13990 __ check_klass_subtype_slow_path_linear($sub$$Register, $super$$Register, 13991 $rcx$$Register, $result$$Register, 13992 nullptr, &miss, 13993 /*set_cond_codes:*/ true); 13994 __ xorptr($result$$Register, $result$$Register); 13995 __ bind(miss); 13996 %} 13997 13998 ins_pipe(pipe_slow); 13999 %} 14000 14001 // ============================================================================ 14002 // Two versions of hashtable-based partialSubtypeCheck, both used when 14003 // we need to search for a super class in the secondary supers array. 14004 // The first is used when we don't know _a priori_ the class being 14005 // searched for. The second, far more common, is used when we do know: 14006 // this is used for instanceof, checkcast, and any case where C2 can 14007 // determine it by constant propagation. 14008 14009 instruct partialSubtypeCheckVarSuper(rsi_RegP sub, rax_RegP super, rdi_RegP result, 14010 rdx_RegL temp1, rcx_RegL temp2, rbx_RegP temp3, r11_RegL temp4, 14011 rFlagsReg cr) 14012 %{ 14013 match(Set result (PartialSubtypeCheck sub super)); 14014 predicate(UseSecondarySupersTable); 14015 effect(KILL cr, TEMP temp1, TEMP temp2, TEMP temp3, TEMP temp4); 14016 14017 ins_cost(1000); 14018 format %{ "partialSubtypeCheck $result, $sub, $super" %} 14019 14020 ins_encode %{ 14021 __ lookup_secondary_supers_table_var($sub$$Register, $super$$Register, $temp1$$Register, $temp2$$Register, 14022 $temp3$$Register, $temp4$$Register, $result$$Register); 14023 %} 14024 14025 ins_pipe(pipe_slow); 14026 %} 14027 14028 instruct partialSubtypeCheckConstSuper(rsi_RegP sub, rax_RegP super_reg, immP super_con, rdi_RegP result, 14029 rdx_RegL temp1, rcx_RegL temp2, rbx_RegP temp3, r11_RegL temp4, 14030 rFlagsReg cr) 14031 %{ 14032 match(Set result (PartialSubtypeCheck sub (Binary super_reg super_con))); 14033 predicate(UseSecondarySupersTable); 14034 effect(KILL cr, TEMP temp1, TEMP temp2, TEMP temp3, TEMP temp4); 14035 14036 ins_cost(700); // smaller than the next version 14037 format %{ "partialSubtypeCheck $result, $sub, $super_reg, $super_con" %} 14038 14039 ins_encode %{ 14040 u1 super_klass_slot = ((Klass*)$super_con$$constant)->hash_slot(); 14041 if (InlineSecondarySupersTest) { 14042 __ lookup_secondary_supers_table_const($sub$$Register, $super_reg$$Register, $temp1$$Register, $temp2$$Register, 14043 $temp3$$Register, $temp4$$Register, $result$$Register, 14044 super_klass_slot); 14045 } else { 14046 __ call(RuntimeAddress(StubRoutines::lookup_secondary_supers_table_stub(super_klass_slot))); 14047 } 14048 %} 14049 14050 ins_pipe(pipe_slow); 14051 %} 14052 14053 // ============================================================================ 14054 // Branch Instructions -- short offset versions 14055 // 14056 // These instructions are used to replace jumps of a long offset (the default 14057 // match) with jumps of a shorter offset. These instructions are all tagged 14058 // with the ins_short_branch attribute, which causes the ADLC to suppress the 14059 // match rules in general matching. Instead, the ADLC generates a conversion 14060 // method in the MachNode which can be used to do in-place replacement of the 14061 // long variant with the shorter variant. The compiler will determine if a 14062 // branch can be taken by the is_short_branch_offset() predicate in the machine 14063 // specific code section of the file. 14064 14065 // Jump Direct - Label defines a relative address from JMP+1 14066 instruct jmpDir_short(label labl) %{ 14067 match(Goto); 14068 effect(USE labl); 14069 14070 ins_cost(300); 14071 format %{ "jmp,s $labl" %} 14072 size(2); 14073 ins_encode %{ 14074 Label* L = $labl$$label; 14075 __ jmpb(*L); 14076 %} 14077 ins_pipe(pipe_jmp); 14078 ins_short_branch(1); 14079 %} 14080 14081 // Jump Direct Conditional - Label defines a relative address from Jcc+1 14082 instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{ 14083 match(If cop cr); 14084 effect(USE labl); 14085 14086 ins_cost(300); 14087 format %{ "j$cop,s $labl" %} 14088 size(2); 14089 ins_encode %{ 14090 Label* L = $labl$$label; 14091 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 14092 %} 14093 ins_pipe(pipe_jcc); 14094 ins_short_branch(1); 14095 %} 14096 14097 // Jump Direct Conditional - Label defines a relative address from Jcc+1 14098 instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{ 14099 match(CountedLoopEnd cop cr); 14100 effect(USE labl); 14101 14102 ins_cost(300); 14103 format %{ "j$cop,s $labl\t# loop end" %} 14104 size(2); 14105 ins_encode %{ 14106 Label* L = $labl$$label; 14107 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 14108 %} 14109 ins_pipe(pipe_jcc); 14110 ins_short_branch(1); 14111 %} 14112 14113 // Jump Direct Conditional - using unsigned comparison 14114 instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 14115 match(If cop cmp); 14116 effect(USE labl); 14117 14118 ins_cost(300); 14119 format %{ "j$cop,us $labl" %} 14120 size(2); 14121 ins_encode %{ 14122 Label* L = $labl$$label; 14123 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 14124 %} 14125 ins_pipe(pipe_jcc); 14126 ins_short_branch(1); 14127 %} 14128 14129 instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 14130 match(If cop cmp); 14131 effect(USE labl); 14132 14133 ins_cost(300); 14134 format %{ "j$cop,us $labl" %} 14135 size(2); 14136 ins_encode %{ 14137 Label* L = $labl$$label; 14138 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 14139 %} 14140 ins_pipe(pipe_jcc); 14141 ins_short_branch(1); 14142 %} 14143 14144 instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 14145 match(If cop cmp); 14146 effect(USE labl); 14147 14148 ins_cost(300); 14149 format %{ $$template 14150 if ($cop$$cmpcode == Assembler::notEqual) { 14151 $$emit$$"jp,u,s $labl\n\t" 14152 $$emit$$"j$cop,u,s $labl" 14153 } else { 14154 $$emit$$"jp,u,s done\n\t" 14155 $$emit$$"j$cop,u,s $labl\n\t" 14156 $$emit$$"done:" 14157 } 14158 %} 14159 size(4); 14160 ins_encode %{ 14161 Label* l = $labl$$label; 14162 if ($cop$$cmpcode == Assembler::notEqual) { 14163 __ jccb(Assembler::parity, *l); 14164 __ jccb(Assembler::notEqual, *l); 14165 } else if ($cop$$cmpcode == Assembler::equal) { 14166 Label done; 14167 __ jccb(Assembler::parity, done); 14168 __ jccb(Assembler::equal, *l); 14169 __ bind(done); 14170 } else { 14171 ShouldNotReachHere(); 14172 } 14173 %} 14174 ins_pipe(pipe_jcc); 14175 ins_short_branch(1); 14176 %} 14177 14178 // ============================================================================ 14179 // inlined locking and unlocking 14180 14181 instruct cmpFastLock(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr) %{ 14182 predicate(LockingMode != LM_LIGHTWEIGHT); 14183 match(Set cr (FastLock object box)); 14184 effect(TEMP tmp, TEMP scr, USE_KILL box); 14185 ins_cost(300); 14186 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr" %} 14187 ins_encode %{ 14188 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, 14189 $scr$$Register, noreg, noreg, r15_thread, nullptr); 14190 %} 14191 ins_pipe(pipe_slow); 14192 %} 14193 14194 instruct cmpFastUnlock(rFlagsReg cr, rRegP object, rax_RegP box, rRegP tmp) %{ 14195 predicate(LockingMode != LM_LIGHTWEIGHT); 14196 match(Set cr (FastUnlock object box)); 14197 effect(TEMP tmp, USE_KILL box); 14198 ins_cost(300); 14199 format %{ "fastunlock $object,$box\t! kills $box,$tmp" %} 14200 ins_encode %{ 14201 __ fast_unlock($object$$Register, $box$$Register, $tmp$$Register); 14202 %} 14203 ins_pipe(pipe_slow); 14204 %} 14205 14206 instruct cmpFastLockLightweight(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI rax_reg, rRegP tmp) %{ 14207 predicate(LockingMode == LM_LIGHTWEIGHT); 14208 match(Set cr (FastLock object box)); 14209 effect(TEMP rax_reg, TEMP tmp, USE_KILL box); 14210 ins_cost(300); 14211 format %{ "fastlock $object,$box\t! kills $box,$rax_reg,$tmp" %} 14212 ins_encode %{ 14213 __ fast_lock_lightweight($object$$Register, $box$$Register, $rax_reg$$Register, $tmp$$Register, r15_thread); 14214 %} 14215 ins_pipe(pipe_slow); 14216 %} 14217 14218 instruct cmpFastUnlockLightweight(rFlagsReg cr, rRegP object, rax_RegP rax_reg, rRegP tmp) %{ 14219 predicate(LockingMode == LM_LIGHTWEIGHT); 14220 match(Set cr (FastUnlock object rax_reg)); 14221 effect(TEMP tmp, USE_KILL rax_reg); 14222 ins_cost(300); 14223 format %{ "fastunlock $object,$rax_reg\t! kills $rax_reg,$tmp" %} 14224 ins_encode %{ 14225 __ fast_unlock_lightweight($object$$Register, $rax_reg$$Register, $tmp$$Register, r15_thread); 14226 %} 14227 ins_pipe(pipe_slow); 14228 %} 14229 14230 14231 // ============================================================================ 14232 // Safepoint Instructions 14233 instruct safePoint_poll_tls(rFlagsReg cr, rRegP poll) 14234 %{ 14235 match(SafePoint poll); 14236 effect(KILL cr, USE poll); 14237 14238 format %{ "testl rax, [$poll]\t" 14239 "# Safepoint: poll for GC" %} 14240 ins_cost(125); 14241 ins_encode %{ 14242 __ relocate(relocInfo::poll_type); 14243 address pre_pc = __ pc(); 14244 __ testl(rax, Address($poll$$Register, 0)); 14245 assert(nativeInstruction_at(pre_pc)->is_safepoint_poll(), "must emit test %%eax [reg]"); 14246 %} 14247 ins_pipe(ialu_reg_mem); 14248 %} 14249 14250 instruct mask_all_evexL(kReg dst, rRegL src) %{ 14251 match(Set dst (MaskAll src)); 14252 format %{ "mask_all_evexL $dst, $src \t! mask all operation" %} 14253 ins_encode %{ 14254 int mask_len = Matcher::vector_length(this); 14255 __ vector_maskall_operation($dst$$KRegister, $src$$Register, mask_len); 14256 %} 14257 ins_pipe( pipe_slow ); 14258 %} 14259 14260 instruct mask_all_evexI_GT32(kReg dst, rRegI src, rRegL tmp) %{ 14261 predicate(Matcher::vector_length(n) > 32); 14262 match(Set dst (MaskAll src)); 14263 effect(TEMP tmp); 14264 format %{ "mask_all_evexI_GT32 $dst, $src \t! using $tmp as TEMP" %} 14265 ins_encode %{ 14266 int mask_len = Matcher::vector_length(this); 14267 __ movslq($tmp$$Register, $src$$Register); 14268 __ vector_maskall_operation($dst$$KRegister, $tmp$$Register, mask_len); 14269 %} 14270 ins_pipe( pipe_slow ); 14271 %} 14272 14273 // ============================================================================ 14274 // Procedure Call/Return Instructions 14275 // Call Java Static Instruction 14276 // Note: If this code changes, the corresponding ret_addr_offset() and 14277 // compute_padding() functions will have to be adjusted. 14278 instruct CallStaticJavaDirect(method meth) %{ 14279 match(CallStaticJava); 14280 effect(USE meth); 14281 14282 ins_cost(300); 14283 format %{ "call,static " %} 14284 opcode(0xE8); /* E8 cd */ 14285 ins_encode(clear_avx, Java_Static_Call(meth), call_epilog); 14286 ins_pipe(pipe_slow); 14287 ins_alignment(4); 14288 %} 14289 14290 // Call Java Dynamic Instruction 14291 // Note: If this code changes, the corresponding ret_addr_offset() and 14292 // compute_padding() functions will have to be adjusted. 14293 instruct CallDynamicJavaDirect(method meth) 14294 %{ 14295 match(CallDynamicJava); 14296 effect(USE meth); 14297 14298 ins_cost(300); 14299 format %{ "movq rax, #Universe::non_oop_word()\n\t" 14300 "call,dynamic " %} 14301 ins_encode(clear_avx, Java_Dynamic_Call(meth), call_epilog); 14302 ins_pipe(pipe_slow); 14303 ins_alignment(4); 14304 %} 14305 14306 // Call Runtime Instruction 14307 instruct CallRuntimeDirect(method meth) 14308 %{ 14309 match(CallRuntime); 14310 effect(USE meth); 14311 14312 ins_cost(300); 14313 format %{ "call,runtime " %} 14314 ins_encode(clear_avx, Java_To_Runtime(meth)); 14315 ins_pipe(pipe_slow); 14316 %} 14317 14318 // Call runtime without safepoint 14319 instruct CallLeafDirect(method meth) 14320 %{ 14321 match(CallLeaf); 14322 effect(USE meth); 14323 14324 ins_cost(300); 14325 format %{ "call_leaf,runtime " %} 14326 ins_encode(clear_avx, Java_To_Runtime(meth)); 14327 ins_pipe(pipe_slow); 14328 %} 14329 14330 // Call runtime without safepoint and with vector arguments 14331 instruct CallLeafDirectVector(method meth) 14332 %{ 14333 match(CallLeafVector); 14334 effect(USE meth); 14335 14336 ins_cost(300); 14337 format %{ "call_leaf,vector " %} 14338 ins_encode(Java_To_Runtime(meth)); 14339 ins_pipe(pipe_slow); 14340 %} 14341 14342 // Call runtime without safepoint 14343 instruct CallLeafNoFPDirect(method meth) 14344 %{ 14345 match(CallLeafNoFP); 14346 effect(USE meth); 14347 14348 ins_cost(300); 14349 format %{ "call_leaf_nofp,runtime " %} 14350 ins_encode(clear_avx, Java_To_Runtime(meth)); 14351 ins_pipe(pipe_slow); 14352 %} 14353 14354 // Return Instruction 14355 // Remove the return address & jump to it. 14356 // Notice: We always emit a nop after a ret to make sure there is room 14357 // for safepoint patching 14358 instruct Ret() 14359 %{ 14360 match(Return); 14361 14362 format %{ "ret" %} 14363 ins_encode %{ 14364 __ ret(0); 14365 %} 14366 ins_pipe(pipe_jmp); 14367 %} 14368 14369 // Tail Call; Jump from runtime stub to Java code. 14370 // Also known as an 'interprocedural jump'. 14371 // Target of jump will eventually return to caller. 14372 // TailJump below removes the return address. 14373 // Don't use rbp for 'jump_target' because a MachEpilogNode has already been 14374 // emitted just above the TailCall which has reset rbp to the caller state. 14375 instruct TailCalljmpInd(no_rbp_RegP jump_target, rbx_RegP method_ptr) 14376 %{ 14377 match(TailCall jump_target method_ptr); 14378 14379 ins_cost(300); 14380 format %{ "jmp $jump_target\t# rbx holds method" %} 14381 ins_encode %{ 14382 __ jmp($jump_target$$Register); 14383 %} 14384 ins_pipe(pipe_jmp); 14385 %} 14386 14387 // Tail Jump; remove the return address; jump to target. 14388 // TailCall above leaves the return address around. 14389 instruct tailjmpInd(no_rbp_RegP jump_target, rax_RegP ex_oop) 14390 %{ 14391 match(TailJump jump_target ex_oop); 14392 14393 ins_cost(300); 14394 format %{ "popq rdx\t# pop return address\n\t" 14395 "jmp $jump_target" %} 14396 ins_encode %{ 14397 __ popq(as_Register(RDX_enc)); 14398 __ jmp($jump_target$$Register); 14399 %} 14400 ins_pipe(pipe_jmp); 14401 %} 14402 14403 // Forward exception. 14404 instruct ForwardExceptionjmp() 14405 %{ 14406 match(ForwardException); 14407 14408 format %{ "jmp forward_exception_stub" %} 14409 ins_encode %{ 14410 __ jump(RuntimeAddress(StubRoutines::forward_exception_entry()), noreg); 14411 %} 14412 ins_pipe(pipe_jmp); 14413 %} 14414 14415 // Create exception oop: created by stack-crawling runtime code. 14416 // Created exception is now available to this handler, and is setup 14417 // just prior to jumping to this handler. No code emitted. 14418 instruct CreateException(rax_RegP ex_oop) 14419 %{ 14420 match(Set ex_oop (CreateEx)); 14421 14422 size(0); 14423 // use the following format syntax 14424 format %{ "# exception oop is in rax; no code emitted" %} 14425 ins_encode(); 14426 ins_pipe(empty); 14427 %} 14428 14429 // Rethrow exception: 14430 // The exception oop will come in the first argument position. 14431 // Then JUMP (not call) to the rethrow stub code. 14432 instruct RethrowException() 14433 %{ 14434 match(Rethrow); 14435 14436 // use the following format syntax 14437 format %{ "jmp rethrow_stub" %} 14438 ins_encode %{ 14439 __ jump(RuntimeAddress(OptoRuntime::rethrow_stub()), noreg); 14440 %} 14441 ins_pipe(pipe_jmp); 14442 %} 14443 14444 // ============================================================================ 14445 // This name is KNOWN by the ADLC and cannot be changed. 14446 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type 14447 // for this guy. 14448 instruct tlsLoadP(r15_RegP dst) %{ 14449 match(Set dst (ThreadLocal)); 14450 effect(DEF dst); 14451 14452 size(0); 14453 format %{ "# TLS is in R15" %} 14454 ins_encode( /*empty encoding*/ ); 14455 ins_pipe(ialu_reg_reg); 14456 %} 14457 14458 14459 //----------PEEPHOLE RULES----------------------------------------------------- 14460 // These must follow all instruction definitions as they use the names 14461 // defined in the instructions definitions. 14462 // 14463 // peeppredicate ( rule_predicate ); 14464 // // the predicate unless which the peephole rule will be ignored 14465 // 14466 // peepmatch ( root_instr_name [preceding_instruction]* ); 14467 // 14468 // peepprocedure ( procedure_name ); 14469 // // provide a procedure name to perform the optimization, the procedure should 14470 // // reside in the architecture dependent peephole file, the method has the 14471 // // signature of MachNode* (Block*, int, PhaseRegAlloc*, (MachNode*)(*)(), int...) 14472 // // with the arguments being the basic block, the current node index inside the 14473 // // block, the register allocator, the functions upon invoked return a new node 14474 // // defined in peepreplace, and the rules of the nodes appearing in the 14475 // // corresponding peepmatch, the function return true if successful, else 14476 // // return false 14477 // 14478 // peepconstraint %{ 14479 // (instruction_number.operand_name relational_op instruction_number.operand_name 14480 // [, ...] ); 14481 // // instruction numbers are zero-based using left to right order in peepmatch 14482 // 14483 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 14484 // // provide an instruction_number.operand_name for each operand that appears 14485 // // in the replacement instruction's match rule 14486 // 14487 // ---------VM FLAGS--------------------------------------------------------- 14488 // 14489 // All peephole optimizations can be turned off using -XX:-OptoPeephole 14490 // 14491 // Each peephole rule is given an identifying number starting with zero and 14492 // increasing by one in the order seen by the parser. An individual peephole 14493 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 14494 // on the command-line. 14495 // 14496 // ---------CURRENT LIMITATIONS---------------------------------------------- 14497 // 14498 // Only transformations inside a basic block (do we need more for peephole) 14499 // 14500 // ---------EXAMPLE---------------------------------------------------------- 14501 // 14502 // // pertinent parts of existing instructions in architecture description 14503 // instruct movI(rRegI dst, rRegI src) 14504 // %{ 14505 // match(Set dst (CopyI src)); 14506 // %} 14507 // 14508 // instruct incI_rReg(rRegI dst, immI_1 src, rFlagsReg cr) 14509 // %{ 14510 // match(Set dst (AddI dst src)); 14511 // effect(KILL cr); 14512 // %} 14513 // 14514 // instruct leaI_rReg_immI(rRegI dst, immI_1 src) 14515 // %{ 14516 // match(Set dst (AddI dst src)); 14517 // %} 14518 // 14519 // 1. Simple replacement 14520 // - Only match adjacent instructions in same basic block 14521 // - Only equality constraints 14522 // - Only constraints between operands, not (0.dest_reg == RAX_enc) 14523 // - Only one replacement instruction 14524 // 14525 // // Change (inc mov) to lea 14526 // peephole %{ 14527 // // lea should only be emitted when beneficial 14528 // peeppredicate( VM_Version::supports_fast_2op_lea() ); 14529 // // increment preceded by register-register move 14530 // peepmatch ( incI_rReg movI ); 14531 // // require that the destination register of the increment 14532 // // match the destination register of the move 14533 // peepconstraint ( 0.dst == 1.dst ); 14534 // // construct a replacement instruction that sets 14535 // // the destination to ( move's source register + one ) 14536 // peepreplace ( leaI_rReg_immI( 0.dst 1.src 0.src ) ); 14537 // %} 14538 // 14539 // 2. Procedural replacement 14540 // - More flexible finding relevent nodes 14541 // - More flexible constraints 14542 // - More flexible transformations 14543 // - May utilise architecture-dependent API more effectively 14544 // - Currently only one replacement instruction due to adlc parsing capabilities 14545 // 14546 // // Change (inc mov) to lea 14547 // peephole %{ 14548 // // lea should only be emitted when beneficial 14549 // peeppredicate( VM_Version::supports_fast_2op_lea() ); 14550 // // the rule numbers of these nodes inside are passed into the function below 14551 // peepmatch ( incI_rReg movI ); 14552 // // the method that takes the responsibility of transformation 14553 // peepprocedure ( inc_mov_to_lea ); 14554 // // the replacement is a leaI_rReg_immI, a lambda upon invoked creating this 14555 // // node is passed into the function above 14556 // peepreplace ( leaI_rReg_immI() ); 14557 // %} 14558 14559 // These instructions is not matched by the matcher but used by the peephole 14560 instruct leaI_rReg_rReg_peep(rRegI dst, rRegI src1, rRegI src2) 14561 %{ 14562 predicate(false); 14563 match(Set dst (AddI src1 src2)); 14564 format %{ "leal $dst, [$src1 + $src2]" %} 14565 ins_encode %{ 14566 Register dst = $dst$$Register; 14567 Register src1 = $src1$$Register; 14568 Register src2 = $src2$$Register; 14569 if (src1 != rbp && src1 != r13) { 14570 __ leal(dst, Address(src1, src2, Address::times_1)); 14571 } else { 14572 assert(src2 != rbp && src2 != r13, ""); 14573 __ leal(dst, Address(src2, src1, Address::times_1)); 14574 } 14575 %} 14576 ins_pipe(ialu_reg_reg); 14577 %} 14578 14579 instruct leaI_rReg_immI_peep(rRegI dst, rRegI src1, immI src2) 14580 %{ 14581 predicate(false); 14582 match(Set dst (AddI src1 src2)); 14583 format %{ "leal $dst, [$src1 + $src2]" %} 14584 ins_encode %{ 14585 __ leal($dst$$Register, Address($src1$$Register, $src2$$constant)); 14586 %} 14587 ins_pipe(ialu_reg_reg); 14588 %} 14589 14590 instruct leaI_rReg_immI2_peep(rRegI dst, rRegI src, immI2 shift) 14591 %{ 14592 predicate(false); 14593 match(Set dst (LShiftI src shift)); 14594 format %{ "leal $dst, [$src << $shift]" %} 14595 ins_encode %{ 14596 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($shift$$constant); 14597 Register src = $src$$Register; 14598 if (scale == Address::times_2 && src != rbp && src != r13) { 14599 __ leal($dst$$Register, Address(src, src, Address::times_1)); 14600 } else { 14601 __ leal($dst$$Register, Address(noreg, src, scale)); 14602 } 14603 %} 14604 ins_pipe(ialu_reg_reg); 14605 %} 14606 14607 instruct leaL_rReg_rReg_peep(rRegL dst, rRegL src1, rRegL src2) 14608 %{ 14609 predicate(false); 14610 match(Set dst (AddL src1 src2)); 14611 format %{ "leaq $dst, [$src1 + $src2]" %} 14612 ins_encode %{ 14613 Register dst = $dst$$Register; 14614 Register src1 = $src1$$Register; 14615 Register src2 = $src2$$Register; 14616 if (src1 != rbp && src1 != r13) { 14617 __ leaq(dst, Address(src1, src2, Address::times_1)); 14618 } else { 14619 assert(src2 != rbp && src2 != r13, ""); 14620 __ leaq(dst, Address(src2, src1, Address::times_1)); 14621 } 14622 %} 14623 ins_pipe(ialu_reg_reg); 14624 %} 14625 14626 instruct leaL_rReg_immL32_peep(rRegL dst, rRegL src1, immL32 src2) 14627 %{ 14628 predicate(false); 14629 match(Set dst (AddL src1 src2)); 14630 format %{ "leaq $dst, [$src1 + $src2]" %} 14631 ins_encode %{ 14632 __ leaq($dst$$Register, Address($src1$$Register, $src2$$constant)); 14633 %} 14634 ins_pipe(ialu_reg_reg); 14635 %} 14636 14637 instruct leaL_rReg_immI2_peep(rRegL dst, rRegL src, immI2 shift) 14638 %{ 14639 predicate(false); 14640 match(Set dst (LShiftL src shift)); 14641 format %{ "leaq $dst, [$src << $shift]" %} 14642 ins_encode %{ 14643 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($shift$$constant); 14644 Register src = $src$$Register; 14645 if (scale == Address::times_2 && src != rbp && src != r13) { 14646 __ leaq($dst$$Register, Address(src, src, Address::times_1)); 14647 } else { 14648 __ leaq($dst$$Register, Address(noreg, src, scale)); 14649 } 14650 %} 14651 ins_pipe(ialu_reg_reg); 14652 %} 14653 14654 // These peephole rules replace mov + I pairs (where I is one of {add, inc, dec, 14655 // sal}) with lea instructions. The {add, sal} rules are beneficial in 14656 // processors with at least partial ALU support for lea 14657 // (supports_fast_2op_lea()), whereas the {inc, dec} rules are only generally 14658 // beneficial for processors with full ALU support 14659 // (VM_Version::supports_fast_3op_lea()) and Intel Cascade Lake. 14660 14661 peephole 14662 %{ 14663 peeppredicate(VM_Version::supports_fast_2op_lea()); 14664 peepmatch (addI_rReg); 14665 peepprocedure (lea_coalesce_reg); 14666 peepreplace (leaI_rReg_rReg_peep()); 14667 %} 14668 14669 peephole 14670 %{ 14671 peeppredicate(VM_Version::supports_fast_2op_lea()); 14672 peepmatch (addI_rReg_imm); 14673 peepprocedure (lea_coalesce_imm); 14674 peepreplace (leaI_rReg_immI_peep()); 14675 %} 14676 14677 peephole 14678 %{ 14679 peeppredicate(VM_Version::supports_fast_3op_lea() || 14680 VM_Version::is_intel_cascade_lake()); 14681 peepmatch (incI_rReg); 14682 peepprocedure (lea_coalesce_imm); 14683 peepreplace (leaI_rReg_immI_peep()); 14684 %} 14685 14686 peephole 14687 %{ 14688 peeppredicate(VM_Version::supports_fast_3op_lea() || 14689 VM_Version::is_intel_cascade_lake()); 14690 peepmatch (decI_rReg); 14691 peepprocedure (lea_coalesce_imm); 14692 peepreplace (leaI_rReg_immI_peep()); 14693 %} 14694 14695 peephole 14696 %{ 14697 peeppredicate(VM_Version::supports_fast_2op_lea()); 14698 peepmatch (salI_rReg_immI2); 14699 peepprocedure (lea_coalesce_imm); 14700 peepreplace (leaI_rReg_immI2_peep()); 14701 %} 14702 14703 peephole 14704 %{ 14705 peeppredicate(VM_Version::supports_fast_2op_lea()); 14706 peepmatch (addL_rReg); 14707 peepprocedure (lea_coalesce_reg); 14708 peepreplace (leaL_rReg_rReg_peep()); 14709 %} 14710 14711 peephole 14712 %{ 14713 peeppredicate(VM_Version::supports_fast_2op_lea()); 14714 peepmatch (addL_rReg_imm); 14715 peepprocedure (lea_coalesce_imm); 14716 peepreplace (leaL_rReg_immL32_peep()); 14717 %} 14718 14719 peephole 14720 %{ 14721 peeppredicate(VM_Version::supports_fast_3op_lea() || 14722 VM_Version::is_intel_cascade_lake()); 14723 peepmatch (incL_rReg); 14724 peepprocedure (lea_coalesce_imm); 14725 peepreplace (leaL_rReg_immL32_peep()); 14726 %} 14727 14728 peephole 14729 %{ 14730 peeppredicate(VM_Version::supports_fast_3op_lea() || 14731 VM_Version::is_intel_cascade_lake()); 14732 peepmatch (decL_rReg); 14733 peepprocedure (lea_coalesce_imm); 14734 peepreplace (leaL_rReg_immL32_peep()); 14735 %} 14736 14737 peephole 14738 %{ 14739 peeppredicate(VM_Version::supports_fast_2op_lea()); 14740 peepmatch (salL_rReg_immI2); 14741 peepprocedure (lea_coalesce_imm); 14742 peepreplace (leaL_rReg_immI2_peep()); 14743 %} 14744 14745 // These peephole rules matches instructions which set flags and are followed by a testI/L_reg 14746 // 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 14747 14748 //int variant 14749 peephole 14750 %{ 14751 peepmatch (testI_reg); 14752 peepprocedure (test_may_remove); 14753 %} 14754 14755 //long variant 14756 peephole 14757 %{ 14758 peepmatch (testL_reg); 14759 peepprocedure (test_may_remove); 14760 %} 14761 14762 14763 //----------SMARTSPILL RULES--------------------------------------------------- 14764 // These must follow all instruction definitions as they use the names 14765 // defined in the instructions definitions.