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 __ setb(Assembler::notEqual, dst); 666 __ movzbl(dst, dst); 667 __ bind(done); 668 } 669 670 // Math.min() # Math.max() 671 // -------------------------- 672 // ucomis[s/d] # 673 // ja -> b # a 674 // jp -> NaN # NaN 675 // jb -> a # b 676 // je # 677 // |-jz -> a | b # a & b 678 // | -> a # 679 static void emit_fp_min_max(MacroAssembler* masm, XMMRegister dst, 680 XMMRegister a, XMMRegister b, 681 XMMRegister xmmt, Register rt, 682 bool min, bool single) { 683 684 Label nan, zero, below, above, done; 685 686 if (single) 687 __ ucomiss(a, b); 688 else 689 __ ucomisd(a, b); 690 691 if (dst->encoding() != (min ? b : a)->encoding()) 692 __ jccb(Assembler::above, above); // CF=0 & ZF=0 693 else 694 __ jccb(Assembler::above, done); 695 696 __ jccb(Assembler::parity, nan); // PF=1 697 __ jccb(Assembler::below, below); // CF=1 698 699 // equal 700 __ vpxor(xmmt, xmmt, xmmt, Assembler::AVX_128bit); 701 if (single) { 702 __ ucomiss(a, xmmt); 703 __ jccb(Assembler::equal, zero); 704 705 __ movflt(dst, a); 706 __ jmp(done); 707 } 708 else { 709 __ ucomisd(a, xmmt); 710 __ jccb(Assembler::equal, zero); 711 712 __ movdbl(dst, a); 713 __ jmp(done); 714 } 715 716 __ bind(zero); 717 if (min) 718 __ vpor(dst, a, b, Assembler::AVX_128bit); 719 else 720 __ vpand(dst, a, b, Assembler::AVX_128bit); 721 722 __ jmp(done); 723 724 __ bind(above); 725 if (single) 726 __ movflt(dst, min ? b : a); 727 else 728 __ movdbl(dst, min ? b : a); 729 730 __ jmp(done); 731 732 __ bind(nan); 733 if (single) { 734 __ movl(rt, 0x7fc00000); // Float.NaN 735 __ movdl(dst, rt); 736 } 737 else { 738 __ mov64(rt, 0x7ff8000000000000L); // Double.NaN 739 __ movdq(dst, rt); 740 } 741 __ jmp(done); 742 743 __ bind(below); 744 if (single) 745 __ movflt(dst, min ? a : b); 746 else 747 __ movdbl(dst, min ? a : b); 748 749 __ bind(done); 750 } 751 752 //============================================================================= 753 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; 754 755 int ConstantTable::calculate_table_base_offset() const { 756 return 0; // absolute addressing, no offset 757 } 758 759 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; } 760 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 761 ShouldNotReachHere(); 762 } 763 764 void MachConstantBaseNode::emit(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const { 765 // Empty encoding 766 } 767 768 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 769 return 0; 770 } 771 772 #ifndef PRODUCT 773 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 774 st->print("# MachConstantBaseNode (empty encoding)"); 775 } 776 #endif 777 778 779 //============================================================================= 780 #ifndef PRODUCT 781 void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 782 Compile* C = ra_->C; 783 784 int framesize = C->output()->frame_size_in_bytes(); 785 int bangsize = C->output()->bang_size_in_bytes(); 786 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 787 // Remove wordSize for return addr which is already pushed. 788 framesize -= wordSize; 789 790 if (C->output()->need_stack_bang(bangsize)) { 791 framesize -= wordSize; 792 st->print("# stack bang (%d bytes)", bangsize); 793 st->print("\n\t"); 794 st->print("pushq rbp\t# Save rbp"); 795 if (PreserveFramePointer) { 796 st->print("\n\t"); 797 st->print("movq rbp, rsp\t# Save the caller's SP into rbp"); 798 } 799 if (framesize) { 800 st->print("\n\t"); 801 st->print("subq rsp, #%d\t# Create frame",framesize); 802 } 803 } else { 804 st->print("subq rsp, #%d\t# Create frame",framesize); 805 st->print("\n\t"); 806 framesize -= wordSize; 807 st->print("movq [rsp + #%d], rbp\t# Save rbp",framesize); 808 if (PreserveFramePointer) { 809 st->print("\n\t"); 810 st->print("movq rbp, rsp\t# Save the caller's SP into rbp"); 811 if (framesize > 0) { 812 st->print("\n\t"); 813 st->print("addq rbp, #%d", framesize); 814 } 815 } 816 } 817 818 if (VerifyStackAtCalls) { 819 st->print("\n\t"); 820 framesize -= wordSize; 821 st->print("movq [rsp + #%d], 0xbadb100d\t# Majik cookie for stack depth check",framesize); 822 #ifdef ASSERT 823 st->print("\n\t"); 824 st->print("# stack alignment check"); 825 #endif 826 } 827 if (C->stub_function() != nullptr && BarrierSet::barrier_set()->barrier_set_nmethod() != nullptr) { 828 st->print("\n\t"); 829 st->print("cmpl [r15_thread + #disarmed_guard_value_offset], #disarmed_guard_value\t"); 830 st->print("\n\t"); 831 st->print("je fast_entry\t"); 832 st->print("\n\t"); 833 st->print("call #nmethod_entry_barrier_stub\t"); 834 st->print("\n\tfast_entry:"); 835 } 836 st->cr(); 837 } 838 #endif 839 840 void MachPrologNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const { 841 Compile* C = ra_->C; 842 843 __ verified_entry(C); 844 845 if (ra_->C->stub_function() == nullptr) { 846 __ entry_barrier(); 847 } 848 849 if (!Compile::current()->output()->in_scratch_emit_size()) { 850 __ bind(*_verified_entry); 851 } 852 853 C->output()->set_frame_complete(__ offset()); 854 855 if (C->has_mach_constant_base_node()) { 856 // NOTE: We set the table base offset here because users might be 857 // emitted before MachConstantBaseNode. 858 ConstantTable& constant_table = C->output()->constant_table(); 859 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset()); 860 } 861 } 862 863 int MachPrologNode::reloc() const 864 { 865 return 0; // a large enough number 866 } 867 868 //============================================================================= 869 #ifndef PRODUCT 870 void MachEpilogNode::format(PhaseRegAlloc* ra_, outputStream* st) const 871 { 872 Compile* C = ra_->C; 873 if (generate_vzeroupper(C)) { 874 st->print("vzeroupper"); 875 st->cr(); st->print("\t"); 876 } 877 878 int framesize = C->output()->frame_size_in_bytes(); 879 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 880 // Remove word for return adr already pushed 881 // and RBP 882 framesize -= 2*wordSize; 883 884 if (framesize) { 885 st->print_cr("addq rsp, %d\t# Destroy frame", framesize); 886 st->print("\t"); 887 } 888 889 st->print_cr("popq rbp"); 890 if (do_polling() && C->is_method_compilation()) { 891 st->print("\t"); 892 st->print_cr("cmpq rsp, poll_offset[r15_thread] \n\t" 893 "ja #safepoint_stub\t" 894 "# Safepoint: poll for GC"); 895 } 896 } 897 #endif 898 899 void MachEpilogNode::emit(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const 900 { 901 Compile* C = ra_->C; 902 903 if (generate_vzeroupper(C)) { 904 // Clear upper bits of YMM registers when current compiled code uses 905 // wide vectors to avoid AVX <-> SSE transition penalty during call. 906 __ vzeroupper(); 907 } 908 909 // Subtract two words to account for return address and rbp 910 int initial_framesize = C->output()->frame_size_in_bytes() - 2*wordSize; 911 __ remove_frame(initial_framesize, C->needs_stack_repair()); 912 913 if (StackReservedPages > 0 && C->has_reserved_stack_access()) { 914 __ reserved_stack_check(); 915 } 916 917 if (do_polling() && C->is_method_compilation()) { 918 Label dummy_label; 919 Label* code_stub = &dummy_label; 920 if (!C->output()->in_scratch_emit_size()) { 921 C2SafepointPollStub* stub = new (C->comp_arena()) C2SafepointPollStub(__ offset()); 922 C->output()->add_stub(stub); 923 code_stub = &stub->entry(); 924 } 925 __ relocate(relocInfo::poll_return_type); 926 __ safepoint_poll(*code_stub, r15_thread, true /* at_return */, true /* in_nmethod */); 927 } 928 } 929 930 int MachEpilogNode::reloc() const 931 { 932 return 2; // a large enough number 933 } 934 935 const Pipeline* MachEpilogNode::pipeline() const 936 { 937 return MachNode::pipeline_class(); 938 } 939 940 //============================================================================= 941 942 enum RC { 943 rc_bad, 944 rc_int, 945 rc_kreg, 946 rc_float, 947 rc_stack 948 }; 949 950 static enum RC rc_class(OptoReg::Name reg) 951 { 952 if( !OptoReg::is_valid(reg) ) return rc_bad; 953 954 if (OptoReg::is_stack(reg)) return rc_stack; 955 956 VMReg r = OptoReg::as_VMReg(reg); 957 958 if (r->is_Register()) return rc_int; 959 960 if (r->is_KRegister()) return rc_kreg; 961 962 assert(r->is_XMMRegister(), "must be"); 963 return rc_float; 964 } 965 966 // Next two methods are shared by 32- and 64-bit VM. They are defined in x86.ad. 967 static void vec_mov_helper(C2_MacroAssembler *masm, int src_lo, int dst_lo, 968 int src_hi, int dst_hi, uint ireg, outputStream* st); 969 970 void vec_spill_helper(C2_MacroAssembler *masm, bool is_load, 971 int stack_offset, int reg, uint ireg, outputStream* st); 972 973 static void vec_stack_to_stack_helper(C2_MacroAssembler *masm, int src_offset, 974 int dst_offset, uint ireg, outputStream* st) { 975 if (masm) { 976 switch (ireg) { 977 case Op_VecS: 978 __ movq(Address(rsp, -8), rax); 979 __ movl(rax, Address(rsp, src_offset)); 980 __ movl(Address(rsp, dst_offset), rax); 981 __ movq(rax, Address(rsp, -8)); 982 break; 983 case Op_VecD: 984 __ pushq(Address(rsp, src_offset)); 985 __ popq (Address(rsp, dst_offset)); 986 break; 987 case Op_VecX: 988 __ pushq(Address(rsp, src_offset)); 989 __ popq (Address(rsp, dst_offset)); 990 __ pushq(Address(rsp, src_offset+8)); 991 __ popq (Address(rsp, dst_offset+8)); 992 break; 993 case Op_VecY: 994 __ vmovdqu(Address(rsp, -32), xmm0); 995 __ vmovdqu(xmm0, Address(rsp, src_offset)); 996 __ vmovdqu(Address(rsp, dst_offset), xmm0); 997 __ vmovdqu(xmm0, Address(rsp, -32)); 998 break; 999 case Op_VecZ: 1000 __ evmovdquq(Address(rsp, -64), xmm0, 2); 1001 __ evmovdquq(xmm0, Address(rsp, src_offset), 2); 1002 __ evmovdquq(Address(rsp, dst_offset), xmm0, 2); 1003 __ evmovdquq(xmm0, Address(rsp, -64), 2); 1004 break; 1005 default: 1006 ShouldNotReachHere(); 1007 } 1008 #ifndef PRODUCT 1009 } else { 1010 switch (ireg) { 1011 case Op_VecS: 1012 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1013 "movl rax, [rsp + #%d]\n\t" 1014 "movl [rsp + #%d], rax\n\t" 1015 "movq rax, [rsp - #8]", 1016 src_offset, dst_offset); 1017 break; 1018 case Op_VecD: 1019 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1020 "popq [rsp + #%d]", 1021 src_offset, dst_offset); 1022 break; 1023 case Op_VecX: 1024 st->print("pushq [rsp + #%d]\t# 128-bit mem-mem spill\n\t" 1025 "popq [rsp + #%d]\n\t" 1026 "pushq [rsp + #%d]\n\t" 1027 "popq [rsp + #%d]", 1028 src_offset, dst_offset, src_offset+8, dst_offset+8); 1029 break; 1030 case Op_VecY: 1031 st->print("vmovdqu [rsp - #32], xmm0\t# 256-bit mem-mem spill\n\t" 1032 "vmovdqu xmm0, [rsp + #%d]\n\t" 1033 "vmovdqu [rsp + #%d], xmm0\n\t" 1034 "vmovdqu xmm0, [rsp - #32]", 1035 src_offset, dst_offset); 1036 break; 1037 case Op_VecZ: 1038 st->print("vmovdqu [rsp - #64], xmm0\t# 512-bit mem-mem spill\n\t" 1039 "vmovdqu xmm0, [rsp + #%d]\n\t" 1040 "vmovdqu [rsp + #%d], xmm0\n\t" 1041 "vmovdqu xmm0, [rsp - #64]", 1042 src_offset, dst_offset); 1043 break; 1044 default: 1045 ShouldNotReachHere(); 1046 } 1047 #endif 1048 } 1049 } 1050 1051 uint MachSpillCopyNode::implementation(C2_MacroAssembler* masm, 1052 PhaseRegAlloc* ra_, 1053 bool do_size, 1054 outputStream* st) const { 1055 assert(masm != nullptr || st != nullptr, "sanity"); 1056 // Get registers to move 1057 OptoReg::Name src_second = ra_->get_reg_second(in(1)); 1058 OptoReg::Name src_first = ra_->get_reg_first(in(1)); 1059 OptoReg::Name dst_second = ra_->get_reg_second(this); 1060 OptoReg::Name dst_first = ra_->get_reg_first(this); 1061 1062 enum RC src_second_rc = rc_class(src_second); 1063 enum RC src_first_rc = rc_class(src_first); 1064 enum RC dst_second_rc = rc_class(dst_second); 1065 enum RC dst_first_rc = rc_class(dst_first); 1066 1067 assert(OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), 1068 "must move at least 1 register" ); 1069 1070 if (src_first == dst_first && src_second == dst_second) { 1071 // Self copy, no move 1072 return 0; 1073 } 1074 if (bottom_type()->isa_vect() != nullptr && bottom_type()->isa_vectmask() == nullptr) { 1075 uint ireg = ideal_reg(); 1076 assert((src_first_rc != rc_int && dst_first_rc != rc_int), "sanity"); 1077 assert((ireg == Op_VecS || ireg == Op_VecD || ireg == Op_VecX || ireg == Op_VecY || ireg == Op_VecZ ), "sanity"); 1078 if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) { 1079 // mem -> mem 1080 int src_offset = ra_->reg2offset(src_first); 1081 int dst_offset = ra_->reg2offset(dst_first); 1082 vec_stack_to_stack_helper(masm, src_offset, dst_offset, ireg, st); 1083 } else if (src_first_rc == rc_float && dst_first_rc == rc_float ) { 1084 vec_mov_helper(masm, src_first, dst_first, src_second, dst_second, ireg, st); 1085 } else if (src_first_rc == rc_float && dst_first_rc == rc_stack ) { 1086 int stack_offset = ra_->reg2offset(dst_first); 1087 vec_spill_helper(masm, false, stack_offset, src_first, ireg, st); 1088 } else if (src_first_rc == rc_stack && dst_first_rc == rc_float ) { 1089 int stack_offset = ra_->reg2offset(src_first); 1090 vec_spill_helper(masm, true, stack_offset, dst_first, ireg, st); 1091 } else { 1092 ShouldNotReachHere(); 1093 } 1094 return 0; 1095 } 1096 if (src_first_rc == rc_stack) { 1097 // mem -> 1098 if (dst_first_rc == rc_stack) { 1099 // mem -> mem 1100 assert(src_second != dst_first, "overlap"); 1101 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1102 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1103 // 64-bit 1104 int src_offset = ra_->reg2offset(src_first); 1105 int dst_offset = ra_->reg2offset(dst_first); 1106 if (masm) { 1107 __ pushq(Address(rsp, src_offset)); 1108 __ popq (Address(rsp, dst_offset)); 1109 #ifndef PRODUCT 1110 } else { 1111 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1112 "popq [rsp + #%d]", 1113 src_offset, dst_offset); 1114 #endif 1115 } 1116 } else { 1117 // 32-bit 1118 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1119 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1120 // No pushl/popl, so: 1121 int src_offset = ra_->reg2offset(src_first); 1122 int dst_offset = ra_->reg2offset(dst_first); 1123 if (masm) { 1124 __ movq(Address(rsp, -8), rax); 1125 __ movl(rax, Address(rsp, src_offset)); 1126 __ movl(Address(rsp, dst_offset), rax); 1127 __ movq(rax, Address(rsp, -8)); 1128 #ifndef PRODUCT 1129 } else { 1130 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1131 "movl rax, [rsp + #%d]\n\t" 1132 "movl [rsp + #%d], rax\n\t" 1133 "movq rax, [rsp - #8]", 1134 src_offset, dst_offset); 1135 #endif 1136 } 1137 } 1138 return 0; 1139 } else if (dst_first_rc == rc_int) { 1140 // mem -> gpr 1141 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1142 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1143 // 64-bit 1144 int offset = ra_->reg2offset(src_first); 1145 if (masm) { 1146 __ movq(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1147 #ifndef PRODUCT 1148 } else { 1149 st->print("movq %s, [rsp + #%d]\t# spill", 1150 Matcher::regName[dst_first], 1151 offset); 1152 #endif 1153 } 1154 } else { 1155 // 32-bit 1156 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1157 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1158 int offset = ra_->reg2offset(src_first); 1159 if (masm) { 1160 __ movl(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1161 #ifndef PRODUCT 1162 } else { 1163 st->print("movl %s, [rsp + #%d]\t# spill", 1164 Matcher::regName[dst_first], 1165 offset); 1166 #endif 1167 } 1168 } 1169 return 0; 1170 } else if (dst_first_rc == rc_float) { 1171 // mem-> xmm 1172 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1173 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1174 // 64-bit 1175 int offset = ra_->reg2offset(src_first); 1176 if (masm) { 1177 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1178 #ifndef PRODUCT 1179 } else { 1180 st->print("%s %s, [rsp + #%d]\t# spill", 1181 UseXmmLoadAndClearUpper ? "movsd " : "movlpd", 1182 Matcher::regName[dst_first], 1183 offset); 1184 #endif 1185 } 1186 } else { 1187 // 32-bit 1188 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1189 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1190 int offset = ra_->reg2offset(src_first); 1191 if (masm) { 1192 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1193 #ifndef PRODUCT 1194 } else { 1195 st->print("movss %s, [rsp + #%d]\t# spill", 1196 Matcher::regName[dst_first], 1197 offset); 1198 #endif 1199 } 1200 } 1201 return 0; 1202 } else if (dst_first_rc == rc_kreg) { 1203 // mem -> kreg 1204 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1205 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1206 // 64-bit 1207 int offset = ra_->reg2offset(src_first); 1208 if (masm) { 1209 __ kmov(as_KRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1210 #ifndef PRODUCT 1211 } else { 1212 st->print("kmovq %s, [rsp + #%d]\t# spill", 1213 Matcher::regName[dst_first], 1214 offset); 1215 #endif 1216 } 1217 } 1218 return 0; 1219 } 1220 } else if (src_first_rc == rc_int) { 1221 // gpr -> 1222 if (dst_first_rc == rc_stack) { 1223 // gpr -> mem 1224 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1225 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1226 // 64-bit 1227 int offset = ra_->reg2offset(dst_first); 1228 if (masm) { 1229 __ movq(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1230 #ifndef PRODUCT 1231 } else { 1232 st->print("movq [rsp + #%d], %s\t# spill", 1233 offset, 1234 Matcher::regName[src_first]); 1235 #endif 1236 } 1237 } else { 1238 // 32-bit 1239 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1240 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1241 int offset = ra_->reg2offset(dst_first); 1242 if (masm) { 1243 __ movl(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1244 #ifndef PRODUCT 1245 } else { 1246 st->print("movl [rsp + #%d], %s\t# spill", 1247 offset, 1248 Matcher::regName[src_first]); 1249 #endif 1250 } 1251 } 1252 return 0; 1253 } else if (dst_first_rc == rc_int) { 1254 // gpr -> gpr 1255 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1256 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1257 // 64-bit 1258 if (masm) { 1259 __ movq(as_Register(Matcher::_regEncode[dst_first]), 1260 as_Register(Matcher::_regEncode[src_first])); 1261 #ifndef PRODUCT 1262 } else { 1263 st->print("movq %s, %s\t# spill", 1264 Matcher::regName[dst_first], 1265 Matcher::regName[src_first]); 1266 #endif 1267 } 1268 return 0; 1269 } else { 1270 // 32-bit 1271 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1272 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1273 if (masm) { 1274 __ movl(as_Register(Matcher::_regEncode[dst_first]), 1275 as_Register(Matcher::_regEncode[src_first])); 1276 #ifndef PRODUCT 1277 } else { 1278 st->print("movl %s, %s\t# spill", 1279 Matcher::regName[dst_first], 1280 Matcher::regName[src_first]); 1281 #endif 1282 } 1283 return 0; 1284 } 1285 } else if (dst_first_rc == rc_float) { 1286 // gpr -> xmm 1287 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1288 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1289 // 64-bit 1290 if (masm) { 1291 __ movdq( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1292 #ifndef PRODUCT 1293 } else { 1294 st->print("movdq %s, %s\t# spill", 1295 Matcher::regName[dst_first], 1296 Matcher::regName[src_first]); 1297 #endif 1298 } 1299 } else { 1300 // 32-bit 1301 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1302 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1303 if (masm) { 1304 __ movdl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1305 #ifndef PRODUCT 1306 } else { 1307 st->print("movdl %s, %s\t# spill", 1308 Matcher::regName[dst_first], 1309 Matcher::regName[src_first]); 1310 #endif 1311 } 1312 } 1313 return 0; 1314 } else if (dst_first_rc == rc_kreg) { 1315 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1316 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1317 // 64-bit 1318 if (masm) { 1319 __ kmov(as_KRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1320 #ifndef PRODUCT 1321 } else { 1322 st->print("kmovq %s, %s\t# spill", 1323 Matcher::regName[dst_first], 1324 Matcher::regName[src_first]); 1325 #endif 1326 } 1327 } 1328 Unimplemented(); 1329 return 0; 1330 } 1331 } else if (src_first_rc == rc_float) { 1332 // xmm -> 1333 if (dst_first_rc == rc_stack) { 1334 // xmm -> mem 1335 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1336 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1337 // 64-bit 1338 int offset = ra_->reg2offset(dst_first); 1339 if (masm) { 1340 __ movdbl( Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1341 #ifndef PRODUCT 1342 } else { 1343 st->print("movsd [rsp + #%d], %s\t# spill", 1344 offset, 1345 Matcher::regName[src_first]); 1346 #endif 1347 } 1348 } else { 1349 // 32-bit 1350 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1351 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1352 int offset = ra_->reg2offset(dst_first); 1353 if (masm) { 1354 __ movflt(Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1355 #ifndef PRODUCT 1356 } else { 1357 st->print("movss [rsp + #%d], %s\t# spill", 1358 offset, 1359 Matcher::regName[src_first]); 1360 #endif 1361 } 1362 } 1363 return 0; 1364 } else if (dst_first_rc == rc_int) { 1365 // xmm -> gpr 1366 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1367 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1368 // 64-bit 1369 if (masm) { 1370 __ movdq( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1371 #ifndef PRODUCT 1372 } else { 1373 st->print("movdq %s, %s\t# spill", 1374 Matcher::regName[dst_first], 1375 Matcher::regName[src_first]); 1376 #endif 1377 } 1378 } else { 1379 // 32-bit 1380 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1381 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1382 if (masm) { 1383 __ movdl( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1384 #ifndef PRODUCT 1385 } else { 1386 st->print("movdl %s, %s\t# spill", 1387 Matcher::regName[dst_first], 1388 Matcher::regName[src_first]); 1389 #endif 1390 } 1391 } 1392 return 0; 1393 } else if (dst_first_rc == rc_float) { 1394 // xmm -> xmm 1395 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1396 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1397 // 64-bit 1398 if (masm) { 1399 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1400 #ifndef PRODUCT 1401 } else { 1402 st->print("%s %s, %s\t# spill", 1403 UseXmmRegToRegMoveAll ? "movapd" : "movsd ", 1404 Matcher::regName[dst_first], 1405 Matcher::regName[src_first]); 1406 #endif 1407 } 1408 } else { 1409 // 32-bit 1410 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1411 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1412 if (masm) { 1413 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1414 #ifndef PRODUCT 1415 } else { 1416 st->print("%s %s, %s\t# spill", 1417 UseXmmRegToRegMoveAll ? "movaps" : "movss ", 1418 Matcher::regName[dst_first], 1419 Matcher::regName[src_first]); 1420 #endif 1421 } 1422 } 1423 return 0; 1424 } else if (dst_first_rc == rc_kreg) { 1425 assert(false, "Illegal spilling"); 1426 return 0; 1427 } 1428 } else if (src_first_rc == rc_kreg) { 1429 if (dst_first_rc == rc_stack) { 1430 // mem -> kreg 1431 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1432 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1433 // 64-bit 1434 int offset = ra_->reg2offset(dst_first); 1435 if (masm) { 1436 __ kmov(Address(rsp, offset), as_KRegister(Matcher::_regEncode[src_first])); 1437 #ifndef PRODUCT 1438 } else { 1439 st->print("kmovq [rsp + #%d] , %s\t# spill", 1440 offset, 1441 Matcher::regName[src_first]); 1442 #endif 1443 } 1444 } 1445 return 0; 1446 } else if (dst_first_rc == rc_int) { 1447 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1448 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1449 // 64-bit 1450 if (masm) { 1451 __ kmov(as_Register(Matcher::_regEncode[dst_first]), as_KRegister(Matcher::_regEncode[src_first])); 1452 #ifndef PRODUCT 1453 } else { 1454 st->print("kmovq %s, %s\t# spill", 1455 Matcher::regName[dst_first], 1456 Matcher::regName[src_first]); 1457 #endif 1458 } 1459 } 1460 Unimplemented(); 1461 return 0; 1462 } else if (dst_first_rc == rc_kreg) { 1463 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1464 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1465 // 64-bit 1466 if (masm) { 1467 __ kmov(as_KRegister(Matcher::_regEncode[dst_first]), as_KRegister(Matcher::_regEncode[src_first])); 1468 #ifndef PRODUCT 1469 } else { 1470 st->print("kmovq %s, %s\t# spill", 1471 Matcher::regName[dst_first], 1472 Matcher::regName[src_first]); 1473 #endif 1474 } 1475 } 1476 return 0; 1477 } else if (dst_first_rc == rc_float) { 1478 assert(false, "Illegal spill"); 1479 return 0; 1480 } 1481 } 1482 1483 assert(0," foo "); 1484 Unimplemented(); 1485 return 0; 1486 } 1487 1488 #ifndef PRODUCT 1489 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream* st) const { 1490 implementation(nullptr, ra_, false, st); 1491 } 1492 #endif 1493 1494 void MachSpillCopyNode::emit(C2_MacroAssembler *masm, PhaseRegAlloc *ra_) const { 1495 implementation(masm, ra_, false, nullptr); 1496 } 1497 1498 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1499 return MachNode::size(ra_); 1500 } 1501 1502 //============================================================================= 1503 #ifndef PRODUCT 1504 void BoxLockNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1505 { 1506 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1507 int reg = ra_->get_reg_first(this); 1508 st->print("leaq %s, [rsp + #%d]\t# box lock", 1509 Matcher::regName[reg], offset); 1510 } 1511 #endif 1512 1513 void BoxLockNode::emit(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const 1514 { 1515 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1516 int reg = ra_->get_encode(this); 1517 1518 __ lea(as_Register(reg), Address(rsp, offset)); 1519 } 1520 1521 uint BoxLockNode::size(PhaseRegAlloc *ra_) const 1522 { 1523 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1524 return (offset < 0x80) ? 5 : 8; // REX 1525 } 1526 1527 //============================================================================= 1528 #ifndef PRODUCT 1529 void MachVEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1530 { 1531 st->print_cr("MachVEPNode"); 1532 } 1533 #endif 1534 1535 void MachVEPNode::emit(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const 1536 { 1537 CodeBuffer* cbuf = masm->code(); 1538 uint insts_size = cbuf->insts_size(); 1539 if (!_verified) { 1540 __ ic_check(1); 1541 } else { 1542 // TODO 8284443 Avoid creation of temporary frame 1543 if (ra_->C->stub_function() == nullptr) { 1544 __ verified_entry(ra_->C, 0); 1545 __ entry_barrier(); 1546 int initial_framesize = ra_->C->output()->frame_size_in_bytes() - 2*wordSize; 1547 __ remove_frame(initial_framesize, false); 1548 } 1549 // Unpack inline type args passed as oop and then jump to 1550 // the verified entry point (skipping the unverified entry). 1551 int sp_inc = __ unpack_inline_args(ra_->C, _receiver_only); 1552 // Emit code for verified entry and save increment for stack repair on return 1553 __ verified_entry(ra_->C, sp_inc); 1554 if (Compile::current()->output()->in_scratch_emit_size()) { 1555 Label dummy_verified_entry; 1556 __ jmp(dummy_verified_entry); 1557 } else { 1558 __ jmp(*_verified_entry); 1559 } 1560 } 1561 /* WARNING these NOPs are critical so that verified entry point is properly 1562 4 bytes aligned for patching by NativeJump::patch_verified_entry() */ 1563 int nops_cnt = 4 - ((cbuf->insts_size() - insts_size) & 0x3); 1564 nops_cnt &= 0x3; // Do not add nops if code is aligned. 1565 if (nops_cnt > 0) { 1566 __ nop(nops_cnt); 1567 } 1568 } 1569 1570 //============================================================================= 1571 #ifndef PRODUCT 1572 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1573 { 1574 if (UseCompressedClassPointers) { 1575 st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1576 st->print_cr("\tcmpl rscratch1, [rax + CompiledICData::speculated_klass_offset()]\t # Inline cache check"); 1577 } else { 1578 st->print_cr("movq rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1579 st->print_cr("\tcmpq rscratch1, [rax + CompiledICData::speculated_klass_offset()]\t # Inline cache check"); 1580 } 1581 st->print_cr("\tjne SharedRuntime::_ic_miss_stub"); 1582 } 1583 #endif 1584 1585 void MachUEPNode::emit(C2_MacroAssembler* masm, PhaseRegAlloc* ra_) const 1586 { 1587 __ ic_check(InteriorEntryAlignment); 1588 } 1589 1590 //============================================================================= 1591 1592 bool Matcher::supports_vector_calling_convention(void) { 1593 if (EnableVectorSupport && UseVectorStubs) { 1594 return true; 1595 } 1596 return false; 1597 } 1598 1599 OptoRegPair Matcher::vector_return_value(uint ideal_reg) { 1600 assert(EnableVectorSupport && UseVectorStubs, "sanity"); 1601 int lo = XMM0_num; 1602 int hi = XMM0b_num; 1603 if (ideal_reg == Op_VecX) hi = XMM0d_num; 1604 else if (ideal_reg == Op_VecY) hi = XMM0h_num; 1605 else if (ideal_reg == Op_VecZ) hi = XMM0p_num; 1606 return OptoRegPair(hi, lo); 1607 } 1608 1609 // Is this branch offset short enough that a short branch can be used? 1610 // 1611 // NOTE: If the platform does not provide any short branch variants, then 1612 // this method should return false for offset 0. 1613 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 1614 // The passed offset is relative to address of the branch. 1615 // On 86 a branch displacement is calculated relative to address 1616 // of a next instruction. 1617 offset -= br_size; 1618 1619 // the short version of jmpConUCF2 contains multiple branches, 1620 // making the reach slightly less 1621 if (rule == jmpConUCF2_rule) 1622 return (-126 <= offset && offset <= 125); 1623 return (-128 <= offset && offset <= 127); 1624 } 1625 1626 // Return whether or not this register is ever used as an argument. 1627 // This function is used on startup to build the trampoline stubs in 1628 // generateOptoStub. Registers not mentioned will be killed by the VM 1629 // call in the trampoline, and arguments in those registers not be 1630 // available to the callee. 1631 bool Matcher::can_be_java_arg(int reg) 1632 { 1633 return 1634 reg == RDI_num || reg == RDI_H_num || 1635 reg == RSI_num || reg == RSI_H_num || 1636 reg == RDX_num || reg == RDX_H_num || 1637 reg == RCX_num || reg == RCX_H_num || 1638 reg == R8_num || reg == R8_H_num || 1639 reg == R9_num || reg == R9_H_num || 1640 reg == R12_num || reg == R12_H_num || 1641 reg == XMM0_num || reg == XMM0b_num || 1642 reg == XMM1_num || reg == XMM1b_num || 1643 reg == XMM2_num || reg == XMM2b_num || 1644 reg == XMM3_num || reg == XMM3b_num || 1645 reg == XMM4_num || reg == XMM4b_num || 1646 reg == XMM5_num || reg == XMM5b_num || 1647 reg == XMM6_num || reg == XMM6b_num || 1648 reg == XMM7_num || reg == XMM7b_num; 1649 } 1650 1651 bool Matcher::is_spillable_arg(int reg) 1652 { 1653 return can_be_java_arg(reg); 1654 } 1655 1656 uint Matcher::int_pressure_limit() 1657 { 1658 return (INTPRESSURE == -1) ? _INT_REG_mask.Size() : INTPRESSURE; 1659 } 1660 1661 uint Matcher::float_pressure_limit() 1662 { 1663 // After experiment around with different values, the following default threshold 1664 // works best for LCM's register pressure scheduling on x64. 1665 uint dec_count = VM_Version::supports_evex() ? 4 : 2; 1666 uint default_float_pressure_threshold = _FLOAT_REG_mask.Size() - dec_count; 1667 return (FLOATPRESSURE == -1) ? default_float_pressure_threshold : FLOATPRESSURE; 1668 } 1669 1670 bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) { 1671 // In 64 bit mode a code which use multiply when 1672 // devisor is constant is faster than hardware 1673 // DIV instruction (it uses MulHiL). 1674 return false; 1675 } 1676 1677 // Register for DIVI projection of divmodI 1678 RegMask Matcher::divI_proj_mask() { 1679 return INT_RAX_REG_mask(); 1680 } 1681 1682 // Register for MODI projection of divmodI 1683 RegMask Matcher::modI_proj_mask() { 1684 return INT_RDX_REG_mask(); 1685 } 1686 1687 // Register for DIVL projection of divmodL 1688 RegMask Matcher::divL_proj_mask() { 1689 return LONG_RAX_REG_mask(); 1690 } 1691 1692 // Register for MODL projection of divmodL 1693 RegMask Matcher::modL_proj_mask() { 1694 return LONG_RDX_REG_mask(); 1695 } 1696 1697 // Register for saving SP into on method handle invokes. Not used on x86_64. 1698 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 1699 return NO_REG_mask(); 1700 } 1701 1702 %} 1703 1704 //----------ENCODING BLOCK----------------------------------------------------- 1705 // This block specifies the encoding classes used by the compiler to 1706 // output byte streams. Encoding classes are parameterized macros 1707 // used by Machine Instruction Nodes in order to generate the bit 1708 // encoding of the instruction. Operands specify their base encoding 1709 // interface with the interface keyword. There are currently 1710 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & 1711 // COND_INTER. REG_INTER causes an operand to generate a function 1712 // which returns its register number when queried. CONST_INTER causes 1713 // an operand to generate a function which returns the value of the 1714 // constant when queried. MEMORY_INTER causes an operand to generate 1715 // four functions which return the Base Register, the Index Register, 1716 // the Scale Value, and the Offset Value of the operand when queried. 1717 // COND_INTER causes an operand to generate six functions which return 1718 // the encoding code (ie - encoding bits for the instruction) 1719 // associated with each basic boolean condition for a conditional 1720 // instruction. 1721 // 1722 // Instructions specify two basic values for encoding. Again, a 1723 // function is available to check if the constant displacement is an 1724 // oop. They use the ins_encode keyword to specify their encoding 1725 // classes (which must be a sequence of enc_class names, and their 1726 // parameters, specified in the encoding block), and they use the 1727 // opcode keyword to specify, in order, their primary, secondary, and 1728 // tertiary opcode. Only the opcode sections which a particular 1729 // instruction needs for encoding need to be specified. 1730 encode %{ 1731 enc_class cdql_enc(no_rax_rdx_RegI div) 1732 %{ 1733 // Full implementation of Java idiv and irem; checks for 1734 // special case as described in JVM spec., p.243 & p.271. 1735 // 1736 // normal case special case 1737 // 1738 // input : rax: dividend min_int 1739 // reg: divisor -1 1740 // 1741 // output: rax: quotient (= rax idiv reg) min_int 1742 // rdx: remainder (= rax irem reg) 0 1743 // 1744 // Code sequnce: 1745 // 1746 // 0: 3d 00 00 00 80 cmp $0x80000000,%eax 1747 // 5: 75 07/08 jne e <normal> 1748 // 7: 33 d2 xor %edx,%edx 1749 // [div >= 8 -> offset + 1] 1750 // [REX_B] 1751 // 9: 83 f9 ff cmp $0xffffffffffffffff,$div 1752 // c: 74 03/04 je 11 <done> 1753 // 000000000000000e <normal>: 1754 // e: 99 cltd 1755 // [div >= 8 -> offset + 1] 1756 // [REX_B] 1757 // f: f7 f9 idiv $div 1758 // 0000000000000011 <done>: 1759 Label normal; 1760 Label done; 1761 1762 // cmp $0x80000000,%eax 1763 __ cmpl(as_Register(RAX_enc), 0x80000000); 1764 1765 // jne e <normal> 1766 __ jccb(Assembler::notEqual, normal); 1767 1768 // xor %edx,%edx 1769 __ xorl(as_Register(RDX_enc), as_Register(RDX_enc)); 1770 1771 // cmp $0xffffffffffffffff,%ecx 1772 __ cmpl($div$$Register, -1); 1773 1774 // je 11 <done> 1775 __ jccb(Assembler::equal, done); 1776 1777 // <normal> 1778 // cltd 1779 __ bind(normal); 1780 __ cdql(); 1781 1782 // idivl 1783 // <done> 1784 __ idivl($div$$Register); 1785 __ bind(done); 1786 %} 1787 1788 enc_class cdqq_enc(no_rax_rdx_RegL div) 1789 %{ 1790 // Full implementation of Java ldiv and lrem; checks for 1791 // special case as described in JVM spec., p.243 & p.271. 1792 // 1793 // normal case special case 1794 // 1795 // input : rax: dividend min_long 1796 // reg: divisor -1 1797 // 1798 // output: rax: quotient (= rax idiv reg) min_long 1799 // rdx: remainder (= rax irem reg) 0 1800 // 1801 // Code sequnce: 1802 // 1803 // 0: 48 ba 00 00 00 00 00 mov $0x8000000000000000,%rdx 1804 // 7: 00 00 80 1805 // a: 48 39 d0 cmp %rdx,%rax 1806 // d: 75 08 jne 17 <normal> 1807 // f: 33 d2 xor %edx,%edx 1808 // 11: 48 83 f9 ff cmp $0xffffffffffffffff,$div 1809 // 15: 74 05 je 1c <done> 1810 // 0000000000000017 <normal>: 1811 // 17: 48 99 cqto 1812 // 19: 48 f7 f9 idiv $div 1813 // 000000000000001c <done>: 1814 Label normal; 1815 Label done; 1816 1817 // mov $0x8000000000000000,%rdx 1818 __ mov64(as_Register(RDX_enc), 0x8000000000000000); 1819 1820 // cmp %rdx,%rax 1821 __ cmpq(as_Register(RAX_enc), as_Register(RDX_enc)); 1822 1823 // jne 17 <normal> 1824 __ jccb(Assembler::notEqual, normal); 1825 1826 // xor %edx,%edx 1827 __ xorl(as_Register(RDX_enc), as_Register(RDX_enc)); 1828 1829 // cmp $0xffffffffffffffff,$div 1830 __ cmpq($div$$Register, -1); 1831 1832 // je 1e <done> 1833 __ jccb(Assembler::equal, done); 1834 1835 // <normal> 1836 // cqto 1837 __ bind(normal); 1838 __ cdqq(); 1839 1840 // idivq (note: must be emitted by the user of this rule) 1841 // <done> 1842 __ idivq($div$$Register); 1843 __ bind(done); 1844 %} 1845 1846 enc_class enc_PartialSubtypeCheck() 1847 %{ 1848 Register Rrdi = as_Register(RDI_enc); // result register 1849 Register Rrax = as_Register(RAX_enc); // super class 1850 Register Rrcx = as_Register(RCX_enc); // killed 1851 Register Rrsi = as_Register(RSI_enc); // sub class 1852 Label miss; 1853 const bool set_cond_codes = true; 1854 1855 __ check_klass_subtype_slow_path(Rrsi, Rrax, Rrcx, Rrdi, 1856 nullptr, &miss, 1857 /*set_cond_codes:*/ true); 1858 if ($primary) { 1859 __ xorptr(Rrdi, Rrdi); 1860 } 1861 __ bind(miss); 1862 %} 1863 1864 enc_class clear_avx %{ 1865 debug_only(int off0 = __ offset()); 1866 if (generate_vzeroupper(Compile::current())) { 1867 // Clear upper bits of YMM registers to avoid AVX <-> SSE transition penalty 1868 // Clear upper bits of YMM registers when current compiled code uses 1869 // wide vectors to avoid AVX <-> SSE transition penalty during call. 1870 __ vzeroupper(); 1871 } 1872 debug_only(int off1 = __ offset()); 1873 assert(off1 - off0 == clear_avx_size(), "correct size prediction"); 1874 %} 1875 1876 enc_class Java_To_Runtime(method meth) %{ 1877 // No relocation needed 1878 __ mov64(r10, (int64_t) $meth$$method); 1879 __ call(r10); 1880 __ post_call_nop(); 1881 %} 1882 1883 enc_class Java_Static_Call(method meth) 1884 %{ 1885 // JAVA STATIC CALL 1886 // CALL to fixup routine. Fixup routine uses ScopeDesc info to 1887 // determine who we intended to call. 1888 if (!_method) { 1889 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, $meth$$method))); 1890 } else if (_method->intrinsic_id() == vmIntrinsicID::_ensureMaterializedForStackWalk) { 1891 // The NOP here is purely to ensure that eliding a call to 1892 // JVM_EnsureMaterializedForStackWalk doesn't change the code size. 1893 __ addr_nop_5(); 1894 __ block_comment("call JVM_EnsureMaterializedForStackWalk (elided)"); 1895 } else { 1896 int method_index = resolved_method_index(masm); 1897 RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 1898 : static_call_Relocation::spec(method_index); 1899 address mark = __ pc(); 1900 int call_offset = __ offset(); 1901 __ call(AddressLiteral(CAST_FROM_FN_PTR(address, $meth$$method), rspec)); 1902 if (CodeBuffer::supports_shared_stubs() && _method->can_be_statically_bound()) { 1903 // Calls of the same statically bound method can share 1904 // a stub to the interpreter. 1905 __ code()->shared_stub_to_interp_for(_method, call_offset); 1906 } else { 1907 // Emit stubs for static call. 1908 address stub = CompiledDirectCall::emit_to_interp_stub(masm, mark); 1909 __ clear_inst_mark(); 1910 if (stub == nullptr) { 1911 ciEnv::current()->record_failure("CodeCache is full"); 1912 return; 1913 } 1914 } 1915 } 1916 __ post_call_nop(); 1917 %} 1918 1919 enc_class Java_Dynamic_Call(method meth) %{ 1920 __ ic_call((address)$meth$$method, resolved_method_index(masm)); 1921 __ post_call_nop(); 1922 %} 1923 1924 %} 1925 1926 1927 1928 //----------FRAME-------------------------------------------------------------- 1929 // Definition of frame structure and management information. 1930 // 1931 // S T A C K L A Y O U T Allocators stack-slot number 1932 // | (to get allocators register number 1933 // G Owned by | | v add OptoReg::stack0()) 1934 // r CALLER | | 1935 // o | +--------+ pad to even-align allocators stack-slot 1936 // w V | pad0 | numbers; owned by CALLER 1937 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned 1938 // h ^ | in | 5 1939 // | | args | 4 Holes in incoming args owned by SELF 1940 // | | | | 3 1941 // | | +--------+ 1942 // V | | old out| Empty on Intel, window on Sparc 1943 // | old |preserve| Must be even aligned. 1944 // | SP-+--------+----> Matcher::_old_SP, even aligned 1945 // | | in | 3 area for Intel ret address 1946 // Owned by |preserve| Empty on Sparc. 1947 // SELF +--------+ 1948 // | | pad2 | 2 pad to align old SP 1949 // | +--------+ 1 1950 // | | locks | 0 1951 // | +--------+----> OptoReg::stack0(), even aligned 1952 // | | pad1 | 11 pad to align new SP 1953 // | +--------+ 1954 // | | | 10 1955 // | | spills | 9 spills 1956 // V | | 8 (pad0 slot for callee) 1957 // -----------+--------+----> Matcher::_out_arg_limit, unaligned 1958 // ^ | out | 7 1959 // | | args | 6 Holes in outgoing args owned by CALLEE 1960 // Owned by +--------+ 1961 // CALLEE | new out| 6 Empty on Intel, window on Sparc 1962 // | new |preserve| Must be even-aligned. 1963 // | SP-+--------+----> Matcher::_new_SP, even aligned 1964 // | | | 1965 // 1966 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 1967 // known from SELF's arguments and the Java calling convention. 1968 // Region 6-7 is determined per call site. 1969 // Note 2: If the calling convention leaves holes in the incoming argument 1970 // area, those holes are owned by SELF. Holes in the outgoing area 1971 // are owned by the CALLEE. Holes should not be necessary in the 1972 // incoming area, as the Java calling convention is completely under 1973 // the control of the AD file. Doubles can be sorted and packed to 1974 // avoid holes. Holes in the outgoing arguments may be necessary for 1975 // varargs C calling conventions. 1976 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 1977 // even aligned with pad0 as needed. 1978 // Region 6 is even aligned. Region 6-7 is NOT even aligned; 1979 // region 6-11 is even aligned; it may be padded out more so that 1980 // the region from SP to FP meets the minimum stack alignment. 1981 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 1982 // alignment. Region 11, pad1, may be dynamically extended so that 1983 // SP meets the minimum alignment. 1984 1985 frame 1986 %{ 1987 // These three registers define part of the calling convention 1988 // between compiled code and the interpreter. 1989 inline_cache_reg(RAX); // Inline Cache Register 1990 1991 // Optional: name the operand used by cisc-spilling to access 1992 // [stack_pointer + offset] 1993 cisc_spilling_operand_name(indOffset32); 1994 1995 // Number of stack slots consumed by locking an object 1996 sync_stack_slots(2); 1997 1998 // Compiled code's Frame Pointer 1999 frame_pointer(RSP); 2000 2001 // Interpreter stores its frame pointer in a register which is 2002 // stored to the stack by I2CAdaptors. 2003 // I2CAdaptors convert from interpreted java to compiled java. 2004 interpreter_frame_pointer(RBP); 2005 2006 // Stack alignment requirement 2007 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 2008 2009 // Number of outgoing stack slots killed above the out_preserve_stack_slots 2010 // for calls to C. Supports the var-args backing area for register parms. 2011 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 2012 2013 // The after-PROLOG location of the return address. Location of 2014 // return address specifies a type (REG or STACK) and a number 2015 // representing the register number (i.e. - use a register name) or 2016 // stack slot. 2017 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 2018 // Otherwise, it is above the locks and verification slot and alignment word 2019 return_addr(STACK - 2 + 2020 align_up((Compile::current()->in_preserve_stack_slots() + 2021 Compile::current()->fixed_slots()), 2022 stack_alignment_in_slots())); 2023 2024 // Location of compiled Java return values. Same as C for now. 2025 return_value 2026 %{ 2027 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 2028 "only return normal values"); 2029 2030 static const int lo[Op_RegL + 1] = { 2031 0, 2032 0, 2033 RAX_num, // Op_RegN 2034 RAX_num, // Op_RegI 2035 RAX_num, // Op_RegP 2036 XMM0_num, // Op_RegF 2037 XMM0_num, // Op_RegD 2038 RAX_num // Op_RegL 2039 }; 2040 static const int hi[Op_RegL + 1] = { 2041 0, 2042 0, 2043 OptoReg::Bad, // Op_RegN 2044 OptoReg::Bad, // Op_RegI 2045 RAX_H_num, // Op_RegP 2046 OptoReg::Bad, // Op_RegF 2047 XMM0b_num, // Op_RegD 2048 RAX_H_num // Op_RegL 2049 }; 2050 // Excluded flags and vector registers. 2051 assert(ARRAY_SIZE(hi) == _last_machine_leaf - 8, "missing type"); 2052 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 2053 %} 2054 %} 2055 2056 //----------ATTRIBUTES--------------------------------------------------------- 2057 //----------Operand Attributes------------------------------------------------- 2058 op_attrib op_cost(0); // Required cost attribute 2059 2060 //----------Instruction Attributes--------------------------------------------- 2061 ins_attrib ins_cost(100); // Required cost attribute 2062 ins_attrib ins_size(8); // Required size attribute (in bits) 2063 ins_attrib ins_short_branch(0); // Required flag: is this instruction 2064 // a non-matching short branch variant 2065 // of some long branch? 2066 ins_attrib ins_alignment(1); // Required alignment attribute (must 2067 // be a power of 2) specifies the 2068 // alignment that some part of the 2069 // instruction (not necessarily the 2070 // start) requires. If > 1, a 2071 // compute_padding() function must be 2072 // provided for the instruction 2073 2074 //----------OPERANDS----------------------------------------------------------- 2075 // Operand definitions must precede instruction definitions for correct parsing 2076 // in the ADLC because operands constitute user defined types which are used in 2077 // instruction definitions. 2078 2079 //----------Simple Operands---------------------------------------------------- 2080 // Immediate Operands 2081 // Integer Immediate 2082 operand immI() 2083 %{ 2084 match(ConI); 2085 2086 op_cost(10); 2087 format %{ %} 2088 interface(CONST_INTER); 2089 %} 2090 2091 // Constant for test vs zero 2092 operand immI_0() 2093 %{ 2094 predicate(n->get_int() == 0); 2095 match(ConI); 2096 2097 op_cost(0); 2098 format %{ %} 2099 interface(CONST_INTER); 2100 %} 2101 2102 // Constant for increment 2103 operand immI_1() 2104 %{ 2105 predicate(n->get_int() == 1); 2106 match(ConI); 2107 2108 op_cost(0); 2109 format %{ %} 2110 interface(CONST_INTER); 2111 %} 2112 2113 // Constant for decrement 2114 operand immI_M1() 2115 %{ 2116 predicate(n->get_int() == -1); 2117 match(ConI); 2118 2119 op_cost(0); 2120 format %{ %} 2121 interface(CONST_INTER); 2122 %} 2123 2124 operand immI_2() 2125 %{ 2126 predicate(n->get_int() == 2); 2127 match(ConI); 2128 2129 op_cost(0); 2130 format %{ %} 2131 interface(CONST_INTER); 2132 %} 2133 2134 operand immI_4() 2135 %{ 2136 predicate(n->get_int() == 4); 2137 match(ConI); 2138 2139 op_cost(0); 2140 format %{ %} 2141 interface(CONST_INTER); 2142 %} 2143 2144 operand immI_8() 2145 %{ 2146 predicate(n->get_int() == 8); 2147 match(ConI); 2148 2149 op_cost(0); 2150 format %{ %} 2151 interface(CONST_INTER); 2152 %} 2153 2154 // Valid scale values for addressing modes 2155 operand immI2() 2156 %{ 2157 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 2158 match(ConI); 2159 2160 format %{ %} 2161 interface(CONST_INTER); 2162 %} 2163 2164 operand immU7() 2165 %{ 2166 predicate((0 <= n->get_int()) && (n->get_int() <= 0x7F)); 2167 match(ConI); 2168 2169 op_cost(5); 2170 format %{ %} 2171 interface(CONST_INTER); 2172 %} 2173 2174 operand immI8() 2175 %{ 2176 predicate((-0x80 <= n->get_int()) && (n->get_int() < 0x80)); 2177 match(ConI); 2178 2179 op_cost(5); 2180 format %{ %} 2181 interface(CONST_INTER); 2182 %} 2183 2184 operand immU8() 2185 %{ 2186 predicate((0 <= n->get_int()) && (n->get_int() <= 255)); 2187 match(ConI); 2188 2189 op_cost(5); 2190 format %{ %} 2191 interface(CONST_INTER); 2192 %} 2193 2194 operand immI16() 2195 %{ 2196 predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767)); 2197 match(ConI); 2198 2199 op_cost(10); 2200 format %{ %} 2201 interface(CONST_INTER); 2202 %} 2203 2204 // Int Immediate non-negative 2205 operand immU31() 2206 %{ 2207 predicate(n->get_int() >= 0); 2208 match(ConI); 2209 2210 op_cost(0); 2211 format %{ %} 2212 interface(CONST_INTER); 2213 %} 2214 2215 // Pointer Immediate 2216 operand immP() 2217 %{ 2218 match(ConP); 2219 2220 op_cost(10); 2221 format %{ %} 2222 interface(CONST_INTER); 2223 %} 2224 2225 // Null Pointer Immediate 2226 operand immP0() 2227 %{ 2228 predicate(n->get_ptr() == 0); 2229 match(ConP); 2230 2231 op_cost(5); 2232 format %{ %} 2233 interface(CONST_INTER); 2234 %} 2235 2236 // Pointer Immediate 2237 operand immN() %{ 2238 match(ConN); 2239 2240 op_cost(10); 2241 format %{ %} 2242 interface(CONST_INTER); 2243 %} 2244 2245 operand immNKlass() %{ 2246 match(ConNKlass); 2247 2248 op_cost(10); 2249 format %{ %} 2250 interface(CONST_INTER); 2251 %} 2252 2253 // Null Pointer Immediate 2254 operand immN0() %{ 2255 predicate(n->get_narrowcon() == 0); 2256 match(ConN); 2257 2258 op_cost(5); 2259 format %{ %} 2260 interface(CONST_INTER); 2261 %} 2262 2263 operand immP31() 2264 %{ 2265 predicate(n->as_Type()->type()->reloc() == relocInfo::none 2266 && (n->get_ptr() >> 31) == 0); 2267 match(ConP); 2268 2269 op_cost(5); 2270 format %{ %} 2271 interface(CONST_INTER); 2272 %} 2273 2274 2275 // Long Immediate 2276 operand immL() 2277 %{ 2278 match(ConL); 2279 2280 op_cost(20); 2281 format %{ %} 2282 interface(CONST_INTER); 2283 %} 2284 2285 // Long Immediate 8-bit 2286 operand immL8() 2287 %{ 2288 predicate(-0x80L <= n->get_long() && n->get_long() < 0x80L); 2289 match(ConL); 2290 2291 op_cost(5); 2292 format %{ %} 2293 interface(CONST_INTER); 2294 %} 2295 2296 // Long Immediate 32-bit unsigned 2297 operand immUL32() 2298 %{ 2299 predicate(n->get_long() == (unsigned int) (n->get_long())); 2300 match(ConL); 2301 2302 op_cost(10); 2303 format %{ %} 2304 interface(CONST_INTER); 2305 %} 2306 2307 // Long Immediate 32-bit signed 2308 operand immL32() 2309 %{ 2310 predicate(n->get_long() == (int) (n->get_long())); 2311 match(ConL); 2312 2313 op_cost(15); 2314 format %{ %} 2315 interface(CONST_INTER); 2316 %} 2317 2318 operand immL_Pow2() 2319 %{ 2320 predicate(is_power_of_2((julong)n->get_long())); 2321 match(ConL); 2322 2323 op_cost(15); 2324 format %{ %} 2325 interface(CONST_INTER); 2326 %} 2327 2328 operand immL_NotPow2() 2329 %{ 2330 predicate(is_power_of_2((julong)~n->get_long())); 2331 match(ConL); 2332 2333 op_cost(15); 2334 format %{ %} 2335 interface(CONST_INTER); 2336 %} 2337 2338 // Long Immediate zero 2339 operand immL0() 2340 %{ 2341 predicate(n->get_long() == 0L); 2342 match(ConL); 2343 2344 op_cost(10); 2345 format %{ %} 2346 interface(CONST_INTER); 2347 %} 2348 2349 // Constant for increment 2350 operand immL1() 2351 %{ 2352 predicate(n->get_long() == 1); 2353 match(ConL); 2354 2355 format %{ %} 2356 interface(CONST_INTER); 2357 %} 2358 2359 // Constant for decrement 2360 operand immL_M1() 2361 %{ 2362 predicate(n->get_long() == -1); 2363 match(ConL); 2364 2365 format %{ %} 2366 interface(CONST_INTER); 2367 %} 2368 2369 // Long Immediate: low 32-bit mask 2370 operand immL_32bits() 2371 %{ 2372 predicate(n->get_long() == 0xFFFFFFFFL); 2373 match(ConL); 2374 op_cost(20); 2375 2376 format %{ %} 2377 interface(CONST_INTER); 2378 %} 2379 2380 // Int Immediate: 2^n-1, positive 2381 operand immI_Pow2M1() 2382 %{ 2383 predicate((n->get_int() > 0) 2384 && is_power_of_2((juint)n->get_int() + 1)); 2385 match(ConI); 2386 2387 op_cost(20); 2388 format %{ %} 2389 interface(CONST_INTER); 2390 %} 2391 2392 // Float Immediate zero 2393 operand immF0() 2394 %{ 2395 predicate(jint_cast(n->getf()) == 0); 2396 match(ConF); 2397 2398 op_cost(5); 2399 format %{ %} 2400 interface(CONST_INTER); 2401 %} 2402 2403 // Float Immediate 2404 operand immF() 2405 %{ 2406 match(ConF); 2407 2408 op_cost(15); 2409 format %{ %} 2410 interface(CONST_INTER); 2411 %} 2412 2413 // Double Immediate zero 2414 operand immD0() 2415 %{ 2416 predicate(jlong_cast(n->getd()) == 0); 2417 match(ConD); 2418 2419 op_cost(5); 2420 format %{ %} 2421 interface(CONST_INTER); 2422 %} 2423 2424 // Double Immediate 2425 operand immD() 2426 %{ 2427 match(ConD); 2428 2429 op_cost(15); 2430 format %{ %} 2431 interface(CONST_INTER); 2432 %} 2433 2434 // Immediates for special shifts (sign extend) 2435 2436 // Constants for increment 2437 operand immI_16() 2438 %{ 2439 predicate(n->get_int() == 16); 2440 match(ConI); 2441 2442 format %{ %} 2443 interface(CONST_INTER); 2444 %} 2445 2446 operand immI_24() 2447 %{ 2448 predicate(n->get_int() == 24); 2449 match(ConI); 2450 2451 format %{ %} 2452 interface(CONST_INTER); 2453 %} 2454 2455 // Constant for byte-wide masking 2456 operand immI_255() 2457 %{ 2458 predicate(n->get_int() == 255); 2459 match(ConI); 2460 2461 format %{ %} 2462 interface(CONST_INTER); 2463 %} 2464 2465 // Constant for short-wide masking 2466 operand immI_65535() 2467 %{ 2468 predicate(n->get_int() == 65535); 2469 match(ConI); 2470 2471 format %{ %} 2472 interface(CONST_INTER); 2473 %} 2474 2475 // Constant for byte-wide masking 2476 operand immL_255() 2477 %{ 2478 predicate(n->get_long() == 255); 2479 match(ConL); 2480 2481 format %{ %} 2482 interface(CONST_INTER); 2483 %} 2484 2485 // Constant for short-wide masking 2486 operand immL_65535() 2487 %{ 2488 predicate(n->get_long() == 65535); 2489 match(ConL); 2490 2491 format %{ %} 2492 interface(CONST_INTER); 2493 %} 2494 2495 operand kReg() 2496 %{ 2497 constraint(ALLOC_IN_RC(vectmask_reg)); 2498 match(RegVectMask); 2499 format %{%} 2500 interface(REG_INTER); 2501 %} 2502 2503 // Register Operands 2504 // Integer Register 2505 operand rRegI() 2506 %{ 2507 constraint(ALLOC_IN_RC(int_reg)); 2508 match(RegI); 2509 2510 match(rax_RegI); 2511 match(rbx_RegI); 2512 match(rcx_RegI); 2513 match(rdx_RegI); 2514 match(rdi_RegI); 2515 2516 format %{ %} 2517 interface(REG_INTER); 2518 %} 2519 2520 // Special Registers 2521 operand rax_RegI() 2522 %{ 2523 constraint(ALLOC_IN_RC(int_rax_reg)); 2524 match(RegI); 2525 match(rRegI); 2526 2527 format %{ "RAX" %} 2528 interface(REG_INTER); 2529 %} 2530 2531 // Special Registers 2532 operand rbx_RegI() 2533 %{ 2534 constraint(ALLOC_IN_RC(int_rbx_reg)); 2535 match(RegI); 2536 match(rRegI); 2537 2538 format %{ "RBX" %} 2539 interface(REG_INTER); 2540 %} 2541 2542 operand rcx_RegI() 2543 %{ 2544 constraint(ALLOC_IN_RC(int_rcx_reg)); 2545 match(RegI); 2546 match(rRegI); 2547 2548 format %{ "RCX" %} 2549 interface(REG_INTER); 2550 %} 2551 2552 operand rdx_RegI() 2553 %{ 2554 constraint(ALLOC_IN_RC(int_rdx_reg)); 2555 match(RegI); 2556 match(rRegI); 2557 2558 format %{ "RDX" %} 2559 interface(REG_INTER); 2560 %} 2561 2562 operand rdi_RegI() 2563 %{ 2564 constraint(ALLOC_IN_RC(int_rdi_reg)); 2565 match(RegI); 2566 match(rRegI); 2567 2568 format %{ "RDI" %} 2569 interface(REG_INTER); 2570 %} 2571 2572 operand no_rax_rdx_RegI() 2573 %{ 2574 constraint(ALLOC_IN_RC(int_no_rax_rdx_reg)); 2575 match(RegI); 2576 match(rbx_RegI); 2577 match(rcx_RegI); 2578 match(rdi_RegI); 2579 2580 format %{ %} 2581 interface(REG_INTER); 2582 %} 2583 2584 operand no_rbp_r13_RegI() 2585 %{ 2586 constraint(ALLOC_IN_RC(int_no_rbp_r13_reg)); 2587 match(RegI); 2588 match(rRegI); 2589 match(rax_RegI); 2590 match(rbx_RegI); 2591 match(rcx_RegI); 2592 match(rdx_RegI); 2593 match(rdi_RegI); 2594 2595 format %{ %} 2596 interface(REG_INTER); 2597 %} 2598 2599 // Pointer Register 2600 operand any_RegP() 2601 %{ 2602 constraint(ALLOC_IN_RC(any_reg)); 2603 match(RegP); 2604 match(rax_RegP); 2605 match(rbx_RegP); 2606 match(rdi_RegP); 2607 match(rsi_RegP); 2608 match(rbp_RegP); 2609 match(r15_RegP); 2610 match(rRegP); 2611 2612 format %{ %} 2613 interface(REG_INTER); 2614 %} 2615 2616 operand rRegP() 2617 %{ 2618 constraint(ALLOC_IN_RC(ptr_reg)); 2619 match(RegP); 2620 match(rax_RegP); 2621 match(rbx_RegP); 2622 match(rdi_RegP); 2623 match(rsi_RegP); 2624 match(rbp_RegP); // See Q&A below about 2625 match(r15_RegP); // r15_RegP and rbp_RegP. 2626 2627 format %{ %} 2628 interface(REG_INTER); 2629 %} 2630 2631 operand rRegN() %{ 2632 constraint(ALLOC_IN_RC(int_reg)); 2633 match(RegN); 2634 2635 format %{ %} 2636 interface(REG_INTER); 2637 %} 2638 2639 // Question: Why is r15_RegP (the read-only TLS register) a match for rRegP? 2640 // Answer: Operand match rules govern the DFA as it processes instruction inputs. 2641 // It's fine for an instruction input that expects rRegP to match a r15_RegP. 2642 // The output of an instruction is controlled by the allocator, which respects 2643 // register class masks, not match rules. Unless an instruction mentions 2644 // r15_RegP or any_RegP explicitly as its output, r15 will not be considered 2645 // by the allocator as an input. 2646 // The same logic applies to rbp_RegP being a match for rRegP: If PreserveFramePointer==true, 2647 // the RBP is used as a proper frame pointer and is not included in ptr_reg. As a 2648 // result, RBP is not included in the output of the instruction either. 2649 2650 // This operand is not allowed to use RBP even if 2651 // RBP is not used to hold the frame pointer. 2652 operand no_rbp_RegP() 2653 %{ 2654 constraint(ALLOC_IN_RC(ptr_reg_no_rbp)); 2655 match(RegP); 2656 match(rbx_RegP); 2657 match(rsi_RegP); 2658 match(rdi_RegP); 2659 2660 format %{ %} 2661 interface(REG_INTER); 2662 %} 2663 2664 // Special Registers 2665 // Return a pointer value 2666 operand rax_RegP() 2667 %{ 2668 constraint(ALLOC_IN_RC(ptr_rax_reg)); 2669 match(RegP); 2670 match(rRegP); 2671 2672 format %{ %} 2673 interface(REG_INTER); 2674 %} 2675 2676 // Special Registers 2677 // Return a compressed pointer value 2678 operand rax_RegN() 2679 %{ 2680 constraint(ALLOC_IN_RC(int_rax_reg)); 2681 match(RegN); 2682 match(rRegN); 2683 2684 format %{ %} 2685 interface(REG_INTER); 2686 %} 2687 2688 // Used in AtomicAdd 2689 operand rbx_RegP() 2690 %{ 2691 constraint(ALLOC_IN_RC(ptr_rbx_reg)); 2692 match(RegP); 2693 match(rRegP); 2694 2695 format %{ %} 2696 interface(REG_INTER); 2697 %} 2698 2699 operand rsi_RegP() 2700 %{ 2701 constraint(ALLOC_IN_RC(ptr_rsi_reg)); 2702 match(RegP); 2703 match(rRegP); 2704 2705 format %{ %} 2706 interface(REG_INTER); 2707 %} 2708 2709 operand rbp_RegP() 2710 %{ 2711 constraint(ALLOC_IN_RC(ptr_rbp_reg)); 2712 match(RegP); 2713 match(rRegP); 2714 2715 format %{ %} 2716 interface(REG_INTER); 2717 %} 2718 2719 // Used in rep stosq 2720 operand rdi_RegP() 2721 %{ 2722 constraint(ALLOC_IN_RC(ptr_rdi_reg)); 2723 match(RegP); 2724 match(rRegP); 2725 2726 format %{ %} 2727 interface(REG_INTER); 2728 %} 2729 2730 operand r15_RegP() 2731 %{ 2732 constraint(ALLOC_IN_RC(ptr_r15_reg)); 2733 match(RegP); 2734 match(rRegP); 2735 2736 format %{ %} 2737 interface(REG_INTER); 2738 %} 2739 2740 operand rRegL() 2741 %{ 2742 constraint(ALLOC_IN_RC(long_reg)); 2743 match(RegL); 2744 match(rax_RegL); 2745 match(rdx_RegL); 2746 2747 format %{ %} 2748 interface(REG_INTER); 2749 %} 2750 2751 // Special Registers 2752 operand no_rax_rdx_RegL() 2753 %{ 2754 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 2755 match(RegL); 2756 match(rRegL); 2757 2758 format %{ %} 2759 interface(REG_INTER); 2760 %} 2761 2762 operand rax_RegL() 2763 %{ 2764 constraint(ALLOC_IN_RC(long_rax_reg)); 2765 match(RegL); 2766 match(rRegL); 2767 2768 format %{ "RAX" %} 2769 interface(REG_INTER); 2770 %} 2771 2772 operand rcx_RegL() 2773 %{ 2774 constraint(ALLOC_IN_RC(long_rcx_reg)); 2775 match(RegL); 2776 match(rRegL); 2777 2778 format %{ %} 2779 interface(REG_INTER); 2780 %} 2781 2782 operand rdx_RegL() 2783 %{ 2784 constraint(ALLOC_IN_RC(long_rdx_reg)); 2785 match(RegL); 2786 match(rRegL); 2787 2788 format %{ %} 2789 interface(REG_INTER); 2790 %} 2791 2792 operand r11_RegL() 2793 %{ 2794 constraint(ALLOC_IN_RC(long_r11_reg)); 2795 match(RegL); 2796 match(rRegL); 2797 2798 format %{ %} 2799 interface(REG_INTER); 2800 %} 2801 2802 operand no_rbp_r13_RegL() 2803 %{ 2804 constraint(ALLOC_IN_RC(long_no_rbp_r13_reg)); 2805 match(RegL); 2806 match(rRegL); 2807 match(rax_RegL); 2808 match(rcx_RegL); 2809 match(rdx_RegL); 2810 2811 format %{ %} 2812 interface(REG_INTER); 2813 %} 2814 2815 // Flags register, used as output of compare instructions 2816 operand rFlagsReg() 2817 %{ 2818 constraint(ALLOC_IN_RC(int_flags)); 2819 match(RegFlags); 2820 2821 format %{ "RFLAGS" %} 2822 interface(REG_INTER); 2823 %} 2824 2825 // Flags register, used as output of FLOATING POINT compare instructions 2826 operand rFlagsRegU() 2827 %{ 2828 constraint(ALLOC_IN_RC(int_flags)); 2829 match(RegFlags); 2830 2831 format %{ "RFLAGS_U" %} 2832 interface(REG_INTER); 2833 %} 2834 2835 operand rFlagsRegUCF() %{ 2836 constraint(ALLOC_IN_RC(int_flags)); 2837 match(RegFlags); 2838 predicate(false); 2839 2840 format %{ "RFLAGS_U_CF" %} 2841 interface(REG_INTER); 2842 %} 2843 2844 // Float register operands 2845 operand regF() %{ 2846 constraint(ALLOC_IN_RC(float_reg)); 2847 match(RegF); 2848 2849 format %{ %} 2850 interface(REG_INTER); 2851 %} 2852 2853 // Float register operands 2854 operand legRegF() %{ 2855 constraint(ALLOC_IN_RC(float_reg_legacy)); 2856 match(RegF); 2857 2858 format %{ %} 2859 interface(REG_INTER); 2860 %} 2861 2862 // Float register operands 2863 operand vlRegF() %{ 2864 constraint(ALLOC_IN_RC(float_reg_vl)); 2865 match(RegF); 2866 2867 format %{ %} 2868 interface(REG_INTER); 2869 %} 2870 2871 // Double register operands 2872 operand regD() %{ 2873 constraint(ALLOC_IN_RC(double_reg)); 2874 match(RegD); 2875 2876 format %{ %} 2877 interface(REG_INTER); 2878 %} 2879 2880 // Double register operands 2881 operand legRegD() %{ 2882 constraint(ALLOC_IN_RC(double_reg_legacy)); 2883 match(RegD); 2884 2885 format %{ %} 2886 interface(REG_INTER); 2887 %} 2888 2889 // Double register operands 2890 operand vlRegD() %{ 2891 constraint(ALLOC_IN_RC(double_reg_vl)); 2892 match(RegD); 2893 2894 format %{ %} 2895 interface(REG_INTER); 2896 %} 2897 2898 //----------Memory Operands---------------------------------------------------- 2899 // Direct Memory Operand 2900 // operand direct(immP addr) 2901 // %{ 2902 // match(addr); 2903 2904 // format %{ "[$addr]" %} 2905 // interface(MEMORY_INTER) %{ 2906 // base(0xFFFFFFFF); 2907 // index(0x4); 2908 // scale(0x0); 2909 // disp($addr); 2910 // %} 2911 // %} 2912 2913 // Indirect Memory Operand 2914 operand indirect(any_RegP reg) 2915 %{ 2916 constraint(ALLOC_IN_RC(ptr_reg)); 2917 match(reg); 2918 2919 format %{ "[$reg]" %} 2920 interface(MEMORY_INTER) %{ 2921 base($reg); 2922 index(0x4); 2923 scale(0x0); 2924 disp(0x0); 2925 %} 2926 %} 2927 2928 // Indirect Memory Plus Short Offset Operand 2929 operand indOffset8(any_RegP reg, immL8 off) 2930 %{ 2931 constraint(ALLOC_IN_RC(ptr_reg)); 2932 match(AddP reg off); 2933 2934 format %{ "[$reg + $off (8-bit)]" %} 2935 interface(MEMORY_INTER) %{ 2936 base($reg); 2937 index(0x4); 2938 scale(0x0); 2939 disp($off); 2940 %} 2941 %} 2942 2943 // Indirect Memory Plus Long Offset Operand 2944 operand indOffset32(any_RegP reg, immL32 off) 2945 %{ 2946 constraint(ALLOC_IN_RC(ptr_reg)); 2947 match(AddP reg off); 2948 2949 format %{ "[$reg + $off (32-bit)]" %} 2950 interface(MEMORY_INTER) %{ 2951 base($reg); 2952 index(0x4); 2953 scale(0x0); 2954 disp($off); 2955 %} 2956 %} 2957 2958 // Indirect Memory Plus Index Register Plus Offset Operand 2959 operand indIndexOffset(any_RegP reg, rRegL lreg, immL32 off) 2960 %{ 2961 constraint(ALLOC_IN_RC(ptr_reg)); 2962 match(AddP (AddP reg lreg) off); 2963 2964 op_cost(10); 2965 format %{"[$reg + $off + $lreg]" %} 2966 interface(MEMORY_INTER) %{ 2967 base($reg); 2968 index($lreg); 2969 scale(0x0); 2970 disp($off); 2971 %} 2972 %} 2973 2974 // Indirect Memory Plus Index Register Plus Offset Operand 2975 operand indIndex(any_RegP reg, rRegL lreg) 2976 %{ 2977 constraint(ALLOC_IN_RC(ptr_reg)); 2978 match(AddP reg lreg); 2979 2980 op_cost(10); 2981 format %{"[$reg + $lreg]" %} 2982 interface(MEMORY_INTER) %{ 2983 base($reg); 2984 index($lreg); 2985 scale(0x0); 2986 disp(0x0); 2987 %} 2988 %} 2989 2990 // Indirect Memory Times Scale Plus Index Register 2991 operand indIndexScale(any_RegP reg, rRegL lreg, immI2 scale) 2992 %{ 2993 constraint(ALLOC_IN_RC(ptr_reg)); 2994 match(AddP reg (LShiftL lreg scale)); 2995 2996 op_cost(10); 2997 format %{"[$reg + $lreg << $scale]" %} 2998 interface(MEMORY_INTER) %{ 2999 base($reg); 3000 index($lreg); 3001 scale($scale); 3002 disp(0x0); 3003 %} 3004 %} 3005 3006 operand indPosIndexScale(any_RegP reg, rRegI idx, immI2 scale) 3007 %{ 3008 constraint(ALLOC_IN_RC(ptr_reg)); 3009 predicate(n->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3010 match(AddP reg (LShiftL (ConvI2L idx) scale)); 3011 3012 op_cost(10); 3013 format %{"[$reg + pos $idx << $scale]" %} 3014 interface(MEMORY_INTER) %{ 3015 base($reg); 3016 index($idx); 3017 scale($scale); 3018 disp(0x0); 3019 %} 3020 %} 3021 3022 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 3023 operand indIndexScaleOffset(any_RegP reg, immL32 off, rRegL lreg, immI2 scale) 3024 %{ 3025 constraint(ALLOC_IN_RC(ptr_reg)); 3026 match(AddP (AddP reg (LShiftL lreg scale)) off); 3027 3028 op_cost(10); 3029 format %{"[$reg + $off + $lreg << $scale]" %} 3030 interface(MEMORY_INTER) %{ 3031 base($reg); 3032 index($lreg); 3033 scale($scale); 3034 disp($off); 3035 %} 3036 %} 3037 3038 // Indirect Memory Plus Positive Index Register Plus Offset Operand 3039 operand indPosIndexOffset(any_RegP reg, immL32 off, rRegI idx) 3040 %{ 3041 constraint(ALLOC_IN_RC(ptr_reg)); 3042 predicate(n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 3043 match(AddP (AddP reg (ConvI2L idx)) off); 3044 3045 op_cost(10); 3046 format %{"[$reg + $off + $idx]" %} 3047 interface(MEMORY_INTER) %{ 3048 base($reg); 3049 index($idx); 3050 scale(0x0); 3051 disp($off); 3052 %} 3053 %} 3054 3055 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 3056 operand indPosIndexScaleOffset(any_RegP reg, immL32 off, rRegI idx, immI2 scale) 3057 %{ 3058 constraint(ALLOC_IN_RC(ptr_reg)); 3059 predicate(n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3060 match(AddP (AddP reg (LShiftL (ConvI2L idx) scale)) off); 3061 3062 op_cost(10); 3063 format %{"[$reg + $off + $idx << $scale]" %} 3064 interface(MEMORY_INTER) %{ 3065 base($reg); 3066 index($idx); 3067 scale($scale); 3068 disp($off); 3069 %} 3070 %} 3071 3072 // Indirect Narrow Oop Operand 3073 operand indCompressedOop(rRegN reg) %{ 3074 predicate(UseCompressedOops && (CompressedOops::shift() == Address::times_8)); 3075 constraint(ALLOC_IN_RC(ptr_reg)); 3076 match(DecodeN reg); 3077 3078 op_cost(10); 3079 format %{"[R12 + $reg << 3] (compressed oop addressing)" %} 3080 interface(MEMORY_INTER) %{ 3081 base(0xc); // R12 3082 index($reg); 3083 scale(0x3); 3084 disp(0x0); 3085 %} 3086 %} 3087 3088 // Indirect Narrow Oop Plus Offset Operand 3089 // Note: x86 architecture doesn't support "scale * index + offset" without a base 3090 // we can't free r12 even with CompressedOops::base() == nullptr. 3091 operand indCompressedOopOffset(rRegN reg, immL32 off) %{ 3092 predicate(UseCompressedOops && (CompressedOops::shift() == Address::times_8)); 3093 constraint(ALLOC_IN_RC(ptr_reg)); 3094 match(AddP (DecodeN reg) off); 3095 3096 op_cost(10); 3097 format %{"[R12 + $reg << 3 + $off] (compressed oop addressing)" %} 3098 interface(MEMORY_INTER) %{ 3099 base(0xc); // R12 3100 index($reg); 3101 scale(0x3); 3102 disp($off); 3103 %} 3104 %} 3105 3106 // Indirect Memory Operand 3107 operand indirectNarrow(rRegN reg) 3108 %{ 3109 predicate(CompressedOops::shift() == 0); 3110 constraint(ALLOC_IN_RC(ptr_reg)); 3111 match(DecodeN reg); 3112 3113 format %{ "[$reg]" %} 3114 interface(MEMORY_INTER) %{ 3115 base($reg); 3116 index(0x4); 3117 scale(0x0); 3118 disp(0x0); 3119 %} 3120 %} 3121 3122 // Indirect Memory Plus Short Offset Operand 3123 operand indOffset8Narrow(rRegN reg, immL8 off) 3124 %{ 3125 predicate(CompressedOops::shift() == 0); 3126 constraint(ALLOC_IN_RC(ptr_reg)); 3127 match(AddP (DecodeN reg) off); 3128 3129 format %{ "[$reg + $off (8-bit)]" %} 3130 interface(MEMORY_INTER) %{ 3131 base($reg); 3132 index(0x4); 3133 scale(0x0); 3134 disp($off); 3135 %} 3136 %} 3137 3138 // Indirect Memory Plus Long Offset Operand 3139 operand indOffset32Narrow(rRegN reg, immL32 off) 3140 %{ 3141 predicate(CompressedOops::shift() == 0); 3142 constraint(ALLOC_IN_RC(ptr_reg)); 3143 match(AddP (DecodeN reg) off); 3144 3145 format %{ "[$reg + $off (32-bit)]" %} 3146 interface(MEMORY_INTER) %{ 3147 base($reg); 3148 index(0x4); 3149 scale(0x0); 3150 disp($off); 3151 %} 3152 %} 3153 3154 // Indirect Memory Plus Index Register Plus Offset Operand 3155 operand indIndexOffsetNarrow(rRegN reg, rRegL lreg, immL32 off) 3156 %{ 3157 predicate(CompressedOops::shift() == 0); 3158 constraint(ALLOC_IN_RC(ptr_reg)); 3159 match(AddP (AddP (DecodeN reg) lreg) off); 3160 3161 op_cost(10); 3162 format %{"[$reg + $off + $lreg]" %} 3163 interface(MEMORY_INTER) %{ 3164 base($reg); 3165 index($lreg); 3166 scale(0x0); 3167 disp($off); 3168 %} 3169 %} 3170 3171 // Indirect Memory Plus Index Register Plus Offset Operand 3172 operand indIndexNarrow(rRegN reg, rRegL lreg) 3173 %{ 3174 predicate(CompressedOops::shift() == 0); 3175 constraint(ALLOC_IN_RC(ptr_reg)); 3176 match(AddP (DecodeN reg) lreg); 3177 3178 op_cost(10); 3179 format %{"[$reg + $lreg]" %} 3180 interface(MEMORY_INTER) %{ 3181 base($reg); 3182 index($lreg); 3183 scale(0x0); 3184 disp(0x0); 3185 %} 3186 %} 3187 3188 // Indirect Memory Times Scale Plus Index Register 3189 operand indIndexScaleNarrow(rRegN reg, rRegL lreg, immI2 scale) 3190 %{ 3191 predicate(CompressedOops::shift() == 0); 3192 constraint(ALLOC_IN_RC(ptr_reg)); 3193 match(AddP (DecodeN reg) (LShiftL lreg scale)); 3194 3195 op_cost(10); 3196 format %{"[$reg + $lreg << $scale]" %} 3197 interface(MEMORY_INTER) %{ 3198 base($reg); 3199 index($lreg); 3200 scale($scale); 3201 disp(0x0); 3202 %} 3203 %} 3204 3205 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 3206 operand indIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegL lreg, immI2 scale) 3207 %{ 3208 predicate(CompressedOops::shift() == 0); 3209 constraint(ALLOC_IN_RC(ptr_reg)); 3210 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off); 3211 3212 op_cost(10); 3213 format %{"[$reg + $off + $lreg << $scale]" %} 3214 interface(MEMORY_INTER) %{ 3215 base($reg); 3216 index($lreg); 3217 scale($scale); 3218 disp($off); 3219 %} 3220 %} 3221 3222 // Indirect Memory Times Plus Positive Index Register Plus Offset Operand 3223 operand indPosIndexOffsetNarrow(rRegN reg, immL32 off, rRegI idx) 3224 %{ 3225 constraint(ALLOC_IN_RC(ptr_reg)); 3226 predicate(CompressedOops::shift() == 0 && n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 3227 match(AddP (AddP (DecodeN reg) (ConvI2L idx)) off); 3228 3229 op_cost(10); 3230 format %{"[$reg + $off + $idx]" %} 3231 interface(MEMORY_INTER) %{ 3232 base($reg); 3233 index($idx); 3234 scale(0x0); 3235 disp($off); 3236 %} 3237 %} 3238 3239 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 3240 operand indPosIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegI idx, immI2 scale) 3241 %{ 3242 constraint(ALLOC_IN_RC(ptr_reg)); 3243 predicate(CompressedOops::shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3244 match(AddP (AddP (DecodeN reg) (LShiftL (ConvI2L idx) scale)) off); 3245 3246 op_cost(10); 3247 format %{"[$reg + $off + $idx << $scale]" %} 3248 interface(MEMORY_INTER) %{ 3249 base($reg); 3250 index($idx); 3251 scale($scale); 3252 disp($off); 3253 %} 3254 %} 3255 3256 //----------Special Memory Operands-------------------------------------------- 3257 // Stack Slot Operand - This operand is used for loading and storing temporary 3258 // values on the stack where a match requires a value to 3259 // flow through memory. 3260 operand stackSlotP(sRegP reg) 3261 %{ 3262 constraint(ALLOC_IN_RC(stack_slots)); 3263 // No match rule because this operand is only generated in matching 3264 3265 format %{ "[$reg]" %} 3266 interface(MEMORY_INTER) %{ 3267 base(0x4); // RSP 3268 index(0x4); // No Index 3269 scale(0x0); // No Scale 3270 disp($reg); // Stack Offset 3271 %} 3272 %} 3273 3274 operand stackSlotI(sRegI reg) 3275 %{ 3276 constraint(ALLOC_IN_RC(stack_slots)); 3277 // No match rule because this operand is only generated in matching 3278 3279 format %{ "[$reg]" %} 3280 interface(MEMORY_INTER) %{ 3281 base(0x4); // RSP 3282 index(0x4); // No Index 3283 scale(0x0); // No Scale 3284 disp($reg); // Stack Offset 3285 %} 3286 %} 3287 3288 operand stackSlotF(sRegF reg) 3289 %{ 3290 constraint(ALLOC_IN_RC(stack_slots)); 3291 // No match rule because this operand is only generated in matching 3292 3293 format %{ "[$reg]" %} 3294 interface(MEMORY_INTER) %{ 3295 base(0x4); // RSP 3296 index(0x4); // No Index 3297 scale(0x0); // No Scale 3298 disp($reg); // Stack Offset 3299 %} 3300 %} 3301 3302 operand stackSlotD(sRegD reg) 3303 %{ 3304 constraint(ALLOC_IN_RC(stack_slots)); 3305 // No match rule because this operand is only generated in matching 3306 3307 format %{ "[$reg]" %} 3308 interface(MEMORY_INTER) %{ 3309 base(0x4); // RSP 3310 index(0x4); // No Index 3311 scale(0x0); // No Scale 3312 disp($reg); // Stack Offset 3313 %} 3314 %} 3315 operand stackSlotL(sRegL reg) 3316 %{ 3317 constraint(ALLOC_IN_RC(stack_slots)); 3318 // No match rule because this operand is only generated in matching 3319 3320 format %{ "[$reg]" %} 3321 interface(MEMORY_INTER) %{ 3322 base(0x4); // RSP 3323 index(0x4); // No Index 3324 scale(0x0); // No Scale 3325 disp($reg); // Stack Offset 3326 %} 3327 %} 3328 3329 //----------Conditional Branch Operands---------------------------------------- 3330 // Comparison Op - This is the operation of the comparison, and is limited to 3331 // the following set of codes: 3332 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 3333 // 3334 // Other attributes of the comparison, such as unsignedness, are specified 3335 // by the comparison instruction that sets a condition code flags register. 3336 // That result is represented by a flags operand whose subtype is appropriate 3337 // to the unsignedness (etc.) of the comparison. 3338 // 3339 // Later, the instruction which matches both the Comparison Op (a Bool) and 3340 // the flags (produced by the Cmp) specifies the coding of the comparison op 3341 // by matching a specific subtype of Bool operand below, such as cmpOpU. 3342 3343 // Comparison Code 3344 operand cmpOp() 3345 %{ 3346 match(Bool); 3347 3348 format %{ "" %} 3349 interface(COND_INTER) %{ 3350 equal(0x4, "e"); 3351 not_equal(0x5, "ne"); 3352 less(0xC, "l"); 3353 greater_equal(0xD, "ge"); 3354 less_equal(0xE, "le"); 3355 greater(0xF, "g"); 3356 overflow(0x0, "o"); 3357 no_overflow(0x1, "no"); 3358 %} 3359 %} 3360 3361 // Comparison Code, unsigned compare. Used by FP also, with 3362 // C2 (unordered) turned into GT or LT already. The other bits 3363 // C0 and C3 are turned into Carry & Zero flags. 3364 operand cmpOpU() 3365 %{ 3366 match(Bool); 3367 3368 format %{ "" %} 3369 interface(COND_INTER) %{ 3370 equal(0x4, "e"); 3371 not_equal(0x5, "ne"); 3372 less(0x2, "b"); 3373 greater_equal(0x3, "ae"); 3374 less_equal(0x6, "be"); 3375 greater(0x7, "a"); 3376 overflow(0x0, "o"); 3377 no_overflow(0x1, "no"); 3378 %} 3379 %} 3380 3381 3382 // Floating comparisons that don't require any fixup for the unordered case, 3383 // If both inputs of the comparison are the same, ZF is always set so we 3384 // don't need to use cmpOpUCF2 for eq/ne 3385 operand cmpOpUCF() %{ 3386 match(Bool); 3387 predicate(n->as_Bool()->_test._test == BoolTest::lt || 3388 n->as_Bool()->_test._test == BoolTest::ge || 3389 n->as_Bool()->_test._test == BoolTest::le || 3390 n->as_Bool()->_test._test == BoolTest::gt || 3391 n->in(1)->in(1) == n->in(1)->in(2)); 3392 format %{ "" %} 3393 interface(COND_INTER) %{ 3394 equal(0xb, "np"); 3395 not_equal(0xa, "p"); 3396 less(0x2, "b"); 3397 greater_equal(0x3, "ae"); 3398 less_equal(0x6, "be"); 3399 greater(0x7, "a"); 3400 overflow(0x0, "o"); 3401 no_overflow(0x1, "no"); 3402 %} 3403 %} 3404 3405 3406 // Floating comparisons that can be fixed up with extra conditional jumps 3407 operand cmpOpUCF2() %{ 3408 match(Bool); 3409 predicate((n->as_Bool()->_test._test == BoolTest::ne || 3410 n->as_Bool()->_test._test == BoolTest::eq) && 3411 n->in(1)->in(1) != n->in(1)->in(2)); 3412 format %{ "" %} 3413 interface(COND_INTER) %{ 3414 equal(0x4, "e"); 3415 not_equal(0x5, "ne"); 3416 less(0x2, "b"); 3417 greater_equal(0x3, "ae"); 3418 less_equal(0x6, "be"); 3419 greater(0x7, "a"); 3420 overflow(0x0, "o"); 3421 no_overflow(0x1, "no"); 3422 %} 3423 %} 3424 3425 //----------OPERAND CLASSES---------------------------------------------------- 3426 // Operand Classes are groups of operands that are used as to simplify 3427 // instruction definitions by not requiring the AD writer to specify separate 3428 // instructions for every form of operand when the instruction accepts 3429 // multiple operand types with the same basic encoding and format. The classic 3430 // case of this is memory operands. 3431 3432 opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex, 3433 indIndexScale, indPosIndexScale, indIndexScaleOffset, indPosIndexOffset, indPosIndexScaleOffset, 3434 indCompressedOop, indCompressedOopOffset, 3435 indirectNarrow, indOffset8Narrow, indOffset32Narrow, 3436 indIndexOffsetNarrow, indIndexNarrow, indIndexScaleNarrow, 3437 indIndexScaleOffsetNarrow, indPosIndexOffsetNarrow, indPosIndexScaleOffsetNarrow); 3438 3439 //----------PIPELINE----------------------------------------------------------- 3440 // Rules which define the behavior of the target architectures pipeline. 3441 pipeline %{ 3442 3443 //----------ATTRIBUTES--------------------------------------------------------- 3444 attributes %{ 3445 variable_size_instructions; // Fixed size instructions 3446 max_instructions_per_bundle = 3; // Up to 3 instructions per bundle 3447 instruction_unit_size = 1; // An instruction is 1 bytes long 3448 instruction_fetch_unit_size = 16; // The processor fetches one line 3449 instruction_fetch_units = 1; // of 16 bytes 3450 3451 // List of nop instructions 3452 nops( MachNop ); 3453 %} 3454 3455 //----------RESOURCES---------------------------------------------------------- 3456 // Resources are the functional units available to the machine 3457 3458 // Generic P2/P3 pipeline 3459 // 3 decoders, only D0 handles big operands; a "bundle" is the limit of 3460 // 3 instructions decoded per cycle. 3461 // 2 load/store ops per cycle, 1 branch, 1 FPU, 3462 // 3 ALU op, only ALU0 handles mul instructions. 3463 resources( D0, D1, D2, DECODE = D0 | D1 | D2, 3464 MS0, MS1, MS2, MEM = MS0 | MS1 | MS2, 3465 BR, FPU, 3466 ALU0, ALU1, ALU2, ALU = ALU0 | ALU1 | ALU2); 3467 3468 //----------PIPELINE DESCRIPTION----------------------------------------------- 3469 // Pipeline Description specifies the stages in the machine's pipeline 3470 3471 // Generic P2/P3 pipeline 3472 pipe_desc(S0, S1, S2, S3, S4, S5); 3473 3474 //----------PIPELINE CLASSES--------------------------------------------------- 3475 // Pipeline Classes describe the stages in which input and output are 3476 // referenced by the hardware pipeline. 3477 3478 // Naming convention: ialu or fpu 3479 // Then: _reg 3480 // Then: _reg if there is a 2nd register 3481 // Then: _long if it's a pair of instructions implementing a long 3482 // Then: _fat if it requires the big decoder 3483 // Or: _mem if it requires the big decoder and a memory unit. 3484 3485 // Integer ALU reg operation 3486 pipe_class ialu_reg(rRegI dst) 3487 %{ 3488 single_instruction; 3489 dst : S4(write); 3490 dst : S3(read); 3491 DECODE : S0; // any decoder 3492 ALU : S3; // any alu 3493 %} 3494 3495 // Long ALU reg operation 3496 pipe_class ialu_reg_long(rRegL dst) 3497 %{ 3498 instruction_count(2); 3499 dst : S4(write); 3500 dst : S3(read); 3501 DECODE : S0(2); // any 2 decoders 3502 ALU : S3(2); // both alus 3503 %} 3504 3505 // Integer ALU reg operation using big decoder 3506 pipe_class ialu_reg_fat(rRegI dst) 3507 %{ 3508 single_instruction; 3509 dst : S4(write); 3510 dst : S3(read); 3511 D0 : S0; // big decoder only 3512 ALU : S3; // any alu 3513 %} 3514 3515 // Integer ALU reg-reg operation 3516 pipe_class ialu_reg_reg(rRegI dst, rRegI src) 3517 %{ 3518 single_instruction; 3519 dst : S4(write); 3520 src : S3(read); 3521 DECODE : S0; // any decoder 3522 ALU : S3; // any alu 3523 %} 3524 3525 // Integer ALU reg-reg operation 3526 pipe_class ialu_reg_reg_fat(rRegI dst, memory src) 3527 %{ 3528 single_instruction; 3529 dst : S4(write); 3530 src : S3(read); 3531 D0 : S0; // big decoder only 3532 ALU : S3; // any alu 3533 %} 3534 3535 // Integer ALU reg-mem operation 3536 pipe_class ialu_reg_mem(rRegI dst, memory mem) 3537 %{ 3538 single_instruction; 3539 dst : S5(write); 3540 mem : S3(read); 3541 D0 : S0; // big decoder only 3542 ALU : S4; // any alu 3543 MEM : S3; // any mem 3544 %} 3545 3546 // Integer mem operation (prefetch) 3547 pipe_class ialu_mem(memory mem) 3548 %{ 3549 single_instruction; 3550 mem : S3(read); 3551 D0 : S0; // big decoder only 3552 MEM : S3; // any mem 3553 %} 3554 3555 // Integer Store to Memory 3556 pipe_class ialu_mem_reg(memory mem, rRegI src) 3557 %{ 3558 single_instruction; 3559 mem : S3(read); 3560 src : S5(read); 3561 D0 : S0; // big decoder only 3562 ALU : S4; // any alu 3563 MEM : S3; 3564 %} 3565 3566 // // Long Store to Memory 3567 // pipe_class ialu_mem_long_reg(memory mem, rRegL src) 3568 // %{ 3569 // instruction_count(2); 3570 // mem : S3(read); 3571 // src : S5(read); 3572 // D0 : S0(2); // big decoder only; twice 3573 // ALU : S4(2); // any 2 alus 3574 // MEM : S3(2); // Both mems 3575 // %} 3576 3577 // Integer Store to Memory 3578 pipe_class ialu_mem_imm(memory mem) 3579 %{ 3580 single_instruction; 3581 mem : S3(read); 3582 D0 : S0; // big decoder only 3583 ALU : S4; // any alu 3584 MEM : S3; 3585 %} 3586 3587 // Integer ALU0 reg-reg operation 3588 pipe_class ialu_reg_reg_alu0(rRegI dst, rRegI src) 3589 %{ 3590 single_instruction; 3591 dst : S4(write); 3592 src : S3(read); 3593 D0 : S0; // Big decoder only 3594 ALU0 : S3; // only alu0 3595 %} 3596 3597 // Integer ALU0 reg-mem operation 3598 pipe_class ialu_reg_mem_alu0(rRegI dst, memory mem) 3599 %{ 3600 single_instruction; 3601 dst : S5(write); 3602 mem : S3(read); 3603 D0 : S0; // big decoder only 3604 ALU0 : S4; // ALU0 only 3605 MEM : S3; // any mem 3606 %} 3607 3608 // Integer ALU reg-reg operation 3609 pipe_class ialu_cr_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2) 3610 %{ 3611 single_instruction; 3612 cr : S4(write); 3613 src1 : S3(read); 3614 src2 : S3(read); 3615 DECODE : S0; // any decoder 3616 ALU : S3; // any alu 3617 %} 3618 3619 // Integer ALU reg-imm operation 3620 pipe_class ialu_cr_reg_imm(rFlagsReg cr, rRegI src1) 3621 %{ 3622 single_instruction; 3623 cr : S4(write); 3624 src1 : S3(read); 3625 DECODE : S0; // any decoder 3626 ALU : S3; // any alu 3627 %} 3628 3629 // Integer ALU reg-mem operation 3630 pipe_class ialu_cr_reg_mem(rFlagsReg cr, rRegI src1, memory src2) 3631 %{ 3632 single_instruction; 3633 cr : S4(write); 3634 src1 : S3(read); 3635 src2 : S3(read); 3636 D0 : S0; // big decoder only 3637 ALU : S4; // any alu 3638 MEM : S3; 3639 %} 3640 3641 // Conditional move reg-reg 3642 pipe_class pipe_cmplt( rRegI p, rRegI q, rRegI y) 3643 %{ 3644 instruction_count(4); 3645 y : S4(read); 3646 q : S3(read); 3647 p : S3(read); 3648 DECODE : S0(4); // any decoder 3649 %} 3650 3651 // Conditional move reg-reg 3652 pipe_class pipe_cmov_reg( rRegI dst, rRegI src, rFlagsReg cr) 3653 %{ 3654 single_instruction; 3655 dst : S4(write); 3656 src : S3(read); 3657 cr : S3(read); 3658 DECODE : S0; // any decoder 3659 %} 3660 3661 // Conditional move reg-mem 3662 pipe_class pipe_cmov_mem( rFlagsReg cr, rRegI dst, memory src) 3663 %{ 3664 single_instruction; 3665 dst : S4(write); 3666 src : S3(read); 3667 cr : S3(read); 3668 DECODE : S0; // any decoder 3669 MEM : S3; 3670 %} 3671 3672 // Conditional move reg-reg long 3673 pipe_class pipe_cmov_reg_long( rFlagsReg cr, rRegL dst, rRegL src) 3674 %{ 3675 single_instruction; 3676 dst : S4(write); 3677 src : S3(read); 3678 cr : S3(read); 3679 DECODE : S0(2); // any 2 decoders 3680 %} 3681 3682 // Float reg-reg operation 3683 pipe_class fpu_reg(regD dst) 3684 %{ 3685 instruction_count(2); 3686 dst : S3(read); 3687 DECODE : S0(2); // any 2 decoders 3688 FPU : S3; 3689 %} 3690 3691 // Float reg-reg operation 3692 pipe_class fpu_reg_reg(regD dst, regD src) 3693 %{ 3694 instruction_count(2); 3695 dst : S4(write); 3696 src : S3(read); 3697 DECODE : S0(2); // any 2 decoders 3698 FPU : S3; 3699 %} 3700 3701 // Float reg-reg operation 3702 pipe_class fpu_reg_reg_reg(regD dst, regD src1, regD src2) 3703 %{ 3704 instruction_count(3); 3705 dst : S4(write); 3706 src1 : S3(read); 3707 src2 : S3(read); 3708 DECODE : S0(3); // any 3 decoders 3709 FPU : S3(2); 3710 %} 3711 3712 // Float reg-reg operation 3713 pipe_class fpu_reg_reg_reg_reg(regD dst, regD src1, regD src2, regD src3) 3714 %{ 3715 instruction_count(4); 3716 dst : S4(write); 3717 src1 : S3(read); 3718 src2 : S3(read); 3719 src3 : S3(read); 3720 DECODE : S0(4); // any 3 decoders 3721 FPU : S3(2); 3722 %} 3723 3724 // Float reg-reg operation 3725 pipe_class fpu_reg_mem_reg_reg(regD dst, memory src1, regD src2, regD src3) 3726 %{ 3727 instruction_count(4); 3728 dst : S4(write); 3729 src1 : S3(read); 3730 src2 : S3(read); 3731 src3 : S3(read); 3732 DECODE : S1(3); // any 3 decoders 3733 D0 : S0; // Big decoder only 3734 FPU : S3(2); 3735 MEM : S3; 3736 %} 3737 3738 // Float reg-mem operation 3739 pipe_class fpu_reg_mem(regD dst, memory mem) 3740 %{ 3741 instruction_count(2); 3742 dst : S5(write); 3743 mem : S3(read); 3744 D0 : S0; // big decoder only 3745 DECODE : S1; // any decoder for FPU POP 3746 FPU : S4; 3747 MEM : S3; // any mem 3748 %} 3749 3750 // Float reg-mem operation 3751 pipe_class fpu_reg_reg_mem(regD dst, regD src1, memory mem) 3752 %{ 3753 instruction_count(3); 3754 dst : S5(write); 3755 src1 : S3(read); 3756 mem : S3(read); 3757 D0 : S0; // big decoder only 3758 DECODE : S1(2); // any decoder for FPU POP 3759 FPU : S4; 3760 MEM : S3; // any mem 3761 %} 3762 3763 // Float mem-reg operation 3764 pipe_class fpu_mem_reg(memory mem, regD src) 3765 %{ 3766 instruction_count(2); 3767 src : S5(read); 3768 mem : S3(read); 3769 DECODE : S0; // any decoder for FPU PUSH 3770 D0 : S1; // big decoder only 3771 FPU : S4; 3772 MEM : S3; // any mem 3773 %} 3774 3775 pipe_class fpu_mem_reg_reg(memory mem, regD src1, regD src2) 3776 %{ 3777 instruction_count(3); 3778 src1 : S3(read); 3779 src2 : S3(read); 3780 mem : S3(read); 3781 DECODE : S0(2); // any decoder for FPU PUSH 3782 D0 : S1; // big decoder only 3783 FPU : S4; 3784 MEM : S3; // any mem 3785 %} 3786 3787 pipe_class fpu_mem_reg_mem(memory mem, regD src1, memory src2) 3788 %{ 3789 instruction_count(3); 3790 src1 : S3(read); 3791 src2 : S3(read); 3792 mem : S4(read); 3793 DECODE : S0; // any decoder for FPU PUSH 3794 D0 : S0(2); // big decoder only 3795 FPU : S4; 3796 MEM : S3(2); // any mem 3797 %} 3798 3799 pipe_class fpu_mem_mem(memory dst, memory src1) 3800 %{ 3801 instruction_count(2); 3802 src1 : S3(read); 3803 dst : S4(read); 3804 D0 : S0(2); // big decoder only 3805 MEM : S3(2); // any mem 3806 %} 3807 3808 pipe_class fpu_mem_mem_mem(memory dst, memory src1, memory src2) 3809 %{ 3810 instruction_count(3); 3811 src1 : S3(read); 3812 src2 : S3(read); 3813 dst : S4(read); 3814 D0 : S0(3); // big decoder only 3815 FPU : S4; 3816 MEM : S3(3); // any mem 3817 %} 3818 3819 pipe_class fpu_mem_reg_con(memory mem, regD src1) 3820 %{ 3821 instruction_count(3); 3822 src1 : S4(read); 3823 mem : S4(read); 3824 DECODE : S0; // any decoder for FPU PUSH 3825 D0 : S0(2); // big decoder only 3826 FPU : S4; 3827 MEM : S3(2); // any mem 3828 %} 3829 3830 // Float load constant 3831 pipe_class fpu_reg_con(regD dst) 3832 %{ 3833 instruction_count(2); 3834 dst : S5(write); 3835 D0 : S0; // big decoder only for the load 3836 DECODE : S1; // any decoder for FPU POP 3837 FPU : S4; 3838 MEM : S3; // any mem 3839 %} 3840 3841 // Float load constant 3842 pipe_class fpu_reg_reg_con(regD dst, regD src) 3843 %{ 3844 instruction_count(3); 3845 dst : S5(write); 3846 src : S3(read); 3847 D0 : S0; // big decoder only for the load 3848 DECODE : S1(2); // any decoder for FPU POP 3849 FPU : S4; 3850 MEM : S3; // any mem 3851 %} 3852 3853 // UnConditional branch 3854 pipe_class pipe_jmp(label labl) 3855 %{ 3856 single_instruction; 3857 BR : S3; 3858 %} 3859 3860 // Conditional branch 3861 pipe_class pipe_jcc(cmpOp cmp, rFlagsReg cr, label labl) 3862 %{ 3863 single_instruction; 3864 cr : S1(read); 3865 BR : S3; 3866 %} 3867 3868 // Allocation idiom 3869 pipe_class pipe_cmpxchg(rRegP dst, rRegP heap_ptr) 3870 %{ 3871 instruction_count(1); force_serialization; 3872 fixed_latency(6); 3873 heap_ptr : S3(read); 3874 DECODE : S0(3); 3875 D0 : S2; 3876 MEM : S3; 3877 ALU : S3(2); 3878 dst : S5(write); 3879 BR : S5; 3880 %} 3881 3882 // Generic big/slow expanded idiom 3883 pipe_class pipe_slow() 3884 %{ 3885 instruction_count(10); multiple_bundles; force_serialization; 3886 fixed_latency(100); 3887 D0 : S0(2); 3888 MEM : S3(2); 3889 %} 3890 3891 // The real do-nothing guy 3892 pipe_class empty() 3893 %{ 3894 instruction_count(0); 3895 %} 3896 3897 // Define the class for the Nop node 3898 define 3899 %{ 3900 MachNop = empty; 3901 %} 3902 3903 %} 3904 3905 //----------INSTRUCTIONS------------------------------------------------------- 3906 // 3907 // match -- States which machine-independent subtree may be replaced 3908 // by this instruction. 3909 // ins_cost -- The estimated cost of this instruction is used by instruction 3910 // selection to identify a minimum cost tree of machine 3911 // instructions that matches a tree of machine-independent 3912 // instructions. 3913 // format -- A string providing the disassembly for this instruction. 3914 // The value of an instruction's operand may be inserted 3915 // by referring to it with a '$' prefix. 3916 // opcode -- Three instruction opcodes may be provided. These are referred 3917 // to within an encode class as $primary, $secondary, and $tertiary 3918 // rrspectively. The primary opcode is commonly used to 3919 // indicate the type of machine instruction, while secondary 3920 // and tertiary are often used for prefix options or addressing 3921 // modes. 3922 // ins_encode -- A list of encode classes with parameters. The encode class 3923 // name must have been defined in an 'enc_class' specification 3924 // in the encode section of the architecture description. 3925 3926 // Dummy reg-to-reg vector moves. Removed during post-selection cleanup. 3927 // Load Float 3928 instruct MoveF2VL(vlRegF dst, regF src) %{ 3929 match(Set dst src); 3930 format %{ "movss $dst,$src\t! load float (4 bytes)" %} 3931 ins_encode %{ 3932 ShouldNotReachHere(); 3933 %} 3934 ins_pipe( fpu_reg_reg ); 3935 %} 3936 3937 // Load Float 3938 instruct MoveF2LEG(legRegF dst, regF src) %{ 3939 match(Set dst src); 3940 format %{ "movss $dst,$src\t# if src != dst load float (4 bytes)" %} 3941 ins_encode %{ 3942 ShouldNotReachHere(); 3943 %} 3944 ins_pipe( fpu_reg_reg ); 3945 %} 3946 3947 // Load Float 3948 instruct MoveVL2F(regF dst, vlRegF src) %{ 3949 match(Set dst src); 3950 format %{ "movss $dst,$src\t! load float (4 bytes)" %} 3951 ins_encode %{ 3952 ShouldNotReachHere(); 3953 %} 3954 ins_pipe( fpu_reg_reg ); 3955 %} 3956 3957 // Load Float 3958 instruct MoveLEG2F(regF dst, legRegF src) %{ 3959 match(Set dst src); 3960 format %{ "movss $dst,$src\t# if src != dst load float (4 bytes)" %} 3961 ins_encode %{ 3962 ShouldNotReachHere(); 3963 %} 3964 ins_pipe( fpu_reg_reg ); 3965 %} 3966 3967 // Load Double 3968 instruct MoveD2VL(vlRegD dst, regD src) %{ 3969 match(Set dst src); 3970 format %{ "movsd $dst,$src\t! load double (8 bytes)" %} 3971 ins_encode %{ 3972 ShouldNotReachHere(); 3973 %} 3974 ins_pipe( fpu_reg_reg ); 3975 %} 3976 3977 // Load Double 3978 instruct MoveD2LEG(legRegD dst, regD src) %{ 3979 match(Set dst src); 3980 format %{ "movsd $dst,$src\t# if src != dst load double (8 bytes)" %} 3981 ins_encode %{ 3982 ShouldNotReachHere(); 3983 %} 3984 ins_pipe( fpu_reg_reg ); 3985 %} 3986 3987 // Load Double 3988 instruct MoveVL2D(regD dst, vlRegD src) %{ 3989 match(Set dst src); 3990 format %{ "movsd $dst,$src\t! load double (8 bytes)" %} 3991 ins_encode %{ 3992 ShouldNotReachHere(); 3993 %} 3994 ins_pipe( fpu_reg_reg ); 3995 %} 3996 3997 // Load Double 3998 instruct MoveLEG2D(regD dst, legRegD src) %{ 3999 match(Set dst src); 4000 format %{ "movsd $dst,$src\t# if src != dst load double (8 bytes)" %} 4001 ins_encode %{ 4002 ShouldNotReachHere(); 4003 %} 4004 ins_pipe( fpu_reg_reg ); 4005 %} 4006 4007 //----------Load/Store/Move Instructions--------------------------------------- 4008 //----------Load Instructions-------------------------------------------------- 4009 4010 // Load Byte (8 bit signed) 4011 instruct loadB(rRegI dst, memory mem) 4012 %{ 4013 match(Set dst (LoadB mem)); 4014 4015 ins_cost(125); 4016 format %{ "movsbl $dst, $mem\t# byte" %} 4017 4018 ins_encode %{ 4019 __ movsbl($dst$$Register, $mem$$Address); 4020 %} 4021 4022 ins_pipe(ialu_reg_mem); 4023 %} 4024 4025 // Load Byte (8 bit signed) into Long Register 4026 instruct loadB2L(rRegL dst, memory mem) 4027 %{ 4028 match(Set dst (ConvI2L (LoadB mem))); 4029 4030 ins_cost(125); 4031 format %{ "movsbq $dst, $mem\t# byte -> long" %} 4032 4033 ins_encode %{ 4034 __ movsbq($dst$$Register, $mem$$Address); 4035 %} 4036 4037 ins_pipe(ialu_reg_mem); 4038 %} 4039 4040 // Load Unsigned Byte (8 bit UNsigned) 4041 instruct loadUB(rRegI dst, memory mem) 4042 %{ 4043 match(Set dst (LoadUB mem)); 4044 4045 ins_cost(125); 4046 format %{ "movzbl $dst, $mem\t# ubyte" %} 4047 4048 ins_encode %{ 4049 __ movzbl($dst$$Register, $mem$$Address); 4050 %} 4051 4052 ins_pipe(ialu_reg_mem); 4053 %} 4054 4055 // Load Unsigned Byte (8 bit UNsigned) into Long Register 4056 instruct loadUB2L(rRegL dst, memory mem) 4057 %{ 4058 match(Set dst (ConvI2L (LoadUB mem))); 4059 4060 ins_cost(125); 4061 format %{ "movzbq $dst, $mem\t# ubyte -> long" %} 4062 4063 ins_encode %{ 4064 __ movzbq($dst$$Register, $mem$$Address); 4065 %} 4066 4067 ins_pipe(ialu_reg_mem); 4068 %} 4069 4070 // Load Unsigned Byte (8 bit UNsigned) with 32-bit mask into Long Register 4071 instruct loadUB2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 4072 match(Set dst (ConvI2L (AndI (LoadUB mem) mask))); 4073 effect(KILL cr); 4074 4075 format %{ "movzbq $dst, $mem\t# ubyte & 32-bit mask -> long\n\t" 4076 "andl $dst, right_n_bits($mask, 8)" %} 4077 ins_encode %{ 4078 Register Rdst = $dst$$Register; 4079 __ movzbq(Rdst, $mem$$Address); 4080 __ andl(Rdst, $mask$$constant & right_n_bits(8)); 4081 %} 4082 ins_pipe(ialu_reg_mem); 4083 %} 4084 4085 // Load Short (16 bit signed) 4086 instruct loadS(rRegI dst, memory mem) 4087 %{ 4088 match(Set dst (LoadS mem)); 4089 4090 ins_cost(125); 4091 format %{ "movswl $dst, $mem\t# short" %} 4092 4093 ins_encode %{ 4094 __ movswl($dst$$Register, $mem$$Address); 4095 %} 4096 4097 ins_pipe(ialu_reg_mem); 4098 %} 4099 4100 // Load Short (16 bit signed) to Byte (8 bit signed) 4101 instruct loadS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4102 match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour)); 4103 4104 ins_cost(125); 4105 format %{ "movsbl $dst, $mem\t# short -> byte" %} 4106 ins_encode %{ 4107 __ movsbl($dst$$Register, $mem$$Address); 4108 %} 4109 ins_pipe(ialu_reg_mem); 4110 %} 4111 4112 // Load Short (16 bit signed) into Long Register 4113 instruct loadS2L(rRegL dst, memory mem) 4114 %{ 4115 match(Set dst (ConvI2L (LoadS mem))); 4116 4117 ins_cost(125); 4118 format %{ "movswq $dst, $mem\t# short -> long" %} 4119 4120 ins_encode %{ 4121 __ movswq($dst$$Register, $mem$$Address); 4122 %} 4123 4124 ins_pipe(ialu_reg_mem); 4125 %} 4126 4127 // Load Unsigned Short/Char (16 bit UNsigned) 4128 instruct loadUS(rRegI dst, memory mem) 4129 %{ 4130 match(Set dst (LoadUS mem)); 4131 4132 ins_cost(125); 4133 format %{ "movzwl $dst, $mem\t# ushort/char" %} 4134 4135 ins_encode %{ 4136 __ movzwl($dst$$Register, $mem$$Address); 4137 %} 4138 4139 ins_pipe(ialu_reg_mem); 4140 %} 4141 4142 // Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed) 4143 instruct loadUS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4144 match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour)); 4145 4146 ins_cost(125); 4147 format %{ "movsbl $dst, $mem\t# ushort -> byte" %} 4148 ins_encode %{ 4149 __ movsbl($dst$$Register, $mem$$Address); 4150 %} 4151 ins_pipe(ialu_reg_mem); 4152 %} 4153 4154 // Load Unsigned Short/Char (16 bit UNsigned) into Long Register 4155 instruct loadUS2L(rRegL dst, memory mem) 4156 %{ 4157 match(Set dst (ConvI2L (LoadUS mem))); 4158 4159 ins_cost(125); 4160 format %{ "movzwq $dst, $mem\t# ushort/char -> long" %} 4161 4162 ins_encode %{ 4163 __ movzwq($dst$$Register, $mem$$Address); 4164 %} 4165 4166 ins_pipe(ialu_reg_mem); 4167 %} 4168 4169 // Load Unsigned Short/Char (16 bit UNsigned) with mask 0xFF into Long Register 4170 instruct loadUS2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 4171 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 4172 4173 format %{ "movzbq $dst, $mem\t# ushort/char & 0xFF -> long" %} 4174 ins_encode %{ 4175 __ movzbq($dst$$Register, $mem$$Address); 4176 %} 4177 ins_pipe(ialu_reg_mem); 4178 %} 4179 4180 // Load Unsigned Short/Char (16 bit UNsigned) with 32-bit mask into Long Register 4181 instruct loadUS2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 4182 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 4183 effect(KILL cr); 4184 4185 format %{ "movzwq $dst, $mem\t# ushort/char & 32-bit mask -> long\n\t" 4186 "andl $dst, right_n_bits($mask, 16)" %} 4187 ins_encode %{ 4188 Register Rdst = $dst$$Register; 4189 __ movzwq(Rdst, $mem$$Address); 4190 __ andl(Rdst, $mask$$constant & right_n_bits(16)); 4191 %} 4192 ins_pipe(ialu_reg_mem); 4193 %} 4194 4195 // Load Integer 4196 instruct loadI(rRegI dst, memory mem) 4197 %{ 4198 match(Set dst (LoadI mem)); 4199 4200 ins_cost(125); 4201 format %{ "movl $dst, $mem\t# int" %} 4202 4203 ins_encode %{ 4204 __ movl($dst$$Register, $mem$$Address); 4205 %} 4206 4207 ins_pipe(ialu_reg_mem); 4208 %} 4209 4210 // Load Integer (32 bit signed) to Byte (8 bit signed) 4211 instruct loadI2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4212 match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour)); 4213 4214 ins_cost(125); 4215 format %{ "movsbl $dst, $mem\t# int -> byte" %} 4216 ins_encode %{ 4217 __ movsbl($dst$$Register, $mem$$Address); 4218 %} 4219 ins_pipe(ialu_reg_mem); 4220 %} 4221 4222 // Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned) 4223 instruct loadI2UB(rRegI dst, memory mem, immI_255 mask) %{ 4224 match(Set dst (AndI (LoadI mem) mask)); 4225 4226 ins_cost(125); 4227 format %{ "movzbl $dst, $mem\t# int -> ubyte" %} 4228 ins_encode %{ 4229 __ movzbl($dst$$Register, $mem$$Address); 4230 %} 4231 ins_pipe(ialu_reg_mem); 4232 %} 4233 4234 // Load Integer (32 bit signed) to Short (16 bit signed) 4235 instruct loadI2S(rRegI dst, memory mem, immI_16 sixteen) %{ 4236 match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen)); 4237 4238 ins_cost(125); 4239 format %{ "movswl $dst, $mem\t# int -> short" %} 4240 ins_encode %{ 4241 __ movswl($dst$$Register, $mem$$Address); 4242 %} 4243 ins_pipe(ialu_reg_mem); 4244 %} 4245 4246 // Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned) 4247 instruct loadI2US(rRegI dst, memory mem, immI_65535 mask) %{ 4248 match(Set dst (AndI (LoadI mem) mask)); 4249 4250 ins_cost(125); 4251 format %{ "movzwl $dst, $mem\t# int -> ushort/char" %} 4252 ins_encode %{ 4253 __ movzwl($dst$$Register, $mem$$Address); 4254 %} 4255 ins_pipe(ialu_reg_mem); 4256 %} 4257 4258 // Load Integer into Long Register 4259 instruct loadI2L(rRegL dst, memory mem) 4260 %{ 4261 match(Set dst (ConvI2L (LoadI mem))); 4262 4263 ins_cost(125); 4264 format %{ "movslq $dst, $mem\t# int -> long" %} 4265 4266 ins_encode %{ 4267 __ movslq($dst$$Register, $mem$$Address); 4268 %} 4269 4270 ins_pipe(ialu_reg_mem); 4271 %} 4272 4273 // Load Integer with mask 0xFF into Long Register 4274 instruct loadI2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 4275 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4276 4277 format %{ "movzbq $dst, $mem\t# int & 0xFF -> long" %} 4278 ins_encode %{ 4279 __ movzbq($dst$$Register, $mem$$Address); 4280 %} 4281 ins_pipe(ialu_reg_mem); 4282 %} 4283 4284 // Load Integer with mask 0xFFFF into Long Register 4285 instruct loadI2L_immI_65535(rRegL dst, memory mem, immI_65535 mask) %{ 4286 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4287 4288 format %{ "movzwq $dst, $mem\t# int & 0xFFFF -> long" %} 4289 ins_encode %{ 4290 __ movzwq($dst$$Register, $mem$$Address); 4291 %} 4292 ins_pipe(ialu_reg_mem); 4293 %} 4294 4295 // Load Integer with a 31-bit mask into Long Register 4296 instruct loadI2L_immU31(rRegL dst, memory mem, immU31 mask, rFlagsReg cr) %{ 4297 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4298 effect(KILL cr); 4299 4300 format %{ "movl $dst, $mem\t# int & 31-bit mask -> long\n\t" 4301 "andl $dst, $mask" %} 4302 ins_encode %{ 4303 Register Rdst = $dst$$Register; 4304 __ movl(Rdst, $mem$$Address); 4305 __ andl(Rdst, $mask$$constant); 4306 %} 4307 ins_pipe(ialu_reg_mem); 4308 %} 4309 4310 // Load Unsigned Integer into Long Register 4311 instruct loadUI2L(rRegL dst, memory mem, immL_32bits mask) 4312 %{ 4313 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 4314 4315 ins_cost(125); 4316 format %{ "movl $dst, $mem\t# uint -> long" %} 4317 4318 ins_encode %{ 4319 __ movl($dst$$Register, $mem$$Address); 4320 %} 4321 4322 ins_pipe(ialu_reg_mem); 4323 %} 4324 4325 // Load Long 4326 instruct loadL(rRegL dst, memory mem) 4327 %{ 4328 match(Set dst (LoadL mem)); 4329 4330 ins_cost(125); 4331 format %{ "movq $dst, $mem\t# long" %} 4332 4333 ins_encode %{ 4334 __ movq($dst$$Register, $mem$$Address); 4335 %} 4336 4337 ins_pipe(ialu_reg_mem); // XXX 4338 %} 4339 4340 // Load Range 4341 instruct loadRange(rRegI dst, memory mem) 4342 %{ 4343 match(Set dst (LoadRange mem)); 4344 4345 ins_cost(125); // XXX 4346 format %{ "movl $dst, $mem\t# range" %} 4347 ins_encode %{ 4348 __ movl($dst$$Register, $mem$$Address); 4349 %} 4350 ins_pipe(ialu_reg_mem); 4351 %} 4352 4353 // Load Pointer 4354 instruct loadP(rRegP dst, memory mem) 4355 %{ 4356 match(Set dst (LoadP mem)); 4357 predicate(n->as_Load()->barrier_data() == 0); 4358 4359 ins_cost(125); // XXX 4360 format %{ "movq $dst, $mem\t# ptr" %} 4361 ins_encode %{ 4362 __ movq($dst$$Register, $mem$$Address); 4363 %} 4364 ins_pipe(ialu_reg_mem); // XXX 4365 %} 4366 4367 // Load Compressed Pointer 4368 instruct loadN(rRegN dst, memory mem) 4369 %{ 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 match(Set mem (StoreN mem src)); 5156 5157 ins_cost(125); // XXX 5158 format %{ "movl $mem, $src\t# compressed ptr" %} 5159 ins_encode %{ 5160 __ movl($mem$$Address, $src$$Register); 5161 %} 5162 ins_pipe(ialu_mem_reg); 5163 %} 5164 5165 instruct storeNKlass(memory mem, rRegN src) 5166 %{ 5167 match(Set mem (StoreNKlass mem src)); 5168 5169 ins_cost(125); // XXX 5170 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5171 ins_encode %{ 5172 __ movl($mem$$Address, $src$$Register); 5173 %} 5174 ins_pipe(ialu_mem_reg); 5175 %} 5176 5177 instruct storeImmN0(memory mem, immN0 zero) 5178 %{ 5179 predicate(CompressedOops::base() == nullptr); 5180 match(Set mem (StoreN mem zero)); 5181 5182 ins_cost(125); // XXX 5183 format %{ "movl $mem, R12\t# compressed ptr (R12_heapbase==0)" %} 5184 ins_encode %{ 5185 __ movl($mem$$Address, r12); 5186 %} 5187 ins_pipe(ialu_mem_reg); 5188 %} 5189 5190 instruct storeImmN(memory mem, immN src) 5191 %{ 5192 match(Set mem (StoreN mem src)); 5193 5194 ins_cost(150); // XXX 5195 format %{ "movl $mem, $src\t# compressed ptr" %} 5196 ins_encode %{ 5197 address con = (address)$src$$constant; 5198 if (con == nullptr) { 5199 __ movl($mem$$Address, 0); 5200 } else { 5201 __ set_narrow_oop($mem$$Address, (jobject)$src$$constant); 5202 } 5203 %} 5204 ins_pipe(ialu_mem_imm); 5205 %} 5206 5207 instruct storeImmNKlass(memory mem, immNKlass src) 5208 %{ 5209 match(Set mem (StoreNKlass mem src)); 5210 5211 ins_cost(150); // XXX 5212 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5213 ins_encode %{ 5214 __ set_narrow_klass($mem$$Address, (Klass*)$src$$constant); 5215 %} 5216 ins_pipe(ialu_mem_imm); 5217 %} 5218 5219 // Store Integer Immediate 5220 instruct storeImmI0(memory mem, immI_0 zero) 5221 %{ 5222 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5223 match(Set mem (StoreI mem zero)); 5224 5225 ins_cost(125); // XXX 5226 format %{ "movl $mem, R12\t# int (R12_heapbase==0)" %} 5227 ins_encode %{ 5228 __ movl($mem$$Address, r12); 5229 %} 5230 ins_pipe(ialu_mem_reg); 5231 %} 5232 5233 instruct storeImmI(memory mem, immI src) 5234 %{ 5235 match(Set mem (StoreI mem src)); 5236 5237 ins_cost(150); 5238 format %{ "movl $mem, $src\t# int" %} 5239 ins_encode %{ 5240 __ movl($mem$$Address, $src$$constant); 5241 %} 5242 ins_pipe(ialu_mem_imm); 5243 %} 5244 5245 // Store Long Immediate 5246 instruct storeImmL0(memory mem, immL0 zero) 5247 %{ 5248 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5249 match(Set mem (StoreL mem zero)); 5250 5251 ins_cost(125); // XXX 5252 format %{ "movq $mem, R12\t# long (R12_heapbase==0)" %} 5253 ins_encode %{ 5254 __ movq($mem$$Address, r12); 5255 %} 5256 ins_pipe(ialu_mem_reg); 5257 %} 5258 5259 instruct storeImmL(memory mem, immL32 src) 5260 %{ 5261 match(Set mem (StoreL mem src)); 5262 5263 ins_cost(150); 5264 format %{ "movq $mem, $src\t# long" %} 5265 ins_encode %{ 5266 __ movq($mem$$Address, $src$$constant); 5267 %} 5268 ins_pipe(ialu_mem_imm); 5269 %} 5270 5271 // Store Short/Char Immediate 5272 instruct storeImmC0(memory mem, immI_0 zero) 5273 %{ 5274 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5275 match(Set mem (StoreC mem zero)); 5276 5277 ins_cost(125); // XXX 5278 format %{ "movw $mem, R12\t# short/char (R12_heapbase==0)" %} 5279 ins_encode %{ 5280 __ movw($mem$$Address, r12); 5281 %} 5282 ins_pipe(ialu_mem_reg); 5283 %} 5284 5285 instruct storeImmI16(memory mem, immI16 src) 5286 %{ 5287 predicate(UseStoreImmI16); 5288 match(Set mem (StoreC mem src)); 5289 5290 ins_cost(150); 5291 format %{ "movw $mem, $src\t# short/char" %} 5292 ins_encode %{ 5293 __ movw($mem$$Address, $src$$constant); 5294 %} 5295 ins_pipe(ialu_mem_imm); 5296 %} 5297 5298 // Store Byte Immediate 5299 instruct storeImmB0(memory mem, immI_0 zero) 5300 %{ 5301 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5302 match(Set mem (StoreB mem zero)); 5303 5304 ins_cost(125); // XXX 5305 format %{ "movb $mem, R12\t# short/char (R12_heapbase==0)" %} 5306 ins_encode %{ 5307 __ movb($mem$$Address, r12); 5308 %} 5309 ins_pipe(ialu_mem_reg); 5310 %} 5311 5312 instruct storeImmB(memory mem, immI8 src) 5313 %{ 5314 match(Set mem (StoreB mem src)); 5315 5316 ins_cost(150); // XXX 5317 format %{ "movb $mem, $src\t# byte" %} 5318 ins_encode %{ 5319 __ movb($mem$$Address, $src$$constant); 5320 %} 5321 ins_pipe(ialu_mem_imm); 5322 %} 5323 5324 // Store CMS card-mark Immediate 5325 instruct storeImmCM0_reg(memory mem, immI_0 zero) 5326 %{ 5327 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5328 match(Set mem (StoreCM mem zero)); 5329 5330 ins_cost(125); // XXX 5331 format %{ "movb $mem, R12\t# CMS card-mark byte 0 (R12_heapbase==0)" %} 5332 ins_encode %{ 5333 __ movb($mem$$Address, r12); 5334 %} 5335 ins_pipe(ialu_mem_reg); 5336 %} 5337 5338 instruct storeImmCM0(memory mem, immI_0 src) 5339 %{ 5340 match(Set mem (StoreCM mem src)); 5341 5342 ins_cost(150); // XXX 5343 format %{ "movb $mem, $src\t# CMS card-mark byte 0" %} 5344 ins_encode %{ 5345 __ movb($mem$$Address, $src$$constant); 5346 %} 5347 ins_pipe(ialu_mem_imm); 5348 %} 5349 5350 // Store Float 5351 instruct storeF(memory mem, regF src) 5352 %{ 5353 match(Set mem (StoreF mem src)); 5354 5355 ins_cost(95); // XXX 5356 format %{ "movss $mem, $src\t# float" %} 5357 ins_encode %{ 5358 __ movflt($mem$$Address, $src$$XMMRegister); 5359 %} 5360 ins_pipe(pipe_slow); // XXX 5361 %} 5362 5363 // Store immediate Float value (it is faster than store from XMM register) 5364 instruct storeF0(memory mem, immF0 zero) 5365 %{ 5366 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5367 match(Set mem (StoreF mem zero)); 5368 5369 ins_cost(25); // XXX 5370 format %{ "movl $mem, R12\t# float 0. (R12_heapbase==0)" %} 5371 ins_encode %{ 5372 __ movl($mem$$Address, r12); 5373 %} 5374 ins_pipe(ialu_mem_reg); 5375 %} 5376 5377 instruct storeF_imm(memory mem, immF src) 5378 %{ 5379 match(Set mem (StoreF mem src)); 5380 5381 ins_cost(50); 5382 format %{ "movl $mem, $src\t# float" %} 5383 ins_encode %{ 5384 __ movl($mem$$Address, jint_cast($src$$constant)); 5385 %} 5386 ins_pipe(ialu_mem_imm); 5387 %} 5388 5389 // Store Double 5390 instruct storeD(memory mem, regD src) 5391 %{ 5392 match(Set mem (StoreD mem src)); 5393 5394 ins_cost(95); // XXX 5395 format %{ "movsd $mem, $src\t# double" %} 5396 ins_encode %{ 5397 __ movdbl($mem$$Address, $src$$XMMRegister); 5398 %} 5399 ins_pipe(pipe_slow); // XXX 5400 %} 5401 5402 // Store immediate double 0.0 (it is faster than store from XMM register) 5403 instruct storeD0_imm(memory mem, immD0 src) 5404 %{ 5405 predicate(!UseCompressedOops || (CompressedOops::base() != nullptr)); 5406 match(Set mem (StoreD mem src)); 5407 5408 ins_cost(50); 5409 format %{ "movq $mem, $src\t# double 0." %} 5410 ins_encode %{ 5411 __ movq($mem$$Address, $src$$constant); 5412 %} 5413 ins_pipe(ialu_mem_imm); 5414 %} 5415 5416 instruct storeD0(memory mem, immD0 zero) 5417 %{ 5418 predicate(UseCompressedOops && (CompressedOops::base() == nullptr)); 5419 match(Set mem (StoreD mem zero)); 5420 5421 ins_cost(25); // XXX 5422 format %{ "movq $mem, R12\t# double 0. (R12_heapbase==0)" %} 5423 ins_encode %{ 5424 __ movq($mem$$Address, r12); 5425 %} 5426 ins_pipe(ialu_mem_reg); 5427 %} 5428 5429 instruct storeSSI(stackSlotI dst, rRegI src) 5430 %{ 5431 match(Set dst src); 5432 5433 ins_cost(100); 5434 format %{ "movl $dst, $src\t# int stk" %} 5435 ins_encode %{ 5436 __ movl($dst$$Address, $src$$Register); 5437 %} 5438 ins_pipe( ialu_mem_reg ); 5439 %} 5440 5441 instruct storeSSL(stackSlotL dst, rRegL src) 5442 %{ 5443 match(Set dst src); 5444 5445 ins_cost(100); 5446 format %{ "movq $dst, $src\t# long stk" %} 5447 ins_encode %{ 5448 __ movq($dst$$Address, $src$$Register); 5449 %} 5450 ins_pipe(ialu_mem_reg); 5451 %} 5452 5453 instruct storeSSP(stackSlotP dst, rRegP src) 5454 %{ 5455 match(Set dst src); 5456 5457 ins_cost(100); 5458 format %{ "movq $dst, $src\t# ptr stk" %} 5459 ins_encode %{ 5460 __ movq($dst$$Address, $src$$Register); 5461 %} 5462 ins_pipe(ialu_mem_reg); 5463 %} 5464 5465 instruct storeSSF(stackSlotF dst, regF src) 5466 %{ 5467 match(Set dst src); 5468 5469 ins_cost(95); // XXX 5470 format %{ "movss $dst, $src\t# float stk" %} 5471 ins_encode %{ 5472 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 5473 %} 5474 ins_pipe(pipe_slow); // XXX 5475 %} 5476 5477 instruct storeSSD(stackSlotD dst, regD src) 5478 %{ 5479 match(Set dst src); 5480 5481 ins_cost(95); // XXX 5482 format %{ "movsd $dst, $src\t# double stk" %} 5483 ins_encode %{ 5484 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 5485 %} 5486 ins_pipe(pipe_slow); // XXX 5487 %} 5488 5489 instruct cacheWB(indirect addr) 5490 %{ 5491 predicate(VM_Version::supports_data_cache_line_flush()); 5492 match(CacheWB addr); 5493 5494 ins_cost(100); 5495 format %{"cache wb $addr" %} 5496 ins_encode %{ 5497 assert($addr->index_position() < 0, "should be"); 5498 assert($addr$$disp == 0, "should be"); 5499 __ cache_wb(Address($addr$$base$$Register, 0)); 5500 %} 5501 ins_pipe(pipe_slow); // XXX 5502 %} 5503 5504 instruct cacheWBPreSync() 5505 %{ 5506 predicate(VM_Version::supports_data_cache_line_flush()); 5507 match(CacheWBPreSync); 5508 5509 ins_cost(100); 5510 format %{"cache wb presync" %} 5511 ins_encode %{ 5512 __ cache_wbsync(true); 5513 %} 5514 ins_pipe(pipe_slow); // XXX 5515 %} 5516 5517 instruct cacheWBPostSync() 5518 %{ 5519 predicate(VM_Version::supports_data_cache_line_flush()); 5520 match(CacheWBPostSync); 5521 5522 ins_cost(100); 5523 format %{"cache wb postsync" %} 5524 ins_encode %{ 5525 __ cache_wbsync(false); 5526 %} 5527 ins_pipe(pipe_slow); // XXX 5528 %} 5529 5530 //----------BSWAP Instructions------------------------------------------------- 5531 instruct bytes_reverse_int(rRegI dst) %{ 5532 match(Set dst (ReverseBytesI dst)); 5533 5534 format %{ "bswapl $dst" %} 5535 ins_encode %{ 5536 __ bswapl($dst$$Register); 5537 %} 5538 ins_pipe( ialu_reg ); 5539 %} 5540 5541 instruct bytes_reverse_long(rRegL dst) %{ 5542 match(Set dst (ReverseBytesL dst)); 5543 5544 format %{ "bswapq $dst" %} 5545 ins_encode %{ 5546 __ bswapq($dst$$Register); 5547 %} 5548 ins_pipe( ialu_reg); 5549 %} 5550 5551 instruct bytes_reverse_unsigned_short(rRegI dst, rFlagsReg cr) %{ 5552 match(Set dst (ReverseBytesUS dst)); 5553 effect(KILL cr); 5554 5555 format %{ "bswapl $dst\n\t" 5556 "shrl $dst,16\n\t" %} 5557 ins_encode %{ 5558 __ bswapl($dst$$Register); 5559 __ shrl($dst$$Register, 16); 5560 %} 5561 ins_pipe( ialu_reg ); 5562 %} 5563 5564 instruct bytes_reverse_short(rRegI dst, rFlagsReg cr) %{ 5565 match(Set dst (ReverseBytesS dst)); 5566 effect(KILL cr); 5567 5568 format %{ "bswapl $dst\n\t" 5569 "sar $dst,16\n\t" %} 5570 ins_encode %{ 5571 __ bswapl($dst$$Register); 5572 __ sarl($dst$$Register, 16); 5573 %} 5574 ins_pipe( ialu_reg ); 5575 %} 5576 5577 //---------- Zeros Count Instructions ------------------------------------------ 5578 5579 instruct countLeadingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 5580 predicate(UseCountLeadingZerosInstruction); 5581 match(Set dst (CountLeadingZerosI src)); 5582 effect(KILL cr); 5583 5584 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 5585 ins_encode %{ 5586 __ lzcntl($dst$$Register, $src$$Register); 5587 %} 5588 ins_pipe(ialu_reg); 5589 %} 5590 5591 instruct countLeadingZerosI_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5592 predicate(UseCountLeadingZerosInstruction); 5593 match(Set dst (CountLeadingZerosI (LoadI src))); 5594 effect(KILL cr); 5595 ins_cost(175); 5596 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 5597 ins_encode %{ 5598 __ lzcntl($dst$$Register, $src$$Address); 5599 %} 5600 ins_pipe(ialu_reg_mem); 5601 %} 5602 5603 instruct countLeadingZerosI_bsr(rRegI dst, rRegI src, rFlagsReg cr) %{ 5604 predicate(!UseCountLeadingZerosInstruction); 5605 match(Set dst (CountLeadingZerosI src)); 5606 effect(KILL cr); 5607 5608 format %{ "bsrl $dst, $src\t# count leading zeros (int)\n\t" 5609 "jnz skip\n\t" 5610 "movl $dst, -1\n" 5611 "skip:\n\t" 5612 "negl $dst\n\t" 5613 "addl $dst, 31" %} 5614 ins_encode %{ 5615 Register Rdst = $dst$$Register; 5616 Register Rsrc = $src$$Register; 5617 Label skip; 5618 __ bsrl(Rdst, Rsrc); 5619 __ jccb(Assembler::notZero, skip); 5620 __ movl(Rdst, -1); 5621 __ bind(skip); 5622 __ negl(Rdst); 5623 __ addl(Rdst, BitsPerInt - 1); 5624 %} 5625 ins_pipe(ialu_reg); 5626 %} 5627 5628 instruct countLeadingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 5629 predicate(UseCountLeadingZerosInstruction); 5630 match(Set dst (CountLeadingZerosL src)); 5631 effect(KILL cr); 5632 5633 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 5634 ins_encode %{ 5635 __ lzcntq($dst$$Register, $src$$Register); 5636 %} 5637 ins_pipe(ialu_reg); 5638 %} 5639 5640 instruct countLeadingZerosL_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5641 predicate(UseCountLeadingZerosInstruction); 5642 match(Set dst (CountLeadingZerosL (LoadL src))); 5643 effect(KILL cr); 5644 ins_cost(175); 5645 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 5646 ins_encode %{ 5647 __ lzcntq($dst$$Register, $src$$Address); 5648 %} 5649 ins_pipe(ialu_reg_mem); 5650 %} 5651 5652 instruct countLeadingZerosL_bsr(rRegI dst, rRegL src, rFlagsReg cr) %{ 5653 predicate(!UseCountLeadingZerosInstruction); 5654 match(Set dst (CountLeadingZerosL src)); 5655 effect(KILL cr); 5656 5657 format %{ "bsrq $dst, $src\t# count leading zeros (long)\n\t" 5658 "jnz skip\n\t" 5659 "movl $dst, -1\n" 5660 "skip:\n\t" 5661 "negl $dst\n\t" 5662 "addl $dst, 63" %} 5663 ins_encode %{ 5664 Register Rdst = $dst$$Register; 5665 Register Rsrc = $src$$Register; 5666 Label skip; 5667 __ bsrq(Rdst, Rsrc); 5668 __ jccb(Assembler::notZero, skip); 5669 __ movl(Rdst, -1); 5670 __ bind(skip); 5671 __ negl(Rdst); 5672 __ addl(Rdst, BitsPerLong - 1); 5673 %} 5674 ins_pipe(ialu_reg); 5675 %} 5676 5677 instruct countTrailingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 5678 predicate(UseCountTrailingZerosInstruction); 5679 match(Set dst (CountTrailingZerosI src)); 5680 effect(KILL cr); 5681 5682 format %{ "tzcntl $dst, $src\t# count trailing zeros (int)" %} 5683 ins_encode %{ 5684 __ tzcntl($dst$$Register, $src$$Register); 5685 %} 5686 ins_pipe(ialu_reg); 5687 %} 5688 5689 instruct countTrailingZerosI_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5690 predicate(UseCountTrailingZerosInstruction); 5691 match(Set dst (CountTrailingZerosI (LoadI src))); 5692 effect(KILL cr); 5693 ins_cost(175); 5694 format %{ "tzcntl $dst, $src\t# count trailing zeros (int)" %} 5695 ins_encode %{ 5696 __ tzcntl($dst$$Register, $src$$Address); 5697 %} 5698 ins_pipe(ialu_reg_mem); 5699 %} 5700 5701 instruct countTrailingZerosI_bsf(rRegI dst, rRegI src, rFlagsReg cr) %{ 5702 predicate(!UseCountTrailingZerosInstruction); 5703 match(Set dst (CountTrailingZerosI src)); 5704 effect(KILL cr); 5705 5706 format %{ "bsfl $dst, $src\t# count trailing zeros (int)\n\t" 5707 "jnz done\n\t" 5708 "movl $dst, 32\n" 5709 "done:" %} 5710 ins_encode %{ 5711 Register Rdst = $dst$$Register; 5712 Label done; 5713 __ bsfl(Rdst, $src$$Register); 5714 __ jccb(Assembler::notZero, done); 5715 __ movl(Rdst, BitsPerInt); 5716 __ bind(done); 5717 %} 5718 ins_pipe(ialu_reg); 5719 %} 5720 5721 instruct countTrailingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 5722 predicate(UseCountTrailingZerosInstruction); 5723 match(Set dst (CountTrailingZerosL src)); 5724 effect(KILL cr); 5725 5726 format %{ "tzcntq $dst, $src\t# count trailing zeros (long)" %} 5727 ins_encode %{ 5728 __ tzcntq($dst$$Register, $src$$Register); 5729 %} 5730 ins_pipe(ialu_reg); 5731 %} 5732 5733 instruct countTrailingZerosL_mem(rRegI dst, memory src, rFlagsReg cr) %{ 5734 predicate(UseCountTrailingZerosInstruction); 5735 match(Set dst (CountTrailingZerosL (LoadL src))); 5736 effect(KILL cr); 5737 ins_cost(175); 5738 format %{ "tzcntq $dst, $src\t# count trailing zeros (long)" %} 5739 ins_encode %{ 5740 __ tzcntq($dst$$Register, $src$$Address); 5741 %} 5742 ins_pipe(ialu_reg_mem); 5743 %} 5744 5745 instruct countTrailingZerosL_bsf(rRegI dst, rRegL src, rFlagsReg cr) %{ 5746 predicate(!UseCountTrailingZerosInstruction); 5747 match(Set dst (CountTrailingZerosL src)); 5748 effect(KILL cr); 5749 5750 format %{ "bsfq $dst, $src\t# count trailing zeros (long)\n\t" 5751 "jnz done\n\t" 5752 "movl $dst, 64\n" 5753 "done:" %} 5754 ins_encode %{ 5755 Register Rdst = $dst$$Register; 5756 Label done; 5757 __ bsfq(Rdst, $src$$Register); 5758 __ jccb(Assembler::notZero, done); 5759 __ movl(Rdst, BitsPerLong); 5760 __ bind(done); 5761 %} 5762 ins_pipe(ialu_reg); 5763 %} 5764 5765 //--------------- Reverse Operation Instructions ---------------- 5766 instruct bytes_reversebit_int(rRegI dst, rRegI src, rRegI rtmp, rFlagsReg cr) %{ 5767 predicate(!VM_Version::supports_gfni()); 5768 match(Set dst (ReverseI src)); 5769 effect(TEMP dst, TEMP rtmp, KILL cr); 5770 format %{ "reverse_int $dst $src\t! using $rtmp as TEMP" %} 5771 ins_encode %{ 5772 __ reverseI($dst$$Register, $src$$Register, xnoreg, xnoreg, $rtmp$$Register); 5773 %} 5774 ins_pipe( ialu_reg ); 5775 %} 5776 5777 instruct bytes_reversebit_int_gfni(rRegI dst, rRegI src, vlRegF xtmp1, vlRegF xtmp2, rRegL rtmp, rFlagsReg cr) %{ 5778 predicate(VM_Version::supports_gfni()); 5779 match(Set dst (ReverseI src)); 5780 effect(TEMP dst, TEMP xtmp1, TEMP xtmp2, TEMP rtmp, KILL cr); 5781 format %{ "reverse_int $dst $src\t! using $rtmp, $xtmp1 and $xtmp2 as TEMP" %} 5782 ins_encode %{ 5783 __ reverseI($dst$$Register, $src$$Register, $xtmp1$$XMMRegister, $xtmp2$$XMMRegister, $rtmp$$Register); 5784 %} 5785 ins_pipe( ialu_reg ); 5786 %} 5787 5788 instruct bytes_reversebit_long(rRegL dst, rRegL src, rRegL rtmp1, rRegL rtmp2, rFlagsReg cr) %{ 5789 predicate(!VM_Version::supports_gfni()); 5790 match(Set dst (ReverseL src)); 5791 effect(TEMP dst, TEMP rtmp1, TEMP rtmp2, KILL cr); 5792 format %{ "reverse_long $dst $src\t! using $rtmp1 and $rtmp2 as TEMP" %} 5793 ins_encode %{ 5794 __ reverseL($dst$$Register, $src$$Register, xnoreg, xnoreg, $rtmp1$$Register, $rtmp2$$Register); 5795 %} 5796 ins_pipe( ialu_reg ); 5797 %} 5798 5799 instruct bytes_reversebit_long_gfni(rRegL dst, rRegL src, vlRegD xtmp1, vlRegD xtmp2, rRegL rtmp, rFlagsReg cr) %{ 5800 predicate(VM_Version::supports_gfni()); 5801 match(Set dst (ReverseL src)); 5802 effect(TEMP dst, TEMP xtmp1, TEMP xtmp2, TEMP rtmp, KILL cr); 5803 format %{ "reverse_long $dst $src\t! using $rtmp, $xtmp1 and $xtmp2 as TEMP" %} 5804 ins_encode %{ 5805 __ reverseL($dst$$Register, $src$$Register, $xtmp1$$XMMRegister, $xtmp2$$XMMRegister, $rtmp$$Register, noreg); 5806 %} 5807 ins_pipe( ialu_reg ); 5808 %} 5809 5810 //---------- Population Count Instructions ------------------------------------- 5811 5812 instruct popCountI(rRegI dst, rRegI src, rFlagsReg cr) %{ 5813 predicate(UsePopCountInstruction); 5814 match(Set dst (PopCountI src)); 5815 effect(KILL cr); 5816 5817 format %{ "popcnt $dst, $src" %} 5818 ins_encode %{ 5819 __ popcntl($dst$$Register, $src$$Register); 5820 %} 5821 ins_pipe(ialu_reg); 5822 %} 5823 5824 instruct popCountI_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 5825 predicate(UsePopCountInstruction); 5826 match(Set dst (PopCountI (LoadI mem))); 5827 effect(KILL cr); 5828 5829 format %{ "popcnt $dst, $mem" %} 5830 ins_encode %{ 5831 __ popcntl($dst$$Register, $mem$$Address); 5832 %} 5833 ins_pipe(ialu_reg); 5834 %} 5835 5836 // Note: Long.bitCount(long) returns an int. 5837 instruct popCountL(rRegI dst, rRegL src, rFlagsReg cr) %{ 5838 predicate(UsePopCountInstruction); 5839 match(Set dst (PopCountL src)); 5840 effect(KILL cr); 5841 5842 format %{ "popcnt $dst, $src" %} 5843 ins_encode %{ 5844 __ popcntq($dst$$Register, $src$$Register); 5845 %} 5846 ins_pipe(ialu_reg); 5847 %} 5848 5849 // Note: Long.bitCount(long) returns an int. 5850 instruct popCountL_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 5851 predicate(UsePopCountInstruction); 5852 match(Set dst (PopCountL (LoadL mem))); 5853 effect(KILL cr); 5854 5855 format %{ "popcnt $dst, $mem" %} 5856 ins_encode %{ 5857 __ popcntq($dst$$Register, $mem$$Address); 5858 %} 5859 ins_pipe(ialu_reg); 5860 %} 5861 5862 5863 //----------MemBar Instructions----------------------------------------------- 5864 // Memory barrier flavors 5865 5866 instruct membar_acquire() 5867 %{ 5868 match(MemBarAcquire); 5869 match(LoadFence); 5870 ins_cost(0); 5871 5872 size(0); 5873 format %{ "MEMBAR-acquire ! (empty encoding)" %} 5874 ins_encode(); 5875 ins_pipe(empty); 5876 %} 5877 5878 instruct membar_acquire_lock() 5879 %{ 5880 match(MemBarAcquireLock); 5881 ins_cost(0); 5882 5883 size(0); 5884 format %{ "MEMBAR-acquire (prior CMPXCHG in FastLock so empty encoding)" %} 5885 ins_encode(); 5886 ins_pipe(empty); 5887 %} 5888 5889 instruct membar_release() 5890 %{ 5891 match(MemBarRelease); 5892 match(StoreFence); 5893 ins_cost(0); 5894 5895 size(0); 5896 format %{ "MEMBAR-release ! (empty encoding)" %} 5897 ins_encode(); 5898 ins_pipe(empty); 5899 %} 5900 5901 instruct membar_release_lock() 5902 %{ 5903 match(MemBarReleaseLock); 5904 ins_cost(0); 5905 5906 size(0); 5907 format %{ "MEMBAR-release (a FastUnlock follows so empty encoding)" %} 5908 ins_encode(); 5909 ins_pipe(empty); 5910 %} 5911 5912 instruct membar_volatile(rFlagsReg cr) %{ 5913 match(MemBarVolatile); 5914 effect(KILL cr); 5915 ins_cost(400); 5916 5917 format %{ 5918 $$template 5919 $$emit$$"lock addl [rsp + #0], 0\t! membar_volatile" 5920 %} 5921 ins_encode %{ 5922 __ membar(Assembler::StoreLoad); 5923 %} 5924 ins_pipe(pipe_slow); 5925 %} 5926 5927 instruct unnecessary_membar_volatile() 5928 %{ 5929 match(MemBarVolatile); 5930 predicate(Matcher::post_store_load_barrier(n)); 5931 ins_cost(0); 5932 5933 size(0); 5934 format %{ "MEMBAR-volatile (unnecessary so empty encoding)" %} 5935 ins_encode(); 5936 ins_pipe(empty); 5937 %} 5938 5939 instruct membar_storestore() %{ 5940 match(MemBarStoreStore); 5941 match(StoreStoreFence); 5942 ins_cost(0); 5943 5944 size(0); 5945 format %{ "MEMBAR-storestore (empty encoding)" %} 5946 ins_encode( ); 5947 ins_pipe(empty); 5948 %} 5949 5950 //----------Move Instructions-------------------------------------------------- 5951 5952 instruct castX2P(rRegP dst, rRegL src) 5953 %{ 5954 match(Set dst (CastX2P src)); 5955 5956 format %{ "movq $dst, $src\t# long->ptr" %} 5957 ins_encode %{ 5958 if ($dst$$reg != $src$$reg) { 5959 __ movptr($dst$$Register, $src$$Register); 5960 } 5961 %} 5962 ins_pipe(ialu_reg_reg); // XXX 5963 %} 5964 5965 instruct castN2X(rRegL dst, rRegN src) 5966 %{ 5967 match(Set dst (CastP2X src)); 5968 5969 format %{ "movq $dst, $src\t# ptr -> long" %} 5970 ins_encode %{ 5971 if ($dst$$reg != $src$$reg) { 5972 __ movptr($dst$$Register, $src$$Register); 5973 } 5974 %} 5975 ins_pipe(ialu_reg_reg); // XXX 5976 %} 5977 5978 instruct castP2X(rRegL dst, rRegP src) 5979 %{ 5980 match(Set dst (CastP2X src)); 5981 5982 format %{ "movq $dst, $src\t# ptr -> long" %} 5983 ins_encode %{ 5984 if ($dst$$reg != $src$$reg) { 5985 __ movptr($dst$$Register, $src$$Register); 5986 } 5987 %} 5988 ins_pipe(ialu_reg_reg); // XXX 5989 %} 5990 5991 // Convert oop into int for vectors alignment masking 5992 instruct convP2I(rRegI dst, rRegP src) 5993 %{ 5994 match(Set dst (ConvL2I (CastP2X src))); 5995 5996 format %{ "movl $dst, $src\t# ptr -> int" %} 5997 ins_encode %{ 5998 __ movl($dst$$Register, $src$$Register); 5999 %} 6000 ins_pipe(ialu_reg_reg); // XXX 6001 %} 6002 6003 // Convert compressed oop into int for vectors alignment masking 6004 // in case of 32bit oops (heap < 4Gb). 6005 instruct convN2I(rRegI dst, rRegN src) 6006 %{ 6007 predicate(CompressedOops::shift() == 0); 6008 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 6009 6010 format %{ "movl $dst, $src\t# compressed ptr -> int" %} 6011 ins_encode %{ 6012 __ movl($dst$$Register, $src$$Register); 6013 %} 6014 ins_pipe(ialu_reg_reg); // XXX 6015 %} 6016 6017 // Convert oop pointer into compressed form 6018 instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{ 6019 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 6020 match(Set dst (EncodeP src)); 6021 effect(KILL cr); 6022 format %{ "encode_heap_oop $dst,$src" %} 6023 ins_encode %{ 6024 Register s = $src$$Register; 6025 Register d = $dst$$Register; 6026 if (s != d) { 6027 __ movq(d, s); 6028 } 6029 __ encode_heap_oop(d); 6030 %} 6031 ins_pipe(ialu_reg_long); 6032 %} 6033 6034 instruct encodeHeapOop_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6035 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 6036 match(Set dst (EncodeP src)); 6037 effect(KILL cr); 6038 format %{ "encode_heap_oop_not_null $dst,$src" %} 6039 ins_encode %{ 6040 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 6041 %} 6042 ins_pipe(ialu_reg_long); 6043 %} 6044 6045 instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{ 6046 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 6047 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 6048 match(Set dst (DecodeN src)); 6049 effect(KILL cr); 6050 format %{ "decode_heap_oop $dst,$src" %} 6051 ins_encode %{ 6052 Register s = $src$$Register; 6053 Register d = $dst$$Register; 6054 if (s != d) { 6055 __ movq(d, s); 6056 } 6057 __ decode_heap_oop(d); 6058 %} 6059 ins_pipe(ialu_reg_long); 6060 %} 6061 6062 instruct decodeHeapOop_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6063 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 6064 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 6065 match(Set dst (DecodeN src)); 6066 effect(KILL cr); 6067 format %{ "decode_heap_oop_not_null $dst,$src" %} 6068 ins_encode %{ 6069 Register s = $src$$Register; 6070 Register d = $dst$$Register; 6071 if (s != d) { 6072 __ decode_heap_oop_not_null(d, s); 6073 } else { 6074 __ decode_heap_oop_not_null(d); 6075 } 6076 %} 6077 ins_pipe(ialu_reg_long); 6078 %} 6079 6080 instruct encodeKlass_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6081 match(Set dst (EncodePKlass src)); 6082 effect(TEMP dst, KILL cr); 6083 format %{ "encode_and_move_klass_not_null $dst,$src" %} 6084 ins_encode %{ 6085 __ encode_and_move_klass_not_null($dst$$Register, $src$$Register); 6086 %} 6087 ins_pipe(ialu_reg_long); 6088 %} 6089 6090 instruct decodeKlass_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6091 match(Set dst (DecodeNKlass src)); 6092 effect(TEMP dst, KILL cr); 6093 format %{ "decode_and_move_klass_not_null $dst,$src" %} 6094 ins_encode %{ 6095 __ decode_and_move_klass_not_null($dst$$Register, $src$$Register); 6096 %} 6097 ins_pipe(ialu_reg_long); 6098 %} 6099 6100 //----------Conditional Move--------------------------------------------------- 6101 // Jump 6102 // dummy instruction for generating temp registers 6103 instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{ 6104 match(Jump (LShiftL switch_val shift)); 6105 ins_cost(350); 6106 predicate(false); 6107 effect(TEMP dest); 6108 6109 format %{ "leaq $dest, [$constantaddress]\n\t" 6110 "jmp [$dest + $switch_val << $shift]\n\t" %} 6111 ins_encode %{ 6112 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6113 // to do that and the compiler is using that register as one it can allocate. 6114 // So we build it all by hand. 6115 // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant); 6116 // ArrayAddress dispatch(table, index); 6117 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant); 6118 __ lea($dest$$Register, $constantaddress); 6119 __ jmp(dispatch); 6120 %} 6121 ins_pipe(pipe_jmp); 6122 %} 6123 6124 instruct jumpXtnd_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{ 6125 match(Jump (AddL (LShiftL switch_val shift) offset)); 6126 ins_cost(350); 6127 effect(TEMP dest); 6128 6129 format %{ "leaq $dest, [$constantaddress]\n\t" 6130 "jmp [$dest + $switch_val << $shift + $offset]\n\t" %} 6131 ins_encode %{ 6132 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6133 // to do that and the compiler is using that register as one it can allocate. 6134 // So we build it all by hand. 6135 // Address index(noreg, switch_reg, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6136 // ArrayAddress dispatch(table, index); 6137 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6138 __ lea($dest$$Register, $constantaddress); 6139 __ jmp(dispatch); 6140 %} 6141 ins_pipe(pipe_jmp); 6142 %} 6143 6144 instruct jumpXtnd(rRegL switch_val, rRegI dest) %{ 6145 match(Jump switch_val); 6146 ins_cost(350); 6147 effect(TEMP dest); 6148 6149 format %{ "leaq $dest, [$constantaddress]\n\t" 6150 "jmp [$dest + $switch_val]\n\t" %} 6151 ins_encode %{ 6152 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6153 // to do that and the compiler is using that register as one it can allocate. 6154 // So we build it all by hand. 6155 // Address index(noreg, switch_reg, Address::times_1); 6156 // ArrayAddress dispatch(table, index); 6157 Address dispatch($dest$$Register, $switch_val$$Register, Address::times_1); 6158 __ lea($dest$$Register, $constantaddress); 6159 __ jmp(dispatch); 6160 %} 6161 ins_pipe(pipe_jmp); 6162 %} 6163 6164 // Conditional move 6165 instruct cmovI_imm_01(rRegI dst, immI_1 src, rFlagsReg cr, cmpOp cop) 6166 %{ 6167 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_int() == 0); 6168 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6169 6170 ins_cost(100); // XXX 6171 format %{ "setbn$cop $dst\t# signed, int" %} 6172 ins_encode %{ 6173 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6174 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6175 %} 6176 ins_pipe(ialu_reg); 6177 %} 6178 6179 instruct cmovI_reg(rRegI dst, rRegI src, rFlagsReg cr, cmpOp cop) 6180 %{ 6181 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6182 6183 ins_cost(200); // XXX 6184 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6185 ins_encode %{ 6186 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6187 %} 6188 ins_pipe(pipe_cmov_reg); 6189 %} 6190 6191 instruct cmovI_imm_01U(rRegI dst, immI_1 src, rFlagsRegU cr, cmpOpU cop) 6192 %{ 6193 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_int() == 0); 6194 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6195 6196 ins_cost(100); // XXX 6197 format %{ "setbn$cop $dst\t# unsigned, int" %} 6198 ins_encode %{ 6199 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6200 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6201 %} 6202 ins_pipe(ialu_reg); 6203 %} 6204 6205 instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{ 6206 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6207 6208 ins_cost(200); // XXX 6209 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6210 ins_encode %{ 6211 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6212 %} 6213 ins_pipe(pipe_cmov_reg); 6214 %} 6215 6216 instruct cmovI_imm_01UCF(rRegI dst, immI_1 src, rFlagsRegUCF cr, cmpOpUCF cop) 6217 %{ 6218 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_int() == 0); 6219 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6220 6221 ins_cost(100); // XXX 6222 format %{ "setbn$cop $dst\t# unsigned, int" %} 6223 ins_encode %{ 6224 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6225 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6226 %} 6227 ins_pipe(ialu_reg); 6228 %} 6229 6230 instruct cmovI_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6231 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6232 ins_cost(200); 6233 expand %{ 6234 cmovI_regU(cop, cr, dst, src); 6235 %} 6236 %} 6237 6238 instruct cmovI_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6239 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6240 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6241 6242 ins_cost(200); // XXX 6243 format %{ "cmovpl $dst, $src\n\t" 6244 "cmovnel $dst, $src" %} 6245 ins_encode %{ 6246 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6247 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6248 %} 6249 ins_pipe(pipe_cmov_reg); 6250 %} 6251 6252 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6253 // inputs of the CMove 6254 instruct cmovI_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6255 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6256 match(Set dst (CMoveI (Binary cop cr) (Binary src dst))); 6257 6258 ins_cost(200); // XXX 6259 format %{ "cmovpl $dst, $src\n\t" 6260 "cmovnel $dst, $src" %} 6261 ins_encode %{ 6262 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6263 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6264 %} 6265 ins_pipe(pipe_cmov_reg); 6266 %} 6267 6268 // Conditional move 6269 instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{ 6270 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6271 6272 ins_cost(250); // XXX 6273 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6274 ins_encode %{ 6275 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6276 %} 6277 ins_pipe(pipe_cmov_mem); 6278 %} 6279 6280 // Conditional move 6281 instruct cmovI_memU(cmpOpU cop, rFlagsRegU cr, rRegI dst, memory src) 6282 %{ 6283 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6284 6285 ins_cost(250); // XXX 6286 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6287 ins_encode %{ 6288 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6289 %} 6290 ins_pipe(pipe_cmov_mem); 6291 %} 6292 6293 instruct cmovI_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, memory src) %{ 6294 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6295 ins_cost(250); 6296 expand %{ 6297 cmovI_memU(cop, cr, dst, src); 6298 %} 6299 %} 6300 6301 // Conditional move 6302 instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop) 6303 %{ 6304 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6305 6306 ins_cost(200); // XXX 6307 format %{ "cmovl$cop $dst, $src\t# signed, compressed ptr" %} 6308 ins_encode %{ 6309 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6310 %} 6311 ins_pipe(pipe_cmov_reg); 6312 %} 6313 6314 // Conditional move 6315 instruct cmovN_regU(cmpOpU cop, rFlagsRegU cr, rRegN dst, rRegN src) 6316 %{ 6317 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6318 6319 ins_cost(200); // XXX 6320 format %{ "cmovl$cop $dst, $src\t# unsigned, compressed ptr" %} 6321 ins_encode %{ 6322 __ cmovl((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6323 %} 6324 ins_pipe(pipe_cmov_reg); 6325 %} 6326 6327 instruct cmovN_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6328 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6329 ins_cost(200); 6330 expand %{ 6331 cmovN_regU(cop, cr, dst, src); 6332 %} 6333 %} 6334 6335 instruct cmovN_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6336 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6337 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6338 6339 ins_cost(200); // XXX 6340 format %{ "cmovpl $dst, $src\n\t" 6341 "cmovnel $dst, $src" %} 6342 ins_encode %{ 6343 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6344 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6345 %} 6346 ins_pipe(pipe_cmov_reg); 6347 %} 6348 6349 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6350 // inputs of the CMove 6351 instruct cmovN_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6352 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6353 match(Set dst (CMoveN (Binary cop cr) (Binary src dst))); 6354 6355 ins_cost(200); // XXX 6356 format %{ "cmovpl $dst, $src\n\t" 6357 "cmovnel $dst, $src" %} 6358 ins_encode %{ 6359 __ cmovl(Assembler::parity, $dst$$Register, $src$$Register); 6360 __ cmovl(Assembler::notEqual, $dst$$Register, $src$$Register); 6361 %} 6362 ins_pipe(pipe_cmov_reg); 6363 %} 6364 6365 // Conditional move 6366 instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop) 6367 %{ 6368 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6369 6370 ins_cost(200); // XXX 6371 format %{ "cmovq$cop $dst, $src\t# signed, ptr" %} 6372 ins_encode %{ 6373 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6374 %} 6375 ins_pipe(pipe_cmov_reg); // XXX 6376 %} 6377 6378 // Conditional move 6379 instruct cmovP_regU(cmpOpU cop, rFlagsRegU cr, rRegP dst, rRegP src) 6380 %{ 6381 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6382 6383 ins_cost(200); // XXX 6384 format %{ "cmovq$cop $dst, $src\t# unsigned, ptr" %} 6385 ins_encode %{ 6386 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6387 %} 6388 ins_pipe(pipe_cmov_reg); // XXX 6389 %} 6390 6391 instruct cmovP_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6392 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6393 ins_cost(200); 6394 expand %{ 6395 cmovP_regU(cop, cr, dst, src); 6396 %} 6397 %} 6398 6399 instruct cmovP_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6400 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6401 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6402 6403 ins_cost(200); // XXX 6404 format %{ "cmovpq $dst, $src\n\t" 6405 "cmovneq $dst, $src" %} 6406 ins_encode %{ 6407 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6408 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6409 %} 6410 ins_pipe(pipe_cmov_reg); 6411 %} 6412 6413 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6414 // inputs of the CMove 6415 instruct cmovP_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6416 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6417 match(Set dst (CMoveP (Binary cop cr) (Binary src dst))); 6418 6419 ins_cost(200); // XXX 6420 format %{ "cmovpq $dst, $src\n\t" 6421 "cmovneq $dst, $src" %} 6422 ins_encode %{ 6423 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6424 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6425 %} 6426 ins_pipe(pipe_cmov_reg); 6427 %} 6428 6429 instruct cmovL_imm_01(rRegL dst, immL1 src, rFlagsReg cr, cmpOp cop) 6430 %{ 6431 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_long() == 0); 6432 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6433 6434 ins_cost(100); // XXX 6435 format %{ "setbn$cop $dst\t# signed, long" %} 6436 ins_encode %{ 6437 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6438 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6439 %} 6440 ins_pipe(ialu_reg); 6441 %} 6442 6443 instruct cmovL_reg(cmpOp cop, rFlagsReg cr, rRegL dst, rRegL src) 6444 %{ 6445 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6446 6447 ins_cost(200); // XXX 6448 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6449 ins_encode %{ 6450 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6451 %} 6452 ins_pipe(pipe_cmov_reg); // XXX 6453 %} 6454 6455 instruct cmovL_mem(cmpOp cop, rFlagsReg cr, rRegL dst, memory src) 6456 %{ 6457 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6458 6459 ins_cost(200); // XXX 6460 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6461 ins_encode %{ 6462 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6463 %} 6464 ins_pipe(pipe_cmov_mem); // XXX 6465 %} 6466 6467 instruct cmovL_imm_01U(rRegL dst, immL1 src, rFlagsRegU cr, cmpOpU cop) 6468 %{ 6469 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_long() == 0); 6470 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6471 6472 ins_cost(100); // XXX 6473 format %{ "setbn$cop $dst\t# unsigned, long" %} 6474 ins_encode %{ 6475 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6476 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6477 %} 6478 ins_pipe(ialu_reg); 6479 %} 6480 6481 instruct cmovL_regU(cmpOpU cop, rFlagsRegU cr, rRegL dst, rRegL src) 6482 %{ 6483 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6484 6485 ins_cost(200); // XXX 6486 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 6487 ins_encode %{ 6488 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Register); 6489 %} 6490 ins_pipe(pipe_cmov_reg); // XXX 6491 %} 6492 6493 instruct cmovL_imm_01UCF(rRegL dst, immL1 src, rFlagsRegUCF cr, cmpOpUCF cop) 6494 %{ 6495 predicate(n->in(2)->in(2)->is_Con() && n->in(2)->in(2)->get_long() == 0); 6496 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6497 6498 ins_cost(100); // XXX 6499 format %{ "setbn$cop $dst\t# unsigned, long" %} 6500 ins_encode %{ 6501 Assembler::Condition cond = (Assembler::Condition)($cop$$cmpcode); 6502 __ setb(MacroAssembler::negate_condition(cond), $dst$$Register); 6503 %} 6504 ins_pipe(ialu_reg); 6505 %} 6506 6507 instruct cmovL_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6508 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6509 ins_cost(200); 6510 expand %{ 6511 cmovL_regU(cop, cr, dst, src); 6512 %} 6513 %} 6514 6515 instruct cmovL_regUCF2_ne(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6516 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::ne); 6517 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6518 6519 ins_cost(200); // XXX 6520 format %{ "cmovpq $dst, $src\n\t" 6521 "cmovneq $dst, $src" %} 6522 ins_encode %{ 6523 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6524 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6525 %} 6526 ins_pipe(pipe_cmov_reg); 6527 %} 6528 6529 // Since (x == y) == !(x != y), we can flip the sense of the test by flipping the 6530 // inputs of the CMove 6531 instruct cmovL_regUCF2_eq(cmpOpUCF2 cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6532 predicate(n->in(1)->in(1)->as_Bool()->_test._test == BoolTest::eq); 6533 match(Set dst (CMoveL (Binary cop cr) (Binary src dst))); 6534 6535 ins_cost(200); // XXX 6536 format %{ "cmovpq $dst, $src\n\t" 6537 "cmovneq $dst, $src" %} 6538 ins_encode %{ 6539 __ cmovq(Assembler::parity, $dst$$Register, $src$$Register); 6540 __ cmovq(Assembler::notEqual, $dst$$Register, $src$$Register); 6541 %} 6542 ins_pipe(pipe_cmov_reg); 6543 %} 6544 6545 instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src) 6546 %{ 6547 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6548 6549 ins_cost(200); // XXX 6550 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 6551 ins_encode %{ 6552 __ cmovq((Assembler::Condition)($cop$$cmpcode), $dst$$Register, $src$$Address); 6553 %} 6554 ins_pipe(pipe_cmov_mem); // XXX 6555 %} 6556 6557 instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{ 6558 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6559 ins_cost(200); 6560 expand %{ 6561 cmovL_memU(cop, cr, dst, src); 6562 %} 6563 %} 6564 6565 instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src) 6566 %{ 6567 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6568 6569 ins_cost(200); // XXX 6570 format %{ "jn$cop skip\t# signed cmove float\n\t" 6571 "movss $dst, $src\n" 6572 "skip:" %} 6573 ins_encode %{ 6574 Label Lskip; 6575 // Invert sense of branch from sense of CMOV 6576 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6577 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 6578 __ bind(Lskip); 6579 %} 6580 ins_pipe(pipe_slow); 6581 %} 6582 6583 instruct cmovF_regU(cmpOpU cop, rFlagsRegU cr, regF dst, regF src) 6584 %{ 6585 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6586 6587 ins_cost(200); // XXX 6588 format %{ "jn$cop skip\t# unsigned cmove float\n\t" 6589 "movss $dst, $src\n" 6590 "skip:" %} 6591 ins_encode %{ 6592 Label Lskip; 6593 // Invert sense of branch from sense of CMOV 6594 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6595 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 6596 __ bind(Lskip); 6597 %} 6598 ins_pipe(pipe_slow); 6599 %} 6600 6601 instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{ 6602 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6603 ins_cost(200); 6604 expand %{ 6605 cmovF_regU(cop, cr, dst, src); 6606 %} 6607 %} 6608 6609 instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src) 6610 %{ 6611 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6612 6613 ins_cost(200); // XXX 6614 format %{ "jn$cop skip\t# signed cmove double\n\t" 6615 "movsd $dst, $src\n" 6616 "skip:" %} 6617 ins_encode %{ 6618 Label Lskip; 6619 // Invert sense of branch from sense of CMOV 6620 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6621 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 6622 __ bind(Lskip); 6623 %} 6624 ins_pipe(pipe_slow); 6625 %} 6626 6627 instruct cmovD_regU(cmpOpU cop, rFlagsRegU cr, regD dst, regD src) 6628 %{ 6629 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6630 6631 ins_cost(200); // XXX 6632 format %{ "jn$cop skip\t# unsigned cmove double\n\t" 6633 "movsd $dst, $src\n" 6634 "skip:" %} 6635 ins_encode %{ 6636 Label Lskip; 6637 // Invert sense of branch from sense of CMOV 6638 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6639 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 6640 __ bind(Lskip); 6641 %} 6642 ins_pipe(pipe_slow); 6643 %} 6644 6645 instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{ 6646 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6647 ins_cost(200); 6648 expand %{ 6649 cmovD_regU(cop, cr, dst, src); 6650 %} 6651 %} 6652 6653 //----------Arithmetic Instructions-------------------------------------------- 6654 //----------Addition Instructions---------------------------------------------- 6655 6656 instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 6657 %{ 6658 match(Set dst (AddI dst src)); 6659 effect(KILL cr); 6660 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); 6661 format %{ "addl $dst, $src\t# int" %} 6662 ins_encode %{ 6663 __ addl($dst$$Register, $src$$Register); 6664 %} 6665 ins_pipe(ialu_reg_reg); 6666 %} 6667 6668 instruct addI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 6669 %{ 6670 match(Set dst (AddI dst src)); 6671 effect(KILL cr); 6672 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); 6673 6674 format %{ "addl $dst, $src\t# int" %} 6675 ins_encode %{ 6676 __ addl($dst$$Register, $src$$constant); 6677 %} 6678 ins_pipe( ialu_reg ); 6679 %} 6680 6681 instruct addI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 6682 %{ 6683 match(Set dst (AddI dst (LoadI src))); 6684 effect(KILL cr); 6685 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); 6686 6687 ins_cost(150); // XXX 6688 format %{ "addl $dst, $src\t# int" %} 6689 ins_encode %{ 6690 __ addl($dst$$Register, $src$$Address); 6691 %} 6692 ins_pipe(ialu_reg_mem); 6693 %} 6694 6695 instruct addI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 6696 %{ 6697 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6698 effect(KILL cr); 6699 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); 6700 6701 ins_cost(150); // XXX 6702 format %{ "addl $dst, $src\t# int" %} 6703 ins_encode %{ 6704 __ addl($dst$$Address, $src$$Register); 6705 %} 6706 ins_pipe(ialu_mem_reg); 6707 %} 6708 6709 instruct addI_mem_imm(memory dst, immI src, rFlagsReg cr) 6710 %{ 6711 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6712 effect(KILL cr); 6713 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); 6714 6715 6716 ins_cost(125); // XXX 6717 format %{ "addl $dst, $src\t# int" %} 6718 ins_encode %{ 6719 __ addl($dst$$Address, $src$$constant); 6720 %} 6721 ins_pipe(ialu_mem_imm); 6722 %} 6723 6724 instruct incI_rReg(rRegI dst, immI_1 src, rFlagsReg cr) 6725 %{ 6726 predicate(UseIncDec); 6727 match(Set dst (AddI dst src)); 6728 effect(KILL cr); 6729 6730 format %{ "incl $dst\t# int" %} 6731 ins_encode %{ 6732 __ incrementl($dst$$Register); 6733 %} 6734 ins_pipe(ialu_reg); 6735 %} 6736 6737 instruct incI_mem(memory dst, immI_1 src, rFlagsReg cr) 6738 %{ 6739 predicate(UseIncDec); 6740 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6741 effect(KILL cr); 6742 6743 ins_cost(125); // XXX 6744 format %{ "incl $dst\t# int" %} 6745 ins_encode %{ 6746 __ incrementl($dst$$Address); 6747 %} 6748 ins_pipe(ialu_mem_imm); 6749 %} 6750 6751 // XXX why does that use AddI 6752 instruct decI_rReg(rRegI dst, immI_M1 src, rFlagsReg cr) 6753 %{ 6754 predicate(UseIncDec); 6755 match(Set dst (AddI dst src)); 6756 effect(KILL cr); 6757 6758 format %{ "decl $dst\t# int" %} 6759 ins_encode %{ 6760 __ decrementl($dst$$Register); 6761 %} 6762 ins_pipe(ialu_reg); 6763 %} 6764 6765 // XXX why does that use AddI 6766 instruct decI_mem(memory dst, immI_M1 src, rFlagsReg cr) 6767 %{ 6768 predicate(UseIncDec); 6769 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6770 effect(KILL cr); 6771 6772 ins_cost(125); // XXX 6773 format %{ "decl $dst\t# int" %} 6774 ins_encode %{ 6775 __ decrementl($dst$$Address); 6776 %} 6777 ins_pipe(ialu_mem_imm); 6778 %} 6779 6780 instruct leaI_rReg_immI2_immI(rRegI dst, rRegI index, immI2 scale, immI disp) 6781 %{ 6782 predicate(VM_Version::supports_fast_2op_lea()); 6783 match(Set dst (AddI (LShiftI index scale) disp)); 6784 6785 format %{ "leal $dst, [$index << $scale + $disp]\t# int" %} 6786 ins_encode %{ 6787 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 6788 __ leal($dst$$Register, Address(noreg, $index$$Register, scale, $disp$$constant)); 6789 %} 6790 ins_pipe(ialu_reg_reg); 6791 %} 6792 6793 instruct leaI_rReg_rReg_immI(rRegI dst, rRegI base, rRegI index, immI disp) 6794 %{ 6795 predicate(VM_Version::supports_fast_3op_lea()); 6796 match(Set dst (AddI (AddI base index) disp)); 6797 6798 format %{ "leal $dst, [$base + $index + $disp]\t# int" %} 6799 ins_encode %{ 6800 __ leal($dst$$Register, Address($base$$Register, $index$$Register, Address::times_1, $disp$$constant)); 6801 %} 6802 ins_pipe(ialu_reg_reg); 6803 %} 6804 6805 instruct leaI_rReg_rReg_immI2(rRegI dst, no_rbp_r13_RegI base, rRegI index, immI2 scale) 6806 %{ 6807 predicate(VM_Version::supports_fast_2op_lea()); 6808 match(Set dst (AddI base (LShiftI index scale))); 6809 6810 format %{ "leal $dst, [$base + $index << $scale]\t# int" %} 6811 ins_encode %{ 6812 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 6813 __ leal($dst$$Register, Address($base$$Register, $index$$Register, scale)); 6814 %} 6815 ins_pipe(ialu_reg_reg); 6816 %} 6817 6818 instruct leaI_rReg_rReg_immI2_immI(rRegI dst, rRegI base, rRegI index, immI2 scale, immI disp) 6819 %{ 6820 predicate(VM_Version::supports_fast_3op_lea()); 6821 match(Set dst (AddI (AddI base (LShiftI index scale)) disp)); 6822 6823 format %{ "leal $dst, [$base + $index << $scale + $disp]\t# int" %} 6824 ins_encode %{ 6825 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 6826 __ leal($dst$$Register, Address($base$$Register, $index$$Register, scale, $disp$$constant)); 6827 %} 6828 ins_pipe(ialu_reg_reg); 6829 %} 6830 6831 instruct addL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 6832 %{ 6833 match(Set dst (AddL dst src)); 6834 effect(KILL cr); 6835 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); 6836 6837 format %{ "addq $dst, $src\t# long" %} 6838 ins_encode %{ 6839 __ addq($dst$$Register, $src$$Register); 6840 %} 6841 ins_pipe(ialu_reg_reg); 6842 %} 6843 6844 instruct addL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 6845 %{ 6846 match(Set dst (AddL dst src)); 6847 effect(KILL cr); 6848 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); 6849 6850 format %{ "addq $dst, $src\t# long" %} 6851 ins_encode %{ 6852 __ addq($dst$$Register, $src$$constant); 6853 %} 6854 ins_pipe( ialu_reg ); 6855 %} 6856 6857 instruct addL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 6858 %{ 6859 match(Set dst (AddL dst (LoadL src))); 6860 effect(KILL cr); 6861 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); 6862 6863 ins_cost(150); // XXX 6864 format %{ "addq $dst, $src\t# long" %} 6865 ins_encode %{ 6866 __ addq($dst$$Register, $src$$Address); 6867 %} 6868 ins_pipe(ialu_reg_mem); 6869 %} 6870 6871 instruct addL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 6872 %{ 6873 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 6874 effect(KILL cr); 6875 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); 6876 6877 ins_cost(150); // XXX 6878 format %{ "addq $dst, $src\t# long" %} 6879 ins_encode %{ 6880 __ addq($dst$$Address, $src$$Register); 6881 %} 6882 ins_pipe(ialu_mem_reg); 6883 %} 6884 6885 instruct addL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 6886 %{ 6887 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 6888 effect(KILL cr); 6889 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); 6890 6891 ins_cost(125); // XXX 6892 format %{ "addq $dst, $src\t# long" %} 6893 ins_encode %{ 6894 __ addq($dst$$Address, $src$$constant); 6895 %} 6896 ins_pipe(ialu_mem_imm); 6897 %} 6898 6899 instruct incL_rReg(rRegI dst, immL1 src, rFlagsReg cr) 6900 %{ 6901 predicate(UseIncDec); 6902 match(Set dst (AddL dst src)); 6903 effect(KILL cr); 6904 6905 format %{ "incq $dst\t# long" %} 6906 ins_encode %{ 6907 __ incrementq($dst$$Register); 6908 %} 6909 ins_pipe(ialu_reg); 6910 %} 6911 6912 instruct incL_mem(memory dst, immL1 src, rFlagsReg cr) 6913 %{ 6914 predicate(UseIncDec); 6915 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 6916 effect(KILL cr); 6917 6918 ins_cost(125); // XXX 6919 format %{ "incq $dst\t# long" %} 6920 ins_encode %{ 6921 __ incrementq($dst$$Address); 6922 %} 6923 ins_pipe(ialu_mem_imm); 6924 %} 6925 6926 // XXX why does that use AddL 6927 instruct decL_rReg(rRegL dst, immL_M1 src, rFlagsReg cr) 6928 %{ 6929 predicate(UseIncDec); 6930 match(Set dst (AddL dst src)); 6931 effect(KILL cr); 6932 6933 format %{ "decq $dst\t# long" %} 6934 ins_encode %{ 6935 __ decrementq($dst$$Register); 6936 %} 6937 ins_pipe(ialu_reg); 6938 %} 6939 6940 // XXX why does that use AddL 6941 instruct decL_mem(memory dst, immL_M1 src, rFlagsReg cr) 6942 %{ 6943 predicate(UseIncDec); 6944 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 6945 effect(KILL cr); 6946 6947 ins_cost(125); // XXX 6948 format %{ "decq $dst\t# long" %} 6949 ins_encode %{ 6950 __ decrementq($dst$$Address); 6951 %} 6952 ins_pipe(ialu_mem_imm); 6953 %} 6954 6955 instruct leaL_rReg_immI2_immL32(rRegL dst, rRegL index, immI2 scale, immL32 disp) 6956 %{ 6957 predicate(VM_Version::supports_fast_2op_lea()); 6958 match(Set dst (AddL (LShiftL index scale) disp)); 6959 6960 format %{ "leaq $dst, [$index << $scale + $disp]\t# long" %} 6961 ins_encode %{ 6962 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 6963 __ leaq($dst$$Register, Address(noreg, $index$$Register, scale, $disp$$constant)); 6964 %} 6965 ins_pipe(ialu_reg_reg); 6966 %} 6967 6968 instruct leaL_rReg_rReg_immL32(rRegL dst, rRegL base, rRegL index, immL32 disp) 6969 %{ 6970 predicate(VM_Version::supports_fast_3op_lea()); 6971 match(Set dst (AddL (AddL base index) disp)); 6972 6973 format %{ "leaq $dst, [$base + $index + $disp]\t# long" %} 6974 ins_encode %{ 6975 __ leaq($dst$$Register, Address($base$$Register, $index$$Register, Address::times_1, $disp$$constant)); 6976 %} 6977 ins_pipe(ialu_reg_reg); 6978 %} 6979 6980 instruct leaL_rReg_rReg_immI2(rRegL dst, no_rbp_r13_RegL base, rRegL index, immI2 scale) 6981 %{ 6982 predicate(VM_Version::supports_fast_2op_lea()); 6983 match(Set dst (AddL base (LShiftL index scale))); 6984 6985 format %{ "leaq $dst, [$base + $index << $scale]\t# long" %} 6986 ins_encode %{ 6987 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 6988 __ leaq($dst$$Register, Address($base$$Register, $index$$Register, scale)); 6989 %} 6990 ins_pipe(ialu_reg_reg); 6991 %} 6992 6993 instruct leaL_rReg_rReg_immI2_immL32(rRegL dst, rRegL base, rRegL index, immI2 scale, immL32 disp) 6994 %{ 6995 predicate(VM_Version::supports_fast_3op_lea()); 6996 match(Set dst (AddL (AddL base (LShiftL index scale)) disp)); 6997 6998 format %{ "leaq $dst, [$base + $index << $scale + $disp]\t# long" %} 6999 ins_encode %{ 7000 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($scale$$constant); 7001 __ leaq($dst$$Register, Address($base$$Register, $index$$Register, scale, $disp$$constant)); 7002 %} 7003 ins_pipe(ialu_reg_reg); 7004 %} 7005 7006 instruct addP_rReg(rRegP dst, rRegL src, rFlagsReg cr) 7007 %{ 7008 match(Set dst (AddP dst src)); 7009 effect(KILL cr); 7010 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); 7011 7012 format %{ "addq $dst, $src\t# ptr" %} 7013 ins_encode %{ 7014 __ addq($dst$$Register, $src$$Register); 7015 %} 7016 ins_pipe(ialu_reg_reg); 7017 %} 7018 7019 instruct addP_rReg_imm(rRegP dst, immL32 src, rFlagsReg cr) 7020 %{ 7021 match(Set dst (AddP dst src)); 7022 effect(KILL cr); 7023 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); 7024 7025 format %{ "addq $dst, $src\t# ptr" %} 7026 ins_encode %{ 7027 __ addq($dst$$Register, $src$$constant); 7028 %} 7029 ins_pipe( ialu_reg ); 7030 %} 7031 7032 // XXX addP mem ops ???? 7033 7034 instruct checkCastPP(rRegP dst) 7035 %{ 7036 match(Set dst (CheckCastPP dst)); 7037 7038 size(0); 7039 format %{ "# checkcastPP of $dst" %} 7040 ins_encode(/* empty encoding */); 7041 ins_pipe(empty); 7042 %} 7043 7044 instruct castPP(rRegP dst) 7045 %{ 7046 match(Set dst (CastPP dst)); 7047 7048 size(0); 7049 format %{ "# castPP of $dst" %} 7050 ins_encode(/* empty encoding */); 7051 ins_pipe(empty); 7052 %} 7053 7054 instruct castII(rRegI dst) 7055 %{ 7056 match(Set dst (CastII dst)); 7057 7058 size(0); 7059 format %{ "# castII of $dst" %} 7060 ins_encode(/* empty encoding */); 7061 ins_cost(0); 7062 ins_pipe(empty); 7063 %} 7064 7065 instruct castLL(rRegL dst) 7066 %{ 7067 match(Set dst (CastLL dst)); 7068 7069 size(0); 7070 format %{ "# castLL of $dst" %} 7071 ins_encode(/* empty encoding */); 7072 ins_cost(0); 7073 ins_pipe(empty); 7074 %} 7075 7076 instruct castFF(regF dst) 7077 %{ 7078 match(Set dst (CastFF dst)); 7079 7080 size(0); 7081 format %{ "# castFF of $dst" %} 7082 ins_encode(/* empty encoding */); 7083 ins_cost(0); 7084 ins_pipe(empty); 7085 %} 7086 7087 instruct castDD(regD dst) 7088 %{ 7089 match(Set dst (CastDD dst)); 7090 7091 size(0); 7092 format %{ "# castDD of $dst" %} 7093 ins_encode(/* empty encoding */); 7094 ins_cost(0); 7095 ins_pipe(empty); 7096 %} 7097 7098 // XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them 7099 instruct compareAndSwapP(rRegI res, 7100 memory mem_ptr, 7101 rax_RegP oldval, rRegP newval, 7102 rFlagsReg cr) 7103 %{ 7104 predicate(n->as_LoadStore()->barrier_data() == 0); 7105 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); 7106 match(Set res (WeakCompareAndSwapP mem_ptr (Binary oldval newval))); 7107 effect(KILL cr, KILL oldval); 7108 7109 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7110 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7111 "sete $res\n\t" 7112 "movzbl $res, $res" %} 7113 ins_encode %{ 7114 __ lock(); 7115 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7116 __ setb(Assembler::equal, $res$$Register); 7117 __ movzbl($res$$Register, $res$$Register); 7118 %} 7119 ins_pipe( pipe_cmpxchg ); 7120 %} 7121 7122 instruct compareAndSwapL(rRegI res, 7123 memory mem_ptr, 7124 rax_RegL oldval, rRegL newval, 7125 rFlagsReg cr) 7126 %{ 7127 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval))); 7128 match(Set res (WeakCompareAndSwapL mem_ptr (Binary oldval newval))); 7129 effect(KILL cr, KILL oldval); 7130 7131 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7132 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7133 "sete $res\n\t" 7134 "movzbl $res, $res" %} 7135 ins_encode %{ 7136 __ lock(); 7137 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7138 __ setb(Assembler::equal, $res$$Register); 7139 __ movzbl($res$$Register, $res$$Register); 7140 %} 7141 ins_pipe( pipe_cmpxchg ); 7142 %} 7143 7144 instruct compareAndSwapI(rRegI res, 7145 memory mem_ptr, 7146 rax_RegI oldval, rRegI newval, 7147 rFlagsReg cr) 7148 %{ 7149 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval))); 7150 match(Set res (WeakCompareAndSwapI mem_ptr (Binary oldval newval))); 7151 effect(KILL cr, KILL oldval); 7152 7153 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7154 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7155 "sete $res\n\t" 7156 "movzbl $res, $res" %} 7157 ins_encode %{ 7158 __ lock(); 7159 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7160 __ setb(Assembler::equal, $res$$Register); 7161 __ movzbl($res$$Register, $res$$Register); 7162 %} 7163 ins_pipe( pipe_cmpxchg ); 7164 %} 7165 7166 instruct compareAndSwapB(rRegI res, 7167 memory mem_ptr, 7168 rax_RegI oldval, rRegI newval, 7169 rFlagsReg cr) 7170 %{ 7171 match(Set res (CompareAndSwapB mem_ptr (Binary oldval newval))); 7172 match(Set res (WeakCompareAndSwapB mem_ptr (Binary oldval newval))); 7173 effect(KILL cr, KILL oldval); 7174 7175 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7176 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7177 "sete $res\n\t" 7178 "movzbl $res, $res" %} 7179 ins_encode %{ 7180 __ lock(); 7181 __ cmpxchgb($newval$$Register, $mem_ptr$$Address); 7182 __ setb(Assembler::equal, $res$$Register); 7183 __ movzbl($res$$Register, $res$$Register); 7184 %} 7185 ins_pipe( pipe_cmpxchg ); 7186 %} 7187 7188 instruct compareAndSwapS(rRegI res, 7189 memory mem_ptr, 7190 rax_RegI oldval, rRegI newval, 7191 rFlagsReg cr) 7192 %{ 7193 match(Set res (CompareAndSwapS mem_ptr (Binary oldval newval))); 7194 match(Set res (WeakCompareAndSwapS mem_ptr (Binary oldval newval))); 7195 effect(KILL cr, KILL oldval); 7196 7197 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7198 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7199 "sete $res\n\t" 7200 "movzbl $res, $res" %} 7201 ins_encode %{ 7202 __ lock(); 7203 __ cmpxchgw($newval$$Register, $mem_ptr$$Address); 7204 __ setb(Assembler::equal, $res$$Register); 7205 __ movzbl($res$$Register, $res$$Register); 7206 %} 7207 ins_pipe( pipe_cmpxchg ); 7208 %} 7209 7210 instruct compareAndSwapN(rRegI res, 7211 memory mem_ptr, 7212 rax_RegN oldval, rRegN newval, 7213 rFlagsReg cr) %{ 7214 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval))); 7215 match(Set res (WeakCompareAndSwapN mem_ptr (Binary oldval newval))); 7216 effect(KILL cr, KILL oldval); 7217 7218 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7219 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7220 "sete $res\n\t" 7221 "movzbl $res, $res" %} 7222 ins_encode %{ 7223 __ lock(); 7224 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7225 __ setb(Assembler::equal, $res$$Register); 7226 __ movzbl($res$$Register, $res$$Register); 7227 %} 7228 ins_pipe( pipe_cmpxchg ); 7229 %} 7230 7231 instruct compareAndExchangeB( 7232 memory mem_ptr, 7233 rax_RegI oldval, rRegI newval, 7234 rFlagsReg cr) 7235 %{ 7236 match(Set oldval (CompareAndExchangeB mem_ptr (Binary oldval newval))); 7237 effect(KILL cr); 7238 7239 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7240 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7241 ins_encode %{ 7242 __ lock(); 7243 __ cmpxchgb($newval$$Register, $mem_ptr$$Address); 7244 %} 7245 ins_pipe( pipe_cmpxchg ); 7246 %} 7247 7248 instruct compareAndExchangeS( 7249 memory mem_ptr, 7250 rax_RegI oldval, rRegI newval, 7251 rFlagsReg cr) 7252 %{ 7253 match(Set oldval (CompareAndExchangeS mem_ptr (Binary oldval newval))); 7254 effect(KILL cr); 7255 7256 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7257 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7258 ins_encode %{ 7259 __ lock(); 7260 __ cmpxchgw($newval$$Register, $mem_ptr$$Address); 7261 %} 7262 ins_pipe( pipe_cmpxchg ); 7263 %} 7264 7265 instruct compareAndExchangeI( 7266 memory mem_ptr, 7267 rax_RegI oldval, rRegI newval, 7268 rFlagsReg cr) 7269 %{ 7270 match(Set oldval (CompareAndExchangeI mem_ptr (Binary oldval newval))); 7271 effect(KILL cr); 7272 7273 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7274 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7275 ins_encode %{ 7276 __ lock(); 7277 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7278 %} 7279 ins_pipe( pipe_cmpxchg ); 7280 %} 7281 7282 instruct compareAndExchangeL( 7283 memory mem_ptr, 7284 rax_RegL oldval, rRegL newval, 7285 rFlagsReg cr) 7286 %{ 7287 match(Set oldval (CompareAndExchangeL 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 compareAndExchangeN( 7300 memory mem_ptr, 7301 rax_RegN oldval, rRegN newval, 7302 rFlagsReg cr) %{ 7303 match(Set oldval (CompareAndExchangeN mem_ptr (Binary oldval newval))); 7304 effect(KILL cr); 7305 7306 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7307 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7308 ins_encode %{ 7309 __ lock(); 7310 __ cmpxchgl($newval$$Register, $mem_ptr$$Address); 7311 %} 7312 ins_pipe( pipe_cmpxchg ); 7313 %} 7314 7315 instruct compareAndExchangeP( 7316 memory mem_ptr, 7317 rax_RegP oldval, rRegP newval, 7318 rFlagsReg cr) 7319 %{ 7320 predicate(n->as_LoadStore()->barrier_data() == 0); 7321 match(Set oldval (CompareAndExchangeP mem_ptr (Binary oldval newval))); 7322 effect(KILL cr); 7323 7324 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7325 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 7326 ins_encode %{ 7327 __ lock(); 7328 __ cmpxchgq($newval$$Register, $mem_ptr$$Address); 7329 %} 7330 ins_pipe( pipe_cmpxchg ); 7331 %} 7332 7333 instruct xaddB_reg_no_res(memory mem, Universe dummy, rRegI add, rFlagsReg cr) %{ 7334 predicate(n->as_LoadStore()->result_not_used()); 7335 match(Set dummy (GetAndAddB mem add)); 7336 effect(KILL cr); 7337 format %{ "addb_lock $mem, $add" %} 7338 ins_encode %{ 7339 __ lock(); 7340 __ addb($mem$$Address, $add$$Register); 7341 %} 7342 ins_pipe(pipe_cmpxchg); 7343 %} 7344 7345 instruct xaddB_imm_no_res(memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7346 predicate(n->as_LoadStore()->result_not_used()); 7347 match(Set dummy (GetAndAddB mem add)); 7348 effect(KILL cr); 7349 format %{ "addb_lock $mem, $add" %} 7350 ins_encode %{ 7351 __ lock(); 7352 __ addb($mem$$Address, $add$$constant); 7353 %} 7354 ins_pipe(pipe_cmpxchg); 7355 %} 7356 7357 instruct xaddB(memory mem, rRegI newval, rFlagsReg cr) %{ 7358 predicate(!n->as_LoadStore()->result_not_used()); 7359 match(Set newval (GetAndAddB mem newval)); 7360 effect(KILL cr); 7361 format %{ "xaddb_lock $mem, $newval" %} 7362 ins_encode %{ 7363 __ lock(); 7364 __ xaddb($mem$$Address, $newval$$Register); 7365 %} 7366 ins_pipe(pipe_cmpxchg); 7367 %} 7368 7369 instruct xaddS_reg_no_res(memory mem, Universe dummy, rRegI add, rFlagsReg cr) %{ 7370 predicate(n->as_LoadStore()->result_not_used()); 7371 match(Set dummy (GetAndAddS mem add)); 7372 effect(KILL cr); 7373 format %{ "addw_lock $mem, $add" %} 7374 ins_encode %{ 7375 __ lock(); 7376 __ addw($mem$$Address, $add$$Register); 7377 %} 7378 ins_pipe(pipe_cmpxchg); 7379 %} 7380 7381 instruct xaddS_imm_no_res(memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7382 predicate(UseStoreImmI16 && n->as_LoadStore()->result_not_used()); 7383 match(Set dummy (GetAndAddS mem add)); 7384 effect(KILL cr); 7385 format %{ "addw_lock $mem, $add" %} 7386 ins_encode %{ 7387 __ lock(); 7388 __ addw($mem$$Address, $add$$constant); 7389 %} 7390 ins_pipe(pipe_cmpxchg); 7391 %} 7392 7393 instruct xaddS(memory mem, rRegI newval, rFlagsReg cr) %{ 7394 predicate(!n->as_LoadStore()->result_not_used()); 7395 match(Set newval (GetAndAddS mem newval)); 7396 effect(KILL cr); 7397 format %{ "xaddw_lock $mem, $newval" %} 7398 ins_encode %{ 7399 __ lock(); 7400 __ xaddw($mem$$Address, $newval$$Register); 7401 %} 7402 ins_pipe(pipe_cmpxchg); 7403 %} 7404 7405 instruct xaddI_reg_no_res(memory mem, Universe dummy, rRegI add, rFlagsReg cr) %{ 7406 predicate(n->as_LoadStore()->result_not_used()); 7407 match(Set dummy (GetAndAddI mem add)); 7408 effect(KILL cr); 7409 format %{ "addl_lock $mem, $add" %} 7410 ins_encode %{ 7411 __ lock(); 7412 __ addl($mem$$Address, $add$$Register); 7413 %} 7414 ins_pipe(pipe_cmpxchg); 7415 %} 7416 7417 instruct xaddI_imm_no_res(memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7418 predicate(n->as_LoadStore()->result_not_used()); 7419 match(Set dummy (GetAndAddI mem add)); 7420 effect(KILL cr); 7421 format %{ "addl_lock $mem, $add" %} 7422 ins_encode %{ 7423 __ lock(); 7424 __ addl($mem$$Address, $add$$constant); 7425 %} 7426 ins_pipe(pipe_cmpxchg); 7427 %} 7428 7429 instruct xaddI(memory mem, rRegI newval, rFlagsReg cr) %{ 7430 predicate(!n->as_LoadStore()->result_not_used()); 7431 match(Set newval (GetAndAddI mem newval)); 7432 effect(KILL cr); 7433 format %{ "xaddl_lock $mem, $newval" %} 7434 ins_encode %{ 7435 __ lock(); 7436 __ xaddl($mem$$Address, $newval$$Register); 7437 %} 7438 ins_pipe(pipe_cmpxchg); 7439 %} 7440 7441 instruct xaddL_reg_no_res(memory mem, Universe dummy, rRegL add, rFlagsReg cr) %{ 7442 predicate(n->as_LoadStore()->result_not_used()); 7443 match(Set dummy (GetAndAddL mem add)); 7444 effect(KILL cr); 7445 format %{ "addq_lock $mem, $add" %} 7446 ins_encode %{ 7447 __ lock(); 7448 __ addq($mem$$Address, $add$$Register); 7449 %} 7450 ins_pipe(pipe_cmpxchg); 7451 %} 7452 7453 instruct xaddL_imm_no_res(memory mem, Universe dummy, immL32 add, rFlagsReg cr) %{ 7454 predicate(n->as_LoadStore()->result_not_used()); 7455 match(Set dummy (GetAndAddL mem add)); 7456 effect(KILL cr); 7457 format %{ "addq_lock $mem, $add" %} 7458 ins_encode %{ 7459 __ lock(); 7460 __ addq($mem$$Address, $add$$constant); 7461 %} 7462 ins_pipe(pipe_cmpxchg); 7463 %} 7464 7465 instruct xaddL(memory mem, rRegL newval, rFlagsReg cr) %{ 7466 predicate(!n->as_LoadStore()->result_not_used()); 7467 match(Set newval (GetAndAddL mem newval)); 7468 effect(KILL cr); 7469 format %{ "xaddq_lock $mem, $newval" %} 7470 ins_encode %{ 7471 __ lock(); 7472 __ xaddq($mem$$Address, $newval$$Register); 7473 %} 7474 ins_pipe(pipe_cmpxchg); 7475 %} 7476 7477 instruct xchgB( memory mem, rRegI newval) %{ 7478 match(Set newval (GetAndSetB mem newval)); 7479 format %{ "XCHGB $newval,[$mem]" %} 7480 ins_encode %{ 7481 __ xchgb($newval$$Register, $mem$$Address); 7482 %} 7483 ins_pipe( pipe_cmpxchg ); 7484 %} 7485 7486 instruct xchgS( memory mem, rRegI newval) %{ 7487 match(Set newval (GetAndSetS mem newval)); 7488 format %{ "XCHGW $newval,[$mem]" %} 7489 ins_encode %{ 7490 __ xchgw($newval$$Register, $mem$$Address); 7491 %} 7492 ins_pipe( pipe_cmpxchg ); 7493 %} 7494 7495 instruct xchgI( memory mem, rRegI newval) %{ 7496 match(Set newval (GetAndSetI mem newval)); 7497 format %{ "XCHGL $newval,[$mem]" %} 7498 ins_encode %{ 7499 __ xchgl($newval$$Register, $mem$$Address); 7500 %} 7501 ins_pipe( pipe_cmpxchg ); 7502 %} 7503 7504 instruct xchgL( memory mem, rRegL newval) %{ 7505 match(Set newval (GetAndSetL mem newval)); 7506 format %{ "XCHGL $newval,[$mem]" %} 7507 ins_encode %{ 7508 __ xchgq($newval$$Register, $mem$$Address); 7509 %} 7510 ins_pipe( pipe_cmpxchg ); 7511 %} 7512 7513 instruct xchgP( memory mem, rRegP newval) %{ 7514 match(Set newval (GetAndSetP mem newval)); 7515 predicate(n->as_LoadStore()->barrier_data() == 0); 7516 format %{ "XCHGQ $newval,[$mem]" %} 7517 ins_encode %{ 7518 __ xchgq($newval$$Register, $mem$$Address); 7519 %} 7520 ins_pipe( pipe_cmpxchg ); 7521 %} 7522 7523 instruct xchgN( memory mem, rRegN newval) %{ 7524 match(Set newval (GetAndSetN mem newval)); 7525 format %{ "XCHGL $newval,$mem]" %} 7526 ins_encode %{ 7527 __ xchgl($newval$$Register, $mem$$Address); 7528 %} 7529 ins_pipe( pipe_cmpxchg ); 7530 %} 7531 7532 //----------Abs Instructions------------------------------------------- 7533 7534 // Integer Absolute Instructions 7535 instruct absI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7536 %{ 7537 match(Set dst (AbsI src)); 7538 effect(TEMP dst, KILL cr); 7539 format %{ "xorl $dst, $dst\t# abs int\n\t" 7540 "subl $dst, $src\n\t" 7541 "cmovll $dst, $src" %} 7542 ins_encode %{ 7543 __ xorl($dst$$Register, $dst$$Register); 7544 __ subl($dst$$Register, $src$$Register); 7545 __ cmovl(Assembler::less, $dst$$Register, $src$$Register); 7546 %} 7547 7548 ins_pipe(ialu_reg_reg); 7549 %} 7550 7551 // Long Absolute Instructions 7552 instruct absL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7553 %{ 7554 match(Set dst (AbsL src)); 7555 effect(TEMP dst, KILL cr); 7556 format %{ "xorl $dst, $dst\t# abs long\n\t" 7557 "subq $dst, $src\n\t" 7558 "cmovlq $dst, $src" %} 7559 ins_encode %{ 7560 __ xorl($dst$$Register, $dst$$Register); 7561 __ subq($dst$$Register, $src$$Register); 7562 __ cmovq(Assembler::less, $dst$$Register, $src$$Register); 7563 %} 7564 7565 ins_pipe(ialu_reg_reg); 7566 %} 7567 7568 //----------Subtraction Instructions------------------------------------------- 7569 7570 // Integer Subtraction Instructions 7571 instruct subI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7572 %{ 7573 match(Set dst (SubI dst src)); 7574 effect(KILL cr); 7575 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); 7576 7577 format %{ "subl $dst, $src\t# int" %} 7578 ins_encode %{ 7579 __ subl($dst$$Register, $src$$Register); 7580 %} 7581 ins_pipe(ialu_reg_reg); 7582 %} 7583 7584 instruct subI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 7585 %{ 7586 match(Set dst (SubI dst (LoadI src))); 7587 effect(KILL cr); 7588 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); 7589 7590 ins_cost(150); 7591 format %{ "subl $dst, $src\t# int" %} 7592 ins_encode %{ 7593 __ subl($dst$$Register, $src$$Address); 7594 %} 7595 ins_pipe(ialu_reg_mem); 7596 %} 7597 7598 instruct subI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 7599 %{ 7600 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 7601 effect(KILL cr); 7602 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); 7603 7604 ins_cost(150); 7605 format %{ "subl $dst, $src\t# int" %} 7606 ins_encode %{ 7607 __ subl($dst$$Address, $src$$Register); 7608 %} 7609 ins_pipe(ialu_mem_reg); 7610 %} 7611 7612 instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7613 %{ 7614 match(Set dst (SubL dst src)); 7615 effect(KILL cr); 7616 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_carry_flag, PD::Flag_sets_parity_flag); 7617 7618 format %{ "subq $dst, $src\t# long" %} 7619 ins_encode %{ 7620 __ subq($dst$$Register, $src$$Register); 7621 %} 7622 ins_pipe(ialu_reg_reg); 7623 %} 7624 7625 instruct subL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 7626 %{ 7627 match(Set dst (SubL dst (LoadL src))); 7628 effect(KILL cr); 7629 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); 7630 7631 ins_cost(150); 7632 format %{ "subq $dst, $src\t# long" %} 7633 ins_encode %{ 7634 __ subq($dst$$Register, $src$$Address); 7635 %} 7636 ins_pipe(ialu_reg_mem); 7637 %} 7638 7639 instruct subL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 7640 %{ 7641 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 7642 effect(KILL cr); 7643 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); 7644 7645 ins_cost(150); 7646 format %{ "subq $dst, $src\t# long" %} 7647 ins_encode %{ 7648 __ subq($dst$$Address, $src$$Register); 7649 %} 7650 ins_pipe(ialu_mem_reg); 7651 %} 7652 7653 // Subtract from a pointer 7654 // XXX hmpf??? 7655 instruct subP_rReg(rRegP dst, rRegI src, immI_0 zero, rFlagsReg cr) 7656 %{ 7657 match(Set dst (AddP dst (SubI zero src))); 7658 effect(KILL cr); 7659 7660 format %{ "subq $dst, $src\t# ptr - int" %} 7661 ins_encode %{ 7662 __ subq($dst$$Register, $src$$Register); 7663 %} 7664 ins_pipe(ialu_reg_reg); 7665 %} 7666 7667 instruct negI_rReg(rRegI dst, immI_0 zero, rFlagsReg cr) 7668 %{ 7669 match(Set dst (SubI zero dst)); 7670 effect(KILL cr); 7671 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7672 7673 format %{ "negl $dst\t# int" %} 7674 ins_encode %{ 7675 __ negl($dst$$Register); 7676 %} 7677 ins_pipe(ialu_reg); 7678 %} 7679 7680 instruct negI_rReg_2(rRegI dst, rFlagsReg cr) 7681 %{ 7682 match(Set dst (NegI dst)); 7683 effect(KILL cr); 7684 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7685 7686 format %{ "negl $dst\t# int" %} 7687 ins_encode %{ 7688 __ negl($dst$$Register); 7689 %} 7690 ins_pipe(ialu_reg); 7691 %} 7692 7693 instruct negI_mem(memory dst, immI_0 zero, rFlagsReg cr) 7694 %{ 7695 match(Set dst (StoreI dst (SubI zero (LoadI dst)))); 7696 effect(KILL cr); 7697 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7698 7699 format %{ "negl $dst\t# int" %} 7700 ins_encode %{ 7701 __ negl($dst$$Address); 7702 %} 7703 ins_pipe(ialu_reg); 7704 %} 7705 7706 instruct negL_rReg(rRegL dst, immL0 zero, rFlagsReg cr) 7707 %{ 7708 match(Set dst (SubL zero dst)); 7709 effect(KILL cr); 7710 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7711 7712 format %{ "negq $dst\t# long" %} 7713 ins_encode %{ 7714 __ negq($dst$$Register); 7715 %} 7716 ins_pipe(ialu_reg); 7717 %} 7718 7719 instruct negL_rReg_2(rRegL dst, rFlagsReg cr) 7720 %{ 7721 match(Set dst (NegL dst)); 7722 effect(KILL cr); 7723 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7724 7725 format %{ "negq $dst\t# int" %} 7726 ins_encode %{ 7727 __ negq($dst$$Register); 7728 %} 7729 ins_pipe(ialu_reg); 7730 %} 7731 7732 instruct negL_mem(memory dst, immL0 zero, rFlagsReg cr) 7733 %{ 7734 match(Set dst (StoreL dst (SubL zero (LoadL dst)))); 7735 effect(KILL cr); 7736 flag(PD::Flag_sets_overflow_flag, PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_sets_parity_flag); 7737 7738 format %{ "negq $dst\t# long" %} 7739 ins_encode %{ 7740 __ negq($dst$$Address); 7741 %} 7742 ins_pipe(ialu_reg); 7743 %} 7744 7745 //----------Multiplication/Division Instructions------------------------------- 7746 // Integer Multiplication Instructions 7747 // Multiply Register 7748 7749 instruct mulI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7750 %{ 7751 match(Set dst (MulI dst src)); 7752 effect(KILL cr); 7753 7754 ins_cost(300); 7755 format %{ "imull $dst, $src\t# int" %} 7756 ins_encode %{ 7757 __ imull($dst$$Register, $src$$Register); 7758 %} 7759 ins_pipe(ialu_reg_reg_alu0); 7760 %} 7761 7762 instruct mulI_rReg_imm(rRegI dst, rRegI src, immI imm, rFlagsReg cr) 7763 %{ 7764 match(Set dst (MulI src imm)); 7765 effect(KILL cr); 7766 7767 ins_cost(300); 7768 format %{ "imull $dst, $src, $imm\t# int" %} 7769 ins_encode %{ 7770 __ imull($dst$$Register, $src$$Register, $imm$$constant); 7771 %} 7772 ins_pipe(ialu_reg_reg_alu0); 7773 %} 7774 7775 instruct mulI_mem(rRegI dst, memory src, rFlagsReg cr) 7776 %{ 7777 match(Set dst (MulI dst (LoadI src))); 7778 effect(KILL cr); 7779 7780 ins_cost(350); 7781 format %{ "imull $dst, $src\t# int" %} 7782 ins_encode %{ 7783 __ imull($dst$$Register, $src$$Address); 7784 %} 7785 ins_pipe(ialu_reg_mem_alu0); 7786 %} 7787 7788 instruct mulI_mem_imm(rRegI dst, memory src, immI imm, rFlagsReg cr) 7789 %{ 7790 match(Set dst (MulI (LoadI src) imm)); 7791 effect(KILL cr); 7792 7793 ins_cost(300); 7794 format %{ "imull $dst, $src, $imm\t# int" %} 7795 ins_encode %{ 7796 __ imull($dst$$Register, $src$$Address, $imm$$constant); 7797 %} 7798 ins_pipe(ialu_reg_mem_alu0); 7799 %} 7800 7801 instruct mulAddS2I_rReg(rRegI dst, rRegI src1, rRegI src2, rRegI src3, rFlagsReg cr) 7802 %{ 7803 match(Set dst (MulAddS2I (Binary dst src1) (Binary src2 src3))); 7804 effect(KILL cr, KILL src2); 7805 7806 expand %{ mulI_rReg(dst, src1, cr); 7807 mulI_rReg(src2, src3, cr); 7808 addI_rReg(dst, src2, cr); %} 7809 %} 7810 7811 instruct mulL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7812 %{ 7813 match(Set dst (MulL dst src)); 7814 effect(KILL cr); 7815 7816 ins_cost(300); 7817 format %{ "imulq $dst, $src\t# long" %} 7818 ins_encode %{ 7819 __ imulq($dst$$Register, $src$$Register); 7820 %} 7821 ins_pipe(ialu_reg_reg_alu0); 7822 %} 7823 7824 instruct mulL_rReg_imm(rRegL dst, rRegL src, immL32 imm, rFlagsReg cr) 7825 %{ 7826 match(Set dst (MulL src imm)); 7827 effect(KILL cr); 7828 7829 ins_cost(300); 7830 format %{ "imulq $dst, $src, $imm\t# long" %} 7831 ins_encode %{ 7832 __ imulq($dst$$Register, $src$$Register, $imm$$constant); 7833 %} 7834 ins_pipe(ialu_reg_reg_alu0); 7835 %} 7836 7837 instruct mulL_mem(rRegL dst, memory src, rFlagsReg cr) 7838 %{ 7839 match(Set dst (MulL dst (LoadL src))); 7840 effect(KILL cr); 7841 7842 ins_cost(350); 7843 format %{ "imulq $dst, $src\t# long" %} 7844 ins_encode %{ 7845 __ imulq($dst$$Register, $src$$Address); 7846 %} 7847 ins_pipe(ialu_reg_mem_alu0); 7848 %} 7849 7850 instruct mulL_mem_imm(rRegL dst, memory src, immL32 imm, rFlagsReg cr) 7851 %{ 7852 match(Set dst (MulL (LoadL src) imm)); 7853 effect(KILL cr); 7854 7855 ins_cost(300); 7856 format %{ "imulq $dst, $src, $imm\t# long" %} 7857 ins_encode %{ 7858 __ imulq($dst$$Register, $src$$Address, $imm$$constant); 7859 %} 7860 ins_pipe(ialu_reg_mem_alu0); 7861 %} 7862 7863 instruct mulHiL_rReg(rdx_RegL dst, rRegL src, rax_RegL rax, rFlagsReg cr) 7864 %{ 7865 match(Set dst (MulHiL src rax)); 7866 effect(USE_KILL rax, KILL cr); 7867 7868 ins_cost(300); 7869 format %{ "imulq RDX:RAX, RAX, $src\t# mulhi" %} 7870 ins_encode %{ 7871 __ imulq($src$$Register); 7872 %} 7873 ins_pipe(ialu_reg_reg_alu0); 7874 %} 7875 7876 instruct umulHiL_rReg(rdx_RegL dst, rRegL src, rax_RegL rax, rFlagsReg cr) 7877 %{ 7878 match(Set dst (UMulHiL src rax)); 7879 effect(USE_KILL rax, KILL cr); 7880 7881 ins_cost(300); 7882 format %{ "mulq RDX:RAX, RAX, $src\t# umulhi" %} 7883 ins_encode %{ 7884 __ mulq($src$$Register); 7885 %} 7886 ins_pipe(ialu_reg_reg_alu0); 7887 %} 7888 7889 instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 7890 rFlagsReg cr) 7891 %{ 7892 match(Set rax (DivI rax div)); 7893 effect(KILL rdx, KILL cr); 7894 7895 ins_cost(30*100+10*100); // XXX 7896 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 7897 "jne,s normal\n\t" 7898 "xorl rdx, rdx\n\t" 7899 "cmpl $div, -1\n\t" 7900 "je,s done\n" 7901 "normal: cdql\n\t" 7902 "idivl $div\n" 7903 "done:" %} 7904 ins_encode(cdql_enc(div)); 7905 ins_pipe(ialu_reg_reg_alu0); 7906 %} 7907 7908 instruct divL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 7909 rFlagsReg cr) 7910 %{ 7911 match(Set rax (DivL rax div)); 7912 effect(KILL rdx, KILL cr); 7913 7914 ins_cost(30*100+10*100); // XXX 7915 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 7916 "cmpq rax, rdx\n\t" 7917 "jne,s normal\n\t" 7918 "xorl rdx, rdx\n\t" 7919 "cmpq $div, -1\n\t" 7920 "je,s done\n" 7921 "normal: cdqq\n\t" 7922 "idivq $div\n" 7923 "done:" %} 7924 ins_encode(cdqq_enc(div)); 7925 ins_pipe(ialu_reg_reg_alu0); 7926 %} 7927 7928 instruct udivI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, rFlagsReg cr) 7929 %{ 7930 match(Set rax (UDivI rax div)); 7931 effect(KILL rdx, KILL cr); 7932 7933 ins_cost(300); 7934 format %{ "udivl $rax,$rax,$div\t# UDivI\n" %} 7935 ins_encode %{ 7936 __ udivI($rax$$Register, $div$$Register, $rdx$$Register); 7937 %} 7938 ins_pipe(ialu_reg_reg_alu0); 7939 %} 7940 7941 instruct udivL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, rFlagsReg cr) 7942 %{ 7943 match(Set rax (UDivL rax div)); 7944 effect(KILL rdx, KILL cr); 7945 7946 ins_cost(300); 7947 format %{ "udivq $rax,$rax,$div\t# UDivL\n" %} 7948 ins_encode %{ 7949 __ udivL($rax$$Register, $div$$Register, $rdx$$Register); 7950 %} 7951 ins_pipe(ialu_reg_reg_alu0); 7952 %} 7953 7954 // Integer DIVMOD with Register, both quotient and mod results 7955 instruct divModI_rReg_divmod(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 7956 rFlagsReg cr) 7957 %{ 7958 match(DivModI rax div); 7959 effect(KILL cr); 7960 7961 ins_cost(30*100+10*100); // XXX 7962 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 7963 "jne,s normal\n\t" 7964 "xorl rdx, rdx\n\t" 7965 "cmpl $div, -1\n\t" 7966 "je,s done\n" 7967 "normal: cdql\n\t" 7968 "idivl $div\n" 7969 "done:" %} 7970 ins_encode(cdql_enc(div)); 7971 ins_pipe(pipe_slow); 7972 %} 7973 7974 // Long DIVMOD with Register, both quotient and mod results 7975 instruct divModL_rReg_divmod(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 7976 rFlagsReg cr) 7977 %{ 7978 match(DivModL rax div); 7979 effect(KILL cr); 7980 7981 ins_cost(30*100+10*100); // XXX 7982 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 7983 "cmpq rax, rdx\n\t" 7984 "jne,s normal\n\t" 7985 "xorl rdx, rdx\n\t" 7986 "cmpq $div, -1\n\t" 7987 "je,s done\n" 7988 "normal: cdqq\n\t" 7989 "idivq $div\n" 7990 "done:" %} 7991 ins_encode(cdqq_enc(div)); 7992 ins_pipe(pipe_slow); 7993 %} 7994 7995 // Unsigned integer DIVMOD with Register, both quotient and mod results 7996 instruct udivModI_rReg_divmod(rax_RegI rax, no_rax_rdx_RegI tmp, rdx_RegI rdx, 7997 no_rax_rdx_RegI div, rFlagsReg cr) 7998 %{ 7999 match(UDivModI rax div); 8000 effect(TEMP tmp, KILL cr); 8001 8002 ins_cost(300); 8003 format %{ "udivl $rax,$rax,$div\t# begin UDivModI\n\t" 8004 "umodl $rdx,$rax,$div\t! using $tmp as TEMP # end UDivModI\n" 8005 %} 8006 ins_encode %{ 8007 __ udivmodI($rax$$Register, $div$$Register, $rdx$$Register, $tmp$$Register); 8008 %} 8009 ins_pipe(pipe_slow); 8010 %} 8011 8012 // Unsigned long DIVMOD with Register, both quotient and mod results 8013 instruct udivModL_rReg_divmod(rax_RegL rax, no_rax_rdx_RegL tmp, rdx_RegL rdx, 8014 no_rax_rdx_RegL div, rFlagsReg cr) 8015 %{ 8016 match(UDivModL rax div); 8017 effect(TEMP tmp, KILL cr); 8018 8019 ins_cost(300); 8020 format %{ "udivq $rax,$rax,$div\t# begin UDivModL\n\t" 8021 "umodq $rdx,$rax,$div\t! using $tmp as TEMP # end UDivModL\n" 8022 %} 8023 ins_encode %{ 8024 __ udivmodL($rax$$Register, $div$$Register, $rdx$$Register, $tmp$$Register); 8025 %} 8026 ins_pipe(pipe_slow); 8027 %} 8028 8029 instruct modI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, 8030 rFlagsReg cr) 8031 %{ 8032 match(Set rdx (ModI rax div)); 8033 effect(KILL rax, KILL cr); 8034 8035 ins_cost(300); // XXX 8036 format %{ "cmpl rax, 0x80000000\t# irem\n\t" 8037 "jne,s normal\n\t" 8038 "xorl rdx, rdx\n\t" 8039 "cmpl $div, -1\n\t" 8040 "je,s done\n" 8041 "normal: cdql\n\t" 8042 "idivl $div\n" 8043 "done:" %} 8044 ins_encode(cdql_enc(div)); 8045 ins_pipe(ialu_reg_reg_alu0); 8046 %} 8047 8048 instruct modL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, 8049 rFlagsReg cr) 8050 %{ 8051 match(Set rdx (ModL rax div)); 8052 effect(KILL rax, KILL cr); 8053 8054 ins_cost(300); // XXX 8055 format %{ "movq rdx, 0x8000000000000000\t# lrem\n\t" 8056 "cmpq rax, rdx\n\t" 8057 "jne,s normal\n\t" 8058 "xorl rdx, rdx\n\t" 8059 "cmpq $div, -1\n\t" 8060 "je,s done\n" 8061 "normal: cdqq\n\t" 8062 "idivq $div\n" 8063 "done:" %} 8064 ins_encode(cdqq_enc(div)); 8065 ins_pipe(ialu_reg_reg_alu0); 8066 %} 8067 8068 instruct umodI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, rFlagsReg cr) 8069 %{ 8070 match(Set rdx (UModI rax div)); 8071 effect(KILL rax, KILL cr); 8072 8073 ins_cost(300); 8074 format %{ "umodl $rdx,$rax,$div\t# UModI\n" %} 8075 ins_encode %{ 8076 __ umodI($rax$$Register, $div$$Register, $rdx$$Register); 8077 %} 8078 ins_pipe(ialu_reg_reg_alu0); 8079 %} 8080 8081 instruct umodL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, rFlagsReg cr) 8082 %{ 8083 match(Set rdx (UModL rax div)); 8084 effect(KILL rax, KILL cr); 8085 8086 ins_cost(300); 8087 format %{ "umodq $rdx,$rax,$div\t# UModL\n" %} 8088 ins_encode %{ 8089 __ umodL($rax$$Register, $div$$Register, $rdx$$Register); 8090 %} 8091 ins_pipe(ialu_reg_reg_alu0); 8092 %} 8093 8094 // Integer Shift Instructions 8095 // Shift Left by one, two, three 8096 instruct salI_rReg_immI2(rRegI dst, immI2 shift, rFlagsReg cr) 8097 %{ 8098 match(Set dst (LShiftI dst shift)); 8099 effect(KILL cr); 8100 8101 format %{ "sall $dst, $shift" %} 8102 ins_encode %{ 8103 __ sall($dst$$Register, $shift$$constant); 8104 %} 8105 ins_pipe(ialu_reg); 8106 %} 8107 8108 // Shift Left by 8-bit immediate 8109 instruct salI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8110 %{ 8111 match(Set dst (LShiftI dst shift)); 8112 effect(KILL cr); 8113 8114 format %{ "sall $dst, $shift" %} 8115 ins_encode %{ 8116 __ sall($dst$$Register, $shift$$constant); 8117 %} 8118 ins_pipe(ialu_reg); 8119 %} 8120 8121 // Shift Left by 8-bit immediate 8122 instruct salI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8123 %{ 8124 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8125 effect(KILL cr); 8126 8127 format %{ "sall $dst, $shift" %} 8128 ins_encode %{ 8129 __ sall($dst$$Address, $shift$$constant); 8130 %} 8131 ins_pipe(ialu_mem_imm); 8132 %} 8133 8134 // Shift Left by variable 8135 instruct salI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8136 %{ 8137 predicate(!VM_Version::supports_bmi2()); 8138 match(Set dst (LShiftI dst shift)); 8139 effect(KILL cr); 8140 8141 format %{ "sall $dst, $shift" %} 8142 ins_encode %{ 8143 __ sall($dst$$Register); 8144 %} 8145 ins_pipe(ialu_reg_reg); 8146 %} 8147 8148 // Shift Left by variable 8149 instruct salI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8150 %{ 8151 predicate(!VM_Version::supports_bmi2()); 8152 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8153 effect(KILL cr); 8154 8155 format %{ "sall $dst, $shift" %} 8156 ins_encode %{ 8157 __ sall($dst$$Address); 8158 %} 8159 ins_pipe(ialu_mem_reg); 8160 %} 8161 8162 instruct salI_rReg_rReg(rRegI dst, rRegI src, rRegI shift) 8163 %{ 8164 predicate(VM_Version::supports_bmi2()); 8165 match(Set dst (LShiftI src shift)); 8166 8167 format %{ "shlxl $dst, $src, $shift" %} 8168 ins_encode %{ 8169 __ shlxl($dst$$Register, $src$$Register, $shift$$Register); 8170 %} 8171 ins_pipe(ialu_reg_reg); 8172 %} 8173 8174 instruct salI_mem_rReg(rRegI dst, memory src, rRegI shift) 8175 %{ 8176 predicate(VM_Version::supports_bmi2()); 8177 match(Set dst (LShiftI (LoadI src) shift)); 8178 ins_cost(175); 8179 format %{ "shlxl $dst, $src, $shift" %} 8180 ins_encode %{ 8181 __ shlxl($dst$$Register, $src$$Address, $shift$$Register); 8182 %} 8183 ins_pipe(ialu_reg_mem); 8184 %} 8185 8186 // Arithmetic Shift Right by 8-bit immediate 8187 instruct sarI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8188 %{ 8189 match(Set dst (RShiftI dst shift)); 8190 effect(KILL cr); 8191 8192 format %{ "sarl $dst, $shift" %} 8193 ins_encode %{ 8194 __ sarl($dst$$Register, $shift$$constant); 8195 %} 8196 ins_pipe(ialu_mem_imm); 8197 %} 8198 8199 // Arithmetic Shift Right by 8-bit immediate 8200 instruct sarI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8201 %{ 8202 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8203 effect(KILL cr); 8204 8205 format %{ "sarl $dst, $shift" %} 8206 ins_encode %{ 8207 __ sarl($dst$$Address, $shift$$constant); 8208 %} 8209 ins_pipe(ialu_mem_imm); 8210 %} 8211 8212 // Arithmetic Shift Right by variable 8213 instruct sarI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8214 %{ 8215 predicate(!VM_Version::supports_bmi2()); 8216 match(Set dst (RShiftI dst shift)); 8217 effect(KILL cr); 8218 8219 format %{ "sarl $dst, $shift" %} 8220 ins_encode %{ 8221 __ sarl($dst$$Register); 8222 %} 8223 ins_pipe(ialu_reg_reg); 8224 %} 8225 8226 // Arithmetic Shift Right by variable 8227 instruct sarI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8228 %{ 8229 predicate(!VM_Version::supports_bmi2()); 8230 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8231 effect(KILL cr); 8232 8233 format %{ "sarl $dst, $shift" %} 8234 ins_encode %{ 8235 __ sarl($dst$$Address); 8236 %} 8237 ins_pipe(ialu_mem_reg); 8238 %} 8239 8240 instruct sarI_rReg_rReg(rRegI dst, rRegI src, rRegI shift) 8241 %{ 8242 predicate(VM_Version::supports_bmi2()); 8243 match(Set dst (RShiftI src shift)); 8244 8245 format %{ "sarxl $dst, $src, $shift" %} 8246 ins_encode %{ 8247 __ sarxl($dst$$Register, $src$$Register, $shift$$Register); 8248 %} 8249 ins_pipe(ialu_reg_reg); 8250 %} 8251 8252 instruct sarI_mem_rReg(rRegI dst, memory src, rRegI shift) 8253 %{ 8254 predicate(VM_Version::supports_bmi2()); 8255 match(Set dst (RShiftI (LoadI src) shift)); 8256 ins_cost(175); 8257 format %{ "sarxl $dst, $src, $shift" %} 8258 ins_encode %{ 8259 __ sarxl($dst$$Register, $src$$Address, $shift$$Register); 8260 %} 8261 ins_pipe(ialu_reg_mem); 8262 %} 8263 8264 // Logical Shift Right by 8-bit immediate 8265 instruct shrI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8266 %{ 8267 match(Set dst (URShiftI dst shift)); 8268 effect(KILL cr); 8269 8270 format %{ "shrl $dst, $shift" %} 8271 ins_encode %{ 8272 __ shrl($dst$$Register, $shift$$constant); 8273 %} 8274 ins_pipe(ialu_reg); 8275 %} 8276 8277 // Logical Shift Right by 8-bit immediate 8278 instruct shrI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8279 %{ 8280 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8281 effect(KILL cr); 8282 8283 format %{ "shrl $dst, $shift" %} 8284 ins_encode %{ 8285 __ shrl($dst$$Address, $shift$$constant); 8286 %} 8287 ins_pipe(ialu_mem_imm); 8288 %} 8289 8290 // Logical Shift Right by variable 8291 instruct shrI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8292 %{ 8293 predicate(!VM_Version::supports_bmi2()); 8294 match(Set dst (URShiftI dst shift)); 8295 effect(KILL cr); 8296 8297 format %{ "shrl $dst, $shift" %} 8298 ins_encode %{ 8299 __ shrl($dst$$Register); 8300 %} 8301 ins_pipe(ialu_reg_reg); 8302 %} 8303 8304 // Logical Shift Right by variable 8305 instruct shrI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8306 %{ 8307 predicate(!VM_Version::supports_bmi2()); 8308 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8309 effect(KILL cr); 8310 8311 format %{ "shrl $dst, $shift" %} 8312 ins_encode %{ 8313 __ shrl($dst$$Address); 8314 %} 8315 ins_pipe(ialu_mem_reg); 8316 %} 8317 8318 instruct shrI_rReg_rReg(rRegI dst, rRegI src, rRegI shift) 8319 %{ 8320 predicate(VM_Version::supports_bmi2()); 8321 match(Set dst (URShiftI src shift)); 8322 8323 format %{ "shrxl $dst, $src, $shift" %} 8324 ins_encode %{ 8325 __ shrxl($dst$$Register, $src$$Register, $shift$$Register); 8326 %} 8327 ins_pipe(ialu_reg_reg); 8328 %} 8329 8330 instruct shrI_mem_rReg(rRegI dst, memory src, rRegI shift) 8331 %{ 8332 predicate(VM_Version::supports_bmi2()); 8333 match(Set dst (URShiftI (LoadI src) shift)); 8334 ins_cost(175); 8335 format %{ "shrxl $dst, $src, $shift" %} 8336 ins_encode %{ 8337 __ shrxl($dst$$Register, $src$$Address, $shift$$Register); 8338 %} 8339 ins_pipe(ialu_reg_mem); 8340 %} 8341 8342 // Long Shift Instructions 8343 // Shift Left by one, two, three 8344 instruct salL_rReg_immI2(rRegL dst, immI2 shift, rFlagsReg cr) 8345 %{ 8346 match(Set dst (LShiftL dst shift)); 8347 effect(KILL cr); 8348 8349 format %{ "salq $dst, $shift" %} 8350 ins_encode %{ 8351 __ salq($dst$$Register, $shift$$constant); 8352 %} 8353 ins_pipe(ialu_reg); 8354 %} 8355 8356 // Shift Left by 8-bit immediate 8357 instruct salL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8358 %{ 8359 match(Set dst (LShiftL dst shift)); 8360 effect(KILL cr); 8361 8362 format %{ "salq $dst, $shift" %} 8363 ins_encode %{ 8364 __ salq($dst$$Register, $shift$$constant); 8365 %} 8366 ins_pipe(ialu_reg); 8367 %} 8368 8369 // Shift Left by 8-bit immediate 8370 instruct salL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8371 %{ 8372 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8373 effect(KILL cr); 8374 8375 format %{ "salq $dst, $shift" %} 8376 ins_encode %{ 8377 __ salq($dst$$Address, $shift$$constant); 8378 %} 8379 ins_pipe(ialu_mem_imm); 8380 %} 8381 8382 // Shift Left by variable 8383 instruct salL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8384 %{ 8385 predicate(!VM_Version::supports_bmi2()); 8386 match(Set dst (LShiftL dst shift)); 8387 effect(KILL cr); 8388 8389 format %{ "salq $dst, $shift" %} 8390 ins_encode %{ 8391 __ salq($dst$$Register); 8392 %} 8393 ins_pipe(ialu_reg_reg); 8394 %} 8395 8396 // Shift Left by variable 8397 instruct salL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8398 %{ 8399 predicate(!VM_Version::supports_bmi2()); 8400 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8401 effect(KILL cr); 8402 8403 format %{ "salq $dst, $shift" %} 8404 ins_encode %{ 8405 __ salq($dst$$Address); 8406 %} 8407 ins_pipe(ialu_mem_reg); 8408 %} 8409 8410 instruct salL_rReg_rReg(rRegL dst, rRegL src, rRegI shift) 8411 %{ 8412 predicate(VM_Version::supports_bmi2()); 8413 match(Set dst (LShiftL src shift)); 8414 8415 format %{ "shlxq $dst, $src, $shift" %} 8416 ins_encode %{ 8417 __ shlxq($dst$$Register, $src$$Register, $shift$$Register); 8418 %} 8419 ins_pipe(ialu_reg_reg); 8420 %} 8421 8422 instruct salL_mem_rReg(rRegL dst, memory src, rRegI shift) 8423 %{ 8424 predicate(VM_Version::supports_bmi2()); 8425 match(Set dst (LShiftL (LoadL src) shift)); 8426 ins_cost(175); 8427 format %{ "shlxq $dst, $src, $shift" %} 8428 ins_encode %{ 8429 __ shlxq($dst$$Register, $src$$Address, $shift$$Register); 8430 %} 8431 ins_pipe(ialu_reg_mem); 8432 %} 8433 8434 // Arithmetic Shift Right by 8-bit immediate 8435 instruct sarL_rReg_imm(rRegL dst, immI shift, rFlagsReg cr) 8436 %{ 8437 match(Set dst (RShiftL dst shift)); 8438 effect(KILL cr); 8439 8440 format %{ "sarq $dst, $shift" %} 8441 ins_encode %{ 8442 __ sarq($dst$$Register, (unsigned char)($shift$$constant & 0x3F)); 8443 %} 8444 ins_pipe(ialu_mem_imm); 8445 %} 8446 8447 // Arithmetic Shift Right by 8-bit immediate 8448 instruct sarL_mem_imm(memory dst, immI shift, rFlagsReg cr) 8449 %{ 8450 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8451 effect(KILL cr); 8452 8453 format %{ "sarq $dst, $shift" %} 8454 ins_encode %{ 8455 __ sarq($dst$$Address, (unsigned char)($shift$$constant & 0x3F)); 8456 %} 8457 ins_pipe(ialu_mem_imm); 8458 %} 8459 8460 // Arithmetic Shift Right by variable 8461 instruct sarL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8462 %{ 8463 predicate(!VM_Version::supports_bmi2()); 8464 match(Set dst (RShiftL dst shift)); 8465 effect(KILL cr); 8466 8467 format %{ "sarq $dst, $shift" %} 8468 ins_encode %{ 8469 __ sarq($dst$$Register); 8470 %} 8471 ins_pipe(ialu_reg_reg); 8472 %} 8473 8474 // Arithmetic Shift Right by variable 8475 instruct sarL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8476 %{ 8477 predicate(!VM_Version::supports_bmi2()); 8478 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8479 effect(KILL cr); 8480 8481 format %{ "sarq $dst, $shift" %} 8482 ins_encode %{ 8483 __ sarq($dst$$Address); 8484 %} 8485 ins_pipe(ialu_mem_reg); 8486 %} 8487 8488 instruct sarL_rReg_rReg(rRegL dst, rRegL src, rRegI shift) 8489 %{ 8490 predicate(VM_Version::supports_bmi2()); 8491 match(Set dst (RShiftL src shift)); 8492 8493 format %{ "sarxq $dst, $src, $shift" %} 8494 ins_encode %{ 8495 __ sarxq($dst$$Register, $src$$Register, $shift$$Register); 8496 %} 8497 ins_pipe(ialu_reg_reg); 8498 %} 8499 8500 instruct sarL_mem_rReg(rRegL dst, memory src, rRegI shift) 8501 %{ 8502 predicate(VM_Version::supports_bmi2()); 8503 match(Set dst (RShiftL (LoadL src) shift)); 8504 ins_cost(175); 8505 format %{ "sarxq $dst, $src, $shift" %} 8506 ins_encode %{ 8507 __ sarxq($dst$$Register, $src$$Address, $shift$$Register); 8508 %} 8509 ins_pipe(ialu_reg_mem); 8510 %} 8511 8512 // Logical Shift Right by 8-bit immediate 8513 instruct shrL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8514 %{ 8515 match(Set dst (URShiftL dst shift)); 8516 effect(KILL cr); 8517 8518 format %{ "shrq $dst, $shift" %} 8519 ins_encode %{ 8520 __ shrq($dst$$Register, $shift$$constant); 8521 %} 8522 ins_pipe(ialu_reg); 8523 %} 8524 8525 // Logical Shift Right by 8-bit immediate 8526 instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8527 %{ 8528 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8529 effect(KILL cr); 8530 8531 format %{ "shrq $dst, $shift" %} 8532 ins_encode %{ 8533 __ shrq($dst$$Address, $shift$$constant); 8534 %} 8535 ins_pipe(ialu_mem_imm); 8536 %} 8537 8538 // Logical Shift Right by variable 8539 instruct shrL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8540 %{ 8541 predicate(!VM_Version::supports_bmi2()); 8542 match(Set dst (URShiftL dst shift)); 8543 effect(KILL cr); 8544 8545 format %{ "shrq $dst, $shift" %} 8546 ins_encode %{ 8547 __ shrq($dst$$Register); 8548 %} 8549 ins_pipe(ialu_reg_reg); 8550 %} 8551 8552 // Logical Shift Right by variable 8553 instruct shrL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8554 %{ 8555 predicate(!VM_Version::supports_bmi2()); 8556 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8557 effect(KILL cr); 8558 8559 format %{ "shrq $dst, $shift" %} 8560 ins_encode %{ 8561 __ shrq($dst$$Address); 8562 %} 8563 ins_pipe(ialu_mem_reg); 8564 %} 8565 8566 instruct shrL_rReg_rReg(rRegL dst, rRegL src, rRegI shift) 8567 %{ 8568 predicate(VM_Version::supports_bmi2()); 8569 match(Set dst (URShiftL src shift)); 8570 8571 format %{ "shrxq $dst, $src, $shift" %} 8572 ins_encode %{ 8573 __ shrxq($dst$$Register, $src$$Register, $shift$$Register); 8574 %} 8575 ins_pipe(ialu_reg_reg); 8576 %} 8577 8578 instruct shrL_mem_rReg(rRegL dst, memory src, rRegI shift) 8579 %{ 8580 predicate(VM_Version::supports_bmi2()); 8581 match(Set dst (URShiftL (LoadL src) shift)); 8582 ins_cost(175); 8583 format %{ "shrxq $dst, $src, $shift" %} 8584 ins_encode %{ 8585 __ shrxq($dst$$Register, $src$$Address, $shift$$Register); 8586 %} 8587 ins_pipe(ialu_reg_mem); 8588 %} 8589 8590 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24. 8591 // This idiom is used by the compiler for the i2b bytecode. 8592 instruct i2b(rRegI dst, rRegI src, immI_24 twentyfour) 8593 %{ 8594 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour)); 8595 8596 format %{ "movsbl $dst, $src\t# i2b" %} 8597 ins_encode %{ 8598 __ movsbl($dst$$Register, $src$$Register); 8599 %} 8600 ins_pipe(ialu_reg_reg); 8601 %} 8602 8603 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16. 8604 // This idiom is used by the compiler the i2s bytecode. 8605 instruct i2s(rRegI dst, rRegI src, immI_16 sixteen) 8606 %{ 8607 match(Set dst (RShiftI (LShiftI src sixteen) sixteen)); 8608 8609 format %{ "movswl $dst, $src\t# i2s" %} 8610 ins_encode %{ 8611 __ movswl($dst$$Register, $src$$Register); 8612 %} 8613 ins_pipe(ialu_reg_reg); 8614 %} 8615 8616 // ROL/ROR instructions 8617 8618 // Rotate left by constant. 8619 instruct rolI_immI8_legacy(rRegI dst, immI8 shift, rFlagsReg cr) 8620 %{ 8621 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8622 match(Set dst (RotateLeft dst shift)); 8623 effect(KILL cr); 8624 format %{ "roll $dst, $shift" %} 8625 ins_encode %{ 8626 __ roll($dst$$Register, $shift$$constant); 8627 %} 8628 ins_pipe(ialu_reg); 8629 %} 8630 8631 instruct rolI_immI8(rRegI dst, rRegI src, immI8 shift) 8632 %{ 8633 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8634 match(Set dst (RotateLeft src shift)); 8635 format %{ "rolxl $dst, $src, $shift" %} 8636 ins_encode %{ 8637 int shift = 32 - ($shift$$constant & 31); 8638 __ rorxl($dst$$Register, $src$$Register, shift); 8639 %} 8640 ins_pipe(ialu_reg_reg); 8641 %} 8642 8643 instruct rolI_mem_immI8(rRegI dst, memory src, immI8 shift) 8644 %{ 8645 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8646 match(Set dst (RotateLeft (LoadI src) shift)); 8647 ins_cost(175); 8648 format %{ "rolxl $dst, $src, $shift" %} 8649 ins_encode %{ 8650 int shift = 32 - ($shift$$constant & 31); 8651 __ rorxl($dst$$Register, $src$$Address, shift); 8652 %} 8653 ins_pipe(ialu_reg_mem); 8654 %} 8655 8656 // Rotate Left by variable 8657 instruct rolI_rReg_Var(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8658 %{ 8659 predicate(n->bottom_type()->basic_type() == T_INT); 8660 match(Set dst (RotateLeft dst shift)); 8661 effect(KILL cr); 8662 format %{ "roll $dst, $shift" %} 8663 ins_encode %{ 8664 __ roll($dst$$Register); 8665 %} 8666 ins_pipe(ialu_reg_reg); 8667 %} 8668 8669 // Rotate Right by constant. 8670 instruct rorI_immI8_legacy(rRegI dst, immI8 shift, rFlagsReg cr) 8671 %{ 8672 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8673 match(Set dst (RotateRight dst shift)); 8674 effect(KILL cr); 8675 format %{ "rorl $dst, $shift" %} 8676 ins_encode %{ 8677 __ rorl($dst$$Register, $shift$$constant); 8678 %} 8679 ins_pipe(ialu_reg); 8680 %} 8681 8682 // Rotate Right by constant. 8683 instruct rorI_immI8(rRegI dst, rRegI src, immI8 shift) 8684 %{ 8685 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8686 match(Set dst (RotateRight src shift)); 8687 format %{ "rorxl $dst, $src, $shift" %} 8688 ins_encode %{ 8689 __ rorxl($dst$$Register, $src$$Register, $shift$$constant); 8690 %} 8691 ins_pipe(ialu_reg_reg); 8692 %} 8693 8694 instruct rorI_mem_immI8(rRegI dst, memory src, immI8 shift) 8695 %{ 8696 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_INT); 8697 match(Set dst (RotateRight (LoadI src) shift)); 8698 ins_cost(175); 8699 format %{ "rorxl $dst, $src, $shift" %} 8700 ins_encode %{ 8701 __ rorxl($dst$$Register, $src$$Address, $shift$$constant); 8702 %} 8703 ins_pipe(ialu_reg_mem); 8704 %} 8705 8706 // Rotate Right by variable 8707 instruct rorI_rReg_Var(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8708 %{ 8709 predicate(n->bottom_type()->basic_type() == T_INT); 8710 match(Set dst (RotateRight dst shift)); 8711 effect(KILL cr); 8712 format %{ "rorl $dst, $shift" %} 8713 ins_encode %{ 8714 __ rorl($dst$$Register); 8715 %} 8716 ins_pipe(ialu_reg_reg); 8717 %} 8718 8719 // Rotate Left by constant. 8720 instruct rolL_immI8_legacy(rRegL dst, immI8 shift, rFlagsReg cr) 8721 %{ 8722 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8723 match(Set dst (RotateLeft dst shift)); 8724 effect(KILL cr); 8725 format %{ "rolq $dst, $shift" %} 8726 ins_encode %{ 8727 __ rolq($dst$$Register, $shift$$constant); 8728 %} 8729 ins_pipe(ialu_reg); 8730 %} 8731 8732 instruct rolL_immI8(rRegL dst, rRegL src, immI8 shift) 8733 %{ 8734 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8735 match(Set dst (RotateLeft src shift)); 8736 format %{ "rolxq $dst, $src, $shift" %} 8737 ins_encode %{ 8738 int shift = 64 - ($shift$$constant & 63); 8739 __ rorxq($dst$$Register, $src$$Register, shift); 8740 %} 8741 ins_pipe(ialu_reg_reg); 8742 %} 8743 8744 instruct rolL_mem_immI8(rRegL dst, memory src, immI8 shift) 8745 %{ 8746 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8747 match(Set dst (RotateLeft (LoadL src) shift)); 8748 ins_cost(175); 8749 format %{ "rolxq $dst, $src, $shift" %} 8750 ins_encode %{ 8751 int shift = 64 - ($shift$$constant & 63); 8752 __ rorxq($dst$$Register, $src$$Address, shift); 8753 %} 8754 ins_pipe(ialu_reg_mem); 8755 %} 8756 8757 // Rotate Left by variable 8758 instruct rolL_rReg_Var(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8759 %{ 8760 predicate(n->bottom_type()->basic_type() == T_LONG); 8761 match(Set dst (RotateLeft dst shift)); 8762 effect(KILL cr); 8763 format %{ "rolq $dst, $shift" %} 8764 ins_encode %{ 8765 __ rolq($dst$$Register); 8766 %} 8767 ins_pipe(ialu_reg_reg); 8768 %} 8769 8770 // Rotate Right by constant. 8771 instruct rorL_immI8_legacy(rRegL dst, immI8 shift, rFlagsReg cr) 8772 %{ 8773 predicate(!VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8774 match(Set dst (RotateRight dst shift)); 8775 effect(KILL cr); 8776 format %{ "rorq $dst, $shift" %} 8777 ins_encode %{ 8778 __ rorq($dst$$Register, $shift$$constant); 8779 %} 8780 ins_pipe(ialu_reg); 8781 %} 8782 8783 // Rotate Right by constant 8784 instruct rorL_immI8(rRegL dst, rRegL src, immI8 shift) 8785 %{ 8786 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8787 match(Set dst (RotateRight src shift)); 8788 format %{ "rorxq $dst, $src, $shift" %} 8789 ins_encode %{ 8790 __ rorxq($dst$$Register, $src$$Register, $shift$$constant); 8791 %} 8792 ins_pipe(ialu_reg_reg); 8793 %} 8794 8795 instruct rorL_mem_immI8(rRegL dst, memory src, immI8 shift) 8796 %{ 8797 predicate(VM_Version::supports_bmi2() && n->bottom_type()->basic_type() == T_LONG); 8798 match(Set dst (RotateRight (LoadL src) shift)); 8799 ins_cost(175); 8800 format %{ "rorxq $dst, $src, $shift" %} 8801 ins_encode %{ 8802 __ rorxq($dst$$Register, $src$$Address, $shift$$constant); 8803 %} 8804 ins_pipe(ialu_reg_mem); 8805 %} 8806 8807 // Rotate Right by variable 8808 instruct rorL_rReg_Var(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8809 %{ 8810 predicate(n->bottom_type()->basic_type() == T_LONG); 8811 match(Set dst (RotateRight dst shift)); 8812 effect(KILL cr); 8813 format %{ "rorq $dst, $shift" %} 8814 ins_encode %{ 8815 __ rorq($dst$$Register); 8816 %} 8817 ins_pipe(ialu_reg_reg); 8818 %} 8819 8820 //----------------------------- CompressBits/ExpandBits ------------------------ 8821 8822 instruct compressBitsL_reg(rRegL dst, rRegL src, rRegL mask) %{ 8823 predicate(n->bottom_type()->isa_long()); 8824 match(Set dst (CompressBits src mask)); 8825 format %{ "pextq $dst, $src, $mask\t! parallel bit extract" %} 8826 ins_encode %{ 8827 __ pextq($dst$$Register, $src$$Register, $mask$$Register); 8828 %} 8829 ins_pipe( pipe_slow ); 8830 %} 8831 8832 instruct expandBitsL_reg(rRegL dst, rRegL src, rRegL mask) %{ 8833 predicate(n->bottom_type()->isa_long()); 8834 match(Set dst (ExpandBits src mask)); 8835 format %{ "pdepq $dst, $src, $mask\t! parallel bit deposit" %} 8836 ins_encode %{ 8837 __ pdepq($dst$$Register, $src$$Register, $mask$$Register); 8838 %} 8839 ins_pipe( pipe_slow ); 8840 %} 8841 8842 instruct compressBitsL_mem(rRegL dst, rRegL src, memory mask) %{ 8843 predicate(n->bottom_type()->isa_long()); 8844 match(Set dst (CompressBits src (LoadL mask))); 8845 format %{ "pextq $dst, $src, $mask\t! parallel bit extract" %} 8846 ins_encode %{ 8847 __ pextq($dst$$Register, $src$$Register, $mask$$Address); 8848 %} 8849 ins_pipe( pipe_slow ); 8850 %} 8851 8852 instruct expandBitsL_mem(rRegL dst, rRegL src, memory mask) %{ 8853 predicate(n->bottom_type()->isa_long()); 8854 match(Set dst (ExpandBits src (LoadL mask))); 8855 format %{ "pdepq $dst, $src, $mask\t! parallel bit deposit" %} 8856 ins_encode %{ 8857 __ pdepq($dst$$Register, $src$$Register, $mask$$Address); 8858 %} 8859 ins_pipe( pipe_slow ); 8860 %} 8861 8862 8863 // Logical Instructions 8864 8865 // Integer Logical Instructions 8866 8867 // And Instructions 8868 // And Register with Register 8869 instruct andI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8870 %{ 8871 match(Set dst (AndI dst src)); 8872 effect(KILL cr); 8873 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); 8874 8875 format %{ "andl $dst, $src\t# int" %} 8876 ins_encode %{ 8877 __ andl($dst$$Register, $src$$Register); 8878 %} 8879 ins_pipe(ialu_reg_reg); 8880 %} 8881 8882 // And Register with Immediate 255 8883 instruct andI_rReg_imm255(rRegI dst, rRegI src, immI_255 mask) 8884 %{ 8885 match(Set dst (AndI src mask)); 8886 8887 format %{ "movzbl $dst, $src\t# int & 0xFF" %} 8888 ins_encode %{ 8889 __ movzbl($dst$$Register, $src$$Register); 8890 %} 8891 ins_pipe(ialu_reg); 8892 %} 8893 8894 // And Register with Immediate 255 and promote to long 8895 instruct andI2L_rReg_imm255(rRegL dst, rRegI src, immI_255 mask) 8896 %{ 8897 match(Set dst (ConvI2L (AndI src mask))); 8898 8899 format %{ "movzbl $dst, $src\t# int & 0xFF -> long" %} 8900 ins_encode %{ 8901 __ movzbl($dst$$Register, $src$$Register); 8902 %} 8903 ins_pipe(ialu_reg); 8904 %} 8905 8906 // And Register with Immediate 65535 8907 instruct andI_rReg_imm65535(rRegI dst, rRegI src, immI_65535 mask) 8908 %{ 8909 match(Set dst (AndI src mask)); 8910 8911 format %{ "movzwl $dst, $src\t# int & 0xFFFF" %} 8912 ins_encode %{ 8913 __ movzwl($dst$$Register, $src$$Register); 8914 %} 8915 ins_pipe(ialu_reg); 8916 %} 8917 8918 // And Register with Immediate 65535 and promote to long 8919 instruct andI2L_rReg_imm65535(rRegL dst, rRegI src, immI_65535 mask) 8920 %{ 8921 match(Set dst (ConvI2L (AndI src mask))); 8922 8923 format %{ "movzwl $dst, $src\t# int & 0xFFFF -> long" %} 8924 ins_encode %{ 8925 __ movzwl($dst$$Register, $src$$Register); 8926 %} 8927 ins_pipe(ialu_reg); 8928 %} 8929 8930 // Can skip int2long conversions after AND with small bitmask 8931 instruct convI2LAndI_reg_immIbitmask(rRegL dst, rRegI src, immI_Pow2M1 mask, rRegI tmp, rFlagsReg cr) 8932 %{ 8933 predicate(VM_Version::supports_bmi2()); 8934 ins_cost(125); 8935 effect(TEMP tmp, KILL cr); 8936 match(Set dst (ConvI2L (AndI src mask))); 8937 format %{ "bzhiq $dst, $src, $mask \t# using $tmp as TEMP, int & immI_Pow2M1 -> long" %} 8938 ins_encode %{ 8939 __ movl($tmp$$Register, exact_log2($mask$$constant + 1)); 8940 __ bzhiq($dst$$Register, $src$$Register, $tmp$$Register); 8941 %} 8942 ins_pipe(ialu_reg_reg); 8943 %} 8944 8945 // And Register with Immediate 8946 instruct andI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 8947 %{ 8948 match(Set dst (AndI dst src)); 8949 effect(KILL cr); 8950 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); 8951 8952 format %{ "andl $dst, $src\t# int" %} 8953 ins_encode %{ 8954 __ andl($dst$$Register, $src$$constant); 8955 %} 8956 ins_pipe(ialu_reg); 8957 %} 8958 8959 // And Register with Memory 8960 instruct andI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 8961 %{ 8962 match(Set dst (AndI dst (LoadI src))); 8963 effect(KILL cr); 8964 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); 8965 8966 ins_cost(150); 8967 format %{ "andl $dst, $src\t# int" %} 8968 ins_encode %{ 8969 __ andl($dst$$Register, $src$$Address); 8970 %} 8971 ins_pipe(ialu_reg_mem); 8972 %} 8973 8974 // And Memory with Register 8975 instruct andB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 8976 %{ 8977 match(Set dst (StoreB dst (AndI (LoadB dst) src))); 8978 effect(KILL cr); 8979 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); 8980 8981 ins_cost(150); 8982 format %{ "andb $dst, $src\t# byte" %} 8983 ins_encode %{ 8984 __ andb($dst$$Address, $src$$Register); 8985 %} 8986 ins_pipe(ialu_mem_reg); 8987 %} 8988 8989 instruct andI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 8990 %{ 8991 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 8992 effect(KILL cr); 8993 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); 8994 8995 ins_cost(150); 8996 format %{ "andl $dst, $src\t# int" %} 8997 ins_encode %{ 8998 __ andl($dst$$Address, $src$$Register); 8999 %} 9000 ins_pipe(ialu_mem_reg); 9001 %} 9002 9003 // And Memory with Immediate 9004 instruct andI_mem_imm(memory dst, immI src, rFlagsReg cr) 9005 %{ 9006 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 9007 effect(KILL cr); 9008 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); 9009 9010 ins_cost(125); 9011 format %{ "andl $dst, $src\t# int" %} 9012 ins_encode %{ 9013 __ andl($dst$$Address, $src$$constant); 9014 %} 9015 ins_pipe(ialu_mem_imm); 9016 %} 9017 9018 // BMI1 instructions 9019 instruct andnI_rReg_rReg_mem(rRegI dst, rRegI src1, memory src2, immI_M1 minus_1, rFlagsReg cr) %{ 9020 match(Set dst (AndI (XorI src1 minus_1) (LoadI src2))); 9021 predicate(UseBMI1Instructions); 9022 effect(KILL cr); 9023 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9024 9025 ins_cost(125); 9026 format %{ "andnl $dst, $src1, $src2" %} 9027 9028 ins_encode %{ 9029 __ andnl($dst$$Register, $src1$$Register, $src2$$Address); 9030 %} 9031 ins_pipe(ialu_reg_mem); 9032 %} 9033 9034 instruct andnI_rReg_rReg_rReg(rRegI dst, rRegI src1, rRegI src2, immI_M1 minus_1, rFlagsReg cr) %{ 9035 match(Set dst (AndI (XorI src1 minus_1) src2)); 9036 predicate(UseBMI1Instructions); 9037 effect(KILL cr); 9038 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9039 9040 format %{ "andnl $dst, $src1, $src2" %} 9041 9042 ins_encode %{ 9043 __ andnl($dst$$Register, $src1$$Register, $src2$$Register); 9044 %} 9045 ins_pipe(ialu_reg); 9046 %} 9047 9048 instruct blsiI_rReg_rReg(rRegI dst, rRegI src, immI_0 imm_zero, rFlagsReg cr) %{ 9049 match(Set dst (AndI (SubI imm_zero src) src)); 9050 predicate(UseBMI1Instructions); 9051 effect(KILL cr); 9052 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9053 9054 format %{ "blsil $dst, $src" %} 9055 9056 ins_encode %{ 9057 __ blsil($dst$$Register, $src$$Register); 9058 %} 9059 ins_pipe(ialu_reg); 9060 %} 9061 9062 instruct blsiI_rReg_mem(rRegI dst, memory src, immI_0 imm_zero, rFlagsReg cr) %{ 9063 match(Set dst (AndI (SubI imm_zero (LoadI src) ) (LoadI src) )); 9064 predicate(UseBMI1Instructions); 9065 effect(KILL cr); 9066 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9067 9068 ins_cost(125); 9069 format %{ "blsil $dst, $src" %} 9070 9071 ins_encode %{ 9072 __ blsil($dst$$Register, $src$$Address); 9073 %} 9074 ins_pipe(ialu_reg_mem); 9075 %} 9076 9077 instruct blsmskI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 9078 %{ 9079 match(Set dst (XorI (AddI (LoadI src) minus_1) (LoadI src) ) ); 9080 predicate(UseBMI1Instructions); 9081 effect(KILL cr); 9082 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 9083 9084 ins_cost(125); 9085 format %{ "blsmskl $dst, $src" %} 9086 9087 ins_encode %{ 9088 __ blsmskl($dst$$Register, $src$$Address); 9089 %} 9090 ins_pipe(ialu_reg_mem); 9091 %} 9092 9093 instruct blsmskI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 9094 %{ 9095 match(Set dst (XorI (AddI src minus_1) src)); 9096 predicate(UseBMI1Instructions); 9097 effect(KILL cr); 9098 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 9099 9100 format %{ "blsmskl $dst, $src" %} 9101 9102 ins_encode %{ 9103 __ blsmskl($dst$$Register, $src$$Register); 9104 %} 9105 9106 ins_pipe(ialu_reg); 9107 %} 9108 9109 instruct blsrI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 9110 %{ 9111 match(Set dst (AndI (AddI src minus_1) src) ); 9112 predicate(UseBMI1Instructions); 9113 effect(KILL cr); 9114 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9115 9116 format %{ "blsrl $dst, $src" %} 9117 9118 ins_encode %{ 9119 __ blsrl($dst$$Register, $src$$Register); 9120 %} 9121 9122 ins_pipe(ialu_reg_mem); 9123 %} 9124 9125 instruct blsrI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 9126 %{ 9127 match(Set dst (AndI (AddI (LoadI src) minus_1) (LoadI src) ) ); 9128 predicate(UseBMI1Instructions); 9129 effect(KILL cr); 9130 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9131 9132 ins_cost(125); 9133 format %{ "blsrl $dst, $src" %} 9134 9135 ins_encode %{ 9136 __ blsrl($dst$$Register, $src$$Address); 9137 %} 9138 9139 ins_pipe(ialu_reg); 9140 %} 9141 9142 // Or Instructions 9143 // Or Register with Register 9144 instruct orI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9145 %{ 9146 match(Set dst (OrI dst src)); 9147 effect(KILL cr); 9148 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); 9149 9150 format %{ "orl $dst, $src\t# int" %} 9151 ins_encode %{ 9152 __ orl($dst$$Register, $src$$Register); 9153 %} 9154 ins_pipe(ialu_reg_reg); 9155 %} 9156 9157 // Or Register with Immediate 9158 instruct orI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9159 %{ 9160 match(Set dst (OrI dst src)); 9161 effect(KILL cr); 9162 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); 9163 9164 format %{ "orl $dst, $src\t# int" %} 9165 ins_encode %{ 9166 __ orl($dst$$Register, $src$$constant); 9167 %} 9168 ins_pipe(ialu_reg); 9169 %} 9170 9171 // Or Register with Memory 9172 instruct orI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9173 %{ 9174 match(Set dst (OrI dst (LoadI src))); 9175 effect(KILL cr); 9176 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); 9177 9178 ins_cost(150); 9179 format %{ "orl $dst, $src\t# int" %} 9180 ins_encode %{ 9181 __ orl($dst$$Register, $src$$Address); 9182 %} 9183 ins_pipe(ialu_reg_mem); 9184 %} 9185 9186 // Or Memory with Register 9187 instruct orB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9188 %{ 9189 match(Set dst (StoreB dst (OrI (LoadB dst) src))); 9190 effect(KILL cr); 9191 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); 9192 9193 ins_cost(150); 9194 format %{ "orb $dst, $src\t# byte" %} 9195 ins_encode %{ 9196 __ orb($dst$$Address, $src$$Register); 9197 %} 9198 ins_pipe(ialu_mem_reg); 9199 %} 9200 9201 instruct orI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9202 %{ 9203 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9204 effect(KILL cr); 9205 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); 9206 9207 ins_cost(150); 9208 format %{ "orl $dst, $src\t# int" %} 9209 ins_encode %{ 9210 __ orl($dst$$Address, $src$$Register); 9211 %} 9212 ins_pipe(ialu_mem_reg); 9213 %} 9214 9215 // Or Memory with Immediate 9216 instruct orI_mem_imm(memory dst, immI src, rFlagsReg cr) 9217 %{ 9218 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9219 effect(KILL cr); 9220 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); 9221 9222 ins_cost(125); 9223 format %{ "orl $dst, $src\t# int" %} 9224 ins_encode %{ 9225 __ orl($dst$$Address, $src$$constant); 9226 %} 9227 ins_pipe(ialu_mem_imm); 9228 %} 9229 9230 // Xor Instructions 9231 // Xor Register with Register 9232 instruct xorI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9233 %{ 9234 match(Set dst (XorI dst src)); 9235 effect(KILL cr); 9236 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); 9237 9238 format %{ "xorl $dst, $src\t# int" %} 9239 ins_encode %{ 9240 __ xorl($dst$$Register, $src$$Register); 9241 %} 9242 ins_pipe(ialu_reg_reg); 9243 %} 9244 9245 // Xor Register with Immediate -1 9246 instruct xorI_rReg_im1(rRegI dst, immI_M1 imm) %{ 9247 match(Set dst (XorI dst imm)); 9248 9249 format %{ "not $dst" %} 9250 ins_encode %{ 9251 __ notl($dst$$Register); 9252 %} 9253 ins_pipe(ialu_reg); 9254 %} 9255 9256 // Xor Register with Immediate 9257 instruct xorI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9258 %{ 9259 match(Set dst (XorI dst src)); 9260 effect(KILL cr); 9261 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); 9262 9263 format %{ "xorl $dst, $src\t# int" %} 9264 ins_encode %{ 9265 __ xorl($dst$$Register, $src$$constant); 9266 %} 9267 ins_pipe(ialu_reg); 9268 %} 9269 9270 // Xor Register with Memory 9271 instruct xorI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9272 %{ 9273 match(Set dst (XorI dst (LoadI src))); 9274 effect(KILL cr); 9275 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); 9276 9277 ins_cost(150); 9278 format %{ "xorl $dst, $src\t# int" %} 9279 ins_encode %{ 9280 __ xorl($dst$$Register, $src$$Address); 9281 %} 9282 ins_pipe(ialu_reg_mem); 9283 %} 9284 9285 // Xor Memory with Register 9286 instruct xorB_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9287 %{ 9288 match(Set dst (StoreB dst (XorI (LoadB dst) src))); 9289 effect(KILL cr); 9290 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); 9291 9292 ins_cost(150); 9293 format %{ "xorb $dst, $src\t# byte" %} 9294 ins_encode %{ 9295 __ xorb($dst$$Address, $src$$Register); 9296 %} 9297 ins_pipe(ialu_mem_reg); 9298 %} 9299 9300 instruct xorI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9301 %{ 9302 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9303 effect(KILL cr); 9304 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); 9305 9306 ins_cost(150); 9307 format %{ "xorl $dst, $src\t# int" %} 9308 ins_encode %{ 9309 __ xorl($dst$$Address, $src$$Register); 9310 %} 9311 ins_pipe(ialu_mem_reg); 9312 %} 9313 9314 // Xor Memory with Immediate 9315 instruct xorI_mem_imm(memory dst, immI src, rFlagsReg cr) 9316 %{ 9317 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9318 effect(KILL cr); 9319 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); 9320 9321 ins_cost(125); 9322 format %{ "xorl $dst, $src\t# int" %} 9323 ins_encode %{ 9324 __ xorl($dst$$Address, $src$$constant); 9325 %} 9326 ins_pipe(ialu_mem_imm); 9327 %} 9328 9329 9330 // Long Logical Instructions 9331 9332 // And Instructions 9333 // And Register with Register 9334 instruct andL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9335 %{ 9336 match(Set dst (AndL dst src)); 9337 effect(KILL cr); 9338 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); 9339 9340 format %{ "andq $dst, $src\t# long" %} 9341 ins_encode %{ 9342 __ andq($dst$$Register, $src$$Register); 9343 %} 9344 ins_pipe(ialu_reg_reg); 9345 %} 9346 9347 // And Register with Immediate 255 9348 instruct andL_rReg_imm255(rRegL dst, rRegL src, immL_255 mask) 9349 %{ 9350 match(Set dst (AndL src mask)); 9351 9352 format %{ "movzbl $dst, $src\t# long & 0xFF" %} 9353 ins_encode %{ 9354 // movzbl zeroes out the upper 32-bit and does not need REX.W 9355 __ movzbl($dst$$Register, $src$$Register); 9356 %} 9357 ins_pipe(ialu_reg); 9358 %} 9359 9360 // And Register with Immediate 65535 9361 instruct andL_rReg_imm65535(rRegL dst, rRegL src, immL_65535 mask) 9362 %{ 9363 match(Set dst (AndL src mask)); 9364 9365 format %{ "movzwl $dst, $src\t# long & 0xFFFF" %} 9366 ins_encode %{ 9367 // movzwl zeroes out the upper 32-bit and does not need REX.W 9368 __ movzwl($dst$$Register, $src$$Register); 9369 %} 9370 ins_pipe(ialu_reg); 9371 %} 9372 9373 // And Register with Immediate 9374 instruct andL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9375 %{ 9376 match(Set dst (AndL dst src)); 9377 effect(KILL cr); 9378 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); 9379 9380 format %{ "andq $dst, $src\t# long" %} 9381 ins_encode %{ 9382 __ andq($dst$$Register, $src$$constant); 9383 %} 9384 ins_pipe(ialu_reg); 9385 %} 9386 9387 // And Register with Memory 9388 instruct andL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9389 %{ 9390 match(Set dst (AndL dst (LoadL src))); 9391 effect(KILL cr); 9392 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); 9393 9394 ins_cost(150); 9395 format %{ "andq $dst, $src\t# long" %} 9396 ins_encode %{ 9397 __ andq($dst$$Register, $src$$Address); 9398 %} 9399 ins_pipe(ialu_reg_mem); 9400 %} 9401 9402 // And Memory with Register 9403 instruct andL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9404 %{ 9405 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9406 effect(KILL cr); 9407 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); 9408 9409 ins_cost(150); 9410 format %{ "andq $dst, $src\t# long" %} 9411 ins_encode %{ 9412 __ andq($dst$$Address, $src$$Register); 9413 %} 9414 ins_pipe(ialu_mem_reg); 9415 %} 9416 9417 // And Memory with Immediate 9418 instruct andL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9419 %{ 9420 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9421 effect(KILL cr); 9422 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); 9423 9424 ins_cost(125); 9425 format %{ "andq $dst, $src\t# long" %} 9426 ins_encode %{ 9427 __ andq($dst$$Address, $src$$constant); 9428 %} 9429 ins_pipe(ialu_mem_imm); 9430 %} 9431 9432 instruct btrL_mem_imm(memory dst, immL_NotPow2 con, rFlagsReg cr) 9433 %{ 9434 // con should be a pure 64-bit immediate given that not(con) is a power of 2 9435 // because AND/OR works well enough for 8/32-bit values. 9436 predicate(log2i_graceful(~n->in(3)->in(2)->get_long()) > 30); 9437 9438 match(Set dst (StoreL dst (AndL (LoadL dst) con))); 9439 effect(KILL cr); 9440 9441 ins_cost(125); 9442 format %{ "btrq $dst, log2(not($con))\t# long" %} 9443 ins_encode %{ 9444 __ btrq($dst$$Address, log2i_exact((julong)~$con$$constant)); 9445 %} 9446 ins_pipe(ialu_mem_imm); 9447 %} 9448 9449 // BMI1 instructions 9450 instruct andnL_rReg_rReg_mem(rRegL dst, rRegL src1, memory src2, immL_M1 minus_1, rFlagsReg cr) %{ 9451 match(Set dst (AndL (XorL src1 minus_1) (LoadL src2))); 9452 predicate(UseBMI1Instructions); 9453 effect(KILL cr); 9454 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9455 9456 ins_cost(125); 9457 format %{ "andnq $dst, $src1, $src2" %} 9458 9459 ins_encode %{ 9460 __ andnq($dst$$Register, $src1$$Register, $src2$$Address); 9461 %} 9462 ins_pipe(ialu_reg_mem); 9463 %} 9464 9465 instruct andnL_rReg_rReg_rReg(rRegL dst, rRegL src1, rRegL src2, immL_M1 minus_1, rFlagsReg cr) %{ 9466 match(Set dst (AndL (XorL src1 minus_1) src2)); 9467 predicate(UseBMI1Instructions); 9468 effect(KILL cr); 9469 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag, PD::Flag_clears_carry_flag); 9470 9471 format %{ "andnq $dst, $src1, $src2" %} 9472 9473 ins_encode %{ 9474 __ andnq($dst$$Register, $src1$$Register, $src2$$Register); 9475 %} 9476 ins_pipe(ialu_reg_mem); 9477 %} 9478 9479 instruct blsiL_rReg_rReg(rRegL dst, rRegL src, immL0 imm_zero, rFlagsReg cr) %{ 9480 match(Set dst (AndL (SubL imm_zero src) src)); 9481 predicate(UseBMI1Instructions); 9482 effect(KILL cr); 9483 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9484 9485 format %{ "blsiq $dst, $src" %} 9486 9487 ins_encode %{ 9488 __ blsiq($dst$$Register, $src$$Register); 9489 %} 9490 ins_pipe(ialu_reg); 9491 %} 9492 9493 instruct blsiL_rReg_mem(rRegL dst, memory src, immL0 imm_zero, rFlagsReg cr) %{ 9494 match(Set dst (AndL (SubL imm_zero (LoadL src) ) (LoadL src) )); 9495 predicate(UseBMI1Instructions); 9496 effect(KILL cr); 9497 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9498 9499 ins_cost(125); 9500 format %{ "blsiq $dst, $src" %} 9501 9502 ins_encode %{ 9503 __ blsiq($dst$$Register, $src$$Address); 9504 %} 9505 ins_pipe(ialu_reg_mem); 9506 %} 9507 9508 instruct blsmskL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 9509 %{ 9510 match(Set dst (XorL (AddL (LoadL src) minus_1) (LoadL src) ) ); 9511 predicate(UseBMI1Instructions); 9512 effect(KILL cr); 9513 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 9514 9515 ins_cost(125); 9516 format %{ "blsmskq $dst, $src" %} 9517 9518 ins_encode %{ 9519 __ blsmskq($dst$$Register, $src$$Address); 9520 %} 9521 ins_pipe(ialu_reg_mem); 9522 %} 9523 9524 instruct blsmskL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 9525 %{ 9526 match(Set dst (XorL (AddL src minus_1) src)); 9527 predicate(UseBMI1Instructions); 9528 effect(KILL cr); 9529 flag(PD::Flag_sets_sign_flag, PD::Flag_clears_zero_flag, PD::Flag_clears_overflow_flag); 9530 9531 format %{ "blsmskq $dst, $src" %} 9532 9533 ins_encode %{ 9534 __ blsmskq($dst$$Register, $src$$Register); 9535 %} 9536 9537 ins_pipe(ialu_reg); 9538 %} 9539 9540 instruct blsrL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 9541 %{ 9542 match(Set dst (AndL (AddL src minus_1) src) ); 9543 predicate(UseBMI1Instructions); 9544 effect(KILL cr); 9545 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9546 9547 format %{ "blsrq $dst, $src" %} 9548 9549 ins_encode %{ 9550 __ blsrq($dst$$Register, $src$$Register); 9551 %} 9552 9553 ins_pipe(ialu_reg); 9554 %} 9555 9556 instruct blsrL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 9557 %{ 9558 match(Set dst (AndL (AddL (LoadL src) minus_1) (LoadL src)) ); 9559 predicate(UseBMI1Instructions); 9560 effect(KILL cr); 9561 flag(PD::Flag_sets_sign_flag, PD::Flag_sets_zero_flag, PD::Flag_clears_overflow_flag); 9562 9563 ins_cost(125); 9564 format %{ "blsrq $dst, $src" %} 9565 9566 ins_encode %{ 9567 __ blsrq($dst$$Register, $src$$Address); 9568 %} 9569 9570 ins_pipe(ialu_reg); 9571 %} 9572 9573 // Or Instructions 9574 // Or Register with Register 9575 instruct orL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9576 %{ 9577 match(Set dst (OrL dst src)); 9578 effect(KILL cr); 9579 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); 9580 9581 format %{ "orq $dst, $src\t# long" %} 9582 ins_encode %{ 9583 __ orq($dst$$Register, $src$$Register); 9584 %} 9585 ins_pipe(ialu_reg_reg); 9586 %} 9587 9588 // Use any_RegP to match R15 (TLS register) without spilling. 9589 instruct orL_rReg_castP2X(rRegL dst, any_RegP src, rFlagsReg cr) %{ 9590 match(Set dst (OrL dst (CastP2X src))); 9591 effect(KILL cr); 9592 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); 9593 9594 format %{ "orq $dst, $src\t# long" %} 9595 ins_encode %{ 9596 __ orq($dst$$Register, $src$$Register); 9597 %} 9598 ins_pipe(ialu_reg_reg); 9599 %} 9600 9601 9602 // Or Register with Immediate 9603 instruct orL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9604 %{ 9605 match(Set dst (OrL dst src)); 9606 effect(KILL cr); 9607 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); 9608 9609 format %{ "orq $dst, $src\t# long" %} 9610 ins_encode %{ 9611 __ orq($dst$$Register, $src$$constant); 9612 %} 9613 ins_pipe(ialu_reg); 9614 %} 9615 9616 // Or Register with Memory 9617 instruct orL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9618 %{ 9619 match(Set dst (OrL dst (LoadL src))); 9620 effect(KILL cr); 9621 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); 9622 9623 ins_cost(150); 9624 format %{ "orq $dst, $src\t# long" %} 9625 ins_encode %{ 9626 __ orq($dst$$Register, $src$$Address); 9627 %} 9628 ins_pipe(ialu_reg_mem); 9629 %} 9630 9631 // Or Memory with Register 9632 instruct orL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9633 %{ 9634 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9635 effect(KILL cr); 9636 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); 9637 9638 ins_cost(150); 9639 format %{ "orq $dst, $src\t# long" %} 9640 ins_encode %{ 9641 __ orq($dst$$Address, $src$$Register); 9642 %} 9643 ins_pipe(ialu_mem_reg); 9644 %} 9645 9646 // Or Memory with Immediate 9647 instruct orL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9648 %{ 9649 match(Set dst (StoreL dst (OrL (LoadL 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 ins_cost(125); 9654 format %{ "orq $dst, $src\t# long" %} 9655 ins_encode %{ 9656 __ orq($dst$$Address, $src$$constant); 9657 %} 9658 ins_pipe(ialu_mem_imm); 9659 %} 9660 9661 instruct btsL_mem_imm(memory dst, immL_Pow2 con, rFlagsReg cr) 9662 %{ 9663 // con should be a pure 64-bit power of 2 immediate 9664 // because AND/OR works well enough for 8/32-bit values. 9665 predicate(log2i_graceful(n->in(3)->in(2)->get_long()) > 31); 9666 9667 match(Set dst (StoreL dst (OrL (LoadL dst) con))); 9668 effect(KILL cr); 9669 9670 ins_cost(125); 9671 format %{ "btsq $dst, log2($con)\t# long" %} 9672 ins_encode %{ 9673 __ btsq($dst$$Address, log2i_exact((julong)$con$$constant)); 9674 %} 9675 ins_pipe(ialu_mem_imm); 9676 %} 9677 9678 // Xor Instructions 9679 // Xor Register with Register 9680 instruct xorL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9681 %{ 9682 match(Set dst (XorL dst src)); 9683 effect(KILL cr); 9684 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); 9685 9686 format %{ "xorq $dst, $src\t# long" %} 9687 ins_encode %{ 9688 __ xorq($dst$$Register, $src$$Register); 9689 %} 9690 ins_pipe(ialu_reg_reg); 9691 %} 9692 9693 // Xor Register with Immediate -1 9694 instruct xorL_rReg_im1(rRegL dst, immL_M1 imm) %{ 9695 match(Set dst (XorL dst imm)); 9696 9697 format %{ "notq $dst" %} 9698 ins_encode %{ 9699 __ notq($dst$$Register); 9700 %} 9701 ins_pipe(ialu_reg); 9702 %} 9703 9704 // Xor Register with Immediate 9705 instruct xorL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9706 %{ 9707 match(Set dst (XorL dst src)); 9708 effect(KILL cr); 9709 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); 9710 9711 format %{ "xorq $dst, $src\t# long" %} 9712 ins_encode %{ 9713 __ xorq($dst$$Register, $src$$constant); 9714 %} 9715 ins_pipe(ialu_reg); 9716 %} 9717 9718 // Xor Register with Memory 9719 instruct xorL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9720 %{ 9721 match(Set dst (XorL dst (LoadL src))); 9722 effect(KILL cr); 9723 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); 9724 9725 ins_cost(150); 9726 format %{ "xorq $dst, $src\t# long" %} 9727 ins_encode %{ 9728 __ xorq($dst$$Register, $src$$Address); 9729 %} 9730 ins_pipe(ialu_reg_mem); 9731 %} 9732 9733 // Xor Memory with Register 9734 instruct xorL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9735 %{ 9736 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 9737 effect(KILL cr); 9738 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); 9739 9740 ins_cost(150); 9741 format %{ "xorq $dst, $src\t# long" %} 9742 ins_encode %{ 9743 __ xorq($dst$$Address, $src$$Register); 9744 %} 9745 ins_pipe(ialu_mem_reg); 9746 %} 9747 9748 // Xor Memory with Immediate 9749 instruct xorL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9750 %{ 9751 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 9752 effect(KILL cr); 9753 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); 9754 9755 ins_cost(125); 9756 format %{ "xorq $dst, $src\t# long" %} 9757 ins_encode %{ 9758 __ xorq($dst$$Address, $src$$constant); 9759 %} 9760 ins_pipe(ialu_mem_imm); 9761 %} 9762 9763 instruct cmpLTMask(rRegI dst, rRegI p, rRegI q, rFlagsReg cr) 9764 %{ 9765 match(Set dst (CmpLTMask p q)); 9766 effect(KILL cr); 9767 9768 ins_cost(400); 9769 format %{ "cmpl $p, $q\t# cmpLTMask\n\t" 9770 "setlt $dst\n\t" 9771 "movzbl $dst, $dst\n\t" 9772 "negl $dst" %} 9773 ins_encode %{ 9774 __ cmpl($p$$Register, $q$$Register); 9775 __ setb(Assembler::less, $dst$$Register); 9776 __ movzbl($dst$$Register, $dst$$Register); 9777 __ negl($dst$$Register); 9778 %} 9779 ins_pipe(pipe_slow); 9780 %} 9781 9782 instruct cmpLTMask0(rRegI dst, immI_0 zero, rFlagsReg cr) 9783 %{ 9784 match(Set dst (CmpLTMask dst zero)); 9785 effect(KILL cr); 9786 9787 ins_cost(100); 9788 format %{ "sarl $dst, #31\t# cmpLTMask0" %} 9789 ins_encode %{ 9790 __ sarl($dst$$Register, 31); 9791 %} 9792 ins_pipe(ialu_reg); 9793 %} 9794 9795 /* Better to save a register than avoid a branch */ 9796 instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 9797 %{ 9798 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q))); 9799 effect(KILL cr); 9800 ins_cost(300); 9801 format %{ "subl $p,$q\t# cadd_cmpLTMask\n\t" 9802 "jge done\n\t" 9803 "addl $p,$y\n" 9804 "done: " %} 9805 ins_encode %{ 9806 Register Rp = $p$$Register; 9807 Register Rq = $q$$Register; 9808 Register Ry = $y$$Register; 9809 Label done; 9810 __ subl(Rp, Rq); 9811 __ jccb(Assembler::greaterEqual, done); 9812 __ addl(Rp, Ry); 9813 __ bind(done); 9814 %} 9815 ins_pipe(pipe_cmplt); 9816 %} 9817 9818 /* Better to save a register than avoid a branch */ 9819 instruct and_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 9820 %{ 9821 match(Set y (AndI (CmpLTMask p q) y)); 9822 effect(KILL cr); 9823 9824 ins_cost(300); 9825 9826 format %{ "cmpl $p, $q\t# and_cmpLTMask\n\t" 9827 "jlt done\n\t" 9828 "xorl $y, $y\n" 9829 "done: " %} 9830 ins_encode %{ 9831 Register Rp = $p$$Register; 9832 Register Rq = $q$$Register; 9833 Register Ry = $y$$Register; 9834 Label done; 9835 __ cmpl(Rp, Rq); 9836 __ jccb(Assembler::less, done); 9837 __ xorl(Ry, Ry); 9838 __ bind(done); 9839 %} 9840 ins_pipe(pipe_cmplt); 9841 %} 9842 9843 9844 //---------- FP Instructions------------------------------------------------ 9845 9846 // Really expensive, avoid 9847 instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2) 9848 %{ 9849 match(Set cr (CmpF src1 src2)); 9850 9851 ins_cost(500); 9852 format %{ "ucomiss $src1, $src2\n\t" 9853 "jnp,s exit\n\t" 9854 "pushfq\t# saw NaN, set CF\n\t" 9855 "andq [rsp], #0xffffff2b\n\t" 9856 "popfq\n" 9857 "exit:" %} 9858 ins_encode %{ 9859 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9860 emit_cmpfp_fixup(masm); 9861 %} 9862 ins_pipe(pipe_slow); 9863 %} 9864 9865 instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{ 9866 match(Set cr (CmpF src1 src2)); 9867 9868 ins_cost(100); 9869 format %{ "ucomiss $src1, $src2" %} 9870 ins_encode %{ 9871 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9872 %} 9873 ins_pipe(pipe_slow); 9874 %} 9875 9876 instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{ 9877 match(Set cr (CmpF src1 (LoadF src2))); 9878 9879 ins_cost(100); 9880 format %{ "ucomiss $src1, $src2" %} 9881 ins_encode %{ 9882 __ ucomiss($src1$$XMMRegister, $src2$$Address); 9883 %} 9884 ins_pipe(pipe_slow); 9885 %} 9886 9887 instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src, immF con) %{ 9888 match(Set cr (CmpF src con)); 9889 ins_cost(100); 9890 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con" %} 9891 ins_encode %{ 9892 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 9893 %} 9894 ins_pipe(pipe_slow); 9895 %} 9896 9897 // Really expensive, avoid 9898 instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2) 9899 %{ 9900 match(Set cr (CmpD src1 src2)); 9901 9902 ins_cost(500); 9903 format %{ "ucomisd $src1, $src2\n\t" 9904 "jnp,s exit\n\t" 9905 "pushfq\t# saw NaN, set CF\n\t" 9906 "andq [rsp], #0xffffff2b\n\t" 9907 "popfq\n" 9908 "exit:" %} 9909 ins_encode %{ 9910 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9911 emit_cmpfp_fixup(masm); 9912 %} 9913 ins_pipe(pipe_slow); 9914 %} 9915 9916 instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{ 9917 match(Set cr (CmpD src1 src2)); 9918 9919 ins_cost(100); 9920 format %{ "ucomisd $src1, $src2 test" %} 9921 ins_encode %{ 9922 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9923 %} 9924 ins_pipe(pipe_slow); 9925 %} 9926 9927 instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{ 9928 match(Set cr (CmpD src1 (LoadD src2))); 9929 9930 ins_cost(100); 9931 format %{ "ucomisd $src1, $src2" %} 9932 ins_encode %{ 9933 __ ucomisd($src1$$XMMRegister, $src2$$Address); 9934 %} 9935 ins_pipe(pipe_slow); 9936 %} 9937 9938 instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src, immD con) %{ 9939 match(Set cr (CmpD src con)); 9940 ins_cost(100); 9941 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con" %} 9942 ins_encode %{ 9943 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 9944 %} 9945 ins_pipe(pipe_slow); 9946 %} 9947 9948 // Compare into -1,0,1 9949 instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr) 9950 %{ 9951 match(Set dst (CmpF3 src1 src2)); 9952 effect(KILL cr); 9953 9954 ins_cost(275); 9955 format %{ "ucomiss $src1, $src2\n\t" 9956 "movl $dst, #-1\n\t" 9957 "jp,s done\n\t" 9958 "jb,s done\n\t" 9959 "setne $dst\n\t" 9960 "movzbl $dst, $dst\n" 9961 "done:" %} 9962 ins_encode %{ 9963 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9964 emit_cmpfp3(masm, $dst$$Register); 9965 %} 9966 ins_pipe(pipe_slow); 9967 %} 9968 9969 // Compare into -1,0,1 9970 instruct cmpF_mem(rRegI dst, regF src1, memory src2, rFlagsReg cr) 9971 %{ 9972 match(Set dst (CmpF3 src1 (LoadF src2))); 9973 effect(KILL cr); 9974 9975 ins_cost(275); 9976 format %{ "ucomiss $src1, $src2\n\t" 9977 "movl $dst, #-1\n\t" 9978 "jp,s done\n\t" 9979 "jb,s done\n\t" 9980 "setne $dst\n\t" 9981 "movzbl $dst, $dst\n" 9982 "done:" %} 9983 ins_encode %{ 9984 __ ucomiss($src1$$XMMRegister, $src2$$Address); 9985 emit_cmpfp3(masm, $dst$$Register); 9986 %} 9987 ins_pipe(pipe_slow); 9988 %} 9989 9990 // Compare into -1,0,1 9991 instruct cmpF_imm(rRegI dst, regF src, immF con, rFlagsReg cr) %{ 9992 match(Set dst (CmpF3 src con)); 9993 effect(KILL cr); 9994 9995 ins_cost(275); 9996 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 9997 "movl $dst, #-1\n\t" 9998 "jp,s done\n\t" 9999 "jb,s done\n\t" 10000 "setne $dst\n\t" 10001 "movzbl $dst, $dst\n" 10002 "done:" %} 10003 ins_encode %{ 10004 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 10005 emit_cmpfp3(masm, $dst$$Register); 10006 %} 10007 ins_pipe(pipe_slow); 10008 %} 10009 10010 // Compare into -1,0,1 10011 instruct cmpD_reg(rRegI dst, regD src1, regD src2, rFlagsReg cr) 10012 %{ 10013 match(Set dst (CmpD3 src1 src2)); 10014 effect(KILL cr); 10015 10016 ins_cost(275); 10017 format %{ "ucomisd $src1, $src2\n\t" 10018 "movl $dst, #-1\n\t" 10019 "jp,s done\n\t" 10020 "jb,s done\n\t" 10021 "setne $dst\n\t" 10022 "movzbl $dst, $dst\n" 10023 "done:" %} 10024 ins_encode %{ 10025 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 10026 emit_cmpfp3(masm, $dst$$Register); 10027 %} 10028 ins_pipe(pipe_slow); 10029 %} 10030 10031 // Compare into -1,0,1 10032 instruct cmpD_mem(rRegI dst, regD src1, memory src2, rFlagsReg cr) 10033 %{ 10034 match(Set dst (CmpD3 src1 (LoadD src2))); 10035 effect(KILL cr); 10036 10037 ins_cost(275); 10038 format %{ "ucomisd $src1, $src2\n\t" 10039 "movl $dst, #-1\n\t" 10040 "jp,s done\n\t" 10041 "jb,s done\n\t" 10042 "setne $dst\n\t" 10043 "movzbl $dst, $dst\n" 10044 "done:" %} 10045 ins_encode %{ 10046 __ ucomisd($src1$$XMMRegister, $src2$$Address); 10047 emit_cmpfp3(masm, $dst$$Register); 10048 %} 10049 ins_pipe(pipe_slow); 10050 %} 10051 10052 // Compare into -1,0,1 10053 instruct cmpD_imm(rRegI dst, regD src, immD con, rFlagsReg cr) %{ 10054 match(Set dst (CmpD3 src con)); 10055 effect(KILL cr); 10056 10057 ins_cost(275); 10058 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 10059 "movl $dst, #-1\n\t" 10060 "jp,s done\n\t" 10061 "jb,s done\n\t" 10062 "setne $dst\n\t" 10063 "movzbl $dst, $dst\n" 10064 "done:" %} 10065 ins_encode %{ 10066 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 10067 emit_cmpfp3(masm, $dst$$Register); 10068 %} 10069 ins_pipe(pipe_slow); 10070 %} 10071 10072 //----------Arithmetic Conversion Instructions--------------------------------- 10073 10074 instruct convF2D_reg_reg(regD dst, regF src) 10075 %{ 10076 match(Set dst (ConvF2D src)); 10077 10078 format %{ "cvtss2sd $dst, $src" %} 10079 ins_encode %{ 10080 __ cvtss2sd ($dst$$XMMRegister, $src$$XMMRegister); 10081 %} 10082 ins_pipe(pipe_slow); // XXX 10083 %} 10084 10085 instruct convF2D_reg_mem(regD dst, memory src) 10086 %{ 10087 predicate(UseAVX == 0); 10088 match(Set dst (ConvF2D (LoadF src))); 10089 10090 format %{ "cvtss2sd $dst, $src" %} 10091 ins_encode %{ 10092 __ cvtss2sd ($dst$$XMMRegister, $src$$Address); 10093 %} 10094 ins_pipe(pipe_slow); // XXX 10095 %} 10096 10097 instruct convD2F_reg_reg(regF dst, regD src) 10098 %{ 10099 match(Set dst (ConvD2F src)); 10100 10101 format %{ "cvtsd2ss $dst, $src" %} 10102 ins_encode %{ 10103 __ cvtsd2ss ($dst$$XMMRegister, $src$$XMMRegister); 10104 %} 10105 ins_pipe(pipe_slow); // XXX 10106 %} 10107 10108 instruct convD2F_reg_mem(regF dst, memory src) 10109 %{ 10110 predicate(UseAVX == 0); 10111 match(Set dst (ConvD2F (LoadD src))); 10112 10113 format %{ "cvtsd2ss $dst, $src" %} 10114 ins_encode %{ 10115 __ cvtsd2ss ($dst$$XMMRegister, $src$$Address); 10116 %} 10117 ins_pipe(pipe_slow); // XXX 10118 %} 10119 10120 // XXX do mem variants 10121 instruct convF2I_reg_reg(rRegI dst, regF src, rFlagsReg cr) 10122 %{ 10123 match(Set dst (ConvF2I src)); 10124 effect(KILL cr); 10125 format %{ "convert_f2i $dst, $src" %} 10126 ins_encode %{ 10127 __ convertF2I(T_INT, T_FLOAT, $dst$$Register, $src$$XMMRegister); 10128 %} 10129 ins_pipe(pipe_slow); 10130 %} 10131 10132 instruct convF2L_reg_reg(rRegL dst, regF src, rFlagsReg cr) 10133 %{ 10134 match(Set dst (ConvF2L src)); 10135 effect(KILL cr); 10136 format %{ "convert_f2l $dst, $src"%} 10137 ins_encode %{ 10138 __ convertF2I(T_LONG, T_FLOAT, $dst$$Register, $src$$XMMRegister); 10139 %} 10140 ins_pipe(pipe_slow); 10141 %} 10142 10143 instruct convD2I_reg_reg(rRegI dst, regD src, rFlagsReg cr) 10144 %{ 10145 match(Set dst (ConvD2I src)); 10146 effect(KILL cr); 10147 format %{ "convert_d2i $dst, $src"%} 10148 ins_encode %{ 10149 __ convertF2I(T_INT, T_DOUBLE, $dst$$Register, $src$$XMMRegister); 10150 %} 10151 ins_pipe(pipe_slow); 10152 %} 10153 10154 instruct convD2L_reg_reg(rRegL dst, regD src, rFlagsReg cr) 10155 %{ 10156 match(Set dst (ConvD2L src)); 10157 effect(KILL cr); 10158 format %{ "convert_d2l $dst, $src"%} 10159 ins_encode %{ 10160 __ convertF2I(T_LONG, T_DOUBLE, $dst$$Register, $src$$XMMRegister); 10161 %} 10162 ins_pipe(pipe_slow); 10163 %} 10164 10165 instruct round_double_reg(rRegL dst, regD src, rRegL rtmp, rcx_RegL rcx, rFlagsReg cr) 10166 %{ 10167 match(Set dst (RoundD src)); 10168 effect(TEMP dst, TEMP rtmp, TEMP rcx, KILL cr); 10169 format %{ "round_double $dst,$src \t! using $rtmp and $rcx as TEMP"%} 10170 ins_encode %{ 10171 __ round_double($dst$$Register, $src$$XMMRegister, $rtmp$$Register, $rcx$$Register); 10172 %} 10173 ins_pipe(pipe_slow); 10174 %} 10175 10176 instruct round_float_reg(rRegI dst, regF src, rRegL rtmp, rcx_RegL rcx, rFlagsReg cr) 10177 %{ 10178 match(Set dst (RoundF src)); 10179 effect(TEMP dst, TEMP rtmp, TEMP rcx, KILL cr); 10180 format %{ "round_float $dst,$src" %} 10181 ins_encode %{ 10182 __ round_float($dst$$Register, $src$$XMMRegister, $rtmp$$Register, $rcx$$Register); 10183 %} 10184 ins_pipe(pipe_slow); 10185 %} 10186 10187 instruct convI2F_reg_reg(vlRegF dst, rRegI src) 10188 %{ 10189 predicate(!UseXmmI2F); 10190 match(Set dst (ConvI2F src)); 10191 10192 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10193 ins_encode %{ 10194 if (UseAVX > 0) { 10195 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 10196 } 10197 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Register); 10198 %} 10199 ins_pipe(pipe_slow); // XXX 10200 %} 10201 10202 instruct convI2F_reg_mem(regF dst, memory src) 10203 %{ 10204 predicate(UseAVX == 0); 10205 match(Set dst (ConvI2F (LoadI src))); 10206 10207 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10208 ins_encode %{ 10209 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Address); 10210 %} 10211 ins_pipe(pipe_slow); // XXX 10212 %} 10213 10214 instruct convI2D_reg_reg(vlRegD dst, rRegI src) 10215 %{ 10216 predicate(!UseXmmI2D); 10217 match(Set dst (ConvI2D src)); 10218 10219 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10220 ins_encode %{ 10221 if (UseAVX > 0) { 10222 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 10223 } 10224 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Register); 10225 %} 10226 ins_pipe(pipe_slow); // XXX 10227 %} 10228 10229 instruct convI2D_reg_mem(regD dst, memory src) 10230 %{ 10231 predicate(UseAVX == 0); 10232 match(Set dst (ConvI2D (LoadI src))); 10233 10234 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10235 ins_encode %{ 10236 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Address); 10237 %} 10238 ins_pipe(pipe_slow); // XXX 10239 %} 10240 10241 instruct convXI2F_reg(regF dst, rRegI src) 10242 %{ 10243 predicate(UseXmmI2F); 10244 match(Set dst (ConvI2F src)); 10245 10246 format %{ "movdl $dst, $src\n\t" 10247 "cvtdq2psl $dst, $dst\t# i2f" %} 10248 ins_encode %{ 10249 __ movdl($dst$$XMMRegister, $src$$Register); 10250 __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister); 10251 %} 10252 ins_pipe(pipe_slow); // XXX 10253 %} 10254 10255 instruct convXI2D_reg(regD dst, rRegI src) 10256 %{ 10257 predicate(UseXmmI2D); 10258 match(Set dst (ConvI2D src)); 10259 10260 format %{ "movdl $dst, $src\n\t" 10261 "cvtdq2pdl $dst, $dst\t# i2d" %} 10262 ins_encode %{ 10263 __ movdl($dst$$XMMRegister, $src$$Register); 10264 __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister); 10265 %} 10266 ins_pipe(pipe_slow); // XXX 10267 %} 10268 10269 instruct convL2F_reg_reg(vlRegF dst, rRegL src) 10270 %{ 10271 match(Set dst (ConvL2F src)); 10272 10273 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10274 ins_encode %{ 10275 if (UseAVX > 0) { 10276 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 10277 } 10278 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Register); 10279 %} 10280 ins_pipe(pipe_slow); // XXX 10281 %} 10282 10283 instruct convL2F_reg_mem(regF dst, memory src) 10284 %{ 10285 predicate(UseAVX == 0); 10286 match(Set dst (ConvL2F (LoadL src))); 10287 10288 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10289 ins_encode %{ 10290 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Address); 10291 %} 10292 ins_pipe(pipe_slow); // XXX 10293 %} 10294 10295 instruct convL2D_reg_reg(vlRegD dst, rRegL src) 10296 %{ 10297 match(Set dst (ConvL2D src)); 10298 10299 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10300 ins_encode %{ 10301 if (UseAVX > 0) { 10302 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 10303 } 10304 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Register); 10305 %} 10306 ins_pipe(pipe_slow); // XXX 10307 %} 10308 10309 instruct convL2D_reg_mem(regD dst, memory src) 10310 %{ 10311 predicate(UseAVX == 0); 10312 match(Set dst (ConvL2D (LoadL src))); 10313 10314 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10315 ins_encode %{ 10316 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Address); 10317 %} 10318 ins_pipe(pipe_slow); // XXX 10319 %} 10320 10321 instruct convI2L_reg_reg(rRegL dst, rRegI src) 10322 %{ 10323 match(Set dst (ConvI2L src)); 10324 10325 ins_cost(125); 10326 format %{ "movslq $dst, $src\t# i2l" %} 10327 ins_encode %{ 10328 __ movslq($dst$$Register, $src$$Register); 10329 %} 10330 ins_pipe(ialu_reg_reg); 10331 %} 10332 10333 // Zero-extend convert int to long 10334 instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask) 10335 %{ 10336 match(Set dst (AndL (ConvI2L src) mask)); 10337 10338 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10339 ins_encode %{ 10340 if ($dst$$reg != $src$$reg) { 10341 __ movl($dst$$Register, $src$$Register); 10342 } 10343 %} 10344 ins_pipe(ialu_reg_reg); 10345 %} 10346 10347 // Zero-extend convert int to long 10348 instruct convI2L_reg_mem_zex(rRegL dst, memory src, immL_32bits mask) 10349 %{ 10350 match(Set dst (AndL (ConvI2L (LoadI src)) mask)); 10351 10352 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10353 ins_encode %{ 10354 __ movl($dst$$Register, $src$$Address); 10355 %} 10356 ins_pipe(ialu_reg_mem); 10357 %} 10358 10359 instruct zerox_long_reg_reg(rRegL dst, rRegL src, immL_32bits mask) 10360 %{ 10361 match(Set dst (AndL src mask)); 10362 10363 format %{ "movl $dst, $src\t# zero-extend long" %} 10364 ins_encode %{ 10365 __ movl($dst$$Register, $src$$Register); 10366 %} 10367 ins_pipe(ialu_reg_reg); 10368 %} 10369 10370 instruct convL2I_reg_reg(rRegI dst, rRegL src) 10371 %{ 10372 match(Set dst (ConvL2I src)); 10373 10374 format %{ "movl $dst, $src\t# l2i" %} 10375 ins_encode %{ 10376 __ movl($dst$$Register, $src$$Register); 10377 %} 10378 ins_pipe(ialu_reg_reg); 10379 %} 10380 10381 10382 instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{ 10383 match(Set dst (MoveF2I src)); 10384 effect(DEF dst, USE src); 10385 10386 ins_cost(125); 10387 format %{ "movl $dst, $src\t# MoveF2I_stack_reg" %} 10388 ins_encode %{ 10389 __ movl($dst$$Register, Address(rsp, $src$$disp)); 10390 %} 10391 ins_pipe(ialu_reg_mem); 10392 %} 10393 10394 instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{ 10395 match(Set dst (MoveI2F src)); 10396 effect(DEF dst, USE src); 10397 10398 ins_cost(125); 10399 format %{ "movss $dst, $src\t# MoveI2F_stack_reg" %} 10400 ins_encode %{ 10401 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 10402 %} 10403 ins_pipe(pipe_slow); 10404 %} 10405 10406 instruct MoveD2L_stack_reg(rRegL dst, stackSlotD src) %{ 10407 match(Set dst (MoveD2L src)); 10408 effect(DEF dst, USE src); 10409 10410 ins_cost(125); 10411 format %{ "movq $dst, $src\t# MoveD2L_stack_reg" %} 10412 ins_encode %{ 10413 __ movq($dst$$Register, Address(rsp, $src$$disp)); 10414 %} 10415 ins_pipe(ialu_reg_mem); 10416 %} 10417 10418 instruct MoveL2D_stack_reg_partial(regD dst, stackSlotL src) %{ 10419 predicate(!UseXmmLoadAndClearUpper); 10420 match(Set dst (MoveL2D src)); 10421 effect(DEF dst, USE src); 10422 10423 ins_cost(125); 10424 format %{ "movlpd $dst, $src\t# MoveL2D_stack_reg" %} 10425 ins_encode %{ 10426 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10427 %} 10428 ins_pipe(pipe_slow); 10429 %} 10430 10431 instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{ 10432 predicate(UseXmmLoadAndClearUpper); 10433 match(Set dst (MoveL2D src)); 10434 effect(DEF dst, USE src); 10435 10436 ins_cost(125); 10437 format %{ "movsd $dst, $src\t# MoveL2D_stack_reg" %} 10438 ins_encode %{ 10439 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10440 %} 10441 ins_pipe(pipe_slow); 10442 %} 10443 10444 10445 instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{ 10446 match(Set dst (MoveF2I src)); 10447 effect(DEF dst, USE src); 10448 10449 ins_cost(95); // XXX 10450 format %{ "movss $dst, $src\t# MoveF2I_reg_stack" %} 10451 ins_encode %{ 10452 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 10453 %} 10454 ins_pipe(pipe_slow); 10455 %} 10456 10457 instruct MoveI2F_reg_stack(stackSlotF dst, rRegI src) %{ 10458 match(Set dst (MoveI2F src)); 10459 effect(DEF dst, USE src); 10460 10461 ins_cost(100); 10462 format %{ "movl $dst, $src\t# MoveI2F_reg_stack" %} 10463 ins_encode %{ 10464 __ movl(Address(rsp, $dst$$disp), $src$$Register); 10465 %} 10466 ins_pipe( ialu_mem_reg ); 10467 %} 10468 10469 instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{ 10470 match(Set dst (MoveD2L src)); 10471 effect(DEF dst, USE src); 10472 10473 ins_cost(95); // XXX 10474 format %{ "movsd $dst, $src\t# MoveL2D_reg_stack" %} 10475 ins_encode %{ 10476 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 10477 %} 10478 ins_pipe(pipe_slow); 10479 %} 10480 10481 instruct MoveL2D_reg_stack(stackSlotD dst, rRegL src) %{ 10482 match(Set dst (MoveL2D src)); 10483 effect(DEF dst, USE src); 10484 10485 ins_cost(100); 10486 format %{ "movq $dst, $src\t# MoveL2D_reg_stack" %} 10487 ins_encode %{ 10488 __ movq(Address(rsp, $dst$$disp), $src$$Register); 10489 %} 10490 ins_pipe(ialu_mem_reg); 10491 %} 10492 10493 instruct MoveF2I_reg_reg(rRegI dst, regF src) %{ 10494 match(Set dst (MoveF2I src)); 10495 effect(DEF dst, USE src); 10496 ins_cost(85); 10497 format %{ "movd $dst,$src\t# MoveF2I" %} 10498 ins_encode %{ 10499 __ movdl($dst$$Register, $src$$XMMRegister); 10500 %} 10501 ins_pipe( pipe_slow ); 10502 %} 10503 10504 instruct MoveD2L_reg_reg(rRegL dst, regD src) %{ 10505 match(Set dst (MoveD2L src)); 10506 effect(DEF dst, USE src); 10507 ins_cost(85); 10508 format %{ "movd $dst,$src\t# MoveD2L" %} 10509 ins_encode %{ 10510 __ movdq($dst$$Register, $src$$XMMRegister); 10511 %} 10512 ins_pipe( pipe_slow ); 10513 %} 10514 10515 instruct MoveI2F_reg_reg(regF dst, rRegI src) %{ 10516 match(Set dst (MoveI2F src)); 10517 effect(DEF dst, USE src); 10518 ins_cost(100); 10519 format %{ "movd $dst,$src\t# MoveI2F" %} 10520 ins_encode %{ 10521 __ movdl($dst$$XMMRegister, $src$$Register); 10522 %} 10523 ins_pipe( pipe_slow ); 10524 %} 10525 10526 instruct MoveL2D_reg_reg(regD dst, rRegL src) %{ 10527 match(Set dst (MoveL2D src)); 10528 effect(DEF dst, USE src); 10529 ins_cost(100); 10530 format %{ "movd $dst,$src\t# MoveL2D" %} 10531 ins_encode %{ 10532 __ movdq($dst$$XMMRegister, $src$$Register); 10533 %} 10534 ins_pipe( pipe_slow ); 10535 %} 10536 10537 10538 // Fast clearing of an array 10539 // Small non-constant lenght ClearArray for non-AVX512 targets. 10540 instruct rep_stos(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegL val, 10541 Universe dummy, rFlagsReg cr) 10542 %{ 10543 predicate(!((ClearArrayNode*)n)->is_large() && !((ClearArrayNode*)n)->word_copy_only() && (UseAVX <= 2)); 10544 match(Set dummy (ClearArray (Binary cnt base) val)); 10545 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, USE_KILL val, KILL cr); 10546 10547 format %{ $$template 10548 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 10549 $$emit$$"jg LARGE\n\t" 10550 $$emit$$"dec rcx\n\t" 10551 $$emit$$"js DONE\t# Zero length\n\t" 10552 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 10553 $$emit$$"dec rcx\n\t" 10554 $$emit$$"jge LOOP\n\t" 10555 $$emit$$"jmp DONE\n\t" 10556 $$emit$$"# LARGE:\n\t" 10557 if (UseFastStosb) { 10558 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10559 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--\n\t" 10560 } else if (UseXMMForObjInit) { 10561 $$emit$$"movdq $tmp, $val\n\t" 10562 $$emit$$"punpcklqdq $tmp, $tmp\n\t" 10563 $$emit$$"vinserti128_high $tmp, $tmp\n\t" 10564 $$emit$$"jmpq L_zero_64_bytes\n\t" 10565 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10566 $$emit$$"vmovdqu $tmp,(rax)\n\t" 10567 $$emit$$"vmovdqu $tmp,0x20(rax)\n\t" 10568 $$emit$$"add 0x40,rax\n\t" 10569 $$emit$$"# L_zero_64_bytes:\n\t" 10570 $$emit$$"sub 0x8,rcx\n\t" 10571 $$emit$$"jge L_loop\n\t" 10572 $$emit$$"add 0x4,rcx\n\t" 10573 $$emit$$"jl L_tail\n\t" 10574 $$emit$$"vmovdqu $tmp,(rax)\n\t" 10575 $$emit$$"add 0x20,rax\n\t" 10576 $$emit$$"sub 0x4,rcx\n\t" 10577 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10578 $$emit$$"add 0x4,rcx\n\t" 10579 $$emit$$"jle L_end\n\t" 10580 $$emit$$"dec rcx\n\t" 10581 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10582 $$emit$$"vmovq xmm0,(rax)\n\t" 10583 $$emit$$"add 0x8,rax\n\t" 10584 $$emit$$"dec rcx\n\t" 10585 $$emit$$"jge L_sloop\n\t" 10586 $$emit$$"# L_end:\n\t" 10587 } else { 10588 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 10589 } 10590 $$emit$$"# DONE" 10591 %} 10592 ins_encode %{ 10593 __ clear_mem($base$$Register, $cnt$$Register, $val$$Register, 10594 $tmp$$XMMRegister, false, false); 10595 %} 10596 ins_pipe(pipe_slow); 10597 %} 10598 10599 instruct rep_stos_word_copy(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegL val, 10600 Universe dummy, rFlagsReg cr) 10601 %{ 10602 predicate(!((ClearArrayNode*)n)->is_large() && ((ClearArrayNode*)n)->word_copy_only() && (UseAVX <= 2)); 10603 match(Set dummy (ClearArray (Binary cnt base) val)); 10604 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, USE_KILL val, KILL cr); 10605 10606 format %{ $$template 10607 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 10608 $$emit$$"jg LARGE\n\t" 10609 $$emit$$"dec rcx\n\t" 10610 $$emit$$"js DONE\t# Zero length\n\t" 10611 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 10612 $$emit$$"dec rcx\n\t" 10613 $$emit$$"jge LOOP\n\t" 10614 $$emit$$"jmp DONE\n\t" 10615 $$emit$$"# LARGE:\n\t" 10616 if (UseXMMForObjInit) { 10617 $$emit$$"movdq $tmp, $val\n\t" 10618 $$emit$$"punpcklqdq $tmp, $tmp\n\t" 10619 $$emit$$"vinserti128_high $tmp, $tmp\n\t" 10620 $$emit$$"jmpq L_zero_64_bytes\n\t" 10621 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10622 $$emit$$"vmovdqu $tmp,(rax)\n\t" 10623 $$emit$$"vmovdqu $tmp,0x20(rax)\n\t" 10624 $$emit$$"add 0x40,rax\n\t" 10625 $$emit$$"# L_zero_64_bytes:\n\t" 10626 $$emit$$"sub 0x8,rcx\n\t" 10627 $$emit$$"jge L_loop\n\t" 10628 $$emit$$"add 0x4,rcx\n\t" 10629 $$emit$$"jl L_tail\n\t" 10630 $$emit$$"vmovdqu $tmp,(rax)\n\t" 10631 $$emit$$"add 0x20,rax\n\t" 10632 $$emit$$"sub 0x4,rcx\n\t" 10633 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10634 $$emit$$"add 0x4,rcx\n\t" 10635 $$emit$$"jle L_end\n\t" 10636 $$emit$$"dec rcx\n\t" 10637 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10638 $$emit$$"vmovq xmm0,(rax)\n\t" 10639 $$emit$$"add 0x8,rax\n\t" 10640 $$emit$$"dec rcx\n\t" 10641 $$emit$$"jge L_sloop\n\t" 10642 $$emit$$"# L_end:\n\t" 10643 } else { 10644 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 10645 } 10646 $$emit$$"# DONE" 10647 %} 10648 ins_encode %{ 10649 __ clear_mem($base$$Register, $cnt$$Register, $val$$Register, 10650 $tmp$$XMMRegister, false, true); 10651 %} 10652 ins_pipe(pipe_slow); 10653 %} 10654 10655 // Small non-constant length ClearArray for AVX512 targets. 10656 instruct rep_stos_evex(rcx_RegL cnt, rdi_RegP base, legRegD tmp, kReg ktmp, rax_RegL val, 10657 Universe dummy, rFlagsReg cr) 10658 %{ 10659 predicate(!((ClearArrayNode*)n)->is_large() && !((ClearArrayNode*)n)->word_copy_only() && (UseAVX > 2)); 10660 match(Set dummy (ClearArray (Binary cnt base) val)); 10661 ins_cost(125); 10662 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, TEMP ktmp, USE_KILL val, KILL cr); 10663 10664 format %{ $$template 10665 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10666 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 10667 $$emit$$"jg LARGE\n\t" 10668 $$emit$$"dec rcx\n\t" 10669 $$emit$$"js DONE\t# Zero length\n\t" 10670 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 10671 $$emit$$"dec rcx\n\t" 10672 $$emit$$"jge LOOP\n\t" 10673 $$emit$$"jmp DONE\n\t" 10674 $$emit$$"# LARGE:\n\t" 10675 if (UseFastStosb) { 10676 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10677 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--\n\t" 10678 } else if (UseXMMForObjInit) { 10679 $$emit$$"mov rdi,rax\n\t" 10680 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 10681 $$emit$$"jmpq L_zero_64_bytes\n\t" 10682 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10683 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10684 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 10685 $$emit$$"add 0x40,rax\n\t" 10686 $$emit$$"# L_zero_64_bytes:\n\t" 10687 $$emit$$"sub 0x8,rcx\n\t" 10688 $$emit$$"jge L_loop\n\t" 10689 $$emit$$"add 0x4,rcx\n\t" 10690 $$emit$$"jl L_tail\n\t" 10691 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10692 $$emit$$"add 0x20,rax\n\t" 10693 $$emit$$"sub 0x4,rcx\n\t" 10694 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10695 $$emit$$"add 0x4,rcx\n\t" 10696 $$emit$$"jle L_end\n\t" 10697 $$emit$$"dec rcx\n\t" 10698 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10699 $$emit$$"vmovq xmm0,(rax)\n\t" 10700 $$emit$$"add 0x8,rax\n\t" 10701 $$emit$$"dec rcx\n\t" 10702 $$emit$$"jge L_sloop\n\t" 10703 $$emit$$"# L_end:\n\t" 10704 } else { 10705 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 10706 } 10707 $$emit$$"# DONE" 10708 %} 10709 ins_encode %{ 10710 __ clear_mem($base$$Register, $cnt$$Register, $val$$Register, 10711 $tmp$$XMMRegister, false, false, $ktmp$$KRegister); 10712 %} 10713 ins_pipe(pipe_slow); 10714 %} 10715 10716 instruct rep_stos_evex_word_copy(rcx_RegL cnt, rdi_RegP base, legRegD tmp, kReg ktmp, rax_RegL val, 10717 Universe dummy, rFlagsReg cr) 10718 %{ 10719 predicate(!((ClearArrayNode*)n)->is_large() && ((ClearArrayNode*)n)->word_copy_only() && (UseAVX > 2)); 10720 match(Set dummy (ClearArray (Binary cnt base) val)); 10721 ins_cost(125); 10722 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, TEMP ktmp, USE_KILL val, KILL cr); 10723 10724 format %{ $$template 10725 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10726 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 10727 $$emit$$"jg LARGE\n\t" 10728 $$emit$$"dec rcx\n\t" 10729 $$emit$$"js DONE\t# Zero length\n\t" 10730 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 10731 $$emit$$"dec rcx\n\t" 10732 $$emit$$"jge LOOP\n\t" 10733 $$emit$$"jmp DONE\n\t" 10734 $$emit$$"# LARGE:\n\t" 10735 if (UseFastStosb) { 10736 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10737 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--\n\t" 10738 } else if (UseXMMForObjInit) { 10739 $$emit$$"mov rdi,rax\n\t" 10740 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 10741 $$emit$$"jmpq L_zero_64_bytes\n\t" 10742 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10743 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10744 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 10745 $$emit$$"add 0x40,rax\n\t" 10746 $$emit$$"# L_zero_64_bytes:\n\t" 10747 $$emit$$"sub 0x8,rcx\n\t" 10748 $$emit$$"jge L_loop\n\t" 10749 $$emit$$"add 0x4,rcx\n\t" 10750 $$emit$$"jl L_tail\n\t" 10751 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10752 $$emit$$"add 0x20,rax\n\t" 10753 $$emit$$"sub 0x4,rcx\n\t" 10754 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10755 $$emit$$"add 0x4,rcx\n\t" 10756 $$emit$$"jle L_end\n\t" 10757 $$emit$$"dec rcx\n\t" 10758 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10759 $$emit$$"vmovq xmm0,(rax)\n\t" 10760 $$emit$$"add 0x8,rax\n\t" 10761 $$emit$$"dec rcx\n\t" 10762 $$emit$$"jge L_sloop\n\t" 10763 $$emit$$"# L_end:\n\t" 10764 } else { 10765 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 10766 } 10767 $$emit$$"# DONE" 10768 %} 10769 ins_encode %{ 10770 __ clear_mem($base$$Register, $cnt$$Register, $val$$Register, 10771 $tmp$$XMMRegister, false, true, $ktmp$$KRegister); 10772 %} 10773 ins_pipe(pipe_slow); 10774 %} 10775 10776 // Large non-constant length ClearArray for non-AVX512 targets. 10777 instruct rep_stos_large(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegL val, 10778 Universe dummy, rFlagsReg cr) 10779 %{ 10780 predicate(((ClearArrayNode*)n)->is_large() && !((ClearArrayNode*)n)->word_copy_only() && (UseAVX <= 2)); 10781 match(Set dummy (ClearArray (Binary cnt base) val)); 10782 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, USE_KILL val, KILL cr); 10783 10784 format %{ $$template 10785 if (UseFastStosb) { 10786 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10787 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--" 10788 } else if (UseXMMForObjInit) { 10789 $$emit$$"movdq $tmp, $val\n\t" 10790 $$emit$$"punpcklqdq $tmp, $tmp\n\t" 10791 $$emit$$"vinserti128_high $tmp, $tmp\n\t" 10792 $$emit$$"jmpq L_zero_64_bytes\n\t" 10793 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10794 $$emit$$"vmovdqu $tmp,(rax)\n\t" 10795 $$emit$$"vmovdqu $tmp,0x20(rax)\n\t" 10796 $$emit$$"add 0x40,rax\n\t" 10797 $$emit$$"# L_zero_64_bytes:\n\t" 10798 $$emit$$"sub 0x8,rcx\n\t" 10799 $$emit$$"jge L_loop\n\t" 10800 $$emit$$"add 0x4,rcx\n\t" 10801 $$emit$$"jl L_tail\n\t" 10802 $$emit$$"vmovdqu $tmp,(rax)\n\t" 10803 $$emit$$"add 0x20,rax\n\t" 10804 $$emit$$"sub 0x4,rcx\n\t" 10805 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10806 $$emit$$"add 0x4,rcx\n\t" 10807 $$emit$$"jle L_end\n\t" 10808 $$emit$$"dec rcx\n\t" 10809 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10810 $$emit$$"vmovq xmm0,(rax)\n\t" 10811 $$emit$$"add 0x8,rax\n\t" 10812 $$emit$$"dec rcx\n\t" 10813 $$emit$$"jge L_sloop\n\t" 10814 $$emit$$"# L_end:\n\t" 10815 } else { 10816 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 10817 } 10818 %} 10819 ins_encode %{ 10820 __ clear_mem($base$$Register, $cnt$$Register, $val$$Register, 10821 $tmp$$XMMRegister, true, false); 10822 %} 10823 ins_pipe(pipe_slow); 10824 %} 10825 10826 instruct rep_stos_large_word_copy(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegL val, 10827 Universe dummy, rFlagsReg cr) 10828 %{ 10829 predicate(((ClearArrayNode*)n)->is_large() && ((ClearArrayNode*)n)->word_copy_only() && (UseAVX <= 2)); 10830 match(Set dummy (ClearArray (Binary cnt base) val)); 10831 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, USE_KILL val, KILL cr); 10832 10833 format %{ $$template 10834 if (UseXMMForObjInit) { 10835 $$emit$$"movdq $tmp, $val\n\t" 10836 $$emit$$"punpcklqdq $tmp, $tmp\n\t" 10837 $$emit$$"vinserti128_high $tmp, $tmp\n\t" 10838 $$emit$$"jmpq L_zero_64_bytes\n\t" 10839 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10840 $$emit$$"vmovdqu $tmp,(rax)\n\t" 10841 $$emit$$"vmovdqu $tmp,0x20(rax)\n\t" 10842 $$emit$$"add 0x40,rax\n\t" 10843 $$emit$$"# L_zero_64_bytes:\n\t" 10844 $$emit$$"sub 0x8,rcx\n\t" 10845 $$emit$$"jge L_loop\n\t" 10846 $$emit$$"add 0x4,rcx\n\t" 10847 $$emit$$"jl L_tail\n\t" 10848 $$emit$$"vmovdqu $tmp,(rax)\n\t" 10849 $$emit$$"add 0x20,rax\n\t" 10850 $$emit$$"sub 0x4,rcx\n\t" 10851 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10852 $$emit$$"add 0x4,rcx\n\t" 10853 $$emit$$"jle L_end\n\t" 10854 $$emit$$"dec rcx\n\t" 10855 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10856 $$emit$$"vmovq xmm0,(rax)\n\t" 10857 $$emit$$"add 0x8,rax\n\t" 10858 $$emit$$"dec rcx\n\t" 10859 $$emit$$"jge L_sloop\n\t" 10860 $$emit$$"# L_end:\n\t" 10861 } else { 10862 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 10863 } 10864 %} 10865 ins_encode %{ 10866 __ clear_mem($base$$Register, $cnt$$Register, $val$$Register, 10867 $tmp$$XMMRegister, true, true); 10868 %} 10869 ins_pipe(pipe_slow); 10870 %} 10871 10872 // Large non-constant length ClearArray for AVX512 targets. 10873 instruct rep_stos_large_evex(rcx_RegL cnt, rdi_RegP base, legRegD tmp, kReg ktmp, rax_RegL val, 10874 Universe dummy, rFlagsReg cr) 10875 %{ 10876 predicate(((ClearArrayNode*)n)->is_large() && !((ClearArrayNode*)n)->word_copy_only() && (UseAVX > 2)); 10877 match(Set dummy (ClearArray (Binary cnt base) val)); 10878 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, TEMP ktmp, USE_KILL val, KILL cr); 10879 10880 format %{ $$template 10881 if (UseFastStosb) { 10882 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10883 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10884 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--" 10885 } else if (UseXMMForObjInit) { 10886 $$emit$$"mov rdi,rax\t# ClearArray:\n\t" 10887 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 10888 $$emit$$"jmpq L_zero_64_bytes\n\t" 10889 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10890 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10891 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 10892 $$emit$$"add 0x40,rax\n\t" 10893 $$emit$$"# L_zero_64_bytes:\n\t" 10894 $$emit$$"sub 0x8,rcx\n\t" 10895 $$emit$$"jge L_loop\n\t" 10896 $$emit$$"add 0x4,rcx\n\t" 10897 $$emit$$"jl L_tail\n\t" 10898 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10899 $$emit$$"add 0x20,rax\n\t" 10900 $$emit$$"sub 0x4,rcx\n\t" 10901 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10902 $$emit$$"add 0x4,rcx\n\t" 10903 $$emit$$"jle L_end\n\t" 10904 $$emit$$"dec rcx\n\t" 10905 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10906 $$emit$$"vmovq xmm0,(rax)\n\t" 10907 $$emit$$"add 0x8,rax\n\t" 10908 $$emit$$"dec rcx\n\t" 10909 $$emit$$"jge L_sloop\n\t" 10910 $$emit$$"# L_end:\n\t" 10911 } else { 10912 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10913 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 10914 } 10915 %} 10916 ins_encode %{ 10917 __ clear_mem($base$$Register, $cnt$$Register, $val$$Register, 10918 $tmp$$XMMRegister, true, false, $ktmp$$KRegister); 10919 %} 10920 ins_pipe(pipe_slow); 10921 %} 10922 10923 instruct rep_stos_large_evex_word_copy(rcx_RegL cnt, rdi_RegP base, legRegD tmp, kReg ktmp, rax_RegL val, 10924 Universe dummy, rFlagsReg cr) 10925 %{ 10926 predicate(((ClearArrayNode*)n)->is_large() && ((ClearArrayNode*)n)->word_copy_only() && (UseAVX > 2)); 10927 match(Set dummy (ClearArray (Binary cnt base) val)); 10928 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, TEMP ktmp, USE_KILL val, KILL cr); 10929 10930 format %{ $$template 10931 if (UseFastStosb) { 10932 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10933 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 10934 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--" 10935 } else if (UseXMMForObjInit) { 10936 $$emit$$"mov rdi,rax\t# ClearArray:\n\t" 10937 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 10938 $$emit$$"jmpq L_zero_64_bytes\n\t" 10939 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 10940 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10941 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 10942 $$emit$$"add 0x40,rax\n\t" 10943 $$emit$$"# L_zero_64_bytes:\n\t" 10944 $$emit$$"sub 0x8,rcx\n\t" 10945 $$emit$$"jge L_loop\n\t" 10946 $$emit$$"add 0x4,rcx\n\t" 10947 $$emit$$"jl L_tail\n\t" 10948 $$emit$$"vmovdqu ymm0,(rax)\n\t" 10949 $$emit$$"add 0x20,rax\n\t" 10950 $$emit$$"sub 0x4,rcx\n\t" 10951 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 10952 $$emit$$"add 0x4,rcx\n\t" 10953 $$emit$$"jle L_end\n\t" 10954 $$emit$$"dec rcx\n\t" 10955 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 10956 $$emit$$"vmovq xmm0,(rax)\n\t" 10957 $$emit$$"add 0x8,rax\n\t" 10958 $$emit$$"dec rcx\n\t" 10959 $$emit$$"jge L_sloop\n\t" 10960 $$emit$$"# L_end:\n\t" 10961 } else { 10962 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 10963 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 10964 } 10965 %} 10966 ins_encode %{ 10967 __ clear_mem($base$$Register, $cnt$$Register, $val$$Register, 10968 $tmp$$XMMRegister, true, true, $ktmp$$KRegister); 10969 %} 10970 ins_pipe(pipe_slow); 10971 %} 10972 10973 // Small constant length ClearArray for AVX512 targets. 10974 instruct rep_stos_im(immL cnt, rRegP base, regD tmp, rax_RegL val, kReg ktmp, Universe dummy, rFlagsReg cr) 10975 %{ 10976 predicate(!((ClearArrayNode*)n)->is_large() && !((ClearArrayNode*)n)->word_copy_only() && 10977 ((MaxVectorSize >= 32) && VM_Version::supports_avx512vl())); 10978 match(Set dummy (ClearArray (Binary cnt base) val)); 10979 ins_cost(100); 10980 effect(TEMP tmp, USE_KILL val, TEMP ktmp, KILL cr); 10981 format %{ "clear_mem_imm $base , $cnt \n\t" %} 10982 ins_encode %{ 10983 __ clear_mem($base$$Register, $cnt$$constant, $val$$Register, $tmp$$XMMRegister, $ktmp$$KRegister); 10984 %} 10985 ins_pipe(pipe_slow); 10986 %} 10987 10988 instruct string_compareL(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10989 rax_RegI result, legRegD tmp1, rFlagsReg cr) 10990 %{ 10991 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 10992 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10993 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10994 10995 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10996 ins_encode %{ 10997 __ string_compare($str1$$Register, $str2$$Register, 10998 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10999 $tmp1$$XMMRegister, StrIntrinsicNode::LL, knoreg); 11000 %} 11001 ins_pipe( pipe_slow ); 11002 %} 11003 11004 instruct string_compareL_evex(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 11005 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 11006 %{ 11007 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 11008 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11009 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11010 11011 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11012 ins_encode %{ 11013 __ string_compare($str1$$Register, $str2$$Register, 11014 $cnt1$$Register, $cnt2$$Register, $result$$Register, 11015 $tmp1$$XMMRegister, StrIntrinsicNode::LL, $ktmp$$KRegister); 11016 %} 11017 ins_pipe( pipe_slow ); 11018 %} 11019 11020 instruct string_compareU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 11021 rax_RegI result, legRegD tmp1, rFlagsReg cr) 11022 %{ 11023 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 11024 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11025 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11026 11027 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11028 ins_encode %{ 11029 __ string_compare($str1$$Register, $str2$$Register, 11030 $cnt1$$Register, $cnt2$$Register, $result$$Register, 11031 $tmp1$$XMMRegister, StrIntrinsicNode::UU, knoreg); 11032 %} 11033 ins_pipe( pipe_slow ); 11034 %} 11035 11036 instruct string_compareU_evex(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 11037 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 11038 %{ 11039 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 11040 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11041 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11042 11043 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11044 ins_encode %{ 11045 __ string_compare($str1$$Register, $str2$$Register, 11046 $cnt1$$Register, $cnt2$$Register, $result$$Register, 11047 $tmp1$$XMMRegister, StrIntrinsicNode::UU, $ktmp$$KRegister); 11048 %} 11049 ins_pipe( pipe_slow ); 11050 %} 11051 11052 instruct string_compareLU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 11053 rax_RegI result, legRegD tmp1, rFlagsReg cr) 11054 %{ 11055 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 11056 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11057 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11058 11059 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11060 ins_encode %{ 11061 __ string_compare($str1$$Register, $str2$$Register, 11062 $cnt1$$Register, $cnt2$$Register, $result$$Register, 11063 $tmp1$$XMMRegister, StrIntrinsicNode::LU, knoreg); 11064 %} 11065 ins_pipe( pipe_slow ); 11066 %} 11067 11068 instruct string_compareLU_evex(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 11069 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 11070 %{ 11071 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 11072 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11073 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11074 11075 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11076 ins_encode %{ 11077 __ string_compare($str1$$Register, $str2$$Register, 11078 $cnt1$$Register, $cnt2$$Register, $result$$Register, 11079 $tmp1$$XMMRegister, StrIntrinsicNode::LU, $ktmp$$KRegister); 11080 %} 11081 ins_pipe( pipe_slow ); 11082 %} 11083 11084 instruct string_compareUL(rsi_RegP str1, rdx_RegI cnt1, rdi_RegP str2, rcx_RegI cnt2, 11085 rax_RegI result, legRegD tmp1, rFlagsReg cr) 11086 %{ 11087 predicate(!VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 11088 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11089 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11090 11091 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11092 ins_encode %{ 11093 __ string_compare($str2$$Register, $str1$$Register, 11094 $cnt2$$Register, $cnt1$$Register, $result$$Register, 11095 $tmp1$$XMMRegister, StrIntrinsicNode::UL, knoreg); 11096 %} 11097 ins_pipe( pipe_slow ); 11098 %} 11099 11100 instruct string_compareUL_evex(rsi_RegP str1, rdx_RegI cnt1, rdi_RegP str2, rcx_RegI cnt2, 11101 rax_RegI result, legRegD tmp1, kReg ktmp, rFlagsReg cr) 11102 %{ 11103 predicate(VM_Version::supports_avx512vlbw() && ((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 11104 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11105 effect(TEMP tmp1, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11106 11107 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11108 ins_encode %{ 11109 __ string_compare($str2$$Register, $str1$$Register, 11110 $cnt2$$Register, $cnt1$$Register, $result$$Register, 11111 $tmp1$$XMMRegister, StrIntrinsicNode::UL, $ktmp$$KRegister); 11112 %} 11113 ins_pipe( pipe_slow ); 11114 %} 11115 11116 // fast search of substring with known size. 11117 instruct string_indexof_conL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 11118 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 11119 %{ 11120 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 11121 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 11122 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 11123 11124 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %} 11125 ins_encode %{ 11126 int icnt2 = (int)$int_cnt2$$constant; 11127 if (icnt2 >= 16) { 11128 // IndexOf for constant substrings with size >= 16 elements 11129 // which don't need to be loaded through stack. 11130 __ string_indexofC8($str1$$Register, $str2$$Register, 11131 $cnt1$$Register, $cnt2$$Register, 11132 icnt2, $result$$Register, 11133 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 11134 } else { 11135 // Small strings are loaded through stack if they cross page boundary. 11136 __ string_indexof($str1$$Register, $str2$$Register, 11137 $cnt1$$Register, $cnt2$$Register, 11138 icnt2, $result$$Register, 11139 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 11140 } 11141 %} 11142 ins_pipe( pipe_slow ); 11143 %} 11144 11145 // fast search of substring with known size. 11146 instruct string_indexof_conU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 11147 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 11148 %{ 11149 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 11150 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 11151 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 11152 11153 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %} 11154 ins_encode %{ 11155 int icnt2 = (int)$int_cnt2$$constant; 11156 if (icnt2 >= 8) { 11157 // IndexOf for constant substrings with size >= 8 elements 11158 // which don't need to be loaded through stack. 11159 __ string_indexofC8($str1$$Register, $str2$$Register, 11160 $cnt1$$Register, $cnt2$$Register, 11161 icnt2, $result$$Register, 11162 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 11163 } else { 11164 // Small strings are loaded through stack if they cross page boundary. 11165 __ string_indexof($str1$$Register, $str2$$Register, 11166 $cnt1$$Register, $cnt2$$Register, 11167 icnt2, $result$$Register, 11168 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 11169 } 11170 %} 11171 ins_pipe( pipe_slow ); 11172 %} 11173 11174 // fast search of substring with known size. 11175 instruct string_indexof_conUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 11176 rbx_RegI result, legRegD tmp_vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 11177 %{ 11178 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 11179 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 11180 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 11181 11182 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $tmp_vec, $cnt1, $cnt2, $tmp" %} 11183 ins_encode %{ 11184 int icnt2 = (int)$int_cnt2$$constant; 11185 if (icnt2 >= 8) { 11186 // IndexOf for constant substrings with size >= 8 elements 11187 // which don't need to be loaded through stack. 11188 __ string_indexofC8($str1$$Register, $str2$$Register, 11189 $cnt1$$Register, $cnt2$$Register, 11190 icnt2, $result$$Register, 11191 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 11192 } else { 11193 // Small strings are loaded through stack if they cross page boundary. 11194 __ string_indexof($str1$$Register, $str2$$Register, 11195 $cnt1$$Register, $cnt2$$Register, 11196 icnt2, $result$$Register, 11197 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 11198 } 11199 %} 11200 ins_pipe( pipe_slow ); 11201 %} 11202 11203 instruct string_indexofL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11204 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr) 11205 %{ 11206 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 11207 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11208 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11209 11210 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11211 ins_encode %{ 11212 __ string_indexof($str1$$Register, $str2$$Register, 11213 $cnt1$$Register, $cnt2$$Register, 11214 (-1), $result$$Register, 11215 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 11216 %} 11217 ins_pipe( pipe_slow ); 11218 %} 11219 11220 instruct string_indexofU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11221 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr) 11222 %{ 11223 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 11224 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11225 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11226 11227 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11228 ins_encode %{ 11229 __ string_indexof($str1$$Register, $str2$$Register, 11230 $cnt1$$Register, $cnt2$$Register, 11231 (-1), $result$$Register, 11232 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 11233 %} 11234 ins_pipe( pipe_slow ); 11235 %} 11236 11237 instruct string_indexofUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11238 rbx_RegI result, legRegD tmp_vec, rcx_RegI tmp, rFlagsReg cr) 11239 %{ 11240 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 11241 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11242 effect(TEMP tmp_vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11243 11244 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11245 ins_encode %{ 11246 __ string_indexof($str1$$Register, $str2$$Register, 11247 $cnt1$$Register, $cnt2$$Register, 11248 (-1), $result$$Register, 11249 $tmp_vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 11250 %} 11251 ins_pipe( pipe_slow ); 11252 %} 11253 11254 instruct string_indexof_char(rdi_RegP str1, rdx_RegI cnt1, rax_RegI ch, 11255 rbx_RegI result, legRegD tmp_vec1, legRegD tmp_vec2, legRegD tmp_vec3, rcx_RegI tmp, rFlagsReg cr) 11256 %{ 11257 predicate(UseSSE42Intrinsics && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::U)); 11258 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 11259 effect(TEMP tmp_vec1, TEMP tmp_vec2, TEMP tmp_vec3, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP tmp, KILL cr); 11260 format %{ "StringUTF16 IndexOf char[] $str1,$cnt1,$ch -> $result // KILL all" %} 11261 ins_encode %{ 11262 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register, 11263 $tmp_vec1$$XMMRegister, $tmp_vec2$$XMMRegister, $tmp_vec3$$XMMRegister, $tmp$$Register); 11264 %} 11265 ins_pipe( pipe_slow ); 11266 %} 11267 11268 instruct stringL_indexof_char(rdi_RegP str1, rdx_RegI cnt1, rax_RegI ch, 11269 rbx_RegI result, legRegD tmp_vec1, legRegD tmp_vec2, legRegD tmp_vec3, rcx_RegI tmp, rFlagsReg cr) 11270 %{ 11271 predicate(UseSSE42Intrinsics && (((StrIndexOfCharNode*)n)->encoding() == StrIntrinsicNode::L)); 11272 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 11273 effect(TEMP tmp_vec1, TEMP tmp_vec2, TEMP tmp_vec3, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP tmp, KILL cr); 11274 format %{ "StringLatin1 IndexOf char[] $str1,$cnt1,$ch -> $result // KILL all" %} 11275 ins_encode %{ 11276 __ stringL_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register, 11277 $tmp_vec1$$XMMRegister, $tmp_vec2$$XMMRegister, $tmp_vec3$$XMMRegister, $tmp$$Register); 11278 %} 11279 ins_pipe( pipe_slow ); 11280 %} 11281 11282 // fast string equals 11283 instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 11284 legRegD tmp1, legRegD tmp2, rbx_RegI tmp3, rFlagsReg cr) 11285 %{ 11286 predicate(!VM_Version::supports_avx512vlbw()); 11287 match(Set result (StrEquals (Binary str1 str2) cnt)); 11288 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 11289 11290 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11291 ins_encode %{ 11292 __ arrays_equals(false, $str1$$Register, $str2$$Register, 11293 $cnt$$Register, $result$$Register, $tmp3$$Register, 11294 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, knoreg); 11295 %} 11296 ins_pipe( pipe_slow ); 11297 %} 11298 11299 instruct string_equals_evex(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 11300 legRegD tmp1, legRegD tmp2, kReg ktmp, rbx_RegI tmp3, rFlagsReg cr) 11301 %{ 11302 predicate(VM_Version::supports_avx512vlbw()); 11303 match(Set result (StrEquals (Binary str1 str2) cnt)); 11304 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 11305 11306 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11307 ins_encode %{ 11308 __ arrays_equals(false, $str1$$Register, $str2$$Register, 11309 $cnt$$Register, $result$$Register, $tmp3$$Register, 11310 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, $ktmp$$KRegister); 11311 %} 11312 ins_pipe( pipe_slow ); 11313 %} 11314 11315 // fast array equals 11316 instruct array_equalsB(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11317 legRegD tmp1, legRegD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11318 %{ 11319 predicate(!VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 11320 match(Set result (AryEq ary1 ary2)); 11321 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11322 11323 format %{ "Array Equals byte[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11324 ins_encode %{ 11325 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11326 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11327 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, knoreg); 11328 %} 11329 ins_pipe( pipe_slow ); 11330 %} 11331 11332 instruct array_equalsB_evex(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11333 legRegD tmp1, legRegD tmp2, kReg ktmp, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11334 %{ 11335 predicate(VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 11336 match(Set result (AryEq ary1 ary2)); 11337 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11338 11339 format %{ "Array Equals byte[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11340 ins_encode %{ 11341 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11342 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11343 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */, $ktmp$$KRegister); 11344 %} 11345 ins_pipe( pipe_slow ); 11346 %} 11347 11348 instruct array_equalsC(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11349 legRegD tmp1, legRegD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11350 %{ 11351 predicate(!VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 11352 match(Set result (AryEq ary1 ary2)); 11353 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11354 11355 format %{ "Array Equals char[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11356 ins_encode %{ 11357 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11358 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11359 $tmp1$$XMMRegister, $tmp2$$XMMRegister, true /* char */, knoreg); 11360 %} 11361 ins_pipe( pipe_slow ); 11362 %} 11363 11364 instruct array_equalsC_evex(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11365 legRegD tmp1, legRegD tmp2, kReg ktmp, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11366 %{ 11367 predicate(VM_Version::supports_avx512vlbw() && ((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 11368 match(Set result (AryEq ary1 ary2)); 11369 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11370 11371 format %{ "Array Equals char[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11372 ins_encode %{ 11373 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11374 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11375 $tmp1$$XMMRegister, $tmp2$$XMMRegister, true /* char */, $ktmp$$KRegister); 11376 %} 11377 ins_pipe( pipe_slow ); 11378 %} 11379 11380 instruct arrays_hashcode(rdi_RegP ary1, rdx_RegI cnt1, rbx_RegI result, immU8 basic_type, 11381 legRegD tmp_vec1, legRegD tmp_vec2, legRegD tmp_vec3, legRegD tmp_vec4, 11382 legRegD tmp_vec5, legRegD tmp_vec6, legRegD tmp_vec7, legRegD tmp_vec8, 11383 legRegD tmp_vec9, legRegD tmp_vec10, legRegD tmp_vec11, legRegD tmp_vec12, 11384 legRegD tmp_vec13, rRegI tmp1, rRegI tmp2, rRegI tmp3, rFlagsReg cr) 11385 %{ 11386 predicate(UseAVX >= 2); 11387 match(Set result (VectorizedHashCode (Binary ary1 cnt1) (Binary result basic_type))); 11388 effect(TEMP tmp_vec1, TEMP tmp_vec2, TEMP tmp_vec3, TEMP tmp_vec4, TEMP tmp_vec5, TEMP tmp_vec6, 11389 TEMP tmp_vec7, TEMP tmp_vec8, TEMP tmp_vec9, TEMP tmp_vec10, TEMP tmp_vec11, TEMP tmp_vec12, 11390 TEMP tmp_vec13, TEMP tmp1, TEMP tmp2, TEMP tmp3, USE_KILL ary1, USE_KILL cnt1, 11391 USE basic_type, KILL cr); 11392 11393 format %{ "Array HashCode array[] $ary1,$cnt1,$result,$basic_type -> $result // KILL all" %} 11394 ins_encode %{ 11395 __ arrays_hashcode($ary1$$Register, $cnt1$$Register, $result$$Register, 11396 $tmp1$$Register, $tmp2$$Register, $tmp3$$Register, 11397 $tmp_vec1$$XMMRegister, $tmp_vec2$$XMMRegister, $tmp_vec3$$XMMRegister, 11398 $tmp_vec4$$XMMRegister, $tmp_vec5$$XMMRegister, $tmp_vec6$$XMMRegister, 11399 $tmp_vec7$$XMMRegister, $tmp_vec8$$XMMRegister, $tmp_vec9$$XMMRegister, 11400 $tmp_vec10$$XMMRegister, $tmp_vec11$$XMMRegister, $tmp_vec12$$XMMRegister, 11401 $tmp_vec13$$XMMRegister, (BasicType)$basic_type$$constant); 11402 %} 11403 ins_pipe( pipe_slow ); 11404 %} 11405 11406 instruct count_positives(rsi_RegP ary1, rcx_RegI len, rax_RegI result, 11407 legRegD tmp1, legRegD tmp2, rbx_RegI tmp3, rFlagsReg cr,) 11408 %{ 11409 predicate(!VM_Version::supports_avx512vlbw() || !VM_Version::supports_bmi2()); 11410 match(Set result (CountPositives ary1 len)); 11411 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr); 11412 11413 format %{ "countPositives byte[] $ary1,$len -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11414 ins_encode %{ 11415 __ count_positives($ary1$$Register, $len$$Register, 11416 $result$$Register, $tmp3$$Register, 11417 $tmp1$$XMMRegister, $tmp2$$XMMRegister, knoreg, knoreg); 11418 %} 11419 ins_pipe( pipe_slow ); 11420 %} 11421 11422 instruct count_positives_evex(rsi_RegP ary1, rcx_RegI len, rax_RegI result, 11423 legRegD tmp1, legRegD tmp2, kReg ktmp1, kReg ktmp2, rbx_RegI tmp3, rFlagsReg cr,) 11424 %{ 11425 predicate(VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2()); 11426 match(Set result (CountPositives ary1 len)); 11427 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp1, TEMP ktmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr); 11428 11429 format %{ "countPositives byte[] $ary1,$len -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11430 ins_encode %{ 11431 __ count_positives($ary1$$Register, $len$$Register, 11432 $result$$Register, $tmp3$$Register, 11433 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $ktmp1$$KRegister, $ktmp2$$KRegister); 11434 %} 11435 ins_pipe( pipe_slow ); 11436 %} 11437 11438 // fast char[] to byte[] compression 11439 instruct string_compress(rsi_RegP src, rdi_RegP dst, rdx_RegI len, legRegD tmp1, legRegD tmp2, legRegD tmp3, 11440 legRegD tmp4, rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11441 predicate(!VM_Version::supports_avx512vlbw() || !VM_Version::supports_bmi2()); 11442 match(Set result (StrCompressedCopy src (Binary dst len))); 11443 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, 11444 USE_KILL len, KILL tmp5, KILL cr); 11445 11446 format %{ "String Compress $src,$dst -> $result // KILL RAX, RCX, RDX" %} 11447 ins_encode %{ 11448 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 11449 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11450 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, 11451 knoreg, knoreg); 11452 %} 11453 ins_pipe( pipe_slow ); 11454 %} 11455 11456 instruct string_compress_evex(rsi_RegP src, rdi_RegP dst, rdx_RegI len, legRegD tmp1, legRegD tmp2, legRegD tmp3, 11457 legRegD tmp4, kReg ktmp1, kReg ktmp2, rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11458 predicate(VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2()); 11459 match(Set result (StrCompressedCopy src (Binary dst len))); 11460 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, TEMP ktmp1, TEMP ktmp2, USE_KILL src, USE_KILL dst, 11461 USE_KILL len, KILL tmp5, KILL cr); 11462 11463 format %{ "String Compress $src,$dst -> $result // KILL RAX, RCX, RDX" %} 11464 ins_encode %{ 11465 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 11466 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11467 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, 11468 $ktmp1$$KRegister, $ktmp2$$KRegister); 11469 %} 11470 ins_pipe( pipe_slow ); 11471 %} 11472 // fast byte[] to char[] inflation 11473 instruct string_inflate(Universe dummy, rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11474 legRegD tmp1, rcx_RegI tmp2, rFlagsReg cr) %{ 11475 predicate(!VM_Version::supports_avx512vlbw() || !VM_Version::supports_bmi2()); 11476 match(Set dummy (StrInflatedCopy src (Binary dst len))); 11477 effect(TEMP tmp1, TEMP tmp2, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 11478 11479 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 11480 ins_encode %{ 11481 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 11482 $tmp1$$XMMRegister, $tmp2$$Register, knoreg); 11483 %} 11484 ins_pipe( pipe_slow ); 11485 %} 11486 11487 instruct string_inflate_evex(Universe dummy, rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11488 legRegD tmp1, kReg ktmp, rcx_RegI tmp2, rFlagsReg cr) %{ 11489 predicate(VM_Version::supports_avx512vlbw() && VM_Version::supports_bmi2()); 11490 match(Set dummy (StrInflatedCopy src (Binary dst len))); 11491 effect(TEMP tmp1, TEMP tmp2, TEMP ktmp, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 11492 11493 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 11494 ins_encode %{ 11495 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 11496 $tmp1$$XMMRegister, $tmp2$$Register, $ktmp$$KRegister); 11497 %} 11498 ins_pipe( pipe_slow ); 11499 %} 11500 11501 // encode char[] to byte[] in ISO_8859_1 11502 instruct encode_iso_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11503 legRegD tmp1, legRegD tmp2, legRegD tmp3, legRegD tmp4, 11504 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11505 predicate(!((EncodeISOArrayNode*)n)->is_ascii()); 11506 match(Set result (EncodeISOArray src (Binary dst len))); 11507 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 11508 11509 format %{ "Encode iso array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %} 11510 ins_encode %{ 11511 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 11512 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11513 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, false); 11514 %} 11515 ins_pipe( pipe_slow ); 11516 %} 11517 11518 // encode char[] to byte[] in ASCII 11519 instruct encode_ascii_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11520 legRegD tmp1, legRegD tmp2, legRegD tmp3, legRegD tmp4, 11521 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11522 predicate(((EncodeISOArrayNode*)n)->is_ascii()); 11523 match(Set result (EncodeISOArray src (Binary dst len))); 11524 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 11525 11526 format %{ "Encode ascii array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %} 11527 ins_encode %{ 11528 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 11529 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11530 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register, true); 11531 %} 11532 ins_pipe( pipe_slow ); 11533 %} 11534 11535 //----------Overflow Math Instructions----------------------------------------- 11536 11537 instruct overflowAddI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 11538 %{ 11539 match(Set cr (OverflowAddI op1 op2)); 11540 effect(DEF cr, USE_KILL op1, USE op2); 11541 11542 format %{ "addl $op1, $op2\t# overflow check int" %} 11543 11544 ins_encode %{ 11545 __ addl($op1$$Register, $op2$$Register); 11546 %} 11547 ins_pipe(ialu_reg_reg); 11548 %} 11549 11550 instruct overflowAddI_rReg_imm(rFlagsReg cr, rax_RegI op1, immI op2) 11551 %{ 11552 match(Set cr (OverflowAddI op1 op2)); 11553 effect(DEF cr, USE_KILL op1, USE op2); 11554 11555 format %{ "addl $op1, $op2\t# overflow check int" %} 11556 11557 ins_encode %{ 11558 __ addl($op1$$Register, $op2$$constant); 11559 %} 11560 ins_pipe(ialu_reg_reg); 11561 %} 11562 11563 instruct overflowAddL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 11564 %{ 11565 match(Set cr (OverflowAddL op1 op2)); 11566 effect(DEF cr, USE_KILL op1, USE op2); 11567 11568 format %{ "addq $op1, $op2\t# overflow check long" %} 11569 ins_encode %{ 11570 __ addq($op1$$Register, $op2$$Register); 11571 %} 11572 ins_pipe(ialu_reg_reg); 11573 %} 11574 11575 instruct overflowAddL_rReg_imm(rFlagsReg cr, rax_RegL op1, immL32 op2) 11576 %{ 11577 match(Set cr (OverflowAddL op1 op2)); 11578 effect(DEF cr, USE_KILL op1, USE op2); 11579 11580 format %{ "addq $op1, $op2\t# overflow check long" %} 11581 ins_encode %{ 11582 __ addq($op1$$Register, $op2$$constant); 11583 %} 11584 ins_pipe(ialu_reg_reg); 11585 %} 11586 11587 instruct overflowSubI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 11588 %{ 11589 match(Set cr (OverflowSubI op1 op2)); 11590 11591 format %{ "cmpl $op1, $op2\t# overflow check int" %} 11592 ins_encode %{ 11593 __ cmpl($op1$$Register, $op2$$Register); 11594 %} 11595 ins_pipe(ialu_reg_reg); 11596 %} 11597 11598 instruct overflowSubI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 11599 %{ 11600 match(Set cr (OverflowSubI op1 op2)); 11601 11602 format %{ "cmpl $op1, $op2\t# overflow check int" %} 11603 ins_encode %{ 11604 __ cmpl($op1$$Register, $op2$$constant); 11605 %} 11606 ins_pipe(ialu_reg_reg); 11607 %} 11608 11609 instruct overflowSubL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 11610 %{ 11611 match(Set cr (OverflowSubL op1 op2)); 11612 11613 format %{ "cmpq $op1, $op2\t# overflow check long" %} 11614 ins_encode %{ 11615 __ cmpq($op1$$Register, $op2$$Register); 11616 %} 11617 ins_pipe(ialu_reg_reg); 11618 %} 11619 11620 instruct overflowSubL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 11621 %{ 11622 match(Set cr (OverflowSubL op1 op2)); 11623 11624 format %{ "cmpq $op1, $op2\t# overflow check long" %} 11625 ins_encode %{ 11626 __ cmpq($op1$$Register, $op2$$constant); 11627 %} 11628 ins_pipe(ialu_reg_reg); 11629 %} 11630 11631 instruct overflowNegI_rReg(rFlagsReg cr, immI_0 zero, rax_RegI op2) 11632 %{ 11633 match(Set cr (OverflowSubI zero op2)); 11634 effect(DEF cr, USE_KILL op2); 11635 11636 format %{ "negl $op2\t# overflow check int" %} 11637 ins_encode %{ 11638 __ negl($op2$$Register); 11639 %} 11640 ins_pipe(ialu_reg_reg); 11641 %} 11642 11643 instruct overflowNegL_rReg(rFlagsReg cr, immL0 zero, rax_RegL op2) 11644 %{ 11645 match(Set cr (OverflowSubL zero op2)); 11646 effect(DEF cr, USE_KILL op2); 11647 11648 format %{ "negq $op2\t# overflow check long" %} 11649 ins_encode %{ 11650 __ negq($op2$$Register); 11651 %} 11652 ins_pipe(ialu_reg_reg); 11653 %} 11654 11655 instruct overflowMulI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 11656 %{ 11657 match(Set cr (OverflowMulI op1 op2)); 11658 effect(DEF cr, USE_KILL op1, USE op2); 11659 11660 format %{ "imull $op1, $op2\t# overflow check int" %} 11661 ins_encode %{ 11662 __ imull($op1$$Register, $op2$$Register); 11663 %} 11664 ins_pipe(ialu_reg_reg_alu0); 11665 %} 11666 11667 instruct overflowMulI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2, rRegI tmp) 11668 %{ 11669 match(Set cr (OverflowMulI op1 op2)); 11670 effect(DEF cr, TEMP tmp, USE op1, USE op2); 11671 11672 format %{ "imull $tmp, $op1, $op2\t# overflow check int" %} 11673 ins_encode %{ 11674 __ imull($tmp$$Register, $op1$$Register, $op2$$constant); 11675 %} 11676 ins_pipe(ialu_reg_reg_alu0); 11677 %} 11678 11679 instruct overflowMulL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 11680 %{ 11681 match(Set cr (OverflowMulL op1 op2)); 11682 effect(DEF cr, USE_KILL op1, USE op2); 11683 11684 format %{ "imulq $op1, $op2\t# overflow check long" %} 11685 ins_encode %{ 11686 __ imulq($op1$$Register, $op2$$Register); 11687 %} 11688 ins_pipe(ialu_reg_reg_alu0); 11689 %} 11690 11691 instruct overflowMulL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2, rRegL tmp) 11692 %{ 11693 match(Set cr (OverflowMulL op1 op2)); 11694 effect(DEF cr, TEMP tmp, USE op1, USE op2); 11695 11696 format %{ "imulq $tmp, $op1, $op2\t# overflow check long" %} 11697 ins_encode %{ 11698 __ imulq($tmp$$Register, $op1$$Register, $op2$$constant); 11699 %} 11700 ins_pipe(ialu_reg_reg_alu0); 11701 %} 11702 11703 11704 //----------Control Flow Instructions------------------------------------------ 11705 // Signed compare Instructions 11706 11707 // XXX more variants!! 11708 instruct compI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 11709 %{ 11710 match(Set cr (CmpI op1 op2)); 11711 effect(DEF cr, USE op1, USE op2); 11712 11713 format %{ "cmpl $op1, $op2" %} 11714 ins_encode %{ 11715 __ cmpl($op1$$Register, $op2$$Register); 11716 %} 11717 ins_pipe(ialu_cr_reg_reg); 11718 %} 11719 11720 instruct compI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 11721 %{ 11722 match(Set cr (CmpI op1 op2)); 11723 11724 format %{ "cmpl $op1, $op2" %} 11725 ins_encode %{ 11726 __ cmpl($op1$$Register, $op2$$constant); 11727 %} 11728 ins_pipe(ialu_cr_reg_imm); 11729 %} 11730 11731 instruct compI_rReg_mem(rFlagsReg cr, rRegI op1, memory op2) 11732 %{ 11733 match(Set cr (CmpI op1 (LoadI op2))); 11734 11735 ins_cost(500); // XXX 11736 format %{ "cmpl $op1, $op2" %} 11737 ins_encode %{ 11738 __ cmpl($op1$$Register, $op2$$Address); 11739 %} 11740 ins_pipe(ialu_cr_reg_mem); 11741 %} 11742 11743 instruct testI_reg(rFlagsReg cr, rRegI src, immI_0 zero) 11744 %{ 11745 match(Set cr (CmpI src zero)); 11746 11747 format %{ "testl $src, $src" %} 11748 ins_encode %{ 11749 __ testl($src$$Register, $src$$Register); 11750 %} 11751 ins_pipe(ialu_cr_reg_imm); 11752 %} 11753 11754 instruct testI_reg_imm(rFlagsReg cr, rRegI src, immI con, immI_0 zero) 11755 %{ 11756 match(Set cr (CmpI (AndI src con) zero)); 11757 11758 format %{ "testl $src, $con" %} 11759 ins_encode %{ 11760 __ testl($src$$Register, $con$$constant); 11761 %} 11762 ins_pipe(ialu_cr_reg_imm); 11763 %} 11764 11765 instruct testI_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2, immI_0 zero) 11766 %{ 11767 match(Set cr (CmpI (AndI src1 src2) zero)); 11768 11769 format %{ "testl $src1, $src2" %} 11770 ins_encode %{ 11771 __ testl($src1$$Register, $src2$$Register); 11772 %} 11773 ins_pipe(ialu_cr_reg_imm); 11774 %} 11775 11776 instruct testI_reg_mem(rFlagsReg cr, rRegI src, memory mem, immI_0 zero) 11777 %{ 11778 match(Set cr (CmpI (AndI src (LoadI mem)) zero)); 11779 11780 format %{ "testl $src, $mem" %} 11781 ins_encode %{ 11782 __ testl($src$$Register, $mem$$Address); 11783 %} 11784 ins_pipe(ialu_cr_reg_mem); 11785 %} 11786 11787 // Unsigned compare Instructions; really, same as signed except they 11788 // produce an rFlagsRegU instead of rFlagsReg. 11789 instruct compU_rReg(rFlagsRegU cr, rRegI op1, rRegI op2) 11790 %{ 11791 match(Set cr (CmpU op1 op2)); 11792 11793 format %{ "cmpl $op1, $op2\t# unsigned" %} 11794 ins_encode %{ 11795 __ cmpl($op1$$Register, $op2$$Register); 11796 %} 11797 ins_pipe(ialu_cr_reg_reg); 11798 %} 11799 11800 instruct compU_rReg_imm(rFlagsRegU cr, rRegI op1, immI op2) 11801 %{ 11802 match(Set cr (CmpU op1 op2)); 11803 11804 format %{ "cmpl $op1, $op2\t# unsigned" %} 11805 ins_encode %{ 11806 __ cmpl($op1$$Register, $op2$$constant); 11807 %} 11808 ins_pipe(ialu_cr_reg_imm); 11809 %} 11810 11811 instruct compU_rReg_mem(rFlagsRegU cr, rRegI op1, memory op2) 11812 %{ 11813 match(Set cr (CmpU op1 (LoadI op2))); 11814 11815 ins_cost(500); // XXX 11816 format %{ "cmpl $op1, $op2\t# unsigned" %} 11817 ins_encode %{ 11818 __ cmpl($op1$$Register, $op2$$Address); 11819 %} 11820 ins_pipe(ialu_cr_reg_mem); 11821 %} 11822 11823 instruct testU_reg(rFlagsRegU cr, rRegI src, immI_0 zero) 11824 %{ 11825 match(Set cr (CmpU src zero)); 11826 11827 format %{ "testl $src, $src\t# unsigned" %} 11828 ins_encode %{ 11829 __ testl($src$$Register, $src$$Register); 11830 %} 11831 ins_pipe(ialu_cr_reg_imm); 11832 %} 11833 11834 instruct compP_rReg(rFlagsRegU cr, rRegP op1, rRegP op2) 11835 %{ 11836 match(Set cr (CmpP op1 op2)); 11837 11838 format %{ "cmpq $op1, $op2\t# ptr" %} 11839 ins_encode %{ 11840 __ cmpq($op1$$Register, $op2$$Register); 11841 %} 11842 ins_pipe(ialu_cr_reg_reg); 11843 %} 11844 11845 instruct compP_rReg_mem(rFlagsRegU cr, rRegP op1, memory op2) 11846 %{ 11847 match(Set cr (CmpP op1 (LoadP op2))); 11848 predicate(n->in(2)->as_Load()->barrier_data() == 0); 11849 11850 ins_cost(500); // XXX 11851 format %{ "cmpq $op1, $op2\t# ptr" %} 11852 ins_encode %{ 11853 __ cmpq($op1$$Register, $op2$$Address); 11854 %} 11855 ins_pipe(ialu_cr_reg_mem); 11856 %} 11857 11858 // XXX this is generalized by compP_rReg_mem??? 11859 // Compare raw pointer (used in out-of-heap check). 11860 // Only works because non-oop pointers must be raw pointers 11861 // and raw pointers have no anti-dependencies. 11862 instruct compP_mem_rReg(rFlagsRegU cr, rRegP op1, memory op2) 11863 %{ 11864 predicate(n->in(2)->in(2)->bottom_type()->reloc() == relocInfo::none && 11865 n->in(2)->as_Load()->barrier_data() == 0); 11866 match(Set cr (CmpP op1 (LoadP op2))); 11867 11868 format %{ "cmpq $op1, $op2\t# raw ptr" %} 11869 ins_encode %{ 11870 __ cmpq($op1$$Register, $op2$$Address); 11871 %} 11872 ins_pipe(ialu_cr_reg_mem); 11873 %} 11874 11875 // This will generate a signed flags result. This should be OK since 11876 // any compare to a zero should be eq/neq. 11877 instruct testP_reg(rFlagsReg cr, rRegP src, immP0 zero) 11878 %{ 11879 match(Set cr (CmpP src zero)); 11880 11881 format %{ "testq $src, $src\t# ptr" %} 11882 ins_encode %{ 11883 __ testq($src$$Register, $src$$Register); 11884 %} 11885 ins_pipe(ialu_cr_reg_imm); 11886 %} 11887 11888 // This will generate a signed flags result. This should be OK since 11889 // any compare to a zero should be eq/neq. 11890 instruct testP_mem(rFlagsReg cr, memory op, immP0 zero) 11891 %{ 11892 predicate((!UseCompressedOops || (CompressedOops::base() != nullptr)) && 11893 n->in(1)->as_Load()->barrier_data() == 0); 11894 match(Set cr (CmpP (LoadP op) zero)); 11895 11896 ins_cost(500); // XXX 11897 format %{ "testq $op, 0xffffffffffffffff\t# ptr" %} 11898 ins_encode %{ 11899 __ testq($op$$Address, 0xFFFFFFFF); 11900 %} 11901 ins_pipe(ialu_cr_reg_imm); 11902 %} 11903 11904 instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero) 11905 %{ 11906 predicate(UseCompressedOops && (CompressedOops::base() == nullptr) && 11907 n->in(1)->as_Load()->barrier_data() == 0); 11908 match(Set cr (CmpP (LoadP mem) zero)); 11909 11910 format %{ "cmpq R12, $mem\t# ptr (R12_heapbase==0)" %} 11911 ins_encode %{ 11912 __ cmpq(r12, $mem$$Address); 11913 %} 11914 ins_pipe(ialu_cr_reg_mem); 11915 %} 11916 11917 instruct compN_rReg(rFlagsRegU cr, rRegN op1, rRegN op2) 11918 %{ 11919 match(Set cr (CmpN op1 op2)); 11920 11921 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 11922 ins_encode %{ __ cmpl($op1$$Register, $op2$$Register); %} 11923 ins_pipe(ialu_cr_reg_reg); 11924 %} 11925 11926 instruct compN_rReg_mem(rFlagsRegU cr, rRegN src, memory mem) 11927 %{ 11928 match(Set cr (CmpN src (LoadN mem))); 11929 11930 format %{ "cmpl $src, $mem\t# compressed ptr" %} 11931 ins_encode %{ 11932 __ cmpl($src$$Register, $mem$$Address); 11933 %} 11934 ins_pipe(ialu_cr_reg_mem); 11935 %} 11936 11937 instruct compN_rReg_imm(rFlagsRegU cr, rRegN op1, immN op2) %{ 11938 match(Set cr (CmpN op1 op2)); 11939 11940 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 11941 ins_encode %{ 11942 __ cmp_narrow_oop($op1$$Register, (jobject)$op2$$constant); 11943 %} 11944 ins_pipe(ialu_cr_reg_imm); 11945 %} 11946 11947 instruct compN_mem_imm(rFlagsRegU cr, memory mem, immN src) 11948 %{ 11949 match(Set cr (CmpN src (LoadN mem))); 11950 11951 format %{ "cmpl $mem, $src\t# compressed ptr" %} 11952 ins_encode %{ 11953 __ cmp_narrow_oop($mem$$Address, (jobject)$src$$constant); 11954 %} 11955 ins_pipe(ialu_cr_reg_mem); 11956 %} 11957 11958 instruct compN_rReg_imm_klass(rFlagsRegU cr, rRegN op1, immNKlass op2) %{ 11959 match(Set cr (CmpN op1 op2)); 11960 11961 format %{ "cmpl $op1, $op2\t# compressed klass ptr" %} 11962 ins_encode %{ 11963 __ cmp_narrow_klass($op1$$Register, (Klass*)$op2$$constant); 11964 %} 11965 ins_pipe(ialu_cr_reg_imm); 11966 %} 11967 11968 instruct compN_mem_imm_klass(rFlagsRegU cr, memory mem, immNKlass src) 11969 %{ 11970 match(Set cr (CmpN src (LoadNKlass mem))); 11971 11972 format %{ "cmpl $mem, $src\t# compressed klass ptr" %} 11973 ins_encode %{ 11974 __ cmp_narrow_klass($mem$$Address, (Klass*)$src$$constant); 11975 %} 11976 ins_pipe(ialu_cr_reg_mem); 11977 %} 11978 11979 instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{ 11980 match(Set cr (CmpN src zero)); 11981 11982 format %{ "testl $src, $src\t# compressed ptr" %} 11983 ins_encode %{ __ testl($src$$Register, $src$$Register); %} 11984 ins_pipe(ialu_cr_reg_imm); 11985 %} 11986 11987 instruct testN_mem(rFlagsReg cr, memory mem, immN0 zero) 11988 %{ 11989 predicate(CompressedOops::base() != nullptr); 11990 match(Set cr (CmpN (LoadN mem) zero)); 11991 11992 ins_cost(500); // XXX 11993 format %{ "testl $mem, 0xffffffff\t# compressed ptr" %} 11994 ins_encode %{ 11995 __ cmpl($mem$$Address, (int)0xFFFFFFFF); 11996 %} 11997 ins_pipe(ialu_cr_reg_mem); 11998 %} 11999 12000 instruct testN_mem_reg0(rFlagsReg cr, memory mem, immN0 zero) 12001 %{ 12002 predicate(CompressedOops::base() == nullptr); 12003 match(Set cr (CmpN (LoadN mem) zero)); 12004 12005 format %{ "cmpl R12, $mem\t# compressed ptr (R12_heapbase==0)" %} 12006 ins_encode %{ 12007 __ cmpl(r12, $mem$$Address); 12008 %} 12009 ins_pipe(ialu_cr_reg_mem); 12010 %} 12011 12012 // Yanked all unsigned pointer compare operations. 12013 // Pointer compares are done with CmpP which is already unsigned. 12014 12015 instruct compL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 12016 %{ 12017 match(Set cr (CmpL op1 op2)); 12018 12019 format %{ "cmpq $op1, $op2" %} 12020 ins_encode %{ 12021 __ cmpq($op1$$Register, $op2$$Register); 12022 %} 12023 ins_pipe(ialu_cr_reg_reg); 12024 %} 12025 12026 instruct compL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 12027 %{ 12028 match(Set cr (CmpL op1 op2)); 12029 12030 format %{ "cmpq $op1, $op2" %} 12031 ins_encode %{ 12032 __ cmpq($op1$$Register, $op2$$constant); 12033 %} 12034 ins_pipe(ialu_cr_reg_imm); 12035 %} 12036 12037 instruct compL_rReg_mem(rFlagsReg cr, rRegL op1, memory op2) 12038 %{ 12039 match(Set cr (CmpL op1 (LoadL op2))); 12040 12041 format %{ "cmpq $op1, $op2" %} 12042 ins_encode %{ 12043 __ cmpq($op1$$Register, $op2$$Address); 12044 %} 12045 ins_pipe(ialu_cr_reg_mem); 12046 %} 12047 12048 instruct testL_reg(rFlagsReg cr, rRegL src, immL0 zero) 12049 %{ 12050 match(Set cr (CmpL src zero)); 12051 12052 format %{ "testq $src, $src" %} 12053 ins_encode %{ 12054 __ testq($src$$Register, $src$$Register); 12055 %} 12056 ins_pipe(ialu_cr_reg_imm); 12057 %} 12058 12059 instruct testL_reg_imm(rFlagsReg cr, rRegL src, immL32 con, immL0 zero) 12060 %{ 12061 match(Set cr (CmpL (AndL src con) zero)); 12062 12063 format %{ "testq $src, $con\t# long" %} 12064 ins_encode %{ 12065 __ testq($src$$Register, $con$$constant); 12066 %} 12067 ins_pipe(ialu_cr_reg_imm); 12068 %} 12069 12070 instruct testL_reg_reg(rFlagsReg cr, rRegL src1, rRegL src2, immL0 zero) 12071 %{ 12072 match(Set cr (CmpL (AndL src1 src2) zero)); 12073 12074 format %{ "testq $src1, $src2\t# long" %} 12075 ins_encode %{ 12076 __ testq($src1$$Register, $src2$$Register); 12077 %} 12078 ins_pipe(ialu_cr_reg_imm); 12079 %} 12080 12081 instruct testL_reg_mem(rFlagsReg cr, rRegL src, memory mem, immL0 zero) 12082 %{ 12083 match(Set cr (CmpL (AndL src (LoadL mem)) zero)); 12084 12085 format %{ "testq $src, $mem" %} 12086 ins_encode %{ 12087 __ testq($src$$Register, $mem$$Address); 12088 %} 12089 ins_pipe(ialu_cr_reg_mem); 12090 %} 12091 12092 instruct testL_reg_mem2(rFlagsReg cr, rRegP src, memory mem, immL0 zero) 12093 %{ 12094 match(Set cr (CmpL (AndL (CastP2X src) (LoadL mem)) zero)); 12095 12096 format %{ "testq $src, $mem" %} 12097 ins_encode %{ 12098 __ testq($src$$Register, $mem$$Address); 12099 %} 12100 ins_pipe(ialu_cr_reg_mem); 12101 %} 12102 12103 // Manifest a CmpU result in an integer register. Very painful. 12104 // This is the test to avoid. 12105 instruct cmpU3_reg_reg(rRegI dst, rRegI src1, rRegI src2, rFlagsReg flags) 12106 %{ 12107 match(Set dst (CmpU3 src1 src2)); 12108 effect(KILL flags); 12109 12110 ins_cost(275); // XXX 12111 format %{ "cmpl $src1, $src2\t# CmpL3\n\t" 12112 "movl $dst, -1\n\t" 12113 "jb,u done\n\t" 12114 "setne $dst\n\t" 12115 "movzbl $dst, $dst\n\t" 12116 "done:" %} 12117 ins_encode %{ 12118 Label done; 12119 __ cmpl($src1$$Register, $src2$$Register); 12120 __ movl($dst$$Register, -1); 12121 __ jccb(Assembler::below, done); 12122 __ setb(Assembler::notZero, $dst$$Register); 12123 __ movzbl($dst$$Register, $dst$$Register); 12124 __ bind(done); 12125 %} 12126 ins_pipe(pipe_slow); 12127 %} 12128 12129 // Manifest a CmpL result in an integer register. Very painful. 12130 // This is the test to avoid. 12131 instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 12132 %{ 12133 match(Set dst (CmpL3 src1 src2)); 12134 effect(KILL flags); 12135 12136 ins_cost(275); // XXX 12137 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 12138 "movl $dst, -1\n\t" 12139 "jl,s done\n\t" 12140 "setne $dst\n\t" 12141 "movzbl $dst, $dst\n\t" 12142 "done:" %} 12143 ins_encode %{ 12144 Label done; 12145 __ cmpq($src1$$Register, $src2$$Register); 12146 __ movl($dst$$Register, -1); 12147 __ jccb(Assembler::less, done); 12148 __ setb(Assembler::notZero, $dst$$Register); 12149 __ movzbl($dst$$Register, $dst$$Register); 12150 __ bind(done); 12151 %} 12152 ins_pipe(pipe_slow); 12153 %} 12154 12155 // Manifest a CmpUL result in an integer register. Very painful. 12156 // This is the test to avoid. 12157 instruct cmpUL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 12158 %{ 12159 match(Set dst (CmpUL3 src1 src2)); 12160 effect(KILL flags); 12161 12162 ins_cost(275); // XXX 12163 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 12164 "movl $dst, -1\n\t" 12165 "jb,u done\n\t" 12166 "setne $dst\n\t" 12167 "movzbl $dst, $dst\n\t" 12168 "done:" %} 12169 ins_encode %{ 12170 Label done; 12171 __ cmpq($src1$$Register, $src2$$Register); 12172 __ movl($dst$$Register, -1); 12173 __ jccb(Assembler::below, done); 12174 __ setb(Assembler::notZero, $dst$$Register); 12175 __ movzbl($dst$$Register, $dst$$Register); 12176 __ bind(done); 12177 %} 12178 ins_pipe(pipe_slow); 12179 %} 12180 12181 // Unsigned long compare Instructions; really, same as signed long except they 12182 // produce an rFlagsRegU instead of rFlagsReg. 12183 instruct compUL_rReg(rFlagsRegU cr, rRegL op1, rRegL op2) 12184 %{ 12185 match(Set cr (CmpUL op1 op2)); 12186 12187 format %{ "cmpq $op1, $op2\t# unsigned" %} 12188 ins_encode %{ 12189 __ cmpq($op1$$Register, $op2$$Register); 12190 %} 12191 ins_pipe(ialu_cr_reg_reg); 12192 %} 12193 12194 instruct compUL_rReg_imm(rFlagsRegU cr, rRegL op1, immL32 op2) 12195 %{ 12196 match(Set cr (CmpUL op1 op2)); 12197 12198 format %{ "cmpq $op1, $op2\t# unsigned" %} 12199 ins_encode %{ 12200 __ cmpq($op1$$Register, $op2$$constant); 12201 %} 12202 ins_pipe(ialu_cr_reg_imm); 12203 %} 12204 12205 instruct compUL_rReg_mem(rFlagsRegU cr, rRegL op1, memory op2) 12206 %{ 12207 match(Set cr (CmpUL op1 (LoadL op2))); 12208 12209 format %{ "cmpq $op1, $op2\t# unsigned" %} 12210 ins_encode %{ 12211 __ cmpq($op1$$Register, $op2$$Address); 12212 %} 12213 ins_pipe(ialu_cr_reg_mem); 12214 %} 12215 12216 instruct testUL_reg(rFlagsRegU cr, rRegL src, immL0 zero) 12217 %{ 12218 match(Set cr (CmpUL src zero)); 12219 12220 format %{ "testq $src, $src\t# unsigned" %} 12221 ins_encode %{ 12222 __ testq($src$$Register, $src$$Register); 12223 %} 12224 ins_pipe(ialu_cr_reg_imm); 12225 %} 12226 12227 instruct compB_mem_imm(rFlagsReg cr, memory mem, immI8 imm) 12228 %{ 12229 match(Set cr (CmpI (LoadB mem) imm)); 12230 12231 ins_cost(125); 12232 format %{ "cmpb $mem, $imm" %} 12233 ins_encode %{ __ cmpb($mem$$Address, $imm$$constant); %} 12234 ins_pipe(ialu_cr_reg_mem); 12235 %} 12236 12237 instruct testUB_mem_imm(rFlagsReg cr, memory mem, immU7 imm, immI_0 zero) 12238 %{ 12239 match(Set cr (CmpI (AndI (LoadUB mem) imm) zero)); 12240 12241 ins_cost(125); 12242 format %{ "testb $mem, $imm\t# ubyte" %} 12243 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %} 12244 ins_pipe(ialu_cr_reg_mem); 12245 %} 12246 12247 instruct testB_mem_imm(rFlagsReg cr, memory mem, immI8 imm, immI_0 zero) 12248 %{ 12249 match(Set cr (CmpI (AndI (LoadB mem) imm) zero)); 12250 12251 ins_cost(125); 12252 format %{ "testb $mem, $imm\t# byte" %} 12253 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %} 12254 ins_pipe(ialu_cr_reg_mem); 12255 %} 12256 12257 //----------Max and Min-------------------------------------------------------- 12258 // Min Instructions 12259 12260 instruct cmovI_reg_g(rRegI dst, rRegI src, rFlagsReg cr) 12261 %{ 12262 effect(USE_DEF dst, USE src, USE cr); 12263 12264 format %{ "cmovlgt $dst, $src\t# min" %} 12265 ins_encode %{ 12266 __ cmovl(Assembler::greater, $dst$$Register, $src$$Register); 12267 %} 12268 ins_pipe(pipe_cmov_reg); 12269 %} 12270 12271 12272 instruct minI_rReg(rRegI dst, rRegI src) 12273 %{ 12274 match(Set dst (MinI dst src)); 12275 12276 ins_cost(200); 12277 expand %{ 12278 rFlagsReg cr; 12279 compI_rReg(cr, dst, src); 12280 cmovI_reg_g(dst, src, cr); 12281 %} 12282 %} 12283 12284 instruct cmovI_reg_l(rRegI dst, rRegI src, rFlagsReg cr) 12285 %{ 12286 effect(USE_DEF dst, USE src, USE cr); 12287 12288 format %{ "cmovllt $dst, $src\t# max" %} 12289 ins_encode %{ 12290 __ cmovl(Assembler::less, $dst$$Register, $src$$Register); 12291 %} 12292 ins_pipe(pipe_cmov_reg); 12293 %} 12294 12295 12296 instruct maxI_rReg(rRegI dst, rRegI src) 12297 %{ 12298 match(Set dst (MaxI dst src)); 12299 12300 ins_cost(200); 12301 expand %{ 12302 rFlagsReg cr; 12303 compI_rReg(cr, dst, src); 12304 cmovI_reg_l(dst, src, cr); 12305 %} 12306 %} 12307 12308 // ============================================================================ 12309 // Branch Instructions 12310 12311 // Jump Direct - Label defines a relative address from JMP+1 12312 instruct jmpDir(label labl) 12313 %{ 12314 match(Goto); 12315 effect(USE labl); 12316 12317 ins_cost(300); 12318 format %{ "jmp $labl" %} 12319 size(5); 12320 ins_encode %{ 12321 Label* L = $labl$$label; 12322 __ jmp(*L, false); // Always long jump 12323 %} 12324 ins_pipe(pipe_jmp); 12325 %} 12326 12327 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12328 instruct jmpCon(cmpOp cop, rFlagsReg cr, label labl) 12329 %{ 12330 match(If cop cr); 12331 effect(USE labl); 12332 12333 ins_cost(300); 12334 format %{ "j$cop $labl" %} 12335 size(6); 12336 ins_encode %{ 12337 Label* L = $labl$$label; 12338 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12339 %} 12340 ins_pipe(pipe_jcc); 12341 %} 12342 12343 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12344 instruct jmpLoopEnd(cmpOp cop, rFlagsReg cr, label labl) 12345 %{ 12346 match(CountedLoopEnd cop cr); 12347 effect(USE labl); 12348 12349 ins_cost(300); 12350 format %{ "j$cop $labl\t# loop end" %} 12351 size(6); 12352 ins_encode %{ 12353 Label* L = $labl$$label; 12354 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12355 %} 12356 ins_pipe(pipe_jcc); 12357 %} 12358 12359 // Jump Direct Conditional - using unsigned comparison 12360 instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12361 match(If cop cmp); 12362 effect(USE labl); 12363 12364 ins_cost(300); 12365 format %{ "j$cop,u $labl" %} 12366 size(6); 12367 ins_encode %{ 12368 Label* L = $labl$$label; 12369 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12370 %} 12371 ins_pipe(pipe_jcc); 12372 %} 12373 12374 instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12375 match(If cop cmp); 12376 effect(USE labl); 12377 12378 ins_cost(200); 12379 format %{ "j$cop,u $labl" %} 12380 size(6); 12381 ins_encode %{ 12382 Label* L = $labl$$label; 12383 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12384 %} 12385 ins_pipe(pipe_jcc); 12386 %} 12387 12388 instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 12389 match(If cop cmp); 12390 effect(USE labl); 12391 12392 ins_cost(200); 12393 format %{ $$template 12394 if ($cop$$cmpcode == Assembler::notEqual) { 12395 $$emit$$"jp,u $labl\n\t" 12396 $$emit$$"j$cop,u $labl" 12397 } else { 12398 $$emit$$"jp,u done\n\t" 12399 $$emit$$"j$cop,u $labl\n\t" 12400 $$emit$$"done:" 12401 } 12402 %} 12403 ins_encode %{ 12404 Label* l = $labl$$label; 12405 if ($cop$$cmpcode == Assembler::notEqual) { 12406 __ jcc(Assembler::parity, *l, false); 12407 __ jcc(Assembler::notEqual, *l, false); 12408 } else if ($cop$$cmpcode == Assembler::equal) { 12409 Label done; 12410 __ jccb(Assembler::parity, done); 12411 __ jcc(Assembler::equal, *l, false); 12412 __ bind(done); 12413 } else { 12414 ShouldNotReachHere(); 12415 } 12416 %} 12417 ins_pipe(pipe_jcc); 12418 %} 12419 12420 // ============================================================================ 12421 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary 12422 // superklass array for an instance of the superklass. Set a hidden 12423 // internal cache on a hit (cache is checked with exposed code in 12424 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The 12425 // encoding ALSO sets flags. 12426 12427 instruct partialSubtypeCheck(rdi_RegP result, 12428 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 12429 rFlagsReg cr) 12430 %{ 12431 match(Set result (PartialSubtypeCheck sub super)); 12432 effect(KILL rcx, KILL cr); 12433 12434 ins_cost(1100); // slightly larger than the next version 12435 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 12436 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 12437 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 12438 "repne scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t" 12439 "jne,s miss\t\t# Missed: rdi not-zero\n\t" 12440 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 12441 "xorq $result, $result\t\t Hit: rdi zero\n\t" 12442 "miss:\t" %} 12443 12444 opcode(0x1); // Force a XOR of RDI 12445 ins_encode(enc_PartialSubtypeCheck()); 12446 ins_pipe(pipe_slow); 12447 %} 12448 12449 instruct partialSubtypeCheckConstSuper(rsi_RegP sub, rax_RegP super_reg, immP super_con, rdi_RegP result, 12450 rdx_RegL temp1, rcx_RegL temp2, rbx_RegP temp3, r11_RegL temp4, 12451 rFlagsReg cr) 12452 %{ 12453 match(Set result (PartialSubtypeCheck sub (Binary super_reg super_con))); 12454 predicate(UseSecondarySupersTable); 12455 effect(KILL cr, TEMP temp1, TEMP temp2, TEMP temp3, TEMP temp4); 12456 12457 ins_cost(700); // smaller than the next version 12458 format %{ "partialSubtypeCheck $result, $sub, $super_reg, $super_con" %} 12459 12460 ins_encode %{ 12461 u1 super_klass_slot = ((Klass*)$super_con$$constant)->hash_slot(); 12462 if (InlineSecondarySupersTest) { 12463 __ lookup_secondary_supers_table($sub$$Register, $super_reg$$Register, $temp1$$Register, $temp2$$Register, 12464 $temp3$$Register, $temp4$$Register, $result$$Register, 12465 super_klass_slot); 12466 } else { 12467 __ call(RuntimeAddress(StubRoutines::lookup_secondary_supers_table_stub(super_klass_slot))); 12468 } 12469 %} 12470 12471 ins_pipe(pipe_slow); 12472 %} 12473 12474 instruct partialSubtypeCheck_vs_Zero(rFlagsReg cr, 12475 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 12476 immP0 zero, 12477 rdi_RegP result) 12478 %{ 12479 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 12480 effect(KILL rcx, KILL result); 12481 12482 ins_cost(1000); 12483 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 12484 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 12485 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 12486 "repne scasq\t# Scan *rdi++ for a match with rax while cx-- != 0\n\t" 12487 "jne,s miss\t\t# Missed: flags nz\n\t" 12488 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 12489 "miss:\t" %} 12490 12491 opcode(0x0); // No need to XOR RDI 12492 ins_encode(enc_PartialSubtypeCheck()); 12493 ins_pipe(pipe_slow); 12494 %} 12495 12496 // ============================================================================ 12497 // Branch Instructions -- short offset versions 12498 // 12499 // These instructions are used to replace jumps of a long offset (the default 12500 // match) with jumps of a shorter offset. These instructions are all tagged 12501 // with the ins_short_branch attribute, which causes the ADLC to suppress the 12502 // match rules in general matching. Instead, the ADLC generates a conversion 12503 // method in the MachNode which can be used to do in-place replacement of the 12504 // long variant with the shorter variant. The compiler will determine if a 12505 // branch can be taken by the is_short_branch_offset() predicate in the machine 12506 // specific code section of the file. 12507 12508 // Jump Direct - Label defines a relative address from JMP+1 12509 instruct jmpDir_short(label labl) %{ 12510 match(Goto); 12511 effect(USE labl); 12512 12513 ins_cost(300); 12514 format %{ "jmp,s $labl" %} 12515 size(2); 12516 ins_encode %{ 12517 Label* L = $labl$$label; 12518 __ jmpb(*L); 12519 %} 12520 ins_pipe(pipe_jmp); 12521 ins_short_branch(1); 12522 %} 12523 12524 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12525 instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{ 12526 match(If cop cr); 12527 effect(USE labl); 12528 12529 ins_cost(300); 12530 format %{ "j$cop,s $labl" %} 12531 size(2); 12532 ins_encode %{ 12533 Label* L = $labl$$label; 12534 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12535 %} 12536 ins_pipe(pipe_jcc); 12537 ins_short_branch(1); 12538 %} 12539 12540 // Jump Direct Conditional - Label defines a relative address from Jcc+1 12541 instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{ 12542 match(CountedLoopEnd cop cr); 12543 effect(USE labl); 12544 12545 ins_cost(300); 12546 format %{ "j$cop,s $labl\t# loop end" %} 12547 size(2); 12548 ins_encode %{ 12549 Label* L = $labl$$label; 12550 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12551 %} 12552 ins_pipe(pipe_jcc); 12553 ins_short_branch(1); 12554 %} 12555 12556 // Jump Direct Conditional - using unsigned comparison 12557 instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12558 match(If cop cmp); 12559 effect(USE labl); 12560 12561 ins_cost(300); 12562 format %{ "j$cop,us $labl" %} 12563 size(2); 12564 ins_encode %{ 12565 Label* L = $labl$$label; 12566 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12567 %} 12568 ins_pipe(pipe_jcc); 12569 ins_short_branch(1); 12570 %} 12571 12572 instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12573 match(If cop cmp); 12574 effect(USE labl); 12575 12576 ins_cost(300); 12577 format %{ "j$cop,us $labl" %} 12578 size(2); 12579 ins_encode %{ 12580 Label* L = $labl$$label; 12581 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12582 %} 12583 ins_pipe(pipe_jcc); 12584 ins_short_branch(1); 12585 %} 12586 12587 instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 12588 match(If cop cmp); 12589 effect(USE labl); 12590 12591 ins_cost(300); 12592 format %{ $$template 12593 if ($cop$$cmpcode == Assembler::notEqual) { 12594 $$emit$$"jp,u,s $labl\n\t" 12595 $$emit$$"j$cop,u,s $labl" 12596 } else { 12597 $$emit$$"jp,u,s done\n\t" 12598 $$emit$$"j$cop,u,s $labl\n\t" 12599 $$emit$$"done:" 12600 } 12601 %} 12602 size(4); 12603 ins_encode %{ 12604 Label* l = $labl$$label; 12605 if ($cop$$cmpcode == Assembler::notEqual) { 12606 __ jccb(Assembler::parity, *l); 12607 __ jccb(Assembler::notEqual, *l); 12608 } else if ($cop$$cmpcode == Assembler::equal) { 12609 Label done; 12610 __ jccb(Assembler::parity, done); 12611 __ jccb(Assembler::equal, *l); 12612 __ bind(done); 12613 } else { 12614 ShouldNotReachHere(); 12615 } 12616 %} 12617 ins_pipe(pipe_jcc); 12618 ins_short_branch(1); 12619 %} 12620 12621 // ============================================================================ 12622 // inlined locking and unlocking 12623 12624 instruct cmpFastLock(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr) %{ 12625 predicate(LockingMode != LM_LIGHTWEIGHT); 12626 match(Set cr (FastLock object box)); 12627 effect(TEMP tmp, TEMP scr, USE_KILL box); 12628 ins_cost(300); 12629 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr" %} 12630 ins_encode %{ 12631 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, 12632 $scr$$Register, noreg, noreg, r15_thread, nullptr); 12633 %} 12634 ins_pipe(pipe_slow); 12635 %} 12636 12637 instruct cmpFastUnlock(rFlagsReg cr, rRegP object, rax_RegP box, rRegP tmp) %{ 12638 predicate(LockingMode != LM_LIGHTWEIGHT); 12639 match(Set cr (FastUnlock object box)); 12640 effect(TEMP tmp, USE_KILL box); 12641 ins_cost(300); 12642 format %{ "fastunlock $object,$box\t! kills $box,$tmp" %} 12643 ins_encode %{ 12644 __ fast_unlock($object$$Register, $box$$Register, $tmp$$Register); 12645 %} 12646 ins_pipe(pipe_slow); 12647 %} 12648 12649 instruct cmpFastLockLightweight(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI rax_reg, rRegP tmp) %{ 12650 predicate(LockingMode == LM_LIGHTWEIGHT); 12651 match(Set cr (FastLock object box)); 12652 effect(TEMP rax_reg, TEMP tmp, USE_KILL box); 12653 ins_cost(300); 12654 format %{ "fastlock $object,$box\t! kills $box,$rax_reg,$tmp" %} 12655 ins_encode %{ 12656 __ fast_lock_lightweight($object$$Register, $box$$Register, $rax_reg$$Register, $tmp$$Register, r15_thread); 12657 %} 12658 ins_pipe(pipe_slow); 12659 %} 12660 12661 instruct cmpFastUnlockLightweight(rFlagsReg cr, rRegP object, rax_RegP rax_reg, rRegP tmp) %{ 12662 predicate(LockingMode == LM_LIGHTWEIGHT); 12663 match(Set cr (FastUnlock object rax_reg)); 12664 effect(TEMP tmp, USE_KILL rax_reg); 12665 ins_cost(300); 12666 format %{ "fastunlock $object,$rax_reg\t! kills $rax_reg,$tmp" %} 12667 ins_encode %{ 12668 __ fast_unlock_lightweight($object$$Register, $rax_reg$$Register, $tmp$$Register, r15_thread); 12669 %} 12670 ins_pipe(pipe_slow); 12671 %} 12672 12673 12674 // ============================================================================ 12675 // Safepoint Instructions 12676 instruct safePoint_poll_tls(rFlagsReg cr, rRegP poll) 12677 %{ 12678 match(SafePoint poll); 12679 effect(KILL cr, USE poll); 12680 12681 format %{ "testl rax, [$poll]\t" 12682 "# Safepoint: poll for GC" %} 12683 ins_cost(125); 12684 ins_encode %{ 12685 __ relocate(relocInfo::poll_type); 12686 address pre_pc = __ pc(); 12687 __ testl(rax, Address($poll$$Register, 0)); 12688 assert(nativeInstruction_at(pre_pc)->is_safepoint_poll(), "must emit test %%eax [reg]"); 12689 %} 12690 ins_pipe(ialu_reg_mem); 12691 %} 12692 12693 instruct mask_all_evexL(kReg dst, rRegL src) %{ 12694 match(Set dst (MaskAll src)); 12695 format %{ "mask_all_evexL $dst, $src \t! mask all operation" %} 12696 ins_encode %{ 12697 int mask_len = Matcher::vector_length(this); 12698 __ vector_maskall_operation($dst$$KRegister, $src$$Register, mask_len); 12699 %} 12700 ins_pipe( pipe_slow ); 12701 %} 12702 12703 instruct mask_all_evexI_GT32(kReg dst, rRegI src, rRegL tmp) %{ 12704 predicate(Matcher::vector_length(n) > 32); 12705 match(Set dst (MaskAll src)); 12706 effect(TEMP tmp); 12707 format %{ "mask_all_evexI_GT32 $dst, $src \t! using $tmp as TEMP" %} 12708 ins_encode %{ 12709 int mask_len = Matcher::vector_length(this); 12710 __ movslq($tmp$$Register, $src$$Register); 12711 __ vector_maskall_operation($dst$$KRegister, $tmp$$Register, mask_len); 12712 %} 12713 ins_pipe( pipe_slow ); 12714 %} 12715 12716 // ============================================================================ 12717 // Procedure Call/Return Instructions 12718 // Call Java Static Instruction 12719 // Note: If this code changes, the corresponding ret_addr_offset() and 12720 // compute_padding() functions will have to be adjusted. 12721 instruct CallStaticJavaDirect(method meth) %{ 12722 match(CallStaticJava); 12723 effect(USE meth); 12724 12725 ins_cost(300); 12726 format %{ "call,static " %} 12727 opcode(0xE8); /* E8 cd */ 12728 ins_encode(clear_avx, Java_Static_Call(meth), call_epilog); 12729 ins_pipe(pipe_slow); 12730 ins_alignment(4); 12731 %} 12732 12733 // Call Java Dynamic Instruction 12734 // Note: If this code changes, the corresponding ret_addr_offset() and 12735 // compute_padding() functions will have to be adjusted. 12736 instruct CallDynamicJavaDirect(method meth) 12737 %{ 12738 match(CallDynamicJava); 12739 effect(USE meth); 12740 12741 ins_cost(300); 12742 format %{ "movq rax, #Universe::non_oop_word()\n\t" 12743 "call,dynamic " %} 12744 ins_encode(clear_avx, Java_Dynamic_Call(meth), call_epilog); 12745 ins_pipe(pipe_slow); 12746 ins_alignment(4); 12747 %} 12748 12749 // Call Runtime Instruction 12750 instruct CallRuntimeDirect(method meth) 12751 %{ 12752 match(CallRuntime); 12753 effect(USE meth); 12754 12755 ins_cost(300); 12756 format %{ "call,runtime " %} 12757 ins_encode(clear_avx, Java_To_Runtime(meth)); 12758 ins_pipe(pipe_slow); 12759 %} 12760 12761 // Call runtime without safepoint 12762 instruct CallLeafDirect(method meth) 12763 %{ 12764 match(CallLeaf); 12765 effect(USE meth); 12766 12767 ins_cost(300); 12768 format %{ "call_leaf,runtime " %} 12769 ins_encode(clear_avx, Java_To_Runtime(meth)); 12770 ins_pipe(pipe_slow); 12771 %} 12772 12773 // Call runtime without safepoint and with vector arguments 12774 instruct CallLeafDirectVector(method meth) 12775 %{ 12776 match(CallLeafVector); 12777 effect(USE meth); 12778 12779 ins_cost(300); 12780 format %{ "call_leaf,vector " %} 12781 ins_encode(Java_To_Runtime(meth)); 12782 ins_pipe(pipe_slow); 12783 %} 12784 12785 // Call runtime without safepoint 12786 // entry point is null, target holds the address to call 12787 instruct CallLeafNoFPInDirect(rRegP target) 12788 %{ 12789 predicate(n->as_Call()->entry_point() == nullptr); 12790 match(CallLeafNoFP target); 12791 12792 ins_cost(300); 12793 format %{ "call_leaf_nofp,runtime indirect " %} 12794 ins_encode %{ 12795 __ call($target$$Register); 12796 %} 12797 12798 ins_pipe(pipe_slow); 12799 %} 12800 12801 instruct CallLeafNoFPDirect(method meth) 12802 %{ 12803 predicate(n->as_Call()->entry_point() != nullptr); 12804 match(CallLeafNoFP); 12805 effect(USE meth); 12806 12807 ins_cost(300); 12808 format %{ "call_leaf_nofp,runtime " %} 12809 ins_encode(clear_avx, Java_To_Runtime(meth)); 12810 ins_pipe(pipe_slow); 12811 %} 12812 12813 // Return Instruction 12814 // Remove the return address & jump to it. 12815 // Notice: We always emit a nop after a ret to make sure there is room 12816 // for safepoint patching 12817 instruct Ret() 12818 %{ 12819 match(Return); 12820 12821 format %{ "ret" %} 12822 ins_encode %{ 12823 __ ret(0); 12824 %} 12825 ins_pipe(pipe_jmp); 12826 %} 12827 12828 // Tail Call; Jump from runtime stub to Java code. 12829 // Also known as an 'interprocedural jump'. 12830 // Target of jump will eventually return to caller. 12831 // TailJump below removes the return address. 12832 // Don't use rbp for 'jump_target' because a MachEpilogNode has already been 12833 // emitted just above the TailCall which has reset rbp to the caller state. 12834 instruct TailCalljmpInd(no_rbp_RegP jump_target, rbx_RegP method_ptr) 12835 %{ 12836 match(TailCall jump_target method_ptr); 12837 12838 ins_cost(300); 12839 format %{ "jmp $jump_target\t# rbx holds method" %} 12840 ins_encode %{ 12841 __ jmp($jump_target$$Register); 12842 %} 12843 ins_pipe(pipe_jmp); 12844 %} 12845 12846 // Tail Jump; remove the return address; jump to target. 12847 // TailCall above leaves the return address around. 12848 instruct tailjmpInd(no_rbp_RegP jump_target, rax_RegP ex_oop) 12849 %{ 12850 match(TailJump jump_target ex_oop); 12851 12852 ins_cost(300); 12853 format %{ "popq rdx\t# pop return address\n\t" 12854 "jmp $jump_target" %} 12855 ins_encode %{ 12856 __ popq(as_Register(RDX_enc)); 12857 __ jmp($jump_target$$Register); 12858 %} 12859 ins_pipe(pipe_jmp); 12860 %} 12861 12862 // Forward exception. 12863 instruct ForwardExceptionjmp() 12864 %{ 12865 match(ForwardException); 12866 12867 format %{ "jmp forward_exception_stub" %} 12868 ins_encode %{ 12869 __ jump(RuntimeAddress(StubRoutines::forward_exception_entry()), noreg); 12870 %} 12871 ins_pipe(pipe_jmp); 12872 %} 12873 12874 // Create exception oop: created by stack-crawling runtime code. 12875 // Created exception is now available to this handler, and is setup 12876 // just prior to jumping to this handler. No code emitted. 12877 instruct CreateException(rax_RegP ex_oop) 12878 %{ 12879 match(Set ex_oop (CreateEx)); 12880 12881 size(0); 12882 // use the following format syntax 12883 format %{ "# exception oop is in rax; no code emitted" %} 12884 ins_encode(); 12885 ins_pipe(empty); 12886 %} 12887 12888 // Rethrow exception: 12889 // The exception oop will come in the first argument position. 12890 // Then JUMP (not call) to the rethrow stub code. 12891 instruct RethrowException() 12892 %{ 12893 match(Rethrow); 12894 12895 // use the following format syntax 12896 format %{ "jmp rethrow_stub" %} 12897 ins_encode %{ 12898 __ jump(RuntimeAddress(OptoRuntime::rethrow_stub()), noreg); 12899 %} 12900 ins_pipe(pipe_jmp); 12901 %} 12902 12903 // ============================================================================ 12904 // This name is KNOWN by the ADLC and cannot be changed. 12905 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type 12906 // for this guy. 12907 instruct tlsLoadP(r15_RegP dst) %{ 12908 match(Set dst (ThreadLocal)); 12909 effect(DEF dst); 12910 12911 size(0); 12912 format %{ "# TLS is in R15" %} 12913 ins_encode( /*empty encoding*/ ); 12914 ins_pipe(ialu_reg_reg); 12915 %} 12916 12917 12918 //----------PEEPHOLE RULES----------------------------------------------------- 12919 // These must follow all instruction definitions as they use the names 12920 // defined in the instructions definitions. 12921 // 12922 // peeppredicate ( rule_predicate ); 12923 // // the predicate unless which the peephole rule will be ignored 12924 // 12925 // peepmatch ( root_instr_name [preceding_instruction]* ); 12926 // 12927 // peepprocedure ( procedure_name ); 12928 // // provide a procedure name to perform the optimization, the procedure should 12929 // // reside in the architecture dependent peephole file, the method has the 12930 // // signature of MachNode* (Block*, int, PhaseRegAlloc*, (MachNode*)(*)(), int...) 12931 // // with the arguments being the basic block, the current node index inside the 12932 // // block, the register allocator, the functions upon invoked return a new node 12933 // // defined in peepreplace, and the rules of the nodes appearing in the 12934 // // corresponding peepmatch, the function return true if successful, else 12935 // // return false 12936 // 12937 // peepconstraint %{ 12938 // (instruction_number.operand_name relational_op instruction_number.operand_name 12939 // [, ...] ); 12940 // // instruction numbers are zero-based using left to right order in peepmatch 12941 // 12942 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 12943 // // provide an instruction_number.operand_name for each operand that appears 12944 // // in the replacement instruction's match rule 12945 // 12946 // ---------VM FLAGS--------------------------------------------------------- 12947 // 12948 // All peephole optimizations can be turned off using -XX:-OptoPeephole 12949 // 12950 // Each peephole rule is given an identifying number starting with zero and 12951 // increasing by one in the order seen by the parser. An individual peephole 12952 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 12953 // on the command-line. 12954 // 12955 // ---------CURRENT LIMITATIONS---------------------------------------------- 12956 // 12957 // Only transformations inside a basic block (do we need more for peephole) 12958 // 12959 // ---------EXAMPLE---------------------------------------------------------- 12960 // 12961 // // pertinent parts of existing instructions in architecture description 12962 // instruct movI(rRegI dst, rRegI src) 12963 // %{ 12964 // match(Set dst (CopyI src)); 12965 // %} 12966 // 12967 // instruct incI_rReg(rRegI dst, immI_1 src, rFlagsReg cr) 12968 // %{ 12969 // match(Set dst (AddI dst src)); 12970 // effect(KILL cr); 12971 // %} 12972 // 12973 // instruct leaI_rReg_immI(rRegI dst, immI_1 src) 12974 // %{ 12975 // match(Set dst (AddI dst src)); 12976 // %} 12977 // 12978 // 1. Simple replacement 12979 // - Only match adjacent instructions in same basic block 12980 // - Only equality constraints 12981 // - Only constraints between operands, not (0.dest_reg == RAX_enc) 12982 // - Only one replacement instruction 12983 // 12984 // // Change (inc mov) to lea 12985 // peephole %{ 12986 // // lea should only be emitted when beneficial 12987 // peeppredicate( VM_Version::supports_fast_2op_lea() ); 12988 // // increment preceded by register-register move 12989 // peepmatch ( incI_rReg movI ); 12990 // // require that the destination register of the increment 12991 // // match the destination register of the move 12992 // peepconstraint ( 0.dst == 1.dst ); 12993 // // construct a replacement instruction that sets 12994 // // the destination to ( move's source register + one ) 12995 // peepreplace ( leaI_rReg_immI( 0.dst 1.src 0.src ) ); 12996 // %} 12997 // 12998 // 2. Procedural replacement 12999 // - More flexible finding relevent nodes 13000 // - More flexible constraints 13001 // - More flexible transformations 13002 // - May utilise architecture-dependent API more effectively 13003 // - Currently only one replacement instruction due to adlc parsing capabilities 13004 // 13005 // // Change (inc mov) to lea 13006 // peephole %{ 13007 // // lea should only be emitted when beneficial 13008 // peeppredicate( VM_Version::supports_fast_2op_lea() ); 13009 // // the rule numbers of these nodes inside are passed into the function below 13010 // peepmatch ( incI_rReg movI ); 13011 // // the method that takes the responsibility of transformation 13012 // peepprocedure ( inc_mov_to_lea ); 13013 // // the replacement is a leaI_rReg_immI, a lambda upon invoked creating this 13014 // // node is passed into the function above 13015 // peepreplace ( leaI_rReg_immI() ); 13016 // %} 13017 13018 // These instructions is not matched by the matcher but used by the peephole 13019 instruct leaI_rReg_rReg_peep(rRegI dst, rRegI src1, rRegI src2) 13020 %{ 13021 predicate(false); 13022 match(Set dst (AddI src1 src2)); 13023 format %{ "leal $dst, [$src1 + $src2]" %} 13024 ins_encode %{ 13025 Register dst = $dst$$Register; 13026 Register src1 = $src1$$Register; 13027 Register src2 = $src2$$Register; 13028 if (src1 != rbp && src1 != r13) { 13029 __ leal(dst, Address(src1, src2, Address::times_1)); 13030 } else { 13031 assert(src2 != rbp && src2 != r13, ""); 13032 __ leal(dst, Address(src2, src1, Address::times_1)); 13033 } 13034 %} 13035 ins_pipe(ialu_reg_reg); 13036 %} 13037 13038 instruct leaI_rReg_immI_peep(rRegI dst, rRegI src1, immI src2) 13039 %{ 13040 predicate(false); 13041 match(Set dst (AddI src1 src2)); 13042 format %{ "leal $dst, [$src1 + $src2]" %} 13043 ins_encode %{ 13044 __ leal($dst$$Register, Address($src1$$Register, $src2$$constant)); 13045 %} 13046 ins_pipe(ialu_reg_reg); 13047 %} 13048 13049 instruct leaI_rReg_immI2_peep(rRegI dst, rRegI src, immI2 shift) 13050 %{ 13051 predicate(false); 13052 match(Set dst (LShiftI src shift)); 13053 format %{ "leal $dst, [$src << $shift]" %} 13054 ins_encode %{ 13055 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($shift$$constant); 13056 Register src = $src$$Register; 13057 if (scale == Address::times_2 && src != rbp && src != r13) { 13058 __ leal($dst$$Register, Address(src, src, Address::times_1)); 13059 } else { 13060 __ leal($dst$$Register, Address(noreg, src, scale)); 13061 } 13062 %} 13063 ins_pipe(ialu_reg_reg); 13064 %} 13065 13066 instruct leaL_rReg_rReg_peep(rRegL dst, rRegL src1, rRegL src2) 13067 %{ 13068 predicate(false); 13069 match(Set dst (AddL src1 src2)); 13070 format %{ "leaq $dst, [$src1 + $src2]" %} 13071 ins_encode %{ 13072 Register dst = $dst$$Register; 13073 Register src1 = $src1$$Register; 13074 Register src2 = $src2$$Register; 13075 if (src1 != rbp && src1 != r13) { 13076 __ leaq(dst, Address(src1, src2, Address::times_1)); 13077 } else { 13078 assert(src2 != rbp && src2 != r13, ""); 13079 __ leaq(dst, Address(src2, src1, Address::times_1)); 13080 } 13081 %} 13082 ins_pipe(ialu_reg_reg); 13083 %} 13084 13085 instruct leaL_rReg_immL32_peep(rRegL dst, rRegL src1, immL32 src2) 13086 %{ 13087 predicate(false); 13088 match(Set dst (AddL src1 src2)); 13089 format %{ "leaq $dst, [$src1 + $src2]" %} 13090 ins_encode %{ 13091 __ leaq($dst$$Register, Address($src1$$Register, $src2$$constant)); 13092 %} 13093 ins_pipe(ialu_reg_reg); 13094 %} 13095 13096 instruct leaL_rReg_immI2_peep(rRegL dst, rRegL src, immI2 shift) 13097 %{ 13098 predicate(false); 13099 match(Set dst (LShiftL src shift)); 13100 format %{ "leaq $dst, [$src << $shift]" %} 13101 ins_encode %{ 13102 Address::ScaleFactor scale = static_cast<Address::ScaleFactor>($shift$$constant); 13103 Register src = $src$$Register; 13104 if (scale == Address::times_2 && src != rbp && src != r13) { 13105 __ leaq($dst$$Register, Address(src, src, Address::times_1)); 13106 } else { 13107 __ leaq($dst$$Register, Address(noreg, src, scale)); 13108 } 13109 %} 13110 ins_pipe(ialu_reg_reg); 13111 %} 13112 13113 // These peephole rules replace mov + I pairs (where I is one of {add, inc, dec, 13114 // sal}) with lea instructions. The {add, sal} rules are beneficial in 13115 // processors with at least partial ALU support for lea 13116 // (supports_fast_2op_lea()), whereas the {inc, dec} rules are only generally 13117 // beneficial for processors with full ALU support 13118 // (VM_Version::supports_fast_3op_lea()) and Intel Cascade Lake. 13119 13120 peephole 13121 %{ 13122 peeppredicate(VM_Version::supports_fast_2op_lea()); 13123 peepmatch (addI_rReg); 13124 peepprocedure (lea_coalesce_reg); 13125 peepreplace (leaI_rReg_rReg_peep()); 13126 %} 13127 13128 peephole 13129 %{ 13130 peeppredicate(VM_Version::supports_fast_2op_lea()); 13131 peepmatch (addI_rReg_imm); 13132 peepprocedure (lea_coalesce_imm); 13133 peepreplace (leaI_rReg_immI_peep()); 13134 %} 13135 13136 peephole 13137 %{ 13138 peeppredicate(VM_Version::supports_fast_3op_lea() || 13139 VM_Version::is_intel_cascade_lake()); 13140 peepmatch (incI_rReg); 13141 peepprocedure (lea_coalesce_imm); 13142 peepreplace (leaI_rReg_immI_peep()); 13143 %} 13144 13145 peephole 13146 %{ 13147 peeppredicate(VM_Version::supports_fast_3op_lea() || 13148 VM_Version::is_intel_cascade_lake()); 13149 peepmatch (decI_rReg); 13150 peepprocedure (lea_coalesce_imm); 13151 peepreplace (leaI_rReg_immI_peep()); 13152 %} 13153 13154 peephole 13155 %{ 13156 peeppredicate(VM_Version::supports_fast_2op_lea()); 13157 peepmatch (salI_rReg_immI2); 13158 peepprocedure (lea_coalesce_imm); 13159 peepreplace (leaI_rReg_immI2_peep()); 13160 %} 13161 13162 peephole 13163 %{ 13164 peeppredicate(VM_Version::supports_fast_2op_lea()); 13165 peepmatch (addL_rReg); 13166 peepprocedure (lea_coalesce_reg); 13167 peepreplace (leaL_rReg_rReg_peep()); 13168 %} 13169 13170 peephole 13171 %{ 13172 peeppredicate(VM_Version::supports_fast_2op_lea()); 13173 peepmatch (addL_rReg_imm); 13174 peepprocedure (lea_coalesce_imm); 13175 peepreplace (leaL_rReg_immL32_peep()); 13176 %} 13177 13178 peephole 13179 %{ 13180 peeppredicate(VM_Version::supports_fast_3op_lea() || 13181 VM_Version::is_intel_cascade_lake()); 13182 peepmatch (incL_rReg); 13183 peepprocedure (lea_coalesce_imm); 13184 peepreplace (leaL_rReg_immL32_peep()); 13185 %} 13186 13187 peephole 13188 %{ 13189 peeppredicate(VM_Version::supports_fast_3op_lea() || 13190 VM_Version::is_intel_cascade_lake()); 13191 peepmatch (decL_rReg); 13192 peepprocedure (lea_coalesce_imm); 13193 peepreplace (leaL_rReg_immL32_peep()); 13194 %} 13195 13196 peephole 13197 %{ 13198 peeppredicate(VM_Version::supports_fast_2op_lea()); 13199 peepmatch (salL_rReg_immI2); 13200 peepprocedure (lea_coalesce_imm); 13201 peepreplace (leaL_rReg_immI2_peep()); 13202 %} 13203 13204 // These peephole rules matches instructions which set flags and are followed by a testI/L_reg 13205 // 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 13206 13207 //int variant 13208 peephole 13209 %{ 13210 peepmatch (testI_reg); 13211 peepprocedure (test_may_remove); 13212 %} 13213 13214 //long variant 13215 peephole 13216 %{ 13217 peepmatch (testL_reg); 13218 peepprocedure (test_may_remove); 13219 %} 13220 13221 13222 //----------SMARTSPILL RULES--------------------------------------------------- 13223 // These must follow all instruction definitions as they use the names 13224 // defined in the instructions definitions.