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 enc_PartialSubtypeCheck() 1846 %{ 1847 Register Rrdi = as_Register(RDI_enc); // result register 1848 Register Rrax = as_Register(RAX_enc); // super class 1849 Register Rrcx = as_Register(RCX_enc); // killed 1850 Register Rrsi = as_Register(RSI_enc); // sub class 1851 Label miss; 1852 const bool set_cond_codes = true; 1853 1854 __ check_klass_subtype_slow_path(Rrsi, Rrax, Rrcx, Rrdi, 1855 nullptr, &miss, 1856 /*set_cond_codes:*/ true); 1857 if ($primary) { 1858 __ xorptr(Rrdi, Rrdi); 1859 } 1860 __ bind(miss); 1861 %} 1862 1863 enc_class clear_avx %{ 1864 debug_only(int off0 = __ offset()); 1865 if (generate_vzeroupper(Compile::current())) { 1866 // Clear upper bits of YMM registers to avoid AVX <-> SSE transition penalty 1867 // Clear upper bits of YMM registers when current compiled code uses 1868 // wide vectors to avoid AVX <-> SSE transition penalty during call. 1869 __ vzeroupper(); 1870 } 1871 debug_only(int off1 = __ offset()); 1872 assert(off1 - off0 == clear_avx_size(), "correct size prediction"); 1873 %} 1874 1875 enc_class Java_To_Runtime(method meth) %{ 1876 // No relocation needed 1877 __ mov64(r10, (int64_t) $meth$$method); 1878 __ call(r10); 1879 __ post_call_nop(); 1880 %} 1881 1882 enc_class Java_Static_Call(method meth) 1883 %{ 1884 // JAVA STATIC CALL 1885 // CALL to fixup routine. Fixup routine uses ScopeDesc info to 1886 // determine who we intended to call. 1887 if (!_method) { 1888 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, $meth$$method))); 1889 } else if (_method->intrinsic_id() == vmIntrinsicID::_ensureMaterializedForStackWalk) { 1890 // The NOP here is purely to ensure that eliding a call to 1891 // JVM_EnsureMaterializedForStackWalk doesn't change the code size. 1892 __ addr_nop_5(); 1893 __ block_comment("call JVM_EnsureMaterializedForStackWalk (elided)"); 1894 } else { 1895 int method_index = resolved_method_index(masm); 1896 RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 1897 : static_call_Relocation::spec(method_index); 1898 address mark = __ pc(); 1899 int call_offset = __ offset(); 1900 __ call(AddressLiteral(CAST_FROM_FN_PTR(address, $meth$$method), rspec)); 1901 if (CodeBuffer::supports_shared_stubs() && _method->can_be_statically_bound()) { 1902 // Calls of the same statically bound method can share 1903 // a stub to the interpreter. 1904 __ code()->shared_stub_to_interp_for(_method, call_offset); 1905 } else { 1906 // Emit stubs for static call. 1907 address stub = CompiledDirectCall::emit_to_interp_stub(masm, mark); 1908 __ clear_inst_mark(); 1909 if (stub == nullptr) { 1910 ciEnv::current()->record_failure("CodeCache is full"); 1911 return; 1912 } 1913 } 1914 } 1915 __ post_call_nop(); 1916 %} 1917 1918 enc_class Java_Dynamic_Call(method meth) %{ 1919 __ ic_call((address)$meth$$method, resolved_method_index(masm)); 1920 __ post_call_nop(); 1921 %} 1922 1923 %} 1924 1925 1926 1927 //----------FRAME-------------------------------------------------------------- 1928 // Definition of frame structure and management information. 1929 // 1930 // S T A C K L A Y O U T Allocators stack-slot number 1931 // | (to get allocators register number 1932 // G Owned by | | v add OptoReg::stack0()) 1933 // r CALLER | | 1934 // o | +--------+ pad to even-align allocators stack-slot 1935 // w V | pad0 | numbers; owned by CALLER 1936 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned 1937 // h ^ | in | 5 1938 // | | args | 4 Holes in incoming args owned by SELF 1939 // | | | | 3 1940 // | | +--------+ 1941 // V | | old out| Empty on Intel, window on Sparc 1942 // | old |preserve| Must be even aligned. 1943 // | SP-+--------+----> Matcher::_old_SP, even aligned 1944 // | | in | 3 area for Intel ret address 1945 // Owned by |preserve| Empty on Sparc. 1946 // SELF +--------+ 1947 // | | pad2 | 2 pad to align old SP 1948 // | +--------+ 1 1949 // | | locks | 0 1950 // | +--------+----> OptoReg::stack0(), even aligned 1951 // | | pad1 | 11 pad to align new SP 1952 // | +--------+ 1953 // | | | 10 1954 // | | spills | 9 spills 1955 // V | | 8 (pad0 slot for callee) 1956 // -----------+--------+----> Matcher::_out_arg_limit, unaligned 1957 // ^ | out | 7 1958 // | | args | 6 Holes in outgoing args owned by CALLEE 1959 // Owned by +--------+ 1960 // CALLEE | new out| 6 Empty on Intel, window on Sparc 1961 // | new |preserve| Must be even-aligned. 1962 // | SP-+--------+----> Matcher::_new_SP, even aligned 1963 // | | | 1964 // 1965 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 1966 // known from SELF's arguments and the Java calling convention. 1967 // Region 6-7 is determined per call site. 1968 // Note 2: If the calling convention leaves holes in the incoming argument 1969 // area, those holes are owned by SELF. Holes in the outgoing area 1970 // are owned by the CALLEE. Holes should not be necessary in the 1971 // incoming area, as the Java calling convention is completely under 1972 // the control of the AD file. Doubles can be sorted and packed to 1973 // avoid holes. Holes in the outgoing arguments may be necessary for 1974 // varargs C calling conventions. 1975 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 1976 // even aligned with pad0 as needed. 1977 // Region 6 is even aligned. Region 6-7 is NOT even aligned; 1978 // region 6-11 is even aligned; it may be padded out more so that 1979 // the region from SP to FP meets the minimum stack alignment. 1980 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 1981 // alignment. Region 11, pad1, may be dynamically extended so that 1982 // SP meets the minimum alignment. 1983 1984 frame 1985 %{ 1986 // These three registers define part of the calling convention 1987 // between compiled code and the interpreter. 1988 inline_cache_reg(RAX); // Inline Cache Register 1989 1990 // Optional: name the operand used by cisc-spilling to access 1991 // [stack_pointer + offset] 1992 cisc_spilling_operand_name(indOffset32); 1993 1994 // Number of stack slots consumed by locking an object 1995 sync_stack_slots(2); 1996 1997 // Compiled code's Frame Pointer 1998 frame_pointer(RSP); 1999 2000 // Interpreter stores its frame pointer in a register which is 2001 // stored to the stack by I2CAdaptors. 2002 // I2CAdaptors convert from interpreted java to compiled java. 2003 interpreter_frame_pointer(RBP); 2004 2005 // Stack alignment requirement 2006 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 2007 2008 // Number of outgoing stack slots killed above the out_preserve_stack_slots 2009 // for calls to C. Supports the var-args backing area for register parms. 2010 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 2011 2012 // The after-PROLOG location of the return address. Location of 2013 // return address specifies a type (REG or STACK) and a number 2014 // representing the register number (i.e. - use a register name) or 2015 // stack slot. 2016 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 2017 // Otherwise, it is above the locks and verification slot and alignment word 2018 return_addr(STACK - 2 + 2019 align_up((Compile::current()->in_preserve_stack_slots() + 2020 Compile::current()->fixed_slots()), 2021 stack_alignment_in_slots())); 2022 2023 // Location of compiled Java return values. Same as C for now. 2024 return_value 2025 %{ 2026 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 2027 "only return normal values"); 2028 2029 static const int lo[Op_RegL + 1] = { 2030 0, 2031 0, 2032 RAX_num, // Op_RegN 2033 RAX_num, // Op_RegI 2034 RAX_num, // Op_RegP 2035 XMM0_num, // Op_RegF 2036 XMM0_num, // Op_RegD 2037 RAX_num // Op_RegL 2038 }; 2039 static const int hi[Op_RegL + 1] = { 2040 0, 2041 0, 2042 OptoReg::Bad, // Op_RegN 2043 OptoReg::Bad, // Op_RegI 2044 RAX_H_num, // Op_RegP 2045 OptoReg::Bad, // Op_RegF 2046 XMM0b_num, // Op_RegD 2047 RAX_H_num // Op_RegL 2048 }; 2049 // Excluded flags and vector registers. 2050 assert(ARRAY_SIZE(hi) == _last_machine_leaf - 8, "missing type"); 2051 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 2052 %} 2053 %} 2054 2055 //----------ATTRIBUTES--------------------------------------------------------- 2056 //----------Operand Attributes------------------------------------------------- 2057 op_attrib op_cost(0); // Required cost attribute 2058 2059 //----------Instruction Attributes--------------------------------------------- 2060 ins_attrib ins_cost(100); // Required cost attribute 2061 ins_attrib ins_size(8); // Required size attribute (in bits) 2062 ins_attrib ins_short_branch(0); // Required flag: is this instruction 2063 // a non-matching short branch variant 2064 // of some long branch? 2065 ins_attrib ins_alignment(1); // Required alignment attribute (must 2066 // be a power of 2) specifies the 2067 // alignment that some part of the 2068 // instruction (not necessarily the 2069 // start) requires. If > 1, a 2070 // compute_padding() function must be 2071 // provided for the instruction 2072 2073 //----------OPERANDS----------------------------------------------------------- 2074 // Operand definitions must precede instruction definitions for correct parsing 2075 // in the ADLC because operands constitute user defined types which are used in 2076 // instruction definitions. 2077 2078 //----------Simple Operands---------------------------------------------------- 2079 // Immediate Operands 2080 // Integer Immediate 2081 operand immI() 2082 %{ 2083 match(ConI); 2084 2085 op_cost(10); 2086 format %{ %} 2087 interface(CONST_INTER); 2088 %} 2089 2090 // Constant for test vs zero 2091 operand immI_0() 2092 %{ 2093 predicate(n->get_int() == 0); 2094 match(ConI); 2095 2096 op_cost(0); 2097 format %{ %} 2098 interface(CONST_INTER); 2099 %} 2100 2101 // Constant for increment 2102 operand immI_1() 2103 %{ 2104 predicate(n->get_int() == 1); 2105 match(ConI); 2106 2107 op_cost(0); 2108 format %{ %} 2109 interface(CONST_INTER); 2110 %} 2111 2112 // Constant for decrement 2113 operand immI_M1() 2114 %{ 2115 predicate(n->get_int() == -1); 2116 match(ConI); 2117 2118 op_cost(0); 2119 format %{ %} 2120 interface(CONST_INTER); 2121 %} 2122 2123 operand immI_2() 2124 %{ 2125 predicate(n->get_int() == 2); 2126 match(ConI); 2127 2128 op_cost(0); 2129 format %{ %} 2130 interface(CONST_INTER); 2131 %} 2132 2133 operand immI_4() 2134 %{ 2135 predicate(n->get_int() == 4); 2136 match(ConI); 2137 2138 op_cost(0); 2139 format %{ %} 2140 interface(CONST_INTER); 2141 %} 2142 2143 operand immI_8() 2144 %{ 2145 predicate(n->get_int() == 8); 2146 match(ConI); 2147 2148 op_cost(0); 2149 format %{ %} 2150 interface(CONST_INTER); 2151 %} 2152 2153 // Valid scale values for addressing modes 2154 operand immI2() 2155 %{ 2156 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 2157 match(ConI); 2158 2159 format %{ %} 2160 interface(CONST_INTER); 2161 %} 2162 2163 operand immU7() 2164 %{ 2165 predicate((0 <= n->get_int()) && (n->get_int() <= 0x7F)); 2166 match(ConI); 2167 2168 op_cost(5); 2169 format %{ %} 2170 interface(CONST_INTER); 2171 %} 2172 2173 operand immI8() 2174 %{ 2175 predicate((-0x80 <= n->get_int()) && (n->get_int() < 0x80)); 2176 match(ConI); 2177 2178 op_cost(5); 2179 format %{ %} 2180 interface(CONST_INTER); 2181 %} 2182 2183 operand immU8() 2184 %{ 2185 predicate((0 <= n->get_int()) && (n->get_int() <= 255)); 2186 match(ConI); 2187 2188 op_cost(5); 2189 format %{ %} 2190 interface(CONST_INTER); 2191 %} 2192 2193 operand immI16() 2194 %{ 2195 predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767)); 2196 match(ConI); 2197 2198 op_cost(10); 2199 format %{ %} 2200 interface(CONST_INTER); 2201 %} 2202 2203 // Int Immediate non-negative 2204 operand immU31() 2205 %{ 2206 predicate(n->get_int() >= 0); 2207 match(ConI); 2208 2209 op_cost(0); 2210 format %{ %} 2211 interface(CONST_INTER); 2212 %} 2213 2214 // Pointer Immediate 2215 operand immP() 2216 %{ 2217 match(ConP); 2218 2219 op_cost(10); 2220 format %{ %} 2221 interface(CONST_INTER); 2222 %} 2223 2224 // Null Pointer Immediate 2225 operand immP0() 2226 %{ 2227 predicate(n->get_ptr() == 0); 2228 match(ConP); 2229 2230 op_cost(5); 2231 format %{ %} 2232 interface(CONST_INTER); 2233 %} 2234 2235 // Pointer Immediate 2236 operand immN() %{ 2237 match(ConN); 2238 2239 op_cost(10); 2240 format %{ %} 2241 interface(CONST_INTER); 2242 %} 2243 2244 operand immNKlass() %{ 2245 match(ConNKlass); 2246 2247 op_cost(10); 2248 format %{ %} 2249 interface(CONST_INTER); 2250 %} 2251 2252 // Null Pointer Immediate 2253 operand immN0() %{ 2254 predicate(n->get_narrowcon() == 0); 2255 match(ConN); 2256 2257 op_cost(5); 2258 format %{ %} 2259 interface(CONST_INTER); 2260 %} 2261 2262 operand immP31() 2263 %{ 2264 predicate(n->as_Type()->type()->reloc() == relocInfo::none 2265 && (n->get_ptr() >> 31) == 0); 2266 match(ConP); 2267 2268 op_cost(5); 2269 format %{ %} 2270 interface(CONST_INTER); 2271 %} 2272 2273 2274 // Long Immediate 2275 operand immL() 2276 %{ 2277 match(ConL); 2278 2279 op_cost(20); 2280 format %{ %} 2281 interface(CONST_INTER); 2282 %} 2283 2284 // Long Immediate 8-bit 2285 operand immL8() 2286 %{ 2287 predicate(-0x80L <= n->get_long() && n->get_long() < 0x80L); 2288 match(ConL); 2289 2290 op_cost(5); 2291 format %{ %} 2292 interface(CONST_INTER); 2293 %} 2294 2295 // Long Immediate 32-bit unsigned 2296 operand immUL32() 2297 %{ 2298 predicate(n->get_long() == (unsigned int) (n->get_long())); 2299 match(ConL); 2300 2301 op_cost(10); 2302 format %{ %} 2303 interface(CONST_INTER); 2304 %} 2305 2306 // Long Immediate 32-bit signed 2307 operand immL32() 2308 %{ 2309 predicate(n->get_long() == (int) (n->get_long())); 2310 match(ConL); 2311 2312 op_cost(15); 2313 format %{ %} 2314 interface(CONST_INTER); 2315 %} 2316 2317 operand immL_Pow2() 2318 %{ 2319 predicate(is_power_of_2((julong)n->get_long())); 2320 match(ConL); 2321 2322 op_cost(15); 2323 format %{ %} 2324 interface(CONST_INTER); 2325 %} 2326 2327 operand immL_NotPow2() 2328 %{ 2329 predicate(is_power_of_2((julong)~n->get_long())); 2330 match(ConL); 2331 2332 op_cost(15); 2333 format %{ %} 2334 interface(CONST_INTER); 2335 %} 2336 2337 // Long Immediate zero 2338 operand immL0() 2339 %{ 2340 predicate(n->get_long() == 0L); 2341 match(ConL); 2342 2343 op_cost(10); 2344 format %{ %} 2345 interface(CONST_INTER); 2346 %} 2347 2348 // Constant for increment 2349 operand immL1() 2350 %{ 2351 predicate(n->get_long() == 1); 2352 match(ConL); 2353 2354 format %{ %} 2355 interface(CONST_INTER); 2356 %} 2357 2358 // Constant for decrement 2359 operand immL_M1() 2360 %{ 2361 predicate(n->get_long() == -1); 2362 match(ConL); 2363 2364 format %{ %} 2365 interface(CONST_INTER); 2366 %} 2367 2368 // Long Immediate: low 32-bit mask 2369 operand immL_32bits() 2370 %{ 2371 predicate(n->get_long() == 0xFFFFFFFFL); 2372 match(ConL); 2373 op_cost(20); 2374 2375 format %{ %} 2376 interface(CONST_INTER); 2377 %} 2378 2379 // Int Immediate: 2^n-1, positive 2380 operand immI_Pow2M1() 2381 %{ 2382 predicate((n->get_int() > 0) 2383 && is_power_of_2((juint)n->get_int() + 1)); 2384 match(ConI); 2385 2386 op_cost(20); 2387 format %{ %} 2388 interface(CONST_INTER); 2389 %} 2390 2391 // Float Immediate zero 2392 operand immF0() 2393 %{ 2394 predicate(jint_cast(n->getf()) == 0); 2395 match(ConF); 2396 2397 op_cost(5); 2398 format %{ %} 2399 interface(CONST_INTER); 2400 %} 2401 2402 // Float Immediate 2403 operand immF() 2404 %{ 2405 match(ConF); 2406 2407 op_cost(15); 2408 format %{ %} 2409 interface(CONST_INTER); 2410 %} 2411 2412 // Double Immediate zero 2413 operand immD0() 2414 %{ 2415 predicate(jlong_cast(n->getd()) == 0); 2416 match(ConD); 2417 2418 op_cost(5); 2419 format %{ %} 2420 interface(CONST_INTER); 2421 %} 2422 2423 // Double Immediate 2424 operand immD() 2425 %{ 2426 match(ConD); 2427 2428 op_cost(15); 2429 format %{ %} 2430 interface(CONST_INTER); 2431 %} 2432 2433 // Immediates for special shifts (sign extend) 2434 2435 // Constants for increment 2436 operand immI_16() 2437 %{ 2438 predicate(n->get_int() == 16); 2439 match(ConI); 2440 2441 format %{ %} 2442 interface(CONST_INTER); 2443 %} 2444 2445 operand immI_24() 2446 %{ 2447 predicate(n->get_int() == 24); 2448 match(ConI); 2449 2450 format %{ %} 2451 interface(CONST_INTER); 2452 %} 2453 2454 // Constant for byte-wide masking 2455 operand immI_255() 2456 %{ 2457 predicate(n->get_int() == 255); 2458 match(ConI); 2459 2460 format %{ %} 2461 interface(CONST_INTER); 2462 %} 2463 2464 // Constant for short-wide masking 2465 operand immI_65535() 2466 %{ 2467 predicate(n->get_int() == 65535); 2468 match(ConI); 2469 2470 format %{ %} 2471 interface(CONST_INTER); 2472 %} 2473 2474 // Constant for byte-wide masking 2475 operand immL_255() 2476 %{ 2477 predicate(n->get_long() == 255); 2478 match(ConL); 2479 2480 format %{ %} 2481 interface(CONST_INTER); 2482 %} 2483 2484 // Constant for short-wide masking 2485 operand immL_65535() 2486 %{ 2487 predicate(n->get_long() == 65535); 2488 match(ConL); 2489 2490 format %{ %} 2491 interface(CONST_INTER); 2492 %} 2493 2494 operand kReg() 2495 %{ 2496 constraint(ALLOC_IN_RC(vectmask_reg)); 2497 match(RegVectMask); 2498 format %{%} 2499 interface(REG_INTER); 2500 %} 2501 2502 // Register Operands 2503 // Integer Register 2504 operand rRegI() 2505 %{ 2506 constraint(ALLOC_IN_RC(int_reg)); 2507 match(RegI); 2508 2509 match(rax_RegI); 2510 match(rbx_RegI); 2511 match(rcx_RegI); 2512 match(rdx_RegI); 2513 match(rdi_RegI); 2514 2515 format %{ %} 2516 interface(REG_INTER); 2517 %} 2518 2519 // Special Registers 2520 operand rax_RegI() 2521 %{ 2522 constraint(ALLOC_IN_RC(int_rax_reg)); 2523 match(RegI); 2524 match(rRegI); 2525 2526 format %{ "RAX" %} 2527 interface(REG_INTER); 2528 %} 2529 2530 // Special Registers 2531 operand rbx_RegI() 2532 %{ 2533 constraint(ALLOC_IN_RC(int_rbx_reg)); 2534 match(RegI); 2535 match(rRegI); 2536 2537 format %{ "RBX" %} 2538 interface(REG_INTER); 2539 %} 2540 2541 operand rcx_RegI() 2542 %{ 2543 constraint(ALLOC_IN_RC(int_rcx_reg)); 2544 match(RegI); 2545 match(rRegI); 2546 2547 format %{ "RCX" %} 2548 interface(REG_INTER); 2549 %} 2550 2551 operand rdx_RegI() 2552 %{ 2553 constraint(ALLOC_IN_RC(int_rdx_reg)); 2554 match(RegI); 2555 match(rRegI); 2556 2557 format %{ "RDX" %} 2558 interface(REG_INTER); 2559 %} 2560 2561 operand rdi_RegI() 2562 %{ 2563 constraint(ALLOC_IN_RC(int_rdi_reg)); 2564 match(RegI); 2565 match(rRegI); 2566 2567 format %{ "RDI" %} 2568 interface(REG_INTER); 2569 %} 2570 2571 operand no_rax_rdx_RegI() 2572 %{ 2573 constraint(ALLOC_IN_RC(int_no_rax_rdx_reg)); 2574 match(RegI); 2575 match(rbx_RegI); 2576 match(rcx_RegI); 2577 match(rdi_RegI); 2578 2579 format %{ %} 2580 interface(REG_INTER); 2581 %} 2582 2583 operand no_rbp_r13_RegI() 2584 %{ 2585 constraint(ALLOC_IN_RC(int_no_rbp_r13_reg)); 2586 match(RegI); 2587 match(rRegI); 2588 match(rax_RegI); 2589 match(rbx_RegI); 2590 match(rcx_RegI); 2591 match(rdx_RegI); 2592 match(rdi_RegI); 2593 2594 format %{ %} 2595 interface(REG_INTER); 2596 %} 2597 2598 // Pointer Register 2599 operand any_RegP() 2600 %{ 2601 constraint(ALLOC_IN_RC(any_reg)); 2602 match(RegP); 2603 match(rax_RegP); 2604 match(rbx_RegP); 2605 match(rdi_RegP); 2606 match(rsi_RegP); 2607 match(rbp_RegP); 2608 match(r15_RegP); 2609 match(rRegP); 2610 2611 format %{ %} 2612 interface(REG_INTER); 2613 %} 2614 2615 operand rRegP() 2616 %{ 2617 constraint(ALLOC_IN_RC(ptr_reg)); 2618 match(RegP); 2619 match(rax_RegP); 2620 match(rbx_RegP); 2621 match(rdi_RegP); 2622 match(rsi_RegP); 2623 match(rbp_RegP); // See Q&A below about 2624 match(r15_RegP); // r15_RegP and rbp_RegP. 2625 2626 format %{ %} 2627 interface(REG_INTER); 2628 %} 2629 2630 operand rRegN() %{ 2631 constraint(ALLOC_IN_RC(int_reg)); 2632 match(RegN); 2633 2634 format %{ %} 2635 interface(REG_INTER); 2636 %} 2637 2638 // Question: Why is r15_RegP (the read-only TLS register) a match for rRegP? 2639 // Answer: Operand match rules govern the DFA as it processes instruction inputs. 2640 // It's fine for an instruction input that expects rRegP to match a r15_RegP. 2641 // The output of an instruction is controlled by the allocator, which respects 2642 // register class masks, not match rules. Unless an instruction mentions 2643 // r15_RegP or any_RegP explicitly as its output, r15 will not be considered 2644 // by the allocator as an input. 2645 // The same logic applies to rbp_RegP being a match for rRegP: If PreserveFramePointer==true, 2646 // the RBP is used as a proper frame pointer and is not included in ptr_reg. As a 2647 // result, RBP is not included in the output of the instruction either. 2648 2649 // This operand is not allowed to use RBP even if 2650 // RBP is not used to hold the frame pointer. 2651 operand no_rbp_RegP() 2652 %{ 2653 constraint(ALLOC_IN_RC(ptr_reg_no_rbp)); 2654 match(RegP); 2655 match(rbx_RegP); 2656 match(rsi_RegP); 2657 match(rdi_RegP); 2658 2659 format %{ %} 2660 interface(REG_INTER); 2661 %} 2662 2663 // Special Registers 2664 // Return a pointer value 2665 operand rax_RegP() 2666 %{ 2667 constraint(ALLOC_IN_RC(ptr_rax_reg)); 2668 match(RegP); 2669 match(rRegP); 2670 2671 format %{ %} 2672 interface(REG_INTER); 2673 %} 2674 2675 // Special Registers 2676 // Return a compressed pointer value 2677 operand rax_RegN() 2678 %{ 2679 constraint(ALLOC_IN_RC(int_rax_reg)); 2680 match(RegN); 2681 match(rRegN); 2682 2683 format %{ %} 2684 interface(REG_INTER); 2685 %} 2686 2687 // Used in AtomicAdd 2688 operand rbx_RegP() 2689 %{ 2690 constraint(ALLOC_IN_RC(ptr_rbx_reg)); 2691 match(RegP); 2692 match(rRegP); 2693 2694 format %{ %} 2695 interface(REG_INTER); 2696 %} 2697 2698 operand rsi_RegP() 2699 %{ 2700 constraint(ALLOC_IN_RC(ptr_rsi_reg)); 2701 match(RegP); 2702 match(rRegP); 2703 2704 format %{ %} 2705 interface(REG_INTER); 2706 %} 2707 2708 operand rbp_RegP() 2709 %{ 2710 constraint(ALLOC_IN_RC(ptr_rbp_reg)); 2711 match(RegP); 2712 match(rRegP); 2713 2714 format %{ %} 2715 interface(REG_INTER); 2716 %} 2717 2718 // Used in rep stosq 2719 operand rdi_RegP() 2720 %{ 2721 constraint(ALLOC_IN_RC(ptr_rdi_reg)); 2722 match(RegP); 2723 match(rRegP); 2724 2725 format %{ %} 2726 interface(REG_INTER); 2727 %} 2728 2729 operand r15_RegP() 2730 %{ 2731 constraint(ALLOC_IN_RC(ptr_r15_reg)); 2732 match(RegP); 2733 match(rRegP); 2734 2735 format %{ %} 2736 interface(REG_INTER); 2737 %} 2738 2739 operand rRegL() 2740 %{ 2741 constraint(ALLOC_IN_RC(long_reg)); 2742 match(RegL); 2743 match(rax_RegL); 2744 match(rdx_RegL); 2745 2746 format %{ %} 2747 interface(REG_INTER); 2748 %} 2749 2750 // Special Registers 2751 operand no_rax_rdx_RegL() 2752 %{ 2753 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 2754 match(RegL); 2755 match(rRegL); 2756 2757 format %{ %} 2758 interface(REG_INTER); 2759 %} 2760 2761 operand rax_RegL() 2762 %{ 2763 constraint(ALLOC_IN_RC(long_rax_reg)); 2764 match(RegL); 2765 match(rRegL); 2766 2767 format %{ "RAX" %} 2768 interface(REG_INTER); 2769 %} 2770 2771 operand rcx_RegL() 2772 %{ 2773 constraint(ALLOC_IN_RC(long_rcx_reg)); 2774 match(RegL); 2775 match(rRegL); 2776 2777 format %{ %} 2778 interface(REG_INTER); 2779 %} 2780 2781 operand rdx_RegL() 2782 %{ 2783 constraint(ALLOC_IN_RC(long_rdx_reg)); 2784 match(RegL); 2785 match(rRegL); 2786 2787 format %{ %} 2788 interface(REG_INTER); 2789 %} 2790 2791 operand r11_RegL() 2792 %{ 2793 constraint(ALLOC_IN_RC(long_r11_reg)); 2794 match(RegL); 2795 match(rRegL); 2796 2797 format %{ %} 2798 interface(REG_INTER); 2799 %} 2800 2801 operand no_rbp_r13_RegL() 2802 %{ 2803 constraint(ALLOC_IN_RC(long_no_rbp_r13_reg)); 2804 match(RegL); 2805 match(rRegL); 2806 match(rax_RegL); 2807 match(rcx_RegL); 2808 match(rdx_RegL); 2809 2810 format %{ %} 2811 interface(REG_INTER); 2812 %} 2813 2814 // Flags register, used as output of compare instructions 2815 operand rFlagsReg() 2816 %{ 2817 constraint(ALLOC_IN_RC(int_flags)); 2818 match(RegFlags); 2819 2820 format %{ "RFLAGS" %} 2821 interface(REG_INTER); 2822 %} 2823 2824 // Flags register, used as output of FLOATING POINT compare instructions 2825 operand rFlagsRegU() 2826 %{ 2827 constraint(ALLOC_IN_RC(int_flags)); 2828 match(RegFlags); 2829 2830 format %{ "RFLAGS_U" %} 2831 interface(REG_INTER); 2832 %} 2833 2834 operand rFlagsRegUCF() %{ 2835 constraint(ALLOC_IN_RC(int_flags)); 2836 match(RegFlags); 2837 predicate(false); 2838 2839 format %{ "RFLAGS_U_CF" %} 2840 interface(REG_INTER); 2841 %} 2842 2843 // Float register operands 2844 operand regF() %{ 2845 constraint(ALLOC_IN_RC(float_reg)); 2846 match(RegF); 2847 2848 format %{ %} 2849 interface(REG_INTER); 2850 %} 2851 2852 // Float register operands 2853 operand legRegF() %{ 2854 constraint(ALLOC_IN_RC(float_reg_legacy)); 2855 match(RegF); 2856 2857 format %{ %} 2858 interface(REG_INTER); 2859 %} 2860 2861 // Float register operands 2862 operand vlRegF() %{ 2863 constraint(ALLOC_IN_RC(float_reg_vl)); 2864 match(RegF); 2865 2866 format %{ %} 2867 interface(REG_INTER); 2868 %} 2869 2870 // Double register operands 2871 operand regD() %{ 2872 constraint(ALLOC_IN_RC(double_reg)); 2873 match(RegD); 2874 2875 format %{ %} 2876 interface(REG_INTER); 2877 %} 2878 2879 // Double register operands 2880 operand legRegD() %{ 2881 constraint(ALLOC_IN_RC(double_reg_legacy)); 2882 match(RegD); 2883 2884 format %{ %} 2885 interface(REG_INTER); 2886 %} 2887 2888 // Double register operands 2889 operand vlRegD() %{ 2890 constraint(ALLOC_IN_RC(double_reg_vl)); 2891 match(RegD); 2892 2893 format %{ %} 2894 interface(REG_INTER); 2895 %} 2896 2897 //----------Memory Operands---------------------------------------------------- 2898 // Direct Memory Operand 2899 // operand direct(immP addr) 2900 // %{ 2901 // match(addr); 2902 2903 // format %{ "[$addr]" %} 2904 // interface(MEMORY_INTER) %{ 2905 // base(0xFFFFFFFF); 2906 // index(0x4); 2907 // scale(0x0); 2908 // disp($addr); 2909 // %} 2910 // %} 2911 2912 // Indirect Memory Operand 2913 operand indirect(any_RegP reg) 2914 %{ 2915 constraint(ALLOC_IN_RC(ptr_reg)); 2916 match(reg); 2917 2918 format %{ "[$reg]" %} 2919 interface(MEMORY_INTER) %{ 2920 base($reg); 2921 index(0x4); 2922 scale(0x0); 2923 disp(0x0); 2924 %} 2925 %} 2926 2927 // Indirect Memory Plus Short Offset Operand 2928 operand indOffset8(any_RegP reg, immL8 off) 2929 %{ 2930 constraint(ALLOC_IN_RC(ptr_reg)); 2931 match(AddP reg off); 2932 2933 format %{ "[$reg + $off (8-bit)]" %} 2934 interface(MEMORY_INTER) %{ 2935 base($reg); 2936 index(0x4); 2937 scale(0x0); 2938 disp($off); 2939 %} 2940 %} 2941 2942 // Indirect Memory Plus Long Offset Operand 2943 operand indOffset32(any_RegP reg, immL32 off) 2944 %{ 2945 constraint(ALLOC_IN_RC(ptr_reg)); 2946 match(AddP reg off); 2947 2948 format %{ "[$reg + $off (32-bit)]" %} 2949 interface(MEMORY_INTER) %{ 2950 base($reg); 2951 index(0x4); 2952 scale(0x0); 2953 disp($off); 2954 %} 2955 %} 2956 2957 // Indirect Memory Plus Index Register Plus Offset Operand 2958 operand indIndexOffset(any_RegP reg, rRegL lreg, immL32 off) 2959 %{ 2960 constraint(ALLOC_IN_RC(ptr_reg)); 2961 match(AddP (AddP reg lreg) off); 2962 2963 op_cost(10); 2964 format %{"[$reg + $off + $lreg]" %} 2965 interface(MEMORY_INTER) %{ 2966 base($reg); 2967 index($lreg); 2968 scale(0x0); 2969 disp($off); 2970 %} 2971 %} 2972 2973 // Indirect Memory Plus Index Register Plus Offset Operand 2974 operand indIndex(any_RegP reg, rRegL lreg) 2975 %{ 2976 constraint(ALLOC_IN_RC(ptr_reg)); 2977 match(AddP reg lreg); 2978 2979 op_cost(10); 2980 format %{"[$reg + $lreg]" %} 2981 interface(MEMORY_INTER) %{ 2982 base($reg); 2983 index($lreg); 2984 scale(0x0); 2985 disp(0x0); 2986 %} 2987 %} 2988 2989 // Indirect Memory Times Scale Plus Index Register 2990 operand indIndexScale(any_RegP reg, rRegL lreg, immI2 scale) 2991 %{ 2992 constraint(ALLOC_IN_RC(ptr_reg)); 2993 match(AddP reg (LShiftL lreg scale)); 2994 2995 op_cost(10); 2996 format %{"[$reg + $lreg << $scale]" %} 2997 interface(MEMORY_INTER) %{ 2998 base($reg); 2999 index($lreg); 3000 scale($scale); 3001 disp(0x0); 3002 %} 3003 %} 3004 3005 operand indPosIndexScale(any_RegP reg, rRegI idx, immI2 scale) 3006 %{ 3007 constraint(ALLOC_IN_RC(ptr_reg)); 3008 predicate(n->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3009 match(AddP reg (LShiftL (ConvI2L idx) scale)); 3010 3011 op_cost(10); 3012 format %{"[$reg + pos $idx << $scale]" %} 3013 interface(MEMORY_INTER) %{ 3014 base($reg); 3015 index($idx); 3016 scale($scale); 3017 disp(0x0); 3018 %} 3019 %} 3020 3021 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 3022 operand indIndexScaleOffset(any_RegP reg, immL32 off, rRegL lreg, immI2 scale) 3023 %{ 3024 constraint(ALLOC_IN_RC(ptr_reg)); 3025 match(AddP (AddP reg (LShiftL lreg scale)) off); 3026 3027 op_cost(10); 3028 format %{"[$reg + $off + $lreg << $scale]" %} 3029 interface(MEMORY_INTER) %{ 3030 base($reg); 3031 index($lreg); 3032 scale($scale); 3033 disp($off); 3034 %} 3035 %} 3036 3037 // Indirect Memory Plus Positive Index Register Plus Offset Operand 3038 operand indPosIndexOffset(any_RegP reg, immL32 off, rRegI idx) 3039 %{ 3040 constraint(ALLOC_IN_RC(ptr_reg)); 3041 predicate(n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 3042 match(AddP (AddP reg (ConvI2L idx)) off); 3043 3044 op_cost(10); 3045 format %{"[$reg + $off + $idx]" %} 3046 interface(MEMORY_INTER) %{ 3047 base($reg); 3048 index($idx); 3049 scale(0x0); 3050 disp($off); 3051 %} 3052 %} 3053 3054 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 3055 operand indPosIndexScaleOffset(any_RegP reg, immL32 off, rRegI idx, immI2 scale) 3056 %{ 3057 constraint(ALLOC_IN_RC(ptr_reg)); 3058 predicate(n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3059 match(AddP (AddP reg (LShiftL (ConvI2L idx) scale)) off); 3060 3061 op_cost(10); 3062 format %{"[$reg + $off + $idx << $scale]" %} 3063 interface(MEMORY_INTER) %{ 3064 base($reg); 3065 index($idx); 3066 scale($scale); 3067 disp($off); 3068 %} 3069 %} 3070 3071 // Indirect Narrow Oop Operand 3072 operand indCompressedOop(rRegN reg) %{ 3073 predicate(UseCompressedOops && (CompressedOops::shift() == Address::times_8)); 3074 constraint(ALLOC_IN_RC(ptr_reg)); 3075 match(DecodeN reg); 3076 3077 op_cost(10); 3078 format %{"[R12 + $reg << 3] (compressed oop addressing)" %} 3079 interface(MEMORY_INTER) %{ 3080 base(0xc); // R12 3081 index($reg); 3082 scale(0x3); 3083 disp(0x0); 3084 %} 3085 %} 3086 3087 // Indirect Narrow Oop Plus Offset Operand 3088 // Note: x86 architecture doesn't support "scale * index + offset" without a base 3089 // we can't free r12 even with CompressedOops::base() == nullptr. 3090 operand indCompressedOopOffset(rRegN reg, immL32 off) %{ 3091 predicate(UseCompressedOops && (CompressedOops::shift() == Address::times_8)); 3092 constraint(ALLOC_IN_RC(ptr_reg)); 3093 match(AddP (DecodeN reg) off); 3094 3095 op_cost(10); 3096 format %{"[R12 + $reg << 3 + $off] (compressed oop addressing)" %} 3097 interface(MEMORY_INTER) %{ 3098 base(0xc); // R12 3099 index($reg); 3100 scale(0x3); 3101 disp($off); 3102 %} 3103 %} 3104 3105 // Indirect Memory Operand 3106 operand indirectNarrow(rRegN reg) 3107 %{ 3108 predicate(CompressedOops::shift() == 0); 3109 constraint(ALLOC_IN_RC(ptr_reg)); 3110 match(DecodeN reg); 3111 3112 format %{ "[$reg]" %} 3113 interface(MEMORY_INTER) %{ 3114 base($reg); 3115 index(0x4); 3116 scale(0x0); 3117 disp(0x0); 3118 %} 3119 %} 3120 3121 // Indirect Memory Plus Short Offset Operand 3122 operand indOffset8Narrow(rRegN reg, immL8 off) 3123 %{ 3124 predicate(CompressedOops::shift() == 0); 3125 constraint(ALLOC_IN_RC(ptr_reg)); 3126 match(AddP (DecodeN reg) off); 3127 3128 format %{ "[$reg + $off (8-bit)]" %} 3129 interface(MEMORY_INTER) %{ 3130 base($reg); 3131 index(0x4); 3132 scale(0x0); 3133 disp($off); 3134 %} 3135 %} 3136 3137 // Indirect Memory Plus Long Offset Operand 3138 operand indOffset32Narrow(rRegN reg, immL32 off) 3139 %{ 3140 predicate(CompressedOops::shift() == 0); 3141 constraint(ALLOC_IN_RC(ptr_reg)); 3142 match(AddP (DecodeN reg) off); 3143 3144 format %{ "[$reg + $off (32-bit)]" %} 3145 interface(MEMORY_INTER) %{ 3146 base($reg); 3147 index(0x4); 3148 scale(0x0); 3149 disp($off); 3150 %} 3151 %} 3152 3153 // Indirect Memory Plus Index Register Plus Offset Operand 3154 operand indIndexOffsetNarrow(rRegN reg, rRegL lreg, immL32 off) 3155 %{ 3156 predicate(CompressedOops::shift() == 0); 3157 constraint(ALLOC_IN_RC(ptr_reg)); 3158 match(AddP (AddP (DecodeN reg) lreg) off); 3159 3160 op_cost(10); 3161 format %{"[$reg + $off + $lreg]" %} 3162 interface(MEMORY_INTER) %{ 3163 base($reg); 3164 index($lreg); 3165 scale(0x0); 3166 disp($off); 3167 %} 3168 %} 3169 3170 // Indirect Memory Plus Index Register Plus Offset Operand 3171 operand indIndexNarrow(rRegN reg, rRegL lreg) 3172 %{ 3173 predicate(CompressedOops::shift() == 0); 3174 constraint(ALLOC_IN_RC(ptr_reg)); 3175 match(AddP (DecodeN reg) lreg); 3176 3177 op_cost(10); 3178 format %{"[$reg + $lreg]" %} 3179 interface(MEMORY_INTER) %{ 3180 base($reg); 3181 index($lreg); 3182 scale(0x0); 3183 disp(0x0); 3184 %} 3185 %} 3186 3187 // Indirect Memory Times Scale Plus Index Register 3188 operand indIndexScaleNarrow(rRegN reg, rRegL lreg, immI2 scale) 3189 %{ 3190 predicate(CompressedOops::shift() == 0); 3191 constraint(ALLOC_IN_RC(ptr_reg)); 3192 match(AddP (DecodeN reg) (LShiftL lreg scale)); 3193 3194 op_cost(10); 3195 format %{"[$reg + $lreg << $scale]" %} 3196 interface(MEMORY_INTER) %{ 3197 base($reg); 3198 index($lreg); 3199 scale($scale); 3200 disp(0x0); 3201 %} 3202 %} 3203 3204 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 3205 operand indIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegL lreg, immI2 scale) 3206 %{ 3207 predicate(CompressedOops::shift() == 0); 3208 constraint(ALLOC_IN_RC(ptr_reg)); 3209 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off); 3210 3211 op_cost(10); 3212 format %{"[$reg + $off + $lreg << $scale]" %} 3213 interface(MEMORY_INTER) %{ 3214 base($reg); 3215 index($lreg); 3216 scale($scale); 3217 disp($off); 3218 %} 3219 %} 3220 3221 // Indirect Memory Times Plus Positive Index Register Plus Offset Operand 3222 operand indPosIndexOffsetNarrow(rRegN reg, immL32 off, rRegI idx) 3223 %{ 3224 constraint(ALLOC_IN_RC(ptr_reg)); 3225 predicate(CompressedOops::shift() == 0 && n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 3226 match(AddP (AddP (DecodeN reg) (ConvI2L idx)) off); 3227 3228 op_cost(10); 3229 format %{"[$reg + $off + $idx]" %} 3230 interface(MEMORY_INTER) %{ 3231 base($reg); 3232 index($idx); 3233 scale(0x0); 3234 disp($off); 3235 %} 3236 %} 3237 3238 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 3239 operand indPosIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegI idx, immI2 scale) 3240 %{ 3241 constraint(ALLOC_IN_RC(ptr_reg)); 3242 predicate(CompressedOops::shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3243 match(AddP (AddP (DecodeN reg) (LShiftL (ConvI2L idx) scale)) off); 3244 3245 op_cost(10); 3246 format %{"[$reg + $off + $idx << $scale]" %} 3247 interface(MEMORY_INTER) %{ 3248 base($reg); 3249 index($idx); 3250 scale($scale); 3251 disp($off); 3252 %} 3253 %} 3254 3255 //----------Special Memory Operands-------------------------------------------- 3256 // Stack Slot Operand - This operand is used for loading and storing temporary 3257 // values on the stack where a match requires a value to 3258 // flow through memory. 3259 operand stackSlotP(sRegP reg) 3260 %{ 3261 constraint(ALLOC_IN_RC(stack_slots)); 3262 // No match rule because this operand is only generated in matching 3263 3264 format %{ "[$reg]" %} 3265 interface(MEMORY_INTER) %{ 3266 base(0x4); // RSP 3267 index(0x4); // No Index 3268 scale(0x0); // No Scale 3269 disp($reg); // Stack Offset 3270 %} 3271 %} 3272 3273 operand stackSlotI(sRegI reg) 3274 %{ 3275 constraint(ALLOC_IN_RC(stack_slots)); 3276 // No match rule because this operand is only generated in matching 3277 3278 format %{ "[$reg]" %} 3279 interface(MEMORY_INTER) %{ 3280 base(0x4); // RSP 3281 index(0x4); // No Index 3282 scale(0x0); // No Scale 3283 disp($reg); // Stack Offset 3284 %} 3285 %} 3286 3287 operand stackSlotF(sRegF reg) 3288 %{ 3289 constraint(ALLOC_IN_RC(stack_slots)); 3290 // No match rule because this operand is only generated in matching 3291 3292 format %{ "[$reg]" %} 3293 interface(MEMORY_INTER) %{ 3294 base(0x4); // RSP 3295 index(0x4); // No Index 3296 scale(0x0); // No Scale 3297 disp($reg); // Stack Offset 3298 %} 3299 %} 3300 3301 operand stackSlotD(sRegD reg) 3302 %{ 3303 constraint(ALLOC_IN_RC(stack_slots)); 3304 // No match rule because this operand is only generated in matching 3305 3306 format %{ "[$reg]" %} 3307 interface(MEMORY_INTER) %{ 3308 base(0x4); // RSP 3309 index(0x4); // No Index 3310 scale(0x0); // No Scale 3311 disp($reg); // Stack Offset 3312 %} 3313 %} 3314 operand stackSlotL(sRegL reg) 3315 %{ 3316 constraint(ALLOC_IN_RC(stack_slots)); 3317 // No match rule because this operand is only generated in matching 3318 3319 format %{ "[$reg]" %} 3320 interface(MEMORY_INTER) %{ 3321 base(0x4); // RSP 3322 index(0x4); // No Index 3323 scale(0x0); // No Scale 3324 disp($reg); // Stack Offset 3325 %} 3326 %} 3327 3328 //----------Conditional Branch Operands---------------------------------------- 3329 // Comparison Op - This is the operation of the comparison, and is limited to 3330 // the following set of codes: 3331 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 3332 // 3333 // Other attributes of the comparison, such as unsignedness, are specified 3334 // by the comparison instruction that sets a condition code flags register. 3335 // That result is represented by a flags operand whose subtype is appropriate 3336 // to the unsignedness (etc.) of the comparison. 3337 // 3338 // Later, the instruction which matches both the Comparison Op (a Bool) and 3339 // the flags (produced by the Cmp) specifies the coding of the comparison op 3340 // by matching a specific subtype of Bool operand below, such as cmpOpU. 3341 3342 // Comparison Code 3343 operand cmpOp() 3344 %{ 3345 match(Bool); 3346 3347 format %{ "" %} 3348 interface(COND_INTER) %{ 3349 equal(0x4, "e"); 3350 not_equal(0x5, "ne"); 3351 less(0xC, "l"); 3352 greater_equal(0xD, "ge"); 3353 less_equal(0xE, "le"); 3354 greater(0xF, "g"); 3355 overflow(0x0, "o"); 3356 no_overflow(0x1, "no"); 3357 %} 3358 %} 3359 3360 // Comparison Code, unsigned compare. Used by FP also, with 3361 // C2 (unordered) turned into GT or LT already. The other bits 3362 // C0 and C3 are turned into Carry & Zero flags. 3363 operand cmpOpU() 3364 %{ 3365 match(Bool); 3366 3367 format %{ "" %} 3368 interface(COND_INTER) %{ 3369 equal(0x4, "e"); 3370 not_equal(0x5, "ne"); 3371 less(0x2, "b"); 3372 greater_equal(0x3, "ae"); 3373 less_equal(0x6, "be"); 3374 greater(0x7, "a"); 3375 overflow(0x0, "o"); 3376 no_overflow(0x1, "no"); 3377 %} 3378 %} 3379 3380 3381 // Floating comparisons that don't require any fixup for the unordered case, 3382 // If both inputs of the comparison are the same, ZF is always set so we 3383 // don't need to use cmpOpUCF2 for eq/ne 3384 operand cmpOpUCF() %{ 3385 match(Bool); 3386 predicate(n->as_Bool()->_test._test == BoolTest::lt || 3387 n->as_Bool()->_test._test == BoolTest::ge || 3388 n->as_Bool()->_test._test == BoolTest::le || 3389 n->as_Bool()->_test._test == BoolTest::gt || 3390 n->in(1)->in(1) == n->in(1)->in(2)); 3391 format %{ "" %} 3392 interface(COND_INTER) %{ 3393 equal(0xb, "np"); 3394 not_equal(0xa, "p"); 3395 less(0x2, "b"); 3396 greater_equal(0x3, "ae"); 3397 less_equal(0x6, "be"); 3398 greater(0x7, "a"); 3399 overflow(0x0, "o"); 3400 no_overflow(0x1, "no"); 3401 %} 3402 %} 3403 3404 3405 // Floating comparisons that can be fixed up with extra conditional jumps 3406 operand cmpOpUCF2() %{ 3407 match(Bool); 3408 predicate((n->as_Bool()->_test._test == BoolTest::ne || 3409 n->as_Bool()->_test._test == BoolTest::eq) && 3410 n->in(1)->in(1) != n->in(1)->in(2)); 3411 format %{ "" %} 3412 interface(COND_INTER) %{ 3413 equal(0x4, "e"); 3414 not_equal(0x5, "ne"); 3415 less(0x2, "b"); 3416 greater_equal(0x3, "ae"); 3417 less_equal(0x6, "be"); 3418 greater(0x7, "a"); 3419 overflow(0x0, "o"); 3420 no_overflow(0x1, "no"); 3421 %} 3422 %} 3423 3424 //----------OPERAND CLASSES---------------------------------------------------- 3425 // Operand Classes are groups of operands that are used as to simplify 3426 // instruction definitions by not requiring the AD writer to specify separate 3427 // instructions for every form of operand when the instruction accepts 3428 // multiple operand types with the same basic encoding and format. The classic 3429 // case of this is memory operands. 3430 3431 opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex, 3432 indIndexScale, indPosIndexScale, indIndexScaleOffset, indPosIndexOffset, indPosIndexScaleOffset, 3433 indCompressedOop, indCompressedOopOffset, 3434 indirectNarrow, indOffset8Narrow, indOffset32Narrow, 3435 indIndexOffsetNarrow, indIndexNarrow, indIndexScaleNarrow, 3436 indIndexScaleOffsetNarrow, indPosIndexOffsetNarrow, indPosIndexScaleOffsetNarrow); 3437 3438 //----------PIPELINE----------------------------------------------------------- 3439 // Rules which define the behavior of the target architectures pipeline. 3440 pipeline %{ 3441 3442 //----------ATTRIBUTES--------------------------------------------------------- 3443 attributes %{ 3444 variable_size_instructions; // Fixed size instructions 3445 max_instructions_per_bundle = 3; // Up to 3 instructions per bundle 3446 instruction_unit_size = 1; // An instruction is 1 bytes long 3447 instruction_fetch_unit_size = 16; // The processor fetches one line 3448 instruction_fetch_units = 1; // of 16 bytes 3449 3450 // List of nop instructions 3451 nops( MachNop ); 3452 %} 3453 3454 //----------RESOURCES---------------------------------------------------------- 3455 // Resources are the functional units available to the machine 3456 3457 // Generic P2/P3 pipeline 3458 // 3 decoders, only D0 handles big operands; a "bundle" is the limit of 3459 // 3 instructions decoded per cycle. 3460 // 2 load/store ops per cycle, 1 branch, 1 FPU, 3461 // 3 ALU op, only ALU0 handles mul instructions. 3462 resources( D0, D1, D2, DECODE = D0 | D1 | D2, 3463 MS0, MS1, MS2, MEM = MS0 | MS1 | MS2, 3464 BR, FPU, 3465 ALU0, ALU1, ALU2, ALU = ALU0 | ALU1 | ALU2); 3466 3467 //----------PIPELINE DESCRIPTION----------------------------------------------- 3468 // Pipeline Description specifies the stages in the machine's pipeline 3469 3470 // Generic P2/P3 pipeline 3471 pipe_desc(S0, S1, S2, S3, S4, S5); 3472 3473 //----------PIPELINE CLASSES--------------------------------------------------- 3474 // Pipeline Classes describe the stages in which input and output are 3475 // referenced by the hardware pipeline. 3476 3477 // Naming convention: ialu or fpu 3478 // Then: _reg 3479 // Then: _reg if there is a 2nd register 3480 // Then: _long if it's a pair of instructions implementing a long 3481 // Then: _fat if it requires the big decoder 3482 // Or: _mem if it requires the big decoder and a memory unit. 3483 3484 // Integer ALU reg operation 3485 pipe_class ialu_reg(rRegI dst) 3486 %{ 3487 single_instruction; 3488 dst : S4(write); 3489 dst : S3(read); 3490 DECODE : S0; // any decoder 3491 ALU : S3; // any alu 3492 %} 3493 3494 // Long ALU reg operation 3495 pipe_class ialu_reg_long(rRegL dst) 3496 %{ 3497 instruction_count(2); 3498 dst : S4(write); 3499 dst : S3(read); 3500 DECODE : S0(2); // any 2 decoders 3501 ALU : S3(2); // both alus 3502 %} 3503 3504 // Integer ALU reg operation using big decoder 3505 pipe_class ialu_reg_fat(rRegI dst) 3506 %{ 3507 single_instruction; 3508 dst : S4(write); 3509 dst : S3(read); 3510 D0 : S0; // big decoder only 3511 ALU : S3; // any alu 3512 %} 3513 3514 // Integer ALU reg-reg operation 3515 pipe_class ialu_reg_reg(rRegI dst, rRegI src) 3516 %{ 3517 single_instruction; 3518 dst : S4(write); 3519 src : S3(read); 3520 DECODE : S0; // any decoder 3521 ALU : S3; // any alu 3522 %} 3523 3524 // Integer ALU reg-reg operation 3525 pipe_class ialu_reg_reg_fat(rRegI dst, memory src) 3526 %{ 3527 single_instruction; 3528 dst : S4(write); 3529 src : S3(read); 3530 D0 : S0; // big decoder only 3531 ALU : S3; // any alu 3532 %} 3533 3534 // Integer ALU reg-mem operation 3535 pipe_class ialu_reg_mem(rRegI dst, memory mem) 3536 %{ 3537 single_instruction; 3538 dst : S5(write); 3539 mem : S3(read); 3540 D0 : S0; // big decoder only 3541 ALU : S4; // any alu 3542 MEM : S3; // any mem 3543 %} 3544 3545 // Integer mem operation (prefetch) 3546 pipe_class ialu_mem(memory mem) 3547 %{ 3548 single_instruction; 3549 mem : S3(read); 3550 D0 : S0; // big decoder only 3551 MEM : S3; // any mem 3552 %} 3553 3554 // Integer Store to Memory 3555 pipe_class ialu_mem_reg(memory mem, rRegI src) 3556 %{ 3557 single_instruction; 3558 mem : S3(read); 3559 src : S5(read); 3560 D0 : S0; // big decoder only 3561 ALU : S4; // any alu 3562 MEM : S3; 3563 %} 3564 3565 // // Long Store to Memory 3566 // pipe_class ialu_mem_long_reg(memory mem, rRegL src) 3567 // %{ 3568 // instruction_count(2); 3569 // mem : S3(read); 3570 // src : S5(read); 3571 // D0 : S0(2); // big decoder only; twice 3572 // ALU : S4(2); // any 2 alus 3573 // MEM : S3(2); // Both mems 3574 // %} 3575 3576 // Integer Store to Memory 3577 pipe_class ialu_mem_imm(memory mem) 3578 %{ 3579 single_instruction; 3580 mem : S3(read); 3581 D0 : S0; // big decoder only 3582 ALU : S4; // any alu 3583 MEM : S3; 3584 %} 3585 3586 // Integer ALU0 reg-reg operation 3587 pipe_class ialu_reg_reg_alu0(rRegI dst, rRegI src) 3588 %{ 3589 single_instruction; 3590 dst : S4(write); 3591 src : S3(read); 3592 D0 : S0; // Big decoder only 3593 ALU0 : S3; // only alu0 3594 %} 3595 3596 // Integer ALU0 reg-mem operation 3597 pipe_class ialu_reg_mem_alu0(rRegI dst, memory mem) 3598 %{ 3599 single_instruction; 3600 dst : S5(write); 3601 mem : S3(read); 3602 D0 : S0; // big decoder only 3603 ALU0 : S4; // ALU0 only 3604 MEM : S3; // any mem 3605 %} 3606 3607 // Integer ALU reg-reg operation 3608 pipe_class ialu_cr_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2) 3609 %{ 3610 single_instruction; 3611 cr : S4(write); 3612 src1 : S3(read); 3613 src2 : S3(read); 3614 DECODE : S0; // any decoder 3615 ALU : S3; // any alu 3616 %} 3617 3618 // Integer ALU reg-imm operation 3619 pipe_class ialu_cr_reg_imm(rFlagsReg cr, rRegI src1) 3620 %{ 3621 single_instruction; 3622 cr : S4(write); 3623 src1 : S3(read); 3624 DECODE : S0; // any decoder 3625 ALU : S3; // any alu 3626 %} 3627 3628 // Integer ALU reg-mem operation 3629 pipe_class ialu_cr_reg_mem(rFlagsReg cr, rRegI src1, memory src2) 3630 %{ 3631 single_instruction; 3632 cr : S4(write); 3633 src1 : S3(read); 3634 src2 : S3(read); 3635 D0 : S0; // big decoder only 3636 ALU : S4; // any alu 3637 MEM : S3; 3638 %} 3639 3640 // Conditional move reg-reg 3641 pipe_class pipe_cmplt( rRegI p, rRegI q, rRegI y) 3642 %{ 3643 instruction_count(4); 3644 y : S4(read); 3645 q : S3(read); 3646 p : S3(read); 3647 DECODE : S0(4); // any decoder 3648 %} 3649 3650 // Conditional move reg-reg 3651 pipe_class pipe_cmov_reg( rRegI dst, rRegI src, rFlagsReg cr) 3652 %{ 3653 single_instruction; 3654 dst : S4(write); 3655 src : S3(read); 3656 cr : S3(read); 3657 DECODE : S0; // any decoder 3658 %} 3659 3660 // Conditional move reg-mem 3661 pipe_class pipe_cmov_mem( rFlagsReg cr, rRegI dst, memory src) 3662 %{ 3663 single_instruction; 3664 dst : S4(write); 3665 src : S3(read); 3666 cr : S3(read); 3667 DECODE : S0; // any decoder 3668 MEM : S3; 3669 %} 3670 3671 // Conditional move reg-reg long 3672 pipe_class pipe_cmov_reg_long( rFlagsReg cr, rRegL dst, rRegL src) 3673 %{ 3674 single_instruction; 3675 dst : S4(write); 3676 src : S3(read); 3677 cr : S3(read); 3678 DECODE : S0(2); // any 2 decoders 3679 %} 3680 3681 // Float reg-reg operation 3682 pipe_class fpu_reg(regD dst) 3683 %{ 3684 instruction_count(2); 3685 dst : S3(read); 3686 DECODE : S0(2); // any 2 decoders 3687 FPU : S3; 3688 %} 3689 3690 // Float reg-reg operation 3691 pipe_class fpu_reg_reg(regD dst, regD src) 3692 %{ 3693 instruction_count(2); 3694 dst : S4(write); 3695 src : S3(read); 3696 DECODE : S0(2); // any 2 decoders 3697 FPU : S3; 3698 %} 3699 3700 // Float reg-reg operation 3701 pipe_class fpu_reg_reg_reg(regD dst, regD src1, regD src2) 3702 %{ 3703 instruction_count(3); 3704 dst : S4(write); 3705 src1 : S3(read); 3706 src2 : S3(read); 3707 DECODE : S0(3); // any 3 decoders 3708 FPU : S3(2); 3709 %} 3710 3711 // Float reg-reg operation 3712 pipe_class fpu_reg_reg_reg_reg(regD dst, regD src1, regD src2, regD src3) 3713 %{ 3714 instruction_count(4); 3715 dst : S4(write); 3716 src1 : S3(read); 3717 src2 : S3(read); 3718 src3 : S3(read); 3719 DECODE : S0(4); // any 3 decoders 3720 FPU : S3(2); 3721 %} 3722 3723 // Float reg-reg operation 3724 pipe_class fpu_reg_mem_reg_reg(regD dst, memory src1, regD src2, regD src3) 3725 %{ 3726 instruction_count(4); 3727 dst : S4(write); 3728 src1 : S3(read); 3729 src2 : S3(read); 3730 src3 : S3(read); 3731 DECODE : S1(3); // any 3 decoders 3732 D0 : S0; // Big decoder only 3733 FPU : S3(2); 3734 MEM : S3; 3735 %} 3736 3737 // Float reg-mem operation 3738 pipe_class fpu_reg_mem(regD dst, memory mem) 3739 %{ 3740 instruction_count(2); 3741 dst : S5(write); 3742 mem : S3(read); 3743 D0 : S0; // big decoder only 3744 DECODE : S1; // any decoder for FPU POP 3745 FPU : S4; 3746 MEM : S3; // any mem 3747 %} 3748 3749 // Float reg-mem operation 3750 pipe_class fpu_reg_reg_mem(regD dst, regD src1, memory mem) 3751 %{ 3752 instruction_count(3); 3753 dst : S5(write); 3754 src1 : S3(read); 3755 mem : S3(read); 3756 D0 : S0; // big decoder only 3757 DECODE : S1(2); // any decoder for FPU POP 3758 FPU : S4; 3759 MEM : S3; // any mem 3760 %} 3761 3762 // Float mem-reg operation 3763 pipe_class fpu_mem_reg(memory mem, regD src) 3764 %{ 3765 instruction_count(2); 3766 src : S5(read); 3767 mem : S3(read); 3768 DECODE : S0; // any decoder for FPU PUSH 3769 D0 : S1; // big decoder only 3770 FPU : S4; 3771 MEM : S3; // any mem 3772 %} 3773 3774 pipe_class fpu_mem_reg_reg(memory mem, regD src1, regD src2) 3775 %{ 3776 instruction_count(3); 3777 src1 : S3(read); 3778 src2 : S3(read); 3779 mem : S3(read); 3780 DECODE : S0(2); // any decoder for FPU PUSH 3781 D0 : S1; // big decoder only 3782 FPU : S4; 3783 MEM : S3; // any mem 3784 %} 3785 3786 pipe_class fpu_mem_reg_mem(memory mem, regD src1, memory src2) 3787 %{ 3788 instruction_count(3); 3789 src1 : S3(read); 3790 src2 : S3(read); 3791 mem : S4(read); 3792 DECODE : S0; // any decoder for FPU PUSH 3793 D0 : S0(2); // big decoder only 3794 FPU : S4; 3795 MEM : S3(2); // any mem 3796 %} 3797 3798 pipe_class fpu_mem_mem(memory dst, memory src1) 3799 %{ 3800 instruction_count(2); 3801 src1 : S3(read); 3802 dst : S4(read); 3803 D0 : S0(2); // big decoder only 3804 MEM : S3(2); // any mem 3805 %} 3806 3807 pipe_class fpu_mem_mem_mem(memory dst, memory src1, memory src2) 3808 %{ 3809 instruction_count(3); 3810 src1 : S3(read); 3811 src2 : S3(read); 3812 dst : S4(read); 3813 D0 : S0(3); // big decoder only 3814 FPU : S4; 3815 MEM : S3(3); // any mem 3816 %} 3817 3818 pipe_class fpu_mem_reg_con(memory mem, regD src1) 3819 %{ 3820 instruction_count(3); 3821 src1 : S4(read); 3822 mem : S4(read); 3823 DECODE : S0; // any decoder for FPU PUSH 3824 D0 : S0(2); // big decoder only 3825 FPU : S4; 3826 MEM : S3(2); // any mem 3827 %} 3828 3829 // Float load constant 3830 pipe_class fpu_reg_con(regD dst) 3831 %{ 3832 instruction_count(2); 3833 dst : S5(write); 3834 D0 : S0; // big decoder only for the load 3835 DECODE : S1; // any decoder for FPU POP 3836 FPU : S4; 3837 MEM : S3; // any mem 3838 %} 3839 3840 // Float load constant 3841 pipe_class fpu_reg_reg_con(regD dst, regD src) 3842 %{ 3843 instruction_count(3); 3844 dst : S5(write); 3845 src : S3(read); 3846 D0 : S0; // big decoder only for the load 3847 DECODE : S1(2); // any decoder for FPU POP 3848 FPU : S4; 3849 MEM : S3; // any mem 3850 %} 3851 3852 // UnConditional branch 3853 pipe_class pipe_jmp(label labl) 3854 %{ 3855 single_instruction; 3856 BR : S3; 3857 %} 3858 3859 // Conditional branch 3860 pipe_class pipe_jcc(cmpOp cmp, rFlagsReg cr, label labl) 3861 %{ 3862 single_instruction; 3863 cr : S1(read); 3864 BR : S3; 3865 %} 3866 3867 // Allocation idiom 3868 pipe_class pipe_cmpxchg(rRegP dst, rRegP heap_ptr) 3869 %{ 3870 instruction_count(1); force_serialization; 3871 fixed_latency(6); 3872 heap_ptr : S3(read); 3873 DECODE : S0(3); 3874 D0 : S2; 3875 MEM : S3; 3876 ALU : S3(2); 3877 dst : S5(write); 3878 BR : S5; 3879 %} 3880 3881 // Generic big/slow expanded idiom 3882 pipe_class pipe_slow() 3883 %{ 3884 instruction_count(10); multiple_bundles; force_serialization; 3885 fixed_latency(100); 3886 D0 : S0(2); 3887 MEM : S3(2); 3888 %} 3889 3890 // The real do-nothing guy 3891 pipe_class empty() 3892 %{ 3893 instruction_count(0); 3894 %} 3895 3896 // Define the class for the Nop node 3897 define 3898 %{ 3899 MachNop = empty; 3900 %} 3901 3902 %} 3903 3904 //----------INSTRUCTIONS------------------------------------------------------- 3905 // 3906 // match -- States which machine-independent subtree may be replaced 3907 // by this instruction. 3908 // ins_cost -- The estimated cost of this instruction is used by instruction 3909 // selection to identify a minimum cost tree of machine 3910 // instructions that matches a tree of machine-independent 3911 // instructions. 3912 // format -- A string providing the disassembly for this instruction. 3913 // The value of an instruction's operand may be inserted 3914 // by referring to it with a '$' prefix. 3915 // opcode -- Three instruction opcodes may be provided. These are referred 3916 // to within an encode class as $primary, $secondary, and $tertiary 3917 // rrspectively. The primary opcode is commonly used to 3918 // indicate the type of machine instruction, while secondary 3919 // and tertiary are often used for prefix options or addressing 3920 // modes. 3921 // ins_encode -- A list of encode classes with parameters. The encode class 3922 // name must have been defined in an 'enc_class' specification 3923 // in the encode section of the architecture description. 3924 3925 // Dummy reg-to-reg vector moves. Removed during post-selection cleanup. 3926 // Load Float 3927 instruct MoveF2VL(vlRegF dst, regF src) %{ 3928 match(Set dst src); 3929 format %{ "movss $dst,$src\t! load float (4 bytes)" %} 3930 ins_encode %{ 3931 ShouldNotReachHere(); 3932 %} 3933 ins_pipe( fpu_reg_reg ); 3934 %} 3935 3936 // Load Float 3937 instruct MoveF2LEG(legRegF dst, regF src) %{ 3938 match(Set dst src); 3939 format %{ "movss $dst,$src\t# if src != dst load float (4 bytes)" %} 3940 ins_encode %{ 3941 ShouldNotReachHere(); 3942 %} 3943 ins_pipe( fpu_reg_reg ); 3944 %} 3945 3946 // Load Float 3947 instruct MoveVL2F(regF dst, vlRegF src) %{ 3948 match(Set dst src); 3949 format %{ "movss $dst,$src\t! load float (4 bytes)" %} 3950 ins_encode %{ 3951 ShouldNotReachHere(); 3952 %} 3953 ins_pipe( fpu_reg_reg ); 3954 %} 3955 3956 // Load Float 3957 instruct MoveLEG2F(regF dst, legRegF src) %{ 3958 match(Set dst src); 3959 format %{ "movss $dst,$src\t# if src != dst load float (4 bytes)" %} 3960 ins_encode %{ 3961 ShouldNotReachHere(); 3962 %} 3963 ins_pipe( fpu_reg_reg ); 3964 %} 3965 3966 // Load Double 3967 instruct MoveD2VL(vlRegD dst, regD src) %{ 3968 match(Set dst src); 3969 format %{ "movsd $dst,$src\t! load double (8 bytes)" %} 3970 ins_encode %{ 3971 ShouldNotReachHere(); 3972 %} 3973 ins_pipe( fpu_reg_reg ); 3974 %} 3975 3976 // Load Double 3977 instruct MoveD2LEG(legRegD dst, regD src) %{ 3978 match(Set dst src); 3979 format %{ "movsd $dst,$src\t# if src != dst load double (8 bytes)" %} 3980 ins_encode %{ 3981 ShouldNotReachHere(); 3982 %} 3983 ins_pipe( fpu_reg_reg ); 3984 %} 3985 3986 // Load Double 3987 instruct MoveVL2D(regD dst, vlRegD src) %{ 3988 match(Set dst src); 3989 format %{ "movsd $dst,$src\t! load double (8 bytes)" %} 3990 ins_encode %{ 3991 ShouldNotReachHere(); 3992 %} 3993 ins_pipe( fpu_reg_reg ); 3994 %} 3995 3996 // Load Double 3997 instruct MoveLEG2D(regD dst, legRegD src) %{ 3998 match(Set dst src); 3999 format %{ "movsd $dst,$src\t# if src != dst load double (8 bytes)" %} 4000 ins_encode %{ 4001 ShouldNotReachHere(); 4002 %} 4003 ins_pipe( fpu_reg_reg ); 4004 %} 4005 4006 //----------Load/Store/Move Instructions--------------------------------------- 4007 //----------Load Instructions-------------------------------------------------- 4008 4009 // Load Byte (8 bit signed) 4010 instruct loadB(rRegI dst, memory mem) 4011 %{ 4012 match(Set dst (LoadB mem)); 4013 4014 ins_cost(125); 4015 format %{ "movsbl $dst, $mem\t# byte" %} 4016 4017 ins_encode %{ 4018 __ movsbl($dst$$Register, $mem$$Address); 4019 %} 4020 4021 ins_pipe(ialu_reg_mem); 4022 %} 4023 4024 // Load Byte (8 bit signed) into Long Register 4025 instruct loadB2L(rRegL dst, memory mem) 4026 %{ 4027 match(Set dst (ConvI2L (LoadB mem))); 4028 4029 ins_cost(125); 4030 format %{ "movsbq $dst, $mem\t# byte -> long" %} 4031 4032 ins_encode %{ 4033 __ movsbq($dst$$Register, $mem$$Address); 4034 %} 4035 4036 ins_pipe(ialu_reg_mem); 4037 %} 4038 4039 // Load Unsigned Byte (8 bit UNsigned) 4040 instruct loadUB(rRegI dst, memory mem) 4041 %{ 4042 match(Set dst (LoadUB mem)); 4043 4044 ins_cost(125); 4045 format %{ "movzbl $dst, $mem\t# ubyte" %} 4046 4047 ins_encode %{ 4048 __ movzbl($dst$$Register, $mem$$Address); 4049 %} 4050 4051 ins_pipe(ialu_reg_mem); 4052 %} 4053 4054 // Load Unsigned Byte (8 bit UNsigned) into Long Register 4055 instruct loadUB2L(rRegL dst, memory mem) 4056 %{ 4057 match(Set dst (ConvI2L (LoadUB mem))); 4058 4059 ins_cost(125); 4060 format %{ "movzbq $dst, $mem\t# ubyte -> long" %} 4061 4062 ins_encode %{ 4063 __ movzbq($dst$$Register, $mem$$Address); 4064 %} 4065 4066 ins_pipe(ialu_reg_mem); 4067 %} 4068 4069 // Load Unsigned Byte (8 bit UNsigned) with 32-bit mask into Long Register 4070 instruct loadUB2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 4071 match(Set dst (ConvI2L (AndI (LoadUB mem) mask))); 4072 effect(KILL cr); 4073 4074 format %{ "movzbq $dst, $mem\t# ubyte & 32-bit mask -> long\n\t" 4075 "andl $dst, right_n_bits($mask, 8)" %} 4076 ins_encode %{ 4077 Register Rdst = $dst$$Register; 4078 __ movzbq(Rdst, $mem$$Address); 4079 __ andl(Rdst, $mask$$constant & right_n_bits(8)); 4080 %} 4081 ins_pipe(ialu_reg_mem); 4082 %} 4083 4084 // Load Short (16 bit signed) 4085 instruct loadS(rRegI dst, memory mem) 4086 %{ 4087 match(Set dst (LoadS mem)); 4088 4089 ins_cost(125); 4090 format %{ "movswl $dst, $mem\t# short" %} 4091 4092 ins_encode %{ 4093 __ movswl($dst$$Register, $mem$$Address); 4094 %} 4095 4096 ins_pipe(ialu_reg_mem); 4097 %} 4098 4099 // Load Short (16 bit signed) to Byte (8 bit signed) 4100 instruct loadS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4101 match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour)); 4102 4103 ins_cost(125); 4104 format %{ "movsbl $dst, $mem\t# short -> byte" %} 4105 ins_encode %{ 4106 __ movsbl($dst$$Register, $mem$$Address); 4107 %} 4108 ins_pipe(ialu_reg_mem); 4109 %} 4110 4111 // Load Short (16 bit signed) into Long Register 4112 instruct loadS2L(rRegL dst, memory mem) 4113 %{ 4114 match(Set dst (ConvI2L (LoadS mem))); 4115 4116 ins_cost(125); 4117 format %{ "movswq $dst, $mem\t# short -> long" %} 4118 4119 ins_encode %{ 4120 __ movswq($dst$$Register, $mem$$Address); 4121 %} 4122 4123 ins_pipe(ialu_reg_mem); 4124 %} 4125 4126 // Load Unsigned Short/Char (16 bit UNsigned) 4127 instruct loadUS(rRegI dst, memory mem) 4128 %{ 4129 match(Set dst (LoadUS mem)); 4130 4131 ins_cost(125); 4132 format %{ "movzwl $dst, $mem\t# ushort/char" %} 4133 4134 ins_encode %{ 4135 __ movzwl($dst$$Register, $mem$$Address); 4136 %} 4137 4138 ins_pipe(ialu_reg_mem); 4139 %} 4140 4141 // Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed) 4142 instruct loadUS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4143 match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour)); 4144 4145 ins_cost(125); 4146 format %{ "movsbl $dst, $mem\t# ushort -> byte" %} 4147 ins_encode %{ 4148 __ movsbl($dst$$Register, $mem$$Address); 4149 %} 4150 ins_pipe(ialu_reg_mem); 4151 %} 4152 4153 // Load Unsigned Short/Char (16 bit UNsigned) into Long Register 4154 instruct loadUS2L(rRegL dst, memory mem) 4155 %{ 4156 match(Set dst (ConvI2L (LoadUS mem))); 4157 4158 ins_cost(125); 4159 format %{ "movzwq $dst, $mem\t# ushort/char -> long" %} 4160 4161 ins_encode %{ 4162 __ movzwq($dst$$Register, $mem$$Address); 4163 %} 4164 4165 ins_pipe(ialu_reg_mem); 4166 %} 4167 4168 // Load Unsigned Short/Char (16 bit UNsigned) with mask 0xFF into Long Register 4169 instruct loadUS2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 4170 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 4171 4172 format %{ "movzbq $dst, $mem\t# ushort/char & 0xFF -> long" %} 4173 ins_encode %{ 4174 __ movzbq($dst$$Register, $mem$$Address); 4175 %} 4176 ins_pipe(ialu_reg_mem); 4177 %} 4178 4179 // Load Unsigned Short/Char (16 bit UNsigned) with 32-bit mask into Long Register 4180 instruct loadUS2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 4181 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 4182 effect(KILL cr); 4183 4184 format %{ "movzwq $dst, $mem\t# ushort/char & 32-bit mask -> long\n\t" 4185 "andl $dst, right_n_bits($mask, 16)" %} 4186 ins_encode %{ 4187 Register Rdst = $dst$$Register; 4188 __ movzwq(Rdst, $mem$$Address); 4189 __ andl(Rdst, $mask$$constant & right_n_bits(16)); 4190 %} 4191 ins_pipe(ialu_reg_mem); 4192 %} 4193 4194 // Load Integer 4195 instruct loadI(rRegI dst, memory mem) 4196 %{ 4197 match(Set dst (LoadI mem)); 4198 4199 ins_cost(125); 4200 format %{ "movl $dst, $mem\t# int" %} 4201 4202 ins_encode %{ 4203 __ movl($dst$$Register, $mem$$Address); 4204 %} 4205 4206 ins_pipe(ialu_reg_mem); 4207 %} 4208 4209 // Load Integer (32 bit signed) to Byte (8 bit signed) 4210 instruct loadI2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4211 match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour)); 4212 4213 ins_cost(125); 4214 format %{ "movsbl $dst, $mem\t# int -> byte" %} 4215 ins_encode %{ 4216 __ movsbl($dst$$Register, $mem$$Address); 4217 %} 4218 ins_pipe(ialu_reg_mem); 4219 %} 4220 4221 // Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned) 4222 instruct loadI2UB(rRegI dst, memory mem, immI_255 mask) %{ 4223 match(Set dst (AndI (LoadI mem) mask)); 4224 4225 ins_cost(125); 4226 format %{ "movzbl $dst, $mem\t# int -> ubyte" %} 4227 ins_encode %{ 4228 __ movzbl($dst$$Register, $mem$$Address); 4229 %} 4230 ins_pipe(ialu_reg_mem); 4231 %} 4232 4233 // Load Integer (32 bit signed) to Short (16 bit signed) 4234 instruct loadI2S(rRegI dst, memory mem, immI_16 sixteen) %{ 4235 match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen)); 4236 4237 ins_cost(125); 4238 format %{ "movswl $dst, $mem\t# int -> short" %} 4239 ins_encode %{ 4240 __ movswl($dst$$Register, $mem$$Address); 4241 %} 4242 ins_pipe(ialu_reg_mem); 4243 %} 4244 4245 // Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned) 4246 instruct loadI2US(rRegI dst, memory mem, immI_65535 mask) %{ 4247 match(Set dst (AndI (LoadI mem) mask)); 4248 4249 ins_cost(125); 4250 format %{ "movzwl $dst, $mem\t# int -> ushort/char" %} 4251 ins_encode %{ 4252 __ movzwl($dst$$Register, $mem$$Address); 4253 %} 4254 ins_pipe(ialu_reg_mem); 4255 %} 4256 4257 // Load Integer into Long Register 4258 instruct loadI2L(rRegL dst, memory mem) 4259 %{ 4260 match(Set dst (ConvI2L (LoadI mem))); 4261 4262 ins_cost(125); 4263 format %{ "movslq $dst, $mem\t# int -> long" %} 4264 4265 ins_encode %{ 4266 __ movslq($dst$$Register, $mem$$Address); 4267 %} 4268 4269 ins_pipe(ialu_reg_mem); 4270 %} 4271 4272 // Load Integer with mask 0xFF into Long Register 4273 instruct loadI2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 4274 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4275 4276 format %{ "movzbq $dst, $mem\t# int & 0xFF -> long" %} 4277 ins_encode %{ 4278 __ movzbq($dst$$Register, $mem$$Address); 4279 %} 4280 ins_pipe(ialu_reg_mem); 4281 %} 4282 4283 // Load Integer with mask 0xFFFF into Long Register 4284 instruct loadI2L_immI_65535(rRegL dst, memory mem, immI_65535 mask) %{ 4285 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4286 4287 format %{ "movzwq $dst, $mem\t# int & 0xFFFF -> long" %} 4288 ins_encode %{ 4289 __ movzwq($dst$$Register, $mem$$Address); 4290 %} 4291 ins_pipe(ialu_reg_mem); 4292 %} 4293 4294 // Load Integer with a 31-bit mask into Long Register 4295 instruct loadI2L_immU31(rRegL dst, memory mem, immU31 mask, rFlagsReg cr) %{ 4296 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4297 effect(KILL cr); 4298 4299 format %{ "movl $dst, $mem\t# int & 31-bit mask -> long\n\t" 4300 "andl $dst, $mask" %} 4301 ins_encode %{ 4302 Register Rdst = $dst$$Register; 4303 __ movl(Rdst, $mem$$Address); 4304 __ andl(Rdst, $mask$$constant); 4305 %} 4306 ins_pipe(ialu_reg_mem); 4307 %} 4308 4309 // Load Unsigned Integer into Long Register 4310 instruct loadUI2L(rRegL dst, memory mem, immL_32bits mask) 4311 %{ 4312 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 4313 4314 ins_cost(125); 4315 format %{ "movl $dst, $mem\t# uint -> long" %} 4316 4317 ins_encode %{ 4318 __ movl($dst$$Register, $mem$$Address); 4319 %} 4320 4321 ins_pipe(ialu_reg_mem); 4322 %} 4323 4324 // Load Long 4325 instruct loadL(rRegL dst, memory mem) 4326 %{ 4327 match(Set dst (LoadL mem)); 4328 4329 ins_cost(125); 4330 format %{ "movq $dst, $mem\t# long" %} 4331 4332 ins_encode %{ 4333 __ movq($dst$$Register, $mem$$Address); 4334 %} 4335 4336 ins_pipe(ialu_reg_mem); // XXX 4337 %} 4338 4339 // Load Range 4340 instruct loadRange(rRegI dst, memory mem) 4341 %{ 4342 match(Set dst (LoadRange mem)); 4343 4344 ins_cost(125); // XXX 4345 format %{ "movl $dst, $mem\t# range" %} 4346 ins_encode %{ 4347 __ movl($dst$$Register, $mem$$Address); 4348 %} 4349 ins_pipe(ialu_reg_mem); 4350 %} 4351 4352 // Load Pointer 4353 instruct loadP(rRegP dst, memory mem) 4354 %{ 4355 match(Set dst (LoadP mem)); 4356 predicate(n->as_Load()->barrier_data() == 0); 4357 4358 ins_cost(125); // XXX 4359 format %{ "movq $dst, $mem\t# ptr" %} 4360 ins_encode %{ 4361 __ movq($dst$$Register, $mem$$Address); 4362 %} 4363 ins_pipe(ialu_reg_mem); // XXX 4364 %} 4365 4366 // Load Compressed Pointer 4367 instruct loadN(rRegN dst, memory mem) 4368 %{ 4369 predicate(n->as_Load()->barrier_data() == 0); 4370 match(Set dst (LoadN mem)); 4371 4372 ins_cost(125); // XXX 4373 format %{ "movl $dst, $mem\t# compressed ptr" %} 4374 ins_encode %{ 4375 __ movl($dst$$Register, $mem$$Address); 4376 %} 4377 ins_pipe(ialu_reg_mem); // XXX 4378 %} 4379 4380 4381 // Load Klass Pointer 4382 instruct loadKlass(rRegP dst, memory mem) 4383 %{ 4384 match(Set dst (LoadKlass mem)); 4385 4386 ins_cost(125); // XXX 4387 format %{ "movq $dst, $mem\t# class" %} 4388 ins_encode %{ 4389 __ movq($dst$$Register, $mem$$Address); 4390 %} 4391 ins_pipe(ialu_reg_mem); // XXX 4392 %} 4393 4394 // Load narrow Klass Pointer 4395 instruct loadNKlass(rRegN dst, memory mem) 4396 %{ 4397 match(Set dst (LoadNKlass mem)); 4398 4399 ins_cost(125); // XXX 4400 format %{ "movl $dst, $mem\t# compressed klass ptr" %} 4401 ins_encode %{ 4402 __ movl($dst$$Register, $mem$$Address); 4403 %} 4404 ins_pipe(ialu_reg_mem); // XXX 4405 %} 4406 4407 // Load Float 4408 instruct loadF(regF dst, memory mem) 4409 %{ 4410 match(Set dst (LoadF mem)); 4411 4412 ins_cost(145); // XXX 4413 format %{ "movss $dst, $mem\t# float" %} 4414 ins_encode %{ 4415 __ movflt($dst$$XMMRegister, $mem$$Address); 4416 %} 4417 ins_pipe(pipe_slow); // XXX 4418 %} 4419 4420 // Load Double 4421 instruct loadD_partial(regD dst, memory mem) 4422 %{ 4423 predicate(!UseXmmLoadAndClearUpper); 4424 match(Set dst (LoadD mem)); 4425 4426 ins_cost(145); // XXX 4427 format %{ "movlpd $dst, $mem\t# double" %} 4428 ins_encode %{ 4429 __ movdbl($dst$$XMMRegister, $mem$$Address); 4430 %} 4431 ins_pipe(pipe_slow); // XXX 4432 %} 4433 4434 instruct loadD(regD dst, memory mem) 4435 %{ 4436 predicate(UseXmmLoadAndClearUpper); 4437 match(Set dst (LoadD mem)); 4438 4439 ins_cost(145); // XXX 4440 format %{ "movsd $dst, $mem\t# double" %} 4441 ins_encode %{ 4442 __ movdbl($dst$$XMMRegister, $mem$$Address); 4443 %} 4444 ins_pipe(pipe_slow); // XXX 4445 %} 4446 4447 // max = java.lang.Math.max(float a, float b) 4448 instruct maxF_reg(legRegF dst, legRegF a, legRegF b, legRegF tmp, legRegF atmp, legRegF btmp) %{ 4449 predicate(UseAVX > 0 && !VLoopReductions::is_reduction(n)); 4450 match(Set dst (MaxF a b)); 4451 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 4452 format %{ "maxF $dst, $a, $b \t! using tmp, atmp and btmp as TEMP" %} 4453 ins_encode %{ 4454 __ vminmax_fp(Op_MaxV, T_FLOAT, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, Assembler::AVX_128bit); 4455 %} 4456 ins_pipe( pipe_slow ); 4457 %} 4458 4459 instruct maxF_reduction_reg(legRegF dst, legRegF a, legRegF b, legRegF xmmt, rRegI tmp, rFlagsReg cr) %{ 4460 predicate(UseAVX > 0 && VLoopReductions::is_reduction(n)); 4461 match(Set dst (MaxF a b)); 4462 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr); 4463 4464 format %{ "$dst = max($a, $b)\t# intrinsic (float)" %} 4465 ins_encode %{ 4466 emit_fp_min_max(masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register, 4467 false /*min*/, true /*single*/); 4468 %} 4469 ins_pipe( pipe_slow ); 4470 %} 4471 4472 // max = java.lang.Math.max(double a, double b) 4473 instruct maxD_reg(legRegD dst, legRegD a, legRegD b, legRegD tmp, legRegD atmp, legRegD btmp) %{ 4474 predicate(UseAVX > 0 && !VLoopReductions::is_reduction(n)); 4475 match(Set dst (MaxD a b)); 4476 effect(USE a, USE b, TEMP atmp, TEMP btmp, TEMP tmp); 4477 format %{ "maxD $dst, $a, $b \t! using tmp, atmp and btmp as TEMP" %} 4478 ins_encode %{ 4479 __ vminmax_fp(Op_MaxV, T_DOUBLE, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, Assembler::AVX_128bit); 4480 %} 4481 ins_pipe( pipe_slow ); 4482 %} 4483 4484 instruct maxD_reduction_reg(legRegD dst, legRegD a, legRegD b, legRegD xmmt, rRegL tmp, rFlagsReg cr) %{ 4485 predicate(UseAVX > 0 && VLoopReductions::is_reduction(n)); 4486 match(Set dst (MaxD a b)); 4487 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr); 4488 4489 format %{ "$dst = max($a, $b)\t# intrinsic (double)" %} 4490 ins_encode %{ 4491 emit_fp_min_max(masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register, 4492 false /*min*/, false /*single*/); 4493 %} 4494 ins_pipe( pipe_slow ); 4495 %} 4496 4497 // min = java.lang.Math.min(float a, float b) 4498 instruct minF_reg(legRegF dst, legRegF a, legRegF b, legRegF tmp, legRegF atmp, legRegF btmp) %{ 4499 predicate(UseAVX > 0 && !VLoopReductions::is_reduction(n)); 4500 match(Set dst (MinF a b)); 4501 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 4502 format %{ "minF $dst, $a, $b \t! using tmp, atmp and btmp as TEMP" %} 4503 ins_encode %{ 4504 __ vminmax_fp(Op_MinV, T_FLOAT, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, Assembler::AVX_128bit); 4505 %} 4506 ins_pipe( pipe_slow ); 4507 %} 4508 4509 instruct minF_reduction_reg(legRegF dst, legRegF a, legRegF b, legRegF xmmt, rRegI tmp, rFlagsReg cr) %{ 4510 predicate(UseAVX > 0 && VLoopReductions::is_reduction(n)); 4511 match(Set dst (MinF a b)); 4512 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr); 4513 4514 format %{ "$dst = min($a, $b)\t# intrinsic (float)" %} 4515 ins_encode %{ 4516 emit_fp_min_max(masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register, 4517 true /*min*/, true /*single*/); 4518 %} 4519 ins_pipe( pipe_slow ); 4520 %} 4521 4522 // min = java.lang.Math.min(double a, double b) 4523 instruct minD_reg(legRegD dst, legRegD a, legRegD b, legRegD tmp, legRegD atmp, legRegD btmp) %{ 4524 predicate(UseAVX > 0 && !VLoopReductions::is_reduction(n)); 4525 match(Set dst (MinD a b)); 4526 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 4527 format %{ "minD $dst, $a, $b \t! using tmp, atmp and btmp as TEMP" %} 4528 ins_encode %{ 4529 __ vminmax_fp(Op_MinV, T_DOUBLE, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, Assembler::AVX_128bit); 4530 %} 4531 ins_pipe( pipe_slow ); 4532 %} 4533 4534 instruct minD_reduction_reg(legRegD dst, legRegD a, legRegD b, legRegD xmmt, rRegL tmp, rFlagsReg cr) %{ 4535 predicate(UseAVX > 0 && VLoopReductions::is_reduction(n)); 4536 match(Set dst (MinD a b)); 4537 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr); 4538 4539 format %{ "$dst = min($a, $b)\t# intrinsic (double)" %} 4540 ins_encode %{ 4541 emit_fp_min_max(masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register, 4542 true /*min*/, false /*single*/); 4543 %} 4544 ins_pipe( pipe_slow ); 4545 %} 4546 4547 // Load Effective Address 4548 instruct leaP8(rRegP dst, indOffset8 mem) 4549 %{ 4550 match(Set dst mem); 4551 4552 ins_cost(110); // XXX 4553 format %{ "leaq $dst, $mem\t# ptr 8" %} 4554 ins_encode %{ 4555 __ leaq($dst$$Register, $mem$$Address); 4556 %} 4557 ins_pipe(ialu_reg_reg_fat); 4558 %} 4559 4560 instruct leaP32(rRegP dst, indOffset32 mem) 4561 %{ 4562 match(Set dst mem); 4563 4564 ins_cost(110); 4565 format %{ "leaq $dst, $mem\t# ptr 32" %} 4566 ins_encode %{ 4567 __ leaq($dst$$Register, $mem$$Address); 4568 %} 4569 ins_pipe(ialu_reg_reg_fat); 4570 %} 4571 4572 instruct leaPIdxOff(rRegP dst, indIndexOffset mem) 4573 %{ 4574 match(Set dst mem); 4575 4576 ins_cost(110); 4577 format %{ "leaq $dst, $mem\t# ptr idxoff" %} 4578 ins_encode %{ 4579 __ leaq($dst$$Register, $mem$$Address); 4580 %} 4581 ins_pipe(ialu_reg_reg_fat); 4582 %} 4583 4584 instruct leaPIdxScale(rRegP dst, indIndexScale mem) 4585 %{ 4586 match(Set dst mem); 4587 4588 ins_cost(110); 4589 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 4590 ins_encode %{ 4591 __ leaq($dst$$Register, $mem$$Address); 4592 %} 4593 ins_pipe(ialu_reg_reg_fat); 4594 %} 4595 4596 instruct leaPPosIdxScale(rRegP dst, indPosIndexScale mem) 4597 %{ 4598 match(Set dst mem); 4599 4600 ins_cost(110); 4601 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 4602 ins_encode %{ 4603 __ leaq($dst$$Register, $mem$$Address); 4604 %} 4605 ins_pipe(ialu_reg_reg_fat); 4606 %} 4607 4608 instruct leaPIdxScaleOff(rRegP dst, indIndexScaleOffset mem) 4609 %{ 4610 match(Set dst mem); 4611 4612 ins_cost(110); 4613 format %{ "leaq $dst, $mem\t# ptr idxscaleoff" %} 4614 ins_encode %{ 4615 __ leaq($dst$$Register, $mem$$Address); 4616 %} 4617 ins_pipe(ialu_reg_reg_fat); 4618 %} 4619 4620 instruct leaPPosIdxOff(rRegP dst, indPosIndexOffset mem) 4621 %{ 4622 match(Set dst mem); 4623 4624 ins_cost(110); 4625 format %{ "leaq $dst, $mem\t# ptr posidxoff" %} 4626 ins_encode %{ 4627 __ leaq($dst$$Register, $mem$$Address); 4628 %} 4629 ins_pipe(ialu_reg_reg_fat); 4630 %} 4631 4632 instruct leaPPosIdxScaleOff(rRegP dst, indPosIndexScaleOffset mem) 4633 %{ 4634 match(Set dst mem); 4635 4636 ins_cost(110); 4637 format %{ "leaq $dst, $mem\t# ptr posidxscaleoff" %} 4638 ins_encode %{ 4639 __ leaq($dst$$Register, $mem$$Address); 4640 %} 4641 ins_pipe(ialu_reg_reg_fat); 4642 %} 4643 4644 // Load Effective Address which uses Narrow (32-bits) oop 4645 instruct leaPCompressedOopOffset(rRegP dst, indCompressedOopOffset mem) 4646 %{ 4647 predicate(UseCompressedOops && (CompressedOops::shift() != 0)); 4648 match(Set dst mem); 4649 4650 ins_cost(110); 4651 format %{ "leaq $dst, $mem\t# ptr compressedoopoff32" %} 4652 ins_encode %{ 4653 __ leaq($dst$$Register, $mem$$Address); 4654 %} 4655 ins_pipe(ialu_reg_reg_fat); 4656 %} 4657 4658 instruct leaP8Narrow(rRegP dst, indOffset8Narrow mem) 4659 %{ 4660 predicate(CompressedOops::shift() == 0); 4661 match(Set dst mem); 4662 4663 ins_cost(110); // XXX 4664 format %{ "leaq $dst, $mem\t# ptr off8narrow" %} 4665 ins_encode %{ 4666 __ leaq($dst$$Register, $mem$$Address); 4667 %} 4668 ins_pipe(ialu_reg_reg_fat); 4669 %} 4670 4671 instruct leaP32Narrow(rRegP dst, indOffset32Narrow mem) 4672 %{ 4673 predicate(CompressedOops::shift() == 0); 4674 match(Set dst mem); 4675 4676 ins_cost(110); 4677 format %{ "leaq $dst, $mem\t# ptr off32narrow" %} 4678 ins_encode %{ 4679 __ leaq($dst$$Register, $mem$$Address); 4680 %} 4681 ins_pipe(ialu_reg_reg_fat); 4682 %} 4683 4684 instruct leaPIdxOffNarrow(rRegP dst, indIndexOffsetNarrow mem) 4685 %{ 4686 predicate(CompressedOops::shift() == 0); 4687 match(Set dst mem); 4688 4689 ins_cost(110); 4690 format %{ "leaq $dst, $mem\t# ptr idxoffnarrow" %} 4691 ins_encode %{ 4692 __ leaq($dst$$Register, $mem$$Address); 4693 %} 4694 ins_pipe(ialu_reg_reg_fat); 4695 %} 4696 4697 instruct leaPIdxScaleNarrow(rRegP dst, indIndexScaleNarrow mem) 4698 %{ 4699 predicate(CompressedOops::shift() == 0); 4700 match(Set dst mem); 4701 4702 ins_cost(110); 4703 format %{ "leaq $dst, $mem\t# ptr idxscalenarrow" %} 4704 ins_encode %{ 4705 __ leaq($dst$$Register, $mem$$Address); 4706 %} 4707 ins_pipe(ialu_reg_reg_fat); 4708 %} 4709 4710 instruct leaPIdxScaleOffNarrow(rRegP dst, indIndexScaleOffsetNarrow mem) 4711 %{ 4712 predicate(CompressedOops::shift() == 0); 4713 match(Set dst mem); 4714 4715 ins_cost(110); 4716 format %{ "leaq $dst, $mem\t# ptr idxscaleoffnarrow" %} 4717 ins_encode %{ 4718 __ leaq($dst$$Register, $mem$$Address); 4719 %} 4720 ins_pipe(ialu_reg_reg_fat); 4721 %} 4722 4723 instruct leaPPosIdxOffNarrow(rRegP dst, indPosIndexOffsetNarrow mem) 4724 %{ 4725 predicate(CompressedOops::shift() == 0); 4726 match(Set dst mem); 4727 4728 ins_cost(110); 4729 format %{ "leaq $dst, $mem\t# ptr posidxoffnarrow" %} 4730 ins_encode %{ 4731 __ leaq($dst$$Register, $mem$$Address); 4732 %} 4733 ins_pipe(ialu_reg_reg_fat); 4734 %} 4735 4736 instruct leaPPosIdxScaleOffNarrow(rRegP dst, indPosIndexScaleOffsetNarrow mem) 4737 %{ 4738 predicate(CompressedOops::shift() == 0); 4739 match(Set dst mem); 4740 4741 ins_cost(110); 4742 format %{ "leaq $dst, $mem\t# ptr posidxscaleoffnarrow" %} 4743 ins_encode %{ 4744 __ leaq($dst$$Register, $mem$$Address); 4745 %} 4746 ins_pipe(ialu_reg_reg_fat); 4747 %} 4748 4749 instruct loadConI(rRegI dst, immI src) 4750 %{ 4751 match(Set dst src); 4752 4753 format %{ "movl $dst, $src\t# int" %} 4754 ins_encode %{ 4755 __ movl($dst$$Register, $src$$constant); 4756 %} 4757 ins_pipe(ialu_reg_fat); // XXX 4758 %} 4759 4760 instruct loadConI0(rRegI dst, immI_0 src, rFlagsReg cr) 4761 %{ 4762 match(Set dst src); 4763 effect(KILL cr); 4764 4765 ins_cost(50); 4766 format %{ "xorl $dst, $dst\t# int" %} 4767 ins_encode %{ 4768 __ xorl($dst$$Register, $dst$$Register); 4769 %} 4770 ins_pipe(ialu_reg); 4771 %} 4772 4773 instruct loadConL(rRegL dst, immL src) 4774 %{ 4775 match(Set dst src); 4776 4777 ins_cost(150); 4778 format %{ "movq $dst, $src\t# long" %} 4779 ins_encode %{ 4780 __ mov64($dst$$Register, $src$$constant); 4781 %} 4782 ins_pipe(ialu_reg); 4783 %} 4784 4785 instruct loadConL0(rRegL dst, immL0 src, rFlagsReg cr) 4786 %{ 4787 match(Set dst src); 4788 effect(KILL cr); 4789 4790 ins_cost(50); 4791 format %{ "xorl $dst, $dst\t# long" %} 4792 ins_encode %{ 4793 __ xorl($dst$$Register, $dst$$Register); 4794 %} 4795 ins_pipe(ialu_reg); // XXX 4796 %} 4797 4798 instruct loadConUL32(rRegL dst, immUL32 src) 4799 %{ 4800 match(Set dst src); 4801 4802 ins_cost(60); 4803 format %{ "movl $dst, $src\t# long (unsigned 32-bit)" %} 4804 ins_encode %{ 4805 __ movl($dst$$Register, $src$$constant); 4806 %} 4807 ins_pipe(ialu_reg); 4808 %} 4809 4810 instruct loadConL32(rRegL dst, immL32 src) 4811 %{ 4812 match(Set dst src); 4813 4814 ins_cost(70); 4815 format %{ "movq $dst, $src\t# long (32-bit)" %} 4816 ins_encode %{ 4817 __ movq($dst$$Register, $src$$constant); 4818 %} 4819 ins_pipe(ialu_reg); 4820 %} 4821 4822 instruct loadConP(rRegP dst, immP con) %{ 4823 match(Set dst con); 4824 4825 format %{ "movq $dst, $con\t# ptr" %} 4826 ins_encode %{ 4827 __ mov64($dst$$Register, $con$$constant, $con->constant_reloc(), RELOC_IMM64); 4828 %} 4829 ins_pipe(ialu_reg_fat); // XXX 4830 %} 4831 4832 instruct loadConP0(rRegP dst, immP0 src, rFlagsReg cr) 4833 %{ 4834 match(Set dst src); 4835 effect(KILL cr); 4836 4837 ins_cost(50); 4838 format %{ "xorl $dst, $dst\t# ptr" %} 4839 ins_encode %{ 4840 __ xorl($dst$$Register, $dst$$Register); 4841 %} 4842 ins_pipe(ialu_reg); 4843 %} 4844 4845 instruct loadConP31(rRegP dst, immP31 src, rFlagsReg cr) 4846 %{ 4847 match(Set dst src); 4848 effect(KILL cr); 4849 4850 ins_cost(60); 4851 format %{ "movl $dst, $src\t# ptr (positive 32-bit)" %} 4852 ins_encode %{ 4853 __ movl($dst$$Register, $src$$constant); 4854 %} 4855 ins_pipe(ialu_reg); 4856 %} 4857 4858 instruct loadConF(regF dst, immF con) %{ 4859 match(Set dst con); 4860 ins_cost(125); 4861 format %{ "movss $dst, [$constantaddress]\t# load from constant table: float=$con" %} 4862 ins_encode %{ 4863 __ movflt($dst$$XMMRegister, $constantaddress($con)); 4864 %} 4865 ins_pipe(pipe_slow); 4866 %} 4867 4868 instruct loadConN0(rRegN dst, immN0 src, rFlagsReg cr) %{ 4869 match(Set dst src); 4870 effect(KILL cr); 4871 format %{ "xorq $dst, $src\t# compressed null pointer" %} 4872 ins_encode %{ 4873 __ xorq($dst$$Register, $dst$$Register); 4874 %} 4875 ins_pipe(ialu_reg); 4876 %} 4877 4878 instruct loadConN(rRegN dst, immN src) %{ 4879 match(Set dst src); 4880 4881 ins_cost(125); 4882 format %{ "movl $dst, $src\t# compressed ptr" %} 4883 ins_encode %{ 4884 address con = (address)$src$$constant; 4885 if (con == nullptr) { 4886 ShouldNotReachHere(); 4887 } else { 4888 __ set_narrow_oop($dst$$Register, (jobject)$src$$constant); 4889 } 4890 %} 4891 ins_pipe(ialu_reg_fat); // XXX 4892 %} 4893 4894 instruct loadConNKlass(rRegN dst, immNKlass src) %{ 4895 match(Set dst src); 4896 4897 ins_cost(125); 4898 format %{ "movl $dst, $src\t# compressed klass ptr" %} 4899 ins_encode %{ 4900 address con = (address)$src$$constant; 4901 if (con == nullptr) { 4902 ShouldNotReachHere(); 4903 } else { 4904 __ set_narrow_klass($dst$$Register, (Klass*)$src$$constant); 4905 } 4906 %} 4907 ins_pipe(ialu_reg_fat); // XXX 4908 %} 4909 4910 instruct loadConF0(regF dst, immF0 src) 4911 %{ 4912 match(Set dst src); 4913 ins_cost(100); 4914 4915 format %{ "xorps $dst, $dst\t# float 0.0" %} 4916 ins_encode %{ 4917 __ xorps($dst$$XMMRegister, $dst$$XMMRegister); 4918 %} 4919 ins_pipe(pipe_slow); 4920 %} 4921 4922 // Use the same format since predicate() can not be used here. 4923 instruct loadConD(regD dst, immD con) %{ 4924 match(Set dst con); 4925 ins_cost(125); 4926 format %{ "movsd $dst, [$constantaddress]\t# load from constant table: double=$con" %} 4927 ins_encode %{ 4928 __ movdbl($dst$$XMMRegister, $constantaddress($con)); 4929 %} 4930 ins_pipe(pipe_slow); 4931 %} 4932 4933 instruct loadConD0(regD dst, immD0 src) 4934 %{ 4935 match(Set dst src); 4936 ins_cost(100); 4937 4938 format %{ "xorpd $dst, $dst\t# double 0.0" %} 4939 ins_encode %{ 4940 __ xorpd($dst$$XMMRegister, $dst$$XMMRegister); 4941 %} 4942 ins_pipe(pipe_slow); 4943 %} 4944 4945 instruct loadSSI(rRegI dst, stackSlotI src) 4946 %{ 4947 match(Set dst src); 4948 4949 ins_cost(125); 4950 format %{ "movl $dst, $src\t# int stk" %} 4951 ins_encode %{ 4952 __ movl($dst$$Register, $src$$Address); 4953 %} 4954 ins_pipe(ialu_reg_mem); 4955 %} 4956 4957 instruct loadSSL(rRegL dst, stackSlotL src) 4958 %{ 4959 match(Set dst src); 4960 4961 ins_cost(125); 4962 format %{ "movq $dst, $src\t# long stk" %} 4963 ins_encode %{ 4964 __ movq($dst$$Register, $src$$Address); 4965 %} 4966 ins_pipe(ialu_reg_mem); 4967 %} 4968 4969 instruct loadSSP(rRegP dst, stackSlotP src) 4970 %{ 4971 match(Set dst src); 4972 4973 ins_cost(125); 4974 format %{ "movq $dst, $src\t# ptr stk" %} 4975 ins_encode %{ 4976 __ movq($dst$$Register, $src$$Address); 4977 %} 4978 ins_pipe(ialu_reg_mem); 4979 %} 4980 4981 instruct loadSSF(regF dst, stackSlotF src) 4982 %{ 4983 match(Set dst src); 4984 4985 ins_cost(125); 4986 format %{ "movss $dst, $src\t# float stk" %} 4987 ins_encode %{ 4988 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 4989 %} 4990 ins_pipe(pipe_slow); // XXX 4991 %} 4992 4993 // Use the same format since predicate() can not be used here. 4994 instruct loadSSD(regD dst, stackSlotD src) 4995 %{ 4996 match(Set dst src); 4997 4998 ins_cost(125); 4999 format %{ "movsd $dst, $src\t# double stk" %} 5000 ins_encode %{ 5001 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 5002 %} 5003 ins_pipe(pipe_slow); // XXX 5004 %} 5005 5006 // Prefetch instructions for allocation. 5007 // Must be safe to execute with invalid address (cannot fault). 5008 5009 instruct prefetchAlloc( memory mem ) %{ 5010 predicate(AllocatePrefetchInstr==3); 5011 match(PrefetchAllocation mem); 5012 ins_cost(125); 5013 5014 format %{ "PREFETCHW $mem\t# Prefetch allocation into level 1 cache and mark modified" %} 5015 ins_encode %{ 5016 __ prefetchw($mem$$Address); 5017 %} 5018 ins_pipe(ialu_mem); 5019 %} 5020 5021 instruct prefetchAllocNTA( memory mem ) %{ 5022 predicate(AllocatePrefetchInstr==0); 5023 match(PrefetchAllocation mem); 5024 ins_cost(125); 5025 5026 format %{ "PREFETCHNTA $mem\t# Prefetch allocation to non-temporal cache for write" %} 5027 ins_encode %{ 5028 __ prefetchnta($mem$$Address); 5029 %} 5030 ins_pipe(ialu_mem); 5031 %} 5032 5033 instruct prefetchAllocT0( memory mem ) %{ 5034 predicate(AllocatePrefetchInstr==1); 5035 match(PrefetchAllocation mem); 5036 ins_cost(125); 5037 5038 format %{ "PREFETCHT0 $mem\t# Prefetch allocation to level 1 and 2 caches for write" %} 5039 ins_encode %{ 5040 __ prefetcht0($mem$$Address); 5041 %} 5042 ins_pipe(ialu_mem); 5043 %} 5044 5045 instruct prefetchAllocT2( memory mem ) %{ 5046 predicate(AllocatePrefetchInstr==2); 5047 match(PrefetchAllocation mem); 5048 ins_cost(125); 5049 5050 format %{ "PREFETCHT2 $mem\t# Prefetch allocation to level 2 cache for write" %} 5051 ins_encode %{ 5052 __ prefetcht2($mem$$Address); 5053 %} 5054 ins_pipe(ialu_mem); 5055 %} 5056 5057 //----------Store Instructions------------------------------------------------- 5058 5059 // Store Byte 5060 instruct storeB(memory mem, rRegI src) 5061 %{ 5062 match(Set mem (StoreB mem src)); 5063 5064 ins_cost(125); // XXX 5065 format %{ "movb $mem, $src\t# byte" %} 5066 ins_encode %{ 5067 __ movb($mem$$Address, $src$$Register); 5068 %} 5069 ins_pipe(ialu_mem_reg); 5070 %} 5071 5072 // Store Char/Short 5073 instruct storeC(memory mem, rRegI src) 5074 %{ 5075 match(Set mem (StoreC mem src)); 5076 5077 ins_cost(125); // XXX 5078 format %{ "movw $mem, $src\t# char/short" %} 5079 ins_encode %{ 5080 __ movw($mem$$Address, $src$$Register); 5081 %} 5082 ins_pipe(ialu_mem_reg); 5083 %} 5084 5085 // Store Integer 5086 instruct storeI(memory mem, rRegI src) 5087 %{ 5088 match(Set mem (StoreI mem src)); 5089 5090 ins_cost(125); // XXX 5091 format %{ "movl $mem, $src\t# int" %} 5092 ins_encode %{ 5093 __ movl($mem$$Address, $src$$Register); 5094 %} 5095 ins_pipe(ialu_mem_reg); 5096 %} 5097 5098 // Store Long 5099 instruct storeL(memory mem, rRegL src) 5100 %{ 5101 match(Set mem (StoreL mem src)); 5102 5103 ins_cost(125); // XXX 5104 format %{ "movq $mem, $src\t# long" %} 5105 ins_encode %{ 5106 __ movq($mem$$Address, $src$$Register); 5107 %} 5108 ins_pipe(ialu_mem_reg); // XXX 5109 %} 5110 5111 // Store Pointer 5112 instruct storeP(memory mem, any_RegP src) 5113 %{ 5114 predicate(n->as_Store()->barrier_data() == 0); 5115 match(Set mem (StoreP mem src)); 5116 5117 ins_cost(125); // XXX 5118 format %{ "movq $mem, $src\t# ptr" %} 5119 ins_encode %{ 5120 __ movq($mem$$Address, $src$$Register); 5121 %} 5122 ins_pipe(ialu_mem_reg); 5123 %} 5124 5125 instruct storeImmP0(memory mem, immP0 zero) 5126 %{ 5127 predicate(UseCompressedOops && (CompressedOops::base() == nullptr) && n->as_Store()->barrier_data() == 0); 5128 match(Set mem (StoreP mem zero)); 5129 5130 ins_cost(125); // XXX 5131 format %{ "movq $mem, R12\t# ptr (R12_heapbase==0)" %} 5132 ins_encode %{ 5133 __ movq($mem$$Address, r12); 5134 %} 5135 ins_pipe(ialu_mem_reg); 5136 %} 5137 5138 // Store Null Pointer, mark word, or other simple pointer constant. 5139 instruct storeImmP(memory mem, immP31 src) 5140 %{ 5141 predicate(n->as_Store()->barrier_data() == 0); 5142 match(Set mem (StoreP mem src)); 5143 5144 ins_cost(150); // XXX 5145 format %{ "movq $mem, $src\t# ptr" %} 5146 ins_encode %{ 5147 __ movq($mem$$Address, $src$$constant); 5148 %} 5149 ins_pipe(ialu_mem_imm); 5150 %} 5151 5152 // Store Compressed Pointer 5153 instruct storeN(memory mem, rRegN src) 5154 %{ 5155 predicate(n->as_Store()->barrier_data() == 0); 5156 match(Set mem (StoreN mem src)); 5157 5158 ins_cost(125); // XXX 5159 format %{ "movl $mem, $src\t# compressed ptr" %} 5160 ins_encode %{ 5161 __ movl($mem$$Address, $src$$Register); 5162 %} 5163 ins_pipe(ialu_mem_reg); 5164 %} 5165 5166 instruct storeNKlass(memory mem, rRegN src) 5167 %{ 5168 match(Set mem (StoreNKlass mem src)); 5169 5170 ins_cost(125); // XXX 5171 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5172 ins_encode %{ 5173 __ movl($mem$$Address, $src$$Register); 5174 %} 5175 ins_pipe(ialu_mem_reg); 5176 %} 5177 5178 instruct storeImmN0(memory mem, immN0 zero) 5179 %{ 5180 predicate(CompressedOops::base() == nullptr && n->as_Store()->barrier_data() == 0); 5181 match(Set mem (StoreN mem zero)); 5182 5183 ins_cost(125); // XXX 5184 format %{ "movl $mem, R12\t# compressed ptr (R12_heapbase==0)" %} 5185 ins_encode %{ 5186 __ movl($mem$$Address, r12); 5187 %} 5188 ins_pipe(ialu_mem_reg); 5189 %} 5190 5191 instruct storeImmN(memory mem, immN src) 5192 %{ 5193 predicate(n->as_Store()->barrier_data() == 0); 5194 match(Set mem (StoreN mem src)); 5195 5196 ins_cost(150); // XXX 5197 format %{ "movl $mem, $src\t# compressed ptr" %} 5198 ins_encode %{ 5199 address con = (address)$src$$constant; 5200 if (con == nullptr) { 5201 __ movl($mem$$Address, 0); 5202 } else { 5203 __ set_narrow_oop($mem$$Address, (jobject)$src$$constant); 5204 } 5205 %} 5206 ins_pipe(ialu_mem_imm); 5207 %} 5208 5209 instruct storeImmNKlass(memory mem, immNKlass src) 5210 %{ 5211 match(Set mem (StoreNKlass mem src)); 5212 5213 ins_cost(150); // XXX 5214 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5215 ins_encode %{ 5216 __ set_narrow_klass($mem$$Address, (Klass*)$src$$constant); 5217 %} 5218 ins_pipe(ialu_mem_imm); 5219 %} 5220 5221 // Store Integer Immediate 5222 instruct storeImmI0(memory mem, immI_0 zero) 5223 %{ 5224 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5225 match(Set mem (StoreI mem zero)); 5226 5227 ins_cost(125); // XXX 5228 format %{ "movl $mem, R12\t# int (R12_heapbase==0)" %} 5229 ins_encode %{ 5230 __ movl($mem$$Address, r12); 5231 %} 5232 ins_pipe(ialu_mem_reg); 5233 %} 5234 5235 instruct storeImmI(memory mem, immI src) 5236 %{ 5237 match(Set mem (StoreI mem src)); 5238 5239 ins_cost(150); 5240 format %{ "movl $mem, $src\t# int" %} 5241 ins_encode %{ 5242 __ movl($mem$$Address, $src$$constant); 5243 %} 5244 ins_pipe(ialu_mem_imm); 5245 %} 5246 5247 // Store Long Immediate 5248 instruct storeImmL0(memory mem, immL0 zero) 5249 %{ 5250 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5251 match(Set mem (StoreL mem zero)); 5252 5253 ins_cost(125); // XXX 5254 format %{ "movq $mem, R12\t# long (R12_heapbase==0)" %} 5255 ins_encode %{ 5256 __ movq($mem$$Address, r12); 5257 %} 5258 ins_pipe(ialu_mem_reg); 5259 %} 5260 5261 instruct storeImmL(memory mem, immL32 src) 5262 %{ 5263 match(Set mem (StoreL mem src)); 5264 5265 ins_cost(150); 5266 format %{ "movq $mem, $src\t# long" %} 5267 ins_encode %{ 5268 __ movq($mem$$Address, $src$$constant); 5269 %} 5270 ins_pipe(ialu_mem_imm); 5271 %} 5272 5273 // Store Short/Char Immediate 5274 instruct storeImmC0(memory mem, immI_0 zero) 5275 %{ 5276 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5277 match(Set mem (StoreC mem zero)); 5278 5279 ins_cost(125); // XXX 5280 format %{ "movw $mem, R12\t# short/char (R12_heapbase==0)" %} 5281 ins_encode %{ 5282 __ movw($mem$$Address, r12); 5283 %} 5284 ins_pipe(ialu_mem_reg); 5285 %} 5286 5287 instruct storeImmI16(memory mem, immI16 src) 5288 %{ 5289 predicate(UseStoreImmI16); 5290 match(Set mem (StoreC mem src)); 5291 5292 ins_cost(150); 5293 format %{ "movw $mem, $src\t# short/char" %} 5294 ins_encode %{ 5295 __ movw($mem$$Address, $src$$constant); 5296 %} 5297 ins_pipe(ialu_mem_imm); 5298 %} 5299 5300 // Store Byte Immediate 5301 instruct storeImmB0(memory mem, immI_0 zero) 5302 %{ 5303 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5304 match(Set mem (StoreB mem zero)); 5305 5306 ins_cost(125); // XXX 5307 format %{ "movb $mem, R12\t# short/char (R12_heapbase==0)" %} 5308 ins_encode %{ 5309 __ movb($mem$$Address, r12); 5310 %} 5311 ins_pipe(ialu_mem_reg); 5312 %} 5313 5314 instruct storeImmB(memory mem, immI8 src) 5315 %{ 5316 match(Set mem (StoreB mem src)); 5317 5318 ins_cost(150); // XXX 5319 format %{ "movb $mem, $src\t# byte" %} 5320 ins_encode %{ 5321 __ movb($mem$$Address, $src$$constant); 5322 %} 5323 ins_pipe(ialu_mem_imm); 5324 %} 5325 5326 // Store Float 5327 instruct storeF(memory mem, regF src) 5328 %{ 5329 match(Set mem (StoreF mem src)); 5330 5331 ins_cost(95); // XXX 5332 format %{ "movss $mem, $src\t# float" %} 5333 ins_encode %{ 5334 __ movflt($mem$$Address, $src$$XMMRegister); 5335 %} 5336 ins_pipe(pipe_slow); // XXX 5337 %} 5338 5339 // Store immediate Float value (it is faster than store from XMM register) 5340 instruct storeF0(memory mem, immF0 zero) 5341 %{ 5342 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5343 match(Set mem (StoreF mem zero)); 5344 5345 ins_cost(25); // XXX 5346 format %{ "movl $mem, R12\t# float 0. (R12_heapbase==0)" %} 5347 ins_encode %{ 5348 __ movl($mem$$Address, r12); 5349 %} 5350 ins_pipe(ialu_mem_reg); 5351 %} 5352 5353 instruct storeF_imm(memory mem, immF src) 5354 %{ 5355 match(Set mem (StoreF mem src)); 5356 5357 ins_cost(50); 5358 format %{ "movl $mem, $src\t# float" %} 5359 ins_encode %{ 5360 __ movl($mem$$Address, jint_cast($src$$constant)); 5361 %} 5362 ins_pipe(ialu_mem_imm); 5363 %} 5364 5365 // Store Double 5366 instruct storeD(memory mem, regD src) 5367 %{ 5368 match(Set mem (StoreD mem src)); 5369 5370 ins_cost(95); // XXX 5371 format %{ "movsd $mem, $src\t# double" %} 5372 ins_encode %{ 5373 __ movdbl($mem$$Address, $src$$XMMRegister); 5374 %} 5375 ins_pipe(pipe_slow); // XXX 5376 %} 5377 5378 // Store immediate double 0.0 (it is faster than store from XMM register) 5379 instruct storeD0_imm(memory mem, immD0 src) 5380 %{ 5381 predicate(!UseCompressedOops || (CompressedOops::base() != nullptr)); 5382 match(Set mem (StoreD mem src)); 5383 5384 ins_cost(50); 5385 format %{ "movq $mem, $src\t# double 0." %} 5386 ins_encode %{ 5387 __ movq($mem$$Address, $src$$constant); 5388 %} 5389 ins_pipe(ialu_mem_imm); 5390 %} 5391 5392 instruct storeD0(memory mem, immD0 zero) 5393 %{ 5394 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5395 match(Set mem (StoreD mem zero)); 5396 5397 ins_cost(25); // XXX 5398 format %{ "movq $mem, R12\t# double 0. (R12_heapbase==0)" %} 5399 ins_encode %{ 5400 __ movq($mem$$Address, r12); 5401 %} 5402 ins_pipe(ialu_mem_reg); 5403 %} 5404 5405 instruct storeSSI(stackSlotI dst, rRegI src) 5406 %{ 5407 match(Set dst src); 5408 5409 ins_cost(100); 5410 format %{ "movl $dst, $src\t# int stk" %} 5411 ins_encode %{ 5412 __ movl($dst$$Address, $src$$Register); 5413 %} 5414 ins_pipe( ialu_mem_reg ); 5415 %} 5416 5417 instruct storeSSL(stackSlotL dst, rRegL src) 5418 %{ 5419 match(Set dst src); 5420 5421 ins_cost(100); 5422 format %{ "movq $dst, $src\t# long stk" %} 5423 ins_encode %{ 5424 __ movq($dst$$Address, $src$$Register); 5425 %} 5426 ins_pipe(ialu_mem_reg); 5427 %} 5428 5429 instruct storeSSP(stackSlotP dst, rRegP src) 5430 %{ 5431 match(Set dst src); 5432 5433 ins_cost(100); 5434 format %{ "movq $dst, $src\t# ptr stk" %} 5435 ins_encode %{ 5436 __ movq($dst$$Address, $src$$Register); 5437 %} 5438 ins_pipe(ialu_mem_reg); 5439 %} 5440 5441 instruct storeSSF(stackSlotF dst, regF src) 5442 %{ 5443 match(Set dst src); 5444 5445 ins_cost(95); // XXX 5446 format %{ "movss $dst, $src\t# float stk" %} 5447 ins_encode %{ 5448 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 5449 %} 5450 ins_pipe(pipe_slow); // XXX 5451 %} 5452 5453 instruct storeSSD(stackSlotD dst, regD src) 5454 %{ 5455 match(Set dst src); 5456 5457 ins_cost(95); // XXX 5458 format %{ "movsd $dst, $src\t# double stk" %} 5459 ins_encode %{ 5460 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 5461 %} 5462 ins_pipe(pipe_slow); // XXX 5463 %} 5464 5465 instruct cacheWB(indirect addr) 5466 %{ 5467 predicate(VM_Version::supports_data_cache_line_flush()); 5468 match(CacheWB addr); 5469 5470 ins_cost(100); 5471 format %{"cache wb $addr" %} 5472 ins_encode %{ 5473 assert($addr->index_position() < 0, "should be"); 5474 assert($addr$$disp == 0, "should be"); 5475 __ cache_wb(Address($addr$$base$$Register, 0)); 5476 %} 5477 ins_pipe(pipe_slow); // XXX 5478 %} 5479 5480 instruct cacheWBPreSync() 5481 %{ 5482 predicate(VM_Version::supports_data_cache_line_flush()); 5483 match(CacheWBPreSync); 5484 5485 ins_cost(100); 5486 format %{"cache wb presync" %} 5487 ins_encode %{ 5488 __ cache_wbsync(true); 5489 %} 5490 ins_pipe(pipe_slow); // XXX 5491 %} 5492 5493 instruct cacheWBPostSync() 5494 %{ 5495 predicate(VM_Version::supports_data_cache_line_flush()); 5496 match(CacheWBPostSync); 5497 5498 ins_cost(100); 5499 format %{"cache wb postsync" %} 5500 ins_encode %{ 5501 __ cache_wbsync(false); 5502 %} 5503 ins_pipe(pipe_slow); // XXX 5504 %} 5505 5506 //----------BSWAP Instructions------------------------------------------------- 5507 instruct bytes_reverse_int(rRegI dst) %{ 5508 match(Set dst (ReverseBytesI dst)); 5509 5510 format %{ "bswapl $dst" %} 5511 ins_encode %{ 5512 __ bswapl($dst$$Register); 5513 %} 5514 ins_pipe( ialu_reg ); 5515 %} 5516 5517 instruct bytes_reverse_long(rRegL dst) %{ 5518 match(Set dst (ReverseBytesL dst)); 5519 5520 format %{ "bswapq $dst" %} 5521 ins_encode %{ 5522 __ bswapq($dst$$Register); 5523 %} 5524 ins_pipe( ialu_reg); 5525 %} 5526 5527 instruct bytes_reverse_unsigned_short(rRegI dst, rFlagsReg cr) %{ 5528 match(Set dst (ReverseBytesUS dst)); 5529 effect(KILL cr); 5530 5531 format %{ "bswapl $dst\n\t" 5532 "shrl $dst,16\n\t" %} 5533 ins_encode %{ 5534 __ bswapl($dst$$Register); 5535 __ shrl($dst$$Register, 16); 5536 %} 5537 ins_pipe( ialu_reg ); 5538 %} 5539 5540 instruct bytes_reverse_short(rRegI dst, rFlagsReg cr) %{ 5541 match(Set dst (ReverseBytesS dst)); 5542 effect(KILL cr); 5543 5544 format %{ "bswapl $dst\n\t" 5545 "sar $dst,16\n\t" %} 5546 ins_encode %{ 5547 __ bswapl($dst$$Register); 5548 __ sarl($dst$$Register, 16); 5549 %} 5550 ins_pipe( ialu_reg ); 5551 %} 5552 5553 //---------- Zeros Count Instructions ------------------------------------------ 5554 5555 instruct countLeadingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 5556 predicate(UseCountLeadingZerosInstruction); 5557 match(Set dst (CountLeadingZerosI src)); 5558 effect(KILL cr); 5559 5560 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 5561 ins_encode %{ 5562 __ lzcntl($dst$$Register, $src$$Register); 5563 %} 5564 ins_pipe(ialu_reg); 5565 %} 5566 5567 instruct countLeadingZerosI_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5568 predicate(UseCountLeadingZerosInstruction); 5569 match(Set dst (CountLeadingZerosI (LoadI src))); 5570 effect(KILL cr); 5571 ins_cost(175); 5572 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 5573 ins_encode %{ 5574 __ lzcntl($dst$$Register, $src$$Address); 5575 %} 5576 ins_pipe(ialu_reg_mem); 5577 %} 5578 5579 instruct countLeadingZerosI_bsr(rRegI dst, rRegI src, rFlagsReg cr) %{ 5580 predicate(!UseCountLeadingZerosInstruction); 5581 match(Set dst (CountLeadingZerosI src)); 5582 effect(KILL cr); 5583 5584 format %{ "bsrl $dst, $src\t# count leading zeros (int)\n\t" 5585 "jnz skip\n\t" 5586 "movl $dst, -1\n" 5587 "skip:\n\t" 5588 "negl $dst\n\t" 5589 "addl $dst, 31" %} 5590 ins_encode %{ 5591 Register Rdst = $dst$$Register; 5592 Register Rsrc = $src$$Register; 5593 Label skip; 5594 __ bsrl(Rdst, Rsrc); 5595 __ jccb(Assembler::notZero, skip); 5596 __ movl(Rdst, -1); 5597 __ bind(skip); 5598 __ negl(Rdst); 5599 __ addl(Rdst, BitsPerInt - 1); 5600 %} 5601 ins_pipe(ialu_reg); 5602 %} 5603 5604 instruct countLeadingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 5605 predicate(UseCountLeadingZerosInstruction); 5606 match(Set dst (CountLeadingZerosL src)); 5607 effect(KILL cr); 5608 5609 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 5610 ins_encode %{ 5611 __ lzcntq($dst$$Register, $src$$Register); 5612 %} 5613 ins_pipe(ialu_reg); 5614 %} 5615 5616 instruct countLeadingZerosL_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5617 predicate(UseCountLeadingZerosInstruction); 5618 match(Set dst (CountLeadingZerosL (LoadL src))); 5619 effect(KILL cr); 5620 ins_cost(175); 5621 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 5622 ins_encode %{ 5623 __ lzcntq($dst$$Register, $src$$Address); 5624 %} 5625 ins_pipe(ialu_reg_mem); 5626 %} 5627 5628 instruct countLeadingZerosL_bsr(rRegI dst, rRegL src, rFlagsReg cr) %{ 5629 predicate(!UseCountLeadingZerosInstruction); 5630 match(Set dst (CountLeadingZerosL src)); 5631 effect(KILL cr); 5632 5633 format %{ "bsrq $dst, $src\t# count leading zeros (long)\n\t" 5634 "jnz skip\n\t" 5635 "movl $dst, -1\n" 5636 "skip:\n\t" 5637 "negl $dst\n\t" 5638 "addl $dst, 63" %} 5639 ins_encode %{ 5640 Register Rdst = $dst$$Register; 5641 Register Rsrc = $src$$Register; 5642 Label skip; 5643 __ bsrq(Rdst, Rsrc); 5644 __ jccb(Assembler::notZero, skip); 5645 __ movl(Rdst, -1); 5646 __ bind(skip); 5647 __ negl(Rdst); 5648 __ addl(Rdst, BitsPerLong - 1); 5649 %} 5650 ins_pipe(ialu_reg); 5651 %} 5652 5653 instruct countTrailingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 5654 predicate(UseCountTrailingZerosInstruction); 5655 match(Set dst (CountTrailingZerosI src)); 5656 effect(KILL cr); 5657 5658 format %{ "tzcntl $dst, $src\t# count trailing zeros (int)" %} 5659 ins_encode %{ 5660 __ tzcntl($dst$$Register, $src$$Register); 5661 %} 5662 ins_pipe(ialu_reg); 5663 %} 5664 5665 instruct countTrailingZerosI_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5666 predicate(UseCountTrailingZerosInstruction); 5667 match(Set dst (CountTrailingZerosI (LoadI src))); 5668 effect(KILL cr); 5669 ins_cost(175); 5670 format %{ "tzcntl $dst, $src\t# count trailing zeros (int)" %} 5671 ins_encode %{ 5672 __ tzcntl($dst$$Register, $src$$Address); 5673 %} 5674 ins_pipe(ialu_reg_mem); 5675 %} 5676 5677 instruct countTrailingZerosI_bsf(rRegI dst, rRegI src, rFlagsReg cr) %{ 5678 predicate(!UseCountTrailingZerosInstruction); 5679 match(Set dst (CountTrailingZerosI src)); 5680 effect(KILL cr); 5681 5682 format %{ "bsfl $dst, $src\t# count trailing zeros (int)\n\t" 5683 "jnz done\n\t" 5684 "movl $dst, 32\n" 5685 "done:" %} 5686 ins_encode %{ 5687 Register Rdst = $dst$$Register; 5688 Label done; 5689 __ bsfl(Rdst, $src$$Register); 5690 __ jccb(Assembler::notZero, done); 5691 __ movl(Rdst, BitsPerInt); 5692 __ bind(done); 5693 %} 5694 ins_pipe(ialu_reg); 5695 %} 5696 5697 instruct countTrailingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 5698 predicate(UseCountTrailingZerosInstruction); 5699 match(Set dst (CountTrailingZerosL src)); 5700 effect(KILL cr); 5701 5702 format %{ "tzcntq $dst, $src\t# count trailing zeros (long)" %} 5703 ins_encode %{ 5704 __ tzcntq($dst$$Register, $src$$Register); 5705 %} 5706 ins_pipe(ialu_reg); 5707 %} 5708 5709 instruct countTrailingZerosL_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5710 predicate(UseCountTrailingZerosInstruction); 5711 match(Set dst (CountTrailingZerosL (LoadL src))); 5712 effect(KILL cr); 5713 ins_cost(175); 5714 format %{ "tzcntq $dst, $src\t# count trailing zeros (long)" %} 5715 ins_encode %{ 5716 __ tzcntq($dst$$Register, $src$$Address); 5717 %} 5718 ins_pipe(ialu_reg_mem); 5719 %} 5720 5721 instruct countTrailingZerosL_bsf(rRegI dst, rRegL src, rFlagsReg cr) %{ 5722 predicate(!UseCountTrailingZerosInstruction); 5723 match(Set dst (CountTrailingZerosL src)); 5724 effect(KILL cr); 5725 5726 format %{ "bsfq $dst, $src\t# count trailing zeros (long)\n\t" 5727 "jnz done\n\t" 5728 "movl $dst, 64\n" 5729 "done:" %} 5730 ins_encode %{ 5731 Register Rdst = $dst$$Register; 5732 Label done; 5733 __ bsfq(Rdst, $src$$Register); 5734 __ jccb(Assembler::notZero, done); 5735 __ movl(Rdst, BitsPerLong); 5736 __ bind(done); 5737 %} 5738 ins_pipe(ialu_reg); 5739 %} 5740 5741 //--------------- Reverse Operation Instructions ---------------- 5742 instruct bytes_reversebit_int(rRegI dst, rRegI src, rRegI rtmp, rFlagsReg cr) %{ 5743 predicate(!VM_Version::supports_gfni()); 5744 match(Set dst (ReverseI src)); 5745 effect(TEMP dst, TEMP rtmp, KILL cr); 5746 format %{ "reverse_int $dst $src\t! using $rtmp as TEMP" %} 5747 ins_encode %{ 5748 __ reverseI($dst$$Register, $src$$Register, xnoreg, xnoreg, $rtmp$$Register); 5749 %} 5750 ins_pipe( ialu_reg ); 5751 %} 5752 5753 instruct bytes_reversebit_int_gfni(rRegI dst, rRegI src, vlRegF xtmp1, vlRegF xtmp2, rRegL rtmp, rFlagsReg cr) %{ 5754 predicate(VM_Version::supports_gfni()); 5755 match(Set dst (ReverseI src)); 5756 effect(TEMP dst, TEMP xtmp1, TEMP xtmp2, TEMP rtmp, KILL cr); 5757 format %{ "reverse_int $dst $src\t! using $rtmp, $xtmp1 and $xtmp2 as TEMP" %} 5758 ins_encode %{ 5759 __ reverseI($dst$$Register, $src$$Register, $xtmp1$$XMMRegister, $xtmp2$$XMMRegister, $rtmp$$Register); 5760 %} 5761 ins_pipe( ialu_reg ); 5762 %} 5763 5764 instruct bytes_reversebit_long(rRegL dst, rRegL src, rRegL rtmp1, rRegL rtmp2, rFlagsReg cr) %{ 5765 predicate(!VM_Version::supports_gfni()); 5766 match(Set dst (ReverseL src)); 5767 effect(TEMP dst, TEMP rtmp1, TEMP rtmp2, KILL cr); 5768 format %{ "reverse_long $dst $src\t! using $rtmp1 and $rtmp2 as TEMP" %} 5769 ins_encode %{ 5770 __ reverseL($dst$$Register, $src$$Register, xnoreg, xnoreg, $rtmp1$$Register, $rtmp2$$Register); 5771 %} 5772 ins_pipe( ialu_reg ); 5773 %} 5774 5775 instruct bytes_reversebit_long_gfni(rRegL dst, rRegL src, vlRegD xtmp1, vlRegD xtmp2, rRegL rtmp, rFlagsReg cr) %{ 5776 predicate(VM_Version::supports_gfni()); 5777 match(Set dst (ReverseL src)); 5778 effect(TEMP dst, TEMP xtmp1, TEMP xtmp2, TEMP rtmp, KILL cr); 5779 format %{ "reverse_long $dst $src\t! using $rtmp, $xtmp1 and $xtmp2 as TEMP" %} 5780 ins_encode %{ 5781 __ reverseL($dst$$Register, $src$$Register, $xtmp1$$XMMRegister, $xtmp2$$XMMRegister, $rtmp$$Register, noreg); 5782 %} 5783 ins_pipe( ialu_reg ); 5784 %} 5785 5786 //---------- Population Count Instructions ------------------------------------- 5787 5788 instruct popCountI(rRegI dst, rRegI src, rFlagsReg cr) %{ 5789 predicate(UsePopCountInstruction); 5790 match(Set dst (PopCountI src)); 5791 effect(KILL cr); 5792 5793 format %{ "popcnt $dst, $src" %} 5794 ins_encode %{ 5795 __ popcntl($dst$$Register, $src$$Register); 5796 %} 5797 ins_pipe(ialu_reg); 5798 %} 5799 5800 instruct popCountI_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 5801 predicate(UsePopCountInstruction); 5802 match(Set dst (PopCountI (LoadI mem))); 5803 effect(KILL cr); 5804 5805 format %{ "popcnt $dst, $mem" %} 5806 ins_encode %{ 5807 __ popcntl($dst$$Register, $mem$$Address); 5808 %} 5809 ins_pipe(ialu_reg); 5810 %} 5811 5812 // Note: Long.bitCount(long) returns an int. 5813 instruct popCountL(rRegI dst, rRegL src, rFlagsReg cr) %{ 5814 predicate(UsePopCountInstruction); 5815 match(Set dst (PopCountL src)); 5816 effect(KILL cr); 5817 5818 format %{ "popcnt $dst, $src" %} 5819 ins_encode %{ 5820 __ popcntq($dst$$Register, $src$$Register); 5821 %} 5822 ins_pipe(ialu_reg); 5823 %} 5824 5825 // Note: Long.bitCount(long) returns an int. 5826 instruct popCountL_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 5827 predicate(UsePopCountInstruction); 5828 match(Set dst (PopCountL (LoadL mem))); 5829 effect(KILL cr); 5830 5831 format %{ "popcnt $dst, $mem" %} 5832 ins_encode %{ 5833 __ popcntq($dst$$Register, $mem$$Address); 5834 %} 5835 ins_pipe(ialu_reg); 5836 %} 5837 5838 5839 //----------MemBar Instructions----------------------------------------------- 5840 // Memory barrier flavors 5841 5842 instruct membar_acquire() 5843 %{ 5844 match(MemBarAcquire); 5845 match(LoadFence); 5846 ins_cost(0); 5847 5848 size(0); 5849 format %{ "MEMBAR-acquire ! (empty encoding)" %} 5850 ins_encode(); 5851 ins_pipe(empty); 5852 %} 5853 5854 instruct membar_acquire_lock() 5855 %{ 5856 match(MemBarAcquireLock); 5857 ins_cost(0); 5858 5859 size(0); 5860 format %{ "MEMBAR-acquire (prior CMPXCHG in FastLock so empty encoding)" %} 5861 ins_encode(); 5862 ins_pipe(empty); 5863 %} 5864 5865 instruct membar_release() 5866 %{ 5867 match(MemBarRelease); 5868 match(StoreFence); 5869 ins_cost(0); 5870 5871 size(0); 5872 format %{ "MEMBAR-release ! (empty encoding)" %} 5873 ins_encode(); 5874 ins_pipe(empty); 5875 %} 5876 5877 instruct membar_release_lock() 5878 %{ 5879 match(MemBarReleaseLock); 5880 ins_cost(0); 5881 5882 size(0); 5883 format %{ "MEMBAR-release (a FastUnlock follows so empty encoding)" %} 5884 ins_encode(); 5885 ins_pipe(empty); 5886 %} 5887 5888 instruct membar_volatile(rFlagsReg cr) %{ 5889 match(MemBarVolatile); 5890 effect(KILL cr); 5891 ins_cost(400); 5892 5893 format %{ 5894 $$template 5895 $$emit$$"lock addl [rsp + #0], 0\t! membar_volatile" 5896 %} 5897 ins_encode %{ 5898 __ membar(Assembler::StoreLoad); 5899 %} 5900 ins_pipe(pipe_slow); 5901 %} 5902 5903 instruct unnecessary_membar_volatile() 5904 %{ 5905 match(MemBarVolatile); 5906 predicate(Matcher::post_store_load_barrier(n)); 5907 ins_cost(0); 5908 5909 size(0); 5910 format %{ "MEMBAR-volatile (unnecessary so empty encoding)" %} 5911 ins_encode(); 5912 ins_pipe(empty); 5913 %} 5914 5915 instruct membar_storestore() %{ 5916 match(MemBarStoreStore); 5917 match(StoreStoreFence); 5918 ins_cost(0); 5919 5920 size(0); 5921 format %{ "MEMBAR-storestore (empty encoding)" %} 5922 ins_encode( ); 5923 ins_pipe(empty); 5924 %} 5925 5926 //----------Move Instructions-------------------------------------------------- 5927 5928 instruct castX2P(rRegP dst, rRegL src) 5929 %{ 5930 match(Set dst (CastX2P src)); 5931 5932 format %{ "movq $dst, $src\t# long->ptr" %} 5933 ins_encode %{ 5934 if ($dst$$reg != $src$$reg) { 5935 __ movptr($dst$$Register, $src$$Register); 5936 } 5937 %} 5938 ins_pipe(ialu_reg_reg); // XXX 5939 %} 5940 5941 instruct castN2X(rRegL dst, rRegN src) 5942 %{ 5943 match(Set dst (CastP2X src)); 5944 5945 format %{ "movq $dst, $src\t# ptr -> long" %} 5946 ins_encode %{ 5947 if ($dst$$reg != $src$$reg) { 5948 __ movptr($dst$$Register, $src$$Register); 5949 } 5950 %} 5951 ins_pipe(ialu_reg_reg); // XXX 5952 %} 5953 5954 instruct castP2X(rRegL dst, rRegP src) 5955 %{ 5956 match(Set dst (CastP2X src)); 5957 5958 format %{ "movq $dst, $src\t# ptr -> long" %} 5959 ins_encode %{ 5960 if ($dst$$reg != $src$$reg) { 5961 __ movptr($dst$$Register, $src$$Register); 5962 } 5963 %} 5964 ins_pipe(ialu_reg_reg); // XXX 5965 %} 5966 5967 // Convert oop into int for vectors alignment masking 5968 instruct convP2I(rRegI dst, rRegP src) 5969 %{ 5970 match(Set dst (ConvL2I (CastP2X src))); 5971 5972 format %{ "movl $dst, $src\t# ptr -> int" %} 5973 ins_encode %{ 5974 __ movl($dst$$Register, $src$$Register); 5975 %} 5976 ins_pipe(ialu_reg_reg); // XXX 5977 %} 5978 5979 // Convert compressed oop into int for vectors alignment masking 5980 // in case of 32bit oops (heap < 4Gb). 5981 instruct convN2I(rRegI dst, rRegN src) 5982 %{ 5983 predicate(CompressedOops::shift() == 0); 5984 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 5985 5986 format %{ "movl $dst, $src\t# compressed ptr -> int" %} 5987 ins_encode %{ 5988 __ movl($dst$$Register, $src$$Register); 5989 %} 5990 ins_pipe(ialu_reg_reg); // XXX 5991 %} 5992 5993 // Convert oop pointer into compressed form 5994 instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{ 5995 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 5996 match(Set dst (EncodeP src)); 5997 effect(KILL cr); 5998 format %{ "encode_heap_oop $dst,$src" %} 5999 ins_encode %{ 6000 Register s = $src$$Register; 6001 Register d = $dst$$Register; 6002 if (s != d) { 6003 __ movq(d, s); 6004 } 6005 __ encode_heap_oop(d); 6006 %} 6007 ins_pipe(ialu_reg_long); 6008 %} 6009 6010 instruct encodeHeapOop_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6011 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 6012 match(Set dst (EncodeP src)); 6013 effect(KILL cr); 6014 format %{ "encode_heap_oop_not_null $dst,$src" %} 6015 ins_encode %{ 6016 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 6017 %} 6018 ins_pipe(ialu_reg_long); 6019 %} 6020 6021 instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{ 6022 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 6023 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 6024 match(Set dst (DecodeN src)); 6025 effect(KILL cr); 6026 format %{ "decode_heap_oop $dst,$src" %} 6027 ins_encode %{ 6028 Register s = $src$$Register; 6029 Register d = $dst$$Register; 6030 if (s != d) { 6031 __ movq(d, s); 6032 } 6033 __ decode_heap_oop(d); 6034 %} 6035 ins_pipe(ialu_reg_long); 6036 %} 6037 6038 instruct decodeHeapOop_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6039 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 6040 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 6041 match(Set dst (DecodeN src)); 6042 effect(KILL cr); 6043 format %{ "decode_heap_oop_not_null $dst,$src" %} 6044 ins_encode %{ 6045 Register s = $src$$Register; 6046 Register d = $dst$$Register; 6047 if (s != d) { 6048 __ decode_heap_oop_not_null(d, s); 6049 } else { 6050 __ decode_heap_oop_not_null(d); 6051 } 6052 %} 6053 ins_pipe(ialu_reg_long); 6054 %} 6055 6056 instruct encodeKlass_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6057 match(Set dst (EncodePKlass src)); 6058 effect(TEMP dst, KILL cr); 6059 format %{ "encode_and_move_klass_not_null $dst,$src" %} 6060 ins_encode %{ 6061 __ encode_and_move_klass_not_null($dst$$Register, $src$$Register); 6062 %} 6063 ins_pipe(ialu_reg_long); 6064 %} 6065 6066 instruct decodeKlass_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6067 match(Set dst (DecodeNKlass src)); 6068 effect(TEMP dst, KILL cr); 6069 format %{ "decode_and_move_klass_not_null $dst,$src" %} 6070 ins_encode %{ 6071 __ decode_and_move_klass_not_null($dst$$Register, $src$$Register); 6072 %} 6073 ins_pipe(ialu_reg_long); 6074 %} 6075 6076 //----------Conditional Move--------------------------------------------------- 6077 // Jump 6078 // dummy instruction for generating temp registers 6079 instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{ 6080 match(Jump (LShiftL switch_val shift)); 6081 ins_cost(350); 6082 predicate(false); 6083 effect(TEMP dest); 6084 6085 format %{ "leaq $dest, [$constantaddress]\n\t" 6086 "jmp [$dest + $switch_val << $shift]\n\t" %} 6087 ins_encode %{ 6088 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6089 // to do that and the compiler is using that register as one it can allocate. 6090 // So we build it all by hand. 6091 // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant); 6092 // ArrayAddress dispatch(table, index); 6093 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant); 6094 __ lea($dest$$Register, $constantaddress); 6095 __ jmp(dispatch); 6096 %} 6097 ins_pipe(pipe_jmp); 6098 %} 6099 6100 instruct jumpXtnd_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{ 6101 match(Jump (AddL (LShiftL switch_val shift) offset)); 6102 ins_cost(350); 6103 effect(TEMP dest); 6104 6105 format %{ "leaq $dest, [$constantaddress]\n\t" 6106 "jmp [$dest + $switch_val << $shift + $offset]\n\t" %} 6107 ins_encode %{ 6108 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6109 // to do that and the compiler is using that register as one it can allocate. 6110 // So we build it all by hand. 6111 // Address index(noreg, switch_reg, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6112 // ArrayAddress dispatch(table, index); 6113 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6114 __ lea($dest$$Register, $constantaddress); 6115 __ jmp(dispatch); 6116 %} 6117 ins_pipe(pipe_jmp); 6118 %} 6119 6120 instruct jumpXtnd(rRegL switch_val, rRegI dest) %{ 6121 match(Jump switch_val); 6122 ins_cost(350); 6123 effect(TEMP dest); 6124 6125 format %{ "leaq $dest, [$constantaddress]\n\t" 6126 "jmp [$dest + $switch_val]\n\t" %} 6127 ins_encode %{ 6128 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6129 // to do that and the compiler is using that register as one it can allocate. 6130 // So we build it all by hand. 6131 // Address index(noreg, switch_reg, Address::times_1); 6132 // ArrayAddress dispatch(table, index); 6133 Address dispatch($dest$$Register, $switch_val$$Register, Address::times_1); 6134 __ lea($dest$$Register, $constantaddress); 6135 __ jmp(dispatch); 6136 %} 6137 ins_pipe(pipe_jmp); 6138 %} 6139 6140 // Conditional move 6141 instruct cmovI_imm_01(rRegI dst, immI_1 src, rFlagsReg cr, cmpOp cop) 6142 %{ 6143 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_int() == 0); 6144 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6145 6146 ins_cost(100); // XXX 6147 format %{ "setbn$cop $dst\t# signed, int" %} 6148 ins_encode %{ 6149 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6150 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6151 %} 6152 ins_pipe(ialu_reg); 6153 %} 6154 6155 instruct cmovI_reg(rRegI dst, rRegI src, rFlagsReg cr, cmpOp cop) 6156 %{ 6157 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6158 6159 ins_cost(200); // XXX 6160 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6161 ins_encode %{ 6162 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6163 %} 6164 ins_pipe(pipe_cmov_reg); 6165 %} 6166 6167 instruct cmovI_imm_01U(rRegI dst, immI_1 src, rFlagsRegU cr, cmpOpU cop) 6168 %{ 6169 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_int() == 0); 6170 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6171 6172 ins_cost(100); // XXX 6173 format %{ "setbn$cop $dst\t# unsigned, int" %} 6174 ins_encode %{ 6175 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6176 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6177 %} 6178 ins_pipe(ialu_reg); 6179 %} 6180 6181 instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{ 6182 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6183 6184 ins_cost(200); // XXX 6185 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6186 ins_encode %{ 6187 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6188 %} 6189 ins_pipe(pipe_cmov_reg); 6190 %} 6191 6192 instruct cmovI_imm_01UCF(rRegI dst, immI_1 src, rFlagsRegUCF cr, cmpOpUCF cop) 6193 %{ 6194 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_int() == 0); 6195 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6196 6197 ins_cost(100); // XXX 6198 format %{ "setbn$cop $dst\t# unsigned, int" %} 6199 ins_encode %{ 6200 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6201 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6202 %} 6203 ins_pipe(ialu_reg); 6204 %} 6205 6206 instruct cmovI_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6207 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6208 ins_cost(200); 6209 expand %{ 6210 cmovI_regU(cop, cr, dst, src); 6211 %} 6212 %} 6213 6214 instruct cmovI_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6215 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6216 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6217 6218 ins_cost(200); // XXX 6219 format %{ "cmovpl $dst, $src\n\t" 6220 "cmovnel $dst, $src" %} 6221 ins_encode %{ 6222 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6223 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6224 %} 6225 ins_pipe(pipe_cmov_reg); 6226 %} 6227 6228 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6229 // inputs of the CMove 6230 instruct cmovI_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6231 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6232 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6233 6234 ins_cost(200); // XXX 6235 format %{ "cmovpl $dst, $src\n\t" 6236 "cmovnel $dst, $src" %} 6237 ins_encode %{ 6238 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6239 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6240 %} 6241 ins_pipe(pipe_cmov_reg); 6242 %} 6243 6244 // Conditional move 6245 instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{ 6246 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6247 6248 ins_cost(250); // XXX 6249 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6250 ins_encode %{ 6251 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6252 %} 6253 ins_pipe(pipe_cmov_mem); 6254 %} 6255 6256 // Conditional move 6257 instruct cmovI_memU(cmpOpU cop, rFlagsRegU cr, rRegI dst, memory src) 6258 %{ 6259 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6260 6261 ins_cost(250); // XXX 6262 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6263 ins_encode %{ 6264 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6265 %} 6266 ins_pipe(pipe_cmov_mem); 6267 %} 6268 6269 instruct cmovI_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, memory src) %{ 6270 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6271 ins_cost(250); 6272 expand %{ 6273 cmovI_memU(cop, cr, dst, src); 6274 %} 6275 %} 6276 6277 // Conditional move 6278 instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop) 6279 %{ 6280 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6281 6282 ins_cost(200); // XXX 6283 format %{ "cmovl$cop $dst, $src\t# signed, compressed ptr" %} 6284 ins_encode %{ 6285 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6286 %} 6287 ins_pipe(pipe_cmov_reg); 6288 %} 6289 6290 // Conditional move 6291 instruct cmovN_regU(cmpOpU cop, rFlagsRegU cr, rRegN dst, rRegN src) 6292 %{ 6293 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6294 6295 ins_cost(200); // XXX 6296 format %{ "cmovl$cop $dst, $src\t# unsigned, compressed ptr" %} 6297 ins_encode %{ 6298 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6299 %} 6300 ins_pipe(pipe_cmov_reg); 6301 %} 6302 6303 instruct cmovN_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6304 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6305 ins_cost(200); 6306 expand %{ 6307 cmovN_regU(cop, cr, dst, src); 6308 %} 6309 %} 6310 6311 instruct cmovN_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6312 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6313 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6314 6315 ins_cost(200); // XXX 6316 format %{ "cmovpl $dst, $src\n\t" 6317 "cmovnel $dst, $src" %} 6318 ins_encode %{ 6319 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6320 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6321 %} 6322 ins_pipe(pipe_cmov_reg); 6323 %} 6324 6325 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6326 // inputs of the CMove 6327 instruct cmovN_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6328 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6329 match(Set dst (CMoveN (Binary cop cr) (Binary src dst))); 6330 6331 ins_cost(200); // XXX 6332 format %{ "cmovpl $dst, $src\n\t" 6333 "cmovnel $dst, $src" %} 6334 ins_encode %{ 6335 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6336 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6337 %} 6338 ins_pipe(pipe_cmov_reg); 6339 %} 6340 6341 // Conditional move 6342 instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop) 6343 %{ 6344 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6345 6346 ins_cost(200); // XXX 6347 format %{ "cmovq$cop $dst, $src\t# signed, ptr" %} 6348 ins_encode %{ 6349 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6350 %} 6351 ins_pipe(pipe_cmov_reg); // XXX 6352 %} 6353 6354 // Conditional move 6355 instruct cmovP_regU(cmpOpU cop, rFlagsRegU cr, rRegP dst, rRegP src) 6356 %{ 6357 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6358 6359 ins_cost(200); // XXX 6360 format %{ "cmovq$cop $dst, $src\t# unsigned, ptr" %} 6361 ins_encode %{ 6362 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6363 %} 6364 ins_pipe(pipe_cmov_reg); // XXX 6365 %} 6366 6367 instruct cmovP_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6368 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6369 ins_cost(200); 6370 expand %{ 6371 cmovP_regU(cop, cr, dst, src); 6372 %} 6373 %} 6374 6375 instruct cmovP_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6376 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6377 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6378 6379 ins_cost(200); // XXX 6380 format %{ "cmovpq $dst, $src\n\t" 6381 "cmovneq $dst, $src" %} 6382 ins_encode %{ 6383 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6384 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6385 %} 6386 ins_pipe(pipe_cmov_reg); 6387 %} 6388 6389 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6390 // inputs of the CMove 6391 instruct cmovP_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6392 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6393 match(Set dst (CMoveP (Binary cop cr) (Binary src dst))); 6394 6395 ins_cost(200); // XXX 6396 format %{ "cmovpq $dst, $src\n\t" 6397 "cmovneq $dst, $src" %} 6398 ins_encode %{ 6399 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6400 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6401 %} 6402 ins_pipe(pipe_cmov_reg); 6403 %} 6404 6405 instruct cmovL_imm_01(rRegL dst, immL1 src, rFlagsReg cr, cmpOp cop) 6406 %{ 6407 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_long() == 0); 6408 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6409 6410 ins_cost(100); // XXX 6411 format %{ "setbn$cop $dst\t# signed, long" %} 6412 ins_encode %{ 6413 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6414 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6415 %} 6416 ins_pipe(ialu_reg); 6417 %} 6418 6419 instruct cmovL_reg(cmpOp cop, rFlagsReg cr, rRegL dst, rRegL src) 6420 %{ 6421 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6422 6423 ins_cost(200); // XXX 6424 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6425 ins_encode %{ 6426 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6427 %} 6428 ins_pipe(pipe_cmov_reg); // XXX 6429 %} 6430 6431 instruct cmovL_mem(cmpOp cop, rFlagsReg cr, rRegL dst, memory src) 6432 %{ 6433 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6434 6435 ins_cost(200); // XXX 6436 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6437 ins_encode %{ 6438 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6439 %} 6440 ins_pipe(pipe_cmov_mem); // XXX 6441 %} 6442 6443 instruct cmovL_imm_01U(rRegL dst, immL1 src, rFlagsRegU cr, cmpOpU cop) 6444 %{ 6445 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_long() == 0); 6446 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6447 6448 ins_cost(100); // XXX 6449 format %{ "setbn$cop $dst\t# unsigned, long" %} 6450 ins_encode %{ 6451 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6452 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6453 %} 6454 ins_pipe(ialu_reg); 6455 %} 6456 6457 instruct cmovL_regU(cmpOpU cop, rFlagsRegU cr, rRegL dst, rRegL src) 6458 %{ 6459 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6460 6461 ins_cost(200); // XXX 6462 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 6463 ins_encode %{ 6464 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6465 %} 6466 ins_pipe(pipe_cmov_reg); // XXX 6467 %} 6468 6469 instruct cmovL_imm_01UCF(rRegL dst, immL1 src, rFlagsRegUCF cr, cmpOpUCF cop) 6470 %{ 6471 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_long() == 0); 6472 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6473 6474 ins_cost(100); // XXX 6475 format %{ "setbn$cop $dst\t# unsigned, long" %} 6476 ins_encode %{ 6477 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6478 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6479 %} 6480 ins_pipe(ialu_reg); 6481 %} 6482 6483 instruct cmovL_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6484 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6485 ins_cost(200); 6486 expand %{ 6487 cmovL_regU(cop, cr, dst, src); 6488 %} 6489 %} 6490 6491 instruct cmovL_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6492 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6493 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6494 6495 ins_cost(200); // XXX 6496 format %{ "cmovpq $dst, $src\n\t" 6497 "cmovneq $dst, $src" %} 6498 ins_encode %{ 6499 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6500 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6501 %} 6502 ins_pipe(pipe_cmov_reg); 6503 %} 6504 6505 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6506 // inputs of the CMove 6507 instruct cmovL_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6508 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6509 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6510 6511 ins_cost(200); // XXX 6512 format %{ "cmovpq $dst, $src\n\t" 6513 "cmovneq $dst, $src" %} 6514 ins_encode %{ 6515 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6516 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6517 %} 6518 ins_pipe(pipe_cmov_reg); 6519 %} 6520 6521 instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src) 6522 %{ 6523 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6524 6525 ins_cost(200); // XXX 6526 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 6527 ins_encode %{ 6528 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6529 %} 6530 ins_pipe(pipe_cmov_mem); // XXX 6531 %} 6532 6533 instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{ 6534 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6535 ins_cost(200); 6536 expand %{ 6537 cmovL_memU(cop, cr, dst, src); 6538 %} 6539 %} 6540 6541 instruct cmovF_reg(cmpOp cop, rFlagsReg 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# signed 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_regU(cmpOpU cop, rFlagsRegU cr, regF dst, regF src) 6560 %{ 6561 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6562 6563 ins_cost(200); // XXX 6564 format %{ "jn$cop skip\t# unsigned cmove float\n\t" 6565 "movss $dst, $src\n" 6566 "skip:" %} 6567 ins_encode %{ 6568 Label Lskip; 6569 // Invert sense of branch from sense of CMOV 6570 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6571 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 6572 __ bind(Lskip); 6573 %} 6574 ins_pipe(pipe_slow); 6575 %} 6576 6577 instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{ 6578 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6579 ins_cost(200); 6580 expand %{ 6581 cmovF_regU(cop, cr, dst, src); 6582 %} 6583 %} 6584 6585 instruct cmovD_reg(cmpOp cop, rFlagsReg 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# signed 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_regU(cmpOpU cop, rFlagsRegU cr, regD dst, regD src) 6604 %{ 6605 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6606 6607 ins_cost(200); // XXX 6608 format %{ "jn$cop skip\t# unsigned cmove double\n\t" 6609 "movsd $dst, $src\n" 6610 "skip:" %} 6611 ins_encode %{ 6612 Label Lskip; 6613 // Invert sense of branch from sense of CMOV 6614 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6615 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 6616 __ bind(Lskip); 6617 %} 6618 ins_pipe(pipe_slow); 6619 %} 6620 6621 instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{ 6622 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6623 ins_cost(200); 6624 expand %{ 6625 cmovD_regU(cop, cr, dst, src); 6626 %} 6627 %} 6628 6629 //----------Arithmetic Instructions-------------------------------------------- 6630 //----------Addition Instructions---------------------------------------------- 6631 6632 instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 6633 %{ 6634 match(Set dst (AddI dst src)); 6635 effect(KILL cr); 6636 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); 6637 format %{ "addl $dst, $src\t# int" %} 6638 ins_encode %{ 6639 __ addl($dst$$Register, $src$$Register); 6640 %} 6641 ins_pipe(ialu_reg_reg); 6642 %} 6643 6644 instruct addI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 6645 %{ 6646 match(Set dst (AddI dst src)); 6647 effect(KILL cr); 6648 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); 6649 6650 format %{ "addl $dst, $src\t# int" %} 6651 ins_encode %{ 6652 __ addl($dst$$Register, $src$$constant); 6653 %} 6654 ins_pipe( ialu_reg ); 6655 %} 6656 6657 instruct addI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 6658 %{ 6659 match(Set dst (AddI dst (LoadI src))); 6660 effect(KILL cr); 6661 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); 6662 6663 ins_cost(150); // XXX 6664 format %{ "addl $dst, $src\t# int" %} 6665 ins_encode %{ 6666 __ addl($dst$$Register, $src$$Address); 6667 %} 6668 ins_pipe(ialu_reg_mem); 6669 %} 6670 6671 instruct addI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 6672 %{ 6673 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6674 effect(KILL cr); 6675 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); 6676 6677 ins_cost(150); // XXX 6678 format %{ "addl $dst, $src\t# int" %} 6679 ins_encode %{ 6680 __ addl($dst$$Address, $src$$Register); 6681 %} 6682 ins_pipe(ialu_mem_reg); 6683 %} 6684 6685 instruct addI_mem_imm(memory dst, immI src, rFlagsReg cr) 6686 %{ 6687 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6688 effect(KILL cr); 6689 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); 6690 6691 6692 ins_cost(125); // XXX 6693 format %{ "addl $dst, $src\t# int" %} 6694 ins_encode %{ 6695 __ addl($dst$$Address, $src$$constant); 6696 %} 6697 ins_pipe(ialu_mem_imm); 6698 %} 6699 6700 instruct incI_rReg(rRegI dst, immI_1 src, rFlagsReg cr) 6701 %{ 6702 predicate(UseIncDec); 6703 match(Set dst (AddI dst src)); 6704 effect(KILL cr); 6705 6706 format %{ "incl $dst\t# int" %} 6707 ins_encode %{ 6708 __ incrementl($dst$$Register); 6709 %} 6710 ins_pipe(ialu_reg); 6711 %} 6712 6713 instruct incI_mem(memory dst, immI_1 src, rFlagsReg cr) 6714 %{ 6715 predicate(UseIncDec); 6716 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6717 effect(KILL cr); 6718 6719 ins_cost(125); // XXX 6720 format %{ "incl $dst\t# int" %} 6721 ins_encode %{ 6722 __ incrementl($dst$$Address); 6723 %} 6724 ins_pipe(ialu_mem_imm); 6725 %} 6726 6727 // XXX why does that use AddI 6728 instruct decI_rReg(rRegI dst, immI_M1 src, rFlagsReg cr) 6729 %{ 6730 predicate(UseIncDec); 6731 match(Set dst (AddI dst src)); 6732 effect(KILL cr); 6733 6734 format %{ "decl $dst\t# int" %} 6735 ins_encode %{ 6736 __ decrementl($dst$$Register); 6737 %} 6738 ins_pipe(ialu_reg); 6739 %} 6740 6741 // XXX why does that use AddI 6742 instruct decI_mem(memory dst, immI_M1 src, rFlagsReg cr) 6743 %{ 6744 predicate(UseIncDec); 6745 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6746 effect(KILL cr); 6747 6748 ins_cost(125); // XXX 6749 format %{ "decl $dst\t# int" %} 6750 ins_encode %{ 6751 __ decrementl($dst$$Address); 6752 %} 6753 ins_pipe(ialu_mem_imm); 6754 %} 6755 6756 instruct leaI_rReg_immI2_immI(rRegI dst, rRegI index, immI2 scale, immI disp) 6757 %{ 6758 predicate(VM_Version::supports_fast_2op_lea()); 6759 match(Set dst (AddI (LShiftI index scale) disp)); 6760 6761 format %{ "leal $dst, [$index << $scale + $disp]\t# int" %} 6762 ins_encode %{ 6763 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 6764 __ leal($dst$$Register, Address(noreg, $index$$Register, scale, $disp$$constant)); 6765 %} 6766 ins_pipe(ialu_reg_reg); 6767 %} 6768 6769 instruct leaI_rReg_rReg_immI(rRegI dst, rRegI base, rRegI index, immI disp) 6770 %{ 6771 predicate(VM_Version::supports_fast_3op_lea()); 6772 match(Set dst (AddI (AddI base index) disp)); 6773 6774 format %{ "leal $dst, [$base + $index + $disp]\t# int" %} 6775 ins_encode %{ 6776 __ leal($dst$$Register, Address($base$$Register, $index$$Register, Address::times_1, $disp$$constant)); 6777 %} 6778 ins_pipe(ialu_reg_reg); 6779 %} 6780 6781 instruct leaI_rReg_rReg_immI2(rRegI dst, no_rbp_r13_RegI base, rRegI index, immI2 scale) 6782 %{ 6783 predicate(VM_Version::supports_fast_2op_lea()); 6784 match(Set dst (AddI base (LShiftI index scale))); 6785 6786 format %{ "leal $dst, [$base + $index << $scale]\t# int" %} 6787 ins_encode %{ 6788 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 6789 __ leal($dst$$Register, Address($base$$Register, $index$$Register, scale)); 6790 %} 6791 ins_pipe(ialu_reg_reg); 6792 %} 6793 6794 instruct leaI_rReg_rReg_immI2_immI(rRegI dst, rRegI base, rRegI index, immI2 scale, immI disp) 6795 %{ 6796 predicate(VM_Version::supports_fast_3op_lea()); 6797 match(Set dst (AddI (AddI base (LShiftI index scale)) disp)); 6798 6799 format %{ "leal $dst, [$base + $index << $scale + $disp]\t# int" %} 6800 ins_encode %{ 6801 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 6802 __ leal($dst$$Register, Address($base$$Register, $index$$Register, scale, $disp$$constant)); 6803 %} 6804 ins_pipe(ialu_reg_reg); 6805 %} 6806 6807 instruct addL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 6808 %{ 6809 match(Set dst (AddL dst src)); 6810 effect(KILL cr); 6811 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); 6812 6813 format %{ "addq $dst, $src\t# long" %} 6814 ins_encode %{ 6815 __ addq($dst$$Register, $src$$Register); 6816 %} 6817 ins_pipe(ialu_reg_reg); 6818 %} 6819 6820 instruct addL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 6821 %{ 6822 match(Set dst (AddL dst src)); 6823 effect(KILL cr); 6824 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); 6825 6826 format %{ "addq $dst, $src\t# long" %} 6827 ins_encode %{ 6828 __ addq($dst$$Register, $src$$constant); 6829 %} 6830 ins_pipe( ialu_reg ); 6831 %} 6832 6833 instruct addL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 6834 %{ 6835 match(Set dst (AddL dst (LoadL src))); 6836 effect(KILL cr); 6837 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); 6838 6839 ins_cost(150); // XXX 6840 format %{ "addq $dst, $src\t# long" %} 6841 ins_encode %{ 6842 __ addq($dst$$Register, $src$$Address); 6843 %} 6844 ins_pipe(ialu_reg_mem); 6845 %} 6846 6847 instruct addL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 6848 %{ 6849 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 6850 effect(KILL cr); 6851 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); 6852 6853 ins_cost(150); // XXX 6854 format %{ "addq $dst, $src\t# long" %} 6855 ins_encode %{ 6856 __ addq($dst$$Address, $src$$Register); 6857 %} 6858 ins_pipe(ialu_mem_reg); 6859 %} 6860 6861 instruct addL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 6862 %{ 6863 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 6864 effect(KILL cr); 6865 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); 6866 6867 ins_cost(125); // XXX 6868 format %{ "addq $dst, $src\t# long" %} 6869 ins_encode %{ 6870 __ addq($dst$$Address, $src$$constant); 6871 %} 6872 ins_pipe(ialu_mem_imm); 6873 %} 6874 6875 instruct incL_rReg(rRegI dst, immL1 src, rFlagsReg cr) 6876 %{ 6877 predicate(UseIncDec); 6878 match(Set dst (AddL dst src)); 6879 effect(KILL cr); 6880 6881 format %{ "incq $dst\t# long" %} 6882 ins_encode %{ 6883 __ incrementq($dst$$Register); 6884 %} 6885 ins_pipe(ialu_reg); 6886 %} 6887 6888 instruct incL_mem(memory dst, immL1 src, rFlagsReg cr) 6889 %{ 6890 predicate(UseIncDec); 6891 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 6892 effect(KILL cr); 6893 6894 ins_cost(125); // XXX 6895 format %{ "incq $dst\t# long" %} 6896 ins_encode %{ 6897 __ incrementq($dst$$Address); 6898 %} 6899 ins_pipe(ialu_mem_imm); 6900 %} 6901 6902 // XXX why does that use AddL 6903 instruct decL_rReg(rRegL dst, immL_M1 src, rFlagsReg cr) 6904 %{ 6905 predicate(UseIncDec); 6906 match(Set dst (AddL dst src)); 6907 effect(KILL cr); 6908 6909 format %{ "decq $dst\t# long" %} 6910 ins_encode %{ 6911 __ decrementq($dst$$Register); 6912 %} 6913 ins_pipe(ialu_reg); 6914 %} 6915 6916 // XXX why does that use AddL 6917 instruct decL_mem(memory dst, immL_M1 src, rFlagsReg cr) 6918 %{ 6919 predicate(UseIncDec); 6920 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 6921 effect(KILL cr); 6922 6923 ins_cost(125); // XXX 6924 format %{ "decq $dst\t# long" %} 6925 ins_encode %{ 6926 __ decrementq($dst$$Address); 6927 %} 6928 ins_pipe(ialu_mem_imm); 6929 %} 6930 6931 instruct leaL_rReg_immI2_immL32(rRegL dst, rRegL index, immI2 scale, immL32 disp) 6932 %{ 6933 predicate(VM_Version::supports_fast_2op_lea()); 6934 match(Set dst (AddL (LShiftL index scale) disp)); 6935 6936 format %{ "leaq $dst, [$index << $scale + $disp]\t# long" %} 6937 ins_encode %{ 6938 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 6939 __ leaq($dst$$Register, Address(noreg, $index$$Register, scale, $disp$$constant)); 6940 %} 6941 ins_pipe(ialu_reg_reg); 6942 %} 6943 6944 instruct leaL_rReg_rReg_immL32(rRegL dst, rRegL base, rRegL index, immL32 disp) 6945 %{ 6946 predicate(VM_Version::supports_fast_3op_lea()); 6947 match(Set dst (AddL (AddL base index) disp)); 6948 6949 format %{ "leaq $dst, [$base + $index + $disp]\t# long" %} 6950 ins_encode %{ 6951 __ leaq($dst$$Register, Address($base$$Register, $index$$Register, Address::times_1, $disp$$constant)); 6952 %} 6953 ins_pipe(ialu_reg_reg); 6954 %} 6955 6956 instruct leaL_rReg_rReg_immI2(rRegL dst, no_rbp_r13_RegL base, rRegL index, immI2 scale) 6957 %{ 6958 predicate(VM_Version::supports_fast_2op_lea()); 6959 match(Set dst (AddL base (LShiftL index scale))); 6960 6961 format %{ "leaq $dst, [$base + $index << $scale]\t# long" %} 6962 ins_encode %{ 6963 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 6964 __ leaq($dst$$Register, Address($base$$Register, $index$$Register, scale)); 6965 %} 6966 ins_pipe(ialu_reg_reg); 6967 %} 6968 6969 instruct leaL_rReg_rReg_immI2_immL32(rRegL dst, rRegL base, rRegL index, immI2 scale, immL32 disp) 6970 %{ 6971 predicate(VM_Version::supports_fast_3op_lea()); 6972 match(Set dst (AddL (AddL base (LShiftL index scale)) disp)); 6973 6974 format %{ "leaq $dst, [$base + $index << $scale + $disp]\t# long" %} 6975 ins_encode %{ 6976 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 6977 __ leaq($dst$$Register, Address($base$$Register, $index$$Register, scale, $disp$$constant)); 6978 %} 6979 ins_pipe(ialu_reg_reg); 6980 %} 6981 6982 instruct addP_rReg(rRegP dst, rRegL src, rFlagsReg cr) 6983 %{ 6984 match(Set dst (AddP dst src)); 6985 effect(KILL cr); 6986 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); 6987 6988 format %{ "addq $dst, $src\t# ptr" %} 6989 ins_encode %{ 6990 __ addq($dst$$Register, $src$$Register); 6991 %} 6992 ins_pipe(ialu_reg_reg); 6993 %} 6994 6995 instruct addP_rReg_imm(rRegP dst, immL32 src, rFlagsReg cr) 6996 %{ 6997 match(Set dst (AddP dst src)); 6998 effect(KILL cr); 6999 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); 7000 7001 format %{ "addq $dst, $src\t# ptr" %} 7002 ins_encode %{ 7003 __ addq($dst$$Register, $src$$constant); 7004 %} 7005 ins_pipe( ialu_reg ); 7006 %} 7007 7008 // XXX addP mem ops ???? 7009 7010 instruct checkCastPP(rRegP dst) 7011 %{ 7012 match(Set dst (CheckCastPP dst)); 7013 7014 size(0); 7015 format %{ "# checkcastPP of $dst" %} 7016 ins_encode(/* empty encoding */); 7017 ins_pipe(empty); 7018 %} 7019 7020 instruct castPP(rRegP dst) 7021 %{ 7022 match(Set dst (CastPP dst)); 7023 7024 size(0); 7025 format %{ "# castPP of $dst" %} 7026 ins_encode(/* empty encoding */); 7027 ins_pipe(empty); 7028 %} 7029 7030 instruct castII(rRegI dst) 7031 %{ 7032 match(Set dst (CastII dst)); 7033 7034 size(0); 7035 format %{ "# castII of $dst" %} 7036 ins_encode(/* empty encoding */); 7037 ins_cost(0); 7038 ins_pipe(empty); 7039 %} 7040 7041 instruct castLL(rRegL dst) 7042 %{ 7043 match(Set dst (CastLL dst)); 7044 7045 size(0); 7046 format %{ "# castLL of $dst" %} 7047 ins_encode(/* empty encoding */); 7048 ins_cost(0); 7049 ins_pipe(empty); 7050 %} 7051 7052 instruct castFF(regF dst) 7053 %{ 7054 match(Set dst (CastFF dst)); 7055 7056 size(0); 7057 format %{ "# castFF of $dst" %} 7058 ins_encode(/* empty encoding */); 7059 ins_cost(0); 7060 ins_pipe(empty); 7061 %} 7062 7063 instruct castDD(regD dst) 7064 %{ 7065 match(Set dst (CastDD dst)); 7066 7067 size(0); 7068 format %{ "# castDD of $dst" %} 7069 ins_encode(/* empty encoding */); 7070 ins_cost(0); 7071 ins_pipe(empty); 7072 %} 7073 7074 // XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them 7075 instruct compareAndSwapP(rRegI res, 7076 memory mem_ptr, 7077 rax_RegP oldval, rRegP newval, 7078 rFlagsReg cr) 7079 %{ 7080 predicate(n->as_LoadStore()->barrier_data() == 0); 7081 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); 7082 match(Set res (WeakCompareAndSwapP mem_ptr (Binary oldval newval))); 7083 effect(KILL cr, KILL oldval); 7084 7085 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7086 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7087 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7088 ins_encode %{ 7089 __ lock(); 7090 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7091 __ setcc(Assembler::equal, $res$$Register); 7092 %} 7093 ins_pipe( pipe_cmpxchg ); 7094 %} 7095 7096 instruct compareAndSwapL(rRegI res, 7097 memory mem_ptr, 7098 rax_RegL oldval, rRegL newval, 7099 rFlagsReg cr) 7100 %{ 7101 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval))); 7102 match(Set res (WeakCompareAndSwapL mem_ptr (Binary oldval newval))); 7103 effect(KILL cr, KILL oldval); 7104 7105 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7106 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7107 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7108 ins_encode %{ 7109 __ lock(); 7110 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7111 __ setcc(Assembler::equal, $res$$Register); 7112 %} 7113 ins_pipe( pipe_cmpxchg ); 7114 %} 7115 7116 instruct compareAndSwapI(rRegI res, 7117 memory mem_ptr, 7118 rax_RegI oldval, rRegI newval, 7119 rFlagsReg cr) 7120 %{ 7121 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval))); 7122 match(Set res (WeakCompareAndSwapI mem_ptr (Binary oldval newval))); 7123 effect(KILL cr, KILL oldval); 7124 7125 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7126 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7127 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7128 ins_encode %{ 7129 __ lock(); 7130 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7131 __ setcc(Assembler::equal, $res$$Register); 7132 %} 7133 ins_pipe( pipe_cmpxchg ); 7134 %} 7135 7136 instruct compareAndSwapB(rRegI res, 7137 memory mem_ptr, 7138 rax_RegI oldval, rRegI newval, 7139 rFlagsReg cr) 7140 %{ 7141 match(Set res (CompareAndSwapB mem_ptr (Binary oldval newval))); 7142 match(Set res (WeakCompareAndSwapB mem_ptr (Binary oldval newval))); 7143 effect(KILL cr, KILL oldval); 7144 7145 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7146 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7147 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7148 ins_encode %{ 7149 __ lock(); 7150 __ cmpxchgb($newval$$Register, $mem_ptr$$Address); 7151 __ setcc(Assembler::equal, $res$$Register); 7152 %} 7153 ins_pipe( pipe_cmpxchg ); 7154 %} 7155 7156 instruct compareAndSwapS(rRegI res, 7157 memory mem_ptr, 7158 rax_RegI oldval, rRegI newval, 7159 rFlagsReg cr) 7160 %{ 7161 match(Set res (CompareAndSwapS mem_ptr (Binary oldval newval))); 7162 match(Set res (WeakCompareAndSwapS mem_ptr (Binary oldval newval))); 7163 effect(KILL cr, KILL oldval); 7164 7165 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7166 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7167 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7168 ins_encode %{ 7169 __ lock(); 7170 __ cmpxchgw($newval$$Register, $mem_ptr$$Address); 7171 __ setcc(Assembler::equal, $res$$Register); 7172 %} 7173 ins_pipe( pipe_cmpxchg ); 7174 %} 7175 7176 instruct compareAndSwapN(rRegI res, 7177 memory mem_ptr, 7178 rax_RegN oldval, rRegN newval, 7179 rFlagsReg cr) %{ 7180 predicate(n->as_LoadStore()->barrier_data() == 0); 7181 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval))); 7182 match(Set res (WeakCompareAndSwapN mem_ptr (Binary oldval newval))); 7183 effect(KILL cr, KILL oldval); 7184 7185 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7186 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7187 "setcc $res \t# emits sete + movzbl or setzue for APX" %} 7188 ins_encode %{ 7189 __ lock(); 7190 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7191 __ setcc(Assembler::equal, $res$$Register); 7192 %} 7193 ins_pipe( pipe_cmpxchg ); 7194 %} 7195 7196 instruct compareAndExchangeB( 7197 memory mem_ptr, 7198 rax_RegI oldval, rRegI newval, 7199 rFlagsReg cr) 7200 %{ 7201 match(Set oldval (CompareAndExchangeB mem_ptr (Binary oldval newval))); 7202 effect(KILL cr); 7203 7204 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7205 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7206 ins_encode %{ 7207 __ lock(); 7208 __ cmpxchgb($newval$$Register, $mem_ptr$$Address); 7209 %} 7210 ins_pipe( pipe_cmpxchg ); 7211 %} 7212 7213 instruct compareAndExchangeS( 7214 memory mem_ptr, 7215 rax_RegI oldval, rRegI newval, 7216 rFlagsReg cr) 7217 %{ 7218 match(Set oldval (CompareAndExchangeS mem_ptr (Binary oldval newval))); 7219 effect(KILL cr); 7220 7221 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7222 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7223 ins_encode %{ 7224 __ lock(); 7225 __ cmpxchgw($newval$$Register, $mem_ptr$$Address); 7226 %} 7227 ins_pipe( pipe_cmpxchg ); 7228 %} 7229 7230 instruct compareAndExchangeI( 7231 memory mem_ptr, 7232 rax_RegI oldval, rRegI newval, 7233 rFlagsReg cr) 7234 %{ 7235 match(Set oldval (CompareAndExchangeI mem_ptr (Binary oldval newval))); 7236 effect(KILL cr); 7237 7238 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7239 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7240 ins_encode %{ 7241 __ lock(); 7242 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7243 %} 7244 ins_pipe( pipe_cmpxchg ); 7245 %} 7246 7247 instruct compareAndExchangeL( 7248 memory mem_ptr, 7249 rax_RegL oldval, rRegL newval, 7250 rFlagsReg cr) 7251 %{ 7252 match(Set oldval (CompareAndExchangeL mem_ptr (Binary oldval newval))); 7253 effect(KILL cr); 7254 7255 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7256 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7257 ins_encode %{ 7258 __ lock(); 7259 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7260 %} 7261 ins_pipe( pipe_cmpxchg ); 7262 %} 7263 7264 instruct compareAndExchangeN( 7265 memory mem_ptr, 7266 rax_RegN oldval, rRegN newval, 7267 rFlagsReg cr) %{ 7268 predicate(n->as_LoadStore()->barrier_data() == 0); 7269 match(Set oldval (CompareAndExchangeN mem_ptr (Binary oldval newval))); 7270 effect(KILL cr); 7271 7272 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7273 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7274 ins_encode %{ 7275 __ lock(); 7276 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7277 %} 7278 ins_pipe( pipe_cmpxchg ); 7279 %} 7280 7281 instruct compareAndExchangeP( 7282 memory mem_ptr, 7283 rax_RegP oldval, rRegP newval, 7284 rFlagsReg cr) 7285 %{ 7286 predicate(n->as_LoadStore()->barrier_data() == 0); 7287 match(Set oldval (CompareAndExchangeP mem_ptr (Binary oldval newval))); 7288 effect(KILL cr); 7289 7290 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7291 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7292 ins_encode %{ 7293 __ lock(); 7294 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7295 %} 7296 ins_pipe( pipe_cmpxchg ); 7297 %} 7298 7299 instruct xaddB_reg_no_res(memory mem, Universe dummy, rRegI add, rFlagsReg cr) %{ 7300 predicate(n->as_LoadStore()->result_not_used()); 7301 match(Set dummy (GetAndAddB mem add)); 7302 effect(KILL cr); 7303 format %{ "addb_lock $mem, $add" %} 7304 ins_encode %{ 7305 __ lock(); 7306 __ addb($mem$$Address, $add$$Register); 7307 %} 7308 ins_pipe(pipe_cmpxchg); 7309 %} 7310 7311 instruct xaddB_imm_no_res(memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7312 predicate(n->as_LoadStore()->result_not_used()); 7313 match(Set dummy (GetAndAddB mem add)); 7314 effect(KILL cr); 7315 format %{ "addb_lock $mem, $add" %} 7316 ins_encode %{ 7317 __ lock(); 7318 __ addb($mem$$Address, $add$$constant); 7319 %} 7320 ins_pipe(pipe_cmpxchg); 7321 %} 7322 7323 instruct xaddB(memory mem, rRegI newval, rFlagsReg cr) %{ 7324 predicate(!n->as_LoadStore()->result_not_used()); 7325 match(Set newval (GetAndAddB mem newval)); 7326 effect(KILL cr); 7327 format %{ "xaddb_lock $mem, $newval" %} 7328 ins_encode %{ 7329 __ lock(); 7330 __ xaddb($mem$$Address, $newval$$Register); 7331 %} 7332 ins_pipe(pipe_cmpxchg); 7333 %} 7334 7335 instruct xaddS_reg_no_res(memory mem, Universe dummy, rRegI add, rFlagsReg cr) %{ 7336 predicate(n->as_LoadStore()->result_not_used()); 7337 match(Set dummy (GetAndAddS mem add)); 7338 effect(KILL cr); 7339 format %{ "addw_lock $mem, $add" %} 7340 ins_encode %{ 7341 __ lock(); 7342 __ addw($mem$$Address, $add$$Register); 7343 %} 7344 ins_pipe(pipe_cmpxchg); 7345 %} 7346 7347 instruct xaddS_imm_no_res(memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7348 predicate(UseStoreImmI16 && n->as_LoadStore()->result_not_used()); 7349 match(Set dummy (GetAndAddS mem add)); 7350 effect(KILL cr); 7351 format %{ "addw_lock $mem, $add" %} 7352 ins_encode %{ 7353 __ lock(); 7354 __ addw($mem$$Address, $add$$constant); 7355 %} 7356 ins_pipe(pipe_cmpxchg); 7357 %} 7358 7359 instruct xaddS(memory mem, rRegI newval, rFlagsReg cr) %{ 7360 predicate(!n->as_LoadStore()->result_not_used()); 7361 match(Set newval (GetAndAddS mem newval)); 7362 effect(KILL cr); 7363 format %{ "xaddw_lock $mem, $newval" %} 7364 ins_encode %{ 7365 __ lock(); 7366 __ xaddw($mem$$Address, $newval$$Register); 7367 %} 7368 ins_pipe(pipe_cmpxchg); 7369 %} 7370 7371 instruct xaddI_reg_no_res(memory mem, Universe dummy, rRegI add, rFlagsReg cr) %{ 7372 predicate(n->as_LoadStore()->result_not_used()); 7373 match(Set dummy (GetAndAddI mem add)); 7374 effect(KILL cr); 7375 format %{ "addl_lock $mem, $add" %} 7376 ins_encode %{ 7377 __ lock(); 7378 __ addl($mem$$Address, $add$$Register); 7379 %} 7380 ins_pipe(pipe_cmpxchg); 7381 %} 7382 7383 instruct xaddI_imm_no_res(memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7384 predicate(n->as_LoadStore()->result_not_used()); 7385 match(Set dummy (GetAndAddI mem add)); 7386 effect(KILL cr); 7387 format %{ "addl_lock $mem, $add" %} 7388 ins_encode %{ 7389 __ lock(); 7390 __ addl($mem$$Address, $add$$constant); 7391 %} 7392 ins_pipe(pipe_cmpxchg); 7393 %} 7394 7395 instruct xaddI(memory mem, rRegI newval, rFlagsReg cr) %{ 7396 predicate(!n->as_LoadStore()->result_not_used()); 7397 match(Set newval (GetAndAddI mem newval)); 7398 effect(KILL cr); 7399 format %{ "xaddl_lock $mem, $newval" %} 7400 ins_encode %{ 7401 __ lock(); 7402 __ xaddl($mem$$Address, $newval$$Register); 7403 %} 7404 ins_pipe(pipe_cmpxchg); 7405 %} 7406 7407 instruct xaddL_reg_no_res(memory mem, Universe dummy, rRegL add, rFlagsReg cr) %{ 7408 predicate(n->as_LoadStore()->result_not_used()); 7409 match(Set dummy (GetAndAddL mem add)); 7410 effect(KILL cr); 7411 format %{ "addq_lock $mem, $add" %} 7412 ins_encode %{ 7413 __ lock(); 7414 __ addq($mem$$Address, $add$$Register); 7415 %} 7416 ins_pipe(pipe_cmpxchg); 7417 %} 7418 7419 instruct xaddL_imm_no_res(memory mem, Universe dummy, immL32 add, rFlagsReg cr) %{ 7420 predicate(n->as_LoadStore()->result_not_used()); 7421 match(Set dummy (GetAndAddL mem add)); 7422 effect(KILL cr); 7423 format %{ "addq_lock $mem, $add" %} 7424 ins_encode %{ 7425 __ lock(); 7426 __ addq($mem$$Address, $add$$constant); 7427 %} 7428 ins_pipe(pipe_cmpxchg); 7429 %} 7430 7431 instruct xaddL(memory mem, rRegL newval, rFlagsReg cr) %{ 7432 predicate(!n->as_LoadStore()->result_not_used()); 7433 match(Set newval (GetAndAddL mem newval)); 7434 effect(KILL cr); 7435 format %{ "xaddq_lock $mem, $newval" %} 7436 ins_encode %{ 7437 __ lock(); 7438 __ xaddq($mem$$Address, $newval$$Register); 7439 %} 7440 ins_pipe(pipe_cmpxchg); 7441 %} 7442 7443 instruct xchgB( memory mem, rRegI newval) %{ 7444 match(Set newval (GetAndSetB mem newval)); 7445 format %{ "XCHGB $newval,[$mem]" %} 7446 ins_encode %{ 7447 __ xchgb($newval$$Register, $mem$$Address); 7448 %} 7449 ins_pipe( pipe_cmpxchg ); 7450 %} 7451 7452 instruct xchgS( memory mem, rRegI newval) %{ 7453 match(Set newval (GetAndSetS mem newval)); 7454 format %{ "XCHGW $newval,[$mem]" %} 7455 ins_encode %{ 7456 __ xchgw($newval$$Register, $mem$$Address); 7457 %} 7458 ins_pipe( pipe_cmpxchg ); 7459 %} 7460 7461 instruct xchgI( memory mem, rRegI newval) %{ 7462 match(Set newval (GetAndSetI mem newval)); 7463 format %{ "XCHGL $newval,[$mem]" %} 7464 ins_encode %{ 7465 __ xchgl($newval$$Register, $mem$$Address); 7466 %} 7467 ins_pipe( pipe_cmpxchg ); 7468 %} 7469 7470 instruct xchgL( memory mem, rRegL newval) %{ 7471 match(Set newval (GetAndSetL mem newval)); 7472 format %{ "XCHGL $newval,[$mem]" %} 7473 ins_encode %{ 7474 __ xchgq($newval$$Register, $mem$$Address); 7475 %} 7476 ins_pipe( pipe_cmpxchg ); 7477 %} 7478 7479 instruct xchgP( memory mem, rRegP newval) %{ 7480 match(Set newval (GetAndSetP mem newval)); 7481 predicate(n->as_LoadStore()->barrier_data() == 0); 7482 format %{ "XCHGQ $newval,[$mem]" %} 7483 ins_encode %{ 7484 __ xchgq($newval$$Register, $mem$$Address); 7485 %} 7486 ins_pipe( pipe_cmpxchg ); 7487 %} 7488 7489 instruct xchgN( memory mem, rRegN newval) %{ 7490 predicate(n->as_LoadStore()->barrier_data() == 0); 7491 match(Set newval (GetAndSetN mem newval)); 7492 format %{ "XCHGL $newval,$mem]" %} 7493 ins_encode %{ 7494 __ xchgl($newval$$Register, $mem$$Address); 7495 %} 7496 ins_pipe( pipe_cmpxchg ); 7497 %} 7498 7499 //----------Abs Instructions------------------------------------------- 7500 7501 // Integer Absolute Instructions 7502 instruct absI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7503 %{ 7504 match(Set dst (AbsI src)); 7505 effect(TEMP dst, KILL cr); 7506 format %{ "xorl $dst, $dst\t# abs int\n\t" 7507 "subl $dst, $src\n\t" 7508 "cmovll $dst, $src" %} 7509 ins_encode %{ 7510 __ xorl($dst$$Register, $dst$$Register); 7511 __ subl($dst$$Register, $src$$Register); 7512 __ cmovl(Assembler::less, $dst$$Register, $src$$Register); 7513 %} 7514 7515 ins_pipe(ialu_reg_reg); 7516 %} 7517 7518 // Long Absolute Instructions 7519 instruct absL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7520 %{ 7521 match(Set dst (AbsL src)); 7522 effect(TEMP dst, KILL cr); 7523 format %{ "xorl $dst, $dst\t# abs long\n\t" 7524 "subq $dst, $src\n\t" 7525 "cmovlq $dst, $src" %} 7526 ins_encode %{ 7527 __ xorl($dst$$Register, $dst$$Register); 7528 __ subq($dst$$Register, $src$$Register); 7529 __ cmovq(Assembler::less, $dst$$Register, $src$$Register); 7530 %} 7531 7532 ins_pipe(ialu_reg_reg); 7533 %} 7534 7535 //----------Subtraction Instructions------------------------------------------- 7536 7537 // Integer Subtraction Instructions 7538 instruct subI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7539 %{ 7540 match(Set dst (SubI dst src)); 7541 effect(KILL cr); 7542 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); 7543 7544 format %{ "subl $dst, $src\t# int" %} 7545 ins_encode %{ 7546 __ subl($dst$$Register, $src$$Register); 7547 %} 7548 ins_pipe(ialu_reg_reg); 7549 %} 7550 7551 instruct subI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 7552 %{ 7553 match(Set dst (SubI dst (LoadI src))); 7554 effect(KILL cr); 7555 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); 7556 7557 ins_cost(150); 7558 format %{ "subl $dst, $src\t# int" %} 7559 ins_encode %{ 7560 __ subl($dst$$Register, $src$$Address); 7561 %} 7562 ins_pipe(ialu_reg_mem); 7563 %} 7564 7565 instruct subI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 7566 %{ 7567 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 7568 effect(KILL cr); 7569 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); 7570 7571 ins_cost(150); 7572 format %{ "subl $dst, $src\t# int" %} 7573 ins_encode %{ 7574 __ subl($dst$$Address, $src$$Register); 7575 %} 7576 ins_pipe(ialu_mem_reg); 7577 %} 7578 7579 instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7580 %{ 7581 match(Set dst (SubL dst src)); 7582 effect(KILL cr); 7583 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); 7584 7585 format %{ "subq $dst, $src\t# long" %} 7586 ins_encode %{ 7587 __ subq($dst$$Register, $src$$Register); 7588 %} 7589 ins_pipe(ialu_reg_reg); 7590 %} 7591 7592 instruct subL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 7593 %{ 7594 match(Set dst (SubL dst (LoadL src))); 7595 effect(KILL cr); 7596 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); 7597 7598 ins_cost(150); 7599 format %{ "subq $dst, $src\t# long" %} 7600 ins_encode %{ 7601 __ subq($dst$$Register, $src$$Address); 7602 %} 7603 ins_pipe(ialu_reg_mem); 7604 %} 7605 7606 instruct subL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 7607 %{ 7608 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 7609 effect(KILL cr); 7610 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); 7611 7612 ins_cost(150); 7613 format %{ "subq $dst, $src\t# long" %} 7614 ins_encode %{ 7615 __ subq($dst$$Address, $src$$Register); 7616 %} 7617 ins_pipe(ialu_mem_reg); 7618 %} 7619 7620 // Subtract from a pointer 7621 // XXX hmpf??? 7622 instruct subP_rReg(rRegP dst, rRegI src, immI_0 zero, rFlagsReg cr) 7623 %{ 7624 match(Set dst (AddP dst (SubI zero src))); 7625 effect(KILL cr); 7626 7627 format %{ "subq $dst, $src\t# ptr - int" %} 7628 ins_encode %{ 7629 __ subq($dst$$Register, $src$$Register); 7630 %} 7631 ins_pipe(ialu_reg_reg); 7632 %} 7633 7634 instruct negI_rReg(rRegI dst, immI_0 zero, rFlagsReg cr) 7635 %{ 7636 match(Set dst (SubI zero dst)); 7637 effect(KILL cr); 7638 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7639 7640 format %{ "negl $dst\t# int" %} 7641 ins_encode %{ 7642 __ negl($dst$$Register); 7643 %} 7644 ins_pipe(ialu_reg); 7645 %} 7646 7647 instruct negI_rReg_2(rRegI dst, rFlagsReg cr) 7648 %{ 7649 match(Set dst (NegI dst)); 7650 effect(KILL cr); 7651 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7652 7653 format %{ "negl $dst\t# int" %} 7654 ins_encode %{ 7655 __ negl($dst$$Register); 7656 %} 7657 ins_pipe(ialu_reg); 7658 %} 7659 7660 instruct negI_mem(memory dst, immI_0 zero, rFlagsReg cr) 7661 %{ 7662 match(Set dst (StoreI dst (SubI zero (LoadI dst)))); 7663 effect(KILL cr); 7664 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7665 7666 format %{ "negl $dst\t# int" %} 7667 ins_encode %{ 7668 __ negl($dst$$Address); 7669 %} 7670 ins_pipe(ialu_reg); 7671 %} 7672 7673 instruct negL_rReg(rRegL dst, immL0 zero, rFlagsReg cr) 7674 %{ 7675 match(Set dst (SubL zero dst)); 7676 effect(KILL cr); 7677 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7678 7679 format %{ "negq $dst\t# long" %} 7680 ins_encode %{ 7681 __ negq($dst$$Register); 7682 %} 7683 ins_pipe(ialu_reg); 7684 %} 7685 7686 instruct negL_rReg_2(rRegL dst, rFlagsReg cr) 7687 %{ 7688 match(Set dst (NegL dst)); 7689 effect(KILL cr); 7690 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7691 7692 format %{ "negq $dst\t# int" %} 7693 ins_encode %{ 7694 __ negq($dst$$Register); 7695 %} 7696 ins_pipe(ialu_reg); 7697 %} 7698 7699 instruct negL_mem(memory dst, immL0 zero, rFlagsReg cr) 7700 %{ 7701 match(Set dst (StoreL dst (SubL zero (LoadL dst)))); 7702 effect(KILL cr); 7703 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7704 7705 format %{ "negq $dst\t# long" %} 7706 ins_encode %{ 7707 __ negq($dst$$Address); 7708 %} 7709 ins_pipe(ialu_reg); 7710 %} 7711 7712 //----------Multiplication/Division Instructions------------------------------- 7713 // Integer Multiplication Instructions 7714 // Multiply Register 7715 7716 instruct mulI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7717 %{ 7718 match(Set dst (MulI dst src)); 7719 effect(KILL cr); 7720 7721 ins_cost(300); 7722 format %{ "imull $dst, $src\t# int" %} 7723 ins_encode %{ 7724 __ imull($dst$$Register, $src$$Register); 7725 %} 7726 ins_pipe(ialu_reg_reg_alu0); 7727 %} 7728 7729 instruct mulI_rReg_imm(rRegI dst, rRegI src, immI imm, rFlagsReg cr) 7730 %{ 7731 match(Set dst (MulI src imm)); 7732 effect(KILL cr); 7733 7734 ins_cost(300); 7735 format %{ "imull $dst, $src, $imm\t# int" %} 7736 ins_encode %{ 7737 __ imull($dst$$Register, $src$$Register, $imm$$constant); 7738 %} 7739 ins_pipe(ialu_reg_reg_alu0); 7740 %} 7741 7742 instruct mulI_mem(rRegI dst, memory src, rFlagsReg cr) 7743 %{ 7744 match(Set dst (MulI dst (LoadI src))); 7745 effect(KILL cr); 7746 7747 ins_cost(350); 7748 format %{ "imull $dst, $src\t# int" %} 7749 ins_encode %{ 7750 __ imull($dst$$Register, $src$$Address); 7751 %} 7752 ins_pipe(ialu_reg_mem_alu0); 7753 %} 7754 7755 instruct mulI_mem_imm(rRegI dst, memory src, immI imm, rFlagsReg cr) 7756 %{ 7757 match(Set dst (MulI (LoadI src) imm)); 7758 effect(KILL cr); 7759 7760 ins_cost(300); 7761 format %{ "imull $dst, $src, $imm\t# int" %} 7762 ins_encode %{ 7763 __ imull($dst$$Register, $src$$Address, $imm$$constant); 7764 %} 7765 ins_pipe(ialu_reg_mem_alu0); 7766 %} 7767 7768 instruct mulAddS2I_rReg(rRegI dst, rRegI src1, rRegI src2, rRegI src3, rFlagsReg cr) 7769 %{ 7770 match(Set dst (MulAddS2I (Binary dst src1) (Binary src2 src3))); 7771 effect(KILL cr, KILL src2); 7772 7773 expand %{ mulI_rReg(dst, src1, cr); 7774 mulI_rReg(src2, src3, cr); 7775 addI_rReg(dst, src2, cr); %} 7776 %} 7777 7778 instruct mulL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7779 %{ 7780 match(Set dst (MulL dst src)); 7781 effect(KILL cr); 7782 7783 ins_cost(300); 7784 format %{ "imulq $dst, $src\t# long" %} 7785 ins_encode %{ 7786 __ imulq($dst$$Register, $src$$Register); 7787 %} 7788 ins_pipe(ialu_reg_reg_alu0); 7789 %} 7790 7791 instruct mulL_rReg_imm(rRegL dst, rRegL src, immL32 imm, rFlagsReg cr) 7792 %{ 7793 match(Set dst (MulL src imm)); 7794 effect(KILL cr); 7795 7796 ins_cost(300); 7797 format %{ "imulq $dst, $src, $imm\t# long" %} 7798 ins_encode %{ 7799 __ imulq($dst$$Register, $src$$Register, $imm$$constant); 7800 %} 7801 ins_pipe(ialu_reg_reg_alu0); 7802 %} 7803 7804 instruct mulL_mem(rRegL dst, memory src, rFlagsReg cr) 7805 %{ 7806 match(Set dst (MulL dst (LoadL src))); 7807 effect(KILL cr); 7808 7809 ins_cost(350); 7810 format %{ "imulq $dst, $src\t# long" %} 7811 ins_encode %{ 7812 __ imulq($dst$$Register, $src$$Address); 7813 %} 7814 ins_pipe(ialu_reg_mem_alu0); 7815 %} 7816 7817 instruct mulL_mem_imm(rRegL dst, memory src, immL32 imm, rFlagsReg cr) 7818 %{ 7819 match(Set dst (MulL (LoadL src) imm)); 7820 effect(KILL cr); 7821 7822 ins_cost(300); 7823 format %{ "imulq $dst, $src, $imm\t# long" %} 7824 ins_encode %{ 7825 __ imulq($dst$$Register, $src$$Address, $imm$$constant); 7826 %} 7827 ins_pipe(ialu_reg_mem_alu0); 7828 %} 7829 7830 instruct mulHiL_rReg(rdx_RegL dst, rRegL src, rax_RegL rax, rFlagsReg cr) 7831 %{ 7832 match(Set dst (MulHiL src rax)); 7833 effect(USE_KILL rax, KILL cr); 7834 7835 ins_cost(300); 7836 format %{ "imulq RDX:RAX, RAX, $src\t# mulhi" %} 7837 ins_encode %{ 7838 __ imulq($src$$Register); 7839 %} 7840 ins_pipe(ialu_reg_reg_alu0); 7841 %} 7842 7843 instruct umulHiL_rReg(rdx_RegL dst, rRegL src, rax_RegL rax, rFlagsReg cr) 7844 %{ 7845 match(Set dst (UMulHiL src rax)); 7846 effect(USE_KILL rax, KILL cr); 7847 7848 ins_cost(300); 7849 format %{ "mulq RDX:RAX, RAX, $src\t# umulhi" %} 7850 ins_encode %{ 7851 __ mulq($src$$Register); 7852 %} 7853 ins_pipe(ialu_reg_reg_alu0); 7854 %} 7855 7856 instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 7857 rFlagsReg cr) 7858 %{ 7859 match(Set rax (DivI rax div)); 7860 effect(KILL rdx, KILL cr); 7861 7862 ins_cost(30*100+10*100); // XXX 7863 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 7864 "jne,s normal\n\t" 7865 "xorl rdx, rdx\n\t" 7866 "cmpl $div, -1\n\t" 7867 "je,s done\n" 7868 "normal: cdql\n\t" 7869 "idivl $div\n" 7870 "done:" %} 7871 ins_encode(cdql_enc(div)); 7872 ins_pipe(ialu_reg_reg_alu0); 7873 %} 7874 7875 instruct divL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 7876 rFlagsReg cr) 7877 %{ 7878 match(Set rax (DivL rax div)); 7879 effect(KILL rdx, KILL cr); 7880 7881 ins_cost(30*100+10*100); // XXX 7882 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 7883 "cmpq rax, rdx\n\t" 7884 "jne,s normal\n\t" 7885 "xorl rdx, rdx\n\t" 7886 "cmpq $div, -1\n\t" 7887 "je,s done\n" 7888 "normal: cdqq\n\t" 7889 "idivq $div\n" 7890 "done:" %} 7891 ins_encode(cdqq_enc(div)); 7892 ins_pipe(ialu_reg_reg_alu0); 7893 %} 7894 7895 instruct udivI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, rFlagsReg cr) 7896 %{ 7897 match(Set rax (UDivI rax div)); 7898 effect(KILL rdx, KILL cr); 7899 7900 ins_cost(300); 7901 format %{ "udivl $rax,$rax,$div\t# UDivI\n" %} 7902 ins_encode %{ 7903 __ udivI($rax$$Register, $div$$Register, $rdx$$Register); 7904 %} 7905 ins_pipe(ialu_reg_reg_alu0); 7906 %} 7907 7908 instruct udivL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, rFlagsReg cr) 7909 %{ 7910 match(Set rax (UDivL rax div)); 7911 effect(KILL rdx, KILL cr); 7912 7913 ins_cost(300); 7914 format %{ "udivq $rax,$rax,$div\t# UDivL\n" %} 7915 ins_encode %{ 7916 __ udivL($rax$$Register, $div$$Register, $rdx$$Register); 7917 %} 7918 ins_pipe(ialu_reg_reg_alu0); 7919 %} 7920 7921 // Integer DIVMOD with Register, both quotient and mod results 7922 instruct divModI_rReg_divmod(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 7923 rFlagsReg cr) 7924 %{ 7925 match(DivModI rax div); 7926 effect(KILL cr); 7927 7928 ins_cost(30*100+10*100); // XXX 7929 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 7930 "jne,s normal\n\t" 7931 "xorl rdx, rdx\n\t" 7932 "cmpl $div, -1\n\t" 7933 "je,s done\n" 7934 "normal: cdql\n\t" 7935 "idivl $div\n" 7936 "done:" %} 7937 ins_encode(cdql_enc(div)); 7938 ins_pipe(pipe_slow); 7939 %} 7940 7941 // Long DIVMOD with Register, both quotient and mod results 7942 instruct divModL_rReg_divmod(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 7943 rFlagsReg cr) 7944 %{ 7945 match(DivModL rax div); 7946 effect(KILL cr); 7947 7948 ins_cost(30*100+10*100); // XXX 7949 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 7950 "cmpq rax, rdx\n\t" 7951 "jne,s normal\n\t" 7952 "xorl rdx, rdx\n\t" 7953 "cmpq $div, -1\n\t" 7954 "je,s done\n" 7955 "normal: cdqq\n\t" 7956 "idivq $div\n" 7957 "done:" %} 7958 ins_encode(cdqq_enc(div)); 7959 ins_pipe(pipe_slow); 7960 %} 7961 7962 // Unsigned integer DIVMOD with Register, both quotient and mod results 7963 instruct udivModI_rReg_divmod(rax_RegI rax, no_rax_rdx_RegI tmp, rdx_RegI rdx, 7964 no_rax_rdx_RegI div, rFlagsReg cr) 7965 %{ 7966 match(UDivModI rax div); 7967 effect(TEMP tmp, KILL cr); 7968 7969 ins_cost(300); 7970 format %{ "udivl $rax,$rax,$div\t# begin UDivModI\n\t" 7971 "umodl $rdx,$rax,$div\t! using $tmp as TEMP # end UDivModI\n" 7972 %} 7973 ins_encode %{ 7974 __ udivmodI($rax$$Register, $div$$Register, $rdx$$Register, $tmp$$Register); 7975 %} 7976 ins_pipe(pipe_slow); 7977 %} 7978 7979 // Unsigned long DIVMOD with Register, both quotient and mod results 7980 instruct udivModL_rReg_divmod(rax_RegL rax, no_rax_rdx_RegL tmp, rdx_RegL rdx, 7981 no_rax_rdx_RegL div, rFlagsReg cr) 7982 %{ 7983 match(UDivModL rax div); 7984 effect(TEMP tmp, KILL cr); 7985 7986 ins_cost(300); 7987 format %{ "udivq $rax,$rax,$div\t# begin UDivModL\n\t" 7988 "umodq $rdx,$rax,$div\t! using $tmp as TEMP # end UDivModL\n" 7989 %} 7990 ins_encode %{ 7991 __ udivmodL($rax$$Register, $div$$Register, $rdx$$Register, $tmp$$Register); 7992 %} 7993 ins_pipe(pipe_slow); 7994 %} 7995 7996 instruct modI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, 7997 rFlagsReg cr) 7998 %{ 7999 match(Set rdx (ModI rax div)); 8000 effect(KILL rax, KILL cr); 8001 8002 ins_cost(300); // XXX 8003 format %{ "cmpl rax, 0x80000000\t# irem\n\t" 8004 "jne,s normal\n\t" 8005 "xorl rdx, rdx\n\t" 8006 "cmpl $div, -1\n\t" 8007 "je,s done\n" 8008 "normal: cdql\n\t" 8009 "idivl $div\n" 8010 "done:" %} 8011 ins_encode(cdql_enc(div)); 8012 ins_pipe(ialu_reg_reg_alu0); 8013 %} 8014 8015 instruct modL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, 8016 rFlagsReg cr) 8017 %{ 8018 match(Set rdx (ModL rax div)); 8019 effect(KILL rax, KILL cr); 8020 8021 ins_cost(300); // XXX 8022 format %{ "movq rdx, 0x8000000000000000\t# lrem\n\t" 8023 "cmpq rax, rdx\n\t" 8024 "jne,s normal\n\t" 8025 "xorl rdx, rdx\n\t" 8026 "cmpq $div, -1\n\t" 8027 "je,s done\n" 8028 "normal: cdqq\n\t" 8029 "idivq $div\n" 8030 "done:" %} 8031 ins_encode(cdqq_enc(div)); 8032 ins_pipe(ialu_reg_reg_alu0); 8033 %} 8034 8035 instruct umodI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, rFlagsReg cr) 8036 %{ 8037 match(Set rdx (UModI rax div)); 8038 effect(KILL rax, KILL cr); 8039 8040 ins_cost(300); 8041 format %{ "umodl $rdx,$rax,$div\t# UModI\n" %} 8042 ins_encode %{ 8043 __ umodI($rax$$Register, $div$$Register, $rdx$$Register); 8044 %} 8045 ins_pipe(ialu_reg_reg_alu0); 8046 %} 8047 8048 instruct umodL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, rFlagsReg cr) 8049 %{ 8050 match(Set rdx (UModL rax div)); 8051 effect(KILL rax, KILL cr); 8052 8053 ins_cost(300); 8054 format %{ "umodq $rdx,$rax,$div\t# UModL\n" %} 8055 ins_encode %{ 8056 __ umodL($rax$$Register, $div$$Register, $rdx$$Register); 8057 %} 8058 ins_pipe(ialu_reg_reg_alu0); 8059 %} 8060 8061 // Integer Shift Instructions 8062 // Shift Left by one, two, three 8063 instruct salI_rReg_immI2(rRegI dst, immI2 shift, rFlagsReg cr) 8064 %{ 8065 match(Set dst (LShiftI dst shift)); 8066 effect(KILL cr); 8067 8068 format %{ "sall $dst, $shift" %} 8069 ins_encode %{ 8070 __ sall($dst$$Register, $shift$$constant); 8071 %} 8072 ins_pipe(ialu_reg); 8073 %} 8074 8075 // Shift Left by 8-bit immediate 8076 instruct salI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8077 %{ 8078 match(Set dst (LShiftI dst shift)); 8079 effect(KILL cr); 8080 8081 format %{ "sall $dst, $shift" %} 8082 ins_encode %{ 8083 __ sall($dst$$Register, $shift$$constant); 8084 %} 8085 ins_pipe(ialu_reg); 8086 %} 8087 8088 // Shift Left by 8-bit immediate 8089 instruct salI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8090 %{ 8091 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8092 effect(KILL cr); 8093 8094 format %{ "sall $dst, $shift" %} 8095 ins_encode %{ 8096 __ sall($dst$$Address, $shift$$constant); 8097 %} 8098 ins_pipe(ialu_mem_imm); 8099 %} 8100 8101 // Shift Left by variable 8102 instruct salI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8103 %{ 8104 predicate(!VM_Version::supports_bmi2()); 8105 match(Set dst (LShiftI dst shift)); 8106 effect(KILL cr); 8107 8108 format %{ "sall $dst, $shift" %} 8109 ins_encode %{ 8110 __ sall($dst$$Register); 8111 %} 8112 ins_pipe(ialu_reg_reg); 8113 %} 8114 8115 // Shift Left by variable 8116 instruct salI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8117 %{ 8118 predicate(!VM_Version::supports_bmi2()); 8119 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8120 effect(KILL cr); 8121 8122 format %{ "sall $dst, $shift" %} 8123 ins_encode %{ 8124 __ sall($dst$$Address); 8125 %} 8126 ins_pipe(ialu_mem_reg); 8127 %} 8128 8129 instruct salI_rReg_rReg(rRegI dst, rRegI src, rRegI shift) 8130 %{ 8131 predicate(VM_Version::supports_bmi2()); 8132 match(Set dst (LShiftI src shift)); 8133 8134 format %{ "shlxl $dst, $src, $shift" %} 8135 ins_encode %{ 8136 __ shlxl($dst$$Register, $src$$Register, $shift$$Register); 8137 %} 8138 ins_pipe(ialu_reg_reg); 8139 %} 8140 8141 instruct salI_mem_rReg(rRegI dst, memory src, rRegI shift) 8142 %{ 8143 predicate(VM_Version::supports_bmi2()); 8144 match(Set dst (LShiftI (LoadI src) shift)); 8145 ins_cost(175); 8146 format %{ "shlxl $dst, $src, $shift" %} 8147 ins_encode %{ 8148 __ shlxl($dst$$Register, $src$$Address, $shift$$Register); 8149 %} 8150 ins_pipe(ialu_reg_mem); 8151 %} 8152 8153 // Arithmetic Shift Right by 8-bit immediate 8154 instruct sarI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8155 %{ 8156 match(Set dst (RShiftI dst shift)); 8157 effect(KILL cr); 8158 8159 format %{ "sarl $dst, $shift" %} 8160 ins_encode %{ 8161 __ sarl($dst$$Register, $shift$$constant); 8162 %} 8163 ins_pipe(ialu_mem_imm); 8164 %} 8165 8166 // Arithmetic Shift Right by 8-bit immediate 8167 instruct sarI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8168 %{ 8169 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8170 effect(KILL cr); 8171 8172 format %{ "sarl $dst, $shift" %} 8173 ins_encode %{ 8174 __ sarl($dst$$Address, $shift$$constant); 8175 %} 8176 ins_pipe(ialu_mem_imm); 8177 %} 8178 8179 // Arithmetic Shift Right by variable 8180 instruct sarI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8181 %{ 8182 predicate(!VM_Version::supports_bmi2()); 8183 match(Set dst (RShiftI dst shift)); 8184 effect(KILL cr); 8185 8186 format %{ "sarl $dst, $shift" %} 8187 ins_encode %{ 8188 __ sarl($dst$$Register); 8189 %} 8190 ins_pipe(ialu_reg_reg); 8191 %} 8192 8193 // Arithmetic Shift Right by variable 8194 instruct sarI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8195 %{ 8196 predicate(!VM_Version::supports_bmi2()); 8197 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8198 effect(KILL cr); 8199 8200 format %{ "sarl $dst, $shift" %} 8201 ins_encode %{ 8202 __ sarl($dst$$Address); 8203 %} 8204 ins_pipe(ialu_mem_reg); 8205 %} 8206 8207 instruct sarI_rReg_rReg(rRegI dst, rRegI src, rRegI shift) 8208 %{ 8209 predicate(VM_Version::supports_bmi2()); 8210 match(Set dst (RShiftI src shift)); 8211 8212 format %{ "sarxl $dst, $src, $shift" %} 8213 ins_encode %{ 8214 __ sarxl($dst$$Register, $src$$Register, $shift$$Register); 8215 %} 8216 ins_pipe(ialu_reg_reg); 8217 %} 8218 8219 instruct sarI_mem_rReg(rRegI dst, memory src, rRegI shift) 8220 %{ 8221 predicate(VM_Version::supports_bmi2()); 8222 match(Set dst (RShiftI (LoadI src) shift)); 8223 ins_cost(175); 8224 format %{ "sarxl $dst, $src, $shift" %} 8225 ins_encode %{ 8226 __ sarxl($dst$$Register, $src$$Address, $shift$$Register); 8227 %} 8228 ins_pipe(ialu_reg_mem); 8229 %} 8230 8231 // Logical Shift Right by 8-bit immediate 8232 instruct shrI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8233 %{ 8234 match(Set dst (URShiftI dst shift)); 8235 effect(KILL cr); 8236 8237 format %{ "shrl $dst, $shift" %} 8238 ins_encode %{ 8239 __ shrl($dst$$Register, $shift$$constant); 8240 %} 8241 ins_pipe(ialu_reg); 8242 %} 8243 8244 // Logical Shift Right by 8-bit immediate 8245 instruct shrI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8246 %{ 8247 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8248 effect(KILL cr); 8249 8250 format %{ "shrl $dst, $shift" %} 8251 ins_encode %{ 8252 __ shrl($dst$$Address, $shift$$constant); 8253 %} 8254 ins_pipe(ialu_mem_imm); 8255 %} 8256 8257 // Logical Shift Right by variable 8258 instruct shrI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8259 %{ 8260 predicate(!VM_Version::supports_bmi2()); 8261 match(Set dst (URShiftI dst shift)); 8262 effect(KILL cr); 8263 8264 format %{ "shrl $dst, $shift" %} 8265 ins_encode %{ 8266 __ shrl($dst$$Register); 8267 %} 8268 ins_pipe(ialu_reg_reg); 8269 %} 8270 8271 // Logical Shift Right by variable 8272 instruct shrI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8273 %{ 8274 predicate(!VM_Version::supports_bmi2()); 8275 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8276 effect(KILL cr); 8277 8278 format %{ "shrl $dst, $shift" %} 8279 ins_encode %{ 8280 __ shrl($dst$$Address); 8281 %} 8282 ins_pipe(ialu_mem_reg); 8283 %} 8284 8285 instruct shrI_rReg_rReg(rRegI dst, rRegI src, rRegI shift) 8286 %{ 8287 predicate(VM_Version::supports_bmi2()); 8288 match(Set dst (URShiftI src shift)); 8289 8290 format %{ "shrxl $dst, $src, $shift" %} 8291 ins_encode %{ 8292 __ shrxl($dst$$Register, $src$$Register, $shift$$Register); 8293 %} 8294 ins_pipe(ialu_reg_reg); 8295 %} 8296 8297 instruct shrI_mem_rReg(rRegI dst, memory src, rRegI shift) 8298 %{ 8299 predicate(VM_Version::supports_bmi2()); 8300 match(Set dst (URShiftI (LoadI src) shift)); 8301 ins_cost(175); 8302 format %{ "shrxl $dst, $src, $shift" %} 8303 ins_encode %{ 8304 __ shrxl($dst$$Register, $src$$Address, $shift$$Register); 8305 %} 8306 ins_pipe(ialu_reg_mem); 8307 %} 8308 8309 // Long Shift Instructions 8310 // Shift Left by one, two, three 8311 instruct salL_rReg_immI2(rRegL dst, immI2 shift, rFlagsReg cr) 8312 %{ 8313 match(Set dst (LShiftL dst shift)); 8314 effect(KILL cr); 8315 8316 format %{ "salq $dst, $shift" %} 8317 ins_encode %{ 8318 __ salq($dst$$Register, $shift$$constant); 8319 %} 8320 ins_pipe(ialu_reg); 8321 %} 8322 8323 // Shift Left by 8-bit immediate 8324 instruct salL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8325 %{ 8326 match(Set dst (LShiftL dst shift)); 8327 effect(KILL cr); 8328 8329 format %{ "salq $dst, $shift" %} 8330 ins_encode %{ 8331 __ salq($dst$$Register, $shift$$constant); 8332 %} 8333 ins_pipe(ialu_reg); 8334 %} 8335 8336 // Shift Left by 8-bit immediate 8337 instruct salL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8338 %{ 8339 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8340 effect(KILL cr); 8341 8342 format %{ "salq $dst, $shift" %} 8343 ins_encode %{ 8344 __ salq($dst$$Address, $shift$$constant); 8345 %} 8346 ins_pipe(ialu_mem_imm); 8347 %} 8348 8349 // Shift Left by variable 8350 instruct salL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8351 %{ 8352 predicate(!VM_Version::supports_bmi2()); 8353 match(Set dst (LShiftL dst shift)); 8354 effect(KILL cr); 8355 8356 format %{ "salq $dst, $shift" %} 8357 ins_encode %{ 8358 __ salq($dst$$Register); 8359 %} 8360 ins_pipe(ialu_reg_reg); 8361 %} 8362 8363 // Shift Left by variable 8364 instruct salL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8365 %{ 8366 predicate(!VM_Version::supports_bmi2()); 8367 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8368 effect(KILL cr); 8369 8370 format %{ "salq $dst, $shift" %} 8371 ins_encode %{ 8372 __ salq($dst$$Address); 8373 %} 8374 ins_pipe(ialu_mem_reg); 8375 %} 8376 8377 instruct salL_rReg_rReg(rRegL dst, rRegL src, rRegI shift) 8378 %{ 8379 predicate(VM_Version::supports_bmi2()); 8380 match(Set dst (LShiftL src shift)); 8381 8382 format %{ "shlxq $dst, $src, $shift" %} 8383 ins_encode %{ 8384 __ shlxq($dst$$Register, $src$$Register, $shift$$Register); 8385 %} 8386 ins_pipe(ialu_reg_reg); 8387 %} 8388 8389 instruct salL_mem_rReg(rRegL dst, memory src, rRegI shift) 8390 %{ 8391 predicate(VM_Version::supports_bmi2()); 8392 match(Set dst (LShiftL (LoadL src) shift)); 8393 ins_cost(175); 8394 format %{ "shlxq $dst, $src, $shift" %} 8395 ins_encode %{ 8396 __ shlxq($dst$$Register, $src$$Address, $shift$$Register); 8397 %} 8398 ins_pipe(ialu_reg_mem); 8399 %} 8400 8401 // Arithmetic Shift Right by 8-bit immediate 8402 instruct sarL_rReg_imm(rRegL dst, immI shift, rFlagsReg cr) 8403 %{ 8404 match(Set dst (RShiftL dst shift)); 8405 effect(KILL cr); 8406 8407 format %{ "sarq $dst, $shift" %} 8408 ins_encode %{ 8409 __ sarq($dst$$Register, (unsigned char)($shift$$constant & 0x3F)); 8410 %} 8411 ins_pipe(ialu_mem_imm); 8412 %} 8413 8414 // Arithmetic Shift Right by 8-bit immediate 8415 instruct sarL_mem_imm(memory dst, immI shift, rFlagsReg cr) 8416 %{ 8417 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8418 effect(KILL cr); 8419 8420 format %{ "sarq $dst, $shift" %} 8421 ins_encode %{ 8422 __ sarq($dst$$Address, (unsigned char)($shift$$constant & 0x3F)); 8423 %} 8424 ins_pipe(ialu_mem_imm); 8425 %} 8426 8427 // Arithmetic Shift Right by variable 8428 instruct sarL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8429 %{ 8430 predicate(!VM_Version::supports_bmi2()); 8431 match(Set dst (RShiftL dst shift)); 8432 effect(KILL cr); 8433 8434 format %{ "sarq $dst, $shift" %} 8435 ins_encode %{ 8436 __ sarq($dst$$Register); 8437 %} 8438 ins_pipe(ialu_reg_reg); 8439 %} 8440 8441 // Arithmetic Shift Right by variable 8442 instruct sarL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8443 %{ 8444 predicate(!VM_Version::supports_bmi2()); 8445 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8446 effect(KILL cr); 8447 8448 format %{ "sarq $dst, $shift" %} 8449 ins_encode %{ 8450 __ sarq($dst$$Address); 8451 %} 8452 ins_pipe(ialu_mem_reg); 8453 %} 8454 8455 instruct sarL_rReg_rReg(rRegL dst, rRegL src, rRegI shift) 8456 %{ 8457 predicate(VM_Version::supports_bmi2()); 8458 match(Set dst (RShiftL src shift)); 8459 8460 format %{ "sarxq $dst, $src, $shift" %} 8461 ins_encode %{ 8462 __ sarxq($dst$$Register, $src$$Register, $shift$$Register); 8463 %} 8464 ins_pipe(ialu_reg_reg); 8465 %} 8466 8467 instruct sarL_mem_rReg(rRegL dst, memory src, rRegI shift) 8468 %{ 8469 predicate(VM_Version::supports_bmi2()); 8470 match(Set dst (RShiftL (LoadL src) shift)); 8471 ins_cost(175); 8472 format %{ "sarxq $dst, $src, $shift" %} 8473 ins_encode %{ 8474 __ sarxq($dst$$Register, $src$$Address, $shift$$Register); 8475 %} 8476 ins_pipe(ialu_reg_mem); 8477 %} 8478 8479 // Logical Shift Right by 8-bit immediate 8480 instruct shrL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8481 %{ 8482 match(Set dst (URShiftL dst shift)); 8483 effect(KILL cr); 8484 8485 format %{ "shrq $dst, $shift" %} 8486 ins_encode %{ 8487 __ shrq($dst$$Register, $shift$$constant); 8488 %} 8489 ins_pipe(ialu_reg); 8490 %} 8491 8492 // Logical Shift Right by 8-bit immediate 8493 instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8494 %{ 8495 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8496 effect(KILL cr); 8497 8498 format %{ "shrq $dst, $shift" %} 8499 ins_encode %{ 8500 __ shrq($dst$$Address, $shift$$constant); 8501 %} 8502 ins_pipe(ialu_mem_imm); 8503 %} 8504 8505 // Logical Shift Right by variable 8506 instruct shrL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8507 %{ 8508 predicate(!VM_Version::supports_bmi2()); 8509 match(Set dst (URShiftL dst shift)); 8510 effect(KILL cr); 8511 8512 format %{ "shrq $dst, $shift" %} 8513 ins_encode %{ 8514 __ shrq($dst$$Register); 8515 %} 8516 ins_pipe(ialu_reg_reg); 8517 %} 8518 8519 // Logical Shift Right by variable 8520 instruct shrL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8521 %{ 8522 predicate(!VM_Version::supports_bmi2()); 8523 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8524 effect(KILL cr); 8525 8526 format %{ "shrq $dst, $shift" %} 8527 ins_encode %{ 8528 __ shrq($dst$$Address); 8529 %} 8530 ins_pipe(ialu_mem_reg); 8531 %} 8532 8533 instruct shrL_rReg_rReg(rRegL dst, rRegL src, rRegI shift) 8534 %{ 8535 predicate(VM_Version::supports_bmi2()); 8536 match(Set dst (URShiftL src shift)); 8537 8538 format %{ "shrxq $dst, $src, $shift" %} 8539 ins_encode %{ 8540 __ shrxq($dst$$Register, $src$$Register, $shift$$Register); 8541 %} 8542 ins_pipe(ialu_reg_reg); 8543 %} 8544 8545 instruct shrL_mem_rReg(rRegL dst, memory src, rRegI shift) 8546 %{ 8547 predicate(VM_Version::supports_bmi2()); 8548 match(Set dst (URShiftL (LoadL src) shift)); 8549 ins_cost(175); 8550 format %{ "shrxq $dst, $src, $shift" %} 8551 ins_encode %{ 8552 __ shrxq($dst$$Register, $src$$Address, $shift$$Register); 8553 %} 8554 ins_pipe(ialu_reg_mem); 8555 %} 8556 8557 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24. 8558 // This idiom is used by the compiler for the i2b bytecode. 8559 instruct i2b(rRegI dst, rRegI src, immI_24 twentyfour) 8560 %{ 8561 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour)); 8562 8563 format %{ "movsbl $dst, $src\t# i2b" %} 8564 ins_encode %{ 8565 __ movsbl($dst$$Register, $src$$Register); 8566 %} 8567 ins_pipe(ialu_reg_reg); 8568 %} 8569 8570 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16. 8571 // This idiom is used by the compiler the i2s bytecode. 8572 instruct i2s(rRegI dst, rRegI src, immI_16 sixteen) 8573 %{ 8574 match(Set dst (RShiftI (LShiftI src sixteen) sixteen)); 8575 8576 format %{ "movswl $dst, $src\t# i2s" %} 8577 ins_encode %{ 8578 __ movswl($dst$$Register, $src$$Register); 8579 %} 8580 ins_pipe(ialu_reg_reg); 8581 %} 8582 8583 // ROL/ROR instructions 8584 8585 // Rotate left by constant. 8586 instruct rolI_immI8_legacy(rRegI dst, immI8 shift, rFlagsReg cr) 8587 %{ 8588 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8589 match(Set dst (RotateLeft dst shift)); 8590 effect(KILL cr); 8591 format %{ "roll $dst, $shift" %} 8592 ins_encode %{ 8593 __ roll($dst$$Register, $shift$$constant); 8594 %} 8595 ins_pipe(ialu_reg); 8596 %} 8597 8598 instruct rolI_immI8(rRegI dst, rRegI src, immI8 shift) 8599 %{ 8600 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8601 match(Set dst (RotateLeft src shift)); 8602 format %{ "rolxl $dst, $src, $shift" %} 8603 ins_encode %{ 8604 int shift = 32 - ($shift$$constant & 31); 8605 __ rorxl($dst$$Register, $src$$Register, shift); 8606 %} 8607 ins_pipe(ialu_reg_reg); 8608 %} 8609 8610 instruct rolI_mem_immI8(rRegI dst, memory src, immI8 shift) 8611 %{ 8612 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8613 match(Set dst (RotateLeft (LoadI src) shift)); 8614 ins_cost(175); 8615 format %{ "rolxl $dst, $src, $shift" %} 8616 ins_encode %{ 8617 int shift = 32 - ($shift$$constant & 31); 8618 __ rorxl($dst$$Register, $src$$Address, shift); 8619 %} 8620 ins_pipe(ialu_reg_mem); 8621 %} 8622 8623 // Rotate Left by variable 8624 instruct rolI_rReg_Var(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8625 %{ 8626 predicate(n->bottom_type()->basic_type() == T_INT); 8627 match(Set dst (RotateLeft dst shift)); 8628 effect(KILL cr); 8629 format %{ "roll $dst, $shift" %} 8630 ins_encode %{ 8631 __ roll($dst$$Register); 8632 %} 8633 ins_pipe(ialu_reg_reg); 8634 %} 8635 8636 // Rotate Right by constant. 8637 instruct rorI_immI8_legacy(rRegI dst, immI8 shift, rFlagsReg cr) 8638 %{ 8639 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8640 match(Set dst (RotateRight dst shift)); 8641 effect(KILL cr); 8642 format %{ "rorl $dst, $shift" %} 8643 ins_encode %{ 8644 __ rorl($dst$$Register, $shift$$constant); 8645 %} 8646 ins_pipe(ialu_reg); 8647 %} 8648 8649 // Rotate Right by constant. 8650 instruct rorI_immI8(rRegI dst, rRegI src, immI8 shift) 8651 %{ 8652 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8653 match(Set dst (RotateRight src shift)); 8654 format %{ "rorxl $dst, $src, $shift" %} 8655 ins_encode %{ 8656 __ rorxl($dst$$Register, $src$$Register, $shift$$constant); 8657 %} 8658 ins_pipe(ialu_reg_reg); 8659 %} 8660 8661 instruct rorI_mem_immI8(rRegI dst, memory src, immI8 shift) 8662 %{ 8663 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8664 match(Set dst (RotateRight (LoadI src) shift)); 8665 ins_cost(175); 8666 format %{ "rorxl $dst, $src, $shift" %} 8667 ins_encode %{ 8668 __ rorxl($dst$$Register, $src$$Address, $shift$$constant); 8669 %} 8670 ins_pipe(ialu_reg_mem); 8671 %} 8672 8673 // Rotate Right by variable 8674 instruct rorI_rReg_Var(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8675 %{ 8676 predicate(n->bottom_type()->basic_type() == T_INT); 8677 match(Set dst (RotateRight dst shift)); 8678 effect(KILL cr); 8679 format %{ "rorl $dst, $shift" %} 8680 ins_encode %{ 8681 __ rorl($dst$$Register); 8682 %} 8683 ins_pipe(ialu_reg_reg); 8684 %} 8685 8686 // Rotate Left by constant. 8687 instruct rolL_immI8_legacy(rRegL dst, immI8 shift, rFlagsReg cr) 8688 %{ 8689 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8690 match(Set dst (RotateLeft dst shift)); 8691 effect(KILL cr); 8692 format %{ "rolq $dst, $shift" %} 8693 ins_encode %{ 8694 __ rolq($dst$$Register, $shift$$constant); 8695 %} 8696 ins_pipe(ialu_reg); 8697 %} 8698 8699 instruct rolL_immI8(rRegL dst, rRegL src, immI8 shift) 8700 %{ 8701 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8702 match(Set dst (RotateLeft src shift)); 8703 format %{ "rolxq $dst, $src, $shift" %} 8704 ins_encode %{ 8705 int shift = 64 - ($shift$$constant & 63); 8706 __ rorxq($dst$$Register, $src$$Register, shift); 8707 %} 8708 ins_pipe(ialu_reg_reg); 8709 %} 8710 8711 instruct rolL_mem_immI8(rRegL dst, memory src, immI8 shift) 8712 %{ 8713 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8714 match(Set dst (RotateLeft (LoadL src) shift)); 8715 ins_cost(175); 8716 format %{ "rolxq $dst, $src, $shift" %} 8717 ins_encode %{ 8718 int shift = 64 - ($shift$$constant & 63); 8719 __ rorxq($dst$$Register, $src$$Address, shift); 8720 %} 8721 ins_pipe(ialu_reg_mem); 8722 %} 8723 8724 // Rotate Left by variable 8725 instruct rolL_rReg_Var(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8726 %{ 8727 predicate(n->bottom_type()->basic_type() == T_LONG); 8728 match(Set dst (RotateLeft dst shift)); 8729 effect(KILL cr); 8730 format %{ "rolq $dst, $shift" %} 8731 ins_encode %{ 8732 __ rolq($dst$$Register); 8733 %} 8734 ins_pipe(ialu_reg_reg); 8735 %} 8736 8737 // Rotate Right by constant. 8738 instruct rorL_immI8_legacy(rRegL dst, immI8 shift, rFlagsReg cr) 8739 %{ 8740 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8741 match(Set dst (RotateRight dst shift)); 8742 effect(KILL cr); 8743 format %{ "rorq $dst, $shift" %} 8744 ins_encode %{ 8745 __ rorq($dst$$Register, $shift$$constant); 8746 %} 8747 ins_pipe(ialu_reg); 8748 %} 8749 8750 // Rotate Right by constant 8751 instruct rorL_immI8(rRegL dst, rRegL src, immI8 shift) 8752 %{ 8753 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8754 match(Set dst (RotateRight src shift)); 8755 format %{ "rorxq $dst, $src, $shift" %} 8756 ins_encode %{ 8757 __ rorxq($dst$$Register, $src$$Register, $shift$$constant); 8758 %} 8759 ins_pipe(ialu_reg_reg); 8760 %} 8761 8762 instruct rorL_mem_immI8(rRegL dst, memory src, immI8 shift) 8763 %{ 8764 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8765 match(Set dst (RotateRight (LoadL src) shift)); 8766 ins_cost(175); 8767 format %{ "rorxq $dst, $src, $shift" %} 8768 ins_encode %{ 8769 __ rorxq($dst$$Register, $src$$Address, $shift$$constant); 8770 %} 8771 ins_pipe(ialu_reg_mem); 8772 %} 8773 8774 // Rotate Right by variable 8775 instruct rorL_rReg_Var(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8776 %{ 8777 predicate(n->bottom_type()->basic_type() == T_LONG); 8778 match(Set dst (RotateRight dst shift)); 8779 effect(KILL cr); 8780 format %{ "rorq $dst, $shift" %} 8781 ins_encode %{ 8782 __ rorq($dst$$Register); 8783 %} 8784 ins_pipe(ialu_reg_reg); 8785 %} 8786 8787 //----------------------------- CompressBits/ExpandBits ------------------------ 8788 8789 instruct compressBitsL_reg(rRegL dst, rRegL src, rRegL mask) %{ 8790 predicate(n->bottom_type()->isa_long()); 8791 match(Set dst (CompressBits src mask)); 8792 format %{ "pextq $dst, $src, $mask\t! parallel bit extract" %} 8793 ins_encode %{ 8794 __ pextq($dst$$Register, $src$$Register, $mask$$Register); 8795 %} 8796 ins_pipe( pipe_slow ); 8797 %} 8798 8799 instruct expandBitsL_reg(rRegL dst, rRegL src, rRegL mask) %{ 8800 predicate(n->bottom_type()->isa_long()); 8801 match(Set dst (ExpandBits src mask)); 8802 format %{ "pdepq $dst, $src, $mask\t! parallel bit deposit" %} 8803 ins_encode %{ 8804 __ pdepq($dst$$Register, $src$$Register, $mask$$Register); 8805 %} 8806 ins_pipe( pipe_slow ); 8807 %} 8808 8809 instruct compressBitsL_mem(rRegL dst, rRegL src, memory mask) %{ 8810 predicate(n->bottom_type()->isa_long()); 8811 match(Set dst (CompressBits src (LoadL mask))); 8812 format %{ "pextq $dst, $src, $mask\t! parallel bit extract" %} 8813 ins_encode %{ 8814 __ pextq($dst$$Register, $src$$Register, $mask$$Address); 8815 %} 8816 ins_pipe( pipe_slow ); 8817 %} 8818 8819 instruct expandBitsL_mem(rRegL dst, rRegL src, memory mask) %{ 8820 predicate(n->bottom_type()->isa_long()); 8821 match(Set dst (ExpandBits src (LoadL mask))); 8822 format %{ "pdepq $dst, $src, $mask\t! parallel bit deposit" %} 8823 ins_encode %{ 8824 __ pdepq($dst$$Register, $src$$Register, $mask$$Address); 8825 %} 8826 ins_pipe( pipe_slow ); 8827 %} 8828 8829 8830 // Logical Instructions 8831 8832 // Integer Logical Instructions 8833 8834 // And Instructions 8835 // And Register with Register 8836 instruct andI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8837 %{ 8838 match(Set dst (AndI dst src)); 8839 effect(KILL cr); 8840 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 8841 8842 format %{ "andl $dst, $src\t# int" %} 8843 ins_encode %{ 8844 __ andl($dst$$Register, $src$$Register); 8845 %} 8846 ins_pipe(ialu_reg_reg); 8847 %} 8848 8849 // And Register with Immediate 255 8850 instruct andI_rReg_imm255(rRegI dst, rRegI src, immI_255 mask) 8851 %{ 8852 match(Set dst (AndI src mask)); 8853 8854 format %{ "movzbl $dst, $src\t# int & 0xFF" %} 8855 ins_encode %{ 8856 __ movzbl($dst$$Register, $src$$Register); 8857 %} 8858 ins_pipe(ialu_reg); 8859 %} 8860 8861 // And Register with Immediate 255 and promote to long 8862 instruct andI2L_rReg_imm255(rRegL dst, rRegI src, immI_255 mask) 8863 %{ 8864 match(Set dst (ConvI2L (AndI src mask))); 8865 8866 format %{ "movzbl $dst, $src\t# int & 0xFF -> long" %} 8867 ins_encode %{ 8868 __ movzbl($dst$$Register, $src$$Register); 8869 %} 8870 ins_pipe(ialu_reg); 8871 %} 8872 8873 // And Register with Immediate 65535 8874 instruct andI_rReg_imm65535(rRegI dst, rRegI src, immI_65535 mask) 8875 %{ 8876 match(Set dst (AndI src mask)); 8877 8878 format %{ "movzwl $dst, $src\t# int & 0xFFFF" %} 8879 ins_encode %{ 8880 __ movzwl($dst$$Register, $src$$Register); 8881 %} 8882 ins_pipe(ialu_reg); 8883 %} 8884 8885 // And Register with Immediate 65535 and promote to long 8886 instruct andI2L_rReg_imm65535(rRegL dst, rRegI src, immI_65535 mask) 8887 %{ 8888 match(Set dst (ConvI2L (AndI src mask))); 8889 8890 format %{ "movzwl $dst, $src\t# int & 0xFFFF -> long" %} 8891 ins_encode %{ 8892 __ movzwl($dst$$Register, $src$$Register); 8893 %} 8894 ins_pipe(ialu_reg); 8895 %} 8896 8897 // Can skip int2long conversions after AND with small bitmask 8898 instruct convI2LAndI_reg_immIbitmask(rRegL dst, rRegI src, immI_Pow2M1 mask, rRegI tmp, rFlagsReg cr) 8899 %{ 8900 predicate(VM_Version::supports_bmi2()); 8901 ins_cost(125); 8902 effect(TEMP tmp, KILL cr); 8903 match(Set dst (ConvI2L (AndI src mask))); 8904 format %{ "bzhiq $dst, $src, $mask \t# using $tmp as TEMP, int & immI_Pow2M1 -> long" %} 8905 ins_encode %{ 8906 __ movl($tmp$$Register, exact_log2($mask$$constant + 1)); 8907 __ bzhiq($dst$$Register, $src$$Register, $tmp$$Register); 8908 %} 8909 ins_pipe(ialu_reg_reg); 8910 %} 8911 8912 // And Register with Immediate 8913 instruct andI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 8914 %{ 8915 match(Set dst (AndI dst src)); 8916 effect(KILL cr); 8917 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 8918 8919 format %{ "andl $dst, $src\t# int" %} 8920 ins_encode %{ 8921 __ andl($dst$$Register, $src$$constant); 8922 %} 8923 ins_pipe(ialu_reg); 8924 %} 8925 8926 // And Register with Memory 8927 instruct andI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 8928 %{ 8929 match(Set dst (AndI dst (LoadI src))); 8930 effect(KILL cr); 8931 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 8932 8933 ins_cost(150); 8934 format %{ "andl $dst, $src\t# int" %} 8935 ins_encode %{ 8936 __ andl($dst$$Register, $src$$Address); 8937 %} 8938 ins_pipe(ialu_reg_mem); 8939 %} 8940 8941 // And Memory with Register 8942 instruct andB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 8943 %{ 8944 match(Set dst (StoreB dst (AndI (LoadB dst) src))); 8945 effect(KILL cr); 8946 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 8947 8948 ins_cost(150); 8949 format %{ "andb $dst, $src\t# byte" %} 8950 ins_encode %{ 8951 __ andb($dst$$Address, $src$$Register); 8952 %} 8953 ins_pipe(ialu_mem_reg); 8954 %} 8955 8956 instruct andI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 8957 %{ 8958 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 8959 effect(KILL cr); 8960 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 8961 8962 ins_cost(150); 8963 format %{ "andl $dst, $src\t# int" %} 8964 ins_encode %{ 8965 __ andl($dst$$Address, $src$$Register); 8966 %} 8967 ins_pipe(ialu_mem_reg); 8968 %} 8969 8970 // And Memory with Immediate 8971 instruct andI_mem_imm(memory dst, immI src, rFlagsReg cr) 8972 %{ 8973 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 8974 effect(KILL cr); 8975 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 8976 8977 ins_cost(125); 8978 format %{ "andl $dst, $src\t# int" %} 8979 ins_encode %{ 8980 __ andl($dst$$Address, $src$$constant); 8981 %} 8982 ins_pipe(ialu_mem_imm); 8983 %} 8984 8985 // BMI1 instructions 8986 instruct andnI_rReg_rReg_mem(rRegI dst, rRegI src1, memory src2, immI_M1 minus_1, rFlagsReg cr) %{ 8987 match(Set dst (AndI (XorI src1 minus_1) (LoadI src2))); 8988 predicate(UseBMI1Instructions); 8989 effect(KILL cr); 8990 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 8991 8992 ins_cost(125); 8993 format %{ "andnl $dst, $src1, $src2" %} 8994 8995 ins_encode %{ 8996 __ andnl($dst$$Register, $src1$$Register, $src2$$Address); 8997 %} 8998 ins_pipe(ialu_reg_mem); 8999 %} 9000 9001 instruct andnI_rReg_rReg_rReg(rRegI dst, rRegI src1, rRegI src2, immI_M1 minus_1, rFlagsReg cr) %{ 9002 match(Set dst (AndI (XorI src1 minus_1) src2)); 9003 predicate(UseBMI1Instructions); 9004 effect(KILL cr); 9005 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9006 9007 format %{ "andnl $dst, $src1, $src2" %} 9008 9009 ins_encode %{ 9010 __ andnl($dst$$Register, $src1$$Register, $src2$$Register); 9011 %} 9012 ins_pipe(ialu_reg); 9013 %} 9014 9015 instruct blsiI_rReg_rReg(rRegI dst, rRegI src, immI_0 imm_zero, rFlagsReg cr) %{ 9016 match(Set dst (AndI (SubI imm_zero src) src)); 9017 predicate(UseBMI1Instructions); 9018 effect(KILL cr); 9019 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9020 9021 format %{ "blsil $dst, $src" %} 9022 9023 ins_encode %{ 9024 __ blsil($dst$$Register, $src$$Register); 9025 %} 9026 ins_pipe(ialu_reg); 9027 %} 9028 9029 instruct blsiI_rReg_mem(rRegI dst, memory src, immI_0 imm_zero, rFlagsReg cr) %{ 9030 match(Set dst (AndI (SubI imm_zero (LoadI src) ) (LoadI src) )); 9031 predicate(UseBMI1Instructions); 9032 effect(KILL cr); 9033 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9034 9035 ins_cost(125); 9036 format %{ "blsil $dst, $src" %} 9037 9038 ins_encode %{ 9039 __ blsil($dst$$Register, $src$$Address); 9040 %} 9041 ins_pipe(ialu_reg_mem); 9042 %} 9043 9044 instruct blsmskI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 9045 %{ 9046 match(Set dst (XorI (AddI (LoadI src) minus_1) (LoadI src) ) ); 9047 predicate(UseBMI1Instructions); 9048 effect(KILL cr); 9049 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 9050 9051 ins_cost(125); 9052 format %{ "blsmskl $dst, $src" %} 9053 9054 ins_encode %{ 9055 __ blsmskl($dst$$Register, $src$$Address); 9056 %} 9057 ins_pipe(ialu_reg_mem); 9058 %} 9059 9060 instruct blsmskI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 9061 %{ 9062 match(Set dst (XorI (AddI src minus_1) src)); 9063 predicate(UseBMI1Instructions); 9064 effect(KILL cr); 9065 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 9066 9067 format %{ "blsmskl $dst, $src" %} 9068 9069 ins_encode %{ 9070 __ blsmskl($dst$$Register, $src$$Register); 9071 %} 9072 9073 ins_pipe(ialu_reg); 9074 %} 9075 9076 instruct blsrI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 9077 %{ 9078 match(Set dst (AndI (AddI src minus_1) src) ); 9079 predicate(UseBMI1Instructions); 9080 effect(KILL cr); 9081 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9082 9083 format %{ "blsrl $dst, $src" %} 9084 9085 ins_encode %{ 9086 __ blsrl($dst$$Register, $src$$Register); 9087 %} 9088 9089 ins_pipe(ialu_reg_mem); 9090 %} 9091 9092 instruct blsrI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 9093 %{ 9094 match(Set dst (AndI (AddI (LoadI src) minus_1) (LoadI src) ) ); 9095 predicate(UseBMI1Instructions); 9096 effect(KILL cr); 9097 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9098 9099 ins_cost(125); 9100 format %{ "blsrl $dst, $src" %} 9101 9102 ins_encode %{ 9103 __ blsrl($dst$$Register, $src$$Address); 9104 %} 9105 9106 ins_pipe(ialu_reg); 9107 %} 9108 9109 // Or Instructions 9110 // Or Register with Register 9111 instruct orI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9112 %{ 9113 match(Set dst (OrI dst src)); 9114 effect(KILL cr); 9115 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9116 9117 format %{ "orl $dst, $src\t# int" %} 9118 ins_encode %{ 9119 __ orl($dst$$Register, $src$$Register); 9120 %} 9121 ins_pipe(ialu_reg_reg); 9122 %} 9123 9124 // Or Register with Immediate 9125 instruct orI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9126 %{ 9127 match(Set dst (OrI dst src)); 9128 effect(KILL cr); 9129 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9130 9131 format %{ "orl $dst, $src\t# int" %} 9132 ins_encode %{ 9133 __ orl($dst$$Register, $src$$constant); 9134 %} 9135 ins_pipe(ialu_reg); 9136 %} 9137 9138 // Or Register with Memory 9139 instruct orI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9140 %{ 9141 match(Set dst (OrI dst (LoadI src))); 9142 effect(KILL cr); 9143 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9144 9145 ins_cost(150); 9146 format %{ "orl $dst, $src\t# int" %} 9147 ins_encode %{ 9148 __ orl($dst$$Register, $src$$Address); 9149 %} 9150 ins_pipe(ialu_reg_mem); 9151 %} 9152 9153 // Or Memory with Register 9154 instruct orB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9155 %{ 9156 match(Set dst (StoreB dst (OrI (LoadB dst) src))); 9157 effect(KILL cr); 9158 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9159 9160 ins_cost(150); 9161 format %{ "orb $dst, $src\t# byte" %} 9162 ins_encode %{ 9163 __ orb($dst$$Address, $src$$Register); 9164 %} 9165 ins_pipe(ialu_mem_reg); 9166 %} 9167 9168 instruct orI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9169 %{ 9170 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9171 effect(KILL cr); 9172 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9173 9174 ins_cost(150); 9175 format %{ "orl $dst, $src\t# int" %} 9176 ins_encode %{ 9177 __ orl($dst$$Address, $src$$Register); 9178 %} 9179 ins_pipe(ialu_mem_reg); 9180 %} 9181 9182 // Or Memory with Immediate 9183 instruct orI_mem_imm(memory dst, immI src, rFlagsReg cr) 9184 %{ 9185 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9186 effect(KILL cr); 9187 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9188 9189 ins_cost(125); 9190 format %{ "orl $dst, $src\t# int" %} 9191 ins_encode %{ 9192 __ orl($dst$$Address, $src$$constant); 9193 %} 9194 ins_pipe(ialu_mem_imm); 9195 %} 9196 9197 // Xor Instructions 9198 // Xor Register with Register 9199 instruct xorI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9200 %{ 9201 match(Set dst (XorI dst src)); 9202 effect(KILL cr); 9203 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9204 9205 format %{ "xorl $dst, $src\t# int" %} 9206 ins_encode %{ 9207 __ xorl($dst$$Register, $src$$Register); 9208 %} 9209 ins_pipe(ialu_reg_reg); 9210 %} 9211 9212 // Xor Register with Immediate -1 9213 instruct xorI_rReg_im1(rRegI dst, immI_M1 imm) %{ 9214 match(Set dst (XorI dst imm)); 9215 9216 format %{ "not $dst" %} 9217 ins_encode %{ 9218 __ notl($dst$$Register); 9219 %} 9220 ins_pipe(ialu_reg); 9221 %} 9222 9223 // Xor Register with Immediate 9224 instruct xorI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9225 %{ 9226 match(Set dst (XorI dst src)); 9227 effect(KILL cr); 9228 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9229 9230 format %{ "xorl $dst, $src\t# int" %} 9231 ins_encode %{ 9232 __ xorl($dst$$Register, $src$$constant); 9233 %} 9234 ins_pipe(ialu_reg); 9235 %} 9236 9237 // Xor Register with Memory 9238 instruct xorI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9239 %{ 9240 match(Set dst (XorI dst (LoadI src))); 9241 effect(KILL cr); 9242 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9243 9244 ins_cost(150); 9245 format %{ "xorl $dst, $src\t# int" %} 9246 ins_encode %{ 9247 __ xorl($dst$$Register, $src$$Address); 9248 %} 9249 ins_pipe(ialu_reg_mem); 9250 %} 9251 9252 // Xor Memory with Register 9253 instruct xorB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9254 %{ 9255 match(Set dst (StoreB dst (XorI (LoadB dst) src))); 9256 effect(KILL cr); 9257 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9258 9259 ins_cost(150); 9260 format %{ "xorb $dst, $src\t# byte" %} 9261 ins_encode %{ 9262 __ xorb($dst$$Address, $src$$Register); 9263 %} 9264 ins_pipe(ialu_mem_reg); 9265 %} 9266 9267 instruct xorI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9268 %{ 9269 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9270 effect(KILL cr); 9271 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9272 9273 ins_cost(150); 9274 format %{ "xorl $dst, $src\t# int" %} 9275 ins_encode %{ 9276 __ xorl($dst$$Address, $src$$Register); 9277 %} 9278 ins_pipe(ialu_mem_reg); 9279 %} 9280 9281 // Xor Memory with Immediate 9282 instruct xorI_mem_imm(memory dst, immI src, rFlagsReg cr) 9283 %{ 9284 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9285 effect(KILL cr); 9286 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9287 9288 ins_cost(125); 9289 format %{ "xorl $dst, $src\t# int" %} 9290 ins_encode %{ 9291 __ xorl($dst$$Address, $src$$constant); 9292 %} 9293 ins_pipe(ialu_mem_imm); 9294 %} 9295 9296 9297 // Long Logical Instructions 9298 9299 // And Instructions 9300 // And Register with Register 9301 instruct andL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9302 %{ 9303 match(Set dst (AndL dst src)); 9304 effect(KILL cr); 9305 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9306 9307 format %{ "andq $dst, $src\t# long" %} 9308 ins_encode %{ 9309 __ andq($dst$$Register, $src$$Register); 9310 %} 9311 ins_pipe(ialu_reg_reg); 9312 %} 9313 9314 // And Register with Immediate 255 9315 instruct andL_rReg_imm255(rRegL dst, rRegL src, immL_255 mask) 9316 %{ 9317 match(Set dst (AndL src mask)); 9318 9319 format %{ "movzbl $dst, $src\t# long & 0xFF" %} 9320 ins_encode %{ 9321 // movzbl zeroes out the upper 32-bit and does not need REX.W 9322 __ movzbl($dst$$Register, $src$$Register); 9323 %} 9324 ins_pipe(ialu_reg); 9325 %} 9326 9327 // And Register with Immediate 65535 9328 instruct andL_rReg_imm65535(rRegL dst, rRegL src, immL_65535 mask) 9329 %{ 9330 match(Set dst (AndL src mask)); 9331 9332 format %{ "movzwl $dst, $src\t# long & 0xFFFF" %} 9333 ins_encode %{ 9334 // movzwl zeroes out the upper 32-bit and does not need REX.W 9335 __ movzwl($dst$$Register, $src$$Register); 9336 %} 9337 ins_pipe(ialu_reg); 9338 %} 9339 9340 // And Register with Immediate 9341 instruct andL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9342 %{ 9343 match(Set dst (AndL dst src)); 9344 effect(KILL cr); 9345 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9346 9347 format %{ "andq $dst, $src\t# long" %} 9348 ins_encode %{ 9349 __ andq($dst$$Register, $src$$constant); 9350 %} 9351 ins_pipe(ialu_reg); 9352 %} 9353 9354 // And Register with Memory 9355 instruct andL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9356 %{ 9357 match(Set dst (AndL dst (LoadL src))); 9358 effect(KILL cr); 9359 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9360 9361 ins_cost(150); 9362 format %{ "andq $dst, $src\t# long" %} 9363 ins_encode %{ 9364 __ andq($dst$$Register, $src$$Address); 9365 %} 9366 ins_pipe(ialu_reg_mem); 9367 %} 9368 9369 // And Memory with Register 9370 instruct andL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9371 %{ 9372 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9373 effect(KILL cr); 9374 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9375 9376 ins_cost(150); 9377 format %{ "andq $dst, $src\t# long" %} 9378 ins_encode %{ 9379 __ andq($dst$$Address, $src$$Register); 9380 %} 9381 ins_pipe(ialu_mem_reg); 9382 %} 9383 9384 // And Memory with Immediate 9385 instruct andL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9386 %{ 9387 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9388 effect(KILL cr); 9389 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9390 9391 ins_cost(125); 9392 format %{ "andq $dst, $src\t# long" %} 9393 ins_encode %{ 9394 __ andq($dst$$Address, $src$$constant); 9395 %} 9396 ins_pipe(ialu_mem_imm); 9397 %} 9398 9399 instruct btrL_mem_imm(memory dst, immL_NotPow2 con, rFlagsReg cr) 9400 %{ 9401 // con should be a pure 64-bit immediate given that not(con) is a power of 2 9402 // because AND/OR works well enough for 8/32-bit values. 9403 predicate(log2i_graceful(~n->in(3)->in(2)->get_long()) > 30); 9404 9405 match(Set dst (StoreL dst (AndL (LoadL dst) con))); 9406 effect(KILL cr); 9407 9408 ins_cost(125); 9409 format %{ "btrq $dst, log2(not($con))\t# long" %} 9410 ins_encode %{ 9411 __ btrq($dst$$Address, log2i_exact((julong)~$con$$constant)); 9412 %} 9413 ins_pipe(ialu_mem_imm); 9414 %} 9415 9416 // BMI1 instructions 9417 instruct andnL_rReg_rReg_mem(rRegL dst, rRegL src1, memory src2, immL_M1 minus_1, rFlagsReg cr) %{ 9418 match(Set dst (AndL (XorL src1 minus_1) (LoadL src2))); 9419 predicate(UseBMI1Instructions); 9420 effect(KILL cr); 9421 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9422 9423 ins_cost(125); 9424 format %{ "andnq $dst, $src1, $src2" %} 9425 9426 ins_encode %{ 9427 __ andnq($dst$$Register, $src1$$Register, $src2$$Address); 9428 %} 9429 ins_pipe(ialu_reg_mem); 9430 %} 9431 9432 instruct andnL_rReg_rReg_rReg(rRegL dst, rRegL src1, rRegL src2, immL_M1 minus_1, rFlagsReg cr) %{ 9433 match(Set dst (AndL (XorL src1 minus_1) src2)); 9434 predicate(UseBMI1Instructions); 9435 effect(KILL cr); 9436 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9437 9438 format %{ "andnq $dst, $src1, $src2" %} 9439 9440 ins_encode %{ 9441 __ andnq($dst$$Register, $src1$$Register, $src2$$Register); 9442 %} 9443 ins_pipe(ialu_reg_mem); 9444 %} 9445 9446 instruct blsiL_rReg_rReg(rRegL dst, rRegL src, immL0 imm_zero, rFlagsReg cr) %{ 9447 match(Set dst (AndL (SubL imm_zero src) src)); 9448 predicate(UseBMI1Instructions); 9449 effect(KILL cr); 9450 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9451 9452 format %{ "blsiq $dst, $src" %} 9453 9454 ins_encode %{ 9455 __ blsiq($dst$$Register, $src$$Register); 9456 %} 9457 ins_pipe(ialu_reg); 9458 %} 9459 9460 instruct blsiL_rReg_mem(rRegL dst, memory src, immL0 imm_zero, rFlagsReg cr) %{ 9461 match(Set dst (AndL (SubL imm_zero (LoadL src) ) (LoadL src) )); 9462 predicate(UseBMI1Instructions); 9463 effect(KILL cr); 9464 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9465 9466 ins_cost(125); 9467 format %{ "blsiq $dst, $src" %} 9468 9469 ins_encode %{ 9470 __ blsiq($dst$$Register, $src$$Address); 9471 %} 9472 ins_pipe(ialu_reg_mem); 9473 %} 9474 9475 instruct blsmskL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 9476 %{ 9477 match(Set dst (XorL (AddL (LoadL src) minus_1) (LoadL src) ) ); 9478 predicate(UseBMI1Instructions); 9479 effect(KILL cr); 9480 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 9481 9482 ins_cost(125); 9483 format %{ "blsmskq $dst, $src" %} 9484 9485 ins_encode %{ 9486 __ blsmskq($dst$$Register, $src$$Address); 9487 %} 9488 ins_pipe(ialu_reg_mem); 9489 %} 9490 9491 instruct blsmskL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 9492 %{ 9493 match(Set dst (XorL (AddL src minus_1) src)); 9494 predicate(UseBMI1Instructions); 9495 effect(KILL cr); 9496 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 9497 9498 format %{ "blsmskq $dst, $src" %} 9499 9500 ins_encode %{ 9501 __ blsmskq($dst$$Register, $src$$Register); 9502 %} 9503 9504 ins_pipe(ialu_reg); 9505 %} 9506 9507 instruct blsrL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 9508 %{ 9509 match(Set dst (AndL (AddL src minus_1) src) ); 9510 predicate(UseBMI1Instructions); 9511 effect(KILL cr); 9512 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9513 9514 format %{ "blsrq $dst, $src" %} 9515 9516 ins_encode %{ 9517 __ blsrq($dst$$Register, $src$$Register); 9518 %} 9519 9520 ins_pipe(ialu_reg); 9521 %} 9522 9523 instruct blsrL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 9524 %{ 9525 match(Set dst (AndL (AddL (LoadL src) minus_1) (LoadL src)) ); 9526 predicate(UseBMI1Instructions); 9527 effect(KILL cr); 9528 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9529 9530 ins_cost(125); 9531 format %{ "blsrq $dst, $src" %} 9532 9533 ins_encode %{ 9534 __ blsrq($dst$$Register, $src$$Address); 9535 %} 9536 9537 ins_pipe(ialu_reg); 9538 %} 9539 9540 // Or Instructions 9541 // Or Register with Register 9542 instruct orL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9543 %{ 9544 match(Set dst (OrL dst src)); 9545 effect(KILL cr); 9546 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9547 9548 format %{ "orq $dst, $src\t# long" %} 9549 ins_encode %{ 9550 __ orq($dst$$Register, $src$$Register); 9551 %} 9552 ins_pipe(ialu_reg_reg); 9553 %} 9554 9555 // Use any_RegP to match R15 (TLS register) without spilling. 9556 instruct orL_rReg_castP2X(rRegL dst, any_RegP src, rFlagsReg cr) %{ 9557 match(Set dst (OrL dst (CastP2X src))); 9558 effect(KILL cr); 9559 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9560 9561 format %{ "orq $dst, $src\t# long" %} 9562 ins_encode %{ 9563 __ orq($dst$$Register, $src$$Register); 9564 %} 9565 ins_pipe(ialu_reg_reg); 9566 %} 9567 9568 9569 // Or Register with Immediate 9570 instruct orL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9571 %{ 9572 match(Set dst (OrL dst src)); 9573 effect(KILL cr); 9574 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9575 9576 format %{ "orq $dst, $src\t# long" %} 9577 ins_encode %{ 9578 __ orq($dst$$Register, $src$$constant); 9579 %} 9580 ins_pipe(ialu_reg); 9581 %} 9582 9583 // Or Register with Memory 9584 instruct orL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9585 %{ 9586 match(Set dst (OrL dst (LoadL src))); 9587 effect(KILL cr); 9588 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9589 9590 ins_cost(150); 9591 format %{ "orq $dst, $src\t# long" %} 9592 ins_encode %{ 9593 __ orq($dst$$Register, $src$$Address); 9594 %} 9595 ins_pipe(ialu_reg_mem); 9596 %} 9597 9598 // Or Memory with Register 9599 instruct orL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9600 %{ 9601 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9602 effect(KILL cr); 9603 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9604 9605 ins_cost(150); 9606 format %{ "orq $dst, $src\t# long" %} 9607 ins_encode %{ 9608 __ orq($dst$$Address, $src$$Register); 9609 %} 9610 ins_pipe(ialu_mem_reg); 9611 %} 9612 9613 // Or Memory with Immediate 9614 instruct orL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9615 %{ 9616 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9617 effect(KILL cr); 9618 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9619 9620 ins_cost(125); 9621 format %{ "orq $dst, $src\t# long" %} 9622 ins_encode %{ 9623 __ orq($dst$$Address, $src$$constant); 9624 %} 9625 ins_pipe(ialu_mem_imm); 9626 %} 9627 9628 instruct btsL_mem_imm(memory dst, immL_Pow2 con, rFlagsReg cr) 9629 %{ 9630 // con should be a pure 64-bit power of 2 immediate 9631 // because AND/OR works well enough for 8/32-bit values. 9632 predicate(log2i_graceful(n->in(3)->in(2)->get_long()) > 31); 9633 9634 match(Set dst (StoreL dst (OrL (LoadL dst) con))); 9635 effect(KILL cr); 9636 9637 ins_cost(125); 9638 format %{ "btsq $dst, log2($con)\t# long" %} 9639 ins_encode %{ 9640 __ btsq($dst$$Address, log2i_exact((julong)$con$$constant)); 9641 %} 9642 ins_pipe(ialu_mem_imm); 9643 %} 9644 9645 // Xor Instructions 9646 // Xor Register with Register 9647 instruct xorL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9648 %{ 9649 match(Set dst (XorL dst src)); 9650 effect(KILL cr); 9651 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9652 9653 format %{ "xorq $dst, $src\t# long" %} 9654 ins_encode %{ 9655 __ xorq($dst$$Register, $src$$Register); 9656 %} 9657 ins_pipe(ialu_reg_reg); 9658 %} 9659 9660 // Xor Register with Immediate -1 9661 instruct xorL_rReg_im1(rRegL dst, immL_M1 imm) %{ 9662 match(Set dst (XorL dst imm)); 9663 9664 format %{ "notq $dst" %} 9665 ins_encode %{ 9666 __ notq($dst$$Register); 9667 %} 9668 ins_pipe(ialu_reg); 9669 %} 9670 9671 // Xor Register with Immediate 9672 instruct xorL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9673 %{ 9674 match(Set dst (XorL dst src)); 9675 effect(KILL cr); 9676 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9677 9678 format %{ "xorq $dst, $src\t# long" %} 9679 ins_encode %{ 9680 __ xorq($dst$$Register, $src$$constant); 9681 %} 9682 ins_pipe(ialu_reg); 9683 %} 9684 9685 // Xor Register with Memory 9686 instruct xorL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9687 %{ 9688 match(Set dst (XorL dst (LoadL src))); 9689 effect(KILL cr); 9690 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9691 9692 ins_cost(150); 9693 format %{ "xorq $dst, $src\t# long" %} 9694 ins_encode %{ 9695 __ xorq($dst$$Register, $src$$Address); 9696 %} 9697 ins_pipe(ialu_reg_mem); 9698 %} 9699 9700 // Xor Memory with Register 9701 instruct xorL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9702 %{ 9703 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 9704 effect(KILL cr); 9705 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9706 9707 ins_cost(150); 9708 format %{ "xorq $dst, $src\t# long" %} 9709 ins_encode %{ 9710 __ xorq($dst$$Address, $src$$Register); 9711 %} 9712 ins_pipe(ialu_mem_reg); 9713 %} 9714 9715 // Xor Memory with Immediate 9716 instruct xorL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9717 %{ 9718 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 9719 effect(KILL cr); 9720 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9721 9722 ins_cost(125); 9723 format %{ "xorq $dst, $src\t# long" %} 9724 ins_encode %{ 9725 __ xorq($dst$$Address, $src$$constant); 9726 %} 9727 ins_pipe(ialu_mem_imm); 9728 %} 9729 9730 instruct cmpLTMask(rRegI dst, rRegI p, rRegI q, rFlagsReg cr) 9731 %{ 9732 match(Set dst (CmpLTMask p q)); 9733 effect(KILL cr); 9734 9735 ins_cost(400); 9736 format %{ "cmpl $p, $q\t# cmpLTMask\n\t" 9737 "setcc $dst \t# emits setlt + movzbl or setzul for APX" 9738 "negl $dst" %} 9739 ins_encode %{ 9740 __ cmpl($p$$Register, $q$$Register); 9741 __ setcc(Assembler::less, $dst$$Register); 9742 __ negl($dst$$Register); 9743 %} 9744 ins_pipe(pipe_slow); 9745 %} 9746 9747 instruct cmpLTMask0(rRegI dst, immI_0 zero, rFlagsReg cr) 9748 %{ 9749 match(Set dst (CmpLTMask dst zero)); 9750 effect(KILL cr); 9751 9752 ins_cost(100); 9753 format %{ "sarl $dst, #31\t# cmpLTMask0" %} 9754 ins_encode %{ 9755 __ sarl($dst$$Register, 31); 9756 %} 9757 ins_pipe(ialu_reg); 9758 %} 9759 9760 /* Better to save a register than avoid a branch */ 9761 instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 9762 %{ 9763 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q))); 9764 effect(KILL cr); 9765 ins_cost(300); 9766 format %{ "subl $p,$q\t# cadd_cmpLTMask\n\t" 9767 "jge done\n\t" 9768 "addl $p,$y\n" 9769 "done: " %} 9770 ins_encode %{ 9771 Register Rp = $p$$Register; 9772 Register Rq = $q$$Register; 9773 Register Ry = $y$$Register; 9774 Label done; 9775 __ subl(Rp, Rq); 9776 __ jccb(Assembler::greaterEqual, done); 9777 __ addl(Rp, Ry); 9778 __ bind(done); 9779 %} 9780 ins_pipe(pipe_cmplt); 9781 %} 9782 9783 /* Better to save a register than avoid a branch */ 9784 instruct and_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 9785 %{ 9786 match(Set y (AndI (CmpLTMask p q) y)); 9787 effect(KILL cr); 9788 9789 ins_cost(300); 9790 9791 format %{ "cmpl $p, $q\t# and_cmpLTMask\n\t" 9792 "jlt done\n\t" 9793 "xorl $y, $y\n" 9794 "done: " %} 9795 ins_encode %{ 9796 Register Rp = $p$$Register; 9797 Register Rq = $q$$Register; 9798 Register Ry = $y$$Register; 9799 Label done; 9800 __ cmpl(Rp, Rq); 9801 __ jccb(Assembler::less, done); 9802 __ xorl(Ry, Ry); 9803 __ bind(done); 9804 %} 9805 ins_pipe(pipe_cmplt); 9806 %} 9807 9808 9809 //---------- FP Instructions------------------------------------------------ 9810 9811 // Really expensive, avoid 9812 instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2) 9813 %{ 9814 match(Set cr (CmpF src1 src2)); 9815 9816 ins_cost(500); 9817 format %{ "ucomiss $src1, $src2\n\t" 9818 "jnp,s exit\n\t" 9819 "pushfq\t# saw NaN, set CF\n\t" 9820 "andq [rsp], #0xffffff2b\n\t" 9821 "popfq\n" 9822 "exit:" %} 9823 ins_encode %{ 9824 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9825 emit_cmpfp_fixup(masm); 9826 %} 9827 ins_pipe(pipe_slow); 9828 %} 9829 9830 instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{ 9831 match(Set cr (CmpF src1 src2)); 9832 9833 ins_cost(100); 9834 format %{ "ucomiss $src1, $src2" %} 9835 ins_encode %{ 9836 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9837 %} 9838 ins_pipe(pipe_slow); 9839 %} 9840 9841 instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{ 9842 match(Set cr (CmpF src1 (LoadF src2))); 9843 9844 ins_cost(100); 9845 format %{ "ucomiss $src1, $src2" %} 9846 ins_encode %{ 9847 __ ucomiss($src1$$XMMRegister, $src2$$Address); 9848 %} 9849 ins_pipe(pipe_slow); 9850 %} 9851 9852 instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src, immF con) %{ 9853 match(Set cr (CmpF src con)); 9854 ins_cost(100); 9855 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con" %} 9856 ins_encode %{ 9857 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 9858 %} 9859 ins_pipe(pipe_slow); 9860 %} 9861 9862 // Really expensive, avoid 9863 instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2) 9864 %{ 9865 match(Set cr (CmpD src1 src2)); 9866 9867 ins_cost(500); 9868 format %{ "ucomisd $src1, $src2\n\t" 9869 "jnp,s exit\n\t" 9870 "pushfq\t# saw NaN, set CF\n\t" 9871 "andq [rsp], #0xffffff2b\n\t" 9872 "popfq\n" 9873 "exit:" %} 9874 ins_encode %{ 9875 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9876 emit_cmpfp_fixup(masm); 9877 %} 9878 ins_pipe(pipe_slow); 9879 %} 9880 9881 instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{ 9882 match(Set cr (CmpD src1 src2)); 9883 9884 ins_cost(100); 9885 format %{ "ucomisd $src1, $src2 test" %} 9886 ins_encode %{ 9887 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9888 %} 9889 ins_pipe(pipe_slow); 9890 %} 9891 9892 instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{ 9893 match(Set cr (CmpD src1 (LoadD src2))); 9894 9895 ins_cost(100); 9896 format %{ "ucomisd $src1, $src2" %} 9897 ins_encode %{ 9898 __ ucomisd($src1$$XMMRegister, $src2$$Address); 9899 %} 9900 ins_pipe(pipe_slow); 9901 %} 9902 9903 instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src, immD con) %{ 9904 match(Set cr (CmpD src con)); 9905 ins_cost(100); 9906 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con" %} 9907 ins_encode %{ 9908 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 9909 %} 9910 ins_pipe(pipe_slow); 9911 %} 9912 9913 // Compare into -1,0,1 9914 instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr) 9915 %{ 9916 match(Set dst (CmpF3 src1 src2)); 9917 effect(KILL cr); 9918 9919 ins_cost(275); 9920 format %{ "ucomiss $src1, $src2\n\t" 9921 "movl $dst, #-1\n\t" 9922 "jp,s done\n\t" 9923 "jb,s done\n\t" 9924 "setne $dst\n\t" 9925 "movzbl $dst, $dst\n" 9926 "done:" %} 9927 ins_encode %{ 9928 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9929 emit_cmpfp3(masm, $dst$$Register); 9930 %} 9931 ins_pipe(pipe_slow); 9932 %} 9933 9934 // Compare into -1,0,1 9935 instruct cmpF_mem(rRegI dst, regF src1, memory src2, rFlagsReg cr) 9936 %{ 9937 match(Set dst (CmpF3 src1 (LoadF src2))); 9938 effect(KILL cr); 9939 9940 ins_cost(275); 9941 format %{ "ucomiss $src1, $src2\n\t" 9942 "movl $dst, #-1\n\t" 9943 "jp,s done\n\t" 9944 "jb,s done\n\t" 9945 "setne $dst\n\t" 9946 "movzbl $dst, $dst\n" 9947 "done:" %} 9948 ins_encode %{ 9949 __ ucomiss($src1$$XMMRegister, $src2$$Address); 9950 emit_cmpfp3(masm, $dst$$Register); 9951 %} 9952 ins_pipe(pipe_slow); 9953 %} 9954 9955 // Compare into -1,0,1 9956 instruct cmpF_imm(rRegI dst, regF src, immF con, rFlagsReg cr) %{ 9957 match(Set dst (CmpF3 src con)); 9958 effect(KILL cr); 9959 9960 ins_cost(275); 9961 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 9962 "movl $dst, #-1\n\t" 9963 "jp,s done\n\t" 9964 "jb,s done\n\t" 9965 "setne $dst\n\t" 9966 "movzbl $dst, $dst\n" 9967 "done:" %} 9968 ins_encode %{ 9969 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 9970 emit_cmpfp3(masm, $dst$$Register); 9971 %} 9972 ins_pipe(pipe_slow); 9973 %} 9974 9975 // Compare into -1,0,1 9976 instruct cmpD_reg(rRegI dst, regD src1, regD src2, rFlagsReg cr) 9977 %{ 9978 match(Set dst (CmpD3 src1 src2)); 9979 effect(KILL cr); 9980 9981 ins_cost(275); 9982 format %{ "ucomisd $src1, $src2\n\t" 9983 "movl $dst, #-1\n\t" 9984 "jp,s done\n\t" 9985 "jb,s done\n\t" 9986 "setne $dst\n\t" 9987 "movzbl $dst, $dst\n" 9988 "done:" %} 9989 ins_encode %{ 9990 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9991 emit_cmpfp3(masm, $dst$$Register); 9992 %} 9993 ins_pipe(pipe_slow); 9994 %} 9995 9996 // Compare into -1,0,1 9997 instruct cmpD_mem(rRegI dst, regD src1, memory src2, rFlagsReg cr) 9998 %{ 9999 match(Set dst (CmpD3 src1 (LoadD src2))); 10000 effect(KILL cr); 10001 10002 ins_cost(275); 10003 format %{ "ucomisd $src1, $src2\n\t" 10004 "movl $dst, #-1\n\t" 10005 "jp,s done\n\t" 10006 "jb,s done\n\t" 10007 "setne $dst\n\t" 10008 "movzbl $dst, $dst\n" 10009 "done:" %} 10010 ins_encode %{ 10011 __ ucomisd($src1$$XMMRegister, $src2$$Address); 10012 emit_cmpfp3(masm, $dst$$Register); 10013 %} 10014 ins_pipe(pipe_slow); 10015 %} 10016 10017 // Compare into -1,0,1 10018 instruct cmpD_imm(rRegI dst, regD src, immD con, rFlagsReg cr) %{ 10019 match(Set dst (CmpD3 src con)); 10020 effect(KILL cr); 10021 10022 ins_cost(275); 10023 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 10024 "movl $dst, #-1\n\t" 10025 "jp,s done\n\t" 10026 "jb,s done\n\t" 10027 "setne $dst\n\t" 10028 "movzbl $dst, $dst\n" 10029 "done:" %} 10030 ins_encode %{ 10031 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 10032 emit_cmpfp3(masm, $dst$$Register); 10033 %} 10034 ins_pipe(pipe_slow); 10035 %} 10036 10037 //----------Arithmetic Conversion Instructions--------------------------------- 10038 10039 instruct convF2D_reg_reg(regD dst, regF src) 10040 %{ 10041 match(Set dst (ConvF2D src)); 10042 10043 format %{ "cvtss2sd $dst, $src" %} 10044 ins_encode %{ 10045 __ cvtss2sd ($dst$$XMMRegister, $src$$XMMRegister); 10046 %} 10047 ins_pipe(pipe_slow); // XXX 10048 %} 10049 10050 instruct convF2D_reg_mem(regD dst, memory src) 10051 %{ 10052 predicate(UseAVX == 0); 10053 match(Set dst (ConvF2D (LoadF src))); 10054 10055 format %{ "cvtss2sd $dst, $src" %} 10056 ins_encode %{ 10057 __ cvtss2sd ($dst$$XMMRegister, $src$$Address); 10058 %} 10059 ins_pipe(pipe_slow); // XXX 10060 %} 10061 10062 instruct convD2F_reg_reg(regF dst, regD src) 10063 %{ 10064 match(Set dst (ConvD2F src)); 10065 10066 format %{ "cvtsd2ss $dst, $src" %} 10067 ins_encode %{ 10068 __ cvtsd2ss ($dst$$XMMRegister, $src$$XMMRegister); 10069 %} 10070 ins_pipe(pipe_slow); // XXX 10071 %} 10072 10073 instruct convD2F_reg_mem(regF dst, memory src) 10074 %{ 10075 predicate(UseAVX == 0); 10076 match(Set dst (ConvD2F (LoadD src))); 10077 10078 format %{ "cvtsd2ss $dst, $src" %} 10079 ins_encode %{ 10080 __ cvtsd2ss ($dst$$XMMRegister, $src$$Address); 10081 %} 10082 ins_pipe(pipe_slow); // XXX 10083 %} 10084 10085 // XXX do mem variants 10086 instruct convF2I_reg_reg(rRegI dst, regF src, rFlagsReg cr) 10087 %{ 10088 match(Set dst (ConvF2I src)); 10089 effect(KILL cr); 10090 format %{ "convert_f2i $dst, $src" %} 10091 ins_encode %{ 10092 __ convertF2I(T_INT, T_FLOAT, $dst$$Register, $src$$XMMRegister); 10093 %} 10094 ins_pipe(pipe_slow); 10095 %} 10096 10097 instruct convF2L_reg_reg(rRegL dst, regF src, rFlagsReg cr) 10098 %{ 10099 match(Set dst (ConvF2L src)); 10100 effect(KILL cr); 10101 format %{ "convert_f2l $dst, $src"%} 10102 ins_encode %{ 10103 __ convertF2I(T_LONG, T_FLOAT, $dst$$Register, $src$$XMMRegister); 10104 %} 10105 ins_pipe(pipe_slow); 10106 %} 10107 10108 instruct convD2I_reg_reg(rRegI dst, regD src, rFlagsReg cr) 10109 %{ 10110 match(Set dst (ConvD2I src)); 10111 effect(KILL cr); 10112 format %{ "convert_d2i $dst, $src"%} 10113 ins_encode %{ 10114 __ convertF2I(T_INT, T_DOUBLE, $dst$$Register, $src$$XMMRegister); 10115 %} 10116 ins_pipe(pipe_slow); 10117 %} 10118 10119 instruct convD2L_reg_reg(rRegL dst, regD src, rFlagsReg cr) 10120 %{ 10121 match(Set dst (ConvD2L src)); 10122 effect(KILL cr); 10123 format %{ "convert_d2l $dst, $src"%} 10124 ins_encode %{ 10125 __ convertF2I(T_LONG, T_DOUBLE, $dst$$Register, $src$$XMMRegister); 10126 %} 10127 ins_pipe(pipe_slow); 10128 %} 10129 10130 instruct round_double_reg(rRegL dst, regD src, rRegL rtmp, rcx_RegL rcx, rFlagsReg cr) 10131 %{ 10132 match(Set dst (RoundD src)); 10133 effect(TEMP dst, TEMP rtmp, TEMP rcx, KILL cr); 10134 format %{ "round_double $dst,$src \t! using $rtmp and $rcx as TEMP"%} 10135 ins_encode %{ 10136 __ round_double($dst$$Register, $src$$XMMRegister, $rtmp$$Register, $rcx$$Register); 10137 %} 10138 ins_pipe(pipe_slow); 10139 %} 10140 10141 instruct round_float_reg(rRegI dst, regF src, rRegL rtmp, rcx_RegL rcx, rFlagsReg cr) 10142 %{ 10143 match(Set dst (RoundF src)); 10144 effect(TEMP dst, TEMP rtmp, TEMP rcx, KILL cr); 10145 format %{ "round_float $dst,$src" %} 10146 ins_encode %{ 10147 __ round_float($dst$$Register, $src$$XMMRegister, $rtmp$$Register, $rcx$$Register); 10148 %} 10149 ins_pipe(pipe_slow); 10150 %} 10151 10152 instruct convI2F_reg_reg(vlRegF dst, rRegI src) 10153 %{ 10154 predicate(!UseXmmI2F); 10155 match(Set dst (ConvI2F src)); 10156 10157 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10158 ins_encode %{ 10159 if (UseAVX > 0) { 10160 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 10161 } 10162 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Register); 10163 %} 10164 ins_pipe(pipe_slow); // XXX 10165 %} 10166 10167 instruct convI2F_reg_mem(regF dst, memory src) 10168 %{ 10169 predicate(UseAVX == 0); 10170 match(Set dst (ConvI2F (LoadI src))); 10171 10172 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10173 ins_encode %{ 10174 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Address); 10175 %} 10176 ins_pipe(pipe_slow); // XXX 10177 %} 10178 10179 instruct convI2D_reg_reg(vlRegD dst, rRegI src) 10180 %{ 10181 predicate(!UseXmmI2D); 10182 match(Set dst (ConvI2D src)); 10183 10184 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10185 ins_encode %{ 10186 if (UseAVX > 0) { 10187 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 10188 } 10189 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Register); 10190 %} 10191 ins_pipe(pipe_slow); // XXX 10192 %} 10193 10194 instruct convI2D_reg_mem(regD dst, memory src) 10195 %{ 10196 predicate(UseAVX == 0); 10197 match(Set dst (ConvI2D (LoadI src))); 10198 10199 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10200 ins_encode %{ 10201 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Address); 10202 %} 10203 ins_pipe(pipe_slow); // XXX 10204 %} 10205 10206 instruct convXI2F_reg(regF dst, rRegI src) 10207 %{ 10208 predicate(UseXmmI2F); 10209 match(Set dst (ConvI2F src)); 10210 10211 format %{ "movdl $dst, $src\n\t" 10212 "cvtdq2psl $dst, $dst\t# i2f" %} 10213 ins_encode %{ 10214 __ movdl($dst$$XMMRegister, $src$$Register); 10215 __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister); 10216 %} 10217 ins_pipe(pipe_slow); // XXX 10218 %} 10219 10220 instruct convXI2D_reg(regD dst, rRegI src) 10221 %{ 10222 predicate(UseXmmI2D); 10223 match(Set dst (ConvI2D src)); 10224 10225 format %{ "movdl $dst, $src\n\t" 10226 "cvtdq2pdl $dst, $dst\t# i2d" %} 10227 ins_encode %{ 10228 __ movdl($dst$$XMMRegister, $src$$Register); 10229 __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister); 10230 %} 10231 ins_pipe(pipe_slow); // XXX 10232 %} 10233 10234 instruct convL2F_reg_reg(vlRegF dst, rRegL src) 10235 %{ 10236 match(Set dst (ConvL2F src)); 10237 10238 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10239 ins_encode %{ 10240 if (UseAVX > 0) { 10241 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 10242 } 10243 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Register); 10244 %} 10245 ins_pipe(pipe_slow); // XXX 10246 %} 10247 10248 instruct convL2F_reg_mem(regF dst, memory src) 10249 %{ 10250 predicate(UseAVX == 0); 10251 match(Set dst (ConvL2F (LoadL src))); 10252 10253 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10254 ins_encode %{ 10255 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Address); 10256 %} 10257 ins_pipe(pipe_slow); // XXX 10258 %} 10259 10260 instruct convL2D_reg_reg(vlRegD dst, rRegL src) 10261 %{ 10262 match(Set dst (ConvL2D src)); 10263 10264 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10265 ins_encode %{ 10266 if (UseAVX > 0) { 10267 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 10268 } 10269 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Register); 10270 %} 10271 ins_pipe(pipe_slow); // XXX 10272 %} 10273 10274 instruct convL2D_reg_mem(regD dst, memory src) 10275 %{ 10276 predicate(UseAVX == 0); 10277 match(Set dst (ConvL2D (LoadL src))); 10278 10279 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10280 ins_encode %{ 10281 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Address); 10282 %} 10283 ins_pipe(pipe_slow); // XXX 10284 %} 10285 10286 instruct convI2L_reg_reg(rRegL dst, rRegI src) 10287 %{ 10288 match(Set dst (ConvI2L src)); 10289 10290 ins_cost(125); 10291 format %{ "movslq $dst, $src\t# i2l" %} 10292 ins_encode %{ 10293 __ movslq($dst$$Register, $src$$Register); 10294 %} 10295 ins_pipe(ialu_reg_reg); 10296 %} 10297 10298 // Zero-extend convert int to long 10299 instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask) 10300 %{ 10301 match(Set dst (AndL (ConvI2L src) mask)); 10302 10303 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10304 ins_encode %{ 10305 if ($dst$$reg != $src$$reg) { 10306 __ movl($dst$$Register, $src$$Register); 10307 } 10308 %} 10309 ins_pipe(ialu_reg_reg); 10310 %} 10311 10312 // Zero-extend convert int to long 10313 instruct convI2L_reg_mem_zex(rRegL dst, memory src, immL_32bits mask) 10314 %{ 10315 match(Set dst (AndL (ConvI2L (LoadI src)) mask)); 10316 10317 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10318 ins_encode %{ 10319 __ movl($dst$$Register, $src$$Address); 10320 %} 10321 ins_pipe(ialu_reg_mem); 10322 %} 10323 10324 instruct zerox_long_reg_reg(rRegL dst, rRegL src, immL_32bits mask) 10325 %{ 10326 match(Set dst (AndL src mask)); 10327 10328 format %{ "movl $dst, $src\t# zero-extend long" %} 10329 ins_encode %{ 10330 __ movl($dst$$Register, $src$$Register); 10331 %} 10332 ins_pipe(ialu_reg_reg); 10333 %} 10334 10335 instruct convL2I_reg_reg(rRegI dst, rRegL src) 10336 %{ 10337 match(Set dst (ConvL2I src)); 10338 10339 format %{ "movl $dst, $src\t# l2i" %} 10340 ins_encode %{ 10341 __ movl($dst$$Register, $src$$Register); 10342 %} 10343 ins_pipe(ialu_reg_reg); 10344 %} 10345 10346 10347 instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{ 10348 match(Set dst (MoveF2I src)); 10349 effect(DEF dst, USE src); 10350 10351 ins_cost(125); 10352 format %{ "movl $dst, $src\t# MoveF2I_stack_reg" %} 10353 ins_encode %{ 10354 __ movl($dst$$Register, Address(rsp, $src$$disp)); 10355 %} 10356 ins_pipe(ialu_reg_mem); 10357 %} 10358 10359 instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{ 10360 match(Set dst (MoveI2F src)); 10361 effect(DEF dst, USE src); 10362 10363 ins_cost(125); 10364 format %{ "movss $dst, $src\t# MoveI2F_stack_reg" %} 10365 ins_encode %{ 10366 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 10367 %} 10368 ins_pipe(pipe_slow); 10369 %} 10370 10371 instruct MoveD2L_stack_reg(rRegL dst, stackSlotD src) %{ 10372 match(Set dst (MoveD2L src)); 10373 effect(DEF dst, USE src); 10374 10375 ins_cost(125); 10376 format %{ "movq $dst, $src\t# MoveD2L_stack_reg" %} 10377 ins_encode %{ 10378 __ movq($dst$$Register, Address(rsp, $src$$disp)); 10379 %} 10380 ins_pipe(ialu_reg_mem); 10381 %} 10382 10383 instruct MoveL2D_stack_reg_partial(regD dst, stackSlotL src) %{ 10384 predicate(!UseXmmLoadAndClearUpper); 10385 match(Set dst (MoveL2D src)); 10386 effect(DEF dst, USE src); 10387 10388 ins_cost(125); 10389 format %{ "movlpd $dst, $src\t# MoveL2D_stack_reg" %} 10390 ins_encode %{ 10391 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10392 %} 10393 ins_pipe(pipe_slow); 10394 %} 10395 10396 instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{ 10397 predicate(UseXmmLoadAndClearUpper); 10398 match(Set dst (MoveL2D src)); 10399 effect(DEF dst, USE src); 10400 10401 ins_cost(125); 10402 format %{ "movsd $dst, $src\t# MoveL2D_stack_reg" %} 10403 ins_encode %{ 10404 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10405 %} 10406 ins_pipe(pipe_slow); 10407 %} 10408 10409 10410 instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{ 10411 match(Set dst (MoveF2I src)); 10412 effect(DEF dst, USE src); 10413 10414 ins_cost(95); // XXX 10415 format %{ "movss $dst, $src\t# MoveF2I_reg_stack" %} 10416 ins_encode %{ 10417 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 10418 %} 10419 ins_pipe(pipe_slow); 10420 %} 10421 10422 instruct MoveI2F_reg_stack(stackSlotF dst, rRegI src) %{ 10423 match(Set dst (MoveI2F src)); 10424 effect(DEF dst, USE src); 10425 10426 ins_cost(100); 10427 format %{ "movl $dst, $src\t# MoveI2F_reg_stack" %} 10428 ins_encode %{ 10429 __ movl(Address(rsp, $dst$$disp), $src$$Register); 10430 %} 10431 ins_pipe( ialu_mem_reg ); 10432 %} 10433 10434 instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{ 10435 match(Set dst (MoveD2L src)); 10436 effect(DEF dst, USE src); 10437 10438 ins_cost(95); // XXX 10439 format %{ "movsd $dst, $src\t# MoveL2D_reg_stack" %} 10440 ins_encode %{ 10441 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 10442 %} 10443 ins_pipe(pipe_slow); 10444 %} 10445 10446 instruct MoveL2D_reg_stack(stackSlotD dst, rRegL src) %{ 10447 match(Set dst (MoveL2D src)); 10448 effect(DEF dst, USE src); 10449 10450 ins_cost(100); 10451 format %{ "movq $dst, $src\t# MoveL2D_reg_stack" %} 10452 ins_encode %{ 10453 __ movq(Address(rsp, $dst$$disp), $src$$Register); 10454 %} 10455 ins_pipe(ialu_mem_reg); 10456 %} 10457 10458 instruct MoveF2I_reg_reg(rRegI dst, regF src) %{ 10459 match(Set dst (MoveF2I src)); 10460 effect(DEF dst, USE src); 10461 ins_cost(85); 10462 format %{ "movd $dst,$src\t# MoveF2I" %} 10463 ins_encode %{ 10464 __ movdl($dst$$Register, $src$$XMMRegister); 10465 %} 10466 ins_pipe( pipe_slow ); 10467 %} 10468 10469 instruct MoveD2L_reg_reg(rRegL dst, regD src) %{ 10470 match(Set dst (MoveD2L src)); 10471 effect(DEF dst, USE src); 10472 ins_cost(85); 10473 format %{ "movd $dst,$src\t# MoveD2L" %} 10474 ins_encode %{ 10475 __ movdq($dst$$Register, $src$$XMMRegister); 10476 %} 10477 ins_pipe( pipe_slow ); 10478 %} 10479 10480 instruct MoveI2F_reg_reg(regF dst, rRegI src) %{ 10481 match(Set dst (MoveI2F src)); 10482 effect(DEF dst, USE src); 10483 ins_cost(100); 10484 format %{ "movd $dst,$src\t# MoveI2F" %} 10485 ins_encode %{ 10486 __ movdl($dst$$XMMRegister, $src$$Register); 10487 %} 10488 ins_pipe( pipe_slow ); 10489 %} 10490 10491 instruct MoveL2D_reg_reg(regD dst, rRegL src) %{ 10492 match(Set dst (MoveL2D src)); 10493 effect(DEF dst, USE src); 10494 ins_cost(100); 10495 format %{ "movd $dst,$src\t# MoveL2D" %} 10496 ins_encode %{ 10497 __ movdq($dst$$XMMRegister, $src$$Register); 10498 %} 10499 ins_pipe( pipe_slow ); 10500 %} 10501 10502 10503 // Fast clearing of an array 10504 // Small non-constant lenght ClearArray for non-AVX512 targets. 10505 instruct rep_stos(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegL val, 10506 Universe dummy, rFlagsReg cr) 10507 %{ 10508 predicate(!((ClearArrayNode*)n)->is_large() && !((ClearArrayNode*)n)->word_copy_only() && (UseAVX <= 2)); 10509 match(Set dummy (ClearArray (Binary cnt base) val)); 10510 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, USE_KILL val, KILL cr); 10511 10512 format %{ $$template 10513 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 10514 $$emit$$"jg LARGE\n\t" 10515 $$emit$$"dec rcx\n\t" 10516 $$emit$$"js DONE\t# Zero length\n\t" 10517 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 10518 $$emit$$"dec rcx\n\t" 10519 $$emit$$"jge LOOP\n\t" 10520 $$emit$$"jmp DONE\n\t" 10521 $$emit$$"# LARGE:\n\t" 10522 if (UseFastStosb) { 10523 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10524 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--\n\t" 10525 } else if (UseXMMForObjInit) { 10526 $$emit$$"movdq $tmp, $val\n\t" 10527 $$emit$$"punpcklqdq $tmp, $tmp\n\t" 10528 $$emit$$"vinserti128_high $tmp, $tmp\n\t" 10529 $$emit$$"jmpq L_zero_64_bytes\n\t" 10530 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10531 $$emit$$"vmovdqu $tmp,(rax)\n\t" 10532 $$emit$$"vmovdqu $tmp,0x20(rax)\n\t" 10533 $$emit$$"add 0x40,rax\n\t" 10534 $$emit$$"# L_zero_64_bytes:\n\t" 10535 $$emit$$"sub 0x8,rcx\n\t" 10536 $$emit$$"jge L_loop\n\t" 10537 $$emit$$"add 0x4,rcx\n\t" 10538 $$emit$$"jl L_tail\n\t" 10539 $$emit$$"vmovdqu $tmp,(rax)\n\t" 10540 $$emit$$"add 0x20,rax\n\t" 10541 $$emit$$"sub 0x4,rcx\n\t" 10542 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10543 $$emit$$"add 0x4,rcx\n\t" 10544 $$emit$$"jle L_end\n\t" 10545 $$emit$$"dec rcx\n\t" 10546 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10547 $$emit$$"vmovq xmm0,(rax)\n\t" 10548 $$emit$$"add 0x8,rax\n\t" 10549 $$emit$$"dec rcx\n\t" 10550 $$emit$$"jge L_sloop\n\t" 10551 $$emit$$"# L_end:\n\t" 10552 } else { 10553 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 10554 } 10555 $$emit$$"# DONE" 10556 %} 10557 ins_encode %{ 10558 __ clear_mem($base$$Register, $cnt$$Register, $val$$Register, 10559 $tmp$$XMMRegister, false, false); 10560 %} 10561 ins_pipe(pipe_slow); 10562 %} 10563 10564 instruct rep_stos_word_copy(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegL val, 10565 Universe dummy, rFlagsReg cr) 10566 %{ 10567 predicate(!((ClearArrayNode*)n)->is_large() && ((ClearArrayNode*)n)->word_copy_only() && (UseAVX <= 2)); 10568 match(Set dummy (ClearArray (Binary cnt base) val)); 10569 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, USE_KILL val, KILL cr); 10570 10571 format %{ $$template 10572 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 10573 $$emit$$"jg LARGE\n\t" 10574 $$emit$$"dec rcx\n\t" 10575 $$emit$$"js DONE\t# Zero length\n\t" 10576 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 10577 $$emit$$"dec rcx\n\t" 10578 $$emit$$"jge LOOP\n\t" 10579 $$emit$$"jmp DONE\n\t" 10580 $$emit$$"# LARGE:\n\t" 10581 if (UseXMMForObjInit) { 10582 $$emit$$"movdq $tmp, $val\n\t" 10583 $$emit$$"punpcklqdq $tmp, $tmp\n\t" 10584 $$emit$$"vinserti128_high $tmp, $tmp\n\t" 10585 $$emit$$"jmpq L_zero_64_bytes\n\t" 10586 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10587 $$emit$$"vmovdqu $tmp,(rax)\n\t" 10588 $$emit$$"vmovdqu $tmp,0x20(rax)\n\t" 10589 $$emit$$"add 0x40,rax\n\t" 10590 $$emit$$"# L_zero_64_bytes:\n\t" 10591 $$emit$$"sub 0x8,rcx\n\t" 10592 $$emit$$"jge L_loop\n\t" 10593 $$emit$$"add 0x4,rcx\n\t" 10594 $$emit$$"jl L_tail\n\t" 10595 $$emit$$"vmovdqu $tmp,(rax)\n\t" 10596 $$emit$$"add 0x20,rax\n\t" 10597 $$emit$$"sub 0x4,rcx\n\t" 10598 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10599 $$emit$$"add 0x4,rcx\n\t" 10600 $$emit$$"jle L_end\n\t" 10601 $$emit$$"dec rcx\n\t" 10602 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10603 $$emit$$"vmovq xmm0,(rax)\n\t" 10604 $$emit$$"add 0x8,rax\n\t" 10605 $$emit$$"dec rcx\n\t" 10606 $$emit$$"jge L_sloop\n\t" 10607 $$emit$$"# L_end:\n\t" 10608 } else { 10609 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 10610 } 10611 $$emit$$"# DONE" 10612 %} 10613 ins_encode %{ 10614 __ clear_mem($base$$Register, $cnt$$Register, $val$$Register, 10615 $tmp$$XMMRegister, false, true); 10616 %} 10617 ins_pipe(pipe_slow); 10618 %} 10619 10620 // Small non-constant length ClearArray for AVX512 targets. 10621 instruct rep_stos_evex(rcx_RegL cnt, rdi_RegP base, legRegD tmp, kReg ktmp, rax_RegL val, 10622 Universe dummy, rFlagsReg cr) 10623 %{ 10624 predicate(!((ClearArrayNode*)n)->is_large() && !((ClearArrayNode*)n)->word_copy_only() && (UseAVX > 2)); 10625 match(Set dummy (ClearArray (Binary cnt base) val)); 10626 ins_cost(125); 10627 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, TEMP ktmp, USE_KILL val, KILL cr); 10628 10629 format %{ $$template 10630 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10631 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 10632 $$emit$$"jg LARGE\n\t" 10633 $$emit$$"dec rcx\n\t" 10634 $$emit$$"js DONE\t# Zero length\n\t" 10635 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 10636 $$emit$$"dec rcx\n\t" 10637 $$emit$$"jge LOOP\n\t" 10638 $$emit$$"jmp DONE\n\t" 10639 $$emit$$"# LARGE:\n\t" 10640 if (UseFastStosb) { 10641 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10642 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--\n\t" 10643 } else if (UseXMMForObjInit) { 10644 $$emit$$"mov rdi,rax\n\t" 10645 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 10646 $$emit$$"jmpq L_zero_64_bytes\n\t" 10647 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10648 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10649 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 10650 $$emit$$"add 0x40,rax\n\t" 10651 $$emit$$"# L_zero_64_bytes:\n\t" 10652 $$emit$$"sub 0x8,rcx\n\t" 10653 $$emit$$"jge L_loop\n\t" 10654 $$emit$$"add 0x4,rcx\n\t" 10655 $$emit$$"jl L_tail\n\t" 10656 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10657 $$emit$$"add 0x20,rax\n\t" 10658 $$emit$$"sub 0x4,rcx\n\t" 10659 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10660 $$emit$$"add 0x4,rcx\n\t" 10661 $$emit$$"jle L_end\n\t" 10662 $$emit$$"dec rcx\n\t" 10663 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10664 $$emit$$"vmovq xmm0,(rax)\n\t" 10665 $$emit$$"add 0x8,rax\n\t" 10666 $$emit$$"dec rcx\n\t" 10667 $$emit$$"jge L_sloop\n\t" 10668 $$emit$$"# L_end:\n\t" 10669 } else { 10670 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 10671 } 10672 $$emit$$"# DONE" 10673 %} 10674 ins_encode %{ 10675 __ clear_mem($base$$Register, $cnt$$Register, $val$$Register, 10676 $tmp$$XMMRegister, false, false, $ktmp$$KRegister); 10677 %} 10678 ins_pipe(pipe_slow); 10679 %} 10680 10681 instruct rep_stos_evex_word_copy(rcx_RegL cnt, rdi_RegP base, legRegD tmp, kReg ktmp, rax_RegL val, 10682 Universe dummy, rFlagsReg cr) 10683 %{ 10684 predicate(!((ClearArrayNode*)n)->is_large() && ((ClearArrayNode*)n)->word_copy_only() && (UseAVX > 2)); 10685 match(Set dummy (ClearArray (Binary cnt base) val)); 10686 ins_cost(125); 10687 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, TEMP ktmp, USE_KILL val, KILL cr); 10688 10689 format %{ $$template 10690 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10691 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 10692 $$emit$$"jg LARGE\n\t" 10693 $$emit$$"dec rcx\n\t" 10694 $$emit$$"js DONE\t# Zero length\n\t" 10695 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 10696 $$emit$$"dec rcx\n\t" 10697 $$emit$$"jge LOOP\n\t" 10698 $$emit$$"jmp DONE\n\t" 10699 $$emit$$"# LARGE:\n\t" 10700 if (UseFastStosb) { 10701 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10702 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--\n\t" 10703 } else if (UseXMMForObjInit) { 10704 $$emit$$"mov rdi,rax\n\t" 10705 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 10706 $$emit$$"jmpq L_zero_64_bytes\n\t" 10707 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10708 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10709 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 10710 $$emit$$"add 0x40,rax\n\t" 10711 $$emit$$"# L_zero_64_bytes:\n\t" 10712 $$emit$$"sub 0x8,rcx\n\t" 10713 $$emit$$"jge L_loop\n\t" 10714 $$emit$$"add 0x4,rcx\n\t" 10715 $$emit$$"jl L_tail\n\t" 10716 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10717 $$emit$$"add 0x20,rax\n\t" 10718 $$emit$$"sub 0x4,rcx\n\t" 10719 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10720 $$emit$$"add 0x4,rcx\n\t" 10721 $$emit$$"jle L_end\n\t" 10722 $$emit$$"dec rcx\n\t" 10723 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10724 $$emit$$"vmovq xmm0,(rax)\n\t" 10725 $$emit$$"add 0x8,rax\n\t" 10726 $$emit$$"dec rcx\n\t" 10727 $$emit$$"jge L_sloop\n\t" 10728 $$emit$$"# L_end:\n\t" 10729 } else { 10730 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 10731 } 10732 $$emit$$"# DONE" 10733 %} 10734 ins_encode %{ 10735 __ clear_mem($base$$Register, $cnt$$Register, $val$$Register, 10736 $tmp$$XMMRegister, false, true, $ktmp$$KRegister); 10737 %} 10738 ins_pipe(pipe_slow); 10739 %} 10740 10741 // Large non-constant length ClearArray for non-AVX512 targets. 10742 instruct rep_stos_large(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegL val, 10743 Universe dummy, rFlagsReg cr) 10744 %{ 10745 predicate(((ClearArrayNode*)n)->is_large() && !((ClearArrayNode*)n)->word_copy_only() && (UseAVX <= 2)); 10746 match(Set dummy (ClearArray (Binary cnt base) val)); 10747 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, USE_KILL val, KILL cr); 10748 10749 format %{ $$template 10750 if (UseFastStosb) { 10751 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10752 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--" 10753 } else if (UseXMMForObjInit) { 10754 $$emit$$"movdq $tmp, $val\n\t" 10755 $$emit$$"punpcklqdq $tmp, $tmp\n\t" 10756 $$emit$$"vinserti128_high $tmp, $tmp\n\t" 10757 $$emit$$"jmpq L_zero_64_bytes\n\t" 10758 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10759 $$emit$$"vmovdqu $tmp,(rax)\n\t" 10760 $$emit$$"vmovdqu $tmp,0x20(rax)\n\t" 10761 $$emit$$"add 0x40,rax\n\t" 10762 $$emit$$"# L_zero_64_bytes:\n\t" 10763 $$emit$$"sub 0x8,rcx\n\t" 10764 $$emit$$"jge L_loop\n\t" 10765 $$emit$$"add 0x4,rcx\n\t" 10766 $$emit$$"jl L_tail\n\t" 10767 $$emit$$"vmovdqu $tmp,(rax)\n\t" 10768 $$emit$$"add 0x20,rax\n\t" 10769 $$emit$$"sub 0x4,rcx\n\t" 10770 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10771 $$emit$$"add 0x4,rcx\n\t" 10772 $$emit$$"jle L_end\n\t" 10773 $$emit$$"dec rcx\n\t" 10774 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10775 $$emit$$"vmovq xmm0,(rax)\n\t" 10776 $$emit$$"add 0x8,rax\n\t" 10777 $$emit$$"dec rcx\n\t" 10778 $$emit$$"jge L_sloop\n\t" 10779 $$emit$$"# L_end:\n\t" 10780 } else { 10781 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 10782 } 10783 %} 10784 ins_encode %{ 10785 __ clear_mem($base$$Register, $cnt$$Register, $val$$Register, 10786 $tmp$$XMMRegister, true, false); 10787 %} 10788 ins_pipe(pipe_slow); 10789 %} 10790 10791 instruct rep_stos_large_word_copy(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegL val, 10792 Universe dummy, rFlagsReg cr) 10793 %{ 10794 predicate(((ClearArrayNode*)n)->is_large() && ((ClearArrayNode*)n)->word_copy_only() && (UseAVX <= 2)); 10795 match(Set dummy (ClearArray (Binary cnt base) val)); 10796 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, USE_KILL val, KILL cr); 10797 10798 format %{ $$template 10799 if (UseXMMForObjInit) { 10800 $$emit$$"movdq $tmp, $val\n\t" 10801 $$emit$$"punpcklqdq $tmp, $tmp\n\t" 10802 $$emit$$"vinserti128_high $tmp, $tmp\n\t" 10803 $$emit$$"jmpq L_zero_64_bytes\n\t" 10804 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10805 $$emit$$"vmovdqu $tmp,(rax)\n\t" 10806 $$emit$$"vmovdqu $tmp,0x20(rax)\n\t" 10807 $$emit$$"add 0x40,rax\n\t" 10808 $$emit$$"# L_zero_64_bytes:\n\t" 10809 $$emit$$"sub 0x8,rcx\n\t" 10810 $$emit$$"jge L_loop\n\t" 10811 $$emit$$"add 0x4,rcx\n\t" 10812 $$emit$$"jl L_tail\n\t" 10813 $$emit$$"vmovdqu $tmp,(rax)\n\t" 10814 $$emit$$"add 0x20,rax\n\t" 10815 $$emit$$"sub 0x4,rcx\n\t" 10816 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10817 $$emit$$"add 0x4,rcx\n\t" 10818 $$emit$$"jle L_end\n\t" 10819 $$emit$$"dec rcx\n\t" 10820 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10821 $$emit$$"vmovq xmm0,(rax)\n\t" 10822 $$emit$$"add 0x8,rax\n\t" 10823 $$emit$$"dec rcx\n\t" 10824 $$emit$$"jge L_sloop\n\t" 10825 $$emit$$"# L_end:\n\t" 10826 } else { 10827 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 10828 } 10829 %} 10830 ins_encode %{ 10831 __ clear_mem($base$$Register, $cnt$$Register, $val$$Register, 10832 $tmp$$XMMRegister, true, true); 10833 %} 10834 ins_pipe(pipe_slow); 10835 %} 10836 10837 // Large non-constant length ClearArray for AVX512 targets. 10838 instruct rep_stos_large_evex(rcx_RegL cnt, rdi_RegP base, legRegD tmp, kReg ktmp, rax_RegL val, 10839 Universe dummy, rFlagsReg cr) 10840 %{ 10841 predicate(((ClearArrayNode*)n)->is_large() && !((ClearArrayNode*)n)->word_copy_only() && (UseAVX > 2)); 10842 match(Set dummy (ClearArray (Binary cnt base) val)); 10843 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, TEMP ktmp, USE_KILL val, KILL cr); 10844 10845 format %{ $$template 10846 if (UseFastStosb) { 10847 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10848 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10849 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--" 10850 } else if (UseXMMForObjInit) { 10851 $$emit$$"mov rdi,rax\t# ClearArray:\n\t" 10852 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 10853 $$emit$$"jmpq L_zero_64_bytes\n\t" 10854 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10855 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10856 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 10857 $$emit$$"add 0x40,rax\n\t" 10858 $$emit$$"# L_zero_64_bytes:\n\t" 10859 $$emit$$"sub 0x8,rcx\n\t" 10860 $$emit$$"jge L_loop\n\t" 10861 $$emit$$"add 0x4,rcx\n\t" 10862 $$emit$$"jl L_tail\n\t" 10863 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10864 $$emit$$"add 0x20,rax\n\t" 10865 $$emit$$"sub 0x4,rcx\n\t" 10866 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10867 $$emit$$"add 0x4,rcx\n\t" 10868 $$emit$$"jle L_end\n\t" 10869 $$emit$$"dec rcx\n\t" 10870 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10871 $$emit$$"vmovq xmm0,(rax)\n\t" 10872 $$emit$$"add 0x8,rax\n\t" 10873 $$emit$$"dec rcx\n\t" 10874 $$emit$$"jge L_sloop\n\t" 10875 $$emit$$"# L_end:\n\t" 10876 } else { 10877 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10878 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 10879 } 10880 %} 10881 ins_encode %{ 10882 __ clear_mem($base$$Register, $cnt$$Register, $val$$Register, 10883 $tmp$$XMMRegister, true, false, $ktmp$$KRegister); 10884 %} 10885 ins_pipe(pipe_slow); 10886 %} 10887 10888 instruct rep_stos_large_evex_word_copy(rcx_RegL cnt, rdi_RegP base, legRegD tmp, kReg ktmp, rax_RegL val, 10889 Universe dummy, rFlagsReg cr) 10890 %{ 10891 predicate(((ClearArrayNode*)n)->is_large() && ((ClearArrayNode*)n)->word_copy_only() && (UseAVX > 2)); 10892 match(Set dummy (ClearArray (Binary cnt base) val)); 10893 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, TEMP ktmp, USE_KILL val, KILL cr); 10894 10895 format %{ $$template 10896 if (UseFastStosb) { 10897 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10898 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10899 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--" 10900 } else if (UseXMMForObjInit) { 10901 $$emit$$"mov rdi,rax\t# ClearArray:\n\t" 10902 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 10903 $$emit$$"jmpq L_zero_64_bytes\n\t" 10904 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10905 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10906 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 10907 $$emit$$"add 0x40,rax\n\t" 10908 $$emit$$"# L_zero_64_bytes:\n\t" 10909 $$emit$$"sub 0x8,rcx\n\t" 10910 $$emit$$"jge L_loop\n\t" 10911 $$emit$$"add 0x4,rcx\n\t" 10912 $$emit$$"jl L_tail\n\t" 10913 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10914 $$emit$$"add 0x20,rax\n\t" 10915 $$emit$$"sub 0x4,rcx\n\t" 10916 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10917 $$emit$$"add 0x4,rcx\n\t" 10918 $$emit$$"jle L_end\n\t" 10919 $$emit$$"dec rcx\n\t" 10920 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10921 $$emit$$"vmovq xmm0,(rax)\n\t" 10922 $$emit$$"add 0x8,rax\n\t" 10923 $$emit$$"dec rcx\n\t" 10924 $$emit$$"jge L_sloop\n\t" 10925 $$emit$$"# L_end:\n\t" 10926 } else { 10927 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10928 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 10929 } 10930 %} 10931 ins_encode %{ 10932 __ clear_mem($base$$Register, $cnt$$Register, $val$$Register, 10933 $tmp$$XMMRegister, true, true, $ktmp$$KRegister); 10934 %} 10935 ins_pipe(pipe_slow); 10936 %} 10937 10938 // Small constant length ClearArray for AVX512 targets. 10939 instruct rep_stos_im(immL cnt, rRegP base, regD tmp, rax_RegL val, kReg ktmp, Universe dummy, rFlagsReg cr) 10940 %{ 10941 predicate(!((ClearArrayNode*)n)->is_large() && !((ClearArrayNode*)n)->word_copy_only() && 10942 ((MaxVectorSize >= 32) && VM_Version::supports_avx512vl())); 10943 match(Set dummy (ClearArray (Binary cnt base) val)); 10944 ins_cost(100); 10945 effect(TEMP tmp, USE_KILL val, TEMP ktmp, KILL cr); 10946 format %{ "clear_mem_imm $base , $cnt \n\t" %} 10947 ins_encode %{ 10948 __ clear_mem($base$$Register, $cnt$$constant, $val$$Register, $tmp$$XMMRegister, $ktmp$$KRegister); 10949 %} 10950 ins_pipe(pipe_slow); 10951 %} 10952 10953 instruct string_compareL(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10954 rax_RegI result, legRegD tmp1, rFlagsReg cr) 10955 %{ 10956 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 10957 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10958 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10959 10960 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10961 ins_encode %{ 10962 __ string_compare($str1$$Register, $str2$$Register, 10963 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10964 $tmp1$$XMMRegister, StrIntrinsicNode::LL, knoreg); 10965 %} 10966 ins_pipe( pipe_slow ); 10967 %} 10968 10969 instruct string_compareL_evex(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10970 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 10971 %{ 10972 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 10973 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10974 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10975 10976 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10977 ins_encode %{ 10978 __ string_compare($str1$$Register, $str2$$Register, 10979 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10980 $tmp1$$XMMRegister, StrIntrinsicNode::LL, $ktmp$$KRegister); 10981 %} 10982 ins_pipe( pipe_slow ); 10983 %} 10984 10985 instruct string_compareU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10986 rax_RegI result, legRegD tmp1, rFlagsReg cr) 10987 %{ 10988 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 10989 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10990 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10991 10992 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10993 ins_encode %{ 10994 __ string_compare($str1$$Register, $str2$$Register, 10995 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10996 $tmp1$$XMMRegister, StrIntrinsicNode::UU, knoreg); 10997 %} 10998 ins_pipe( pipe_slow ); 10999 %} 11000 11001 instruct string_compareU_evex(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 11002 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 11003 %{ 11004 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 11005 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11006 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11007 11008 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11009 ins_encode %{ 11010 __ string_compare($str1$$Register, $str2$$Register, 11011 $cnt1$$Register, $cnt2$$Register, $result$$Register, 11012 $tmp1$$XMMRegister, StrIntrinsicNode::UU, $ktmp$$KRegister); 11013 %} 11014 ins_pipe( pipe_slow ); 11015 %} 11016 11017 instruct string_compareLU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 11018 rax_RegI result, legRegD tmp1, rFlagsReg cr) 11019 %{ 11020 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 11021 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11022 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11023 11024 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11025 ins_encode %{ 11026 __ string_compare($str1$$Register, $str2$$Register, 11027 $cnt1$$Register, $cnt2$$Register, $result$$Register, 11028 $tmp1$$XMMRegister, StrIntrinsicNode::LU, knoreg); 11029 %} 11030 ins_pipe( pipe_slow ); 11031 %} 11032 11033 instruct string_compareLU_evex(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 11034 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 11035 %{ 11036 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 11037 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11038 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11039 11040 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11041 ins_encode %{ 11042 __ string_compare($str1$$Register, $str2$$Register, 11043 $cnt1$$Register, $cnt2$$Register, $result$$Register, 11044 $tmp1$$XMMRegister, StrIntrinsicNode::LU, $ktmp$$KRegister); 11045 %} 11046 ins_pipe( pipe_slow ); 11047 %} 11048 11049 instruct string_compareUL(rsi_RegP str1, rdx_RegI cnt1, rdi_RegP str2, rcx_RegI cnt2, 11050 rax_RegI result, legRegD tmp1, rFlagsReg cr) 11051 %{ 11052 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 11053 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11054 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11055 11056 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11057 ins_encode %{ 11058 __ string_compare($str2$$Register, $str1$$Register, 11059 $cnt2$$Register, $cnt1$$Register, $result$$Register, 11060 $tmp1$$XMMRegister, StrIntrinsicNode::UL, knoreg); 11061 %} 11062 ins_pipe( pipe_slow ); 11063 %} 11064 11065 instruct string_compareUL_evex(rsi_RegP str1, rdx_RegI cnt1, rdi_RegP str2, rcx_RegI cnt2, 11066 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 11067 %{ 11068 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 11069 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11070 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11071 11072 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11073 ins_encode %{ 11074 __ string_compare($str2$$Register, $str1$$Register, 11075 $cnt2$$Register, $cnt1$$Register, $result$$Register, 11076 $tmp1$$XMMRegister, StrIntrinsicNode::UL, $ktmp$$KRegister); 11077 %} 11078 ins_pipe( pipe_slow ); 11079 %} 11080 11081 // fast search of substring with known size. 11082 instruct string_indexof_conL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 11083 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 11084 %{ 11085 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 11086 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 11087 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 11088 11089 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %} 11090 ins_encode %{ 11091 int icnt2 = (int)$int_cnt2$$constant; 11092 if (icnt2 >= 16) { 11093 // IndexOf for constant substrings with size >= 16 elements 11094 // which don't need to be loaded through stack. 11095 __ string_indexofC8($str1$$Register, $str2$$Register, 11096 $cnt1$$Register, $cnt2$$Register, 11097 icnt2, $result$$Register, 11098 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 11099 } else { 11100 // Small strings are loaded through stack if they cross page boundary. 11101 __ string_indexof($str1$$Register, $str2$$Register, 11102 $cnt1$$Register, $cnt2$$Register, 11103 icnt2, $result$$Register, 11104 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 11105 } 11106 %} 11107 ins_pipe( pipe_slow ); 11108 %} 11109 11110 // fast search of substring with known size. 11111 instruct string_indexof_conU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 11112 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 11113 %{ 11114 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 11115 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 11116 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 11117 11118 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %} 11119 ins_encode %{ 11120 int icnt2 = (int)$int_cnt2$$constant; 11121 if (icnt2 >= 8) { 11122 // IndexOf for constant substrings with size >= 8 elements 11123 // which don't need to be loaded through stack. 11124 __ string_indexofC8($str1$$Register, $str2$$Register, 11125 $cnt1$$Register, $cnt2$$Register, 11126 icnt2, $result$$Register, 11127 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 11128 } else { 11129 // Small strings are loaded through stack if they cross page boundary. 11130 __ string_indexof($str1$$Register, $str2$$Register, 11131 $cnt1$$Register, $cnt2$$Register, 11132 icnt2, $result$$Register, 11133 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 11134 } 11135 %} 11136 ins_pipe( pipe_slow ); 11137 %} 11138 11139 // fast search of substring with known size. 11140 instruct string_indexof_conUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 11141 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 11142 %{ 11143 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 11144 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 11145 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 11146 11147 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %} 11148 ins_encode %{ 11149 int icnt2 = (int)$int_cnt2$$constant; 11150 if (icnt2 >= 8) { 11151 // IndexOf for constant substrings with size >= 8 elements 11152 // which don't need to be loaded through stack. 11153 __ string_indexofC8($str1$$Register, $str2$$Register, 11154 $cnt1$$Register, $cnt2$$Register, 11155 icnt2, $result$$Register, 11156 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 11157 } else { 11158 // Small strings are loaded through stack if they cross page boundary. 11159 __ string_indexof($str1$$Register, $str2$$Register, 11160 $cnt1$$Register, $cnt2$$Register, 11161 icnt2, $result$$Register, 11162 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 11163 } 11164 %} 11165 ins_pipe( pipe_slow ); 11166 %} 11167 11168 instruct string_indexofL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11169 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr) 11170 %{ 11171 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 11172 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11173 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11174 11175 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11176 ins_encode %{ 11177 __ string_indexof($str1$$Register, $str2$$Register, 11178 $cnt1$$Register, $cnt2$$Register, 11179 (-1), $result$$Register, 11180 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 11181 %} 11182 ins_pipe( pipe_slow ); 11183 %} 11184 11185 instruct string_indexofU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11186 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr) 11187 %{ 11188 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 11189 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11190 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11191 11192 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11193 ins_encode %{ 11194 __ string_indexof($str1$$Register, $str2$$Register, 11195 $cnt1$$Register, $cnt2$$Register, 11196 (-1), $result$$Register, 11197 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 11198 %} 11199 ins_pipe( pipe_slow ); 11200 %} 11201 11202 instruct string_indexofUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11203 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr) 11204 %{ 11205 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 11206 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11207 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11208 11209 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11210 ins_encode %{ 11211 __ string_indexof($str1$$Register, $str2$$Register, 11212 $cnt1$$Register, $cnt2$$Register, 11213 (-1), $result$$Register, 11214 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 11215 %} 11216 ins_pipe( pipe_slow ); 11217 %} 11218 11219 instruct string_indexof_char(rdi_RegP str1, rdx_RegI cnt1, rax_RegI ch, 11220 rbx_RegI result, legRegD tmp_vec1, legRegD tmp_vec2, legRegD tmp_vec3, rcx_RegI tmp, rFlagsReg cr) 11221 %{ 11222 predicate(UseSSE42Intrinsics && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::U)); 11223 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 11224 effect(TEMP tmp_vec1, TEMP tmp_vec2, TEMP tmp_vec3, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP tmp, KILL cr); 11225 format %{ "StringUTF16 IndexOf char[] $str1,$cnt1,$ch -> $result // KILL all" %} 11226 ins_encode %{ 11227 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register, 11228 $tmp_vec1$$XMMRegister, $tmp_vec2$$XMMRegister, $tmp_vec3$$XMMRegister, $tmp$$Register); 11229 %} 11230 ins_pipe( pipe_slow ); 11231 %} 11232 11233 instruct stringL_indexof_char(rdi_RegP str1, rdx_RegI cnt1, rax_RegI ch, 11234 rbx_RegI result, legRegD tmp_vec1, legRegD tmp_vec2, legRegD tmp_vec3, rcx_RegI tmp, rFlagsReg cr) 11235 %{ 11236 predicate(UseSSE42Intrinsics && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::L)); 11237 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 11238 effect(TEMP tmp_vec1, TEMP tmp_vec2, TEMP tmp_vec3, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP tmp, KILL cr); 11239 format %{ "StringLatin1 IndexOf char[] $str1,$cnt1,$ch -> $result // KILL all" %} 11240 ins_encode %{ 11241 __ stringL_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register, 11242 $tmp_vec1$$XMMRegister, $tmp_vec2$$XMMRegister, $tmp_vec3$$XMMRegister, $tmp$$Register); 11243 %} 11244 ins_pipe( pipe_slow ); 11245 %} 11246 11247 // fast string equals 11248 instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 11249 legRegD tmp1, legRegD tmp2, rbx_RegI tmp3, rFlagsReg cr) 11250 %{ 11251 predicate(!VM_Version::supports_avx512vlbw()); 11252 match(Set result (StrEquals (Binary str1 str2) cnt)); 11253 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 11254 11255 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11256 ins_encode %{ 11257 __ arrays_equals(false, $str1$$Register, $str2$$Register, 11258 $cnt$$Register, $result$$Register, $tmp3$$Register, 11259 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, knoreg); 11260 %} 11261 ins_pipe( pipe_slow ); 11262 %} 11263 11264 instruct string_equals_evex(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 11265 legRegD tmp1, legRegD tmp2, kReg ktmp, rbx_RegI tmp3, rFlagsReg cr) 11266 %{ 11267 predicate(VM_Version::supports_avx512vlbw()); 11268 match(Set result (StrEquals (Binary str1 str2) cnt)); 11269 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 11270 11271 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11272 ins_encode %{ 11273 __ arrays_equals(false, $str1$$Register, $str2$$Register, 11274 $cnt$$Register, $result$$Register, $tmp3$$Register, 11275 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, $ktmp$$KRegister); 11276 %} 11277 ins_pipe( pipe_slow ); 11278 %} 11279 11280 // fast array equals 11281 instruct array_equalsB(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11282 legRegD tmp1, legRegD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11283 %{ 11284 predicate(!VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 11285 match(Set result (AryEq ary1 ary2)); 11286 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11287 11288 format %{ "Array Equals byte[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11289 ins_encode %{ 11290 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11291 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11292 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, knoreg); 11293 %} 11294 ins_pipe( pipe_slow ); 11295 %} 11296 11297 instruct array_equalsB_evex(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11298 legRegD tmp1, legRegD tmp2, kReg ktmp, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11299 %{ 11300 predicate(VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 11301 match(Set result (AryEq ary1 ary2)); 11302 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11303 11304 format %{ "Array Equals byte[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11305 ins_encode %{ 11306 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11307 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11308 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, $ktmp$$KRegister); 11309 %} 11310 ins_pipe( pipe_slow ); 11311 %} 11312 11313 instruct array_equalsC(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11314 legRegD tmp1, legRegD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11315 %{ 11316 predicate(!VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 11317 match(Set result (AryEq ary1 ary2)); 11318 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11319 11320 format %{ "Array Equals char[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11321 ins_encode %{ 11322 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11323 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11324 $tmp1$$XMMRegister, $tmp2$$XMMRegister, true /* char */, knoreg); 11325 %} 11326 ins_pipe( pipe_slow ); 11327 %} 11328 11329 instruct array_equalsC_evex(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11330 legRegD tmp1, legRegD tmp2, kReg ktmp, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11331 %{ 11332 predicate(VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 11333 match(Set result (AryEq ary1 ary2)); 11334 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11335 11336 format %{ "Array Equals char[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11337 ins_encode %{ 11338 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11339 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11340 $tmp1$$XMMRegister, $tmp2$$XMMRegister, true /* char */, $ktmp$$KRegister); 11341 %} 11342 ins_pipe( pipe_slow ); 11343 %} 11344 11345 instruct arrays_hashcode(rdi_RegP ary1, rdx_RegI cnt1, rbx_RegI result, immU8 basic_type, 11346 legRegD tmp_vec1, legRegD tmp_vec2, legRegD tmp_vec3, legRegD tmp_vec4, 11347 legRegD tmp_vec5, legRegD tmp_vec6, legRegD tmp_vec7, legRegD tmp_vec8, 11348 legRegD tmp_vec9, legRegD tmp_vec10, legRegD tmp_vec11, legRegD tmp_vec12, 11349 legRegD tmp_vec13, rRegI tmp1, rRegI tmp2, rRegI tmp3, rFlagsReg cr) 11350 %{ 11351 predicate(UseAVX >= 2); 11352 match(Set result (VectorizedHashCode (Binary ary1 cnt1) (Binary result basic_type))); 11353 effect(TEMP tmp_vec1, TEMP tmp_vec2, TEMP tmp_vec3, TEMP tmp_vec4, TEMP tmp_vec5, TEMP tmp_vec6, 11354 TEMP tmp_vec7, TEMP tmp_vec8, TEMP tmp_vec9, TEMP tmp_vec10, TEMP tmp_vec11, TEMP tmp_vec12, 11355 TEMP tmp_vec13, TEMP tmp1, TEMP tmp2, TEMP tmp3, USE_KILL ary1, USE_KILL cnt1, 11356 USE basic_type, KILL cr); 11357 11358 format %{ "Array HashCode array[] $ary1,$cnt1,$result,$basic_type -> $result // KILL all" %} 11359 ins_encode %{ 11360 __ arrays_hashcode($ary1$$Register, $cnt1$$Register, $result$$Register, 11361 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 11362 $tmp_vec1$$XMMRegister, $tmp_vec2$$XMMRegister, $tmp_vec3$$XMMRegister, 11363 $tmp_vec4$$XMMRegister, $tmp_vec5$$XMMRegister, $tmp_vec6$$XMMRegister, 11364 $tmp_vec7$$XMMRegister, $tmp_vec8$$XMMRegister, $tmp_vec9$$XMMRegister, 11365 $tmp_vec10$$XMMRegister, $tmp_vec11$$XMMRegister, $tmp_vec12$$XMMRegister, 11366 $tmp_vec13$$XMMRegister, (BasicType)$basic_type$$constant); 11367 %} 11368 ins_pipe( pipe_slow ); 11369 %} 11370 11371 instruct count_positives(rsi_RegP ary1, rcx_RegI len, rax_RegI result, 11372 legRegD tmp1, legRegD tmp2, rbx_RegI tmp3, rFlagsReg cr,) 11373 %{ 11374 predicate(!VM_Version::supports_avx512vlbw() || !VM_Version::supports_bmi2()); 11375 match(Set result (CountPositives ary1 len)); 11376 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr); 11377 11378 format %{ "countPositives byte[] $ary1,$len -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11379 ins_encode %{ 11380 __ count_positives($ary1$$Register, $len$$Register, 11381 $result$$Register, $tmp3$$Register, 11382 $tmp1$$XMMRegister, $tmp2$$XMMRegister, knoreg, knoreg); 11383 %} 11384 ins_pipe( pipe_slow ); 11385 %} 11386 11387 instruct count_positives_evex(rsi_RegP ary1, rcx_RegI len, rax_RegI result, 11388 legRegD tmp1, legRegD tmp2, kReg ktmp1, kReg ktmp2, rbx_RegI tmp3, rFlagsReg cr,) 11389 %{ 11390 predicate(VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2()); 11391 match(Set result (CountPositives ary1 len)); 11392 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp1, TEMP ktmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr); 11393 11394 format %{ "countPositives byte[] $ary1,$len -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11395 ins_encode %{ 11396 __ count_positives($ary1$$Register, $len$$Register, 11397 $result$$Register, $tmp3$$Register, 11398 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $ktmp1$$KRegister, $ktmp2$$KRegister); 11399 %} 11400 ins_pipe( pipe_slow ); 11401 %} 11402 11403 // fast char[] to byte[] compression 11404 instruct string_compress(rsi_RegP src, rdi_RegP dst, rdx_RegI len, legRegD tmp1, legRegD tmp2, legRegD tmp3, 11405 legRegD tmp4, rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11406 predicate(!VM_Version::supports_avx512vlbw() || !VM_Version::supports_bmi2()); 11407 match(Set result (StrCompressedCopy src (Binary dst len))); 11408 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, 11409 USE_KILL len, KILL tmp5, KILL cr); 11410 11411 format %{ "String Compress $src,$dst -> $result // KILL RAX, RCX, RDX" %} 11412 ins_encode %{ 11413 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 11414 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11415 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, 11416 knoreg, knoreg); 11417 %} 11418 ins_pipe( pipe_slow ); 11419 %} 11420 11421 instruct string_compress_evex(rsi_RegP src, rdi_RegP dst, rdx_RegI len, legRegD tmp1, legRegD tmp2, legRegD tmp3, 11422 legRegD tmp4, kReg ktmp1, kReg ktmp2, rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11423 predicate(VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2()); 11424 match(Set result (StrCompressedCopy src (Binary dst len))); 11425 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP ktmp1, TEMP ktmp2, USE_KILL src, USE_KILL dst, 11426 USE_KILL len, KILL tmp5, KILL cr); 11427 11428 format %{ "String Compress $src,$dst -> $result // KILL RAX, RCX, RDX" %} 11429 ins_encode %{ 11430 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 11431 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11432 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, 11433 $ktmp1$$KRegister, $ktmp2$$KRegister); 11434 %} 11435 ins_pipe( pipe_slow ); 11436 %} 11437 // fast byte[] to char[] inflation 11438 instruct string_inflate(Universe dummy, rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11439 legRegD tmp1, rcx_RegI tmp2, rFlagsReg cr) %{ 11440 predicate(!VM_Version::supports_avx512vlbw() || !VM_Version::supports_bmi2()); 11441 match(Set dummy (StrInflatedCopy src (Binary dst len))); 11442 effect(TEMP tmp1, TEMP tmp2, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 11443 11444 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 11445 ins_encode %{ 11446 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 11447 $tmp1$$XMMRegister, $tmp2$$Register, knoreg); 11448 %} 11449 ins_pipe( pipe_slow ); 11450 %} 11451 11452 instruct string_inflate_evex(Universe dummy, rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11453 legRegD tmp1, kReg ktmp, rcx_RegI tmp2, rFlagsReg cr) %{ 11454 predicate(VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2()); 11455 match(Set dummy (StrInflatedCopy src (Binary dst len))); 11456 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 11457 11458 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 11459 ins_encode %{ 11460 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 11461 $tmp1$$XMMRegister, $tmp2$$Register, $ktmp$$KRegister); 11462 %} 11463 ins_pipe( pipe_slow ); 11464 %} 11465 11466 // encode char[] to byte[] in ISO_8859_1 11467 instruct encode_iso_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11468 legRegD tmp1, legRegD tmp2, legRegD tmp3, legRegD tmp4, 11469 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11470 predicate(!((EncodeISOArrayNode*)n)->is_ascii()); 11471 match(Set result (EncodeISOArray src (Binary dst len))); 11472 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 11473 11474 format %{ "Encode iso array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %} 11475 ins_encode %{ 11476 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 11477 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11478 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, false); 11479 %} 11480 ins_pipe( pipe_slow ); 11481 %} 11482 11483 // encode char[] to byte[] in ASCII 11484 instruct encode_ascii_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11485 legRegD tmp1, legRegD tmp2, legRegD tmp3, legRegD tmp4, 11486 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11487 predicate(((EncodeISOArrayNode*)n)->is_ascii()); 11488 match(Set result (EncodeISOArray src (Binary dst len))); 11489 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 11490 11491 format %{ "Encode ascii array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %} 11492 ins_encode %{ 11493 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 11494 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11495 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, true); 11496 %} 11497 ins_pipe( pipe_slow ); 11498 %} 11499 11500 //----------Overflow Math Instructions----------------------------------------- 11501 11502 instruct overflowAddI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 11503 %{ 11504 match(Set cr (OverflowAddI op1 op2)); 11505 effect(DEF cr, USE_KILL op1, USE op2); 11506 11507 format %{ "addl $op1, $op2\t# overflow check int" %} 11508 11509 ins_encode %{ 11510 __ addl($op1$$Register, $op2$$Register); 11511 %} 11512 ins_pipe(ialu_reg_reg); 11513 %} 11514 11515 instruct overflowAddI_rReg_imm(rFlagsReg cr, rax_RegI op1, immI op2) 11516 %{ 11517 match(Set cr (OverflowAddI op1 op2)); 11518 effect(DEF cr, USE_KILL op1, USE op2); 11519 11520 format %{ "addl $op1, $op2\t# overflow check int" %} 11521 11522 ins_encode %{ 11523 __ addl($op1$$Register, $op2$$constant); 11524 %} 11525 ins_pipe(ialu_reg_reg); 11526 %} 11527 11528 instruct overflowAddL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 11529 %{ 11530 match(Set cr (OverflowAddL op1 op2)); 11531 effect(DEF cr, USE_KILL op1, USE op2); 11532 11533 format %{ "addq $op1, $op2\t# overflow check long" %} 11534 ins_encode %{ 11535 __ addq($op1$$Register, $op2$$Register); 11536 %} 11537 ins_pipe(ialu_reg_reg); 11538 %} 11539 11540 instruct overflowAddL_rReg_imm(rFlagsReg cr, rax_RegL op1, immL32 op2) 11541 %{ 11542 match(Set cr (OverflowAddL op1 op2)); 11543 effect(DEF cr, USE_KILL op1, USE op2); 11544 11545 format %{ "addq $op1, $op2\t# overflow check long" %} 11546 ins_encode %{ 11547 __ addq($op1$$Register, $op2$$constant); 11548 %} 11549 ins_pipe(ialu_reg_reg); 11550 %} 11551 11552 instruct overflowSubI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 11553 %{ 11554 match(Set cr (OverflowSubI op1 op2)); 11555 11556 format %{ "cmpl $op1, $op2\t# overflow check int" %} 11557 ins_encode %{ 11558 __ cmpl($op1$$Register, $op2$$Register); 11559 %} 11560 ins_pipe(ialu_reg_reg); 11561 %} 11562 11563 instruct overflowSubI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 11564 %{ 11565 match(Set cr (OverflowSubI op1 op2)); 11566 11567 format %{ "cmpl $op1, $op2\t# overflow check int" %} 11568 ins_encode %{ 11569 __ cmpl($op1$$Register, $op2$$constant); 11570 %} 11571 ins_pipe(ialu_reg_reg); 11572 %} 11573 11574 instruct overflowSubL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 11575 %{ 11576 match(Set cr (OverflowSubL op1 op2)); 11577 11578 format %{ "cmpq $op1, $op2\t# overflow check long" %} 11579 ins_encode %{ 11580 __ cmpq($op1$$Register, $op2$$Register); 11581 %} 11582 ins_pipe(ialu_reg_reg); 11583 %} 11584 11585 instruct overflowSubL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 11586 %{ 11587 match(Set cr (OverflowSubL op1 op2)); 11588 11589 format %{ "cmpq $op1, $op2\t# overflow check long" %} 11590 ins_encode %{ 11591 __ cmpq($op1$$Register, $op2$$constant); 11592 %} 11593 ins_pipe(ialu_reg_reg); 11594 %} 11595 11596 instruct overflowNegI_rReg(rFlagsReg cr, immI_0 zero, rax_RegI op2) 11597 %{ 11598 match(Set cr (OverflowSubI zero op2)); 11599 effect(DEF cr, USE_KILL op2); 11600 11601 format %{ "negl $op2\t# overflow check int" %} 11602 ins_encode %{ 11603 __ negl($op2$$Register); 11604 %} 11605 ins_pipe(ialu_reg_reg); 11606 %} 11607 11608 instruct overflowNegL_rReg(rFlagsReg cr, immL0 zero, rax_RegL op2) 11609 %{ 11610 match(Set cr (OverflowSubL zero op2)); 11611 effect(DEF cr, USE_KILL op2); 11612 11613 format %{ "negq $op2\t# overflow check long" %} 11614 ins_encode %{ 11615 __ negq($op2$$Register); 11616 %} 11617 ins_pipe(ialu_reg_reg); 11618 %} 11619 11620 instruct overflowMulI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 11621 %{ 11622 match(Set cr (OverflowMulI op1 op2)); 11623 effect(DEF cr, USE_KILL op1, USE op2); 11624 11625 format %{ "imull $op1, $op2\t# overflow check int" %} 11626 ins_encode %{ 11627 __ imull($op1$$Register, $op2$$Register); 11628 %} 11629 ins_pipe(ialu_reg_reg_alu0); 11630 %} 11631 11632 instruct overflowMulI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2, rRegI tmp) 11633 %{ 11634 match(Set cr (OverflowMulI op1 op2)); 11635 effect(DEF cr, TEMP tmp, USE op1, USE op2); 11636 11637 format %{ "imull $tmp, $op1, $op2\t# overflow check int" %} 11638 ins_encode %{ 11639 __ imull($tmp$$Register, $op1$$Register, $op2$$constant); 11640 %} 11641 ins_pipe(ialu_reg_reg_alu0); 11642 %} 11643 11644 instruct overflowMulL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 11645 %{ 11646 match(Set cr (OverflowMulL op1 op2)); 11647 effect(DEF cr, USE_KILL op1, USE op2); 11648 11649 format %{ "imulq $op1, $op2\t# overflow check long" %} 11650 ins_encode %{ 11651 __ imulq($op1$$Register, $op2$$Register); 11652 %} 11653 ins_pipe(ialu_reg_reg_alu0); 11654 %} 11655 11656 instruct overflowMulL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2, rRegL tmp) 11657 %{ 11658 match(Set cr (OverflowMulL op1 op2)); 11659 effect(DEF cr, TEMP tmp, USE op1, USE op2); 11660 11661 format %{ "imulq $tmp, $op1, $op2\t# overflow check long" %} 11662 ins_encode %{ 11663 __ imulq($tmp$$Register, $op1$$Register, $op2$$constant); 11664 %} 11665 ins_pipe(ialu_reg_reg_alu0); 11666 %} 11667 11668 11669 //----------Control Flow Instructions------------------------------------------ 11670 // Signed compare Instructions 11671 11672 // XXX more variants!! 11673 instruct compI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 11674 %{ 11675 match(Set cr (CmpI op1 op2)); 11676 effect(DEF cr, USE op1, USE op2); 11677 11678 format %{ "cmpl $op1, $op2" %} 11679 ins_encode %{ 11680 __ cmpl($op1$$Register, $op2$$Register); 11681 %} 11682 ins_pipe(ialu_cr_reg_reg); 11683 %} 11684 11685 instruct compI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 11686 %{ 11687 match(Set cr (CmpI op1 op2)); 11688 11689 format %{ "cmpl $op1, $op2" %} 11690 ins_encode %{ 11691 __ cmpl($op1$$Register, $op2$$constant); 11692 %} 11693 ins_pipe(ialu_cr_reg_imm); 11694 %} 11695 11696 instruct compI_rReg_mem(rFlagsReg cr, rRegI op1, memory op2) 11697 %{ 11698 match(Set cr (CmpI op1 (LoadI op2))); 11699 11700 ins_cost(500); // XXX 11701 format %{ "cmpl $op1, $op2" %} 11702 ins_encode %{ 11703 __ cmpl($op1$$Register, $op2$$Address); 11704 %} 11705 ins_pipe(ialu_cr_reg_mem); 11706 %} 11707 11708 instruct testI_reg(rFlagsReg cr, rRegI src, immI_0 zero) 11709 %{ 11710 match(Set cr (CmpI src zero)); 11711 11712 format %{ "testl $src, $src" %} 11713 ins_encode %{ 11714 __ testl($src$$Register, $src$$Register); 11715 %} 11716 ins_pipe(ialu_cr_reg_imm); 11717 %} 11718 11719 instruct testI_reg_imm(rFlagsReg cr, rRegI src, immI con, immI_0 zero) 11720 %{ 11721 match(Set cr (CmpI (AndI src con) zero)); 11722 11723 format %{ "testl $src, $con" %} 11724 ins_encode %{ 11725 __ testl($src$$Register, $con$$constant); 11726 %} 11727 ins_pipe(ialu_cr_reg_imm); 11728 %} 11729 11730 instruct testI_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2, immI_0 zero) 11731 %{ 11732 match(Set cr (CmpI (AndI src1 src2) zero)); 11733 11734 format %{ "testl $src1, $src2" %} 11735 ins_encode %{ 11736 __ testl($src1$$Register, $src2$$Register); 11737 %} 11738 ins_pipe(ialu_cr_reg_imm); 11739 %} 11740 11741 instruct testI_reg_mem(rFlagsReg cr, rRegI src, memory mem, immI_0 zero) 11742 %{ 11743 match(Set cr (CmpI (AndI src (LoadI mem)) zero)); 11744 11745 format %{ "testl $src, $mem" %} 11746 ins_encode %{ 11747 __ testl($src$$Register, $mem$$Address); 11748 %} 11749 ins_pipe(ialu_cr_reg_mem); 11750 %} 11751 11752 // Unsigned compare Instructions; really, same as signed except they 11753 // produce an rFlagsRegU instead of rFlagsReg. 11754 instruct compU_rReg(rFlagsRegU cr, rRegI op1, rRegI op2) 11755 %{ 11756 match(Set cr (CmpU op1 op2)); 11757 11758 format %{ "cmpl $op1, $op2\t# unsigned" %} 11759 ins_encode %{ 11760 __ cmpl($op1$$Register, $op2$$Register); 11761 %} 11762 ins_pipe(ialu_cr_reg_reg); 11763 %} 11764 11765 instruct compU_rReg_imm(rFlagsRegU cr, rRegI op1, immI op2) 11766 %{ 11767 match(Set cr (CmpU op1 op2)); 11768 11769 format %{ "cmpl $op1, $op2\t# unsigned" %} 11770 ins_encode %{ 11771 __ cmpl($op1$$Register, $op2$$constant); 11772 %} 11773 ins_pipe(ialu_cr_reg_imm); 11774 %} 11775 11776 instruct compU_rReg_mem(rFlagsRegU cr, rRegI op1, memory op2) 11777 %{ 11778 match(Set cr (CmpU op1 (LoadI op2))); 11779 11780 ins_cost(500); // XXX 11781 format %{ "cmpl $op1, $op2\t# unsigned" %} 11782 ins_encode %{ 11783 __ cmpl($op1$$Register, $op2$$Address); 11784 %} 11785 ins_pipe(ialu_cr_reg_mem); 11786 %} 11787 11788 instruct testU_reg(rFlagsRegU cr, rRegI src, immI_0 zero) 11789 %{ 11790 match(Set cr (CmpU src zero)); 11791 11792 format %{ "testl $src, $src\t# unsigned" %} 11793 ins_encode %{ 11794 __ testl($src$$Register, $src$$Register); 11795 %} 11796 ins_pipe(ialu_cr_reg_imm); 11797 %} 11798 11799 instruct compP_rReg(rFlagsRegU cr, rRegP op1, rRegP op2) 11800 %{ 11801 match(Set cr (CmpP op1 op2)); 11802 11803 format %{ "cmpq $op1, $op2\t# ptr" %} 11804 ins_encode %{ 11805 __ cmpq($op1$$Register, $op2$$Register); 11806 %} 11807 ins_pipe(ialu_cr_reg_reg); 11808 %} 11809 11810 instruct compP_rReg_mem(rFlagsRegU cr, rRegP op1, memory op2) 11811 %{ 11812 match(Set cr (CmpP op1 (LoadP op2))); 11813 predicate(n->in(2)->as_Load()->barrier_data() == 0); 11814 11815 ins_cost(500); // XXX 11816 format %{ "cmpq $op1, $op2\t# ptr" %} 11817 ins_encode %{ 11818 __ cmpq($op1$$Register, $op2$$Address); 11819 %} 11820 ins_pipe(ialu_cr_reg_mem); 11821 %} 11822 11823 // XXX this is generalized by compP_rReg_mem??? 11824 // Compare raw pointer (used in out-of-heap check). 11825 // Only works because non-oop pointers must be raw pointers 11826 // and raw pointers have no anti-dependencies. 11827 instruct compP_mem_rReg(rFlagsRegU cr, rRegP op1, memory op2) 11828 %{ 11829 predicate(n->in(2)->in(2)->bottom_type()->reloc() == relocInfo::none && 11830 n->in(2)->as_Load()->barrier_data() == 0); 11831 match(Set cr (CmpP op1 (LoadP op2))); 11832 11833 format %{ "cmpq $op1, $op2\t# raw ptr" %} 11834 ins_encode %{ 11835 __ cmpq($op1$$Register, $op2$$Address); 11836 %} 11837 ins_pipe(ialu_cr_reg_mem); 11838 %} 11839 11840 // This will generate a signed flags result. This should be OK since 11841 // any compare to a zero should be eq/neq. 11842 instruct testP_reg(rFlagsReg cr, rRegP src, immP0 zero) 11843 %{ 11844 match(Set cr (CmpP src zero)); 11845 11846 format %{ "testq $src, $src\t# ptr" %} 11847 ins_encode %{ 11848 __ testq($src$$Register, $src$$Register); 11849 %} 11850 ins_pipe(ialu_cr_reg_imm); 11851 %} 11852 11853 // This will generate a signed flags result. This should be OK since 11854 // any compare to a zero should be eq/neq. 11855 instruct testP_mem(rFlagsReg cr, memory op, immP0 zero) 11856 %{ 11857 predicate((!UseCompressedOops || (CompressedOops::base() != nullptr)) && 11858 n->in(1)->as_Load()->barrier_data() == 0); 11859 match(Set cr (CmpP (LoadP op) zero)); 11860 11861 ins_cost(500); // XXX 11862 format %{ "testq $op, 0xffffffffffffffff\t# ptr" %} 11863 ins_encode %{ 11864 __ testq($op$$Address, 0xFFFFFFFF); 11865 %} 11866 ins_pipe(ialu_cr_reg_imm); 11867 %} 11868 11869 instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero) 11870 %{ 11871 predicate(UseCompressedOops && (CompressedOops::base() == nullptr) && 11872 n->in(1)->as_Load()->barrier_data() == 0); 11873 match(Set cr (CmpP (LoadP mem) zero)); 11874 11875 format %{ "cmpq R12, $mem\t# ptr (R12_heapbase==0)" %} 11876 ins_encode %{ 11877 __ cmpq(r12, $mem$$Address); 11878 %} 11879 ins_pipe(ialu_cr_reg_mem); 11880 %} 11881 11882 instruct compN_rReg(rFlagsRegU cr, rRegN op1, rRegN op2) 11883 %{ 11884 match(Set cr (CmpN op1 op2)); 11885 11886 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 11887 ins_encode %{ __ cmpl($op1$$Register, $op2$$Register); %} 11888 ins_pipe(ialu_cr_reg_reg); 11889 %} 11890 11891 instruct compN_rReg_mem(rFlagsRegU cr, rRegN src, memory mem) 11892 %{ 11893 predicate(n->in(2)->as_Load()->barrier_data() == 0); 11894 match(Set cr (CmpN src (LoadN mem))); 11895 11896 format %{ "cmpl $src, $mem\t# compressed ptr" %} 11897 ins_encode %{ 11898 __ cmpl($src$$Register, $mem$$Address); 11899 %} 11900 ins_pipe(ialu_cr_reg_mem); 11901 %} 11902 11903 instruct compN_rReg_imm(rFlagsRegU cr, rRegN op1, immN op2) %{ 11904 match(Set cr (CmpN op1 op2)); 11905 11906 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 11907 ins_encode %{ 11908 __ cmp_narrow_oop($op1$$Register, (jobject)$op2$$constant); 11909 %} 11910 ins_pipe(ialu_cr_reg_imm); 11911 %} 11912 11913 instruct compN_mem_imm(rFlagsRegU cr, memory mem, immN src) 11914 %{ 11915 predicate(n->in(2)->as_Load()->barrier_data() == 0); 11916 match(Set cr (CmpN src (LoadN mem))); 11917 11918 format %{ "cmpl $mem, $src\t# compressed ptr" %} 11919 ins_encode %{ 11920 __ cmp_narrow_oop($mem$$Address, (jobject)$src$$constant); 11921 %} 11922 ins_pipe(ialu_cr_reg_mem); 11923 %} 11924 11925 instruct compN_rReg_imm_klass(rFlagsRegU cr, rRegN op1, immNKlass op2) %{ 11926 match(Set cr (CmpN op1 op2)); 11927 11928 format %{ "cmpl $op1, $op2\t# compressed klass ptr" %} 11929 ins_encode %{ 11930 __ cmp_narrow_klass($op1$$Register, (Klass*)$op2$$constant); 11931 %} 11932 ins_pipe(ialu_cr_reg_imm); 11933 %} 11934 11935 instruct compN_mem_imm_klass(rFlagsRegU cr, memory mem, immNKlass src) 11936 %{ 11937 match(Set cr (CmpN src (LoadNKlass mem))); 11938 11939 format %{ "cmpl $mem, $src\t# compressed klass ptr" %} 11940 ins_encode %{ 11941 __ cmp_narrow_klass($mem$$Address, (Klass*)$src$$constant); 11942 %} 11943 ins_pipe(ialu_cr_reg_mem); 11944 %} 11945 11946 instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{ 11947 match(Set cr (CmpN src zero)); 11948 11949 format %{ "testl $src, $src\t# compressed ptr" %} 11950 ins_encode %{ __ testl($src$$Register, $src$$Register); %} 11951 ins_pipe(ialu_cr_reg_imm); 11952 %} 11953 11954 instruct testN_mem(rFlagsReg cr, memory mem, immN0 zero) 11955 %{ 11956 predicate(CompressedOops::base() != nullptr && 11957 n->in(1)->as_Load()->barrier_data() == 0); 11958 match(Set cr (CmpN (LoadN mem) zero)); 11959 11960 ins_cost(500); // XXX 11961 format %{ "testl $mem, 0xffffffff\t# compressed ptr" %} 11962 ins_encode %{ 11963 __ cmpl($mem$$Address, (int)0xFFFFFFFF); 11964 %} 11965 ins_pipe(ialu_cr_reg_mem); 11966 %} 11967 11968 instruct testN_mem_reg0(rFlagsReg cr, memory mem, immN0 zero) 11969 %{ 11970 predicate(CompressedOops::base() == nullptr && 11971 n->in(1)->as_Load()->barrier_data() == 0); 11972 match(Set cr (CmpN (LoadN mem) zero)); 11973 11974 format %{ "cmpl R12, $mem\t# compressed ptr (R12_heapbase==0)" %} 11975 ins_encode %{ 11976 __ cmpl(r12, $mem$$Address); 11977 %} 11978 ins_pipe(ialu_cr_reg_mem); 11979 %} 11980 11981 // Yanked all unsigned pointer compare operations. 11982 // Pointer compares are done with CmpP which is already unsigned. 11983 11984 instruct compL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 11985 %{ 11986 match(Set cr (CmpL op1 op2)); 11987 11988 format %{ "cmpq $op1, $op2" %} 11989 ins_encode %{ 11990 __ cmpq($op1$$Register, $op2$$Register); 11991 %} 11992 ins_pipe(ialu_cr_reg_reg); 11993 %} 11994 11995 instruct compL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 11996 %{ 11997 match(Set cr (CmpL op1 op2)); 11998 11999 format %{ "cmpq $op1, $op2" %} 12000 ins_encode %{ 12001 __ cmpq($op1$$Register, $op2$$constant); 12002 %} 12003 ins_pipe(ialu_cr_reg_imm); 12004 %} 12005 12006 instruct compL_rReg_mem(rFlagsReg cr, rRegL op1, memory op2) 12007 %{ 12008 match(Set cr (CmpL op1 (LoadL op2))); 12009 12010 format %{ "cmpq $op1, $op2" %} 12011 ins_encode %{ 12012 __ cmpq($op1$$Register, $op2$$Address); 12013 %} 12014 ins_pipe(ialu_cr_reg_mem); 12015 %} 12016 12017 instruct testL_reg(rFlagsReg cr, rRegL src, immL0 zero) 12018 %{ 12019 match(Set cr (CmpL src zero)); 12020 12021 format %{ "testq $src, $src" %} 12022 ins_encode %{ 12023 __ testq($src$$Register, $src$$Register); 12024 %} 12025 ins_pipe(ialu_cr_reg_imm); 12026 %} 12027 12028 instruct testL_reg_imm(rFlagsReg cr, rRegL src, immL32 con, immL0 zero) 12029 %{ 12030 match(Set cr (CmpL (AndL src con) zero)); 12031 12032 format %{ "testq $src, $con\t# long" %} 12033 ins_encode %{ 12034 __ testq($src$$Register, $con$$constant); 12035 %} 12036 ins_pipe(ialu_cr_reg_imm); 12037 %} 12038 12039 instruct testL_reg_reg(rFlagsReg cr, rRegL src1, rRegL src2, immL0 zero) 12040 %{ 12041 match(Set cr (CmpL (AndL src1 src2) zero)); 12042 12043 format %{ "testq $src1, $src2\t# long" %} 12044 ins_encode %{ 12045 __ testq($src1$$Register, $src2$$Register); 12046 %} 12047 ins_pipe(ialu_cr_reg_imm); 12048 %} 12049 12050 instruct testL_reg_mem(rFlagsReg cr, rRegL src, memory mem, immL0 zero) 12051 %{ 12052 match(Set cr (CmpL (AndL src (LoadL mem)) zero)); 12053 12054 format %{ "testq $src, $mem" %} 12055 ins_encode %{ 12056 __ testq($src$$Register, $mem$$Address); 12057 %} 12058 ins_pipe(ialu_cr_reg_mem); 12059 %} 12060 12061 instruct testL_reg_mem2(rFlagsReg cr, rRegP src, memory mem, immL0 zero) 12062 %{ 12063 match(Set cr (CmpL (AndL (CastP2X src) (LoadL mem)) zero)); 12064 12065 format %{ "testq $src, $mem" %} 12066 ins_encode %{ 12067 __ testq($src$$Register, $mem$$Address); 12068 %} 12069 ins_pipe(ialu_cr_reg_mem); 12070 %} 12071 12072 // Manifest a CmpU result in an integer register. Very painful. 12073 // This is the test to avoid. 12074 instruct cmpU3_reg_reg(rRegI dst, rRegI src1, rRegI src2, rFlagsReg flags) 12075 %{ 12076 match(Set dst (CmpU3 src1 src2)); 12077 effect(KILL flags); 12078 12079 ins_cost(275); // XXX 12080 format %{ "cmpl $src1, $src2\t# CmpL3\n\t" 12081 "movl $dst, -1\n\t" 12082 "jb,u done\n\t" 12083 "setcc $dst \t# emits setne + movzbl or setzune for APX" 12084 "done:" %} 12085 ins_encode %{ 12086 Label done; 12087 __ cmpl($src1$$Register, $src2$$Register); 12088 __ movl($dst$$Register, -1); 12089 __ jccb(Assembler::below, done); 12090 __ setcc(Assembler::notZero, $dst$$Register); 12091 __ bind(done); 12092 %} 12093 ins_pipe(pipe_slow); 12094 %} 12095 12096 // Manifest a CmpL result in an integer register. Very painful. 12097 // This is the test to avoid. 12098 instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 12099 %{ 12100 match(Set dst (CmpL3 src1 src2)); 12101 effect(KILL flags); 12102 12103 ins_cost(275); // XXX 12104 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 12105 "movl $dst, -1\n\t" 12106 "jl,s done\n\t" 12107 "setcc $dst \t# emits setne + movzbl or setzune for APX" 12108 "done:" %} 12109 ins_encode %{ 12110 Label done; 12111 __ cmpq($src1$$Register, $src2$$Register); 12112 __ movl($dst$$Register, -1); 12113 __ jccb(Assembler::less, done); 12114 __ setcc(Assembler::notZero, $dst$$Register); 12115 __ bind(done); 12116 %} 12117 ins_pipe(pipe_slow); 12118 %} 12119 12120 // Manifest a CmpUL result in an integer register. Very painful. 12121 // This is the test to avoid. 12122 instruct cmpUL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 12123 %{ 12124 match(Set dst (CmpUL3 src1 src2)); 12125 effect(KILL flags); 12126 12127 ins_cost(275); // XXX 12128 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 12129 "movl $dst, -1\n\t" 12130 "jb,u done\n\t" 12131 "setcc $dst \t# emits setne + movzbl or setzune for APX" 12132 "done:" %} 12133 ins_encode %{ 12134 Label done; 12135 __ cmpq($src1$$Register, $src2$$Register); 12136 __ movl($dst$$Register, -1); 12137 __ jccb(Assembler::below, done); 12138 __ setcc(Assembler::notZero, $dst$$Register); 12139 __ bind(done); 12140 %} 12141 ins_pipe(pipe_slow); 12142 %} 12143 12144 // Unsigned long compare Instructions; really, same as signed long except they 12145 // produce an rFlagsRegU instead of rFlagsReg. 12146 instruct compUL_rReg(rFlagsRegU cr, rRegL op1, rRegL op2) 12147 %{ 12148 match(Set cr (CmpUL op1 op2)); 12149 12150 format %{ "cmpq $op1, $op2\t# unsigned" %} 12151 ins_encode %{ 12152 __ cmpq($op1$$Register, $op2$$Register); 12153 %} 12154 ins_pipe(ialu_cr_reg_reg); 12155 %} 12156 12157 instruct compUL_rReg_imm(rFlagsRegU cr, rRegL op1, immL32 op2) 12158 %{ 12159 match(Set cr (CmpUL op1 op2)); 12160 12161 format %{ "cmpq $op1, $op2\t# unsigned" %} 12162 ins_encode %{ 12163 __ cmpq($op1$$Register, $op2$$constant); 12164 %} 12165 ins_pipe(ialu_cr_reg_imm); 12166 %} 12167 12168 instruct compUL_rReg_mem(rFlagsRegU cr, rRegL op1, memory op2) 12169 %{ 12170 match(Set cr (CmpUL op1 (LoadL op2))); 12171 12172 format %{ "cmpq $op1, $op2\t# unsigned" %} 12173 ins_encode %{ 12174 __ cmpq($op1$$Register, $op2$$Address); 12175 %} 12176 ins_pipe(ialu_cr_reg_mem); 12177 %} 12178 12179 instruct testUL_reg(rFlagsRegU cr, rRegL src, immL0 zero) 12180 %{ 12181 match(Set cr (CmpUL src zero)); 12182 12183 format %{ "testq $src, $src\t# unsigned" %} 12184 ins_encode %{ 12185 __ testq($src$$Register, $src$$Register); 12186 %} 12187 ins_pipe(ialu_cr_reg_imm); 12188 %} 12189 12190 instruct compB_mem_imm(rFlagsReg cr, memory mem, immI8 imm) 12191 %{ 12192 match(Set cr (CmpI (LoadB mem) imm)); 12193 12194 ins_cost(125); 12195 format %{ "cmpb $mem, $imm" %} 12196 ins_encode %{ __ cmpb($mem$$Address, $imm$$constant); %} 12197 ins_pipe(ialu_cr_reg_mem); 12198 %} 12199 12200 instruct testUB_mem_imm(rFlagsReg cr, memory mem, immU7 imm, immI_0 zero) 12201 %{ 12202 match(Set cr (CmpI (AndI (LoadUB mem) imm) zero)); 12203 12204 ins_cost(125); 12205 format %{ "testb $mem, $imm\t# ubyte" %} 12206 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %} 12207 ins_pipe(ialu_cr_reg_mem); 12208 %} 12209 12210 instruct testB_mem_imm(rFlagsReg cr, memory mem, immI8 imm, immI_0 zero) 12211 %{ 12212 match(Set cr (CmpI (AndI (LoadB mem) imm) zero)); 12213 12214 ins_cost(125); 12215 format %{ "testb $mem, $imm\t# byte" %} 12216 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %} 12217 ins_pipe(ialu_cr_reg_mem); 12218 %} 12219 12220 //----------Max and Min-------------------------------------------------------- 12221 // Min Instructions 12222 12223 instruct cmovI_reg_g(rRegI dst, rRegI src, rFlagsReg cr) 12224 %{ 12225 effect(USE_DEF dst, USE src, USE cr); 12226 12227 format %{ "cmovlgt $dst, $src\t# min" %} 12228 ins_encode %{ 12229 __ cmovl(Assembler::greater, $dst$$Register, $src$$Register); 12230 %} 12231 ins_pipe(pipe_cmov_reg); 12232 %} 12233 12234 12235 instruct minI_rReg(rRegI dst, rRegI src) 12236 %{ 12237 match(Set dst (MinI dst src)); 12238 12239 ins_cost(200); 12240 expand %{ 12241 rFlagsReg cr; 12242 compI_rReg(cr, dst, src); 12243 cmovI_reg_g(dst, src, cr); 12244 %} 12245 %} 12246 12247 instruct cmovI_reg_l(rRegI dst, rRegI src, rFlagsReg cr) 12248 %{ 12249 effect(USE_DEF dst, USE src, USE cr); 12250 12251 format %{ "cmovllt $dst, $src\t# max" %} 12252 ins_encode %{ 12253 __ cmovl(Assembler::less, $dst$$Register, $src$$Register); 12254 %} 12255 ins_pipe(pipe_cmov_reg); 12256 %} 12257 12258 12259 instruct maxI_rReg(rRegI dst, rRegI src) 12260 %{ 12261 match(Set dst (MaxI dst src)); 12262 12263 ins_cost(200); 12264 expand %{ 12265 rFlagsReg cr; 12266 compI_rReg(cr, dst, src); 12267 cmovI_reg_l(dst, src, cr); 12268 %} 12269 %} 12270 12271 // ============================================================================ 12272 // Branch Instructions 12273 12274 // Jump Direct - Label defines a relative address from JMP+1 12275 instruct jmpDir(label labl) 12276 %{ 12277 match(Goto); 12278 effect(USE labl); 12279 12280 ins_cost(300); 12281 format %{ "jmp $labl" %} 12282 size(5); 12283 ins_encode %{ 12284 Label* L = $labl$$label; 12285 __ jmp(*L, false); // Always long jump 12286 %} 12287 ins_pipe(pipe_jmp); 12288 %} 12289 12290 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12291 instruct jmpCon(cmpOp cop, rFlagsReg cr, label labl) 12292 %{ 12293 match(If cop cr); 12294 effect(USE labl); 12295 12296 ins_cost(300); 12297 format %{ "j$cop $labl" %} 12298 size(6); 12299 ins_encode %{ 12300 Label* L = $labl$$label; 12301 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12302 %} 12303 ins_pipe(pipe_jcc); 12304 %} 12305 12306 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12307 instruct jmpLoopEnd(cmpOp cop, rFlagsReg cr, label labl) 12308 %{ 12309 match(CountedLoopEnd cop cr); 12310 effect(USE labl); 12311 12312 ins_cost(300); 12313 format %{ "j$cop $labl\t# loop end" %} 12314 size(6); 12315 ins_encode %{ 12316 Label* L = $labl$$label; 12317 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12318 %} 12319 ins_pipe(pipe_jcc); 12320 %} 12321 12322 // Jump Direct Conditional - using unsigned comparison 12323 instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12324 match(If cop cmp); 12325 effect(USE labl); 12326 12327 ins_cost(300); 12328 format %{ "j$cop,u $labl" %} 12329 size(6); 12330 ins_encode %{ 12331 Label* L = $labl$$label; 12332 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12333 %} 12334 ins_pipe(pipe_jcc); 12335 %} 12336 12337 instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12338 match(If cop cmp); 12339 effect(USE labl); 12340 12341 ins_cost(200); 12342 format %{ "j$cop,u $labl" %} 12343 size(6); 12344 ins_encode %{ 12345 Label* L = $labl$$label; 12346 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12347 %} 12348 ins_pipe(pipe_jcc); 12349 %} 12350 12351 instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 12352 match(If cop cmp); 12353 effect(USE labl); 12354 12355 ins_cost(200); 12356 format %{ $$template 12357 if ($cop$$cmpcode == Assembler::notEqual) { 12358 $$emit$$"jp,u $labl\n\t" 12359 $$emit$$"j$cop,u $labl" 12360 } else { 12361 $$emit$$"jp,u done\n\t" 12362 $$emit$$"j$cop,u $labl\n\t" 12363 $$emit$$"done:" 12364 } 12365 %} 12366 ins_encode %{ 12367 Label* l = $labl$$label; 12368 if ($cop$$cmpcode == Assembler::notEqual) { 12369 __ jcc(Assembler::parity, *l, false); 12370 __ jcc(Assembler::notEqual, *l, false); 12371 } else if ($cop$$cmpcode == Assembler::equal) { 12372 Label done; 12373 __ jccb(Assembler::parity, done); 12374 __ jcc(Assembler::equal, *l, false); 12375 __ bind(done); 12376 } else { 12377 ShouldNotReachHere(); 12378 } 12379 %} 12380 ins_pipe(pipe_jcc); 12381 %} 12382 12383 // ============================================================================ 12384 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary 12385 // superklass array for an instance of the superklass. Set a hidden 12386 // internal cache on a hit (cache is checked with exposed code in 12387 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The 12388 // encoding ALSO sets flags. 12389 12390 instruct partialSubtypeCheck(rdi_RegP result, 12391 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 12392 rFlagsReg cr) 12393 %{ 12394 match(Set result (PartialSubtypeCheck sub super)); 12395 effect(KILL rcx, KILL cr); 12396 12397 ins_cost(1100); // slightly larger than the next version 12398 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 12399 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 12400 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 12401 "repne scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t" 12402 "jne,s miss\t\t# Missed: rdi not-zero\n\t" 12403 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 12404 "xorq $result, $result\t\t Hit: rdi zero\n\t" 12405 "miss:\t" %} 12406 12407 opcode(0x1); // Force a XOR of RDI 12408 ins_encode(enc_PartialSubtypeCheck()); 12409 ins_pipe(pipe_slow); 12410 %} 12411 12412 instruct partialSubtypeCheckConstSuper(rsi_RegP sub, rax_RegP super_reg, immP super_con, rdi_RegP result, 12413 rdx_RegL temp1, rcx_RegL temp2, rbx_RegP temp3, r11_RegL temp4, 12414 rFlagsReg cr) 12415 %{ 12416 match(Set result (PartialSubtypeCheck sub (Binary super_reg super_con))); 12417 predicate(UseSecondarySupersTable); 12418 effect(KILL cr, TEMP temp1, TEMP temp2, TEMP temp3, TEMP temp4); 12419 12420 ins_cost(700); // smaller than the next version 12421 format %{ "partialSubtypeCheck $result, $sub, $super_reg, $super_con" %} 12422 12423 ins_encode %{ 12424 u1 super_klass_slot = ((Klass*)$super_con$$constant)->hash_slot(); 12425 if (InlineSecondarySupersTest) { 12426 __ lookup_secondary_supers_table($sub$$Register, $super_reg$$Register, $temp1$$Register, $temp2$$Register, 12427 $temp3$$Register, $temp4$$Register, $result$$Register, 12428 super_klass_slot); 12429 } else { 12430 __ call(RuntimeAddress(StubRoutines::lookup_secondary_supers_table_stub(super_klass_slot))); 12431 } 12432 %} 12433 12434 ins_pipe(pipe_slow); 12435 %} 12436 12437 instruct partialSubtypeCheck_vs_Zero(rFlagsReg cr, 12438 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 12439 immP0 zero, 12440 rdi_RegP result) 12441 %{ 12442 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 12443 effect(KILL rcx, KILL result); 12444 12445 ins_cost(1000); 12446 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 12447 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 12448 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 12449 "repne scasq\t# Scan *rdi++ for a match with rax while cx-- != 0\n\t" 12450 "jne,s miss\t\t# Missed: flags nz\n\t" 12451 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 12452 "miss:\t" %} 12453 12454 opcode(0x0); // No need to XOR RDI 12455 ins_encode(enc_PartialSubtypeCheck()); 12456 ins_pipe(pipe_slow); 12457 %} 12458 12459 // ============================================================================ 12460 // Branch Instructions -- short offset versions 12461 // 12462 // These instructions are used to replace jumps of a long offset (the default 12463 // match) with jumps of a shorter offset. These instructions are all tagged 12464 // with the ins_short_branch attribute, which causes the ADLC to suppress the 12465 // match rules in general matching. Instead, the ADLC generates a conversion 12466 // method in the MachNode which can be used to do in-place replacement of the 12467 // long variant with the shorter variant. The compiler will determine if a 12468 // branch can be taken by the is_short_branch_offset() predicate in the machine 12469 // specific code section of the file. 12470 12471 // Jump Direct - Label defines a relative address from JMP+1 12472 instruct jmpDir_short(label labl) %{ 12473 match(Goto); 12474 effect(USE labl); 12475 12476 ins_cost(300); 12477 format %{ "jmp,s $labl" %} 12478 size(2); 12479 ins_encode %{ 12480 Label* L = $labl$$label; 12481 __ jmpb(*L); 12482 %} 12483 ins_pipe(pipe_jmp); 12484 ins_short_branch(1); 12485 %} 12486 12487 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12488 instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{ 12489 match(If cop cr); 12490 effect(USE labl); 12491 12492 ins_cost(300); 12493 format %{ "j$cop,s $labl" %} 12494 size(2); 12495 ins_encode %{ 12496 Label* L = $labl$$label; 12497 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12498 %} 12499 ins_pipe(pipe_jcc); 12500 ins_short_branch(1); 12501 %} 12502 12503 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12504 instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{ 12505 match(CountedLoopEnd cop cr); 12506 effect(USE labl); 12507 12508 ins_cost(300); 12509 format %{ "j$cop,s $labl\t# loop end" %} 12510 size(2); 12511 ins_encode %{ 12512 Label* L = $labl$$label; 12513 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12514 %} 12515 ins_pipe(pipe_jcc); 12516 ins_short_branch(1); 12517 %} 12518 12519 // Jump Direct Conditional - using unsigned comparison 12520 instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12521 match(If cop cmp); 12522 effect(USE labl); 12523 12524 ins_cost(300); 12525 format %{ "j$cop,us $labl" %} 12526 size(2); 12527 ins_encode %{ 12528 Label* L = $labl$$label; 12529 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12530 %} 12531 ins_pipe(pipe_jcc); 12532 ins_short_branch(1); 12533 %} 12534 12535 instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12536 match(If cop cmp); 12537 effect(USE labl); 12538 12539 ins_cost(300); 12540 format %{ "j$cop,us $labl" %} 12541 size(2); 12542 ins_encode %{ 12543 Label* L = $labl$$label; 12544 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12545 %} 12546 ins_pipe(pipe_jcc); 12547 ins_short_branch(1); 12548 %} 12549 12550 instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 12551 match(If cop cmp); 12552 effect(USE labl); 12553 12554 ins_cost(300); 12555 format %{ $$template 12556 if ($cop$$cmpcode == Assembler::notEqual) { 12557 $$emit$$"jp,u,s $labl\n\t" 12558 $$emit$$"j$cop,u,s $labl" 12559 } else { 12560 $$emit$$"jp,u,s done\n\t" 12561 $$emit$$"j$cop,u,s $labl\n\t" 12562 $$emit$$"done:" 12563 } 12564 %} 12565 size(4); 12566 ins_encode %{ 12567 Label* l = $labl$$label; 12568 if ($cop$$cmpcode == Assembler::notEqual) { 12569 __ jccb(Assembler::parity, *l); 12570 __ jccb(Assembler::notEqual, *l); 12571 } else if ($cop$$cmpcode == Assembler::equal) { 12572 Label done; 12573 __ jccb(Assembler::parity, done); 12574 __ jccb(Assembler::equal, *l); 12575 __ bind(done); 12576 } else { 12577 ShouldNotReachHere(); 12578 } 12579 %} 12580 ins_pipe(pipe_jcc); 12581 ins_short_branch(1); 12582 %} 12583 12584 // ============================================================================ 12585 // inlined locking and unlocking 12586 12587 instruct cmpFastLock(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr) %{ 12588 predicate(LockingMode != LM_LIGHTWEIGHT); 12589 match(Set cr (FastLock object box)); 12590 effect(TEMP tmp, TEMP scr, USE_KILL box); 12591 ins_cost(300); 12592 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr" %} 12593 ins_encode %{ 12594 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, 12595 $scr$$Register, noreg, noreg, r15_thread, nullptr); 12596 %} 12597 ins_pipe(pipe_slow); 12598 %} 12599 12600 instruct cmpFastUnlock(rFlagsReg cr, rRegP object, rax_RegP box, rRegP tmp) %{ 12601 predicate(LockingMode != LM_LIGHTWEIGHT); 12602 match(Set cr (FastUnlock object box)); 12603 effect(TEMP tmp, USE_KILL box); 12604 ins_cost(300); 12605 format %{ "fastunlock $object,$box\t! kills $box,$tmp" %} 12606 ins_encode %{ 12607 __ fast_unlock($object$$Register, $box$$Register, $tmp$$Register); 12608 %} 12609 ins_pipe(pipe_slow); 12610 %} 12611 12612 instruct cmpFastLockLightweight(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI rax_reg, rRegP tmp) %{ 12613 predicate(LockingMode == LM_LIGHTWEIGHT); 12614 match(Set cr (FastLock object box)); 12615 effect(TEMP rax_reg, TEMP tmp, USE_KILL box); 12616 ins_cost(300); 12617 format %{ "fastlock $object,$box\t! kills $box,$rax_reg,$tmp" %} 12618 ins_encode %{ 12619 __ fast_lock_lightweight($object$$Register, $box$$Register, $rax_reg$$Register, $tmp$$Register, r15_thread); 12620 %} 12621 ins_pipe(pipe_slow); 12622 %} 12623 12624 instruct cmpFastUnlockLightweight(rFlagsReg cr, rRegP object, rax_RegP rax_reg, rRegP tmp) %{ 12625 predicate(LockingMode == LM_LIGHTWEIGHT); 12626 match(Set cr (FastUnlock object rax_reg)); 12627 effect(TEMP tmp, USE_KILL rax_reg); 12628 ins_cost(300); 12629 format %{ "fastunlock $object,$rax_reg\t! kills $rax_reg,$tmp" %} 12630 ins_encode %{ 12631 __ fast_unlock_lightweight($object$$Register, $rax_reg$$Register, $tmp$$Register, r15_thread); 12632 %} 12633 ins_pipe(pipe_slow); 12634 %} 12635 12636 12637 // ============================================================================ 12638 // Safepoint Instructions 12639 instruct safePoint_poll_tls(rFlagsReg cr, rRegP poll) 12640 %{ 12641 match(SafePoint poll); 12642 effect(KILL cr, USE poll); 12643 12644 format %{ "testl rax, [$poll]\t" 12645 "# Safepoint: poll for GC" %} 12646 ins_cost(125); 12647 ins_encode %{ 12648 __ relocate(relocInfo::poll_type); 12649 address pre_pc = __ pc(); 12650 __ testl(rax, Address($poll$$Register, 0)); 12651 assert(nativeInstruction_at(pre_pc)->is_safepoint_poll(), "must emit test %%eax [reg]"); 12652 %} 12653 ins_pipe(ialu_reg_mem); 12654 %} 12655 12656 instruct mask_all_evexL(kReg dst, rRegL src) %{ 12657 match(Set dst (MaskAll src)); 12658 format %{ "mask_all_evexL $dst, $src \t! mask all operation" %} 12659 ins_encode %{ 12660 int mask_len = Matcher::vector_length(this); 12661 __ vector_maskall_operation($dst$$KRegister, $src$$Register, mask_len); 12662 %} 12663 ins_pipe( pipe_slow ); 12664 %} 12665 12666 instruct mask_all_evexI_GT32(kReg dst, rRegI src, rRegL tmp) %{ 12667 predicate(Matcher::vector_length(n) > 32); 12668 match(Set dst (MaskAll src)); 12669 effect(TEMP tmp); 12670 format %{ "mask_all_evexI_GT32 $dst, $src \t! using $tmp as TEMP" %} 12671 ins_encode %{ 12672 int mask_len = Matcher::vector_length(this); 12673 __ movslq($tmp$$Register, $src$$Register); 12674 __ vector_maskall_operation($dst$$KRegister, $tmp$$Register, mask_len); 12675 %} 12676 ins_pipe( pipe_slow ); 12677 %} 12678 12679 // ============================================================================ 12680 // Procedure Call/Return Instructions 12681 // Call Java Static Instruction 12682 // Note: If this code changes, the corresponding ret_addr_offset() and 12683 // compute_padding() functions will have to be adjusted. 12684 instruct CallStaticJavaDirect(method meth) %{ 12685 match(CallStaticJava); 12686 effect(USE meth); 12687 12688 ins_cost(300); 12689 format %{ "call,static " %} 12690 opcode(0xE8); /* E8 cd */ 12691 ins_encode(clear_avx, Java_Static_Call(meth), call_epilog); 12692 ins_pipe(pipe_slow); 12693 ins_alignment(4); 12694 %} 12695 12696 // Call Java Dynamic Instruction 12697 // Note: If this code changes, the corresponding ret_addr_offset() and 12698 // compute_padding() functions will have to be adjusted. 12699 instruct CallDynamicJavaDirect(method meth) 12700 %{ 12701 match(CallDynamicJava); 12702 effect(USE meth); 12703 12704 ins_cost(300); 12705 format %{ "movq rax, #Universe::non_oop_word()\n\t" 12706 "call,dynamic " %} 12707 ins_encode(clear_avx, Java_Dynamic_Call(meth), call_epilog); 12708 ins_pipe(pipe_slow); 12709 ins_alignment(4); 12710 %} 12711 12712 // Call Runtime Instruction 12713 instruct CallRuntimeDirect(method meth) 12714 %{ 12715 match(CallRuntime); 12716 effect(USE meth); 12717 12718 ins_cost(300); 12719 format %{ "call,runtime " %} 12720 ins_encode(clear_avx, Java_To_Runtime(meth)); 12721 ins_pipe(pipe_slow); 12722 %} 12723 12724 // Call runtime without safepoint 12725 instruct CallLeafDirect(method meth) 12726 %{ 12727 match(CallLeaf); 12728 effect(USE meth); 12729 12730 ins_cost(300); 12731 format %{ "call_leaf,runtime " %} 12732 ins_encode(clear_avx, Java_To_Runtime(meth)); 12733 ins_pipe(pipe_slow); 12734 %} 12735 12736 // Call runtime without safepoint and with vector arguments 12737 instruct CallLeafDirectVector(method meth) 12738 %{ 12739 match(CallLeafVector); 12740 effect(USE meth); 12741 12742 ins_cost(300); 12743 format %{ "call_leaf,vector " %} 12744 ins_encode(Java_To_Runtime(meth)); 12745 ins_pipe(pipe_slow); 12746 %} 12747 12748 // Call runtime without safepoint 12749 // entry point is null, target holds the address to call 12750 instruct CallLeafNoFPInDirect(rRegP target) 12751 %{ 12752 predicate(n->as_Call()->entry_point() == nullptr); 12753 match(CallLeafNoFP target); 12754 12755 ins_cost(300); 12756 format %{ "call_leaf_nofp,runtime indirect " %} 12757 ins_encode %{ 12758 __ call($target$$Register); 12759 %} 12760 12761 ins_pipe(pipe_slow); 12762 %} 12763 12764 instruct CallLeafNoFPDirect(method meth) 12765 %{ 12766 predicate(n->as_Call()->entry_point() != nullptr); 12767 match(CallLeafNoFP); 12768 effect(USE meth); 12769 12770 ins_cost(300); 12771 format %{ "call_leaf_nofp,runtime " %} 12772 ins_encode(clear_avx, Java_To_Runtime(meth)); 12773 ins_pipe(pipe_slow); 12774 %} 12775 12776 // Return Instruction 12777 // Remove the return address & jump to it. 12778 // Notice: We always emit a nop after a ret to make sure there is room 12779 // for safepoint patching 12780 instruct Ret() 12781 %{ 12782 match(Return); 12783 12784 format %{ "ret" %} 12785 ins_encode %{ 12786 __ ret(0); 12787 %} 12788 ins_pipe(pipe_jmp); 12789 %} 12790 12791 // Tail Call; Jump from runtime stub to Java code. 12792 // Also known as an 'interprocedural jump'. 12793 // Target of jump will eventually return to caller. 12794 // TailJump below removes the return address. 12795 // Don't use rbp for 'jump_target' because a MachEpilogNode has already been 12796 // emitted just above the TailCall which has reset rbp to the caller state. 12797 instruct TailCalljmpInd(no_rbp_RegP jump_target, rbx_RegP method_ptr) 12798 %{ 12799 match(TailCall jump_target method_ptr); 12800 12801 ins_cost(300); 12802 format %{ "jmp $jump_target\t# rbx holds method" %} 12803 ins_encode %{ 12804 __ jmp($jump_target$$Register); 12805 %} 12806 ins_pipe(pipe_jmp); 12807 %} 12808 12809 // Tail Jump; remove the return address; jump to target. 12810 // TailCall above leaves the return address around. 12811 instruct tailjmpInd(no_rbp_RegP jump_target, rax_RegP ex_oop) 12812 %{ 12813 match(TailJump jump_target ex_oop); 12814 12815 ins_cost(300); 12816 format %{ "popq rdx\t# pop return address\n\t" 12817 "jmp $jump_target" %} 12818 ins_encode %{ 12819 __ popq(as_Register(RDX_enc)); 12820 __ jmp($jump_target$$Register); 12821 %} 12822 ins_pipe(pipe_jmp); 12823 %} 12824 12825 // Forward exception. 12826 instruct ForwardExceptionjmp() 12827 %{ 12828 match(ForwardException); 12829 12830 format %{ "jmp forward_exception_stub" %} 12831 ins_encode %{ 12832 __ jump(RuntimeAddress(StubRoutines::forward_exception_entry()), noreg); 12833 %} 12834 ins_pipe(pipe_jmp); 12835 %} 12836 12837 // Create exception oop: created by stack-crawling runtime code. 12838 // Created exception is now available to this handler, and is setup 12839 // just prior to jumping to this handler. No code emitted. 12840 instruct CreateException(rax_RegP ex_oop) 12841 %{ 12842 match(Set ex_oop (CreateEx)); 12843 12844 size(0); 12845 // use the following format syntax 12846 format %{ "# exception oop is in rax; no code emitted" %} 12847 ins_encode(); 12848 ins_pipe(empty); 12849 %} 12850 12851 // Rethrow exception: 12852 // The exception oop will come in the first argument position. 12853 // Then JUMP (not call) to the rethrow stub code. 12854 instruct RethrowException() 12855 %{ 12856 match(Rethrow); 12857 12858 // use the following format syntax 12859 format %{ "jmp rethrow_stub" %} 12860 ins_encode %{ 12861 __ jump(RuntimeAddress(OptoRuntime::rethrow_stub()), noreg); 12862 %} 12863 ins_pipe(pipe_jmp); 12864 %} 12865 12866 // ============================================================================ 12867 // This name is KNOWN by the ADLC and cannot be changed. 12868 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type 12869 // for this guy. 12870 instruct tlsLoadP(r15_RegP dst) %{ 12871 match(Set dst (ThreadLocal)); 12872 effect(DEF dst); 12873 12874 size(0); 12875 format %{ "# TLS is in R15" %} 12876 ins_encode( /*empty encoding*/ ); 12877 ins_pipe(ialu_reg_reg); 12878 %} 12879 12880 12881 //----------PEEPHOLE RULES----------------------------------------------------- 12882 // These must follow all instruction definitions as they use the names 12883 // defined in the instructions definitions. 12884 // 12885 // peeppredicate ( rule_predicate ); 12886 // // the predicate unless which the peephole rule will be ignored 12887 // 12888 // peepmatch ( root_instr_name [preceding_instruction]* ); 12889 // 12890 // peepprocedure ( procedure_name ); 12891 // // provide a procedure name to perform the optimization, the procedure should 12892 // // reside in the architecture dependent peephole file, the method has the 12893 // // signature of MachNode* (Block*, int, PhaseRegAlloc*, (MachNode*)(*)(), int...) 12894 // // with the arguments being the basic block, the current node index inside the 12895 // // block, the register allocator, the functions upon invoked return a new node 12896 // // defined in peepreplace, and the rules of the nodes appearing in the 12897 // // corresponding peepmatch, the function return true if successful, else 12898 // // return false 12899 // 12900 // peepconstraint %{ 12901 // (instruction_number.operand_name relational_op instruction_number.operand_name 12902 // [, ...] ); 12903 // // instruction numbers are zero-based using left to right order in peepmatch 12904 // 12905 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 12906 // // provide an instruction_number.operand_name for each operand that appears 12907 // // in the replacement instruction's match rule 12908 // 12909 // ---------VM FLAGS--------------------------------------------------------- 12910 // 12911 // All peephole optimizations can be turned off using -XX:-OptoPeephole 12912 // 12913 // Each peephole rule is given an identifying number starting with zero and 12914 // increasing by one in the order seen by the parser. An individual peephole 12915 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 12916 // on the command-line. 12917 // 12918 // ---------CURRENT LIMITATIONS---------------------------------------------- 12919 // 12920 // Only transformations inside a basic block (do we need more for peephole) 12921 // 12922 // ---------EXAMPLE---------------------------------------------------------- 12923 // 12924 // // pertinent parts of existing instructions in architecture description 12925 // instruct movI(rRegI dst, rRegI src) 12926 // %{ 12927 // match(Set dst (CopyI src)); 12928 // %} 12929 // 12930 // instruct incI_rReg(rRegI dst, immI_1 src, rFlagsReg cr) 12931 // %{ 12932 // match(Set dst (AddI dst src)); 12933 // effect(KILL cr); 12934 // %} 12935 // 12936 // instruct leaI_rReg_immI(rRegI dst, immI_1 src) 12937 // %{ 12938 // match(Set dst (AddI dst src)); 12939 // %} 12940 // 12941 // 1. Simple replacement 12942 // - Only match adjacent instructions in same basic block 12943 // - Only equality constraints 12944 // - Only constraints between operands, not (0.dest_reg == RAX_enc) 12945 // - Only one replacement instruction 12946 // 12947 // // Change (inc mov) to lea 12948 // peephole %{ 12949 // // lea should only be emitted when beneficial 12950 // peeppredicate( VM_Version::supports_fast_2op_lea() ); 12951 // // increment preceded by register-register move 12952 // peepmatch ( incI_rReg movI ); 12953 // // require that the destination register of the increment 12954 // // match the destination register of the move 12955 // peepconstraint ( 0.dst == 1.dst ); 12956 // // construct a replacement instruction that sets 12957 // // the destination to ( move's source register + one ) 12958 // peepreplace ( leaI_rReg_immI( 0.dst 1.src 0.src ) ); 12959 // %} 12960 // 12961 // 2. Procedural replacement 12962 // - More flexible finding relevent nodes 12963 // - More flexible constraints 12964 // - More flexible transformations 12965 // - May utilise architecture-dependent API more effectively 12966 // - Currently only one replacement instruction due to adlc parsing capabilities 12967 // 12968 // // Change (inc mov) to lea 12969 // peephole %{ 12970 // // lea should only be emitted when beneficial 12971 // peeppredicate( VM_Version::supports_fast_2op_lea() ); 12972 // // the rule numbers of these nodes inside are passed into the function below 12973 // peepmatch ( incI_rReg movI ); 12974 // // the method that takes the responsibility of transformation 12975 // peepprocedure ( inc_mov_to_lea ); 12976 // // the replacement is a leaI_rReg_immI, a lambda upon invoked creating this 12977 // // node is passed into the function above 12978 // peepreplace ( leaI_rReg_immI() ); 12979 // %} 12980 12981 // These instructions is not matched by the matcher but used by the peephole 12982 instruct leaI_rReg_rReg_peep(rRegI dst, rRegI src1, rRegI src2) 12983 %{ 12984 predicate(false); 12985 match(Set dst (AddI src1 src2)); 12986 format %{ "leal $dst, [$src1 + $src2]" %} 12987 ins_encode %{ 12988 Register dst = $dst$$Register; 12989 Register src1 = $src1$$Register; 12990 Register src2 = $src2$$Register; 12991 if (src1 != rbp && src1 != r13) { 12992 __ leal(dst, Address(src1, src2, Address::times_1)); 12993 } else { 12994 assert(src2 != rbp && src2 != r13, ""); 12995 __ leal(dst, Address(src2, src1, Address::times_1)); 12996 } 12997 %} 12998 ins_pipe(ialu_reg_reg); 12999 %} 13000 13001 instruct leaI_rReg_immI_peep(rRegI dst, rRegI src1, immI src2) 13002 %{ 13003 predicate(false); 13004 match(Set dst (AddI src1 src2)); 13005 format %{ "leal $dst, [$src1 + $src2]" %} 13006 ins_encode %{ 13007 __ leal($dst$$Register, Address($src1$$Register, $src2$$constant)); 13008 %} 13009 ins_pipe(ialu_reg_reg); 13010 %} 13011 13012 instruct leaI_rReg_immI2_peep(rRegI dst, rRegI src, immI2 shift) 13013 %{ 13014 predicate(false); 13015 match(Set dst (LShiftI src shift)); 13016 format %{ "leal $dst, [$src << $shift]" %} 13017 ins_encode %{ 13018 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($shift$$constant); 13019 Register src = $src$$Register; 13020 if (scale == Address::times_2 && src != rbp && src != r13) { 13021 __ leal($dst$$Register, Address(src, src, Address::times_1)); 13022 } else { 13023 __ leal($dst$$Register, Address(noreg, src, scale)); 13024 } 13025 %} 13026 ins_pipe(ialu_reg_reg); 13027 %} 13028 13029 instruct leaL_rReg_rReg_peep(rRegL dst, rRegL src1, rRegL src2) 13030 %{ 13031 predicate(false); 13032 match(Set dst (AddL src1 src2)); 13033 format %{ "leaq $dst, [$src1 + $src2]" %} 13034 ins_encode %{ 13035 Register dst = $dst$$Register; 13036 Register src1 = $src1$$Register; 13037 Register src2 = $src2$$Register; 13038 if (src1 != rbp && src1 != r13) { 13039 __ leaq(dst, Address(src1, src2, Address::times_1)); 13040 } else { 13041 assert(src2 != rbp && src2 != r13, ""); 13042 __ leaq(dst, Address(src2, src1, Address::times_1)); 13043 } 13044 %} 13045 ins_pipe(ialu_reg_reg); 13046 %} 13047 13048 instruct leaL_rReg_immL32_peep(rRegL dst, rRegL src1, immL32 src2) 13049 %{ 13050 predicate(false); 13051 match(Set dst (AddL src1 src2)); 13052 format %{ "leaq $dst, [$src1 + $src2]" %} 13053 ins_encode %{ 13054 __ leaq($dst$$Register, Address($src1$$Register, $src2$$constant)); 13055 %} 13056 ins_pipe(ialu_reg_reg); 13057 %} 13058 13059 instruct leaL_rReg_immI2_peep(rRegL dst, rRegL src, immI2 shift) 13060 %{ 13061 predicate(false); 13062 match(Set dst (LShiftL src shift)); 13063 format %{ "leaq $dst, [$src << $shift]" %} 13064 ins_encode %{ 13065 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($shift$$constant); 13066 Register src = $src$$Register; 13067 if (scale == Address::times_2 && src != rbp && src != r13) { 13068 __ leaq($dst$$Register, Address(src, src, Address::times_1)); 13069 } else { 13070 __ leaq($dst$$Register, Address(noreg, src, scale)); 13071 } 13072 %} 13073 ins_pipe(ialu_reg_reg); 13074 %} 13075 13076 // These peephole rules replace mov + I pairs (where I is one of {add, inc, dec, 13077 // sal}) with lea instructions. The {add, sal} rules are beneficial in 13078 // processors with at least partial ALU support for lea 13079 // (supports_fast_2op_lea()), whereas the {inc, dec} rules are only generally 13080 // beneficial for processors with full ALU support 13081 // (VM_Version::supports_fast_3op_lea()) and Intel Cascade Lake. 13082 13083 peephole 13084 %{ 13085 peeppredicate(VM_Version::supports_fast_2op_lea()); 13086 peepmatch (addI_rReg); 13087 peepprocedure (lea_coalesce_reg); 13088 peepreplace (leaI_rReg_rReg_peep()); 13089 %} 13090 13091 peephole 13092 %{ 13093 peeppredicate(VM_Version::supports_fast_2op_lea()); 13094 peepmatch (addI_rReg_imm); 13095 peepprocedure (lea_coalesce_imm); 13096 peepreplace (leaI_rReg_immI_peep()); 13097 %} 13098 13099 peephole 13100 %{ 13101 peeppredicate(VM_Version::supports_fast_3op_lea() || 13102 VM_Version::is_intel_cascade_lake()); 13103 peepmatch (incI_rReg); 13104 peepprocedure (lea_coalesce_imm); 13105 peepreplace (leaI_rReg_immI_peep()); 13106 %} 13107 13108 peephole 13109 %{ 13110 peeppredicate(VM_Version::supports_fast_3op_lea() || 13111 VM_Version::is_intel_cascade_lake()); 13112 peepmatch (decI_rReg); 13113 peepprocedure (lea_coalesce_imm); 13114 peepreplace (leaI_rReg_immI_peep()); 13115 %} 13116 13117 peephole 13118 %{ 13119 peeppredicate(VM_Version::supports_fast_2op_lea()); 13120 peepmatch (salI_rReg_immI2); 13121 peepprocedure (lea_coalesce_imm); 13122 peepreplace (leaI_rReg_immI2_peep()); 13123 %} 13124 13125 peephole 13126 %{ 13127 peeppredicate(VM_Version::supports_fast_2op_lea()); 13128 peepmatch (addL_rReg); 13129 peepprocedure (lea_coalesce_reg); 13130 peepreplace (leaL_rReg_rReg_peep()); 13131 %} 13132 13133 peephole 13134 %{ 13135 peeppredicate(VM_Version::supports_fast_2op_lea()); 13136 peepmatch (addL_rReg_imm); 13137 peepprocedure (lea_coalesce_imm); 13138 peepreplace (leaL_rReg_immL32_peep()); 13139 %} 13140 13141 peephole 13142 %{ 13143 peeppredicate(VM_Version::supports_fast_3op_lea() || 13144 VM_Version::is_intel_cascade_lake()); 13145 peepmatch (incL_rReg); 13146 peepprocedure (lea_coalesce_imm); 13147 peepreplace (leaL_rReg_immL32_peep()); 13148 %} 13149 13150 peephole 13151 %{ 13152 peeppredicate(VM_Version::supports_fast_3op_lea() || 13153 VM_Version::is_intel_cascade_lake()); 13154 peepmatch (decL_rReg); 13155 peepprocedure (lea_coalesce_imm); 13156 peepreplace (leaL_rReg_immL32_peep()); 13157 %} 13158 13159 peephole 13160 %{ 13161 peeppredicate(VM_Version::supports_fast_2op_lea()); 13162 peepmatch (salL_rReg_immI2); 13163 peepprocedure (lea_coalesce_imm); 13164 peepreplace (leaL_rReg_immI2_peep()); 13165 %} 13166 13167 // These peephole rules matches instructions which set flags and are followed by a testI/L_reg 13168 // 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 13169 13170 //int variant 13171 peephole 13172 %{ 13173 peepmatch (testI_reg); 13174 peepprocedure (test_may_remove); 13175 %} 13176 13177 //long variant 13178 peephole 13179 %{ 13180 peepmatch (testL_reg); 13181 peepprocedure (test_may_remove); 13182 %} 13183 13184 13185 //----------SMARTSPILL RULES--------------------------------------------------- 13186 // These must follow all instruction definitions as they use the names 13187 // defined in the instructions definitions.