x86_64.ad revision 3142:9b8ce46870df
1// 2// Copyright (c) 2003, 2012, 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// archtecture. 31 32register %{ 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 70reg_def RAX (SOC, SOC, Op_RegI, 0, rax->as_VMReg()); 71reg_def RAX_H(SOC, SOC, Op_RegI, 0, rax->as_VMReg()->next()); 72 73reg_def RCX (SOC, SOC, Op_RegI, 1, rcx->as_VMReg()); 74reg_def RCX_H(SOC, SOC, Op_RegI, 1, rcx->as_VMReg()->next()); 75 76reg_def RDX (SOC, SOC, Op_RegI, 2, rdx->as_VMReg()); 77reg_def RDX_H(SOC, SOC, Op_RegI, 2, rdx->as_VMReg()->next()); 78 79reg_def RBX (SOC, SOE, Op_RegI, 3, rbx->as_VMReg()); 80reg_def RBX_H(SOC, SOE, Op_RegI, 3, rbx->as_VMReg()->next()); 81 82reg_def RSP (NS, NS, Op_RegI, 4, rsp->as_VMReg()); 83reg_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 86reg_def RBP (NS, SOE, Op_RegI, 5, rbp->as_VMReg()); 87reg_def RBP_H(NS, SOE, Op_RegI, 5, rbp->as_VMReg()->next()); 88 89#ifdef _WIN64 90 91reg_def RSI (SOC, SOE, Op_RegI, 6, rsi->as_VMReg()); 92reg_def RSI_H(SOC, SOE, Op_RegI, 6, rsi->as_VMReg()->next()); 93 94reg_def RDI (SOC, SOE, Op_RegI, 7, rdi->as_VMReg()); 95reg_def RDI_H(SOC, SOE, Op_RegI, 7, rdi->as_VMReg()->next()); 96 97#else 98 99reg_def RSI (SOC, SOC, Op_RegI, 6, rsi->as_VMReg()); 100reg_def RSI_H(SOC, SOC, Op_RegI, 6, rsi->as_VMReg()->next()); 101 102reg_def RDI (SOC, SOC, Op_RegI, 7, rdi->as_VMReg()); 103reg_def RDI_H(SOC, SOC, Op_RegI, 7, rdi->as_VMReg()->next()); 104 105#endif 106 107reg_def R8 (SOC, SOC, Op_RegI, 8, r8->as_VMReg()); 108reg_def R8_H (SOC, SOC, Op_RegI, 8, r8->as_VMReg()->next()); 109 110reg_def R9 (SOC, SOC, Op_RegI, 9, r9->as_VMReg()); 111reg_def R9_H (SOC, SOC, Op_RegI, 9, r9->as_VMReg()->next()); 112 113reg_def R10 (SOC, SOC, Op_RegI, 10, r10->as_VMReg()); 114reg_def R10_H(SOC, SOC, Op_RegI, 10, r10->as_VMReg()->next()); 115 116reg_def R11 (SOC, SOC, Op_RegI, 11, r11->as_VMReg()); 117reg_def R11_H(SOC, SOC, Op_RegI, 11, r11->as_VMReg()->next()); 118 119reg_def R12 (SOC, SOE, Op_RegI, 12, r12->as_VMReg()); 120reg_def R12_H(SOC, SOE, Op_RegI, 12, r12->as_VMReg()->next()); 121 122reg_def R13 (SOC, SOE, Op_RegI, 13, r13->as_VMReg()); 123reg_def R13_H(SOC, SOE, Op_RegI, 13, r13->as_VMReg()->next()); 124 125reg_def R14 (SOC, SOE, Op_RegI, 14, r14->as_VMReg()); 126reg_def R14_H(SOC, SOE, Op_RegI, 14, r14->as_VMReg()->next()); 127 128reg_def R15 (SOC, SOE, Op_RegI, 15, r15->as_VMReg()); 129reg_def R15_H(SOC, SOE, Op_RegI, 15, r15->as_VMReg()->next()); 130 131 132// Floating Point Registers 133 134// XMM registers. 128-bit registers or 4 words each, labeled (a)-d. 135// Word a in each register holds a Float, words ab hold a Double. We 136// currently do not use the SIMD capabilities, so registers cd are 137// unused at the moment. 138// XMM8-XMM15 must be encoded with REX. 139// Linux ABI: No register preserved across function calls 140// XMM0-XMM7 might hold parameters 141// Windows ABI: XMM6-XMM15 preserved across function calls 142// XMM0-XMM3 might hold parameters 143 144reg_def XMM0 (SOC, SOC, Op_RegF, 0, xmm0->as_VMReg()); 145reg_def XMM0_H (SOC, SOC, Op_RegF, 0, xmm0->as_VMReg()->next()); 146 147reg_def XMM1 (SOC, SOC, Op_RegF, 1, xmm1->as_VMReg()); 148reg_def XMM1_H (SOC, SOC, Op_RegF, 1, xmm1->as_VMReg()->next()); 149 150reg_def XMM2 (SOC, SOC, Op_RegF, 2, xmm2->as_VMReg()); 151reg_def XMM2_H (SOC, SOC, Op_RegF, 2, xmm2->as_VMReg()->next()); 152 153reg_def XMM3 (SOC, SOC, Op_RegF, 3, xmm3->as_VMReg()); 154reg_def XMM3_H (SOC, SOC, Op_RegF, 3, xmm3->as_VMReg()->next()); 155 156reg_def XMM4 (SOC, SOC, Op_RegF, 4, xmm4->as_VMReg()); 157reg_def XMM4_H (SOC, SOC, Op_RegF, 4, xmm4->as_VMReg()->next()); 158 159reg_def XMM5 (SOC, SOC, Op_RegF, 5, xmm5->as_VMReg()); 160reg_def XMM5_H (SOC, SOC, Op_RegF, 5, xmm5->as_VMReg()->next()); 161 162#ifdef _WIN64 163 164reg_def XMM6 (SOC, SOE, Op_RegF, 6, xmm6->as_VMReg()); 165reg_def XMM6_H (SOC, SOE, Op_RegF, 6, xmm6->as_VMReg()->next()); 166 167reg_def XMM7 (SOC, SOE, Op_RegF, 7, xmm7->as_VMReg()); 168reg_def XMM7_H (SOC, SOE, Op_RegF, 7, xmm7->as_VMReg()->next()); 169 170reg_def XMM8 (SOC, SOE, Op_RegF, 8, xmm8->as_VMReg()); 171reg_def XMM8_H (SOC, SOE, Op_RegF, 8, xmm8->as_VMReg()->next()); 172 173reg_def XMM9 (SOC, SOE, Op_RegF, 9, xmm9->as_VMReg()); 174reg_def XMM9_H (SOC, SOE, Op_RegF, 9, xmm9->as_VMReg()->next()); 175 176reg_def XMM10 (SOC, SOE, Op_RegF, 10, xmm10->as_VMReg()); 177reg_def XMM10_H(SOC, SOE, Op_RegF, 10, xmm10->as_VMReg()->next()); 178 179reg_def XMM11 (SOC, SOE, Op_RegF, 11, xmm11->as_VMReg()); 180reg_def XMM11_H(SOC, SOE, Op_RegF, 11, xmm11->as_VMReg()->next()); 181 182reg_def XMM12 (SOC, SOE, Op_RegF, 12, xmm12->as_VMReg()); 183reg_def XMM12_H(SOC, SOE, Op_RegF, 12, xmm12->as_VMReg()->next()); 184 185reg_def XMM13 (SOC, SOE, Op_RegF, 13, xmm13->as_VMReg()); 186reg_def XMM13_H(SOC, SOE, Op_RegF, 13, xmm13->as_VMReg()->next()); 187 188reg_def XMM14 (SOC, SOE, Op_RegF, 14, xmm14->as_VMReg()); 189reg_def XMM14_H(SOC, SOE, Op_RegF, 14, xmm14->as_VMReg()->next()); 190 191reg_def XMM15 (SOC, SOE, Op_RegF, 15, xmm15->as_VMReg()); 192reg_def XMM15_H(SOC, SOE, Op_RegF, 15, xmm15->as_VMReg()->next()); 193 194#else 195 196reg_def XMM6 (SOC, SOC, Op_RegF, 6, xmm6->as_VMReg()); 197reg_def XMM6_H (SOC, SOC, Op_RegF, 6, xmm6->as_VMReg()->next()); 198 199reg_def XMM7 (SOC, SOC, Op_RegF, 7, xmm7->as_VMReg()); 200reg_def XMM7_H (SOC, SOC, Op_RegF, 7, xmm7->as_VMReg()->next()); 201 202reg_def XMM8 (SOC, SOC, Op_RegF, 8, xmm8->as_VMReg()); 203reg_def XMM8_H (SOC, SOC, Op_RegF, 8, xmm8->as_VMReg()->next()); 204 205reg_def XMM9 (SOC, SOC, Op_RegF, 9, xmm9->as_VMReg()); 206reg_def XMM9_H (SOC, SOC, Op_RegF, 9, xmm9->as_VMReg()->next()); 207 208reg_def XMM10 (SOC, SOC, Op_RegF, 10, xmm10->as_VMReg()); 209reg_def XMM10_H(SOC, SOC, Op_RegF, 10, xmm10->as_VMReg()->next()); 210 211reg_def XMM11 (SOC, SOC, Op_RegF, 11, xmm11->as_VMReg()); 212reg_def XMM11_H(SOC, SOC, Op_RegF, 11, xmm11->as_VMReg()->next()); 213 214reg_def XMM12 (SOC, SOC, Op_RegF, 12, xmm12->as_VMReg()); 215reg_def XMM12_H(SOC, SOC, Op_RegF, 12, xmm12->as_VMReg()->next()); 216 217reg_def XMM13 (SOC, SOC, Op_RegF, 13, xmm13->as_VMReg()); 218reg_def XMM13_H(SOC, SOC, Op_RegF, 13, xmm13->as_VMReg()->next()); 219 220reg_def XMM14 (SOC, SOC, Op_RegF, 14, xmm14->as_VMReg()); 221reg_def XMM14_H(SOC, SOC, Op_RegF, 14, xmm14->as_VMReg()->next()); 222 223reg_def XMM15 (SOC, SOC, Op_RegF, 15, xmm15->as_VMReg()); 224reg_def XMM15_H(SOC, SOC, Op_RegF, 15, xmm15->as_VMReg()->next()); 225 226#endif // _WIN64 227 228reg_def RFLAGS(SOC, SOC, 0, 16, VMRegImpl::Bad()); 229 230// Specify priority of register selection within phases of register 231// allocation. Highest priority is first. A useful heuristic is to 232// give registers a low priority when they are required by machine 233// instructions, like EAX and EDX on I486, and choose no-save registers 234// before save-on-call, & save-on-call before save-on-entry. Registers 235// which participate in fixed calling sequences should come last. 236// Registers which are used as pairs must fall on an even boundary. 237 238alloc_class chunk0(R10, R10_H, 239 R11, R11_H, 240 R8, R8_H, 241 R9, R9_H, 242 R12, R12_H, 243 RCX, RCX_H, 244 RBX, RBX_H, 245 RDI, RDI_H, 246 RDX, RDX_H, 247 RSI, RSI_H, 248 RAX, RAX_H, 249 RBP, RBP_H, 250 R13, R13_H, 251 R14, R14_H, 252 R15, R15_H, 253 RSP, RSP_H); 254 255// XXX probably use 8-15 first on Linux 256alloc_class chunk1(XMM0, XMM0_H, 257 XMM1, XMM1_H, 258 XMM2, XMM2_H, 259 XMM3, XMM3_H, 260 XMM4, XMM4_H, 261 XMM5, XMM5_H, 262 XMM6, XMM6_H, 263 XMM7, XMM7_H, 264 XMM8, XMM8_H, 265 XMM9, XMM9_H, 266 XMM10, XMM10_H, 267 XMM11, XMM11_H, 268 XMM12, XMM12_H, 269 XMM13, XMM13_H, 270 XMM14, XMM14_H, 271 XMM15, XMM15_H); 272 273alloc_class chunk2(RFLAGS); 274 275 276//----------Architecture Description Register Classes-------------------------- 277// Several register classes are automatically defined based upon information in 278// this architecture description. 279// 1) reg_class inline_cache_reg ( /* as def'd in frame section */ ) 280// 2) reg_class compiler_method_oop_reg ( /* as def'd in frame section */ ) 281// 2) reg_class interpreter_method_oop_reg ( /* as def'd in frame section */ ) 282// 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ ) 283// 284 285// Class for all pointer registers (including RSP) 286reg_class any_reg(RAX, RAX_H, 287 RDX, RDX_H, 288 RBP, RBP_H, 289 RDI, RDI_H, 290 RSI, RSI_H, 291 RCX, RCX_H, 292 RBX, RBX_H, 293 RSP, RSP_H, 294 R8, R8_H, 295 R9, R9_H, 296 R10, R10_H, 297 R11, R11_H, 298 R12, R12_H, 299 R13, R13_H, 300 R14, R14_H, 301 R15, R15_H); 302 303// Class for all pointer registers except RSP 304reg_class ptr_reg(RAX, RAX_H, 305 RDX, RDX_H, 306 RBP, RBP_H, 307 RDI, RDI_H, 308 RSI, RSI_H, 309 RCX, RCX_H, 310 RBX, RBX_H, 311 R8, R8_H, 312 R9, R9_H, 313 R10, R10_H, 314 R11, R11_H, 315 R13, R13_H, 316 R14, R14_H); 317 318// Class for all pointer registers except RAX and RSP 319reg_class ptr_no_rax_reg(RDX, RDX_H, 320 RBP, RBP_H, 321 RDI, RDI_H, 322 RSI, RSI_H, 323 RCX, RCX_H, 324 RBX, RBX_H, 325 R8, R8_H, 326 R9, R9_H, 327 R10, R10_H, 328 R11, R11_H, 329 R13, R13_H, 330 R14, R14_H); 331 332reg_class ptr_no_rbp_reg(RDX, RDX_H, 333 RAX, RAX_H, 334 RDI, RDI_H, 335 RSI, RSI_H, 336 RCX, RCX_H, 337 RBX, RBX_H, 338 R8, R8_H, 339 R9, R9_H, 340 R10, R10_H, 341 R11, R11_H, 342 R13, R13_H, 343 R14, R14_H); 344 345// Class for all pointer registers except RAX, RBX and RSP 346reg_class ptr_no_rax_rbx_reg(RDX, RDX_H, 347 RBP, RBP_H, 348 RDI, RDI_H, 349 RSI, RSI_H, 350 RCX, RCX_H, 351 R8, R8_H, 352 R9, R9_H, 353 R10, R10_H, 354 R11, R11_H, 355 R13, R13_H, 356 R14, R14_H); 357 358// Singleton class for RAX pointer register 359reg_class ptr_rax_reg(RAX, RAX_H); 360 361// Singleton class for RBX pointer register 362reg_class ptr_rbx_reg(RBX, RBX_H); 363 364// Singleton class for RSI pointer register 365reg_class ptr_rsi_reg(RSI, RSI_H); 366 367// Singleton class for RDI pointer register 368reg_class ptr_rdi_reg(RDI, RDI_H); 369 370// Singleton class for RBP pointer register 371reg_class ptr_rbp_reg(RBP, RBP_H); 372 373// Singleton class for stack pointer 374reg_class ptr_rsp_reg(RSP, RSP_H); 375 376// Singleton class for TLS pointer 377reg_class ptr_r15_reg(R15, R15_H); 378 379// Class for all long registers (except RSP) 380reg_class long_reg(RAX, RAX_H, 381 RDX, RDX_H, 382 RBP, RBP_H, 383 RDI, RDI_H, 384 RSI, RSI_H, 385 RCX, RCX_H, 386 RBX, RBX_H, 387 R8, R8_H, 388 R9, R9_H, 389 R10, R10_H, 390 R11, R11_H, 391 R13, R13_H, 392 R14, R14_H); 393 394// Class for all long registers except RAX, RDX (and RSP) 395reg_class long_no_rax_rdx_reg(RBP, RBP_H, 396 RDI, RDI_H, 397 RSI, RSI_H, 398 RCX, RCX_H, 399 RBX, RBX_H, 400 R8, R8_H, 401 R9, R9_H, 402 R10, R10_H, 403 R11, R11_H, 404 R13, R13_H, 405 R14, R14_H); 406 407// Class for all long registers except RCX (and RSP) 408reg_class long_no_rcx_reg(RBP, RBP_H, 409 RDI, RDI_H, 410 RSI, RSI_H, 411 RAX, RAX_H, 412 RDX, RDX_H, 413 RBX, RBX_H, 414 R8, R8_H, 415 R9, R9_H, 416 R10, R10_H, 417 R11, R11_H, 418 R13, R13_H, 419 R14, R14_H); 420 421// Class for all long registers except RAX (and RSP) 422reg_class long_no_rax_reg(RBP, RBP_H, 423 RDX, RDX_H, 424 RDI, RDI_H, 425 RSI, RSI_H, 426 RCX, RCX_H, 427 RBX, RBX_H, 428 R8, R8_H, 429 R9, R9_H, 430 R10, R10_H, 431 R11, R11_H, 432 R13, R13_H, 433 R14, R14_H); 434 435// Singleton class for RAX long register 436reg_class long_rax_reg(RAX, RAX_H); 437 438// Singleton class for RCX long register 439reg_class long_rcx_reg(RCX, RCX_H); 440 441// Singleton class for RDX long register 442reg_class long_rdx_reg(RDX, RDX_H); 443 444// Class for all int registers (except RSP) 445reg_class int_reg(RAX, 446 RDX, 447 RBP, 448 RDI, 449 RSI, 450 RCX, 451 RBX, 452 R8, 453 R9, 454 R10, 455 R11, 456 R13, 457 R14); 458 459// Class for all int registers except RCX (and RSP) 460reg_class int_no_rcx_reg(RAX, 461 RDX, 462 RBP, 463 RDI, 464 RSI, 465 RBX, 466 R8, 467 R9, 468 R10, 469 R11, 470 R13, 471 R14); 472 473// Class for all int registers except RAX, RDX (and RSP) 474reg_class int_no_rax_rdx_reg(RBP, 475 RDI, 476 RSI, 477 RCX, 478 RBX, 479 R8, 480 R9, 481 R10, 482 R11, 483 R13, 484 R14); 485 486// Singleton class for RAX int register 487reg_class int_rax_reg(RAX); 488 489// Singleton class for RBX int register 490reg_class int_rbx_reg(RBX); 491 492// Singleton class for RCX int register 493reg_class int_rcx_reg(RCX); 494 495// Singleton class for RCX int register 496reg_class int_rdx_reg(RDX); 497 498// Singleton class for RCX int register 499reg_class int_rdi_reg(RDI); 500 501// Singleton class for instruction pointer 502// reg_class ip_reg(RIP); 503 504// Singleton class for condition codes 505reg_class int_flags(RFLAGS); 506 507// Class for all float registers 508reg_class float_reg(XMM0, 509 XMM1, 510 XMM2, 511 XMM3, 512 XMM4, 513 XMM5, 514 XMM6, 515 XMM7, 516 XMM8, 517 XMM9, 518 XMM10, 519 XMM11, 520 XMM12, 521 XMM13, 522 XMM14, 523 XMM15); 524 525// Class for all double registers 526reg_class double_reg(XMM0, XMM0_H, 527 XMM1, XMM1_H, 528 XMM2, XMM2_H, 529 XMM3, XMM3_H, 530 XMM4, XMM4_H, 531 XMM5, XMM5_H, 532 XMM6, XMM6_H, 533 XMM7, XMM7_H, 534 XMM8, XMM8_H, 535 XMM9, XMM9_H, 536 XMM10, XMM10_H, 537 XMM11, XMM11_H, 538 XMM12, XMM12_H, 539 XMM13, XMM13_H, 540 XMM14, XMM14_H, 541 XMM15, XMM15_H); 542%} 543 544 545//----------SOURCE BLOCK------------------------------------------------------- 546// This is a block of C++ code which provides values, functions, and 547// definitions necessary in the rest of the architecture description 548source %{ 549#define RELOC_IMM64 Assembler::imm_operand 550#define RELOC_DISP32 Assembler::disp32_operand 551 552#define __ _masm. 553 554static int preserve_SP_size() { 555 return 3; // rex.w, op, rm(reg/reg) 556} 557 558// !!!!! Special hack to get all types of calls to specify the byte offset 559// from the start of the call to the point where the return address 560// will point. 561int MachCallStaticJavaNode::ret_addr_offset() 562{ 563 int offset = 5; // 5 bytes from start of call to where return address points 564 if (_method_handle_invoke) 565 offset += preserve_SP_size(); 566 return offset; 567} 568 569int MachCallDynamicJavaNode::ret_addr_offset() 570{ 571 return 15; // 15 bytes from start of call to where return address points 572} 573 574// In os_cpu .ad file 575// int MachCallRuntimeNode::ret_addr_offset() 576 577// Indicate if the safepoint node needs the polling page as an input, 578// it does if the polling page is more than disp32 away. 579bool SafePointNode::needs_polling_address_input() 580{ 581 return Assembler::is_polling_page_far(); 582} 583 584// 585// Compute padding required for nodes which need alignment 586// 587 588// The address of the call instruction needs to be 4-byte aligned to 589// ensure that it does not span a cache line so that it can be patched. 590int CallStaticJavaDirectNode::compute_padding(int current_offset) const 591{ 592 current_offset += 1; // skip call opcode byte 593 return round_to(current_offset, alignment_required()) - current_offset; 594} 595 596// The address of the call instruction needs to be 4-byte aligned to 597// ensure that it does not span a cache line so that it can be patched. 598int CallStaticJavaHandleNode::compute_padding(int current_offset) const 599{ 600 current_offset += preserve_SP_size(); // skip mov rbp, rsp 601 current_offset += 1; // skip call opcode byte 602 return round_to(current_offset, alignment_required()) - current_offset; 603} 604 605// The address of the call instruction needs to be 4-byte aligned to 606// ensure that it does not span a cache line so that it can be patched. 607int CallDynamicJavaDirectNode::compute_padding(int current_offset) const 608{ 609 current_offset += 11; // skip movq instruction + call opcode byte 610 return round_to(current_offset, alignment_required()) - current_offset; 611} 612 613// EMIT_RM() 614void emit_rm(CodeBuffer &cbuf, int f1, int f2, int f3) { 615 unsigned char c = (unsigned char) ((f1 << 6) | (f2 << 3) | f3); 616 cbuf.insts()->emit_int8(c); 617} 618 619// EMIT_CC() 620void emit_cc(CodeBuffer &cbuf, int f1, int f2) { 621 unsigned char c = (unsigned char) (f1 | f2); 622 cbuf.insts()->emit_int8(c); 623} 624 625// EMIT_OPCODE() 626void emit_opcode(CodeBuffer &cbuf, int code) { 627 cbuf.insts()->emit_int8((unsigned char) code); 628} 629 630// EMIT_OPCODE() w/ relocation information 631void emit_opcode(CodeBuffer &cbuf, 632 int code, relocInfo::relocType reloc, int offset, int format) 633{ 634 cbuf.relocate(cbuf.insts_mark() + offset, reloc, format); 635 emit_opcode(cbuf, code); 636} 637 638// EMIT_D8() 639void emit_d8(CodeBuffer &cbuf, int d8) { 640 cbuf.insts()->emit_int8((unsigned char) d8); 641} 642 643// EMIT_D16() 644void emit_d16(CodeBuffer &cbuf, int d16) { 645 cbuf.insts()->emit_int16(d16); 646} 647 648// EMIT_D32() 649void emit_d32(CodeBuffer &cbuf, int d32) { 650 cbuf.insts()->emit_int32(d32); 651} 652 653// EMIT_D64() 654void emit_d64(CodeBuffer &cbuf, int64_t d64) { 655 cbuf.insts()->emit_int64(d64); 656} 657 658// emit 32 bit value and construct relocation entry from relocInfo::relocType 659void emit_d32_reloc(CodeBuffer& cbuf, 660 int d32, 661 relocInfo::relocType reloc, 662 int format) 663{ 664 assert(reloc != relocInfo::external_word_type, "use 2-arg emit_d32_reloc"); 665 cbuf.relocate(cbuf.insts_mark(), reloc, format); 666 cbuf.insts()->emit_int32(d32); 667} 668 669// emit 32 bit value and construct relocation entry from RelocationHolder 670void emit_d32_reloc(CodeBuffer& cbuf, int d32, RelocationHolder const& rspec, int format) { 671#ifdef ASSERT 672 if (rspec.reloc()->type() == relocInfo::oop_type && 673 d32 != 0 && d32 != (intptr_t) Universe::non_oop_word()) { 674 assert(oop((intptr_t)d32)->is_oop() && (ScavengeRootsInCode || !oop((intptr_t)d32)->is_scavengable()), "cannot embed scavengable oops in code"); 675 } 676#endif 677 cbuf.relocate(cbuf.insts_mark(), rspec, format); 678 cbuf.insts()->emit_int32(d32); 679} 680 681void emit_d32_reloc(CodeBuffer& cbuf, address addr) { 682 address next_ip = cbuf.insts_end() + 4; 683 emit_d32_reloc(cbuf, (int) (addr - next_ip), 684 external_word_Relocation::spec(addr), 685 RELOC_DISP32); 686} 687 688 689// emit 64 bit value and construct relocation entry from relocInfo::relocType 690void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, relocInfo::relocType reloc, int format) { 691 cbuf.relocate(cbuf.insts_mark(), reloc, format); 692 cbuf.insts()->emit_int64(d64); 693} 694 695// emit 64 bit value and construct relocation entry from RelocationHolder 696void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, RelocationHolder const& rspec, int format) { 697#ifdef ASSERT 698 if (rspec.reloc()->type() == relocInfo::oop_type && 699 d64 != 0 && d64 != (int64_t) Universe::non_oop_word()) { 700 assert(oop(d64)->is_oop() && (ScavengeRootsInCode || !oop(d64)->is_scavengable()), 701 "cannot embed scavengable oops in code"); 702 } 703#endif 704 cbuf.relocate(cbuf.insts_mark(), rspec, format); 705 cbuf.insts()->emit_int64(d64); 706} 707 708// Access stack slot for load or store 709void store_to_stackslot(CodeBuffer &cbuf, int opcode, int rm_field, int disp) 710{ 711 emit_opcode(cbuf, opcode); // (e.g., FILD [RSP+src]) 712 if (-0x80 <= disp && disp < 0x80) { 713 emit_rm(cbuf, 0x01, rm_field, RSP_enc); // R/M byte 714 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte 715 emit_d8(cbuf, disp); // Displacement // R/M byte 716 } else { 717 emit_rm(cbuf, 0x02, rm_field, RSP_enc); // R/M byte 718 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte 719 emit_d32(cbuf, disp); // Displacement // R/M byte 720 } 721} 722 723 // rRegI ereg, memory mem) %{ // emit_reg_mem 724void encode_RegMem(CodeBuffer &cbuf, 725 int reg, 726 int base, int index, int scale, int disp, bool disp_is_oop) 727{ 728 assert(!disp_is_oop, "cannot have disp"); 729 int regenc = reg & 7; 730 int baseenc = base & 7; 731 int indexenc = index & 7; 732 733 // There is no index & no scale, use form without SIB byte 734 if (index == 0x4 && scale == 0 && base != RSP_enc && base != R12_enc) { 735 // If no displacement, mode is 0x0; unless base is [RBP] or [R13] 736 if (disp == 0 && base != RBP_enc && base != R13_enc) { 737 emit_rm(cbuf, 0x0, regenc, baseenc); // * 738 } else if (-0x80 <= disp && disp < 0x80 && !disp_is_oop) { 739 // If 8-bit displacement, mode 0x1 740 emit_rm(cbuf, 0x1, regenc, baseenc); // * 741 emit_d8(cbuf, disp); 742 } else { 743 // If 32-bit displacement 744 if (base == -1) { // Special flag for absolute address 745 emit_rm(cbuf, 0x0, regenc, 0x5); // * 746 if (disp_is_oop) { 747 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 748 } else { 749 emit_d32(cbuf, disp); 750 } 751 } else { 752 // Normal base + offset 753 emit_rm(cbuf, 0x2, regenc, baseenc); // * 754 if (disp_is_oop) { 755 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 756 } else { 757 emit_d32(cbuf, disp); 758 } 759 } 760 } 761 } else { 762 // Else, encode with the SIB byte 763 // If no displacement, mode is 0x0; unless base is [RBP] or [R13] 764 if (disp == 0 && base != RBP_enc && base != R13_enc) { 765 // If no displacement 766 emit_rm(cbuf, 0x0, regenc, 0x4); // * 767 emit_rm(cbuf, scale, indexenc, baseenc); 768 } else { 769 if (-0x80 <= disp && disp < 0x80 && !disp_is_oop) { 770 // If 8-bit displacement, mode 0x1 771 emit_rm(cbuf, 0x1, regenc, 0x4); // * 772 emit_rm(cbuf, scale, indexenc, baseenc); 773 emit_d8(cbuf, disp); 774 } else { 775 // If 32-bit displacement 776 if (base == 0x04 ) { 777 emit_rm(cbuf, 0x2, regenc, 0x4); 778 emit_rm(cbuf, scale, indexenc, 0x04); // XXX is this valid??? 779 } else { 780 emit_rm(cbuf, 0x2, regenc, 0x4); 781 emit_rm(cbuf, scale, indexenc, baseenc); // * 782 } 783 if (disp_is_oop) { 784 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 785 } else { 786 emit_d32(cbuf, disp); 787 } 788 } 789 } 790 } 791} 792 793// This could be in MacroAssembler but it's fairly C2 specific 794void emit_cmpfp_fixup(MacroAssembler& _masm) { 795 Label exit; 796 __ jccb(Assembler::noParity, exit); 797 __ pushf(); 798 // 799 // comiss/ucomiss instructions set ZF,PF,CF flags and 800 // zero OF,AF,SF for NaN values. 801 // Fixup flags by zeroing ZF,PF so that compare of NaN 802 // values returns 'less than' result (CF is set). 803 // Leave the rest of flags unchanged. 804 // 805 // 7 6 5 4 3 2 1 0 806 // |S|Z|r|A|r|P|r|C| (r - reserved bit) 807 // 0 0 1 0 1 0 1 1 (0x2B) 808 // 809 __ andq(Address(rsp, 0), 0xffffff2b); 810 __ popf(); 811 __ bind(exit); 812} 813 814void emit_cmpfp3(MacroAssembler& _masm, Register dst) { 815 Label done; 816 __ movl(dst, -1); 817 __ jcc(Assembler::parity, done); 818 __ jcc(Assembler::below, done); 819 __ setb(Assembler::notEqual, dst); 820 __ movzbl(dst, dst); 821 __ bind(done); 822} 823 824 825//============================================================================= 826const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; 827 828int Compile::ConstantTable::calculate_table_base_offset() const { 829 return 0; // absolute addressing, no offset 830} 831 832void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 833 // Empty encoding 834} 835 836uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 837 return 0; 838} 839 840#ifndef PRODUCT 841void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 842 st->print("# MachConstantBaseNode (empty encoding)"); 843} 844#endif 845 846 847//============================================================================= 848#ifndef PRODUCT 849void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 850 Compile* C = ra_->C; 851 852 int framesize = C->frame_slots() << LogBytesPerInt; 853 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 854 // Remove wordSize for return addr which is already pushed. 855 framesize -= wordSize; 856 857 if (C->need_stack_bang(framesize)) { 858 framesize -= wordSize; 859 st->print("# stack bang"); 860 st->print("\n\t"); 861 st->print("pushq rbp\t# Save rbp"); 862 if (framesize) { 863 st->print("\n\t"); 864 st->print("subq rsp, #%d\t# Create frame",framesize); 865 } 866 } else { 867 st->print("subq rsp, #%d\t# Create frame",framesize); 868 st->print("\n\t"); 869 framesize -= wordSize; 870 st->print("movq [rsp + #%d], rbp\t# Save rbp",framesize); 871 } 872 873 if (VerifyStackAtCalls) { 874 st->print("\n\t"); 875 framesize -= wordSize; 876 st->print("movq [rsp + #%d], 0xbadb100d\t# Majik cookie for stack depth check",framesize); 877#ifdef ASSERT 878 st->print("\n\t"); 879 st->print("# stack alignment check"); 880#endif 881 } 882 st->cr(); 883} 884#endif 885 886void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 887 Compile* C = ra_->C; 888 MacroAssembler _masm(&cbuf); 889 890 int framesize = C->frame_slots() << LogBytesPerInt; 891 892 __ verified_entry(framesize, C->need_stack_bang(framesize), false); 893 894 C->set_frame_complete(cbuf.insts_size()); 895 896 if (C->has_mach_constant_base_node()) { 897 // NOTE: We set the table base offset here because users might be 898 // emitted before MachConstantBaseNode. 899 Compile::ConstantTable& constant_table = C->constant_table(); 900 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset()); 901 } 902} 903 904uint MachPrologNode::size(PhaseRegAlloc* ra_) const 905{ 906 return MachNode::size(ra_); // too many variables; just compute it 907 // the hard way 908} 909 910int MachPrologNode::reloc() const 911{ 912 return 0; // a large enough number 913} 914 915//============================================================================= 916#ifndef PRODUCT 917void MachEpilogNode::format(PhaseRegAlloc* ra_, outputStream* st) const 918{ 919 Compile* C = ra_->C; 920 int framesize = C->frame_slots() << LogBytesPerInt; 921 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 922 // Remove word for return adr already pushed 923 // and RBP 924 framesize -= 2*wordSize; 925 926 if (framesize) { 927 st->print_cr("addq rsp, %d\t# Destroy frame", framesize); 928 st->print("\t"); 929 } 930 931 st->print_cr("popq rbp"); 932 if (do_polling() && C->is_method_compilation()) { 933 st->print("\t"); 934 if (Assembler::is_polling_page_far()) { 935 st->print_cr("movq rscratch1, #polling_page_address\n\t" 936 "testl rax, [rscratch1]\t" 937 "# Safepoint: poll for GC"); 938 } else { 939 st->print_cr("testl rax, [rip + #offset_to_poll_page]\t" 940 "# Safepoint: poll for GC"); 941 } 942 } 943} 944#endif 945 946void MachEpilogNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 947{ 948 Compile* C = ra_->C; 949 int framesize = C->frame_slots() << LogBytesPerInt; 950 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 951 // Remove word for return adr already pushed 952 // and RBP 953 framesize -= 2*wordSize; 954 955 // Note that VerifyStackAtCalls' Majik cookie does not change the frame size popped here 956 957 if (framesize) { 958 emit_opcode(cbuf, Assembler::REX_W); 959 if (framesize < 0x80) { 960 emit_opcode(cbuf, 0x83); // addq rsp, #framesize 961 emit_rm(cbuf, 0x3, 0x00, RSP_enc); 962 emit_d8(cbuf, framesize); 963 } else { 964 emit_opcode(cbuf, 0x81); // addq rsp, #framesize 965 emit_rm(cbuf, 0x3, 0x00, RSP_enc); 966 emit_d32(cbuf, framesize); 967 } 968 } 969 970 // popq rbp 971 emit_opcode(cbuf, 0x58 | RBP_enc); 972 973 if (do_polling() && C->is_method_compilation()) { 974 MacroAssembler _masm(&cbuf); 975 AddressLiteral polling_page(os::get_polling_page(), relocInfo::poll_return_type); 976 if (Assembler::is_polling_page_far()) { 977 __ lea(rscratch1, polling_page); 978 __ relocate(relocInfo::poll_return_type); 979 __ testl(rax, Address(rscratch1, 0)); 980 } else { 981 __ testl(rax, polling_page); 982 } 983 } 984} 985 986uint MachEpilogNode::size(PhaseRegAlloc* ra_) const 987{ 988 return MachNode::size(ra_); // too many variables; just compute it 989 // the hard way 990} 991 992int MachEpilogNode::reloc() const 993{ 994 return 2; // a large enough number 995} 996 997const Pipeline* MachEpilogNode::pipeline() const 998{ 999 return MachNode::pipeline_class(); 1000} 1001 1002int MachEpilogNode::safepoint_offset() const 1003{ 1004 return 0; 1005} 1006 1007//============================================================================= 1008 1009enum RC { 1010 rc_bad, 1011 rc_int, 1012 rc_float, 1013 rc_stack 1014}; 1015 1016static enum RC rc_class(OptoReg::Name reg) 1017{ 1018 if( !OptoReg::is_valid(reg) ) return rc_bad; 1019 1020 if (OptoReg::is_stack(reg)) return rc_stack; 1021 1022 VMReg r = OptoReg::as_VMReg(reg); 1023 1024 if (r->is_Register()) return rc_int; 1025 1026 assert(r->is_XMMRegister(), "must be"); 1027 return rc_float; 1028} 1029 1030uint MachSpillCopyNode::implementation(CodeBuffer* cbuf, 1031 PhaseRegAlloc* ra_, 1032 bool do_size, 1033 outputStream* st) const 1034{ 1035 1036 // Get registers to move 1037 OptoReg::Name src_second = ra_->get_reg_second(in(1)); 1038 OptoReg::Name src_first = ra_->get_reg_first(in(1)); 1039 OptoReg::Name dst_second = ra_->get_reg_second(this); 1040 OptoReg::Name dst_first = ra_->get_reg_first(this); 1041 1042 enum RC src_second_rc = rc_class(src_second); 1043 enum RC src_first_rc = rc_class(src_first); 1044 enum RC dst_second_rc = rc_class(dst_second); 1045 enum RC dst_first_rc = rc_class(dst_first); 1046 1047 assert(OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), 1048 "must move at least 1 register" ); 1049 1050 if (src_first == dst_first && src_second == dst_second) { 1051 // Self copy, no move 1052 return 0; 1053 } else if (src_first_rc == rc_stack) { 1054 // mem -> 1055 if (dst_first_rc == rc_stack) { 1056 // mem -> mem 1057 assert(src_second != dst_first, "overlap"); 1058 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1059 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1060 // 64-bit 1061 int src_offset = ra_->reg2offset(src_first); 1062 int dst_offset = ra_->reg2offset(dst_first); 1063 if (cbuf) { 1064 emit_opcode(*cbuf, 0xFF); 1065 encode_RegMem(*cbuf, RSI_enc, RSP_enc, 0x4, 0, src_offset, false); 1066 1067 emit_opcode(*cbuf, 0x8F); 1068 encode_RegMem(*cbuf, RAX_enc, RSP_enc, 0x4, 0, dst_offset, false); 1069 1070#ifndef PRODUCT 1071 } else if (!do_size) { 1072 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1073 "popq [rsp + #%d]", 1074 src_offset, 1075 dst_offset); 1076#endif 1077 } 1078 return 1079 3 + ((src_offset == 0) ? 0 : (src_offset < 0x80 ? 1 : 4)) + 1080 3 + ((dst_offset == 0) ? 0 : (dst_offset < 0x80 ? 1 : 4)); 1081 } else { 1082 // 32-bit 1083 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1084 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1085 // No pushl/popl, so: 1086 int src_offset = ra_->reg2offset(src_first); 1087 int dst_offset = ra_->reg2offset(dst_first); 1088 if (cbuf) { 1089 emit_opcode(*cbuf, Assembler::REX_W); 1090 emit_opcode(*cbuf, 0x89); 1091 emit_opcode(*cbuf, 0x44); 1092 emit_opcode(*cbuf, 0x24); 1093 emit_opcode(*cbuf, 0xF8); 1094 1095 emit_opcode(*cbuf, 0x8B); 1096 encode_RegMem(*cbuf, 1097 RAX_enc, 1098 RSP_enc, 0x4, 0, src_offset, 1099 false); 1100 1101 emit_opcode(*cbuf, 0x89); 1102 encode_RegMem(*cbuf, 1103 RAX_enc, 1104 RSP_enc, 0x4, 0, dst_offset, 1105 false); 1106 1107 emit_opcode(*cbuf, Assembler::REX_W); 1108 emit_opcode(*cbuf, 0x8B); 1109 emit_opcode(*cbuf, 0x44); 1110 emit_opcode(*cbuf, 0x24); 1111 emit_opcode(*cbuf, 0xF8); 1112 1113#ifndef PRODUCT 1114 } else if (!do_size) { 1115 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1116 "movl rax, [rsp + #%d]\n\t" 1117 "movl [rsp + #%d], rax\n\t" 1118 "movq rax, [rsp - #8]", 1119 src_offset, 1120 dst_offset); 1121#endif 1122 } 1123 return 1124 5 + // movq 1125 3 + ((src_offset == 0) ? 0 : (src_offset < 0x80 ? 1 : 4)) + // movl 1126 3 + ((dst_offset == 0) ? 0 : (dst_offset < 0x80 ? 1 : 4)) + // movl 1127 5; // movq 1128 } 1129 } else if (dst_first_rc == rc_int) { 1130 // mem -> gpr 1131 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1132 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1133 // 64-bit 1134 int offset = ra_->reg2offset(src_first); 1135 if (cbuf) { 1136 if (Matcher::_regEncode[dst_first] < 8) { 1137 emit_opcode(*cbuf, Assembler::REX_W); 1138 } else { 1139 emit_opcode(*cbuf, Assembler::REX_WR); 1140 } 1141 emit_opcode(*cbuf, 0x8B); 1142 encode_RegMem(*cbuf, 1143 Matcher::_regEncode[dst_first], 1144 RSP_enc, 0x4, 0, offset, 1145 false); 1146#ifndef PRODUCT 1147 } else if (!do_size) { 1148 st->print("movq %s, [rsp + #%d]\t# spill", 1149 Matcher::regName[dst_first], 1150 offset); 1151#endif 1152 } 1153 return 1154 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) + 4; // REX 1155 } else { 1156 // 32-bit 1157 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1158 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1159 int offset = ra_->reg2offset(src_first); 1160 if (cbuf) { 1161 if (Matcher::_regEncode[dst_first] >= 8) { 1162 emit_opcode(*cbuf, Assembler::REX_R); 1163 } 1164 emit_opcode(*cbuf, 0x8B); 1165 encode_RegMem(*cbuf, 1166 Matcher::_regEncode[dst_first], 1167 RSP_enc, 0x4, 0, offset, 1168 false); 1169#ifndef PRODUCT 1170 } else if (!do_size) { 1171 st->print("movl %s, [rsp + #%d]\t# spill", 1172 Matcher::regName[dst_first], 1173 offset); 1174#endif 1175 } 1176 return 1177 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) + 1178 ((Matcher::_regEncode[dst_first] < 8) 1179 ? 3 1180 : 4); // REX 1181 } 1182 } else if (dst_first_rc == rc_float) { 1183 // mem-> xmm 1184 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1185 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1186 // 64-bit 1187 int offset = ra_->reg2offset(src_first); 1188 if (cbuf) { 1189 MacroAssembler _masm(cbuf); 1190 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1191#ifndef PRODUCT 1192 } else if (!do_size) { 1193 st->print("%s %s, [rsp + #%d]\t# spill", 1194 UseXmmLoadAndClearUpper ? "movsd " : "movlpd", 1195 Matcher::regName[dst_first], 1196 offset); 1197#endif 1198 } 1199 return 1200 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) + 1201 ((Matcher::_regEncode[dst_first] >= 8) 1202 ? 6 1203 : (5 + ((UseAVX>0)?1:0))); // REX 1204 } else { 1205 // 32-bit 1206 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1207 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1208 int offset = ra_->reg2offset(src_first); 1209 if (cbuf) { 1210 MacroAssembler _masm(cbuf); 1211 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1212#ifndef PRODUCT 1213 } else if (!do_size) { 1214 st->print("movss %s, [rsp + #%d]\t# spill", 1215 Matcher::regName[dst_first], 1216 offset); 1217#endif 1218 } 1219 return 1220 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) + 1221 ((Matcher::_regEncode[dst_first] >= 8) 1222 ? 6 1223 : (5 + ((UseAVX>0)?1:0))); // REX 1224 } 1225 } 1226 } else if (src_first_rc == rc_int) { 1227 // gpr -> 1228 if (dst_first_rc == rc_stack) { 1229 // gpr -> mem 1230 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1231 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1232 // 64-bit 1233 int offset = ra_->reg2offset(dst_first); 1234 if (cbuf) { 1235 if (Matcher::_regEncode[src_first] < 8) { 1236 emit_opcode(*cbuf, Assembler::REX_W); 1237 } else { 1238 emit_opcode(*cbuf, Assembler::REX_WR); 1239 } 1240 emit_opcode(*cbuf, 0x89); 1241 encode_RegMem(*cbuf, 1242 Matcher::_regEncode[src_first], 1243 RSP_enc, 0x4, 0, offset, 1244 false); 1245#ifndef PRODUCT 1246 } else if (!do_size) { 1247 st->print("movq [rsp + #%d], %s\t# spill", 1248 offset, 1249 Matcher::regName[src_first]); 1250#endif 1251 } 1252 return ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) + 4; // REX 1253 } else { 1254 // 32-bit 1255 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1256 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1257 int offset = ra_->reg2offset(dst_first); 1258 if (cbuf) { 1259 if (Matcher::_regEncode[src_first] >= 8) { 1260 emit_opcode(*cbuf, Assembler::REX_R); 1261 } 1262 emit_opcode(*cbuf, 0x89); 1263 encode_RegMem(*cbuf, 1264 Matcher::_regEncode[src_first], 1265 RSP_enc, 0x4, 0, offset, 1266 false); 1267#ifndef PRODUCT 1268 } else if (!do_size) { 1269 st->print("movl [rsp + #%d], %s\t# spill", 1270 offset, 1271 Matcher::regName[src_first]); 1272#endif 1273 } 1274 return 1275 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) + 1276 ((Matcher::_regEncode[src_first] < 8) 1277 ? 3 1278 : 4); // REX 1279 } 1280 } else if (dst_first_rc == rc_int) { 1281 // gpr -> gpr 1282 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1283 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1284 // 64-bit 1285 if (cbuf) { 1286 if (Matcher::_regEncode[dst_first] < 8) { 1287 if (Matcher::_regEncode[src_first] < 8) { 1288 emit_opcode(*cbuf, Assembler::REX_W); 1289 } else { 1290 emit_opcode(*cbuf, Assembler::REX_WB); 1291 } 1292 } else { 1293 if (Matcher::_regEncode[src_first] < 8) { 1294 emit_opcode(*cbuf, Assembler::REX_WR); 1295 } else { 1296 emit_opcode(*cbuf, Assembler::REX_WRB); 1297 } 1298 } 1299 emit_opcode(*cbuf, 0x8B); 1300 emit_rm(*cbuf, 0x3, 1301 Matcher::_regEncode[dst_first] & 7, 1302 Matcher::_regEncode[src_first] & 7); 1303#ifndef PRODUCT 1304 } else if (!do_size) { 1305 st->print("movq %s, %s\t# spill", 1306 Matcher::regName[dst_first], 1307 Matcher::regName[src_first]); 1308#endif 1309 } 1310 return 3; // REX 1311 } else { 1312 // 32-bit 1313 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1314 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1315 if (cbuf) { 1316 if (Matcher::_regEncode[dst_first] < 8) { 1317 if (Matcher::_regEncode[src_first] >= 8) { 1318 emit_opcode(*cbuf, Assembler::REX_B); 1319 } 1320 } else { 1321 if (Matcher::_regEncode[src_first] < 8) { 1322 emit_opcode(*cbuf, Assembler::REX_R); 1323 } else { 1324 emit_opcode(*cbuf, Assembler::REX_RB); 1325 } 1326 } 1327 emit_opcode(*cbuf, 0x8B); 1328 emit_rm(*cbuf, 0x3, 1329 Matcher::_regEncode[dst_first] & 7, 1330 Matcher::_regEncode[src_first] & 7); 1331#ifndef PRODUCT 1332 } else if (!do_size) { 1333 st->print("movl %s, %s\t# spill", 1334 Matcher::regName[dst_first], 1335 Matcher::regName[src_first]); 1336#endif 1337 } 1338 return 1339 (Matcher::_regEncode[src_first] < 8 && Matcher::_regEncode[dst_first] < 8) 1340 ? 2 1341 : 3; // REX 1342 } 1343 } else if (dst_first_rc == rc_float) { 1344 // gpr -> xmm 1345 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1346 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1347 // 64-bit 1348 if (cbuf) { 1349 MacroAssembler _masm(cbuf); 1350 __ movdq( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1351#ifndef PRODUCT 1352 } else if (!do_size) { 1353 st->print("movdq %s, %s\t# spill", 1354 Matcher::regName[dst_first], 1355 Matcher::regName[src_first]); 1356#endif 1357 } 1358 return 5; // REX 1359 } else { 1360 // 32-bit 1361 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1362 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1363 if (cbuf) { 1364 MacroAssembler _masm(cbuf); 1365 __ movdl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1366#ifndef PRODUCT 1367 } else if (!do_size) { 1368 st->print("movdl %s, %s\t# spill", 1369 Matcher::regName[dst_first], 1370 Matcher::regName[src_first]); 1371#endif 1372 } 1373 return 1374 (Matcher::_regEncode[src_first] >= 8 || Matcher::_regEncode[dst_first] >= 8) 1375 ? 5 1376 : (4 + ((UseAVX>0)?1:0)); // REX 1377 } 1378 } 1379 } else if (src_first_rc == rc_float) { 1380 // xmm -> 1381 if (dst_first_rc == rc_stack) { 1382 // xmm -> mem 1383 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1384 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1385 // 64-bit 1386 int offset = ra_->reg2offset(dst_first); 1387 if (cbuf) { 1388 MacroAssembler _masm(cbuf); 1389 __ movdbl( Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1390#ifndef PRODUCT 1391 } else if (!do_size) { 1392 st->print("movsd [rsp + #%d], %s\t# spill", 1393 offset, 1394 Matcher::regName[src_first]); 1395#endif 1396 } 1397 return 1398 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) + 1399 ((Matcher::_regEncode[src_first] >= 8) 1400 ? 6 1401 : (5 + ((UseAVX>0)?1:0))); // REX 1402 } else { 1403 // 32-bit 1404 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1405 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1406 int offset = ra_->reg2offset(dst_first); 1407 if (cbuf) { 1408 MacroAssembler _masm(cbuf); 1409 __ movflt(Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1410#ifndef PRODUCT 1411 } else if (!do_size) { 1412 st->print("movss [rsp + #%d], %s\t# spill", 1413 offset, 1414 Matcher::regName[src_first]); 1415#endif 1416 } 1417 return 1418 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) + 1419 ((Matcher::_regEncode[src_first] >=8) 1420 ? 6 1421 : (5 + ((UseAVX>0)?1:0))); // REX 1422 } 1423 } else if (dst_first_rc == rc_int) { 1424 // xmm -> gpr 1425 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1426 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1427 // 64-bit 1428 if (cbuf) { 1429 MacroAssembler _masm(cbuf); 1430 __ movdq( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1431#ifndef PRODUCT 1432 } else if (!do_size) { 1433 st->print("movdq %s, %s\t# spill", 1434 Matcher::regName[dst_first], 1435 Matcher::regName[src_first]); 1436#endif 1437 } 1438 return 5; // REX 1439 } else { 1440 // 32-bit 1441 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1442 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1443 if (cbuf) { 1444 MacroAssembler _masm(cbuf); 1445 __ movdl( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1446#ifndef PRODUCT 1447 } else if (!do_size) { 1448 st->print("movdl %s, %s\t# spill", 1449 Matcher::regName[dst_first], 1450 Matcher::regName[src_first]); 1451#endif 1452 } 1453 return 1454 (Matcher::_regEncode[src_first] >= 8 || Matcher::_regEncode[dst_first] >= 8) 1455 ? 5 1456 : (4 + ((UseAVX>0)?1:0)); // REX 1457 } 1458 } else if (dst_first_rc == rc_float) { 1459 // xmm -> xmm 1460 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1461 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1462 // 64-bit 1463 if (cbuf) { 1464 MacroAssembler _masm(cbuf); 1465 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1466#ifndef PRODUCT 1467 } else if (!do_size) { 1468 st->print("%s %s, %s\t# spill", 1469 UseXmmRegToRegMoveAll ? "movapd" : "movsd ", 1470 Matcher::regName[dst_first], 1471 Matcher::regName[src_first]); 1472#endif 1473 } 1474 return 1475 (Matcher::_regEncode[src_first] >= 8 || Matcher::_regEncode[dst_first] >= 8) 1476 ? 5 1477 : (4 + ((UseAVX>0)?1:0)); // REX 1478 } else { 1479 // 32-bit 1480 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1481 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1482 if (cbuf) { 1483 MacroAssembler _masm(cbuf); 1484 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1485#ifndef PRODUCT 1486 } else if (!do_size) { 1487 st->print("%s %s, %s\t# spill", 1488 UseXmmRegToRegMoveAll ? "movaps" : "movss ", 1489 Matcher::regName[dst_first], 1490 Matcher::regName[src_first]); 1491#endif 1492 } 1493 return ((UseAVX>0) ? 5: 1494 ((Matcher::_regEncode[src_first] >= 8 || Matcher::_regEncode[dst_first] >= 8) 1495 ? (UseXmmRegToRegMoveAll ? 4 : 5) 1496 : (UseXmmRegToRegMoveAll ? 3 : 4))); // REX 1497 } 1498 } 1499 } 1500 1501 assert(0," foo "); 1502 Unimplemented(); 1503 1504 return 0; 1505} 1506 1507#ifndef PRODUCT 1508void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream* st) const 1509{ 1510 implementation(NULL, ra_, false, st); 1511} 1512#endif 1513 1514void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const 1515{ 1516 implementation(&cbuf, ra_, false, NULL); 1517} 1518 1519uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const 1520{ 1521 return implementation(NULL, ra_, true, NULL); 1522} 1523 1524//============================================================================= 1525#ifndef PRODUCT 1526void BoxLockNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1527{ 1528 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1529 int reg = ra_->get_reg_first(this); 1530 st->print("leaq %s, [rsp + #%d]\t# box lock", 1531 Matcher::regName[reg], offset); 1532} 1533#endif 1534 1535void BoxLockNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1536{ 1537 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1538 int reg = ra_->get_encode(this); 1539 if (offset >= 0x80) { 1540 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR); 1541 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset] 1542 emit_rm(cbuf, 0x2, reg & 7, 0x04); 1543 emit_rm(cbuf, 0x0, 0x04, RSP_enc); 1544 emit_d32(cbuf, offset); 1545 } else { 1546 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR); 1547 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset] 1548 emit_rm(cbuf, 0x1, reg & 7, 0x04); 1549 emit_rm(cbuf, 0x0, 0x04, RSP_enc); 1550 emit_d8(cbuf, offset); 1551 } 1552} 1553 1554uint BoxLockNode::size(PhaseRegAlloc *ra_) const 1555{ 1556 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1557 return (offset < 0x80) ? 5 : 8; // REX 1558} 1559 1560//============================================================================= 1561 1562// emit call stub, compiled java to interpreter 1563void emit_java_to_interp(CodeBuffer& cbuf) 1564{ 1565 // Stub is fixed up when the corresponding call is converted from 1566 // calling compiled code to calling interpreted code. 1567 // movq rbx, 0 1568 // jmp -5 # to self 1569 1570 address mark = cbuf.insts_mark(); // get mark within main instrs section 1571 1572 // Note that the code buffer's insts_mark is always relative to insts. 1573 // That's why we must use the macroassembler to generate a stub. 1574 MacroAssembler _masm(&cbuf); 1575 1576 address base = 1577 __ start_a_stub(Compile::MAX_stubs_size); 1578 if (base == NULL) return; // CodeBuffer::expand failed 1579 // static stub relocation stores the instruction address of the call 1580 __ relocate(static_stub_Relocation::spec(mark), RELOC_IMM64); 1581 // static stub relocation also tags the methodOop in the code-stream. 1582 __ movoop(rbx, (jobject) NULL); // method is zapped till fixup time 1583 // This is recognized as unresolved by relocs/nativeinst/ic code 1584 __ jump(RuntimeAddress(__ pc())); 1585 1586 // Update current stubs pointer and restore insts_end. 1587 __ end_a_stub(); 1588} 1589 1590// size of call stub, compiled java to interpretor 1591uint size_java_to_interp() 1592{ 1593 return 15; // movq (1+1+8); jmp (1+4) 1594} 1595 1596// relocation entries for call stub, compiled java to interpretor 1597uint reloc_java_to_interp() 1598{ 1599 return 4; // 3 in emit_java_to_interp + 1 in Java_Static_Call 1600} 1601 1602//============================================================================= 1603#ifndef PRODUCT 1604void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1605{ 1606 if (UseCompressedOops) { 1607 st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1608 if (Universe::narrow_oop_shift() != 0) { 1609 st->print_cr("\tdecode_heap_oop_not_null rscratch1, rscratch1"); 1610 } 1611 st->print_cr("\tcmpq rax, rscratch1\t # Inline cache check"); 1612 } else { 1613 st->print_cr("\tcmpq rax, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t" 1614 "# Inline cache check"); 1615 } 1616 st->print_cr("\tjne SharedRuntime::_ic_miss_stub"); 1617 st->print_cr("\tnop\t# nops to align entry point"); 1618} 1619#endif 1620 1621void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1622{ 1623 MacroAssembler masm(&cbuf); 1624 uint insts_size = cbuf.insts_size(); 1625 if (UseCompressedOops) { 1626 masm.load_klass(rscratch1, j_rarg0); 1627 masm.cmpptr(rax, rscratch1); 1628 } else { 1629 masm.cmpptr(rax, Address(j_rarg0, oopDesc::klass_offset_in_bytes())); 1630 } 1631 1632 masm.jump_cc(Assembler::notEqual, RuntimeAddress(SharedRuntime::get_ic_miss_stub())); 1633 1634 /* WARNING these NOPs are critical so that verified entry point is properly 1635 4 bytes aligned for patching by NativeJump::patch_verified_entry() */ 1636 int nops_cnt = 4 - ((cbuf.insts_size() - insts_size) & 0x3); 1637 if (OptoBreakpoint) { 1638 // Leave space for int3 1639 nops_cnt -= 1; 1640 } 1641 nops_cnt &= 0x3; // Do not add nops if code is aligned. 1642 if (nops_cnt > 0) 1643 masm.nop(nops_cnt); 1644} 1645 1646uint MachUEPNode::size(PhaseRegAlloc* ra_) const 1647{ 1648 return MachNode::size(ra_); // too many variables; just compute it 1649 // the hard way 1650} 1651 1652 1653//============================================================================= 1654uint size_exception_handler() 1655{ 1656 // NativeCall instruction size is the same as NativeJump. 1657 // Note that this value is also credited (in output.cpp) to 1658 // the size of the code section. 1659 return NativeJump::instruction_size; 1660} 1661 1662// Emit exception handler code. 1663int emit_exception_handler(CodeBuffer& cbuf) 1664{ 1665 1666 // Note that the code buffer's insts_mark is always relative to insts. 1667 // That's why we must use the macroassembler to generate a handler. 1668 MacroAssembler _masm(&cbuf); 1669 address base = 1670 __ start_a_stub(size_exception_handler()); 1671 if (base == NULL) return 0; // CodeBuffer::expand failed 1672 int offset = __ offset(); 1673 __ jump(RuntimeAddress(OptoRuntime::exception_blob()->entry_point())); 1674 assert(__ offset() - offset <= (int) size_exception_handler(), "overflow"); 1675 __ end_a_stub(); 1676 return offset; 1677} 1678 1679uint size_deopt_handler() 1680{ 1681 // three 5 byte instructions 1682 return 15; 1683} 1684 1685// Emit deopt handler code. 1686int emit_deopt_handler(CodeBuffer& cbuf) 1687{ 1688 1689 // Note that the code buffer's insts_mark is always relative to insts. 1690 // That's why we must use the macroassembler to generate a handler. 1691 MacroAssembler _masm(&cbuf); 1692 address base = 1693 __ start_a_stub(size_deopt_handler()); 1694 if (base == NULL) return 0; // CodeBuffer::expand failed 1695 int offset = __ offset(); 1696 address the_pc = (address) __ pc(); 1697 Label next; 1698 // push a "the_pc" on the stack without destroying any registers 1699 // as they all may be live. 1700 1701 // push address of "next" 1702 __ call(next, relocInfo::none); // reloc none is fine since it is a disp32 1703 __ bind(next); 1704 // adjust it so it matches "the_pc" 1705 __ subptr(Address(rsp, 0), __ offset() - offset); 1706 __ jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack())); 1707 assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow"); 1708 __ end_a_stub(); 1709 return offset; 1710} 1711 1712 1713const bool Matcher::match_rule_supported(int opcode) { 1714 if (!has_match_rule(opcode)) 1715 return false; 1716 1717 return true; // Per default match rules are supported. 1718} 1719 1720int Matcher::regnum_to_fpu_offset(int regnum) 1721{ 1722 return regnum - 32; // The FP registers are in the second chunk 1723} 1724 1725// This is UltraSparc specific, true just means we have fast l2f conversion 1726const bool Matcher::convL2FSupported(void) { 1727 return true; 1728} 1729 1730// Vector width in bytes 1731const uint Matcher::vector_width_in_bytes(void) { 1732 return 8; 1733} 1734 1735// Vector ideal reg 1736const uint Matcher::vector_ideal_reg(void) { 1737 return Op_RegD; 1738} 1739 1740// Is this branch offset short enough that a short branch can be used? 1741// 1742// NOTE: If the platform does not provide any short branch variants, then 1743// this method should return false for offset 0. 1744bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 1745 // The passed offset is relative to address of the branch. 1746 // On 86 a branch displacement is calculated relative to address 1747 // of a next instruction. 1748 offset -= br_size; 1749 1750 // the short version of jmpConUCF2 contains multiple branches, 1751 // making the reach slightly less 1752 if (rule == jmpConUCF2_rule) 1753 return (-126 <= offset && offset <= 125); 1754 return (-128 <= offset && offset <= 127); 1755} 1756 1757const bool Matcher::isSimpleConstant64(jlong value) { 1758 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?. 1759 //return value == (int) value; // Cf. storeImmL and immL32. 1760 1761 // Probably always true, even if a temp register is required. 1762 return true; 1763} 1764 1765// The ecx parameter to rep stosq for the ClearArray node is in words. 1766const bool Matcher::init_array_count_is_in_bytes = false; 1767 1768// Threshold size for cleararray. 1769const int Matcher::init_array_short_size = 8 * BytesPerLong; 1770 1771// No additional cost for CMOVL. 1772const int Matcher::long_cmove_cost() { return 0; } 1773 1774// No CMOVF/CMOVD with SSE2 1775const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; } 1776 1777// Should the Matcher clone shifts on addressing modes, expecting them 1778// to be subsumed into complex addressing expressions or compute them 1779// into registers? True for Intel but false for most RISCs 1780const bool Matcher::clone_shift_expressions = true; 1781 1782// Do we need to mask the count passed to shift instructions or does 1783// the cpu only look at the lower 5/6 bits anyway? 1784const bool Matcher::need_masked_shift_count = false; 1785 1786bool Matcher::narrow_oop_use_complex_address() { 1787 assert(UseCompressedOops, "only for compressed oops code"); 1788 return (LogMinObjAlignmentInBytes <= 3); 1789} 1790 1791// Is it better to copy float constants, or load them directly from 1792// memory? Intel can load a float constant from a direct address, 1793// requiring no extra registers. Most RISCs will have to materialize 1794// an address into a register first, so they would do better to copy 1795// the constant from stack. 1796const bool Matcher::rematerialize_float_constants = true; // XXX 1797 1798// If CPU can load and store mis-aligned doubles directly then no 1799// fixup is needed. Else we split the double into 2 integer pieces 1800// and move it piece-by-piece. Only happens when passing doubles into 1801// C code as the Java calling convention forces doubles to be aligned. 1802const bool Matcher::misaligned_doubles_ok = true; 1803 1804// No-op on amd64 1805void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) {} 1806 1807// Advertise here if the CPU requires explicit rounding operations to 1808// implement the UseStrictFP mode. 1809const bool Matcher::strict_fp_requires_explicit_rounding = true; 1810 1811// Are floats conerted to double when stored to stack during deoptimization? 1812// On x64 it is stored without convertion so we can use normal access. 1813bool Matcher::float_in_double() { return false; } 1814 1815// Do ints take an entire long register or just half? 1816const bool Matcher::int_in_long = true; 1817 1818// Return whether or not this register is ever used as an argument. 1819// This function is used on startup to build the trampoline stubs in 1820// generateOptoStub. Registers not mentioned will be killed by the VM 1821// call in the trampoline, and arguments in those registers not be 1822// available to the callee. 1823bool Matcher::can_be_java_arg(int reg) 1824{ 1825 return 1826 reg == RDI_num || reg == RDI_H_num || 1827 reg == RSI_num || reg == RSI_H_num || 1828 reg == RDX_num || reg == RDX_H_num || 1829 reg == RCX_num || reg == RCX_H_num || 1830 reg == R8_num || reg == R8_H_num || 1831 reg == R9_num || reg == R9_H_num || 1832 reg == R12_num || reg == R12_H_num || 1833 reg == XMM0_num || reg == XMM0_H_num || 1834 reg == XMM1_num || reg == XMM1_H_num || 1835 reg == XMM2_num || reg == XMM2_H_num || 1836 reg == XMM3_num || reg == XMM3_H_num || 1837 reg == XMM4_num || reg == XMM4_H_num || 1838 reg == XMM5_num || reg == XMM5_H_num || 1839 reg == XMM6_num || reg == XMM6_H_num || 1840 reg == XMM7_num || reg == XMM7_H_num; 1841} 1842 1843bool Matcher::is_spillable_arg(int reg) 1844{ 1845 return can_be_java_arg(reg); 1846} 1847 1848bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) { 1849 // In 64 bit mode a code which use multiply when 1850 // devisor is constant is faster than hardware 1851 // DIV instruction (it uses MulHiL). 1852 return false; 1853} 1854 1855// Register for DIVI projection of divmodI 1856RegMask Matcher::divI_proj_mask() { 1857 return INT_RAX_REG_mask(); 1858} 1859 1860// Register for MODI projection of divmodI 1861RegMask Matcher::modI_proj_mask() { 1862 return INT_RDX_REG_mask(); 1863} 1864 1865// Register for DIVL projection of divmodL 1866RegMask Matcher::divL_proj_mask() { 1867 return LONG_RAX_REG_mask(); 1868} 1869 1870// Register for MODL projection of divmodL 1871RegMask Matcher::modL_proj_mask() { 1872 return LONG_RDX_REG_mask(); 1873} 1874 1875const RegMask Matcher::method_handle_invoke_SP_save_mask() { 1876 return PTR_RBP_REG_mask(); 1877} 1878 1879static Address build_address(int b, int i, int s, int d) { 1880 Register index = as_Register(i); 1881 Address::ScaleFactor scale = (Address::ScaleFactor)s; 1882 if (index == rsp) { 1883 index = noreg; 1884 scale = Address::no_scale; 1885 } 1886 Address addr(as_Register(b), index, scale, d); 1887 return addr; 1888} 1889 1890%} 1891 1892//----------ENCODING BLOCK----------------------------------------------------- 1893// This block specifies the encoding classes used by the compiler to 1894// output byte streams. Encoding classes are parameterized macros 1895// used by Machine Instruction Nodes in order to generate the bit 1896// encoding of the instruction. Operands specify their base encoding 1897// interface with the interface keyword. There are currently 1898// supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & 1899// COND_INTER. REG_INTER causes an operand to generate a function 1900// which returns its register number when queried. CONST_INTER causes 1901// an operand to generate a function which returns the value of the 1902// constant when queried. MEMORY_INTER causes an operand to generate 1903// four functions which return the Base Register, the Index Register, 1904// the Scale Value, and the Offset Value of the operand when queried. 1905// COND_INTER causes an operand to generate six functions which return 1906// the encoding code (ie - encoding bits for the instruction) 1907// associated with each basic boolean condition for a conditional 1908// instruction. 1909// 1910// Instructions specify two basic values for encoding. Again, a 1911// function is available to check if the constant displacement is an 1912// oop. They use the ins_encode keyword to specify their encoding 1913// classes (which must be a sequence of enc_class names, and their 1914// parameters, specified in the encoding block), and they use the 1915// opcode keyword to specify, in order, their primary, secondary, and 1916// tertiary opcode. Only the opcode sections which a particular 1917// instruction needs for encoding need to be specified. 1918encode %{ 1919 // Build emit functions for each basic byte or larger field in the 1920 // intel encoding scheme (opcode, rm, sib, immediate), and call them 1921 // from C++ code in the enc_class source block. Emit functions will 1922 // live in the main source block for now. In future, we can 1923 // generalize this by adding a syntax that specifies the sizes of 1924 // fields in an order, so that the adlc can build the emit functions 1925 // automagically 1926 1927 // Emit primary opcode 1928 enc_class OpcP 1929 %{ 1930 emit_opcode(cbuf, $primary); 1931 %} 1932 1933 // Emit secondary opcode 1934 enc_class OpcS 1935 %{ 1936 emit_opcode(cbuf, $secondary); 1937 %} 1938 1939 // Emit tertiary opcode 1940 enc_class OpcT 1941 %{ 1942 emit_opcode(cbuf, $tertiary); 1943 %} 1944 1945 // Emit opcode directly 1946 enc_class Opcode(immI d8) 1947 %{ 1948 emit_opcode(cbuf, $d8$$constant); 1949 %} 1950 1951 // Emit size prefix 1952 enc_class SizePrefix 1953 %{ 1954 emit_opcode(cbuf, 0x66); 1955 %} 1956 1957 enc_class reg(rRegI reg) 1958 %{ 1959 emit_rm(cbuf, 0x3, 0, $reg$$reg & 7); 1960 %} 1961 1962 enc_class reg_reg(rRegI dst, rRegI src) 1963 %{ 1964 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); 1965 %} 1966 1967 enc_class opc_reg_reg(immI opcode, rRegI dst, rRegI src) 1968 %{ 1969 emit_opcode(cbuf, $opcode$$constant); 1970 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); 1971 %} 1972 1973 enc_class cdql_enc(no_rax_rdx_RegI div) 1974 %{ 1975 // Full implementation of Java idiv and irem; checks for 1976 // special case as described in JVM spec., p.243 & p.271. 1977 // 1978 // normal case special case 1979 // 1980 // input : rax: dividend min_int 1981 // reg: divisor -1 1982 // 1983 // output: rax: quotient (= rax idiv reg) min_int 1984 // rdx: remainder (= rax irem reg) 0 1985 // 1986 // Code sequnce: 1987 // 1988 // 0: 3d 00 00 00 80 cmp $0x80000000,%eax 1989 // 5: 75 07/08 jne e <normal> 1990 // 7: 33 d2 xor %edx,%edx 1991 // [div >= 8 -> offset + 1] 1992 // [REX_B] 1993 // 9: 83 f9 ff cmp $0xffffffffffffffff,$div 1994 // c: 74 03/04 je 11 <done> 1995 // 000000000000000e <normal>: 1996 // e: 99 cltd 1997 // [div >= 8 -> offset + 1] 1998 // [REX_B] 1999 // f: f7 f9 idiv $div 2000 // 0000000000000011 <done>: 2001 2002 // cmp $0x80000000,%eax 2003 emit_opcode(cbuf, 0x3d); 2004 emit_d8(cbuf, 0x00); 2005 emit_d8(cbuf, 0x00); 2006 emit_d8(cbuf, 0x00); 2007 emit_d8(cbuf, 0x80); 2008 2009 // jne e <normal> 2010 emit_opcode(cbuf, 0x75); 2011 emit_d8(cbuf, $div$$reg < 8 ? 0x07 : 0x08); 2012 2013 // xor %edx,%edx 2014 emit_opcode(cbuf, 0x33); 2015 emit_d8(cbuf, 0xD2); 2016 2017 // cmp $0xffffffffffffffff,%ecx 2018 if ($div$$reg >= 8) { 2019 emit_opcode(cbuf, Assembler::REX_B); 2020 } 2021 emit_opcode(cbuf, 0x83); 2022 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7); 2023 emit_d8(cbuf, 0xFF); 2024 2025 // je 11 <done> 2026 emit_opcode(cbuf, 0x74); 2027 emit_d8(cbuf, $div$$reg < 8 ? 0x03 : 0x04); 2028 2029 // <normal> 2030 // cltd 2031 emit_opcode(cbuf, 0x99); 2032 2033 // idivl (note: must be emitted by the user of this rule) 2034 // <done> 2035 %} 2036 2037 enc_class cdqq_enc(no_rax_rdx_RegL div) 2038 %{ 2039 // Full implementation of Java ldiv and lrem; checks for 2040 // special case as described in JVM spec., p.243 & p.271. 2041 // 2042 // normal case special case 2043 // 2044 // input : rax: dividend min_long 2045 // reg: divisor -1 2046 // 2047 // output: rax: quotient (= rax idiv reg) min_long 2048 // rdx: remainder (= rax irem reg) 0 2049 // 2050 // Code sequnce: 2051 // 2052 // 0: 48 ba 00 00 00 00 00 mov $0x8000000000000000,%rdx 2053 // 7: 00 00 80 2054 // a: 48 39 d0 cmp %rdx,%rax 2055 // d: 75 08 jne 17 <normal> 2056 // f: 33 d2 xor %edx,%edx 2057 // 11: 48 83 f9 ff cmp $0xffffffffffffffff,$div 2058 // 15: 74 05 je 1c <done> 2059 // 0000000000000017 <normal>: 2060 // 17: 48 99 cqto 2061 // 19: 48 f7 f9 idiv $div 2062 // 000000000000001c <done>: 2063 2064 // mov $0x8000000000000000,%rdx 2065 emit_opcode(cbuf, Assembler::REX_W); 2066 emit_opcode(cbuf, 0xBA); 2067 emit_d8(cbuf, 0x00); 2068 emit_d8(cbuf, 0x00); 2069 emit_d8(cbuf, 0x00); 2070 emit_d8(cbuf, 0x00); 2071 emit_d8(cbuf, 0x00); 2072 emit_d8(cbuf, 0x00); 2073 emit_d8(cbuf, 0x00); 2074 emit_d8(cbuf, 0x80); 2075 2076 // cmp %rdx,%rax 2077 emit_opcode(cbuf, Assembler::REX_W); 2078 emit_opcode(cbuf, 0x39); 2079 emit_d8(cbuf, 0xD0); 2080 2081 // jne 17 <normal> 2082 emit_opcode(cbuf, 0x75); 2083 emit_d8(cbuf, 0x08); 2084 2085 // xor %edx,%edx 2086 emit_opcode(cbuf, 0x33); 2087 emit_d8(cbuf, 0xD2); 2088 2089 // cmp $0xffffffffffffffff,$div 2090 emit_opcode(cbuf, $div$$reg < 8 ? Assembler::REX_W : Assembler::REX_WB); 2091 emit_opcode(cbuf, 0x83); 2092 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7); 2093 emit_d8(cbuf, 0xFF); 2094 2095 // je 1e <done> 2096 emit_opcode(cbuf, 0x74); 2097 emit_d8(cbuf, 0x05); 2098 2099 // <normal> 2100 // cqto 2101 emit_opcode(cbuf, Assembler::REX_W); 2102 emit_opcode(cbuf, 0x99); 2103 2104 // idivq (note: must be emitted by the user of this rule) 2105 // <done> 2106 %} 2107 2108 // Opcde enc_class for 8/32 bit immediate instructions with sign-extension 2109 enc_class OpcSE(immI imm) 2110 %{ 2111 // Emit primary opcode and set sign-extend bit 2112 // Check for 8-bit immediate, and set sign extend bit in opcode 2113 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2114 emit_opcode(cbuf, $primary | 0x02); 2115 } else { 2116 // 32-bit immediate 2117 emit_opcode(cbuf, $primary); 2118 } 2119 %} 2120 2121 enc_class OpcSErm(rRegI dst, immI imm) 2122 %{ 2123 // OpcSEr/m 2124 int dstenc = $dst$$reg; 2125 if (dstenc >= 8) { 2126 emit_opcode(cbuf, Assembler::REX_B); 2127 dstenc -= 8; 2128 } 2129 // Emit primary opcode and set sign-extend bit 2130 // Check for 8-bit immediate, and set sign extend bit in opcode 2131 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2132 emit_opcode(cbuf, $primary | 0x02); 2133 } else { 2134 // 32-bit immediate 2135 emit_opcode(cbuf, $primary); 2136 } 2137 // Emit r/m byte with secondary opcode, after primary opcode. 2138 emit_rm(cbuf, 0x3, $secondary, dstenc); 2139 %} 2140 2141 enc_class OpcSErm_wide(rRegL dst, immI imm) 2142 %{ 2143 // OpcSEr/m 2144 int dstenc = $dst$$reg; 2145 if (dstenc < 8) { 2146 emit_opcode(cbuf, Assembler::REX_W); 2147 } else { 2148 emit_opcode(cbuf, Assembler::REX_WB); 2149 dstenc -= 8; 2150 } 2151 // Emit primary opcode and set sign-extend bit 2152 // Check for 8-bit immediate, and set sign extend bit in opcode 2153 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2154 emit_opcode(cbuf, $primary | 0x02); 2155 } else { 2156 // 32-bit immediate 2157 emit_opcode(cbuf, $primary); 2158 } 2159 // Emit r/m byte with secondary opcode, after primary opcode. 2160 emit_rm(cbuf, 0x3, $secondary, dstenc); 2161 %} 2162 2163 enc_class Con8or32(immI imm) 2164 %{ 2165 // Check for 8-bit immediate, and set sign extend bit in opcode 2166 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2167 $$$emit8$imm$$constant; 2168 } else { 2169 // 32-bit immediate 2170 $$$emit32$imm$$constant; 2171 } 2172 %} 2173 2174 enc_class opc2_reg(rRegI dst) 2175 %{ 2176 // BSWAP 2177 emit_cc(cbuf, $secondary, $dst$$reg); 2178 %} 2179 2180 enc_class opc3_reg(rRegI dst) 2181 %{ 2182 // BSWAP 2183 emit_cc(cbuf, $tertiary, $dst$$reg); 2184 %} 2185 2186 enc_class reg_opc(rRegI div) 2187 %{ 2188 // INC, DEC, IDIV, IMOD, JMP indirect, ... 2189 emit_rm(cbuf, 0x3, $secondary, $div$$reg & 7); 2190 %} 2191 2192 enc_class enc_cmov(cmpOp cop) 2193 %{ 2194 // CMOV 2195 $$$emit8$primary; 2196 emit_cc(cbuf, $secondary, $cop$$cmpcode); 2197 %} 2198 2199 enc_class enc_PartialSubtypeCheck() 2200 %{ 2201 Register Rrdi = as_Register(RDI_enc); // result register 2202 Register Rrax = as_Register(RAX_enc); // super class 2203 Register Rrcx = as_Register(RCX_enc); // killed 2204 Register Rrsi = as_Register(RSI_enc); // sub class 2205 Label miss; 2206 const bool set_cond_codes = true; 2207 2208 MacroAssembler _masm(&cbuf); 2209 __ check_klass_subtype_slow_path(Rrsi, Rrax, Rrcx, Rrdi, 2210 NULL, &miss, 2211 /*set_cond_codes:*/ true); 2212 if ($primary) { 2213 __ xorptr(Rrdi, Rrdi); 2214 } 2215 __ bind(miss); 2216 %} 2217 2218 enc_class Java_To_Interpreter(method meth) 2219 %{ 2220 // CALL Java_To_Interpreter 2221 // This is the instruction starting address for relocation info. 2222 cbuf.set_insts_mark(); 2223 $$$emit8$primary; 2224 // CALL directly to the runtime 2225 emit_d32_reloc(cbuf, 2226 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2227 runtime_call_Relocation::spec(), 2228 RELOC_DISP32); 2229 %} 2230 2231 enc_class Java_Static_Call(method meth) 2232 %{ 2233 // JAVA STATIC CALL 2234 // CALL to fixup routine. Fixup routine uses ScopeDesc info to 2235 // determine who we intended to call. 2236 cbuf.set_insts_mark(); 2237 $$$emit8$primary; 2238 2239 if (!_method) { 2240 emit_d32_reloc(cbuf, 2241 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2242 runtime_call_Relocation::spec(), 2243 RELOC_DISP32); 2244 } else if (_optimized_virtual) { 2245 emit_d32_reloc(cbuf, 2246 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2247 opt_virtual_call_Relocation::spec(), 2248 RELOC_DISP32); 2249 } else { 2250 emit_d32_reloc(cbuf, 2251 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2252 static_call_Relocation::spec(), 2253 RELOC_DISP32); 2254 } 2255 if (_method) { 2256 // Emit stub for static call 2257 emit_java_to_interp(cbuf); 2258 } 2259 %} 2260 2261 enc_class Java_Dynamic_Call(method meth) 2262 %{ 2263 // JAVA DYNAMIC CALL 2264 // !!!!! 2265 // Generate "movq rax, -1", placeholder instruction to load oop-info 2266 // emit_call_dynamic_prologue( cbuf ); 2267 cbuf.set_insts_mark(); 2268 2269 // movq rax, -1 2270 emit_opcode(cbuf, Assembler::REX_W); 2271 emit_opcode(cbuf, 0xB8 | RAX_enc); 2272 emit_d64_reloc(cbuf, 2273 (int64_t) Universe::non_oop_word(), 2274 oop_Relocation::spec_for_immediate(), RELOC_IMM64); 2275 address virtual_call_oop_addr = cbuf.insts_mark(); 2276 // CALL to fixup routine. Fixup routine uses ScopeDesc info to determine 2277 // who we intended to call. 2278 cbuf.set_insts_mark(); 2279 $$$emit8$primary; 2280 emit_d32_reloc(cbuf, 2281 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2282 virtual_call_Relocation::spec(virtual_call_oop_addr), 2283 RELOC_DISP32); 2284 %} 2285 2286 enc_class Java_Compiled_Call(method meth) 2287 %{ 2288 // JAVA COMPILED CALL 2289 int disp = in_bytes(methodOopDesc:: from_compiled_offset()); 2290 2291 // XXX XXX offset is 128 is 1.5 NON-PRODUCT !!! 2292 // assert(-0x80 <= disp && disp < 0x80, "compiled_code_offset isn't small"); 2293 2294 // callq *disp(%rax) 2295 cbuf.set_insts_mark(); 2296 $$$emit8$primary; 2297 if (disp < 0x80) { 2298 emit_rm(cbuf, 0x01, $secondary, RAX_enc); // R/M byte 2299 emit_d8(cbuf, disp); // Displacement 2300 } else { 2301 emit_rm(cbuf, 0x02, $secondary, RAX_enc); // R/M byte 2302 emit_d32(cbuf, disp); // Displacement 2303 } 2304 %} 2305 2306 enc_class reg_opc_imm(rRegI dst, immI8 shift) 2307 %{ 2308 // SAL, SAR, SHR 2309 int dstenc = $dst$$reg; 2310 if (dstenc >= 8) { 2311 emit_opcode(cbuf, Assembler::REX_B); 2312 dstenc -= 8; 2313 } 2314 $$$emit8$primary; 2315 emit_rm(cbuf, 0x3, $secondary, dstenc); 2316 $$$emit8$shift$$constant; 2317 %} 2318 2319 enc_class reg_opc_imm_wide(rRegL dst, immI8 shift) 2320 %{ 2321 // SAL, SAR, SHR 2322 int dstenc = $dst$$reg; 2323 if (dstenc < 8) { 2324 emit_opcode(cbuf, Assembler::REX_W); 2325 } else { 2326 emit_opcode(cbuf, Assembler::REX_WB); 2327 dstenc -= 8; 2328 } 2329 $$$emit8$primary; 2330 emit_rm(cbuf, 0x3, $secondary, dstenc); 2331 $$$emit8$shift$$constant; 2332 %} 2333 2334 enc_class load_immI(rRegI dst, immI src) 2335 %{ 2336 int dstenc = $dst$$reg; 2337 if (dstenc >= 8) { 2338 emit_opcode(cbuf, Assembler::REX_B); 2339 dstenc -= 8; 2340 } 2341 emit_opcode(cbuf, 0xB8 | dstenc); 2342 $$$emit32$src$$constant; 2343 %} 2344 2345 enc_class load_immL(rRegL dst, immL src) 2346 %{ 2347 int dstenc = $dst$$reg; 2348 if (dstenc < 8) { 2349 emit_opcode(cbuf, Assembler::REX_W); 2350 } else { 2351 emit_opcode(cbuf, Assembler::REX_WB); 2352 dstenc -= 8; 2353 } 2354 emit_opcode(cbuf, 0xB8 | dstenc); 2355 emit_d64(cbuf, $src$$constant); 2356 %} 2357 2358 enc_class load_immUL32(rRegL dst, immUL32 src) 2359 %{ 2360 // same as load_immI, but this time we care about zeroes in the high word 2361 int dstenc = $dst$$reg; 2362 if (dstenc >= 8) { 2363 emit_opcode(cbuf, Assembler::REX_B); 2364 dstenc -= 8; 2365 } 2366 emit_opcode(cbuf, 0xB8 | dstenc); 2367 $$$emit32$src$$constant; 2368 %} 2369 2370 enc_class load_immL32(rRegL dst, immL32 src) 2371 %{ 2372 int dstenc = $dst$$reg; 2373 if (dstenc < 8) { 2374 emit_opcode(cbuf, Assembler::REX_W); 2375 } else { 2376 emit_opcode(cbuf, Assembler::REX_WB); 2377 dstenc -= 8; 2378 } 2379 emit_opcode(cbuf, 0xC7); 2380 emit_rm(cbuf, 0x03, 0x00, dstenc); 2381 $$$emit32$src$$constant; 2382 %} 2383 2384 enc_class load_immP31(rRegP dst, immP32 src) 2385 %{ 2386 // same as load_immI, but this time we care about zeroes in the high word 2387 int dstenc = $dst$$reg; 2388 if (dstenc >= 8) { 2389 emit_opcode(cbuf, Assembler::REX_B); 2390 dstenc -= 8; 2391 } 2392 emit_opcode(cbuf, 0xB8 | dstenc); 2393 $$$emit32$src$$constant; 2394 %} 2395 2396 enc_class load_immP(rRegP dst, immP src) 2397 %{ 2398 int dstenc = $dst$$reg; 2399 if (dstenc < 8) { 2400 emit_opcode(cbuf, Assembler::REX_W); 2401 } else { 2402 emit_opcode(cbuf, Assembler::REX_WB); 2403 dstenc -= 8; 2404 } 2405 emit_opcode(cbuf, 0xB8 | dstenc); 2406 // This next line should be generated from ADLC 2407 if ($src->constant_is_oop()) { 2408 emit_d64_reloc(cbuf, $src$$constant, relocInfo::oop_type, RELOC_IMM64); 2409 } else { 2410 emit_d64(cbuf, $src$$constant); 2411 } 2412 %} 2413 2414 enc_class Con32(immI src) 2415 %{ 2416 // Output immediate 2417 $$$emit32$src$$constant; 2418 %} 2419 2420 enc_class Con64(immL src) 2421 %{ 2422 // Output immediate 2423 emit_d64($src$$constant); 2424 %} 2425 2426 enc_class Con32F_as_bits(immF src) 2427 %{ 2428 // Output Float immediate bits 2429 jfloat jf = $src$$constant; 2430 jint jf_as_bits = jint_cast(jf); 2431 emit_d32(cbuf, jf_as_bits); 2432 %} 2433 2434 enc_class Con16(immI src) 2435 %{ 2436 // Output immediate 2437 $$$emit16$src$$constant; 2438 %} 2439 2440 // How is this different from Con32??? XXX 2441 enc_class Con_d32(immI src) 2442 %{ 2443 emit_d32(cbuf,$src$$constant); 2444 %} 2445 2446 enc_class conmemref (rRegP t1) %{ // Con32(storeImmI) 2447 // Output immediate memory reference 2448 emit_rm(cbuf, 0x00, $t1$$reg, 0x05 ); 2449 emit_d32(cbuf, 0x00); 2450 %} 2451 2452 enc_class lock_prefix() 2453 %{ 2454 if (os::is_MP()) { 2455 emit_opcode(cbuf, 0xF0); // lock 2456 } 2457 %} 2458 2459 enc_class REX_mem(memory mem) 2460 %{ 2461 if ($mem$$base >= 8) { 2462 if ($mem$$index < 8) { 2463 emit_opcode(cbuf, Assembler::REX_B); 2464 } else { 2465 emit_opcode(cbuf, Assembler::REX_XB); 2466 } 2467 } else { 2468 if ($mem$$index >= 8) { 2469 emit_opcode(cbuf, Assembler::REX_X); 2470 } 2471 } 2472 %} 2473 2474 enc_class REX_mem_wide(memory mem) 2475 %{ 2476 if ($mem$$base >= 8) { 2477 if ($mem$$index < 8) { 2478 emit_opcode(cbuf, Assembler::REX_WB); 2479 } else { 2480 emit_opcode(cbuf, Assembler::REX_WXB); 2481 } 2482 } else { 2483 if ($mem$$index < 8) { 2484 emit_opcode(cbuf, Assembler::REX_W); 2485 } else { 2486 emit_opcode(cbuf, Assembler::REX_WX); 2487 } 2488 } 2489 %} 2490 2491 // for byte regs 2492 enc_class REX_breg(rRegI reg) 2493 %{ 2494 if ($reg$$reg >= 4) { 2495 emit_opcode(cbuf, $reg$$reg < 8 ? Assembler::REX : Assembler::REX_B); 2496 } 2497 %} 2498 2499 // for byte regs 2500 enc_class REX_reg_breg(rRegI dst, rRegI src) 2501 %{ 2502 if ($dst$$reg < 8) { 2503 if ($src$$reg >= 4) { 2504 emit_opcode(cbuf, $src$$reg < 8 ? Assembler::REX : Assembler::REX_B); 2505 } 2506 } else { 2507 if ($src$$reg < 8) { 2508 emit_opcode(cbuf, Assembler::REX_R); 2509 } else { 2510 emit_opcode(cbuf, Assembler::REX_RB); 2511 } 2512 } 2513 %} 2514 2515 // for byte regs 2516 enc_class REX_breg_mem(rRegI reg, memory mem) 2517 %{ 2518 if ($reg$$reg < 8) { 2519 if ($mem$$base < 8) { 2520 if ($mem$$index >= 8) { 2521 emit_opcode(cbuf, Assembler::REX_X); 2522 } else if ($reg$$reg >= 4) { 2523 emit_opcode(cbuf, Assembler::REX); 2524 } 2525 } else { 2526 if ($mem$$index < 8) { 2527 emit_opcode(cbuf, Assembler::REX_B); 2528 } else { 2529 emit_opcode(cbuf, Assembler::REX_XB); 2530 } 2531 } 2532 } else { 2533 if ($mem$$base < 8) { 2534 if ($mem$$index < 8) { 2535 emit_opcode(cbuf, Assembler::REX_R); 2536 } else { 2537 emit_opcode(cbuf, Assembler::REX_RX); 2538 } 2539 } else { 2540 if ($mem$$index < 8) { 2541 emit_opcode(cbuf, Assembler::REX_RB); 2542 } else { 2543 emit_opcode(cbuf, Assembler::REX_RXB); 2544 } 2545 } 2546 } 2547 %} 2548 2549 enc_class REX_reg(rRegI reg) 2550 %{ 2551 if ($reg$$reg >= 8) { 2552 emit_opcode(cbuf, Assembler::REX_B); 2553 } 2554 %} 2555 2556 enc_class REX_reg_wide(rRegI reg) 2557 %{ 2558 if ($reg$$reg < 8) { 2559 emit_opcode(cbuf, Assembler::REX_W); 2560 } else { 2561 emit_opcode(cbuf, Assembler::REX_WB); 2562 } 2563 %} 2564 2565 enc_class REX_reg_reg(rRegI dst, rRegI src) 2566 %{ 2567 if ($dst$$reg < 8) { 2568 if ($src$$reg >= 8) { 2569 emit_opcode(cbuf, Assembler::REX_B); 2570 } 2571 } else { 2572 if ($src$$reg < 8) { 2573 emit_opcode(cbuf, Assembler::REX_R); 2574 } else { 2575 emit_opcode(cbuf, Assembler::REX_RB); 2576 } 2577 } 2578 %} 2579 2580 enc_class REX_reg_reg_wide(rRegI dst, rRegI src) 2581 %{ 2582 if ($dst$$reg < 8) { 2583 if ($src$$reg < 8) { 2584 emit_opcode(cbuf, Assembler::REX_W); 2585 } else { 2586 emit_opcode(cbuf, Assembler::REX_WB); 2587 } 2588 } else { 2589 if ($src$$reg < 8) { 2590 emit_opcode(cbuf, Assembler::REX_WR); 2591 } else { 2592 emit_opcode(cbuf, Assembler::REX_WRB); 2593 } 2594 } 2595 %} 2596 2597 enc_class REX_reg_mem(rRegI reg, memory mem) 2598 %{ 2599 if ($reg$$reg < 8) { 2600 if ($mem$$base < 8) { 2601 if ($mem$$index >= 8) { 2602 emit_opcode(cbuf, Assembler::REX_X); 2603 } 2604 } else { 2605 if ($mem$$index < 8) { 2606 emit_opcode(cbuf, Assembler::REX_B); 2607 } else { 2608 emit_opcode(cbuf, Assembler::REX_XB); 2609 } 2610 } 2611 } else { 2612 if ($mem$$base < 8) { 2613 if ($mem$$index < 8) { 2614 emit_opcode(cbuf, Assembler::REX_R); 2615 } else { 2616 emit_opcode(cbuf, Assembler::REX_RX); 2617 } 2618 } else { 2619 if ($mem$$index < 8) { 2620 emit_opcode(cbuf, Assembler::REX_RB); 2621 } else { 2622 emit_opcode(cbuf, Assembler::REX_RXB); 2623 } 2624 } 2625 } 2626 %} 2627 2628 enc_class REX_reg_mem_wide(rRegL reg, memory mem) 2629 %{ 2630 if ($reg$$reg < 8) { 2631 if ($mem$$base < 8) { 2632 if ($mem$$index < 8) { 2633 emit_opcode(cbuf, Assembler::REX_W); 2634 } else { 2635 emit_opcode(cbuf, Assembler::REX_WX); 2636 } 2637 } else { 2638 if ($mem$$index < 8) { 2639 emit_opcode(cbuf, Assembler::REX_WB); 2640 } else { 2641 emit_opcode(cbuf, Assembler::REX_WXB); 2642 } 2643 } 2644 } else { 2645 if ($mem$$base < 8) { 2646 if ($mem$$index < 8) { 2647 emit_opcode(cbuf, Assembler::REX_WR); 2648 } else { 2649 emit_opcode(cbuf, Assembler::REX_WRX); 2650 } 2651 } else { 2652 if ($mem$$index < 8) { 2653 emit_opcode(cbuf, Assembler::REX_WRB); 2654 } else { 2655 emit_opcode(cbuf, Assembler::REX_WRXB); 2656 } 2657 } 2658 } 2659 %} 2660 2661 enc_class reg_mem(rRegI ereg, memory mem) 2662 %{ 2663 // High registers handle in encode_RegMem 2664 int reg = $ereg$$reg; 2665 int base = $mem$$base; 2666 int index = $mem$$index; 2667 int scale = $mem$$scale; 2668 int disp = $mem$$disp; 2669 bool disp_is_oop = $mem->disp_is_oop(); 2670 2671 encode_RegMem(cbuf, reg, base, index, scale, disp, disp_is_oop); 2672 %} 2673 2674 enc_class RM_opc_mem(immI rm_opcode, memory mem) 2675 %{ 2676 int rm_byte_opcode = $rm_opcode$$constant; 2677 2678 // High registers handle in encode_RegMem 2679 int base = $mem$$base; 2680 int index = $mem$$index; 2681 int scale = $mem$$scale; 2682 int displace = $mem$$disp; 2683 2684 bool disp_is_oop = $mem->disp_is_oop(); // disp-as-oop when 2685 // working with static 2686 // globals 2687 encode_RegMem(cbuf, rm_byte_opcode, base, index, scale, displace, 2688 disp_is_oop); 2689 %} 2690 2691 enc_class reg_lea(rRegI dst, rRegI src0, immI src1) 2692 %{ 2693 int reg_encoding = $dst$$reg; 2694 int base = $src0$$reg; // 0xFFFFFFFF indicates no base 2695 int index = 0x04; // 0x04 indicates no index 2696 int scale = 0x00; // 0x00 indicates no scale 2697 int displace = $src1$$constant; // 0x00 indicates no displacement 2698 bool disp_is_oop = false; 2699 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, 2700 disp_is_oop); 2701 %} 2702 2703 enc_class neg_reg(rRegI dst) 2704 %{ 2705 int dstenc = $dst$$reg; 2706 if (dstenc >= 8) { 2707 emit_opcode(cbuf, Assembler::REX_B); 2708 dstenc -= 8; 2709 } 2710 // NEG $dst 2711 emit_opcode(cbuf, 0xF7); 2712 emit_rm(cbuf, 0x3, 0x03, dstenc); 2713 %} 2714 2715 enc_class neg_reg_wide(rRegI dst) 2716 %{ 2717 int dstenc = $dst$$reg; 2718 if (dstenc < 8) { 2719 emit_opcode(cbuf, Assembler::REX_W); 2720 } else { 2721 emit_opcode(cbuf, Assembler::REX_WB); 2722 dstenc -= 8; 2723 } 2724 // NEG $dst 2725 emit_opcode(cbuf, 0xF7); 2726 emit_rm(cbuf, 0x3, 0x03, dstenc); 2727 %} 2728 2729 enc_class setLT_reg(rRegI dst) 2730 %{ 2731 int dstenc = $dst$$reg; 2732 if (dstenc >= 8) { 2733 emit_opcode(cbuf, Assembler::REX_B); 2734 dstenc -= 8; 2735 } else if (dstenc >= 4) { 2736 emit_opcode(cbuf, Assembler::REX); 2737 } 2738 // SETLT $dst 2739 emit_opcode(cbuf, 0x0F); 2740 emit_opcode(cbuf, 0x9C); 2741 emit_rm(cbuf, 0x3, 0x0, dstenc); 2742 %} 2743 2744 enc_class setNZ_reg(rRegI dst) 2745 %{ 2746 int dstenc = $dst$$reg; 2747 if (dstenc >= 8) { 2748 emit_opcode(cbuf, Assembler::REX_B); 2749 dstenc -= 8; 2750 } else if (dstenc >= 4) { 2751 emit_opcode(cbuf, Assembler::REX); 2752 } 2753 // SETNZ $dst 2754 emit_opcode(cbuf, 0x0F); 2755 emit_opcode(cbuf, 0x95); 2756 emit_rm(cbuf, 0x3, 0x0, dstenc); 2757 %} 2758 2759 2760 // Compare the lonogs and set -1, 0, or 1 into dst 2761 enc_class cmpl3_flag(rRegL src1, rRegL src2, rRegI dst) 2762 %{ 2763 int src1enc = $src1$$reg; 2764 int src2enc = $src2$$reg; 2765 int dstenc = $dst$$reg; 2766 2767 // cmpq $src1, $src2 2768 if (src1enc < 8) { 2769 if (src2enc < 8) { 2770 emit_opcode(cbuf, Assembler::REX_W); 2771 } else { 2772 emit_opcode(cbuf, Assembler::REX_WB); 2773 } 2774 } else { 2775 if (src2enc < 8) { 2776 emit_opcode(cbuf, Assembler::REX_WR); 2777 } else { 2778 emit_opcode(cbuf, Assembler::REX_WRB); 2779 } 2780 } 2781 emit_opcode(cbuf, 0x3B); 2782 emit_rm(cbuf, 0x3, src1enc & 7, src2enc & 7); 2783 2784 // movl $dst, -1 2785 if (dstenc >= 8) { 2786 emit_opcode(cbuf, Assembler::REX_B); 2787 } 2788 emit_opcode(cbuf, 0xB8 | (dstenc & 7)); 2789 emit_d32(cbuf, -1); 2790 2791 // jl,s done 2792 emit_opcode(cbuf, 0x7C); 2793 emit_d8(cbuf, dstenc < 4 ? 0x06 : 0x08); 2794 2795 // setne $dst 2796 if (dstenc >= 4) { 2797 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_B); 2798 } 2799 emit_opcode(cbuf, 0x0F); 2800 emit_opcode(cbuf, 0x95); 2801 emit_opcode(cbuf, 0xC0 | (dstenc & 7)); 2802 2803 // movzbl $dst, $dst 2804 if (dstenc >= 4) { 2805 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_RB); 2806 } 2807 emit_opcode(cbuf, 0x0F); 2808 emit_opcode(cbuf, 0xB6); 2809 emit_rm(cbuf, 0x3, dstenc & 7, dstenc & 7); 2810 %} 2811 2812 enc_class Push_ResultXD(regD dst) %{ 2813 MacroAssembler _masm(&cbuf); 2814 __ fstp_d(Address(rsp, 0)); 2815 __ movdbl($dst$$XMMRegister, Address(rsp, 0)); 2816 __ addptr(rsp, 8); 2817 %} 2818 2819 enc_class Push_SrcXD(regD src) %{ 2820 MacroAssembler _masm(&cbuf); 2821 __ subptr(rsp, 8); 2822 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 2823 __ fld_d(Address(rsp, 0)); 2824 %} 2825 2826 2827 // obj: object to lock 2828 // box: box address (header location) -- killed 2829 // tmp: rax -- killed 2830 // scr: rbx -- killed 2831 // 2832 // What follows is a direct transliteration of fast_lock() and fast_unlock() 2833 // from i486.ad. See that file for comments. 2834 // TODO: where possible switch from movq (r, 0) to movl(r,0) and 2835 // use the shorter encoding. (Movl clears the high-order 32-bits). 2836 2837 2838 enc_class Fast_Lock(rRegP obj, rRegP box, rax_RegI tmp, rRegP scr) 2839 %{ 2840 Register objReg = as_Register((int)$obj$$reg); 2841 Register boxReg = as_Register((int)$box$$reg); 2842 Register tmpReg = as_Register($tmp$$reg); 2843 Register scrReg = as_Register($scr$$reg); 2844 MacroAssembler masm(&cbuf); 2845 2846 // Verify uniqueness of register assignments -- necessary but not sufficient 2847 assert (objReg != boxReg && objReg != tmpReg && 2848 objReg != scrReg && tmpReg != scrReg, "invariant") ; 2849 2850 if (_counters != NULL) { 2851 masm.atomic_incl(ExternalAddress((address) _counters->total_entry_count_addr())); 2852 } 2853 if (EmitSync & 1) { 2854 // Without cast to int32_t a movptr will destroy r10 which is typically obj 2855 masm.movptr (Address(boxReg, 0), (int32_t)intptr_t(markOopDesc::unused_mark())) ; 2856 masm.cmpptr(rsp, (int32_t)NULL_WORD) ; 2857 } else 2858 if (EmitSync & 2) { 2859 Label DONE_LABEL; 2860 if (UseBiasedLocking) { 2861 // Note: tmpReg maps to the swap_reg argument and scrReg to the tmp_reg argument. 2862 masm.biased_locking_enter(boxReg, objReg, tmpReg, scrReg, false, DONE_LABEL, NULL, _counters); 2863 } 2864 // QQQ was movl... 2865 masm.movptr(tmpReg, 0x1); 2866 masm.orptr(tmpReg, Address(objReg, 0)); 2867 masm.movptr(Address(boxReg, 0), tmpReg); 2868 if (os::is_MP()) { 2869 masm.lock(); 2870 } 2871 masm.cmpxchgptr(boxReg, Address(objReg, 0)); // Updates tmpReg 2872 masm.jcc(Assembler::equal, DONE_LABEL); 2873 2874 // Recursive locking 2875 masm.subptr(tmpReg, rsp); 2876 masm.andptr(tmpReg, 7 - os::vm_page_size()); 2877 masm.movptr(Address(boxReg, 0), tmpReg); 2878 2879 masm.bind(DONE_LABEL); 2880 masm.nop(); // avoid branch to branch 2881 } else { 2882 Label DONE_LABEL, IsInflated, Egress; 2883 2884 masm.movptr(tmpReg, Address(objReg, 0)) ; 2885 masm.testl (tmpReg, 0x02) ; // inflated vs stack-locked|neutral|biased 2886 masm.jcc (Assembler::notZero, IsInflated) ; 2887 2888 // it's stack-locked, biased or neutral 2889 // TODO: optimize markword triage order to reduce the number of 2890 // conditional branches in the most common cases. 2891 // Beware -- there's a subtle invariant that fetch of the markword 2892 // at [FETCH], below, will never observe a biased encoding (*101b). 2893 // If this invariant is not held we'll suffer exclusion (safety) failure. 2894 2895 if (UseBiasedLocking && !UseOptoBiasInlining) { 2896 masm.biased_locking_enter(boxReg, objReg, tmpReg, scrReg, true, DONE_LABEL, NULL, _counters); 2897 masm.movptr(tmpReg, Address(objReg, 0)) ; // [FETCH] 2898 } 2899 2900 // was q will it destroy high? 2901 masm.orl (tmpReg, 1) ; 2902 masm.movptr(Address(boxReg, 0), tmpReg) ; 2903 if (os::is_MP()) { masm.lock(); } 2904 masm.cmpxchgptr(boxReg, Address(objReg, 0)); // Updates tmpReg 2905 if (_counters != NULL) { 2906 masm.cond_inc32(Assembler::equal, 2907 ExternalAddress((address) _counters->fast_path_entry_count_addr())); 2908 } 2909 masm.jcc (Assembler::equal, DONE_LABEL); 2910 2911 // Recursive locking 2912 masm.subptr(tmpReg, rsp); 2913 masm.andptr(tmpReg, 7 - os::vm_page_size()); 2914 masm.movptr(Address(boxReg, 0), tmpReg); 2915 if (_counters != NULL) { 2916 masm.cond_inc32(Assembler::equal, 2917 ExternalAddress((address) _counters->fast_path_entry_count_addr())); 2918 } 2919 masm.jmp (DONE_LABEL) ; 2920 2921 masm.bind (IsInflated) ; 2922 // It's inflated 2923 2924 // TODO: someday avoid the ST-before-CAS penalty by 2925 // relocating (deferring) the following ST. 2926 // We should also think about trying a CAS without having 2927 // fetched _owner. If the CAS is successful we may 2928 // avoid an RTO->RTS upgrade on the $line. 2929 // Without cast to int32_t a movptr will destroy r10 which is typically obj 2930 masm.movptr(Address(boxReg, 0), (int32_t)intptr_t(markOopDesc::unused_mark())) ; 2931 2932 masm.mov (boxReg, tmpReg) ; 2933 masm.movptr (tmpReg, Address(tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; 2934 masm.testptr(tmpReg, tmpReg) ; 2935 masm.jcc (Assembler::notZero, DONE_LABEL) ; 2936 2937 // It's inflated and appears unlocked 2938 if (os::is_MP()) { masm.lock(); } 2939 masm.cmpxchgptr(r15_thread, Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; 2940 // Intentional fall-through into DONE_LABEL ... 2941 2942 masm.bind (DONE_LABEL) ; 2943 masm.nop () ; // avoid jmp to jmp 2944 } 2945 %} 2946 2947 // obj: object to unlock 2948 // box: box address (displaced header location), killed 2949 // RBX: killed tmp; cannot be obj nor box 2950 enc_class Fast_Unlock(rRegP obj, rax_RegP box, rRegP tmp) 2951 %{ 2952 2953 Register objReg = as_Register($obj$$reg); 2954 Register boxReg = as_Register($box$$reg); 2955 Register tmpReg = as_Register($tmp$$reg); 2956 MacroAssembler masm(&cbuf); 2957 2958 if (EmitSync & 4) { 2959 masm.cmpptr(rsp, 0) ; 2960 } else 2961 if (EmitSync & 8) { 2962 Label DONE_LABEL; 2963 if (UseBiasedLocking) { 2964 masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL); 2965 } 2966 2967 // Check whether the displaced header is 0 2968 //(=> recursive unlock) 2969 masm.movptr(tmpReg, Address(boxReg, 0)); 2970 masm.testptr(tmpReg, tmpReg); 2971 masm.jcc(Assembler::zero, DONE_LABEL); 2972 2973 // If not recursive lock, reset the header to displaced header 2974 if (os::is_MP()) { 2975 masm.lock(); 2976 } 2977 masm.cmpxchgptr(tmpReg, Address(objReg, 0)); // Uses RAX which is box 2978 masm.bind(DONE_LABEL); 2979 masm.nop(); // avoid branch to branch 2980 } else { 2981 Label DONE_LABEL, Stacked, CheckSucc ; 2982 2983 if (UseBiasedLocking && !UseOptoBiasInlining) { 2984 masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL); 2985 } 2986 2987 masm.movptr(tmpReg, Address(objReg, 0)) ; 2988 masm.cmpptr(Address(boxReg, 0), (int32_t)NULL_WORD) ; 2989 masm.jcc (Assembler::zero, DONE_LABEL) ; 2990 masm.testl (tmpReg, 0x02) ; 2991 masm.jcc (Assembler::zero, Stacked) ; 2992 2993 // It's inflated 2994 masm.movptr(boxReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; 2995 masm.xorptr(boxReg, r15_thread) ; 2996 masm.orptr (boxReg, Address (tmpReg, ObjectMonitor::recursions_offset_in_bytes()-2)) ; 2997 masm.jcc (Assembler::notZero, DONE_LABEL) ; 2998 masm.movptr(boxReg, Address (tmpReg, ObjectMonitor::cxq_offset_in_bytes()-2)) ; 2999 masm.orptr (boxReg, Address (tmpReg, ObjectMonitor::EntryList_offset_in_bytes()-2)) ; 3000 masm.jcc (Assembler::notZero, CheckSucc) ; 3001 masm.movptr(Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), (int32_t)NULL_WORD) ; 3002 masm.jmp (DONE_LABEL) ; 3003 3004 if ((EmitSync & 65536) == 0) { 3005 Label LSuccess, LGoSlowPath ; 3006 masm.bind (CheckSucc) ; 3007 masm.cmpptr(Address (tmpReg, ObjectMonitor::succ_offset_in_bytes()-2), (int32_t)NULL_WORD) ; 3008 masm.jcc (Assembler::zero, LGoSlowPath) ; 3009 3010 // I'd much rather use lock:andl m->_owner, 0 as it's faster than the 3011 // the explicit ST;MEMBAR combination, but masm doesn't currently support 3012 // "ANDQ M,IMM". Don't use MFENCE here. lock:add to TOS, xchg, etc 3013 // are all faster when the write buffer is populated. 3014 masm.movptr (Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), (int32_t)NULL_WORD) ; 3015 if (os::is_MP()) { 3016 masm.lock () ; masm.addl (Address(rsp, 0), 0) ; 3017 } 3018 masm.cmpptr(Address (tmpReg, ObjectMonitor::succ_offset_in_bytes()-2), (int32_t)NULL_WORD) ; 3019 masm.jcc (Assembler::notZero, LSuccess) ; 3020 3021 masm.movptr (boxReg, (int32_t)NULL_WORD) ; // box is really EAX 3022 if (os::is_MP()) { masm.lock(); } 3023 masm.cmpxchgptr(r15_thread, Address(tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)); 3024 masm.jcc (Assembler::notEqual, LSuccess) ; 3025 // Intentional fall-through into slow-path 3026 3027 masm.bind (LGoSlowPath) ; 3028 masm.orl (boxReg, 1) ; // set ICC.ZF=0 to indicate failure 3029 masm.jmp (DONE_LABEL) ; 3030 3031 masm.bind (LSuccess) ; 3032 masm.testl (boxReg, 0) ; // set ICC.ZF=1 to indicate success 3033 masm.jmp (DONE_LABEL) ; 3034 } 3035 3036 masm.bind (Stacked) ; 3037 masm.movptr(tmpReg, Address (boxReg, 0)) ; // re-fetch 3038 if (os::is_MP()) { masm.lock(); } 3039 masm.cmpxchgptr(tmpReg, Address(objReg, 0)); // Uses RAX which is box 3040 3041 if (EmitSync & 65536) { 3042 masm.bind (CheckSucc) ; 3043 } 3044 masm.bind(DONE_LABEL); 3045 if (EmitSync & 32768) { 3046 masm.nop(); // avoid branch to branch 3047 } 3048 } 3049 %} 3050 3051 3052 enc_class enc_rethrow() 3053 %{ 3054 cbuf.set_insts_mark(); 3055 emit_opcode(cbuf, 0xE9); // jmp entry 3056 emit_d32_reloc(cbuf, 3057 (int) (OptoRuntime::rethrow_stub() - cbuf.insts_end() - 4), 3058 runtime_call_Relocation::spec(), 3059 RELOC_DISP32); 3060 %} 3061 3062%} 3063 3064 3065 3066//----------FRAME-------------------------------------------------------------- 3067// Definition of frame structure and management information. 3068// 3069// S T A C K L A Y O U T Allocators stack-slot number 3070// | (to get allocators register number 3071// G Owned by | | v add OptoReg::stack0()) 3072// r CALLER | | 3073// o | +--------+ pad to even-align allocators stack-slot 3074// w V | pad0 | numbers; owned by CALLER 3075// t -----------+--------+----> Matcher::_in_arg_limit, unaligned 3076// h ^ | in | 5 3077// | | args | 4 Holes in incoming args owned by SELF 3078// | | | | 3 3079// | | +--------+ 3080// V | | old out| Empty on Intel, window on Sparc 3081// | old |preserve| Must be even aligned. 3082// | SP-+--------+----> Matcher::_old_SP, even aligned 3083// | | in | 3 area for Intel ret address 3084// Owned by |preserve| Empty on Sparc. 3085// SELF +--------+ 3086// | | pad2 | 2 pad to align old SP 3087// | +--------+ 1 3088// | | locks | 0 3089// | +--------+----> OptoReg::stack0(), even aligned 3090// | | pad1 | 11 pad to align new SP 3091// | +--------+ 3092// | | | 10 3093// | | spills | 9 spills 3094// V | | 8 (pad0 slot for callee) 3095// -----------+--------+----> Matcher::_out_arg_limit, unaligned 3096// ^ | out | 7 3097// | | args | 6 Holes in outgoing args owned by CALLEE 3098// Owned by +--------+ 3099// CALLEE | new out| 6 Empty on Intel, window on Sparc 3100// | new |preserve| Must be even-aligned. 3101// | SP-+--------+----> Matcher::_new_SP, even aligned 3102// | | | 3103// 3104// Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 3105// known from SELF's arguments and the Java calling convention. 3106// Region 6-7 is determined per call site. 3107// Note 2: If the calling convention leaves holes in the incoming argument 3108// area, those holes are owned by SELF. Holes in the outgoing area 3109// are owned by the CALLEE. Holes should not be nessecary in the 3110// incoming area, as the Java calling convention is completely under 3111// the control of the AD file. Doubles can be sorted and packed to 3112// avoid holes. Holes in the outgoing arguments may be nessecary for 3113// varargs C calling conventions. 3114// Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 3115// even aligned with pad0 as needed. 3116// Region 6 is even aligned. Region 6-7 is NOT even aligned; 3117// region 6-11 is even aligned; it may be padded out more so that 3118// the region from SP to FP meets the minimum stack alignment. 3119// Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 3120// alignment. Region 11, pad1, may be dynamically extended so that 3121// SP meets the minimum alignment. 3122 3123frame 3124%{ 3125 // What direction does stack grow in (assumed to be same for C & Java) 3126 stack_direction(TOWARDS_LOW); 3127 3128 // These three registers define part of the calling convention 3129 // between compiled code and the interpreter. 3130 inline_cache_reg(RAX); // Inline Cache Register 3131 interpreter_method_oop_reg(RBX); // Method Oop Register when 3132 // calling interpreter 3133 3134 // Optional: name the operand used by cisc-spilling to access 3135 // [stack_pointer + offset] 3136 cisc_spilling_operand_name(indOffset32); 3137 3138 // Number of stack slots consumed by locking an object 3139 sync_stack_slots(2); 3140 3141 // Compiled code's Frame Pointer 3142 frame_pointer(RSP); 3143 3144 // Interpreter stores its frame pointer in a register which is 3145 // stored to the stack by I2CAdaptors. 3146 // I2CAdaptors convert from interpreted java to compiled java. 3147 interpreter_frame_pointer(RBP); 3148 3149 // Stack alignment requirement 3150 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 3151 3152 // Number of stack slots between incoming argument block and the start of 3153 // a new frame. The PROLOG must add this many slots to the stack. The 3154 // EPILOG must remove this many slots. amd64 needs two slots for 3155 // return address. 3156 in_preserve_stack_slots(4 + 2 * VerifyStackAtCalls); 3157 3158 // Number of outgoing stack slots killed above the out_preserve_stack_slots 3159 // for calls to C. Supports the var-args backing area for register parms. 3160 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 3161 3162 // The after-PROLOG location of the return address. Location of 3163 // return address specifies a type (REG or STACK) and a number 3164 // representing the register number (i.e. - use a register name) or 3165 // stack slot. 3166 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 3167 // Otherwise, it is above the locks and verification slot and alignment word 3168 return_addr(STACK - 2 + 3169 round_to((Compile::current()->in_preserve_stack_slots() + 3170 Compile::current()->fixed_slots()), 3171 stack_alignment_in_slots())); 3172 3173 // Body of function which returns an integer array locating 3174 // arguments either in registers or in stack slots. Passed an array 3175 // of ideal registers called "sig" and a "length" count. Stack-slot 3176 // offsets are based on outgoing arguments, i.e. a CALLER setting up 3177 // arguments for a CALLEE. Incoming stack arguments are 3178 // automatically biased by the preserve_stack_slots field above. 3179 3180 calling_convention 3181 %{ 3182 // No difference between ingoing/outgoing just pass false 3183 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 3184 %} 3185 3186 c_calling_convention 3187 %{ 3188 // This is obviously always outgoing 3189 (void) SharedRuntime::c_calling_convention(sig_bt, regs, length); 3190 %} 3191 3192 // Location of compiled Java return values. Same as C for now. 3193 return_value 3194 %{ 3195 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 3196 "only return normal values"); 3197 3198 static const int lo[Op_RegL + 1] = { 3199 0, 3200 0, 3201 RAX_num, // Op_RegN 3202 RAX_num, // Op_RegI 3203 RAX_num, // Op_RegP 3204 XMM0_num, // Op_RegF 3205 XMM0_num, // Op_RegD 3206 RAX_num // Op_RegL 3207 }; 3208 static const int hi[Op_RegL + 1] = { 3209 0, 3210 0, 3211 OptoReg::Bad, // Op_RegN 3212 OptoReg::Bad, // Op_RegI 3213 RAX_H_num, // Op_RegP 3214 OptoReg::Bad, // Op_RegF 3215 XMM0_H_num, // Op_RegD 3216 RAX_H_num // Op_RegL 3217 }; 3218 assert(ARRAY_SIZE(hi) == _last_machine_leaf - 1, "missing type"); 3219 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 3220 %} 3221%} 3222 3223//----------ATTRIBUTES--------------------------------------------------------- 3224//----------Operand Attributes------------------------------------------------- 3225op_attrib op_cost(0); // Required cost attribute 3226 3227//----------Instruction Attributes--------------------------------------------- 3228ins_attrib ins_cost(100); // Required cost attribute 3229ins_attrib ins_size(8); // Required size attribute (in bits) 3230ins_attrib ins_short_branch(0); // Required flag: is this instruction 3231 // a non-matching short branch variant 3232 // of some long branch? 3233ins_attrib ins_alignment(1); // Required alignment attribute (must 3234 // be a power of 2) specifies the 3235 // alignment that some part of the 3236 // instruction (not necessarily the 3237 // start) requires. If > 1, a 3238 // compute_padding() function must be 3239 // provided for the instruction 3240 3241//----------OPERANDS----------------------------------------------------------- 3242// Operand definitions must precede instruction definitions for correct parsing 3243// in the ADLC because operands constitute user defined types which are used in 3244// instruction definitions. 3245 3246//----------Simple Operands---------------------------------------------------- 3247// Immediate Operands 3248// Integer Immediate 3249operand immI() 3250%{ 3251 match(ConI); 3252 3253 op_cost(10); 3254 format %{ %} 3255 interface(CONST_INTER); 3256%} 3257 3258// Constant for test vs zero 3259operand immI0() 3260%{ 3261 predicate(n->get_int() == 0); 3262 match(ConI); 3263 3264 op_cost(0); 3265 format %{ %} 3266 interface(CONST_INTER); 3267%} 3268 3269// Constant for increment 3270operand immI1() 3271%{ 3272 predicate(n->get_int() == 1); 3273 match(ConI); 3274 3275 op_cost(0); 3276 format %{ %} 3277 interface(CONST_INTER); 3278%} 3279 3280// Constant for decrement 3281operand immI_M1() 3282%{ 3283 predicate(n->get_int() == -1); 3284 match(ConI); 3285 3286 op_cost(0); 3287 format %{ %} 3288 interface(CONST_INTER); 3289%} 3290 3291// Valid scale values for addressing modes 3292operand immI2() 3293%{ 3294 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 3295 match(ConI); 3296 3297 format %{ %} 3298 interface(CONST_INTER); 3299%} 3300 3301operand immI8() 3302%{ 3303 predicate((-0x80 <= n->get_int()) && (n->get_int() < 0x80)); 3304 match(ConI); 3305 3306 op_cost(5); 3307 format %{ %} 3308 interface(CONST_INTER); 3309%} 3310 3311operand immI16() 3312%{ 3313 predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767)); 3314 match(ConI); 3315 3316 op_cost(10); 3317 format %{ %} 3318 interface(CONST_INTER); 3319%} 3320 3321// Constant for long shifts 3322operand immI_32() 3323%{ 3324 predicate( n->get_int() == 32 ); 3325 match(ConI); 3326 3327 op_cost(0); 3328 format %{ %} 3329 interface(CONST_INTER); 3330%} 3331 3332// Constant for long shifts 3333operand immI_64() 3334%{ 3335 predicate( n->get_int() == 64 ); 3336 match(ConI); 3337 3338 op_cost(0); 3339 format %{ %} 3340 interface(CONST_INTER); 3341%} 3342 3343// Pointer Immediate 3344operand immP() 3345%{ 3346 match(ConP); 3347 3348 op_cost(10); 3349 format %{ %} 3350 interface(CONST_INTER); 3351%} 3352 3353// NULL Pointer Immediate 3354operand immP0() 3355%{ 3356 predicate(n->get_ptr() == 0); 3357 match(ConP); 3358 3359 op_cost(5); 3360 format %{ %} 3361 interface(CONST_INTER); 3362%} 3363 3364operand immP_poll() %{ 3365 predicate(n->get_ptr() != 0 && n->get_ptr() == (intptr_t)os::get_polling_page()); 3366 match(ConP); 3367 3368 // formats are generated automatically for constants and base registers 3369 format %{ %} 3370 interface(CONST_INTER); 3371%} 3372 3373// Pointer Immediate 3374operand immN() %{ 3375 match(ConN); 3376 3377 op_cost(10); 3378 format %{ %} 3379 interface(CONST_INTER); 3380%} 3381 3382// NULL Pointer Immediate 3383operand immN0() %{ 3384 predicate(n->get_narrowcon() == 0); 3385 match(ConN); 3386 3387 op_cost(5); 3388 format %{ %} 3389 interface(CONST_INTER); 3390%} 3391 3392operand immP31() 3393%{ 3394 predicate(!n->as_Type()->type()->isa_oopptr() 3395 && (n->get_ptr() >> 31) == 0); 3396 match(ConP); 3397 3398 op_cost(5); 3399 format %{ %} 3400 interface(CONST_INTER); 3401%} 3402 3403 3404// Long Immediate 3405operand immL() 3406%{ 3407 match(ConL); 3408 3409 op_cost(20); 3410 format %{ %} 3411 interface(CONST_INTER); 3412%} 3413 3414// Long Immediate 8-bit 3415operand immL8() 3416%{ 3417 predicate(-0x80L <= n->get_long() && n->get_long() < 0x80L); 3418 match(ConL); 3419 3420 op_cost(5); 3421 format %{ %} 3422 interface(CONST_INTER); 3423%} 3424 3425// Long Immediate 32-bit unsigned 3426operand immUL32() 3427%{ 3428 predicate(n->get_long() == (unsigned int) (n->get_long())); 3429 match(ConL); 3430 3431 op_cost(10); 3432 format %{ %} 3433 interface(CONST_INTER); 3434%} 3435 3436// Long Immediate 32-bit signed 3437operand immL32() 3438%{ 3439 predicate(n->get_long() == (int) (n->get_long())); 3440 match(ConL); 3441 3442 op_cost(15); 3443 format %{ %} 3444 interface(CONST_INTER); 3445%} 3446 3447// Long Immediate zero 3448operand immL0() 3449%{ 3450 predicate(n->get_long() == 0L); 3451 match(ConL); 3452 3453 op_cost(10); 3454 format %{ %} 3455 interface(CONST_INTER); 3456%} 3457 3458// Constant for increment 3459operand immL1() 3460%{ 3461 predicate(n->get_long() == 1); 3462 match(ConL); 3463 3464 format %{ %} 3465 interface(CONST_INTER); 3466%} 3467 3468// Constant for decrement 3469operand immL_M1() 3470%{ 3471 predicate(n->get_long() == -1); 3472 match(ConL); 3473 3474 format %{ %} 3475 interface(CONST_INTER); 3476%} 3477 3478// Long Immediate: the value 10 3479operand immL10() 3480%{ 3481 predicate(n->get_long() == 10); 3482 match(ConL); 3483 3484 format %{ %} 3485 interface(CONST_INTER); 3486%} 3487 3488// Long immediate from 0 to 127. 3489// Used for a shorter form of long mul by 10. 3490operand immL_127() 3491%{ 3492 predicate(0 <= n->get_long() && n->get_long() < 0x80); 3493 match(ConL); 3494 3495 op_cost(10); 3496 format %{ %} 3497 interface(CONST_INTER); 3498%} 3499 3500// Long Immediate: low 32-bit mask 3501operand immL_32bits() 3502%{ 3503 predicate(n->get_long() == 0xFFFFFFFFL); 3504 match(ConL); 3505 op_cost(20); 3506 3507 format %{ %} 3508 interface(CONST_INTER); 3509%} 3510 3511// Float Immediate zero 3512operand immF0() 3513%{ 3514 predicate(jint_cast(n->getf()) == 0); 3515 match(ConF); 3516 3517 op_cost(5); 3518 format %{ %} 3519 interface(CONST_INTER); 3520%} 3521 3522// Float Immediate 3523operand immF() 3524%{ 3525 match(ConF); 3526 3527 op_cost(15); 3528 format %{ %} 3529 interface(CONST_INTER); 3530%} 3531 3532// Double Immediate zero 3533operand immD0() 3534%{ 3535 predicate(jlong_cast(n->getd()) == 0); 3536 match(ConD); 3537 3538 op_cost(5); 3539 format %{ %} 3540 interface(CONST_INTER); 3541%} 3542 3543// Double Immediate 3544operand immD() 3545%{ 3546 match(ConD); 3547 3548 op_cost(15); 3549 format %{ %} 3550 interface(CONST_INTER); 3551%} 3552 3553// Immediates for special shifts (sign extend) 3554 3555// Constants for increment 3556operand immI_16() 3557%{ 3558 predicate(n->get_int() == 16); 3559 match(ConI); 3560 3561 format %{ %} 3562 interface(CONST_INTER); 3563%} 3564 3565operand immI_24() 3566%{ 3567 predicate(n->get_int() == 24); 3568 match(ConI); 3569 3570 format %{ %} 3571 interface(CONST_INTER); 3572%} 3573 3574// Constant for byte-wide masking 3575operand immI_255() 3576%{ 3577 predicate(n->get_int() == 255); 3578 match(ConI); 3579 3580 format %{ %} 3581 interface(CONST_INTER); 3582%} 3583 3584// Constant for short-wide masking 3585operand immI_65535() 3586%{ 3587 predicate(n->get_int() == 65535); 3588 match(ConI); 3589 3590 format %{ %} 3591 interface(CONST_INTER); 3592%} 3593 3594// Constant for byte-wide masking 3595operand immL_255() 3596%{ 3597 predicate(n->get_long() == 255); 3598 match(ConL); 3599 3600 format %{ %} 3601 interface(CONST_INTER); 3602%} 3603 3604// Constant for short-wide masking 3605operand immL_65535() 3606%{ 3607 predicate(n->get_long() == 65535); 3608 match(ConL); 3609 3610 format %{ %} 3611 interface(CONST_INTER); 3612%} 3613 3614// Register Operands 3615// Integer Register 3616operand rRegI() 3617%{ 3618 constraint(ALLOC_IN_RC(int_reg)); 3619 match(RegI); 3620 3621 match(rax_RegI); 3622 match(rbx_RegI); 3623 match(rcx_RegI); 3624 match(rdx_RegI); 3625 match(rdi_RegI); 3626 3627 format %{ %} 3628 interface(REG_INTER); 3629%} 3630 3631// Special Registers 3632operand rax_RegI() 3633%{ 3634 constraint(ALLOC_IN_RC(int_rax_reg)); 3635 match(RegI); 3636 match(rRegI); 3637 3638 format %{ "RAX" %} 3639 interface(REG_INTER); 3640%} 3641 3642// Special Registers 3643operand rbx_RegI() 3644%{ 3645 constraint(ALLOC_IN_RC(int_rbx_reg)); 3646 match(RegI); 3647 match(rRegI); 3648 3649 format %{ "RBX" %} 3650 interface(REG_INTER); 3651%} 3652 3653operand rcx_RegI() 3654%{ 3655 constraint(ALLOC_IN_RC(int_rcx_reg)); 3656 match(RegI); 3657 match(rRegI); 3658 3659 format %{ "RCX" %} 3660 interface(REG_INTER); 3661%} 3662 3663operand rdx_RegI() 3664%{ 3665 constraint(ALLOC_IN_RC(int_rdx_reg)); 3666 match(RegI); 3667 match(rRegI); 3668 3669 format %{ "RDX" %} 3670 interface(REG_INTER); 3671%} 3672 3673operand rdi_RegI() 3674%{ 3675 constraint(ALLOC_IN_RC(int_rdi_reg)); 3676 match(RegI); 3677 match(rRegI); 3678 3679 format %{ "RDI" %} 3680 interface(REG_INTER); 3681%} 3682 3683operand no_rcx_RegI() 3684%{ 3685 constraint(ALLOC_IN_RC(int_no_rcx_reg)); 3686 match(RegI); 3687 match(rax_RegI); 3688 match(rbx_RegI); 3689 match(rdx_RegI); 3690 match(rdi_RegI); 3691 3692 format %{ %} 3693 interface(REG_INTER); 3694%} 3695 3696operand no_rax_rdx_RegI() 3697%{ 3698 constraint(ALLOC_IN_RC(int_no_rax_rdx_reg)); 3699 match(RegI); 3700 match(rbx_RegI); 3701 match(rcx_RegI); 3702 match(rdi_RegI); 3703 3704 format %{ %} 3705 interface(REG_INTER); 3706%} 3707 3708// Pointer Register 3709operand any_RegP() 3710%{ 3711 constraint(ALLOC_IN_RC(any_reg)); 3712 match(RegP); 3713 match(rax_RegP); 3714 match(rbx_RegP); 3715 match(rdi_RegP); 3716 match(rsi_RegP); 3717 match(rbp_RegP); 3718 match(r15_RegP); 3719 match(rRegP); 3720 3721 format %{ %} 3722 interface(REG_INTER); 3723%} 3724 3725operand rRegP() 3726%{ 3727 constraint(ALLOC_IN_RC(ptr_reg)); 3728 match(RegP); 3729 match(rax_RegP); 3730 match(rbx_RegP); 3731 match(rdi_RegP); 3732 match(rsi_RegP); 3733 match(rbp_RegP); 3734 match(r15_RegP); // See Q&A below about r15_RegP. 3735 3736 format %{ %} 3737 interface(REG_INTER); 3738%} 3739 3740operand rRegN() %{ 3741 constraint(ALLOC_IN_RC(int_reg)); 3742 match(RegN); 3743 3744 format %{ %} 3745 interface(REG_INTER); 3746%} 3747 3748// Question: Why is r15_RegP (the read-only TLS register) a match for rRegP? 3749// Answer: Operand match rules govern the DFA as it processes instruction inputs. 3750// It's fine for an instruction input which expects rRegP to match a r15_RegP. 3751// The output of an instruction is controlled by the allocator, which respects 3752// register class masks, not match rules. Unless an instruction mentions 3753// r15_RegP or any_RegP explicitly as its output, r15 will not be considered 3754// by the allocator as an input. 3755 3756operand no_rax_RegP() 3757%{ 3758 constraint(ALLOC_IN_RC(ptr_no_rax_reg)); 3759 match(RegP); 3760 match(rbx_RegP); 3761 match(rsi_RegP); 3762 match(rdi_RegP); 3763 3764 format %{ %} 3765 interface(REG_INTER); 3766%} 3767 3768operand no_rbp_RegP() 3769%{ 3770 constraint(ALLOC_IN_RC(ptr_no_rbp_reg)); 3771 match(RegP); 3772 match(rbx_RegP); 3773 match(rsi_RegP); 3774 match(rdi_RegP); 3775 3776 format %{ %} 3777 interface(REG_INTER); 3778%} 3779 3780operand no_rax_rbx_RegP() 3781%{ 3782 constraint(ALLOC_IN_RC(ptr_no_rax_rbx_reg)); 3783 match(RegP); 3784 match(rsi_RegP); 3785 match(rdi_RegP); 3786 3787 format %{ %} 3788 interface(REG_INTER); 3789%} 3790 3791// Special Registers 3792// Return a pointer value 3793operand rax_RegP() 3794%{ 3795 constraint(ALLOC_IN_RC(ptr_rax_reg)); 3796 match(RegP); 3797 match(rRegP); 3798 3799 format %{ %} 3800 interface(REG_INTER); 3801%} 3802 3803// Special Registers 3804// Return a compressed pointer value 3805operand rax_RegN() 3806%{ 3807 constraint(ALLOC_IN_RC(int_rax_reg)); 3808 match(RegN); 3809 match(rRegN); 3810 3811 format %{ %} 3812 interface(REG_INTER); 3813%} 3814 3815// Used in AtomicAdd 3816operand rbx_RegP() 3817%{ 3818 constraint(ALLOC_IN_RC(ptr_rbx_reg)); 3819 match(RegP); 3820 match(rRegP); 3821 3822 format %{ %} 3823 interface(REG_INTER); 3824%} 3825 3826operand rsi_RegP() 3827%{ 3828 constraint(ALLOC_IN_RC(ptr_rsi_reg)); 3829 match(RegP); 3830 match(rRegP); 3831 3832 format %{ %} 3833 interface(REG_INTER); 3834%} 3835 3836// Used in rep stosq 3837operand rdi_RegP() 3838%{ 3839 constraint(ALLOC_IN_RC(ptr_rdi_reg)); 3840 match(RegP); 3841 match(rRegP); 3842 3843 format %{ %} 3844 interface(REG_INTER); 3845%} 3846 3847operand rbp_RegP() 3848%{ 3849 constraint(ALLOC_IN_RC(ptr_rbp_reg)); 3850 match(RegP); 3851 match(rRegP); 3852 3853 format %{ %} 3854 interface(REG_INTER); 3855%} 3856 3857operand r15_RegP() 3858%{ 3859 constraint(ALLOC_IN_RC(ptr_r15_reg)); 3860 match(RegP); 3861 match(rRegP); 3862 3863 format %{ %} 3864 interface(REG_INTER); 3865%} 3866 3867operand rRegL() 3868%{ 3869 constraint(ALLOC_IN_RC(long_reg)); 3870 match(RegL); 3871 match(rax_RegL); 3872 match(rdx_RegL); 3873 3874 format %{ %} 3875 interface(REG_INTER); 3876%} 3877 3878// Special Registers 3879operand no_rax_rdx_RegL() 3880%{ 3881 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 3882 match(RegL); 3883 match(rRegL); 3884 3885 format %{ %} 3886 interface(REG_INTER); 3887%} 3888 3889operand no_rax_RegL() 3890%{ 3891 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 3892 match(RegL); 3893 match(rRegL); 3894 match(rdx_RegL); 3895 3896 format %{ %} 3897 interface(REG_INTER); 3898%} 3899 3900operand no_rcx_RegL() 3901%{ 3902 constraint(ALLOC_IN_RC(long_no_rcx_reg)); 3903 match(RegL); 3904 match(rRegL); 3905 3906 format %{ %} 3907 interface(REG_INTER); 3908%} 3909 3910operand rax_RegL() 3911%{ 3912 constraint(ALLOC_IN_RC(long_rax_reg)); 3913 match(RegL); 3914 match(rRegL); 3915 3916 format %{ "RAX" %} 3917 interface(REG_INTER); 3918%} 3919 3920operand rcx_RegL() 3921%{ 3922 constraint(ALLOC_IN_RC(long_rcx_reg)); 3923 match(RegL); 3924 match(rRegL); 3925 3926 format %{ %} 3927 interface(REG_INTER); 3928%} 3929 3930operand rdx_RegL() 3931%{ 3932 constraint(ALLOC_IN_RC(long_rdx_reg)); 3933 match(RegL); 3934 match(rRegL); 3935 3936 format %{ %} 3937 interface(REG_INTER); 3938%} 3939 3940// Flags register, used as output of compare instructions 3941operand rFlagsReg() 3942%{ 3943 constraint(ALLOC_IN_RC(int_flags)); 3944 match(RegFlags); 3945 3946 format %{ "RFLAGS" %} 3947 interface(REG_INTER); 3948%} 3949 3950// Flags register, used as output of FLOATING POINT compare instructions 3951operand rFlagsRegU() 3952%{ 3953 constraint(ALLOC_IN_RC(int_flags)); 3954 match(RegFlags); 3955 3956 format %{ "RFLAGS_U" %} 3957 interface(REG_INTER); 3958%} 3959 3960operand rFlagsRegUCF() %{ 3961 constraint(ALLOC_IN_RC(int_flags)); 3962 match(RegFlags); 3963 predicate(false); 3964 3965 format %{ "RFLAGS_U_CF" %} 3966 interface(REG_INTER); 3967%} 3968 3969// Float register operands 3970operand regF() 3971%{ 3972 constraint(ALLOC_IN_RC(float_reg)); 3973 match(RegF); 3974 3975 format %{ %} 3976 interface(REG_INTER); 3977%} 3978 3979// Double register operands 3980operand regD() 3981%{ 3982 constraint(ALLOC_IN_RC(double_reg)); 3983 match(RegD); 3984 3985 format %{ %} 3986 interface(REG_INTER); 3987%} 3988 3989 3990//----------Memory Operands---------------------------------------------------- 3991// Direct Memory Operand 3992// operand direct(immP addr) 3993// %{ 3994// match(addr); 3995 3996// format %{ "[$addr]" %} 3997// interface(MEMORY_INTER) %{ 3998// base(0xFFFFFFFF); 3999// index(0x4); 4000// scale(0x0); 4001// disp($addr); 4002// %} 4003// %} 4004 4005// Indirect Memory Operand 4006operand indirect(any_RegP reg) 4007%{ 4008 constraint(ALLOC_IN_RC(ptr_reg)); 4009 match(reg); 4010 4011 format %{ "[$reg]" %} 4012 interface(MEMORY_INTER) %{ 4013 base($reg); 4014 index(0x4); 4015 scale(0x0); 4016 disp(0x0); 4017 %} 4018%} 4019 4020// Indirect Memory Plus Short Offset Operand 4021operand indOffset8(any_RegP reg, immL8 off) 4022%{ 4023 constraint(ALLOC_IN_RC(ptr_reg)); 4024 match(AddP reg off); 4025 4026 format %{ "[$reg + $off (8-bit)]" %} 4027 interface(MEMORY_INTER) %{ 4028 base($reg); 4029 index(0x4); 4030 scale(0x0); 4031 disp($off); 4032 %} 4033%} 4034 4035// Indirect Memory Plus Long Offset Operand 4036operand indOffset32(any_RegP reg, immL32 off) 4037%{ 4038 constraint(ALLOC_IN_RC(ptr_reg)); 4039 match(AddP reg off); 4040 4041 format %{ "[$reg + $off (32-bit)]" %} 4042 interface(MEMORY_INTER) %{ 4043 base($reg); 4044 index(0x4); 4045 scale(0x0); 4046 disp($off); 4047 %} 4048%} 4049 4050// Indirect Memory Plus Index Register Plus Offset Operand 4051operand indIndexOffset(any_RegP reg, rRegL lreg, immL32 off) 4052%{ 4053 constraint(ALLOC_IN_RC(ptr_reg)); 4054 match(AddP (AddP reg lreg) off); 4055 4056 op_cost(10); 4057 format %{"[$reg + $off + $lreg]" %} 4058 interface(MEMORY_INTER) %{ 4059 base($reg); 4060 index($lreg); 4061 scale(0x0); 4062 disp($off); 4063 %} 4064%} 4065 4066// Indirect Memory Plus Index Register Plus Offset Operand 4067operand indIndex(any_RegP reg, rRegL lreg) 4068%{ 4069 constraint(ALLOC_IN_RC(ptr_reg)); 4070 match(AddP reg lreg); 4071 4072 op_cost(10); 4073 format %{"[$reg + $lreg]" %} 4074 interface(MEMORY_INTER) %{ 4075 base($reg); 4076 index($lreg); 4077 scale(0x0); 4078 disp(0x0); 4079 %} 4080%} 4081 4082// Indirect Memory Times Scale Plus Index Register 4083operand indIndexScale(any_RegP reg, rRegL lreg, immI2 scale) 4084%{ 4085 constraint(ALLOC_IN_RC(ptr_reg)); 4086 match(AddP reg (LShiftL lreg scale)); 4087 4088 op_cost(10); 4089 format %{"[$reg + $lreg << $scale]" %} 4090 interface(MEMORY_INTER) %{ 4091 base($reg); 4092 index($lreg); 4093 scale($scale); 4094 disp(0x0); 4095 %} 4096%} 4097 4098// Indirect Memory Times Scale Plus Index Register Plus Offset Operand 4099operand indIndexScaleOffset(any_RegP reg, immL32 off, rRegL lreg, immI2 scale) 4100%{ 4101 constraint(ALLOC_IN_RC(ptr_reg)); 4102 match(AddP (AddP reg (LShiftL lreg scale)) off); 4103 4104 op_cost(10); 4105 format %{"[$reg + $off + $lreg << $scale]" %} 4106 interface(MEMORY_INTER) %{ 4107 base($reg); 4108 index($lreg); 4109 scale($scale); 4110 disp($off); 4111 %} 4112%} 4113 4114// Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 4115operand indPosIndexScaleOffset(any_RegP reg, immL32 off, rRegI idx, immI2 scale) 4116%{ 4117 constraint(ALLOC_IN_RC(ptr_reg)); 4118 predicate(n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 4119 match(AddP (AddP reg (LShiftL (ConvI2L idx) scale)) off); 4120 4121 op_cost(10); 4122 format %{"[$reg + $off + $idx << $scale]" %} 4123 interface(MEMORY_INTER) %{ 4124 base($reg); 4125 index($idx); 4126 scale($scale); 4127 disp($off); 4128 %} 4129%} 4130 4131// Indirect Narrow Oop Plus Offset Operand 4132// Note: x86 architecture doesn't support "scale * index + offset" without a base 4133// we can't free r12 even with Universe::narrow_oop_base() == NULL. 4134operand indCompressedOopOffset(rRegN reg, immL32 off) %{ 4135 predicate(UseCompressedOops && (Universe::narrow_oop_shift() == Address::times_8)); 4136 constraint(ALLOC_IN_RC(ptr_reg)); 4137 match(AddP (DecodeN reg) off); 4138 4139 op_cost(10); 4140 format %{"[R12 + $reg << 3 + $off] (compressed oop addressing)" %} 4141 interface(MEMORY_INTER) %{ 4142 base(0xc); // R12 4143 index($reg); 4144 scale(0x3); 4145 disp($off); 4146 %} 4147%} 4148 4149// Indirect Memory Operand 4150operand indirectNarrow(rRegN reg) 4151%{ 4152 predicate(Universe::narrow_oop_shift() == 0); 4153 constraint(ALLOC_IN_RC(ptr_reg)); 4154 match(DecodeN reg); 4155 4156 format %{ "[$reg]" %} 4157 interface(MEMORY_INTER) %{ 4158 base($reg); 4159 index(0x4); 4160 scale(0x0); 4161 disp(0x0); 4162 %} 4163%} 4164 4165// Indirect Memory Plus Short Offset Operand 4166operand indOffset8Narrow(rRegN reg, immL8 off) 4167%{ 4168 predicate(Universe::narrow_oop_shift() == 0); 4169 constraint(ALLOC_IN_RC(ptr_reg)); 4170 match(AddP (DecodeN reg) off); 4171 4172 format %{ "[$reg + $off (8-bit)]" %} 4173 interface(MEMORY_INTER) %{ 4174 base($reg); 4175 index(0x4); 4176 scale(0x0); 4177 disp($off); 4178 %} 4179%} 4180 4181// Indirect Memory Plus Long Offset Operand 4182operand indOffset32Narrow(rRegN reg, immL32 off) 4183%{ 4184 predicate(Universe::narrow_oop_shift() == 0); 4185 constraint(ALLOC_IN_RC(ptr_reg)); 4186 match(AddP (DecodeN reg) off); 4187 4188 format %{ "[$reg + $off (32-bit)]" %} 4189 interface(MEMORY_INTER) %{ 4190 base($reg); 4191 index(0x4); 4192 scale(0x0); 4193 disp($off); 4194 %} 4195%} 4196 4197// Indirect Memory Plus Index Register Plus Offset Operand 4198operand indIndexOffsetNarrow(rRegN reg, rRegL lreg, immL32 off) 4199%{ 4200 predicate(Universe::narrow_oop_shift() == 0); 4201 constraint(ALLOC_IN_RC(ptr_reg)); 4202 match(AddP (AddP (DecodeN reg) lreg) off); 4203 4204 op_cost(10); 4205 format %{"[$reg + $off + $lreg]" %} 4206 interface(MEMORY_INTER) %{ 4207 base($reg); 4208 index($lreg); 4209 scale(0x0); 4210 disp($off); 4211 %} 4212%} 4213 4214// Indirect Memory Plus Index Register Plus Offset Operand 4215operand indIndexNarrow(rRegN reg, rRegL lreg) 4216%{ 4217 predicate(Universe::narrow_oop_shift() == 0); 4218 constraint(ALLOC_IN_RC(ptr_reg)); 4219 match(AddP (DecodeN reg) lreg); 4220 4221 op_cost(10); 4222 format %{"[$reg + $lreg]" %} 4223 interface(MEMORY_INTER) %{ 4224 base($reg); 4225 index($lreg); 4226 scale(0x0); 4227 disp(0x0); 4228 %} 4229%} 4230 4231// Indirect Memory Times Scale Plus Index Register 4232operand indIndexScaleNarrow(rRegN reg, rRegL lreg, immI2 scale) 4233%{ 4234 predicate(Universe::narrow_oop_shift() == 0); 4235 constraint(ALLOC_IN_RC(ptr_reg)); 4236 match(AddP (DecodeN reg) (LShiftL lreg scale)); 4237 4238 op_cost(10); 4239 format %{"[$reg + $lreg << $scale]" %} 4240 interface(MEMORY_INTER) %{ 4241 base($reg); 4242 index($lreg); 4243 scale($scale); 4244 disp(0x0); 4245 %} 4246%} 4247 4248// Indirect Memory Times Scale Plus Index Register Plus Offset Operand 4249operand indIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegL lreg, immI2 scale) 4250%{ 4251 predicate(Universe::narrow_oop_shift() == 0); 4252 constraint(ALLOC_IN_RC(ptr_reg)); 4253 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off); 4254 4255 op_cost(10); 4256 format %{"[$reg + $off + $lreg << $scale]" %} 4257 interface(MEMORY_INTER) %{ 4258 base($reg); 4259 index($lreg); 4260 scale($scale); 4261 disp($off); 4262 %} 4263%} 4264 4265// Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 4266operand indPosIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegI idx, immI2 scale) 4267%{ 4268 constraint(ALLOC_IN_RC(ptr_reg)); 4269 predicate(Universe::narrow_oop_shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 4270 match(AddP (AddP (DecodeN reg) (LShiftL (ConvI2L idx) scale)) off); 4271 4272 op_cost(10); 4273 format %{"[$reg + $off + $idx << $scale]" %} 4274 interface(MEMORY_INTER) %{ 4275 base($reg); 4276 index($idx); 4277 scale($scale); 4278 disp($off); 4279 %} 4280%} 4281 4282 4283//----------Special Memory Operands-------------------------------------------- 4284// Stack Slot Operand - This operand is used for loading and storing temporary 4285// values on the stack where a match requires a value to 4286// flow through memory. 4287operand stackSlotP(sRegP reg) 4288%{ 4289 constraint(ALLOC_IN_RC(stack_slots)); 4290 // No match rule because this operand is only generated in matching 4291 4292 format %{ "[$reg]" %} 4293 interface(MEMORY_INTER) %{ 4294 base(0x4); // RSP 4295 index(0x4); // No Index 4296 scale(0x0); // No Scale 4297 disp($reg); // Stack Offset 4298 %} 4299%} 4300 4301operand stackSlotI(sRegI reg) 4302%{ 4303 constraint(ALLOC_IN_RC(stack_slots)); 4304 // No match rule because this operand is only generated in matching 4305 4306 format %{ "[$reg]" %} 4307 interface(MEMORY_INTER) %{ 4308 base(0x4); // RSP 4309 index(0x4); // No Index 4310 scale(0x0); // No Scale 4311 disp($reg); // Stack Offset 4312 %} 4313%} 4314 4315operand stackSlotF(sRegF reg) 4316%{ 4317 constraint(ALLOC_IN_RC(stack_slots)); 4318 // No match rule because this operand is only generated in matching 4319 4320 format %{ "[$reg]" %} 4321 interface(MEMORY_INTER) %{ 4322 base(0x4); // RSP 4323 index(0x4); // No Index 4324 scale(0x0); // No Scale 4325 disp($reg); // Stack Offset 4326 %} 4327%} 4328 4329operand stackSlotD(sRegD reg) 4330%{ 4331 constraint(ALLOC_IN_RC(stack_slots)); 4332 // No match rule because this operand is only generated in matching 4333 4334 format %{ "[$reg]" %} 4335 interface(MEMORY_INTER) %{ 4336 base(0x4); // RSP 4337 index(0x4); // No Index 4338 scale(0x0); // No Scale 4339 disp($reg); // Stack Offset 4340 %} 4341%} 4342operand stackSlotL(sRegL reg) 4343%{ 4344 constraint(ALLOC_IN_RC(stack_slots)); 4345 // No match rule because this operand is only generated in matching 4346 4347 format %{ "[$reg]" %} 4348 interface(MEMORY_INTER) %{ 4349 base(0x4); // RSP 4350 index(0x4); // No Index 4351 scale(0x0); // No Scale 4352 disp($reg); // Stack Offset 4353 %} 4354%} 4355 4356//----------Conditional Branch Operands---------------------------------------- 4357// Comparison Op - This is the operation of the comparison, and is limited to 4358// the following set of codes: 4359// L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 4360// 4361// Other attributes of the comparison, such as unsignedness, are specified 4362// by the comparison instruction that sets a condition code flags register. 4363// That result is represented by a flags operand whose subtype is appropriate 4364// to the unsignedness (etc.) of the comparison. 4365// 4366// Later, the instruction which matches both the Comparison Op (a Bool) and 4367// the flags (produced by the Cmp) specifies the coding of the comparison op 4368// by matching a specific subtype of Bool operand below, such as cmpOpU. 4369 4370// Comparision Code 4371operand cmpOp() 4372%{ 4373 match(Bool); 4374 4375 format %{ "" %} 4376 interface(COND_INTER) %{ 4377 equal(0x4, "e"); 4378 not_equal(0x5, "ne"); 4379 less(0xC, "l"); 4380 greater_equal(0xD, "ge"); 4381 less_equal(0xE, "le"); 4382 greater(0xF, "g"); 4383 %} 4384%} 4385 4386// Comparison Code, unsigned compare. Used by FP also, with 4387// C2 (unordered) turned into GT or LT already. The other bits 4388// C0 and C3 are turned into Carry & Zero flags. 4389operand cmpOpU() 4390%{ 4391 match(Bool); 4392 4393 format %{ "" %} 4394 interface(COND_INTER) %{ 4395 equal(0x4, "e"); 4396 not_equal(0x5, "ne"); 4397 less(0x2, "b"); 4398 greater_equal(0x3, "nb"); 4399 less_equal(0x6, "be"); 4400 greater(0x7, "nbe"); 4401 %} 4402%} 4403 4404 4405// Floating comparisons that don't require any fixup for the unordered case 4406operand cmpOpUCF() %{ 4407 match(Bool); 4408 predicate(n->as_Bool()->_test._test == BoolTest::lt || 4409 n->as_Bool()->_test._test == BoolTest::ge || 4410 n->as_Bool()->_test._test == BoolTest::le || 4411 n->as_Bool()->_test._test == BoolTest::gt); 4412 format %{ "" %} 4413 interface(COND_INTER) %{ 4414 equal(0x4, "e"); 4415 not_equal(0x5, "ne"); 4416 less(0x2, "b"); 4417 greater_equal(0x3, "nb"); 4418 less_equal(0x6, "be"); 4419 greater(0x7, "nbe"); 4420 %} 4421%} 4422 4423 4424// Floating comparisons that can be fixed up with extra conditional jumps 4425operand cmpOpUCF2() %{ 4426 match(Bool); 4427 predicate(n->as_Bool()->_test._test == BoolTest::ne || 4428 n->as_Bool()->_test._test == BoolTest::eq); 4429 format %{ "" %} 4430 interface(COND_INTER) %{ 4431 equal(0x4, "e"); 4432 not_equal(0x5, "ne"); 4433 less(0x2, "b"); 4434 greater_equal(0x3, "nb"); 4435 less_equal(0x6, "be"); 4436 greater(0x7, "nbe"); 4437 %} 4438%} 4439 4440 4441//----------OPERAND CLASSES---------------------------------------------------- 4442// Operand Classes are groups of operands that are used as to simplify 4443// instruction definitions by not requiring the AD writer to specify separate 4444// instructions for every form of operand when the instruction accepts 4445// multiple operand types with the same basic encoding and format. The classic 4446// case of this is memory operands. 4447 4448opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex, 4449 indIndexScale, indIndexScaleOffset, indPosIndexScaleOffset, 4450 indCompressedOopOffset, 4451 indirectNarrow, indOffset8Narrow, indOffset32Narrow, 4452 indIndexOffsetNarrow, indIndexNarrow, indIndexScaleNarrow, 4453 indIndexScaleOffsetNarrow, indPosIndexScaleOffsetNarrow); 4454 4455//----------PIPELINE----------------------------------------------------------- 4456// Rules which define the behavior of the target architectures pipeline. 4457pipeline %{ 4458 4459//----------ATTRIBUTES--------------------------------------------------------- 4460attributes %{ 4461 variable_size_instructions; // Fixed size instructions 4462 max_instructions_per_bundle = 3; // Up to 3 instructions per bundle 4463 instruction_unit_size = 1; // An instruction is 1 bytes long 4464 instruction_fetch_unit_size = 16; // The processor fetches one line 4465 instruction_fetch_units = 1; // of 16 bytes 4466 4467 // List of nop instructions 4468 nops( MachNop ); 4469%} 4470 4471//----------RESOURCES---------------------------------------------------------- 4472// Resources are the functional units available to the machine 4473 4474// Generic P2/P3 pipeline 4475// 3 decoders, only D0 handles big operands; a "bundle" is the limit of 4476// 3 instructions decoded per cycle. 4477// 2 load/store ops per cycle, 1 branch, 1 FPU, 4478// 3 ALU op, only ALU0 handles mul instructions. 4479resources( D0, D1, D2, DECODE = D0 | D1 | D2, 4480 MS0, MS1, MS2, MEM = MS0 | MS1 | MS2, 4481 BR, FPU, 4482 ALU0, ALU1, ALU2, ALU = ALU0 | ALU1 | ALU2); 4483 4484//----------PIPELINE DESCRIPTION----------------------------------------------- 4485// Pipeline Description specifies the stages in the machine's pipeline 4486 4487// Generic P2/P3 pipeline 4488pipe_desc(S0, S1, S2, S3, S4, S5); 4489 4490//----------PIPELINE CLASSES--------------------------------------------------- 4491// Pipeline Classes describe the stages in which input and output are 4492// referenced by the hardware pipeline. 4493 4494// Naming convention: ialu or fpu 4495// Then: _reg 4496// Then: _reg if there is a 2nd register 4497// Then: _long if it's a pair of instructions implementing a long 4498// Then: _fat if it requires the big decoder 4499// Or: _mem if it requires the big decoder and a memory unit. 4500 4501// Integer ALU reg operation 4502pipe_class ialu_reg(rRegI dst) 4503%{ 4504 single_instruction; 4505 dst : S4(write); 4506 dst : S3(read); 4507 DECODE : S0; // any decoder 4508 ALU : S3; // any alu 4509%} 4510 4511// Long ALU reg operation 4512pipe_class ialu_reg_long(rRegL dst) 4513%{ 4514 instruction_count(2); 4515 dst : S4(write); 4516 dst : S3(read); 4517 DECODE : S0(2); // any 2 decoders 4518 ALU : S3(2); // both alus 4519%} 4520 4521// Integer ALU reg operation using big decoder 4522pipe_class ialu_reg_fat(rRegI dst) 4523%{ 4524 single_instruction; 4525 dst : S4(write); 4526 dst : S3(read); 4527 D0 : S0; // big decoder only 4528 ALU : S3; // any alu 4529%} 4530 4531// Long ALU reg operation using big decoder 4532pipe_class ialu_reg_long_fat(rRegL dst) 4533%{ 4534 instruction_count(2); 4535 dst : S4(write); 4536 dst : S3(read); 4537 D0 : S0(2); // big decoder only; twice 4538 ALU : S3(2); // any 2 alus 4539%} 4540 4541// Integer ALU reg-reg operation 4542pipe_class ialu_reg_reg(rRegI dst, rRegI src) 4543%{ 4544 single_instruction; 4545 dst : S4(write); 4546 src : S3(read); 4547 DECODE : S0; // any decoder 4548 ALU : S3; // any alu 4549%} 4550 4551// Long ALU reg-reg operation 4552pipe_class ialu_reg_reg_long(rRegL dst, rRegL src) 4553%{ 4554 instruction_count(2); 4555 dst : S4(write); 4556 src : S3(read); 4557 DECODE : S0(2); // any 2 decoders 4558 ALU : S3(2); // both alus 4559%} 4560 4561// Integer ALU reg-reg operation 4562pipe_class ialu_reg_reg_fat(rRegI dst, memory src) 4563%{ 4564 single_instruction; 4565 dst : S4(write); 4566 src : S3(read); 4567 D0 : S0; // big decoder only 4568 ALU : S3; // any alu 4569%} 4570 4571// Long ALU reg-reg operation 4572pipe_class ialu_reg_reg_long_fat(rRegL dst, rRegL src) 4573%{ 4574 instruction_count(2); 4575 dst : S4(write); 4576 src : S3(read); 4577 D0 : S0(2); // big decoder only; twice 4578 ALU : S3(2); // both alus 4579%} 4580 4581// Integer ALU reg-mem operation 4582pipe_class ialu_reg_mem(rRegI dst, memory mem) 4583%{ 4584 single_instruction; 4585 dst : S5(write); 4586 mem : S3(read); 4587 D0 : S0; // big decoder only 4588 ALU : S4; // any alu 4589 MEM : S3; // any mem 4590%} 4591 4592// Integer mem operation (prefetch) 4593pipe_class ialu_mem(memory mem) 4594%{ 4595 single_instruction; 4596 mem : S3(read); 4597 D0 : S0; // big decoder only 4598 MEM : S3; // any mem 4599%} 4600 4601// Integer Store to Memory 4602pipe_class ialu_mem_reg(memory mem, rRegI src) 4603%{ 4604 single_instruction; 4605 mem : S3(read); 4606 src : S5(read); 4607 D0 : S0; // big decoder only 4608 ALU : S4; // any alu 4609 MEM : S3; 4610%} 4611 4612// // Long Store to Memory 4613// pipe_class ialu_mem_long_reg(memory mem, rRegL src) 4614// %{ 4615// instruction_count(2); 4616// mem : S3(read); 4617// src : S5(read); 4618// D0 : S0(2); // big decoder only; twice 4619// ALU : S4(2); // any 2 alus 4620// MEM : S3(2); // Both mems 4621// %} 4622 4623// Integer Store to Memory 4624pipe_class ialu_mem_imm(memory mem) 4625%{ 4626 single_instruction; 4627 mem : S3(read); 4628 D0 : S0; // big decoder only 4629 ALU : S4; // any alu 4630 MEM : S3; 4631%} 4632 4633// Integer ALU0 reg-reg operation 4634pipe_class ialu_reg_reg_alu0(rRegI dst, rRegI src) 4635%{ 4636 single_instruction; 4637 dst : S4(write); 4638 src : S3(read); 4639 D0 : S0; // Big decoder only 4640 ALU0 : S3; // only alu0 4641%} 4642 4643// Integer ALU0 reg-mem operation 4644pipe_class ialu_reg_mem_alu0(rRegI dst, memory mem) 4645%{ 4646 single_instruction; 4647 dst : S5(write); 4648 mem : S3(read); 4649 D0 : S0; // big decoder only 4650 ALU0 : S4; // ALU0 only 4651 MEM : S3; // any mem 4652%} 4653 4654// Integer ALU reg-reg operation 4655pipe_class ialu_cr_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2) 4656%{ 4657 single_instruction; 4658 cr : S4(write); 4659 src1 : S3(read); 4660 src2 : S3(read); 4661 DECODE : S0; // any decoder 4662 ALU : S3; // any alu 4663%} 4664 4665// Integer ALU reg-imm operation 4666pipe_class ialu_cr_reg_imm(rFlagsReg cr, rRegI src1) 4667%{ 4668 single_instruction; 4669 cr : S4(write); 4670 src1 : S3(read); 4671 DECODE : S0; // any decoder 4672 ALU : S3; // any alu 4673%} 4674 4675// Integer ALU reg-mem operation 4676pipe_class ialu_cr_reg_mem(rFlagsReg cr, rRegI src1, memory src2) 4677%{ 4678 single_instruction; 4679 cr : S4(write); 4680 src1 : S3(read); 4681 src2 : S3(read); 4682 D0 : S0; // big decoder only 4683 ALU : S4; // any alu 4684 MEM : S3; 4685%} 4686 4687// Conditional move reg-reg 4688pipe_class pipe_cmplt( rRegI p, rRegI q, rRegI y) 4689%{ 4690 instruction_count(4); 4691 y : S4(read); 4692 q : S3(read); 4693 p : S3(read); 4694 DECODE : S0(4); // any decoder 4695%} 4696 4697// Conditional move reg-reg 4698pipe_class pipe_cmov_reg( rRegI dst, rRegI src, rFlagsReg cr) 4699%{ 4700 single_instruction; 4701 dst : S4(write); 4702 src : S3(read); 4703 cr : S3(read); 4704 DECODE : S0; // any decoder 4705%} 4706 4707// Conditional move reg-mem 4708pipe_class pipe_cmov_mem( rFlagsReg cr, rRegI dst, memory src) 4709%{ 4710 single_instruction; 4711 dst : S4(write); 4712 src : S3(read); 4713 cr : S3(read); 4714 DECODE : S0; // any decoder 4715 MEM : S3; 4716%} 4717 4718// Conditional move reg-reg long 4719pipe_class pipe_cmov_reg_long( rFlagsReg cr, rRegL dst, rRegL src) 4720%{ 4721 single_instruction; 4722 dst : S4(write); 4723 src : S3(read); 4724 cr : S3(read); 4725 DECODE : S0(2); // any 2 decoders 4726%} 4727 4728// XXX 4729// // Conditional move double reg-reg 4730// pipe_class pipe_cmovD_reg( rFlagsReg cr, regDPR1 dst, regD src) 4731// %{ 4732// single_instruction; 4733// dst : S4(write); 4734// src : S3(read); 4735// cr : S3(read); 4736// DECODE : S0; // any decoder 4737// %} 4738 4739// Float reg-reg operation 4740pipe_class fpu_reg(regD dst) 4741%{ 4742 instruction_count(2); 4743 dst : S3(read); 4744 DECODE : S0(2); // any 2 decoders 4745 FPU : S3; 4746%} 4747 4748// Float reg-reg operation 4749pipe_class fpu_reg_reg(regD dst, regD src) 4750%{ 4751 instruction_count(2); 4752 dst : S4(write); 4753 src : S3(read); 4754 DECODE : S0(2); // any 2 decoders 4755 FPU : S3; 4756%} 4757 4758// Float reg-reg operation 4759pipe_class fpu_reg_reg_reg(regD dst, regD src1, regD src2) 4760%{ 4761 instruction_count(3); 4762 dst : S4(write); 4763 src1 : S3(read); 4764 src2 : S3(read); 4765 DECODE : S0(3); // any 3 decoders 4766 FPU : S3(2); 4767%} 4768 4769// Float reg-reg operation 4770pipe_class fpu_reg_reg_reg_reg(regD dst, regD src1, regD src2, regD src3) 4771%{ 4772 instruction_count(4); 4773 dst : S4(write); 4774 src1 : S3(read); 4775 src2 : S3(read); 4776 src3 : S3(read); 4777 DECODE : S0(4); // any 3 decoders 4778 FPU : S3(2); 4779%} 4780 4781// Float reg-reg operation 4782pipe_class fpu_reg_mem_reg_reg(regD dst, memory src1, regD src2, regD src3) 4783%{ 4784 instruction_count(4); 4785 dst : S4(write); 4786 src1 : S3(read); 4787 src2 : S3(read); 4788 src3 : S3(read); 4789 DECODE : S1(3); // any 3 decoders 4790 D0 : S0; // Big decoder only 4791 FPU : S3(2); 4792 MEM : S3; 4793%} 4794 4795// Float reg-mem operation 4796pipe_class fpu_reg_mem(regD dst, memory mem) 4797%{ 4798 instruction_count(2); 4799 dst : S5(write); 4800 mem : S3(read); 4801 D0 : S0; // big decoder only 4802 DECODE : S1; // any decoder for FPU POP 4803 FPU : S4; 4804 MEM : S3; // any mem 4805%} 4806 4807// Float reg-mem operation 4808pipe_class fpu_reg_reg_mem(regD dst, regD src1, memory mem) 4809%{ 4810 instruction_count(3); 4811 dst : S5(write); 4812 src1 : S3(read); 4813 mem : S3(read); 4814 D0 : S0; // big decoder only 4815 DECODE : S1(2); // any decoder for FPU POP 4816 FPU : S4; 4817 MEM : S3; // any mem 4818%} 4819 4820// Float mem-reg operation 4821pipe_class fpu_mem_reg(memory mem, regD src) 4822%{ 4823 instruction_count(2); 4824 src : S5(read); 4825 mem : S3(read); 4826 DECODE : S0; // any decoder for FPU PUSH 4827 D0 : S1; // big decoder only 4828 FPU : S4; 4829 MEM : S3; // any mem 4830%} 4831 4832pipe_class fpu_mem_reg_reg(memory mem, regD src1, regD src2) 4833%{ 4834 instruction_count(3); 4835 src1 : S3(read); 4836 src2 : S3(read); 4837 mem : S3(read); 4838 DECODE : S0(2); // any decoder for FPU PUSH 4839 D0 : S1; // big decoder only 4840 FPU : S4; 4841 MEM : S3; // any mem 4842%} 4843 4844pipe_class fpu_mem_reg_mem(memory mem, regD src1, memory src2) 4845%{ 4846 instruction_count(3); 4847 src1 : S3(read); 4848 src2 : S3(read); 4849 mem : S4(read); 4850 DECODE : S0; // any decoder for FPU PUSH 4851 D0 : S0(2); // big decoder only 4852 FPU : S4; 4853 MEM : S3(2); // any mem 4854%} 4855 4856pipe_class fpu_mem_mem(memory dst, memory src1) 4857%{ 4858 instruction_count(2); 4859 src1 : S3(read); 4860 dst : S4(read); 4861 D0 : S0(2); // big decoder only 4862 MEM : S3(2); // any mem 4863%} 4864 4865pipe_class fpu_mem_mem_mem(memory dst, memory src1, memory src2) 4866%{ 4867 instruction_count(3); 4868 src1 : S3(read); 4869 src2 : S3(read); 4870 dst : S4(read); 4871 D0 : S0(3); // big decoder only 4872 FPU : S4; 4873 MEM : S3(3); // any mem 4874%} 4875 4876pipe_class fpu_mem_reg_con(memory mem, regD src1) 4877%{ 4878 instruction_count(3); 4879 src1 : S4(read); 4880 mem : S4(read); 4881 DECODE : S0; // any decoder for FPU PUSH 4882 D0 : S0(2); // big decoder only 4883 FPU : S4; 4884 MEM : S3(2); // any mem 4885%} 4886 4887// Float load constant 4888pipe_class fpu_reg_con(regD dst) 4889%{ 4890 instruction_count(2); 4891 dst : S5(write); 4892 D0 : S0; // big decoder only for the load 4893 DECODE : S1; // any decoder for FPU POP 4894 FPU : S4; 4895 MEM : S3; // any mem 4896%} 4897 4898// Float load constant 4899pipe_class fpu_reg_reg_con(regD dst, regD src) 4900%{ 4901 instruction_count(3); 4902 dst : S5(write); 4903 src : S3(read); 4904 D0 : S0; // big decoder only for the load 4905 DECODE : S1(2); // any decoder for FPU POP 4906 FPU : S4; 4907 MEM : S3; // any mem 4908%} 4909 4910// UnConditional branch 4911pipe_class pipe_jmp(label labl) 4912%{ 4913 single_instruction; 4914 BR : S3; 4915%} 4916 4917// Conditional branch 4918pipe_class pipe_jcc(cmpOp cmp, rFlagsReg cr, label labl) 4919%{ 4920 single_instruction; 4921 cr : S1(read); 4922 BR : S3; 4923%} 4924 4925// Allocation idiom 4926pipe_class pipe_cmpxchg(rRegP dst, rRegP heap_ptr) 4927%{ 4928 instruction_count(1); force_serialization; 4929 fixed_latency(6); 4930 heap_ptr : S3(read); 4931 DECODE : S0(3); 4932 D0 : S2; 4933 MEM : S3; 4934 ALU : S3(2); 4935 dst : S5(write); 4936 BR : S5; 4937%} 4938 4939// Generic big/slow expanded idiom 4940pipe_class pipe_slow() 4941%{ 4942 instruction_count(10); multiple_bundles; force_serialization; 4943 fixed_latency(100); 4944 D0 : S0(2); 4945 MEM : S3(2); 4946%} 4947 4948// The real do-nothing guy 4949pipe_class empty() 4950%{ 4951 instruction_count(0); 4952%} 4953 4954// Define the class for the Nop node 4955define 4956%{ 4957 MachNop = empty; 4958%} 4959 4960%} 4961 4962//----------INSTRUCTIONS------------------------------------------------------- 4963// 4964// match -- States which machine-independent subtree may be replaced 4965// by this instruction. 4966// ins_cost -- The estimated cost of this instruction is used by instruction 4967// selection to identify a minimum cost tree of machine 4968// instructions that matches a tree of machine-independent 4969// instructions. 4970// format -- A string providing the disassembly for this instruction. 4971// The value of an instruction's operand may be inserted 4972// by referring to it with a '$' prefix. 4973// opcode -- Three instruction opcodes may be provided. These are referred 4974// to within an encode class as $primary, $secondary, and $tertiary 4975// rrspectively. The primary opcode is commonly used to 4976// indicate the type of machine instruction, while secondary 4977// and tertiary are often used for prefix options or addressing 4978// modes. 4979// ins_encode -- A list of encode classes with parameters. The encode class 4980// name must have been defined in an 'enc_class' specification 4981// in the encode section of the architecture description. 4982 4983 4984//----------Load/Store/Move Instructions--------------------------------------- 4985//----------Load Instructions-------------------------------------------------- 4986 4987// Load Byte (8 bit signed) 4988instruct loadB(rRegI dst, memory mem) 4989%{ 4990 match(Set dst (LoadB mem)); 4991 4992 ins_cost(125); 4993 format %{ "movsbl $dst, $mem\t# byte" %} 4994 4995 ins_encode %{ 4996 __ movsbl($dst$$Register, $mem$$Address); 4997 %} 4998 4999 ins_pipe(ialu_reg_mem); 5000%} 5001 5002// Load Byte (8 bit signed) into Long Register 5003instruct loadB2L(rRegL dst, memory mem) 5004%{ 5005 match(Set dst (ConvI2L (LoadB mem))); 5006 5007 ins_cost(125); 5008 format %{ "movsbq $dst, $mem\t# byte -> long" %} 5009 5010 ins_encode %{ 5011 __ movsbq($dst$$Register, $mem$$Address); 5012 %} 5013 5014 ins_pipe(ialu_reg_mem); 5015%} 5016 5017// Load Unsigned Byte (8 bit UNsigned) 5018instruct loadUB(rRegI dst, memory mem) 5019%{ 5020 match(Set dst (LoadUB mem)); 5021 5022 ins_cost(125); 5023 format %{ "movzbl $dst, $mem\t# ubyte" %} 5024 5025 ins_encode %{ 5026 __ movzbl($dst$$Register, $mem$$Address); 5027 %} 5028 5029 ins_pipe(ialu_reg_mem); 5030%} 5031 5032// Load Unsigned Byte (8 bit UNsigned) into Long Register 5033instruct loadUB2L(rRegL dst, memory mem) 5034%{ 5035 match(Set dst (ConvI2L (LoadUB mem))); 5036 5037 ins_cost(125); 5038 format %{ "movzbq $dst, $mem\t# ubyte -> long" %} 5039 5040 ins_encode %{ 5041 __ movzbq($dst$$Register, $mem$$Address); 5042 %} 5043 5044 ins_pipe(ialu_reg_mem); 5045%} 5046 5047// Load Unsigned Byte (8 bit UNsigned) with a 8-bit mask into Long Register 5048instruct loadUB2L_immI8(rRegL dst, memory mem, immI8 mask, rFlagsReg cr) %{ 5049 match(Set dst (ConvI2L (AndI (LoadUB mem) mask))); 5050 effect(KILL cr); 5051 5052 format %{ "movzbq $dst, $mem\t# ubyte & 8-bit mask -> long\n\t" 5053 "andl $dst, $mask" %} 5054 ins_encode %{ 5055 Register Rdst = $dst$$Register; 5056 __ movzbq(Rdst, $mem$$Address); 5057 __ andl(Rdst, $mask$$constant); 5058 %} 5059 ins_pipe(ialu_reg_mem); 5060%} 5061 5062// Load Short (16 bit signed) 5063instruct loadS(rRegI dst, memory mem) 5064%{ 5065 match(Set dst (LoadS mem)); 5066 5067 ins_cost(125); 5068 format %{ "movswl $dst, $mem\t# short" %} 5069 5070 ins_encode %{ 5071 __ movswl($dst$$Register, $mem$$Address); 5072 %} 5073 5074 ins_pipe(ialu_reg_mem); 5075%} 5076 5077// Load Short (16 bit signed) to Byte (8 bit signed) 5078instruct loadS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 5079 match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour)); 5080 5081 ins_cost(125); 5082 format %{ "movsbl $dst, $mem\t# short -> byte" %} 5083 ins_encode %{ 5084 __ movsbl($dst$$Register, $mem$$Address); 5085 %} 5086 ins_pipe(ialu_reg_mem); 5087%} 5088 5089// Load Short (16 bit signed) into Long Register 5090instruct loadS2L(rRegL dst, memory mem) 5091%{ 5092 match(Set dst (ConvI2L (LoadS mem))); 5093 5094 ins_cost(125); 5095 format %{ "movswq $dst, $mem\t# short -> long" %} 5096 5097 ins_encode %{ 5098 __ movswq($dst$$Register, $mem$$Address); 5099 %} 5100 5101 ins_pipe(ialu_reg_mem); 5102%} 5103 5104// Load Unsigned Short/Char (16 bit UNsigned) 5105instruct loadUS(rRegI dst, memory mem) 5106%{ 5107 match(Set dst (LoadUS mem)); 5108 5109 ins_cost(125); 5110 format %{ "movzwl $dst, $mem\t# ushort/char" %} 5111 5112 ins_encode %{ 5113 __ movzwl($dst$$Register, $mem$$Address); 5114 %} 5115 5116 ins_pipe(ialu_reg_mem); 5117%} 5118 5119// Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed) 5120instruct loadUS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 5121 match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour)); 5122 5123 ins_cost(125); 5124 format %{ "movsbl $dst, $mem\t# ushort -> byte" %} 5125 ins_encode %{ 5126 __ movsbl($dst$$Register, $mem$$Address); 5127 %} 5128 ins_pipe(ialu_reg_mem); 5129%} 5130 5131// Load Unsigned Short/Char (16 bit UNsigned) into Long Register 5132instruct loadUS2L(rRegL dst, memory mem) 5133%{ 5134 match(Set dst (ConvI2L (LoadUS mem))); 5135 5136 ins_cost(125); 5137 format %{ "movzwq $dst, $mem\t# ushort/char -> long" %} 5138 5139 ins_encode %{ 5140 __ movzwq($dst$$Register, $mem$$Address); 5141 %} 5142 5143 ins_pipe(ialu_reg_mem); 5144%} 5145 5146// Load Unsigned Short/Char (16 bit UNsigned) with mask 0xFF into Long Register 5147instruct loadUS2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 5148 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 5149 5150 format %{ "movzbq $dst, $mem\t# ushort/char & 0xFF -> long" %} 5151 ins_encode %{ 5152 __ movzbq($dst$$Register, $mem$$Address); 5153 %} 5154 ins_pipe(ialu_reg_mem); 5155%} 5156 5157// Load Unsigned Short/Char (16 bit UNsigned) with mask into Long Register 5158instruct loadUS2L_immI16(rRegL dst, memory mem, immI16 mask, rFlagsReg cr) %{ 5159 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 5160 effect(KILL cr); 5161 5162 format %{ "movzwq $dst, $mem\t# ushort/char & 16-bit mask -> long\n\t" 5163 "andl $dst, $mask" %} 5164 ins_encode %{ 5165 Register Rdst = $dst$$Register; 5166 __ movzwq(Rdst, $mem$$Address); 5167 __ andl(Rdst, $mask$$constant); 5168 %} 5169 ins_pipe(ialu_reg_mem); 5170%} 5171 5172// Load Integer 5173instruct loadI(rRegI dst, memory mem) 5174%{ 5175 match(Set dst (LoadI mem)); 5176 5177 ins_cost(125); 5178 format %{ "movl $dst, $mem\t# int" %} 5179 5180 ins_encode %{ 5181 __ movl($dst$$Register, $mem$$Address); 5182 %} 5183 5184 ins_pipe(ialu_reg_mem); 5185%} 5186 5187// Load Integer (32 bit signed) to Byte (8 bit signed) 5188instruct loadI2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 5189 match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour)); 5190 5191 ins_cost(125); 5192 format %{ "movsbl $dst, $mem\t# int -> byte" %} 5193 ins_encode %{ 5194 __ movsbl($dst$$Register, $mem$$Address); 5195 %} 5196 ins_pipe(ialu_reg_mem); 5197%} 5198 5199// Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned) 5200instruct loadI2UB(rRegI dst, memory mem, immI_255 mask) %{ 5201 match(Set dst (AndI (LoadI mem) mask)); 5202 5203 ins_cost(125); 5204 format %{ "movzbl $dst, $mem\t# int -> ubyte" %} 5205 ins_encode %{ 5206 __ movzbl($dst$$Register, $mem$$Address); 5207 %} 5208 ins_pipe(ialu_reg_mem); 5209%} 5210 5211// Load Integer (32 bit signed) to Short (16 bit signed) 5212instruct loadI2S(rRegI dst, memory mem, immI_16 sixteen) %{ 5213 match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen)); 5214 5215 ins_cost(125); 5216 format %{ "movswl $dst, $mem\t# int -> short" %} 5217 ins_encode %{ 5218 __ movswl($dst$$Register, $mem$$Address); 5219 %} 5220 ins_pipe(ialu_reg_mem); 5221%} 5222 5223// Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned) 5224instruct loadI2US(rRegI dst, memory mem, immI_65535 mask) %{ 5225 match(Set dst (AndI (LoadI mem) mask)); 5226 5227 ins_cost(125); 5228 format %{ "movzwl $dst, $mem\t# int -> ushort/char" %} 5229 ins_encode %{ 5230 __ movzwl($dst$$Register, $mem$$Address); 5231 %} 5232 ins_pipe(ialu_reg_mem); 5233%} 5234 5235// Load Integer into Long Register 5236instruct loadI2L(rRegL dst, memory mem) 5237%{ 5238 match(Set dst (ConvI2L (LoadI mem))); 5239 5240 ins_cost(125); 5241 format %{ "movslq $dst, $mem\t# int -> long" %} 5242 5243 ins_encode %{ 5244 __ movslq($dst$$Register, $mem$$Address); 5245 %} 5246 5247 ins_pipe(ialu_reg_mem); 5248%} 5249 5250// Load Integer with mask 0xFF into Long Register 5251instruct loadI2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 5252 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 5253 5254 format %{ "movzbq $dst, $mem\t# int & 0xFF -> long" %} 5255 ins_encode %{ 5256 __ movzbq($dst$$Register, $mem$$Address); 5257 %} 5258 ins_pipe(ialu_reg_mem); 5259%} 5260 5261// Load Integer with mask 0xFFFF into Long Register 5262instruct loadI2L_immI_65535(rRegL dst, memory mem, immI_65535 mask) %{ 5263 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 5264 5265 format %{ "movzwq $dst, $mem\t# int & 0xFFFF -> long" %} 5266 ins_encode %{ 5267 __ movzwq($dst$$Register, $mem$$Address); 5268 %} 5269 ins_pipe(ialu_reg_mem); 5270%} 5271 5272// Load Integer with a 32-bit mask into Long Register 5273instruct loadI2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 5274 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 5275 effect(KILL cr); 5276 5277 format %{ "movl $dst, $mem\t# int & 32-bit mask -> long\n\t" 5278 "andl $dst, $mask" %} 5279 ins_encode %{ 5280 Register Rdst = $dst$$Register; 5281 __ movl(Rdst, $mem$$Address); 5282 __ andl(Rdst, $mask$$constant); 5283 %} 5284 ins_pipe(ialu_reg_mem); 5285%} 5286 5287// Load Unsigned Integer into Long Register 5288instruct loadUI2L(rRegL dst, memory mem) 5289%{ 5290 match(Set dst (LoadUI2L mem)); 5291 5292 ins_cost(125); 5293 format %{ "movl $dst, $mem\t# uint -> long" %} 5294 5295 ins_encode %{ 5296 __ movl($dst$$Register, $mem$$Address); 5297 %} 5298 5299 ins_pipe(ialu_reg_mem); 5300%} 5301 5302// Load Long 5303instruct loadL(rRegL dst, memory mem) 5304%{ 5305 match(Set dst (LoadL mem)); 5306 5307 ins_cost(125); 5308 format %{ "movq $dst, $mem\t# long" %} 5309 5310 ins_encode %{ 5311 __ movq($dst$$Register, $mem$$Address); 5312 %} 5313 5314 ins_pipe(ialu_reg_mem); // XXX 5315%} 5316 5317// Load Range 5318instruct loadRange(rRegI dst, memory mem) 5319%{ 5320 match(Set dst (LoadRange mem)); 5321 5322 ins_cost(125); // XXX 5323 format %{ "movl $dst, $mem\t# range" %} 5324 opcode(0x8B); 5325 ins_encode(REX_reg_mem(dst, mem), OpcP, reg_mem(dst, mem)); 5326 ins_pipe(ialu_reg_mem); 5327%} 5328 5329// Load Pointer 5330instruct loadP(rRegP dst, memory mem) 5331%{ 5332 match(Set dst (LoadP mem)); 5333 5334 ins_cost(125); // XXX 5335 format %{ "movq $dst, $mem\t# ptr" %} 5336 opcode(0x8B); 5337 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5338 ins_pipe(ialu_reg_mem); // XXX 5339%} 5340 5341// Load Compressed Pointer 5342instruct loadN(rRegN dst, memory mem) 5343%{ 5344 match(Set dst (LoadN mem)); 5345 5346 ins_cost(125); // XXX 5347 format %{ "movl $dst, $mem\t# compressed ptr" %} 5348 ins_encode %{ 5349 __ movl($dst$$Register, $mem$$Address); 5350 %} 5351 ins_pipe(ialu_reg_mem); // XXX 5352%} 5353 5354 5355// Load Klass Pointer 5356instruct loadKlass(rRegP dst, memory mem) 5357%{ 5358 match(Set dst (LoadKlass mem)); 5359 5360 ins_cost(125); // XXX 5361 format %{ "movq $dst, $mem\t# class" %} 5362 opcode(0x8B); 5363 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5364 ins_pipe(ialu_reg_mem); // XXX 5365%} 5366 5367// Load narrow Klass Pointer 5368instruct loadNKlass(rRegN dst, memory mem) 5369%{ 5370 match(Set dst (LoadNKlass mem)); 5371 5372 ins_cost(125); // XXX 5373 format %{ "movl $dst, $mem\t# compressed klass ptr" %} 5374 ins_encode %{ 5375 __ movl($dst$$Register, $mem$$Address); 5376 %} 5377 ins_pipe(ialu_reg_mem); // XXX 5378%} 5379 5380// Load Float 5381instruct loadF(regF dst, memory mem) 5382%{ 5383 match(Set dst (LoadF mem)); 5384 5385 ins_cost(145); // XXX 5386 format %{ "movss $dst, $mem\t# float" %} 5387 ins_encode %{ 5388 __ movflt($dst$$XMMRegister, $mem$$Address); 5389 %} 5390 ins_pipe(pipe_slow); // XXX 5391%} 5392 5393// Load Double 5394instruct loadD_partial(regD dst, memory mem) 5395%{ 5396 predicate(!UseXmmLoadAndClearUpper); 5397 match(Set dst (LoadD mem)); 5398 5399 ins_cost(145); // XXX 5400 format %{ "movlpd $dst, $mem\t# double" %} 5401 ins_encode %{ 5402 __ movdbl($dst$$XMMRegister, $mem$$Address); 5403 %} 5404 ins_pipe(pipe_slow); // XXX 5405%} 5406 5407instruct loadD(regD dst, memory mem) 5408%{ 5409 predicate(UseXmmLoadAndClearUpper); 5410 match(Set dst (LoadD mem)); 5411 5412 ins_cost(145); // XXX 5413 format %{ "movsd $dst, $mem\t# double" %} 5414 ins_encode %{ 5415 __ movdbl($dst$$XMMRegister, $mem$$Address); 5416 %} 5417 ins_pipe(pipe_slow); // XXX 5418%} 5419 5420// Load Aligned Packed Byte to XMM register 5421instruct loadA8B(regD dst, memory mem) %{ 5422 match(Set dst (Load8B mem)); 5423 ins_cost(125); 5424 format %{ "MOVQ $dst,$mem\t! packed8B" %} 5425 ins_encode %{ 5426 __ movq($dst$$XMMRegister, $mem$$Address); 5427 %} 5428 ins_pipe( pipe_slow ); 5429%} 5430 5431// Load Aligned Packed Short to XMM register 5432instruct loadA4S(regD dst, memory mem) %{ 5433 match(Set dst (Load4S mem)); 5434 ins_cost(125); 5435 format %{ "MOVQ $dst,$mem\t! packed4S" %} 5436 ins_encode %{ 5437 __ movq($dst$$XMMRegister, $mem$$Address); 5438 %} 5439 ins_pipe( pipe_slow ); 5440%} 5441 5442// Load Aligned Packed Char to XMM register 5443instruct loadA4C(regD dst, memory mem) %{ 5444 match(Set dst (Load4C mem)); 5445 ins_cost(125); 5446 format %{ "MOVQ $dst,$mem\t! packed4C" %} 5447 ins_encode %{ 5448 __ movq($dst$$XMMRegister, $mem$$Address); 5449 %} 5450 ins_pipe( pipe_slow ); 5451%} 5452 5453// Load Aligned Packed Integer to XMM register 5454instruct load2IU(regD dst, memory mem) %{ 5455 match(Set dst (Load2I mem)); 5456 ins_cost(125); 5457 format %{ "MOVQ $dst,$mem\t! packed2I" %} 5458 ins_encode %{ 5459 __ movq($dst$$XMMRegister, $mem$$Address); 5460 %} 5461 ins_pipe( pipe_slow ); 5462%} 5463 5464// Load Aligned Packed Single to XMM 5465instruct loadA2F(regD dst, memory mem) %{ 5466 match(Set dst (Load2F mem)); 5467 ins_cost(125); 5468 format %{ "MOVQ $dst,$mem\t! packed2F" %} 5469 ins_encode %{ 5470 __ movq($dst$$XMMRegister, $mem$$Address); 5471 %} 5472 ins_pipe( pipe_slow ); 5473%} 5474 5475// Load Effective Address 5476instruct leaP8(rRegP dst, indOffset8 mem) 5477%{ 5478 match(Set dst mem); 5479 5480 ins_cost(110); // XXX 5481 format %{ "leaq $dst, $mem\t# ptr 8" %} 5482 opcode(0x8D); 5483 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5484 ins_pipe(ialu_reg_reg_fat); 5485%} 5486 5487instruct leaP32(rRegP dst, indOffset32 mem) 5488%{ 5489 match(Set dst mem); 5490 5491 ins_cost(110); 5492 format %{ "leaq $dst, $mem\t# ptr 32" %} 5493 opcode(0x8D); 5494 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5495 ins_pipe(ialu_reg_reg_fat); 5496%} 5497 5498// instruct leaPIdx(rRegP dst, indIndex mem) 5499// %{ 5500// match(Set dst mem); 5501 5502// ins_cost(110); 5503// format %{ "leaq $dst, $mem\t# ptr idx" %} 5504// opcode(0x8D); 5505// ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5506// ins_pipe(ialu_reg_reg_fat); 5507// %} 5508 5509instruct leaPIdxOff(rRegP dst, indIndexOffset mem) 5510%{ 5511 match(Set dst mem); 5512 5513 ins_cost(110); 5514 format %{ "leaq $dst, $mem\t# ptr idxoff" %} 5515 opcode(0x8D); 5516 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5517 ins_pipe(ialu_reg_reg_fat); 5518%} 5519 5520instruct leaPIdxScale(rRegP dst, indIndexScale mem) 5521%{ 5522 match(Set dst mem); 5523 5524 ins_cost(110); 5525 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 5526 opcode(0x8D); 5527 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5528 ins_pipe(ialu_reg_reg_fat); 5529%} 5530 5531instruct leaPIdxScaleOff(rRegP dst, indIndexScaleOffset mem) 5532%{ 5533 match(Set dst mem); 5534 5535 ins_cost(110); 5536 format %{ "leaq $dst, $mem\t# ptr idxscaleoff" %} 5537 opcode(0x8D); 5538 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5539 ins_pipe(ialu_reg_reg_fat); 5540%} 5541 5542instruct leaPPosIdxScaleOff(rRegP dst, indPosIndexScaleOffset mem) 5543%{ 5544 match(Set dst mem); 5545 5546 ins_cost(110); 5547 format %{ "leaq $dst, $mem\t# ptr posidxscaleoff" %} 5548 opcode(0x8D); 5549 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5550 ins_pipe(ialu_reg_reg_fat); 5551%} 5552 5553// Load Effective Address which uses Narrow (32-bits) oop 5554instruct leaPCompressedOopOffset(rRegP dst, indCompressedOopOffset mem) 5555%{ 5556 predicate(UseCompressedOops && (Universe::narrow_oop_shift() != 0)); 5557 match(Set dst mem); 5558 5559 ins_cost(110); 5560 format %{ "leaq $dst, $mem\t# ptr compressedoopoff32" %} 5561 opcode(0x8D); 5562 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5563 ins_pipe(ialu_reg_reg_fat); 5564%} 5565 5566instruct leaP8Narrow(rRegP dst, indOffset8Narrow mem) 5567%{ 5568 predicate(Universe::narrow_oop_shift() == 0); 5569 match(Set dst mem); 5570 5571 ins_cost(110); // XXX 5572 format %{ "leaq $dst, $mem\t# ptr off8narrow" %} 5573 opcode(0x8D); 5574 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5575 ins_pipe(ialu_reg_reg_fat); 5576%} 5577 5578instruct leaP32Narrow(rRegP dst, indOffset32Narrow mem) 5579%{ 5580 predicate(Universe::narrow_oop_shift() == 0); 5581 match(Set dst mem); 5582 5583 ins_cost(110); 5584 format %{ "leaq $dst, $mem\t# ptr off32narrow" %} 5585 opcode(0x8D); 5586 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5587 ins_pipe(ialu_reg_reg_fat); 5588%} 5589 5590instruct leaPIdxOffNarrow(rRegP dst, indIndexOffsetNarrow mem) 5591%{ 5592 predicate(Universe::narrow_oop_shift() == 0); 5593 match(Set dst mem); 5594 5595 ins_cost(110); 5596 format %{ "leaq $dst, $mem\t# ptr idxoffnarrow" %} 5597 opcode(0x8D); 5598 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5599 ins_pipe(ialu_reg_reg_fat); 5600%} 5601 5602instruct leaPIdxScaleNarrow(rRegP dst, indIndexScaleNarrow mem) 5603%{ 5604 predicate(Universe::narrow_oop_shift() == 0); 5605 match(Set dst mem); 5606 5607 ins_cost(110); 5608 format %{ "leaq $dst, $mem\t# ptr idxscalenarrow" %} 5609 opcode(0x8D); 5610 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5611 ins_pipe(ialu_reg_reg_fat); 5612%} 5613 5614instruct leaPIdxScaleOffNarrow(rRegP dst, indIndexScaleOffsetNarrow mem) 5615%{ 5616 predicate(Universe::narrow_oop_shift() == 0); 5617 match(Set dst mem); 5618 5619 ins_cost(110); 5620 format %{ "leaq $dst, $mem\t# ptr idxscaleoffnarrow" %} 5621 opcode(0x8D); 5622 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5623 ins_pipe(ialu_reg_reg_fat); 5624%} 5625 5626instruct leaPPosIdxScaleOffNarrow(rRegP dst, indPosIndexScaleOffsetNarrow mem) 5627%{ 5628 predicate(Universe::narrow_oop_shift() == 0); 5629 match(Set dst mem); 5630 5631 ins_cost(110); 5632 format %{ "leaq $dst, $mem\t# ptr posidxscaleoffnarrow" %} 5633 opcode(0x8D); 5634 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5635 ins_pipe(ialu_reg_reg_fat); 5636%} 5637 5638instruct loadConI(rRegI dst, immI src) 5639%{ 5640 match(Set dst src); 5641 5642 format %{ "movl $dst, $src\t# int" %} 5643 ins_encode(load_immI(dst, src)); 5644 ins_pipe(ialu_reg_fat); // XXX 5645%} 5646 5647instruct loadConI0(rRegI dst, immI0 src, rFlagsReg cr) 5648%{ 5649 match(Set dst src); 5650 effect(KILL cr); 5651 5652 ins_cost(50); 5653 format %{ "xorl $dst, $dst\t# int" %} 5654 opcode(0x33); /* + rd */ 5655 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5656 ins_pipe(ialu_reg); 5657%} 5658 5659instruct loadConL(rRegL dst, immL src) 5660%{ 5661 match(Set dst src); 5662 5663 ins_cost(150); 5664 format %{ "movq $dst, $src\t# long" %} 5665 ins_encode(load_immL(dst, src)); 5666 ins_pipe(ialu_reg); 5667%} 5668 5669instruct loadConL0(rRegL dst, immL0 src, rFlagsReg cr) 5670%{ 5671 match(Set dst src); 5672 effect(KILL cr); 5673 5674 ins_cost(50); 5675 format %{ "xorl $dst, $dst\t# long" %} 5676 opcode(0x33); /* + rd */ 5677 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5678 ins_pipe(ialu_reg); // XXX 5679%} 5680 5681instruct loadConUL32(rRegL dst, immUL32 src) 5682%{ 5683 match(Set dst src); 5684 5685 ins_cost(60); 5686 format %{ "movl $dst, $src\t# long (unsigned 32-bit)" %} 5687 ins_encode(load_immUL32(dst, src)); 5688 ins_pipe(ialu_reg); 5689%} 5690 5691instruct loadConL32(rRegL dst, immL32 src) 5692%{ 5693 match(Set dst src); 5694 5695 ins_cost(70); 5696 format %{ "movq $dst, $src\t# long (32-bit)" %} 5697 ins_encode(load_immL32(dst, src)); 5698 ins_pipe(ialu_reg); 5699%} 5700 5701instruct loadConP(rRegP dst, immP con) %{ 5702 match(Set dst con); 5703 5704 format %{ "movq $dst, $con\t# ptr" %} 5705 ins_encode(load_immP(dst, con)); 5706 ins_pipe(ialu_reg_fat); // XXX 5707%} 5708 5709instruct loadConP0(rRegP dst, immP0 src, rFlagsReg cr) 5710%{ 5711 match(Set dst src); 5712 effect(KILL cr); 5713 5714 ins_cost(50); 5715 format %{ "xorl $dst, $dst\t# ptr" %} 5716 opcode(0x33); /* + rd */ 5717 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5718 ins_pipe(ialu_reg); 5719%} 5720 5721instruct loadConP_poll(rRegP dst, immP_poll src) %{ 5722 match(Set dst src); 5723 format %{ "movq $dst, $src\t!ptr" %} 5724 ins_encode %{ 5725 AddressLiteral polling_page(os::get_polling_page(), relocInfo::poll_type); 5726 __ lea($dst$$Register, polling_page); 5727 %} 5728 ins_pipe(ialu_reg_fat); 5729%} 5730 5731instruct loadConP31(rRegP dst, immP31 src, rFlagsReg cr) 5732%{ 5733 match(Set dst src); 5734 effect(KILL cr); 5735 5736 ins_cost(60); 5737 format %{ "movl $dst, $src\t# ptr (positive 32-bit)" %} 5738 ins_encode(load_immP31(dst, src)); 5739 ins_pipe(ialu_reg); 5740%} 5741 5742instruct loadConF(regF dst, immF con) %{ 5743 match(Set dst con); 5744 ins_cost(125); 5745 format %{ "movss $dst, [$constantaddress]\t# load from constant table: float=$con" %} 5746 ins_encode %{ 5747 __ movflt($dst$$XMMRegister, $constantaddress($con)); 5748 %} 5749 ins_pipe(pipe_slow); 5750%} 5751 5752instruct loadConN0(rRegN dst, immN0 src, rFlagsReg cr) %{ 5753 match(Set dst src); 5754 effect(KILL cr); 5755 format %{ "xorq $dst, $src\t# compressed NULL ptr" %} 5756 ins_encode %{ 5757 __ xorq($dst$$Register, $dst$$Register); 5758 %} 5759 ins_pipe(ialu_reg); 5760%} 5761 5762instruct loadConN(rRegN dst, immN src) %{ 5763 match(Set dst src); 5764 5765 ins_cost(125); 5766 format %{ "movl $dst, $src\t# compressed ptr" %} 5767 ins_encode %{ 5768 address con = (address)$src$$constant; 5769 if (con == NULL) { 5770 ShouldNotReachHere(); 5771 } else { 5772 __ set_narrow_oop($dst$$Register, (jobject)$src$$constant); 5773 } 5774 %} 5775 ins_pipe(ialu_reg_fat); // XXX 5776%} 5777 5778instruct loadConF0(regF dst, immF0 src) 5779%{ 5780 match(Set dst src); 5781 ins_cost(100); 5782 5783 format %{ "xorps $dst, $dst\t# float 0.0" %} 5784 ins_encode %{ 5785 __ xorps($dst$$XMMRegister, $dst$$XMMRegister); 5786 %} 5787 ins_pipe(pipe_slow); 5788%} 5789 5790// Use the same format since predicate() can not be used here. 5791instruct loadConD(regD dst, immD con) %{ 5792 match(Set dst con); 5793 ins_cost(125); 5794 format %{ "movsd $dst, [$constantaddress]\t# load from constant table: double=$con" %} 5795 ins_encode %{ 5796 __ movdbl($dst$$XMMRegister, $constantaddress($con)); 5797 %} 5798 ins_pipe(pipe_slow); 5799%} 5800 5801instruct loadConD0(regD dst, immD0 src) 5802%{ 5803 match(Set dst src); 5804 ins_cost(100); 5805 5806 format %{ "xorpd $dst, $dst\t# double 0.0" %} 5807 ins_encode %{ 5808 __ xorpd ($dst$$XMMRegister, $dst$$XMMRegister); 5809 %} 5810 ins_pipe(pipe_slow); 5811%} 5812 5813instruct loadSSI(rRegI dst, stackSlotI src) 5814%{ 5815 match(Set dst src); 5816 5817 ins_cost(125); 5818 format %{ "movl $dst, $src\t# int stk" %} 5819 opcode(0x8B); 5820 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 5821 ins_pipe(ialu_reg_mem); 5822%} 5823 5824instruct loadSSL(rRegL dst, stackSlotL src) 5825%{ 5826 match(Set dst src); 5827 5828 ins_cost(125); 5829 format %{ "movq $dst, $src\t# long stk" %} 5830 opcode(0x8B); 5831 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 5832 ins_pipe(ialu_reg_mem); 5833%} 5834 5835instruct loadSSP(rRegP dst, stackSlotP src) 5836%{ 5837 match(Set dst src); 5838 5839 ins_cost(125); 5840 format %{ "movq $dst, $src\t# ptr stk" %} 5841 opcode(0x8B); 5842 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 5843 ins_pipe(ialu_reg_mem); 5844%} 5845 5846instruct loadSSF(regF dst, stackSlotF src) 5847%{ 5848 match(Set dst src); 5849 5850 ins_cost(125); 5851 format %{ "movss $dst, $src\t# float stk" %} 5852 ins_encode %{ 5853 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 5854 %} 5855 ins_pipe(pipe_slow); // XXX 5856%} 5857 5858// Use the same format since predicate() can not be used here. 5859instruct loadSSD(regD dst, stackSlotD src) 5860%{ 5861 match(Set dst src); 5862 5863 ins_cost(125); 5864 format %{ "movsd $dst, $src\t# double stk" %} 5865 ins_encode %{ 5866 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 5867 %} 5868 ins_pipe(pipe_slow); // XXX 5869%} 5870 5871// Prefetch instructions. 5872// Must be safe to execute with invalid address (cannot fault). 5873 5874instruct prefetchr( memory mem ) %{ 5875 predicate(ReadPrefetchInstr==3); 5876 match(PrefetchRead mem); 5877 ins_cost(125); 5878 5879 format %{ "PREFETCHR $mem\t# Prefetch into level 1 cache" %} 5880 ins_encode %{ 5881 __ prefetchr($mem$$Address); 5882 %} 5883 ins_pipe(ialu_mem); 5884%} 5885 5886instruct prefetchrNTA( memory mem ) %{ 5887 predicate(ReadPrefetchInstr==0); 5888 match(PrefetchRead mem); 5889 ins_cost(125); 5890 5891 format %{ "PREFETCHNTA $mem\t# Prefetch into non-temporal cache for read" %} 5892 ins_encode %{ 5893 __ prefetchnta($mem$$Address); 5894 %} 5895 ins_pipe(ialu_mem); 5896%} 5897 5898instruct prefetchrT0( memory mem ) %{ 5899 predicate(ReadPrefetchInstr==1); 5900 match(PrefetchRead mem); 5901 ins_cost(125); 5902 5903 format %{ "PREFETCHT0 $mem\t# prefetch into L1 and L2 caches for read" %} 5904 ins_encode %{ 5905 __ prefetcht0($mem$$Address); 5906 %} 5907 ins_pipe(ialu_mem); 5908%} 5909 5910instruct prefetchrT2( memory mem ) %{ 5911 predicate(ReadPrefetchInstr==2); 5912 match(PrefetchRead mem); 5913 ins_cost(125); 5914 5915 format %{ "PREFETCHT2 $mem\t# prefetch into L2 caches for read" %} 5916 ins_encode %{ 5917 __ prefetcht2($mem$$Address); 5918 %} 5919 ins_pipe(ialu_mem); 5920%} 5921 5922instruct prefetchwNTA( memory mem ) %{ 5923 match(PrefetchWrite mem); 5924 ins_cost(125); 5925 5926 format %{ "PREFETCHNTA $mem\t# Prefetch to non-temporal cache for write" %} 5927 ins_encode %{ 5928 __ prefetchnta($mem$$Address); 5929 %} 5930 ins_pipe(ialu_mem); 5931%} 5932 5933// Prefetch instructions for allocation. 5934 5935instruct prefetchAlloc( memory mem ) %{ 5936 predicate(AllocatePrefetchInstr==3); 5937 match(PrefetchAllocation mem); 5938 ins_cost(125); 5939 5940 format %{ "PREFETCHW $mem\t# Prefetch allocation into level 1 cache and mark modified" %} 5941 ins_encode %{ 5942 __ prefetchw($mem$$Address); 5943 %} 5944 ins_pipe(ialu_mem); 5945%} 5946 5947instruct prefetchAllocNTA( memory mem ) %{ 5948 predicate(AllocatePrefetchInstr==0); 5949 match(PrefetchAllocation mem); 5950 ins_cost(125); 5951 5952 format %{ "PREFETCHNTA $mem\t# Prefetch allocation to non-temporal cache for write" %} 5953 ins_encode %{ 5954 __ prefetchnta($mem$$Address); 5955 %} 5956 ins_pipe(ialu_mem); 5957%} 5958 5959instruct prefetchAllocT0( memory mem ) %{ 5960 predicate(AllocatePrefetchInstr==1); 5961 match(PrefetchAllocation mem); 5962 ins_cost(125); 5963 5964 format %{ "PREFETCHT0 $mem\t# Prefetch allocation to level 1 and 2 caches for write" %} 5965 ins_encode %{ 5966 __ prefetcht0($mem$$Address); 5967 %} 5968 ins_pipe(ialu_mem); 5969%} 5970 5971instruct prefetchAllocT2( memory mem ) %{ 5972 predicate(AllocatePrefetchInstr==2); 5973 match(PrefetchAllocation mem); 5974 ins_cost(125); 5975 5976 format %{ "PREFETCHT2 $mem\t# Prefetch allocation to level 2 cache for write" %} 5977 ins_encode %{ 5978 __ prefetcht2($mem$$Address); 5979 %} 5980 ins_pipe(ialu_mem); 5981%} 5982 5983//----------Store Instructions------------------------------------------------- 5984 5985// Store Byte 5986instruct storeB(memory mem, rRegI src) 5987%{ 5988 match(Set mem (StoreB mem src)); 5989 5990 ins_cost(125); // XXX 5991 format %{ "movb $mem, $src\t# byte" %} 5992 opcode(0x88); 5993 ins_encode(REX_breg_mem(src, mem), OpcP, reg_mem(src, mem)); 5994 ins_pipe(ialu_mem_reg); 5995%} 5996 5997// Store Char/Short 5998instruct storeC(memory mem, rRegI src) 5999%{ 6000 match(Set mem (StoreC mem src)); 6001 6002 ins_cost(125); // XXX 6003 format %{ "movw $mem, $src\t# char/short" %} 6004 opcode(0x89); 6005 ins_encode(SizePrefix, REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 6006 ins_pipe(ialu_mem_reg); 6007%} 6008 6009// Store Integer 6010instruct storeI(memory mem, rRegI src) 6011%{ 6012 match(Set mem (StoreI mem src)); 6013 6014 ins_cost(125); // XXX 6015 format %{ "movl $mem, $src\t# int" %} 6016 opcode(0x89); 6017 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 6018 ins_pipe(ialu_mem_reg); 6019%} 6020 6021// Store Long 6022instruct storeL(memory mem, rRegL src) 6023%{ 6024 match(Set mem (StoreL mem src)); 6025 6026 ins_cost(125); // XXX 6027 format %{ "movq $mem, $src\t# long" %} 6028 opcode(0x89); 6029 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 6030 ins_pipe(ialu_mem_reg); // XXX 6031%} 6032 6033// Store Pointer 6034instruct storeP(memory mem, any_RegP src) 6035%{ 6036 match(Set mem (StoreP mem src)); 6037 6038 ins_cost(125); // XXX 6039 format %{ "movq $mem, $src\t# ptr" %} 6040 opcode(0x89); 6041 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 6042 ins_pipe(ialu_mem_reg); 6043%} 6044 6045instruct storeImmP0(memory mem, immP0 zero) 6046%{ 6047 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL)); 6048 match(Set mem (StoreP mem zero)); 6049 6050 ins_cost(125); // XXX 6051 format %{ "movq $mem, R12\t# ptr (R12_heapbase==0)" %} 6052 ins_encode %{ 6053 __ movq($mem$$Address, r12); 6054 %} 6055 ins_pipe(ialu_mem_reg); 6056%} 6057 6058// Store NULL Pointer, mark word, or other simple pointer constant. 6059instruct storeImmP(memory mem, immP31 src) 6060%{ 6061 match(Set mem (StoreP mem src)); 6062 6063 ins_cost(150); // XXX 6064 format %{ "movq $mem, $src\t# ptr" %} 6065 opcode(0xC7); /* C7 /0 */ 6066 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 6067 ins_pipe(ialu_mem_imm); 6068%} 6069 6070// Store Compressed Pointer 6071instruct storeN(memory mem, rRegN src) 6072%{ 6073 match(Set mem (StoreN mem src)); 6074 6075 ins_cost(125); // XXX 6076 format %{ "movl $mem, $src\t# compressed ptr" %} 6077 ins_encode %{ 6078 __ movl($mem$$Address, $src$$Register); 6079 %} 6080 ins_pipe(ialu_mem_reg); 6081%} 6082 6083instruct storeImmN0(memory mem, immN0 zero) 6084%{ 6085 predicate(Universe::narrow_oop_base() == NULL); 6086 match(Set mem (StoreN mem zero)); 6087 6088 ins_cost(125); // XXX 6089 format %{ "movl $mem, R12\t# compressed ptr (R12_heapbase==0)" %} 6090 ins_encode %{ 6091 __ movl($mem$$Address, r12); 6092 %} 6093 ins_pipe(ialu_mem_reg); 6094%} 6095 6096instruct storeImmN(memory mem, immN src) 6097%{ 6098 match(Set mem (StoreN mem src)); 6099 6100 ins_cost(150); // XXX 6101 format %{ "movl $mem, $src\t# compressed ptr" %} 6102 ins_encode %{ 6103 address con = (address)$src$$constant; 6104 if (con == NULL) { 6105 __ movl($mem$$Address, (int32_t)0); 6106 } else { 6107 __ set_narrow_oop($mem$$Address, (jobject)$src$$constant); 6108 } 6109 %} 6110 ins_pipe(ialu_mem_imm); 6111%} 6112 6113// Store Integer Immediate 6114instruct storeImmI0(memory mem, immI0 zero) 6115%{ 6116 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL)); 6117 match(Set mem (StoreI mem zero)); 6118 6119 ins_cost(125); // XXX 6120 format %{ "movl $mem, R12\t# int (R12_heapbase==0)" %} 6121 ins_encode %{ 6122 __ movl($mem$$Address, r12); 6123 %} 6124 ins_pipe(ialu_mem_reg); 6125%} 6126 6127instruct storeImmI(memory mem, immI src) 6128%{ 6129 match(Set mem (StoreI mem src)); 6130 6131 ins_cost(150); 6132 format %{ "movl $mem, $src\t# int" %} 6133 opcode(0xC7); /* C7 /0 */ 6134 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 6135 ins_pipe(ialu_mem_imm); 6136%} 6137 6138// Store Long Immediate 6139instruct storeImmL0(memory mem, immL0 zero) 6140%{ 6141 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL)); 6142 match(Set mem (StoreL mem zero)); 6143 6144 ins_cost(125); // XXX 6145 format %{ "movq $mem, R12\t# long (R12_heapbase==0)" %} 6146 ins_encode %{ 6147 __ movq($mem$$Address, r12); 6148 %} 6149 ins_pipe(ialu_mem_reg); 6150%} 6151 6152instruct storeImmL(memory mem, immL32 src) 6153%{ 6154 match(Set mem (StoreL mem src)); 6155 6156 ins_cost(150); 6157 format %{ "movq $mem, $src\t# long" %} 6158 opcode(0xC7); /* C7 /0 */ 6159 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 6160 ins_pipe(ialu_mem_imm); 6161%} 6162 6163// Store Short/Char Immediate 6164instruct storeImmC0(memory mem, immI0 zero) 6165%{ 6166 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL)); 6167 match(Set mem (StoreC mem zero)); 6168 6169 ins_cost(125); // XXX 6170 format %{ "movw $mem, R12\t# short/char (R12_heapbase==0)" %} 6171 ins_encode %{ 6172 __ movw($mem$$Address, r12); 6173 %} 6174 ins_pipe(ialu_mem_reg); 6175%} 6176 6177instruct storeImmI16(memory mem, immI16 src) 6178%{ 6179 predicate(UseStoreImmI16); 6180 match(Set mem (StoreC mem src)); 6181 6182 ins_cost(150); 6183 format %{ "movw $mem, $src\t# short/char" %} 6184 opcode(0xC7); /* C7 /0 Same as 32 store immediate with prefix */ 6185 ins_encode(SizePrefix, REX_mem(mem), OpcP, RM_opc_mem(0x00, mem),Con16(src)); 6186 ins_pipe(ialu_mem_imm); 6187%} 6188 6189// Store Byte Immediate 6190instruct storeImmB0(memory mem, immI0 zero) 6191%{ 6192 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL)); 6193 match(Set mem (StoreB mem zero)); 6194 6195 ins_cost(125); // XXX 6196 format %{ "movb $mem, R12\t# short/char (R12_heapbase==0)" %} 6197 ins_encode %{ 6198 __ movb($mem$$Address, r12); 6199 %} 6200 ins_pipe(ialu_mem_reg); 6201%} 6202 6203instruct storeImmB(memory mem, immI8 src) 6204%{ 6205 match(Set mem (StoreB mem src)); 6206 6207 ins_cost(150); // XXX 6208 format %{ "movb $mem, $src\t# byte" %} 6209 opcode(0xC6); /* C6 /0 */ 6210 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src)); 6211 ins_pipe(ialu_mem_imm); 6212%} 6213 6214// Store Aligned Packed Byte XMM register to memory 6215instruct storeA8B(memory mem, regD src) %{ 6216 match(Set mem (Store8B mem src)); 6217 ins_cost(145); 6218 format %{ "MOVQ $mem,$src\t! packed8B" %} 6219 ins_encode %{ 6220 __ movq($mem$$Address, $src$$XMMRegister); 6221 %} 6222 ins_pipe( pipe_slow ); 6223%} 6224 6225// Store Aligned Packed Char/Short XMM register to memory 6226instruct storeA4C(memory mem, regD src) %{ 6227 match(Set mem (Store4C mem src)); 6228 ins_cost(145); 6229 format %{ "MOVQ $mem,$src\t! packed4C" %} 6230 ins_encode %{ 6231 __ movq($mem$$Address, $src$$XMMRegister); 6232 %} 6233 ins_pipe( pipe_slow ); 6234%} 6235 6236// Store Aligned Packed Integer XMM register to memory 6237instruct storeA2I(memory mem, regD src) %{ 6238 match(Set mem (Store2I mem src)); 6239 ins_cost(145); 6240 format %{ "MOVQ $mem,$src\t! packed2I" %} 6241 ins_encode %{ 6242 __ movq($mem$$Address, $src$$XMMRegister); 6243 %} 6244 ins_pipe( pipe_slow ); 6245%} 6246 6247// Store CMS card-mark Immediate 6248instruct storeImmCM0_reg(memory mem, immI0 zero) 6249%{ 6250 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL)); 6251 match(Set mem (StoreCM mem zero)); 6252 6253 ins_cost(125); // XXX 6254 format %{ "movb $mem, R12\t# CMS card-mark byte 0 (R12_heapbase==0)" %} 6255 ins_encode %{ 6256 __ movb($mem$$Address, r12); 6257 %} 6258 ins_pipe(ialu_mem_reg); 6259%} 6260 6261instruct storeImmCM0(memory mem, immI0 src) 6262%{ 6263 match(Set mem (StoreCM mem src)); 6264 6265 ins_cost(150); // XXX 6266 format %{ "movb $mem, $src\t# CMS card-mark byte 0" %} 6267 opcode(0xC6); /* C6 /0 */ 6268 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src)); 6269 ins_pipe(ialu_mem_imm); 6270%} 6271 6272// Store Aligned Packed Single Float XMM register to memory 6273instruct storeA2F(memory mem, regD src) %{ 6274 match(Set mem (Store2F mem src)); 6275 ins_cost(145); 6276 format %{ "MOVQ $mem,$src\t! packed2F" %} 6277 ins_encode %{ 6278 __ movq($mem$$Address, $src$$XMMRegister); 6279 %} 6280 ins_pipe( pipe_slow ); 6281%} 6282 6283// Store Float 6284instruct storeF(memory mem, regF src) 6285%{ 6286 match(Set mem (StoreF mem src)); 6287 6288 ins_cost(95); // XXX 6289 format %{ "movss $mem, $src\t# float" %} 6290 ins_encode %{ 6291 __ movflt($mem$$Address, $src$$XMMRegister); 6292 %} 6293 ins_pipe(pipe_slow); // XXX 6294%} 6295 6296// Store immediate Float value (it is faster than store from XMM register) 6297instruct storeF0(memory mem, immF0 zero) 6298%{ 6299 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL)); 6300 match(Set mem (StoreF mem zero)); 6301 6302 ins_cost(25); // XXX 6303 format %{ "movl $mem, R12\t# float 0. (R12_heapbase==0)" %} 6304 ins_encode %{ 6305 __ movl($mem$$Address, r12); 6306 %} 6307 ins_pipe(ialu_mem_reg); 6308%} 6309 6310instruct storeF_imm(memory mem, immF src) 6311%{ 6312 match(Set mem (StoreF mem src)); 6313 6314 ins_cost(50); 6315 format %{ "movl $mem, $src\t# float" %} 6316 opcode(0xC7); /* C7 /0 */ 6317 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src)); 6318 ins_pipe(ialu_mem_imm); 6319%} 6320 6321// Store Double 6322instruct storeD(memory mem, regD src) 6323%{ 6324 match(Set mem (StoreD mem src)); 6325 6326 ins_cost(95); // XXX 6327 format %{ "movsd $mem, $src\t# double" %} 6328 ins_encode %{ 6329 __ movdbl($mem$$Address, $src$$XMMRegister); 6330 %} 6331 ins_pipe(pipe_slow); // XXX 6332%} 6333 6334// Store immediate double 0.0 (it is faster than store from XMM register) 6335instruct storeD0_imm(memory mem, immD0 src) 6336%{ 6337 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL)); 6338 match(Set mem (StoreD mem src)); 6339 6340 ins_cost(50); 6341 format %{ "movq $mem, $src\t# double 0." %} 6342 opcode(0xC7); /* C7 /0 */ 6343 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src)); 6344 ins_pipe(ialu_mem_imm); 6345%} 6346 6347instruct storeD0(memory mem, immD0 zero) 6348%{ 6349 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL)); 6350 match(Set mem (StoreD mem zero)); 6351 6352 ins_cost(25); // XXX 6353 format %{ "movq $mem, R12\t# double 0. (R12_heapbase==0)" %} 6354 ins_encode %{ 6355 __ movq($mem$$Address, r12); 6356 %} 6357 ins_pipe(ialu_mem_reg); 6358%} 6359 6360instruct storeSSI(stackSlotI dst, rRegI src) 6361%{ 6362 match(Set dst src); 6363 6364 ins_cost(100); 6365 format %{ "movl $dst, $src\t# int stk" %} 6366 opcode(0x89); 6367 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 6368 ins_pipe( ialu_mem_reg ); 6369%} 6370 6371instruct storeSSL(stackSlotL dst, rRegL src) 6372%{ 6373 match(Set dst src); 6374 6375 ins_cost(100); 6376 format %{ "movq $dst, $src\t# long stk" %} 6377 opcode(0x89); 6378 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 6379 ins_pipe(ialu_mem_reg); 6380%} 6381 6382instruct storeSSP(stackSlotP dst, rRegP src) 6383%{ 6384 match(Set dst src); 6385 6386 ins_cost(100); 6387 format %{ "movq $dst, $src\t# ptr stk" %} 6388 opcode(0x89); 6389 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 6390 ins_pipe(ialu_mem_reg); 6391%} 6392 6393instruct storeSSF(stackSlotF dst, regF src) 6394%{ 6395 match(Set dst src); 6396 6397 ins_cost(95); // XXX 6398 format %{ "movss $dst, $src\t# float stk" %} 6399 ins_encode %{ 6400 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 6401 %} 6402 ins_pipe(pipe_slow); // XXX 6403%} 6404 6405instruct storeSSD(stackSlotD dst, regD src) 6406%{ 6407 match(Set dst src); 6408 6409 ins_cost(95); // XXX 6410 format %{ "movsd $dst, $src\t# double stk" %} 6411 ins_encode %{ 6412 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 6413 %} 6414 ins_pipe(pipe_slow); // XXX 6415%} 6416 6417//----------BSWAP Instructions------------------------------------------------- 6418instruct bytes_reverse_int(rRegI dst) %{ 6419 match(Set dst (ReverseBytesI dst)); 6420 6421 format %{ "bswapl $dst" %} 6422 opcode(0x0F, 0xC8); /*Opcode 0F /C8 */ 6423 ins_encode( REX_reg(dst), OpcP, opc2_reg(dst) ); 6424 ins_pipe( ialu_reg ); 6425%} 6426 6427instruct bytes_reverse_long(rRegL dst) %{ 6428 match(Set dst (ReverseBytesL dst)); 6429 6430 format %{ "bswapq $dst" %} 6431 6432 opcode(0x0F, 0xC8); /* Opcode 0F /C8 */ 6433 ins_encode( REX_reg_wide(dst), OpcP, opc2_reg(dst) ); 6434 ins_pipe( ialu_reg); 6435%} 6436 6437instruct bytes_reverse_unsigned_short(rRegI dst) %{ 6438 match(Set dst (ReverseBytesUS dst)); 6439 6440 format %{ "bswapl $dst\n\t" 6441 "shrl $dst,16\n\t" %} 6442 ins_encode %{ 6443 __ bswapl($dst$$Register); 6444 __ shrl($dst$$Register, 16); 6445 %} 6446 ins_pipe( ialu_reg ); 6447%} 6448 6449instruct bytes_reverse_short(rRegI dst) %{ 6450 match(Set dst (ReverseBytesS dst)); 6451 6452 format %{ "bswapl $dst\n\t" 6453 "sar $dst,16\n\t" %} 6454 ins_encode %{ 6455 __ bswapl($dst$$Register); 6456 __ sarl($dst$$Register, 16); 6457 %} 6458 ins_pipe( ialu_reg ); 6459%} 6460 6461//---------- Zeros Count Instructions ------------------------------------------ 6462 6463instruct countLeadingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6464 predicate(UseCountLeadingZerosInstruction); 6465 match(Set dst (CountLeadingZerosI src)); 6466 effect(KILL cr); 6467 6468 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 6469 ins_encode %{ 6470 __ lzcntl($dst$$Register, $src$$Register); 6471 %} 6472 ins_pipe(ialu_reg); 6473%} 6474 6475instruct countLeadingZerosI_bsr(rRegI dst, rRegI src, rFlagsReg cr) %{ 6476 predicate(!UseCountLeadingZerosInstruction); 6477 match(Set dst (CountLeadingZerosI src)); 6478 effect(KILL cr); 6479 6480 format %{ "bsrl $dst, $src\t# count leading zeros (int)\n\t" 6481 "jnz skip\n\t" 6482 "movl $dst, -1\n" 6483 "skip:\n\t" 6484 "negl $dst\n\t" 6485 "addl $dst, 31" %} 6486 ins_encode %{ 6487 Register Rdst = $dst$$Register; 6488 Register Rsrc = $src$$Register; 6489 Label skip; 6490 __ bsrl(Rdst, Rsrc); 6491 __ jccb(Assembler::notZero, skip); 6492 __ movl(Rdst, -1); 6493 __ bind(skip); 6494 __ negl(Rdst); 6495 __ addl(Rdst, BitsPerInt - 1); 6496 %} 6497 ins_pipe(ialu_reg); 6498%} 6499 6500instruct countLeadingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6501 predicate(UseCountLeadingZerosInstruction); 6502 match(Set dst (CountLeadingZerosL src)); 6503 effect(KILL cr); 6504 6505 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 6506 ins_encode %{ 6507 __ lzcntq($dst$$Register, $src$$Register); 6508 %} 6509 ins_pipe(ialu_reg); 6510%} 6511 6512instruct countLeadingZerosL_bsr(rRegI dst, rRegL src, rFlagsReg cr) %{ 6513 predicate(!UseCountLeadingZerosInstruction); 6514 match(Set dst (CountLeadingZerosL src)); 6515 effect(KILL cr); 6516 6517 format %{ "bsrq $dst, $src\t# count leading zeros (long)\n\t" 6518 "jnz skip\n\t" 6519 "movl $dst, -1\n" 6520 "skip:\n\t" 6521 "negl $dst\n\t" 6522 "addl $dst, 63" %} 6523 ins_encode %{ 6524 Register Rdst = $dst$$Register; 6525 Register Rsrc = $src$$Register; 6526 Label skip; 6527 __ bsrq(Rdst, Rsrc); 6528 __ jccb(Assembler::notZero, skip); 6529 __ movl(Rdst, -1); 6530 __ bind(skip); 6531 __ negl(Rdst); 6532 __ addl(Rdst, BitsPerLong - 1); 6533 %} 6534 ins_pipe(ialu_reg); 6535%} 6536 6537instruct countTrailingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6538 match(Set dst (CountTrailingZerosI src)); 6539 effect(KILL cr); 6540 6541 format %{ "bsfl $dst, $src\t# count trailing zeros (int)\n\t" 6542 "jnz done\n\t" 6543 "movl $dst, 32\n" 6544 "done:" %} 6545 ins_encode %{ 6546 Register Rdst = $dst$$Register; 6547 Label done; 6548 __ bsfl(Rdst, $src$$Register); 6549 __ jccb(Assembler::notZero, done); 6550 __ movl(Rdst, BitsPerInt); 6551 __ bind(done); 6552 %} 6553 ins_pipe(ialu_reg); 6554%} 6555 6556instruct countTrailingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6557 match(Set dst (CountTrailingZerosL src)); 6558 effect(KILL cr); 6559 6560 format %{ "bsfq $dst, $src\t# count trailing zeros (long)\n\t" 6561 "jnz done\n\t" 6562 "movl $dst, 64\n" 6563 "done:" %} 6564 ins_encode %{ 6565 Register Rdst = $dst$$Register; 6566 Label done; 6567 __ bsfq(Rdst, $src$$Register); 6568 __ jccb(Assembler::notZero, done); 6569 __ movl(Rdst, BitsPerLong); 6570 __ bind(done); 6571 %} 6572 ins_pipe(ialu_reg); 6573%} 6574 6575 6576//---------- Population Count Instructions ------------------------------------- 6577 6578instruct popCountI(rRegI dst, rRegI src) %{ 6579 predicate(UsePopCountInstruction); 6580 match(Set dst (PopCountI src)); 6581 6582 format %{ "popcnt $dst, $src" %} 6583 ins_encode %{ 6584 __ popcntl($dst$$Register, $src$$Register); 6585 %} 6586 ins_pipe(ialu_reg); 6587%} 6588 6589instruct popCountI_mem(rRegI dst, memory mem) %{ 6590 predicate(UsePopCountInstruction); 6591 match(Set dst (PopCountI (LoadI mem))); 6592 6593 format %{ "popcnt $dst, $mem" %} 6594 ins_encode %{ 6595 __ popcntl($dst$$Register, $mem$$Address); 6596 %} 6597 ins_pipe(ialu_reg); 6598%} 6599 6600// Note: Long.bitCount(long) returns an int. 6601instruct popCountL(rRegI dst, rRegL src) %{ 6602 predicate(UsePopCountInstruction); 6603 match(Set dst (PopCountL src)); 6604 6605 format %{ "popcnt $dst, $src" %} 6606 ins_encode %{ 6607 __ popcntq($dst$$Register, $src$$Register); 6608 %} 6609 ins_pipe(ialu_reg); 6610%} 6611 6612// Note: Long.bitCount(long) returns an int. 6613instruct popCountL_mem(rRegI dst, memory mem) %{ 6614 predicate(UsePopCountInstruction); 6615 match(Set dst (PopCountL (LoadL mem))); 6616 6617 format %{ "popcnt $dst, $mem" %} 6618 ins_encode %{ 6619 __ popcntq($dst$$Register, $mem$$Address); 6620 %} 6621 ins_pipe(ialu_reg); 6622%} 6623 6624 6625//----------MemBar Instructions----------------------------------------------- 6626// Memory barrier flavors 6627 6628instruct membar_acquire() 6629%{ 6630 match(MemBarAcquire); 6631 ins_cost(0); 6632 6633 size(0); 6634 format %{ "MEMBAR-acquire ! (empty encoding)" %} 6635 ins_encode(); 6636 ins_pipe(empty); 6637%} 6638 6639instruct membar_acquire_lock() 6640%{ 6641 match(MemBarAcquireLock); 6642 ins_cost(0); 6643 6644 size(0); 6645 format %{ "MEMBAR-acquire (prior CMPXCHG in FastLock so empty encoding)" %} 6646 ins_encode(); 6647 ins_pipe(empty); 6648%} 6649 6650instruct membar_release() 6651%{ 6652 match(MemBarRelease); 6653 ins_cost(0); 6654 6655 size(0); 6656 format %{ "MEMBAR-release ! (empty encoding)" %} 6657 ins_encode(); 6658 ins_pipe(empty); 6659%} 6660 6661instruct membar_release_lock() 6662%{ 6663 match(MemBarReleaseLock); 6664 ins_cost(0); 6665 6666 size(0); 6667 format %{ "MEMBAR-release (a FastUnlock follows so empty encoding)" %} 6668 ins_encode(); 6669 ins_pipe(empty); 6670%} 6671 6672instruct membar_volatile(rFlagsReg cr) %{ 6673 match(MemBarVolatile); 6674 effect(KILL cr); 6675 ins_cost(400); 6676 6677 format %{ 6678 $$template 6679 if (os::is_MP()) { 6680 $$emit$$"lock addl [rsp + #0], 0\t! membar_volatile" 6681 } else { 6682 $$emit$$"MEMBAR-volatile ! (empty encoding)" 6683 } 6684 %} 6685 ins_encode %{ 6686 __ membar(Assembler::StoreLoad); 6687 %} 6688 ins_pipe(pipe_slow); 6689%} 6690 6691instruct unnecessary_membar_volatile() 6692%{ 6693 match(MemBarVolatile); 6694 predicate(Matcher::post_store_load_barrier(n)); 6695 ins_cost(0); 6696 6697 size(0); 6698 format %{ "MEMBAR-volatile (unnecessary so empty encoding)" %} 6699 ins_encode(); 6700 ins_pipe(empty); 6701%} 6702 6703instruct membar_storestore() %{ 6704 match(MemBarStoreStore); 6705 ins_cost(0); 6706 6707 size(0); 6708 format %{ "MEMBAR-storestore (empty encoding)" %} 6709 ins_encode( ); 6710 ins_pipe(empty); 6711%} 6712 6713//----------Move Instructions-------------------------------------------------- 6714 6715instruct castX2P(rRegP dst, rRegL src) 6716%{ 6717 match(Set dst (CastX2P src)); 6718 6719 format %{ "movq $dst, $src\t# long->ptr" %} 6720 ins_encode %{ 6721 if ($dst$$reg != $src$$reg) { 6722 __ movptr($dst$$Register, $src$$Register); 6723 } 6724 %} 6725 ins_pipe(ialu_reg_reg); // XXX 6726%} 6727 6728instruct castP2X(rRegL dst, rRegP src) 6729%{ 6730 match(Set dst (CastP2X src)); 6731 6732 format %{ "movq $dst, $src\t# ptr -> long" %} 6733 ins_encode %{ 6734 if ($dst$$reg != $src$$reg) { 6735 __ movptr($dst$$Register, $src$$Register); 6736 } 6737 %} 6738 ins_pipe(ialu_reg_reg); // XXX 6739%} 6740 6741 6742// Convert oop pointer into compressed form 6743instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{ 6744 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 6745 match(Set dst (EncodeP src)); 6746 effect(KILL cr); 6747 format %{ "encode_heap_oop $dst,$src" %} 6748 ins_encode %{ 6749 Register s = $src$$Register; 6750 Register d = $dst$$Register; 6751 if (s != d) { 6752 __ movq(d, s); 6753 } 6754 __ encode_heap_oop(d); 6755 %} 6756 ins_pipe(ialu_reg_long); 6757%} 6758 6759instruct encodeHeapOop_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6760 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 6761 match(Set dst (EncodeP src)); 6762 effect(KILL cr); 6763 format %{ "encode_heap_oop_not_null $dst,$src" %} 6764 ins_encode %{ 6765 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 6766 %} 6767 ins_pipe(ialu_reg_long); 6768%} 6769 6770instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{ 6771 predicate(n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull && 6772 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant); 6773 match(Set dst (DecodeN src)); 6774 effect(KILL cr); 6775 format %{ "decode_heap_oop $dst,$src" %} 6776 ins_encode %{ 6777 Register s = $src$$Register; 6778 Register d = $dst$$Register; 6779 if (s != d) { 6780 __ movq(d, s); 6781 } 6782 __ decode_heap_oop(d); 6783 %} 6784 ins_pipe(ialu_reg_long); 6785%} 6786 6787instruct decodeHeapOop_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6788 predicate(n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull || 6789 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant); 6790 match(Set dst (DecodeN src)); 6791 effect(KILL cr); 6792 format %{ "decode_heap_oop_not_null $dst,$src" %} 6793 ins_encode %{ 6794 Register s = $src$$Register; 6795 Register d = $dst$$Register; 6796 if (s != d) { 6797 __ decode_heap_oop_not_null(d, s); 6798 } else { 6799 __ decode_heap_oop_not_null(d); 6800 } 6801 %} 6802 ins_pipe(ialu_reg_long); 6803%} 6804 6805 6806//----------Conditional Move--------------------------------------------------- 6807// Jump 6808// dummy instruction for generating temp registers 6809instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{ 6810 match(Jump (LShiftL switch_val shift)); 6811 ins_cost(350); 6812 predicate(false); 6813 effect(TEMP dest); 6814 6815 format %{ "leaq $dest, [$constantaddress]\n\t" 6816 "jmp [$dest + $switch_val << $shift]\n\t" %} 6817 ins_encode %{ 6818 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6819 // to do that and the compiler is using that register as one it can allocate. 6820 // So we build it all by hand. 6821 // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant); 6822 // ArrayAddress dispatch(table, index); 6823 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant); 6824 __ lea($dest$$Register, $constantaddress); 6825 __ jmp(dispatch); 6826 %} 6827 ins_pipe(pipe_jmp); 6828%} 6829 6830instruct jumpXtnd_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{ 6831 match(Jump (AddL (LShiftL switch_val shift) offset)); 6832 ins_cost(350); 6833 effect(TEMP dest); 6834 6835 format %{ "leaq $dest, [$constantaddress]\n\t" 6836 "jmp [$dest + $switch_val << $shift + $offset]\n\t" %} 6837 ins_encode %{ 6838 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6839 // to do that and the compiler is using that register as one it can allocate. 6840 // So we build it all by hand. 6841 // Address index(noreg, switch_reg, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6842 // ArrayAddress dispatch(table, index); 6843 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6844 __ lea($dest$$Register, $constantaddress); 6845 __ jmp(dispatch); 6846 %} 6847 ins_pipe(pipe_jmp); 6848%} 6849 6850instruct jumpXtnd(rRegL switch_val, rRegI dest) %{ 6851 match(Jump switch_val); 6852 ins_cost(350); 6853 effect(TEMP dest); 6854 6855 format %{ "leaq $dest, [$constantaddress]\n\t" 6856 "jmp [$dest + $switch_val]\n\t" %} 6857 ins_encode %{ 6858 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6859 // to do that and the compiler is using that register as one it can allocate. 6860 // So we build it all by hand. 6861 // Address index(noreg, switch_reg, Address::times_1); 6862 // ArrayAddress dispatch(table, index); 6863 Address dispatch($dest$$Register, $switch_val$$Register, Address::times_1); 6864 __ lea($dest$$Register, $constantaddress); 6865 __ jmp(dispatch); 6866 %} 6867 ins_pipe(pipe_jmp); 6868%} 6869 6870// Conditional move 6871instruct cmovI_reg(rRegI dst, rRegI src, rFlagsReg cr, cmpOp cop) 6872%{ 6873 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6874 6875 ins_cost(200); // XXX 6876 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6877 opcode(0x0F, 0x40); 6878 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6879 ins_pipe(pipe_cmov_reg); 6880%} 6881 6882instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{ 6883 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6884 6885 ins_cost(200); // XXX 6886 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6887 opcode(0x0F, 0x40); 6888 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6889 ins_pipe(pipe_cmov_reg); 6890%} 6891 6892instruct cmovI_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6893 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6894 ins_cost(200); 6895 expand %{ 6896 cmovI_regU(cop, cr, dst, src); 6897 %} 6898%} 6899 6900// Conditional move 6901instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{ 6902 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6903 6904 ins_cost(250); // XXX 6905 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6906 opcode(0x0F, 0x40); 6907 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6908 ins_pipe(pipe_cmov_mem); 6909%} 6910 6911// Conditional move 6912instruct cmovI_memU(cmpOpU cop, rFlagsRegU cr, rRegI dst, memory src) 6913%{ 6914 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6915 6916 ins_cost(250); // XXX 6917 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6918 opcode(0x0F, 0x40); 6919 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6920 ins_pipe(pipe_cmov_mem); 6921%} 6922 6923instruct cmovI_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, memory src) %{ 6924 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6925 ins_cost(250); 6926 expand %{ 6927 cmovI_memU(cop, cr, dst, src); 6928 %} 6929%} 6930 6931// Conditional move 6932instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop) 6933%{ 6934 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6935 6936 ins_cost(200); // XXX 6937 format %{ "cmovl$cop $dst, $src\t# signed, compressed ptr" %} 6938 opcode(0x0F, 0x40); 6939 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6940 ins_pipe(pipe_cmov_reg); 6941%} 6942 6943// Conditional move 6944instruct cmovN_regU(cmpOpU cop, rFlagsRegU cr, rRegN dst, rRegN src) 6945%{ 6946 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6947 6948 ins_cost(200); // XXX 6949 format %{ "cmovl$cop $dst, $src\t# unsigned, compressed ptr" %} 6950 opcode(0x0F, 0x40); 6951 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6952 ins_pipe(pipe_cmov_reg); 6953%} 6954 6955instruct cmovN_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6956 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6957 ins_cost(200); 6958 expand %{ 6959 cmovN_regU(cop, cr, dst, src); 6960 %} 6961%} 6962 6963// Conditional move 6964instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop) 6965%{ 6966 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6967 6968 ins_cost(200); // XXX 6969 format %{ "cmovq$cop $dst, $src\t# signed, ptr" %} 6970 opcode(0x0F, 0x40); 6971 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6972 ins_pipe(pipe_cmov_reg); // XXX 6973%} 6974 6975// Conditional move 6976instruct cmovP_regU(cmpOpU cop, rFlagsRegU cr, rRegP dst, rRegP src) 6977%{ 6978 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6979 6980 ins_cost(200); // XXX 6981 format %{ "cmovq$cop $dst, $src\t# unsigned, ptr" %} 6982 opcode(0x0F, 0x40); 6983 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6984 ins_pipe(pipe_cmov_reg); // XXX 6985%} 6986 6987instruct cmovP_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6988 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6989 ins_cost(200); 6990 expand %{ 6991 cmovP_regU(cop, cr, dst, src); 6992 %} 6993%} 6994 6995// DISABLED: Requires the ADLC to emit a bottom_type call that 6996// correctly meets the two pointer arguments; one is an incoming 6997// register but the other is a memory operand. ALSO appears to 6998// be buggy with implicit null checks. 6999// 7000//// Conditional move 7001//instruct cmovP_mem(cmpOp cop, rFlagsReg cr, rRegP dst, memory src) 7002//%{ 7003// match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); 7004// ins_cost(250); 7005// format %{ "CMOV$cop $dst,$src\t# ptr" %} 7006// opcode(0x0F,0x40); 7007// ins_encode( enc_cmov(cop), reg_mem( dst, src ) ); 7008// ins_pipe( pipe_cmov_mem ); 7009//%} 7010// 7011//// Conditional move 7012//instruct cmovP_memU(cmpOpU cop, rFlagsRegU cr, rRegP dst, memory src) 7013//%{ 7014// match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); 7015// ins_cost(250); 7016// format %{ "CMOV$cop $dst,$src\t# ptr" %} 7017// opcode(0x0F,0x40); 7018// ins_encode( enc_cmov(cop), reg_mem( dst, src ) ); 7019// ins_pipe( pipe_cmov_mem ); 7020//%} 7021 7022instruct cmovL_reg(cmpOp cop, rFlagsReg cr, rRegL dst, rRegL src) 7023%{ 7024 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 7025 7026 ins_cost(200); // XXX 7027 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 7028 opcode(0x0F, 0x40); 7029 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7030 ins_pipe(pipe_cmov_reg); // XXX 7031%} 7032 7033instruct cmovL_mem(cmpOp cop, rFlagsReg cr, rRegL dst, memory src) 7034%{ 7035 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 7036 7037 ins_cost(200); // XXX 7038 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 7039 opcode(0x0F, 0x40); 7040 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src)); 7041 ins_pipe(pipe_cmov_mem); // XXX 7042%} 7043 7044instruct cmovL_regU(cmpOpU cop, rFlagsRegU cr, rRegL dst, rRegL src) 7045%{ 7046 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 7047 7048 ins_cost(200); // XXX 7049 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 7050 opcode(0x0F, 0x40); 7051 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7052 ins_pipe(pipe_cmov_reg); // XXX 7053%} 7054 7055instruct cmovL_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 7056 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 7057 ins_cost(200); 7058 expand %{ 7059 cmovL_regU(cop, cr, dst, src); 7060 %} 7061%} 7062 7063instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src) 7064%{ 7065 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 7066 7067 ins_cost(200); // XXX 7068 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 7069 opcode(0x0F, 0x40); 7070 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src)); 7071 ins_pipe(pipe_cmov_mem); // XXX 7072%} 7073 7074instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{ 7075 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 7076 ins_cost(200); 7077 expand %{ 7078 cmovL_memU(cop, cr, dst, src); 7079 %} 7080%} 7081 7082instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src) 7083%{ 7084 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7085 7086 ins_cost(200); // XXX 7087 format %{ "jn$cop skip\t# signed cmove float\n\t" 7088 "movss $dst, $src\n" 7089 "skip:" %} 7090 ins_encode %{ 7091 Label Lskip; 7092 // Invert sense of branch from sense of CMOV 7093 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7094 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 7095 __ bind(Lskip); 7096 %} 7097 ins_pipe(pipe_slow); 7098%} 7099 7100// instruct cmovF_mem(cmpOp cop, rFlagsReg cr, regF dst, memory src) 7101// %{ 7102// match(Set dst (CMoveF (Binary cop cr) (Binary dst (LoadL src)))); 7103 7104// ins_cost(200); // XXX 7105// format %{ "jn$cop skip\t# signed cmove float\n\t" 7106// "movss $dst, $src\n" 7107// "skip:" %} 7108// ins_encode(enc_cmovf_mem_branch(cop, dst, src)); 7109// ins_pipe(pipe_slow); 7110// %} 7111 7112instruct cmovF_regU(cmpOpU cop, rFlagsRegU cr, regF dst, regF src) 7113%{ 7114 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7115 7116 ins_cost(200); // XXX 7117 format %{ "jn$cop skip\t# unsigned cmove float\n\t" 7118 "movss $dst, $src\n" 7119 "skip:" %} 7120 ins_encode %{ 7121 Label Lskip; 7122 // Invert sense of branch from sense of CMOV 7123 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7124 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 7125 __ bind(Lskip); 7126 %} 7127 ins_pipe(pipe_slow); 7128%} 7129 7130instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{ 7131 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7132 ins_cost(200); 7133 expand %{ 7134 cmovF_regU(cop, cr, dst, src); 7135 %} 7136%} 7137 7138instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src) 7139%{ 7140 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7141 7142 ins_cost(200); // XXX 7143 format %{ "jn$cop skip\t# signed cmove double\n\t" 7144 "movsd $dst, $src\n" 7145 "skip:" %} 7146 ins_encode %{ 7147 Label Lskip; 7148 // Invert sense of branch from sense of CMOV 7149 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7150 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 7151 __ bind(Lskip); 7152 %} 7153 ins_pipe(pipe_slow); 7154%} 7155 7156instruct cmovD_regU(cmpOpU cop, rFlagsRegU cr, regD dst, regD src) 7157%{ 7158 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7159 7160 ins_cost(200); // XXX 7161 format %{ "jn$cop skip\t# unsigned cmove double\n\t" 7162 "movsd $dst, $src\n" 7163 "skip:" %} 7164 ins_encode %{ 7165 Label Lskip; 7166 // Invert sense of branch from sense of CMOV 7167 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7168 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 7169 __ bind(Lskip); 7170 %} 7171 ins_pipe(pipe_slow); 7172%} 7173 7174instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{ 7175 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7176 ins_cost(200); 7177 expand %{ 7178 cmovD_regU(cop, cr, dst, src); 7179 %} 7180%} 7181 7182//----------Arithmetic Instructions-------------------------------------------- 7183//----------Addition Instructions---------------------------------------------- 7184 7185instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7186%{ 7187 match(Set dst (AddI dst src)); 7188 effect(KILL cr); 7189 7190 format %{ "addl $dst, $src\t# int" %} 7191 opcode(0x03); 7192 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 7193 ins_pipe(ialu_reg_reg); 7194%} 7195 7196instruct addI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 7197%{ 7198 match(Set dst (AddI dst src)); 7199 effect(KILL cr); 7200 7201 format %{ "addl $dst, $src\t# int" %} 7202 opcode(0x81, 0x00); /* /0 id */ 7203 ins_encode(OpcSErm(dst, src), Con8or32(src)); 7204 ins_pipe( ialu_reg ); 7205%} 7206 7207instruct addI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 7208%{ 7209 match(Set dst (AddI dst (LoadI src))); 7210 effect(KILL cr); 7211 7212 ins_cost(125); // XXX 7213 format %{ "addl $dst, $src\t# int" %} 7214 opcode(0x03); 7215 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 7216 ins_pipe(ialu_reg_mem); 7217%} 7218 7219instruct addI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 7220%{ 7221 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7222 effect(KILL cr); 7223 7224 ins_cost(150); // XXX 7225 format %{ "addl $dst, $src\t# int" %} 7226 opcode(0x01); /* Opcode 01 /r */ 7227 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 7228 ins_pipe(ialu_mem_reg); 7229%} 7230 7231instruct addI_mem_imm(memory dst, immI src, rFlagsReg cr) 7232%{ 7233 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7234 effect(KILL cr); 7235 7236 ins_cost(125); // XXX 7237 format %{ "addl $dst, $src\t# int" %} 7238 opcode(0x81); /* Opcode 81 /0 id */ 7239 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src)); 7240 ins_pipe(ialu_mem_imm); 7241%} 7242 7243instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr) 7244%{ 7245 predicate(UseIncDec); 7246 match(Set dst (AddI dst src)); 7247 effect(KILL cr); 7248 7249 format %{ "incl $dst\t# int" %} 7250 opcode(0xFF, 0x00); // FF /0 7251 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7252 ins_pipe(ialu_reg); 7253%} 7254 7255instruct incI_mem(memory dst, immI1 src, rFlagsReg cr) 7256%{ 7257 predicate(UseIncDec); 7258 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7259 effect(KILL cr); 7260 7261 ins_cost(125); // XXX 7262 format %{ "incl $dst\t# int" %} 7263 opcode(0xFF); /* Opcode FF /0 */ 7264 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x00, dst)); 7265 ins_pipe(ialu_mem_imm); 7266%} 7267 7268// XXX why does that use AddI 7269instruct decI_rReg(rRegI dst, immI_M1 src, rFlagsReg cr) 7270%{ 7271 predicate(UseIncDec); 7272 match(Set dst (AddI dst src)); 7273 effect(KILL cr); 7274 7275 format %{ "decl $dst\t# int" %} 7276 opcode(0xFF, 0x01); // FF /1 7277 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7278 ins_pipe(ialu_reg); 7279%} 7280 7281// XXX why does that use AddI 7282instruct decI_mem(memory dst, immI_M1 src, rFlagsReg cr) 7283%{ 7284 predicate(UseIncDec); 7285 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7286 effect(KILL cr); 7287 7288 ins_cost(125); // XXX 7289 format %{ "decl $dst\t# int" %} 7290 opcode(0xFF); /* Opcode FF /1 */ 7291 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x01, dst)); 7292 ins_pipe(ialu_mem_imm); 7293%} 7294 7295instruct leaI_rReg_immI(rRegI dst, rRegI src0, immI src1) 7296%{ 7297 match(Set dst (AddI src0 src1)); 7298 7299 ins_cost(110); 7300 format %{ "addr32 leal $dst, [$src0 + $src1]\t# int" %} 7301 opcode(0x8D); /* 0x8D /r */ 7302 ins_encode(Opcode(0x67), REX_reg_reg(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX 7303 ins_pipe(ialu_reg_reg); 7304%} 7305 7306instruct addL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7307%{ 7308 match(Set dst (AddL dst src)); 7309 effect(KILL cr); 7310 7311 format %{ "addq $dst, $src\t# long" %} 7312 opcode(0x03); 7313 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7314 ins_pipe(ialu_reg_reg); 7315%} 7316 7317instruct addL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 7318%{ 7319 match(Set dst (AddL dst src)); 7320 effect(KILL cr); 7321 7322 format %{ "addq $dst, $src\t# long" %} 7323 opcode(0x81, 0x00); /* /0 id */ 7324 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7325 ins_pipe( ialu_reg ); 7326%} 7327 7328instruct addL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 7329%{ 7330 match(Set dst (AddL dst (LoadL src))); 7331 effect(KILL cr); 7332 7333 ins_cost(125); // XXX 7334 format %{ "addq $dst, $src\t# long" %} 7335 opcode(0x03); 7336 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 7337 ins_pipe(ialu_reg_mem); 7338%} 7339 7340instruct addL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 7341%{ 7342 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7343 effect(KILL cr); 7344 7345 ins_cost(150); // XXX 7346 format %{ "addq $dst, $src\t# long" %} 7347 opcode(0x01); /* Opcode 01 /r */ 7348 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 7349 ins_pipe(ialu_mem_reg); 7350%} 7351 7352instruct addL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 7353%{ 7354 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7355 effect(KILL cr); 7356 7357 ins_cost(125); // XXX 7358 format %{ "addq $dst, $src\t# long" %} 7359 opcode(0x81); /* Opcode 81 /0 id */ 7360 ins_encode(REX_mem_wide(dst), 7361 OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src)); 7362 ins_pipe(ialu_mem_imm); 7363%} 7364 7365instruct incL_rReg(rRegI dst, immL1 src, rFlagsReg cr) 7366%{ 7367 predicate(UseIncDec); 7368 match(Set dst (AddL dst src)); 7369 effect(KILL cr); 7370 7371 format %{ "incq $dst\t# long" %} 7372 opcode(0xFF, 0x00); // FF /0 7373 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 7374 ins_pipe(ialu_reg); 7375%} 7376 7377instruct incL_mem(memory dst, immL1 src, rFlagsReg cr) 7378%{ 7379 predicate(UseIncDec); 7380 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7381 effect(KILL cr); 7382 7383 ins_cost(125); // XXX 7384 format %{ "incq $dst\t# long" %} 7385 opcode(0xFF); /* Opcode FF /0 */ 7386 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x00, dst)); 7387 ins_pipe(ialu_mem_imm); 7388%} 7389 7390// XXX why does that use AddL 7391instruct decL_rReg(rRegL dst, immL_M1 src, rFlagsReg cr) 7392%{ 7393 predicate(UseIncDec); 7394 match(Set dst (AddL dst src)); 7395 effect(KILL cr); 7396 7397 format %{ "decq $dst\t# long" %} 7398 opcode(0xFF, 0x01); // FF /1 7399 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 7400 ins_pipe(ialu_reg); 7401%} 7402 7403// XXX why does that use AddL 7404instruct decL_mem(memory dst, immL_M1 src, rFlagsReg cr) 7405%{ 7406 predicate(UseIncDec); 7407 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7408 effect(KILL cr); 7409 7410 ins_cost(125); // XXX 7411 format %{ "decq $dst\t# long" %} 7412 opcode(0xFF); /* Opcode FF /1 */ 7413 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x01, dst)); 7414 ins_pipe(ialu_mem_imm); 7415%} 7416 7417instruct leaL_rReg_immL(rRegL dst, rRegL src0, immL32 src1) 7418%{ 7419 match(Set dst (AddL src0 src1)); 7420 7421 ins_cost(110); 7422 format %{ "leaq $dst, [$src0 + $src1]\t# long" %} 7423 opcode(0x8D); /* 0x8D /r */ 7424 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX 7425 ins_pipe(ialu_reg_reg); 7426%} 7427 7428instruct addP_rReg(rRegP dst, rRegL src, rFlagsReg cr) 7429%{ 7430 match(Set dst (AddP dst src)); 7431 effect(KILL cr); 7432 7433 format %{ "addq $dst, $src\t# ptr" %} 7434 opcode(0x03); 7435 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7436 ins_pipe(ialu_reg_reg); 7437%} 7438 7439instruct addP_rReg_imm(rRegP dst, immL32 src, rFlagsReg cr) 7440%{ 7441 match(Set dst (AddP dst src)); 7442 effect(KILL cr); 7443 7444 format %{ "addq $dst, $src\t# ptr" %} 7445 opcode(0x81, 0x00); /* /0 id */ 7446 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7447 ins_pipe( ialu_reg ); 7448%} 7449 7450// XXX addP mem ops ???? 7451 7452instruct leaP_rReg_imm(rRegP dst, rRegP src0, immL32 src1) 7453%{ 7454 match(Set dst (AddP src0 src1)); 7455 7456 ins_cost(110); 7457 format %{ "leaq $dst, [$src0 + $src1]\t# ptr" %} 7458 opcode(0x8D); /* 0x8D /r */ 7459 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1));// XXX 7460 ins_pipe(ialu_reg_reg); 7461%} 7462 7463instruct checkCastPP(rRegP dst) 7464%{ 7465 match(Set dst (CheckCastPP dst)); 7466 7467 size(0); 7468 format %{ "# checkcastPP of $dst" %} 7469 ins_encode(/* empty encoding */); 7470 ins_pipe(empty); 7471%} 7472 7473instruct castPP(rRegP dst) 7474%{ 7475 match(Set dst (CastPP dst)); 7476 7477 size(0); 7478 format %{ "# castPP of $dst" %} 7479 ins_encode(/* empty encoding */); 7480 ins_pipe(empty); 7481%} 7482 7483instruct castII(rRegI dst) 7484%{ 7485 match(Set dst (CastII dst)); 7486 7487 size(0); 7488 format %{ "# castII of $dst" %} 7489 ins_encode(/* empty encoding */); 7490 ins_cost(0); 7491 ins_pipe(empty); 7492%} 7493 7494// LoadP-locked same as a regular LoadP when used with compare-swap 7495instruct loadPLocked(rRegP dst, memory mem) 7496%{ 7497 match(Set dst (LoadPLocked mem)); 7498 7499 ins_cost(125); // XXX 7500 format %{ "movq $dst, $mem\t# ptr locked" %} 7501 opcode(0x8B); 7502 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 7503 ins_pipe(ialu_reg_mem); // XXX 7504%} 7505 7506// LoadL-locked - same as a regular LoadL when used with compare-swap 7507instruct loadLLocked(rRegL dst, memory mem) 7508%{ 7509 match(Set dst (LoadLLocked mem)); 7510 7511 ins_cost(125); // XXX 7512 format %{ "movq $dst, $mem\t# long locked" %} 7513 opcode(0x8B); 7514 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 7515 ins_pipe(ialu_reg_mem); // XXX 7516%} 7517 7518// Conditional-store of the updated heap-top. 7519// Used during allocation of the shared heap. 7520// Sets flags (EQ) on success. Implemented with a CMPXCHG on Intel. 7521 7522instruct storePConditional(memory heap_top_ptr, 7523 rax_RegP oldval, rRegP newval, 7524 rFlagsReg cr) 7525%{ 7526 match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval))); 7527 7528 format %{ "cmpxchgq $heap_top_ptr, $newval\t# (ptr) " 7529 "If rax == $heap_top_ptr then store $newval into $heap_top_ptr" %} 7530 opcode(0x0F, 0xB1); 7531 ins_encode(lock_prefix, 7532 REX_reg_mem_wide(newval, heap_top_ptr), 7533 OpcP, OpcS, 7534 reg_mem(newval, heap_top_ptr)); 7535 ins_pipe(pipe_cmpxchg); 7536%} 7537 7538// Conditional-store of an int value. 7539// ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG. 7540instruct storeIConditional(memory mem, rax_RegI oldval, rRegI newval, rFlagsReg cr) 7541%{ 7542 match(Set cr (StoreIConditional mem (Binary oldval newval))); 7543 effect(KILL oldval); 7544 7545 format %{ "cmpxchgl $mem, $newval\t# If rax == $mem then store $newval into $mem" %} 7546 opcode(0x0F, 0xB1); 7547 ins_encode(lock_prefix, 7548 REX_reg_mem(newval, mem), 7549 OpcP, OpcS, 7550 reg_mem(newval, mem)); 7551 ins_pipe(pipe_cmpxchg); 7552%} 7553 7554// Conditional-store of a long value. 7555// ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG. 7556instruct storeLConditional(memory mem, rax_RegL oldval, rRegL newval, rFlagsReg cr) 7557%{ 7558 match(Set cr (StoreLConditional mem (Binary oldval newval))); 7559 effect(KILL oldval); 7560 7561 format %{ "cmpxchgq $mem, $newval\t# If rax == $mem then store $newval into $mem" %} 7562 opcode(0x0F, 0xB1); 7563 ins_encode(lock_prefix, 7564 REX_reg_mem_wide(newval, mem), 7565 OpcP, OpcS, 7566 reg_mem(newval, mem)); 7567 ins_pipe(pipe_cmpxchg); 7568%} 7569 7570 7571// XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them 7572instruct compareAndSwapP(rRegI res, 7573 memory mem_ptr, 7574 rax_RegP oldval, rRegP newval, 7575 rFlagsReg cr) 7576%{ 7577 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); 7578 effect(KILL cr, KILL oldval); 7579 7580 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7581 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7582 "sete $res\n\t" 7583 "movzbl $res, $res" %} 7584 opcode(0x0F, 0xB1); 7585 ins_encode(lock_prefix, 7586 REX_reg_mem_wide(newval, mem_ptr), 7587 OpcP, OpcS, 7588 reg_mem(newval, mem_ptr), 7589 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7590 REX_reg_breg(res, res), // movzbl 7591 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7592 ins_pipe( pipe_cmpxchg ); 7593%} 7594 7595instruct compareAndSwapL(rRegI res, 7596 memory mem_ptr, 7597 rax_RegL oldval, rRegL newval, 7598 rFlagsReg cr) 7599%{ 7600 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval))); 7601 effect(KILL cr, KILL oldval); 7602 7603 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7604 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7605 "sete $res\n\t" 7606 "movzbl $res, $res" %} 7607 opcode(0x0F, 0xB1); 7608 ins_encode(lock_prefix, 7609 REX_reg_mem_wide(newval, mem_ptr), 7610 OpcP, OpcS, 7611 reg_mem(newval, mem_ptr), 7612 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7613 REX_reg_breg(res, res), // movzbl 7614 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7615 ins_pipe( pipe_cmpxchg ); 7616%} 7617 7618instruct compareAndSwapI(rRegI res, 7619 memory mem_ptr, 7620 rax_RegI oldval, rRegI newval, 7621 rFlagsReg cr) 7622%{ 7623 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval))); 7624 effect(KILL cr, KILL oldval); 7625 7626 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7627 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7628 "sete $res\n\t" 7629 "movzbl $res, $res" %} 7630 opcode(0x0F, 0xB1); 7631 ins_encode(lock_prefix, 7632 REX_reg_mem(newval, mem_ptr), 7633 OpcP, OpcS, 7634 reg_mem(newval, mem_ptr), 7635 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7636 REX_reg_breg(res, res), // movzbl 7637 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7638 ins_pipe( pipe_cmpxchg ); 7639%} 7640 7641 7642instruct compareAndSwapN(rRegI res, 7643 memory mem_ptr, 7644 rax_RegN oldval, rRegN newval, 7645 rFlagsReg cr) %{ 7646 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval))); 7647 effect(KILL cr, KILL oldval); 7648 7649 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7650 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7651 "sete $res\n\t" 7652 "movzbl $res, $res" %} 7653 opcode(0x0F, 0xB1); 7654 ins_encode(lock_prefix, 7655 REX_reg_mem(newval, mem_ptr), 7656 OpcP, OpcS, 7657 reg_mem(newval, mem_ptr), 7658 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7659 REX_reg_breg(res, res), // movzbl 7660 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7661 ins_pipe( pipe_cmpxchg ); 7662%} 7663 7664//----------Subtraction Instructions------------------------------------------- 7665 7666// Integer Subtraction Instructions 7667instruct subI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7668%{ 7669 match(Set dst (SubI dst src)); 7670 effect(KILL cr); 7671 7672 format %{ "subl $dst, $src\t# int" %} 7673 opcode(0x2B); 7674 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 7675 ins_pipe(ialu_reg_reg); 7676%} 7677 7678instruct subI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 7679%{ 7680 match(Set dst (SubI dst src)); 7681 effect(KILL cr); 7682 7683 format %{ "subl $dst, $src\t# int" %} 7684 opcode(0x81, 0x05); /* Opcode 81 /5 */ 7685 ins_encode(OpcSErm(dst, src), Con8or32(src)); 7686 ins_pipe(ialu_reg); 7687%} 7688 7689instruct subI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 7690%{ 7691 match(Set dst (SubI dst (LoadI src))); 7692 effect(KILL cr); 7693 7694 ins_cost(125); 7695 format %{ "subl $dst, $src\t# int" %} 7696 opcode(0x2B); 7697 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 7698 ins_pipe(ialu_reg_mem); 7699%} 7700 7701instruct subI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 7702%{ 7703 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 7704 effect(KILL cr); 7705 7706 ins_cost(150); 7707 format %{ "subl $dst, $src\t# int" %} 7708 opcode(0x29); /* Opcode 29 /r */ 7709 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 7710 ins_pipe(ialu_mem_reg); 7711%} 7712 7713instruct subI_mem_imm(memory dst, immI src, rFlagsReg cr) 7714%{ 7715 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 7716 effect(KILL cr); 7717 7718 ins_cost(125); // XXX 7719 format %{ "subl $dst, $src\t# int" %} 7720 opcode(0x81); /* Opcode 81 /5 id */ 7721 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); 7722 ins_pipe(ialu_mem_imm); 7723%} 7724 7725instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7726%{ 7727 match(Set dst (SubL dst src)); 7728 effect(KILL cr); 7729 7730 format %{ "subq $dst, $src\t# long" %} 7731 opcode(0x2B); 7732 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7733 ins_pipe(ialu_reg_reg); 7734%} 7735 7736instruct subL_rReg_imm(rRegI dst, immL32 src, rFlagsReg cr) 7737%{ 7738 match(Set dst (SubL dst src)); 7739 effect(KILL cr); 7740 7741 format %{ "subq $dst, $src\t# long" %} 7742 opcode(0x81, 0x05); /* Opcode 81 /5 */ 7743 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7744 ins_pipe(ialu_reg); 7745%} 7746 7747instruct subL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 7748%{ 7749 match(Set dst (SubL dst (LoadL src))); 7750 effect(KILL cr); 7751 7752 ins_cost(125); 7753 format %{ "subq $dst, $src\t# long" %} 7754 opcode(0x2B); 7755 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 7756 ins_pipe(ialu_reg_mem); 7757%} 7758 7759instruct subL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 7760%{ 7761 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 7762 effect(KILL cr); 7763 7764 ins_cost(150); 7765 format %{ "subq $dst, $src\t# long" %} 7766 opcode(0x29); /* Opcode 29 /r */ 7767 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 7768 ins_pipe(ialu_mem_reg); 7769%} 7770 7771instruct subL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 7772%{ 7773 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 7774 effect(KILL cr); 7775 7776 ins_cost(125); // XXX 7777 format %{ "subq $dst, $src\t# long" %} 7778 opcode(0x81); /* Opcode 81 /5 id */ 7779 ins_encode(REX_mem_wide(dst), 7780 OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); 7781 ins_pipe(ialu_mem_imm); 7782%} 7783 7784// Subtract from a pointer 7785// XXX hmpf??? 7786instruct subP_rReg(rRegP dst, rRegI src, immI0 zero, rFlagsReg cr) 7787%{ 7788 match(Set dst (AddP dst (SubI zero src))); 7789 effect(KILL cr); 7790 7791 format %{ "subq $dst, $src\t# ptr - int" %} 7792 opcode(0x2B); 7793 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7794 ins_pipe(ialu_reg_reg); 7795%} 7796 7797instruct negI_rReg(rRegI dst, immI0 zero, rFlagsReg cr) 7798%{ 7799 match(Set dst (SubI zero dst)); 7800 effect(KILL cr); 7801 7802 format %{ "negl $dst\t# int" %} 7803 opcode(0xF7, 0x03); // Opcode F7 /3 7804 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7805 ins_pipe(ialu_reg); 7806%} 7807 7808instruct negI_mem(memory dst, immI0 zero, rFlagsReg cr) 7809%{ 7810 match(Set dst (StoreI dst (SubI zero (LoadI dst)))); 7811 effect(KILL cr); 7812 7813 format %{ "negl $dst\t# int" %} 7814 opcode(0xF7, 0x03); // Opcode F7 /3 7815 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 7816 ins_pipe(ialu_reg); 7817%} 7818 7819instruct negL_rReg(rRegL dst, immL0 zero, rFlagsReg cr) 7820%{ 7821 match(Set dst (SubL zero dst)); 7822 effect(KILL cr); 7823 7824 format %{ "negq $dst\t# long" %} 7825 opcode(0xF7, 0x03); // Opcode F7 /3 7826 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 7827 ins_pipe(ialu_reg); 7828%} 7829 7830instruct negL_mem(memory dst, immL0 zero, rFlagsReg cr) 7831%{ 7832 match(Set dst (StoreL dst (SubL zero (LoadL dst)))); 7833 effect(KILL cr); 7834 7835 format %{ "negq $dst\t# long" %} 7836 opcode(0xF7, 0x03); // Opcode F7 /3 7837 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 7838 ins_pipe(ialu_reg); 7839%} 7840 7841 7842//----------Multiplication/Division Instructions------------------------------- 7843// Integer Multiplication Instructions 7844// Multiply Register 7845 7846instruct mulI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7847%{ 7848 match(Set dst (MulI dst src)); 7849 effect(KILL cr); 7850 7851 ins_cost(300); 7852 format %{ "imull $dst, $src\t# int" %} 7853 opcode(0x0F, 0xAF); 7854 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 7855 ins_pipe(ialu_reg_reg_alu0); 7856%} 7857 7858instruct mulI_rReg_imm(rRegI dst, rRegI src, immI imm, rFlagsReg cr) 7859%{ 7860 match(Set dst (MulI src imm)); 7861 effect(KILL cr); 7862 7863 ins_cost(300); 7864 format %{ "imull $dst, $src, $imm\t# int" %} 7865 opcode(0x69); /* 69 /r id */ 7866 ins_encode(REX_reg_reg(dst, src), 7867 OpcSE(imm), reg_reg(dst, src), Con8or32(imm)); 7868 ins_pipe(ialu_reg_reg_alu0); 7869%} 7870 7871instruct mulI_mem(rRegI dst, memory src, rFlagsReg cr) 7872%{ 7873 match(Set dst (MulI dst (LoadI src))); 7874 effect(KILL cr); 7875 7876 ins_cost(350); 7877 format %{ "imull $dst, $src\t# int" %} 7878 opcode(0x0F, 0xAF); 7879 ins_encode(REX_reg_mem(dst, src), OpcP, OpcS, reg_mem(dst, src)); 7880 ins_pipe(ialu_reg_mem_alu0); 7881%} 7882 7883instruct mulI_mem_imm(rRegI dst, memory src, immI imm, rFlagsReg cr) 7884%{ 7885 match(Set dst (MulI (LoadI src) imm)); 7886 effect(KILL cr); 7887 7888 ins_cost(300); 7889 format %{ "imull $dst, $src, $imm\t# int" %} 7890 opcode(0x69); /* 69 /r id */ 7891 ins_encode(REX_reg_mem(dst, src), 7892 OpcSE(imm), reg_mem(dst, src), Con8or32(imm)); 7893 ins_pipe(ialu_reg_mem_alu0); 7894%} 7895 7896instruct mulL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7897%{ 7898 match(Set dst (MulL dst src)); 7899 effect(KILL cr); 7900 7901 ins_cost(300); 7902 format %{ "imulq $dst, $src\t# long" %} 7903 opcode(0x0F, 0xAF); 7904 ins_encode(REX_reg_reg_wide(dst, src), OpcP, OpcS, reg_reg(dst, src)); 7905 ins_pipe(ialu_reg_reg_alu0); 7906%} 7907 7908instruct mulL_rReg_imm(rRegL dst, rRegL src, immL32 imm, rFlagsReg cr) 7909%{ 7910 match(Set dst (MulL src imm)); 7911 effect(KILL cr); 7912 7913 ins_cost(300); 7914 format %{ "imulq $dst, $src, $imm\t# long" %} 7915 opcode(0x69); /* 69 /r id */ 7916 ins_encode(REX_reg_reg_wide(dst, src), 7917 OpcSE(imm), reg_reg(dst, src), Con8or32(imm)); 7918 ins_pipe(ialu_reg_reg_alu0); 7919%} 7920 7921instruct mulL_mem(rRegL dst, memory src, rFlagsReg cr) 7922%{ 7923 match(Set dst (MulL dst (LoadL src))); 7924 effect(KILL cr); 7925 7926 ins_cost(350); 7927 format %{ "imulq $dst, $src\t# long" %} 7928 opcode(0x0F, 0xAF); 7929 ins_encode(REX_reg_mem_wide(dst, src), OpcP, OpcS, reg_mem(dst, src)); 7930 ins_pipe(ialu_reg_mem_alu0); 7931%} 7932 7933instruct mulL_mem_imm(rRegL dst, memory src, immL32 imm, rFlagsReg cr) 7934%{ 7935 match(Set dst (MulL (LoadL src) imm)); 7936 effect(KILL cr); 7937 7938 ins_cost(300); 7939 format %{ "imulq $dst, $src, $imm\t# long" %} 7940 opcode(0x69); /* 69 /r id */ 7941 ins_encode(REX_reg_mem_wide(dst, src), 7942 OpcSE(imm), reg_mem(dst, src), Con8or32(imm)); 7943 ins_pipe(ialu_reg_mem_alu0); 7944%} 7945 7946instruct mulHiL_rReg(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr) 7947%{ 7948 match(Set dst (MulHiL src rax)); 7949 effect(USE_KILL rax, KILL cr); 7950 7951 ins_cost(300); 7952 format %{ "imulq RDX:RAX, RAX, $src\t# mulhi" %} 7953 opcode(0xF7, 0x5); /* Opcode F7 /5 */ 7954 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); 7955 ins_pipe(ialu_reg_reg_alu0); 7956%} 7957 7958instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 7959 rFlagsReg cr) 7960%{ 7961 match(Set rax (DivI rax div)); 7962 effect(KILL rdx, KILL cr); 7963 7964 ins_cost(30*100+10*100); // XXX 7965 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 7966 "jne,s normal\n\t" 7967 "xorl rdx, rdx\n\t" 7968 "cmpl $div, -1\n\t" 7969 "je,s done\n" 7970 "normal: cdql\n\t" 7971 "idivl $div\n" 7972 "done:" %} 7973 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 7974 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 7975 ins_pipe(ialu_reg_reg_alu0); 7976%} 7977 7978instruct divL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 7979 rFlagsReg cr) 7980%{ 7981 match(Set rax (DivL rax div)); 7982 effect(KILL rdx, KILL cr); 7983 7984 ins_cost(30*100+10*100); // XXX 7985 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 7986 "cmpq rax, rdx\n\t" 7987 "jne,s normal\n\t" 7988 "xorl rdx, rdx\n\t" 7989 "cmpq $div, -1\n\t" 7990 "je,s done\n" 7991 "normal: cdqq\n\t" 7992 "idivq $div\n" 7993 "done:" %} 7994 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 7995 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 7996 ins_pipe(ialu_reg_reg_alu0); 7997%} 7998 7999// Integer DIVMOD with Register, both quotient and mod results 8000instruct divModI_rReg_divmod(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 8001 rFlagsReg cr) 8002%{ 8003 match(DivModI rax div); 8004 effect(KILL cr); 8005 8006 ins_cost(30*100+10*100); // XXX 8007 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 8008 "jne,s normal\n\t" 8009 "xorl rdx, rdx\n\t" 8010 "cmpl $div, -1\n\t" 8011 "je,s done\n" 8012 "normal: cdql\n\t" 8013 "idivl $div\n" 8014 "done:" %} 8015 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8016 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8017 ins_pipe(pipe_slow); 8018%} 8019 8020// Long DIVMOD with Register, both quotient and mod results 8021instruct divModL_rReg_divmod(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 8022 rFlagsReg cr) 8023%{ 8024 match(DivModL rax div); 8025 effect(KILL cr); 8026 8027 ins_cost(30*100+10*100); // XXX 8028 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 8029 "cmpq rax, rdx\n\t" 8030 "jne,s normal\n\t" 8031 "xorl rdx, rdx\n\t" 8032 "cmpq $div, -1\n\t" 8033 "je,s done\n" 8034 "normal: cdqq\n\t" 8035 "idivq $div\n" 8036 "done:" %} 8037 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8038 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8039 ins_pipe(pipe_slow); 8040%} 8041 8042//----------- DivL-By-Constant-Expansions-------------------------------------- 8043// DivI cases are handled by the compiler 8044 8045// Magic constant, reciprocal of 10 8046instruct loadConL_0x6666666666666667(rRegL dst) 8047%{ 8048 effect(DEF dst); 8049 8050 format %{ "movq $dst, #0x666666666666667\t# Used in div-by-10" %} 8051 ins_encode(load_immL(dst, 0x6666666666666667)); 8052 ins_pipe(ialu_reg); 8053%} 8054 8055instruct mul_hi(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr) 8056%{ 8057 effect(DEF dst, USE src, USE_KILL rax, KILL cr); 8058 8059 format %{ "imulq rdx:rax, rax, $src\t# Used in div-by-10" %} 8060 opcode(0xF7, 0x5); /* Opcode F7 /5 */ 8061 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); 8062 ins_pipe(ialu_reg_reg_alu0); 8063%} 8064 8065instruct sarL_rReg_63(rRegL dst, rFlagsReg cr) 8066%{ 8067 effect(USE_DEF dst, KILL cr); 8068 8069 format %{ "sarq $dst, #63\t# Used in div-by-10" %} 8070 opcode(0xC1, 0x7); /* C1 /7 ib */ 8071 ins_encode(reg_opc_imm_wide(dst, 0x3F)); 8072 ins_pipe(ialu_reg); 8073%} 8074 8075instruct sarL_rReg_2(rRegL dst, rFlagsReg cr) 8076%{ 8077 effect(USE_DEF dst, KILL cr); 8078 8079 format %{ "sarq $dst, #2\t# Used in div-by-10" %} 8080 opcode(0xC1, 0x7); /* C1 /7 ib */ 8081 ins_encode(reg_opc_imm_wide(dst, 0x2)); 8082 ins_pipe(ialu_reg); 8083%} 8084 8085instruct divL_10(rdx_RegL dst, no_rax_RegL src, immL10 div) 8086%{ 8087 match(Set dst (DivL src div)); 8088 8089 ins_cost((5+8)*100); 8090 expand %{ 8091 rax_RegL rax; // Killed temp 8092 rFlagsReg cr; // Killed 8093 loadConL_0x6666666666666667(rax); // movq rax, 0x6666666666666667 8094 mul_hi(dst, src, rax, cr); // mulq rdx:rax <= rax * $src 8095 sarL_rReg_63(src, cr); // sarq src, 63 8096 sarL_rReg_2(dst, cr); // sarq rdx, 2 8097 subL_rReg(dst, src, cr); // subl rdx, src 8098 %} 8099%} 8100 8101//----------------------------------------------------------------------------- 8102 8103instruct modI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, 8104 rFlagsReg cr) 8105%{ 8106 match(Set rdx (ModI rax div)); 8107 effect(KILL rax, KILL cr); 8108 8109 ins_cost(300); // XXX 8110 format %{ "cmpl rax, 0x80000000\t# irem\n\t" 8111 "jne,s normal\n\t" 8112 "xorl rdx, rdx\n\t" 8113 "cmpl $div, -1\n\t" 8114 "je,s done\n" 8115 "normal: cdql\n\t" 8116 "idivl $div\n" 8117 "done:" %} 8118 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8119 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8120 ins_pipe(ialu_reg_reg_alu0); 8121%} 8122 8123instruct modL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, 8124 rFlagsReg cr) 8125%{ 8126 match(Set rdx (ModL rax div)); 8127 effect(KILL rax, KILL cr); 8128 8129 ins_cost(300); // XXX 8130 format %{ "movq rdx, 0x8000000000000000\t# lrem\n\t" 8131 "cmpq rax, rdx\n\t" 8132 "jne,s normal\n\t" 8133 "xorl rdx, rdx\n\t" 8134 "cmpq $div, -1\n\t" 8135 "je,s done\n" 8136 "normal: cdqq\n\t" 8137 "idivq $div\n" 8138 "done:" %} 8139 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8140 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8141 ins_pipe(ialu_reg_reg_alu0); 8142%} 8143 8144// Integer Shift Instructions 8145// Shift Left by one 8146instruct salI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8147%{ 8148 match(Set dst (LShiftI dst shift)); 8149 effect(KILL cr); 8150 8151 format %{ "sall $dst, $shift" %} 8152 opcode(0xD1, 0x4); /* D1 /4 */ 8153 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8154 ins_pipe(ialu_reg); 8155%} 8156 8157// Shift Left by one 8158instruct salI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8159%{ 8160 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8161 effect(KILL cr); 8162 8163 format %{ "sall $dst, $shift\t" %} 8164 opcode(0xD1, 0x4); /* D1 /4 */ 8165 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8166 ins_pipe(ialu_mem_imm); 8167%} 8168 8169// Shift Left by 8-bit immediate 8170instruct salI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8171%{ 8172 match(Set dst (LShiftI dst shift)); 8173 effect(KILL cr); 8174 8175 format %{ "sall $dst, $shift" %} 8176 opcode(0xC1, 0x4); /* C1 /4 ib */ 8177 ins_encode(reg_opc_imm(dst, shift)); 8178 ins_pipe(ialu_reg); 8179%} 8180 8181// Shift Left by 8-bit immediate 8182instruct salI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8183%{ 8184 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8185 effect(KILL cr); 8186 8187 format %{ "sall $dst, $shift" %} 8188 opcode(0xC1, 0x4); /* C1 /4 ib */ 8189 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8190 ins_pipe(ialu_mem_imm); 8191%} 8192 8193// Shift Left by variable 8194instruct salI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8195%{ 8196 match(Set dst (LShiftI dst shift)); 8197 effect(KILL cr); 8198 8199 format %{ "sall $dst, $shift" %} 8200 opcode(0xD3, 0x4); /* D3 /4 */ 8201 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8202 ins_pipe(ialu_reg_reg); 8203%} 8204 8205// Shift Left by variable 8206instruct salI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8207%{ 8208 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8209 effect(KILL cr); 8210 8211 format %{ "sall $dst, $shift" %} 8212 opcode(0xD3, 0x4); /* D3 /4 */ 8213 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8214 ins_pipe(ialu_mem_reg); 8215%} 8216 8217// Arithmetic shift right by one 8218instruct sarI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8219%{ 8220 match(Set dst (RShiftI dst shift)); 8221 effect(KILL cr); 8222 8223 format %{ "sarl $dst, $shift" %} 8224 opcode(0xD1, 0x7); /* D1 /7 */ 8225 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8226 ins_pipe(ialu_reg); 8227%} 8228 8229// Arithmetic shift right by one 8230instruct sarI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8231%{ 8232 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8233 effect(KILL cr); 8234 8235 format %{ "sarl $dst, $shift" %} 8236 opcode(0xD1, 0x7); /* D1 /7 */ 8237 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8238 ins_pipe(ialu_mem_imm); 8239%} 8240 8241// Arithmetic Shift Right by 8-bit immediate 8242instruct sarI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8243%{ 8244 match(Set dst (RShiftI dst shift)); 8245 effect(KILL cr); 8246 8247 format %{ "sarl $dst, $shift" %} 8248 opcode(0xC1, 0x7); /* C1 /7 ib */ 8249 ins_encode(reg_opc_imm(dst, shift)); 8250 ins_pipe(ialu_mem_imm); 8251%} 8252 8253// Arithmetic Shift Right by 8-bit immediate 8254instruct sarI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8255%{ 8256 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8257 effect(KILL cr); 8258 8259 format %{ "sarl $dst, $shift" %} 8260 opcode(0xC1, 0x7); /* C1 /7 ib */ 8261 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8262 ins_pipe(ialu_mem_imm); 8263%} 8264 8265// Arithmetic Shift Right by variable 8266instruct sarI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8267%{ 8268 match(Set dst (RShiftI dst shift)); 8269 effect(KILL cr); 8270 8271 format %{ "sarl $dst, $shift" %} 8272 opcode(0xD3, 0x7); /* D3 /7 */ 8273 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8274 ins_pipe(ialu_reg_reg); 8275%} 8276 8277// Arithmetic Shift Right by variable 8278instruct sarI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8279%{ 8280 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8281 effect(KILL cr); 8282 8283 format %{ "sarl $dst, $shift" %} 8284 opcode(0xD3, 0x7); /* D3 /7 */ 8285 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8286 ins_pipe(ialu_mem_reg); 8287%} 8288 8289// Logical shift right by one 8290instruct shrI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8291%{ 8292 match(Set dst (URShiftI dst shift)); 8293 effect(KILL cr); 8294 8295 format %{ "shrl $dst, $shift" %} 8296 opcode(0xD1, 0x5); /* D1 /5 */ 8297 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8298 ins_pipe(ialu_reg); 8299%} 8300 8301// Logical shift right by one 8302instruct shrI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8303%{ 8304 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8305 effect(KILL cr); 8306 8307 format %{ "shrl $dst, $shift" %} 8308 opcode(0xD1, 0x5); /* D1 /5 */ 8309 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8310 ins_pipe(ialu_mem_imm); 8311%} 8312 8313// Logical Shift Right by 8-bit immediate 8314instruct shrI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8315%{ 8316 match(Set dst (URShiftI dst shift)); 8317 effect(KILL cr); 8318 8319 format %{ "shrl $dst, $shift" %} 8320 opcode(0xC1, 0x5); /* C1 /5 ib */ 8321 ins_encode(reg_opc_imm(dst, shift)); 8322 ins_pipe(ialu_reg); 8323%} 8324 8325// Logical Shift Right by 8-bit immediate 8326instruct shrI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8327%{ 8328 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8329 effect(KILL cr); 8330 8331 format %{ "shrl $dst, $shift" %} 8332 opcode(0xC1, 0x5); /* C1 /5 ib */ 8333 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8334 ins_pipe(ialu_mem_imm); 8335%} 8336 8337// Logical Shift Right by variable 8338instruct shrI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8339%{ 8340 match(Set dst (URShiftI dst shift)); 8341 effect(KILL cr); 8342 8343 format %{ "shrl $dst, $shift" %} 8344 opcode(0xD3, 0x5); /* D3 /5 */ 8345 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8346 ins_pipe(ialu_reg_reg); 8347%} 8348 8349// Logical Shift Right by variable 8350instruct shrI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8351%{ 8352 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8353 effect(KILL cr); 8354 8355 format %{ "shrl $dst, $shift" %} 8356 opcode(0xD3, 0x5); /* D3 /5 */ 8357 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8358 ins_pipe(ialu_mem_reg); 8359%} 8360 8361// Long Shift Instructions 8362// Shift Left by one 8363instruct salL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8364%{ 8365 match(Set dst (LShiftL dst shift)); 8366 effect(KILL cr); 8367 8368 format %{ "salq $dst, $shift" %} 8369 opcode(0xD1, 0x4); /* D1 /4 */ 8370 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8371 ins_pipe(ialu_reg); 8372%} 8373 8374// Shift Left by one 8375instruct salL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8376%{ 8377 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8378 effect(KILL cr); 8379 8380 format %{ "salq $dst, $shift" %} 8381 opcode(0xD1, 0x4); /* D1 /4 */ 8382 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8383 ins_pipe(ialu_mem_imm); 8384%} 8385 8386// Shift Left by 8-bit immediate 8387instruct salL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8388%{ 8389 match(Set dst (LShiftL dst shift)); 8390 effect(KILL cr); 8391 8392 format %{ "salq $dst, $shift" %} 8393 opcode(0xC1, 0x4); /* C1 /4 ib */ 8394 ins_encode(reg_opc_imm_wide(dst, shift)); 8395 ins_pipe(ialu_reg); 8396%} 8397 8398// Shift Left by 8-bit immediate 8399instruct salL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8400%{ 8401 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8402 effect(KILL cr); 8403 8404 format %{ "salq $dst, $shift" %} 8405 opcode(0xC1, 0x4); /* C1 /4 ib */ 8406 ins_encode(REX_mem_wide(dst), OpcP, 8407 RM_opc_mem(secondary, dst), Con8or32(shift)); 8408 ins_pipe(ialu_mem_imm); 8409%} 8410 8411// Shift Left by variable 8412instruct salL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8413%{ 8414 match(Set dst (LShiftL dst shift)); 8415 effect(KILL cr); 8416 8417 format %{ "salq $dst, $shift" %} 8418 opcode(0xD3, 0x4); /* D3 /4 */ 8419 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8420 ins_pipe(ialu_reg_reg); 8421%} 8422 8423// Shift Left by variable 8424instruct salL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8425%{ 8426 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8427 effect(KILL cr); 8428 8429 format %{ "salq $dst, $shift" %} 8430 opcode(0xD3, 0x4); /* D3 /4 */ 8431 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8432 ins_pipe(ialu_mem_reg); 8433%} 8434 8435// Arithmetic shift right by one 8436instruct sarL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8437%{ 8438 match(Set dst (RShiftL dst shift)); 8439 effect(KILL cr); 8440 8441 format %{ "sarq $dst, $shift" %} 8442 opcode(0xD1, 0x7); /* D1 /7 */ 8443 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8444 ins_pipe(ialu_reg); 8445%} 8446 8447// Arithmetic shift right by one 8448instruct sarL_mem_1(memory dst, immI1 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 opcode(0xD1, 0x7); /* D1 /7 */ 8455 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8456 ins_pipe(ialu_mem_imm); 8457%} 8458 8459// Arithmetic Shift Right by 8-bit immediate 8460instruct sarL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8461%{ 8462 match(Set dst (RShiftL dst shift)); 8463 effect(KILL cr); 8464 8465 format %{ "sarq $dst, $shift" %} 8466 opcode(0xC1, 0x7); /* C1 /7 ib */ 8467 ins_encode(reg_opc_imm_wide(dst, shift)); 8468 ins_pipe(ialu_mem_imm); 8469%} 8470 8471// Arithmetic Shift Right by 8-bit immediate 8472instruct sarL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8473%{ 8474 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8475 effect(KILL cr); 8476 8477 format %{ "sarq $dst, $shift" %} 8478 opcode(0xC1, 0x7); /* C1 /7 ib */ 8479 ins_encode(REX_mem_wide(dst), OpcP, 8480 RM_opc_mem(secondary, dst), Con8or32(shift)); 8481 ins_pipe(ialu_mem_imm); 8482%} 8483 8484// Arithmetic Shift Right by variable 8485instruct sarL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8486%{ 8487 match(Set dst (RShiftL dst shift)); 8488 effect(KILL cr); 8489 8490 format %{ "sarq $dst, $shift" %} 8491 opcode(0xD3, 0x7); /* D3 /7 */ 8492 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8493 ins_pipe(ialu_reg_reg); 8494%} 8495 8496// Arithmetic Shift Right by variable 8497instruct sarL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8498%{ 8499 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8500 effect(KILL cr); 8501 8502 format %{ "sarq $dst, $shift" %} 8503 opcode(0xD3, 0x7); /* D3 /7 */ 8504 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8505 ins_pipe(ialu_mem_reg); 8506%} 8507 8508// Logical shift right by one 8509instruct shrL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8510%{ 8511 match(Set dst (URShiftL dst shift)); 8512 effect(KILL cr); 8513 8514 format %{ "shrq $dst, $shift" %} 8515 opcode(0xD1, 0x5); /* D1 /5 */ 8516 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst )); 8517 ins_pipe(ialu_reg); 8518%} 8519 8520// Logical shift right by one 8521instruct shrL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8522%{ 8523 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8524 effect(KILL cr); 8525 8526 format %{ "shrq $dst, $shift" %} 8527 opcode(0xD1, 0x5); /* D1 /5 */ 8528 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8529 ins_pipe(ialu_mem_imm); 8530%} 8531 8532// Logical Shift Right by 8-bit immediate 8533instruct shrL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8534%{ 8535 match(Set dst (URShiftL dst shift)); 8536 effect(KILL cr); 8537 8538 format %{ "shrq $dst, $shift" %} 8539 opcode(0xC1, 0x5); /* C1 /5 ib */ 8540 ins_encode(reg_opc_imm_wide(dst, shift)); 8541 ins_pipe(ialu_reg); 8542%} 8543 8544 8545// Logical Shift Right by 8-bit immediate 8546instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8547%{ 8548 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8549 effect(KILL cr); 8550 8551 format %{ "shrq $dst, $shift" %} 8552 opcode(0xC1, 0x5); /* C1 /5 ib */ 8553 ins_encode(REX_mem_wide(dst), OpcP, 8554 RM_opc_mem(secondary, dst), Con8or32(shift)); 8555 ins_pipe(ialu_mem_imm); 8556%} 8557 8558// Logical Shift Right by variable 8559instruct shrL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8560%{ 8561 match(Set dst (URShiftL dst shift)); 8562 effect(KILL cr); 8563 8564 format %{ "shrq $dst, $shift" %} 8565 opcode(0xD3, 0x5); /* D3 /5 */ 8566 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8567 ins_pipe(ialu_reg_reg); 8568%} 8569 8570// Logical Shift Right by variable 8571instruct shrL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8572%{ 8573 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8574 effect(KILL cr); 8575 8576 format %{ "shrq $dst, $shift" %} 8577 opcode(0xD3, 0x5); /* D3 /5 */ 8578 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8579 ins_pipe(ialu_mem_reg); 8580%} 8581 8582// Logical Shift Right by 24, followed by Arithmetic Shift Left by 24. 8583// This idiom is used by the compiler for the i2b bytecode. 8584instruct i2b(rRegI dst, rRegI src, immI_24 twentyfour) 8585%{ 8586 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour)); 8587 8588 format %{ "movsbl $dst, $src\t# i2b" %} 8589 opcode(0x0F, 0xBE); 8590 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8591 ins_pipe(ialu_reg_reg); 8592%} 8593 8594// Logical Shift Right by 16, followed by Arithmetic Shift Left by 16. 8595// This idiom is used by the compiler the i2s bytecode. 8596instruct i2s(rRegI dst, rRegI src, immI_16 sixteen) 8597%{ 8598 match(Set dst (RShiftI (LShiftI src sixteen) sixteen)); 8599 8600 format %{ "movswl $dst, $src\t# i2s" %} 8601 opcode(0x0F, 0xBF); 8602 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8603 ins_pipe(ialu_reg_reg); 8604%} 8605 8606// ROL/ROR instructions 8607 8608// ROL expand 8609instruct rolI_rReg_imm1(rRegI dst, rFlagsReg cr) %{ 8610 effect(KILL cr, USE_DEF dst); 8611 8612 format %{ "roll $dst" %} 8613 opcode(0xD1, 0x0); /* Opcode D1 /0 */ 8614 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8615 ins_pipe(ialu_reg); 8616%} 8617 8618instruct rolI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) %{ 8619 effect(USE_DEF dst, USE shift, KILL cr); 8620 8621 format %{ "roll $dst, $shift" %} 8622 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */ 8623 ins_encode( reg_opc_imm(dst, shift) ); 8624 ins_pipe(ialu_reg); 8625%} 8626 8627instruct rolI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr) 8628%{ 8629 effect(USE_DEF dst, USE shift, KILL cr); 8630 8631 format %{ "roll $dst, $shift" %} 8632 opcode(0xD3, 0x0); /* Opcode D3 /0 */ 8633 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8634 ins_pipe(ialu_reg_reg); 8635%} 8636// end of ROL expand 8637 8638// Rotate Left by one 8639instruct rolI_rReg_i1(rRegI dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr) 8640%{ 8641 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift))); 8642 8643 expand %{ 8644 rolI_rReg_imm1(dst, cr); 8645 %} 8646%} 8647 8648// Rotate Left by 8-bit immediate 8649instruct rolI_rReg_i8(rRegI dst, immI8 lshift, immI8 rshift, rFlagsReg cr) 8650%{ 8651 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 8652 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift))); 8653 8654 expand %{ 8655 rolI_rReg_imm8(dst, lshift, cr); 8656 %} 8657%} 8658 8659// Rotate Left by variable 8660instruct rolI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 8661%{ 8662 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI zero shift)))); 8663 8664 expand %{ 8665 rolI_rReg_CL(dst, shift, cr); 8666 %} 8667%} 8668 8669// Rotate Left by variable 8670instruct rolI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr) 8671%{ 8672 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI c32 shift)))); 8673 8674 expand %{ 8675 rolI_rReg_CL(dst, shift, cr); 8676 %} 8677%} 8678 8679// ROR expand 8680instruct rorI_rReg_imm1(rRegI dst, rFlagsReg cr) 8681%{ 8682 effect(USE_DEF dst, KILL cr); 8683 8684 format %{ "rorl $dst" %} 8685 opcode(0xD1, 0x1); /* D1 /1 */ 8686 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8687 ins_pipe(ialu_reg); 8688%} 8689 8690instruct rorI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) 8691%{ 8692 effect(USE_DEF dst, USE shift, KILL cr); 8693 8694 format %{ "rorl $dst, $shift" %} 8695 opcode(0xC1, 0x1); /* C1 /1 ib */ 8696 ins_encode(reg_opc_imm(dst, shift)); 8697 ins_pipe(ialu_reg); 8698%} 8699 8700instruct rorI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr) 8701%{ 8702 effect(USE_DEF dst, USE shift, KILL cr); 8703 8704 format %{ "rorl $dst, $shift" %} 8705 opcode(0xD3, 0x1); /* D3 /1 */ 8706 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8707 ins_pipe(ialu_reg_reg); 8708%} 8709// end of ROR expand 8710 8711// Rotate Right by one 8712instruct rorI_rReg_i1(rRegI dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr) 8713%{ 8714 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift))); 8715 8716 expand %{ 8717 rorI_rReg_imm1(dst, cr); 8718 %} 8719%} 8720 8721// Rotate Right by 8-bit immediate 8722instruct rorI_rReg_i8(rRegI dst, immI8 rshift, immI8 lshift, rFlagsReg cr) 8723%{ 8724 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 8725 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift))); 8726 8727 expand %{ 8728 rorI_rReg_imm8(dst, rshift, cr); 8729 %} 8730%} 8731 8732// Rotate Right by variable 8733instruct rorI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 8734%{ 8735 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI zero shift)))); 8736 8737 expand %{ 8738 rorI_rReg_CL(dst, shift, cr); 8739 %} 8740%} 8741 8742// Rotate Right by variable 8743instruct rorI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr) 8744%{ 8745 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI c32 shift)))); 8746 8747 expand %{ 8748 rorI_rReg_CL(dst, shift, cr); 8749 %} 8750%} 8751 8752// for long rotate 8753// ROL expand 8754instruct rolL_rReg_imm1(rRegL dst, rFlagsReg cr) %{ 8755 effect(USE_DEF dst, KILL cr); 8756 8757 format %{ "rolq $dst" %} 8758 opcode(0xD1, 0x0); /* Opcode D1 /0 */ 8759 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8760 ins_pipe(ialu_reg); 8761%} 8762 8763instruct rolL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) %{ 8764 effect(USE_DEF dst, USE shift, KILL cr); 8765 8766 format %{ "rolq $dst, $shift" %} 8767 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */ 8768 ins_encode( reg_opc_imm_wide(dst, shift) ); 8769 ins_pipe(ialu_reg); 8770%} 8771 8772instruct rolL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr) 8773%{ 8774 effect(USE_DEF dst, USE shift, KILL cr); 8775 8776 format %{ "rolq $dst, $shift" %} 8777 opcode(0xD3, 0x0); /* Opcode D3 /0 */ 8778 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8779 ins_pipe(ialu_reg_reg); 8780%} 8781// end of ROL expand 8782 8783// Rotate Left by one 8784instruct rolL_rReg_i1(rRegL dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr) 8785%{ 8786 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift))); 8787 8788 expand %{ 8789 rolL_rReg_imm1(dst, cr); 8790 %} 8791%} 8792 8793// Rotate Left by 8-bit immediate 8794instruct rolL_rReg_i8(rRegL dst, immI8 lshift, immI8 rshift, rFlagsReg cr) 8795%{ 8796 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f)); 8797 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift))); 8798 8799 expand %{ 8800 rolL_rReg_imm8(dst, lshift, cr); 8801 %} 8802%} 8803 8804// Rotate Left by variable 8805instruct rolL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 8806%{ 8807 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI zero shift)))); 8808 8809 expand %{ 8810 rolL_rReg_CL(dst, shift, cr); 8811 %} 8812%} 8813 8814// Rotate Left by variable 8815instruct rolL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr) 8816%{ 8817 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI c64 shift)))); 8818 8819 expand %{ 8820 rolL_rReg_CL(dst, shift, cr); 8821 %} 8822%} 8823 8824// ROR expand 8825instruct rorL_rReg_imm1(rRegL dst, rFlagsReg cr) 8826%{ 8827 effect(USE_DEF dst, KILL cr); 8828 8829 format %{ "rorq $dst" %} 8830 opcode(0xD1, 0x1); /* D1 /1 */ 8831 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8832 ins_pipe(ialu_reg); 8833%} 8834 8835instruct rorL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) 8836%{ 8837 effect(USE_DEF dst, USE shift, KILL cr); 8838 8839 format %{ "rorq $dst, $shift" %} 8840 opcode(0xC1, 0x1); /* C1 /1 ib */ 8841 ins_encode(reg_opc_imm_wide(dst, shift)); 8842 ins_pipe(ialu_reg); 8843%} 8844 8845instruct rorL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr) 8846%{ 8847 effect(USE_DEF dst, USE shift, KILL cr); 8848 8849 format %{ "rorq $dst, $shift" %} 8850 opcode(0xD3, 0x1); /* D3 /1 */ 8851 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8852 ins_pipe(ialu_reg_reg); 8853%} 8854// end of ROR expand 8855 8856// Rotate Right by one 8857instruct rorL_rReg_i1(rRegL dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr) 8858%{ 8859 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift))); 8860 8861 expand %{ 8862 rorL_rReg_imm1(dst, cr); 8863 %} 8864%} 8865 8866// Rotate Right by 8-bit immediate 8867instruct rorL_rReg_i8(rRegL dst, immI8 rshift, immI8 lshift, rFlagsReg cr) 8868%{ 8869 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f)); 8870 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift))); 8871 8872 expand %{ 8873 rorL_rReg_imm8(dst, rshift, cr); 8874 %} 8875%} 8876 8877// Rotate Right by variable 8878instruct rorL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 8879%{ 8880 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI zero shift)))); 8881 8882 expand %{ 8883 rorL_rReg_CL(dst, shift, cr); 8884 %} 8885%} 8886 8887// Rotate Right by variable 8888instruct rorL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr) 8889%{ 8890 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI c64 shift)))); 8891 8892 expand %{ 8893 rorL_rReg_CL(dst, shift, cr); 8894 %} 8895%} 8896 8897// Logical Instructions 8898 8899// Integer Logical Instructions 8900 8901// And Instructions 8902// And Register with Register 8903instruct andI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8904%{ 8905 match(Set dst (AndI dst src)); 8906 effect(KILL cr); 8907 8908 format %{ "andl $dst, $src\t# int" %} 8909 opcode(0x23); 8910 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 8911 ins_pipe(ialu_reg_reg); 8912%} 8913 8914// And Register with Immediate 255 8915instruct andI_rReg_imm255(rRegI dst, immI_255 src) 8916%{ 8917 match(Set dst (AndI dst src)); 8918 8919 format %{ "movzbl $dst, $dst\t# int & 0xFF" %} 8920 opcode(0x0F, 0xB6); 8921 ins_encode(REX_reg_breg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 8922 ins_pipe(ialu_reg); 8923%} 8924 8925// And Register with Immediate 255 and promote to long 8926instruct andI2L_rReg_imm255(rRegL dst, rRegI src, immI_255 mask) 8927%{ 8928 match(Set dst (ConvI2L (AndI src mask))); 8929 8930 format %{ "movzbl $dst, $src\t# int & 0xFF -> long" %} 8931 opcode(0x0F, 0xB6); 8932 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8933 ins_pipe(ialu_reg); 8934%} 8935 8936// And Register with Immediate 65535 8937instruct andI_rReg_imm65535(rRegI dst, immI_65535 src) 8938%{ 8939 match(Set dst (AndI dst src)); 8940 8941 format %{ "movzwl $dst, $dst\t# int & 0xFFFF" %} 8942 opcode(0x0F, 0xB7); 8943 ins_encode(REX_reg_reg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 8944 ins_pipe(ialu_reg); 8945%} 8946 8947// And Register with Immediate 65535 and promote to long 8948instruct andI2L_rReg_imm65535(rRegL dst, rRegI src, immI_65535 mask) 8949%{ 8950 match(Set dst (ConvI2L (AndI src mask))); 8951 8952 format %{ "movzwl $dst, $src\t# int & 0xFFFF -> long" %} 8953 opcode(0x0F, 0xB7); 8954 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8955 ins_pipe(ialu_reg); 8956%} 8957 8958// And Register with Immediate 8959instruct andI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 8960%{ 8961 match(Set dst (AndI dst src)); 8962 effect(KILL cr); 8963 8964 format %{ "andl $dst, $src\t# int" %} 8965 opcode(0x81, 0x04); /* Opcode 81 /4 */ 8966 ins_encode(OpcSErm(dst, src), Con8or32(src)); 8967 ins_pipe(ialu_reg); 8968%} 8969 8970// And Register with Memory 8971instruct andI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 8972%{ 8973 match(Set dst (AndI dst (LoadI src))); 8974 effect(KILL cr); 8975 8976 ins_cost(125); 8977 format %{ "andl $dst, $src\t# int" %} 8978 opcode(0x23); 8979 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 8980 ins_pipe(ialu_reg_mem); 8981%} 8982 8983// And Memory with Register 8984instruct andI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 8985%{ 8986 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 8987 effect(KILL cr); 8988 8989 ins_cost(150); 8990 format %{ "andl $dst, $src\t# int" %} 8991 opcode(0x21); /* Opcode 21 /r */ 8992 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 8993 ins_pipe(ialu_mem_reg); 8994%} 8995 8996// And Memory with Immediate 8997instruct andI_mem_imm(memory dst, immI src, rFlagsReg cr) 8998%{ 8999 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 9000 effect(KILL cr); 9001 9002 ins_cost(125); 9003 format %{ "andl $dst, $src\t# int" %} 9004 opcode(0x81, 0x4); /* Opcode 81 /4 id */ 9005 ins_encode(REX_mem(dst), OpcSE(src), 9006 RM_opc_mem(secondary, dst), Con8or32(src)); 9007 ins_pipe(ialu_mem_imm); 9008%} 9009 9010// Or Instructions 9011// Or Register with Register 9012instruct orI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9013%{ 9014 match(Set dst (OrI dst src)); 9015 effect(KILL cr); 9016 9017 format %{ "orl $dst, $src\t# int" %} 9018 opcode(0x0B); 9019 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9020 ins_pipe(ialu_reg_reg); 9021%} 9022 9023// Or Register with Immediate 9024instruct orI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9025%{ 9026 match(Set dst (OrI dst src)); 9027 effect(KILL cr); 9028 9029 format %{ "orl $dst, $src\t# int" %} 9030 opcode(0x81, 0x01); /* Opcode 81 /1 id */ 9031 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9032 ins_pipe(ialu_reg); 9033%} 9034 9035// Or Register with Memory 9036instruct orI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9037%{ 9038 match(Set dst (OrI dst (LoadI src))); 9039 effect(KILL cr); 9040 9041 ins_cost(125); 9042 format %{ "orl $dst, $src\t# int" %} 9043 opcode(0x0B); 9044 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9045 ins_pipe(ialu_reg_mem); 9046%} 9047 9048// Or Memory with Register 9049instruct orI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9050%{ 9051 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9052 effect(KILL cr); 9053 9054 ins_cost(150); 9055 format %{ "orl $dst, $src\t# int" %} 9056 opcode(0x09); /* Opcode 09 /r */ 9057 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9058 ins_pipe(ialu_mem_reg); 9059%} 9060 9061// Or Memory with Immediate 9062instruct orI_mem_imm(memory dst, immI src, rFlagsReg cr) 9063%{ 9064 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9065 effect(KILL cr); 9066 9067 ins_cost(125); 9068 format %{ "orl $dst, $src\t# int" %} 9069 opcode(0x81, 0x1); /* Opcode 81 /1 id */ 9070 ins_encode(REX_mem(dst), OpcSE(src), 9071 RM_opc_mem(secondary, dst), Con8or32(src)); 9072 ins_pipe(ialu_mem_imm); 9073%} 9074 9075// Xor Instructions 9076// Xor Register with Register 9077instruct xorI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9078%{ 9079 match(Set dst (XorI dst src)); 9080 effect(KILL cr); 9081 9082 format %{ "xorl $dst, $src\t# int" %} 9083 opcode(0x33); 9084 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9085 ins_pipe(ialu_reg_reg); 9086%} 9087 9088// Xor Register with Immediate -1 9089instruct xorI_rReg_im1(rRegI dst, immI_M1 imm) %{ 9090 match(Set dst (XorI dst imm)); 9091 9092 format %{ "not $dst" %} 9093 ins_encode %{ 9094 __ notl($dst$$Register); 9095 %} 9096 ins_pipe(ialu_reg); 9097%} 9098 9099// Xor Register with Immediate 9100instruct xorI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9101%{ 9102 match(Set dst (XorI dst src)); 9103 effect(KILL cr); 9104 9105 format %{ "xorl $dst, $src\t# int" %} 9106 opcode(0x81, 0x06); /* Opcode 81 /6 id */ 9107 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9108 ins_pipe(ialu_reg); 9109%} 9110 9111// Xor Register with Memory 9112instruct xorI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9113%{ 9114 match(Set dst (XorI dst (LoadI src))); 9115 effect(KILL cr); 9116 9117 ins_cost(125); 9118 format %{ "xorl $dst, $src\t# int" %} 9119 opcode(0x33); 9120 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9121 ins_pipe(ialu_reg_mem); 9122%} 9123 9124// Xor Memory with Register 9125instruct xorI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9126%{ 9127 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9128 effect(KILL cr); 9129 9130 ins_cost(150); 9131 format %{ "xorl $dst, $src\t# int" %} 9132 opcode(0x31); /* Opcode 31 /r */ 9133 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9134 ins_pipe(ialu_mem_reg); 9135%} 9136 9137// Xor Memory with Immediate 9138instruct xorI_mem_imm(memory dst, immI src, rFlagsReg cr) 9139%{ 9140 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9141 effect(KILL cr); 9142 9143 ins_cost(125); 9144 format %{ "xorl $dst, $src\t# int" %} 9145 opcode(0x81, 0x6); /* Opcode 81 /6 id */ 9146 ins_encode(REX_mem(dst), OpcSE(src), 9147 RM_opc_mem(secondary, dst), Con8or32(src)); 9148 ins_pipe(ialu_mem_imm); 9149%} 9150 9151 9152// Long Logical Instructions 9153 9154// And Instructions 9155// And Register with Register 9156instruct andL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9157%{ 9158 match(Set dst (AndL dst src)); 9159 effect(KILL cr); 9160 9161 format %{ "andq $dst, $src\t# long" %} 9162 opcode(0x23); 9163 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9164 ins_pipe(ialu_reg_reg); 9165%} 9166 9167// And Register with Immediate 255 9168instruct andL_rReg_imm255(rRegL dst, immL_255 src) 9169%{ 9170 match(Set dst (AndL dst src)); 9171 9172 format %{ "movzbq $dst, $dst\t# long & 0xFF" %} 9173 opcode(0x0F, 0xB6); 9174 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9175 ins_pipe(ialu_reg); 9176%} 9177 9178// And Register with Immediate 65535 9179instruct andL_rReg_imm65535(rRegL dst, immL_65535 src) 9180%{ 9181 match(Set dst (AndL dst src)); 9182 9183 format %{ "movzwq $dst, $dst\t# long & 0xFFFF" %} 9184 opcode(0x0F, 0xB7); 9185 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9186 ins_pipe(ialu_reg); 9187%} 9188 9189// And Register with Immediate 9190instruct andL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9191%{ 9192 match(Set dst (AndL dst src)); 9193 effect(KILL cr); 9194 9195 format %{ "andq $dst, $src\t# long" %} 9196 opcode(0x81, 0x04); /* Opcode 81 /4 */ 9197 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9198 ins_pipe(ialu_reg); 9199%} 9200 9201// And Register with Memory 9202instruct andL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9203%{ 9204 match(Set dst (AndL dst (LoadL src))); 9205 effect(KILL cr); 9206 9207 ins_cost(125); 9208 format %{ "andq $dst, $src\t# long" %} 9209 opcode(0x23); 9210 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9211 ins_pipe(ialu_reg_mem); 9212%} 9213 9214// And Memory with Register 9215instruct andL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9216%{ 9217 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9218 effect(KILL cr); 9219 9220 ins_cost(150); 9221 format %{ "andq $dst, $src\t# long" %} 9222 opcode(0x21); /* Opcode 21 /r */ 9223 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9224 ins_pipe(ialu_mem_reg); 9225%} 9226 9227// And Memory with Immediate 9228instruct andL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9229%{ 9230 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9231 effect(KILL cr); 9232 9233 ins_cost(125); 9234 format %{ "andq $dst, $src\t# long" %} 9235 opcode(0x81, 0x4); /* Opcode 81 /4 id */ 9236 ins_encode(REX_mem_wide(dst), OpcSE(src), 9237 RM_opc_mem(secondary, dst), Con8or32(src)); 9238 ins_pipe(ialu_mem_imm); 9239%} 9240 9241// Or Instructions 9242// Or Register with Register 9243instruct orL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9244%{ 9245 match(Set dst (OrL dst src)); 9246 effect(KILL cr); 9247 9248 format %{ "orq $dst, $src\t# long" %} 9249 opcode(0x0B); 9250 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9251 ins_pipe(ialu_reg_reg); 9252%} 9253 9254// Use any_RegP to match R15 (TLS register) without spilling. 9255instruct orL_rReg_castP2X(rRegL dst, any_RegP src, rFlagsReg cr) %{ 9256 match(Set dst (OrL dst (CastP2X src))); 9257 effect(KILL cr); 9258 9259 format %{ "orq $dst, $src\t# long" %} 9260 opcode(0x0B); 9261 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9262 ins_pipe(ialu_reg_reg); 9263%} 9264 9265 9266// Or Register with Immediate 9267instruct orL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9268%{ 9269 match(Set dst (OrL dst src)); 9270 effect(KILL cr); 9271 9272 format %{ "orq $dst, $src\t# long" %} 9273 opcode(0x81, 0x01); /* Opcode 81 /1 id */ 9274 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9275 ins_pipe(ialu_reg); 9276%} 9277 9278// Or Register with Memory 9279instruct orL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9280%{ 9281 match(Set dst (OrL dst (LoadL src))); 9282 effect(KILL cr); 9283 9284 ins_cost(125); 9285 format %{ "orq $dst, $src\t# long" %} 9286 opcode(0x0B); 9287 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9288 ins_pipe(ialu_reg_mem); 9289%} 9290 9291// Or Memory with Register 9292instruct orL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9293%{ 9294 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9295 effect(KILL cr); 9296 9297 ins_cost(150); 9298 format %{ "orq $dst, $src\t# long" %} 9299 opcode(0x09); /* Opcode 09 /r */ 9300 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9301 ins_pipe(ialu_mem_reg); 9302%} 9303 9304// Or Memory with Immediate 9305instruct orL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9306%{ 9307 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9308 effect(KILL cr); 9309 9310 ins_cost(125); 9311 format %{ "orq $dst, $src\t# long" %} 9312 opcode(0x81, 0x1); /* Opcode 81 /1 id */ 9313 ins_encode(REX_mem_wide(dst), OpcSE(src), 9314 RM_opc_mem(secondary, dst), Con8or32(src)); 9315 ins_pipe(ialu_mem_imm); 9316%} 9317 9318// Xor Instructions 9319// Xor Register with Register 9320instruct xorL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9321%{ 9322 match(Set dst (XorL dst src)); 9323 effect(KILL cr); 9324 9325 format %{ "xorq $dst, $src\t# long" %} 9326 opcode(0x33); 9327 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9328 ins_pipe(ialu_reg_reg); 9329%} 9330 9331// Xor Register with Immediate -1 9332instruct xorL_rReg_im1(rRegL dst, immL_M1 imm) %{ 9333 match(Set dst (XorL dst imm)); 9334 9335 format %{ "notq $dst" %} 9336 ins_encode %{ 9337 __ notq($dst$$Register); 9338 %} 9339 ins_pipe(ialu_reg); 9340%} 9341 9342// Xor Register with Immediate 9343instruct xorL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9344%{ 9345 match(Set dst (XorL dst src)); 9346 effect(KILL cr); 9347 9348 format %{ "xorq $dst, $src\t# long" %} 9349 opcode(0x81, 0x06); /* Opcode 81 /6 id */ 9350 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9351 ins_pipe(ialu_reg); 9352%} 9353 9354// Xor Register with Memory 9355instruct xorL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9356%{ 9357 match(Set dst (XorL dst (LoadL src))); 9358 effect(KILL cr); 9359 9360 ins_cost(125); 9361 format %{ "xorq $dst, $src\t# long" %} 9362 opcode(0x33); 9363 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9364 ins_pipe(ialu_reg_mem); 9365%} 9366 9367// Xor Memory with Register 9368instruct xorL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9369%{ 9370 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 9371 effect(KILL cr); 9372 9373 ins_cost(150); 9374 format %{ "xorq $dst, $src\t# long" %} 9375 opcode(0x31); /* Opcode 31 /r */ 9376 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9377 ins_pipe(ialu_mem_reg); 9378%} 9379 9380// Xor Memory with Immediate 9381instruct xorL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9382%{ 9383 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 9384 effect(KILL cr); 9385 9386 ins_cost(125); 9387 format %{ "xorq $dst, $src\t# long" %} 9388 opcode(0x81, 0x6); /* Opcode 81 /6 id */ 9389 ins_encode(REX_mem_wide(dst), OpcSE(src), 9390 RM_opc_mem(secondary, dst), Con8or32(src)); 9391 ins_pipe(ialu_mem_imm); 9392%} 9393 9394// Convert Int to Boolean 9395instruct convI2B(rRegI dst, rRegI src, rFlagsReg cr) 9396%{ 9397 match(Set dst (Conv2B src)); 9398 effect(KILL cr); 9399 9400 format %{ "testl $src, $src\t# ci2b\n\t" 9401 "setnz $dst\n\t" 9402 "movzbl $dst, $dst" %} 9403 ins_encode(REX_reg_reg(src, src), opc_reg_reg(0x85, src, src), // testl 9404 setNZ_reg(dst), 9405 REX_reg_breg(dst, dst), // movzbl 9406 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst)); 9407 ins_pipe(pipe_slow); // XXX 9408%} 9409 9410// Convert Pointer to Boolean 9411instruct convP2B(rRegI dst, rRegP src, rFlagsReg cr) 9412%{ 9413 match(Set dst (Conv2B src)); 9414 effect(KILL cr); 9415 9416 format %{ "testq $src, $src\t# cp2b\n\t" 9417 "setnz $dst\n\t" 9418 "movzbl $dst, $dst" %} 9419 ins_encode(REX_reg_reg_wide(src, src), opc_reg_reg(0x85, src, src), // testq 9420 setNZ_reg(dst), 9421 REX_reg_breg(dst, dst), // movzbl 9422 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst)); 9423 ins_pipe(pipe_slow); // XXX 9424%} 9425 9426instruct cmpLTMask(rRegI dst, rRegI p, rRegI q, rFlagsReg cr) 9427%{ 9428 match(Set dst (CmpLTMask p q)); 9429 effect(KILL cr); 9430 9431 ins_cost(400); // XXX 9432 format %{ "cmpl $p, $q\t# cmpLTMask\n\t" 9433 "setlt $dst\n\t" 9434 "movzbl $dst, $dst\n\t" 9435 "negl $dst" %} 9436 ins_encode(REX_reg_reg(p, q), opc_reg_reg(0x3B, p, q), // cmpl 9437 setLT_reg(dst), 9438 REX_reg_breg(dst, dst), // movzbl 9439 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst), 9440 neg_reg(dst)); 9441 ins_pipe(pipe_slow); 9442%} 9443 9444instruct cmpLTMask0(rRegI dst, immI0 zero, rFlagsReg cr) 9445%{ 9446 match(Set dst (CmpLTMask dst zero)); 9447 effect(KILL cr); 9448 9449 ins_cost(100); // XXX 9450 format %{ "sarl $dst, #31\t# cmpLTMask0" %} 9451 opcode(0xC1, 0x7); /* C1 /7 ib */ 9452 ins_encode(reg_opc_imm(dst, 0x1F)); 9453 ins_pipe(ialu_reg); 9454%} 9455 9456 9457instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y, rRegI tmp, rFlagsReg cr) 9458%{ 9459 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q))); 9460 effect(TEMP tmp, KILL cr); 9461 9462 ins_cost(400); // XXX 9463 format %{ "subl $p, $q\t# cadd_cmpLTMask1\n\t" 9464 "sbbl $tmp, $tmp\n\t" 9465 "andl $tmp, $y\n\t" 9466 "addl $p, $tmp" %} 9467 ins_encode %{ 9468 Register Rp = $p$$Register; 9469 Register Rq = $q$$Register; 9470 Register Ry = $y$$Register; 9471 Register Rt = $tmp$$Register; 9472 __ subl(Rp, Rq); 9473 __ sbbl(Rt, Rt); 9474 __ andl(Rt, Ry); 9475 __ addl(Rp, Rt); 9476 %} 9477 ins_pipe(pipe_cmplt); 9478%} 9479 9480//---------- FP Instructions------------------------------------------------ 9481 9482instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2) 9483%{ 9484 match(Set cr (CmpF src1 src2)); 9485 9486 ins_cost(145); 9487 format %{ "ucomiss $src1, $src2\n\t" 9488 "jnp,s exit\n\t" 9489 "pushfq\t# saw NaN, set CF\n\t" 9490 "andq [rsp], #0xffffff2b\n\t" 9491 "popfq\n" 9492 "exit:" %} 9493 ins_encode %{ 9494 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9495 emit_cmpfp_fixup(_masm); 9496 %} 9497 ins_pipe(pipe_slow); 9498%} 9499 9500instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{ 9501 match(Set cr (CmpF src1 src2)); 9502 9503 ins_cost(100); 9504 format %{ "ucomiss $src1, $src2" %} 9505 ins_encode %{ 9506 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9507 %} 9508 ins_pipe(pipe_slow); 9509%} 9510 9511instruct cmpF_cc_mem(rFlagsRegU cr, regF src1, memory src2) 9512%{ 9513 match(Set cr (CmpF src1 (LoadF src2))); 9514 9515 ins_cost(145); 9516 format %{ "ucomiss $src1, $src2\n\t" 9517 "jnp,s exit\n\t" 9518 "pushfq\t# saw NaN, set CF\n\t" 9519 "andq [rsp], #0xffffff2b\n\t" 9520 "popfq\n" 9521 "exit:" %} 9522 ins_encode %{ 9523 __ ucomiss($src1$$XMMRegister, $src2$$Address); 9524 emit_cmpfp_fixup(_masm); 9525 %} 9526 ins_pipe(pipe_slow); 9527%} 9528 9529instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{ 9530 match(Set cr (CmpF src1 (LoadF src2))); 9531 9532 ins_cost(100); 9533 format %{ "ucomiss $src1, $src2" %} 9534 ins_encode %{ 9535 __ ucomiss($src1$$XMMRegister, $src2$$Address); 9536 %} 9537 ins_pipe(pipe_slow); 9538%} 9539 9540instruct cmpF_cc_imm(rFlagsRegU cr, regF src, immF con) %{ 9541 match(Set cr (CmpF src con)); 9542 9543 ins_cost(145); 9544 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 9545 "jnp,s exit\n\t" 9546 "pushfq\t# saw NaN, set CF\n\t" 9547 "andq [rsp], #0xffffff2b\n\t" 9548 "popfq\n" 9549 "exit:" %} 9550 ins_encode %{ 9551 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 9552 emit_cmpfp_fixup(_masm); 9553 %} 9554 ins_pipe(pipe_slow); 9555%} 9556 9557instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src, immF con) %{ 9558 match(Set cr (CmpF src con)); 9559 ins_cost(100); 9560 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con" %} 9561 ins_encode %{ 9562 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 9563 %} 9564 ins_pipe(pipe_slow); 9565%} 9566 9567instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2) 9568%{ 9569 match(Set cr (CmpD src1 src2)); 9570 9571 ins_cost(145); 9572 format %{ "ucomisd $src1, $src2\n\t" 9573 "jnp,s exit\n\t" 9574 "pushfq\t# saw NaN, set CF\n\t" 9575 "andq [rsp], #0xffffff2b\n\t" 9576 "popfq\n" 9577 "exit:" %} 9578 ins_encode %{ 9579 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9580 emit_cmpfp_fixup(_masm); 9581 %} 9582 ins_pipe(pipe_slow); 9583%} 9584 9585instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{ 9586 match(Set cr (CmpD src1 src2)); 9587 9588 ins_cost(100); 9589 format %{ "ucomisd $src1, $src2 test" %} 9590 ins_encode %{ 9591 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9592 %} 9593 ins_pipe(pipe_slow); 9594%} 9595 9596instruct cmpD_cc_mem(rFlagsRegU cr, regD src1, memory src2) 9597%{ 9598 match(Set cr (CmpD src1 (LoadD src2))); 9599 9600 ins_cost(145); 9601 format %{ "ucomisd $src1, $src2\n\t" 9602 "jnp,s exit\n\t" 9603 "pushfq\t# saw NaN, set CF\n\t" 9604 "andq [rsp], #0xffffff2b\n\t" 9605 "popfq\n" 9606 "exit:" %} 9607 ins_encode %{ 9608 __ ucomisd($src1$$XMMRegister, $src2$$Address); 9609 emit_cmpfp_fixup(_masm); 9610 %} 9611 ins_pipe(pipe_slow); 9612%} 9613 9614instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{ 9615 match(Set cr (CmpD src1 (LoadD src2))); 9616 9617 ins_cost(100); 9618 format %{ "ucomisd $src1, $src2" %} 9619 ins_encode %{ 9620 __ ucomisd($src1$$XMMRegister, $src2$$Address); 9621 %} 9622 ins_pipe(pipe_slow); 9623%} 9624 9625instruct cmpD_cc_imm(rFlagsRegU cr, regD src, immD con) %{ 9626 match(Set cr (CmpD src con)); 9627 9628 ins_cost(145); 9629 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 9630 "jnp,s exit\n\t" 9631 "pushfq\t# saw NaN, set CF\n\t" 9632 "andq [rsp], #0xffffff2b\n\t" 9633 "popfq\n" 9634 "exit:" %} 9635 ins_encode %{ 9636 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 9637 emit_cmpfp_fixup(_masm); 9638 %} 9639 ins_pipe(pipe_slow); 9640%} 9641 9642instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src, immD con) %{ 9643 match(Set cr (CmpD src con)); 9644 ins_cost(100); 9645 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con" %} 9646 ins_encode %{ 9647 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 9648 %} 9649 ins_pipe(pipe_slow); 9650%} 9651 9652// Compare into -1,0,1 9653instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr) 9654%{ 9655 match(Set dst (CmpF3 src1 src2)); 9656 effect(KILL cr); 9657 9658 ins_cost(275); 9659 format %{ "ucomiss $src1, $src2\n\t" 9660 "movl $dst, #-1\n\t" 9661 "jp,s done\n\t" 9662 "jb,s done\n\t" 9663 "setne $dst\n\t" 9664 "movzbl $dst, $dst\n" 9665 "done:" %} 9666 ins_encode %{ 9667 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9668 emit_cmpfp3(_masm, $dst$$Register); 9669 %} 9670 ins_pipe(pipe_slow); 9671%} 9672 9673// Compare into -1,0,1 9674instruct cmpF_mem(rRegI dst, regF src1, memory src2, rFlagsReg cr) 9675%{ 9676 match(Set dst (CmpF3 src1 (LoadF src2))); 9677 effect(KILL cr); 9678 9679 ins_cost(275); 9680 format %{ "ucomiss $src1, $src2\n\t" 9681 "movl $dst, #-1\n\t" 9682 "jp,s done\n\t" 9683 "jb,s done\n\t" 9684 "setne $dst\n\t" 9685 "movzbl $dst, $dst\n" 9686 "done:" %} 9687 ins_encode %{ 9688 __ ucomiss($src1$$XMMRegister, $src2$$Address); 9689 emit_cmpfp3(_masm, $dst$$Register); 9690 %} 9691 ins_pipe(pipe_slow); 9692%} 9693 9694// Compare into -1,0,1 9695instruct cmpF_imm(rRegI dst, regF src, immF con, rFlagsReg cr) %{ 9696 match(Set dst (CmpF3 src con)); 9697 effect(KILL cr); 9698 9699 ins_cost(275); 9700 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 9701 "movl $dst, #-1\n\t" 9702 "jp,s done\n\t" 9703 "jb,s done\n\t" 9704 "setne $dst\n\t" 9705 "movzbl $dst, $dst\n" 9706 "done:" %} 9707 ins_encode %{ 9708 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 9709 emit_cmpfp3(_masm, $dst$$Register); 9710 %} 9711 ins_pipe(pipe_slow); 9712%} 9713 9714// Compare into -1,0,1 9715instruct cmpD_reg(rRegI dst, regD src1, regD src2, rFlagsReg cr) 9716%{ 9717 match(Set dst (CmpD3 src1 src2)); 9718 effect(KILL cr); 9719 9720 ins_cost(275); 9721 format %{ "ucomisd $src1, $src2\n\t" 9722 "movl $dst, #-1\n\t" 9723 "jp,s done\n\t" 9724 "jb,s done\n\t" 9725 "setne $dst\n\t" 9726 "movzbl $dst, $dst\n" 9727 "done:" %} 9728 ins_encode %{ 9729 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9730 emit_cmpfp3(_masm, $dst$$Register); 9731 %} 9732 ins_pipe(pipe_slow); 9733%} 9734 9735// Compare into -1,0,1 9736instruct cmpD_mem(rRegI dst, regD src1, memory src2, rFlagsReg cr) 9737%{ 9738 match(Set dst (CmpD3 src1 (LoadD src2))); 9739 effect(KILL cr); 9740 9741 ins_cost(275); 9742 format %{ "ucomisd $src1, $src2\n\t" 9743 "movl $dst, #-1\n\t" 9744 "jp,s done\n\t" 9745 "jb,s done\n\t" 9746 "setne $dst\n\t" 9747 "movzbl $dst, $dst\n" 9748 "done:" %} 9749 ins_encode %{ 9750 __ ucomisd($src1$$XMMRegister, $src2$$Address); 9751 emit_cmpfp3(_masm, $dst$$Register); 9752 %} 9753 ins_pipe(pipe_slow); 9754%} 9755 9756// Compare into -1,0,1 9757instruct cmpD_imm(rRegI dst, regD src, immD con, rFlagsReg cr) %{ 9758 match(Set dst (CmpD3 src con)); 9759 effect(KILL cr); 9760 9761 ins_cost(275); 9762 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 9763 "movl $dst, #-1\n\t" 9764 "jp,s done\n\t" 9765 "jb,s done\n\t" 9766 "setne $dst\n\t" 9767 "movzbl $dst, $dst\n" 9768 "done:" %} 9769 ins_encode %{ 9770 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 9771 emit_cmpfp3(_masm, $dst$$Register); 9772 %} 9773 ins_pipe(pipe_slow); 9774%} 9775 9776// -----------Trig and Trancendental Instructions------------------------------ 9777instruct cosD_reg(regD dst) %{ 9778 match(Set dst (CosD dst)); 9779 9780 format %{ "dcos $dst\n\t" %} 9781 opcode(0xD9, 0xFF); 9782 ins_encode( Push_SrcXD(dst), OpcP, OpcS, Push_ResultXD(dst) ); 9783 ins_pipe( pipe_slow ); 9784%} 9785 9786instruct sinD_reg(regD dst) %{ 9787 match(Set dst (SinD dst)); 9788 9789 format %{ "dsin $dst\n\t" %} 9790 opcode(0xD9, 0xFE); 9791 ins_encode( Push_SrcXD(dst), OpcP, OpcS, Push_ResultXD(dst) ); 9792 ins_pipe( pipe_slow ); 9793%} 9794 9795instruct tanD_reg(regD dst) %{ 9796 match(Set dst (TanD dst)); 9797 9798 format %{ "dtan $dst\n\t" %} 9799 ins_encode( Push_SrcXD(dst), 9800 Opcode(0xD9), Opcode(0xF2), //fptan 9801 Opcode(0xDD), Opcode(0xD8), //fstp st 9802 Push_ResultXD(dst) ); 9803 ins_pipe( pipe_slow ); 9804%} 9805 9806instruct log10D_reg(regD dst) %{ 9807 // The source and result Double operands in XMM registers 9808 match(Set dst (Log10D dst)); 9809 // fldlg2 ; push log_10(2) on the FPU stack; full 80-bit number 9810 // fyl2x ; compute log_10(2) * log_2(x) 9811 format %{ "fldlg2\t\t\t#Log10\n\t" 9812 "fyl2x\t\t\t# Q=Log10*Log_2(x)\n\t" 9813 %} 9814 ins_encode(Opcode(0xD9), Opcode(0xEC), // fldlg2 9815 Push_SrcXD(dst), 9816 Opcode(0xD9), Opcode(0xF1), // fyl2x 9817 Push_ResultXD(dst)); 9818 9819 ins_pipe( pipe_slow ); 9820%} 9821 9822instruct logD_reg(regD dst) %{ 9823 // The source and result Double operands in XMM registers 9824 match(Set dst (LogD dst)); 9825 // fldln2 ; push log_e(2) on the FPU stack; full 80-bit number 9826 // fyl2x ; compute log_e(2) * log_2(x) 9827 format %{ "fldln2\t\t\t#Log_e\n\t" 9828 "fyl2x\t\t\t# Q=Log_e*Log_2(x)\n\t" 9829 %} 9830 ins_encode( Opcode(0xD9), Opcode(0xED), // fldln2 9831 Push_SrcXD(dst), 9832 Opcode(0xD9), Opcode(0xF1), // fyl2x 9833 Push_ResultXD(dst)); 9834 ins_pipe( pipe_slow ); 9835%} 9836 9837 9838 9839//----------Arithmetic Conversion Instructions--------------------------------- 9840 9841instruct roundFloat_nop(regF dst) 9842%{ 9843 match(Set dst (RoundFloat dst)); 9844 9845 ins_cost(0); 9846 ins_encode(); 9847 ins_pipe(empty); 9848%} 9849 9850instruct roundDouble_nop(regD dst) 9851%{ 9852 match(Set dst (RoundDouble dst)); 9853 9854 ins_cost(0); 9855 ins_encode(); 9856 ins_pipe(empty); 9857%} 9858 9859instruct convF2D_reg_reg(regD dst, regF src) 9860%{ 9861 match(Set dst (ConvF2D src)); 9862 9863 format %{ "cvtss2sd $dst, $src" %} 9864 ins_encode %{ 9865 __ cvtss2sd ($dst$$XMMRegister, $src$$XMMRegister); 9866 %} 9867 ins_pipe(pipe_slow); // XXX 9868%} 9869 9870instruct convF2D_reg_mem(regD dst, memory src) 9871%{ 9872 match(Set dst (ConvF2D (LoadF src))); 9873 9874 format %{ "cvtss2sd $dst, $src" %} 9875 ins_encode %{ 9876 __ cvtss2sd ($dst$$XMMRegister, $src$$Address); 9877 %} 9878 ins_pipe(pipe_slow); // XXX 9879%} 9880 9881instruct convD2F_reg_reg(regF dst, regD src) 9882%{ 9883 match(Set dst (ConvD2F src)); 9884 9885 format %{ "cvtsd2ss $dst, $src" %} 9886 ins_encode %{ 9887 __ cvtsd2ss ($dst$$XMMRegister, $src$$XMMRegister); 9888 %} 9889 ins_pipe(pipe_slow); // XXX 9890%} 9891 9892instruct convD2F_reg_mem(regF dst, memory src) 9893%{ 9894 match(Set dst (ConvD2F (LoadD src))); 9895 9896 format %{ "cvtsd2ss $dst, $src" %} 9897 ins_encode %{ 9898 __ cvtsd2ss ($dst$$XMMRegister, $src$$Address); 9899 %} 9900 ins_pipe(pipe_slow); // XXX 9901%} 9902 9903// XXX do mem variants 9904instruct convF2I_reg_reg(rRegI dst, regF src, rFlagsReg cr) 9905%{ 9906 match(Set dst (ConvF2I src)); 9907 effect(KILL cr); 9908 9909 format %{ "cvttss2sil $dst, $src\t# f2i\n\t" 9910 "cmpl $dst, #0x80000000\n\t" 9911 "jne,s done\n\t" 9912 "subq rsp, #8\n\t" 9913 "movss [rsp], $src\n\t" 9914 "call f2i_fixup\n\t" 9915 "popq $dst\n" 9916 "done: "%} 9917 ins_encode %{ 9918 Label done; 9919 __ cvttss2sil($dst$$Register, $src$$XMMRegister); 9920 __ cmpl($dst$$Register, 0x80000000); 9921 __ jccb(Assembler::notEqual, done); 9922 __ subptr(rsp, 8); 9923 __ movflt(Address(rsp, 0), $src$$XMMRegister); 9924 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::f2i_fixup()))); 9925 __ pop($dst$$Register); 9926 __ bind(done); 9927 %} 9928 ins_pipe(pipe_slow); 9929%} 9930 9931instruct convF2L_reg_reg(rRegL dst, regF src, rFlagsReg cr) 9932%{ 9933 match(Set dst (ConvF2L src)); 9934 effect(KILL cr); 9935 9936 format %{ "cvttss2siq $dst, $src\t# f2l\n\t" 9937 "cmpq $dst, [0x8000000000000000]\n\t" 9938 "jne,s done\n\t" 9939 "subq rsp, #8\n\t" 9940 "movss [rsp], $src\n\t" 9941 "call f2l_fixup\n\t" 9942 "popq $dst\n" 9943 "done: "%} 9944 ins_encode %{ 9945 Label done; 9946 __ cvttss2siq($dst$$Register, $src$$XMMRegister); 9947 __ cmp64($dst$$Register, 9948 ExternalAddress((address) StubRoutines::x86::double_sign_flip())); 9949 __ jccb(Assembler::notEqual, done); 9950 __ subptr(rsp, 8); 9951 __ movflt(Address(rsp, 0), $src$$XMMRegister); 9952 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::f2l_fixup()))); 9953 __ pop($dst$$Register); 9954 __ bind(done); 9955 %} 9956 ins_pipe(pipe_slow); 9957%} 9958 9959instruct convD2I_reg_reg(rRegI dst, regD src, rFlagsReg cr) 9960%{ 9961 match(Set dst (ConvD2I src)); 9962 effect(KILL cr); 9963 9964 format %{ "cvttsd2sil $dst, $src\t# d2i\n\t" 9965 "cmpl $dst, #0x80000000\n\t" 9966 "jne,s done\n\t" 9967 "subq rsp, #8\n\t" 9968 "movsd [rsp], $src\n\t" 9969 "call d2i_fixup\n\t" 9970 "popq $dst\n" 9971 "done: "%} 9972 ins_encode %{ 9973 Label done; 9974 __ cvttsd2sil($dst$$Register, $src$$XMMRegister); 9975 __ cmpl($dst$$Register, 0x80000000); 9976 __ jccb(Assembler::notEqual, done); 9977 __ subptr(rsp, 8); 9978 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 9979 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::d2i_fixup()))); 9980 __ pop($dst$$Register); 9981 __ bind(done); 9982 %} 9983 ins_pipe(pipe_slow); 9984%} 9985 9986instruct convD2L_reg_reg(rRegL dst, regD src, rFlagsReg cr) 9987%{ 9988 match(Set dst (ConvD2L src)); 9989 effect(KILL cr); 9990 9991 format %{ "cvttsd2siq $dst, $src\t# d2l\n\t" 9992 "cmpq $dst, [0x8000000000000000]\n\t" 9993 "jne,s done\n\t" 9994 "subq rsp, #8\n\t" 9995 "movsd [rsp], $src\n\t" 9996 "call d2l_fixup\n\t" 9997 "popq $dst\n" 9998 "done: "%} 9999 ins_encode %{ 10000 Label done; 10001 __ cvttsd2siq($dst$$Register, $src$$XMMRegister); 10002 __ cmp64($dst$$Register, 10003 ExternalAddress((address) StubRoutines::x86::double_sign_flip())); 10004 __ jccb(Assembler::notEqual, done); 10005 __ subptr(rsp, 8); 10006 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 10007 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::d2l_fixup()))); 10008 __ pop($dst$$Register); 10009 __ bind(done); 10010 %} 10011 ins_pipe(pipe_slow); 10012%} 10013 10014instruct convI2F_reg_reg(regF dst, rRegI src) 10015%{ 10016 predicate(!UseXmmI2F); 10017 match(Set dst (ConvI2F src)); 10018 10019 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10020 ins_encode %{ 10021 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Register); 10022 %} 10023 ins_pipe(pipe_slow); // XXX 10024%} 10025 10026instruct convI2F_reg_mem(regF dst, memory src) 10027%{ 10028 match(Set dst (ConvI2F (LoadI src))); 10029 10030 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10031 ins_encode %{ 10032 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Address); 10033 %} 10034 ins_pipe(pipe_slow); // XXX 10035%} 10036 10037instruct convI2D_reg_reg(regD dst, rRegI src) 10038%{ 10039 predicate(!UseXmmI2D); 10040 match(Set dst (ConvI2D src)); 10041 10042 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10043 ins_encode %{ 10044 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Register); 10045 %} 10046 ins_pipe(pipe_slow); // XXX 10047%} 10048 10049instruct convI2D_reg_mem(regD dst, memory src) 10050%{ 10051 match(Set dst (ConvI2D (LoadI src))); 10052 10053 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10054 ins_encode %{ 10055 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Address); 10056 %} 10057 ins_pipe(pipe_slow); // XXX 10058%} 10059 10060instruct convXI2F_reg(regF dst, rRegI src) 10061%{ 10062 predicate(UseXmmI2F); 10063 match(Set dst (ConvI2F src)); 10064 10065 format %{ "movdl $dst, $src\n\t" 10066 "cvtdq2psl $dst, $dst\t# i2f" %} 10067 ins_encode %{ 10068 __ movdl($dst$$XMMRegister, $src$$Register); 10069 __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister); 10070 %} 10071 ins_pipe(pipe_slow); // XXX 10072%} 10073 10074instruct convXI2D_reg(regD dst, rRegI src) 10075%{ 10076 predicate(UseXmmI2D); 10077 match(Set dst (ConvI2D src)); 10078 10079 format %{ "movdl $dst, $src\n\t" 10080 "cvtdq2pdl $dst, $dst\t# i2d" %} 10081 ins_encode %{ 10082 __ movdl($dst$$XMMRegister, $src$$Register); 10083 __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister); 10084 %} 10085 ins_pipe(pipe_slow); // XXX 10086%} 10087 10088instruct convL2F_reg_reg(regF dst, rRegL src) 10089%{ 10090 match(Set dst (ConvL2F src)); 10091 10092 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10093 ins_encode %{ 10094 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Register); 10095 %} 10096 ins_pipe(pipe_slow); // XXX 10097%} 10098 10099instruct convL2F_reg_mem(regF dst, memory src) 10100%{ 10101 match(Set dst (ConvL2F (LoadL src))); 10102 10103 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10104 ins_encode %{ 10105 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Address); 10106 %} 10107 ins_pipe(pipe_slow); // XXX 10108%} 10109 10110instruct convL2D_reg_reg(regD dst, rRegL src) 10111%{ 10112 match(Set dst (ConvL2D src)); 10113 10114 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10115 ins_encode %{ 10116 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Register); 10117 %} 10118 ins_pipe(pipe_slow); // XXX 10119%} 10120 10121instruct convL2D_reg_mem(regD dst, memory src) 10122%{ 10123 match(Set dst (ConvL2D (LoadL src))); 10124 10125 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10126 ins_encode %{ 10127 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Address); 10128 %} 10129 ins_pipe(pipe_slow); // XXX 10130%} 10131 10132instruct convI2L_reg_reg(rRegL dst, rRegI src) 10133%{ 10134 match(Set dst (ConvI2L src)); 10135 10136 ins_cost(125); 10137 format %{ "movslq $dst, $src\t# i2l" %} 10138 ins_encode %{ 10139 __ movslq($dst$$Register, $src$$Register); 10140 %} 10141 ins_pipe(ialu_reg_reg); 10142%} 10143 10144// instruct convI2L_reg_reg_foo(rRegL dst, rRegI src) 10145// %{ 10146// match(Set dst (ConvI2L src)); 10147// // predicate(_kids[0]->_leaf->as_Type()->type()->is_int()->_lo >= 0 && 10148// // _kids[0]->_leaf->as_Type()->type()->is_int()->_hi >= 0); 10149// predicate(((const TypeNode*) n)->type()->is_long()->_hi == 10150// (unsigned int) ((const TypeNode*) n)->type()->is_long()->_hi && 10151// ((const TypeNode*) n)->type()->is_long()->_lo == 10152// (unsigned int) ((const TypeNode*) n)->type()->is_long()->_lo); 10153 10154// format %{ "movl $dst, $src\t# unsigned i2l" %} 10155// ins_encode(enc_copy(dst, src)); 10156// // opcode(0x63); // needs REX.W 10157// // ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst,src)); 10158// ins_pipe(ialu_reg_reg); 10159// %} 10160 10161// Zero-extend convert int to long 10162instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask) 10163%{ 10164 match(Set dst (AndL (ConvI2L src) mask)); 10165 10166 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10167 ins_encode %{ 10168 if ($dst$$reg != $src$$reg) { 10169 __ movl($dst$$Register, $src$$Register); 10170 } 10171 %} 10172 ins_pipe(ialu_reg_reg); 10173%} 10174 10175// Zero-extend convert int to long 10176instruct convI2L_reg_mem_zex(rRegL dst, memory src, immL_32bits mask) 10177%{ 10178 match(Set dst (AndL (ConvI2L (LoadI src)) mask)); 10179 10180 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10181 ins_encode %{ 10182 __ movl($dst$$Register, $src$$Address); 10183 %} 10184 ins_pipe(ialu_reg_mem); 10185%} 10186 10187instruct zerox_long_reg_reg(rRegL dst, rRegL src, immL_32bits mask) 10188%{ 10189 match(Set dst (AndL src mask)); 10190 10191 format %{ "movl $dst, $src\t# zero-extend long" %} 10192 ins_encode %{ 10193 __ movl($dst$$Register, $src$$Register); 10194 %} 10195 ins_pipe(ialu_reg_reg); 10196%} 10197 10198instruct convL2I_reg_reg(rRegI dst, rRegL src) 10199%{ 10200 match(Set dst (ConvL2I src)); 10201 10202 format %{ "movl $dst, $src\t# l2i" %} 10203 ins_encode %{ 10204 __ movl($dst$$Register, $src$$Register); 10205 %} 10206 ins_pipe(ialu_reg_reg); 10207%} 10208 10209 10210instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{ 10211 match(Set dst (MoveF2I src)); 10212 effect(DEF dst, USE src); 10213 10214 ins_cost(125); 10215 format %{ "movl $dst, $src\t# MoveF2I_stack_reg" %} 10216 ins_encode %{ 10217 __ movl($dst$$Register, Address(rsp, $src$$disp)); 10218 %} 10219 ins_pipe(ialu_reg_mem); 10220%} 10221 10222instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{ 10223 match(Set dst (MoveI2F src)); 10224 effect(DEF dst, USE src); 10225 10226 ins_cost(125); 10227 format %{ "movss $dst, $src\t# MoveI2F_stack_reg" %} 10228 ins_encode %{ 10229 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 10230 %} 10231 ins_pipe(pipe_slow); 10232%} 10233 10234instruct MoveD2L_stack_reg(rRegL dst, stackSlotD src) %{ 10235 match(Set dst (MoveD2L src)); 10236 effect(DEF dst, USE src); 10237 10238 ins_cost(125); 10239 format %{ "movq $dst, $src\t# MoveD2L_stack_reg" %} 10240 ins_encode %{ 10241 __ movq($dst$$Register, Address(rsp, $src$$disp)); 10242 %} 10243 ins_pipe(ialu_reg_mem); 10244%} 10245 10246instruct MoveL2D_stack_reg_partial(regD dst, stackSlotL src) %{ 10247 predicate(!UseXmmLoadAndClearUpper); 10248 match(Set dst (MoveL2D src)); 10249 effect(DEF dst, USE src); 10250 10251 ins_cost(125); 10252 format %{ "movlpd $dst, $src\t# MoveL2D_stack_reg" %} 10253 ins_encode %{ 10254 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10255 %} 10256 ins_pipe(pipe_slow); 10257%} 10258 10259instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{ 10260 predicate(UseXmmLoadAndClearUpper); 10261 match(Set dst (MoveL2D src)); 10262 effect(DEF dst, USE src); 10263 10264 ins_cost(125); 10265 format %{ "movsd $dst, $src\t# MoveL2D_stack_reg" %} 10266 ins_encode %{ 10267 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10268 %} 10269 ins_pipe(pipe_slow); 10270%} 10271 10272 10273instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{ 10274 match(Set dst (MoveF2I src)); 10275 effect(DEF dst, USE src); 10276 10277 ins_cost(95); // XXX 10278 format %{ "movss $dst, $src\t# MoveF2I_reg_stack" %} 10279 ins_encode %{ 10280 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 10281 %} 10282 ins_pipe(pipe_slow); 10283%} 10284 10285instruct MoveI2F_reg_stack(stackSlotF dst, rRegI src) %{ 10286 match(Set dst (MoveI2F src)); 10287 effect(DEF dst, USE src); 10288 10289 ins_cost(100); 10290 format %{ "movl $dst, $src\t# MoveI2F_reg_stack" %} 10291 ins_encode %{ 10292 __ movl(Address(rsp, $dst$$disp), $src$$Register); 10293 %} 10294 ins_pipe( ialu_mem_reg ); 10295%} 10296 10297instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{ 10298 match(Set dst (MoveD2L src)); 10299 effect(DEF dst, USE src); 10300 10301 ins_cost(95); // XXX 10302 format %{ "movsd $dst, $src\t# MoveL2D_reg_stack" %} 10303 ins_encode %{ 10304 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 10305 %} 10306 ins_pipe(pipe_slow); 10307%} 10308 10309instruct MoveL2D_reg_stack(stackSlotD dst, rRegL src) %{ 10310 match(Set dst (MoveL2D src)); 10311 effect(DEF dst, USE src); 10312 10313 ins_cost(100); 10314 format %{ "movq $dst, $src\t# MoveL2D_reg_stack" %} 10315 ins_encode %{ 10316 __ movq(Address(rsp, $dst$$disp), $src$$Register); 10317 %} 10318 ins_pipe(ialu_mem_reg); 10319%} 10320 10321instruct MoveF2I_reg_reg(rRegI dst, regF src) %{ 10322 match(Set dst (MoveF2I src)); 10323 effect(DEF dst, USE src); 10324 ins_cost(85); 10325 format %{ "movd $dst,$src\t# MoveF2I" %} 10326 ins_encode %{ 10327 __ movdl($dst$$Register, $src$$XMMRegister); 10328 %} 10329 ins_pipe( pipe_slow ); 10330%} 10331 10332instruct MoveD2L_reg_reg(rRegL dst, regD src) %{ 10333 match(Set dst (MoveD2L src)); 10334 effect(DEF dst, USE src); 10335 ins_cost(85); 10336 format %{ "movd $dst,$src\t# MoveD2L" %} 10337 ins_encode %{ 10338 __ movdq($dst$$Register, $src$$XMMRegister); 10339 %} 10340 ins_pipe( pipe_slow ); 10341%} 10342 10343// The next instructions have long latency and use Int unit. Set high cost. 10344instruct MoveI2F_reg_reg(regF dst, rRegI src) %{ 10345 match(Set dst (MoveI2F src)); 10346 effect(DEF dst, USE src); 10347 ins_cost(300); 10348 format %{ "movd $dst,$src\t# MoveI2F" %} 10349 ins_encode %{ 10350 __ movdl($dst$$XMMRegister, $src$$Register); 10351 %} 10352 ins_pipe( pipe_slow ); 10353%} 10354 10355instruct MoveL2D_reg_reg(regD dst, rRegL src) %{ 10356 match(Set dst (MoveL2D src)); 10357 effect(DEF dst, USE src); 10358 ins_cost(300); 10359 format %{ "movd $dst,$src\t# MoveL2D" %} 10360 ins_encode %{ 10361 __ movdq($dst$$XMMRegister, $src$$Register); 10362 %} 10363 ins_pipe( pipe_slow ); 10364%} 10365 10366// Replicate scalar to packed byte (1 byte) values in xmm 10367instruct Repl8B_reg(regD dst, regD src) %{ 10368 match(Set dst (Replicate8B src)); 10369 format %{ "MOVDQA $dst,$src\n\t" 10370 "PUNPCKLBW $dst,$dst\n\t" 10371 "PSHUFLW $dst,$dst,0x00\t! replicate8B" %} 10372 ins_encode %{ 10373 if ($dst$$reg != $src$$reg) { 10374 __ movdqa($dst$$XMMRegister, $src$$XMMRegister); 10375 } 10376 __ punpcklbw($dst$$XMMRegister, $dst$$XMMRegister); 10377 __ pshuflw($dst$$XMMRegister, $dst$$XMMRegister, 0x00); 10378 %} 10379 ins_pipe( pipe_slow ); 10380%} 10381 10382// Replicate scalar to packed byte (1 byte) values in xmm 10383instruct Repl8B_rRegI(regD dst, rRegI src) %{ 10384 match(Set dst (Replicate8B src)); 10385 format %{ "MOVD $dst,$src\n\t" 10386 "PUNPCKLBW $dst,$dst\n\t" 10387 "PSHUFLW $dst,$dst,0x00\t! replicate8B" %} 10388 ins_encode %{ 10389 __ movdl($dst$$XMMRegister, $src$$Register); 10390 __ punpcklbw($dst$$XMMRegister, $dst$$XMMRegister); 10391 __ pshuflw($dst$$XMMRegister, $dst$$XMMRegister, 0x00); 10392 %} 10393 ins_pipe( pipe_slow ); 10394%} 10395 10396// Replicate scalar zero to packed byte (1 byte) values in xmm 10397instruct Repl8B_immI0(regD dst, immI0 zero) %{ 10398 match(Set dst (Replicate8B zero)); 10399 format %{ "PXOR $dst,$dst\t! replicate8B" %} 10400 ins_encode %{ 10401 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 10402 %} 10403 ins_pipe( fpu_reg_reg ); 10404%} 10405 10406// Replicate scalar to packed shore (2 byte) values in xmm 10407instruct Repl4S_reg(regD dst, regD src) %{ 10408 match(Set dst (Replicate4S src)); 10409 format %{ "PSHUFLW $dst,$src,0x00\t! replicate4S" %} 10410 ins_encode %{ 10411 __ pshuflw($dst$$XMMRegister, $src$$XMMRegister, 0x00); 10412 %} 10413 ins_pipe( fpu_reg_reg ); 10414%} 10415 10416// Replicate scalar to packed shore (2 byte) values in xmm 10417instruct Repl4S_rRegI(regD dst, rRegI src) %{ 10418 match(Set dst (Replicate4S src)); 10419 format %{ "MOVD $dst,$src\n\t" 10420 "PSHUFLW $dst,$dst,0x00\t! replicate4S" %} 10421 ins_encode %{ 10422 __ movdl($dst$$XMMRegister, $src$$Register); 10423 __ pshuflw($dst$$XMMRegister, $dst$$XMMRegister, 0x00); 10424 %} 10425 ins_pipe( fpu_reg_reg ); 10426%} 10427 10428// Replicate scalar zero to packed short (2 byte) values in xmm 10429instruct Repl4S_immI0(regD dst, immI0 zero) %{ 10430 match(Set dst (Replicate4S zero)); 10431 format %{ "PXOR $dst,$dst\t! replicate4S" %} 10432 ins_encode %{ 10433 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 10434 %} 10435 ins_pipe( fpu_reg_reg ); 10436%} 10437 10438// Replicate scalar to packed char (2 byte) values in xmm 10439instruct Repl4C_reg(regD dst, regD src) %{ 10440 match(Set dst (Replicate4C src)); 10441 format %{ "PSHUFLW $dst,$src,0x00\t! replicate4C" %} 10442 ins_encode %{ 10443 __ pshuflw($dst$$XMMRegister, $src$$XMMRegister, 0x00); 10444 %} 10445 ins_pipe( fpu_reg_reg ); 10446%} 10447 10448// Replicate scalar to packed char (2 byte) values in xmm 10449instruct Repl4C_rRegI(regD dst, rRegI src) %{ 10450 match(Set dst (Replicate4C src)); 10451 format %{ "MOVD $dst,$src\n\t" 10452 "PSHUFLW $dst,$dst,0x00\t! replicate4C" %} 10453 ins_encode %{ 10454 __ movdl($dst$$XMMRegister, $src$$Register); 10455 __ pshuflw($dst$$XMMRegister, $dst$$XMMRegister, 0x00); 10456 %} 10457 ins_pipe( fpu_reg_reg ); 10458%} 10459 10460// Replicate scalar zero to packed char (2 byte) values in xmm 10461instruct Repl4C_immI0(regD dst, immI0 zero) %{ 10462 match(Set dst (Replicate4C zero)); 10463 format %{ "PXOR $dst,$dst\t! replicate4C" %} 10464 ins_encode %{ 10465 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 10466 %} 10467 ins_pipe( fpu_reg_reg ); 10468%} 10469 10470// Replicate scalar to packed integer (4 byte) values in xmm 10471instruct Repl2I_reg(regD dst, regD src) %{ 10472 match(Set dst (Replicate2I src)); 10473 format %{ "PSHUFD $dst,$src,0x00\t! replicate2I" %} 10474 ins_encode %{ 10475 __ pshufd($dst$$XMMRegister, $src$$XMMRegister, 0x00); 10476 %} 10477 ins_pipe( fpu_reg_reg ); 10478%} 10479 10480// Replicate scalar to packed integer (4 byte) values in xmm 10481instruct Repl2I_rRegI(regD dst, rRegI src) %{ 10482 match(Set dst (Replicate2I src)); 10483 format %{ "MOVD $dst,$src\n\t" 10484 "PSHUFD $dst,$dst,0x00\t! replicate2I" %} 10485 ins_encode %{ 10486 __ movdl($dst$$XMMRegister, $src$$Register); 10487 __ pshufd($dst$$XMMRegister, $dst$$XMMRegister, 0x00); 10488 %} 10489 ins_pipe( fpu_reg_reg ); 10490%} 10491 10492// Replicate scalar zero to packed integer (2 byte) values in xmm 10493instruct Repl2I_immI0(regD dst, immI0 zero) %{ 10494 match(Set dst (Replicate2I zero)); 10495 format %{ "PXOR $dst,$dst\t! replicate2I" %} 10496 ins_encode %{ 10497 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 10498 %} 10499 ins_pipe( fpu_reg_reg ); 10500%} 10501 10502// Replicate scalar to packed single precision floating point values in xmm 10503instruct Repl2F_reg(regD dst, regD src) %{ 10504 match(Set dst (Replicate2F src)); 10505 format %{ "PSHUFD $dst,$src,0xe0\t! replicate2F" %} 10506 ins_encode %{ 10507 __ pshufd($dst$$XMMRegister, $src$$XMMRegister, 0xe0); 10508 %} 10509 ins_pipe( fpu_reg_reg ); 10510%} 10511 10512// Replicate scalar to packed single precision floating point values in xmm 10513instruct Repl2F_regF(regD dst, regF src) %{ 10514 match(Set dst (Replicate2F src)); 10515 format %{ "PSHUFD $dst,$src,0xe0\t! replicate2F" %} 10516 ins_encode %{ 10517 __ pshufd($dst$$XMMRegister, $src$$XMMRegister, 0xe0); 10518 %} 10519 ins_pipe( fpu_reg_reg ); 10520%} 10521 10522// Replicate scalar to packed single precision floating point values in xmm 10523instruct Repl2F_immF0(regD dst, immF0 zero) %{ 10524 match(Set dst (Replicate2F zero)); 10525 format %{ "PXOR $dst,$dst\t! replicate2F" %} 10526 ins_encode %{ 10527 __ pxor($dst$$XMMRegister, $dst$$XMMRegister); 10528 %} 10529 ins_pipe( fpu_reg_reg ); 10530%} 10531 10532 10533// ======================================================================= 10534// fast clearing of an array 10535instruct rep_stos(rcx_RegL cnt, rdi_RegP base, rax_RegI zero, Universe dummy, 10536 rFlagsReg cr) 10537%{ 10538 match(Set dummy (ClearArray cnt base)); 10539 effect(USE_KILL cnt, USE_KILL base, KILL zero, KILL cr); 10540 10541 format %{ "xorl rax, rax\t# ClearArray:\n\t" 10542 "rep stosq\t# Store rax to *rdi++ while rcx--" %} 10543 ins_encode(opc_reg_reg(0x33, RAX, RAX), // xorl %eax, %eax 10544 Opcode(0xF3), Opcode(0x48), Opcode(0xAB)); // rep REX_W stos 10545 ins_pipe(pipe_slow); 10546%} 10547 10548instruct string_compare(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10549 rax_RegI result, regD tmp1, rFlagsReg cr) 10550%{ 10551 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10552 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10553 10554 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10555 ins_encode %{ 10556 __ string_compare($str1$$Register, $str2$$Register, 10557 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10558 $tmp1$$XMMRegister); 10559 %} 10560 ins_pipe( pipe_slow ); 10561%} 10562 10563// fast search of substring with known size. 10564instruct string_indexof_con(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 10565 rbx_RegI result, regD vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 10566%{ 10567 predicate(UseSSE42Intrinsics); 10568 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 10569 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 10570 10571 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 10572 ins_encode %{ 10573 int icnt2 = (int)$int_cnt2$$constant; 10574 if (icnt2 >= 8) { 10575 // IndexOf for constant substrings with size >= 8 elements 10576 // which don't need to be loaded through stack. 10577 __ string_indexofC8($str1$$Register, $str2$$Register, 10578 $cnt1$$Register, $cnt2$$Register, 10579 icnt2, $result$$Register, 10580 $vec$$XMMRegister, $tmp$$Register); 10581 } else { 10582 // Small strings are loaded through stack if they cross page boundary. 10583 __ string_indexof($str1$$Register, $str2$$Register, 10584 $cnt1$$Register, $cnt2$$Register, 10585 icnt2, $result$$Register, 10586 $vec$$XMMRegister, $tmp$$Register); 10587 } 10588 %} 10589 ins_pipe( pipe_slow ); 10590%} 10591 10592instruct string_indexof(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 10593 rbx_RegI result, regD vec, rcx_RegI tmp, rFlagsReg cr) 10594%{ 10595 predicate(UseSSE42Intrinsics); 10596 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 10597 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 10598 10599 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 10600 ins_encode %{ 10601 __ string_indexof($str1$$Register, $str2$$Register, 10602 $cnt1$$Register, $cnt2$$Register, 10603 (-1), $result$$Register, 10604 $vec$$XMMRegister, $tmp$$Register); 10605 %} 10606 ins_pipe( pipe_slow ); 10607%} 10608 10609// fast string equals 10610instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 10611 regD tmp1, regD tmp2, rbx_RegI tmp3, rFlagsReg cr) 10612%{ 10613 match(Set result (StrEquals (Binary str1 str2) cnt)); 10614 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 10615 10616 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 10617 ins_encode %{ 10618 __ char_arrays_equals(false, $str1$$Register, $str2$$Register, 10619 $cnt$$Register, $result$$Register, $tmp3$$Register, 10620 $tmp1$$XMMRegister, $tmp2$$XMMRegister); 10621 %} 10622 ins_pipe( pipe_slow ); 10623%} 10624 10625// fast array equals 10626instruct array_equals(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 10627 regD tmp1, regD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 10628%{ 10629 match(Set result (AryEq ary1 ary2)); 10630 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 10631 //ins_cost(300); 10632 10633 format %{ "Array Equals $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 10634 ins_encode %{ 10635 __ char_arrays_equals(true, $ary1$$Register, $ary2$$Register, 10636 $tmp3$$Register, $result$$Register, $tmp4$$Register, 10637 $tmp1$$XMMRegister, $tmp2$$XMMRegister); 10638 %} 10639 ins_pipe( pipe_slow ); 10640%} 10641 10642//----------Control Flow Instructions------------------------------------------ 10643// Signed compare Instructions 10644 10645// XXX more variants!! 10646instruct compI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 10647%{ 10648 match(Set cr (CmpI op1 op2)); 10649 effect(DEF cr, USE op1, USE op2); 10650 10651 format %{ "cmpl $op1, $op2" %} 10652 opcode(0x3B); /* Opcode 3B /r */ 10653 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2)); 10654 ins_pipe(ialu_cr_reg_reg); 10655%} 10656 10657instruct compI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 10658%{ 10659 match(Set cr (CmpI op1 op2)); 10660 10661 format %{ "cmpl $op1, $op2" %} 10662 opcode(0x81, 0x07); /* Opcode 81 /7 */ 10663 ins_encode(OpcSErm(op1, op2), Con8or32(op2)); 10664 ins_pipe(ialu_cr_reg_imm); 10665%} 10666 10667instruct compI_rReg_mem(rFlagsReg cr, rRegI op1, memory op2) 10668%{ 10669 match(Set cr (CmpI op1 (LoadI op2))); 10670 10671 ins_cost(500); // XXX 10672 format %{ "cmpl $op1, $op2" %} 10673 opcode(0x3B); /* Opcode 3B /r */ 10674 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2)); 10675 ins_pipe(ialu_cr_reg_mem); 10676%} 10677 10678instruct testI_reg(rFlagsReg cr, rRegI src, immI0 zero) 10679%{ 10680 match(Set cr (CmpI src zero)); 10681 10682 format %{ "testl $src, $src" %} 10683 opcode(0x85); 10684 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src)); 10685 ins_pipe(ialu_cr_reg_imm); 10686%} 10687 10688instruct testI_reg_imm(rFlagsReg cr, rRegI src, immI con, immI0 zero) 10689%{ 10690 match(Set cr (CmpI (AndI src con) zero)); 10691 10692 format %{ "testl $src, $con" %} 10693 opcode(0xF7, 0x00); 10694 ins_encode(REX_reg(src), OpcP, reg_opc(src), Con32(con)); 10695 ins_pipe(ialu_cr_reg_imm); 10696%} 10697 10698instruct testI_reg_mem(rFlagsReg cr, rRegI src, memory mem, immI0 zero) 10699%{ 10700 match(Set cr (CmpI (AndI src (LoadI mem)) zero)); 10701 10702 format %{ "testl $src, $mem" %} 10703 opcode(0x85); 10704 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 10705 ins_pipe(ialu_cr_reg_mem); 10706%} 10707 10708// Unsigned compare Instructions; really, same as signed except they 10709// produce an rFlagsRegU instead of rFlagsReg. 10710instruct compU_rReg(rFlagsRegU cr, rRegI op1, rRegI op2) 10711%{ 10712 match(Set cr (CmpU op1 op2)); 10713 10714 format %{ "cmpl $op1, $op2\t# unsigned" %} 10715 opcode(0x3B); /* Opcode 3B /r */ 10716 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2)); 10717 ins_pipe(ialu_cr_reg_reg); 10718%} 10719 10720instruct compU_rReg_imm(rFlagsRegU cr, rRegI op1, immI op2) 10721%{ 10722 match(Set cr (CmpU op1 op2)); 10723 10724 format %{ "cmpl $op1, $op2\t# unsigned" %} 10725 opcode(0x81,0x07); /* Opcode 81 /7 */ 10726 ins_encode(OpcSErm(op1, op2), Con8or32(op2)); 10727 ins_pipe(ialu_cr_reg_imm); 10728%} 10729 10730instruct compU_rReg_mem(rFlagsRegU cr, rRegI op1, memory op2) 10731%{ 10732 match(Set cr (CmpU op1 (LoadI op2))); 10733 10734 ins_cost(500); // XXX 10735 format %{ "cmpl $op1, $op2\t# unsigned" %} 10736 opcode(0x3B); /* Opcode 3B /r */ 10737 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2)); 10738 ins_pipe(ialu_cr_reg_mem); 10739%} 10740 10741// // // Cisc-spilled version of cmpU_rReg 10742// //instruct compU_mem_rReg(rFlagsRegU cr, memory op1, rRegI op2) 10743// //%{ 10744// // match(Set cr (CmpU (LoadI op1) op2)); 10745// // 10746// // format %{ "CMPu $op1,$op2" %} 10747// // ins_cost(500); 10748// // opcode(0x39); /* Opcode 39 /r */ 10749// // ins_encode( OpcP, reg_mem( op1, op2) ); 10750// //%} 10751 10752instruct testU_reg(rFlagsRegU cr, rRegI src, immI0 zero) 10753%{ 10754 match(Set cr (CmpU src zero)); 10755 10756 format %{ "testl $src, $src\t# unsigned" %} 10757 opcode(0x85); 10758 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src)); 10759 ins_pipe(ialu_cr_reg_imm); 10760%} 10761 10762instruct compP_rReg(rFlagsRegU cr, rRegP op1, rRegP op2) 10763%{ 10764 match(Set cr (CmpP op1 op2)); 10765 10766 format %{ "cmpq $op1, $op2\t# ptr" %} 10767 opcode(0x3B); /* Opcode 3B /r */ 10768 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 10769 ins_pipe(ialu_cr_reg_reg); 10770%} 10771 10772instruct compP_rReg_mem(rFlagsRegU cr, rRegP op1, memory op2) 10773%{ 10774 match(Set cr (CmpP op1 (LoadP op2))); 10775 10776 ins_cost(500); // XXX 10777 format %{ "cmpq $op1, $op2\t# ptr" %} 10778 opcode(0x3B); /* Opcode 3B /r */ 10779 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 10780 ins_pipe(ialu_cr_reg_mem); 10781%} 10782 10783// // // Cisc-spilled version of cmpP_rReg 10784// //instruct compP_mem_rReg(rFlagsRegU cr, memory op1, rRegP op2) 10785// //%{ 10786// // match(Set cr (CmpP (LoadP op1) op2)); 10787// // 10788// // format %{ "CMPu $op1,$op2" %} 10789// // ins_cost(500); 10790// // opcode(0x39); /* Opcode 39 /r */ 10791// // ins_encode( OpcP, reg_mem( op1, op2) ); 10792// //%} 10793 10794// XXX this is generalized by compP_rReg_mem??? 10795// Compare raw pointer (used in out-of-heap check). 10796// Only works because non-oop pointers must be raw pointers 10797// and raw pointers have no anti-dependencies. 10798instruct compP_mem_rReg(rFlagsRegU cr, rRegP op1, memory op2) 10799%{ 10800 predicate(!n->in(2)->in(2)->bottom_type()->isa_oop_ptr()); 10801 match(Set cr (CmpP op1 (LoadP op2))); 10802 10803 format %{ "cmpq $op1, $op2\t# raw ptr" %} 10804 opcode(0x3B); /* Opcode 3B /r */ 10805 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 10806 ins_pipe(ialu_cr_reg_mem); 10807%} 10808 10809// This will generate a signed flags result. This should be OK since 10810// any compare to a zero should be eq/neq. 10811instruct testP_reg(rFlagsReg cr, rRegP src, immP0 zero) 10812%{ 10813 match(Set cr (CmpP src zero)); 10814 10815 format %{ "testq $src, $src\t# ptr" %} 10816 opcode(0x85); 10817 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 10818 ins_pipe(ialu_cr_reg_imm); 10819%} 10820 10821// This will generate a signed flags result. This should be OK since 10822// any compare to a zero should be eq/neq. 10823instruct testP_mem(rFlagsReg cr, memory op, immP0 zero) 10824%{ 10825 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL)); 10826 match(Set cr (CmpP (LoadP op) zero)); 10827 10828 ins_cost(500); // XXX 10829 format %{ "testq $op, 0xffffffffffffffff\t# ptr" %} 10830 opcode(0xF7); /* Opcode F7 /0 */ 10831 ins_encode(REX_mem_wide(op), 10832 OpcP, RM_opc_mem(0x00, op), Con_d32(0xFFFFFFFF)); 10833 ins_pipe(ialu_cr_reg_imm); 10834%} 10835 10836instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero) 10837%{ 10838 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL)); 10839 match(Set cr (CmpP (LoadP mem) zero)); 10840 10841 format %{ "cmpq R12, $mem\t# ptr (R12_heapbase==0)" %} 10842 ins_encode %{ 10843 __ cmpq(r12, $mem$$Address); 10844 %} 10845 ins_pipe(ialu_cr_reg_mem); 10846%} 10847 10848instruct compN_rReg(rFlagsRegU cr, rRegN op1, rRegN op2) 10849%{ 10850 match(Set cr (CmpN op1 op2)); 10851 10852 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 10853 ins_encode %{ __ cmpl($op1$$Register, $op2$$Register); %} 10854 ins_pipe(ialu_cr_reg_reg); 10855%} 10856 10857instruct compN_rReg_mem(rFlagsRegU cr, rRegN src, memory mem) 10858%{ 10859 match(Set cr (CmpN src (LoadN mem))); 10860 10861 format %{ "cmpl $src, $mem\t# compressed ptr" %} 10862 ins_encode %{ 10863 __ cmpl($src$$Register, $mem$$Address); 10864 %} 10865 ins_pipe(ialu_cr_reg_mem); 10866%} 10867 10868instruct compN_rReg_imm(rFlagsRegU cr, rRegN op1, immN op2) %{ 10869 match(Set cr (CmpN op1 op2)); 10870 10871 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 10872 ins_encode %{ 10873 __ cmp_narrow_oop($op1$$Register, (jobject)$op2$$constant); 10874 %} 10875 ins_pipe(ialu_cr_reg_imm); 10876%} 10877 10878instruct compN_mem_imm(rFlagsRegU cr, memory mem, immN src) 10879%{ 10880 match(Set cr (CmpN src (LoadN mem))); 10881 10882 format %{ "cmpl $mem, $src\t# compressed ptr" %} 10883 ins_encode %{ 10884 __ cmp_narrow_oop($mem$$Address, (jobject)$src$$constant); 10885 %} 10886 ins_pipe(ialu_cr_reg_mem); 10887%} 10888 10889instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{ 10890 match(Set cr (CmpN src zero)); 10891 10892 format %{ "testl $src, $src\t# compressed ptr" %} 10893 ins_encode %{ __ testl($src$$Register, $src$$Register); %} 10894 ins_pipe(ialu_cr_reg_imm); 10895%} 10896 10897instruct testN_mem(rFlagsReg cr, memory mem, immN0 zero) 10898%{ 10899 predicate(Universe::narrow_oop_base() != NULL); 10900 match(Set cr (CmpN (LoadN mem) zero)); 10901 10902 ins_cost(500); // XXX 10903 format %{ "testl $mem, 0xffffffff\t# compressed ptr" %} 10904 ins_encode %{ 10905 __ cmpl($mem$$Address, (int)0xFFFFFFFF); 10906 %} 10907 ins_pipe(ialu_cr_reg_mem); 10908%} 10909 10910instruct testN_mem_reg0(rFlagsReg cr, memory mem, immN0 zero) 10911%{ 10912 predicate(Universe::narrow_oop_base() == NULL); 10913 match(Set cr (CmpN (LoadN mem) zero)); 10914 10915 format %{ "cmpl R12, $mem\t# compressed ptr (R12_heapbase==0)" %} 10916 ins_encode %{ 10917 __ cmpl(r12, $mem$$Address); 10918 %} 10919 ins_pipe(ialu_cr_reg_mem); 10920%} 10921 10922// Yanked all unsigned pointer compare operations. 10923// Pointer compares are done with CmpP which is already unsigned. 10924 10925instruct compL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 10926%{ 10927 match(Set cr (CmpL op1 op2)); 10928 10929 format %{ "cmpq $op1, $op2" %} 10930 opcode(0x3B); /* Opcode 3B /r */ 10931 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 10932 ins_pipe(ialu_cr_reg_reg); 10933%} 10934 10935instruct compL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 10936%{ 10937 match(Set cr (CmpL op1 op2)); 10938 10939 format %{ "cmpq $op1, $op2" %} 10940 opcode(0x81, 0x07); /* Opcode 81 /7 */ 10941 ins_encode(OpcSErm_wide(op1, op2), Con8or32(op2)); 10942 ins_pipe(ialu_cr_reg_imm); 10943%} 10944 10945instruct compL_rReg_mem(rFlagsReg cr, rRegL op1, memory op2) 10946%{ 10947 match(Set cr (CmpL op1 (LoadL op2))); 10948 10949 format %{ "cmpq $op1, $op2" %} 10950 opcode(0x3B); /* Opcode 3B /r */ 10951 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 10952 ins_pipe(ialu_cr_reg_mem); 10953%} 10954 10955instruct testL_reg(rFlagsReg cr, rRegL src, immL0 zero) 10956%{ 10957 match(Set cr (CmpL src zero)); 10958 10959 format %{ "testq $src, $src" %} 10960 opcode(0x85); 10961 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 10962 ins_pipe(ialu_cr_reg_imm); 10963%} 10964 10965instruct testL_reg_imm(rFlagsReg cr, rRegL src, immL32 con, immL0 zero) 10966%{ 10967 match(Set cr (CmpL (AndL src con) zero)); 10968 10969 format %{ "testq $src, $con\t# long" %} 10970 opcode(0xF7, 0x00); 10971 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src), Con32(con)); 10972 ins_pipe(ialu_cr_reg_imm); 10973%} 10974 10975instruct testL_reg_mem(rFlagsReg cr, rRegL src, memory mem, immL0 zero) 10976%{ 10977 match(Set cr (CmpL (AndL src (LoadL mem)) zero)); 10978 10979 format %{ "testq $src, $mem" %} 10980 opcode(0x85); 10981 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 10982 ins_pipe(ialu_cr_reg_mem); 10983%} 10984 10985// Manifest a CmpL result in an integer register. Very painful. 10986// This is the test to avoid. 10987instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 10988%{ 10989 match(Set dst (CmpL3 src1 src2)); 10990 effect(KILL flags); 10991 10992 ins_cost(275); // XXX 10993 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 10994 "movl $dst, -1\n\t" 10995 "jl,s done\n\t" 10996 "setne $dst\n\t" 10997 "movzbl $dst, $dst\n\t" 10998 "done:" %} 10999 ins_encode(cmpl3_flag(src1, src2, dst)); 11000 ins_pipe(pipe_slow); 11001%} 11002 11003//----------Max and Min-------------------------------------------------------- 11004// Min Instructions 11005 11006instruct cmovI_reg_g(rRegI dst, rRegI src, rFlagsReg cr) 11007%{ 11008 effect(USE_DEF dst, USE src, USE cr); 11009 11010 format %{ "cmovlgt $dst, $src\t# min" %} 11011 opcode(0x0F, 0x4F); 11012 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 11013 ins_pipe(pipe_cmov_reg); 11014%} 11015 11016 11017instruct minI_rReg(rRegI dst, rRegI src) 11018%{ 11019 match(Set dst (MinI dst src)); 11020 11021 ins_cost(200); 11022 expand %{ 11023 rFlagsReg cr; 11024 compI_rReg(cr, dst, src); 11025 cmovI_reg_g(dst, src, cr); 11026 %} 11027%} 11028 11029instruct cmovI_reg_l(rRegI dst, rRegI src, rFlagsReg cr) 11030%{ 11031 effect(USE_DEF dst, USE src, USE cr); 11032 11033 format %{ "cmovllt $dst, $src\t# max" %} 11034 opcode(0x0F, 0x4C); 11035 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 11036 ins_pipe(pipe_cmov_reg); 11037%} 11038 11039 11040instruct maxI_rReg(rRegI dst, rRegI src) 11041%{ 11042 match(Set dst (MaxI dst src)); 11043 11044 ins_cost(200); 11045 expand %{ 11046 rFlagsReg cr; 11047 compI_rReg(cr, dst, src); 11048 cmovI_reg_l(dst, src, cr); 11049 %} 11050%} 11051 11052// ============================================================================ 11053// Branch Instructions 11054 11055// Jump Direct - Label defines a relative address from JMP+1 11056instruct jmpDir(label labl) 11057%{ 11058 match(Goto); 11059 effect(USE labl); 11060 11061 ins_cost(300); 11062 format %{ "jmp $labl" %} 11063 size(5); 11064 ins_encode %{ 11065 Label* L = $labl$$label; 11066 __ jmp(*L, false); // Always long jump 11067 %} 11068 ins_pipe(pipe_jmp); 11069%} 11070 11071// Jump Direct Conditional - Label defines a relative address from Jcc+1 11072instruct jmpCon(cmpOp cop, rFlagsReg cr, label labl) 11073%{ 11074 match(If cop cr); 11075 effect(USE labl); 11076 11077 ins_cost(300); 11078 format %{ "j$cop $labl" %} 11079 size(6); 11080 ins_encode %{ 11081 Label* L = $labl$$label; 11082 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11083 %} 11084 ins_pipe(pipe_jcc); 11085%} 11086 11087// Jump Direct Conditional - Label defines a relative address from Jcc+1 11088instruct jmpLoopEnd(cmpOp cop, rFlagsReg cr, label labl) 11089%{ 11090 match(CountedLoopEnd cop cr); 11091 effect(USE labl); 11092 11093 ins_cost(300); 11094 format %{ "j$cop $labl\t# loop end" %} 11095 size(6); 11096 ins_encode %{ 11097 Label* L = $labl$$label; 11098 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11099 %} 11100 ins_pipe(pipe_jcc); 11101%} 11102 11103// Jump Direct Conditional - Label defines a relative address from Jcc+1 11104instruct jmpLoopEndU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 11105 match(CountedLoopEnd cop cmp); 11106 effect(USE labl); 11107 11108 ins_cost(300); 11109 format %{ "j$cop,u $labl\t# loop end" %} 11110 size(6); 11111 ins_encode %{ 11112 Label* L = $labl$$label; 11113 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11114 %} 11115 ins_pipe(pipe_jcc); 11116%} 11117 11118instruct jmpLoopEndUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 11119 match(CountedLoopEnd cop cmp); 11120 effect(USE labl); 11121 11122 ins_cost(200); 11123 format %{ "j$cop,u $labl\t# loop end" %} 11124 size(6); 11125 ins_encode %{ 11126 Label* L = $labl$$label; 11127 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11128 %} 11129 ins_pipe(pipe_jcc); 11130%} 11131 11132// Jump Direct Conditional - using unsigned comparison 11133instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 11134 match(If cop cmp); 11135 effect(USE labl); 11136 11137 ins_cost(300); 11138 format %{ "j$cop,u $labl" %} 11139 size(6); 11140 ins_encode %{ 11141 Label* L = $labl$$label; 11142 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11143 %} 11144 ins_pipe(pipe_jcc); 11145%} 11146 11147instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 11148 match(If cop cmp); 11149 effect(USE labl); 11150 11151 ins_cost(200); 11152 format %{ "j$cop,u $labl" %} 11153 size(6); 11154 ins_encode %{ 11155 Label* L = $labl$$label; 11156 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11157 %} 11158 ins_pipe(pipe_jcc); 11159%} 11160 11161instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 11162 match(If cop cmp); 11163 effect(USE labl); 11164 11165 ins_cost(200); 11166 format %{ $$template 11167 if ($cop$$cmpcode == Assembler::notEqual) { 11168 $$emit$$"jp,u $labl\n\t" 11169 $$emit$$"j$cop,u $labl" 11170 } else { 11171 $$emit$$"jp,u done\n\t" 11172 $$emit$$"j$cop,u $labl\n\t" 11173 $$emit$$"done:" 11174 } 11175 %} 11176 ins_encode %{ 11177 Label* l = $labl$$label; 11178 if ($cop$$cmpcode == Assembler::notEqual) { 11179 __ jcc(Assembler::parity, *l, false); 11180 __ jcc(Assembler::notEqual, *l, false); 11181 } else if ($cop$$cmpcode == Assembler::equal) { 11182 Label done; 11183 __ jccb(Assembler::parity, done); 11184 __ jcc(Assembler::equal, *l, false); 11185 __ bind(done); 11186 } else { 11187 ShouldNotReachHere(); 11188 } 11189 %} 11190 ins_pipe(pipe_jcc); 11191%} 11192 11193// ============================================================================ 11194// The 2nd slow-half of a subtype check. Scan the subklass's 2ndary 11195// superklass array for an instance of the superklass. Set a hidden 11196// internal cache on a hit (cache is checked with exposed code in 11197// gen_subtype_check()). Return NZ for a miss or zero for a hit. The 11198// encoding ALSO sets flags. 11199 11200instruct partialSubtypeCheck(rdi_RegP result, 11201 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 11202 rFlagsReg cr) 11203%{ 11204 match(Set result (PartialSubtypeCheck sub super)); 11205 effect(KILL rcx, KILL cr); 11206 11207 ins_cost(1100); // slightly larger than the next version 11208 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 11209 "movl rcx, [rdi + arrayOopDesc::length_offset_in_bytes()]\t# length to scan\n\t" 11210 "addq rdi, arrayOopDex::base_offset_in_bytes(T_OBJECT)\t# Skip to start of data; set NZ in case count is zero\n\t" 11211 "repne scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t" 11212 "jne,s miss\t\t# Missed: rdi not-zero\n\t" 11213 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 11214 "xorq $result, $result\t\t Hit: rdi zero\n\t" 11215 "miss:\t" %} 11216 11217 opcode(0x1); // Force a XOR of RDI 11218 ins_encode(enc_PartialSubtypeCheck()); 11219 ins_pipe(pipe_slow); 11220%} 11221 11222instruct partialSubtypeCheck_vs_Zero(rFlagsReg cr, 11223 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 11224 immP0 zero, 11225 rdi_RegP result) 11226%{ 11227 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 11228 effect(KILL rcx, KILL result); 11229 11230 ins_cost(1000); 11231 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 11232 "movl rcx, [rdi + arrayOopDesc::length_offset_in_bytes()]\t# length to scan\n\t" 11233 "addq rdi, arrayOopDex::base_offset_in_bytes(T_OBJECT)\t# Skip to start of data; set NZ in case count is zero\n\t" 11234 "repne scasq\t# Scan *rdi++ for a match with rax while cx-- != 0\n\t" 11235 "jne,s miss\t\t# Missed: flags nz\n\t" 11236 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 11237 "miss:\t" %} 11238 11239 opcode(0x0); // No need to XOR RDI 11240 ins_encode(enc_PartialSubtypeCheck()); 11241 ins_pipe(pipe_slow); 11242%} 11243 11244// ============================================================================ 11245// Branch Instructions -- short offset versions 11246// 11247// These instructions are used to replace jumps of a long offset (the default 11248// match) with jumps of a shorter offset. These instructions are all tagged 11249// with the ins_short_branch attribute, which causes the ADLC to suppress the 11250// match rules in general matching. Instead, the ADLC generates a conversion 11251// method in the MachNode which can be used to do in-place replacement of the 11252// long variant with the shorter variant. The compiler will determine if a 11253// branch can be taken by the is_short_branch_offset() predicate in the machine 11254// specific code section of the file. 11255 11256// Jump Direct - Label defines a relative address from JMP+1 11257instruct jmpDir_short(label labl) %{ 11258 match(Goto); 11259 effect(USE labl); 11260 11261 ins_cost(300); 11262 format %{ "jmp,s $labl" %} 11263 size(2); 11264 ins_encode %{ 11265 Label* L = $labl$$label; 11266 __ jmpb(*L); 11267 %} 11268 ins_pipe(pipe_jmp); 11269 ins_short_branch(1); 11270%} 11271 11272// Jump Direct Conditional - Label defines a relative address from Jcc+1 11273instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{ 11274 match(If cop cr); 11275 effect(USE labl); 11276 11277 ins_cost(300); 11278 format %{ "j$cop,s $labl" %} 11279 size(2); 11280 ins_encode %{ 11281 Label* L = $labl$$label; 11282 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 11283 %} 11284 ins_pipe(pipe_jcc); 11285 ins_short_branch(1); 11286%} 11287 11288// Jump Direct Conditional - Label defines a relative address from Jcc+1 11289instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{ 11290 match(CountedLoopEnd cop cr); 11291 effect(USE labl); 11292 11293 ins_cost(300); 11294 format %{ "j$cop,s $labl\t# loop end" %} 11295 size(2); 11296 ins_encode %{ 11297 Label* L = $labl$$label; 11298 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 11299 %} 11300 ins_pipe(pipe_jcc); 11301 ins_short_branch(1); 11302%} 11303 11304// Jump Direct Conditional - Label defines a relative address from Jcc+1 11305instruct jmpLoopEndU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 11306 match(CountedLoopEnd cop cmp); 11307 effect(USE labl); 11308 11309 ins_cost(300); 11310 format %{ "j$cop,us $labl\t# loop end" %} 11311 size(2); 11312 ins_encode %{ 11313 Label* L = $labl$$label; 11314 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 11315 %} 11316 ins_pipe(pipe_jcc); 11317 ins_short_branch(1); 11318%} 11319 11320instruct jmpLoopEndUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 11321 match(CountedLoopEnd cop cmp); 11322 effect(USE labl); 11323 11324 ins_cost(300); 11325 format %{ "j$cop,us $labl\t# loop end" %} 11326 size(2); 11327 ins_encode %{ 11328 Label* L = $labl$$label; 11329 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 11330 %} 11331 ins_pipe(pipe_jcc); 11332 ins_short_branch(1); 11333%} 11334 11335// Jump Direct Conditional - using unsigned comparison 11336instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 11337 match(If cop cmp); 11338 effect(USE labl); 11339 11340 ins_cost(300); 11341 format %{ "j$cop,us $labl" %} 11342 size(2); 11343 ins_encode %{ 11344 Label* L = $labl$$label; 11345 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 11346 %} 11347 ins_pipe(pipe_jcc); 11348 ins_short_branch(1); 11349%} 11350 11351instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 11352 match(If cop cmp); 11353 effect(USE labl); 11354 11355 ins_cost(300); 11356 format %{ "j$cop,us $labl" %} 11357 size(2); 11358 ins_encode %{ 11359 Label* L = $labl$$label; 11360 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 11361 %} 11362 ins_pipe(pipe_jcc); 11363 ins_short_branch(1); 11364%} 11365 11366instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 11367 match(If cop cmp); 11368 effect(USE labl); 11369 11370 ins_cost(300); 11371 format %{ $$template 11372 if ($cop$$cmpcode == Assembler::notEqual) { 11373 $$emit$$"jp,u,s $labl\n\t" 11374 $$emit$$"j$cop,u,s $labl" 11375 } else { 11376 $$emit$$"jp,u,s done\n\t" 11377 $$emit$$"j$cop,u,s $labl\n\t" 11378 $$emit$$"done:" 11379 } 11380 %} 11381 size(4); 11382 ins_encode %{ 11383 Label* l = $labl$$label; 11384 if ($cop$$cmpcode == Assembler::notEqual) { 11385 __ jccb(Assembler::parity, *l); 11386 __ jccb(Assembler::notEqual, *l); 11387 } else if ($cop$$cmpcode == Assembler::equal) { 11388 Label done; 11389 __ jccb(Assembler::parity, done); 11390 __ jccb(Assembler::equal, *l); 11391 __ bind(done); 11392 } else { 11393 ShouldNotReachHere(); 11394 } 11395 %} 11396 ins_pipe(pipe_jcc); 11397 ins_short_branch(1); 11398%} 11399 11400// ============================================================================ 11401// inlined locking and unlocking 11402 11403instruct cmpFastLock(rFlagsReg cr, 11404 rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr) 11405%{ 11406 match(Set cr (FastLock object box)); 11407 effect(TEMP tmp, TEMP scr, USE_KILL box); 11408 11409 ins_cost(300); 11410 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr" %} 11411 ins_encode(Fast_Lock(object, box, tmp, scr)); 11412 ins_pipe(pipe_slow); 11413%} 11414 11415instruct cmpFastUnlock(rFlagsReg cr, 11416 rRegP object, rax_RegP box, rRegP tmp) 11417%{ 11418 match(Set cr (FastUnlock object box)); 11419 effect(TEMP tmp, USE_KILL box); 11420 11421 ins_cost(300); 11422 format %{ "fastunlock $object,$box\t! kills $box,$tmp" %} 11423 ins_encode(Fast_Unlock(object, box, tmp)); 11424 ins_pipe(pipe_slow); 11425%} 11426 11427 11428// ============================================================================ 11429// Safepoint Instructions 11430instruct safePoint_poll(rFlagsReg cr) 11431%{ 11432 predicate(!Assembler::is_polling_page_far()); 11433 match(SafePoint); 11434 effect(KILL cr); 11435 11436 format %{ "testl rax, [rip + #offset_to_poll_page]\t" 11437 "# Safepoint: poll for GC" %} 11438 ins_cost(125); 11439 ins_encode %{ 11440 AddressLiteral addr(os::get_polling_page(), relocInfo::poll_type); 11441 __ testl(rax, addr); 11442 %} 11443 ins_pipe(ialu_reg_mem); 11444%} 11445 11446instruct safePoint_poll_far(rFlagsReg cr, rRegP poll) 11447%{ 11448 predicate(Assembler::is_polling_page_far()); 11449 match(SafePoint poll); 11450 effect(KILL cr, USE poll); 11451 11452 format %{ "testl rax, [$poll]\t" 11453 "# Safepoint: poll for GC" %} 11454 ins_cost(125); 11455 ins_encode %{ 11456 __ relocate(relocInfo::poll_type); 11457 __ testl(rax, Address($poll$$Register, 0)); 11458 %} 11459 ins_pipe(ialu_reg_mem); 11460%} 11461 11462// ============================================================================ 11463// Procedure Call/Return Instructions 11464// Call Java Static Instruction 11465// Note: If this code changes, the corresponding ret_addr_offset() and 11466// compute_padding() functions will have to be adjusted. 11467instruct CallStaticJavaDirect(method meth) %{ 11468 match(CallStaticJava); 11469 predicate(!((CallStaticJavaNode*) n)->is_method_handle_invoke()); 11470 effect(USE meth); 11471 11472 ins_cost(300); 11473 format %{ "call,static " %} 11474 opcode(0xE8); /* E8 cd */ 11475 ins_encode(Java_Static_Call(meth), call_epilog); 11476 ins_pipe(pipe_slow); 11477 ins_alignment(4); 11478%} 11479 11480// Call Java Static Instruction (method handle version) 11481// Note: If this code changes, the corresponding ret_addr_offset() and 11482// compute_padding() functions will have to be adjusted. 11483instruct CallStaticJavaHandle(method meth, rbp_RegP rbp_mh_SP_save) %{ 11484 match(CallStaticJava); 11485 predicate(((CallStaticJavaNode*) n)->is_method_handle_invoke()); 11486 effect(USE meth); 11487 // RBP is saved by all callees (for interpreter stack correction). 11488 // We use it here for a similar purpose, in {preserve,restore}_SP. 11489 11490 ins_cost(300); 11491 format %{ "call,static/MethodHandle " %} 11492 opcode(0xE8); /* E8 cd */ 11493 ins_encode(preserve_SP, 11494 Java_Static_Call(meth), 11495 restore_SP, 11496 call_epilog); 11497 ins_pipe(pipe_slow); 11498 ins_alignment(4); 11499%} 11500 11501// Call Java Dynamic Instruction 11502// Note: If this code changes, the corresponding ret_addr_offset() and 11503// compute_padding() functions will have to be adjusted. 11504instruct CallDynamicJavaDirect(method meth) 11505%{ 11506 match(CallDynamicJava); 11507 effect(USE meth); 11508 11509 ins_cost(300); 11510 format %{ "movq rax, #Universe::non_oop_word()\n\t" 11511 "call,dynamic " %} 11512 opcode(0xE8); /* E8 cd */ 11513 ins_encode(Java_Dynamic_Call(meth), call_epilog); 11514 ins_pipe(pipe_slow); 11515 ins_alignment(4); 11516%} 11517 11518// Call Runtime Instruction 11519instruct CallRuntimeDirect(method meth) 11520%{ 11521 match(CallRuntime); 11522 effect(USE meth); 11523 11524 ins_cost(300); 11525 format %{ "call,runtime " %} 11526 opcode(0xE8); /* E8 cd */ 11527 ins_encode(Java_To_Runtime(meth)); 11528 ins_pipe(pipe_slow); 11529%} 11530 11531// Call runtime without safepoint 11532instruct CallLeafDirect(method meth) 11533%{ 11534 match(CallLeaf); 11535 effect(USE meth); 11536 11537 ins_cost(300); 11538 format %{ "call_leaf,runtime " %} 11539 opcode(0xE8); /* E8 cd */ 11540 ins_encode(Java_To_Runtime(meth)); 11541 ins_pipe(pipe_slow); 11542%} 11543 11544// Call runtime without safepoint 11545instruct CallLeafNoFPDirect(method meth) 11546%{ 11547 match(CallLeafNoFP); 11548 effect(USE meth); 11549 11550 ins_cost(300); 11551 format %{ "call_leaf_nofp,runtime " %} 11552 opcode(0xE8); /* E8 cd */ 11553 ins_encode(Java_To_Runtime(meth)); 11554 ins_pipe(pipe_slow); 11555%} 11556 11557// Return Instruction 11558// Remove the return address & jump to it. 11559// Notice: We always emit a nop after a ret to make sure there is room 11560// for safepoint patching 11561instruct Ret() 11562%{ 11563 match(Return); 11564 11565 format %{ "ret" %} 11566 opcode(0xC3); 11567 ins_encode(OpcP); 11568 ins_pipe(pipe_jmp); 11569%} 11570 11571// Tail Call; Jump from runtime stub to Java code. 11572// Also known as an 'interprocedural jump'. 11573// Target of jump will eventually return to caller. 11574// TailJump below removes the return address. 11575instruct TailCalljmpInd(no_rbp_RegP jump_target, rbx_RegP method_oop) 11576%{ 11577 match(TailCall jump_target method_oop); 11578 11579 ins_cost(300); 11580 format %{ "jmp $jump_target\t# rbx holds method oop" %} 11581 opcode(0xFF, 0x4); /* Opcode FF /4 */ 11582 ins_encode(REX_reg(jump_target), OpcP, reg_opc(jump_target)); 11583 ins_pipe(pipe_jmp); 11584%} 11585 11586// Tail Jump; remove the return address; jump to target. 11587// TailCall above leaves the return address around. 11588instruct tailjmpInd(no_rbp_RegP jump_target, rax_RegP ex_oop) 11589%{ 11590 match(TailJump jump_target ex_oop); 11591 11592 ins_cost(300); 11593 format %{ "popq rdx\t# pop return address\n\t" 11594 "jmp $jump_target" %} 11595 opcode(0xFF, 0x4); /* Opcode FF /4 */ 11596 ins_encode(Opcode(0x5a), // popq rdx 11597 REX_reg(jump_target), OpcP, reg_opc(jump_target)); 11598 ins_pipe(pipe_jmp); 11599%} 11600 11601// Create exception oop: created by stack-crawling runtime code. 11602// Created exception is now available to this handler, and is setup 11603// just prior to jumping to this handler. No code emitted. 11604instruct CreateException(rax_RegP ex_oop) 11605%{ 11606 match(Set ex_oop (CreateEx)); 11607 11608 size(0); 11609 // use the following format syntax 11610 format %{ "# exception oop is in rax; no code emitted" %} 11611 ins_encode(); 11612 ins_pipe(empty); 11613%} 11614 11615// Rethrow exception: 11616// The exception oop will come in the first argument position. 11617// Then JUMP (not call) to the rethrow stub code. 11618instruct RethrowException() 11619%{ 11620 match(Rethrow); 11621 11622 // use the following format syntax 11623 format %{ "jmp rethrow_stub" %} 11624 ins_encode(enc_rethrow); 11625 ins_pipe(pipe_jmp); 11626%} 11627 11628 11629// ============================================================================ 11630// This name is KNOWN by the ADLC and cannot be changed. 11631// The ADLC forces a 'TypeRawPtr::BOTTOM' output type 11632// for this guy. 11633instruct tlsLoadP(r15_RegP dst) %{ 11634 match(Set dst (ThreadLocal)); 11635 effect(DEF dst); 11636 11637 size(0); 11638 format %{ "# TLS is in R15" %} 11639 ins_encode( /*empty encoding*/ ); 11640 ins_pipe(ialu_reg_reg); 11641%} 11642 11643 11644//----------PEEPHOLE RULES----------------------------------------------------- 11645// These must follow all instruction definitions as they use the names 11646// defined in the instructions definitions. 11647// 11648// peepmatch ( root_instr_name [preceding_instruction]* ); 11649// 11650// peepconstraint %{ 11651// (instruction_number.operand_name relational_op instruction_number.operand_name 11652// [, ...] ); 11653// // instruction numbers are zero-based using left to right order in peepmatch 11654// 11655// peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 11656// // provide an instruction_number.operand_name for each operand that appears 11657// // in the replacement instruction's match rule 11658// 11659// ---------VM FLAGS--------------------------------------------------------- 11660// 11661// All peephole optimizations can be turned off using -XX:-OptoPeephole 11662// 11663// Each peephole rule is given an identifying number starting with zero and 11664// increasing by one in the order seen by the parser. An individual peephole 11665// can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 11666// on the command-line. 11667// 11668// ---------CURRENT LIMITATIONS---------------------------------------------- 11669// 11670// Only match adjacent instructions in same basic block 11671// Only equality constraints 11672// Only constraints between operands, not (0.dest_reg == RAX_enc) 11673// Only one replacement instruction 11674// 11675// ---------EXAMPLE---------------------------------------------------------- 11676// 11677// // pertinent parts of existing instructions in architecture description 11678// instruct movI(rRegI dst, rRegI src) 11679// %{ 11680// match(Set dst (CopyI src)); 11681// %} 11682// 11683// instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr) 11684// %{ 11685// match(Set dst (AddI dst src)); 11686// effect(KILL cr); 11687// %} 11688// 11689// // Change (inc mov) to lea 11690// peephole %{ 11691// // increment preceeded by register-register move 11692// peepmatch ( incI_rReg movI ); 11693// // require that the destination register of the increment 11694// // match the destination register of the move 11695// peepconstraint ( 0.dst == 1.dst ); 11696// // construct a replacement instruction that sets 11697// // the destination to ( move's source register + one ) 11698// peepreplace ( leaI_rReg_immI( 0.dst 1.src 0.src ) ); 11699// %} 11700// 11701 11702// Implementation no longer uses movX instructions since 11703// machine-independent system no longer uses CopyX nodes. 11704// 11705// peephole 11706// %{ 11707// peepmatch (incI_rReg movI); 11708// peepconstraint (0.dst == 1.dst); 11709// peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 11710// %} 11711 11712// peephole 11713// %{ 11714// peepmatch (decI_rReg movI); 11715// peepconstraint (0.dst == 1.dst); 11716// peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 11717// %} 11718 11719// peephole 11720// %{ 11721// peepmatch (addI_rReg_imm movI); 11722// peepconstraint (0.dst == 1.dst); 11723// peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 11724// %} 11725 11726// peephole 11727// %{ 11728// peepmatch (incL_rReg movL); 11729// peepconstraint (0.dst == 1.dst); 11730// peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 11731// %} 11732 11733// peephole 11734// %{ 11735// peepmatch (decL_rReg movL); 11736// peepconstraint (0.dst == 1.dst); 11737// peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 11738// %} 11739 11740// peephole 11741// %{ 11742// peepmatch (addL_rReg_imm movL); 11743// peepconstraint (0.dst == 1.dst); 11744// peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 11745// %} 11746 11747// peephole 11748// %{ 11749// peepmatch (addP_rReg_imm movP); 11750// peepconstraint (0.dst == 1.dst); 11751// peepreplace (leaP_rReg_imm(0.dst 1.src 0.src)); 11752// %} 11753 11754// // Change load of spilled value to only a spill 11755// instruct storeI(memory mem, rRegI src) 11756// %{ 11757// match(Set mem (StoreI mem src)); 11758// %} 11759// 11760// instruct loadI(rRegI dst, memory mem) 11761// %{ 11762// match(Set dst (LoadI mem)); 11763// %} 11764// 11765 11766peephole 11767%{ 11768 peepmatch (loadI storeI); 11769 peepconstraint (1.src == 0.dst, 1.mem == 0.mem); 11770 peepreplace (storeI(1.mem 1.mem 1.src)); 11771%} 11772 11773peephole 11774%{ 11775 peepmatch (loadL storeL); 11776 peepconstraint (1.src == 0.dst, 1.mem == 0.mem); 11777 peepreplace (storeL(1.mem 1.mem 1.src)); 11778%} 11779 11780//----------SMARTSPILL RULES--------------------------------------------------- 11781// These must follow all instruction definitions as they use the names 11782// defined in the instructions definitions. 11783