1 // 2 // Copyright (c) 2003, 2024, 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 %} 426 427 // Register masks 428 source_hpp %{ 429 430 extern RegMask _ANY_REG_mask; 431 extern RegMask _PTR_REG_mask; 432 extern RegMask _PTR_REG_NO_RBP_mask; 433 extern RegMask _PTR_NO_RAX_REG_mask; 434 extern RegMask _PTR_NO_RAX_RBX_REG_mask; 435 extern RegMask _LONG_REG_mask; 436 extern RegMask _LONG_NO_RAX_RDX_REG_mask; 437 extern RegMask _LONG_NO_RCX_REG_mask; 438 extern RegMask _LONG_NO_RBP_R13_REG_mask; 439 extern RegMask _INT_REG_mask; 440 extern RegMask _INT_NO_RAX_RDX_REG_mask; 441 extern RegMask _INT_NO_RCX_REG_mask; 442 extern RegMask _INT_NO_RBP_R13_REG_mask; 443 extern RegMask _FLOAT_REG_mask; 444 445 extern RegMask _STACK_OR_PTR_REG_mask; 446 extern RegMask _STACK_OR_LONG_REG_mask; 447 extern RegMask _STACK_OR_INT_REG_mask; 448 449 inline const RegMask& STACK_OR_PTR_REG_mask() { return _STACK_OR_PTR_REG_mask; } 450 inline const RegMask& STACK_OR_LONG_REG_mask() { return _STACK_OR_LONG_REG_mask; } 451 inline const RegMask& STACK_OR_INT_REG_mask() { return _STACK_OR_INT_REG_mask; } 452 453 %} 454 455 source %{ 456 #define RELOC_IMM64 Assembler::imm_operand 457 #define RELOC_DISP32 Assembler::disp32_operand 458 459 #define __ masm-> 460 461 RegMask _ANY_REG_mask; 462 RegMask _PTR_REG_mask; 463 RegMask _PTR_REG_NO_RBP_mask; 464 RegMask _PTR_NO_RAX_REG_mask; 465 RegMask _PTR_NO_RAX_RBX_REG_mask; 466 RegMask _LONG_REG_mask; 467 RegMask _LONG_NO_RAX_RDX_REG_mask; 468 RegMask _LONG_NO_RCX_REG_mask; 469 RegMask _LONG_NO_RBP_R13_REG_mask; 470 RegMask _INT_REG_mask; 471 RegMask _INT_NO_RAX_RDX_REG_mask; 472 RegMask _INT_NO_RCX_REG_mask; 473 RegMask _INT_NO_RBP_R13_REG_mask; 474 RegMask _FLOAT_REG_mask; 475 RegMask _STACK_OR_PTR_REG_mask; 476 RegMask _STACK_OR_LONG_REG_mask; 477 RegMask _STACK_OR_INT_REG_mask; 478 479 static bool need_r12_heapbase() { 480 return UseCompressedOops; 481 } 482 483 void reg_mask_init() { 484 constexpr Register egprs[] = {r16, r17, r18, r19, r20, r21, r22, r23, r24, r25, r26, r27, r28, r29, r30, r31}; 485 486 // _ALL_REG_mask is generated by adlc from the all_reg register class below. 487 // We derive a number of subsets from it. 488 _ANY_REG_mask = _ALL_REG_mask; 489 490 if (PreserveFramePointer) { 491 _ANY_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg())); 492 _ANY_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg()->next())); 493 } 494 if (need_r12_heapbase()) { 495 _ANY_REG_mask.Remove(OptoReg::as_OptoReg(r12->as_VMReg())); 496 _ANY_REG_mask.Remove(OptoReg::as_OptoReg(r12->as_VMReg()->next())); 497 } 498 499 _PTR_REG_mask = _ANY_REG_mask; 500 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(rsp->as_VMReg())); 501 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(rsp->as_VMReg()->next())); 502 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(r15->as_VMReg())); 503 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(r15->as_VMReg()->next())); 504 if (!UseAPX) { 505 for (uint i = 0; i < sizeof(egprs)/sizeof(Register); i++) { 506 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(egprs[i]->as_VMReg())); 507 _PTR_REG_mask.Remove(OptoReg::as_OptoReg(egprs[i]->as_VMReg()->next())); 508 } 509 } 510 511 _STACK_OR_PTR_REG_mask = _PTR_REG_mask; 512 _STACK_OR_PTR_REG_mask.OR(STACK_OR_STACK_SLOTS_mask()); 513 514 _PTR_REG_NO_RBP_mask = _PTR_REG_mask; 515 _PTR_REG_NO_RBP_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg())); 516 _PTR_REG_NO_RBP_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg()->next())); 517 518 _PTR_NO_RAX_REG_mask = _PTR_REG_mask; 519 _PTR_NO_RAX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg())); 520 _PTR_NO_RAX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg()->next())); 521 522 _PTR_NO_RAX_RBX_REG_mask = _PTR_NO_RAX_REG_mask; 523 _PTR_NO_RAX_RBX_REG_mask.Remove(OptoReg::as_OptoReg(rbx->as_VMReg())); 524 _PTR_NO_RAX_RBX_REG_mask.Remove(OptoReg::as_OptoReg(rbx->as_VMReg()->next())); 525 526 527 _LONG_REG_mask = _PTR_REG_mask; 528 _STACK_OR_LONG_REG_mask = _LONG_REG_mask; 529 _STACK_OR_LONG_REG_mask.OR(STACK_OR_STACK_SLOTS_mask()); 530 531 _LONG_NO_RAX_RDX_REG_mask = _LONG_REG_mask; 532 _LONG_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg())); 533 _LONG_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg()->next())); 534 _LONG_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rdx->as_VMReg())); 535 _LONG_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rdx->as_VMReg()->next())); 536 537 _LONG_NO_RCX_REG_mask = _LONG_REG_mask; 538 _LONG_NO_RCX_REG_mask.Remove(OptoReg::as_OptoReg(rcx->as_VMReg())); 539 _LONG_NO_RCX_REG_mask.Remove(OptoReg::as_OptoReg(rcx->as_VMReg()->next())); 540 541 _LONG_NO_RBP_R13_REG_mask = _LONG_REG_mask; 542 _LONG_NO_RBP_R13_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg())); 543 _LONG_NO_RBP_R13_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg()->next())); 544 _LONG_NO_RBP_R13_REG_mask.Remove(OptoReg::as_OptoReg(r13->as_VMReg())); 545 _LONG_NO_RBP_R13_REG_mask.Remove(OptoReg::as_OptoReg(r13->as_VMReg()->next())); 546 547 _INT_REG_mask = _ALL_INT_REG_mask; 548 if (!UseAPX) { 549 for (uint i = 0; i < sizeof(egprs)/sizeof(Register); i++) { 550 _INT_REG_mask.Remove(OptoReg::as_OptoReg(egprs[i]->as_VMReg())); 551 } 552 } 553 554 if (PreserveFramePointer) { 555 _INT_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg())); 556 } 557 if (need_r12_heapbase()) { 558 _INT_REG_mask.Remove(OptoReg::as_OptoReg(r12->as_VMReg())); 559 } 560 561 _STACK_OR_INT_REG_mask = _INT_REG_mask; 562 _STACK_OR_INT_REG_mask.OR(STACK_OR_STACK_SLOTS_mask()); 563 564 _INT_NO_RAX_RDX_REG_mask = _INT_REG_mask; 565 _INT_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rax->as_VMReg())); 566 _INT_NO_RAX_RDX_REG_mask.Remove(OptoReg::as_OptoReg(rdx->as_VMReg())); 567 568 _INT_NO_RCX_REG_mask = _INT_REG_mask; 569 _INT_NO_RCX_REG_mask.Remove(OptoReg::as_OptoReg(rcx->as_VMReg())); 570 571 _INT_NO_RBP_R13_REG_mask = _INT_REG_mask; 572 _INT_NO_RBP_R13_REG_mask.Remove(OptoReg::as_OptoReg(rbp->as_VMReg())); 573 _INT_NO_RBP_R13_REG_mask.Remove(OptoReg::as_OptoReg(r13->as_VMReg())); 574 575 // _FLOAT_REG_LEGACY_mask/_FLOAT_REG_EVEX_mask is generated by adlc 576 // from the float_reg_legacy/float_reg_evex register class. 577 _FLOAT_REG_mask = VM_Version::supports_evex() ? _FLOAT_REG_EVEX_mask : _FLOAT_REG_LEGACY_mask; 578 } 579 580 static bool generate_vzeroupper(Compile* C) { 581 return (VM_Version::supports_vzeroupper() && (C->max_vector_size() > 16 || C->clear_upper_avx() == true)) ? true: false; // Generate vzeroupper 582 } 583 584 static int clear_avx_size() { 585 return generate_vzeroupper(Compile::current()) ? 3: 0; // vzeroupper 586 } 587 588 // !!!!! Special hack to get all types of calls to specify the byte offset 589 // from the start of the call to the point where the return address 590 // will point. 591 int MachCallStaticJavaNode::ret_addr_offset() 592 { 593 int offset = 5; // 5 bytes from start of call to where return address points 594 offset += clear_avx_size(); 595 return offset; 596 } 597 598 int MachCallDynamicJavaNode::ret_addr_offset() 599 { 600 int offset = 15; // 15 bytes from start of call to where return address points 601 offset += clear_avx_size(); 602 return offset; 603 } 604 605 int MachCallRuntimeNode::ret_addr_offset() { 606 if (_entry_point == nullptr) { 607 // CallLeafNoFPInDirect 608 return 3; // callq (register) 609 } 610 int offset = 13; // movq r10,#addr; callq (r10) 611 if (this->ideal_Opcode() != Op_CallLeafVector) { 612 offset += clear_avx_size(); 613 } 614 return offset; 615 } 616 617 // 618 // Compute padding required for nodes which need alignment 619 // 620 621 // The address of the call instruction needs to be 4-byte aligned to 622 // ensure that it does not span a cache line so that it can be patched. 623 int CallStaticJavaDirectNode::compute_padding(int current_offset) const 624 { 625 current_offset += clear_avx_size(); // skip vzeroupper 626 current_offset += 1; // skip call opcode byte 627 return align_up(current_offset, alignment_required()) - current_offset; 628 } 629 630 // The address of the call instruction needs to be 4-byte aligned to 631 // ensure that it does not span a cache line so that it can be patched. 632 int CallDynamicJavaDirectNode::compute_padding(int current_offset) const 633 { 634 current_offset += clear_avx_size(); // skip vzeroupper 635 current_offset += 11; // skip movq instruction + call opcode byte 636 return align_up(current_offset, alignment_required()) - current_offset; 637 } 638 639 // This could be in MacroAssembler but it's fairly C2 specific 640 static void emit_cmpfp_fixup(MacroAssembler* masm) { 641 Label exit; 642 __ jccb(Assembler::noParity, exit); 643 __ pushf(); 644 // 645 // comiss/ucomiss instructions set ZF,PF,CF flags and 646 // zero OF,AF,SF for NaN values. 647 // Fixup flags by zeroing ZF,PF so that compare of NaN 648 // values returns 'less than' result (CF is set). 649 // Leave the rest of flags unchanged. 650 // 651 // 7 6 5 4 3 2 1 0 652 // |S|Z|r|A|r|P|r|C| (r - reserved bit) 653 // 0 0 1 0 1 0 1 1 (0x2B) 654 // 655 __ andq(Address(rsp, 0), 0xffffff2b); 656 __ popf(); 657 __ bind(exit); 658 } 659 660 static void emit_cmpfp3(MacroAssembler* masm, Register dst) { 661 Label done; 662 __ movl(dst, -1); 663 __ jcc(Assembler::parity, done); 664 __ jcc(Assembler::below, done); 665 __ setcc(Assembler::notEqual, dst); 666 __ bind(done); 667 } 668 669 // Math.min() # Math.max() 670 // -------------------------- 671 // ucomis[s/d] # 672 // ja -> b # a 673 // jp -> NaN # NaN 674 // jb -> a # b 675 // je # 676 // |-jz -> a | b # a & b 677 // | -> a # 678 static void emit_fp_min_max(MacroAssembler* masm, XMMRegister dst, 679 XMMRegister a, XMMRegister b, 680 XMMRegister xmmt, Register rt, 681 bool min, bool single) { 682 683 Label nan, zero, below, above, done; 684 685 if (single) 686 __ ucomiss(a, b); 687 else 688 __ ucomisd(a, b); 689 690 if (dst->encoding() != (min ? b : a)->encoding()) 691 __ jccb(Assembler::above, above); // CF=0 & ZF=0 692 else 693 __ jccb(Assembler::above, done); 694 695 __ jccb(Assembler::parity, nan); // PF=1 696 __ jccb(Assembler::below, below); // CF=1 697 698 // equal 699 __ vpxor(xmmt, xmmt, xmmt, Assembler::AVX_128bit); 700 if (single) { 701 __ ucomiss(a, xmmt); 702 __ jccb(Assembler::equal, zero); 703 704 __ movflt(dst, a); 705 __ jmp(done); 706 } 707 else { 708 __ ucomisd(a, xmmt); 709 __ jccb(Assembler::equal, zero); 710 711 __ movdbl(dst, a); 712 __ jmp(done); 713 } 714 715 __ bind(zero); 716 if (min) 717 __ vpor(dst, a, b, Assembler::AVX_128bit); 718 else 719 __ vpand(dst, a, b, Assembler::AVX_128bit); 720 721 __ jmp(done); 722 723 __ bind(above); 724 if (single) 725 __ movflt(dst, min ? b : a); 726 else 727 __ movdbl(dst, min ? b : a); 728 729 __ jmp(done); 730 731 __ bind(nan); 732 if (single) { 733 __ movl(rt, 0x7fc00000); // Float.NaN 734 __ movdl(dst, rt); 735 } 736 else { 737 __ mov64(rt, 0x7ff8000000000000L); // Double.NaN 738 __ movdq(dst, rt); 739 } 740 __ jmp(done); 741 742 __ bind(below); 743 if (single) 744 __ movflt(dst, min ? a : b); 745 else 746 __ movdbl(dst, min ? a : b); 747 748 __ bind(done); 749 } 750 751 //============================================================================= 752 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; 753 754 int ConstantTable::calculate_table_base_offset() const { 755 return 0; // absolute addressing, no offset 756 } 757 758 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; } 759 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 760 ShouldNotReachHere(); 761 } 762 763 void MachConstantBaseNode::emit(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const { 764 // Empty encoding 765 } 766 767 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 768 return 0; 769 } 770 771 #ifndef PRODUCT 772 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 773 st->print("# MachConstantBaseNode (empty encoding)"); 774 } 775 #endif 776 777 778 //============================================================================= 779 #ifndef PRODUCT 780 void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 781 Compile* C = ra_->C; 782 783 int framesize = C->output()->frame_size_in_bytes(); 784 int bangsize = C->output()->bang_size_in_bytes(); 785 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 786 // Remove wordSize for return addr which is already pushed. 787 framesize -= wordSize; 788 789 if (C->output()->need_stack_bang(bangsize)) { 790 framesize -= wordSize; 791 st->print("# stack bang (%d bytes)", bangsize); 792 st->print("\n\t"); 793 st->print("pushq rbp\t# Save rbp"); 794 if (PreserveFramePointer) { 795 st->print("\n\t"); 796 st->print("movq rbp, rsp\t# Save the caller's SP into rbp"); 797 } 798 if (framesize) { 799 st->print("\n\t"); 800 st->print("subq rsp, #%d\t# Create frame",framesize); 801 } 802 } else { 803 st->print("subq rsp, #%d\t# Create frame",framesize); 804 st->print("\n\t"); 805 framesize -= wordSize; 806 st->print("movq [rsp + #%d], rbp\t# Save rbp",framesize); 807 if (PreserveFramePointer) { 808 st->print("\n\t"); 809 st->print("movq rbp, rsp\t# Save the caller's SP into rbp"); 810 if (framesize > 0) { 811 st->print("\n\t"); 812 st->print("addq rbp, #%d", framesize); 813 } 814 } 815 } 816 817 if (VerifyStackAtCalls) { 818 st->print("\n\t"); 819 framesize -= wordSize; 820 st->print("movq [rsp + #%d], 0xbadb100d\t# Majik cookie for stack depth check",framesize); 821 #ifdef ASSERT 822 st->print("\n\t"); 823 st->print("# stack alignment check"); 824 #endif 825 } 826 if (C->stub_function() != nullptr && BarrierSet::barrier_set()->barrier_set_nmethod() != nullptr) { 827 st->print("\n\t"); 828 st->print("cmpl [r15_thread + #disarmed_guard_value_offset], #disarmed_guard_value\t"); 829 st->print("\n\t"); 830 st->print("je fast_entry\t"); 831 st->print("\n\t"); 832 st->print("call #nmethod_entry_barrier_stub\t"); 833 st->print("\n\tfast_entry:"); 834 } 835 st->cr(); 836 } 837 #endif 838 839 void MachPrologNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const { 840 Compile* C = ra_->C; 841 842 __ verified_entry(C); 843 844 if (ra_->C->stub_function() == nullptr) { 845 __ entry_barrier(); 846 } 847 848 if (!Compile::current()->output()->in_scratch_emit_size()) { 849 __ bind(*_verified_entry); 850 } 851 852 C->output()->set_frame_complete(__ offset()); 853 854 if (C->has_mach_constant_base_node()) { 855 // NOTE: We set the table base offset here because users might be 856 // emitted before MachConstantBaseNode. 857 ConstantTable& constant_table = C->output()->constant_table(); 858 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset()); 859 } 860 } 861 862 int MachPrologNode::reloc() const 863 { 864 return 0; // a large enough number 865 } 866 867 //============================================================================= 868 #ifndef PRODUCT 869 void MachEpilogNode::format(PhaseRegAlloc* ra_, outputStream* st) const 870 { 871 Compile* C = ra_->C; 872 if (generate_vzeroupper(C)) { 873 st->print("vzeroupper"); 874 st->cr(); st->print("\t"); 875 } 876 877 int framesize = C->output()->frame_size_in_bytes(); 878 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 879 // Remove word for return adr already pushed 880 // and RBP 881 framesize -= 2*wordSize; 882 883 if (framesize) { 884 st->print_cr("addq rsp, %d\t# Destroy frame", framesize); 885 st->print("\t"); 886 } 887 888 st->print_cr("popq rbp"); 889 if (do_polling() && C->is_method_compilation()) { 890 st->print("\t"); 891 st->print_cr("cmpq rsp, poll_offset[r15_thread] \n\t" 892 "ja #safepoint_stub\t" 893 "# Safepoint: poll for GC"); 894 } 895 } 896 #endif 897 898 void MachEpilogNode::emit(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const 899 { 900 Compile* C = ra_->C; 901 902 if (generate_vzeroupper(C)) { 903 // Clear upper bits of YMM registers when current compiled code uses 904 // wide vectors to avoid AVX <-> SSE transition penalty during call. 905 __ vzeroupper(); 906 } 907 908 // Subtract two words to account for return address and rbp 909 int initial_framesize = C->output()->frame_size_in_bytes() - 2*wordSize; 910 __ remove_frame(initial_framesize, C->needs_stack_repair()); 911 912 if (StackReservedPages > 0 && C->has_reserved_stack_access()) { 913 __ reserved_stack_check(); 914 } 915 916 if (do_polling() && C->is_method_compilation()) { 917 Label dummy_label; 918 Label* code_stub = &dummy_label; 919 if (!C->output()->in_scratch_emit_size()) { 920 C2SafepointPollStub* stub = new (C->comp_arena()) C2SafepointPollStub(__ offset()); 921 C->output()->add_stub(stub); 922 code_stub = &stub->entry(); 923 } 924 __ relocate(relocInfo::poll_return_type); 925 __ safepoint_poll(*code_stub, r15_thread, true /* at_return */, true /* in_nmethod */); 926 } 927 } 928 929 int MachEpilogNode::reloc() const 930 { 931 return 2; // a large enough number 932 } 933 934 const Pipeline* MachEpilogNode::pipeline() const 935 { 936 return MachNode::pipeline_class(); 937 } 938 939 //============================================================================= 940 941 enum RC { 942 rc_bad, 943 rc_int, 944 rc_kreg, 945 rc_float, 946 rc_stack 947 }; 948 949 static enum RC rc_class(OptoReg::Name reg) 950 { 951 if( !OptoReg::is_valid(reg) ) return rc_bad; 952 953 if (OptoReg::is_stack(reg)) return rc_stack; 954 955 VMReg r = OptoReg::as_VMReg(reg); 956 957 if (r->is_Register()) return rc_int; 958 959 if (r->is_KRegister()) return rc_kreg; 960 961 assert(r->is_XMMRegister(), "must be"); 962 return rc_float; 963 } 964 965 // Next two methods are shared by 32- and 64-bit VM. They are defined in x86.ad. 966 static void vec_mov_helper(C2_MacroAssembler *masm, int src_lo, int dst_lo, 967 int src_hi, int dst_hi, uint ireg, outputStream* st); 968 969 void vec_spill_helper(C2_MacroAssembler *masm, bool is_load, 970 int stack_offset, int reg, uint ireg, outputStream* st); 971 972 static void vec_stack_to_stack_helper(C2_MacroAssembler *masm, int src_offset, 973 int dst_offset, uint ireg, outputStream* st) { 974 if (masm) { 975 switch (ireg) { 976 case Op_VecS: 977 __ movq(Address(rsp, -8), rax); 978 __ movl(rax, Address(rsp, src_offset)); 979 __ movl(Address(rsp, dst_offset), rax); 980 __ movq(rax, Address(rsp, -8)); 981 break; 982 case Op_VecD: 983 __ pushq(Address(rsp, src_offset)); 984 __ popq (Address(rsp, dst_offset)); 985 break; 986 case Op_VecX: 987 __ pushq(Address(rsp, src_offset)); 988 __ popq (Address(rsp, dst_offset)); 989 __ pushq(Address(rsp, src_offset+8)); 990 __ popq (Address(rsp, dst_offset+8)); 991 break; 992 case Op_VecY: 993 __ vmovdqu(Address(rsp, -32), xmm0); 994 __ vmovdqu(xmm0, Address(rsp, src_offset)); 995 __ vmovdqu(Address(rsp, dst_offset), xmm0); 996 __ vmovdqu(xmm0, Address(rsp, -32)); 997 break; 998 case Op_VecZ: 999 __ evmovdquq(Address(rsp, -64), xmm0, 2); 1000 __ evmovdquq(xmm0, Address(rsp, src_offset), 2); 1001 __ evmovdquq(Address(rsp, dst_offset), xmm0, 2); 1002 __ evmovdquq(xmm0, Address(rsp, -64), 2); 1003 break; 1004 default: 1005 ShouldNotReachHere(); 1006 } 1007 #ifndef PRODUCT 1008 } else { 1009 switch (ireg) { 1010 case Op_VecS: 1011 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1012 "movl rax, [rsp + #%d]\n\t" 1013 "movl [rsp + #%d], rax\n\t" 1014 "movq rax, [rsp - #8]", 1015 src_offset, dst_offset); 1016 break; 1017 case Op_VecD: 1018 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1019 "popq [rsp + #%d]", 1020 src_offset, dst_offset); 1021 break; 1022 case Op_VecX: 1023 st->print("pushq [rsp + #%d]\t# 128-bit mem-mem spill\n\t" 1024 "popq [rsp + #%d]\n\t" 1025 "pushq [rsp + #%d]\n\t" 1026 "popq [rsp + #%d]", 1027 src_offset, dst_offset, src_offset+8, dst_offset+8); 1028 break; 1029 case Op_VecY: 1030 st->print("vmovdqu [rsp - #32], xmm0\t# 256-bit mem-mem spill\n\t" 1031 "vmovdqu xmm0, [rsp + #%d]\n\t" 1032 "vmovdqu [rsp + #%d], xmm0\n\t" 1033 "vmovdqu xmm0, [rsp - #32]", 1034 src_offset, dst_offset); 1035 break; 1036 case Op_VecZ: 1037 st->print("vmovdqu [rsp - #64], xmm0\t# 512-bit mem-mem spill\n\t" 1038 "vmovdqu xmm0, [rsp + #%d]\n\t" 1039 "vmovdqu [rsp + #%d], xmm0\n\t" 1040 "vmovdqu xmm0, [rsp - #64]", 1041 src_offset, dst_offset); 1042 break; 1043 default: 1044 ShouldNotReachHere(); 1045 } 1046 #endif 1047 } 1048 } 1049 1050 uint MachSpillCopyNode::implementation(C2_MacroAssembler* masm, 1051 PhaseRegAlloc* ra_, 1052 bool do_size, 1053 outputStream* st) const { 1054 assert(masm != nullptr || st != nullptr, "sanity"); 1055 // Get registers to move 1056 OptoReg::Name src_second = ra_->get_reg_second(in(1)); 1057 OptoReg::Name src_first = ra_->get_reg_first(in(1)); 1058 OptoReg::Name dst_second = ra_->get_reg_second(this); 1059 OptoReg::Name dst_first = ra_->get_reg_first(this); 1060 1061 enum RC src_second_rc = rc_class(src_second); 1062 enum RC src_first_rc = rc_class(src_first); 1063 enum RC dst_second_rc = rc_class(dst_second); 1064 enum RC dst_first_rc = rc_class(dst_first); 1065 1066 assert(OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), 1067 "must move at least 1 register" ); 1068 1069 if (src_first == dst_first && src_second == dst_second) { 1070 // Self copy, no move 1071 return 0; 1072 } 1073 if (bottom_type()->isa_vect() != nullptr && bottom_type()->isa_vectmask() == nullptr) { 1074 uint ireg = ideal_reg(); 1075 assert((src_first_rc != rc_int && dst_first_rc != rc_int), "sanity"); 1076 assert((ireg == Op_VecS || ireg == Op_VecD || ireg == Op_VecX || ireg == Op_VecY || ireg == Op_VecZ ), "sanity"); 1077 if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) { 1078 // mem -> mem 1079 int src_offset = ra_->reg2offset(src_first); 1080 int dst_offset = ra_->reg2offset(dst_first); 1081 vec_stack_to_stack_helper(masm, src_offset, dst_offset, ireg, st); 1082 } else if (src_first_rc == rc_float && dst_first_rc == rc_float ) { 1083 vec_mov_helper(masm, src_first, dst_first, src_second, dst_second, ireg, st); 1084 } else if (src_first_rc == rc_float && dst_first_rc == rc_stack ) { 1085 int stack_offset = ra_->reg2offset(dst_first); 1086 vec_spill_helper(masm, false, stack_offset, src_first, ireg, st); 1087 } else if (src_first_rc == rc_stack && dst_first_rc == rc_float ) { 1088 int stack_offset = ra_->reg2offset(src_first); 1089 vec_spill_helper(masm, true, stack_offset, dst_first, ireg, st); 1090 } else { 1091 ShouldNotReachHere(); 1092 } 1093 return 0; 1094 } 1095 if (src_first_rc == rc_stack) { 1096 // mem -> 1097 if (dst_first_rc == rc_stack) { 1098 // mem -> mem 1099 assert(src_second != dst_first, "overlap"); 1100 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1101 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1102 // 64-bit 1103 int src_offset = ra_->reg2offset(src_first); 1104 int dst_offset = ra_->reg2offset(dst_first); 1105 if (masm) { 1106 __ pushq(Address(rsp, src_offset)); 1107 __ popq (Address(rsp, dst_offset)); 1108 #ifndef PRODUCT 1109 } else { 1110 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1111 "popq [rsp + #%d]", 1112 src_offset, dst_offset); 1113 #endif 1114 } 1115 } else { 1116 // 32-bit 1117 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1118 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1119 // No pushl/popl, so: 1120 int src_offset = ra_->reg2offset(src_first); 1121 int dst_offset = ra_->reg2offset(dst_first); 1122 if (masm) { 1123 __ movq(Address(rsp, -8), rax); 1124 __ movl(rax, Address(rsp, src_offset)); 1125 __ movl(Address(rsp, dst_offset), rax); 1126 __ movq(rax, Address(rsp, -8)); 1127 #ifndef PRODUCT 1128 } else { 1129 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1130 "movl rax, [rsp + #%d]\n\t" 1131 "movl [rsp + #%d], rax\n\t" 1132 "movq rax, [rsp - #8]", 1133 src_offset, dst_offset); 1134 #endif 1135 } 1136 } 1137 return 0; 1138 } else if (dst_first_rc == rc_int) { 1139 // mem -> gpr 1140 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1141 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1142 // 64-bit 1143 int offset = ra_->reg2offset(src_first); 1144 if (masm) { 1145 __ movq(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1146 #ifndef PRODUCT 1147 } else { 1148 st->print("movq %s, [rsp + #%d]\t# spill", 1149 Matcher::regName[dst_first], 1150 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 int offset = ra_->reg2offset(src_first); 1158 if (masm) { 1159 __ movl(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1160 #ifndef PRODUCT 1161 } else { 1162 st->print("movl %s, [rsp + #%d]\t# spill", 1163 Matcher::regName[dst_first], 1164 offset); 1165 #endif 1166 } 1167 } 1168 return 0; 1169 } else if (dst_first_rc == rc_float) { 1170 // mem-> xmm 1171 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1172 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1173 // 64-bit 1174 int offset = ra_->reg2offset(src_first); 1175 if (masm) { 1176 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1177 #ifndef PRODUCT 1178 } else { 1179 st->print("%s %s, [rsp + #%d]\t# spill", 1180 UseXmmLoadAndClearUpper ? "movsd " : "movlpd", 1181 Matcher::regName[dst_first], 1182 offset); 1183 #endif 1184 } 1185 } else { 1186 // 32-bit 1187 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1188 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1189 int offset = ra_->reg2offset(src_first); 1190 if (masm) { 1191 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1192 #ifndef PRODUCT 1193 } else { 1194 st->print("movss %s, [rsp + #%d]\t# spill", 1195 Matcher::regName[dst_first], 1196 offset); 1197 #endif 1198 } 1199 } 1200 return 0; 1201 } else if (dst_first_rc == rc_kreg) { 1202 // mem -> kreg 1203 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1204 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1205 // 64-bit 1206 int offset = ra_->reg2offset(src_first); 1207 if (masm) { 1208 __ kmov(as_KRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1209 #ifndef PRODUCT 1210 } else { 1211 st->print("kmovq %s, [rsp + #%d]\t# spill", 1212 Matcher::regName[dst_first], 1213 offset); 1214 #endif 1215 } 1216 } 1217 return 0; 1218 } 1219 } else if (src_first_rc == rc_int) { 1220 // gpr -> 1221 if (dst_first_rc == rc_stack) { 1222 // gpr -> mem 1223 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1224 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1225 // 64-bit 1226 int offset = ra_->reg2offset(dst_first); 1227 if (masm) { 1228 __ movq(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1229 #ifndef PRODUCT 1230 } else { 1231 st->print("movq [rsp + #%d], %s\t# spill", 1232 offset, 1233 Matcher::regName[src_first]); 1234 #endif 1235 } 1236 } else { 1237 // 32-bit 1238 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1239 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1240 int offset = ra_->reg2offset(dst_first); 1241 if (masm) { 1242 __ movl(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1243 #ifndef PRODUCT 1244 } else { 1245 st->print("movl [rsp + #%d], %s\t# spill", 1246 offset, 1247 Matcher::regName[src_first]); 1248 #endif 1249 } 1250 } 1251 return 0; 1252 } else if (dst_first_rc == rc_int) { 1253 // gpr -> gpr 1254 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1255 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1256 // 64-bit 1257 if (masm) { 1258 __ movq(as_Register(Matcher::_regEncode[dst_first]), 1259 as_Register(Matcher::_regEncode[src_first])); 1260 #ifndef PRODUCT 1261 } else { 1262 st->print("movq %s, %s\t# spill", 1263 Matcher::regName[dst_first], 1264 Matcher::regName[src_first]); 1265 #endif 1266 } 1267 return 0; 1268 } else { 1269 // 32-bit 1270 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1271 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1272 if (masm) { 1273 __ movl(as_Register(Matcher::_regEncode[dst_first]), 1274 as_Register(Matcher::_regEncode[src_first])); 1275 #ifndef PRODUCT 1276 } else { 1277 st->print("movl %s, %s\t# spill", 1278 Matcher::regName[dst_first], 1279 Matcher::regName[src_first]); 1280 #endif 1281 } 1282 return 0; 1283 } 1284 } else if (dst_first_rc == rc_float) { 1285 // gpr -> xmm 1286 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1287 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1288 // 64-bit 1289 if (masm) { 1290 __ movdq( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1291 #ifndef PRODUCT 1292 } else { 1293 st->print("movdq %s, %s\t# spill", 1294 Matcher::regName[dst_first], 1295 Matcher::regName[src_first]); 1296 #endif 1297 } 1298 } else { 1299 // 32-bit 1300 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1301 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1302 if (masm) { 1303 __ movdl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1304 #ifndef PRODUCT 1305 } else { 1306 st->print("movdl %s, %s\t# spill", 1307 Matcher::regName[dst_first], 1308 Matcher::regName[src_first]); 1309 #endif 1310 } 1311 } 1312 return 0; 1313 } else if (dst_first_rc == rc_kreg) { 1314 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1315 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1316 // 64-bit 1317 if (masm) { 1318 __ kmov(as_KRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1319 #ifndef PRODUCT 1320 } else { 1321 st->print("kmovq %s, %s\t# spill", 1322 Matcher::regName[dst_first], 1323 Matcher::regName[src_first]); 1324 #endif 1325 } 1326 } 1327 Unimplemented(); 1328 return 0; 1329 } 1330 } else if (src_first_rc == rc_float) { 1331 // xmm -> 1332 if (dst_first_rc == rc_stack) { 1333 // xmm -> mem 1334 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1335 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1336 // 64-bit 1337 int offset = ra_->reg2offset(dst_first); 1338 if (masm) { 1339 __ movdbl( Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1340 #ifndef PRODUCT 1341 } else { 1342 st->print("movsd [rsp + #%d], %s\t# spill", 1343 offset, 1344 Matcher::regName[src_first]); 1345 #endif 1346 } 1347 } else { 1348 // 32-bit 1349 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1350 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1351 int offset = ra_->reg2offset(dst_first); 1352 if (masm) { 1353 __ movflt(Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1354 #ifndef PRODUCT 1355 } else { 1356 st->print("movss [rsp + #%d], %s\t# spill", 1357 offset, 1358 Matcher::regName[src_first]); 1359 #endif 1360 } 1361 } 1362 return 0; 1363 } else if (dst_first_rc == rc_int) { 1364 // xmm -> gpr 1365 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1366 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1367 // 64-bit 1368 if (masm) { 1369 __ movdq( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1370 #ifndef PRODUCT 1371 } else { 1372 st->print("movdq %s, %s\t# spill", 1373 Matcher::regName[dst_first], 1374 Matcher::regName[src_first]); 1375 #endif 1376 } 1377 } else { 1378 // 32-bit 1379 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1380 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1381 if (masm) { 1382 __ movdl( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1383 #ifndef PRODUCT 1384 } else { 1385 st->print("movdl %s, %s\t# spill", 1386 Matcher::regName[dst_first], 1387 Matcher::regName[src_first]); 1388 #endif 1389 } 1390 } 1391 return 0; 1392 } else if (dst_first_rc == rc_float) { 1393 // xmm -> xmm 1394 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1395 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1396 // 64-bit 1397 if (masm) { 1398 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1399 #ifndef PRODUCT 1400 } else { 1401 st->print("%s %s, %s\t# spill", 1402 UseXmmRegToRegMoveAll ? "movapd" : "movsd ", 1403 Matcher::regName[dst_first], 1404 Matcher::regName[src_first]); 1405 #endif 1406 } 1407 } else { 1408 // 32-bit 1409 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1410 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1411 if (masm) { 1412 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1413 #ifndef PRODUCT 1414 } else { 1415 st->print("%s %s, %s\t# spill", 1416 UseXmmRegToRegMoveAll ? "movaps" : "movss ", 1417 Matcher::regName[dst_first], 1418 Matcher::regName[src_first]); 1419 #endif 1420 } 1421 } 1422 return 0; 1423 } else if (dst_first_rc == rc_kreg) { 1424 assert(false, "Illegal spilling"); 1425 return 0; 1426 } 1427 } else if (src_first_rc == rc_kreg) { 1428 if (dst_first_rc == rc_stack) { 1429 // mem -> kreg 1430 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1431 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1432 // 64-bit 1433 int offset = ra_->reg2offset(dst_first); 1434 if (masm) { 1435 __ kmov(Address(rsp, offset), as_KRegister(Matcher::_regEncode[src_first])); 1436 #ifndef PRODUCT 1437 } else { 1438 st->print("kmovq [rsp + #%d] , %s\t# spill", 1439 offset, 1440 Matcher::regName[src_first]); 1441 #endif 1442 } 1443 } 1444 return 0; 1445 } else if (dst_first_rc == rc_int) { 1446 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1447 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1448 // 64-bit 1449 if (masm) { 1450 __ kmov(as_Register(Matcher::_regEncode[dst_first]), as_KRegister(Matcher::_regEncode[src_first])); 1451 #ifndef PRODUCT 1452 } else { 1453 st->print("kmovq %s, %s\t# spill", 1454 Matcher::regName[dst_first], 1455 Matcher::regName[src_first]); 1456 #endif 1457 } 1458 } 1459 Unimplemented(); 1460 return 0; 1461 } else if (dst_first_rc == rc_kreg) { 1462 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1463 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1464 // 64-bit 1465 if (masm) { 1466 __ kmov(as_KRegister(Matcher::_regEncode[dst_first]), as_KRegister(Matcher::_regEncode[src_first])); 1467 #ifndef PRODUCT 1468 } else { 1469 st->print("kmovq %s, %s\t# spill", 1470 Matcher::regName[dst_first], 1471 Matcher::regName[src_first]); 1472 #endif 1473 } 1474 } 1475 return 0; 1476 } else if (dst_first_rc == rc_float) { 1477 assert(false, "Illegal spill"); 1478 return 0; 1479 } 1480 } 1481 1482 assert(0," foo "); 1483 Unimplemented(); 1484 return 0; 1485 } 1486 1487 #ifndef PRODUCT 1488 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream* st) const { 1489 implementation(nullptr, ra_, false, st); 1490 } 1491 #endif 1492 1493 void MachSpillCopyNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const { 1494 implementation(masm, ra_, false, nullptr); 1495 } 1496 1497 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1498 return MachNode::size(ra_); 1499 } 1500 1501 //============================================================================= 1502 #ifndef PRODUCT 1503 void BoxLockNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1504 { 1505 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1506 int reg = ra_->get_reg_first(this); 1507 st->print("leaq %s, [rsp + #%d]\t# box lock", 1508 Matcher::regName[reg], offset); 1509 } 1510 #endif 1511 1512 void BoxLockNode::emit(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const 1513 { 1514 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1515 int reg = ra_->get_encode(this); 1516 1517 __ lea(as_Register(reg), Address(rsp, offset)); 1518 } 1519 1520 uint BoxLockNode::size(PhaseRegAlloc *ra_) const 1521 { 1522 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1523 return (offset < 0x80) ? 5 : 8; // REX 1524 } 1525 1526 //============================================================================= 1527 #ifndef PRODUCT 1528 void MachVEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1529 { 1530 st->print_cr("MachVEPNode"); 1531 } 1532 #endif 1533 1534 void MachVEPNode::emit(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const 1535 { 1536 CodeBuffer* cbuf = masm->code(); 1537 uint insts_size = cbuf->insts_size(); 1538 if (!_verified) { 1539 __ ic_check(1); 1540 } else { 1541 // TODO 8284443 Avoid creation of temporary frame 1542 if (ra_->C->stub_function() == nullptr) { 1543 __ verified_entry(ra_->C, 0); 1544 __ entry_barrier(); 1545 int initial_framesize = ra_->C->output()->frame_size_in_bytes() - 2*wordSize; 1546 __ remove_frame(initial_framesize, false); 1547 } 1548 // Unpack inline type args passed as oop and then jump to 1549 // the verified entry point (skipping the unverified entry). 1550 int sp_inc = __ unpack_inline_args(ra_->C, _receiver_only); 1551 // Emit code for verified entry and save increment for stack repair on return 1552 __ verified_entry(ra_->C, sp_inc); 1553 if (Compile::current()->output()->in_scratch_emit_size()) { 1554 Label dummy_verified_entry; 1555 __ jmp(dummy_verified_entry); 1556 } else { 1557 __ jmp(*_verified_entry); 1558 } 1559 } 1560 /* WARNING these NOPs are critical so that verified entry point is properly 1561 4 bytes aligned for patching by NativeJump::patch_verified_entry() */ 1562 int nops_cnt = 4 - ((cbuf->insts_size() - insts_size) & 0x3); 1563 nops_cnt &= 0x3; // Do not add nops if code is aligned. 1564 if (nops_cnt > 0) { 1565 __ nop(nops_cnt); 1566 } 1567 } 1568 1569 //============================================================================= 1570 #ifndef PRODUCT 1571 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1572 { 1573 if (UseCompressedClassPointers) { 1574 st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1575 st->print_cr("\tcmpl rscratch1, [rax + CompiledICData::speculated_klass_offset()]\t # Inline cache check"); 1576 } else { 1577 st->print_cr("movq rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1578 st->print_cr("\tcmpq rscratch1, [rax + CompiledICData::speculated_klass_offset()]\t # Inline cache check"); 1579 } 1580 st->print_cr("\tjne SharedRuntime::_ic_miss_stub"); 1581 } 1582 #endif 1583 1584 void MachUEPNode::emit(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const 1585 { 1586 __ ic_check(InteriorEntryAlignment); 1587 } 1588 1589 //============================================================================= 1590 1591 bool Matcher::supports_vector_calling_convention(void) { 1592 if (EnableVectorSupport && UseVectorStubs) { 1593 return true; 1594 } 1595 return false; 1596 } 1597 1598 OptoRegPair Matcher::vector_return_value(uint ideal_reg) { 1599 assert(EnableVectorSupport && UseVectorStubs, "sanity"); 1600 int lo = XMM0_num; 1601 int hi = XMM0b_num; 1602 if (ideal_reg == Op_VecX) hi = XMM0d_num; 1603 else if (ideal_reg == Op_VecY) hi = XMM0h_num; 1604 else if (ideal_reg == Op_VecZ) hi = XMM0p_num; 1605 return OptoRegPair(hi, lo); 1606 } 1607 1608 // Is this branch offset short enough that a short branch can be used? 1609 // 1610 // NOTE: If the platform does not provide any short branch variants, then 1611 // this method should return false for offset 0. 1612 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 1613 // The passed offset is relative to address of the branch. 1614 // On 86 a branch displacement is calculated relative to address 1615 // of a next instruction. 1616 offset -= br_size; 1617 1618 // the short version of jmpConUCF2 contains multiple branches, 1619 // making the reach slightly less 1620 if (rule == jmpConUCF2_rule) 1621 return (-126 <= offset && offset <= 125); 1622 return (-128 <= offset && offset <= 127); 1623 } 1624 1625 // Return whether or not this register is ever used as an argument. 1626 // This function is used on startup to build the trampoline stubs in 1627 // generateOptoStub. Registers not mentioned will be killed by the VM 1628 // call in the trampoline, and arguments in those registers not be 1629 // available to the callee. 1630 bool Matcher::can_be_java_arg(int reg) 1631 { 1632 return 1633 reg == RDI_num || reg == RDI_H_num || 1634 reg == RSI_num || reg == RSI_H_num || 1635 reg == RDX_num || reg == RDX_H_num || 1636 reg == RCX_num || reg == RCX_H_num || 1637 reg == R8_num || reg == R8_H_num || 1638 reg == R9_num || reg == R9_H_num || 1639 reg == R12_num || reg == R12_H_num || 1640 reg == XMM0_num || reg == XMM0b_num || 1641 reg == XMM1_num || reg == XMM1b_num || 1642 reg == XMM2_num || reg == XMM2b_num || 1643 reg == XMM3_num || reg == XMM3b_num || 1644 reg == XMM4_num || reg == XMM4b_num || 1645 reg == XMM5_num || reg == XMM5b_num || 1646 reg == XMM6_num || reg == XMM6b_num || 1647 reg == XMM7_num || reg == XMM7b_num; 1648 } 1649 1650 bool Matcher::is_spillable_arg(int reg) 1651 { 1652 return can_be_java_arg(reg); 1653 } 1654 1655 uint Matcher::int_pressure_limit() 1656 { 1657 return (INTPRESSURE == -1) ? _INT_REG_mask.Size() : INTPRESSURE; 1658 } 1659 1660 uint Matcher::float_pressure_limit() 1661 { 1662 // After experiment around with different values, the following default threshold 1663 // works best for LCM's register pressure scheduling on x64. 1664 uint dec_count = VM_Version::supports_evex() ? 4 : 2; 1665 uint default_float_pressure_threshold = _FLOAT_REG_mask.Size() - dec_count; 1666 return (FLOATPRESSURE == -1) ? default_float_pressure_threshold : FLOATPRESSURE; 1667 } 1668 1669 bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) { 1670 // In 64 bit mode a code which use multiply when 1671 // devisor is constant is faster than hardware 1672 // DIV instruction (it uses MulHiL). 1673 return false; 1674 } 1675 1676 // Register for DIVI projection of divmodI 1677 RegMask Matcher::divI_proj_mask() { 1678 return INT_RAX_REG_mask(); 1679 } 1680 1681 // Register for MODI projection of divmodI 1682 RegMask Matcher::modI_proj_mask() { 1683 return INT_RDX_REG_mask(); 1684 } 1685 1686 // Register for DIVL projection of divmodL 1687 RegMask Matcher::divL_proj_mask() { 1688 return LONG_RAX_REG_mask(); 1689 } 1690 1691 // Register for MODL projection of divmodL 1692 RegMask Matcher::modL_proj_mask() { 1693 return LONG_RDX_REG_mask(); 1694 } 1695 1696 // Register for saving SP into on method handle invokes. Not used on x86_64. 1697 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 1698 return NO_REG_mask(); 1699 } 1700 1701 %} 1702 1703 //----------ENCODING BLOCK----------------------------------------------------- 1704 // This block specifies the encoding classes used by the compiler to 1705 // output byte streams. Encoding classes are parameterized macros 1706 // used by Machine Instruction Nodes in order to generate the bit 1707 // encoding of the instruction. Operands specify their base encoding 1708 // interface with the interface keyword. There are currently 1709 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & 1710 // COND_INTER. REG_INTER causes an operand to generate a function 1711 // which returns its register number when queried. CONST_INTER causes 1712 // an operand to generate a function which returns the value of the 1713 // constant when queried. MEMORY_INTER causes an operand to generate 1714 // four functions which return the Base Register, the Index Register, 1715 // the Scale Value, and the Offset Value of the operand when queried. 1716 // COND_INTER causes an operand to generate six functions which return 1717 // the encoding code (ie - encoding bits for the instruction) 1718 // associated with each basic boolean condition for a conditional 1719 // instruction. 1720 // 1721 // Instructions specify two basic values for encoding. Again, a 1722 // function is available to check if the constant displacement is an 1723 // oop. They use the ins_encode keyword to specify their encoding 1724 // classes (which must be a sequence of enc_class names, and their 1725 // parameters, specified in the encoding block), and they use the 1726 // opcode keyword to specify, in order, their primary, secondary, and 1727 // tertiary opcode. Only the opcode sections which a particular 1728 // instruction needs for encoding need to be specified. 1729 encode %{ 1730 enc_class cdql_enc(no_rax_rdx_RegI div) 1731 %{ 1732 // Full implementation of Java idiv and irem; checks for 1733 // special case as described in JVM spec., p.243 & p.271. 1734 // 1735 // normal case special case 1736 // 1737 // input : rax: dividend min_int 1738 // reg: divisor -1 1739 // 1740 // output: rax: quotient (= rax idiv reg) min_int 1741 // rdx: remainder (= rax irem reg) 0 1742 // 1743 // Code sequnce: 1744 // 1745 // 0: 3d 00 00 00 80 cmp $0x80000000,%eax 1746 // 5: 75 07/08 jne e <normal> 1747 // 7: 33 d2 xor %edx,%edx 1748 // [div >= 8 -> offset + 1] 1749 // [REX_B] 1750 // 9: 83 f9 ff cmp $0xffffffffffffffff,$div 1751 // c: 74 03/04 je 11 <done> 1752 // 000000000000000e <normal>: 1753 // e: 99 cltd 1754 // [div >= 8 -> offset + 1] 1755 // [REX_B] 1756 // f: f7 f9 idiv $div 1757 // 0000000000000011 <done>: 1758 Label normal; 1759 Label done; 1760 1761 // cmp $0x80000000,%eax 1762 __ cmpl(as_Register(RAX_enc), 0x80000000); 1763 1764 // jne e <normal> 1765 __ jccb(Assembler::notEqual, normal); 1766 1767 // xor %edx,%edx 1768 __ xorl(as_Register(RDX_enc), as_Register(RDX_enc)); 1769 1770 // cmp $0xffffffffffffffff,%ecx 1771 __ cmpl($div$$Register, -1); 1772 1773 // je 11 <done> 1774 __ jccb(Assembler::equal, done); 1775 1776 // <normal> 1777 // cltd 1778 __ bind(normal); 1779 __ cdql(); 1780 1781 // idivl 1782 // <done> 1783 __ idivl($div$$Register); 1784 __ bind(done); 1785 %} 1786 1787 enc_class cdqq_enc(no_rax_rdx_RegL div) 1788 %{ 1789 // Full implementation of Java ldiv and lrem; checks for 1790 // special case as described in JVM spec., p.243 & p.271. 1791 // 1792 // normal case special case 1793 // 1794 // input : rax: dividend min_long 1795 // reg: divisor -1 1796 // 1797 // output: rax: quotient (= rax idiv reg) min_long 1798 // rdx: remainder (= rax irem reg) 0 1799 // 1800 // Code sequnce: 1801 // 1802 // 0: 48 ba 00 00 00 00 00 mov $0x8000000000000000,%rdx 1803 // 7: 00 00 80 1804 // a: 48 39 d0 cmp %rdx,%rax 1805 // d: 75 08 jne 17 <normal> 1806 // f: 33 d2 xor %edx,%edx 1807 // 11: 48 83 f9 ff cmp $0xffffffffffffffff,$div 1808 // 15: 74 05 je 1c <done> 1809 // 0000000000000017 <normal>: 1810 // 17: 48 99 cqto 1811 // 19: 48 f7 f9 idiv $div 1812 // 000000000000001c <done>: 1813 Label normal; 1814 Label done; 1815 1816 // mov $0x8000000000000000,%rdx 1817 __ mov64(as_Register(RDX_enc), 0x8000000000000000); 1818 1819 // cmp %rdx,%rax 1820 __ cmpq(as_Register(RAX_enc), as_Register(RDX_enc)); 1821 1822 // jne 17 <normal> 1823 __ jccb(Assembler::notEqual, normal); 1824 1825 // xor %edx,%edx 1826 __ xorl(as_Register(RDX_enc), as_Register(RDX_enc)); 1827 1828 // cmp $0xffffffffffffffff,$div 1829 __ cmpq($div$$Register, -1); 1830 1831 // je 1e <done> 1832 __ jccb(Assembler::equal, done); 1833 1834 // <normal> 1835 // cqto 1836 __ bind(normal); 1837 __ cdqq(); 1838 1839 // idivq (note: must be emitted by the user of this rule) 1840 // <done> 1841 __ idivq($div$$Register); 1842 __ bind(done); 1843 %} 1844 1845 enc_class clear_avx %{ 1846 debug_only(int off0 = __ offset()); 1847 if (generate_vzeroupper(Compile::current())) { 1848 // Clear upper bits of YMM registers to avoid AVX <-> SSE transition penalty 1849 // Clear upper bits of YMM registers when current compiled code uses 1850 // wide vectors to avoid AVX <-> SSE transition penalty during call. 1851 __ vzeroupper(); 1852 } 1853 debug_only(int off1 = __ offset()); 1854 assert(off1 - off0 == clear_avx_size(), "correct size prediction"); 1855 %} 1856 1857 enc_class Java_To_Runtime(method meth) %{ 1858 // No relocation needed 1859 __ mov64(r10, (int64_t) $meth$$method); 1860 __ call(r10); 1861 __ post_call_nop(); 1862 %} 1863 1864 enc_class Java_Static_Call(method meth) 1865 %{ 1866 // JAVA STATIC CALL 1867 // CALL to fixup routine. Fixup routine uses ScopeDesc info to 1868 // determine who we intended to call. 1869 if (!_method) { 1870 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, $meth$$method))); 1871 } else if (_method->intrinsic_id() == vmIntrinsicID::_ensureMaterializedForStackWalk) { 1872 // The NOP here is purely to ensure that eliding a call to 1873 // JVM_EnsureMaterializedForStackWalk doesn't change the code size. 1874 __ addr_nop_5(); 1875 __ block_comment("call JVM_EnsureMaterializedForStackWalk (elided)"); 1876 } else { 1877 int method_index = resolved_method_index(masm); 1878 RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 1879 : static_call_Relocation::spec(method_index); 1880 address mark = __ pc(); 1881 int call_offset = __ offset(); 1882 __ call(AddressLiteral(CAST_FROM_FN_PTR(address, $meth$$method), rspec)); 1883 if (CodeBuffer::supports_shared_stubs() && _method->can_be_statically_bound()) { 1884 // Calls of the same statically bound method can share 1885 // a stub to the interpreter. 1886 __ code()->shared_stub_to_interp_for(_method, call_offset); 1887 } else { 1888 // Emit stubs for static call. 1889 address stub = CompiledDirectCall::emit_to_interp_stub(masm, mark); 1890 __ clear_inst_mark(); 1891 if (stub == nullptr) { 1892 ciEnv::current()->record_failure("CodeCache is full"); 1893 return; 1894 } 1895 } 1896 } 1897 __ post_call_nop(); 1898 %} 1899 1900 enc_class Java_Dynamic_Call(method meth) %{ 1901 __ ic_call((address)$meth$$method, resolved_method_index(masm)); 1902 __ post_call_nop(); 1903 %} 1904 1905 %} 1906 1907 1908 1909 //----------FRAME-------------------------------------------------------------- 1910 // Definition of frame structure and management information. 1911 // 1912 // S T A C K L A Y O U T Allocators stack-slot number 1913 // | (to get allocators register number 1914 // G Owned by | | v add OptoReg::stack0()) 1915 // r CALLER | | 1916 // o | +--------+ pad to even-align allocators stack-slot 1917 // w V | pad0 | numbers; owned by CALLER 1918 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned 1919 // h ^ | in | 5 1920 // | | args | 4 Holes in incoming args owned by SELF 1921 // | | | | 3 1922 // | | +--------+ 1923 // V | | old out| Empty on Intel, window on Sparc 1924 // | old |preserve| Must be even aligned. 1925 // | SP-+--------+----> Matcher::_old_SP, even aligned 1926 // | | in | 3 area for Intel ret address 1927 // Owned by |preserve| Empty on Sparc. 1928 // SELF +--------+ 1929 // | | pad2 | 2 pad to align old SP 1930 // | +--------+ 1 1931 // | | locks | 0 1932 // | +--------+----> OptoReg::stack0(), even aligned 1933 // | | pad1 | 11 pad to align new SP 1934 // | +--------+ 1935 // | | | 10 1936 // | | spills | 9 spills 1937 // V | | 8 (pad0 slot for callee) 1938 // -----------+--------+----> Matcher::_out_arg_limit, unaligned 1939 // ^ | out | 7 1940 // | | args | 6 Holes in outgoing args owned by CALLEE 1941 // Owned by +--------+ 1942 // CALLEE | new out| 6 Empty on Intel, window on Sparc 1943 // | new |preserve| Must be even-aligned. 1944 // | SP-+--------+----> Matcher::_new_SP, even aligned 1945 // | | | 1946 // 1947 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 1948 // known from SELF's arguments and the Java calling convention. 1949 // Region 6-7 is determined per call site. 1950 // Note 2: If the calling convention leaves holes in the incoming argument 1951 // area, those holes are owned by SELF. Holes in the outgoing area 1952 // are owned by the CALLEE. Holes should not be necessary in the 1953 // incoming area, as the Java calling convention is completely under 1954 // the control of the AD file. Doubles can be sorted and packed to 1955 // avoid holes. Holes in the outgoing arguments may be necessary for 1956 // varargs C calling conventions. 1957 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 1958 // even aligned with pad0 as needed. 1959 // Region 6 is even aligned. Region 6-7 is NOT even aligned; 1960 // region 6-11 is even aligned; it may be padded out more so that 1961 // the region from SP to FP meets the minimum stack alignment. 1962 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 1963 // alignment. Region 11, pad1, may be dynamically extended so that 1964 // SP meets the minimum alignment. 1965 1966 frame 1967 %{ 1968 // These three registers define part of the calling convention 1969 // between compiled code and the interpreter. 1970 inline_cache_reg(RAX); // Inline Cache Register 1971 1972 // Optional: name the operand used by cisc-spilling to access 1973 // [stack_pointer + offset] 1974 cisc_spilling_operand_name(indOffset32); 1975 1976 // Number of stack slots consumed by locking an object 1977 sync_stack_slots(2); 1978 1979 // Compiled code's Frame Pointer 1980 frame_pointer(RSP); 1981 1982 // Interpreter stores its frame pointer in a register which is 1983 // stored to the stack by I2CAdaptors. 1984 // I2CAdaptors convert from interpreted java to compiled java. 1985 interpreter_frame_pointer(RBP); 1986 1987 // Stack alignment requirement 1988 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 1989 1990 // Number of outgoing stack slots killed above the out_preserve_stack_slots 1991 // for calls to C. Supports the var-args backing area for register parms. 1992 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 1993 1994 // The after-PROLOG location of the return address. Location of 1995 // return address specifies a type (REG or STACK) and a number 1996 // representing the register number (i.e. - use a register name) or 1997 // stack slot. 1998 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 1999 // Otherwise, it is above the locks and verification slot and alignment word 2000 return_addr(STACK - 2 + 2001 align_up((Compile::current()->in_preserve_stack_slots() + 2002 Compile::current()->fixed_slots()), 2003 stack_alignment_in_slots())); 2004 2005 // Location of compiled Java return values. Same as C for now. 2006 return_value 2007 %{ 2008 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 2009 "only return normal values"); 2010 2011 static const int lo[Op_RegL + 1] = { 2012 0, 2013 0, 2014 RAX_num, // Op_RegN 2015 RAX_num, // Op_RegI 2016 RAX_num, // Op_RegP 2017 XMM0_num, // Op_RegF 2018 XMM0_num, // Op_RegD 2019 RAX_num // Op_RegL 2020 }; 2021 static const int hi[Op_RegL + 1] = { 2022 0, 2023 0, 2024 OptoReg::Bad, // Op_RegN 2025 OptoReg::Bad, // Op_RegI 2026 RAX_H_num, // Op_RegP 2027 OptoReg::Bad, // Op_RegF 2028 XMM0b_num, // Op_RegD 2029 RAX_H_num // Op_RegL 2030 }; 2031 // Excluded flags and vector registers. 2032 assert(ARRAY_SIZE(hi) == _last_machine_leaf - 8, "missing type"); 2033 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 2034 %} 2035 %} 2036 2037 //----------ATTRIBUTES--------------------------------------------------------- 2038 //----------Operand Attributes------------------------------------------------- 2039 op_attrib op_cost(0); // Required cost attribute 2040 2041 //----------Instruction Attributes--------------------------------------------- 2042 ins_attrib ins_cost(100); // Required cost attribute 2043 ins_attrib ins_size(8); // Required size attribute (in bits) 2044 ins_attrib ins_short_branch(0); // Required flag: is this instruction 2045 // a non-matching short branch variant 2046 // of some long branch? 2047 ins_attrib ins_alignment(1); // Required alignment attribute (must 2048 // be a power of 2) specifies the 2049 // alignment that some part of the 2050 // instruction (not necessarily the 2051 // start) requires. If > 1, a 2052 // compute_padding() function must be 2053 // provided for the instruction 2054 2055 //----------OPERANDS----------------------------------------------------------- 2056 // Operand definitions must precede instruction definitions for correct parsing 2057 // in the ADLC because operands constitute user defined types which are used in 2058 // instruction definitions. 2059 2060 //----------Simple Operands---------------------------------------------------- 2061 // Immediate Operands 2062 // Integer Immediate 2063 operand immI() 2064 %{ 2065 match(ConI); 2066 2067 op_cost(10); 2068 format %{ %} 2069 interface(CONST_INTER); 2070 %} 2071 2072 // Constant for test vs zero 2073 operand immI_0() 2074 %{ 2075 predicate(n->get_int() == 0); 2076 match(ConI); 2077 2078 op_cost(0); 2079 format %{ %} 2080 interface(CONST_INTER); 2081 %} 2082 2083 // Constant for increment 2084 operand immI_1() 2085 %{ 2086 predicate(n->get_int() == 1); 2087 match(ConI); 2088 2089 op_cost(0); 2090 format %{ %} 2091 interface(CONST_INTER); 2092 %} 2093 2094 // Constant for decrement 2095 operand immI_M1() 2096 %{ 2097 predicate(n->get_int() == -1); 2098 match(ConI); 2099 2100 op_cost(0); 2101 format %{ %} 2102 interface(CONST_INTER); 2103 %} 2104 2105 operand immI_2() 2106 %{ 2107 predicate(n->get_int() == 2); 2108 match(ConI); 2109 2110 op_cost(0); 2111 format %{ %} 2112 interface(CONST_INTER); 2113 %} 2114 2115 operand immI_4() 2116 %{ 2117 predicate(n->get_int() == 4); 2118 match(ConI); 2119 2120 op_cost(0); 2121 format %{ %} 2122 interface(CONST_INTER); 2123 %} 2124 2125 operand immI_8() 2126 %{ 2127 predicate(n->get_int() == 8); 2128 match(ConI); 2129 2130 op_cost(0); 2131 format %{ %} 2132 interface(CONST_INTER); 2133 %} 2134 2135 // Valid scale values for addressing modes 2136 operand immI2() 2137 %{ 2138 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 2139 match(ConI); 2140 2141 format %{ %} 2142 interface(CONST_INTER); 2143 %} 2144 2145 operand immU7() 2146 %{ 2147 predicate((0 <= n->get_int()) && (n->get_int() <= 0x7F)); 2148 match(ConI); 2149 2150 op_cost(5); 2151 format %{ %} 2152 interface(CONST_INTER); 2153 %} 2154 2155 operand immI8() 2156 %{ 2157 predicate((-0x80 <= n->get_int()) && (n->get_int() < 0x80)); 2158 match(ConI); 2159 2160 op_cost(5); 2161 format %{ %} 2162 interface(CONST_INTER); 2163 %} 2164 2165 operand immU8() 2166 %{ 2167 predicate((0 <= n->get_int()) && (n->get_int() <= 255)); 2168 match(ConI); 2169 2170 op_cost(5); 2171 format %{ %} 2172 interface(CONST_INTER); 2173 %} 2174 2175 operand immI16() 2176 %{ 2177 predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767)); 2178 match(ConI); 2179 2180 op_cost(10); 2181 format %{ %} 2182 interface(CONST_INTER); 2183 %} 2184 2185 // Int Immediate non-negative 2186 operand immU31() 2187 %{ 2188 predicate(n->get_int() >= 0); 2189 match(ConI); 2190 2191 op_cost(0); 2192 format %{ %} 2193 interface(CONST_INTER); 2194 %} 2195 2196 // Pointer Immediate 2197 operand immP() 2198 %{ 2199 match(ConP); 2200 2201 op_cost(10); 2202 format %{ %} 2203 interface(CONST_INTER); 2204 %} 2205 2206 // Null Pointer Immediate 2207 operand immP0() 2208 %{ 2209 predicate(n->get_ptr() == 0); 2210 match(ConP); 2211 2212 op_cost(5); 2213 format %{ %} 2214 interface(CONST_INTER); 2215 %} 2216 2217 // Pointer Immediate 2218 operand immN() %{ 2219 match(ConN); 2220 2221 op_cost(10); 2222 format %{ %} 2223 interface(CONST_INTER); 2224 %} 2225 2226 operand immNKlass() %{ 2227 match(ConNKlass); 2228 2229 op_cost(10); 2230 format %{ %} 2231 interface(CONST_INTER); 2232 %} 2233 2234 // Null Pointer Immediate 2235 operand immN0() %{ 2236 predicate(n->get_narrowcon() == 0); 2237 match(ConN); 2238 2239 op_cost(5); 2240 format %{ %} 2241 interface(CONST_INTER); 2242 %} 2243 2244 operand immP31() 2245 %{ 2246 predicate(n->as_Type()->type()->reloc() == relocInfo::none 2247 && (n->get_ptr() >> 31) == 0); 2248 match(ConP); 2249 2250 op_cost(5); 2251 format %{ %} 2252 interface(CONST_INTER); 2253 %} 2254 2255 2256 // Long Immediate 2257 operand immL() 2258 %{ 2259 match(ConL); 2260 2261 op_cost(20); 2262 format %{ %} 2263 interface(CONST_INTER); 2264 %} 2265 2266 // Long Immediate 8-bit 2267 operand immL8() 2268 %{ 2269 predicate(-0x80L <= n->get_long() && n->get_long() < 0x80L); 2270 match(ConL); 2271 2272 op_cost(5); 2273 format %{ %} 2274 interface(CONST_INTER); 2275 %} 2276 2277 // Long Immediate 32-bit unsigned 2278 operand immUL32() 2279 %{ 2280 predicate(n->get_long() == (unsigned int) (n->get_long())); 2281 match(ConL); 2282 2283 op_cost(10); 2284 format %{ %} 2285 interface(CONST_INTER); 2286 %} 2287 2288 // Long Immediate 32-bit signed 2289 operand immL32() 2290 %{ 2291 predicate(n->get_long() == (int) (n->get_long())); 2292 match(ConL); 2293 2294 op_cost(15); 2295 format %{ %} 2296 interface(CONST_INTER); 2297 %} 2298 2299 operand immL_Pow2() 2300 %{ 2301 predicate(is_power_of_2((julong)n->get_long())); 2302 match(ConL); 2303 2304 op_cost(15); 2305 format %{ %} 2306 interface(CONST_INTER); 2307 %} 2308 2309 operand immL_NotPow2() 2310 %{ 2311 predicate(is_power_of_2((julong)~n->get_long())); 2312 match(ConL); 2313 2314 op_cost(15); 2315 format %{ %} 2316 interface(CONST_INTER); 2317 %} 2318 2319 // Long Immediate zero 2320 operand immL0() 2321 %{ 2322 predicate(n->get_long() == 0L); 2323 match(ConL); 2324 2325 op_cost(10); 2326 format %{ %} 2327 interface(CONST_INTER); 2328 %} 2329 2330 // Constant for increment 2331 operand immL1() 2332 %{ 2333 predicate(n->get_long() == 1); 2334 match(ConL); 2335 2336 format %{ %} 2337 interface(CONST_INTER); 2338 %} 2339 2340 // Constant for decrement 2341 operand immL_M1() 2342 %{ 2343 predicate(n->get_long() == -1); 2344 match(ConL); 2345 2346 format %{ %} 2347 interface(CONST_INTER); 2348 %} 2349 2350 // Long Immediate: low 32-bit mask 2351 operand immL_32bits() 2352 %{ 2353 predicate(n->get_long() == 0xFFFFFFFFL); 2354 match(ConL); 2355 op_cost(20); 2356 2357 format %{ %} 2358 interface(CONST_INTER); 2359 %} 2360 2361 // Int Immediate: 2^n-1, positive 2362 operand immI_Pow2M1() 2363 %{ 2364 predicate((n->get_int() > 0) 2365 && is_power_of_2((juint)n->get_int() + 1)); 2366 match(ConI); 2367 2368 op_cost(20); 2369 format %{ %} 2370 interface(CONST_INTER); 2371 %} 2372 2373 // Float Immediate zero 2374 operand immF0() 2375 %{ 2376 predicate(jint_cast(n->getf()) == 0); 2377 match(ConF); 2378 2379 op_cost(5); 2380 format %{ %} 2381 interface(CONST_INTER); 2382 %} 2383 2384 // Float Immediate 2385 operand immF() 2386 %{ 2387 match(ConF); 2388 2389 op_cost(15); 2390 format %{ %} 2391 interface(CONST_INTER); 2392 %} 2393 2394 // Double Immediate zero 2395 operand immD0() 2396 %{ 2397 predicate(jlong_cast(n->getd()) == 0); 2398 match(ConD); 2399 2400 op_cost(5); 2401 format %{ %} 2402 interface(CONST_INTER); 2403 %} 2404 2405 // Double Immediate 2406 operand immD() 2407 %{ 2408 match(ConD); 2409 2410 op_cost(15); 2411 format %{ %} 2412 interface(CONST_INTER); 2413 %} 2414 2415 // Immediates for special shifts (sign extend) 2416 2417 // Constants for increment 2418 operand immI_16() 2419 %{ 2420 predicate(n->get_int() == 16); 2421 match(ConI); 2422 2423 format %{ %} 2424 interface(CONST_INTER); 2425 %} 2426 2427 operand immI_24() 2428 %{ 2429 predicate(n->get_int() == 24); 2430 match(ConI); 2431 2432 format %{ %} 2433 interface(CONST_INTER); 2434 %} 2435 2436 // Constant for byte-wide masking 2437 operand immI_255() 2438 %{ 2439 predicate(n->get_int() == 255); 2440 match(ConI); 2441 2442 format %{ %} 2443 interface(CONST_INTER); 2444 %} 2445 2446 // Constant for short-wide masking 2447 operand immI_65535() 2448 %{ 2449 predicate(n->get_int() == 65535); 2450 match(ConI); 2451 2452 format %{ %} 2453 interface(CONST_INTER); 2454 %} 2455 2456 // Constant for byte-wide masking 2457 operand immL_255() 2458 %{ 2459 predicate(n->get_long() == 255); 2460 match(ConL); 2461 2462 format %{ %} 2463 interface(CONST_INTER); 2464 %} 2465 2466 // Constant for short-wide masking 2467 operand immL_65535() 2468 %{ 2469 predicate(n->get_long() == 65535); 2470 match(ConL); 2471 2472 format %{ %} 2473 interface(CONST_INTER); 2474 %} 2475 2476 operand kReg() 2477 %{ 2478 constraint(ALLOC_IN_RC(vectmask_reg)); 2479 match(RegVectMask); 2480 format %{%} 2481 interface(REG_INTER); 2482 %} 2483 2484 // Register Operands 2485 // Integer Register 2486 operand rRegI() 2487 %{ 2488 constraint(ALLOC_IN_RC(int_reg)); 2489 match(RegI); 2490 2491 match(rax_RegI); 2492 match(rbx_RegI); 2493 match(rcx_RegI); 2494 match(rdx_RegI); 2495 match(rdi_RegI); 2496 2497 format %{ %} 2498 interface(REG_INTER); 2499 %} 2500 2501 // Special Registers 2502 operand rax_RegI() 2503 %{ 2504 constraint(ALLOC_IN_RC(int_rax_reg)); 2505 match(RegI); 2506 match(rRegI); 2507 2508 format %{ "RAX" %} 2509 interface(REG_INTER); 2510 %} 2511 2512 // Special Registers 2513 operand rbx_RegI() 2514 %{ 2515 constraint(ALLOC_IN_RC(int_rbx_reg)); 2516 match(RegI); 2517 match(rRegI); 2518 2519 format %{ "RBX" %} 2520 interface(REG_INTER); 2521 %} 2522 2523 operand rcx_RegI() 2524 %{ 2525 constraint(ALLOC_IN_RC(int_rcx_reg)); 2526 match(RegI); 2527 match(rRegI); 2528 2529 format %{ "RCX" %} 2530 interface(REG_INTER); 2531 %} 2532 2533 operand rdx_RegI() 2534 %{ 2535 constraint(ALLOC_IN_RC(int_rdx_reg)); 2536 match(RegI); 2537 match(rRegI); 2538 2539 format %{ "RDX" %} 2540 interface(REG_INTER); 2541 %} 2542 2543 operand rdi_RegI() 2544 %{ 2545 constraint(ALLOC_IN_RC(int_rdi_reg)); 2546 match(RegI); 2547 match(rRegI); 2548 2549 format %{ "RDI" %} 2550 interface(REG_INTER); 2551 %} 2552 2553 operand no_rax_rdx_RegI() 2554 %{ 2555 constraint(ALLOC_IN_RC(int_no_rax_rdx_reg)); 2556 match(RegI); 2557 match(rbx_RegI); 2558 match(rcx_RegI); 2559 match(rdi_RegI); 2560 2561 format %{ %} 2562 interface(REG_INTER); 2563 %} 2564 2565 operand no_rbp_r13_RegI() 2566 %{ 2567 constraint(ALLOC_IN_RC(int_no_rbp_r13_reg)); 2568 match(RegI); 2569 match(rRegI); 2570 match(rax_RegI); 2571 match(rbx_RegI); 2572 match(rcx_RegI); 2573 match(rdx_RegI); 2574 match(rdi_RegI); 2575 2576 format %{ %} 2577 interface(REG_INTER); 2578 %} 2579 2580 // Pointer Register 2581 operand any_RegP() 2582 %{ 2583 constraint(ALLOC_IN_RC(any_reg)); 2584 match(RegP); 2585 match(rax_RegP); 2586 match(rbx_RegP); 2587 match(rdi_RegP); 2588 match(rsi_RegP); 2589 match(rbp_RegP); 2590 match(r15_RegP); 2591 match(rRegP); 2592 2593 format %{ %} 2594 interface(REG_INTER); 2595 %} 2596 2597 operand rRegP() 2598 %{ 2599 constraint(ALLOC_IN_RC(ptr_reg)); 2600 match(RegP); 2601 match(rax_RegP); 2602 match(rbx_RegP); 2603 match(rdi_RegP); 2604 match(rsi_RegP); 2605 match(rbp_RegP); // See Q&A below about 2606 match(r15_RegP); // r15_RegP and rbp_RegP. 2607 2608 format %{ %} 2609 interface(REG_INTER); 2610 %} 2611 2612 operand rRegN() %{ 2613 constraint(ALLOC_IN_RC(int_reg)); 2614 match(RegN); 2615 2616 format %{ %} 2617 interface(REG_INTER); 2618 %} 2619 2620 // Question: Why is r15_RegP (the read-only TLS register) a match for rRegP? 2621 // Answer: Operand match rules govern the DFA as it processes instruction inputs. 2622 // It's fine for an instruction input that expects rRegP to match a r15_RegP. 2623 // The output of an instruction is controlled by the allocator, which respects 2624 // register class masks, not match rules. Unless an instruction mentions 2625 // r15_RegP or any_RegP explicitly as its output, r15 will not be considered 2626 // by the allocator as an input. 2627 // The same logic applies to rbp_RegP being a match for rRegP: If PreserveFramePointer==true, 2628 // the RBP is used as a proper frame pointer and is not included in ptr_reg. As a 2629 // result, RBP is not included in the output of the instruction either. 2630 2631 // This operand is not allowed to use RBP even if 2632 // RBP is not used to hold the frame pointer. 2633 operand no_rbp_RegP() 2634 %{ 2635 constraint(ALLOC_IN_RC(ptr_reg_no_rbp)); 2636 match(RegP); 2637 match(rbx_RegP); 2638 match(rsi_RegP); 2639 match(rdi_RegP); 2640 2641 format %{ %} 2642 interface(REG_INTER); 2643 %} 2644 2645 // Special Registers 2646 // Return a pointer value 2647 operand rax_RegP() 2648 %{ 2649 constraint(ALLOC_IN_RC(ptr_rax_reg)); 2650 match(RegP); 2651 match(rRegP); 2652 2653 format %{ %} 2654 interface(REG_INTER); 2655 %} 2656 2657 // Special Registers 2658 // Return a compressed pointer value 2659 operand rax_RegN() 2660 %{ 2661 constraint(ALLOC_IN_RC(int_rax_reg)); 2662 match(RegN); 2663 match(rRegN); 2664 2665 format %{ %} 2666 interface(REG_INTER); 2667 %} 2668 2669 // Used in AtomicAdd 2670 operand rbx_RegP() 2671 %{ 2672 constraint(ALLOC_IN_RC(ptr_rbx_reg)); 2673 match(RegP); 2674 match(rRegP); 2675 2676 format %{ %} 2677 interface(REG_INTER); 2678 %} 2679 2680 operand rsi_RegP() 2681 %{ 2682 constraint(ALLOC_IN_RC(ptr_rsi_reg)); 2683 match(RegP); 2684 match(rRegP); 2685 2686 format %{ %} 2687 interface(REG_INTER); 2688 %} 2689 2690 operand rbp_RegP() 2691 %{ 2692 constraint(ALLOC_IN_RC(ptr_rbp_reg)); 2693 match(RegP); 2694 match(rRegP); 2695 2696 format %{ %} 2697 interface(REG_INTER); 2698 %} 2699 2700 // Used in rep stosq 2701 operand rdi_RegP() 2702 %{ 2703 constraint(ALLOC_IN_RC(ptr_rdi_reg)); 2704 match(RegP); 2705 match(rRegP); 2706 2707 format %{ %} 2708 interface(REG_INTER); 2709 %} 2710 2711 operand r15_RegP() 2712 %{ 2713 constraint(ALLOC_IN_RC(ptr_r15_reg)); 2714 match(RegP); 2715 match(rRegP); 2716 2717 format %{ %} 2718 interface(REG_INTER); 2719 %} 2720 2721 operand rRegL() 2722 %{ 2723 constraint(ALLOC_IN_RC(long_reg)); 2724 match(RegL); 2725 match(rax_RegL); 2726 match(rdx_RegL); 2727 2728 format %{ %} 2729 interface(REG_INTER); 2730 %} 2731 2732 // Special Registers 2733 operand no_rax_rdx_RegL() 2734 %{ 2735 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 2736 match(RegL); 2737 match(rRegL); 2738 2739 format %{ %} 2740 interface(REG_INTER); 2741 %} 2742 2743 operand rax_RegL() 2744 %{ 2745 constraint(ALLOC_IN_RC(long_rax_reg)); 2746 match(RegL); 2747 match(rRegL); 2748 2749 format %{ "RAX" %} 2750 interface(REG_INTER); 2751 %} 2752 2753 operand rcx_RegL() 2754 %{ 2755 constraint(ALLOC_IN_RC(long_rcx_reg)); 2756 match(RegL); 2757 match(rRegL); 2758 2759 format %{ %} 2760 interface(REG_INTER); 2761 %} 2762 2763 operand rdx_RegL() 2764 %{ 2765 constraint(ALLOC_IN_RC(long_rdx_reg)); 2766 match(RegL); 2767 match(rRegL); 2768 2769 format %{ %} 2770 interface(REG_INTER); 2771 %} 2772 2773 operand r11_RegL() 2774 %{ 2775 constraint(ALLOC_IN_RC(long_r11_reg)); 2776 match(RegL); 2777 match(rRegL); 2778 2779 format %{ %} 2780 interface(REG_INTER); 2781 %} 2782 2783 operand no_rbp_r13_RegL() 2784 %{ 2785 constraint(ALLOC_IN_RC(long_no_rbp_r13_reg)); 2786 match(RegL); 2787 match(rRegL); 2788 match(rax_RegL); 2789 match(rcx_RegL); 2790 match(rdx_RegL); 2791 2792 format %{ %} 2793 interface(REG_INTER); 2794 %} 2795 2796 // Flags register, used as output of compare instructions 2797 operand rFlagsReg() 2798 %{ 2799 constraint(ALLOC_IN_RC(int_flags)); 2800 match(RegFlags); 2801 2802 format %{ "RFLAGS" %} 2803 interface(REG_INTER); 2804 %} 2805 2806 // Flags register, used as output of FLOATING POINT compare instructions 2807 operand rFlagsRegU() 2808 %{ 2809 constraint(ALLOC_IN_RC(int_flags)); 2810 match(RegFlags); 2811 2812 format %{ "RFLAGS_U" %} 2813 interface(REG_INTER); 2814 %} 2815 2816 operand rFlagsRegUCF() %{ 2817 constraint(ALLOC_IN_RC(int_flags)); 2818 match(RegFlags); 2819 predicate(false); 2820 2821 format %{ "RFLAGS_U_CF" %} 2822 interface(REG_INTER); 2823 %} 2824 2825 // Float register operands 2826 operand regF() %{ 2827 constraint(ALLOC_IN_RC(float_reg)); 2828 match(RegF); 2829 2830 format %{ %} 2831 interface(REG_INTER); 2832 %} 2833 2834 // Float register operands 2835 operand legRegF() %{ 2836 constraint(ALLOC_IN_RC(float_reg_legacy)); 2837 match(RegF); 2838 2839 format %{ %} 2840 interface(REG_INTER); 2841 %} 2842 2843 // Float register operands 2844 operand vlRegF() %{ 2845 constraint(ALLOC_IN_RC(float_reg_vl)); 2846 match(RegF); 2847 2848 format %{ %} 2849 interface(REG_INTER); 2850 %} 2851 2852 // Double register operands 2853 operand regD() %{ 2854 constraint(ALLOC_IN_RC(double_reg)); 2855 match(RegD); 2856 2857 format %{ %} 2858 interface(REG_INTER); 2859 %} 2860 2861 // Double register operands 2862 operand legRegD() %{ 2863 constraint(ALLOC_IN_RC(double_reg_legacy)); 2864 match(RegD); 2865 2866 format %{ %} 2867 interface(REG_INTER); 2868 %} 2869 2870 // Double register operands 2871 operand vlRegD() %{ 2872 constraint(ALLOC_IN_RC(double_reg_vl)); 2873 match(RegD); 2874 2875 format %{ %} 2876 interface(REG_INTER); 2877 %} 2878 2879 //----------Memory Operands---------------------------------------------------- 2880 // Direct Memory Operand 2881 // operand direct(immP addr) 2882 // %{ 2883 // match(addr); 2884 2885 // format %{ "[$addr]" %} 2886 // interface(MEMORY_INTER) %{ 2887 // base(0xFFFFFFFF); 2888 // index(0x4); 2889 // scale(0x0); 2890 // disp($addr); 2891 // %} 2892 // %} 2893 2894 // Indirect Memory Operand 2895 operand indirect(any_RegP reg) 2896 %{ 2897 constraint(ALLOC_IN_RC(ptr_reg)); 2898 match(reg); 2899 2900 format %{ "[$reg]" %} 2901 interface(MEMORY_INTER) %{ 2902 base($reg); 2903 index(0x4); 2904 scale(0x0); 2905 disp(0x0); 2906 %} 2907 %} 2908 2909 // Indirect Memory Plus Short Offset Operand 2910 operand indOffset8(any_RegP reg, immL8 off) 2911 %{ 2912 constraint(ALLOC_IN_RC(ptr_reg)); 2913 match(AddP reg off); 2914 2915 format %{ "[$reg + $off (8-bit)]" %} 2916 interface(MEMORY_INTER) %{ 2917 base($reg); 2918 index(0x4); 2919 scale(0x0); 2920 disp($off); 2921 %} 2922 %} 2923 2924 // Indirect Memory Plus Long Offset Operand 2925 operand indOffset32(any_RegP reg, immL32 off) 2926 %{ 2927 constraint(ALLOC_IN_RC(ptr_reg)); 2928 match(AddP reg off); 2929 2930 format %{ "[$reg + $off (32-bit)]" %} 2931 interface(MEMORY_INTER) %{ 2932 base($reg); 2933 index(0x4); 2934 scale(0x0); 2935 disp($off); 2936 %} 2937 %} 2938 2939 // Indirect Memory Plus Index Register Plus Offset Operand 2940 operand indIndexOffset(any_RegP reg, rRegL lreg, immL32 off) 2941 %{ 2942 constraint(ALLOC_IN_RC(ptr_reg)); 2943 match(AddP (AddP reg lreg) off); 2944 2945 op_cost(10); 2946 format %{"[$reg + $off + $lreg]" %} 2947 interface(MEMORY_INTER) %{ 2948 base($reg); 2949 index($lreg); 2950 scale(0x0); 2951 disp($off); 2952 %} 2953 %} 2954 2955 // Indirect Memory Plus Index Register Plus Offset Operand 2956 operand indIndex(any_RegP reg, rRegL lreg) 2957 %{ 2958 constraint(ALLOC_IN_RC(ptr_reg)); 2959 match(AddP reg lreg); 2960 2961 op_cost(10); 2962 format %{"[$reg + $lreg]" %} 2963 interface(MEMORY_INTER) %{ 2964 base($reg); 2965 index($lreg); 2966 scale(0x0); 2967 disp(0x0); 2968 %} 2969 %} 2970 2971 // Indirect Memory Times Scale Plus Index Register 2972 operand indIndexScale(any_RegP reg, rRegL lreg, immI2 scale) 2973 %{ 2974 constraint(ALLOC_IN_RC(ptr_reg)); 2975 match(AddP reg (LShiftL lreg scale)); 2976 2977 op_cost(10); 2978 format %{"[$reg + $lreg << $scale]" %} 2979 interface(MEMORY_INTER) %{ 2980 base($reg); 2981 index($lreg); 2982 scale($scale); 2983 disp(0x0); 2984 %} 2985 %} 2986 2987 operand indPosIndexScale(any_RegP reg, rRegI idx, immI2 scale) 2988 %{ 2989 constraint(ALLOC_IN_RC(ptr_reg)); 2990 predicate(n->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 2991 match(AddP reg (LShiftL (ConvI2L idx) scale)); 2992 2993 op_cost(10); 2994 format %{"[$reg + pos $idx << $scale]" %} 2995 interface(MEMORY_INTER) %{ 2996 base($reg); 2997 index($idx); 2998 scale($scale); 2999 disp(0x0); 3000 %} 3001 %} 3002 3003 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 3004 operand indIndexScaleOffset(any_RegP reg, immL32 off, rRegL lreg, immI2 scale) 3005 %{ 3006 constraint(ALLOC_IN_RC(ptr_reg)); 3007 match(AddP (AddP reg (LShiftL lreg scale)) off); 3008 3009 op_cost(10); 3010 format %{"[$reg + $off + $lreg << $scale]" %} 3011 interface(MEMORY_INTER) %{ 3012 base($reg); 3013 index($lreg); 3014 scale($scale); 3015 disp($off); 3016 %} 3017 %} 3018 3019 // Indirect Memory Plus Positive Index Register Plus Offset Operand 3020 operand indPosIndexOffset(any_RegP reg, immL32 off, rRegI idx) 3021 %{ 3022 constraint(ALLOC_IN_RC(ptr_reg)); 3023 predicate(n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 3024 match(AddP (AddP reg (ConvI2L idx)) off); 3025 3026 op_cost(10); 3027 format %{"[$reg + $off + $idx]" %} 3028 interface(MEMORY_INTER) %{ 3029 base($reg); 3030 index($idx); 3031 scale(0x0); 3032 disp($off); 3033 %} 3034 %} 3035 3036 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 3037 operand indPosIndexScaleOffset(any_RegP reg, immL32 off, rRegI idx, immI2 scale) 3038 %{ 3039 constraint(ALLOC_IN_RC(ptr_reg)); 3040 predicate(n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3041 match(AddP (AddP reg (LShiftL (ConvI2L idx) scale)) off); 3042 3043 op_cost(10); 3044 format %{"[$reg + $off + $idx << $scale]" %} 3045 interface(MEMORY_INTER) %{ 3046 base($reg); 3047 index($idx); 3048 scale($scale); 3049 disp($off); 3050 %} 3051 %} 3052 3053 // Indirect Narrow Oop Operand 3054 operand indCompressedOop(rRegN reg) %{ 3055 predicate(UseCompressedOops && (CompressedOops::shift() == Address::times_8)); 3056 constraint(ALLOC_IN_RC(ptr_reg)); 3057 match(DecodeN reg); 3058 3059 op_cost(10); 3060 format %{"[R12 + $reg << 3] (compressed oop addressing)" %} 3061 interface(MEMORY_INTER) %{ 3062 base(0xc); // R12 3063 index($reg); 3064 scale(0x3); 3065 disp(0x0); 3066 %} 3067 %} 3068 3069 // Indirect Narrow Oop Plus Offset Operand 3070 // Note: x86 architecture doesn't support "scale * index + offset" without a base 3071 // we can't free r12 even with CompressedOops::base() == nullptr. 3072 operand indCompressedOopOffset(rRegN reg, immL32 off) %{ 3073 predicate(UseCompressedOops && (CompressedOops::shift() == Address::times_8)); 3074 constraint(ALLOC_IN_RC(ptr_reg)); 3075 match(AddP (DecodeN reg) off); 3076 3077 op_cost(10); 3078 format %{"[R12 + $reg << 3 + $off] (compressed oop addressing)" %} 3079 interface(MEMORY_INTER) %{ 3080 base(0xc); // R12 3081 index($reg); 3082 scale(0x3); 3083 disp($off); 3084 %} 3085 %} 3086 3087 // Indirect Memory Operand 3088 operand indirectNarrow(rRegN reg) 3089 %{ 3090 predicate(CompressedOops::shift() == 0); 3091 constraint(ALLOC_IN_RC(ptr_reg)); 3092 match(DecodeN reg); 3093 3094 format %{ "[$reg]" %} 3095 interface(MEMORY_INTER) %{ 3096 base($reg); 3097 index(0x4); 3098 scale(0x0); 3099 disp(0x0); 3100 %} 3101 %} 3102 3103 // Indirect Memory Plus Short Offset Operand 3104 operand indOffset8Narrow(rRegN reg, immL8 off) 3105 %{ 3106 predicate(CompressedOops::shift() == 0); 3107 constraint(ALLOC_IN_RC(ptr_reg)); 3108 match(AddP (DecodeN reg) off); 3109 3110 format %{ "[$reg + $off (8-bit)]" %} 3111 interface(MEMORY_INTER) %{ 3112 base($reg); 3113 index(0x4); 3114 scale(0x0); 3115 disp($off); 3116 %} 3117 %} 3118 3119 // Indirect Memory Plus Long Offset Operand 3120 operand indOffset32Narrow(rRegN reg, immL32 off) 3121 %{ 3122 predicate(CompressedOops::shift() == 0); 3123 constraint(ALLOC_IN_RC(ptr_reg)); 3124 match(AddP (DecodeN reg) off); 3125 3126 format %{ "[$reg + $off (32-bit)]" %} 3127 interface(MEMORY_INTER) %{ 3128 base($reg); 3129 index(0x4); 3130 scale(0x0); 3131 disp($off); 3132 %} 3133 %} 3134 3135 // Indirect Memory Plus Index Register Plus Offset Operand 3136 operand indIndexOffsetNarrow(rRegN reg, rRegL lreg, immL32 off) 3137 %{ 3138 predicate(CompressedOops::shift() == 0); 3139 constraint(ALLOC_IN_RC(ptr_reg)); 3140 match(AddP (AddP (DecodeN reg) lreg) off); 3141 3142 op_cost(10); 3143 format %{"[$reg + $off + $lreg]" %} 3144 interface(MEMORY_INTER) %{ 3145 base($reg); 3146 index($lreg); 3147 scale(0x0); 3148 disp($off); 3149 %} 3150 %} 3151 3152 // Indirect Memory Plus Index Register Plus Offset Operand 3153 operand indIndexNarrow(rRegN reg, rRegL lreg) 3154 %{ 3155 predicate(CompressedOops::shift() == 0); 3156 constraint(ALLOC_IN_RC(ptr_reg)); 3157 match(AddP (DecodeN reg) lreg); 3158 3159 op_cost(10); 3160 format %{"[$reg + $lreg]" %} 3161 interface(MEMORY_INTER) %{ 3162 base($reg); 3163 index($lreg); 3164 scale(0x0); 3165 disp(0x0); 3166 %} 3167 %} 3168 3169 // Indirect Memory Times Scale Plus Index Register 3170 operand indIndexScaleNarrow(rRegN reg, rRegL lreg, immI2 scale) 3171 %{ 3172 predicate(CompressedOops::shift() == 0); 3173 constraint(ALLOC_IN_RC(ptr_reg)); 3174 match(AddP (DecodeN reg) (LShiftL lreg scale)); 3175 3176 op_cost(10); 3177 format %{"[$reg + $lreg << $scale]" %} 3178 interface(MEMORY_INTER) %{ 3179 base($reg); 3180 index($lreg); 3181 scale($scale); 3182 disp(0x0); 3183 %} 3184 %} 3185 3186 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 3187 operand indIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegL lreg, immI2 scale) 3188 %{ 3189 predicate(CompressedOops::shift() == 0); 3190 constraint(ALLOC_IN_RC(ptr_reg)); 3191 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off); 3192 3193 op_cost(10); 3194 format %{"[$reg + $off + $lreg << $scale]" %} 3195 interface(MEMORY_INTER) %{ 3196 base($reg); 3197 index($lreg); 3198 scale($scale); 3199 disp($off); 3200 %} 3201 %} 3202 3203 // Indirect Memory Times Plus Positive Index Register Plus Offset Operand 3204 operand indPosIndexOffsetNarrow(rRegN reg, immL32 off, rRegI idx) 3205 %{ 3206 constraint(ALLOC_IN_RC(ptr_reg)); 3207 predicate(CompressedOops::shift() == 0 && n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 3208 match(AddP (AddP (DecodeN reg) (ConvI2L idx)) off); 3209 3210 op_cost(10); 3211 format %{"[$reg + $off + $idx]" %} 3212 interface(MEMORY_INTER) %{ 3213 base($reg); 3214 index($idx); 3215 scale(0x0); 3216 disp($off); 3217 %} 3218 %} 3219 3220 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 3221 operand indPosIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegI idx, immI2 scale) 3222 %{ 3223 constraint(ALLOC_IN_RC(ptr_reg)); 3224 predicate(CompressedOops::shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3225 match(AddP (AddP (DecodeN reg) (LShiftL (ConvI2L idx) scale)) off); 3226 3227 op_cost(10); 3228 format %{"[$reg + $off + $idx << $scale]" %} 3229 interface(MEMORY_INTER) %{ 3230 base($reg); 3231 index($idx); 3232 scale($scale); 3233 disp($off); 3234 %} 3235 %} 3236 3237 //----------Special Memory Operands-------------------------------------------- 3238 // Stack Slot Operand - This operand is used for loading and storing temporary 3239 // values on the stack where a match requires a value to 3240 // flow through memory. 3241 operand stackSlotP(sRegP reg) 3242 %{ 3243 constraint(ALLOC_IN_RC(stack_slots)); 3244 // No match rule because this operand is only generated in matching 3245 3246 format %{ "[$reg]" %} 3247 interface(MEMORY_INTER) %{ 3248 base(0x4); // RSP 3249 index(0x4); // No Index 3250 scale(0x0); // No Scale 3251 disp($reg); // Stack Offset 3252 %} 3253 %} 3254 3255 operand stackSlotI(sRegI reg) 3256 %{ 3257 constraint(ALLOC_IN_RC(stack_slots)); 3258 // No match rule because this operand is only generated in matching 3259 3260 format %{ "[$reg]" %} 3261 interface(MEMORY_INTER) %{ 3262 base(0x4); // RSP 3263 index(0x4); // No Index 3264 scale(0x0); // No Scale 3265 disp($reg); // Stack Offset 3266 %} 3267 %} 3268 3269 operand stackSlotF(sRegF reg) 3270 %{ 3271 constraint(ALLOC_IN_RC(stack_slots)); 3272 // No match rule because this operand is only generated in matching 3273 3274 format %{ "[$reg]" %} 3275 interface(MEMORY_INTER) %{ 3276 base(0x4); // RSP 3277 index(0x4); // No Index 3278 scale(0x0); // No Scale 3279 disp($reg); // Stack Offset 3280 %} 3281 %} 3282 3283 operand stackSlotD(sRegD reg) 3284 %{ 3285 constraint(ALLOC_IN_RC(stack_slots)); 3286 // No match rule because this operand is only generated in matching 3287 3288 format %{ "[$reg]" %} 3289 interface(MEMORY_INTER) %{ 3290 base(0x4); // RSP 3291 index(0x4); // No Index 3292 scale(0x0); // No Scale 3293 disp($reg); // Stack Offset 3294 %} 3295 %} 3296 operand stackSlotL(sRegL reg) 3297 %{ 3298 constraint(ALLOC_IN_RC(stack_slots)); 3299 // No match rule because this operand is only generated in matching 3300 3301 format %{ "[$reg]" %} 3302 interface(MEMORY_INTER) %{ 3303 base(0x4); // RSP 3304 index(0x4); // No Index 3305 scale(0x0); // No Scale 3306 disp($reg); // Stack Offset 3307 %} 3308 %} 3309 3310 //----------Conditional Branch Operands---------------------------------------- 3311 // Comparison Op - This is the operation of the comparison, and is limited to 3312 // the following set of codes: 3313 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 3314 // 3315 // Other attributes of the comparison, such as unsignedness, are specified 3316 // by the comparison instruction that sets a condition code flags register. 3317 // That result is represented by a flags operand whose subtype is appropriate 3318 // to the unsignedness (etc.) of the comparison. 3319 // 3320 // Later, the instruction which matches both the Comparison Op (a Bool) and 3321 // the flags (produced by the Cmp) specifies the coding of the comparison op 3322 // by matching a specific subtype of Bool operand below, such as cmpOpU. 3323 3324 // Comparison Code 3325 operand cmpOp() 3326 %{ 3327 match(Bool); 3328 3329 format %{ "" %} 3330 interface(COND_INTER) %{ 3331 equal(0x4, "e"); 3332 not_equal(0x5, "ne"); 3333 less(0xC, "l"); 3334 greater_equal(0xD, "ge"); 3335 less_equal(0xE, "le"); 3336 greater(0xF, "g"); 3337 overflow(0x0, "o"); 3338 no_overflow(0x1, "no"); 3339 %} 3340 %} 3341 3342 // Comparison Code, unsigned compare. Used by FP also, with 3343 // C2 (unordered) turned into GT or LT already. The other bits 3344 // C0 and C3 are turned into Carry & Zero flags. 3345 operand cmpOpU() 3346 %{ 3347 match(Bool); 3348 3349 format %{ "" %} 3350 interface(COND_INTER) %{ 3351 equal(0x4, "e"); 3352 not_equal(0x5, "ne"); 3353 less(0x2, "b"); 3354 greater_equal(0x3, "ae"); 3355 less_equal(0x6, "be"); 3356 greater(0x7, "a"); 3357 overflow(0x0, "o"); 3358 no_overflow(0x1, "no"); 3359 %} 3360 %} 3361 3362 3363 // Floating comparisons that don't require any fixup for the unordered case, 3364 // If both inputs of the comparison are the same, ZF is always set so we 3365 // don't need to use cmpOpUCF2 for eq/ne 3366 operand cmpOpUCF() %{ 3367 match(Bool); 3368 predicate(n->as_Bool()->_test._test == BoolTest::lt || 3369 n->as_Bool()->_test._test == BoolTest::ge || 3370 n->as_Bool()->_test._test == BoolTest::le || 3371 n->as_Bool()->_test._test == BoolTest::gt || 3372 n->in(1)->in(1) == n->in(1)->in(2)); 3373 format %{ "" %} 3374 interface(COND_INTER) %{ 3375 equal(0xb, "np"); 3376 not_equal(0xa, "p"); 3377 less(0x2, "b"); 3378 greater_equal(0x3, "ae"); 3379 less_equal(0x6, "be"); 3380 greater(0x7, "a"); 3381 overflow(0x0, "o"); 3382 no_overflow(0x1, "no"); 3383 %} 3384 %} 3385 3386 3387 // Floating comparisons that can be fixed up with extra conditional jumps 3388 operand cmpOpUCF2() %{ 3389 match(Bool); 3390 predicate((n->as_Bool()->_test._test == BoolTest::ne || 3391 n->as_Bool()->_test._test == BoolTest::eq) && 3392 n->in(1)->in(1) != n->in(1)->in(2)); 3393 format %{ "" %} 3394 interface(COND_INTER) %{ 3395 equal(0x4, "e"); 3396 not_equal(0x5, "ne"); 3397 less(0x2, "b"); 3398 greater_equal(0x3, "ae"); 3399 less_equal(0x6, "be"); 3400 greater(0x7, "a"); 3401 overflow(0x0, "o"); 3402 no_overflow(0x1, "no"); 3403 %} 3404 %} 3405 3406 //----------OPERAND CLASSES---------------------------------------------------- 3407 // Operand Classes are groups of operands that are used as to simplify 3408 // instruction definitions by not requiring the AD writer to specify separate 3409 // instructions for every form of operand when the instruction accepts 3410 // multiple operand types with the same basic encoding and format. The classic 3411 // case of this is memory operands. 3412 3413 opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex, 3414 indIndexScale, indPosIndexScale, indIndexScaleOffset, indPosIndexOffset, indPosIndexScaleOffset, 3415 indCompressedOop, indCompressedOopOffset, 3416 indirectNarrow, indOffset8Narrow, indOffset32Narrow, 3417 indIndexOffsetNarrow, indIndexNarrow, indIndexScaleNarrow, 3418 indIndexScaleOffsetNarrow, indPosIndexOffsetNarrow, indPosIndexScaleOffsetNarrow); 3419 3420 //----------PIPELINE----------------------------------------------------------- 3421 // Rules which define the behavior of the target architectures pipeline. 3422 pipeline %{ 3423 3424 //----------ATTRIBUTES--------------------------------------------------------- 3425 attributes %{ 3426 variable_size_instructions; // Fixed size instructions 3427 max_instructions_per_bundle = 3; // Up to 3 instructions per bundle 3428 instruction_unit_size = 1; // An instruction is 1 bytes long 3429 instruction_fetch_unit_size = 16; // The processor fetches one line 3430 instruction_fetch_units = 1; // of 16 bytes 3431 3432 // List of nop instructions 3433 nops( MachNop ); 3434 %} 3435 3436 //----------RESOURCES---------------------------------------------------------- 3437 // Resources are the functional units available to the machine 3438 3439 // Generic P2/P3 pipeline 3440 // 3 decoders, only D0 handles big operands; a "bundle" is the limit of 3441 // 3 instructions decoded per cycle. 3442 // 2 load/store ops per cycle, 1 branch, 1 FPU, 3443 // 3 ALU op, only ALU0 handles mul instructions. 3444 resources( D0, D1, D2, DECODE = D0 | D1 | D2, 3445 MS0, MS1, MS2, MEM = MS0 | MS1 | MS2, 3446 BR, FPU, 3447 ALU0, ALU1, ALU2, ALU = ALU0 | ALU1 | ALU2); 3448 3449 //----------PIPELINE DESCRIPTION----------------------------------------------- 3450 // Pipeline Description specifies the stages in the machine's pipeline 3451 3452 // Generic P2/P3 pipeline 3453 pipe_desc(S0, S1, S2, S3, S4, S5); 3454 3455 //----------PIPELINE CLASSES--------------------------------------------------- 3456 // Pipeline Classes describe the stages in which input and output are 3457 // referenced by the hardware pipeline. 3458 3459 // Naming convention: ialu or fpu 3460 // Then: _reg 3461 // Then: _reg if there is a 2nd register 3462 // Then: _long if it's a pair of instructions implementing a long 3463 // Then: _fat if it requires the big decoder 3464 // Or: _mem if it requires the big decoder and a memory unit. 3465 3466 // Integer ALU reg operation 3467 pipe_class ialu_reg(rRegI dst) 3468 %{ 3469 single_instruction; 3470 dst : S4(write); 3471 dst : S3(read); 3472 DECODE : S0; // any decoder 3473 ALU : S3; // any alu 3474 %} 3475 3476 // Long ALU reg operation 3477 pipe_class ialu_reg_long(rRegL dst) 3478 %{ 3479 instruction_count(2); 3480 dst : S4(write); 3481 dst : S3(read); 3482 DECODE : S0(2); // any 2 decoders 3483 ALU : S3(2); // both alus 3484 %} 3485 3486 // Integer ALU reg operation using big decoder 3487 pipe_class ialu_reg_fat(rRegI dst) 3488 %{ 3489 single_instruction; 3490 dst : S4(write); 3491 dst : S3(read); 3492 D0 : S0; // big decoder only 3493 ALU : S3; // any alu 3494 %} 3495 3496 // Integer ALU reg-reg operation 3497 pipe_class ialu_reg_reg(rRegI dst, rRegI src) 3498 %{ 3499 single_instruction; 3500 dst : S4(write); 3501 src : S3(read); 3502 DECODE : S0; // any decoder 3503 ALU : S3; // any alu 3504 %} 3505 3506 // Integer ALU reg-reg operation 3507 pipe_class ialu_reg_reg_fat(rRegI dst, memory src) 3508 %{ 3509 single_instruction; 3510 dst : S4(write); 3511 src : S3(read); 3512 D0 : S0; // big decoder only 3513 ALU : S3; // any alu 3514 %} 3515 3516 // Integer ALU reg-mem operation 3517 pipe_class ialu_reg_mem(rRegI dst, memory mem) 3518 %{ 3519 single_instruction; 3520 dst : S5(write); 3521 mem : S3(read); 3522 D0 : S0; // big decoder only 3523 ALU : S4; // any alu 3524 MEM : S3; // any mem 3525 %} 3526 3527 // Integer mem operation (prefetch) 3528 pipe_class ialu_mem(memory mem) 3529 %{ 3530 single_instruction; 3531 mem : S3(read); 3532 D0 : S0; // big decoder only 3533 MEM : S3; // any mem 3534 %} 3535 3536 // Integer Store to Memory 3537 pipe_class ialu_mem_reg(memory mem, rRegI src) 3538 %{ 3539 single_instruction; 3540 mem : S3(read); 3541 src : S5(read); 3542 D0 : S0; // big decoder only 3543 ALU : S4; // any alu 3544 MEM : S3; 3545 %} 3546 3547 // // Long Store to Memory 3548 // pipe_class ialu_mem_long_reg(memory mem, rRegL src) 3549 // %{ 3550 // instruction_count(2); 3551 // mem : S3(read); 3552 // src : S5(read); 3553 // D0 : S0(2); // big decoder only; twice 3554 // ALU : S4(2); // any 2 alus 3555 // MEM : S3(2); // Both mems 3556 // %} 3557 3558 // Integer Store to Memory 3559 pipe_class ialu_mem_imm(memory mem) 3560 %{ 3561 single_instruction; 3562 mem : S3(read); 3563 D0 : S0; // big decoder only 3564 ALU : S4; // any alu 3565 MEM : S3; 3566 %} 3567 3568 // Integer ALU0 reg-reg operation 3569 pipe_class ialu_reg_reg_alu0(rRegI dst, rRegI src) 3570 %{ 3571 single_instruction; 3572 dst : S4(write); 3573 src : S3(read); 3574 D0 : S0; // Big decoder only 3575 ALU0 : S3; // only alu0 3576 %} 3577 3578 // Integer ALU0 reg-mem operation 3579 pipe_class ialu_reg_mem_alu0(rRegI dst, memory mem) 3580 %{ 3581 single_instruction; 3582 dst : S5(write); 3583 mem : S3(read); 3584 D0 : S0; // big decoder only 3585 ALU0 : S4; // ALU0 only 3586 MEM : S3; // any mem 3587 %} 3588 3589 // Integer ALU reg-reg operation 3590 pipe_class ialu_cr_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2) 3591 %{ 3592 single_instruction; 3593 cr : S4(write); 3594 src1 : S3(read); 3595 src2 : S3(read); 3596 DECODE : S0; // any decoder 3597 ALU : S3; // any alu 3598 %} 3599 3600 // Integer ALU reg-imm operation 3601 pipe_class ialu_cr_reg_imm(rFlagsReg cr, rRegI src1) 3602 %{ 3603 single_instruction; 3604 cr : S4(write); 3605 src1 : S3(read); 3606 DECODE : S0; // any decoder 3607 ALU : S3; // any alu 3608 %} 3609 3610 // Integer ALU reg-mem operation 3611 pipe_class ialu_cr_reg_mem(rFlagsReg cr, rRegI src1, memory src2) 3612 %{ 3613 single_instruction; 3614 cr : S4(write); 3615 src1 : S3(read); 3616 src2 : S3(read); 3617 D0 : S0; // big decoder only 3618 ALU : S4; // any alu 3619 MEM : S3; 3620 %} 3621 3622 // Conditional move reg-reg 3623 pipe_class pipe_cmplt( rRegI p, rRegI q, rRegI y) 3624 %{ 3625 instruction_count(4); 3626 y : S4(read); 3627 q : S3(read); 3628 p : S3(read); 3629 DECODE : S0(4); // any decoder 3630 %} 3631 3632 // Conditional move reg-reg 3633 pipe_class pipe_cmov_reg( rRegI dst, rRegI src, rFlagsReg cr) 3634 %{ 3635 single_instruction; 3636 dst : S4(write); 3637 src : S3(read); 3638 cr : S3(read); 3639 DECODE : S0; // any decoder 3640 %} 3641 3642 // Conditional move reg-mem 3643 pipe_class pipe_cmov_mem( rFlagsReg cr, rRegI dst, memory src) 3644 %{ 3645 single_instruction; 3646 dst : S4(write); 3647 src : S3(read); 3648 cr : S3(read); 3649 DECODE : S0; // any decoder 3650 MEM : S3; 3651 %} 3652 3653 // Conditional move reg-reg long 3654 pipe_class pipe_cmov_reg_long( rFlagsReg cr, rRegL dst, rRegL src) 3655 %{ 3656 single_instruction; 3657 dst : S4(write); 3658 src : S3(read); 3659 cr : S3(read); 3660 DECODE : S0(2); // any 2 decoders 3661 %} 3662 3663 // Float reg-reg operation 3664 pipe_class fpu_reg(regD dst) 3665 %{ 3666 instruction_count(2); 3667 dst : S3(read); 3668 DECODE : S0(2); // any 2 decoders 3669 FPU : S3; 3670 %} 3671 3672 // Float reg-reg operation 3673 pipe_class fpu_reg_reg(regD dst, regD src) 3674 %{ 3675 instruction_count(2); 3676 dst : S4(write); 3677 src : S3(read); 3678 DECODE : S0(2); // any 2 decoders 3679 FPU : S3; 3680 %} 3681 3682 // Float reg-reg operation 3683 pipe_class fpu_reg_reg_reg(regD dst, regD src1, regD src2) 3684 %{ 3685 instruction_count(3); 3686 dst : S4(write); 3687 src1 : S3(read); 3688 src2 : S3(read); 3689 DECODE : S0(3); // any 3 decoders 3690 FPU : S3(2); 3691 %} 3692 3693 // Float reg-reg operation 3694 pipe_class fpu_reg_reg_reg_reg(regD dst, regD src1, regD src2, regD src3) 3695 %{ 3696 instruction_count(4); 3697 dst : S4(write); 3698 src1 : S3(read); 3699 src2 : S3(read); 3700 src3 : S3(read); 3701 DECODE : S0(4); // any 3 decoders 3702 FPU : S3(2); 3703 %} 3704 3705 // Float reg-reg operation 3706 pipe_class fpu_reg_mem_reg_reg(regD dst, memory src1, regD src2, regD src3) 3707 %{ 3708 instruction_count(4); 3709 dst : S4(write); 3710 src1 : S3(read); 3711 src2 : S3(read); 3712 src3 : S3(read); 3713 DECODE : S1(3); // any 3 decoders 3714 D0 : S0; // Big decoder only 3715 FPU : S3(2); 3716 MEM : S3; 3717 %} 3718 3719 // Float reg-mem operation 3720 pipe_class fpu_reg_mem(regD dst, memory mem) 3721 %{ 3722 instruction_count(2); 3723 dst : S5(write); 3724 mem : S3(read); 3725 D0 : S0; // big decoder only 3726 DECODE : S1; // any decoder for FPU POP 3727 FPU : S4; 3728 MEM : S3; // any mem 3729 %} 3730 3731 // Float reg-mem operation 3732 pipe_class fpu_reg_reg_mem(regD dst, regD src1, memory mem) 3733 %{ 3734 instruction_count(3); 3735 dst : S5(write); 3736 src1 : S3(read); 3737 mem : S3(read); 3738 D0 : S0; // big decoder only 3739 DECODE : S1(2); // any decoder for FPU POP 3740 FPU : S4; 3741 MEM : S3; // any mem 3742 %} 3743 3744 // Float mem-reg operation 3745 pipe_class fpu_mem_reg(memory mem, regD src) 3746 %{ 3747 instruction_count(2); 3748 src : S5(read); 3749 mem : S3(read); 3750 DECODE : S0; // any decoder for FPU PUSH 3751 D0 : S1; // big decoder only 3752 FPU : S4; 3753 MEM : S3; // any mem 3754 %} 3755 3756 pipe_class fpu_mem_reg_reg(memory mem, regD src1, regD src2) 3757 %{ 3758 instruction_count(3); 3759 src1 : S3(read); 3760 src2 : S3(read); 3761 mem : S3(read); 3762 DECODE : S0(2); // any decoder for FPU PUSH 3763 D0 : S1; // big decoder only 3764 FPU : S4; 3765 MEM : S3; // any mem 3766 %} 3767 3768 pipe_class fpu_mem_reg_mem(memory mem, regD src1, memory src2) 3769 %{ 3770 instruction_count(3); 3771 src1 : S3(read); 3772 src2 : S3(read); 3773 mem : S4(read); 3774 DECODE : S0; // any decoder for FPU PUSH 3775 D0 : S0(2); // big decoder only 3776 FPU : S4; 3777 MEM : S3(2); // any mem 3778 %} 3779 3780 pipe_class fpu_mem_mem(memory dst, memory src1) 3781 %{ 3782 instruction_count(2); 3783 src1 : S3(read); 3784 dst : S4(read); 3785 D0 : S0(2); // big decoder only 3786 MEM : S3(2); // any mem 3787 %} 3788 3789 pipe_class fpu_mem_mem_mem(memory dst, memory src1, memory src2) 3790 %{ 3791 instruction_count(3); 3792 src1 : S3(read); 3793 src2 : S3(read); 3794 dst : S4(read); 3795 D0 : S0(3); // big decoder only 3796 FPU : S4; 3797 MEM : S3(3); // any mem 3798 %} 3799 3800 pipe_class fpu_mem_reg_con(memory mem, regD src1) 3801 %{ 3802 instruction_count(3); 3803 src1 : S4(read); 3804 mem : S4(read); 3805 DECODE : S0; // any decoder for FPU PUSH 3806 D0 : S0(2); // big decoder only 3807 FPU : S4; 3808 MEM : S3(2); // any mem 3809 %} 3810 3811 // Float load constant 3812 pipe_class fpu_reg_con(regD dst) 3813 %{ 3814 instruction_count(2); 3815 dst : S5(write); 3816 D0 : S0; // big decoder only for the load 3817 DECODE : S1; // any decoder for FPU POP 3818 FPU : S4; 3819 MEM : S3; // any mem 3820 %} 3821 3822 // Float load constant 3823 pipe_class fpu_reg_reg_con(regD dst, regD src) 3824 %{ 3825 instruction_count(3); 3826 dst : S5(write); 3827 src : S3(read); 3828 D0 : S0; // big decoder only for the load 3829 DECODE : S1(2); // any decoder for FPU POP 3830 FPU : S4; 3831 MEM : S3; // any mem 3832 %} 3833 3834 // UnConditional branch 3835 pipe_class pipe_jmp(label labl) 3836 %{ 3837 single_instruction; 3838 BR : S3; 3839 %} 3840 3841 // Conditional branch 3842 pipe_class pipe_jcc(cmpOp cmp, rFlagsReg cr, label labl) 3843 %{ 3844 single_instruction; 3845 cr : S1(read); 3846 BR : S3; 3847 %} 3848 3849 // Allocation idiom 3850 pipe_class pipe_cmpxchg(rRegP dst, rRegP heap_ptr) 3851 %{ 3852 instruction_count(1); force_serialization; 3853 fixed_latency(6); 3854 heap_ptr : S3(read); 3855 DECODE : S0(3); 3856 D0 : S2; 3857 MEM : S3; 3858 ALU : S3(2); 3859 dst : S5(write); 3860 BR : S5; 3861 %} 3862 3863 // Generic big/slow expanded idiom 3864 pipe_class pipe_slow() 3865 %{ 3866 instruction_count(10); multiple_bundles; force_serialization; 3867 fixed_latency(100); 3868 D0 : S0(2); 3869 MEM : S3(2); 3870 %} 3871 3872 // The real do-nothing guy 3873 pipe_class empty() 3874 %{ 3875 instruction_count(0); 3876 %} 3877 3878 // Define the class for the Nop node 3879 define 3880 %{ 3881 MachNop = empty; 3882 %} 3883 3884 %} 3885 3886 //----------INSTRUCTIONS------------------------------------------------------- 3887 // 3888 // match -- States which machine-independent subtree may be replaced 3889 // by this instruction. 3890 // ins_cost -- The estimated cost of this instruction is used by instruction 3891 // selection to identify a minimum cost tree of machine 3892 // instructions that matches a tree of machine-independent 3893 // instructions. 3894 // format -- A string providing the disassembly for this instruction. 3895 // The value of an instruction's operand may be inserted 3896 // by referring to it with a '$' prefix. 3897 // opcode -- Three instruction opcodes may be provided. These are referred 3898 // to within an encode class as $primary, $secondary, and $tertiary 3899 // rrspectively. The primary opcode is commonly used to 3900 // indicate the type of machine instruction, while secondary 3901 // and tertiary are often used for prefix options or addressing 3902 // modes. 3903 // ins_encode -- A list of encode classes with parameters. The encode class 3904 // name must have been defined in an 'enc_class' specification 3905 // in the encode section of the architecture description. 3906 3907 // Dummy reg-to-reg vector moves. Removed during post-selection cleanup. 3908 // Load Float 3909 instruct MoveF2VL(vlRegF dst, regF src) %{ 3910 match(Set dst src); 3911 format %{ "movss $dst,$src\t! load float (4 bytes)" %} 3912 ins_encode %{ 3913 ShouldNotReachHere(); 3914 %} 3915 ins_pipe( fpu_reg_reg ); 3916 %} 3917 3918 // Load Float 3919 instruct MoveF2LEG(legRegF dst, regF src) %{ 3920 match(Set dst src); 3921 format %{ "movss $dst,$src\t# if src != dst load float (4 bytes)" %} 3922 ins_encode %{ 3923 ShouldNotReachHere(); 3924 %} 3925 ins_pipe( fpu_reg_reg ); 3926 %} 3927 3928 // Load Float 3929 instruct MoveVL2F(regF dst, vlRegF src) %{ 3930 match(Set dst src); 3931 format %{ "movss $dst,$src\t! load float (4 bytes)" %} 3932 ins_encode %{ 3933 ShouldNotReachHere(); 3934 %} 3935 ins_pipe( fpu_reg_reg ); 3936 %} 3937 3938 // Load Float 3939 instruct MoveLEG2F(regF dst, legRegF src) %{ 3940 match(Set dst src); 3941 format %{ "movss $dst,$src\t# if src != dst load float (4 bytes)" %} 3942 ins_encode %{ 3943 ShouldNotReachHere(); 3944 %} 3945 ins_pipe( fpu_reg_reg ); 3946 %} 3947 3948 // Load Double 3949 instruct MoveD2VL(vlRegD dst, regD src) %{ 3950 match(Set dst src); 3951 format %{ "movsd $dst,$src\t! load double (8 bytes)" %} 3952 ins_encode %{ 3953 ShouldNotReachHere(); 3954 %} 3955 ins_pipe( fpu_reg_reg ); 3956 %} 3957 3958 // Load Double 3959 instruct MoveD2LEG(legRegD dst, regD src) %{ 3960 match(Set dst src); 3961 format %{ "movsd $dst,$src\t# if src != dst load double (8 bytes)" %} 3962 ins_encode %{ 3963 ShouldNotReachHere(); 3964 %} 3965 ins_pipe( fpu_reg_reg ); 3966 %} 3967 3968 // Load Double 3969 instruct MoveVL2D(regD dst, vlRegD src) %{ 3970 match(Set dst src); 3971 format %{ "movsd $dst,$src\t! load double (8 bytes)" %} 3972 ins_encode %{ 3973 ShouldNotReachHere(); 3974 %} 3975 ins_pipe( fpu_reg_reg ); 3976 %} 3977 3978 // Load Double 3979 instruct MoveLEG2D(regD dst, legRegD src) %{ 3980 match(Set dst src); 3981 format %{ "movsd $dst,$src\t# if src != dst load double (8 bytes)" %} 3982 ins_encode %{ 3983 ShouldNotReachHere(); 3984 %} 3985 ins_pipe( fpu_reg_reg ); 3986 %} 3987 3988 //----------Load/Store/Move Instructions--------------------------------------- 3989 //----------Load Instructions-------------------------------------------------- 3990 3991 // Load Byte (8 bit signed) 3992 instruct loadB(rRegI dst, memory mem) 3993 %{ 3994 match(Set dst (LoadB mem)); 3995 3996 ins_cost(125); 3997 format %{ "movsbl $dst, $mem\t# byte" %} 3998 3999 ins_encode %{ 4000 __ movsbl($dst$$Register, $mem$$Address); 4001 %} 4002 4003 ins_pipe(ialu_reg_mem); 4004 %} 4005 4006 // Load Byte (8 bit signed) into Long Register 4007 instruct loadB2L(rRegL dst, memory mem) 4008 %{ 4009 match(Set dst (ConvI2L (LoadB mem))); 4010 4011 ins_cost(125); 4012 format %{ "movsbq $dst, $mem\t# byte -> long" %} 4013 4014 ins_encode %{ 4015 __ movsbq($dst$$Register, $mem$$Address); 4016 %} 4017 4018 ins_pipe(ialu_reg_mem); 4019 %} 4020 4021 // Load Unsigned Byte (8 bit UNsigned) 4022 instruct loadUB(rRegI dst, memory mem) 4023 %{ 4024 match(Set dst (LoadUB mem)); 4025 4026 ins_cost(125); 4027 format %{ "movzbl $dst, $mem\t# ubyte" %} 4028 4029 ins_encode %{ 4030 __ movzbl($dst$$Register, $mem$$Address); 4031 %} 4032 4033 ins_pipe(ialu_reg_mem); 4034 %} 4035 4036 // Load Unsigned Byte (8 bit UNsigned) into Long Register 4037 instruct loadUB2L(rRegL dst, memory mem) 4038 %{ 4039 match(Set dst (ConvI2L (LoadUB mem))); 4040 4041 ins_cost(125); 4042 format %{ "movzbq $dst, $mem\t# ubyte -> long" %} 4043 4044 ins_encode %{ 4045 __ movzbq($dst$$Register, $mem$$Address); 4046 %} 4047 4048 ins_pipe(ialu_reg_mem); 4049 %} 4050 4051 // Load Unsigned Byte (8 bit UNsigned) with 32-bit mask into Long Register 4052 instruct loadUB2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 4053 match(Set dst (ConvI2L (AndI (LoadUB mem) mask))); 4054 effect(KILL cr); 4055 4056 format %{ "movzbq $dst, $mem\t# ubyte & 32-bit mask -> long\n\t" 4057 "andl $dst, right_n_bits($mask, 8)" %} 4058 ins_encode %{ 4059 Register Rdst = $dst$$Register; 4060 __ movzbq(Rdst, $mem$$Address); 4061 __ andl(Rdst, $mask$$constant & right_n_bits(8)); 4062 %} 4063 ins_pipe(ialu_reg_mem); 4064 %} 4065 4066 // Load Short (16 bit signed) 4067 instruct loadS(rRegI dst, memory mem) 4068 %{ 4069 match(Set dst (LoadS mem)); 4070 4071 ins_cost(125); 4072 format %{ "movswl $dst, $mem\t# short" %} 4073 4074 ins_encode %{ 4075 __ movswl($dst$$Register, $mem$$Address); 4076 %} 4077 4078 ins_pipe(ialu_reg_mem); 4079 %} 4080 4081 // Load Short (16 bit signed) to Byte (8 bit signed) 4082 instruct loadS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4083 match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour)); 4084 4085 ins_cost(125); 4086 format %{ "movsbl $dst, $mem\t# short -> byte" %} 4087 ins_encode %{ 4088 __ movsbl($dst$$Register, $mem$$Address); 4089 %} 4090 ins_pipe(ialu_reg_mem); 4091 %} 4092 4093 // Load Short (16 bit signed) into Long Register 4094 instruct loadS2L(rRegL dst, memory mem) 4095 %{ 4096 match(Set dst (ConvI2L (LoadS mem))); 4097 4098 ins_cost(125); 4099 format %{ "movswq $dst, $mem\t# short -> long" %} 4100 4101 ins_encode %{ 4102 __ movswq($dst$$Register, $mem$$Address); 4103 %} 4104 4105 ins_pipe(ialu_reg_mem); 4106 %} 4107 4108 // Load Unsigned Short/Char (16 bit UNsigned) 4109 instruct loadUS(rRegI dst, memory mem) 4110 %{ 4111 match(Set dst (LoadUS mem)); 4112 4113 ins_cost(125); 4114 format %{ "movzwl $dst, $mem\t# ushort/char" %} 4115 4116 ins_encode %{ 4117 __ movzwl($dst$$Register, $mem$$Address); 4118 %} 4119 4120 ins_pipe(ialu_reg_mem); 4121 %} 4122 4123 // Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed) 4124 instruct loadUS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4125 match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour)); 4126 4127 ins_cost(125); 4128 format %{ "movsbl $dst, $mem\t# ushort -> byte" %} 4129 ins_encode %{ 4130 __ movsbl($dst$$Register, $mem$$Address); 4131 %} 4132 ins_pipe(ialu_reg_mem); 4133 %} 4134 4135 // Load Unsigned Short/Char (16 bit UNsigned) into Long Register 4136 instruct loadUS2L(rRegL dst, memory mem) 4137 %{ 4138 match(Set dst (ConvI2L (LoadUS mem))); 4139 4140 ins_cost(125); 4141 format %{ "movzwq $dst, $mem\t# ushort/char -> long" %} 4142 4143 ins_encode %{ 4144 __ movzwq($dst$$Register, $mem$$Address); 4145 %} 4146 4147 ins_pipe(ialu_reg_mem); 4148 %} 4149 4150 // Load Unsigned Short/Char (16 bit UNsigned) with mask 0xFF into Long Register 4151 instruct loadUS2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 4152 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 4153 4154 format %{ "movzbq $dst, $mem\t# ushort/char & 0xFF -> long" %} 4155 ins_encode %{ 4156 __ movzbq($dst$$Register, $mem$$Address); 4157 %} 4158 ins_pipe(ialu_reg_mem); 4159 %} 4160 4161 // Load Unsigned Short/Char (16 bit UNsigned) with 32-bit mask into Long Register 4162 instruct loadUS2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 4163 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 4164 effect(KILL cr); 4165 4166 format %{ "movzwq $dst, $mem\t# ushort/char & 32-bit mask -> long\n\t" 4167 "andl $dst, right_n_bits($mask, 16)" %} 4168 ins_encode %{ 4169 Register Rdst = $dst$$Register; 4170 __ movzwq(Rdst, $mem$$Address); 4171 __ andl(Rdst, $mask$$constant & right_n_bits(16)); 4172 %} 4173 ins_pipe(ialu_reg_mem); 4174 %} 4175 4176 // Load Integer 4177 instruct loadI(rRegI dst, memory mem) 4178 %{ 4179 match(Set dst (LoadI mem)); 4180 4181 ins_cost(125); 4182 format %{ "movl $dst, $mem\t# int" %} 4183 4184 ins_encode %{ 4185 __ movl($dst$$Register, $mem$$Address); 4186 %} 4187 4188 ins_pipe(ialu_reg_mem); 4189 %} 4190 4191 // Load Integer (32 bit signed) to Byte (8 bit signed) 4192 instruct loadI2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4193 match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour)); 4194 4195 ins_cost(125); 4196 format %{ "movsbl $dst, $mem\t# int -> byte" %} 4197 ins_encode %{ 4198 __ movsbl($dst$$Register, $mem$$Address); 4199 %} 4200 ins_pipe(ialu_reg_mem); 4201 %} 4202 4203 // Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned) 4204 instruct loadI2UB(rRegI dst, memory mem, immI_255 mask) %{ 4205 match(Set dst (AndI (LoadI mem) mask)); 4206 4207 ins_cost(125); 4208 format %{ "movzbl $dst, $mem\t# int -> ubyte" %} 4209 ins_encode %{ 4210 __ movzbl($dst$$Register, $mem$$Address); 4211 %} 4212 ins_pipe(ialu_reg_mem); 4213 %} 4214 4215 // Load Integer (32 bit signed) to Short (16 bit signed) 4216 instruct loadI2S(rRegI dst, memory mem, immI_16 sixteen) %{ 4217 match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen)); 4218 4219 ins_cost(125); 4220 format %{ "movswl $dst, $mem\t# int -> short" %} 4221 ins_encode %{ 4222 __ movswl($dst$$Register, $mem$$Address); 4223 %} 4224 ins_pipe(ialu_reg_mem); 4225 %} 4226 4227 // Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned) 4228 instruct loadI2US(rRegI dst, memory mem, immI_65535 mask) %{ 4229 match(Set dst (AndI (LoadI mem) mask)); 4230 4231 ins_cost(125); 4232 format %{ "movzwl $dst, $mem\t# int -> ushort/char" %} 4233 ins_encode %{ 4234 __ movzwl($dst$$Register, $mem$$Address); 4235 %} 4236 ins_pipe(ialu_reg_mem); 4237 %} 4238 4239 // Load Integer into Long Register 4240 instruct loadI2L(rRegL dst, memory mem) 4241 %{ 4242 match(Set dst (ConvI2L (LoadI mem))); 4243 4244 ins_cost(125); 4245 format %{ "movslq $dst, $mem\t# int -> long" %} 4246 4247 ins_encode %{ 4248 __ movslq($dst$$Register, $mem$$Address); 4249 %} 4250 4251 ins_pipe(ialu_reg_mem); 4252 %} 4253 4254 // Load Integer with mask 0xFF into Long Register 4255 instruct loadI2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 4256 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4257 4258 format %{ "movzbq $dst, $mem\t# int & 0xFF -> long" %} 4259 ins_encode %{ 4260 __ movzbq($dst$$Register, $mem$$Address); 4261 %} 4262 ins_pipe(ialu_reg_mem); 4263 %} 4264 4265 // Load Integer with mask 0xFFFF into Long Register 4266 instruct loadI2L_immI_65535(rRegL dst, memory mem, immI_65535 mask) %{ 4267 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4268 4269 format %{ "movzwq $dst, $mem\t# int & 0xFFFF -> long" %} 4270 ins_encode %{ 4271 __ movzwq($dst$$Register, $mem$$Address); 4272 %} 4273 ins_pipe(ialu_reg_mem); 4274 %} 4275 4276 // Load Integer with a 31-bit mask into Long Register 4277 instruct loadI2L_immU31(rRegL dst, memory mem, immU31 mask, rFlagsReg cr) %{ 4278 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4279 effect(KILL cr); 4280 4281 format %{ "movl $dst, $mem\t# int & 31-bit mask -> long\n\t" 4282 "andl $dst, $mask" %} 4283 ins_encode %{ 4284 Register Rdst = $dst$$Register; 4285 __ movl(Rdst, $mem$$Address); 4286 __ andl(Rdst, $mask$$constant); 4287 %} 4288 ins_pipe(ialu_reg_mem); 4289 %} 4290 4291 // Load Unsigned Integer into Long Register 4292 instruct loadUI2L(rRegL dst, memory mem, immL_32bits mask) 4293 %{ 4294 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 4295 4296 ins_cost(125); 4297 format %{ "movl $dst, $mem\t# uint -> long" %} 4298 4299 ins_encode %{ 4300 __ movl($dst$$Register, $mem$$Address); 4301 %} 4302 4303 ins_pipe(ialu_reg_mem); 4304 %} 4305 4306 // Load Long 4307 instruct loadL(rRegL dst, memory mem) 4308 %{ 4309 match(Set dst (LoadL mem)); 4310 4311 ins_cost(125); 4312 format %{ "movq $dst, $mem\t# long" %} 4313 4314 ins_encode %{ 4315 __ movq($dst$$Register, $mem$$Address); 4316 %} 4317 4318 ins_pipe(ialu_reg_mem); // XXX 4319 %} 4320 4321 // Load Range 4322 instruct loadRange(rRegI dst, memory mem) 4323 %{ 4324 match(Set dst (LoadRange mem)); 4325 4326 ins_cost(125); // XXX 4327 format %{ "movl $dst, $mem\t# range" %} 4328 ins_encode %{ 4329 __ movl($dst$$Register, $mem$$Address); 4330 %} 4331 ins_pipe(ialu_reg_mem); 4332 %} 4333 4334 // Load Pointer 4335 instruct loadP(rRegP dst, memory mem) 4336 %{ 4337 match(Set dst (LoadP mem)); 4338 predicate(n->as_Load()->barrier_data() == 0); 4339 4340 ins_cost(125); // XXX 4341 format %{ "movq $dst, $mem\t# ptr" %} 4342 ins_encode %{ 4343 __ movq($dst$$Register, $mem$$Address); 4344 %} 4345 ins_pipe(ialu_reg_mem); // XXX 4346 %} 4347 4348 // Load Compressed Pointer 4349 instruct loadN(rRegN dst, memory mem) 4350 %{ 4351 predicate(n->as_Load()->barrier_data() == 0); 4352 match(Set dst (LoadN mem)); 4353 4354 ins_cost(125); // XXX 4355 format %{ "movl $dst, $mem\t# compressed ptr" %} 4356 ins_encode %{ 4357 __ movl($dst$$Register, $mem$$Address); 4358 %} 4359 ins_pipe(ialu_reg_mem); // XXX 4360 %} 4361 4362 4363 // Load Klass Pointer 4364 instruct loadKlass(rRegP dst, memory mem) 4365 %{ 4366 match(Set dst (LoadKlass mem)); 4367 4368 ins_cost(125); // XXX 4369 format %{ "movq $dst, $mem\t# class" %} 4370 ins_encode %{ 4371 __ movq($dst$$Register, $mem$$Address); 4372 %} 4373 ins_pipe(ialu_reg_mem); // XXX 4374 %} 4375 4376 // Load narrow Klass Pointer 4377 instruct loadNKlass(rRegN dst, memory mem) 4378 %{ 4379 match(Set dst (LoadNKlass mem)); 4380 4381 ins_cost(125); // XXX 4382 format %{ "movl $dst, $mem\t# compressed klass ptr" %} 4383 ins_encode %{ 4384 __ movl($dst$$Register, $mem$$Address); 4385 %} 4386 ins_pipe(ialu_reg_mem); // XXX 4387 %} 4388 4389 // Load Float 4390 instruct loadF(regF dst, memory mem) 4391 %{ 4392 match(Set dst (LoadF mem)); 4393 4394 ins_cost(145); // XXX 4395 format %{ "movss $dst, $mem\t# float" %} 4396 ins_encode %{ 4397 __ movflt($dst$$XMMRegister, $mem$$Address); 4398 %} 4399 ins_pipe(pipe_slow); // XXX 4400 %} 4401 4402 // Load Double 4403 instruct loadD_partial(regD dst, memory mem) 4404 %{ 4405 predicate(!UseXmmLoadAndClearUpper); 4406 match(Set dst (LoadD mem)); 4407 4408 ins_cost(145); // XXX 4409 format %{ "movlpd $dst, $mem\t# double" %} 4410 ins_encode %{ 4411 __ movdbl($dst$$XMMRegister, $mem$$Address); 4412 %} 4413 ins_pipe(pipe_slow); // XXX 4414 %} 4415 4416 instruct loadD(regD dst, memory mem) 4417 %{ 4418 predicate(UseXmmLoadAndClearUpper); 4419 match(Set dst (LoadD mem)); 4420 4421 ins_cost(145); // XXX 4422 format %{ "movsd $dst, $mem\t# double" %} 4423 ins_encode %{ 4424 __ movdbl($dst$$XMMRegister, $mem$$Address); 4425 %} 4426 ins_pipe(pipe_slow); // XXX 4427 %} 4428 4429 // max = java.lang.Math.max(float a, float b) 4430 instruct maxF_reg(legRegF dst, legRegF a, legRegF b, legRegF tmp, legRegF atmp, legRegF btmp) %{ 4431 predicate(UseAVX > 0 && !VLoopReductions::is_reduction(n)); 4432 match(Set dst (MaxF a b)); 4433 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 4434 format %{ "maxF $dst, $a, $b \t! using tmp, atmp and btmp as TEMP" %} 4435 ins_encode %{ 4436 __ vminmax_fp(Op_MaxV, T_FLOAT, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, Assembler::AVX_128bit); 4437 %} 4438 ins_pipe( pipe_slow ); 4439 %} 4440 4441 instruct maxF_reduction_reg(legRegF dst, legRegF a, legRegF b, legRegF xmmt, rRegI tmp, rFlagsReg cr) %{ 4442 predicate(UseAVX > 0 && VLoopReductions::is_reduction(n)); 4443 match(Set dst (MaxF a b)); 4444 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr); 4445 4446 format %{ "$dst = max($a, $b)\t# intrinsic (float)" %} 4447 ins_encode %{ 4448 emit_fp_min_max(masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register, 4449 false /*min*/, true /*single*/); 4450 %} 4451 ins_pipe( pipe_slow ); 4452 %} 4453 4454 // max = java.lang.Math.max(double a, double b) 4455 instruct maxD_reg(legRegD dst, legRegD a, legRegD b, legRegD tmp, legRegD atmp, legRegD btmp) %{ 4456 predicate(UseAVX > 0 && !VLoopReductions::is_reduction(n)); 4457 match(Set dst (MaxD a b)); 4458 effect(USE a, USE b, TEMP atmp, TEMP btmp, TEMP tmp); 4459 format %{ "maxD $dst, $a, $b \t! using tmp, atmp and btmp as TEMP" %} 4460 ins_encode %{ 4461 __ vminmax_fp(Op_MaxV, T_DOUBLE, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, Assembler::AVX_128bit); 4462 %} 4463 ins_pipe( pipe_slow ); 4464 %} 4465 4466 instruct maxD_reduction_reg(legRegD dst, legRegD a, legRegD b, legRegD xmmt, rRegL tmp, rFlagsReg cr) %{ 4467 predicate(UseAVX > 0 && VLoopReductions::is_reduction(n)); 4468 match(Set dst (MaxD a b)); 4469 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr); 4470 4471 format %{ "$dst = max($a, $b)\t# intrinsic (double)" %} 4472 ins_encode %{ 4473 emit_fp_min_max(masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register, 4474 false /*min*/, false /*single*/); 4475 %} 4476 ins_pipe( pipe_slow ); 4477 %} 4478 4479 // min = java.lang.Math.min(float a, float b) 4480 instruct minF_reg(legRegF dst, legRegF a, legRegF b, legRegF tmp, legRegF atmp, legRegF btmp) %{ 4481 predicate(UseAVX > 0 && !VLoopReductions::is_reduction(n)); 4482 match(Set dst (MinF a b)); 4483 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 4484 format %{ "minF $dst, $a, $b \t! using tmp, atmp and btmp as TEMP" %} 4485 ins_encode %{ 4486 __ vminmax_fp(Op_MinV, T_FLOAT, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, Assembler::AVX_128bit); 4487 %} 4488 ins_pipe( pipe_slow ); 4489 %} 4490 4491 instruct minF_reduction_reg(legRegF dst, legRegF a, legRegF b, legRegF xmmt, rRegI tmp, rFlagsReg cr) %{ 4492 predicate(UseAVX > 0 && VLoopReductions::is_reduction(n)); 4493 match(Set dst (MinF a b)); 4494 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr); 4495 4496 format %{ "$dst = min($a, $b)\t# intrinsic (float)" %} 4497 ins_encode %{ 4498 emit_fp_min_max(masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register, 4499 true /*min*/, true /*single*/); 4500 %} 4501 ins_pipe( pipe_slow ); 4502 %} 4503 4504 // min = java.lang.Math.min(double a, double b) 4505 instruct minD_reg(legRegD dst, legRegD a, legRegD b, legRegD tmp, legRegD atmp, legRegD btmp) %{ 4506 predicate(UseAVX > 0 && !VLoopReductions::is_reduction(n)); 4507 match(Set dst (MinD a b)); 4508 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 4509 format %{ "minD $dst, $a, $b \t! using tmp, atmp and btmp as TEMP" %} 4510 ins_encode %{ 4511 __ vminmax_fp(Op_MinV, T_DOUBLE, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, Assembler::AVX_128bit); 4512 %} 4513 ins_pipe( pipe_slow ); 4514 %} 4515 4516 instruct minD_reduction_reg(legRegD dst, legRegD a, legRegD b, legRegD xmmt, rRegL tmp, rFlagsReg cr) %{ 4517 predicate(UseAVX > 0 && VLoopReductions::is_reduction(n)); 4518 match(Set dst (MinD a b)); 4519 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr); 4520 4521 format %{ "$dst = min($a, $b)\t# intrinsic (double)" %} 4522 ins_encode %{ 4523 emit_fp_min_max(masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register, 4524 true /*min*/, false /*single*/); 4525 %} 4526 ins_pipe( pipe_slow ); 4527 %} 4528 4529 // Load Effective Address 4530 instruct leaP8(rRegP dst, indOffset8 mem) 4531 %{ 4532 match(Set dst mem); 4533 4534 ins_cost(110); // XXX 4535 format %{ "leaq $dst, $mem\t# ptr 8" %} 4536 ins_encode %{ 4537 __ leaq($dst$$Register, $mem$$Address); 4538 %} 4539 ins_pipe(ialu_reg_reg_fat); 4540 %} 4541 4542 instruct leaP32(rRegP dst, indOffset32 mem) 4543 %{ 4544 match(Set dst mem); 4545 4546 ins_cost(110); 4547 format %{ "leaq $dst, $mem\t# ptr 32" %} 4548 ins_encode %{ 4549 __ leaq($dst$$Register, $mem$$Address); 4550 %} 4551 ins_pipe(ialu_reg_reg_fat); 4552 %} 4553 4554 instruct leaPIdxOff(rRegP dst, indIndexOffset mem) 4555 %{ 4556 match(Set dst mem); 4557 4558 ins_cost(110); 4559 format %{ "leaq $dst, $mem\t# ptr idxoff" %} 4560 ins_encode %{ 4561 __ leaq($dst$$Register, $mem$$Address); 4562 %} 4563 ins_pipe(ialu_reg_reg_fat); 4564 %} 4565 4566 instruct leaPIdxScale(rRegP dst, indIndexScale mem) 4567 %{ 4568 match(Set dst mem); 4569 4570 ins_cost(110); 4571 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 4572 ins_encode %{ 4573 __ leaq($dst$$Register, $mem$$Address); 4574 %} 4575 ins_pipe(ialu_reg_reg_fat); 4576 %} 4577 4578 instruct leaPPosIdxScale(rRegP dst, indPosIndexScale mem) 4579 %{ 4580 match(Set dst mem); 4581 4582 ins_cost(110); 4583 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 4584 ins_encode %{ 4585 __ leaq($dst$$Register, $mem$$Address); 4586 %} 4587 ins_pipe(ialu_reg_reg_fat); 4588 %} 4589 4590 instruct leaPIdxScaleOff(rRegP dst, indIndexScaleOffset mem) 4591 %{ 4592 match(Set dst mem); 4593 4594 ins_cost(110); 4595 format %{ "leaq $dst, $mem\t# ptr idxscaleoff" %} 4596 ins_encode %{ 4597 __ leaq($dst$$Register, $mem$$Address); 4598 %} 4599 ins_pipe(ialu_reg_reg_fat); 4600 %} 4601 4602 instruct leaPPosIdxOff(rRegP dst, indPosIndexOffset mem) 4603 %{ 4604 match(Set dst mem); 4605 4606 ins_cost(110); 4607 format %{ "leaq $dst, $mem\t# ptr posidxoff" %} 4608 ins_encode %{ 4609 __ leaq($dst$$Register, $mem$$Address); 4610 %} 4611 ins_pipe(ialu_reg_reg_fat); 4612 %} 4613 4614 instruct leaPPosIdxScaleOff(rRegP dst, indPosIndexScaleOffset mem) 4615 %{ 4616 match(Set dst mem); 4617 4618 ins_cost(110); 4619 format %{ "leaq $dst, $mem\t# ptr posidxscaleoff" %} 4620 ins_encode %{ 4621 __ leaq($dst$$Register, $mem$$Address); 4622 %} 4623 ins_pipe(ialu_reg_reg_fat); 4624 %} 4625 4626 // Load Effective Address which uses Narrow (32-bits) oop 4627 instruct leaPCompressedOopOffset(rRegP dst, indCompressedOopOffset mem) 4628 %{ 4629 predicate(UseCompressedOops && (CompressedOops::shift() != 0)); 4630 match(Set dst mem); 4631 4632 ins_cost(110); 4633 format %{ "leaq $dst, $mem\t# ptr compressedoopoff32" %} 4634 ins_encode %{ 4635 __ leaq($dst$$Register, $mem$$Address); 4636 %} 4637 ins_pipe(ialu_reg_reg_fat); 4638 %} 4639 4640 instruct leaP8Narrow(rRegP dst, indOffset8Narrow mem) 4641 %{ 4642 predicate(CompressedOops::shift() == 0); 4643 match(Set dst mem); 4644 4645 ins_cost(110); // XXX 4646 format %{ "leaq $dst, $mem\t# ptr off8narrow" %} 4647 ins_encode %{ 4648 __ leaq($dst$$Register, $mem$$Address); 4649 %} 4650 ins_pipe(ialu_reg_reg_fat); 4651 %} 4652 4653 instruct leaP32Narrow(rRegP dst, indOffset32Narrow mem) 4654 %{ 4655 predicate(CompressedOops::shift() == 0); 4656 match(Set dst mem); 4657 4658 ins_cost(110); 4659 format %{ "leaq $dst, $mem\t# ptr off32narrow" %} 4660 ins_encode %{ 4661 __ leaq($dst$$Register, $mem$$Address); 4662 %} 4663 ins_pipe(ialu_reg_reg_fat); 4664 %} 4665 4666 instruct leaPIdxOffNarrow(rRegP dst, indIndexOffsetNarrow mem) 4667 %{ 4668 predicate(CompressedOops::shift() == 0); 4669 match(Set dst mem); 4670 4671 ins_cost(110); 4672 format %{ "leaq $dst, $mem\t# ptr idxoffnarrow" %} 4673 ins_encode %{ 4674 __ leaq($dst$$Register, $mem$$Address); 4675 %} 4676 ins_pipe(ialu_reg_reg_fat); 4677 %} 4678 4679 instruct leaPIdxScaleNarrow(rRegP dst, indIndexScaleNarrow mem) 4680 %{ 4681 predicate(CompressedOops::shift() == 0); 4682 match(Set dst mem); 4683 4684 ins_cost(110); 4685 format %{ "leaq $dst, $mem\t# ptr idxscalenarrow" %} 4686 ins_encode %{ 4687 __ leaq($dst$$Register, $mem$$Address); 4688 %} 4689 ins_pipe(ialu_reg_reg_fat); 4690 %} 4691 4692 instruct leaPIdxScaleOffNarrow(rRegP dst, indIndexScaleOffsetNarrow mem) 4693 %{ 4694 predicate(CompressedOops::shift() == 0); 4695 match(Set dst mem); 4696 4697 ins_cost(110); 4698 format %{ "leaq $dst, $mem\t# ptr idxscaleoffnarrow" %} 4699 ins_encode %{ 4700 __ leaq($dst$$Register, $mem$$Address); 4701 %} 4702 ins_pipe(ialu_reg_reg_fat); 4703 %} 4704 4705 instruct leaPPosIdxOffNarrow(rRegP dst, indPosIndexOffsetNarrow mem) 4706 %{ 4707 predicate(CompressedOops::shift() == 0); 4708 match(Set dst mem); 4709 4710 ins_cost(110); 4711 format %{ "leaq $dst, $mem\t# ptr posidxoffnarrow" %} 4712 ins_encode %{ 4713 __ leaq($dst$$Register, $mem$$Address); 4714 %} 4715 ins_pipe(ialu_reg_reg_fat); 4716 %} 4717 4718 instruct leaPPosIdxScaleOffNarrow(rRegP dst, indPosIndexScaleOffsetNarrow mem) 4719 %{ 4720 predicate(CompressedOops::shift() == 0); 4721 match(Set dst mem); 4722 4723 ins_cost(110); 4724 format %{ "leaq $dst, $mem\t# ptr posidxscaleoffnarrow" %} 4725 ins_encode %{ 4726 __ leaq($dst$$Register, $mem$$Address); 4727 %} 4728 ins_pipe(ialu_reg_reg_fat); 4729 %} 4730 4731 instruct loadConI(rRegI dst, immI src) 4732 %{ 4733 match(Set dst src); 4734 4735 format %{ "movl $dst, $src\t# int" %} 4736 ins_encode %{ 4737 __ movl($dst$$Register, $src$$constant); 4738 %} 4739 ins_pipe(ialu_reg_fat); // XXX 4740 %} 4741 4742 instruct loadConI0(rRegI dst, immI_0 src, rFlagsReg cr) 4743 %{ 4744 match(Set dst src); 4745 effect(KILL cr); 4746 4747 ins_cost(50); 4748 format %{ "xorl $dst, $dst\t# int" %} 4749 ins_encode %{ 4750 __ xorl($dst$$Register, $dst$$Register); 4751 %} 4752 ins_pipe(ialu_reg); 4753 %} 4754 4755 instruct loadConL(rRegL dst, immL src) 4756 %{ 4757 match(Set dst src); 4758 4759 ins_cost(150); 4760 format %{ "movq $dst, $src\t# long" %} 4761 ins_encode %{ 4762 __ mov64($dst$$Register, $src$$constant); 4763 %} 4764 ins_pipe(ialu_reg); 4765 %} 4766 4767 instruct loadConL0(rRegL dst, immL0 src, rFlagsReg cr) 4768 %{ 4769 match(Set dst src); 4770 effect(KILL cr); 4771 4772 ins_cost(50); 4773 format %{ "xorl $dst, $dst\t# long" %} 4774 ins_encode %{ 4775 __ xorl($dst$$Register, $dst$$Register); 4776 %} 4777 ins_pipe(ialu_reg); // XXX 4778 %} 4779 4780 instruct loadConUL32(rRegL dst, immUL32 src) 4781 %{ 4782 match(Set dst src); 4783 4784 ins_cost(60); 4785 format %{ "movl $dst, $src\t# long (unsigned 32-bit)" %} 4786 ins_encode %{ 4787 __ movl($dst$$Register, $src$$constant); 4788 %} 4789 ins_pipe(ialu_reg); 4790 %} 4791 4792 instruct loadConL32(rRegL dst, immL32 src) 4793 %{ 4794 match(Set dst src); 4795 4796 ins_cost(70); 4797 format %{ "movq $dst, $src\t# long (32-bit)" %} 4798 ins_encode %{ 4799 __ movq($dst$$Register, $src$$constant); 4800 %} 4801 ins_pipe(ialu_reg); 4802 %} 4803 4804 instruct loadConP(rRegP dst, immP con) %{ 4805 match(Set dst con); 4806 4807 format %{ "movq $dst, $con\t# ptr" %} 4808 ins_encode %{ 4809 __ mov64($dst$$Register, $con$$constant, $con->constant_reloc(), RELOC_IMM64); 4810 %} 4811 ins_pipe(ialu_reg_fat); // XXX 4812 %} 4813 4814 instruct loadConP0(rRegP dst, immP0 src, rFlagsReg cr) 4815 %{ 4816 match(Set dst src); 4817 effect(KILL cr); 4818 4819 ins_cost(50); 4820 format %{ "xorl $dst, $dst\t# ptr" %} 4821 ins_encode %{ 4822 __ xorl($dst$$Register, $dst$$Register); 4823 %} 4824 ins_pipe(ialu_reg); 4825 %} 4826 4827 instruct loadConP31(rRegP dst, immP31 src, rFlagsReg cr) 4828 %{ 4829 match(Set dst src); 4830 effect(KILL cr); 4831 4832 ins_cost(60); 4833 format %{ "movl $dst, $src\t# ptr (positive 32-bit)" %} 4834 ins_encode %{ 4835 __ movl($dst$$Register, $src$$constant); 4836 %} 4837 ins_pipe(ialu_reg); 4838 %} 4839 4840 instruct loadConF(regF dst, immF con) %{ 4841 match(Set dst con); 4842 ins_cost(125); 4843 format %{ "movss $dst, [$constantaddress]\t# load from constant table: float=$con" %} 4844 ins_encode %{ 4845 __ movflt($dst$$XMMRegister, $constantaddress($con)); 4846 %} 4847 ins_pipe(pipe_slow); 4848 %} 4849 4850 instruct loadConN0(rRegN dst, immN0 src, rFlagsReg cr) %{ 4851 match(Set dst src); 4852 effect(KILL cr); 4853 format %{ "xorq $dst, $src\t# compressed null pointer" %} 4854 ins_encode %{ 4855 __ xorq($dst$$Register, $dst$$Register); 4856 %} 4857 ins_pipe(ialu_reg); 4858 %} 4859 4860 instruct loadConN(rRegN dst, immN src) %{ 4861 match(Set dst src); 4862 4863 ins_cost(125); 4864 format %{ "movl $dst, $src\t# compressed ptr" %} 4865 ins_encode %{ 4866 address con = (address)$src$$constant; 4867 if (con == nullptr) { 4868 ShouldNotReachHere(); 4869 } else { 4870 __ set_narrow_oop($dst$$Register, (jobject)$src$$constant); 4871 } 4872 %} 4873 ins_pipe(ialu_reg_fat); // XXX 4874 %} 4875 4876 instruct loadConNKlass(rRegN dst, immNKlass src) %{ 4877 match(Set dst src); 4878 4879 ins_cost(125); 4880 format %{ "movl $dst, $src\t# compressed klass ptr" %} 4881 ins_encode %{ 4882 address con = (address)$src$$constant; 4883 if (con == nullptr) { 4884 ShouldNotReachHere(); 4885 } else { 4886 __ set_narrow_klass($dst$$Register, (Klass*)$src$$constant); 4887 } 4888 %} 4889 ins_pipe(ialu_reg_fat); // XXX 4890 %} 4891 4892 instruct loadConF0(regF dst, immF0 src) 4893 %{ 4894 match(Set dst src); 4895 ins_cost(100); 4896 4897 format %{ "xorps $dst, $dst\t# float 0.0" %} 4898 ins_encode %{ 4899 __ xorps($dst$$XMMRegister, $dst$$XMMRegister); 4900 %} 4901 ins_pipe(pipe_slow); 4902 %} 4903 4904 // Use the same format since predicate() can not be used here. 4905 instruct loadConD(regD dst, immD con) %{ 4906 match(Set dst con); 4907 ins_cost(125); 4908 format %{ "movsd $dst, [$constantaddress]\t# load from constant table: double=$con" %} 4909 ins_encode %{ 4910 __ movdbl($dst$$XMMRegister, $constantaddress($con)); 4911 %} 4912 ins_pipe(pipe_slow); 4913 %} 4914 4915 instruct loadConD0(regD dst, immD0 src) 4916 %{ 4917 match(Set dst src); 4918 ins_cost(100); 4919 4920 format %{ "xorpd $dst, $dst\t# double 0.0" %} 4921 ins_encode %{ 4922 __ xorpd($dst$$XMMRegister, $dst$$XMMRegister); 4923 %} 4924 ins_pipe(pipe_slow); 4925 %} 4926 4927 instruct loadSSI(rRegI dst, stackSlotI src) 4928 %{ 4929 match(Set dst src); 4930 4931 ins_cost(125); 4932 format %{ "movl $dst, $src\t# int stk" %} 4933 ins_encode %{ 4934 __ movl($dst$$Register, $src$$Address); 4935 %} 4936 ins_pipe(ialu_reg_mem); 4937 %} 4938 4939 instruct loadSSL(rRegL dst, stackSlotL src) 4940 %{ 4941 match(Set dst src); 4942 4943 ins_cost(125); 4944 format %{ "movq $dst, $src\t# long stk" %} 4945 ins_encode %{ 4946 __ movq($dst$$Register, $src$$Address); 4947 %} 4948 ins_pipe(ialu_reg_mem); 4949 %} 4950 4951 instruct loadSSP(rRegP dst, stackSlotP src) 4952 %{ 4953 match(Set dst src); 4954 4955 ins_cost(125); 4956 format %{ "movq $dst, $src\t# ptr stk" %} 4957 ins_encode %{ 4958 __ movq($dst$$Register, $src$$Address); 4959 %} 4960 ins_pipe(ialu_reg_mem); 4961 %} 4962 4963 instruct loadSSF(regF dst, stackSlotF src) 4964 %{ 4965 match(Set dst src); 4966 4967 ins_cost(125); 4968 format %{ "movss $dst, $src\t# float stk" %} 4969 ins_encode %{ 4970 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 4971 %} 4972 ins_pipe(pipe_slow); // XXX 4973 %} 4974 4975 // Use the same format since predicate() can not be used here. 4976 instruct loadSSD(regD dst, stackSlotD src) 4977 %{ 4978 match(Set dst src); 4979 4980 ins_cost(125); 4981 format %{ "movsd $dst, $src\t# double stk" %} 4982 ins_encode %{ 4983 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 4984 %} 4985 ins_pipe(pipe_slow); // XXX 4986 %} 4987 4988 // Prefetch instructions for allocation. 4989 // Must be safe to execute with invalid address (cannot fault). 4990 4991 instruct prefetchAlloc( memory mem ) %{ 4992 predicate(AllocatePrefetchInstr==3); 4993 match(PrefetchAllocation mem); 4994 ins_cost(125); 4995 4996 format %{ "PREFETCHW $mem\t# Prefetch allocation into level 1 cache and mark modified" %} 4997 ins_encode %{ 4998 __ prefetchw($mem$$Address); 4999 %} 5000 ins_pipe(ialu_mem); 5001 %} 5002 5003 instruct prefetchAllocNTA( memory mem ) %{ 5004 predicate(AllocatePrefetchInstr==0); 5005 match(PrefetchAllocation mem); 5006 ins_cost(125); 5007 5008 format %{ "PREFETCHNTA $mem\t# Prefetch allocation to non-temporal cache for write" %} 5009 ins_encode %{ 5010 __ prefetchnta($mem$$Address); 5011 %} 5012 ins_pipe(ialu_mem); 5013 %} 5014 5015 instruct prefetchAllocT0( memory mem ) %{ 5016 predicate(AllocatePrefetchInstr==1); 5017 match(PrefetchAllocation mem); 5018 ins_cost(125); 5019 5020 format %{ "PREFETCHT0 $mem\t# Prefetch allocation to level 1 and 2 caches for write" %} 5021 ins_encode %{ 5022 __ prefetcht0($mem$$Address); 5023 %} 5024 ins_pipe(ialu_mem); 5025 %} 5026 5027 instruct prefetchAllocT2( memory mem ) %{ 5028 predicate(AllocatePrefetchInstr==2); 5029 match(PrefetchAllocation mem); 5030 ins_cost(125); 5031 5032 format %{ "PREFETCHT2 $mem\t# Prefetch allocation to level 2 cache for write" %} 5033 ins_encode %{ 5034 __ prefetcht2($mem$$Address); 5035 %} 5036 ins_pipe(ialu_mem); 5037 %} 5038 5039 //----------Store Instructions------------------------------------------------- 5040 5041 // Store Byte 5042 instruct storeB(memory mem, rRegI src) 5043 %{ 5044 match(Set mem (StoreB mem src)); 5045 5046 ins_cost(125); // XXX 5047 format %{ "movb $mem, $src\t# byte" %} 5048 ins_encode %{ 5049 __ movb($mem$$Address, $src$$Register); 5050 %} 5051 ins_pipe(ialu_mem_reg); 5052 %} 5053 5054 // Store Char/Short 5055 instruct storeC(memory mem, rRegI src) 5056 %{ 5057 match(Set mem (StoreC mem src)); 5058 5059 ins_cost(125); // XXX 5060 format %{ "movw $mem, $src\t# char/short" %} 5061 ins_encode %{ 5062 __ movw($mem$$Address, $src$$Register); 5063 %} 5064 ins_pipe(ialu_mem_reg); 5065 %} 5066 5067 // Store Integer 5068 instruct storeI(memory mem, rRegI src) 5069 %{ 5070 match(Set mem (StoreI mem src)); 5071 5072 ins_cost(125); // XXX 5073 format %{ "movl $mem, $src\t# int" %} 5074 ins_encode %{ 5075 __ movl($mem$$Address, $src$$Register); 5076 %} 5077 ins_pipe(ialu_mem_reg); 5078 %} 5079 5080 // Store Long 5081 instruct storeL(memory mem, rRegL src) 5082 %{ 5083 match(Set mem (StoreL mem src)); 5084 5085 ins_cost(125); // XXX 5086 format %{ "movq $mem, $src\t# long" %} 5087 ins_encode %{ 5088 __ movq($mem$$Address, $src$$Register); 5089 %} 5090 ins_pipe(ialu_mem_reg); // XXX 5091 %} 5092 5093 // Store Pointer 5094 instruct storeP(memory mem, any_RegP src) 5095 %{ 5096 predicate(n->as_Store()->barrier_data() == 0); 5097 match(Set mem (StoreP mem src)); 5098 5099 ins_cost(125); // XXX 5100 format %{ "movq $mem, $src\t# ptr" %} 5101 ins_encode %{ 5102 __ movq($mem$$Address, $src$$Register); 5103 %} 5104 ins_pipe(ialu_mem_reg); 5105 %} 5106 5107 instruct storeImmP0(memory mem, immP0 zero) 5108 %{ 5109 predicate(UseCompressedOops && (CompressedOops::base() == nullptr) && n->as_Store()->barrier_data() == 0); 5110 match(Set mem (StoreP mem zero)); 5111 5112 ins_cost(125); // XXX 5113 format %{ "movq $mem, R12\t# ptr (R12_heapbase==0)" %} 5114 ins_encode %{ 5115 __ movq($mem$$Address, r12); 5116 %} 5117 ins_pipe(ialu_mem_reg); 5118 %} 5119 5120 // Store Null Pointer, mark word, or other simple pointer constant. 5121 instruct storeImmP(memory mem, immP31 src) 5122 %{ 5123 predicate(n->as_Store()->barrier_data() == 0); 5124 match(Set mem (StoreP mem src)); 5125 5126 ins_cost(150); // XXX 5127 format %{ "movq $mem, $src\t# ptr" %} 5128 ins_encode %{ 5129 __ movq($mem$$Address, $src$$constant); 5130 %} 5131 ins_pipe(ialu_mem_imm); 5132 %} 5133 5134 // Store Compressed Pointer 5135 instruct storeN(memory mem, rRegN src) 5136 %{ 5137 predicate(n->as_Store()->barrier_data() == 0); 5138 match(Set mem (StoreN mem src)); 5139 5140 ins_cost(125); // XXX 5141 format %{ "movl $mem, $src\t# compressed ptr" %} 5142 ins_encode %{ 5143 __ movl($mem$$Address, $src$$Register); 5144 %} 5145 ins_pipe(ialu_mem_reg); 5146 %} 5147 5148 instruct storeNKlass(memory mem, rRegN src) 5149 %{ 5150 match(Set mem (StoreNKlass mem src)); 5151 5152 ins_cost(125); // XXX 5153 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5154 ins_encode %{ 5155 __ movl($mem$$Address, $src$$Register); 5156 %} 5157 ins_pipe(ialu_mem_reg); 5158 %} 5159 5160 instruct storeImmN0(memory mem, immN0 zero) 5161 %{ 5162 predicate(CompressedOops::base() == nullptr && n->as_Store()->barrier_data() == 0); 5163 match(Set mem (StoreN mem zero)); 5164 5165 ins_cost(125); // XXX 5166 format %{ "movl $mem, R12\t# compressed ptr (R12_heapbase==0)" %} 5167 ins_encode %{ 5168 __ movl($mem$$Address, r12); 5169 %} 5170 ins_pipe(ialu_mem_reg); 5171 %} 5172 5173 instruct storeImmN(memory mem, immN src) 5174 %{ 5175 predicate(n->as_Store()->barrier_data() == 0); 5176 match(Set mem (StoreN mem src)); 5177 5178 ins_cost(150); // XXX 5179 format %{ "movl $mem, $src\t# compressed ptr" %} 5180 ins_encode %{ 5181 address con = (address)$src$$constant; 5182 if (con == nullptr) { 5183 __ movl($mem$$Address, 0); 5184 } else { 5185 __ set_narrow_oop($mem$$Address, (jobject)$src$$constant); 5186 } 5187 %} 5188 ins_pipe(ialu_mem_imm); 5189 %} 5190 5191 instruct storeImmNKlass(memory mem, immNKlass src) 5192 %{ 5193 match(Set mem (StoreNKlass mem src)); 5194 5195 ins_cost(150); // XXX 5196 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5197 ins_encode %{ 5198 __ set_narrow_klass($mem$$Address, (Klass*)$src$$constant); 5199 %} 5200 ins_pipe(ialu_mem_imm); 5201 %} 5202 5203 // Store Integer Immediate 5204 instruct storeImmI0(memory mem, immI_0 zero) 5205 %{ 5206 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5207 match(Set mem (StoreI mem zero)); 5208 5209 ins_cost(125); // XXX 5210 format %{ "movl $mem, R12\t# int (R12_heapbase==0)" %} 5211 ins_encode %{ 5212 __ movl($mem$$Address, r12); 5213 %} 5214 ins_pipe(ialu_mem_reg); 5215 %} 5216 5217 instruct storeImmI(memory mem, immI src) 5218 %{ 5219 match(Set mem (StoreI mem src)); 5220 5221 ins_cost(150); 5222 format %{ "movl $mem, $src\t# int" %} 5223 ins_encode %{ 5224 __ movl($mem$$Address, $src$$constant); 5225 %} 5226 ins_pipe(ialu_mem_imm); 5227 %} 5228 5229 // Store Long Immediate 5230 instruct storeImmL0(memory mem, immL0 zero) 5231 %{ 5232 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5233 match(Set mem (StoreL mem zero)); 5234 5235 ins_cost(125); // XXX 5236 format %{ "movq $mem, R12\t# long (R12_heapbase==0)" %} 5237 ins_encode %{ 5238 __ movq($mem$$Address, r12); 5239 %} 5240 ins_pipe(ialu_mem_reg); 5241 %} 5242 5243 instruct storeImmL(memory mem, immL32 src) 5244 %{ 5245 match(Set mem (StoreL mem src)); 5246 5247 ins_cost(150); 5248 format %{ "movq $mem, $src\t# long" %} 5249 ins_encode %{ 5250 __ movq($mem$$Address, $src$$constant); 5251 %} 5252 ins_pipe(ialu_mem_imm); 5253 %} 5254 5255 // Store Short/Char Immediate 5256 instruct storeImmC0(memory mem, immI_0 zero) 5257 %{ 5258 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5259 match(Set mem (StoreC mem zero)); 5260 5261 ins_cost(125); // XXX 5262 format %{ "movw $mem, R12\t# short/char (R12_heapbase==0)" %} 5263 ins_encode %{ 5264 __ movw($mem$$Address, r12); 5265 %} 5266 ins_pipe(ialu_mem_reg); 5267 %} 5268 5269 instruct storeImmI16(memory mem, immI16 src) 5270 %{ 5271 predicate(UseStoreImmI16); 5272 match(Set mem (StoreC mem src)); 5273 5274 ins_cost(150); 5275 format %{ "movw $mem, $src\t# short/char" %} 5276 ins_encode %{ 5277 __ movw($mem$$Address, $src$$constant); 5278 %} 5279 ins_pipe(ialu_mem_imm); 5280 %} 5281 5282 // Store Byte Immediate 5283 instruct storeImmB0(memory mem, immI_0 zero) 5284 %{ 5285 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5286 match(Set mem (StoreB mem zero)); 5287 5288 ins_cost(125); // XXX 5289 format %{ "movb $mem, R12\t# short/char (R12_heapbase==0)" %} 5290 ins_encode %{ 5291 __ movb($mem$$Address, r12); 5292 %} 5293 ins_pipe(ialu_mem_reg); 5294 %} 5295 5296 instruct storeImmB(memory mem, immI8 src) 5297 %{ 5298 match(Set mem (StoreB mem src)); 5299 5300 ins_cost(150); // XXX 5301 format %{ "movb $mem, $src\t# byte" %} 5302 ins_encode %{ 5303 __ movb($mem$$Address, $src$$constant); 5304 %} 5305 ins_pipe(ialu_mem_imm); 5306 %} 5307 5308 // Store Float 5309 instruct storeF(memory mem, regF src) 5310 %{ 5311 match(Set mem (StoreF mem src)); 5312 5313 ins_cost(95); // XXX 5314 format %{ "movss $mem, $src\t# float" %} 5315 ins_encode %{ 5316 __ movflt($mem$$Address, $src$$XMMRegister); 5317 %} 5318 ins_pipe(pipe_slow); // XXX 5319 %} 5320 5321 // Store immediate Float value (it is faster than store from XMM register) 5322 instruct storeF0(memory mem, immF0 zero) 5323 %{ 5324 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5325 match(Set mem (StoreF mem zero)); 5326 5327 ins_cost(25); // XXX 5328 format %{ "movl $mem, R12\t# float 0. (R12_heapbase==0)" %} 5329 ins_encode %{ 5330 __ movl($mem$$Address, r12); 5331 %} 5332 ins_pipe(ialu_mem_reg); 5333 %} 5334 5335 instruct storeF_imm(memory mem, immF src) 5336 %{ 5337 match(Set mem (StoreF mem src)); 5338 5339 ins_cost(50); 5340 format %{ "movl $mem, $src\t# float" %} 5341 ins_encode %{ 5342 __ movl($mem$$Address, jint_cast($src$$constant)); 5343 %} 5344 ins_pipe(ialu_mem_imm); 5345 %} 5346 5347 // Store Double 5348 instruct storeD(memory mem, regD src) 5349 %{ 5350 match(Set mem (StoreD mem src)); 5351 5352 ins_cost(95); // XXX 5353 format %{ "movsd $mem, $src\t# double" %} 5354 ins_encode %{ 5355 __ movdbl($mem$$Address, $src$$XMMRegister); 5356 %} 5357 ins_pipe(pipe_slow); // XXX 5358 %} 5359 5360 // Store immediate double 0.0 (it is faster than store from XMM register) 5361 instruct storeD0_imm(memory mem, immD0 src) 5362 %{ 5363 predicate(!UseCompressedOops || (CompressedOops::base() != nullptr)); 5364 match(Set mem (StoreD mem src)); 5365 5366 ins_cost(50); 5367 format %{ "movq $mem, $src\t# double 0." %} 5368 ins_encode %{ 5369 __ movq($mem$$Address, $src$$constant); 5370 %} 5371 ins_pipe(ialu_mem_imm); 5372 %} 5373 5374 instruct storeD0(memory mem, immD0 zero) 5375 %{ 5376 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5377 match(Set mem (StoreD mem zero)); 5378 5379 ins_cost(25); // XXX 5380 format %{ "movq $mem, R12\t# double 0. (R12_heapbase==0)" %} 5381 ins_encode %{ 5382 __ movq($mem$$Address, r12); 5383 %} 5384 ins_pipe(ialu_mem_reg); 5385 %} 5386 5387 instruct storeSSI(stackSlotI dst, rRegI src) 5388 %{ 5389 match(Set dst src); 5390 5391 ins_cost(100); 5392 format %{ "movl $dst, $src\t# int stk" %} 5393 ins_encode %{ 5394 __ movl($dst$$Address, $src$$Register); 5395 %} 5396 ins_pipe( ialu_mem_reg ); 5397 %} 5398 5399 instruct storeSSL(stackSlotL dst, rRegL src) 5400 %{ 5401 match(Set dst src); 5402 5403 ins_cost(100); 5404 format %{ "movq $dst, $src\t# long stk" %} 5405 ins_encode %{ 5406 __ movq($dst$$Address, $src$$Register); 5407 %} 5408 ins_pipe(ialu_mem_reg); 5409 %} 5410 5411 instruct storeSSP(stackSlotP dst, rRegP src) 5412 %{ 5413 match(Set dst src); 5414 5415 ins_cost(100); 5416 format %{ "movq $dst, $src\t# ptr stk" %} 5417 ins_encode %{ 5418 __ movq($dst$$Address, $src$$Register); 5419 %} 5420 ins_pipe(ialu_mem_reg); 5421 %} 5422 5423 instruct storeSSF(stackSlotF dst, regF src) 5424 %{ 5425 match(Set dst src); 5426 5427 ins_cost(95); // XXX 5428 format %{ "movss $dst, $src\t# float stk" %} 5429 ins_encode %{ 5430 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 5431 %} 5432 ins_pipe(pipe_slow); // XXX 5433 %} 5434 5435 instruct storeSSD(stackSlotD dst, regD src) 5436 %{ 5437 match(Set dst src); 5438 5439 ins_cost(95); // XXX 5440 format %{ "movsd $dst, $src\t# double stk" %} 5441 ins_encode %{ 5442 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 5443 %} 5444 ins_pipe(pipe_slow); // XXX 5445 %} 5446 5447 instruct cacheWB(indirect addr) 5448 %{ 5449 predicate(VM_Version::supports_data_cache_line_flush()); 5450 match(CacheWB addr); 5451 5452 ins_cost(100); 5453 format %{"cache wb $addr" %} 5454 ins_encode %{ 5455 assert($addr->index_position() < 0, "should be"); 5456 assert($addr$$disp == 0, "should be"); 5457 __ cache_wb(Address($addr$$base$$Register, 0)); 5458 %} 5459 ins_pipe(pipe_slow); // XXX 5460 %} 5461 5462 instruct cacheWBPreSync() 5463 %{ 5464 predicate(VM_Version::supports_data_cache_line_flush()); 5465 match(CacheWBPreSync); 5466 5467 ins_cost(100); 5468 format %{"cache wb presync" %} 5469 ins_encode %{ 5470 __ cache_wbsync(true); 5471 %} 5472 ins_pipe(pipe_slow); // XXX 5473 %} 5474 5475 instruct cacheWBPostSync() 5476 %{ 5477 predicate(VM_Version::supports_data_cache_line_flush()); 5478 match(CacheWBPostSync); 5479 5480 ins_cost(100); 5481 format %{"cache wb postsync" %} 5482 ins_encode %{ 5483 __ cache_wbsync(false); 5484 %} 5485 ins_pipe(pipe_slow); // XXX 5486 %} 5487 5488 //----------BSWAP Instructions------------------------------------------------- 5489 instruct bytes_reverse_int(rRegI dst) %{ 5490 match(Set dst (ReverseBytesI dst)); 5491 5492 format %{ "bswapl $dst" %} 5493 ins_encode %{ 5494 __ bswapl($dst$$Register); 5495 %} 5496 ins_pipe( ialu_reg ); 5497 %} 5498 5499 instruct bytes_reverse_long(rRegL dst) %{ 5500 match(Set dst (ReverseBytesL dst)); 5501 5502 format %{ "bswapq $dst" %} 5503 ins_encode %{ 5504 __ bswapq($dst$$Register); 5505 %} 5506 ins_pipe( ialu_reg); 5507 %} 5508 5509 instruct bytes_reverse_unsigned_short(rRegI dst, rFlagsReg cr) %{ 5510 match(Set dst (ReverseBytesUS dst)); 5511 effect(KILL cr); 5512 5513 format %{ "bswapl $dst\n\t" 5514 "shrl $dst,16\n\t" %} 5515 ins_encode %{ 5516 __ bswapl($dst$$Register); 5517 __ shrl($dst$$Register, 16); 5518 %} 5519 ins_pipe( ialu_reg ); 5520 %} 5521 5522 instruct bytes_reverse_short(rRegI dst, rFlagsReg cr) %{ 5523 match(Set dst (ReverseBytesS dst)); 5524 effect(KILL cr); 5525 5526 format %{ "bswapl $dst\n\t" 5527 "sar $dst,16\n\t" %} 5528 ins_encode %{ 5529 __ bswapl($dst$$Register); 5530 __ sarl($dst$$Register, 16); 5531 %} 5532 ins_pipe( ialu_reg ); 5533 %} 5534 5535 //---------- Zeros Count Instructions ------------------------------------------ 5536 5537 instruct countLeadingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 5538 predicate(UseCountLeadingZerosInstruction); 5539 match(Set dst (CountLeadingZerosI src)); 5540 effect(KILL cr); 5541 5542 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 5543 ins_encode %{ 5544 __ lzcntl($dst$$Register, $src$$Register); 5545 %} 5546 ins_pipe(ialu_reg); 5547 %} 5548 5549 instruct countLeadingZerosI_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5550 predicate(UseCountLeadingZerosInstruction); 5551 match(Set dst (CountLeadingZerosI (LoadI src))); 5552 effect(KILL cr); 5553 ins_cost(175); 5554 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 5555 ins_encode %{ 5556 __ lzcntl($dst$$Register, $src$$Address); 5557 %} 5558 ins_pipe(ialu_reg_mem); 5559 %} 5560 5561 instruct countLeadingZerosI_bsr(rRegI dst, rRegI src, rFlagsReg cr) %{ 5562 predicate(!UseCountLeadingZerosInstruction); 5563 match(Set dst (CountLeadingZerosI src)); 5564 effect(KILL cr); 5565 5566 format %{ "bsrl $dst, $src\t# count leading zeros (int)\n\t" 5567 "jnz skip\n\t" 5568 "movl $dst, -1\n" 5569 "skip:\n\t" 5570 "negl $dst\n\t" 5571 "addl $dst, 31" %} 5572 ins_encode %{ 5573 Register Rdst = $dst$$Register; 5574 Register Rsrc = $src$$Register; 5575 Label skip; 5576 __ bsrl(Rdst, Rsrc); 5577 __ jccb(Assembler::notZero, skip); 5578 __ movl(Rdst, -1); 5579 __ bind(skip); 5580 __ negl(Rdst); 5581 __ addl(Rdst, BitsPerInt - 1); 5582 %} 5583 ins_pipe(ialu_reg); 5584 %} 5585 5586 instruct countLeadingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 5587 predicate(UseCountLeadingZerosInstruction); 5588 match(Set dst (CountLeadingZerosL src)); 5589 effect(KILL cr); 5590 5591 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 5592 ins_encode %{ 5593 __ lzcntq($dst$$Register, $src$$Register); 5594 %} 5595 ins_pipe(ialu_reg); 5596 %} 5597 5598 instruct countLeadingZerosL_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5599 predicate(UseCountLeadingZerosInstruction); 5600 match(Set dst (CountLeadingZerosL (LoadL src))); 5601 effect(KILL cr); 5602 ins_cost(175); 5603 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 5604 ins_encode %{ 5605 __ lzcntq($dst$$Register, $src$$Address); 5606 %} 5607 ins_pipe(ialu_reg_mem); 5608 %} 5609 5610 instruct countLeadingZerosL_bsr(rRegI dst, rRegL src, rFlagsReg cr) %{ 5611 predicate(!UseCountLeadingZerosInstruction); 5612 match(Set dst (CountLeadingZerosL src)); 5613 effect(KILL cr); 5614 5615 format %{ "bsrq $dst, $src\t# count leading zeros (long)\n\t" 5616 "jnz skip\n\t" 5617 "movl $dst, -1\n" 5618 "skip:\n\t" 5619 "negl $dst\n\t" 5620 "addl $dst, 63" %} 5621 ins_encode %{ 5622 Register Rdst = $dst$$Register; 5623 Register Rsrc = $src$$Register; 5624 Label skip; 5625 __ bsrq(Rdst, Rsrc); 5626 __ jccb(Assembler::notZero, skip); 5627 __ movl(Rdst, -1); 5628 __ bind(skip); 5629 __ negl(Rdst); 5630 __ addl(Rdst, BitsPerLong - 1); 5631 %} 5632 ins_pipe(ialu_reg); 5633 %} 5634 5635 instruct countTrailingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 5636 predicate(UseCountTrailingZerosInstruction); 5637 match(Set dst (CountTrailingZerosI src)); 5638 effect(KILL cr); 5639 5640 format %{ "tzcntl $dst, $src\t# count trailing zeros (int)" %} 5641 ins_encode %{ 5642 __ tzcntl($dst$$Register, $src$$Register); 5643 %} 5644 ins_pipe(ialu_reg); 5645 %} 5646 5647 instruct countTrailingZerosI_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5648 predicate(UseCountTrailingZerosInstruction); 5649 match(Set dst (CountTrailingZerosI (LoadI src))); 5650 effect(KILL cr); 5651 ins_cost(175); 5652 format %{ "tzcntl $dst, $src\t# count trailing zeros (int)" %} 5653 ins_encode %{ 5654 __ tzcntl($dst$$Register, $src$$Address); 5655 %} 5656 ins_pipe(ialu_reg_mem); 5657 %} 5658 5659 instruct countTrailingZerosI_bsf(rRegI dst, rRegI src, rFlagsReg cr) %{ 5660 predicate(!UseCountTrailingZerosInstruction); 5661 match(Set dst (CountTrailingZerosI src)); 5662 effect(KILL cr); 5663 5664 format %{ "bsfl $dst, $src\t# count trailing zeros (int)\n\t" 5665 "jnz done\n\t" 5666 "movl $dst, 32\n" 5667 "done:" %} 5668 ins_encode %{ 5669 Register Rdst = $dst$$Register; 5670 Label done; 5671 __ bsfl(Rdst, $src$$Register); 5672 __ jccb(Assembler::notZero, done); 5673 __ movl(Rdst, BitsPerInt); 5674 __ bind(done); 5675 %} 5676 ins_pipe(ialu_reg); 5677 %} 5678 5679 instruct countTrailingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 5680 predicate(UseCountTrailingZerosInstruction); 5681 match(Set dst (CountTrailingZerosL src)); 5682 effect(KILL cr); 5683 5684 format %{ "tzcntq $dst, $src\t# count trailing zeros (long)" %} 5685 ins_encode %{ 5686 __ tzcntq($dst$$Register, $src$$Register); 5687 %} 5688 ins_pipe(ialu_reg); 5689 %} 5690 5691 instruct countTrailingZerosL_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5692 predicate(UseCountTrailingZerosInstruction); 5693 match(Set dst (CountTrailingZerosL (LoadL src))); 5694 effect(KILL cr); 5695 ins_cost(175); 5696 format %{ "tzcntq $dst, $src\t# count trailing zeros (long)" %} 5697 ins_encode %{ 5698 __ tzcntq($dst$$Register, $src$$Address); 5699 %} 5700 ins_pipe(ialu_reg_mem); 5701 %} 5702 5703 instruct countTrailingZerosL_bsf(rRegI dst, rRegL src, rFlagsReg cr) %{ 5704 predicate(!UseCountTrailingZerosInstruction); 5705 match(Set dst (CountTrailingZerosL src)); 5706 effect(KILL cr); 5707 5708 format %{ "bsfq $dst, $src\t# count trailing zeros (long)\n\t" 5709 "jnz done\n\t" 5710 "movl $dst, 64\n" 5711 "done:" %} 5712 ins_encode %{ 5713 Register Rdst = $dst$$Register; 5714 Label done; 5715 __ bsfq(Rdst, $src$$Register); 5716 __ jccb(Assembler::notZero, done); 5717 __ movl(Rdst, BitsPerLong); 5718 __ bind(done); 5719 %} 5720 ins_pipe(ialu_reg); 5721 %} 5722 5723 //--------------- Reverse Operation Instructions ---------------- 5724 instruct bytes_reversebit_int(rRegI dst, rRegI src, rRegI rtmp, rFlagsReg cr) %{ 5725 predicate(!VM_Version::supports_gfni()); 5726 match(Set dst (ReverseI src)); 5727 effect(TEMP dst, TEMP rtmp, KILL cr); 5728 format %{ "reverse_int $dst $src\t! using $rtmp as TEMP" %} 5729 ins_encode %{ 5730 __ reverseI($dst$$Register, $src$$Register, xnoreg, xnoreg, $rtmp$$Register); 5731 %} 5732 ins_pipe( ialu_reg ); 5733 %} 5734 5735 instruct bytes_reversebit_int_gfni(rRegI dst, rRegI src, vlRegF xtmp1, vlRegF xtmp2, rRegL rtmp, rFlagsReg cr) %{ 5736 predicate(VM_Version::supports_gfni()); 5737 match(Set dst (ReverseI src)); 5738 effect(TEMP dst, TEMP xtmp1, TEMP xtmp2, TEMP rtmp, KILL cr); 5739 format %{ "reverse_int $dst $src\t! using $rtmp, $xtmp1 and $xtmp2 as TEMP" %} 5740 ins_encode %{ 5741 __ reverseI($dst$$Register, $src$$Register, $xtmp1$$XMMRegister, $xtmp2$$XMMRegister, $rtmp$$Register); 5742 %} 5743 ins_pipe( ialu_reg ); 5744 %} 5745 5746 instruct bytes_reversebit_long(rRegL dst, rRegL src, rRegL rtmp1, rRegL rtmp2, rFlagsReg cr) %{ 5747 predicate(!VM_Version::supports_gfni()); 5748 match(Set dst (ReverseL src)); 5749 effect(TEMP dst, TEMP rtmp1, TEMP rtmp2, KILL cr); 5750 format %{ "reverse_long $dst $src\t! using $rtmp1 and $rtmp2 as TEMP" %} 5751 ins_encode %{ 5752 __ reverseL($dst$$Register, $src$$Register, xnoreg, xnoreg, $rtmp1$$Register, $rtmp2$$Register); 5753 %} 5754 ins_pipe( ialu_reg ); 5755 %} 5756 5757 instruct bytes_reversebit_long_gfni(rRegL dst, rRegL src, vlRegD xtmp1, vlRegD xtmp2, rRegL rtmp, rFlagsReg cr) %{ 5758 predicate(VM_Version::supports_gfni()); 5759 match(Set dst (ReverseL src)); 5760 effect(TEMP dst, TEMP xtmp1, TEMP xtmp2, TEMP rtmp, KILL cr); 5761 format %{ "reverse_long $dst $src\t! using $rtmp, $xtmp1 and $xtmp2 as TEMP" %} 5762 ins_encode %{ 5763 __ reverseL($dst$$Register, $src$$Register, $xtmp1$$XMMRegister, $xtmp2$$XMMRegister, $rtmp$$Register, noreg); 5764 %} 5765 ins_pipe( ialu_reg ); 5766 %} 5767 5768 //---------- Population Count Instructions ------------------------------------- 5769 5770 instruct popCountI(rRegI dst, rRegI src, rFlagsReg cr) %{ 5771 predicate(UsePopCountInstruction); 5772 match(Set dst (PopCountI src)); 5773 effect(KILL cr); 5774 5775 format %{ "popcnt $dst, $src" %} 5776 ins_encode %{ 5777 __ popcntl($dst$$Register, $src$$Register); 5778 %} 5779 ins_pipe(ialu_reg); 5780 %} 5781 5782 instruct popCountI_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 5783 predicate(UsePopCountInstruction); 5784 match(Set dst (PopCountI (LoadI mem))); 5785 effect(KILL cr); 5786 5787 format %{ "popcnt $dst, $mem" %} 5788 ins_encode %{ 5789 __ popcntl($dst$$Register, $mem$$Address); 5790 %} 5791 ins_pipe(ialu_reg); 5792 %} 5793 5794 // Note: Long.bitCount(long) returns an int. 5795 instruct popCountL(rRegI dst, rRegL src, rFlagsReg cr) %{ 5796 predicate(UsePopCountInstruction); 5797 match(Set dst (PopCountL src)); 5798 effect(KILL cr); 5799 5800 format %{ "popcnt $dst, $src" %} 5801 ins_encode %{ 5802 __ popcntq($dst$$Register, $src$$Register); 5803 %} 5804 ins_pipe(ialu_reg); 5805 %} 5806 5807 // Note: Long.bitCount(long) returns an int. 5808 instruct popCountL_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 5809 predicate(UsePopCountInstruction); 5810 match(Set dst (PopCountL (LoadL mem))); 5811 effect(KILL cr); 5812 5813 format %{ "popcnt $dst, $mem" %} 5814 ins_encode %{ 5815 __ popcntq($dst$$Register, $mem$$Address); 5816 %} 5817 ins_pipe(ialu_reg); 5818 %} 5819 5820 5821 //----------MemBar Instructions----------------------------------------------- 5822 // Memory barrier flavors 5823 5824 instruct membar_acquire() 5825 %{ 5826 match(MemBarAcquire); 5827 match(LoadFence); 5828 ins_cost(0); 5829 5830 size(0); 5831 format %{ "MEMBAR-acquire ! (empty encoding)" %} 5832 ins_encode(); 5833 ins_pipe(empty); 5834 %} 5835 5836 instruct membar_acquire_lock() 5837 %{ 5838 match(MemBarAcquireLock); 5839 ins_cost(0); 5840 5841 size(0); 5842 format %{ "MEMBAR-acquire (prior CMPXCHG in FastLock so empty encoding)" %} 5843 ins_encode(); 5844 ins_pipe(empty); 5845 %} 5846 5847 instruct membar_release() 5848 %{ 5849 match(MemBarRelease); 5850 match(StoreFence); 5851 ins_cost(0); 5852 5853 size(0); 5854 format %{ "MEMBAR-release ! (empty encoding)" %} 5855 ins_encode(); 5856 ins_pipe(empty); 5857 %} 5858 5859 instruct membar_release_lock() 5860 %{ 5861 match(MemBarReleaseLock); 5862 ins_cost(0); 5863 5864 size(0); 5865 format %{ "MEMBAR-release (a FastUnlock follows so empty encoding)" %} 5866 ins_encode(); 5867 ins_pipe(empty); 5868 %} 5869 5870 instruct membar_volatile(rFlagsReg cr) %{ 5871 match(MemBarVolatile); 5872 effect(KILL cr); 5873 ins_cost(400); 5874 5875 format %{ 5876 $$template 5877 $$emit$$"lock addl [rsp + #0], 0\t! membar_volatile" 5878 %} 5879 ins_encode %{ 5880 __ membar(Assembler::StoreLoad); 5881 %} 5882 ins_pipe(pipe_slow); 5883 %} 5884 5885 instruct unnecessary_membar_volatile() 5886 %{ 5887 match(MemBarVolatile); 5888 predicate(Matcher::post_store_load_barrier(n)); 5889 ins_cost(0); 5890 5891 size(0); 5892 format %{ "MEMBAR-volatile (unnecessary so empty encoding)" %} 5893 ins_encode(); 5894 ins_pipe(empty); 5895 %} 5896 5897 instruct membar_storestore() %{ 5898 match(MemBarStoreStore); 5899 match(StoreStoreFence); 5900 ins_cost(0); 5901 5902 size(0); 5903 format %{ "MEMBAR-storestore (empty encoding)" %} 5904 ins_encode( ); 5905 ins_pipe(empty); 5906 %} 5907 5908 //----------Move Instructions-------------------------------------------------- 5909 5910 instruct castX2P(rRegP dst, rRegL src) 5911 %{ 5912 match(Set dst (CastX2P src)); 5913 5914 format %{ "movq $dst, $src\t# long->ptr" %} 5915 ins_encode %{ 5916 if ($dst$$reg != $src$$reg) { 5917 __ movptr($dst$$Register, $src$$Register); 5918 } 5919 %} 5920 ins_pipe(ialu_reg_reg); // XXX 5921 %} 5922 5923 instruct castN2X(rRegL dst, rRegN src) 5924 %{ 5925 match(Set dst (CastP2X src)); 5926 5927 format %{ "movq $dst, $src\t# ptr -> long" %} 5928 ins_encode %{ 5929 if ($dst$$reg != $src$$reg) { 5930 __ movptr($dst$$Register, $src$$Register); 5931 } 5932 %} 5933 ins_pipe(ialu_reg_reg); // XXX 5934 %} 5935 5936 instruct castP2X(rRegL dst, rRegP src) 5937 %{ 5938 match(Set dst (CastP2X src)); 5939 5940 format %{ "movq $dst, $src\t# ptr -> long" %} 5941 ins_encode %{ 5942 if ($dst$$reg != $src$$reg) { 5943 __ movptr($dst$$Register, $src$$Register); 5944 } 5945 %} 5946 ins_pipe(ialu_reg_reg); // XXX 5947 %} 5948 5949 // Convert oop into int for vectors alignment masking 5950 instruct convP2I(rRegI dst, rRegP src) 5951 %{ 5952 match(Set dst (ConvL2I (CastP2X src))); 5953 5954 format %{ "movl $dst, $src\t# ptr -> int" %} 5955 ins_encode %{ 5956 __ movl($dst$$Register, $src$$Register); 5957 %} 5958 ins_pipe(ialu_reg_reg); // XXX 5959 %} 5960 5961 // Convert compressed oop into int for vectors alignment masking 5962 // in case of 32bit oops (heap < 4Gb). 5963 instruct convN2I(rRegI dst, rRegN src) 5964 %{ 5965 predicate(CompressedOops::shift() == 0); 5966 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 5967 5968 format %{ "movl $dst, $src\t# compressed ptr -> int" %} 5969 ins_encode %{ 5970 __ movl($dst$$Register, $src$$Register); 5971 %} 5972 ins_pipe(ialu_reg_reg); // XXX 5973 %} 5974 5975 // Convert oop pointer into compressed form 5976 instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{ 5977 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 5978 match(Set dst (EncodeP src)); 5979 effect(KILL cr); 5980 format %{ "encode_heap_oop $dst,$src" %} 5981 ins_encode %{ 5982 Register s = $src$$Register; 5983 Register d = $dst$$Register; 5984 if (s != d) { 5985 __ movq(d, s); 5986 } 5987 __ encode_heap_oop(d); 5988 %} 5989 ins_pipe(ialu_reg_long); 5990 %} 5991 5992 instruct encodeHeapOop_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 5993 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 5994 match(Set dst (EncodeP src)); 5995 effect(KILL cr); 5996 format %{ "encode_heap_oop_not_null $dst,$src" %} 5997 ins_encode %{ 5998 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 5999 %} 6000 ins_pipe(ialu_reg_long); 6001 %} 6002 6003 instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{ 6004 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 6005 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 6006 match(Set dst (DecodeN src)); 6007 effect(KILL cr); 6008 format %{ "decode_heap_oop $dst,$src" %} 6009 ins_encode %{ 6010 Register s = $src$$Register; 6011 Register d = $dst$$Register; 6012 if (s != d) { 6013 __ movq(d, s); 6014 } 6015 __ decode_heap_oop(d); 6016 %} 6017 ins_pipe(ialu_reg_long); 6018 %} 6019 6020 instruct decodeHeapOop_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6021 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 6022 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 6023 match(Set dst (DecodeN src)); 6024 effect(KILL cr); 6025 format %{ "decode_heap_oop_not_null $dst,$src" %} 6026 ins_encode %{ 6027 Register s = $src$$Register; 6028 Register d = $dst$$Register; 6029 if (s != d) { 6030 __ decode_heap_oop_not_null(d, s); 6031 } else { 6032 __ decode_heap_oop_not_null(d); 6033 } 6034 %} 6035 ins_pipe(ialu_reg_long); 6036 %} 6037 6038 instruct encodeKlass_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6039 match(Set dst (EncodePKlass src)); 6040 effect(TEMP dst, KILL cr); 6041 format %{ "encode_and_move_klass_not_null $dst,$src" %} 6042 ins_encode %{ 6043 __ encode_and_move_klass_not_null($dst$$Register, $src$$Register); 6044 %} 6045 ins_pipe(ialu_reg_long); 6046 %} 6047 6048 instruct decodeKlass_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6049 match(Set dst (DecodeNKlass src)); 6050 effect(TEMP dst, KILL cr); 6051 format %{ "decode_and_move_klass_not_null $dst,$src" %} 6052 ins_encode %{ 6053 __ decode_and_move_klass_not_null($dst$$Register, $src$$Register); 6054 %} 6055 ins_pipe(ialu_reg_long); 6056 %} 6057 6058 //----------Conditional Move--------------------------------------------------- 6059 // Jump 6060 // dummy instruction for generating temp registers 6061 instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{ 6062 match(Jump (LShiftL switch_val shift)); 6063 ins_cost(350); 6064 predicate(false); 6065 effect(TEMP dest); 6066 6067 format %{ "leaq $dest, [$constantaddress]\n\t" 6068 "jmp [$dest + $switch_val << $shift]\n\t" %} 6069 ins_encode %{ 6070 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6071 // to do that and the compiler is using that register as one it can allocate. 6072 // So we build it all by hand. 6073 // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant); 6074 // ArrayAddress dispatch(table, index); 6075 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant); 6076 __ lea($dest$$Register, $constantaddress); 6077 __ jmp(dispatch); 6078 %} 6079 ins_pipe(pipe_jmp); 6080 %} 6081 6082 instruct jumpXtnd_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{ 6083 match(Jump (AddL (LShiftL switch_val shift) offset)); 6084 ins_cost(350); 6085 effect(TEMP dest); 6086 6087 format %{ "leaq $dest, [$constantaddress]\n\t" 6088 "jmp [$dest + $switch_val << $shift + $offset]\n\t" %} 6089 ins_encode %{ 6090 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6091 // to do that and the compiler is using that register as one it can allocate. 6092 // So we build it all by hand. 6093 // Address index(noreg, switch_reg, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6094 // ArrayAddress dispatch(table, index); 6095 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6096 __ lea($dest$$Register, $constantaddress); 6097 __ jmp(dispatch); 6098 %} 6099 ins_pipe(pipe_jmp); 6100 %} 6101 6102 instruct jumpXtnd(rRegL switch_val, rRegI dest) %{ 6103 match(Jump switch_val); 6104 ins_cost(350); 6105 effect(TEMP dest); 6106 6107 format %{ "leaq $dest, [$constantaddress]\n\t" 6108 "jmp [$dest + $switch_val]\n\t" %} 6109 ins_encode %{ 6110 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6111 // to do that and the compiler is using that register as one it can allocate. 6112 // So we build it all by hand. 6113 // Address index(noreg, switch_reg, Address::times_1); 6114 // ArrayAddress dispatch(table, index); 6115 Address dispatch($dest$$Register, $switch_val$$Register, Address::times_1); 6116 __ lea($dest$$Register, $constantaddress); 6117 __ jmp(dispatch); 6118 %} 6119 ins_pipe(pipe_jmp); 6120 %} 6121 6122 // Conditional move 6123 instruct cmovI_imm_01(rRegI dst, immI_1 src, rFlagsReg cr, cmpOp cop) 6124 %{ 6125 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_int() == 0); 6126 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6127 6128 ins_cost(100); // XXX 6129 format %{ "setbn$cop $dst\t# signed, int" %} 6130 ins_encode %{ 6131 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6132 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6133 %} 6134 ins_pipe(ialu_reg); 6135 %} 6136 6137 instruct cmovI_reg(rRegI dst, rRegI src, rFlagsReg cr, cmpOp cop) 6138 %{ 6139 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6140 6141 ins_cost(200); // XXX 6142 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6143 ins_encode %{ 6144 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6145 %} 6146 ins_pipe(pipe_cmov_reg); 6147 %} 6148 6149 instruct cmovI_imm_01U(rRegI dst, immI_1 src, rFlagsRegU cr, cmpOpU cop) 6150 %{ 6151 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_int() == 0); 6152 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6153 6154 ins_cost(100); // XXX 6155 format %{ "setbn$cop $dst\t# unsigned, int" %} 6156 ins_encode %{ 6157 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6158 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6159 %} 6160 ins_pipe(ialu_reg); 6161 %} 6162 6163 instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{ 6164 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6165 6166 ins_cost(200); // XXX 6167 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6168 ins_encode %{ 6169 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6170 %} 6171 ins_pipe(pipe_cmov_reg); 6172 %} 6173 6174 instruct cmovI_imm_01UCF(rRegI dst, immI_1 src, rFlagsRegUCF cr, cmpOpUCF cop) 6175 %{ 6176 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_int() == 0); 6177 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6178 6179 ins_cost(100); // XXX 6180 format %{ "setbn$cop $dst\t# unsigned, int" %} 6181 ins_encode %{ 6182 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6183 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6184 %} 6185 ins_pipe(ialu_reg); 6186 %} 6187 6188 instruct cmovI_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6189 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6190 ins_cost(200); 6191 expand %{ 6192 cmovI_regU(cop, cr, dst, src); 6193 %} 6194 %} 6195 6196 instruct cmovI_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6197 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6198 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6199 6200 ins_cost(200); // XXX 6201 format %{ "cmovpl $dst, $src\n\t" 6202 "cmovnel $dst, $src" %} 6203 ins_encode %{ 6204 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6205 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6206 %} 6207 ins_pipe(pipe_cmov_reg); 6208 %} 6209 6210 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6211 // inputs of the CMove 6212 instruct cmovI_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6213 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6214 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6215 6216 ins_cost(200); // XXX 6217 format %{ "cmovpl $dst, $src\n\t" 6218 "cmovnel $dst, $src" %} 6219 ins_encode %{ 6220 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6221 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6222 %} 6223 ins_pipe(pipe_cmov_reg); 6224 %} 6225 6226 // Conditional move 6227 instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{ 6228 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6229 6230 ins_cost(250); // XXX 6231 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6232 ins_encode %{ 6233 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6234 %} 6235 ins_pipe(pipe_cmov_mem); 6236 %} 6237 6238 // Conditional move 6239 instruct cmovI_memU(cmpOpU cop, rFlagsRegU cr, rRegI dst, memory src) 6240 %{ 6241 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6242 6243 ins_cost(250); // XXX 6244 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6245 ins_encode %{ 6246 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6247 %} 6248 ins_pipe(pipe_cmov_mem); 6249 %} 6250 6251 instruct cmovI_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, memory src) %{ 6252 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6253 ins_cost(250); 6254 expand %{ 6255 cmovI_memU(cop, cr, dst, src); 6256 %} 6257 %} 6258 6259 // Conditional move 6260 instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop) 6261 %{ 6262 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6263 6264 ins_cost(200); // XXX 6265 format %{ "cmovl$cop $dst, $src\t# signed, compressed ptr" %} 6266 ins_encode %{ 6267 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6268 %} 6269 ins_pipe(pipe_cmov_reg); 6270 %} 6271 6272 // Conditional move 6273 instruct cmovN_regU(cmpOpU cop, rFlagsRegU cr, rRegN dst, rRegN src) 6274 %{ 6275 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6276 6277 ins_cost(200); // XXX 6278 format %{ "cmovl$cop $dst, $src\t# unsigned, compressed ptr" %} 6279 ins_encode %{ 6280 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6281 %} 6282 ins_pipe(pipe_cmov_reg); 6283 %} 6284 6285 instruct cmovN_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6286 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6287 ins_cost(200); 6288 expand %{ 6289 cmovN_regU(cop, cr, dst, src); 6290 %} 6291 %} 6292 6293 instruct cmovN_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6294 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6295 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6296 6297 ins_cost(200); // XXX 6298 format %{ "cmovpl $dst, $src\n\t" 6299 "cmovnel $dst, $src" %} 6300 ins_encode %{ 6301 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6302 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6303 %} 6304 ins_pipe(pipe_cmov_reg); 6305 %} 6306 6307 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6308 // inputs of the CMove 6309 instruct cmovN_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6310 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6311 match(Set dst (CMoveN (Binary cop cr) (Binary src dst))); 6312 6313 ins_cost(200); // XXX 6314 format %{ "cmovpl $dst, $src\n\t" 6315 "cmovnel $dst, $src" %} 6316 ins_encode %{ 6317 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6318 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6319 %} 6320 ins_pipe(pipe_cmov_reg); 6321 %} 6322 6323 // Conditional move 6324 instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop) 6325 %{ 6326 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6327 6328 ins_cost(200); // XXX 6329 format %{ "cmovq$cop $dst, $src\t# signed, ptr" %} 6330 ins_encode %{ 6331 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6332 %} 6333 ins_pipe(pipe_cmov_reg); // XXX 6334 %} 6335 6336 // Conditional move 6337 instruct cmovP_regU(cmpOpU cop, rFlagsRegU cr, rRegP dst, rRegP src) 6338 %{ 6339 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6340 6341 ins_cost(200); // XXX 6342 format %{ "cmovq$cop $dst, $src\t# unsigned, ptr" %} 6343 ins_encode %{ 6344 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6345 %} 6346 ins_pipe(pipe_cmov_reg); // XXX 6347 %} 6348 6349 instruct cmovP_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6350 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6351 ins_cost(200); 6352 expand %{ 6353 cmovP_regU(cop, cr, dst, src); 6354 %} 6355 %} 6356 6357 instruct cmovP_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6358 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6359 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6360 6361 ins_cost(200); // XXX 6362 format %{ "cmovpq $dst, $src\n\t" 6363 "cmovneq $dst, $src" %} 6364 ins_encode %{ 6365 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6366 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6367 %} 6368 ins_pipe(pipe_cmov_reg); 6369 %} 6370 6371 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6372 // inputs of the CMove 6373 instruct cmovP_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6374 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6375 match(Set dst (CMoveP (Binary cop cr) (Binary src dst))); 6376 6377 ins_cost(200); // XXX 6378 format %{ "cmovpq $dst, $src\n\t" 6379 "cmovneq $dst, $src" %} 6380 ins_encode %{ 6381 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6382 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6383 %} 6384 ins_pipe(pipe_cmov_reg); 6385 %} 6386 6387 instruct cmovL_imm_01(rRegL dst, immL1 src, rFlagsReg cr, cmpOp cop) 6388 %{ 6389 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_long() == 0); 6390 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6391 6392 ins_cost(100); // XXX 6393 format %{ "setbn$cop $dst\t# signed, long" %} 6394 ins_encode %{ 6395 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6396 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6397 %} 6398 ins_pipe(ialu_reg); 6399 %} 6400 6401 instruct cmovL_reg(cmpOp cop, rFlagsReg cr, rRegL dst, rRegL src) 6402 %{ 6403 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6404 6405 ins_cost(200); // XXX 6406 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6407 ins_encode %{ 6408 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6409 %} 6410 ins_pipe(pipe_cmov_reg); // XXX 6411 %} 6412 6413 instruct cmovL_mem(cmpOp cop, rFlagsReg cr, rRegL dst, memory src) 6414 %{ 6415 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6416 6417 ins_cost(200); // XXX 6418 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6419 ins_encode %{ 6420 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6421 %} 6422 ins_pipe(pipe_cmov_mem); // XXX 6423 %} 6424 6425 instruct cmovL_imm_01U(rRegL dst, immL1 src, rFlagsRegU cr, cmpOpU cop) 6426 %{ 6427 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_long() == 0); 6428 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6429 6430 ins_cost(100); // XXX 6431 format %{ "setbn$cop $dst\t# unsigned, long" %} 6432 ins_encode %{ 6433 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6434 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6435 %} 6436 ins_pipe(ialu_reg); 6437 %} 6438 6439 instruct cmovL_regU(cmpOpU cop, rFlagsRegU cr, rRegL dst, rRegL src) 6440 %{ 6441 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6442 6443 ins_cost(200); // XXX 6444 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 6445 ins_encode %{ 6446 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6447 %} 6448 ins_pipe(pipe_cmov_reg); // XXX 6449 %} 6450 6451 instruct cmovL_imm_01UCF(rRegL dst, immL1 src, rFlagsRegUCF cr, cmpOpUCF cop) 6452 %{ 6453 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_long() == 0); 6454 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6455 6456 ins_cost(100); // XXX 6457 format %{ "setbn$cop $dst\t# unsigned, long" %} 6458 ins_encode %{ 6459 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6460 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6461 %} 6462 ins_pipe(ialu_reg); 6463 %} 6464 6465 instruct cmovL_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6466 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6467 ins_cost(200); 6468 expand %{ 6469 cmovL_regU(cop, cr, dst, src); 6470 %} 6471 %} 6472 6473 instruct cmovL_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6474 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6475 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6476 6477 ins_cost(200); // XXX 6478 format %{ "cmovpq $dst, $src\n\t" 6479 "cmovneq $dst, $src" %} 6480 ins_encode %{ 6481 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6482 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6483 %} 6484 ins_pipe(pipe_cmov_reg); 6485 %} 6486 6487 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6488 // inputs of the CMove 6489 instruct cmovL_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6490 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6491 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6492 6493 ins_cost(200); // XXX 6494 format %{ "cmovpq $dst, $src\n\t" 6495 "cmovneq $dst, $src" %} 6496 ins_encode %{ 6497 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6498 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6499 %} 6500 ins_pipe(pipe_cmov_reg); 6501 %} 6502 6503 instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src) 6504 %{ 6505 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6506 6507 ins_cost(200); // XXX 6508 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 6509 ins_encode %{ 6510 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6511 %} 6512 ins_pipe(pipe_cmov_mem); // XXX 6513 %} 6514 6515 instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{ 6516 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6517 ins_cost(200); 6518 expand %{ 6519 cmovL_memU(cop, cr, dst, src); 6520 %} 6521 %} 6522 6523 instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src) 6524 %{ 6525 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6526 6527 ins_cost(200); // XXX 6528 format %{ "jn$cop skip\t# signed cmove float\n\t" 6529 "movss $dst, $src\n" 6530 "skip:" %} 6531 ins_encode %{ 6532 Label Lskip; 6533 // Invert sense of branch from sense of CMOV 6534 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6535 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 6536 __ bind(Lskip); 6537 %} 6538 ins_pipe(pipe_slow); 6539 %} 6540 6541 instruct cmovF_regU(cmpOpU cop, rFlagsRegU cr, regF dst, regF src) 6542 %{ 6543 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6544 6545 ins_cost(200); // XXX 6546 format %{ "jn$cop skip\t# unsigned cmove float\n\t" 6547 "movss $dst, $src\n" 6548 "skip:" %} 6549 ins_encode %{ 6550 Label Lskip; 6551 // Invert sense of branch from sense of CMOV 6552 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6553 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 6554 __ bind(Lskip); 6555 %} 6556 ins_pipe(pipe_slow); 6557 %} 6558 6559 instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{ 6560 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6561 ins_cost(200); 6562 expand %{ 6563 cmovF_regU(cop, cr, dst, src); 6564 %} 6565 %} 6566 6567 instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src) 6568 %{ 6569 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6570 6571 ins_cost(200); // XXX 6572 format %{ "jn$cop skip\t# signed cmove double\n\t" 6573 "movsd $dst, $src\n" 6574 "skip:" %} 6575 ins_encode %{ 6576 Label Lskip; 6577 // Invert sense of branch from sense of CMOV 6578 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6579 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 6580 __ bind(Lskip); 6581 %} 6582 ins_pipe(pipe_slow); 6583 %} 6584 6585 instruct cmovD_regU(cmpOpU cop, rFlagsRegU cr, regD dst, regD src) 6586 %{ 6587 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6588 6589 ins_cost(200); // XXX 6590 format %{ "jn$cop skip\t# unsigned cmove double\n\t" 6591 "movsd $dst, $src\n" 6592 "skip:" %} 6593 ins_encode %{ 6594 Label Lskip; 6595 // Invert sense of branch from sense of CMOV 6596 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6597 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 6598 __ bind(Lskip); 6599 %} 6600 ins_pipe(pipe_slow); 6601 %} 6602 6603 instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{ 6604 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6605 ins_cost(200); 6606 expand %{ 6607 cmovD_regU(cop, cr, dst, src); 6608 %} 6609 %} 6610 6611 //----------Arithmetic Instructions-------------------------------------------- 6612 //----------Addition Instructions---------------------------------------------- 6613 6614 instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 6615 %{ 6616 match(Set dst (AddI dst src)); 6617 effect(KILL cr); 6618 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); 6619 format %{ "addl $dst, $src\t# int" %} 6620 ins_encode %{ 6621 __ addl($dst$$Register, $src$$Register); 6622 %} 6623 ins_pipe(ialu_reg_reg); 6624 %} 6625 6626 instruct addI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 6627 %{ 6628 match(Set dst (AddI dst src)); 6629 effect(KILL cr); 6630 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); 6631 6632 format %{ "addl $dst, $src\t# int" %} 6633 ins_encode %{ 6634 __ addl($dst$$Register, $src$$constant); 6635 %} 6636 ins_pipe( ialu_reg ); 6637 %} 6638 6639 instruct addI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 6640 %{ 6641 match(Set dst (AddI dst (LoadI src))); 6642 effect(KILL cr); 6643 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); 6644 6645 ins_cost(150); // XXX 6646 format %{ "addl $dst, $src\t# int" %} 6647 ins_encode %{ 6648 __ addl($dst$$Register, $src$$Address); 6649 %} 6650 ins_pipe(ialu_reg_mem); 6651 %} 6652 6653 instruct addI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 6654 %{ 6655 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6656 effect(KILL cr); 6657 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); 6658 6659 ins_cost(150); // XXX 6660 format %{ "addl $dst, $src\t# int" %} 6661 ins_encode %{ 6662 __ addl($dst$$Address, $src$$Register); 6663 %} 6664 ins_pipe(ialu_mem_reg); 6665 %} 6666 6667 instruct addI_mem_imm(memory dst, immI src, rFlagsReg cr) 6668 %{ 6669 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6670 effect(KILL cr); 6671 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); 6672 6673 6674 ins_cost(125); // XXX 6675 format %{ "addl $dst, $src\t# int" %} 6676 ins_encode %{ 6677 __ addl($dst$$Address, $src$$constant); 6678 %} 6679 ins_pipe(ialu_mem_imm); 6680 %} 6681 6682 instruct incI_rReg(rRegI dst, immI_1 src, rFlagsReg cr) 6683 %{ 6684 predicate(UseIncDec); 6685 match(Set dst (AddI dst src)); 6686 effect(KILL cr); 6687 6688 format %{ "incl $dst\t# int" %} 6689 ins_encode %{ 6690 __ incrementl($dst$$Register); 6691 %} 6692 ins_pipe(ialu_reg); 6693 %} 6694 6695 instruct incI_mem(memory dst, immI_1 src, rFlagsReg cr) 6696 %{ 6697 predicate(UseIncDec); 6698 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6699 effect(KILL cr); 6700 6701 ins_cost(125); // XXX 6702 format %{ "incl $dst\t# int" %} 6703 ins_encode %{ 6704 __ incrementl($dst$$Address); 6705 %} 6706 ins_pipe(ialu_mem_imm); 6707 %} 6708 6709 // XXX why does that use AddI 6710 instruct decI_rReg(rRegI dst, immI_M1 src, rFlagsReg cr) 6711 %{ 6712 predicate(UseIncDec); 6713 match(Set dst (AddI dst src)); 6714 effect(KILL cr); 6715 6716 format %{ "decl $dst\t# int" %} 6717 ins_encode %{ 6718 __ decrementl($dst$$Register); 6719 %} 6720 ins_pipe(ialu_reg); 6721 %} 6722 6723 // XXX why does that use AddI 6724 instruct decI_mem(memory dst, immI_M1 src, rFlagsReg cr) 6725 %{ 6726 predicate(UseIncDec); 6727 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6728 effect(KILL cr); 6729 6730 ins_cost(125); // XXX 6731 format %{ "decl $dst\t# int" %} 6732 ins_encode %{ 6733 __ decrementl($dst$$Address); 6734 %} 6735 ins_pipe(ialu_mem_imm); 6736 %} 6737 6738 instruct leaI_rReg_immI2_immI(rRegI dst, rRegI index, immI2 scale, immI disp) 6739 %{ 6740 predicate(VM_Version::supports_fast_2op_lea()); 6741 match(Set dst (AddI (LShiftI index scale) disp)); 6742 6743 format %{ "leal $dst, [$index << $scale + $disp]\t# int" %} 6744 ins_encode %{ 6745 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 6746 __ leal($dst$$Register, Address(noreg, $index$$Register, scale, $disp$$constant)); 6747 %} 6748 ins_pipe(ialu_reg_reg); 6749 %} 6750 6751 instruct leaI_rReg_rReg_immI(rRegI dst, rRegI base, rRegI index, immI disp) 6752 %{ 6753 predicate(VM_Version::supports_fast_3op_lea()); 6754 match(Set dst (AddI (AddI base index) disp)); 6755 6756 format %{ "leal $dst, [$base + $index + $disp]\t# int" %} 6757 ins_encode %{ 6758 __ leal($dst$$Register, Address($base$$Register, $index$$Register, Address::times_1, $disp$$constant)); 6759 %} 6760 ins_pipe(ialu_reg_reg); 6761 %} 6762 6763 instruct leaI_rReg_rReg_immI2(rRegI dst, no_rbp_r13_RegI base, rRegI index, immI2 scale) 6764 %{ 6765 predicate(VM_Version::supports_fast_2op_lea()); 6766 match(Set dst (AddI base (LShiftI index scale))); 6767 6768 format %{ "leal $dst, [$base + $index << $scale]\t# int" %} 6769 ins_encode %{ 6770 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 6771 __ leal($dst$$Register, Address($base$$Register, $index$$Register, scale)); 6772 %} 6773 ins_pipe(ialu_reg_reg); 6774 %} 6775 6776 instruct leaI_rReg_rReg_immI2_immI(rRegI dst, rRegI base, rRegI index, immI2 scale, immI disp) 6777 %{ 6778 predicate(VM_Version::supports_fast_3op_lea()); 6779 match(Set dst (AddI (AddI base (LShiftI index scale)) disp)); 6780 6781 format %{ "leal $dst, [$base + $index << $scale + $disp]\t# int" %} 6782 ins_encode %{ 6783 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 6784 __ leal($dst$$Register, Address($base$$Register, $index$$Register, scale, $disp$$constant)); 6785 %} 6786 ins_pipe(ialu_reg_reg); 6787 %} 6788 6789 instruct addL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 6790 %{ 6791 match(Set dst (AddL dst src)); 6792 effect(KILL cr); 6793 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); 6794 6795 format %{ "addq $dst, $src\t# long" %} 6796 ins_encode %{ 6797 __ addq($dst$$Register, $src$$Register); 6798 %} 6799 ins_pipe(ialu_reg_reg); 6800 %} 6801 6802 instruct addL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 6803 %{ 6804 match(Set dst (AddL dst src)); 6805 effect(KILL cr); 6806 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); 6807 6808 format %{ "addq $dst, $src\t# long" %} 6809 ins_encode %{ 6810 __ addq($dst$$Register, $src$$constant); 6811 %} 6812 ins_pipe( ialu_reg ); 6813 %} 6814 6815 instruct addL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 6816 %{ 6817 match(Set dst (AddL dst (LoadL src))); 6818 effect(KILL cr); 6819 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); 6820 6821 ins_cost(150); // XXX 6822 format %{ "addq $dst, $src\t# long" %} 6823 ins_encode %{ 6824 __ addq($dst$$Register, $src$$Address); 6825 %} 6826 ins_pipe(ialu_reg_mem); 6827 %} 6828 6829 instruct addL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 6830 %{ 6831 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 6832 effect(KILL cr); 6833 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); 6834 6835 ins_cost(150); // XXX 6836 format %{ "addq $dst, $src\t# long" %} 6837 ins_encode %{ 6838 __ addq($dst$$Address, $src$$Register); 6839 %} 6840 ins_pipe(ialu_mem_reg); 6841 %} 6842 6843 instruct addL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 6844 %{ 6845 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 6846 effect(KILL cr); 6847 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); 6848 6849 ins_cost(125); // XXX 6850 format %{ "addq $dst, $src\t# long" %} 6851 ins_encode %{ 6852 __ addq($dst$$Address, $src$$constant); 6853 %} 6854 ins_pipe(ialu_mem_imm); 6855 %} 6856 6857 instruct incL_rReg(rRegI dst, immL1 src, rFlagsReg cr) 6858 %{ 6859 predicate(UseIncDec); 6860 match(Set dst (AddL dst src)); 6861 effect(KILL cr); 6862 6863 format %{ "incq $dst\t# long" %} 6864 ins_encode %{ 6865 __ incrementq($dst$$Register); 6866 %} 6867 ins_pipe(ialu_reg); 6868 %} 6869 6870 instruct incL_mem(memory dst, immL1 src, rFlagsReg cr) 6871 %{ 6872 predicate(UseIncDec); 6873 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 6874 effect(KILL cr); 6875 6876 ins_cost(125); // XXX 6877 format %{ "incq $dst\t# long" %} 6878 ins_encode %{ 6879 __ incrementq($dst$$Address); 6880 %} 6881 ins_pipe(ialu_mem_imm); 6882 %} 6883 6884 // XXX why does that use AddL 6885 instruct decL_rReg(rRegL dst, immL_M1 src, rFlagsReg cr) 6886 %{ 6887 predicate(UseIncDec); 6888 match(Set dst (AddL dst src)); 6889 effect(KILL cr); 6890 6891 format %{ "decq $dst\t# long" %} 6892 ins_encode %{ 6893 __ decrementq($dst$$Register); 6894 %} 6895 ins_pipe(ialu_reg); 6896 %} 6897 6898 // XXX why does that use AddL 6899 instruct decL_mem(memory dst, immL_M1 src, rFlagsReg cr) 6900 %{ 6901 predicate(UseIncDec); 6902 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 6903 effect(KILL cr); 6904 6905 ins_cost(125); // XXX 6906 format %{ "decq $dst\t# long" %} 6907 ins_encode %{ 6908 __ decrementq($dst$$Address); 6909 %} 6910 ins_pipe(ialu_mem_imm); 6911 %} 6912 6913 instruct leaL_rReg_immI2_immL32(rRegL dst, rRegL index, immI2 scale, immL32 disp) 6914 %{ 6915 predicate(VM_Version::supports_fast_2op_lea()); 6916 match(Set dst (AddL (LShiftL index scale) disp)); 6917 6918 format %{ "leaq $dst, [$index << $scale + $disp]\t# long" %} 6919 ins_encode %{ 6920 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 6921 __ leaq($dst$$Register, Address(noreg, $index$$Register, scale, $disp$$constant)); 6922 %} 6923 ins_pipe(ialu_reg_reg); 6924 %} 6925 6926 instruct leaL_rReg_rReg_immL32(rRegL dst, rRegL base, rRegL index, immL32 disp) 6927 %{ 6928 predicate(VM_Version::supports_fast_3op_lea()); 6929 match(Set dst (AddL (AddL base index) disp)); 6930 6931 format %{ "leaq $dst, [$base + $index + $disp]\t# long" %} 6932 ins_encode %{ 6933 __ leaq($dst$$Register, Address($base$$Register, $index$$Register, Address::times_1, $disp$$constant)); 6934 %} 6935 ins_pipe(ialu_reg_reg); 6936 %} 6937 6938 instruct leaL_rReg_rReg_immI2(rRegL dst, no_rbp_r13_RegL base, rRegL index, immI2 scale) 6939 %{ 6940 predicate(VM_Version::supports_fast_2op_lea()); 6941 match(Set dst (AddL base (LShiftL index scale))); 6942 6943 format %{ "leaq $dst, [$base + $index << $scale]\t# long" %} 6944 ins_encode %{ 6945 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 6946 __ leaq($dst$$Register, Address($base$$Register, $index$$Register, scale)); 6947 %} 6948 ins_pipe(ialu_reg_reg); 6949 %} 6950 6951 instruct leaL_rReg_rReg_immI2_immL32(rRegL dst, rRegL base, rRegL index, immI2 scale, immL32 disp) 6952 %{ 6953 predicate(VM_Version::supports_fast_3op_lea()); 6954 match(Set dst (AddL (AddL base (LShiftL index scale)) disp)); 6955 6956 format %{ "leaq $dst, [$base + $index << $scale + $disp]\t# long" %} 6957 ins_encode %{ 6958 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 6959 __ leaq($dst$$Register, Address($base$$Register, $index$$Register, scale, $disp$$constant)); 6960 %} 6961 ins_pipe(ialu_reg_reg); 6962 %} 6963 6964 instruct addP_rReg(rRegP dst, rRegL src, rFlagsReg cr) 6965 %{ 6966 match(Set dst (AddP dst src)); 6967 effect(KILL cr); 6968 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 6969 6970 format %{ "addq $dst, $src\t# ptr" %} 6971 ins_encode %{ 6972 __ addq($dst$$Register, $src$$Register); 6973 %} 6974 ins_pipe(ialu_reg_reg); 6975 %} 6976 6977 instruct addP_rReg_imm(rRegP dst, immL32 src, rFlagsReg cr) 6978 %{ 6979 match(Set dst (AddP dst src)); 6980 effect(KILL cr); 6981 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 6982 6983 format %{ "addq $dst, $src\t# ptr" %} 6984 ins_encode %{ 6985 __ addq($dst$$Register, $src$$constant); 6986 %} 6987 ins_pipe( ialu_reg ); 6988 %} 6989 6990 // XXX addP mem ops ???? 6991 6992 instruct checkCastPP(rRegP dst) 6993 %{ 6994 match(Set dst (CheckCastPP dst)); 6995 6996 size(0); 6997 format %{ "# checkcastPP of $dst" %} 6998 ins_encode(/* empty encoding */); 6999 ins_pipe(empty); 7000 %} 7001 7002 instruct castPP(rRegP dst) 7003 %{ 7004 match(Set dst (CastPP dst)); 7005 7006 size(0); 7007 format %{ "# castPP of $dst" %} 7008 ins_encode(/* empty encoding */); 7009 ins_pipe(empty); 7010 %} 7011 7012 instruct castII(rRegI dst) 7013 %{ 7014 match(Set dst (CastII dst)); 7015 7016 size(0); 7017 format %{ "# castII of $dst" %} 7018 ins_encode(/* empty encoding */); 7019 ins_cost(0); 7020 ins_pipe(empty); 7021 %} 7022 7023 instruct castLL(rRegL dst) 7024 %{ 7025 match(Set dst (CastLL dst)); 7026 7027 size(0); 7028 format %{ "# castLL of $dst" %} 7029 ins_encode(/* empty encoding */); 7030 ins_cost(0); 7031 ins_pipe(empty); 7032 %} 7033 7034 instruct castFF(regF dst) 7035 %{ 7036 match(Set dst (CastFF dst)); 7037 7038 size(0); 7039 format %{ "# castFF of $dst" %} 7040 ins_encode(/* empty encoding */); 7041 ins_cost(0); 7042 ins_pipe(empty); 7043 %} 7044 7045 instruct castDD(regD dst) 7046 %{ 7047 match(Set dst (CastDD dst)); 7048 7049 size(0); 7050 format %{ "# castDD of $dst" %} 7051 ins_encode(/* empty encoding */); 7052 ins_cost(0); 7053 ins_pipe(empty); 7054 %} 7055 7056 // XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them 7057 instruct compareAndSwapP(rRegI res, 7058 memory mem_ptr, 7059 rax_RegP oldval, rRegP newval, 7060 rFlagsReg cr) 7061 %{ 7062 predicate(n->as_LoadStore()->barrier_data() == 0); 7063 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); 7064 match(Set res (WeakCompareAndSwapP mem_ptr (Binary oldval newval))); 7065 effect(KILL cr, KILL oldval); 7066 7067 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7068 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7069 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7070 ins_encode %{ 7071 __ lock(); 7072 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7073 __ setcc(Assembler::equal, $res$$Register); 7074 %} 7075 ins_pipe( pipe_cmpxchg ); 7076 %} 7077 7078 instruct compareAndSwapL(rRegI res, 7079 memory mem_ptr, 7080 rax_RegL oldval, rRegL newval, 7081 rFlagsReg cr) 7082 %{ 7083 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval))); 7084 match(Set res (WeakCompareAndSwapL mem_ptr (Binary oldval newval))); 7085 effect(KILL cr, KILL oldval); 7086 7087 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7088 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7089 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7090 ins_encode %{ 7091 __ lock(); 7092 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7093 __ setcc(Assembler::equal, $res$$Register); 7094 %} 7095 ins_pipe( pipe_cmpxchg ); 7096 %} 7097 7098 instruct compareAndSwapI(rRegI res, 7099 memory mem_ptr, 7100 rax_RegI oldval, rRegI newval, 7101 rFlagsReg cr) 7102 %{ 7103 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval))); 7104 match(Set res (WeakCompareAndSwapI mem_ptr (Binary oldval newval))); 7105 effect(KILL cr, KILL oldval); 7106 7107 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7108 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7109 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7110 ins_encode %{ 7111 __ lock(); 7112 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7113 __ setcc(Assembler::equal, $res$$Register); 7114 %} 7115 ins_pipe( pipe_cmpxchg ); 7116 %} 7117 7118 instruct compareAndSwapB(rRegI res, 7119 memory mem_ptr, 7120 rax_RegI oldval, rRegI newval, 7121 rFlagsReg cr) 7122 %{ 7123 match(Set res (CompareAndSwapB mem_ptr (Binary oldval newval))); 7124 match(Set res (WeakCompareAndSwapB mem_ptr (Binary oldval newval))); 7125 effect(KILL cr, KILL oldval); 7126 7127 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7128 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7129 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7130 ins_encode %{ 7131 __ lock(); 7132 __ cmpxchgb($newval$$Register, $mem_ptr$$Address); 7133 __ setcc(Assembler::equal, $res$$Register); 7134 %} 7135 ins_pipe( pipe_cmpxchg ); 7136 %} 7137 7138 instruct compareAndSwapS(rRegI res, 7139 memory mem_ptr, 7140 rax_RegI oldval, rRegI newval, 7141 rFlagsReg cr) 7142 %{ 7143 match(Set res (CompareAndSwapS mem_ptr (Binary oldval newval))); 7144 match(Set res (WeakCompareAndSwapS mem_ptr (Binary oldval newval))); 7145 effect(KILL cr, KILL oldval); 7146 7147 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7148 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7149 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7150 ins_encode %{ 7151 __ lock(); 7152 __ cmpxchgw($newval$$Register, $mem_ptr$$Address); 7153 __ setcc(Assembler::equal, $res$$Register); 7154 %} 7155 ins_pipe( pipe_cmpxchg ); 7156 %} 7157 7158 instruct compareAndSwapN(rRegI res, 7159 memory mem_ptr, 7160 rax_RegN oldval, rRegN newval, 7161 rFlagsReg cr) %{ 7162 predicate(n->as_LoadStore()->barrier_data() == 0); 7163 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval))); 7164 match(Set res (WeakCompareAndSwapN mem_ptr (Binary oldval newval))); 7165 effect(KILL cr, KILL oldval); 7166 7167 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7168 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7169 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7170 ins_encode %{ 7171 __ lock(); 7172 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7173 __ setcc(Assembler::equal, $res$$Register); 7174 %} 7175 ins_pipe( pipe_cmpxchg ); 7176 %} 7177 7178 instruct compareAndExchangeB( 7179 memory mem_ptr, 7180 rax_RegI oldval, rRegI newval, 7181 rFlagsReg cr) 7182 %{ 7183 match(Set oldval (CompareAndExchangeB mem_ptr (Binary oldval newval))); 7184 effect(KILL cr); 7185 7186 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7187 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7188 ins_encode %{ 7189 __ lock(); 7190 __ cmpxchgb($newval$$Register, $mem_ptr$$Address); 7191 %} 7192 ins_pipe( pipe_cmpxchg ); 7193 %} 7194 7195 instruct compareAndExchangeS( 7196 memory mem_ptr, 7197 rax_RegI oldval, rRegI newval, 7198 rFlagsReg cr) 7199 %{ 7200 match(Set oldval (CompareAndExchangeS mem_ptr (Binary oldval newval))); 7201 effect(KILL cr); 7202 7203 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7204 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7205 ins_encode %{ 7206 __ lock(); 7207 __ cmpxchgw($newval$$Register, $mem_ptr$$Address); 7208 %} 7209 ins_pipe( pipe_cmpxchg ); 7210 %} 7211 7212 instruct compareAndExchangeI( 7213 memory mem_ptr, 7214 rax_RegI oldval, rRegI newval, 7215 rFlagsReg cr) 7216 %{ 7217 match(Set oldval (CompareAndExchangeI mem_ptr (Binary oldval newval))); 7218 effect(KILL cr); 7219 7220 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7221 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7222 ins_encode %{ 7223 __ lock(); 7224 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7225 %} 7226 ins_pipe( pipe_cmpxchg ); 7227 %} 7228 7229 instruct compareAndExchangeL( 7230 memory mem_ptr, 7231 rax_RegL oldval, rRegL newval, 7232 rFlagsReg cr) 7233 %{ 7234 match(Set oldval (CompareAndExchangeL mem_ptr (Binary oldval newval))); 7235 effect(KILL cr); 7236 7237 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7238 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7239 ins_encode %{ 7240 __ lock(); 7241 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7242 %} 7243 ins_pipe( pipe_cmpxchg ); 7244 %} 7245 7246 instruct compareAndExchangeN( 7247 memory mem_ptr, 7248 rax_RegN oldval, rRegN newval, 7249 rFlagsReg cr) %{ 7250 predicate(n->as_LoadStore()->barrier_data() == 0); 7251 match(Set oldval (CompareAndExchangeN mem_ptr (Binary oldval newval))); 7252 effect(KILL cr); 7253 7254 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7255 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7256 ins_encode %{ 7257 __ lock(); 7258 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7259 %} 7260 ins_pipe( pipe_cmpxchg ); 7261 %} 7262 7263 instruct compareAndExchangeP( 7264 memory mem_ptr, 7265 rax_RegP oldval, rRegP newval, 7266 rFlagsReg cr) 7267 %{ 7268 predicate(n->as_LoadStore()->barrier_data() == 0); 7269 match(Set oldval (CompareAndExchangeP mem_ptr (Binary oldval newval))); 7270 effect(KILL cr); 7271 7272 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7273 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7274 ins_encode %{ 7275 __ lock(); 7276 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7277 %} 7278 ins_pipe( pipe_cmpxchg ); 7279 %} 7280 7281 instruct xaddB_reg_no_res(memory mem, Universe dummy, rRegI add, rFlagsReg cr) %{ 7282 predicate(n->as_LoadStore()->result_not_used()); 7283 match(Set dummy (GetAndAddB mem add)); 7284 effect(KILL cr); 7285 format %{ "addb_lock $mem, $add" %} 7286 ins_encode %{ 7287 __ lock(); 7288 __ addb($mem$$Address, $add$$Register); 7289 %} 7290 ins_pipe(pipe_cmpxchg); 7291 %} 7292 7293 instruct xaddB_imm_no_res(memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7294 predicate(n->as_LoadStore()->result_not_used()); 7295 match(Set dummy (GetAndAddB mem add)); 7296 effect(KILL cr); 7297 format %{ "addb_lock $mem, $add" %} 7298 ins_encode %{ 7299 __ lock(); 7300 __ addb($mem$$Address, $add$$constant); 7301 %} 7302 ins_pipe(pipe_cmpxchg); 7303 %} 7304 7305 instruct xaddB(memory mem, rRegI newval, rFlagsReg cr) %{ 7306 predicate(!n->as_LoadStore()->result_not_used()); 7307 match(Set newval (GetAndAddB mem newval)); 7308 effect(KILL cr); 7309 format %{ "xaddb_lock $mem, $newval" %} 7310 ins_encode %{ 7311 __ lock(); 7312 __ xaddb($mem$$Address, $newval$$Register); 7313 %} 7314 ins_pipe(pipe_cmpxchg); 7315 %} 7316 7317 instruct xaddS_reg_no_res(memory mem, Universe dummy, rRegI add, rFlagsReg cr) %{ 7318 predicate(n->as_LoadStore()->result_not_used()); 7319 match(Set dummy (GetAndAddS mem add)); 7320 effect(KILL cr); 7321 format %{ "addw_lock $mem, $add" %} 7322 ins_encode %{ 7323 __ lock(); 7324 __ addw($mem$$Address, $add$$Register); 7325 %} 7326 ins_pipe(pipe_cmpxchg); 7327 %} 7328 7329 instruct xaddS_imm_no_res(memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7330 predicate(UseStoreImmI16 && n->as_LoadStore()->result_not_used()); 7331 match(Set dummy (GetAndAddS mem add)); 7332 effect(KILL cr); 7333 format %{ "addw_lock $mem, $add" %} 7334 ins_encode %{ 7335 __ lock(); 7336 __ addw($mem$$Address, $add$$constant); 7337 %} 7338 ins_pipe(pipe_cmpxchg); 7339 %} 7340 7341 instruct xaddS(memory mem, rRegI newval, rFlagsReg cr) %{ 7342 predicate(!n->as_LoadStore()->result_not_used()); 7343 match(Set newval (GetAndAddS mem newval)); 7344 effect(KILL cr); 7345 format %{ "xaddw_lock $mem, $newval" %} 7346 ins_encode %{ 7347 __ lock(); 7348 __ xaddw($mem$$Address, $newval$$Register); 7349 %} 7350 ins_pipe(pipe_cmpxchg); 7351 %} 7352 7353 instruct xaddI_reg_no_res(memory mem, Universe dummy, rRegI add, rFlagsReg cr) %{ 7354 predicate(n->as_LoadStore()->result_not_used()); 7355 match(Set dummy (GetAndAddI mem add)); 7356 effect(KILL cr); 7357 format %{ "addl_lock $mem, $add" %} 7358 ins_encode %{ 7359 __ lock(); 7360 __ addl($mem$$Address, $add$$Register); 7361 %} 7362 ins_pipe(pipe_cmpxchg); 7363 %} 7364 7365 instruct xaddI_imm_no_res(memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7366 predicate(n->as_LoadStore()->result_not_used()); 7367 match(Set dummy (GetAndAddI mem add)); 7368 effect(KILL cr); 7369 format %{ "addl_lock $mem, $add" %} 7370 ins_encode %{ 7371 __ lock(); 7372 __ addl($mem$$Address, $add$$constant); 7373 %} 7374 ins_pipe(pipe_cmpxchg); 7375 %} 7376 7377 instruct xaddI(memory mem, rRegI newval, rFlagsReg cr) %{ 7378 predicate(!n->as_LoadStore()->result_not_used()); 7379 match(Set newval (GetAndAddI mem newval)); 7380 effect(KILL cr); 7381 format %{ "xaddl_lock $mem, $newval" %} 7382 ins_encode %{ 7383 __ lock(); 7384 __ xaddl($mem$$Address, $newval$$Register); 7385 %} 7386 ins_pipe(pipe_cmpxchg); 7387 %} 7388 7389 instruct xaddL_reg_no_res(memory mem, Universe dummy, rRegL add, rFlagsReg cr) %{ 7390 predicate(n->as_LoadStore()->result_not_used()); 7391 match(Set dummy (GetAndAddL mem add)); 7392 effect(KILL cr); 7393 format %{ "addq_lock $mem, $add" %} 7394 ins_encode %{ 7395 __ lock(); 7396 __ addq($mem$$Address, $add$$Register); 7397 %} 7398 ins_pipe(pipe_cmpxchg); 7399 %} 7400 7401 instruct xaddL_imm_no_res(memory mem, Universe dummy, immL32 add, rFlagsReg cr) %{ 7402 predicate(n->as_LoadStore()->result_not_used()); 7403 match(Set dummy (GetAndAddL mem add)); 7404 effect(KILL cr); 7405 format %{ "addq_lock $mem, $add" %} 7406 ins_encode %{ 7407 __ lock(); 7408 __ addq($mem$$Address, $add$$constant); 7409 %} 7410 ins_pipe(pipe_cmpxchg); 7411 %} 7412 7413 instruct xaddL(memory mem, rRegL newval, rFlagsReg cr) %{ 7414 predicate(!n->as_LoadStore()->result_not_used()); 7415 match(Set newval (GetAndAddL mem newval)); 7416 effect(KILL cr); 7417 format %{ "xaddq_lock $mem, $newval" %} 7418 ins_encode %{ 7419 __ lock(); 7420 __ xaddq($mem$$Address, $newval$$Register); 7421 %} 7422 ins_pipe(pipe_cmpxchg); 7423 %} 7424 7425 instruct xchgB( memory mem, rRegI newval) %{ 7426 match(Set newval (GetAndSetB mem newval)); 7427 format %{ "XCHGB $newval,[$mem]" %} 7428 ins_encode %{ 7429 __ xchgb($newval$$Register, $mem$$Address); 7430 %} 7431 ins_pipe( pipe_cmpxchg ); 7432 %} 7433 7434 instruct xchgS( memory mem, rRegI newval) %{ 7435 match(Set newval (GetAndSetS mem newval)); 7436 format %{ "XCHGW $newval,[$mem]" %} 7437 ins_encode %{ 7438 __ xchgw($newval$$Register, $mem$$Address); 7439 %} 7440 ins_pipe( pipe_cmpxchg ); 7441 %} 7442 7443 instruct xchgI( memory mem, rRegI newval) %{ 7444 match(Set newval (GetAndSetI mem newval)); 7445 format %{ "XCHGL $newval,[$mem]" %} 7446 ins_encode %{ 7447 __ xchgl($newval$$Register, $mem$$Address); 7448 %} 7449 ins_pipe( pipe_cmpxchg ); 7450 %} 7451 7452 instruct xchgL( memory mem, rRegL newval) %{ 7453 match(Set newval (GetAndSetL mem newval)); 7454 format %{ "XCHGL $newval,[$mem]" %} 7455 ins_encode %{ 7456 __ xchgq($newval$$Register, $mem$$Address); 7457 %} 7458 ins_pipe( pipe_cmpxchg ); 7459 %} 7460 7461 instruct xchgP( memory mem, rRegP newval) %{ 7462 match(Set newval (GetAndSetP mem newval)); 7463 predicate(n->as_LoadStore()->barrier_data() == 0); 7464 format %{ "XCHGQ $newval,[$mem]" %} 7465 ins_encode %{ 7466 __ xchgq($newval$$Register, $mem$$Address); 7467 %} 7468 ins_pipe( pipe_cmpxchg ); 7469 %} 7470 7471 instruct xchgN( memory mem, rRegN newval) %{ 7472 predicate(n->as_LoadStore()->barrier_data() == 0); 7473 match(Set newval (GetAndSetN mem newval)); 7474 format %{ "XCHGL $newval,$mem]" %} 7475 ins_encode %{ 7476 __ xchgl($newval$$Register, $mem$$Address); 7477 %} 7478 ins_pipe( pipe_cmpxchg ); 7479 %} 7480 7481 //----------Abs Instructions------------------------------------------- 7482 7483 // Integer Absolute Instructions 7484 instruct absI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7485 %{ 7486 match(Set dst (AbsI src)); 7487 effect(TEMP dst, KILL cr); 7488 format %{ "xorl $dst, $dst\t# abs int\n\t" 7489 "subl $dst, $src\n\t" 7490 "cmovll $dst, $src" %} 7491 ins_encode %{ 7492 __ xorl($dst$$Register, $dst$$Register); 7493 __ subl($dst$$Register, $src$$Register); 7494 __ cmovl(Assembler::less, $dst$$Register, $src$$Register); 7495 %} 7496 7497 ins_pipe(ialu_reg_reg); 7498 %} 7499 7500 // Long Absolute Instructions 7501 instruct absL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7502 %{ 7503 match(Set dst (AbsL src)); 7504 effect(TEMP dst, KILL cr); 7505 format %{ "xorl $dst, $dst\t# abs long\n\t" 7506 "subq $dst, $src\n\t" 7507 "cmovlq $dst, $src" %} 7508 ins_encode %{ 7509 __ xorl($dst$$Register, $dst$$Register); 7510 __ subq($dst$$Register, $src$$Register); 7511 __ cmovq(Assembler::less, $dst$$Register, $src$$Register); 7512 %} 7513 7514 ins_pipe(ialu_reg_reg); 7515 %} 7516 7517 //----------Subtraction Instructions------------------------------------------- 7518 7519 // Integer Subtraction Instructions 7520 instruct subI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7521 %{ 7522 match(Set dst (SubI dst src)); 7523 effect(KILL cr); 7524 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); 7525 7526 format %{ "subl $dst, $src\t# int" %} 7527 ins_encode %{ 7528 __ subl($dst$$Register, $src$$Register); 7529 %} 7530 ins_pipe(ialu_reg_reg); 7531 %} 7532 7533 instruct subI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 7534 %{ 7535 match(Set dst (SubI dst (LoadI src))); 7536 effect(KILL cr); 7537 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); 7538 7539 ins_cost(150); 7540 format %{ "subl $dst, $src\t# int" %} 7541 ins_encode %{ 7542 __ subl($dst$$Register, $src$$Address); 7543 %} 7544 ins_pipe(ialu_reg_mem); 7545 %} 7546 7547 instruct subI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 7548 %{ 7549 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 7550 effect(KILL cr); 7551 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); 7552 7553 ins_cost(150); 7554 format %{ "subl $dst, $src\t# int" %} 7555 ins_encode %{ 7556 __ subl($dst$$Address, $src$$Register); 7557 %} 7558 ins_pipe(ialu_mem_reg); 7559 %} 7560 7561 instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7562 %{ 7563 match(Set dst (SubL dst src)); 7564 effect(KILL cr); 7565 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); 7566 7567 format %{ "subq $dst, $src\t# long" %} 7568 ins_encode %{ 7569 __ subq($dst$$Register, $src$$Register); 7570 %} 7571 ins_pipe(ialu_reg_reg); 7572 %} 7573 7574 instruct subL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 7575 %{ 7576 match(Set dst (SubL dst (LoadL src))); 7577 effect(KILL cr); 7578 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); 7579 7580 ins_cost(150); 7581 format %{ "subq $dst, $src\t# long" %} 7582 ins_encode %{ 7583 __ subq($dst$$Register, $src$$Address); 7584 %} 7585 ins_pipe(ialu_reg_mem); 7586 %} 7587 7588 instruct subL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 7589 %{ 7590 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 7591 effect(KILL cr); 7592 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 7593 7594 ins_cost(150); 7595 format %{ "subq $dst, $src\t# long" %} 7596 ins_encode %{ 7597 __ subq($dst$$Address, $src$$Register); 7598 %} 7599 ins_pipe(ialu_mem_reg); 7600 %} 7601 7602 // Subtract from a pointer 7603 // XXX hmpf??? 7604 instruct subP_rReg(rRegP dst, rRegI src, immI_0 zero, rFlagsReg cr) 7605 %{ 7606 match(Set dst (AddP dst (SubI zero src))); 7607 effect(KILL cr); 7608 7609 format %{ "subq $dst, $src\t# ptr - int" %} 7610 ins_encode %{ 7611 __ subq($dst$$Register, $src$$Register); 7612 %} 7613 ins_pipe(ialu_reg_reg); 7614 %} 7615 7616 instruct negI_rReg(rRegI dst, immI_0 zero, rFlagsReg cr) 7617 %{ 7618 match(Set dst (SubI zero dst)); 7619 effect(KILL cr); 7620 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7621 7622 format %{ "negl $dst\t# int" %} 7623 ins_encode %{ 7624 __ negl($dst$$Register); 7625 %} 7626 ins_pipe(ialu_reg); 7627 %} 7628 7629 instruct negI_rReg_2(rRegI dst, rFlagsReg cr) 7630 %{ 7631 match(Set dst (NegI dst)); 7632 effect(KILL cr); 7633 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7634 7635 format %{ "negl $dst\t# int" %} 7636 ins_encode %{ 7637 __ negl($dst$$Register); 7638 %} 7639 ins_pipe(ialu_reg); 7640 %} 7641 7642 instruct negI_mem(memory dst, immI_0 zero, rFlagsReg cr) 7643 %{ 7644 match(Set dst (StoreI dst (SubI zero (LoadI dst)))); 7645 effect(KILL cr); 7646 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7647 7648 format %{ "negl $dst\t# int" %} 7649 ins_encode %{ 7650 __ negl($dst$$Address); 7651 %} 7652 ins_pipe(ialu_reg); 7653 %} 7654 7655 instruct negL_rReg(rRegL dst, immL0 zero, rFlagsReg cr) 7656 %{ 7657 match(Set dst (SubL zero dst)); 7658 effect(KILL cr); 7659 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7660 7661 format %{ "negq $dst\t# long" %} 7662 ins_encode %{ 7663 __ negq($dst$$Register); 7664 %} 7665 ins_pipe(ialu_reg); 7666 %} 7667 7668 instruct negL_rReg_2(rRegL dst, rFlagsReg cr) 7669 %{ 7670 match(Set dst (NegL dst)); 7671 effect(KILL cr); 7672 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7673 7674 format %{ "negq $dst\t# int" %} 7675 ins_encode %{ 7676 __ negq($dst$$Register); 7677 %} 7678 ins_pipe(ialu_reg); 7679 %} 7680 7681 instruct negL_mem(memory dst, immL0 zero, rFlagsReg cr) 7682 %{ 7683 match(Set dst (StoreL dst (SubL zero (LoadL dst)))); 7684 effect(KILL cr); 7685 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7686 7687 format %{ "negq $dst\t# long" %} 7688 ins_encode %{ 7689 __ negq($dst$$Address); 7690 %} 7691 ins_pipe(ialu_reg); 7692 %} 7693 7694 //----------Multiplication/Division Instructions------------------------------- 7695 // Integer Multiplication Instructions 7696 // Multiply Register 7697 7698 instruct mulI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7699 %{ 7700 match(Set dst (MulI dst src)); 7701 effect(KILL cr); 7702 7703 ins_cost(300); 7704 format %{ "imull $dst, $src\t# int" %} 7705 ins_encode %{ 7706 __ imull($dst$$Register, $src$$Register); 7707 %} 7708 ins_pipe(ialu_reg_reg_alu0); 7709 %} 7710 7711 instruct mulI_rReg_imm(rRegI dst, rRegI src, immI imm, rFlagsReg cr) 7712 %{ 7713 match(Set dst (MulI src imm)); 7714 effect(KILL cr); 7715 7716 ins_cost(300); 7717 format %{ "imull $dst, $src, $imm\t# int" %} 7718 ins_encode %{ 7719 __ imull($dst$$Register, $src$$Register, $imm$$constant); 7720 %} 7721 ins_pipe(ialu_reg_reg_alu0); 7722 %} 7723 7724 instruct mulI_mem(rRegI dst, memory src, rFlagsReg cr) 7725 %{ 7726 match(Set dst (MulI dst (LoadI src))); 7727 effect(KILL cr); 7728 7729 ins_cost(350); 7730 format %{ "imull $dst, $src\t# int" %} 7731 ins_encode %{ 7732 __ imull($dst$$Register, $src$$Address); 7733 %} 7734 ins_pipe(ialu_reg_mem_alu0); 7735 %} 7736 7737 instruct mulI_mem_imm(rRegI dst, memory src, immI imm, rFlagsReg cr) 7738 %{ 7739 match(Set dst (MulI (LoadI src) imm)); 7740 effect(KILL cr); 7741 7742 ins_cost(300); 7743 format %{ "imull $dst, $src, $imm\t# int" %} 7744 ins_encode %{ 7745 __ imull($dst$$Register, $src$$Address, $imm$$constant); 7746 %} 7747 ins_pipe(ialu_reg_mem_alu0); 7748 %} 7749 7750 instruct mulAddS2I_rReg(rRegI dst, rRegI src1, rRegI src2, rRegI src3, rFlagsReg cr) 7751 %{ 7752 match(Set dst (MulAddS2I (Binary dst src1) (Binary src2 src3))); 7753 effect(KILL cr, KILL src2); 7754 7755 expand %{ mulI_rReg(dst, src1, cr); 7756 mulI_rReg(src2, src3, cr); 7757 addI_rReg(dst, src2, cr); %} 7758 %} 7759 7760 instruct mulL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7761 %{ 7762 match(Set dst (MulL dst src)); 7763 effect(KILL cr); 7764 7765 ins_cost(300); 7766 format %{ "imulq $dst, $src\t# long" %} 7767 ins_encode %{ 7768 __ imulq($dst$$Register, $src$$Register); 7769 %} 7770 ins_pipe(ialu_reg_reg_alu0); 7771 %} 7772 7773 instruct mulL_rReg_imm(rRegL dst, rRegL src, immL32 imm, rFlagsReg cr) 7774 %{ 7775 match(Set dst (MulL src imm)); 7776 effect(KILL cr); 7777 7778 ins_cost(300); 7779 format %{ "imulq $dst, $src, $imm\t# long" %} 7780 ins_encode %{ 7781 __ imulq($dst$$Register, $src$$Register, $imm$$constant); 7782 %} 7783 ins_pipe(ialu_reg_reg_alu0); 7784 %} 7785 7786 instruct mulL_mem(rRegL dst, memory src, rFlagsReg cr) 7787 %{ 7788 match(Set dst (MulL dst (LoadL src))); 7789 effect(KILL cr); 7790 7791 ins_cost(350); 7792 format %{ "imulq $dst, $src\t# long" %} 7793 ins_encode %{ 7794 __ imulq($dst$$Register, $src$$Address); 7795 %} 7796 ins_pipe(ialu_reg_mem_alu0); 7797 %} 7798 7799 instruct mulL_mem_imm(rRegL dst, memory src, immL32 imm, rFlagsReg cr) 7800 %{ 7801 match(Set dst (MulL (LoadL src) imm)); 7802 effect(KILL cr); 7803 7804 ins_cost(300); 7805 format %{ "imulq $dst, $src, $imm\t# long" %} 7806 ins_encode %{ 7807 __ imulq($dst$$Register, $src$$Address, $imm$$constant); 7808 %} 7809 ins_pipe(ialu_reg_mem_alu0); 7810 %} 7811 7812 instruct mulHiL_rReg(rdx_RegL dst, rRegL src, rax_RegL rax, rFlagsReg cr) 7813 %{ 7814 match(Set dst (MulHiL src rax)); 7815 effect(USE_KILL rax, KILL cr); 7816 7817 ins_cost(300); 7818 format %{ "imulq RDX:RAX, RAX, $src\t# mulhi" %} 7819 ins_encode %{ 7820 __ imulq($src$$Register); 7821 %} 7822 ins_pipe(ialu_reg_reg_alu0); 7823 %} 7824 7825 instruct umulHiL_rReg(rdx_RegL dst, rRegL src, rax_RegL rax, rFlagsReg cr) 7826 %{ 7827 match(Set dst (UMulHiL src rax)); 7828 effect(USE_KILL rax, KILL cr); 7829 7830 ins_cost(300); 7831 format %{ "mulq RDX:RAX, RAX, $src\t# umulhi" %} 7832 ins_encode %{ 7833 __ mulq($src$$Register); 7834 %} 7835 ins_pipe(ialu_reg_reg_alu0); 7836 %} 7837 7838 instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 7839 rFlagsReg cr) 7840 %{ 7841 match(Set rax (DivI rax div)); 7842 effect(KILL rdx, KILL cr); 7843 7844 ins_cost(30*100+10*100); // XXX 7845 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 7846 "jne,s normal\n\t" 7847 "xorl rdx, rdx\n\t" 7848 "cmpl $div, -1\n\t" 7849 "je,s done\n" 7850 "normal: cdql\n\t" 7851 "idivl $div\n" 7852 "done:" %} 7853 ins_encode(cdql_enc(div)); 7854 ins_pipe(ialu_reg_reg_alu0); 7855 %} 7856 7857 instruct divL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 7858 rFlagsReg cr) 7859 %{ 7860 match(Set rax (DivL rax div)); 7861 effect(KILL rdx, KILL cr); 7862 7863 ins_cost(30*100+10*100); // XXX 7864 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 7865 "cmpq rax, rdx\n\t" 7866 "jne,s normal\n\t" 7867 "xorl rdx, rdx\n\t" 7868 "cmpq $div, -1\n\t" 7869 "je,s done\n" 7870 "normal: cdqq\n\t" 7871 "idivq $div\n" 7872 "done:" %} 7873 ins_encode(cdqq_enc(div)); 7874 ins_pipe(ialu_reg_reg_alu0); 7875 %} 7876 7877 instruct udivI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, rFlagsReg cr) 7878 %{ 7879 match(Set rax (UDivI rax div)); 7880 effect(KILL rdx, KILL cr); 7881 7882 ins_cost(300); 7883 format %{ "udivl $rax,$rax,$div\t# UDivI\n" %} 7884 ins_encode %{ 7885 __ udivI($rax$$Register, $div$$Register, $rdx$$Register); 7886 %} 7887 ins_pipe(ialu_reg_reg_alu0); 7888 %} 7889 7890 instruct udivL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, rFlagsReg cr) 7891 %{ 7892 match(Set rax (UDivL rax div)); 7893 effect(KILL rdx, KILL cr); 7894 7895 ins_cost(300); 7896 format %{ "udivq $rax,$rax,$div\t# UDivL\n" %} 7897 ins_encode %{ 7898 __ udivL($rax$$Register, $div$$Register, $rdx$$Register); 7899 %} 7900 ins_pipe(ialu_reg_reg_alu0); 7901 %} 7902 7903 // Integer DIVMOD with Register, both quotient and mod results 7904 instruct divModI_rReg_divmod(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 7905 rFlagsReg cr) 7906 %{ 7907 match(DivModI rax div); 7908 effect(KILL cr); 7909 7910 ins_cost(30*100+10*100); // XXX 7911 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 7912 "jne,s normal\n\t" 7913 "xorl rdx, rdx\n\t" 7914 "cmpl $div, -1\n\t" 7915 "je,s done\n" 7916 "normal: cdql\n\t" 7917 "idivl $div\n" 7918 "done:" %} 7919 ins_encode(cdql_enc(div)); 7920 ins_pipe(pipe_slow); 7921 %} 7922 7923 // Long DIVMOD with Register, both quotient and mod results 7924 instruct divModL_rReg_divmod(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 7925 rFlagsReg cr) 7926 %{ 7927 match(DivModL rax div); 7928 effect(KILL cr); 7929 7930 ins_cost(30*100+10*100); // XXX 7931 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 7932 "cmpq rax, rdx\n\t" 7933 "jne,s normal\n\t" 7934 "xorl rdx, rdx\n\t" 7935 "cmpq $div, -1\n\t" 7936 "je,s done\n" 7937 "normal: cdqq\n\t" 7938 "idivq $div\n" 7939 "done:" %} 7940 ins_encode(cdqq_enc(div)); 7941 ins_pipe(pipe_slow); 7942 %} 7943 7944 // Unsigned integer DIVMOD with Register, both quotient and mod results 7945 instruct udivModI_rReg_divmod(rax_RegI rax, no_rax_rdx_RegI tmp, rdx_RegI rdx, 7946 no_rax_rdx_RegI div, rFlagsReg cr) 7947 %{ 7948 match(UDivModI rax div); 7949 effect(TEMP tmp, KILL cr); 7950 7951 ins_cost(300); 7952 format %{ "udivl $rax,$rax,$div\t# begin UDivModI\n\t" 7953 "umodl $rdx,$rax,$div\t! using $tmp as TEMP # end UDivModI\n" 7954 %} 7955 ins_encode %{ 7956 __ udivmodI($rax$$Register, $div$$Register, $rdx$$Register, $tmp$$Register); 7957 %} 7958 ins_pipe(pipe_slow); 7959 %} 7960 7961 // Unsigned long DIVMOD with Register, both quotient and mod results 7962 instruct udivModL_rReg_divmod(rax_RegL rax, no_rax_rdx_RegL tmp, rdx_RegL rdx, 7963 no_rax_rdx_RegL div, rFlagsReg cr) 7964 %{ 7965 match(UDivModL rax div); 7966 effect(TEMP tmp, KILL cr); 7967 7968 ins_cost(300); 7969 format %{ "udivq $rax,$rax,$div\t# begin UDivModL\n\t" 7970 "umodq $rdx,$rax,$div\t! using $tmp as TEMP # end UDivModL\n" 7971 %} 7972 ins_encode %{ 7973 __ udivmodL($rax$$Register, $div$$Register, $rdx$$Register, $tmp$$Register); 7974 %} 7975 ins_pipe(pipe_slow); 7976 %} 7977 7978 instruct modI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, 7979 rFlagsReg cr) 7980 %{ 7981 match(Set rdx (ModI rax div)); 7982 effect(KILL rax, KILL cr); 7983 7984 ins_cost(300); // XXX 7985 format %{ "cmpl rax, 0x80000000\t# irem\n\t" 7986 "jne,s normal\n\t" 7987 "xorl rdx, rdx\n\t" 7988 "cmpl $div, -1\n\t" 7989 "je,s done\n" 7990 "normal: cdql\n\t" 7991 "idivl $div\n" 7992 "done:" %} 7993 ins_encode(cdql_enc(div)); 7994 ins_pipe(ialu_reg_reg_alu0); 7995 %} 7996 7997 instruct modL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, 7998 rFlagsReg cr) 7999 %{ 8000 match(Set rdx (ModL rax div)); 8001 effect(KILL rax, KILL cr); 8002 8003 ins_cost(300); // XXX 8004 format %{ "movq rdx, 0x8000000000000000\t# lrem\n\t" 8005 "cmpq rax, rdx\n\t" 8006 "jne,s normal\n\t" 8007 "xorl rdx, rdx\n\t" 8008 "cmpq $div, -1\n\t" 8009 "je,s done\n" 8010 "normal: cdqq\n\t" 8011 "idivq $div\n" 8012 "done:" %} 8013 ins_encode(cdqq_enc(div)); 8014 ins_pipe(ialu_reg_reg_alu0); 8015 %} 8016 8017 instruct umodI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, rFlagsReg cr) 8018 %{ 8019 match(Set rdx (UModI rax div)); 8020 effect(KILL rax, KILL cr); 8021 8022 ins_cost(300); 8023 format %{ "umodl $rdx,$rax,$div\t# UModI\n" %} 8024 ins_encode %{ 8025 __ umodI($rax$$Register, $div$$Register, $rdx$$Register); 8026 %} 8027 ins_pipe(ialu_reg_reg_alu0); 8028 %} 8029 8030 instruct umodL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, rFlagsReg cr) 8031 %{ 8032 match(Set rdx (UModL rax div)); 8033 effect(KILL rax, KILL cr); 8034 8035 ins_cost(300); 8036 format %{ "umodq $rdx,$rax,$div\t# UModL\n" %} 8037 ins_encode %{ 8038 __ umodL($rax$$Register, $div$$Register, $rdx$$Register); 8039 %} 8040 ins_pipe(ialu_reg_reg_alu0); 8041 %} 8042 8043 // Integer Shift Instructions 8044 // Shift Left by one, two, three 8045 instruct salI_rReg_immI2(rRegI dst, immI2 shift, rFlagsReg cr) 8046 %{ 8047 match(Set dst (LShiftI dst shift)); 8048 effect(KILL cr); 8049 8050 format %{ "sall $dst, $shift" %} 8051 ins_encode %{ 8052 __ sall($dst$$Register, $shift$$constant); 8053 %} 8054 ins_pipe(ialu_reg); 8055 %} 8056 8057 // Shift Left by 8-bit immediate 8058 instruct salI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8059 %{ 8060 match(Set dst (LShiftI dst shift)); 8061 effect(KILL cr); 8062 8063 format %{ "sall $dst, $shift" %} 8064 ins_encode %{ 8065 __ sall($dst$$Register, $shift$$constant); 8066 %} 8067 ins_pipe(ialu_reg); 8068 %} 8069 8070 // Shift Left by 8-bit immediate 8071 instruct salI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8072 %{ 8073 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8074 effect(KILL cr); 8075 8076 format %{ "sall $dst, $shift" %} 8077 ins_encode %{ 8078 __ sall($dst$$Address, $shift$$constant); 8079 %} 8080 ins_pipe(ialu_mem_imm); 8081 %} 8082 8083 // Shift Left by variable 8084 instruct salI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8085 %{ 8086 predicate(!VM_Version::supports_bmi2()); 8087 match(Set dst (LShiftI dst shift)); 8088 effect(KILL cr); 8089 8090 format %{ "sall $dst, $shift" %} 8091 ins_encode %{ 8092 __ sall($dst$$Register); 8093 %} 8094 ins_pipe(ialu_reg_reg); 8095 %} 8096 8097 // Shift Left by variable 8098 instruct salI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8099 %{ 8100 predicate(!VM_Version::supports_bmi2()); 8101 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8102 effect(KILL cr); 8103 8104 format %{ "sall $dst, $shift" %} 8105 ins_encode %{ 8106 __ sall($dst$$Address); 8107 %} 8108 ins_pipe(ialu_mem_reg); 8109 %} 8110 8111 instruct salI_rReg_rReg(rRegI dst, rRegI src, rRegI shift) 8112 %{ 8113 predicate(VM_Version::supports_bmi2()); 8114 match(Set dst (LShiftI src shift)); 8115 8116 format %{ "shlxl $dst, $src, $shift" %} 8117 ins_encode %{ 8118 __ shlxl($dst$$Register, $src$$Register, $shift$$Register); 8119 %} 8120 ins_pipe(ialu_reg_reg); 8121 %} 8122 8123 instruct salI_mem_rReg(rRegI dst, memory src, rRegI shift) 8124 %{ 8125 predicate(VM_Version::supports_bmi2()); 8126 match(Set dst (LShiftI (LoadI src) shift)); 8127 ins_cost(175); 8128 format %{ "shlxl $dst, $src, $shift" %} 8129 ins_encode %{ 8130 __ shlxl($dst$$Register, $src$$Address, $shift$$Register); 8131 %} 8132 ins_pipe(ialu_reg_mem); 8133 %} 8134 8135 // Arithmetic Shift Right by 8-bit immediate 8136 instruct sarI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8137 %{ 8138 match(Set dst (RShiftI dst shift)); 8139 effect(KILL cr); 8140 8141 format %{ "sarl $dst, $shift" %} 8142 ins_encode %{ 8143 __ sarl($dst$$Register, $shift$$constant); 8144 %} 8145 ins_pipe(ialu_mem_imm); 8146 %} 8147 8148 // Arithmetic Shift Right by 8-bit immediate 8149 instruct sarI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8150 %{ 8151 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8152 effect(KILL cr); 8153 8154 format %{ "sarl $dst, $shift" %} 8155 ins_encode %{ 8156 __ sarl($dst$$Address, $shift$$constant); 8157 %} 8158 ins_pipe(ialu_mem_imm); 8159 %} 8160 8161 // Arithmetic Shift Right by variable 8162 instruct sarI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8163 %{ 8164 predicate(!VM_Version::supports_bmi2()); 8165 match(Set dst (RShiftI dst shift)); 8166 effect(KILL cr); 8167 8168 format %{ "sarl $dst, $shift" %} 8169 ins_encode %{ 8170 __ sarl($dst$$Register); 8171 %} 8172 ins_pipe(ialu_reg_reg); 8173 %} 8174 8175 // Arithmetic Shift Right by variable 8176 instruct sarI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8177 %{ 8178 predicate(!VM_Version::supports_bmi2()); 8179 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8180 effect(KILL cr); 8181 8182 format %{ "sarl $dst, $shift" %} 8183 ins_encode %{ 8184 __ sarl($dst$$Address); 8185 %} 8186 ins_pipe(ialu_mem_reg); 8187 %} 8188 8189 instruct sarI_rReg_rReg(rRegI dst, rRegI src, rRegI shift) 8190 %{ 8191 predicate(VM_Version::supports_bmi2()); 8192 match(Set dst (RShiftI src shift)); 8193 8194 format %{ "sarxl $dst, $src, $shift" %} 8195 ins_encode %{ 8196 __ sarxl($dst$$Register, $src$$Register, $shift$$Register); 8197 %} 8198 ins_pipe(ialu_reg_reg); 8199 %} 8200 8201 instruct sarI_mem_rReg(rRegI dst, memory src, rRegI shift) 8202 %{ 8203 predicate(VM_Version::supports_bmi2()); 8204 match(Set dst (RShiftI (LoadI src) shift)); 8205 ins_cost(175); 8206 format %{ "sarxl $dst, $src, $shift" %} 8207 ins_encode %{ 8208 __ sarxl($dst$$Register, $src$$Address, $shift$$Register); 8209 %} 8210 ins_pipe(ialu_reg_mem); 8211 %} 8212 8213 // Logical Shift Right by 8-bit immediate 8214 instruct shrI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8215 %{ 8216 match(Set dst (URShiftI dst shift)); 8217 effect(KILL cr); 8218 8219 format %{ "shrl $dst, $shift" %} 8220 ins_encode %{ 8221 __ shrl($dst$$Register, $shift$$constant); 8222 %} 8223 ins_pipe(ialu_reg); 8224 %} 8225 8226 // Logical Shift Right by 8-bit immediate 8227 instruct shrI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8228 %{ 8229 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8230 effect(KILL cr); 8231 8232 format %{ "shrl $dst, $shift" %} 8233 ins_encode %{ 8234 __ shrl($dst$$Address, $shift$$constant); 8235 %} 8236 ins_pipe(ialu_mem_imm); 8237 %} 8238 8239 // Logical Shift Right by variable 8240 instruct shrI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8241 %{ 8242 predicate(!VM_Version::supports_bmi2()); 8243 match(Set dst (URShiftI dst shift)); 8244 effect(KILL cr); 8245 8246 format %{ "shrl $dst, $shift" %} 8247 ins_encode %{ 8248 __ shrl($dst$$Register); 8249 %} 8250 ins_pipe(ialu_reg_reg); 8251 %} 8252 8253 // Logical Shift Right by variable 8254 instruct shrI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8255 %{ 8256 predicate(!VM_Version::supports_bmi2()); 8257 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8258 effect(KILL cr); 8259 8260 format %{ "shrl $dst, $shift" %} 8261 ins_encode %{ 8262 __ shrl($dst$$Address); 8263 %} 8264 ins_pipe(ialu_mem_reg); 8265 %} 8266 8267 instruct shrI_rReg_rReg(rRegI dst, rRegI src, rRegI shift) 8268 %{ 8269 predicate(VM_Version::supports_bmi2()); 8270 match(Set dst (URShiftI src shift)); 8271 8272 format %{ "shrxl $dst, $src, $shift" %} 8273 ins_encode %{ 8274 __ shrxl($dst$$Register, $src$$Register, $shift$$Register); 8275 %} 8276 ins_pipe(ialu_reg_reg); 8277 %} 8278 8279 instruct shrI_mem_rReg(rRegI dst, memory src, rRegI shift) 8280 %{ 8281 predicate(VM_Version::supports_bmi2()); 8282 match(Set dst (URShiftI (LoadI src) shift)); 8283 ins_cost(175); 8284 format %{ "shrxl $dst, $src, $shift" %} 8285 ins_encode %{ 8286 __ shrxl($dst$$Register, $src$$Address, $shift$$Register); 8287 %} 8288 ins_pipe(ialu_reg_mem); 8289 %} 8290 8291 // Long Shift Instructions 8292 // Shift Left by one, two, three 8293 instruct salL_rReg_immI2(rRegL dst, immI2 shift, rFlagsReg cr) 8294 %{ 8295 match(Set dst (LShiftL dst shift)); 8296 effect(KILL cr); 8297 8298 format %{ "salq $dst, $shift" %} 8299 ins_encode %{ 8300 __ salq($dst$$Register, $shift$$constant); 8301 %} 8302 ins_pipe(ialu_reg); 8303 %} 8304 8305 // Shift Left by 8-bit immediate 8306 instruct salL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8307 %{ 8308 match(Set dst (LShiftL dst shift)); 8309 effect(KILL cr); 8310 8311 format %{ "salq $dst, $shift" %} 8312 ins_encode %{ 8313 __ salq($dst$$Register, $shift$$constant); 8314 %} 8315 ins_pipe(ialu_reg); 8316 %} 8317 8318 // Shift Left by 8-bit immediate 8319 instruct salL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8320 %{ 8321 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8322 effect(KILL cr); 8323 8324 format %{ "salq $dst, $shift" %} 8325 ins_encode %{ 8326 __ salq($dst$$Address, $shift$$constant); 8327 %} 8328 ins_pipe(ialu_mem_imm); 8329 %} 8330 8331 // Shift Left by variable 8332 instruct salL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8333 %{ 8334 predicate(!VM_Version::supports_bmi2()); 8335 match(Set dst (LShiftL dst shift)); 8336 effect(KILL cr); 8337 8338 format %{ "salq $dst, $shift" %} 8339 ins_encode %{ 8340 __ salq($dst$$Register); 8341 %} 8342 ins_pipe(ialu_reg_reg); 8343 %} 8344 8345 // Shift Left by variable 8346 instruct salL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8347 %{ 8348 predicate(!VM_Version::supports_bmi2()); 8349 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8350 effect(KILL cr); 8351 8352 format %{ "salq $dst, $shift" %} 8353 ins_encode %{ 8354 __ salq($dst$$Address); 8355 %} 8356 ins_pipe(ialu_mem_reg); 8357 %} 8358 8359 instruct salL_rReg_rReg(rRegL dst, rRegL src, rRegI shift) 8360 %{ 8361 predicate(VM_Version::supports_bmi2()); 8362 match(Set dst (LShiftL src shift)); 8363 8364 format %{ "shlxq $dst, $src, $shift" %} 8365 ins_encode %{ 8366 __ shlxq($dst$$Register, $src$$Register, $shift$$Register); 8367 %} 8368 ins_pipe(ialu_reg_reg); 8369 %} 8370 8371 instruct salL_mem_rReg(rRegL dst, memory src, rRegI shift) 8372 %{ 8373 predicate(VM_Version::supports_bmi2()); 8374 match(Set dst (LShiftL (LoadL src) shift)); 8375 ins_cost(175); 8376 format %{ "shlxq $dst, $src, $shift" %} 8377 ins_encode %{ 8378 __ shlxq($dst$$Register, $src$$Address, $shift$$Register); 8379 %} 8380 ins_pipe(ialu_reg_mem); 8381 %} 8382 8383 // Arithmetic Shift Right by 8-bit immediate 8384 instruct sarL_rReg_imm(rRegL dst, immI shift, rFlagsReg cr) 8385 %{ 8386 match(Set dst (RShiftL dst shift)); 8387 effect(KILL cr); 8388 8389 format %{ "sarq $dst, $shift" %} 8390 ins_encode %{ 8391 __ sarq($dst$$Register, (unsigned char)($shift$$constant & 0x3F)); 8392 %} 8393 ins_pipe(ialu_mem_imm); 8394 %} 8395 8396 // Arithmetic Shift Right by 8-bit immediate 8397 instruct sarL_mem_imm(memory dst, immI shift, rFlagsReg cr) 8398 %{ 8399 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8400 effect(KILL cr); 8401 8402 format %{ "sarq $dst, $shift" %} 8403 ins_encode %{ 8404 __ sarq($dst$$Address, (unsigned char)($shift$$constant & 0x3F)); 8405 %} 8406 ins_pipe(ialu_mem_imm); 8407 %} 8408 8409 // Arithmetic Shift Right by variable 8410 instruct sarL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8411 %{ 8412 predicate(!VM_Version::supports_bmi2()); 8413 match(Set dst (RShiftL dst shift)); 8414 effect(KILL cr); 8415 8416 format %{ "sarq $dst, $shift" %} 8417 ins_encode %{ 8418 __ sarq($dst$$Register); 8419 %} 8420 ins_pipe(ialu_reg_reg); 8421 %} 8422 8423 // Arithmetic Shift Right by variable 8424 instruct sarL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8425 %{ 8426 predicate(!VM_Version::supports_bmi2()); 8427 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8428 effect(KILL cr); 8429 8430 format %{ "sarq $dst, $shift" %} 8431 ins_encode %{ 8432 __ sarq($dst$$Address); 8433 %} 8434 ins_pipe(ialu_mem_reg); 8435 %} 8436 8437 instruct sarL_rReg_rReg(rRegL dst, rRegL src, rRegI shift) 8438 %{ 8439 predicate(VM_Version::supports_bmi2()); 8440 match(Set dst (RShiftL src shift)); 8441 8442 format %{ "sarxq $dst, $src, $shift" %} 8443 ins_encode %{ 8444 __ sarxq($dst$$Register, $src$$Register, $shift$$Register); 8445 %} 8446 ins_pipe(ialu_reg_reg); 8447 %} 8448 8449 instruct sarL_mem_rReg(rRegL dst, memory src, rRegI shift) 8450 %{ 8451 predicate(VM_Version::supports_bmi2()); 8452 match(Set dst (RShiftL (LoadL src) shift)); 8453 ins_cost(175); 8454 format %{ "sarxq $dst, $src, $shift" %} 8455 ins_encode %{ 8456 __ sarxq($dst$$Register, $src$$Address, $shift$$Register); 8457 %} 8458 ins_pipe(ialu_reg_mem); 8459 %} 8460 8461 // Logical Shift Right by 8-bit immediate 8462 instruct shrL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8463 %{ 8464 match(Set dst (URShiftL dst shift)); 8465 effect(KILL cr); 8466 8467 format %{ "shrq $dst, $shift" %} 8468 ins_encode %{ 8469 __ shrq($dst$$Register, $shift$$constant); 8470 %} 8471 ins_pipe(ialu_reg); 8472 %} 8473 8474 // Logical Shift Right by 8-bit immediate 8475 instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8476 %{ 8477 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8478 effect(KILL cr); 8479 8480 format %{ "shrq $dst, $shift" %} 8481 ins_encode %{ 8482 __ shrq($dst$$Address, $shift$$constant); 8483 %} 8484 ins_pipe(ialu_mem_imm); 8485 %} 8486 8487 // Logical Shift Right by variable 8488 instruct shrL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8489 %{ 8490 predicate(!VM_Version::supports_bmi2()); 8491 match(Set dst (URShiftL dst shift)); 8492 effect(KILL cr); 8493 8494 format %{ "shrq $dst, $shift" %} 8495 ins_encode %{ 8496 __ shrq($dst$$Register); 8497 %} 8498 ins_pipe(ialu_reg_reg); 8499 %} 8500 8501 // Logical Shift Right by variable 8502 instruct shrL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8503 %{ 8504 predicate(!VM_Version::supports_bmi2()); 8505 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8506 effect(KILL cr); 8507 8508 format %{ "shrq $dst, $shift" %} 8509 ins_encode %{ 8510 __ shrq($dst$$Address); 8511 %} 8512 ins_pipe(ialu_mem_reg); 8513 %} 8514 8515 instruct shrL_rReg_rReg(rRegL dst, rRegL src, rRegI shift) 8516 %{ 8517 predicate(VM_Version::supports_bmi2()); 8518 match(Set dst (URShiftL src shift)); 8519 8520 format %{ "shrxq $dst, $src, $shift" %} 8521 ins_encode %{ 8522 __ shrxq($dst$$Register, $src$$Register, $shift$$Register); 8523 %} 8524 ins_pipe(ialu_reg_reg); 8525 %} 8526 8527 instruct shrL_mem_rReg(rRegL dst, memory src, rRegI shift) 8528 %{ 8529 predicate(VM_Version::supports_bmi2()); 8530 match(Set dst (URShiftL (LoadL src) shift)); 8531 ins_cost(175); 8532 format %{ "shrxq $dst, $src, $shift" %} 8533 ins_encode %{ 8534 __ shrxq($dst$$Register, $src$$Address, $shift$$Register); 8535 %} 8536 ins_pipe(ialu_reg_mem); 8537 %} 8538 8539 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24. 8540 // This idiom is used by the compiler for the i2b bytecode. 8541 instruct i2b(rRegI dst, rRegI src, immI_24 twentyfour) 8542 %{ 8543 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour)); 8544 8545 format %{ "movsbl $dst, $src\t# i2b" %} 8546 ins_encode %{ 8547 __ movsbl($dst$$Register, $src$$Register); 8548 %} 8549 ins_pipe(ialu_reg_reg); 8550 %} 8551 8552 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16. 8553 // This idiom is used by the compiler the i2s bytecode. 8554 instruct i2s(rRegI dst, rRegI src, immI_16 sixteen) 8555 %{ 8556 match(Set dst (RShiftI (LShiftI src sixteen) sixteen)); 8557 8558 format %{ "movswl $dst, $src\t# i2s" %} 8559 ins_encode %{ 8560 __ movswl($dst$$Register, $src$$Register); 8561 %} 8562 ins_pipe(ialu_reg_reg); 8563 %} 8564 8565 // ROL/ROR instructions 8566 8567 // Rotate left by constant. 8568 instruct rolI_immI8_legacy(rRegI dst, immI8 shift, rFlagsReg cr) 8569 %{ 8570 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8571 match(Set dst (RotateLeft dst shift)); 8572 effect(KILL cr); 8573 format %{ "roll $dst, $shift" %} 8574 ins_encode %{ 8575 __ roll($dst$$Register, $shift$$constant); 8576 %} 8577 ins_pipe(ialu_reg); 8578 %} 8579 8580 instruct rolI_immI8(rRegI dst, rRegI src, immI8 shift) 8581 %{ 8582 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8583 match(Set dst (RotateLeft src shift)); 8584 format %{ "rolxl $dst, $src, $shift" %} 8585 ins_encode %{ 8586 int shift = 32 - ($shift$$constant & 31); 8587 __ rorxl($dst$$Register, $src$$Register, shift); 8588 %} 8589 ins_pipe(ialu_reg_reg); 8590 %} 8591 8592 instruct rolI_mem_immI8(rRegI dst, memory src, immI8 shift) 8593 %{ 8594 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8595 match(Set dst (RotateLeft (LoadI src) shift)); 8596 ins_cost(175); 8597 format %{ "rolxl $dst, $src, $shift" %} 8598 ins_encode %{ 8599 int shift = 32 - ($shift$$constant & 31); 8600 __ rorxl($dst$$Register, $src$$Address, shift); 8601 %} 8602 ins_pipe(ialu_reg_mem); 8603 %} 8604 8605 // Rotate Left by variable 8606 instruct rolI_rReg_Var(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8607 %{ 8608 predicate(n->bottom_type()->basic_type() == T_INT); 8609 match(Set dst (RotateLeft dst shift)); 8610 effect(KILL cr); 8611 format %{ "roll $dst, $shift" %} 8612 ins_encode %{ 8613 __ roll($dst$$Register); 8614 %} 8615 ins_pipe(ialu_reg_reg); 8616 %} 8617 8618 // Rotate Right by constant. 8619 instruct rorI_immI8_legacy(rRegI dst, immI8 shift, rFlagsReg cr) 8620 %{ 8621 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8622 match(Set dst (RotateRight dst shift)); 8623 effect(KILL cr); 8624 format %{ "rorl $dst, $shift" %} 8625 ins_encode %{ 8626 __ rorl($dst$$Register, $shift$$constant); 8627 %} 8628 ins_pipe(ialu_reg); 8629 %} 8630 8631 // Rotate Right by constant. 8632 instruct rorI_immI8(rRegI dst, rRegI src, immI8 shift) 8633 %{ 8634 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8635 match(Set dst (RotateRight src shift)); 8636 format %{ "rorxl $dst, $src, $shift" %} 8637 ins_encode %{ 8638 __ rorxl($dst$$Register, $src$$Register, $shift$$constant); 8639 %} 8640 ins_pipe(ialu_reg_reg); 8641 %} 8642 8643 instruct rorI_mem_immI8(rRegI dst, memory src, immI8 shift) 8644 %{ 8645 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8646 match(Set dst (RotateRight (LoadI src) shift)); 8647 ins_cost(175); 8648 format %{ "rorxl $dst, $src, $shift" %} 8649 ins_encode %{ 8650 __ rorxl($dst$$Register, $src$$Address, $shift$$constant); 8651 %} 8652 ins_pipe(ialu_reg_mem); 8653 %} 8654 8655 // Rotate Right by variable 8656 instruct rorI_rReg_Var(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8657 %{ 8658 predicate(n->bottom_type()->basic_type() == T_INT); 8659 match(Set dst (RotateRight dst shift)); 8660 effect(KILL cr); 8661 format %{ "rorl $dst, $shift" %} 8662 ins_encode %{ 8663 __ rorl($dst$$Register); 8664 %} 8665 ins_pipe(ialu_reg_reg); 8666 %} 8667 8668 // Rotate Left by constant. 8669 instruct rolL_immI8_legacy(rRegL dst, immI8 shift, rFlagsReg cr) 8670 %{ 8671 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8672 match(Set dst (RotateLeft dst shift)); 8673 effect(KILL cr); 8674 format %{ "rolq $dst, $shift" %} 8675 ins_encode %{ 8676 __ rolq($dst$$Register, $shift$$constant); 8677 %} 8678 ins_pipe(ialu_reg); 8679 %} 8680 8681 instruct rolL_immI8(rRegL dst, rRegL src, immI8 shift) 8682 %{ 8683 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8684 match(Set dst (RotateLeft src shift)); 8685 format %{ "rolxq $dst, $src, $shift" %} 8686 ins_encode %{ 8687 int shift = 64 - ($shift$$constant & 63); 8688 __ rorxq($dst$$Register, $src$$Register, shift); 8689 %} 8690 ins_pipe(ialu_reg_reg); 8691 %} 8692 8693 instruct rolL_mem_immI8(rRegL dst, memory src, immI8 shift) 8694 %{ 8695 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8696 match(Set dst (RotateLeft (LoadL src) shift)); 8697 ins_cost(175); 8698 format %{ "rolxq $dst, $src, $shift" %} 8699 ins_encode %{ 8700 int shift = 64 - ($shift$$constant & 63); 8701 __ rorxq($dst$$Register, $src$$Address, shift); 8702 %} 8703 ins_pipe(ialu_reg_mem); 8704 %} 8705 8706 // Rotate Left by variable 8707 instruct rolL_rReg_Var(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8708 %{ 8709 predicate(n->bottom_type()->basic_type() == T_LONG); 8710 match(Set dst (RotateLeft dst shift)); 8711 effect(KILL cr); 8712 format %{ "rolq $dst, $shift" %} 8713 ins_encode %{ 8714 __ rolq($dst$$Register); 8715 %} 8716 ins_pipe(ialu_reg_reg); 8717 %} 8718 8719 // Rotate Right by constant. 8720 instruct rorL_immI8_legacy(rRegL dst, immI8 shift, rFlagsReg cr) 8721 %{ 8722 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8723 match(Set dst (RotateRight dst shift)); 8724 effect(KILL cr); 8725 format %{ "rorq $dst, $shift" %} 8726 ins_encode %{ 8727 __ rorq($dst$$Register, $shift$$constant); 8728 %} 8729 ins_pipe(ialu_reg); 8730 %} 8731 8732 // Rotate Right by constant 8733 instruct rorL_immI8(rRegL dst, rRegL src, immI8 shift) 8734 %{ 8735 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8736 match(Set dst (RotateRight src shift)); 8737 format %{ "rorxq $dst, $src, $shift" %} 8738 ins_encode %{ 8739 __ rorxq($dst$$Register, $src$$Register, $shift$$constant); 8740 %} 8741 ins_pipe(ialu_reg_reg); 8742 %} 8743 8744 instruct rorL_mem_immI8(rRegL dst, memory src, immI8 shift) 8745 %{ 8746 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8747 match(Set dst (RotateRight (LoadL src) shift)); 8748 ins_cost(175); 8749 format %{ "rorxq $dst, $src, $shift" %} 8750 ins_encode %{ 8751 __ rorxq($dst$$Register, $src$$Address, $shift$$constant); 8752 %} 8753 ins_pipe(ialu_reg_mem); 8754 %} 8755 8756 // Rotate Right by variable 8757 instruct rorL_rReg_Var(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8758 %{ 8759 predicate(n->bottom_type()->basic_type() == T_LONG); 8760 match(Set dst (RotateRight dst shift)); 8761 effect(KILL cr); 8762 format %{ "rorq $dst, $shift" %} 8763 ins_encode %{ 8764 __ rorq($dst$$Register); 8765 %} 8766 ins_pipe(ialu_reg_reg); 8767 %} 8768 8769 //----------------------------- CompressBits/ExpandBits ------------------------ 8770 8771 instruct compressBitsL_reg(rRegL dst, rRegL src, rRegL mask) %{ 8772 predicate(n->bottom_type()->isa_long()); 8773 match(Set dst (CompressBits src mask)); 8774 format %{ "pextq $dst, $src, $mask\t! parallel bit extract" %} 8775 ins_encode %{ 8776 __ pextq($dst$$Register, $src$$Register, $mask$$Register); 8777 %} 8778 ins_pipe( pipe_slow ); 8779 %} 8780 8781 instruct expandBitsL_reg(rRegL dst, rRegL src, rRegL mask) %{ 8782 predicate(n->bottom_type()->isa_long()); 8783 match(Set dst (ExpandBits src mask)); 8784 format %{ "pdepq $dst, $src, $mask\t! parallel bit deposit" %} 8785 ins_encode %{ 8786 __ pdepq($dst$$Register, $src$$Register, $mask$$Register); 8787 %} 8788 ins_pipe( pipe_slow ); 8789 %} 8790 8791 instruct compressBitsL_mem(rRegL dst, rRegL src, memory mask) %{ 8792 predicate(n->bottom_type()->isa_long()); 8793 match(Set dst (CompressBits src (LoadL mask))); 8794 format %{ "pextq $dst, $src, $mask\t! parallel bit extract" %} 8795 ins_encode %{ 8796 __ pextq($dst$$Register, $src$$Register, $mask$$Address); 8797 %} 8798 ins_pipe( pipe_slow ); 8799 %} 8800 8801 instruct expandBitsL_mem(rRegL dst, rRegL src, memory mask) %{ 8802 predicate(n->bottom_type()->isa_long()); 8803 match(Set dst (ExpandBits src (LoadL mask))); 8804 format %{ "pdepq $dst, $src, $mask\t! parallel bit deposit" %} 8805 ins_encode %{ 8806 __ pdepq($dst$$Register, $src$$Register, $mask$$Address); 8807 %} 8808 ins_pipe( pipe_slow ); 8809 %} 8810 8811 8812 // Logical Instructions 8813 8814 // Integer Logical Instructions 8815 8816 // And Instructions 8817 // And Register with Register 8818 instruct andI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8819 %{ 8820 match(Set dst (AndI dst src)); 8821 effect(KILL cr); 8822 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 8823 8824 format %{ "andl $dst, $src\t# int" %} 8825 ins_encode %{ 8826 __ andl($dst$$Register, $src$$Register); 8827 %} 8828 ins_pipe(ialu_reg_reg); 8829 %} 8830 8831 // And Register with Immediate 255 8832 instruct andI_rReg_imm255(rRegI dst, rRegI src, immI_255 mask) 8833 %{ 8834 match(Set dst (AndI src mask)); 8835 8836 format %{ "movzbl $dst, $src\t# int & 0xFF" %} 8837 ins_encode %{ 8838 __ movzbl($dst$$Register, $src$$Register); 8839 %} 8840 ins_pipe(ialu_reg); 8841 %} 8842 8843 // And Register with Immediate 255 and promote to long 8844 instruct andI2L_rReg_imm255(rRegL dst, rRegI src, immI_255 mask) 8845 %{ 8846 match(Set dst (ConvI2L (AndI src mask))); 8847 8848 format %{ "movzbl $dst, $src\t# int & 0xFF -> long" %} 8849 ins_encode %{ 8850 __ movzbl($dst$$Register, $src$$Register); 8851 %} 8852 ins_pipe(ialu_reg); 8853 %} 8854 8855 // And Register with Immediate 65535 8856 instruct andI_rReg_imm65535(rRegI dst, rRegI src, immI_65535 mask) 8857 %{ 8858 match(Set dst (AndI src mask)); 8859 8860 format %{ "movzwl $dst, $src\t# int & 0xFFFF" %} 8861 ins_encode %{ 8862 __ movzwl($dst$$Register, $src$$Register); 8863 %} 8864 ins_pipe(ialu_reg); 8865 %} 8866 8867 // And Register with Immediate 65535 and promote to long 8868 instruct andI2L_rReg_imm65535(rRegL dst, rRegI src, immI_65535 mask) 8869 %{ 8870 match(Set dst (ConvI2L (AndI src mask))); 8871 8872 format %{ "movzwl $dst, $src\t# int & 0xFFFF -> long" %} 8873 ins_encode %{ 8874 __ movzwl($dst$$Register, $src$$Register); 8875 %} 8876 ins_pipe(ialu_reg); 8877 %} 8878 8879 // Can skip int2long conversions after AND with small bitmask 8880 instruct convI2LAndI_reg_immIbitmask(rRegL dst, rRegI src, immI_Pow2M1 mask, rRegI tmp, rFlagsReg cr) 8881 %{ 8882 predicate(VM_Version::supports_bmi2()); 8883 ins_cost(125); 8884 effect(TEMP tmp, KILL cr); 8885 match(Set dst (ConvI2L (AndI src mask))); 8886 format %{ "bzhiq $dst, $src, $mask \t# using $tmp as TEMP, int & immI_Pow2M1 -> long" %} 8887 ins_encode %{ 8888 __ movl($tmp$$Register, exact_log2($mask$$constant + 1)); 8889 __ bzhiq($dst$$Register, $src$$Register, $tmp$$Register); 8890 %} 8891 ins_pipe(ialu_reg_reg); 8892 %} 8893 8894 // And Register with Immediate 8895 instruct andI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 8896 %{ 8897 match(Set dst (AndI dst src)); 8898 effect(KILL cr); 8899 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 8900 8901 format %{ "andl $dst, $src\t# int" %} 8902 ins_encode %{ 8903 __ andl($dst$$Register, $src$$constant); 8904 %} 8905 ins_pipe(ialu_reg); 8906 %} 8907 8908 // And Register with Memory 8909 instruct andI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 8910 %{ 8911 match(Set dst (AndI dst (LoadI src))); 8912 effect(KILL cr); 8913 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 8914 8915 ins_cost(150); 8916 format %{ "andl $dst, $src\t# int" %} 8917 ins_encode %{ 8918 __ andl($dst$$Register, $src$$Address); 8919 %} 8920 ins_pipe(ialu_reg_mem); 8921 %} 8922 8923 // And Memory with Register 8924 instruct andB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 8925 %{ 8926 match(Set dst (StoreB dst (AndI (LoadB dst) src))); 8927 effect(KILL cr); 8928 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 8929 8930 ins_cost(150); 8931 format %{ "andb $dst, $src\t# byte" %} 8932 ins_encode %{ 8933 __ andb($dst$$Address, $src$$Register); 8934 %} 8935 ins_pipe(ialu_mem_reg); 8936 %} 8937 8938 instruct andI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 8939 %{ 8940 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 8941 effect(KILL cr); 8942 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 8943 8944 ins_cost(150); 8945 format %{ "andl $dst, $src\t# int" %} 8946 ins_encode %{ 8947 __ andl($dst$$Address, $src$$Register); 8948 %} 8949 ins_pipe(ialu_mem_reg); 8950 %} 8951 8952 // And Memory with Immediate 8953 instruct andI_mem_imm(memory dst, immI src, rFlagsReg cr) 8954 %{ 8955 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 8956 effect(KILL cr); 8957 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 8958 8959 ins_cost(125); 8960 format %{ "andl $dst, $src\t# int" %} 8961 ins_encode %{ 8962 __ andl($dst$$Address, $src$$constant); 8963 %} 8964 ins_pipe(ialu_mem_imm); 8965 %} 8966 8967 // BMI1 instructions 8968 instruct andnI_rReg_rReg_mem(rRegI dst, rRegI src1, memory src2, immI_M1 minus_1, rFlagsReg cr) %{ 8969 match(Set dst (AndI (XorI src1 minus_1) (LoadI src2))); 8970 predicate(UseBMI1Instructions); 8971 effect(KILL cr); 8972 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 8973 8974 ins_cost(125); 8975 format %{ "andnl $dst, $src1, $src2" %} 8976 8977 ins_encode %{ 8978 __ andnl($dst$$Register, $src1$$Register, $src2$$Address); 8979 %} 8980 ins_pipe(ialu_reg_mem); 8981 %} 8982 8983 instruct andnI_rReg_rReg_rReg(rRegI dst, rRegI src1, rRegI src2, immI_M1 minus_1, rFlagsReg cr) %{ 8984 match(Set dst (AndI (XorI src1 minus_1) src2)); 8985 predicate(UseBMI1Instructions); 8986 effect(KILL cr); 8987 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 8988 8989 format %{ "andnl $dst, $src1, $src2" %} 8990 8991 ins_encode %{ 8992 __ andnl($dst$$Register, $src1$$Register, $src2$$Register); 8993 %} 8994 ins_pipe(ialu_reg); 8995 %} 8996 8997 instruct blsiI_rReg_rReg(rRegI dst, rRegI src, immI_0 imm_zero, rFlagsReg cr) %{ 8998 match(Set dst (AndI (SubI imm_zero src) src)); 8999 predicate(UseBMI1Instructions); 9000 effect(KILL cr); 9001 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9002 9003 format %{ "blsil $dst, $src" %} 9004 9005 ins_encode %{ 9006 __ blsil($dst$$Register, $src$$Register); 9007 %} 9008 ins_pipe(ialu_reg); 9009 %} 9010 9011 instruct blsiI_rReg_mem(rRegI dst, memory src, immI_0 imm_zero, rFlagsReg cr) %{ 9012 match(Set dst (AndI (SubI imm_zero (LoadI src) ) (LoadI src) )); 9013 predicate(UseBMI1Instructions); 9014 effect(KILL cr); 9015 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9016 9017 ins_cost(125); 9018 format %{ "blsil $dst, $src" %} 9019 9020 ins_encode %{ 9021 __ blsil($dst$$Register, $src$$Address); 9022 %} 9023 ins_pipe(ialu_reg_mem); 9024 %} 9025 9026 instruct blsmskI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 9027 %{ 9028 match(Set dst (XorI (AddI (LoadI src) minus_1) (LoadI src) ) ); 9029 predicate(UseBMI1Instructions); 9030 effect(KILL cr); 9031 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 9032 9033 ins_cost(125); 9034 format %{ "blsmskl $dst, $src" %} 9035 9036 ins_encode %{ 9037 __ blsmskl($dst$$Register, $src$$Address); 9038 %} 9039 ins_pipe(ialu_reg_mem); 9040 %} 9041 9042 instruct blsmskI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 9043 %{ 9044 match(Set dst (XorI (AddI src minus_1) src)); 9045 predicate(UseBMI1Instructions); 9046 effect(KILL cr); 9047 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 9048 9049 format %{ "blsmskl $dst, $src" %} 9050 9051 ins_encode %{ 9052 __ blsmskl($dst$$Register, $src$$Register); 9053 %} 9054 9055 ins_pipe(ialu_reg); 9056 %} 9057 9058 instruct blsrI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 9059 %{ 9060 match(Set dst (AndI (AddI src minus_1) src) ); 9061 predicate(UseBMI1Instructions); 9062 effect(KILL cr); 9063 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9064 9065 format %{ "blsrl $dst, $src" %} 9066 9067 ins_encode %{ 9068 __ blsrl($dst$$Register, $src$$Register); 9069 %} 9070 9071 ins_pipe(ialu_reg_mem); 9072 %} 9073 9074 instruct blsrI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 9075 %{ 9076 match(Set dst (AndI (AddI (LoadI src) minus_1) (LoadI src) ) ); 9077 predicate(UseBMI1Instructions); 9078 effect(KILL cr); 9079 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9080 9081 ins_cost(125); 9082 format %{ "blsrl $dst, $src" %} 9083 9084 ins_encode %{ 9085 __ blsrl($dst$$Register, $src$$Address); 9086 %} 9087 9088 ins_pipe(ialu_reg); 9089 %} 9090 9091 // Or Instructions 9092 // Or Register with Register 9093 instruct orI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9094 %{ 9095 match(Set dst (OrI dst src)); 9096 effect(KILL cr); 9097 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9098 9099 format %{ "orl $dst, $src\t# int" %} 9100 ins_encode %{ 9101 __ orl($dst$$Register, $src$$Register); 9102 %} 9103 ins_pipe(ialu_reg_reg); 9104 %} 9105 9106 // Or Register with Immediate 9107 instruct orI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9108 %{ 9109 match(Set dst (OrI dst src)); 9110 effect(KILL cr); 9111 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9112 9113 format %{ "orl $dst, $src\t# int" %} 9114 ins_encode %{ 9115 __ orl($dst$$Register, $src$$constant); 9116 %} 9117 ins_pipe(ialu_reg); 9118 %} 9119 9120 // Or Register with Memory 9121 instruct orI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9122 %{ 9123 match(Set dst (OrI dst (LoadI src))); 9124 effect(KILL cr); 9125 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9126 9127 ins_cost(150); 9128 format %{ "orl $dst, $src\t# int" %} 9129 ins_encode %{ 9130 __ orl($dst$$Register, $src$$Address); 9131 %} 9132 ins_pipe(ialu_reg_mem); 9133 %} 9134 9135 // Or Memory with Register 9136 instruct orB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9137 %{ 9138 match(Set dst (StoreB dst (OrI (LoadB dst) src))); 9139 effect(KILL cr); 9140 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9141 9142 ins_cost(150); 9143 format %{ "orb $dst, $src\t# byte" %} 9144 ins_encode %{ 9145 __ orb($dst$$Address, $src$$Register); 9146 %} 9147 ins_pipe(ialu_mem_reg); 9148 %} 9149 9150 instruct orI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9151 %{ 9152 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9153 effect(KILL cr); 9154 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9155 9156 ins_cost(150); 9157 format %{ "orl $dst, $src\t# int" %} 9158 ins_encode %{ 9159 __ orl($dst$$Address, $src$$Register); 9160 %} 9161 ins_pipe(ialu_mem_reg); 9162 %} 9163 9164 // Or Memory with Immediate 9165 instruct orI_mem_imm(memory dst, immI src, rFlagsReg cr) 9166 %{ 9167 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9168 effect(KILL cr); 9169 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9170 9171 ins_cost(125); 9172 format %{ "orl $dst, $src\t# int" %} 9173 ins_encode %{ 9174 __ orl($dst$$Address, $src$$constant); 9175 %} 9176 ins_pipe(ialu_mem_imm); 9177 %} 9178 9179 // Xor Instructions 9180 // Xor Register with Register 9181 instruct xorI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9182 %{ 9183 match(Set dst (XorI dst src)); 9184 effect(KILL cr); 9185 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9186 9187 format %{ "xorl $dst, $src\t# int" %} 9188 ins_encode %{ 9189 __ xorl($dst$$Register, $src$$Register); 9190 %} 9191 ins_pipe(ialu_reg_reg); 9192 %} 9193 9194 // Xor Register with Immediate -1 9195 instruct xorI_rReg_im1(rRegI dst, immI_M1 imm) %{ 9196 match(Set dst (XorI dst imm)); 9197 9198 format %{ "not $dst" %} 9199 ins_encode %{ 9200 __ notl($dst$$Register); 9201 %} 9202 ins_pipe(ialu_reg); 9203 %} 9204 9205 // Xor Register with Immediate 9206 instruct xorI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9207 %{ 9208 match(Set dst (XorI dst src)); 9209 effect(KILL cr); 9210 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9211 9212 format %{ "xorl $dst, $src\t# int" %} 9213 ins_encode %{ 9214 __ xorl($dst$$Register, $src$$constant); 9215 %} 9216 ins_pipe(ialu_reg); 9217 %} 9218 9219 // Xor Register with Memory 9220 instruct xorI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9221 %{ 9222 match(Set dst (XorI dst (LoadI src))); 9223 effect(KILL cr); 9224 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9225 9226 ins_cost(150); 9227 format %{ "xorl $dst, $src\t# int" %} 9228 ins_encode %{ 9229 __ xorl($dst$$Register, $src$$Address); 9230 %} 9231 ins_pipe(ialu_reg_mem); 9232 %} 9233 9234 // Xor Memory with Register 9235 instruct xorB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9236 %{ 9237 match(Set dst (StoreB dst (XorI (LoadB dst) src))); 9238 effect(KILL cr); 9239 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9240 9241 ins_cost(150); 9242 format %{ "xorb $dst, $src\t# byte" %} 9243 ins_encode %{ 9244 __ xorb($dst$$Address, $src$$Register); 9245 %} 9246 ins_pipe(ialu_mem_reg); 9247 %} 9248 9249 instruct xorI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9250 %{ 9251 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9252 effect(KILL cr); 9253 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9254 9255 ins_cost(150); 9256 format %{ "xorl $dst, $src\t# int" %} 9257 ins_encode %{ 9258 __ xorl($dst$$Address, $src$$Register); 9259 %} 9260 ins_pipe(ialu_mem_reg); 9261 %} 9262 9263 // Xor Memory with Immediate 9264 instruct xorI_mem_imm(memory dst, immI src, rFlagsReg cr) 9265 %{ 9266 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9267 effect(KILL cr); 9268 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9269 9270 ins_cost(125); 9271 format %{ "xorl $dst, $src\t# int" %} 9272 ins_encode %{ 9273 __ xorl($dst$$Address, $src$$constant); 9274 %} 9275 ins_pipe(ialu_mem_imm); 9276 %} 9277 9278 9279 // Long Logical Instructions 9280 9281 // And Instructions 9282 // And Register with Register 9283 instruct andL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9284 %{ 9285 match(Set dst (AndL dst src)); 9286 effect(KILL cr); 9287 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9288 9289 format %{ "andq $dst, $src\t# long" %} 9290 ins_encode %{ 9291 __ andq($dst$$Register, $src$$Register); 9292 %} 9293 ins_pipe(ialu_reg_reg); 9294 %} 9295 9296 // And Register with Immediate 255 9297 instruct andL_rReg_imm255(rRegL dst, rRegL src, immL_255 mask) 9298 %{ 9299 match(Set dst (AndL src mask)); 9300 9301 format %{ "movzbl $dst, $src\t# long & 0xFF" %} 9302 ins_encode %{ 9303 // movzbl zeroes out the upper 32-bit and does not need REX.W 9304 __ movzbl($dst$$Register, $src$$Register); 9305 %} 9306 ins_pipe(ialu_reg); 9307 %} 9308 9309 // And Register with Immediate 65535 9310 instruct andL_rReg_imm65535(rRegL dst, rRegL src, immL_65535 mask) 9311 %{ 9312 match(Set dst (AndL src mask)); 9313 9314 format %{ "movzwl $dst, $src\t# long & 0xFFFF" %} 9315 ins_encode %{ 9316 // movzwl zeroes out the upper 32-bit and does not need REX.W 9317 __ movzwl($dst$$Register, $src$$Register); 9318 %} 9319 ins_pipe(ialu_reg); 9320 %} 9321 9322 // And Register with Immediate 9323 instruct andL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9324 %{ 9325 match(Set dst (AndL dst src)); 9326 effect(KILL cr); 9327 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9328 9329 format %{ "andq $dst, $src\t# long" %} 9330 ins_encode %{ 9331 __ andq($dst$$Register, $src$$constant); 9332 %} 9333 ins_pipe(ialu_reg); 9334 %} 9335 9336 // And Register with Memory 9337 instruct andL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9338 %{ 9339 match(Set dst (AndL dst (LoadL src))); 9340 effect(KILL cr); 9341 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9342 9343 ins_cost(150); 9344 format %{ "andq $dst, $src\t# long" %} 9345 ins_encode %{ 9346 __ andq($dst$$Register, $src$$Address); 9347 %} 9348 ins_pipe(ialu_reg_mem); 9349 %} 9350 9351 // And Memory with Register 9352 instruct andL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9353 %{ 9354 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9355 effect(KILL cr); 9356 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9357 9358 ins_cost(150); 9359 format %{ "andq $dst, $src\t# long" %} 9360 ins_encode %{ 9361 __ andq($dst$$Address, $src$$Register); 9362 %} 9363 ins_pipe(ialu_mem_reg); 9364 %} 9365 9366 // And Memory with Immediate 9367 instruct andL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9368 %{ 9369 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9370 effect(KILL cr); 9371 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9372 9373 ins_cost(125); 9374 format %{ "andq $dst, $src\t# long" %} 9375 ins_encode %{ 9376 __ andq($dst$$Address, $src$$constant); 9377 %} 9378 ins_pipe(ialu_mem_imm); 9379 %} 9380 9381 instruct btrL_mem_imm(memory dst, immL_NotPow2 con, rFlagsReg cr) 9382 %{ 9383 // con should be a pure 64-bit immediate given that not(con) is a power of 2 9384 // because AND/OR works well enough for 8/32-bit values. 9385 predicate(log2i_graceful(~n->in(3)->in(2)->get_long()) > 30); 9386 9387 match(Set dst (StoreL dst (AndL (LoadL dst) con))); 9388 effect(KILL cr); 9389 9390 ins_cost(125); 9391 format %{ "btrq $dst, log2(not($con))\t# long" %} 9392 ins_encode %{ 9393 __ btrq($dst$$Address, log2i_exact((julong)~$con$$constant)); 9394 %} 9395 ins_pipe(ialu_mem_imm); 9396 %} 9397 9398 // BMI1 instructions 9399 instruct andnL_rReg_rReg_mem(rRegL dst, rRegL src1, memory src2, immL_M1 minus_1, rFlagsReg cr) %{ 9400 match(Set dst (AndL (XorL src1 minus_1) (LoadL src2))); 9401 predicate(UseBMI1Instructions); 9402 effect(KILL cr); 9403 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9404 9405 ins_cost(125); 9406 format %{ "andnq $dst, $src1, $src2" %} 9407 9408 ins_encode %{ 9409 __ andnq($dst$$Register, $src1$$Register, $src2$$Address); 9410 %} 9411 ins_pipe(ialu_reg_mem); 9412 %} 9413 9414 instruct andnL_rReg_rReg_rReg(rRegL dst, rRegL src1, rRegL src2, immL_M1 minus_1, rFlagsReg cr) %{ 9415 match(Set dst (AndL (XorL src1 minus_1) src2)); 9416 predicate(UseBMI1Instructions); 9417 effect(KILL cr); 9418 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9419 9420 format %{ "andnq $dst, $src1, $src2" %} 9421 9422 ins_encode %{ 9423 __ andnq($dst$$Register, $src1$$Register, $src2$$Register); 9424 %} 9425 ins_pipe(ialu_reg_mem); 9426 %} 9427 9428 instruct blsiL_rReg_rReg(rRegL dst, rRegL src, immL0 imm_zero, rFlagsReg cr) %{ 9429 match(Set dst (AndL (SubL imm_zero src) src)); 9430 predicate(UseBMI1Instructions); 9431 effect(KILL cr); 9432 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9433 9434 format %{ "blsiq $dst, $src" %} 9435 9436 ins_encode %{ 9437 __ blsiq($dst$$Register, $src$$Register); 9438 %} 9439 ins_pipe(ialu_reg); 9440 %} 9441 9442 instruct blsiL_rReg_mem(rRegL dst, memory src, immL0 imm_zero, rFlagsReg cr) %{ 9443 match(Set dst (AndL (SubL imm_zero (LoadL src) ) (LoadL src) )); 9444 predicate(UseBMI1Instructions); 9445 effect(KILL cr); 9446 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9447 9448 ins_cost(125); 9449 format %{ "blsiq $dst, $src" %} 9450 9451 ins_encode %{ 9452 __ blsiq($dst$$Register, $src$$Address); 9453 %} 9454 ins_pipe(ialu_reg_mem); 9455 %} 9456 9457 instruct blsmskL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 9458 %{ 9459 match(Set dst (XorL (AddL (LoadL src) minus_1) (LoadL src) ) ); 9460 predicate(UseBMI1Instructions); 9461 effect(KILL cr); 9462 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 9463 9464 ins_cost(125); 9465 format %{ "blsmskq $dst, $src" %} 9466 9467 ins_encode %{ 9468 __ blsmskq($dst$$Register, $src$$Address); 9469 %} 9470 ins_pipe(ialu_reg_mem); 9471 %} 9472 9473 instruct blsmskL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 9474 %{ 9475 match(Set dst (XorL (AddL src minus_1) src)); 9476 predicate(UseBMI1Instructions); 9477 effect(KILL cr); 9478 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 9479 9480 format %{ "blsmskq $dst, $src" %} 9481 9482 ins_encode %{ 9483 __ blsmskq($dst$$Register, $src$$Register); 9484 %} 9485 9486 ins_pipe(ialu_reg); 9487 %} 9488 9489 instruct blsrL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 9490 %{ 9491 match(Set dst (AndL (AddL src minus_1) src) ); 9492 predicate(UseBMI1Instructions); 9493 effect(KILL cr); 9494 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9495 9496 format %{ "blsrq $dst, $src" %} 9497 9498 ins_encode %{ 9499 __ blsrq($dst$$Register, $src$$Register); 9500 %} 9501 9502 ins_pipe(ialu_reg); 9503 %} 9504 9505 instruct blsrL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 9506 %{ 9507 match(Set dst (AndL (AddL (LoadL src) minus_1) (LoadL src)) ); 9508 predicate(UseBMI1Instructions); 9509 effect(KILL cr); 9510 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9511 9512 ins_cost(125); 9513 format %{ "blsrq $dst, $src" %} 9514 9515 ins_encode %{ 9516 __ blsrq($dst$$Register, $src$$Address); 9517 %} 9518 9519 ins_pipe(ialu_reg); 9520 %} 9521 9522 // Or Instructions 9523 // Or Register with Register 9524 instruct orL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9525 %{ 9526 match(Set dst (OrL dst src)); 9527 effect(KILL cr); 9528 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9529 9530 format %{ "orq $dst, $src\t# long" %} 9531 ins_encode %{ 9532 __ orq($dst$$Register, $src$$Register); 9533 %} 9534 ins_pipe(ialu_reg_reg); 9535 %} 9536 9537 // Use any_RegP to match R15 (TLS register) without spilling. 9538 instruct orL_rReg_castP2X(rRegL dst, any_RegP src, rFlagsReg cr) %{ 9539 match(Set dst (OrL dst (CastP2X src))); 9540 effect(KILL cr); 9541 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9542 9543 format %{ "orq $dst, $src\t# long" %} 9544 ins_encode %{ 9545 __ orq($dst$$Register, $src$$Register); 9546 %} 9547 ins_pipe(ialu_reg_reg); 9548 %} 9549 9550 9551 // Or Register with Immediate 9552 instruct orL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9553 %{ 9554 match(Set dst (OrL dst src)); 9555 effect(KILL cr); 9556 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9557 9558 format %{ "orq $dst, $src\t# long" %} 9559 ins_encode %{ 9560 __ orq($dst$$Register, $src$$constant); 9561 %} 9562 ins_pipe(ialu_reg); 9563 %} 9564 9565 // Or Register with Memory 9566 instruct orL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9567 %{ 9568 match(Set dst (OrL dst (LoadL src))); 9569 effect(KILL cr); 9570 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9571 9572 ins_cost(150); 9573 format %{ "orq $dst, $src\t# long" %} 9574 ins_encode %{ 9575 __ orq($dst$$Register, $src$$Address); 9576 %} 9577 ins_pipe(ialu_reg_mem); 9578 %} 9579 9580 // Or Memory with Register 9581 instruct orL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9582 %{ 9583 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9584 effect(KILL cr); 9585 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9586 9587 ins_cost(150); 9588 format %{ "orq $dst, $src\t# long" %} 9589 ins_encode %{ 9590 __ orq($dst$$Address, $src$$Register); 9591 %} 9592 ins_pipe(ialu_mem_reg); 9593 %} 9594 9595 // Or Memory with Immediate 9596 instruct orL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9597 %{ 9598 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9599 effect(KILL cr); 9600 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9601 9602 ins_cost(125); 9603 format %{ "orq $dst, $src\t# long" %} 9604 ins_encode %{ 9605 __ orq($dst$$Address, $src$$constant); 9606 %} 9607 ins_pipe(ialu_mem_imm); 9608 %} 9609 9610 instruct btsL_mem_imm(memory dst, immL_Pow2 con, rFlagsReg cr) 9611 %{ 9612 // con should be a pure 64-bit power of 2 immediate 9613 // because AND/OR works well enough for 8/32-bit values. 9614 predicate(log2i_graceful(n->in(3)->in(2)->get_long()) > 31); 9615 9616 match(Set dst (StoreL dst (OrL (LoadL dst) con))); 9617 effect(KILL cr); 9618 9619 ins_cost(125); 9620 format %{ "btsq $dst, log2($con)\t# long" %} 9621 ins_encode %{ 9622 __ btsq($dst$$Address, log2i_exact((julong)$con$$constant)); 9623 %} 9624 ins_pipe(ialu_mem_imm); 9625 %} 9626 9627 // Xor Instructions 9628 // Xor Register with Register 9629 instruct xorL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9630 %{ 9631 match(Set dst (XorL dst src)); 9632 effect(KILL cr); 9633 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9634 9635 format %{ "xorq $dst, $src\t# long" %} 9636 ins_encode %{ 9637 __ xorq($dst$$Register, $src$$Register); 9638 %} 9639 ins_pipe(ialu_reg_reg); 9640 %} 9641 9642 // Xor Register with Immediate -1 9643 instruct xorL_rReg_im1(rRegL dst, immL_M1 imm) %{ 9644 match(Set dst (XorL dst imm)); 9645 9646 format %{ "notq $dst" %} 9647 ins_encode %{ 9648 __ notq($dst$$Register); 9649 %} 9650 ins_pipe(ialu_reg); 9651 %} 9652 9653 // Xor Register with Immediate 9654 instruct xorL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9655 %{ 9656 match(Set dst (XorL dst src)); 9657 effect(KILL cr); 9658 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9659 9660 format %{ "xorq $dst, $src\t# long" %} 9661 ins_encode %{ 9662 __ xorq($dst$$Register, $src$$constant); 9663 %} 9664 ins_pipe(ialu_reg); 9665 %} 9666 9667 // Xor Register with Memory 9668 instruct xorL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9669 %{ 9670 match(Set dst (XorL dst (LoadL src))); 9671 effect(KILL cr); 9672 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9673 9674 ins_cost(150); 9675 format %{ "xorq $dst, $src\t# long" %} 9676 ins_encode %{ 9677 __ xorq($dst$$Register, $src$$Address); 9678 %} 9679 ins_pipe(ialu_reg_mem); 9680 %} 9681 9682 // Xor Memory with Register 9683 instruct xorL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9684 %{ 9685 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 9686 effect(KILL cr); 9687 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9688 9689 ins_cost(150); 9690 format %{ "xorq $dst, $src\t# long" %} 9691 ins_encode %{ 9692 __ xorq($dst$$Address, $src$$Register); 9693 %} 9694 ins_pipe(ialu_mem_reg); 9695 %} 9696 9697 // Xor Memory with Immediate 9698 instruct xorL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9699 %{ 9700 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 9701 effect(KILL cr); 9702 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9703 9704 ins_cost(125); 9705 format %{ "xorq $dst, $src\t# long" %} 9706 ins_encode %{ 9707 __ xorq($dst$$Address, $src$$constant); 9708 %} 9709 ins_pipe(ialu_mem_imm); 9710 %} 9711 9712 instruct cmpLTMask(rRegI dst, rRegI p, rRegI q, rFlagsReg cr) 9713 %{ 9714 match(Set dst (CmpLTMask p q)); 9715 effect(KILL cr); 9716 9717 ins_cost(400); 9718 format %{ "cmpl $p, $q\t# cmpLTMask\n\t" 9719 "setcc $dst \t# emits setlt + movzbl or setzul for APX" 9720 "negl $dst" %} 9721 ins_encode %{ 9722 __ cmpl($p$$Register, $q$$Register); 9723 __ setcc(Assembler::less, $dst$$Register); 9724 __ negl($dst$$Register); 9725 %} 9726 ins_pipe(pipe_slow); 9727 %} 9728 9729 instruct cmpLTMask0(rRegI dst, immI_0 zero, rFlagsReg cr) 9730 %{ 9731 match(Set dst (CmpLTMask dst zero)); 9732 effect(KILL cr); 9733 9734 ins_cost(100); 9735 format %{ "sarl $dst, #31\t# cmpLTMask0" %} 9736 ins_encode %{ 9737 __ sarl($dst$$Register, 31); 9738 %} 9739 ins_pipe(ialu_reg); 9740 %} 9741 9742 /* Better to save a register than avoid a branch */ 9743 instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 9744 %{ 9745 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q))); 9746 effect(KILL cr); 9747 ins_cost(300); 9748 format %{ "subl $p,$q\t# cadd_cmpLTMask\n\t" 9749 "jge done\n\t" 9750 "addl $p,$y\n" 9751 "done: " %} 9752 ins_encode %{ 9753 Register Rp = $p$$Register; 9754 Register Rq = $q$$Register; 9755 Register Ry = $y$$Register; 9756 Label done; 9757 __ subl(Rp, Rq); 9758 __ jccb(Assembler::greaterEqual, done); 9759 __ addl(Rp, Ry); 9760 __ bind(done); 9761 %} 9762 ins_pipe(pipe_cmplt); 9763 %} 9764 9765 /* Better to save a register than avoid a branch */ 9766 instruct and_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 9767 %{ 9768 match(Set y (AndI (CmpLTMask p q) y)); 9769 effect(KILL cr); 9770 9771 ins_cost(300); 9772 9773 format %{ "cmpl $p, $q\t# and_cmpLTMask\n\t" 9774 "jlt done\n\t" 9775 "xorl $y, $y\n" 9776 "done: " %} 9777 ins_encode %{ 9778 Register Rp = $p$$Register; 9779 Register Rq = $q$$Register; 9780 Register Ry = $y$$Register; 9781 Label done; 9782 __ cmpl(Rp, Rq); 9783 __ jccb(Assembler::less, done); 9784 __ xorl(Ry, Ry); 9785 __ bind(done); 9786 %} 9787 ins_pipe(pipe_cmplt); 9788 %} 9789 9790 9791 //---------- FP Instructions------------------------------------------------ 9792 9793 // Really expensive, avoid 9794 instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2) 9795 %{ 9796 match(Set cr (CmpF src1 src2)); 9797 9798 ins_cost(500); 9799 format %{ "ucomiss $src1, $src2\n\t" 9800 "jnp,s exit\n\t" 9801 "pushfq\t# saw NaN, set CF\n\t" 9802 "andq [rsp], #0xffffff2b\n\t" 9803 "popfq\n" 9804 "exit:" %} 9805 ins_encode %{ 9806 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9807 emit_cmpfp_fixup(masm); 9808 %} 9809 ins_pipe(pipe_slow); 9810 %} 9811 9812 instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{ 9813 match(Set cr (CmpF src1 src2)); 9814 9815 ins_cost(100); 9816 format %{ "ucomiss $src1, $src2" %} 9817 ins_encode %{ 9818 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9819 %} 9820 ins_pipe(pipe_slow); 9821 %} 9822 9823 instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{ 9824 match(Set cr (CmpF src1 (LoadF src2))); 9825 9826 ins_cost(100); 9827 format %{ "ucomiss $src1, $src2" %} 9828 ins_encode %{ 9829 __ ucomiss($src1$$XMMRegister, $src2$$Address); 9830 %} 9831 ins_pipe(pipe_slow); 9832 %} 9833 9834 instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src, immF con) %{ 9835 match(Set cr (CmpF src con)); 9836 ins_cost(100); 9837 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con" %} 9838 ins_encode %{ 9839 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 9840 %} 9841 ins_pipe(pipe_slow); 9842 %} 9843 9844 // Really expensive, avoid 9845 instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2) 9846 %{ 9847 match(Set cr (CmpD src1 src2)); 9848 9849 ins_cost(500); 9850 format %{ "ucomisd $src1, $src2\n\t" 9851 "jnp,s exit\n\t" 9852 "pushfq\t# saw NaN, set CF\n\t" 9853 "andq [rsp], #0xffffff2b\n\t" 9854 "popfq\n" 9855 "exit:" %} 9856 ins_encode %{ 9857 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9858 emit_cmpfp_fixup(masm); 9859 %} 9860 ins_pipe(pipe_slow); 9861 %} 9862 9863 instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{ 9864 match(Set cr (CmpD src1 src2)); 9865 9866 ins_cost(100); 9867 format %{ "ucomisd $src1, $src2 test" %} 9868 ins_encode %{ 9869 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9870 %} 9871 ins_pipe(pipe_slow); 9872 %} 9873 9874 instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{ 9875 match(Set cr (CmpD src1 (LoadD src2))); 9876 9877 ins_cost(100); 9878 format %{ "ucomisd $src1, $src2" %} 9879 ins_encode %{ 9880 __ ucomisd($src1$$XMMRegister, $src2$$Address); 9881 %} 9882 ins_pipe(pipe_slow); 9883 %} 9884 9885 instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src, immD con) %{ 9886 match(Set cr (CmpD src con)); 9887 ins_cost(100); 9888 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con" %} 9889 ins_encode %{ 9890 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 9891 %} 9892 ins_pipe(pipe_slow); 9893 %} 9894 9895 // Compare into -1,0,1 9896 instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr) 9897 %{ 9898 match(Set dst (CmpF3 src1 src2)); 9899 effect(KILL cr); 9900 9901 ins_cost(275); 9902 format %{ "ucomiss $src1, $src2\n\t" 9903 "movl $dst, #-1\n\t" 9904 "jp,s done\n\t" 9905 "jb,s done\n\t" 9906 "setne $dst\n\t" 9907 "movzbl $dst, $dst\n" 9908 "done:" %} 9909 ins_encode %{ 9910 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9911 emit_cmpfp3(masm, $dst$$Register); 9912 %} 9913 ins_pipe(pipe_slow); 9914 %} 9915 9916 // Compare into -1,0,1 9917 instruct cmpF_mem(rRegI dst, regF src1, memory src2, rFlagsReg cr) 9918 %{ 9919 match(Set dst (CmpF3 src1 (LoadF src2))); 9920 effect(KILL cr); 9921 9922 ins_cost(275); 9923 format %{ "ucomiss $src1, $src2\n\t" 9924 "movl $dst, #-1\n\t" 9925 "jp,s done\n\t" 9926 "jb,s done\n\t" 9927 "setne $dst\n\t" 9928 "movzbl $dst, $dst\n" 9929 "done:" %} 9930 ins_encode %{ 9931 __ ucomiss($src1$$XMMRegister, $src2$$Address); 9932 emit_cmpfp3(masm, $dst$$Register); 9933 %} 9934 ins_pipe(pipe_slow); 9935 %} 9936 9937 // Compare into -1,0,1 9938 instruct cmpF_imm(rRegI dst, regF src, immF con, rFlagsReg cr) %{ 9939 match(Set dst (CmpF3 src con)); 9940 effect(KILL cr); 9941 9942 ins_cost(275); 9943 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 9944 "movl $dst, #-1\n\t" 9945 "jp,s done\n\t" 9946 "jb,s done\n\t" 9947 "setne $dst\n\t" 9948 "movzbl $dst, $dst\n" 9949 "done:" %} 9950 ins_encode %{ 9951 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 9952 emit_cmpfp3(masm, $dst$$Register); 9953 %} 9954 ins_pipe(pipe_slow); 9955 %} 9956 9957 // Compare into -1,0,1 9958 instruct cmpD_reg(rRegI dst, regD src1, regD src2, rFlagsReg cr) 9959 %{ 9960 match(Set dst (CmpD3 src1 src2)); 9961 effect(KILL cr); 9962 9963 ins_cost(275); 9964 format %{ "ucomisd $src1, $src2\n\t" 9965 "movl $dst, #-1\n\t" 9966 "jp,s done\n\t" 9967 "jb,s done\n\t" 9968 "setne $dst\n\t" 9969 "movzbl $dst, $dst\n" 9970 "done:" %} 9971 ins_encode %{ 9972 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9973 emit_cmpfp3(masm, $dst$$Register); 9974 %} 9975 ins_pipe(pipe_slow); 9976 %} 9977 9978 // Compare into -1,0,1 9979 instruct cmpD_mem(rRegI dst, regD src1, memory src2, rFlagsReg cr) 9980 %{ 9981 match(Set dst (CmpD3 src1 (LoadD src2))); 9982 effect(KILL cr); 9983 9984 ins_cost(275); 9985 format %{ "ucomisd $src1, $src2\n\t" 9986 "movl $dst, #-1\n\t" 9987 "jp,s done\n\t" 9988 "jb,s done\n\t" 9989 "setne $dst\n\t" 9990 "movzbl $dst, $dst\n" 9991 "done:" %} 9992 ins_encode %{ 9993 __ ucomisd($src1$$XMMRegister, $src2$$Address); 9994 emit_cmpfp3(masm, $dst$$Register); 9995 %} 9996 ins_pipe(pipe_slow); 9997 %} 9998 9999 // Compare into -1,0,1 10000 instruct cmpD_imm(rRegI dst, regD src, immD con, rFlagsReg cr) %{ 10001 match(Set dst (CmpD3 src con)); 10002 effect(KILL cr); 10003 10004 ins_cost(275); 10005 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 10006 "movl $dst, #-1\n\t" 10007 "jp,s done\n\t" 10008 "jb,s done\n\t" 10009 "setne $dst\n\t" 10010 "movzbl $dst, $dst\n" 10011 "done:" %} 10012 ins_encode %{ 10013 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 10014 emit_cmpfp3(masm, $dst$$Register); 10015 %} 10016 ins_pipe(pipe_slow); 10017 %} 10018 10019 //----------Arithmetic Conversion Instructions--------------------------------- 10020 10021 instruct convF2D_reg_reg(regD dst, regF src) 10022 %{ 10023 match(Set dst (ConvF2D src)); 10024 10025 format %{ "cvtss2sd $dst, $src" %} 10026 ins_encode %{ 10027 __ cvtss2sd ($dst$$XMMRegister, $src$$XMMRegister); 10028 %} 10029 ins_pipe(pipe_slow); // XXX 10030 %} 10031 10032 instruct convF2D_reg_mem(regD dst, memory src) 10033 %{ 10034 predicate(UseAVX == 0); 10035 match(Set dst (ConvF2D (LoadF src))); 10036 10037 format %{ "cvtss2sd $dst, $src" %} 10038 ins_encode %{ 10039 __ cvtss2sd ($dst$$XMMRegister, $src$$Address); 10040 %} 10041 ins_pipe(pipe_slow); // XXX 10042 %} 10043 10044 instruct convD2F_reg_reg(regF dst, regD src) 10045 %{ 10046 match(Set dst (ConvD2F src)); 10047 10048 format %{ "cvtsd2ss $dst, $src" %} 10049 ins_encode %{ 10050 __ cvtsd2ss ($dst$$XMMRegister, $src$$XMMRegister); 10051 %} 10052 ins_pipe(pipe_slow); // XXX 10053 %} 10054 10055 instruct convD2F_reg_mem(regF dst, memory src) 10056 %{ 10057 predicate(UseAVX == 0); 10058 match(Set dst (ConvD2F (LoadD src))); 10059 10060 format %{ "cvtsd2ss $dst, $src" %} 10061 ins_encode %{ 10062 __ cvtsd2ss ($dst$$XMMRegister, $src$$Address); 10063 %} 10064 ins_pipe(pipe_slow); // XXX 10065 %} 10066 10067 // XXX do mem variants 10068 instruct convF2I_reg_reg(rRegI dst, regF src, rFlagsReg cr) 10069 %{ 10070 match(Set dst (ConvF2I src)); 10071 effect(KILL cr); 10072 format %{ "convert_f2i $dst, $src" %} 10073 ins_encode %{ 10074 __ convertF2I(T_INT, T_FLOAT, $dst$$Register, $src$$XMMRegister); 10075 %} 10076 ins_pipe(pipe_slow); 10077 %} 10078 10079 instruct convF2L_reg_reg(rRegL dst, regF src, rFlagsReg cr) 10080 %{ 10081 match(Set dst (ConvF2L src)); 10082 effect(KILL cr); 10083 format %{ "convert_f2l $dst, $src"%} 10084 ins_encode %{ 10085 __ convertF2I(T_LONG, T_FLOAT, $dst$$Register, $src$$XMMRegister); 10086 %} 10087 ins_pipe(pipe_slow); 10088 %} 10089 10090 instruct convD2I_reg_reg(rRegI dst, regD src, rFlagsReg cr) 10091 %{ 10092 match(Set dst (ConvD2I src)); 10093 effect(KILL cr); 10094 format %{ "convert_d2i $dst, $src"%} 10095 ins_encode %{ 10096 __ convertF2I(T_INT, T_DOUBLE, $dst$$Register, $src$$XMMRegister); 10097 %} 10098 ins_pipe(pipe_slow); 10099 %} 10100 10101 instruct convD2L_reg_reg(rRegL dst, regD src, rFlagsReg cr) 10102 %{ 10103 match(Set dst (ConvD2L src)); 10104 effect(KILL cr); 10105 format %{ "convert_d2l $dst, $src"%} 10106 ins_encode %{ 10107 __ convertF2I(T_LONG, T_DOUBLE, $dst$$Register, $src$$XMMRegister); 10108 %} 10109 ins_pipe(pipe_slow); 10110 %} 10111 10112 instruct round_double_reg(rRegL dst, regD src, rRegL rtmp, rcx_RegL rcx, rFlagsReg cr) 10113 %{ 10114 match(Set dst (RoundD src)); 10115 effect(TEMP dst, TEMP rtmp, TEMP rcx, KILL cr); 10116 format %{ "round_double $dst,$src \t! using $rtmp and $rcx as TEMP"%} 10117 ins_encode %{ 10118 __ round_double($dst$$Register, $src$$XMMRegister, $rtmp$$Register, $rcx$$Register); 10119 %} 10120 ins_pipe(pipe_slow); 10121 %} 10122 10123 instruct round_float_reg(rRegI dst, regF src, rRegL rtmp, rcx_RegL rcx, rFlagsReg cr) 10124 %{ 10125 match(Set dst (RoundF src)); 10126 effect(TEMP dst, TEMP rtmp, TEMP rcx, KILL cr); 10127 format %{ "round_float $dst,$src" %} 10128 ins_encode %{ 10129 __ round_float($dst$$Register, $src$$XMMRegister, $rtmp$$Register, $rcx$$Register); 10130 %} 10131 ins_pipe(pipe_slow); 10132 %} 10133 10134 instruct convI2F_reg_reg(vlRegF dst, rRegI src) 10135 %{ 10136 predicate(!UseXmmI2F); 10137 match(Set dst (ConvI2F src)); 10138 10139 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10140 ins_encode %{ 10141 if (UseAVX > 0) { 10142 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 10143 } 10144 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Register); 10145 %} 10146 ins_pipe(pipe_slow); // XXX 10147 %} 10148 10149 instruct convI2F_reg_mem(regF dst, memory src) 10150 %{ 10151 predicate(UseAVX == 0); 10152 match(Set dst (ConvI2F (LoadI src))); 10153 10154 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10155 ins_encode %{ 10156 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Address); 10157 %} 10158 ins_pipe(pipe_slow); // XXX 10159 %} 10160 10161 instruct convI2D_reg_reg(vlRegD dst, rRegI src) 10162 %{ 10163 predicate(!UseXmmI2D); 10164 match(Set dst (ConvI2D src)); 10165 10166 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10167 ins_encode %{ 10168 if (UseAVX > 0) { 10169 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 10170 } 10171 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Register); 10172 %} 10173 ins_pipe(pipe_slow); // XXX 10174 %} 10175 10176 instruct convI2D_reg_mem(regD dst, memory src) 10177 %{ 10178 predicate(UseAVX == 0); 10179 match(Set dst (ConvI2D (LoadI src))); 10180 10181 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10182 ins_encode %{ 10183 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Address); 10184 %} 10185 ins_pipe(pipe_slow); // XXX 10186 %} 10187 10188 instruct convXI2F_reg(regF dst, rRegI src) 10189 %{ 10190 predicate(UseXmmI2F); 10191 match(Set dst (ConvI2F src)); 10192 10193 format %{ "movdl $dst, $src\n\t" 10194 "cvtdq2psl $dst, $dst\t# i2f" %} 10195 ins_encode %{ 10196 __ movdl($dst$$XMMRegister, $src$$Register); 10197 __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister); 10198 %} 10199 ins_pipe(pipe_slow); // XXX 10200 %} 10201 10202 instruct convXI2D_reg(regD dst, rRegI src) 10203 %{ 10204 predicate(UseXmmI2D); 10205 match(Set dst (ConvI2D src)); 10206 10207 format %{ "movdl $dst, $src\n\t" 10208 "cvtdq2pdl $dst, $dst\t# i2d" %} 10209 ins_encode %{ 10210 __ movdl($dst$$XMMRegister, $src$$Register); 10211 __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister); 10212 %} 10213 ins_pipe(pipe_slow); // XXX 10214 %} 10215 10216 instruct convL2F_reg_reg(vlRegF dst, rRegL src) 10217 %{ 10218 match(Set dst (ConvL2F src)); 10219 10220 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10221 ins_encode %{ 10222 if (UseAVX > 0) { 10223 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 10224 } 10225 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Register); 10226 %} 10227 ins_pipe(pipe_slow); // XXX 10228 %} 10229 10230 instruct convL2F_reg_mem(regF dst, memory src) 10231 %{ 10232 predicate(UseAVX == 0); 10233 match(Set dst (ConvL2F (LoadL src))); 10234 10235 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10236 ins_encode %{ 10237 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Address); 10238 %} 10239 ins_pipe(pipe_slow); // XXX 10240 %} 10241 10242 instruct convL2D_reg_reg(vlRegD dst, rRegL src) 10243 %{ 10244 match(Set dst (ConvL2D src)); 10245 10246 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10247 ins_encode %{ 10248 if (UseAVX > 0) { 10249 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 10250 } 10251 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Register); 10252 %} 10253 ins_pipe(pipe_slow); // XXX 10254 %} 10255 10256 instruct convL2D_reg_mem(regD dst, memory src) 10257 %{ 10258 predicate(UseAVX == 0); 10259 match(Set dst (ConvL2D (LoadL src))); 10260 10261 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10262 ins_encode %{ 10263 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Address); 10264 %} 10265 ins_pipe(pipe_slow); // XXX 10266 %} 10267 10268 instruct convI2L_reg_reg(rRegL dst, rRegI src) 10269 %{ 10270 match(Set dst (ConvI2L src)); 10271 10272 ins_cost(125); 10273 format %{ "movslq $dst, $src\t# i2l" %} 10274 ins_encode %{ 10275 __ movslq($dst$$Register, $src$$Register); 10276 %} 10277 ins_pipe(ialu_reg_reg); 10278 %} 10279 10280 // Zero-extend convert int to long 10281 instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask) 10282 %{ 10283 match(Set dst (AndL (ConvI2L src) mask)); 10284 10285 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10286 ins_encode %{ 10287 if ($dst$$reg != $src$$reg) { 10288 __ movl($dst$$Register, $src$$Register); 10289 } 10290 %} 10291 ins_pipe(ialu_reg_reg); 10292 %} 10293 10294 // Zero-extend convert int to long 10295 instruct convI2L_reg_mem_zex(rRegL dst, memory src, immL_32bits mask) 10296 %{ 10297 match(Set dst (AndL (ConvI2L (LoadI src)) mask)); 10298 10299 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10300 ins_encode %{ 10301 __ movl($dst$$Register, $src$$Address); 10302 %} 10303 ins_pipe(ialu_reg_mem); 10304 %} 10305 10306 instruct zerox_long_reg_reg(rRegL dst, rRegL src, immL_32bits mask) 10307 %{ 10308 match(Set dst (AndL src mask)); 10309 10310 format %{ "movl $dst, $src\t# zero-extend long" %} 10311 ins_encode %{ 10312 __ movl($dst$$Register, $src$$Register); 10313 %} 10314 ins_pipe(ialu_reg_reg); 10315 %} 10316 10317 instruct convL2I_reg_reg(rRegI dst, rRegL src) 10318 %{ 10319 match(Set dst (ConvL2I src)); 10320 10321 format %{ "movl $dst, $src\t# l2i" %} 10322 ins_encode %{ 10323 __ movl($dst$$Register, $src$$Register); 10324 %} 10325 ins_pipe(ialu_reg_reg); 10326 %} 10327 10328 10329 instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{ 10330 match(Set dst (MoveF2I src)); 10331 effect(DEF dst, USE src); 10332 10333 ins_cost(125); 10334 format %{ "movl $dst, $src\t# MoveF2I_stack_reg" %} 10335 ins_encode %{ 10336 __ movl($dst$$Register, Address(rsp, $src$$disp)); 10337 %} 10338 ins_pipe(ialu_reg_mem); 10339 %} 10340 10341 instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{ 10342 match(Set dst (MoveI2F src)); 10343 effect(DEF dst, USE src); 10344 10345 ins_cost(125); 10346 format %{ "movss $dst, $src\t# MoveI2F_stack_reg" %} 10347 ins_encode %{ 10348 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 10349 %} 10350 ins_pipe(pipe_slow); 10351 %} 10352 10353 instruct MoveD2L_stack_reg(rRegL dst, stackSlotD src) %{ 10354 match(Set dst (MoveD2L src)); 10355 effect(DEF dst, USE src); 10356 10357 ins_cost(125); 10358 format %{ "movq $dst, $src\t# MoveD2L_stack_reg" %} 10359 ins_encode %{ 10360 __ movq($dst$$Register, Address(rsp, $src$$disp)); 10361 %} 10362 ins_pipe(ialu_reg_mem); 10363 %} 10364 10365 instruct MoveL2D_stack_reg_partial(regD dst, stackSlotL src) %{ 10366 predicate(!UseXmmLoadAndClearUpper); 10367 match(Set dst (MoveL2D src)); 10368 effect(DEF dst, USE src); 10369 10370 ins_cost(125); 10371 format %{ "movlpd $dst, $src\t# MoveL2D_stack_reg" %} 10372 ins_encode %{ 10373 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10374 %} 10375 ins_pipe(pipe_slow); 10376 %} 10377 10378 instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{ 10379 predicate(UseXmmLoadAndClearUpper); 10380 match(Set dst (MoveL2D src)); 10381 effect(DEF dst, USE src); 10382 10383 ins_cost(125); 10384 format %{ "movsd $dst, $src\t# MoveL2D_stack_reg" %} 10385 ins_encode %{ 10386 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10387 %} 10388 ins_pipe(pipe_slow); 10389 %} 10390 10391 10392 instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{ 10393 match(Set dst (MoveF2I src)); 10394 effect(DEF dst, USE src); 10395 10396 ins_cost(95); // XXX 10397 format %{ "movss $dst, $src\t# MoveF2I_reg_stack" %} 10398 ins_encode %{ 10399 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 10400 %} 10401 ins_pipe(pipe_slow); 10402 %} 10403 10404 instruct MoveI2F_reg_stack(stackSlotF dst, rRegI src) %{ 10405 match(Set dst (MoveI2F src)); 10406 effect(DEF dst, USE src); 10407 10408 ins_cost(100); 10409 format %{ "movl $dst, $src\t# MoveI2F_reg_stack" %} 10410 ins_encode %{ 10411 __ movl(Address(rsp, $dst$$disp), $src$$Register); 10412 %} 10413 ins_pipe( ialu_mem_reg ); 10414 %} 10415 10416 instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{ 10417 match(Set dst (MoveD2L src)); 10418 effect(DEF dst, USE src); 10419 10420 ins_cost(95); // XXX 10421 format %{ "movsd $dst, $src\t# MoveL2D_reg_stack" %} 10422 ins_encode %{ 10423 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 10424 %} 10425 ins_pipe(pipe_slow); 10426 %} 10427 10428 instruct MoveL2D_reg_stack(stackSlotD dst, rRegL src) %{ 10429 match(Set dst (MoveL2D src)); 10430 effect(DEF dst, USE src); 10431 10432 ins_cost(100); 10433 format %{ "movq $dst, $src\t# MoveL2D_reg_stack" %} 10434 ins_encode %{ 10435 __ movq(Address(rsp, $dst$$disp), $src$$Register); 10436 %} 10437 ins_pipe(ialu_mem_reg); 10438 %} 10439 10440 instruct MoveF2I_reg_reg(rRegI dst, regF src) %{ 10441 match(Set dst (MoveF2I src)); 10442 effect(DEF dst, USE src); 10443 ins_cost(85); 10444 format %{ "movd $dst,$src\t# MoveF2I" %} 10445 ins_encode %{ 10446 __ movdl($dst$$Register, $src$$XMMRegister); 10447 %} 10448 ins_pipe( pipe_slow ); 10449 %} 10450 10451 instruct MoveD2L_reg_reg(rRegL dst, regD src) %{ 10452 match(Set dst (MoveD2L src)); 10453 effect(DEF dst, USE src); 10454 ins_cost(85); 10455 format %{ "movd $dst,$src\t# MoveD2L" %} 10456 ins_encode %{ 10457 __ movdq($dst$$Register, $src$$XMMRegister); 10458 %} 10459 ins_pipe( pipe_slow ); 10460 %} 10461 10462 instruct MoveI2F_reg_reg(regF dst, rRegI src) %{ 10463 match(Set dst (MoveI2F src)); 10464 effect(DEF dst, USE src); 10465 ins_cost(100); 10466 format %{ "movd $dst,$src\t# MoveI2F" %} 10467 ins_encode %{ 10468 __ movdl($dst$$XMMRegister, $src$$Register); 10469 %} 10470 ins_pipe( pipe_slow ); 10471 %} 10472 10473 instruct MoveL2D_reg_reg(regD dst, rRegL src) %{ 10474 match(Set dst (MoveL2D src)); 10475 effect(DEF dst, USE src); 10476 ins_cost(100); 10477 format %{ "movd $dst,$src\t# MoveL2D" %} 10478 ins_encode %{ 10479 __ movdq($dst$$XMMRegister, $src$$Register); 10480 %} 10481 ins_pipe( pipe_slow ); 10482 %} 10483 10484 10485 // Fast clearing of an array 10486 // Small non-constant lenght ClearArray for non-AVX512 targets. 10487 instruct rep_stos(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegL val, 10488 Universe dummy, rFlagsReg cr) 10489 %{ 10490 predicate(!((ClearArrayNode*)n)->is_large() && !((ClearArrayNode*)n)->word_copy_only() && (UseAVX <= 2)); 10491 match(Set dummy (ClearArray (Binary cnt base) val)); 10492 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, USE_KILL val, KILL cr); 10493 10494 format %{ $$template 10495 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 10496 $$emit$$"jg LARGE\n\t" 10497 $$emit$$"dec rcx\n\t" 10498 $$emit$$"js DONE\t# Zero length\n\t" 10499 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 10500 $$emit$$"dec rcx\n\t" 10501 $$emit$$"jge LOOP\n\t" 10502 $$emit$$"jmp DONE\n\t" 10503 $$emit$$"# LARGE:\n\t" 10504 if (UseFastStosb) { 10505 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10506 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--\n\t" 10507 } else if (UseXMMForObjInit) { 10508 $$emit$$"movdq $tmp, $val\n\t" 10509 $$emit$$"punpcklqdq $tmp, $tmp\n\t" 10510 $$emit$$"vinserti128_high $tmp, $tmp\n\t" 10511 $$emit$$"jmpq L_zero_64_bytes\n\t" 10512 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10513 $$emit$$"vmovdqu $tmp,(rax)\n\t" 10514 $$emit$$"vmovdqu $tmp,0x20(rax)\n\t" 10515 $$emit$$"add 0x40,rax\n\t" 10516 $$emit$$"# L_zero_64_bytes:\n\t" 10517 $$emit$$"sub 0x8,rcx\n\t" 10518 $$emit$$"jge L_loop\n\t" 10519 $$emit$$"add 0x4,rcx\n\t" 10520 $$emit$$"jl L_tail\n\t" 10521 $$emit$$"vmovdqu $tmp,(rax)\n\t" 10522 $$emit$$"add 0x20,rax\n\t" 10523 $$emit$$"sub 0x4,rcx\n\t" 10524 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10525 $$emit$$"add 0x4,rcx\n\t" 10526 $$emit$$"jle L_end\n\t" 10527 $$emit$$"dec rcx\n\t" 10528 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10529 $$emit$$"vmovq xmm0,(rax)\n\t" 10530 $$emit$$"add 0x8,rax\n\t" 10531 $$emit$$"dec rcx\n\t" 10532 $$emit$$"jge L_sloop\n\t" 10533 $$emit$$"# L_end:\n\t" 10534 } else { 10535 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 10536 } 10537 $$emit$$"# DONE" 10538 %} 10539 ins_encode %{ 10540 __ clear_mem($base$$Register, $cnt$$Register, $val$$Register, 10541 $tmp$$XMMRegister, false, false); 10542 %} 10543 ins_pipe(pipe_slow); 10544 %} 10545 10546 instruct rep_stos_word_copy(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegL val, 10547 Universe dummy, rFlagsReg cr) 10548 %{ 10549 predicate(!((ClearArrayNode*)n)->is_large() && ((ClearArrayNode*)n)->word_copy_only() && (UseAVX <= 2)); 10550 match(Set dummy (ClearArray (Binary cnt base) val)); 10551 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, USE_KILL val, KILL cr); 10552 10553 format %{ $$template 10554 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 10555 $$emit$$"jg LARGE\n\t" 10556 $$emit$$"dec rcx\n\t" 10557 $$emit$$"js DONE\t# Zero length\n\t" 10558 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 10559 $$emit$$"dec rcx\n\t" 10560 $$emit$$"jge LOOP\n\t" 10561 $$emit$$"jmp DONE\n\t" 10562 $$emit$$"# LARGE:\n\t" 10563 if (UseXMMForObjInit) { 10564 $$emit$$"movdq $tmp, $val\n\t" 10565 $$emit$$"punpcklqdq $tmp, $tmp\n\t" 10566 $$emit$$"vinserti128_high $tmp, $tmp\n\t" 10567 $$emit$$"jmpq L_zero_64_bytes\n\t" 10568 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10569 $$emit$$"vmovdqu $tmp,(rax)\n\t" 10570 $$emit$$"vmovdqu $tmp,0x20(rax)\n\t" 10571 $$emit$$"add 0x40,rax\n\t" 10572 $$emit$$"# L_zero_64_bytes:\n\t" 10573 $$emit$$"sub 0x8,rcx\n\t" 10574 $$emit$$"jge L_loop\n\t" 10575 $$emit$$"add 0x4,rcx\n\t" 10576 $$emit$$"jl L_tail\n\t" 10577 $$emit$$"vmovdqu $tmp,(rax)\n\t" 10578 $$emit$$"add 0x20,rax\n\t" 10579 $$emit$$"sub 0x4,rcx\n\t" 10580 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10581 $$emit$$"add 0x4,rcx\n\t" 10582 $$emit$$"jle L_end\n\t" 10583 $$emit$$"dec rcx\n\t" 10584 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10585 $$emit$$"vmovq xmm0,(rax)\n\t" 10586 $$emit$$"add 0x8,rax\n\t" 10587 $$emit$$"dec rcx\n\t" 10588 $$emit$$"jge L_sloop\n\t" 10589 $$emit$$"# L_end:\n\t" 10590 } else { 10591 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 10592 } 10593 $$emit$$"# DONE" 10594 %} 10595 ins_encode %{ 10596 __ clear_mem($base$$Register, $cnt$$Register, $val$$Register, 10597 $tmp$$XMMRegister, false, true); 10598 %} 10599 ins_pipe(pipe_slow); 10600 %} 10601 10602 // Small non-constant length ClearArray for AVX512 targets. 10603 instruct rep_stos_evex(rcx_RegL cnt, rdi_RegP base, legRegD tmp, kReg ktmp, rax_RegL val, 10604 Universe dummy, rFlagsReg cr) 10605 %{ 10606 predicate(!((ClearArrayNode*)n)->is_large() && !((ClearArrayNode*)n)->word_copy_only() && (UseAVX > 2)); 10607 match(Set dummy (ClearArray (Binary cnt base) val)); 10608 ins_cost(125); 10609 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, TEMP ktmp, USE_KILL val, KILL cr); 10610 10611 format %{ $$template 10612 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10613 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 10614 $$emit$$"jg LARGE\n\t" 10615 $$emit$$"dec rcx\n\t" 10616 $$emit$$"js DONE\t# Zero length\n\t" 10617 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 10618 $$emit$$"dec rcx\n\t" 10619 $$emit$$"jge LOOP\n\t" 10620 $$emit$$"jmp DONE\n\t" 10621 $$emit$$"# LARGE:\n\t" 10622 if (UseFastStosb) { 10623 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10624 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--\n\t" 10625 } else if (UseXMMForObjInit) { 10626 $$emit$$"mov rdi,rax\n\t" 10627 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 10628 $$emit$$"jmpq L_zero_64_bytes\n\t" 10629 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10630 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10631 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 10632 $$emit$$"add 0x40,rax\n\t" 10633 $$emit$$"# L_zero_64_bytes:\n\t" 10634 $$emit$$"sub 0x8,rcx\n\t" 10635 $$emit$$"jge L_loop\n\t" 10636 $$emit$$"add 0x4,rcx\n\t" 10637 $$emit$$"jl L_tail\n\t" 10638 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10639 $$emit$$"add 0x20,rax\n\t" 10640 $$emit$$"sub 0x4,rcx\n\t" 10641 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10642 $$emit$$"add 0x4,rcx\n\t" 10643 $$emit$$"jle L_end\n\t" 10644 $$emit$$"dec rcx\n\t" 10645 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10646 $$emit$$"vmovq xmm0,(rax)\n\t" 10647 $$emit$$"add 0x8,rax\n\t" 10648 $$emit$$"dec rcx\n\t" 10649 $$emit$$"jge L_sloop\n\t" 10650 $$emit$$"# L_end:\n\t" 10651 } else { 10652 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 10653 } 10654 $$emit$$"# DONE" 10655 %} 10656 ins_encode %{ 10657 __ clear_mem($base$$Register, $cnt$$Register, $val$$Register, 10658 $tmp$$XMMRegister, false, false, $ktmp$$KRegister); 10659 %} 10660 ins_pipe(pipe_slow); 10661 %} 10662 10663 instruct rep_stos_evex_word_copy(rcx_RegL cnt, rdi_RegP base, legRegD tmp, kReg ktmp, rax_RegL val, 10664 Universe dummy, rFlagsReg cr) 10665 %{ 10666 predicate(!((ClearArrayNode*)n)->is_large() && ((ClearArrayNode*)n)->word_copy_only() && (UseAVX > 2)); 10667 match(Set dummy (ClearArray (Binary cnt base) val)); 10668 ins_cost(125); 10669 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, TEMP ktmp, USE_KILL val, KILL cr); 10670 10671 format %{ $$template 10672 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10673 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 10674 $$emit$$"jg LARGE\n\t" 10675 $$emit$$"dec rcx\n\t" 10676 $$emit$$"js DONE\t# Zero length\n\t" 10677 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 10678 $$emit$$"dec rcx\n\t" 10679 $$emit$$"jge LOOP\n\t" 10680 $$emit$$"jmp DONE\n\t" 10681 $$emit$$"# LARGE:\n\t" 10682 if (UseFastStosb) { 10683 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10684 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--\n\t" 10685 } else if (UseXMMForObjInit) { 10686 $$emit$$"mov rdi,rax\n\t" 10687 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 10688 $$emit$$"jmpq L_zero_64_bytes\n\t" 10689 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10690 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10691 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 10692 $$emit$$"add 0x40,rax\n\t" 10693 $$emit$$"# L_zero_64_bytes:\n\t" 10694 $$emit$$"sub 0x8,rcx\n\t" 10695 $$emit$$"jge L_loop\n\t" 10696 $$emit$$"add 0x4,rcx\n\t" 10697 $$emit$$"jl L_tail\n\t" 10698 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10699 $$emit$$"add 0x20,rax\n\t" 10700 $$emit$$"sub 0x4,rcx\n\t" 10701 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10702 $$emit$$"add 0x4,rcx\n\t" 10703 $$emit$$"jle L_end\n\t" 10704 $$emit$$"dec rcx\n\t" 10705 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10706 $$emit$$"vmovq xmm0,(rax)\n\t" 10707 $$emit$$"add 0x8,rax\n\t" 10708 $$emit$$"dec rcx\n\t" 10709 $$emit$$"jge L_sloop\n\t" 10710 $$emit$$"# L_end:\n\t" 10711 } else { 10712 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 10713 } 10714 $$emit$$"# DONE" 10715 %} 10716 ins_encode %{ 10717 __ clear_mem($base$$Register, $cnt$$Register, $val$$Register, 10718 $tmp$$XMMRegister, false, true, $ktmp$$KRegister); 10719 %} 10720 ins_pipe(pipe_slow); 10721 %} 10722 10723 // Large non-constant length ClearArray for non-AVX512 targets. 10724 instruct rep_stos_large(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegL val, 10725 Universe dummy, rFlagsReg cr) 10726 %{ 10727 predicate(((ClearArrayNode*)n)->is_large() && !((ClearArrayNode*)n)->word_copy_only() && (UseAVX <= 2)); 10728 match(Set dummy (ClearArray (Binary cnt base) val)); 10729 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, USE_KILL val, KILL cr); 10730 10731 format %{ $$template 10732 if (UseFastStosb) { 10733 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10734 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--" 10735 } else if (UseXMMForObjInit) { 10736 $$emit$$"movdq $tmp, $val\n\t" 10737 $$emit$$"punpcklqdq $tmp, $tmp\n\t" 10738 $$emit$$"vinserti128_high $tmp, $tmp\n\t" 10739 $$emit$$"jmpq L_zero_64_bytes\n\t" 10740 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10741 $$emit$$"vmovdqu $tmp,(rax)\n\t" 10742 $$emit$$"vmovdqu $tmp,0x20(rax)\n\t" 10743 $$emit$$"add 0x40,rax\n\t" 10744 $$emit$$"# L_zero_64_bytes:\n\t" 10745 $$emit$$"sub 0x8,rcx\n\t" 10746 $$emit$$"jge L_loop\n\t" 10747 $$emit$$"add 0x4,rcx\n\t" 10748 $$emit$$"jl L_tail\n\t" 10749 $$emit$$"vmovdqu $tmp,(rax)\n\t" 10750 $$emit$$"add 0x20,rax\n\t" 10751 $$emit$$"sub 0x4,rcx\n\t" 10752 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10753 $$emit$$"add 0x4,rcx\n\t" 10754 $$emit$$"jle L_end\n\t" 10755 $$emit$$"dec rcx\n\t" 10756 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10757 $$emit$$"vmovq xmm0,(rax)\n\t" 10758 $$emit$$"add 0x8,rax\n\t" 10759 $$emit$$"dec rcx\n\t" 10760 $$emit$$"jge L_sloop\n\t" 10761 $$emit$$"# L_end:\n\t" 10762 } else { 10763 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 10764 } 10765 %} 10766 ins_encode %{ 10767 __ clear_mem($base$$Register, $cnt$$Register, $val$$Register, 10768 $tmp$$XMMRegister, true, false); 10769 %} 10770 ins_pipe(pipe_slow); 10771 %} 10772 10773 instruct rep_stos_large_word_copy(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegL val, 10774 Universe dummy, rFlagsReg cr) 10775 %{ 10776 predicate(((ClearArrayNode*)n)->is_large() && ((ClearArrayNode*)n)->word_copy_only() && (UseAVX <= 2)); 10777 match(Set dummy (ClearArray (Binary cnt base) val)); 10778 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, USE_KILL val, KILL cr); 10779 10780 format %{ $$template 10781 if (UseXMMForObjInit) { 10782 $$emit$$"movdq $tmp, $val\n\t" 10783 $$emit$$"punpcklqdq $tmp, $tmp\n\t" 10784 $$emit$$"vinserti128_high $tmp, $tmp\n\t" 10785 $$emit$$"jmpq L_zero_64_bytes\n\t" 10786 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10787 $$emit$$"vmovdqu $tmp,(rax)\n\t" 10788 $$emit$$"vmovdqu $tmp,0x20(rax)\n\t" 10789 $$emit$$"add 0x40,rax\n\t" 10790 $$emit$$"# L_zero_64_bytes:\n\t" 10791 $$emit$$"sub 0x8,rcx\n\t" 10792 $$emit$$"jge L_loop\n\t" 10793 $$emit$$"add 0x4,rcx\n\t" 10794 $$emit$$"jl L_tail\n\t" 10795 $$emit$$"vmovdqu $tmp,(rax)\n\t" 10796 $$emit$$"add 0x20,rax\n\t" 10797 $$emit$$"sub 0x4,rcx\n\t" 10798 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10799 $$emit$$"add 0x4,rcx\n\t" 10800 $$emit$$"jle L_end\n\t" 10801 $$emit$$"dec rcx\n\t" 10802 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10803 $$emit$$"vmovq xmm0,(rax)\n\t" 10804 $$emit$$"add 0x8,rax\n\t" 10805 $$emit$$"dec rcx\n\t" 10806 $$emit$$"jge L_sloop\n\t" 10807 $$emit$$"# L_end:\n\t" 10808 } else { 10809 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 10810 } 10811 %} 10812 ins_encode %{ 10813 __ clear_mem($base$$Register, $cnt$$Register, $val$$Register, 10814 $tmp$$XMMRegister, true, true); 10815 %} 10816 ins_pipe(pipe_slow); 10817 %} 10818 10819 // Large non-constant length ClearArray for AVX512 targets. 10820 instruct rep_stos_large_evex(rcx_RegL cnt, rdi_RegP base, legRegD tmp, kReg ktmp, rax_RegL val, 10821 Universe dummy, rFlagsReg cr) 10822 %{ 10823 predicate(((ClearArrayNode*)n)->is_large() && !((ClearArrayNode*)n)->word_copy_only() && (UseAVX > 2)); 10824 match(Set dummy (ClearArray (Binary cnt base) val)); 10825 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, TEMP ktmp, USE_KILL val, KILL cr); 10826 10827 format %{ $$template 10828 if (UseFastStosb) { 10829 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10830 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10831 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--" 10832 } else if (UseXMMForObjInit) { 10833 $$emit$$"mov rdi,rax\t# ClearArray:\n\t" 10834 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 10835 $$emit$$"jmpq L_zero_64_bytes\n\t" 10836 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10837 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10838 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 10839 $$emit$$"add 0x40,rax\n\t" 10840 $$emit$$"# L_zero_64_bytes:\n\t" 10841 $$emit$$"sub 0x8,rcx\n\t" 10842 $$emit$$"jge L_loop\n\t" 10843 $$emit$$"add 0x4,rcx\n\t" 10844 $$emit$$"jl L_tail\n\t" 10845 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10846 $$emit$$"add 0x20,rax\n\t" 10847 $$emit$$"sub 0x4,rcx\n\t" 10848 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10849 $$emit$$"add 0x4,rcx\n\t" 10850 $$emit$$"jle L_end\n\t" 10851 $$emit$$"dec rcx\n\t" 10852 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10853 $$emit$$"vmovq xmm0,(rax)\n\t" 10854 $$emit$$"add 0x8,rax\n\t" 10855 $$emit$$"dec rcx\n\t" 10856 $$emit$$"jge L_sloop\n\t" 10857 $$emit$$"# L_end:\n\t" 10858 } else { 10859 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10860 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 10861 } 10862 %} 10863 ins_encode %{ 10864 __ clear_mem($base$$Register, $cnt$$Register, $val$$Register, 10865 $tmp$$XMMRegister, true, false, $ktmp$$KRegister); 10866 %} 10867 ins_pipe(pipe_slow); 10868 %} 10869 10870 instruct rep_stos_large_evex_word_copy(rcx_RegL cnt, rdi_RegP base, legRegD tmp, kReg ktmp, rax_RegL val, 10871 Universe dummy, rFlagsReg cr) 10872 %{ 10873 predicate(((ClearArrayNode*)n)->is_large() && ((ClearArrayNode*)n)->word_copy_only() && (UseAVX > 2)); 10874 match(Set dummy (ClearArray (Binary cnt base) val)); 10875 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, TEMP ktmp, USE_KILL val, KILL cr); 10876 10877 format %{ $$template 10878 if (UseFastStosb) { 10879 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10880 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10881 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--" 10882 } else if (UseXMMForObjInit) { 10883 $$emit$$"mov rdi,rax\t# ClearArray:\n\t" 10884 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 10885 $$emit$$"jmpq L_zero_64_bytes\n\t" 10886 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10887 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10888 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 10889 $$emit$$"add 0x40,rax\n\t" 10890 $$emit$$"# L_zero_64_bytes:\n\t" 10891 $$emit$$"sub 0x8,rcx\n\t" 10892 $$emit$$"jge L_loop\n\t" 10893 $$emit$$"add 0x4,rcx\n\t" 10894 $$emit$$"jl L_tail\n\t" 10895 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10896 $$emit$$"add 0x20,rax\n\t" 10897 $$emit$$"sub 0x4,rcx\n\t" 10898 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10899 $$emit$$"add 0x4,rcx\n\t" 10900 $$emit$$"jle L_end\n\t" 10901 $$emit$$"dec rcx\n\t" 10902 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10903 $$emit$$"vmovq xmm0,(rax)\n\t" 10904 $$emit$$"add 0x8,rax\n\t" 10905 $$emit$$"dec rcx\n\t" 10906 $$emit$$"jge L_sloop\n\t" 10907 $$emit$$"# L_end:\n\t" 10908 } else { 10909 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10910 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 10911 } 10912 %} 10913 ins_encode %{ 10914 __ clear_mem($base$$Register, $cnt$$Register, $val$$Register, 10915 $tmp$$XMMRegister, true, true, $ktmp$$KRegister); 10916 %} 10917 ins_pipe(pipe_slow); 10918 %} 10919 10920 // Small constant length ClearArray for AVX512 targets. 10921 instruct rep_stos_im(immL cnt, rRegP base, regD tmp, rax_RegL val, kReg ktmp, Universe dummy, rFlagsReg cr) 10922 %{ 10923 predicate(!((ClearArrayNode*)n)->is_large() && !((ClearArrayNode*)n)->word_copy_only() && 10924 ((MaxVectorSize >= 32) && VM_Version::supports_avx512vl())); 10925 match(Set dummy (ClearArray (Binary cnt base) val)); 10926 ins_cost(100); 10927 effect(TEMP tmp, USE_KILL val, TEMP ktmp, KILL cr); 10928 format %{ "clear_mem_imm $base , $cnt \n\t" %} 10929 ins_encode %{ 10930 __ clear_mem($base$$Register, $cnt$$constant, $val$$Register, $tmp$$XMMRegister, $ktmp$$KRegister); 10931 %} 10932 ins_pipe(pipe_slow); 10933 %} 10934 10935 instruct string_compareL(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10936 rax_RegI result, legRegD tmp1, rFlagsReg cr) 10937 %{ 10938 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 10939 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10940 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10941 10942 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10943 ins_encode %{ 10944 __ string_compare($str1$$Register, $str2$$Register, 10945 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10946 $tmp1$$XMMRegister, StrIntrinsicNode::LL, knoreg); 10947 %} 10948 ins_pipe( pipe_slow ); 10949 %} 10950 10951 instruct string_compareL_evex(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10952 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 10953 %{ 10954 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 10955 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10956 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10957 10958 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10959 ins_encode %{ 10960 __ string_compare($str1$$Register, $str2$$Register, 10961 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10962 $tmp1$$XMMRegister, StrIntrinsicNode::LL, $ktmp$$KRegister); 10963 %} 10964 ins_pipe( pipe_slow ); 10965 %} 10966 10967 instruct string_compareU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10968 rax_RegI result, legRegD tmp1, rFlagsReg cr) 10969 %{ 10970 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 10971 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10972 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10973 10974 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10975 ins_encode %{ 10976 __ string_compare($str1$$Register, $str2$$Register, 10977 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10978 $tmp1$$XMMRegister, StrIntrinsicNode::UU, knoreg); 10979 %} 10980 ins_pipe( pipe_slow ); 10981 %} 10982 10983 instruct string_compareU_evex(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10984 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 10985 %{ 10986 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 10987 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10988 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10989 10990 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10991 ins_encode %{ 10992 __ string_compare($str1$$Register, $str2$$Register, 10993 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10994 $tmp1$$XMMRegister, StrIntrinsicNode::UU, $ktmp$$KRegister); 10995 %} 10996 ins_pipe( pipe_slow ); 10997 %} 10998 10999 instruct string_compareLU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 11000 rax_RegI result, legRegD tmp1, rFlagsReg cr) 11001 %{ 11002 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 11003 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11004 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11005 11006 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11007 ins_encode %{ 11008 __ string_compare($str1$$Register, $str2$$Register, 11009 $cnt1$$Register, $cnt2$$Register, $result$$Register, 11010 $tmp1$$XMMRegister, StrIntrinsicNode::LU, knoreg); 11011 %} 11012 ins_pipe( pipe_slow ); 11013 %} 11014 11015 instruct string_compareLU_evex(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 11016 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 11017 %{ 11018 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 11019 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11020 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11021 11022 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11023 ins_encode %{ 11024 __ string_compare($str1$$Register, $str2$$Register, 11025 $cnt1$$Register, $cnt2$$Register, $result$$Register, 11026 $tmp1$$XMMRegister, StrIntrinsicNode::LU, $ktmp$$KRegister); 11027 %} 11028 ins_pipe( pipe_slow ); 11029 %} 11030 11031 instruct string_compareUL(rsi_RegP str1, rdx_RegI cnt1, rdi_RegP str2, rcx_RegI cnt2, 11032 rax_RegI result, legRegD tmp1, rFlagsReg cr) 11033 %{ 11034 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 11035 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11036 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11037 11038 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11039 ins_encode %{ 11040 __ string_compare($str2$$Register, $str1$$Register, 11041 $cnt2$$Register, $cnt1$$Register, $result$$Register, 11042 $tmp1$$XMMRegister, StrIntrinsicNode::UL, knoreg); 11043 %} 11044 ins_pipe( pipe_slow ); 11045 %} 11046 11047 instruct string_compareUL_evex(rsi_RegP str1, rdx_RegI cnt1, rdi_RegP str2, rcx_RegI cnt2, 11048 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 11049 %{ 11050 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 11051 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11052 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11053 11054 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11055 ins_encode %{ 11056 __ string_compare($str2$$Register, $str1$$Register, 11057 $cnt2$$Register, $cnt1$$Register, $result$$Register, 11058 $tmp1$$XMMRegister, StrIntrinsicNode::UL, $ktmp$$KRegister); 11059 %} 11060 ins_pipe( pipe_slow ); 11061 %} 11062 11063 // fast search of substring with known size. 11064 instruct string_indexof_conL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 11065 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 11066 %{ 11067 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 11068 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 11069 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 11070 11071 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %} 11072 ins_encode %{ 11073 int icnt2 = (int)$int_cnt2$$constant; 11074 if (icnt2 >= 16) { 11075 // IndexOf for constant substrings with size >= 16 elements 11076 // which don't need to be loaded through stack. 11077 __ string_indexofC8($str1$$Register, $str2$$Register, 11078 $cnt1$$Register, $cnt2$$Register, 11079 icnt2, $result$$Register, 11080 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 11081 } else { 11082 // Small strings are loaded through stack if they cross page boundary. 11083 __ string_indexof($str1$$Register, $str2$$Register, 11084 $cnt1$$Register, $cnt2$$Register, 11085 icnt2, $result$$Register, 11086 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 11087 } 11088 %} 11089 ins_pipe( pipe_slow ); 11090 %} 11091 11092 // fast search of substring with known size. 11093 instruct string_indexof_conU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 11094 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 11095 %{ 11096 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 11097 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 11098 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 11099 11100 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %} 11101 ins_encode %{ 11102 int icnt2 = (int)$int_cnt2$$constant; 11103 if (icnt2 >= 8) { 11104 // IndexOf for constant substrings with size >= 8 elements 11105 // which don't need to be loaded through stack. 11106 __ string_indexofC8($str1$$Register, $str2$$Register, 11107 $cnt1$$Register, $cnt2$$Register, 11108 icnt2, $result$$Register, 11109 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 11110 } else { 11111 // Small strings are loaded through stack if they cross page boundary. 11112 __ string_indexof($str1$$Register, $str2$$Register, 11113 $cnt1$$Register, $cnt2$$Register, 11114 icnt2, $result$$Register, 11115 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 11116 } 11117 %} 11118 ins_pipe( pipe_slow ); 11119 %} 11120 11121 // fast search of substring with known size. 11122 instruct string_indexof_conUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 11123 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 11124 %{ 11125 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 11126 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 11127 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 11128 11129 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %} 11130 ins_encode %{ 11131 int icnt2 = (int)$int_cnt2$$constant; 11132 if (icnt2 >= 8) { 11133 // IndexOf for constant substrings with size >= 8 elements 11134 // which don't need to be loaded through stack. 11135 __ string_indexofC8($str1$$Register, $str2$$Register, 11136 $cnt1$$Register, $cnt2$$Register, 11137 icnt2, $result$$Register, 11138 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 11139 } else { 11140 // Small strings are loaded through stack if they cross page boundary. 11141 __ string_indexof($str1$$Register, $str2$$Register, 11142 $cnt1$$Register, $cnt2$$Register, 11143 icnt2, $result$$Register, 11144 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 11145 } 11146 %} 11147 ins_pipe( pipe_slow ); 11148 %} 11149 11150 instruct string_indexofL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11151 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr) 11152 %{ 11153 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 11154 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11155 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11156 11157 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11158 ins_encode %{ 11159 __ string_indexof($str1$$Register, $str2$$Register, 11160 $cnt1$$Register, $cnt2$$Register, 11161 (-1), $result$$Register, 11162 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 11163 %} 11164 ins_pipe( pipe_slow ); 11165 %} 11166 11167 instruct string_indexofU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11168 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr) 11169 %{ 11170 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 11171 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11172 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11173 11174 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11175 ins_encode %{ 11176 __ string_indexof($str1$$Register, $str2$$Register, 11177 $cnt1$$Register, $cnt2$$Register, 11178 (-1), $result$$Register, 11179 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 11180 %} 11181 ins_pipe( pipe_slow ); 11182 %} 11183 11184 instruct string_indexofUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11185 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr) 11186 %{ 11187 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 11188 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11189 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11190 11191 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11192 ins_encode %{ 11193 __ string_indexof($str1$$Register, $str2$$Register, 11194 $cnt1$$Register, $cnt2$$Register, 11195 (-1), $result$$Register, 11196 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 11197 %} 11198 ins_pipe( pipe_slow ); 11199 %} 11200 11201 instruct string_indexof_char(rdi_RegP str1, rdx_RegI cnt1, rax_RegI ch, 11202 rbx_RegI result, legRegD tmp_vec1, legRegD tmp_vec2, legRegD tmp_vec3, rcx_RegI tmp, rFlagsReg cr) 11203 %{ 11204 predicate(UseSSE42Intrinsics && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::U)); 11205 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 11206 effect(TEMP tmp_vec1, TEMP tmp_vec2, TEMP tmp_vec3, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP tmp, KILL cr); 11207 format %{ "StringUTF16 IndexOf char[] $str1,$cnt1,$ch -> $result // KILL all" %} 11208 ins_encode %{ 11209 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register, 11210 $tmp_vec1$$XMMRegister, $tmp_vec2$$XMMRegister, $tmp_vec3$$XMMRegister, $tmp$$Register); 11211 %} 11212 ins_pipe( pipe_slow ); 11213 %} 11214 11215 instruct stringL_indexof_char(rdi_RegP str1, rdx_RegI cnt1, rax_RegI ch, 11216 rbx_RegI result, legRegD tmp_vec1, legRegD tmp_vec2, legRegD tmp_vec3, rcx_RegI tmp, rFlagsReg cr) 11217 %{ 11218 predicate(UseSSE42Intrinsics && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::L)); 11219 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 11220 effect(TEMP tmp_vec1, TEMP tmp_vec2, TEMP tmp_vec3, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP tmp, KILL cr); 11221 format %{ "StringLatin1 IndexOf char[] $str1,$cnt1,$ch -> $result // KILL all" %} 11222 ins_encode %{ 11223 __ stringL_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register, 11224 $tmp_vec1$$XMMRegister, $tmp_vec2$$XMMRegister, $tmp_vec3$$XMMRegister, $tmp$$Register); 11225 %} 11226 ins_pipe( pipe_slow ); 11227 %} 11228 11229 // fast string equals 11230 instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 11231 legRegD tmp1, legRegD tmp2, rbx_RegI tmp3, rFlagsReg cr) 11232 %{ 11233 predicate(!VM_Version::supports_avx512vlbw()); 11234 match(Set result (StrEquals (Binary str1 str2) cnt)); 11235 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 11236 11237 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11238 ins_encode %{ 11239 __ arrays_equals(false, $str1$$Register, $str2$$Register, 11240 $cnt$$Register, $result$$Register, $tmp3$$Register, 11241 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, knoreg); 11242 %} 11243 ins_pipe( pipe_slow ); 11244 %} 11245 11246 instruct string_equals_evex(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 11247 legRegD tmp1, legRegD tmp2, kReg ktmp, rbx_RegI tmp3, rFlagsReg cr) 11248 %{ 11249 predicate(VM_Version::supports_avx512vlbw()); 11250 match(Set result (StrEquals (Binary str1 str2) cnt)); 11251 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 11252 11253 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11254 ins_encode %{ 11255 __ arrays_equals(false, $str1$$Register, $str2$$Register, 11256 $cnt$$Register, $result$$Register, $tmp3$$Register, 11257 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, $ktmp$$KRegister); 11258 %} 11259 ins_pipe( pipe_slow ); 11260 %} 11261 11262 // fast array equals 11263 instruct array_equalsB(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11264 legRegD tmp1, legRegD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11265 %{ 11266 predicate(!VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 11267 match(Set result (AryEq ary1 ary2)); 11268 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11269 11270 format %{ "Array Equals byte[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11271 ins_encode %{ 11272 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11273 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11274 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, knoreg); 11275 %} 11276 ins_pipe( pipe_slow ); 11277 %} 11278 11279 instruct array_equalsB_evex(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11280 legRegD tmp1, legRegD tmp2, kReg ktmp, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11281 %{ 11282 predicate(VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 11283 match(Set result (AryEq ary1 ary2)); 11284 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11285 11286 format %{ "Array Equals byte[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11287 ins_encode %{ 11288 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11289 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11290 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, $ktmp$$KRegister); 11291 %} 11292 ins_pipe( pipe_slow ); 11293 %} 11294 11295 instruct array_equalsC(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11296 legRegD tmp1, legRegD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11297 %{ 11298 predicate(!VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 11299 match(Set result (AryEq ary1 ary2)); 11300 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11301 11302 format %{ "Array Equals char[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11303 ins_encode %{ 11304 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11305 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11306 $tmp1$$XMMRegister, $tmp2$$XMMRegister, true /* char */, knoreg); 11307 %} 11308 ins_pipe( pipe_slow ); 11309 %} 11310 11311 instruct array_equalsC_evex(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11312 legRegD tmp1, legRegD tmp2, kReg ktmp, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11313 %{ 11314 predicate(VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 11315 match(Set result (AryEq ary1 ary2)); 11316 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11317 11318 format %{ "Array Equals char[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11319 ins_encode %{ 11320 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11321 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11322 $tmp1$$XMMRegister, $tmp2$$XMMRegister, true /* char */, $ktmp$$KRegister); 11323 %} 11324 ins_pipe( pipe_slow ); 11325 %} 11326 11327 instruct arrays_hashcode(rdi_RegP ary1, rdx_RegI cnt1, rbx_RegI result, immU8 basic_type, 11328 legRegD tmp_vec1, legRegD tmp_vec2, legRegD tmp_vec3, legRegD tmp_vec4, 11329 legRegD tmp_vec5, legRegD tmp_vec6, legRegD tmp_vec7, legRegD tmp_vec8, 11330 legRegD tmp_vec9, legRegD tmp_vec10, legRegD tmp_vec11, legRegD tmp_vec12, 11331 legRegD tmp_vec13, rRegI tmp1, rRegI tmp2, rRegI tmp3, rFlagsReg cr) 11332 %{ 11333 predicate(UseAVX >= 2); 11334 match(Set result (VectorizedHashCode (Binary ary1 cnt1) (Binary result basic_type))); 11335 effect(TEMP tmp_vec1, TEMP tmp_vec2, TEMP tmp_vec3, TEMP tmp_vec4, TEMP tmp_vec5, TEMP tmp_vec6, 11336 TEMP tmp_vec7, TEMP tmp_vec8, TEMP tmp_vec9, TEMP tmp_vec10, TEMP tmp_vec11, TEMP tmp_vec12, 11337 TEMP tmp_vec13, TEMP tmp1, TEMP tmp2, TEMP tmp3, USE_KILL ary1, USE_KILL cnt1, 11338 USE basic_type, KILL cr); 11339 11340 format %{ "Array HashCode array[] $ary1,$cnt1,$result,$basic_type -> $result // KILL all" %} 11341 ins_encode %{ 11342 __ arrays_hashcode($ary1$$Register, $cnt1$$Register, $result$$Register, 11343 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 11344 $tmp_vec1$$XMMRegister, $tmp_vec2$$XMMRegister, $tmp_vec3$$XMMRegister, 11345 $tmp_vec4$$XMMRegister, $tmp_vec5$$XMMRegister, $tmp_vec6$$XMMRegister, 11346 $tmp_vec7$$XMMRegister, $tmp_vec8$$XMMRegister, $tmp_vec9$$XMMRegister, 11347 $tmp_vec10$$XMMRegister, $tmp_vec11$$XMMRegister, $tmp_vec12$$XMMRegister, 11348 $tmp_vec13$$XMMRegister, (BasicType)$basic_type$$constant); 11349 %} 11350 ins_pipe( pipe_slow ); 11351 %} 11352 11353 instruct count_positives(rsi_RegP ary1, rcx_RegI len, rax_RegI result, 11354 legRegD tmp1, legRegD tmp2, rbx_RegI tmp3, rFlagsReg cr,) 11355 %{ 11356 predicate(!VM_Version::supports_avx512vlbw() || !VM_Version::supports_bmi2()); 11357 match(Set result (CountPositives ary1 len)); 11358 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr); 11359 11360 format %{ "countPositives byte[] $ary1,$len -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11361 ins_encode %{ 11362 __ count_positives($ary1$$Register, $len$$Register, 11363 $result$$Register, $tmp3$$Register, 11364 $tmp1$$XMMRegister, $tmp2$$XMMRegister, knoreg, knoreg); 11365 %} 11366 ins_pipe( pipe_slow ); 11367 %} 11368 11369 instruct count_positives_evex(rsi_RegP ary1, rcx_RegI len, rax_RegI result, 11370 legRegD tmp1, legRegD tmp2, kReg ktmp1, kReg ktmp2, rbx_RegI tmp3, rFlagsReg cr,) 11371 %{ 11372 predicate(VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2()); 11373 match(Set result (CountPositives ary1 len)); 11374 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp1, TEMP ktmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr); 11375 11376 format %{ "countPositives byte[] $ary1,$len -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11377 ins_encode %{ 11378 __ count_positives($ary1$$Register, $len$$Register, 11379 $result$$Register, $tmp3$$Register, 11380 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $ktmp1$$KRegister, $ktmp2$$KRegister); 11381 %} 11382 ins_pipe( pipe_slow ); 11383 %} 11384 11385 // fast char[] to byte[] compression 11386 instruct string_compress(rsi_RegP src, rdi_RegP dst, rdx_RegI len, legRegD tmp1, legRegD tmp2, legRegD tmp3, 11387 legRegD tmp4, rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11388 predicate(!VM_Version::supports_avx512vlbw() || !VM_Version::supports_bmi2()); 11389 match(Set result (StrCompressedCopy src (Binary dst len))); 11390 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, 11391 USE_KILL len, KILL tmp5, KILL cr); 11392 11393 format %{ "String Compress $src,$dst -> $result // KILL RAX, RCX, RDX" %} 11394 ins_encode %{ 11395 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 11396 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11397 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, 11398 knoreg, knoreg); 11399 %} 11400 ins_pipe( pipe_slow ); 11401 %} 11402 11403 instruct string_compress_evex(rsi_RegP src, rdi_RegP dst, rdx_RegI len, legRegD tmp1, legRegD tmp2, legRegD tmp3, 11404 legRegD tmp4, kReg ktmp1, kReg ktmp2, rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11405 predicate(VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2()); 11406 match(Set result (StrCompressedCopy src (Binary dst len))); 11407 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP ktmp1, TEMP ktmp2, USE_KILL src, USE_KILL dst, 11408 USE_KILL len, KILL tmp5, KILL cr); 11409 11410 format %{ "String Compress $src,$dst -> $result // KILL RAX, RCX, RDX" %} 11411 ins_encode %{ 11412 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 11413 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11414 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, 11415 $ktmp1$$KRegister, $ktmp2$$KRegister); 11416 %} 11417 ins_pipe( pipe_slow ); 11418 %} 11419 // fast byte[] to char[] inflation 11420 instruct string_inflate(Universe dummy, rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11421 legRegD tmp1, rcx_RegI tmp2, rFlagsReg cr) %{ 11422 predicate(!VM_Version::supports_avx512vlbw() || !VM_Version::supports_bmi2()); 11423 match(Set dummy (StrInflatedCopy src (Binary dst len))); 11424 effect(TEMP tmp1, TEMP tmp2, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 11425 11426 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 11427 ins_encode %{ 11428 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 11429 $tmp1$$XMMRegister, $tmp2$$Register, knoreg); 11430 %} 11431 ins_pipe( pipe_slow ); 11432 %} 11433 11434 instruct string_inflate_evex(Universe dummy, rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11435 legRegD tmp1, kReg ktmp, rcx_RegI tmp2, rFlagsReg cr) %{ 11436 predicate(VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2()); 11437 match(Set dummy (StrInflatedCopy src (Binary dst len))); 11438 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 11439 11440 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 11441 ins_encode %{ 11442 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 11443 $tmp1$$XMMRegister, $tmp2$$Register, $ktmp$$KRegister); 11444 %} 11445 ins_pipe( pipe_slow ); 11446 %} 11447 11448 // encode char[] to byte[] in ISO_8859_1 11449 instruct encode_iso_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11450 legRegD tmp1, legRegD tmp2, legRegD tmp3, legRegD tmp4, 11451 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11452 predicate(!((EncodeISOArrayNode*)n)->is_ascii()); 11453 match(Set result (EncodeISOArray src (Binary dst len))); 11454 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 11455 11456 format %{ "Encode iso array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %} 11457 ins_encode %{ 11458 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 11459 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11460 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, false); 11461 %} 11462 ins_pipe( pipe_slow ); 11463 %} 11464 11465 // encode char[] to byte[] in ASCII 11466 instruct encode_ascii_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11467 legRegD tmp1, legRegD tmp2, legRegD tmp3, legRegD tmp4, 11468 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11469 predicate(((EncodeISOArrayNode*)n)->is_ascii()); 11470 match(Set result (EncodeISOArray src (Binary dst len))); 11471 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 11472 11473 format %{ "Encode ascii array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %} 11474 ins_encode %{ 11475 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 11476 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11477 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, true); 11478 %} 11479 ins_pipe( pipe_slow ); 11480 %} 11481 11482 //----------Overflow Math Instructions----------------------------------------- 11483 11484 instruct overflowAddI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 11485 %{ 11486 match(Set cr (OverflowAddI op1 op2)); 11487 effect(DEF cr, USE_KILL op1, USE op2); 11488 11489 format %{ "addl $op1, $op2\t# overflow check int" %} 11490 11491 ins_encode %{ 11492 __ addl($op1$$Register, $op2$$Register); 11493 %} 11494 ins_pipe(ialu_reg_reg); 11495 %} 11496 11497 instruct overflowAddI_rReg_imm(rFlagsReg cr, rax_RegI op1, immI op2) 11498 %{ 11499 match(Set cr (OverflowAddI op1 op2)); 11500 effect(DEF cr, USE_KILL op1, USE op2); 11501 11502 format %{ "addl $op1, $op2\t# overflow check int" %} 11503 11504 ins_encode %{ 11505 __ addl($op1$$Register, $op2$$constant); 11506 %} 11507 ins_pipe(ialu_reg_reg); 11508 %} 11509 11510 instruct overflowAddL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 11511 %{ 11512 match(Set cr (OverflowAddL op1 op2)); 11513 effect(DEF cr, USE_KILL op1, USE op2); 11514 11515 format %{ "addq $op1, $op2\t# overflow check long" %} 11516 ins_encode %{ 11517 __ addq($op1$$Register, $op2$$Register); 11518 %} 11519 ins_pipe(ialu_reg_reg); 11520 %} 11521 11522 instruct overflowAddL_rReg_imm(rFlagsReg cr, rax_RegL op1, immL32 op2) 11523 %{ 11524 match(Set cr (OverflowAddL op1 op2)); 11525 effect(DEF cr, USE_KILL op1, USE op2); 11526 11527 format %{ "addq $op1, $op2\t# overflow check long" %} 11528 ins_encode %{ 11529 __ addq($op1$$Register, $op2$$constant); 11530 %} 11531 ins_pipe(ialu_reg_reg); 11532 %} 11533 11534 instruct overflowSubI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 11535 %{ 11536 match(Set cr (OverflowSubI op1 op2)); 11537 11538 format %{ "cmpl $op1, $op2\t# overflow check int" %} 11539 ins_encode %{ 11540 __ cmpl($op1$$Register, $op2$$Register); 11541 %} 11542 ins_pipe(ialu_reg_reg); 11543 %} 11544 11545 instruct overflowSubI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 11546 %{ 11547 match(Set cr (OverflowSubI op1 op2)); 11548 11549 format %{ "cmpl $op1, $op2\t# overflow check int" %} 11550 ins_encode %{ 11551 __ cmpl($op1$$Register, $op2$$constant); 11552 %} 11553 ins_pipe(ialu_reg_reg); 11554 %} 11555 11556 instruct overflowSubL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 11557 %{ 11558 match(Set cr (OverflowSubL op1 op2)); 11559 11560 format %{ "cmpq $op1, $op2\t# overflow check long" %} 11561 ins_encode %{ 11562 __ cmpq($op1$$Register, $op2$$Register); 11563 %} 11564 ins_pipe(ialu_reg_reg); 11565 %} 11566 11567 instruct overflowSubL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 11568 %{ 11569 match(Set cr (OverflowSubL op1 op2)); 11570 11571 format %{ "cmpq $op1, $op2\t# overflow check long" %} 11572 ins_encode %{ 11573 __ cmpq($op1$$Register, $op2$$constant); 11574 %} 11575 ins_pipe(ialu_reg_reg); 11576 %} 11577 11578 instruct overflowNegI_rReg(rFlagsReg cr, immI_0 zero, rax_RegI op2) 11579 %{ 11580 match(Set cr (OverflowSubI zero op2)); 11581 effect(DEF cr, USE_KILL op2); 11582 11583 format %{ "negl $op2\t# overflow check int" %} 11584 ins_encode %{ 11585 __ negl($op2$$Register); 11586 %} 11587 ins_pipe(ialu_reg_reg); 11588 %} 11589 11590 instruct overflowNegL_rReg(rFlagsReg cr, immL0 zero, rax_RegL op2) 11591 %{ 11592 match(Set cr (OverflowSubL zero op2)); 11593 effect(DEF cr, USE_KILL op2); 11594 11595 format %{ "negq $op2\t# overflow check long" %} 11596 ins_encode %{ 11597 __ negq($op2$$Register); 11598 %} 11599 ins_pipe(ialu_reg_reg); 11600 %} 11601 11602 instruct overflowMulI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 11603 %{ 11604 match(Set cr (OverflowMulI op1 op2)); 11605 effect(DEF cr, USE_KILL op1, USE op2); 11606 11607 format %{ "imull $op1, $op2\t# overflow check int" %} 11608 ins_encode %{ 11609 __ imull($op1$$Register, $op2$$Register); 11610 %} 11611 ins_pipe(ialu_reg_reg_alu0); 11612 %} 11613 11614 instruct overflowMulI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2, rRegI tmp) 11615 %{ 11616 match(Set cr (OverflowMulI op1 op2)); 11617 effect(DEF cr, TEMP tmp, USE op1, USE op2); 11618 11619 format %{ "imull $tmp, $op1, $op2\t# overflow check int" %} 11620 ins_encode %{ 11621 __ imull($tmp$$Register, $op1$$Register, $op2$$constant); 11622 %} 11623 ins_pipe(ialu_reg_reg_alu0); 11624 %} 11625 11626 instruct overflowMulL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 11627 %{ 11628 match(Set cr (OverflowMulL op1 op2)); 11629 effect(DEF cr, USE_KILL op1, USE op2); 11630 11631 format %{ "imulq $op1, $op2\t# overflow check long" %} 11632 ins_encode %{ 11633 __ imulq($op1$$Register, $op2$$Register); 11634 %} 11635 ins_pipe(ialu_reg_reg_alu0); 11636 %} 11637 11638 instruct overflowMulL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2, rRegL tmp) 11639 %{ 11640 match(Set cr (OverflowMulL op1 op2)); 11641 effect(DEF cr, TEMP tmp, USE op1, USE op2); 11642 11643 format %{ "imulq $tmp, $op1, $op2\t# overflow check long" %} 11644 ins_encode %{ 11645 __ imulq($tmp$$Register, $op1$$Register, $op2$$constant); 11646 %} 11647 ins_pipe(ialu_reg_reg_alu0); 11648 %} 11649 11650 11651 //----------Control Flow Instructions------------------------------------------ 11652 // Signed compare Instructions 11653 11654 // XXX more variants!! 11655 instruct compI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 11656 %{ 11657 match(Set cr (CmpI op1 op2)); 11658 effect(DEF cr, USE op1, USE op2); 11659 11660 format %{ "cmpl $op1, $op2" %} 11661 ins_encode %{ 11662 __ cmpl($op1$$Register, $op2$$Register); 11663 %} 11664 ins_pipe(ialu_cr_reg_reg); 11665 %} 11666 11667 instruct compI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 11668 %{ 11669 match(Set cr (CmpI op1 op2)); 11670 11671 format %{ "cmpl $op1, $op2" %} 11672 ins_encode %{ 11673 __ cmpl($op1$$Register, $op2$$constant); 11674 %} 11675 ins_pipe(ialu_cr_reg_imm); 11676 %} 11677 11678 instruct compI_rReg_mem(rFlagsReg cr, rRegI op1, memory op2) 11679 %{ 11680 match(Set cr (CmpI op1 (LoadI op2))); 11681 11682 ins_cost(500); // XXX 11683 format %{ "cmpl $op1, $op2" %} 11684 ins_encode %{ 11685 __ cmpl($op1$$Register, $op2$$Address); 11686 %} 11687 ins_pipe(ialu_cr_reg_mem); 11688 %} 11689 11690 instruct testI_reg(rFlagsReg cr, rRegI src, immI_0 zero) 11691 %{ 11692 match(Set cr (CmpI src zero)); 11693 11694 format %{ "testl $src, $src" %} 11695 ins_encode %{ 11696 __ testl($src$$Register, $src$$Register); 11697 %} 11698 ins_pipe(ialu_cr_reg_imm); 11699 %} 11700 11701 instruct testI_reg_imm(rFlagsReg cr, rRegI src, immI con, immI_0 zero) 11702 %{ 11703 match(Set cr (CmpI (AndI src con) zero)); 11704 11705 format %{ "testl $src, $con" %} 11706 ins_encode %{ 11707 __ testl($src$$Register, $con$$constant); 11708 %} 11709 ins_pipe(ialu_cr_reg_imm); 11710 %} 11711 11712 instruct testI_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2, immI_0 zero) 11713 %{ 11714 match(Set cr (CmpI (AndI src1 src2) zero)); 11715 11716 format %{ "testl $src1, $src2" %} 11717 ins_encode %{ 11718 __ testl($src1$$Register, $src2$$Register); 11719 %} 11720 ins_pipe(ialu_cr_reg_imm); 11721 %} 11722 11723 instruct testI_reg_mem(rFlagsReg cr, rRegI src, memory mem, immI_0 zero) 11724 %{ 11725 match(Set cr (CmpI (AndI src (LoadI mem)) zero)); 11726 11727 format %{ "testl $src, $mem" %} 11728 ins_encode %{ 11729 __ testl($src$$Register, $mem$$Address); 11730 %} 11731 ins_pipe(ialu_cr_reg_mem); 11732 %} 11733 11734 // Unsigned compare Instructions; really, same as signed except they 11735 // produce an rFlagsRegU instead of rFlagsReg. 11736 instruct compU_rReg(rFlagsRegU cr, rRegI op1, rRegI op2) 11737 %{ 11738 match(Set cr (CmpU op1 op2)); 11739 11740 format %{ "cmpl $op1, $op2\t# unsigned" %} 11741 ins_encode %{ 11742 __ cmpl($op1$$Register, $op2$$Register); 11743 %} 11744 ins_pipe(ialu_cr_reg_reg); 11745 %} 11746 11747 instruct compU_rReg_imm(rFlagsRegU cr, rRegI op1, immI op2) 11748 %{ 11749 match(Set cr (CmpU op1 op2)); 11750 11751 format %{ "cmpl $op1, $op2\t# unsigned" %} 11752 ins_encode %{ 11753 __ cmpl($op1$$Register, $op2$$constant); 11754 %} 11755 ins_pipe(ialu_cr_reg_imm); 11756 %} 11757 11758 instruct compU_rReg_mem(rFlagsRegU cr, rRegI op1, memory op2) 11759 %{ 11760 match(Set cr (CmpU op1 (LoadI op2))); 11761 11762 ins_cost(500); // XXX 11763 format %{ "cmpl $op1, $op2\t# unsigned" %} 11764 ins_encode %{ 11765 __ cmpl($op1$$Register, $op2$$Address); 11766 %} 11767 ins_pipe(ialu_cr_reg_mem); 11768 %} 11769 11770 instruct testU_reg(rFlagsRegU cr, rRegI src, immI_0 zero) 11771 %{ 11772 match(Set cr (CmpU src zero)); 11773 11774 format %{ "testl $src, $src\t# unsigned" %} 11775 ins_encode %{ 11776 __ testl($src$$Register, $src$$Register); 11777 %} 11778 ins_pipe(ialu_cr_reg_imm); 11779 %} 11780 11781 instruct compP_rReg(rFlagsRegU cr, rRegP op1, rRegP op2) 11782 %{ 11783 match(Set cr (CmpP op1 op2)); 11784 11785 format %{ "cmpq $op1, $op2\t# ptr" %} 11786 ins_encode %{ 11787 __ cmpq($op1$$Register, $op2$$Register); 11788 %} 11789 ins_pipe(ialu_cr_reg_reg); 11790 %} 11791 11792 instruct compP_rReg_mem(rFlagsRegU cr, rRegP op1, memory op2) 11793 %{ 11794 match(Set cr (CmpP op1 (LoadP op2))); 11795 predicate(n->in(2)->as_Load()->barrier_data() == 0); 11796 11797 ins_cost(500); // XXX 11798 format %{ "cmpq $op1, $op2\t# ptr" %} 11799 ins_encode %{ 11800 __ cmpq($op1$$Register, $op2$$Address); 11801 %} 11802 ins_pipe(ialu_cr_reg_mem); 11803 %} 11804 11805 // XXX this is generalized by compP_rReg_mem??? 11806 // Compare raw pointer (used in out-of-heap check). 11807 // Only works because non-oop pointers must be raw pointers 11808 // and raw pointers have no anti-dependencies. 11809 instruct compP_mem_rReg(rFlagsRegU cr, rRegP op1, memory op2) 11810 %{ 11811 predicate(n->in(2)->in(2)->bottom_type()->reloc() == relocInfo::none && 11812 n->in(2)->as_Load()->barrier_data() == 0); 11813 match(Set cr (CmpP op1 (LoadP op2))); 11814 11815 format %{ "cmpq $op1, $op2\t# raw ptr" %} 11816 ins_encode %{ 11817 __ cmpq($op1$$Register, $op2$$Address); 11818 %} 11819 ins_pipe(ialu_cr_reg_mem); 11820 %} 11821 11822 // This will generate a signed flags result. This should be OK since 11823 // any compare to a zero should be eq/neq. 11824 instruct testP_reg(rFlagsReg cr, rRegP src, immP0 zero) 11825 %{ 11826 match(Set cr (CmpP src zero)); 11827 11828 format %{ "testq $src, $src\t# ptr" %} 11829 ins_encode %{ 11830 __ testq($src$$Register, $src$$Register); 11831 %} 11832 ins_pipe(ialu_cr_reg_imm); 11833 %} 11834 11835 // This will generate a signed flags result. This should be OK since 11836 // any compare to a zero should be eq/neq. 11837 instruct testP_mem(rFlagsReg cr, memory op, immP0 zero) 11838 %{ 11839 predicate((!UseCompressedOops || (CompressedOops::base() != nullptr)) && 11840 n->in(1)->as_Load()->barrier_data() == 0); 11841 match(Set cr (CmpP (LoadP op) zero)); 11842 11843 ins_cost(500); // XXX 11844 format %{ "testq $op, 0xffffffffffffffff\t# ptr" %} 11845 ins_encode %{ 11846 __ testq($op$$Address, 0xFFFFFFFF); 11847 %} 11848 ins_pipe(ialu_cr_reg_imm); 11849 %} 11850 11851 instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero) 11852 %{ 11853 predicate(UseCompressedOops && (CompressedOops::base() == nullptr) && 11854 n->in(1)->as_Load()->barrier_data() == 0); 11855 match(Set cr (CmpP (LoadP mem) zero)); 11856 11857 format %{ "cmpq R12, $mem\t# ptr (R12_heapbase==0)" %} 11858 ins_encode %{ 11859 __ cmpq(r12, $mem$$Address); 11860 %} 11861 ins_pipe(ialu_cr_reg_mem); 11862 %} 11863 11864 instruct compN_rReg(rFlagsRegU cr, rRegN op1, rRegN op2) 11865 %{ 11866 match(Set cr (CmpN op1 op2)); 11867 11868 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 11869 ins_encode %{ __ cmpl($op1$$Register, $op2$$Register); %} 11870 ins_pipe(ialu_cr_reg_reg); 11871 %} 11872 11873 instruct compN_rReg_mem(rFlagsRegU cr, rRegN src, memory mem) 11874 %{ 11875 predicate(n->in(2)->as_Load()->barrier_data() == 0); 11876 match(Set cr (CmpN src (LoadN mem))); 11877 11878 format %{ "cmpl $src, $mem\t# compressed ptr" %} 11879 ins_encode %{ 11880 __ cmpl($src$$Register, $mem$$Address); 11881 %} 11882 ins_pipe(ialu_cr_reg_mem); 11883 %} 11884 11885 instruct compN_rReg_imm(rFlagsRegU cr, rRegN op1, immN op2) %{ 11886 match(Set cr (CmpN op1 op2)); 11887 11888 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 11889 ins_encode %{ 11890 __ cmp_narrow_oop($op1$$Register, (jobject)$op2$$constant); 11891 %} 11892 ins_pipe(ialu_cr_reg_imm); 11893 %} 11894 11895 instruct compN_mem_imm(rFlagsRegU cr, memory mem, immN src) 11896 %{ 11897 predicate(n->in(2)->as_Load()->barrier_data() == 0); 11898 match(Set cr (CmpN src (LoadN mem))); 11899 11900 format %{ "cmpl $mem, $src\t# compressed ptr" %} 11901 ins_encode %{ 11902 __ cmp_narrow_oop($mem$$Address, (jobject)$src$$constant); 11903 %} 11904 ins_pipe(ialu_cr_reg_mem); 11905 %} 11906 11907 instruct compN_rReg_imm_klass(rFlagsRegU cr, rRegN op1, immNKlass op2) %{ 11908 match(Set cr (CmpN op1 op2)); 11909 11910 format %{ "cmpl $op1, $op2\t# compressed klass ptr" %} 11911 ins_encode %{ 11912 __ cmp_narrow_klass($op1$$Register, (Klass*)$op2$$constant); 11913 %} 11914 ins_pipe(ialu_cr_reg_imm); 11915 %} 11916 11917 instruct compN_mem_imm_klass(rFlagsRegU cr, memory mem, immNKlass src) 11918 %{ 11919 match(Set cr (CmpN src (LoadNKlass mem))); 11920 11921 format %{ "cmpl $mem, $src\t# compressed klass ptr" %} 11922 ins_encode %{ 11923 __ cmp_narrow_klass($mem$$Address, (Klass*)$src$$constant); 11924 %} 11925 ins_pipe(ialu_cr_reg_mem); 11926 %} 11927 11928 instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{ 11929 match(Set cr (CmpN src zero)); 11930 11931 format %{ "testl $src, $src\t# compressed ptr" %} 11932 ins_encode %{ __ testl($src$$Register, $src$$Register); %} 11933 ins_pipe(ialu_cr_reg_imm); 11934 %} 11935 11936 instruct testN_mem(rFlagsReg cr, memory mem, immN0 zero) 11937 %{ 11938 predicate(CompressedOops::base() != nullptr && 11939 n->in(1)->as_Load()->barrier_data() == 0); 11940 match(Set cr (CmpN (LoadN mem) zero)); 11941 11942 ins_cost(500); // XXX 11943 format %{ "testl $mem, 0xffffffff\t# compressed ptr" %} 11944 ins_encode %{ 11945 __ cmpl($mem$$Address, (int)0xFFFFFFFF); 11946 %} 11947 ins_pipe(ialu_cr_reg_mem); 11948 %} 11949 11950 instruct testN_mem_reg0(rFlagsReg cr, memory mem, immN0 zero) 11951 %{ 11952 predicate(CompressedOops::base() == nullptr && 11953 n->in(1)->as_Load()->barrier_data() == 0); 11954 match(Set cr (CmpN (LoadN mem) zero)); 11955 11956 format %{ "cmpl R12, $mem\t# compressed ptr (R12_heapbase==0)" %} 11957 ins_encode %{ 11958 __ cmpl(r12, $mem$$Address); 11959 %} 11960 ins_pipe(ialu_cr_reg_mem); 11961 %} 11962 11963 // Yanked all unsigned pointer compare operations. 11964 // Pointer compares are done with CmpP which is already unsigned. 11965 11966 instruct compL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 11967 %{ 11968 match(Set cr (CmpL op1 op2)); 11969 11970 format %{ "cmpq $op1, $op2" %} 11971 ins_encode %{ 11972 __ cmpq($op1$$Register, $op2$$Register); 11973 %} 11974 ins_pipe(ialu_cr_reg_reg); 11975 %} 11976 11977 instruct compL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 11978 %{ 11979 match(Set cr (CmpL op1 op2)); 11980 11981 format %{ "cmpq $op1, $op2" %} 11982 ins_encode %{ 11983 __ cmpq($op1$$Register, $op2$$constant); 11984 %} 11985 ins_pipe(ialu_cr_reg_imm); 11986 %} 11987 11988 instruct compL_rReg_mem(rFlagsReg cr, rRegL op1, memory op2) 11989 %{ 11990 match(Set cr (CmpL op1 (LoadL op2))); 11991 11992 format %{ "cmpq $op1, $op2" %} 11993 ins_encode %{ 11994 __ cmpq($op1$$Register, $op2$$Address); 11995 %} 11996 ins_pipe(ialu_cr_reg_mem); 11997 %} 11998 11999 instruct testL_reg(rFlagsReg cr, rRegL src, immL0 zero) 12000 %{ 12001 match(Set cr (CmpL src zero)); 12002 12003 format %{ "testq $src, $src" %} 12004 ins_encode %{ 12005 __ testq($src$$Register, $src$$Register); 12006 %} 12007 ins_pipe(ialu_cr_reg_imm); 12008 %} 12009 12010 instruct testL_reg_imm(rFlagsReg cr, rRegL src, immL32 con, immL0 zero) 12011 %{ 12012 match(Set cr (CmpL (AndL src con) zero)); 12013 12014 format %{ "testq $src, $con\t# long" %} 12015 ins_encode %{ 12016 __ testq($src$$Register, $con$$constant); 12017 %} 12018 ins_pipe(ialu_cr_reg_imm); 12019 %} 12020 12021 instruct testL_reg_reg(rFlagsReg cr, rRegL src1, rRegL src2, immL0 zero) 12022 %{ 12023 match(Set cr (CmpL (AndL src1 src2) zero)); 12024 12025 format %{ "testq $src1, $src2\t# long" %} 12026 ins_encode %{ 12027 __ testq($src1$$Register, $src2$$Register); 12028 %} 12029 ins_pipe(ialu_cr_reg_imm); 12030 %} 12031 12032 instruct testL_reg_mem(rFlagsReg cr, rRegL src, memory mem, immL0 zero) 12033 %{ 12034 match(Set cr (CmpL (AndL src (LoadL mem)) zero)); 12035 12036 format %{ "testq $src, $mem" %} 12037 ins_encode %{ 12038 __ testq($src$$Register, $mem$$Address); 12039 %} 12040 ins_pipe(ialu_cr_reg_mem); 12041 %} 12042 12043 instruct testL_reg_mem2(rFlagsReg cr, rRegP src, memory mem, immL0 zero) 12044 %{ 12045 match(Set cr (CmpL (AndL (CastP2X src) (LoadL mem)) zero)); 12046 12047 format %{ "testq $src, $mem" %} 12048 ins_encode %{ 12049 __ testq($src$$Register, $mem$$Address); 12050 %} 12051 ins_pipe(ialu_cr_reg_mem); 12052 %} 12053 12054 // Manifest a CmpU result in an integer register. Very painful. 12055 // This is the test to avoid. 12056 instruct cmpU3_reg_reg(rRegI dst, rRegI src1, rRegI src2, rFlagsReg flags) 12057 %{ 12058 match(Set dst (CmpU3 src1 src2)); 12059 effect(KILL flags); 12060 12061 ins_cost(275); // XXX 12062 format %{ "cmpl $src1, $src2\t# CmpL3\n\t" 12063 "movl $dst, -1\n\t" 12064 "jb,u done\n\t" 12065 "setcc $dst \t# emits setne + movzbl or setzune for APX" 12066 "done:" %} 12067 ins_encode %{ 12068 Label done; 12069 __ cmpl($src1$$Register, $src2$$Register); 12070 __ movl($dst$$Register, -1); 12071 __ jccb(Assembler::below, done); 12072 __ setcc(Assembler::notZero, $dst$$Register); 12073 __ bind(done); 12074 %} 12075 ins_pipe(pipe_slow); 12076 %} 12077 12078 // Manifest a CmpL result in an integer register. Very painful. 12079 // This is the test to avoid. 12080 instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 12081 %{ 12082 match(Set dst (CmpL3 src1 src2)); 12083 effect(KILL flags); 12084 12085 ins_cost(275); // XXX 12086 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 12087 "movl $dst, -1\n\t" 12088 "jl,s done\n\t" 12089 "setcc $dst \t# emits setne + movzbl or setzune for APX" 12090 "done:" %} 12091 ins_encode %{ 12092 Label done; 12093 __ cmpq($src1$$Register, $src2$$Register); 12094 __ movl($dst$$Register, -1); 12095 __ jccb(Assembler::less, done); 12096 __ setcc(Assembler::notZero, $dst$$Register); 12097 __ bind(done); 12098 %} 12099 ins_pipe(pipe_slow); 12100 %} 12101 12102 // Manifest a CmpUL result in an integer register. Very painful. 12103 // This is the test to avoid. 12104 instruct cmpUL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 12105 %{ 12106 match(Set dst (CmpUL3 src1 src2)); 12107 effect(KILL flags); 12108 12109 ins_cost(275); // XXX 12110 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 12111 "movl $dst, -1\n\t" 12112 "jb,u done\n\t" 12113 "setcc $dst \t# emits setne + movzbl or setzune for APX" 12114 "done:" %} 12115 ins_encode %{ 12116 Label done; 12117 __ cmpq($src1$$Register, $src2$$Register); 12118 __ movl($dst$$Register, -1); 12119 __ jccb(Assembler::below, done); 12120 __ setcc(Assembler::notZero, $dst$$Register); 12121 __ bind(done); 12122 %} 12123 ins_pipe(pipe_slow); 12124 %} 12125 12126 // Unsigned long compare Instructions; really, same as signed long except they 12127 // produce an rFlagsRegU instead of rFlagsReg. 12128 instruct compUL_rReg(rFlagsRegU cr, rRegL op1, rRegL op2) 12129 %{ 12130 match(Set cr (CmpUL op1 op2)); 12131 12132 format %{ "cmpq $op1, $op2\t# unsigned" %} 12133 ins_encode %{ 12134 __ cmpq($op1$$Register, $op2$$Register); 12135 %} 12136 ins_pipe(ialu_cr_reg_reg); 12137 %} 12138 12139 instruct compUL_rReg_imm(rFlagsRegU cr, rRegL op1, immL32 op2) 12140 %{ 12141 match(Set cr (CmpUL op1 op2)); 12142 12143 format %{ "cmpq $op1, $op2\t# unsigned" %} 12144 ins_encode %{ 12145 __ cmpq($op1$$Register, $op2$$constant); 12146 %} 12147 ins_pipe(ialu_cr_reg_imm); 12148 %} 12149 12150 instruct compUL_rReg_mem(rFlagsRegU cr, rRegL op1, memory op2) 12151 %{ 12152 match(Set cr (CmpUL op1 (LoadL op2))); 12153 12154 format %{ "cmpq $op1, $op2\t# unsigned" %} 12155 ins_encode %{ 12156 __ cmpq($op1$$Register, $op2$$Address); 12157 %} 12158 ins_pipe(ialu_cr_reg_mem); 12159 %} 12160 12161 instruct testUL_reg(rFlagsRegU cr, rRegL src, immL0 zero) 12162 %{ 12163 match(Set cr (CmpUL src zero)); 12164 12165 format %{ "testq $src, $src\t# unsigned" %} 12166 ins_encode %{ 12167 __ testq($src$$Register, $src$$Register); 12168 %} 12169 ins_pipe(ialu_cr_reg_imm); 12170 %} 12171 12172 instruct compB_mem_imm(rFlagsReg cr, memory mem, immI8 imm) 12173 %{ 12174 match(Set cr (CmpI (LoadB mem) imm)); 12175 12176 ins_cost(125); 12177 format %{ "cmpb $mem, $imm" %} 12178 ins_encode %{ __ cmpb($mem$$Address, $imm$$constant); %} 12179 ins_pipe(ialu_cr_reg_mem); 12180 %} 12181 12182 instruct testUB_mem_imm(rFlagsReg cr, memory mem, immU7 imm, immI_0 zero) 12183 %{ 12184 match(Set cr (CmpI (AndI (LoadUB mem) imm) zero)); 12185 12186 ins_cost(125); 12187 format %{ "testb $mem, $imm\t# ubyte" %} 12188 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %} 12189 ins_pipe(ialu_cr_reg_mem); 12190 %} 12191 12192 instruct testB_mem_imm(rFlagsReg cr, memory mem, immI8 imm, immI_0 zero) 12193 %{ 12194 match(Set cr (CmpI (AndI (LoadB mem) imm) zero)); 12195 12196 ins_cost(125); 12197 format %{ "testb $mem, $imm\t# byte" %} 12198 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %} 12199 ins_pipe(ialu_cr_reg_mem); 12200 %} 12201 12202 //----------Max and Min-------------------------------------------------------- 12203 // Min Instructions 12204 12205 instruct cmovI_reg_g(rRegI dst, rRegI src, rFlagsReg cr) 12206 %{ 12207 effect(USE_DEF dst, USE src, USE cr); 12208 12209 format %{ "cmovlgt $dst, $src\t# min" %} 12210 ins_encode %{ 12211 __ cmovl(Assembler::greater, $dst$$Register, $src$$Register); 12212 %} 12213 ins_pipe(pipe_cmov_reg); 12214 %} 12215 12216 12217 instruct minI_rReg(rRegI dst, rRegI src) 12218 %{ 12219 match(Set dst (MinI dst src)); 12220 12221 ins_cost(200); 12222 expand %{ 12223 rFlagsReg cr; 12224 compI_rReg(cr, dst, src); 12225 cmovI_reg_g(dst, src, cr); 12226 %} 12227 %} 12228 12229 instruct cmovI_reg_l(rRegI dst, rRegI src, rFlagsReg cr) 12230 %{ 12231 effect(USE_DEF dst, USE src, USE cr); 12232 12233 format %{ "cmovllt $dst, $src\t# max" %} 12234 ins_encode %{ 12235 __ cmovl(Assembler::less, $dst$$Register, $src$$Register); 12236 %} 12237 ins_pipe(pipe_cmov_reg); 12238 %} 12239 12240 12241 instruct maxI_rReg(rRegI dst, rRegI src) 12242 %{ 12243 match(Set dst (MaxI dst src)); 12244 12245 ins_cost(200); 12246 expand %{ 12247 rFlagsReg cr; 12248 compI_rReg(cr, dst, src); 12249 cmovI_reg_l(dst, src, cr); 12250 %} 12251 %} 12252 12253 // ============================================================================ 12254 // Branch Instructions 12255 12256 // Jump Direct - Label defines a relative address from JMP+1 12257 instruct jmpDir(label labl) 12258 %{ 12259 match(Goto); 12260 effect(USE labl); 12261 12262 ins_cost(300); 12263 format %{ "jmp $labl" %} 12264 size(5); 12265 ins_encode %{ 12266 Label* L = $labl$$label; 12267 __ jmp(*L, false); // Always long jump 12268 %} 12269 ins_pipe(pipe_jmp); 12270 %} 12271 12272 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12273 instruct jmpCon(cmpOp cop, rFlagsReg cr, label labl) 12274 %{ 12275 match(If cop cr); 12276 effect(USE labl); 12277 12278 ins_cost(300); 12279 format %{ "j$cop $labl" %} 12280 size(6); 12281 ins_encode %{ 12282 Label* L = $labl$$label; 12283 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12284 %} 12285 ins_pipe(pipe_jcc); 12286 %} 12287 12288 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12289 instruct jmpLoopEnd(cmpOp cop, rFlagsReg cr, label labl) 12290 %{ 12291 match(CountedLoopEnd cop cr); 12292 effect(USE labl); 12293 12294 ins_cost(300); 12295 format %{ "j$cop $labl\t# loop end" %} 12296 size(6); 12297 ins_encode %{ 12298 Label* L = $labl$$label; 12299 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12300 %} 12301 ins_pipe(pipe_jcc); 12302 %} 12303 12304 // Jump Direct Conditional - using unsigned comparison 12305 instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12306 match(If cop cmp); 12307 effect(USE labl); 12308 12309 ins_cost(300); 12310 format %{ "j$cop,u $labl" %} 12311 size(6); 12312 ins_encode %{ 12313 Label* L = $labl$$label; 12314 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12315 %} 12316 ins_pipe(pipe_jcc); 12317 %} 12318 12319 instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12320 match(If cop cmp); 12321 effect(USE labl); 12322 12323 ins_cost(200); 12324 format %{ "j$cop,u $labl" %} 12325 size(6); 12326 ins_encode %{ 12327 Label* L = $labl$$label; 12328 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12329 %} 12330 ins_pipe(pipe_jcc); 12331 %} 12332 12333 instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 12334 match(If cop cmp); 12335 effect(USE labl); 12336 12337 ins_cost(200); 12338 format %{ $$template 12339 if ($cop$$cmpcode == Assembler::notEqual) { 12340 $$emit$$"jp,u $labl\n\t" 12341 $$emit$$"j$cop,u $labl" 12342 } else { 12343 $$emit$$"jp,u done\n\t" 12344 $$emit$$"j$cop,u $labl\n\t" 12345 $$emit$$"done:" 12346 } 12347 %} 12348 ins_encode %{ 12349 Label* l = $labl$$label; 12350 if ($cop$$cmpcode == Assembler::notEqual) { 12351 __ jcc(Assembler::parity, *l, false); 12352 __ jcc(Assembler::notEqual, *l, false); 12353 } else if ($cop$$cmpcode == Assembler::equal) { 12354 Label done; 12355 __ jccb(Assembler::parity, done); 12356 __ jcc(Assembler::equal, *l, false); 12357 __ bind(done); 12358 } else { 12359 ShouldNotReachHere(); 12360 } 12361 %} 12362 ins_pipe(pipe_jcc); 12363 %} 12364 12365 // ============================================================================ 12366 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary 12367 // superklass array for an instance of the superklass. Set a hidden 12368 // internal cache on a hit (cache is checked with exposed code in 12369 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The 12370 // encoding ALSO sets flags. 12371 12372 instruct partialSubtypeCheck(rdi_RegP result, 12373 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 12374 rFlagsReg cr) 12375 %{ 12376 match(Set result (PartialSubtypeCheck sub super)); 12377 predicate(!UseSecondarySupersTable); 12378 effect(KILL rcx, KILL cr); 12379 12380 ins_cost(1100); // slightly larger than the next version 12381 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 12382 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 12383 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 12384 "repne scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t" 12385 "jne,s miss\t\t# Missed: rdi not-zero\n\t" 12386 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 12387 "xorq $result, $result\t\t Hit: rdi zero\n\t" 12388 "miss:\t" %} 12389 12390 ins_encode %{ 12391 Label miss; 12392 // NB: Callers may assume that, when $result is a valid register, 12393 // check_klass_subtype_slow_path_linear sets it to a nonzero 12394 // value. 12395 __ check_klass_subtype_slow_path_linear($sub$$Register, $super$$Register, 12396 $rcx$$Register, $result$$Register, 12397 nullptr, &miss, 12398 /*set_cond_codes:*/ true); 12399 __ xorptr($result$$Register, $result$$Register); 12400 __ bind(miss); 12401 %} 12402 12403 ins_pipe(pipe_slow); 12404 %} 12405 12406 // ============================================================================ 12407 // Two versions of hashtable-based partialSubtypeCheck, both used when 12408 // we need to search for a super class in the secondary supers array. 12409 // The first is used when we don't know _a priori_ the class being 12410 // searched for. The second, far more common, is used when we do know: 12411 // this is used for instanceof, checkcast, and any case where C2 can 12412 // determine it by constant propagation. 12413 12414 instruct partialSubtypeCheckVarSuper(rsi_RegP sub, rax_RegP super, rdi_RegP result, 12415 rdx_RegL temp1, rcx_RegL temp2, rbx_RegP temp3, r11_RegL temp4, 12416 rFlagsReg cr) 12417 %{ 12418 match(Set result (PartialSubtypeCheck sub super)); 12419 predicate(UseSecondarySupersTable); 12420 effect(KILL cr, TEMP temp1, TEMP temp2, TEMP temp3, TEMP temp4); 12421 12422 ins_cost(1000); 12423 format %{ "partialSubtypeCheck $result, $sub, $super" %} 12424 12425 ins_encode %{ 12426 __ lookup_secondary_supers_table_var($sub$$Register, $super$$Register, $temp1$$Register, $temp2$$Register, 12427 $temp3$$Register, $temp4$$Register, $result$$Register); 12428 %} 12429 12430 ins_pipe(pipe_slow); 12431 %} 12432 12433 instruct partialSubtypeCheckConstSuper(rsi_RegP sub, rax_RegP super_reg, immP super_con, rdi_RegP result, 12434 rdx_RegL temp1, rcx_RegL temp2, rbx_RegP temp3, r11_RegL temp4, 12435 rFlagsReg cr) 12436 %{ 12437 match(Set result (PartialSubtypeCheck sub (Binary super_reg super_con))); 12438 predicate(UseSecondarySupersTable); 12439 effect(KILL cr, TEMP temp1, TEMP temp2, TEMP temp3, TEMP temp4); 12440 12441 ins_cost(700); // smaller than the next version 12442 format %{ "partialSubtypeCheck $result, $sub, $super_reg, $super_con" %} 12443 12444 ins_encode %{ 12445 u1 super_klass_slot = ((Klass*)$super_con$$constant)->hash_slot(); 12446 if (InlineSecondarySupersTest) { 12447 __ lookup_secondary_supers_table_const($sub$$Register, $super_reg$$Register, $temp1$$Register, $temp2$$Register, 12448 $temp3$$Register, $temp4$$Register, $result$$Register, 12449 super_klass_slot); 12450 } else { 12451 __ call(RuntimeAddress(StubRoutines::lookup_secondary_supers_table_stub(super_klass_slot))); 12452 } 12453 %} 12454 12455 ins_pipe(pipe_slow); 12456 %} 12457 12458 // ============================================================================ 12459 // Branch Instructions -- short offset versions 12460 // 12461 // These instructions are used to replace jumps of a long offset (the default 12462 // match) with jumps of a shorter offset. These instructions are all tagged 12463 // with the ins_short_branch attribute, which causes the ADLC to suppress the 12464 // match rules in general matching. Instead, the ADLC generates a conversion 12465 // method in the MachNode which can be used to do in-place replacement of the 12466 // long variant with the shorter variant. The compiler will determine if a 12467 // branch can be taken by the is_short_branch_offset() predicate in the machine 12468 // specific code section of the file. 12469 12470 // Jump Direct - Label defines a relative address from JMP+1 12471 instruct jmpDir_short(label labl) %{ 12472 match(Goto); 12473 effect(USE labl); 12474 12475 ins_cost(300); 12476 format %{ "jmp,s $labl" %} 12477 size(2); 12478 ins_encode %{ 12479 Label* L = $labl$$label; 12480 __ jmpb(*L); 12481 %} 12482 ins_pipe(pipe_jmp); 12483 ins_short_branch(1); 12484 %} 12485 12486 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12487 instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{ 12488 match(If cop cr); 12489 effect(USE labl); 12490 12491 ins_cost(300); 12492 format %{ "j$cop,s $labl" %} 12493 size(2); 12494 ins_encode %{ 12495 Label* L = $labl$$label; 12496 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12497 %} 12498 ins_pipe(pipe_jcc); 12499 ins_short_branch(1); 12500 %} 12501 12502 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12503 instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{ 12504 match(CountedLoopEnd cop cr); 12505 effect(USE labl); 12506 12507 ins_cost(300); 12508 format %{ "j$cop,s $labl\t# loop end" %} 12509 size(2); 12510 ins_encode %{ 12511 Label* L = $labl$$label; 12512 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12513 %} 12514 ins_pipe(pipe_jcc); 12515 ins_short_branch(1); 12516 %} 12517 12518 // Jump Direct Conditional - using unsigned comparison 12519 instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12520 match(If cop cmp); 12521 effect(USE labl); 12522 12523 ins_cost(300); 12524 format %{ "j$cop,us $labl" %} 12525 size(2); 12526 ins_encode %{ 12527 Label* L = $labl$$label; 12528 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12529 %} 12530 ins_pipe(pipe_jcc); 12531 ins_short_branch(1); 12532 %} 12533 12534 instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12535 match(If cop cmp); 12536 effect(USE labl); 12537 12538 ins_cost(300); 12539 format %{ "j$cop,us $labl" %} 12540 size(2); 12541 ins_encode %{ 12542 Label* L = $labl$$label; 12543 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12544 %} 12545 ins_pipe(pipe_jcc); 12546 ins_short_branch(1); 12547 %} 12548 12549 instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 12550 match(If cop cmp); 12551 effect(USE labl); 12552 12553 ins_cost(300); 12554 format %{ $$template 12555 if ($cop$$cmpcode == Assembler::notEqual) { 12556 $$emit$$"jp,u,s $labl\n\t" 12557 $$emit$$"j$cop,u,s $labl" 12558 } else { 12559 $$emit$$"jp,u,s done\n\t" 12560 $$emit$$"j$cop,u,s $labl\n\t" 12561 $$emit$$"done:" 12562 } 12563 %} 12564 size(4); 12565 ins_encode %{ 12566 Label* l = $labl$$label; 12567 if ($cop$$cmpcode == Assembler::notEqual) { 12568 __ jccb(Assembler::parity, *l); 12569 __ jccb(Assembler::notEqual, *l); 12570 } else if ($cop$$cmpcode == Assembler::equal) { 12571 Label done; 12572 __ jccb(Assembler::parity, done); 12573 __ jccb(Assembler::equal, *l); 12574 __ bind(done); 12575 } else { 12576 ShouldNotReachHere(); 12577 } 12578 %} 12579 ins_pipe(pipe_jcc); 12580 ins_short_branch(1); 12581 %} 12582 12583 // ============================================================================ 12584 // inlined locking and unlocking 12585 12586 instruct cmpFastLock(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr) %{ 12587 predicate(LockingMode != LM_LIGHTWEIGHT); 12588 match(Set cr (FastLock object box)); 12589 effect(TEMP tmp, TEMP scr, USE_KILL box); 12590 ins_cost(300); 12591 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr" %} 12592 ins_encode %{ 12593 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, 12594 $scr$$Register, noreg, noreg, r15_thread, nullptr); 12595 %} 12596 ins_pipe(pipe_slow); 12597 %} 12598 12599 instruct cmpFastUnlock(rFlagsReg cr, rRegP object, rax_RegP box, rRegP tmp) %{ 12600 predicate(LockingMode != LM_LIGHTWEIGHT); 12601 match(Set cr (FastUnlock object box)); 12602 effect(TEMP tmp, USE_KILL box); 12603 ins_cost(300); 12604 format %{ "fastunlock $object,$box\t! kills $box,$tmp" %} 12605 ins_encode %{ 12606 __ fast_unlock($object$$Register, $box$$Register, $tmp$$Register); 12607 %} 12608 ins_pipe(pipe_slow); 12609 %} 12610 12611 instruct cmpFastLockLightweight(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI rax_reg, rRegP tmp) %{ 12612 predicate(LockingMode == LM_LIGHTWEIGHT); 12613 match(Set cr (FastLock object box)); 12614 effect(TEMP rax_reg, TEMP tmp, USE_KILL box); 12615 ins_cost(300); 12616 format %{ "fastlock $object,$box\t! kills $box,$rax_reg,$tmp" %} 12617 ins_encode %{ 12618 __ fast_lock_lightweight($object$$Register, $box$$Register, $rax_reg$$Register, $tmp$$Register, r15_thread); 12619 %} 12620 ins_pipe(pipe_slow); 12621 %} 12622 12623 instruct cmpFastUnlockLightweight(rFlagsReg cr, rRegP object, rax_RegP rax_reg, rRegP tmp) %{ 12624 predicate(LockingMode == LM_LIGHTWEIGHT); 12625 match(Set cr (FastUnlock object rax_reg)); 12626 effect(TEMP tmp, USE_KILL rax_reg); 12627 ins_cost(300); 12628 format %{ "fastunlock $object,$rax_reg\t! kills $rax_reg,$tmp" %} 12629 ins_encode %{ 12630 __ fast_unlock_lightweight($object$$Register, $rax_reg$$Register, $tmp$$Register, r15_thread); 12631 %} 12632 ins_pipe(pipe_slow); 12633 %} 12634 12635 12636 // ============================================================================ 12637 // Safepoint Instructions 12638 instruct safePoint_poll_tls(rFlagsReg cr, rRegP poll) 12639 %{ 12640 match(SafePoint poll); 12641 effect(KILL cr, USE poll); 12642 12643 format %{ "testl rax, [$poll]\t" 12644 "# Safepoint: poll for GC" %} 12645 ins_cost(125); 12646 ins_encode %{ 12647 __ relocate(relocInfo::poll_type); 12648 address pre_pc = __ pc(); 12649 __ testl(rax, Address($poll$$Register, 0)); 12650 assert(nativeInstruction_at(pre_pc)->is_safepoint_poll(), "must emit test %%eax [reg]"); 12651 %} 12652 ins_pipe(ialu_reg_mem); 12653 %} 12654 12655 instruct mask_all_evexL(kReg dst, rRegL src) %{ 12656 match(Set dst (MaskAll src)); 12657 format %{ "mask_all_evexL $dst, $src \t! mask all operation" %} 12658 ins_encode %{ 12659 int mask_len = Matcher::vector_length(this); 12660 __ vector_maskall_operation($dst$$KRegister, $src$$Register, mask_len); 12661 %} 12662 ins_pipe( pipe_slow ); 12663 %} 12664 12665 instruct mask_all_evexI_GT32(kReg dst, rRegI src, rRegL tmp) %{ 12666 predicate(Matcher::vector_length(n) > 32); 12667 match(Set dst (MaskAll src)); 12668 effect(TEMP tmp); 12669 format %{ "mask_all_evexI_GT32 $dst, $src \t! using $tmp as TEMP" %} 12670 ins_encode %{ 12671 int mask_len = Matcher::vector_length(this); 12672 __ movslq($tmp$$Register, $src$$Register); 12673 __ vector_maskall_operation($dst$$KRegister, $tmp$$Register, mask_len); 12674 %} 12675 ins_pipe( pipe_slow ); 12676 %} 12677 12678 // ============================================================================ 12679 // Procedure Call/Return Instructions 12680 // Call Java Static Instruction 12681 // Note: If this code changes, the corresponding ret_addr_offset() and 12682 // compute_padding() functions will have to be adjusted. 12683 instruct CallStaticJavaDirect(method meth) %{ 12684 match(CallStaticJava); 12685 effect(USE meth); 12686 12687 ins_cost(300); 12688 format %{ "call,static " %} 12689 opcode(0xE8); /* E8 cd */ 12690 ins_encode(clear_avx, Java_Static_Call(meth), call_epilog); 12691 ins_pipe(pipe_slow); 12692 ins_alignment(4); 12693 %} 12694 12695 // Call Java Dynamic Instruction 12696 // Note: If this code changes, the corresponding ret_addr_offset() and 12697 // compute_padding() functions will have to be adjusted. 12698 instruct CallDynamicJavaDirect(method meth) 12699 %{ 12700 match(CallDynamicJava); 12701 effect(USE meth); 12702 12703 ins_cost(300); 12704 format %{ "movq rax, #Universe::non_oop_word()\n\t" 12705 "call,dynamic " %} 12706 ins_encode(clear_avx, Java_Dynamic_Call(meth), call_epilog); 12707 ins_pipe(pipe_slow); 12708 ins_alignment(4); 12709 %} 12710 12711 // Call Runtime Instruction 12712 instruct CallRuntimeDirect(method meth) 12713 %{ 12714 match(CallRuntime); 12715 effect(USE meth); 12716 12717 ins_cost(300); 12718 format %{ "call,runtime " %} 12719 ins_encode(clear_avx, Java_To_Runtime(meth)); 12720 ins_pipe(pipe_slow); 12721 %} 12722 12723 // Call runtime without safepoint 12724 instruct CallLeafDirect(method meth) 12725 %{ 12726 match(CallLeaf); 12727 effect(USE meth); 12728 12729 ins_cost(300); 12730 format %{ "call_leaf,runtime " %} 12731 ins_encode(clear_avx, Java_To_Runtime(meth)); 12732 ins_pipe(pipe_slow); 12733 %} 12734 12735 // Call runtime without safepoint and with vector arguments 12736 instruct CallLeafDirectVector(method meth) 12737 %{ 12738 match(CallLeafVector); 12739 effect(USE meth); 12740 12741 ins_cost(300); 12742 format %{ "call_leaf,vector " %} 12743 ins_encode(Java_To_Runtime(meth)); 12744 ins_pipe(pipe_slow); 12745 %} 12746 12747 // Call runtime without safepoint 12748 // entry point is null, target holds the address to call 12749 instruct CallLeafNoFPInDirect(rRegP target) 12750 %{ 12751 predicate(n->as_Call()->entry_point() == nullptr); 12752 match(CallLeafNoFP target); 12753 12754 ins_cost(300); 12755 format %{ "call_leaf_nofp,runtime indirect " %} 12756 ins_encode %{ 12757 __ call($target$$Register); 12758 %} 12759 12760 ins_pipe(pipe_slow); 12761 %} 12762 12763 instruct CallLeafNoFPDirect(method meth) 12764 %{ 12765 predicate(n->as_Call()->entry_point() != nullptr); 12766 match(CallLeafNoFP); 12767 effect(USE meth); 12768 12769 ins_cost(300); 12770 format %{ "call_leaf_nofp,runtime " %} 12771 ins_encode(clear_avx, Java_To_Runtime(meth)); 12772 ins_pipe(pipe_slow); 12773 %} 12774 12775 // Return Instruction 12776 // Remove the return address & jump to it. 12777 // Notice: We always emit a nop after a ret to make sure there is room 12778 // for safepoint patching 12779 instruct Ret() 12780 %{ 12781 match(Return); 12782 12783 format %{ "ret" %} 12784 ins_encode %{ 12785 __ ret(0); 12786 %} 12787 ins_pipe(pipe_jmp); 12788 %} 12789 12790 // Tail Call; Jump from runtime stub to Java code. 12791 // Also known as an 'interprocedural jump'. 12792 // Target of jump will eventually return to caller. 12793 // TailJump below removes the return address. 12794 // Don't use rbp for 'jump_target' because a MachEpilogNode has already been 12795 // emitted just above the TailCall which has reset rbp to the caller state. 12796 instruct TailCalljmpInd(no_rbp_RegP jump_target, rbx_RegP method_ptr) 12797 %{ 12798 match(TailCall jump_target method_ptr); 12799 12800 ins_cost(300); 12801 format %{ "jmp $jump_target\t# rbx holds method" %} 12802 ins_encode %{ 12803 __ jmp($jump_target$$Register); 12804 %} 12805 ins_pipe(pipe_jmp); 12806 %} 12807 12808 // Tail Jump; remove the return address; jump to target. 12809 // TailCall above leaves the return address around. 12810 instruct tailjmpInd(no_rbp_RegP jump_target, rax_RegP ex_oop) 12811 %{ 12812 match(TailJump jump_target ex_oop); 12813 12814 ins_cost(300); 12815 format %{ "popq rdx\t# pop return address\n\t" 12816 "jmp $jump_target" %} 12817 ins_encode %{ 12818 __ popq(as_Register(RDX_enc)); 12819 __ jmp($jump_target$$Register); 12820 %} 12821 ins_pipe(pipe_jmp); 12822 %} 12823 12824 // Forward exception. 12825 instruct ForwardExceptionjmp() 12826 %{ 12827 match(ForwardException); 12828 12829 format %{ "jmp forward_exception_stub" %} 12830 ins_encode %{ 12831 __ jump(RuntimeAddress(StubRoutines::forward_exception_entry()), noreg); 12832 %} 12833 ins_pipe(pipe_jmp); 12834 %} 12835 12836 // Create exception oop: created by stack-crawling runtime code. 12837 // Created exception is now available to this handler, and is setup 12838 // just prior to jumping to this handler. No code emitted. 12839 instruct CreateException(rax_RegP ex_oop) 12840 %{ 12841 match(Set ex_oop (CreateEx)); 12842 12843 size(0); 12844 // use the following format syntax 12845 format %{ "# exception oop is in rax; no code emitted" %} 12846 ins_encode(); 12847 ins_pipe(empty); 12848 %} 12849 12850 // Rethrow exception: 12851 // The exception oop will come in the first argument position. 12852 // Then JUMP (not call) to the rethrow stub code. 12853 instruct RethrowException() 12854 %{ 12855 match(Rethrow); 12856 12857 // use the following format syntax 12858 format %{ "jmp rethrow_stub" %} 12859 ins_encode %{ 12860 __ jump(RuntimeAddress(OptoRuntime::rethrow_stub()), noreg); 12861 %} 12862 ins_pipe(pipe_jmp); 12863 %} 12864 12865 // ============================================================================ 12866 // This name is KNOWN by the ADLC and cannot be changed. 12867 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type 12868 // for this guy. 12869 instruct tlsLoadP(r15_RegP dst) %{ 12870 match(Set dst (ThreadLocal)); 12871 effect(DEF dst); 12872 12873 size(0); 12874 format %{ "# TLS is in R15" %} 12875 ins_encode( /*empty encoding*/ ); 12876 ins_pipe(ialu_reg_reg); 12877 %} 12878 12879 12880 //----------PEEPHOLE RULES----------------------------------------------------- 12881 // These must follow all instruction definitions as they use the names 12882 // defined in the instructions definitions. 12883 // 12884 // peeppredicate ( rule_predicate ); 12885 // // the predicate unless which the peephole rule will be ignored 12886 // 12887 // peepmatch ( root_instr_name [preceding_instruction]* ); 12888 // 12889 // peepprocedure ( procedure_name ); 12890 // // provide a procedure name to perform the optimization, the procedure should 12891 // // reside in the architecture dependent peephole file, the method has the 12892 // // signature of MachNode* (Block*, int, PhaseRegAlloc*, (MachNode*)(*)(), int...) 12893 // // with the arguments being the basic block, the current node index inside the 12894 // // block, the register allocator, the functions upon invoked return a new node 12895 // // defined in peepreplace, and the rules of the nodes appearing in the 12896 // // corresponding peepmatch, the function return true if successful, else 12897 // // return false 12898 // 12899 // peepconstraint %{ 12900 // (instruction_number.operand_name relational_op instruction_number.operand_name 12901 // [, ...] ); 12902 // // instruction numbers are zero-based using left to right order in peepmatch 12903 // 12904 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 12905 // // provide an instruction_number.operand_name for each operand that appears 12906 // // in the replacement instruction's match rule 12907 // 12908 // ---------VM FLAGS--------------------------------------------------------- 12909 // 12910 // All peephole optimizations can be turned off using -XX:-OptoPeephole 12911 // 12912 // Each peephole rule is given an identifying number starting with zero and 12913 // increasing by one in the order seen by the parser. An individual peephole 12914 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 12915 // on the command-line. 12916 // 12917 // ---------CURRENT LIMITATIONS---------------------------------------------- 12918 // 12919 // Only transformations inside a basic block (do we need more for peephole) 12920 // 12921 // ---------EXAMPLE---------------------------------------------------------- 12922 // 12923 // // pertinent parts of existing instructions in architecture description 12924 // instruct movI(rRegI dst, rRegI src) 12925 // %{ 12926 // match(Set dst (CopyI src)); 12927 // %} 12928 // 12929 // instruct incI_rReg(rRegI dst, immI_1 src, rFlagsReg cr) 12930 // %{ 12931 // match(Set dst (AddI dst src)); 12932 // effect(KILL cr); 12933 // %} 12934 // 12935 // instruct leaI_rReg_immI(rRegI dst, immI_1 src) 12936 // %{ 12937 // match(Set dst (AddI dst src)); 12938 // %} 12939 // 12940 // 1. Simple replacement 12941 // - Only match adjacent instructions in same basic block 12942 // - Only equality constraints 12943 // - Only constraints between operands, not (0.dest_reg == RAX_enc) 12944 // - Only one replacement instruction 12945 // 12946 // // Change (inc mov) to lea 12947 // peephole %{ 12948 // // lea should only be emitted when beneficial 12949 // peeppredicate( VM_Version::supports_fast_2op_lea() ); 12950 // // increment preceded by register-register move 12951 // peepmatch ( incI_rReg movI ); 12952 // // require that the destination register of the increment 12953 // // match the destination register of the move 12954 // peepconstraint ( 0.dst == 1.dst ); 12955 // // construct a replacement instruction that sets 12956 // // the destination to ( move's source register + one ) 12957 // peepreplace ( leaI_rReg_immI( 0.dst 1.src 0.src ) ); 12958 // %} 12959 // 12960 // 2. Procedural replacement 12961 // - More flexible finding relevent nodes 12962 // - More flexible constraints 12963 // - More flexible transformations 12964 // - May utilise architecture-dependent API more effectively 12965 // - Currently only one replacement instruction due to adlc parsing capabilities 12966 // 12967 // // Change (inc mov) to lea 12968 // peephole %{ 12969 // // lea should only be emitted when beneficial 12970 // peeppredicate( VM_Version::supports_fast_2op_lea() ); 12971 // // the rule numbers of these nodes inside are passed into the function below 12972 // peepmatch ( incI_rReg movI ); 12973 // // the method that takes the responsibility of transformation 12974 // peepprocedure ( inc_mov_to_lea ); 12975 // // the replacement is a leaI_rReg_immI, a lambda upon invoked creating this 12976 // // node is passed into the function above 12977 // peepreplace ( leaI_rReg_immI() ); 12978 // %} 12979 12980 // These instructions is not matched by the matcher but used by the peephole 12981 instruct leaI_rReg_rReg_peep(rRegI dst, rRegI src1, rRegI src2) 12982 %{ 12983 predicate(false); 12984 match(Set dst (AddI src1 src2)); 12985 format %{ "leal $dst, [$src1 + $src2]" %} 12986 ins_encode %{ 12987 Register dst = $dst$$Register; 12988 Register src1 = $src1$$Register; 12989 Register src2 = $src2$$Register; 12990 if (src1 != rbp && src1 != r13) { 12991 __ leal(dst, Address(src1, src2, Address::times_1)); 12992 } else { 12993 assert(src2 != rbp && src2 != r13, ""); 12994 __ leal(dst, Address(src2, src1, Address::times_1)); 12995 } 12996 %} 12997 ins_pipe(ialu_reg_reg); 12998 %} 12999 13000 instruct leaI_rReg_immI_peep(rRegI dst, rRegI src1, immI src2) 13001 %{ 13002 predicate(false); 13003 match(Set dst (AddI src1 src2)); 13004 format %{ "leal $dst, [$src1 + $src2]" %} 13005 ins_encode %{ 13006 __ leal($dst$$Register, Address($src1$$Register, $src2$$constant)); 13007 %} 13008 ins_pipe(ialu_reg_reg); 13009 %} 13010 13011 instruct leaI_rReg_immI2_peep(rRegI dst, rRegI src, immI2 shift) 13012 %{ 13013 predicate(false); 13014 match(Set dst (LShiftI src shift)); 13015 format %{ "leal $dst, [$src << $shift]" %} 13016 ins_encode %{ 13017 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($shift$$constant); 13018 Register src = $src$$Register; 13019 if (scale == Address::times_2 && src != rbp && src != r13) { 13020 __ leal($dst$$Register, Address(src, src, Address::times_1)); 13021 } else { 13022 __ leal($dst$$Register, Address(noreg, src, scale)); 13023 } 13024 %} 13025 ins_pipe(ialu_reg_reg); 13026 %} 13027 13028 instruct leaL_rReg_rReg_peep(rRegL dst, rRegL src1, rRegL src2) 13029 %{ 13030 predicate(false); 13031 match(Set dst (AddL src1 src2)); 13032 format %{ "leaq $dst, [$src1 + $src2]" %} 13033 ins_encode %{ 13034 Register dst = $dst$$Register; 13035 Register src1 = $src1$$Register; 13036 Register src2 = $src2$$Register; 13037 if (src1 != rbp && src1 != r13) { 13038 __ leaq(dst, Address(src1, src2, Address::times_1)); 13039 } else { 13040 assert(src2 != rbp && src2 != r13, ""); 13041 __ leaq(dst, Address(src2, src1, Address::times_1)); 13042 } 13043 %} 13044 ins_pipe(ialu_reg_reg); 13045 %} 13046 13047 instruct leaL_rReg_immL32_peep(rRegL dst, rRegL src1, immL32 src2) 13048 %{ 13049 predicate(false); 13050 match(Set dst (AddL src1 src2)); 13051 format %{ "leaq $dst, [$src1 + $src2]" %} 13052 ins_encode %{ 13053 __ leaq($dst$$Register, Address($src1$$Register, $src2$$constant)); 13054 %} 13055 ins_pipe(ialu_reg_reg); 13056 %} 13057 13058 instruct leaL_rReg_immI2_peep(rRegL dst, rRegL src, immI2 shift) 13059 %{ 13060 predicate(false); 13061 match(Set dst (LShiftL src shift)); 13062 format %{ "leaq $dst, [$src << $shift]" %} 13063 ins_encode %{ 13064 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($shift$$constant); 13065 Register src = $src$$Register; 13066 if (scale == Address::times_2 && src != rbp && src != r13) { 13067 __ leaq($dst$$Register, Address(src, src, Address::times_1)); 13068 } else { 13069 __ leaq($dst$$Register, Address(noreg, src, scale)); 13070 } 13071 %} 13072 ins_pipe(ialu_reg_reg); 13073 %} 13074 13075 // These peephole rules replace mov + I pairs (where I is one of {add, inc, dec, 13076 // sal}) with lea instructions. The {add, sal} rules are beneficial in 13077 // processors with at least partial ALU support for lea 13078 // (supports_fast_2op_lea()), whereas the {inc, dec} rules are only generally 13079 // beneficial for processors with full ALU support 13080 // (VM_Version::supports_fast_3op_lea()) and Intel Cascade Lake. 13081 13082 peephole 13083 %{ 13084 peeppredicate(VM_Version::supports_fast_2op_lea()); 13085 peepmatch (addI_rReg); 13086 peepprocedure (lea_coalesce_reg); 13087 peepreplace (leaI_rReg_rReg_peep()); 13088 %} 13089 13090 peephole 13091 %{ 13092 peeppredicate(VM_Version::supports_fast_2op_lea()); 13093 peepmatch (addI_rReg_imm); 13094 peepprocedure (lea_coalesce_imm); 13095 peepreplace (leaI_rReg_immI_peep()); 13096 %} 13097 13098 peephole 13099 %{ 13100 peeppredicate(VM_Version::supports_fast_3op_lea() || 13101 VM_Version::is_intel_cascade_lake()); 13102 peepmatch (incI_rReg); 13103 peepprocedure (lea_coalesce_imm); 13104 peepreplace (leaI_rReg_immI_peep()); 13105 %} 13106 13107 peephole 13108 %{ 13109 peeppredicate(VM_Version::supports_fast_3op_lea() || 13110 VM_Version::is_intel_cascade_lake()); 13111 peepmatch (decI_rReg); 13112 peepprocedure (lea_coalesce_imm); 13113 peepreplace (leaI_rReg_immI_peep()); 13114 %} 13115 13116 peephole 13117 %{ 13118 peeppredicate(VM_Version::supports_fast_2op_lea()); 13119 peepmatch (salI_rReg_immI2); 13120 peepprocedure (lea_coalesce_imm); 13121 peepreplace (leaI_rReg_immI2_peep()); 13122 %} 13123 13124 peephole 13125 %{ 13126 peeppredicate(VM_Version::supports_fast_2op_lea()); 13127 peepmatch (addL_rReg); 13128 peepprocedure (lea_coalesce_reg); 13129 peepreplace (leaL_rReg_rReg_peep()); 13130 %} 13131 13132 peephole 13133 %{ 13134 peeppredicate(VM_Version::supports_fast_2op_lea()); 13135 peepmatch (addL_rReg_imm); 13136 peepprocedure (lea_coalesce_imm); 13137 peepreplace (leaL_rReg_immL32_peep()); 13138 %} 13139 13140 peephole 13141 %{ 13142 peeppredicate(VM_Version::supports_fast_3op_lea() || 13143 VM_Version::is_intel_cascade_lake()); 13144 peepmatch (incL_rReg); 13145 peepprocedure (lea_coalesce_imm); 13146 peepreplace (leaL_rReg_immL32_peep()); 13147 %} 13148 13149 peephole 13150 %{ 13151 peeppredicate(VM_Version::supports_fast_3op_lea() || 13152 VM_Version::is_intel_cascade_lake()); 13153 peepmatch (decL_rReg); 13154 peepprocedure (lea_coalesce_imm); 13155 peepreplace (leaL_rReg_immL32_peep()); 13156 %} 13157 13158 peephole 13159 %{ 13160 peeppredicate(VM_Version::supports_fast_2op_lea()); 13161 peepmatch (salL_rReg_immI2); 13162 peepprocedure (lea_coalesce_imm); 13163 peepreplace (leaL_rReg_immI2_peep()); 13164 %} 13165 13166 // These peephole rules matches instructions which set flags and are followed by a testI/L_reg 13167 // 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 13168 13169 //int variant 13170 peephole 13171 %{ 13172 peepmatch (testI_reg); 13173 peepprocedure (test_may_remove); 13174 %} 13175 13176 //long variant 13177 peephole 13178 %{ 13179 peepmatch (testL_reg); 13180 peepprocedure (test_may_remove); 13181 %} 13182 13183 13184 //----------SMARTSPILL RULES--------------------------------------------------- 13185 // These must follow all instruction definitions as they use the names 13186 // defined in the instructions definitions.