x86_64.ad revision 579:0fbdb4381b99
1// 2// Copyright 2003-2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 20// CA 95054 USA or visit www.sun.com if you need additional information or 21// have any 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 R12, R12_H, 330 R13, R13_H, 331 R14, R14_H); 332 333reg_class ptr_no_rbp_reg(RDX, RDX_H, 334 RAX, RAX_H, 335 RDI, RDI_H, 336 RSI, RSI_H, 337 RCX, RCX_H, 338 RBX, RBX_H, 339 R8, R8_H, 340 R9, R9_H, 341 R10, R10_H, 342 R11, R11_H, 343 R12, R12_H, 344 R13, R13_H, 345 R14, R14_H); 346 347// Class for all pointer registers except RAX, RBX and RSP 348reg_class ptr_no_rax_rbx_reg(RDX, RDX_H, 349 RBP, RBP_H, 350 RDI, RDI_H, 351 RSI, RSI_H, 352 RCX, RCX_H, 353 R8, R8_H, 354 R9, R9_H, 355 R10, R10_H, 356 R11, R11_H, 357 R12, R12_H, 358 R13, R13_H, 359 R14, R14_H); 360 361// Singleton class for RAX pointer register 362reg_class ptr_rax_reg(RAX, RAX_H); 363 364// Singleton class for RBX pointer register 365reg_class ptr_rbx_reg(RBX, RBX_H); 366 367// Singleton class for RSI pointer register 368reg_class ptr_rsi_reg(RSI, RSI_H); 369 370// Singleton class for RDI pointer register 371reg_class ptr_rdi_reg(RDI, RDI_H); 372 373// Singleton class for RBP pointer register 374reg_class ptr_rbp_reg(RBP, RBP_H); 375 376// Singleton class for stack pointer 377reg_class ptr_rsp_reg(RSP, RSP_H); 378 379// Singleton class for TLS pointer 380reg_class ptr_r15_reg(R15, R15_H); 381 382// Class for all long registers (except RSP) 383reg_class long_reg(RAX, RAX_H, 384 RDX, RDX_H, 385 RBP, RBP_H, 386 RDI, RDI_H, 387 RSI, RSI_H, 388 RCX, RCX_H, 389 RBX, RBX_H, 390 R8, R8_H, 391 R9, R9_H, 392 R10, R10_H, 393 R11, R11_H, 394 R13, R13_H, 395 R14, R14_H); 396 397// Class for all long registers except RAX, RDX (and RSP) 398reg_class long_no_rax_rdx_reg(RBP, RBP_H, 399 RDI, RDI_H, 400 RSI, RSI_H, 401 RCX, RCX_H, 402 RBX, RBX_H, 403 R8, R8_H, 404 R9, R9_H, 405 R10, R10_H, 406 R11, R11_H, 407 R13, R13_H, 408 R14, R14_H); 409 410// Class for all long registers except RCX (and RSP) 411reg_class long_no_rcx_reg(RBP, RBP_H, 412 RDI, RDI_H, 413 RSI, RSI_H, 414 RAX, RAX_H, 415 RDX, RDX_H, 416 RBX, RBX_H, 417 R8, R8_H, 418 R9, R9_H, 419 R10, R10_H, 420 R11, R11_H, 421 R13, R13_H, 422 R14, R14_H); 423 424// Class for all long registers except RAX (and RSP) 425reg_class long_no_rax_reg(RBP, RBP_H, 426 RDX, RDX_H, 427 RDI, RDI_H, 428 RSI, RSI_H, 429 RCX, RCX_H, 430 RBX, RBX_H, 431 R8, R8_H, 432 R9, R9_H, 433 R10, R10_H, 434 R11, R11_H, 435 R13, R13_H, 436 R14, R14_H); 437 438// Singleton class for RAX long register 439reg_class long_rax_reg(RAX, RAX_H); 440 441// Singleton class for RCX long register 442reg_class long_rcx_reg(RCX, RCX_H); 443 444// Singleton class for RDX long register 445reg_class long_rdx_reg(RDX, RDX_H); 446 447// Singleton class for R12 long register 448reg_class long_r12_reg(R12, R12_H); 449 450// Class for all int registers (except RSP) 451reg_class int_reg(RAX, 452 RDX, 453 RBP, 454 RDI, 455 RSI, 456 RCX, 457 RBX, 458 R8, 459 R9, 460 R10, 461 R11, 462 R13, 463 R14); 464 465// Class for all int registers except RCX (and RSP) 466reg_class int_no_rcx_reg(RAX, 467 RDX, 468 RBP, 469 RDI, 470 RSI, 471 RBX, 472 R8, 473 R9, 474 R10, 475 R11, 476 R13, 477 R14); 478 479// Class for all int registers except RAX, RDX (and RSP) 480reg_class int_no_rax_rdx_reg(RBP, 481 RDI, 482 RSI, 483 RCX, 484 RBX, 485 R8, 486 R9, 487 R10, 488 R11, 489 R13, 490 R14); 491 492// Singleton class for RAX int register 493reg_class int_rax_reg(RAX); 494 495// Singleton class for RBX int register 496reg_class int_rbx_reg(RBX); 497 498// Singleton class for RCX int register 499reg_class int_rcx_reg(RCX); 500 501// Singleton class for RCX int register 502reg_class int_rdx_reg(RDX); 503 504// Singleton class for RCX int register 505reg_class int_rdi_reg(RDI); 506 507// Singleton class for instruction pointer 508// reg_class ip_reg(RIP); 509 510// Singleton class for condition codes 511reg_class int_flags(RFLAGS); 512 513// Class for all float registers 514reg_class float_reg(XMM0, 515 XMM1, 516 XMM2, 517 XMM3, 518 XMM4, 519 XMM5, 520 XMM6, 521 XMM7, 522 XMM8, 523 XMM9, 524 XMM10, 525 XMM11, 526 XMM12, 527 XMM13, 528 XMM14, 529 XMM15); 530 531// Class for all double registers 532reg_class double_reg(XMM0, XMM0_H, 533 XMM1, XMM1_H, 534 XMM2, XMM2_H, 535 XMM3, XMM3_H, 536 XMM4, XMM4_H, 537 XMM5, XMM5_H, 538 XMM6, XMM6_H, 539 XMM7, XMM7_H, 540 XMM8, XMM8_H, 541 XMM9, XMM9_H, 542 XMM10, XMM10_H, 543 XMM11, XMM11_H, 544 XMM12, XMM12_H, 545 XMM13, XMM13_H, 546 XMM14, XMM14_H, 547 XMM15, XMM15_H); 548%} 549 550 551//----------SOURCE BLOCK------------------------------------------------------- 552// This is a block of C++ code which provides values, functions, and 553// definitions necessary in the rest of the architecture description 554source %{ 555#define RELOC_IMM64 Assembler::imm_operand 556#define RELOC_DISP32 Assembler::disp32_operand 557 558#define __ _masm. 559 560// !!!!! Special hack to get all types of calls to specify the byte offset 561// from the start of the call to the point where the return address 562// will point. 563int MachCallStaticJavaNode::ret_addr_offset() 564{ 565 return 5; // 5 bytes from start of call to where return address points 566} 567 568int MachCallDynamicJavaNode::ret_addr_offset() 569{ 570 return 15; // 15 bytes from start of call to where return address points 571} 572 573// In os_cpu .ad file 574// int MachCallRuntimeNode::ret_addr_offset() 575 576// Indicate if the safepoint node needs the polling page as an input. 577// Since amd64 does not have absolute addressing but RIP-relative 578// addressing and the polling page is within 2G, it doesn't. 579bool SafePointNode::needs_polling_address_input() 580{ 581 return false; 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 CallDynamicJavaDirectNode::compute_padding(int current_offset) const 599{ 600 current_offset += 11; // skip movq instruction + call opcode byte 601 return round_to(current_offset, alignment_required()) - current_offset; 602} 603 604#ifndef PRODUCT 605void MachBreakpointNode::format(PhaseRegAlloc*, outputStream* st) const 606{ 607 st->print("INT3"); 608} 609#endif 610 611// EMIT_RM() 612void emit_rm(CodeBuffer &cbuf, int f1, int f2, int f3) 613{ 614 unsigned char c = (unsigned char) ((f1 << 6) | (f2 << 3) | f3); 615 *(cbuf.code_end()) = c; 616 cbuf.set_code_end(cbuf.code_end() + 1); 617} 618 619// EMIT_CC() 620void emit_cc(CodeBuffer &cbuf, int f1, int f2) 621{ 622 unsigned char c = (unsigned char) (f1 | f2); 623 *(cbuf.code_end()) = c; 624 cbuf.set_code_end(cbuf.code_end() + 1); 625} 626 627// EMIT_OPCODE() 628void emit_opcode(CodeBuffer &cbuf, int code) 629{ 630 *(cbuf.code_end()) = (unsigned char) code; 631 cbuf.set_code_end(cbuf.code_end() + 1); 632} 633 634// EMIT_OPCODE() w/ relocation information 635void emit_opcode(CodeBuffer &cbuf, 636 int code, relocInfo::relocType reloc, int offset, int format) 637{ 638 cbuf.relocate(cbuf.inst_mark() + offset, reloc, format); 639 emit_opcode(cbuf, code); 640} 641 642// EMIT_D8() 643void emit_d8(CodeBuffer &cbuf, int d8) 644{ 645 *(cbuf.code_end()) = (unsigned char) d8; 646 cbuf.set_code_end(cbuf.code_end() + 1); 647} 648 649// EMIT_D16() 650void emit_d16(CodeBuffer &cbuf, int d16) 651{ 652 *((short *)(cbuf.code_end())) = d16; 653 cbuf.set_code_end(cbuf.code_end() + 2); 654} 655 656// EMIT_D32() 657void emit_d32(CodeBuffer &cbuf, int d32) 658{ 659 *((int *)(cbuf.code_end())) = d32; 660 cbuf.set_code_end(cbuf.code_end() + 4); 661} 662 663// EMIT_D64() 664void emit_d64(CodeBuffer &cbuf, int64_t d64) 665{ 666 *((int64_t*) (cbuf.code_end())) = d64; 667 cbuf.set_code_end(cbuf.code_end() + 8); 668} 669 670// emit 32 bit value and construct relocation entry from relocInfo::relocType 671void emit_d32_reloc(CodeBuffer& cbuf, 672 int d32, 673 relocInfo::relocType reloc, 674 int format) 675{ 676 assert(reloc != relocInfo::external_word_type, "use 2-arg emit_d32_reloc"); 677 cbuf.relocate(cbuf.inst_mark(), reloc, format); 678 679 *((int*) (cbuf.code_end())) = d32; 680 cbuf.set_code_end(cbuf.code_end() + 4); 681} 682 683// emit 32 bit value and construct relocation entry from RelocationHolder 684void emit_d32_reloc(CodeBuffer& cbuf, 685 int d32, 686 RelocationHolder const& rspec, 687 int format) 688{ 689#ifdef ASSERT 690 if (rspec.reloc()->type() == relocInfo::oop_type && 691 d32 != 0 && d32 != (intptr_t) Universe::non_oop_word()) { 692 assert(oop((intptr_t)d32)->is_oop() && oop((intptr_t)d32)->is_perm(), "cannot embed non-perm oops in code"); 693 } 694#endif 695 cbuf.relocate(cbuf.inst_mark(), rspec, format); 696 697 *((int* )(cbuf.code_end())) = d32; 698 cbuf.set_code_end(cbuf.code_end() + 4); 699} 700 701void emit_d32_reloc(CodeBuffer& cbuf, address addr) { 702 address next_ip = cbuf.code_end() + 4; 703 emit_d32_reloc(cbuf, (int) (addr - next_ip), 704 external_word_Relocation::spec(addr), 705 RELOC_DISP32); 706} 707 708 709// emit 64 bit value and construct relocation entry from relocInfo::relocType 710void emit_d64_reloc(CodeBuffer& cbuf, 711 int64_t d64, 712 relocInfo::relocType reloc, 713 int format) 714{ 715 cbuf.relocate(cbuf.inst_mark(), reloc, format); 716 717 *((int64_t*) (cbuf.code_end())) = d64; 718 cbuf.set_code_end(cbuf.code_end() + 8); 719} 720 721// emit 64 bit value and construct relocation entry from RelocationHolder 722void emit_d64_reloc(CodeBuffer& cbuf, 723 int64_t d64, 724 RelocationHolder const& rspec, 725 int format) 726{ 727#ifdef ASSERT 728 if (rspec.reloc()->type() == relocInfo::oop_type && 729 d64 != 0 && d64 != (int64_t) Universe::non_oop_word()) { 730 assert(oop(d64)->is_oop() && oop(d64)->is_perm(), 731 "cannot embed non-perm oops in code"); 732 } 733#endif 734 cbuf.relocate(cbuf.inst_mark(), rspec, format); 735 736 *((int64_t*) (cbuf.code_end())) = d64; 737 cbuf.set_code_end(cbuf.code_end() + 8); 738} 739 740// Access stack slot for load or store 741void store_to_stackslot(CodeBuffer &cbuf, int opcode, int rm_field, int disp) 742{ 743 emit_opcode(cbuf, opcode); // (e.g., FILD [RSP+src]) 744 if (-0x80 <= disp && disp < 0x80) { 745 emit_rm(cbuf, 0x01, rm_field, RSP_enc); // R/M byte 746 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte 747 emit_d8(cbuf, disp); // Displacement // R/M byte 748 } else { 749 emit_rm(cbuf, 0x02, rm_field, RSP_enc); // R/M byte 750 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte 751 emit_d32(cbuf, disp); // Displacement // R/M byte 752 } 753} 754 755 // rRegI ereg, memory mem) %{ // emit_reg_mem 756void encode_RegMem(CodeBuffer &cbuf, 757 int reg, 758 int base, int index, int scale, int disp, bool disp_is_oop) 759{ 760 assert(!disp_is_oop, "cannot have disp"); 761 int regenc = reg & 7; 762 int baseenc = base & 7; 763 int indexenc = index & 7; 764 765 // There is no index & no scale, use form without SIB byte 766 if (index == 0x4 && scale == 0 && base != RSP_enc && base != R12_enc) { 767 // If no displacement, mode is 0x0; unless base is [RBP] or [R13] 768 if (disp == 0 && base != RBP_enc && base != R13_enc) { 769 emit_rm(cbuf, 0x0, regenc, baseenc); // * 770 } else if (-0x80 <= disp && disp < 0x80 && !disp_is_oop) { 771 // If 8-bit displacement, mode 0x1 772 emit_rm(cbuf, 0x1, regenc, baseenc); // * 773 emit_d8(cbuf, disp); 774 } else { 775 // If 32-bit displacement 776 if (base == -1) { // Special flag for absolute address 777 emit_rm(cbuf, 0x0, regenc, 0x5); // * 778 if (disp_is_oop) { 779 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 780 } else { 781 emit_d32(cbuf, disp); 782 } 783 } else { 784 // Normal base + offset 785 emit_rm(cbuf, 0x2, regenc, baseenc); // * 786 if (disp_is_oop) { 787 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 788 } else { 789 emit_d32(cbuf, disp); 790 } 791 } 792 } 793 } else { 794 // Else, encode with the SIB byte 795 // If no displacement, mode is 0x0; unless base is [RBP] or [R13] 796 if (disp == 0 && base != RBP_enc && base != R13_enc) { 797 // If no displacement 798 emit_rm(cbuf, 0x0, regenc, 0x4); // * 799 emit_rm(cbuf, scale, indexenc, baseenc); 800 } else { 801 if (-0x80 <= disp && disp < 0x80 && !disp_is_oop) { 802 // If 8-bit displacement, mode 0x1 803 emit_rm(cbuf, 0x1, regenc, 0x4); // * 804 emit_rm(cbuf, scale, indexenc, baseenc); 805 emit_d8(cbuf, disp); 806 } else { 807 // If 32-bit displacement 808 if (base == 0x04 ) { 809 emit_rm(cbuf, 0x2, regenc, 0x4); 810 emit_rm(cbuf, scale, indexenc, 0x04); // XXX is this valid??? 811 } else { 812 emit_rm(cbuf, 0x2, regenc, 0x4); 813 emit_rm(cbuf, scale, indexenc, baseenc); // * 814 } 815 if (disp_is_oop) { 816 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 817 } else { 818 emit_d32(cbuf, disp); 819 } 820 } 821 } 822 } 823} 824 825void encode_copy(CodeBuffer &cbuf, int dstenc, int srcenc) 826{ 827 if (dstenc != srcenc) { 828 if (dstenc < 8) { 829 if (srcenc >= 8) { 830 emit_opcode(cbuf, Assembler::REX_B); 831 srcenc -= 8; 832 } 833 } else { 834 if (srcenc < 8) { 835 emit_opcode(cbuf, Assembler::REX_R); 836 } else { 837 emit_opcode(cbuf, Assembler::REX_RB); 838 srcenc -= 8; 839 } 840 dstenc -= 8; 841 } 842 843 emit_opcode(cbuf, 0x8B); 844 emit_rm(cbuf, 0x3, dstenc, srcenc); 845 } 846} 847 848void encode_CopyXD( CodeBuffer &cbuf, int dst_encoding, int src_encoding ) { 849 if( dst_encoding == src_encoding ) { 850 // reg-reg copy, use an empty encoding 851 } else { 852 MacroAssembler _masm(&cbuf); 853 854 __ movdqa(as_XMMRegister(dst_encoding), as_XMMRegister(src_encoding)); 855 } 856} 857 858 859//============================================================================= 860#ifndef PRODUCT 861void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const 862{ 863 Compile* C = ra_->C; 864 865 int framesize = C->frame_slots() << LogBytesPerInt; 866 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 867 // Remove wordSize for return adr already pushed 868 // and another for the RBP we are going to save 869 framesize -= 2*wordSize; 870 bool need_nop = true; 871 872 // Calls to C2R adapters often do not accept exceptional returns. 873 // We require that their callers must bang for them. But be 874 // careful, because some VM calls (such as call site linkage) can 875 // use several kilobytes of stack. But the stack safety zone should 876 // account for that. See bugs 4446381, 4468289, 4497237. 877 if (C->need_stack_bang(framesize)) { 878 st->print_cr("# stack bang"); st->print("\t"); 879 need_nop = false; 880 } 881 st->print_cr("pushq rbp"); st->print("\t"); 882 883 if (VerifyStackAtCalls) { 884 // Majik cookie to verify stack depth 885 st->print_cr("pushq 0xffffffffbadb100d" 886 "\t# Majik cookie for stack depth check"); 887 st->print("\t"); 888 framesize -= wordSize; // Remove 2 for cookie 889 need_nop = false; 890 } 891 892 if (framesize) { 893 st->print("subq rsp, #%d\t# Create frame", framesize); 894 if (framesize < 0x80 && need_nop) { 895 st->print("\n\tnop\t# nop for patch_verified_entry"); 896 } 897 } 898} 899#endif 900 901void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const 902{ 903 Compile* C = ra_->C; 904 905 // WARNING: Initial instruction MUST be 5 bytes or longer so that 906 // NativeJump::patch_verified_entry will be able to patch out the entry 907 // code safely. The fldcw is ok at 6 bytes, the push to verify stack 908 // depth is ok at 5 bytes, the frame allocation can be either 3 or 909 // 6 bytes. So if we don't do the fldcw or the push then we must 910 // use the 6 byte frame allocation even if we have no frame. :-( 911 // If method sets FPU control word do it now 912 913 int framesize = C->frame_slots() << LogBytesPerInt; 914 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 915 // Remove wordSize for return adr already pushed 916 // and another for the RBP we are going to save 917 framesize -= 2*wordSize; 918 bool need_nop = true; 919 920 // Calls to C2R adapters often do not accept exceptional returns. 921 // We require that their callers must bang for them. But be 922 // careful, because some VM calls (such as call site linkage) can 923 // use several kilobytes of stack. But the stack safety zone should 924 // account for that. See bugs 4446381, 4468289, 4497237. 925 if (C->need_stack_bang(framesize)) { 926 MacroAssembler masm(&cbuf); 927 masm.generate_stack_overflow_check(framesize); 928 need_nop = false; 929 } 930 931 // We always push rbp so that on return to interpreter rbp will be 932 // restored correctly and we can correct the stack. 933 emit_opcode(cbuf, 0x50 | RBP_enc); 934 935 if (VerifyStackAtCalls) { 936 // Majik cookie to verify stack depth 937 emit_opcode(cbuf, 0x68); // pushq (sign-extended) 0xbadb100d 938 emit_d32(cbuf, 0xbadb100d); 939 framesize -= wordSize; // Remove 2 for cookie 940 need_nop = false; 941 } 942 943 if (framesize) { 944 emit_opcode(cbuf, Assembler::REX_W); 945 if (framesize < 0x80) { 946 emit_opcode(cbuf, 0x83); // sub SP,#framesize 947 emit_rm(cbuf, 0x3, 0x05, RSP_enc); 948 emit_d8(cbuf, framesize); 949 if (need_nop) { 950 emit_opcode(cbuf, 0x90); // nop 951 } 952 } else { 953 emit_opcode(cbuf, 0x81); // sub SP,#framesize 954 emit_rm(cbuf, 0x3, 0x05, RSP_enc); 955 emit_d32(cbuf, framesize); 956 } 957 } 958 959 C->set_frame_complete(cbuf.code_end() - cbuf.code_begin()); 960 961#ifdef ASSERT 962 if (VerifyStackAtCalls) { 963 Label L; 964 MacroAssembler masm(&cbuf); 965 masm.push(rax); 966 masm.mov(rax, rsp); 967 masm.andptr(rax, StackAlignmentInBytes-1); 968 masm.cmpptr(rax, StackAlignmentInBytes-wordSize); 969 masm.pop(rax); 970 masm.jcc(Assembler::equal, L); 971 masm.stop("Stack is not properly aligned!"); 972 masm.bind(L); 973 } 974#endif 975} 976 977uint MachPrologNode::size(PhaseRegAlloc* ra_) const 978{ 979 return MachNode::size(ra_); // too many variables; just compute it 980 // the hard way 981} 982 983int MachPrologNode::reloc() const 984{ 985 return 0; // a large enough number 986} 987 988//============================================================================= 989#ifndef PRODUCT 990void MachEpilogNode::format(PhaseRegAlloc* ra_, outputStream* st) const 991{ 992 Compile* C = ra_->C; 993 int framesize = C->frame_slots() << LogBytesPerInt; 994 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 995 // Remove word for return adr already pushed 996 // and RBP 997 framesize -= 2*wordSize; 998 999 if (framesize) { 1000 st->print_cr("addq\trsp, %d\t# Destroy frame", framesize); 1001 st->print("\t"); 1002 } 1003 1004 st->print_cr("popq\trbp"); 1005 if (do_polling() && C->is_method_compilation()) { 1006 st->print_cr("\ttestl\trax, [rip + #offset_to_poll_page]\t" 1007 "# Safepoint: poll for GC"); 1008 st->print("\t"); 1009 } 1010} 1011#endif 1012 1013void MachEpilogNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1014{ 1015 Compile* C = ra_->C; 1016 int framesize = C->frame_slots() << LogBytesPerInt; 1017 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 1018 // Remove word for return adr already pushed 1019 // and RBP 1020 framesize -= 2*wordSize; 1021 1022 // Note that VerifyStackAtCalls' Majik cookie does not change the frame size popped here 1023 1024 if (framesize) { 1025 emit_opcode(cbuf, Assembler::REX_W); 1026 if (framesize < 0x80) { 1027 emit_opcode(cbuf, 0x83); // addq rsp, #framesize 1028 emit_rm(cbuf, 0x3, 0x00, RSP_enc); 1029 emit_d8(cbuf, framesize); 1030 } else { 1031 emit_opcode(cbuf, 0x81); // addq rsp, #framesize 1032 emit_rm(cbuf, 0x3, 0x00, RSP_enc); 1033 emit_d32(cbuf, framesize); 1034 } 1035 } 1036 1037 // popq rbp 1038 emit_opcode(cbuf, 0x58 | RBP_enc); 1039 1040 if (do_polling() && C->is_method_compilation()) { 1041 // testl %rax, off(%rip) // Opcode + ModRM + Disp32 == 6 bytes 1042 // XXX reg_mem doesn't support RIP-relative addressing yet 1043 cbuf.set_inst_mark(); 1044 cbuf.relocate(cbuf.inst_mark(), relocInfo::poll_return_type, 0); // XXX 1045 emit_opcode(cbuf, 0x85); // testl 1046 emit_rm(cbuf, 0x0, RAX_enc, 0x5); // 00 rax 101 == 0x5 1047 // cbuf.inst_mark() is beginning of instruction 1048 emit_d32_reloc(cbuf, os::get_polling_page()); 1049// relocInfo::poll_return_type, 1050 } 1051} 1052 1053uint MachEpilogNode::size(PhaseRegAlloc* ra_) const 1054{ 1055 Compile* C = ra_->C; 1056 int framesize = C->frame_slots() << LogBytesPerInt; 1057 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 1058 // Remove word for return adr already pushed 1059 // and RBP 1060 framesize -= 2*wordSize; 1061 1062 uint size = 0; 1063 1064 if (do_polling() && C->is_method_compilation()) { 1065 size += 6; 1066 } 1067 1068 // count popq rbp 1069 size++; 1070 1071 if (framesize) { 1072 if (framesize < 0x80) { 1073 size += 4; 1074 } else if (framesize) { 1075 size += 7; 1076 } 1077 } 1078 1079 return size; 1080} 1081 1082int MachEpilogNode::reloc() const 1083{ 1084 return 2; // a large enough number 1085} 1086 1087const Pipeline* MachEpilogNode::pipeline() const 1088{ 1089 return MachNode::pipeline_class(); 1090} 1091 1092int MachEpilogNode::safepoint_offset() const 1093{ 1094 return 0; 1095} 1096 1097//============================================================================= 1098 1099enum RC { 1100 rc_bad, 1101 rc_int, 1102 rc_float, 1103 rc_stack 1104}; 1105 1106static enum RC rc_class(OptoReg::Name reg) 1107{ 1108 if( !OptoReg::is_valid(reg) ) return rc_bad; 1109 1110 if (OptoReg::is_stack(reg)) return rc_stack; 1111 1112 VMReg r = OptoReg::as_VMReg(reg); 1113 1114 if (r->is_Register()) return rc_int; 1115 1116 assert(r->is_XMMRegister(), "must be"); 1117 return rc_float; 1118} 1119 1120uint MachSpillCopyNode::implementation(CodeBuffer* cbuf, 1121 PhaseRegAlloc* ra_, 1122 bool do_size, 1123 outputStream* st) const 1124{ 1125 1126 // Get registers to move 1127 OptoReg::Name src_second = ra_->get_reg_second(in(1)); 1128 OptoReg::Name src_first = ra_->get_reg_first(in(1)); 1129 OptoReg::Name dst_second = ra_->get_reg_second(this); 1130 OptoReg::Name dst_first = ra_->get_reg_first(this); 1131 1132 enum RC src_second_rc = rc_class(src_second); 1133 enum RC src_first_rc = rc_class(src_first); 1134 enum RC dst_second_rc = rc_class(dst_second); 1135 enum RC dst_first_rc = rc_class(dst_first); 1136 1137 assert(OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), 1138 "must move at least 1 register" ); 1139 1140 if (src_first == dst_first && src_second == dst_second) { 1141 // Self copy, no move 1142 return 0; 1143 } else if (src_first_rc == rc_stack) { 1144 // mem -> 1145 if (dst_first_rc == rc_stack) { 1146 // mem -> mem 1147 assert(src_second != dst_first, "overlap"); 1148 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1149 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1150 // 64-bit 1151 int src_offset = ra_->reg2offset(src_first); 1152 int dst_offset = ra_->reg2offset(dst_first); 1153 if (cbuf) { 1154 emit_opcode(*cbuf, 0xFF); 1155 encode_RegMem(*cbuf, RSI_enc, RSP_enc, 0x4, 0, src_offset, false); 1156 1157 emit_opcode(*cbuf, 0x8F); 1158 encode_RegMem(*cbuf, RAX_enc, RSP_enc, 0x4, 0, dst_offset, false); 1159 1160#ifndef PRODUCT 1161 } else if (!do_size) { 1162 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1163 "popq [rsp + #%d]", 1164 src_offset, 1165 dst_offset); 1166#endif 1167 } 1168 return 1169 3 + ((src_offset == 0) ? 0 : (src_offset < 0x80 ? 1 : 4)) + 1170 3 + ((dst_offset == 0) ? 0 : (dst_offset < 0x80 ? 1 : 4)); 1171 } else { 1172 // 32-bit 1173 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1174 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1175 // No pushl/popl, so: 1176 int src_offset = ra_->reg2offset(src_first); 1177 int dst_offset = ra_->reg2offset(dst_first); 1178 if (cbuf) { 1179 emit_opcode(*cbuf, Assembler::REX_W); 1180 emit_opcode(*cbuf, 0x89); 1181 emit_opcode(*cbuf, 0x44); 1182 emit_opcode(*cbuf, 0x24); 1183 emit_opcode(*cbuf, 0xF8); 1184 1185 emit_opcode(*cbuf, 0x8B); 1186 encode_RegMem(*cbuf, 1187 RAX_enc, 1188 RSP_enc, 0x4, 0, src_offset, 1189 false); 1190 1191 emit_opcode(*cbuf, 0x89); 1192 encode_RegMem(*cbuf, 1193 RAX_enc, 1194 RSP_enc, 0x4, 0, dst_offset, 1195 false); 1196 1197 emit_opcode(*cbuf, Assembler::REX_W); 1198 emit_opcode(*cbuf, 0x8B); 1199 emit_opcode(*cbuf, 0x44); 1200 emit_opcode(*cbuf, 0x24); 1201 emit_opcode(*cbuf, 0xF8); 1202 1203#ifndef PRODUCT 1204 } else if (!do_size) { 1205 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1206 "movl rax, [rsp + #%d]\n\t" 1207 "movl [rsp + #%d], rax\n\t" 1208 "movq rax, [rsp - #8]", 1209 src_offset, 1210 dst_offset); 1211#endif 1212 } 1213 return 1214 5 + // movq 1215 3 + ((src_offset == 0) ? 0 : (src_offset < 0x80 ? 1 : 4)) + // movl 1216 3 + ((dst_offset == 0) ? 0 : (dst_offset < 0x80 ? 1 : 4)) + // movl 1217 5; // movq 1218 } 1219 } else if (dst_first_rc == rc_int) { 1220 // mem -> gpr 1221 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1222 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1223 // 64-bit 1224 int offset = ra_->reg2offset(src_first); 1225 if (cbuf) { 1226 if (Matcher::_regEncode[dst_first] < 8) { 1227 emit_opcode(*cbuf, Assembler::REX_W); 1228 } else { 1229 emit_opcode(*cbuf, Assembler::REX_WR); 1230 } 1231 emit_opcode(*cbuf, 0x8B); 1232 encode_RegMem(*cbuf, 1233 Matcher::_regEncode[dst_first], 1234 RSP_enc, 0x4, 0, offset, 1235 false); 1236#ifndef PRODUCT 1237 } else if (!do_size) { 1238 st->print("movq %s, [rsp + #%d]\t# spill", 1239 Matcher::regName[dst_first], 1240 offset); 1241#endif 1242 } 1243 return 1244 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) + 4; // REX 1245 } else { 1246 // 32-bit 1247 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1248 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1249 int offset = ra_->reg2offset(src_first); 1250 if (cbuf) { 1251 if (Matcher::_regEncode[dst_first] >= 8) { 1252 emit_opcode(*cbuf, Assembler::REX_R); 1253 } 1254 emit_opcode(*cbuf, 0x8B); 1255 encode_RegMem(*cbuf, 1256 Matcher::_regEncode[dst_first], 1257 RSP_enc, 0x4, 0, offset, 1258 false); 1259#ifndef PRODUCT 1260 } else if (!do_size) { 1261 st->print("movl %s, [rsp + #%d]\t# spill", 1262 Matcher::regName[dst_first], 1263 offset); 1264#endif 1265 } 1266 return 1267 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) + 1268 ((Matcher::_regEncode[dst_first] < 8) 1269 ? 3 1270 : 4); // REX 1271 } 1272 } else if (dst_first_rc == rc_float) { 1273 // mem-> xmm 1274 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1275 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1276 // 64-bit 1277 int offset = ra_->reg2offset(src_first); 1278 if (cbuf) { 1279 emit_opcode(*cbuf, UseXmmLoadAndClearUpper ? 0xF2 : 0x66); 1280 if (Matcher::_regEncode[dst_first] >= 8) { 1281 emit_opcode(*cbuf, Assembler::REX_R); 1282 } 1283 emit_opcode(*cbuf, 0x0F); 1284 emit_opcode(*cbuf, UseXmmLoadAndClearUpper ? 0x10 : 0x12); 1285 encode_RegMem(*cbuf, 1286 Matcher::_regEncode[dst_first], 1287 RSP_enc, 0x4, 0, offset, 1288 false); 1289#ifndef PRODUCT 1290 } else if (!do_size) { 1291 st->print("%s %s, [rsp + #%d]\t# spill", 1292 UseXmmLoadAndClearUpper ? "movsd " : "movlpd", 1293 Matcher::regName[dst_first], 1294 offset); 1295#endif 1296 } 1297 return 1298 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) + 1299 ((Matcher::_regEncode[dst_first] < 8) 1300 ? 5 1301 : 6); // REX 1302 } else { 1303 // 32-bit 1304 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1305 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1306 int offset = ra_->reg2offset(src_first); 1307 if (cbuf) { 1308 emit_opcode(*cbuf, 0xF3); 1309 if (Matcher::_regEncode[dst_first] >= 8) { 1310 emit_opcode(*cbuf, Assembler::REX_R); 1311 } 1312 emit_opcode(*cbuf, 0x0F); 1313 emit_opcode(*cbuf, 0x10); 1314 encode_RegMem(*cbuf, 1315 Matcher::_regEncode[dst_first], 1316 RSP_enc, 0x4, 0, offset, 1317 false); 1318#ifndef PRODUCT 1319 } else if (!do_size) { 1320 st->print("movss %s, [rsp + #%d]\t# spill", 1321 Matcher::regName[dst_first], 1322 offset); 1323#endif 1324 } 1325 return 1326 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) + 1327 ((Matcher::_regEncode[dst_first] < 8) 1328 ? 5 1329 : 6); // REX 1330 } 1331 } 1332 } else if (src_first_rc == rc_int) { 1333 // gpr -> 1334 if (dst_first_rc == rc_stack) { 1335 // gpr -> mem 1336 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1337 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1338 // 64-bit 1339 int offset = ra_->reg2offset(dst_first); 1340 if (cbuf) { 1341 if (Matcher::_regEncode[src_first] < 8) { 1342 emit_opcode(*cbuf, Assembler::REX_W); 1343 } else { 1344 emit_opcode(*cbuf, Assembler::REX_WR); 1345 } 1346 emit_opcode(*cbuf, 0x89); 1347 encode_RegMem(*cbuf, 1348 Matcher::_regEncode[src_first], 1349 RSP_enc, 0x4, 0, offset, 1350 false); 1351#ifndef PRODUCT 1352 } else if (!do_size) { 1353 st->print("movq [rsp + #%d], %s\t# spill", 1354 offset, 1355 Matcher::regName[src_first]); 1356#endif 1357 } 1358 return ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) + 4; // 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 int offset = ra_->reg2offset(dst_first); 1364 if (cbuf) { 1365 if (Matcher::_regEncode[src_first] >= 8) { 1366 emit_opcode(*cbuf, Assembler::REX_R); 1367 } 1368 emit_opcode(*cbuf, 0x89); 1369 encode_RegMem(*cbuf, 1370 Matcher::_regEncode[src_first], 1371 RSP_enc, 0x4, 0, offset, 1372 false); 1373#ifndef PRODUCT 1374 } else if (!do_size) { 1375 st->print("movl [rsp + #%d], %s\t# spill", 1376 offset, 1377 Matcher::regName[src_first]); 1378#endif 1379 } 1380 return 1381 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) + 1382 ((Matcher::_regEncode[src_first] < 8) 1383 ? 3 1384 : 4); // REX 1385 } 1386 } else if (dst_first_rc == rc_int) { 1387 // gpr -> gpr 1388 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1389 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1390 // 64-bit 1391 if (cbuf) { 1392 if (Matcher::_regEncode[dst_first] < 8) { 1393 if (Matcher::_regEncode[src_first] < 8) { 1394 emit_opcode(*cbuf, Assembler::REX_W); 1395 } else { 1396 emit_opcode(*cbuf, Assembler::REX_WB); 1397 } 1398 } else { 1399 if (Matcher::_regEncode[src_first] < 8) { 1400 emit_opcode(*cbuf, Assembler::REX_WR); 1401 } else { 1402 emit_opcode(*cbuf, Assembler::REX_WRB); 1403 } 1404 } 1405 emit_opcode(*cbuf, 0x8B); 1406 emit_rm(*cbuf, 0x3, 1407 Matcher::_regEncode[dst_first] & 7, 1408 Matcher::_regEncode[src_first] & 7); 1409#ifndef PRODUCT 1410 } else if (!do_size) { 1411 st->print("movq %s, %s\t# spill", 1412 Matcher::regName[dst_first], 1413 Matcher::regName[src_first]); 1414#endif 1415 } 1416 return 3; // REX 1417 } else { 1418 // 32-bit 1419 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1420 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1421 if (cbuf) { 1422 if (Matcher::_regEncode[dst_first] < 8) { 1423 if (Matcher::_regEncode[src_first] >= 8) { 1424 emit_opcode(*cbuf, Assembler::REX_B); 1425 } 1426 } else { 1427 if (Matcher::_regEncode[src_first] < 8) { 1428 emit_opcode(*cbuf, Assembler::REX_R); 1429 } else { 1430 emit_opcode(*cbuf, Assembler::REX_RB); 1431 } 1432 } 1433 emit_opcode(*cbuf, 0x8B); 1434 emit_rm(*cbuf, 0x3, 1435 Matcher::_regEncode[dst_first] & 7, 1436 Matcher::_regEncode[src_first] & 7); 1437#ifndef PRODUCT 1438 } else if (!do_size) { 1439 st->print("movl %s, %s\t# spill", 1440 Matcher::regName[dst_first], 1441 Matcher::regName[src_first]); 1442#endif 1443 } 1444 return 1445 (Matcher::_regEncode[src_first] < 8 && Matcher::_regEncode[dst_first] < 8) 1446 ? 2 1447 : 3; // REX 1448 } 1449 } else if (dst_first_rc == rc_float) { 1450 // gpr -> xmm 1451 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1452 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1453 // 64-bit 1454 if (cbuf) { 1455 emit_opcode(*cbuf, 0x66); 1456 if (Matcher::_regEncode[dst_first] < 8) { 1457 if (Matcher::_regEncode[src_first] < 8) { 1458 emit_opcode(*cbuf, Assembler::REX_W); 1459 } else { 1460 emit_opcode(*cbuf, Assembler::REX_WB); 1461 } 1462 } else { 1463 if (Matcher::_regEncode[src_first] < 8) { 1464 emit_opcode(*cbuf, Assembler::REX_WR); 1465 } else { 1466 emit_opcode(*cbuf, Assembler::REX_WRB); 1467 } 1468 } 1469 emit_opcode(*cbuf, 0x0F); 1470 emit_opcode(*cbuf, 0x6E); 1471 emit_rm(*cbuf, 0x3, 1472 Matcher::_regEncode[dst_first] & 7, 1473 Matcher::_regEncode[src_first] & 7); 1474#ifndef PRODUCT 1475 } else if (!do_size) { 1476 st->print("movdq %s, %s\t# spill", 1477 Matcher::regName[dst_first], 1478 Matcher::regName[src_first]); 1479#endif 1480 } 1481 return 5; // REX 1482 } else { 1483 // 32-bit 1484 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1485 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1486 if (cbuf) { 1487 emit_opcode(*cbuf, 0x66); 1488 if (Matcher::_regEncode[dst_first] < 8) { 1489 if (Matcher::_regEncode[src_first] >= 8) { 1490 emit_opcode(*cbuf, Assembler::REX_B); 1491 } 1492 } else { 1493 if (Matcher::_regEncode[src_first] < 8) { 1494 emit_opcode(*cbuf, Assembler::REX_R); 1495 } else { 1496 emit_opcode(*cbuf, Assembler::REX_RB); 1497 } 1498 } 1499 emit_opcode(*cbuf, 0x0F); 1500 emit_opcode(*cbuf, 0x6E); 1501 emit_rm(*cbuf, 0x3, 1502 Matcher::_regEncode[dst_first] & 7, 1503 Matcher::_regEncode[src_first] & 7); 1504#ifndef PRODUCT 1505 } else if (!do_size) { 1506 st->print("movdl %s, %s\t# spill", 1507 Matcher::regName[dst_first], 1508 Matcher::regName[src_first]); 1509#endif 1510 } 1511 return 1512 (Matcher::_regEncode[src_first] < 8 && Matcher::_regEncode[dst_first] < 8) 1513 ? 4 1514 : 5; // REX 1515 } 1516 } 1517 } else if (src_first_rc == rc_float) { 1518 // xmm -> 1519 if (dst_first_rc == rc_stack) { 1520 // xmm -> mem 1521 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1522 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1523 // 64-bit 1524 int offset = ra_->reg2offset(dst_first); 1525 if (cbuf) { 1526 emit_opcode(*cbuf, 0xF2); 1527 if (Matcher::_regEncode[src_first] >= 8) { 1528 emit_opcode(*cbuf, Assembler::REX_R); 1529 } 1530 emit_opcode(*cbuf, 0x0F); 1531 emit_opcode(*cbuf, 0x11); 1532 encode_RegMem(*cbuf, 1533 Matcher::_regEncode[src_first], 1534 RSP_enc, 0x4, 0, offset, 1535 false); 1536#ifndef PRODUCT 1537 } else if (!do_size) { 1538 st->print("movsd [rsp + #%d], %s\t# spill", 1539 offset, 1540 Matcher::regName[src_first]); 1541#endif 1542 } 1543 return 1544 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) + 1545 ((Matcher::_regEncode[src_first] < 8) 1546 ? 5 1547 : 6); // REX 1548 } else { 1549 // 32-bit 1550 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1551 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1552 int offset = ra_->reg2offset(dst_first); 1553 if (cbuf) { 1554 emit_opcode(*cbuf, 0xF3); 1555 if (Matcher::_regEncode[src_first] >= 8) { 1556 emit_opcode(*cbuf, Assembler::REX_R); 1557 } 1558 emit_opcode(*cbuf, 0x0F); 1559 emit_opcode(*cbuf, 0x11); 1560 encode_RegMem(*cbuf, 1561 Matcher::_regEncode[src_first], 1562 RSP_enc, 0x4, 0, offset, 1563 false); 1564#ifndef PRODUCT 1565 } else if (!do_size) { 1566 st->print("movss [rsp + #%d], %s\t# spill", 1567 offset, 1568 Matcher::regName[src_first]); 1569#endif 1570 } 1571 return 1572 ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) + 1573 ((Matcher::_regEncode[src_first] < 8) 1574 ? 5 1575 : 6); // REX 1576 } 1577 } else if (dst_first_rc == rc_int) { 1578 // xmm -> gpr 1579 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1580 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1581 // 64-bit 1582 if (cbuf) { 1583 emit_opcode(*cbuf, 0x66); 1584 if (Matcher::_regEncode[dst_first] < 8) { 1585 if (Matcher::_regEncode[src_first] < 8) { 1586 emit_opcode(*cbuf, Assembler::REX_W); 1587 } else { 1588 emit_opcode(*cbuf, Assembler::REX_WR); // attention! 1589 } 1590 } else { 1591 if (Matcher::_regEncode[src_first] < 8) { 1592 emit_opcode(*cbuf, Assembler::REX_WB); // attention! 1593 } else { 1594 emit_opcode(*cbuf, Assembler::REX_WRB); 1595 } 1596 } 1597 emit_opcode(*cbuf, 0x0F); 1598 emit_opcode(*cbuf, 0x7E); 1599 emit_rm(*cbuf, 0x3, 1600 Matcher::_regEncode[dst_first] & 7, 1601 Matcher::_regEncode[src_first] & 7); 1602#ifndef PRODUCT 1603 } else if (!do_size) { 1604 st->print("movdq %s, %s\t# spill", 1605 Matcher::regName[dst_first], 1606 Matcher::regName[src_first]); 1607#endif 1608 } 1609 return 5; // REX 1610 } else { 1611 // 32-bit 1612 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1613 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1614 if (cbuf) { 1615 emit_opcode(*cbuf, 0x66); 1616 if (Matcher::_regEncode[dst_first] < 8) { 1617 if (Matcher::_regEncode[src_first] >= 8) { 1618 emit_opcode(*cbuf, Assembler::REX_R); // attention! 1619 } 1620 } else { 1621 if (Matcher::_regEncode[src_first] < 8) { 1622 emit_opcode(*cbuf, Assembler::REX_B); // attention! 1623 } else { 1624 emit_opcode(*cbuf, Assembler::REX_RB); 1625 } 1626 } 1627 emit_opcode(*cbuf, 0x0F); 1628 emit_opcode(*cbuf, 0x7E); 1629 emit_rm(*cbuf, 0x3, 1630 Matcher::_regEncode[dst_first] & 7, 1631 Matcher::_regEncode[src_first] & 7); 1632#ifndef PRODUCT 1633 } else if (!do_size) { 1634 st->print("movdl %s, %s\t# spill", 1635 Matcher::regName[dst_first], 1636 Matcher::regName[src_first]); 1637#endif 1638 } 1639 return 1640 (Matcher::_regEncode[src_first] < 8 && Matcher::_regEncode[dst_first] < 8) 1641 ? 4 1642 : 5; // REX 1643 } 1644 } else if (dst_first_rc == rc_float) { 1645 // xmm -> xmm 1646 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1647 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1648 // 64-bit 1649 if (cbuf) { 1650 emit_opcode(*cbuf, UseXmmRegToRegMoveAll ? 0x66 : 0xF2); 1651 if (Matcher::_regEncode[dst_first] < 8) { 1652 if (Matcher::_regEncode[src_first] >= 8) { 1653 emit_opcode(*cbuf, Assembler::REX_B); 1654 } 1655 } else { 1656 if (Matcher::_regEncode[src_first] < 8) { 1657 emit_opcode(*cbuf, Assembler::REX_R); 1658 } else { 1659 emit_opcode(*cbuf, Assembler::REX_RB); 1660 } 1661 } 1662 emit_opcode(*cbuf, 0x0F); 1663 emit_opcode(*cbuf, UseXmmRegToRegMoveAll ? 0x28 : 0x10); 1664 emit_rm(*cbuf, 0x3, 1665 Matcher::_regEncode[dst_first] & 7, 1666 Matcher::_regEncode[src_first] & 7); 1667#ifndef PRODUCT 1668 } else if (!do_size) { 1669 st->print("%s %s, %s\t# spill", 1670 UseXmmRegToRegMoveAll ? "movapd" : "movsd ", 1671 Matcher::regName[dst_first], 1672 Matcher::regName[src_first]); 1673#endif 1674 } 1675 return 1676 (Matcher::_regEncode[src_first] < 8 && Matcher::_regEncode[dst_first] < 8) 1677 ? 4 1678 : 5; // REX 1679 } else { 1680 // 32-bit 1681 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1682 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1683 if (cbuf) { 1684 if (!UseXmmRegToRegMoveAll) 1685 emit_opcode(*cbuf, 0xF3); 1686 if (Matcher::_regEncode[dst_first] < 8) { 1687 if (Matcher::_regEncode[src_first] >= 8) { 1688 emit_opcode(*cbuf, Assembler::REX_B); 1689 } 1690 } else { 1691 if (Matcher::_regEncode[src_first] < 8) { 1692 emit_opcode(*cbuf, Assembler::REX_R); 1693 } else { 1694 emit_opcode(*cbuf, Assembler::REX_RB); 1695 } 1696 } 1697 emit_opcode(*cbuf, 0x0F); 1698 emit_opcode(*cbuf, UseXmmRegToRegMoveAll ? 0x28 : 0x10); 1699 emit_rm(*cbuf, 0x3, 1700 Matcher::_regEncode[dst_first] & 7, 1701 Matcher::_regEncode[src_first] & 7); 1702#ifndef PRODUCT 1703 } else if (!do_size) { 1704 st->print("%s %s, %s\t# spill", 1705 UseXmmRegToRegMoveAll ? "movaps" : "movss ", 1706 Matcher::regName[dst_first], 1707 Matcher::regName[src_first]); 1708#endif 1709 } 1710 return 1711 (Matcher::_regEncode[src_first] < 8 && Matcher::_regEncode[dst_first] < 8) 1712 ? (UseXmmRegToRegMoveAll ? 3 : 4) 1713 : (UseXmmRegToRegMoveAll ? 4 : 5); // REX 1714 } 1715 } 1716 } 1717 1718 assert(0," foo "); 1719 Unimplemented(); 1720 1721 return 0; 1722} 1723 1724#ifndef PRODUCT 1725void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream* st) const 1726{ 1727 implementation(NULL, ra_, false, st); 1728} 1729#endif 1730 1731void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const 1732{ 1733 implementation(&cbuf, ra_, false, NULL); 1734} 1735 1736uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const 1737{ 1738 return implementation(NULL, ra_, true, NULL); 1739} 1740 1741//============================================================================= 1742#ifndef PRODUCT 1743void MachNopNode::format(PhaseRegAlloc*, outputStream* st) const 1744{ 1745 st->print("nop \t# %d bytes pad for loops and calls", _count); 1746} 1747#endif 1748 1749void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc*) const 1750{ 1751 MacroAssembler _masm(&cbuf); 1752 __ nop(_count); 1753} 1754 1755uint MachNopNode::size(PhaseRegAlloc*) const 1756{ 1757 return _count; 1758} 1759 1760 1761//============================================================================= 1762#ifndef PRODUCT 1763void BoxLockNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1764{ 1765 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1766 int reg = ra_->get_reg_first(this); 1767 st->print("leaq %s, [rsp + #%d]\t# box lock", 1768 Matcher::regName[reg], offset); 1769} 1770#endif 1771 1772void BoxLockNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1773{ 1774 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1775 int reg = ra_->get_encode(this); 1776 if (offset >= 0x80) { 1777 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR); 1778 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset] 1779 emit_rm(cbuf, 0x2, reg & 7, 0x04); 1780 emit_rm(cbuf, 0x0, 0x04, RSP_enc); 1781 emit_d32(cbuf, offset); 1782 } else { 1783 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR); 1784 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset] 1785 emit_rm(cbuf, 0x1, reg & 7, 0x04); 1786 emit_rm(cbuf, 0x0, 0x04, RSP_enc); 1787 emit_d8(cbuf, offset); 1788 } 1789} 1790 1791uint BoxLockNode::size(PhaseRegAlloc *ra_) const 1792{ 1793 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1794 return (offset < 0x80) ? 5 : 8; // REX 1795} 1796 1797//============================================================================= 1798 1799// emit call stub, compiled java to interpreter 1800void emit_java_to_interp(CodeBuffer& cbuf) 1801{ 1802 // Stub is fixed up when the corresponding call is converted from 1803 // calling compiled code to calling interpreted code. 1804 // movq rbx, 0 1805 // jmp -5 # to self 1806 1807 address mark = cbuf.inst_mark(); // get mark within main instrs section 1808 1809 // Note that the code buffer's inst_mark is always relative to insts. 1810 // That's why we must use the macroassembler to generate a stub. 1811 MacroAssembler _masm(&cbuf); 1812 1813 address base = 1814 __ start_a_stub(Compile::MAX_stubs_size); 1815 if (base == NULL) return; // CodeBuffer::expand failed 1816 // static stub relocation stores the instruction address of the call 1817 __ relocate(static_stub_Relocation::spec(mark), RELOC_IMM64); 1818 // static stub relocation also tags the methodOop in the code-stream. 1819 __ movoop(rbx, (jobject) NULL); // method is zapped till fixup time 1820 // This is recognized as unresolved by relocs/nativeinst/ic code 1821 __ jump(RuntimeAddress(__ pc())); 1822 1823 // Update current stubs pointer and restore code_end. 1824 __ end_a_stub(); 1825} 1826 1827// size of call stub, compiled java to interpretor 1828uint size_java_to_interp() 1829{ 1830 return 15; // movq (1+1+8); jmp (1+4) 1831} 1832 1833// relocation entries for call stub, compiled java to interpretor 1834uint reloc_java_to_interp() 1835{ 1836 return 4; // 3 in emit_java_to_interp + 1 in Java_Static_Call 1837} 1838 1839//============================================================================= 1840#ifndef PRODUCT 1841void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1842{ 1843 if (UseCompressedOops) { 1844 st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes() #%d]\t", oopDesc::klass_offset_in_bytes()); 1845 st->print_cr("leaq rscratch1, [r12_heapbase, r, Address::times_8, 0]"); 1846 st->print_cr("cmpq rax, rscratch1\t # Inline cache check"); 1847 } else { 1848 st->print_cr("cmpq rax, [j_rarg0 + oopDesc::klass_offset_in_bytes() #%d]\t" 1849 "# Inline cache check", oopDesc::klass_offset_in_bytes()); 1850 } 1851 st->print_cr("\tjne SharedRuntime::_ic_miss_stub"); 1852 st->print_cr("\tnop"); 1853 if (!OptoBreakpoint) { 1854 st->print_cr("\tnop"); 1855 } 1856} 1857#endif 1858 1859void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1860{ 1861 MacroAssembler masm(&cbuf); 1862#ifdef ASSERT 1863 uint code_size = cbuf.code_size(); 1864#endif 1865 if (UseCompressedOops) { 1866 masm.load_klass(rscratch1, j_rarg0); 1867 masm.cmpptr(rax, rscratch1); 1868 } else { 1869 masm.cmpptr(rax, Address(j_rarg0, oopDesc::klass_offset_in_bytes())); 1870 } 1871 1872 masm.jump_cc(Assembler::notEqual, RuntimeAddress(SharedRuntime::get_ic_miss_stub())); 1873 1874 /* WARNING these NOPs are critical so that verified entry point is properly 1875 aligned for patching by NativeJump::patch_verified_entry() */ 1876 int nops_cnt = 1; 1877 if (!OptoBreakpoint) { 1878 // Leave space for int3 1879 nops_cnt += 1; 1880 } 1881 if (UseCompressedOops) { 1882 // ??? divisible by 4 is aligned? 1883 nops_cnt += 1; 1884 } 1885 masm.nop(nops_cnt); 1886 1887 assert(cbuf.code_size() - code_size == size(ra_), 1888 "checking code size of inline cache node"); 1889} 1890 1891uint MachUEPNode::size(PhaseRegAlloc* ra_) const 1892{ 1893 if (UseCompressedOops) { 1894 return OptoBreakpoint ? 19 : 20; 1895 } else { 1896 return OptoBreakpoint ? 11 : 12; 1897 } 1898} 1899 1900 1901//============================================================================= 1902uint size_exception_handler() 1903{ 1904 // NativeCall instruction size is the same as NativeJump. 1905 // Note that this value is also credited (in output.cpp) to 1906 // the size of the code section. 1907 return NativeJump::instruction_size; 1908} 1909 1910// Emit exception handler code. 1911int emit_exception_handler(CodeBuffer& cbuf) 1912{ 1913 1914 // Note that the code buffer's inst_mark is always relative to insts. 1915 // That's why we must use the macroassembler to generate a handler. 1916 MacroAssembler _masm(&cbuf); 1917 address base = 1918 __ start_a_stub(size_exception_handler()); 1919 if (base == NULL) return 0; // CodeBuffer::expand failed 1920 int offset = __ offset(); 1921 __ jump(RuntimeAddress(OptoRuntime::exception_blob()->instructions_begin())); 1922 assert(__ offset() - offset <= (int) size_exception_handler(), "overflow"); 1923 __ end_a_stub(); 1924 return offset; 1925} 1926 1927uint size_deopt_handler() 1928{ 1929 // three 5 byte instructions 1930 return 15; 1931} 1932 1933// Emit deopt handler code. 1934int emit_deopt_handler(CodeBuffer& cbuf) 1935{ 1936 1937 // Note that the code buffer's inst_mark is always relative to insts. 1938 // That's why we must use the macroassembler to generate a handler. 1939 MacroAssembler _masm(&cbuf); 1940 address base = 1941 __ start_a_stub(size_deopt_handler()); 1942 if (base == NULL) return 0; // CodeBuffer::expand failed 1943 int offset = __ offset(); 1944 address the_pc = (address) __ pc(); 1945 Label next; 1946 // push a "the_pc" on the stack without destroying any registers 1947 // as they all may be live. 1948 1949 // push address of "next" 1950 __ call(next, relocInfo::none); // reloc none is fine since it is a disp32 1951 __ bind(next); 1952 // adjust it so it matches "the_pc" 1953 __ subptr(Address(rsp, 0), __ offset() - offset); 1954 __ jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack())); 1955 assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow"); 1956 __ end_a_stub(); 1957 return offset; 1958} 1959 1960static void emit_double_constant(CodeBuffer& cbuf, double x) { 1961 int mark = cbuf.insts()->mark_off(); 1962 MacroAssembler _masm(&cbuf); 1963 address double_address = __ double_constant(x); 1964 cbuf.insts()->set_mark_off(mark); // preserve mark across masm shift 1965 emit_d32_reloc(cbuf, 1966 (int) (double_address - cbuf.code_end() - 4), 1967 internal_word_Relocation::spec(double_address), 1968 RELOC_DISP32); 1969} 1970 1971static void emit_float_constant(CodeBuffer& cbuf, float x) { 1972 int mark = cbuf.insts()->mark_off(); 1973 MacroAssembler _masm(&cbuf); 1974 address float_address = __ float_constant(x); 1975 cbuf.insts()->set_mark_off(mark); // preserve mark across masm shift 1976 emit_d32_reloc(cbuf, 1977 (int) (float_address - cbuf.code_end() - 4), 1978 internal_word_Relocation::spec(float_address), 1979 RELOC_DISP32); 1980} 1981 1982 1983int Matcher::regnum_to_fpu_offset(int regnum) 1984{ 1985 return regnum - 32; // The FP registers are in the second chunk 1986} 1987 1988// This is UltraSparc specific, true just means we have fast l2f conversion 1989const bool Matcher::convL2FSupported(void) { 1990 return true; 1991} 1992 1993// Vector width in bytes 1994const uint Matcher::vector_width_in_bytes(void) { 1995 return 8; 1996} 1997 1998// Vector ideal reg 1999const uint Matcher::vector_ideal_reg(void) { 2000 return Op_RegD; 2001} 2002 2003// Is this branch offset short enough that a short branch can be used? 2004// 2005// NOTE: If the platform does not provide any short branch variants, then 2006// this method should return false for offset 0. 2007bool Matcher::is_short_branch_offset(int rule, int offset) { 2008 // the short version of jmpConUCF2 contains multiple branches, 2009 // making the reach slightly less 2010 if (rule == jmpConUCF2_rule) 2011 return (-126 <= offset && offset <= 125); 2012 return (-128 <= offset && offset <= 127); 2013} 2014 2015const bool Matcher::isSimpleConstant64(jlong value) { 2016 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?. 2017 //return value == (int) value; // Cf. storeImmL and immL32. 2018 2019 // Probably always true, even if a temp register is required. 2020 return true; 2021} 2022 2023// The ecx parameter to rep stosq for the ClearArray node is in words. 2024const bool Matcher::init_array_count_is_in_bytes = false; 2025 2026// Threshold size for cleararray. 2027const int Matcher::init_array_short_size = 8 * BytesPerLong; 2028 2029// Should the Matcher clone shifts on addressing modes, expecting them 2030// to be subsumed into complex addressing expressions or compute them 2031// into registers? True for Intel but false for most RISCs 2032const bool Matcher::clone_shift_expressions = true; 2033 2034// Is it better to copy float constants, or load them directly from 2035// memory? Intel can load a float constant from a direct address, 2036// requiring no extra registers. Most RISCs will have to materialize 2037// an address into a register first, so they would do better to copy 2038// the constant from stack. 2039const bool Matcher::rematerialize_float_constants = true; // XXX 2040 2041// If CPU can load and store mis-aligned doubles directly then no 2042// fixup is needed. Else we split the double into 2 integer pieces 2043// and move it piece-by-piece. Only happens when passing doubles into 2044// C code as the Java calling convention forces doubles to be aligned. 2045const bool Matcher::misaligned_doubles_ok = true; 2046 2047// No-op on amd64 2048void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) {} 2049 2050// Advertise here if the CPU requires explicit rounding operations to 2051// implement the UseStrictFP mode. 2052const bool Matcher::strict_fp_requires_explicit_rounding = true; 2053 2054// Do floats take an entire double register or just half? 2055const bool Matcher::float_in_double = true; 2056// Do ints take an entire long register or just half? 2057const bool Matcher::int_in_long = true; 2058 2059// Return whether or not this register is ever used as an argument. 2060// This function is used on startup to build the trampoline stubs in 2061// generateOptoStub. Registers not mentioned will be killed by the VM 2062// call in the trampoline, and arguments in those registers not be 2063// available to the callee. 2064bool Matcher::can_be_java_arg(int reg) 2065{ 2066 return 2067 reg == RDI_num || reg == RDI_H_num || 2068 reg == RSI_num || reg == RSI_H_num || 2069 reg == RDX_num || reg == RDX_H_num || 2070 reg == RCX_num || reg == RCX_H_num || 2071 reg == R8_num || reg == R8_H_num || 2072 reg == R9_num || reg == R9_H_num || 2073 reg == R12_num || reg == R12_H_num || 2074 reg == XMM0_num || reg == XMM0_H_num || 2075 reg == XMM1_num || reg == XMM1_H_num || 2076 reg == XMM2_num || reg == XMM2_H_num || 2077 reg == XMM3_num || reg == XMM3_H_num || 2078 reg == XMM4_num || reg == XMM4_H_num || 2079 reg == XMM5_num || reg == XMM5_H_num || 2080 reg == XMM6_num || reg == XMM6_H_num || 2081 reg == XMM7_num || reg == XMM7_H_num; 2082} 2083 2084bool Matcher::is_spillable_arg(int reg) 2085{ 2086 return can_be_java_arg(reg); 2087} 2088 2089// Register for DIVI projection of divmodI 2090RegMask Matcher::divI_proj_mask() { 2091 return INT_RAX_REG_mask; 2092} 2093 2094// Register for MODI projection of divmodI 2095RegMask Matcher::modI_proj_mask() { 2096 return INT_RDX_REG_mask; 2097} 2098 2099// Register for DIVL projection of divmodL 2100RegMask Matcher::divL_proj_mask() { 2101 return LONG_RAX_REG_mask; 2102} 2103 2104// Register for MODL projection of divmodL 2105RegMask Matcher::modL_proj_mask() { 2106 return LONG_RDX_REG_mask; 2107} 2108 2109static Address build_address(int b, int i, int s, int d) { 2110 Register index = as_Register(i); 2111 Address::ScaleFactor scale = (Address::ScaleFactor)s; 2112 if (index == rsp) { 2113 index = noreg; 2114 scale = Address::no_scale; 2115 } 2116 Address addr(as_Register(b), index, scale, d); 2117 return addr; 2118} 2119 2120%} 2121 2122//----------ENCODING BLOCK----------------------------------------------------- 2123// This block specifies the encoding classes used by the compiler to 2124// output byte streams. Encoding classes are parameterized macros 2125// used by Machine Instruction Nodes in order to generate the bit 2126// encoding of the instruction. Operands specify their base encoding 2127// interface with the interface keyword. There are currently 2128// supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & 2129// COND_INTER. REG_INTER causes an operand to generate a function 2130// which returns its register number when queried. CONST_INTER causes 2131// an operand to generate a function which returns the value of the 2132// constant when queried. MEMORY_INTER causes an operand to generate 2133// four functions which return the Base Register, the Index Register, 2134// the Scale Value, and the Offset Value of the operand when queried. 2135// COND_INTER causes an operand to generate six functions which return 2136// the encoding code (ie - encoding bits for the instruction) 2137// associated with each basic boolean condition for a conditional 2138// instruction. 2139// 2140// Instructions specify two basic values for encoding. Again, a 2141// function is available to check if the constant displacement is an 2142// oop. They use the ins_encode keyword to specify their encoding 2143// classes (which must be a sequence of enc_class names, and their 2144// parameters, specified in the encoding block), and they use the 2145// opcode keyword to specify, in order, their primary, secondary, and 2146// tertiary opcode. Only the opcode sections which a particular 2147// instruction needs for encoding need to be specified. 2148encode %{ 2149 // Build emit functions for each basic byte or larger field in the 2150 // intel encoding scheme (opcode, rm, sib, immediate), and call them 2151 // from C++ code in the enc_class source block. Emit functions will 2152 // live in the main source block for now. In future, we can 2153 // generalize this by adding a syntax that specifies the sizes of 2154 // fields in an order, so that the adlc can build the emit functions 2155 // automagically 2156 2157 // Emit primary opcode 2158 enc_class OpcP 2159 %{ 2160 emit_opcode(cbuf, $primary); 2161 %} 2162 2163 // Emit secondary opcode 2164 enc_class OpcS 2165 %{ 2166 emit_opcode(cbuf, $secondary); 2167 %} 2168 2169 // Emit tertiary opcode 2170 enc_class OpcT 2171 %{ 2172 emit_opcode(cbuf, $tertiary); 2173 %} 2174 2175 // Emit opcode directly 2176 enc_class Opcode(immI d8) 2177 %{ 2178 emit_opcode(cbuf, $d8$$constant); 2179 %} 2180 2181 // Emit size prefix 2182 enc_class SizePrefix 2183 %{ 2184 emit_opcode(cbuf, 0x66); 2185 %} 2186 2187 enc_class reg(rRegI reg) 2188 %{ 2189 emit_rm(cbuf, 0x3, 0, $reg$$reg & 7); 2190 %} 2191 2192 enc_class reg_reg(rRegI dst, rRegI src) 2193 %{ 2194 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); 2195 %} 2196 2197 enc_class opc_reg_reg(immI opcode, rRegI dst, rRegI src) 2198 %{ 2199 emit_opcode(cbuf, $opcode$$constant); 2200 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); 2201 %} 2202 2203 enc_class cmpfp_fixup() 2204 %{ 2205 // jnp,s exit 2206 emit_opcode(cbuf, 0x7B); 2207 emit_d8(cbuf, 0x0A); 2208 2209 // pushfq 2210 emit_opcode(cbuf, 0x9C); 2211 2212 // andq $0xffffff2b, (%rsp) 2213 emit_opcode(cbuf, Assembler::REX_W); 2214 emit_opcode(cbuf, 0x81); 2215 emit_opcode(cbuf, 0x24); 2216 emit_opcode(cbuf, 0x24); 2217 emit_d32(cbuf, 0xffffff2b); 2218 2219 // popfq 2220 emit_opcode(cbuf, 0x9D); 2221 2222 // nop (target for branch to avoid branch to branch) 2223 emit_opcode(cbuf, 0x90); 2224 %} 2225 2226 enc_class cmpfp3(rRegI dst) 2227 %{ 2228 int dstenc = $dst$$reg; 2229 2230 // movl $dst, -1 2231 if (dstenc >= 8) { 2232 emit_opcode(cbuf, Assembler::REX_B); 2233 } 2234 emit_opcode(cbuf, 0xB8 | (dstenc & 7)); 2235 emit_d32(cbuf, -1); 2236 2237 // jp,s done 2238 emit_opcode(cbuf, 0x7A); 2239 emit_d8(cbuf, dstenc < 4 ? 0x08 : 0x0A); 2240 2241 // jb,s done 2242 emit_opcode(cbuf, 0x72); 2243 emit_d8(cbuf, dstenc < 4 ? 0x06 : 0x08); 2244 2245 // setne $dst 2246 if (dstenc >= 4) { 2247 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_B); 2248 } 2249 emit_opcode(cbuf, 0x0F); 2250 emit_opcode(cbuf, 0x95); 2251 emit_opcode(cbuf, 0xC0 | (dstenc & 7)); 2252 2253 // movzbl $dst, $dst 2254 if (dstenc >= 4) { 2255 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_RB); 2256 } 2257 emit_opcode(cbuf, 0x0F); 2258 emit_opcode(cbuf, 0xB6); 2259 emit_rm(cbuf, 0x3, dstenc & 7, dstenc & 7); 2260 %} 2261 2262 enc_class cdql_enc(no_rax_rdx_RegI div) 2263 %{ 2264 // Full implementation of Java idiv and irem; checks for 2265 // special case as described in JVM spec., p.243 & p.271. 2266 // 2267 // normal case special case 2268 // 2269 // input : rax: dividend min_int 2270 // reg: divisor -1 2271 // 2272 // output: rax: quotient (= rax idiv reg) min_int 2273 // rdx: remainder (= rax irem reg) 0 2274 // 2275 // Code sequnce: 2276 // 2277 // 0: 3d 00 00 00 80 cmp $0x80000000,%eax 2278 // 5: 75 07/08 jne e <normal> 2279 // 7: 33 d2 xor %edx,%edx 2280 // [div >= 8 -> offset + 1] 2281 // [REX_B] 2282 // 9: 83 f9 ff cmp $0xffffffffffffffff,$div 2283 // c: 74 03/04 je 11 <done> 2284 // 000000000000000e <normal>: 2285 // e: 99 cltd 2286 // [div >= 8 -> offset + 1] 2287 // [REX_B] 2288 // f: f7 f9 idiv $div 2289 // 0000000000000011 <done>: 2290 2291 // cmp $0x80000000,%eax 2292 emit_opcode(cbuf, 0x3d); 2293 emit_d8(cbuf, 0x00); 2294 emit_d8(cbuf, 0x00); 2295 emit_d8(cbuf, 0x00); 2296 emit_d8(cbuf, 0x80); 2297 2298 // jne e <normal> 2299 emit_opcode(cbuf, 0x75); 2300 emit_d8(cbuf, $div$$reg < 8 ? 0x07 : 0x08); 2301 2302 // xor %edx,%edx 2303 emit_opcode(cbuf, 0x33); 2304 emit_d8(cbuf, 0xD2); 2305 2306 // cmp $0xffffffffffffffff,%ecx 2307 if ($div$$reg >= 8) { 2308 emit_opcode(cbuf, Assembler::REX_B); 2309 } 2310 emit_opcode(cbuf, 0x83); 2311 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7); 2312 emit_d8(cbuf, 0xFF); 2313 2314 // je 11 <done> 2315 emit_opcode(cbuf, 0x74); 2316 emit_d8(cbuf, $div$$reg < 8 ? 0x03 : 0x04); 2317 2318 // <normal> 2319 // cltd 2320 emit_opcode(cbuf, 0x99); 2321 2322 // idivl (note: must be emitted by the user of this rule) 2323 // <done> 2324 %} 2325 2326 enc_class cdqq_enc(no_rax_rdx_RegL div) 2327 %{ 2328 // Full implementation of Java ldiv and lrem; checks for 2329 // special case as described in JVM spec., p.243 & p.271. 2330 // 2331 // normal case special case 2332 // 2333 // input : rax: dividend min_long 2334 // reg: divisor -1 2335 // 2336 // output: rax: quotient (= rax idiv reg) min_long 2337 // rdx: remainder (= rax irem reg) 0 2338 // 2339 // Code sequnce: 2340 // 2341 // 0: 48 ba 00 00 00 00 00 mov $0x8000000000000000,%rdx 2342 // 7: 00 00 80 2343 // a: 48 39 d0 cmp %rdx,%rax 2344 // d: 75 08 jne 17 <normal> 2345 // f: 33 d2 xor %edx,%edx 2346 // 11: 48 83 f9 ff cmp $0xffffffffffffffff,$div 2347 // 15: 74 05 je 1c <done> 2348 // 0000000000000017 <normal>: 2349 // 17: 48 99 cqto 2350 // 19: 48 f7 f9 idiv $div 2351 // 000000000000001c <done>: 2352 2353 // mov $0x8000000000000000,%rdx 2354 emit_opcode(cbuf, Assembler::REX_W); 2355 emit_opcode(cbuf, 0xBA); 2356 emit_d8(cbuf, 0x00); 2357 emit_d8(cbuf, 0x00); 2358 emit_d8(cbuf, 0x00); 2359 emit_d8(cbuf, 0x00); 2360 emit_d8(cbuf, 0x00); 2361 emit_d8(cbuf, 0x00); 2362 emit_d8(cbuf, 0x00); 2363 emit_d8(cbuf, 0x80); 2364 2365 // cmp %rdx,%rax 2366 emit_opcode(cbuf, Assembler::REX_W); 2367 emit_opcode(cbuf, 0x39); 2368 emit_d8(cbuf, 0xD0); 2369 2370 // jne 17 <normal> 2371 emit_opcode(cbuf, 0x75); 2372 emit_d8(cbuf, 0x08); 2373 2374 // xor %edx,%edx 2375 emit_opcode(cbuf, 0x33); 2376 emit_d8(cbuf, 0xD2); 2377 2378 // cmp $0xffffffffffffffff,$div 2379 emit_opcode(cbuf, $div$$reg < 8 ? Assembler::REX_W : Assembler::REX_WB); 2380 emit_opcode(cbuf, 0x83); 2381 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7); 2382 emit_d8(cbuf, 0xFF); 2383 2384 // je 1e <done> 2385 emit_opcode(cbuf, 0x74); 2386 emit_d8(cbuf, 0x05); 2387 2388 // <normal> 2389 // cqto 2390 emit_opcode(cbuf, Assembler::REX_W); 2391 emit_opcode(cbuf, 0x99); 2392 2393 // idivq (note: must be emitted by the user of this rule) 2394 // <done> 2395 %} 2396 2397 // Opcde enc_class for 8/32 bit immediate instructions with sign-extension 2398 enc_class OpcSE(immI imm) 2399 %{ 2400 // Emit primary opcode and set sign-extend bit 2401 // Check for 8-bit immediate, and set sign extend bit in opcode 2402 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2403 emit_opcode(cbuf, $primary | 0x02); 2404 } else { 2405 // 32-bit immediate 2406 emit_opcode(cbuf, $primary); 2407 } 2408 %} 2409 2410 enc_class OpcSErm(rRegI dst, immI imm) 2411 %{ 2412 // OpcSEr/m 2413 int dstenc = $dst$$reg; 2414 if (dstenc >= 8) { 2415 emit_opcode(cbuf, Assembler::REX_B); 2416 dstenc -= 8; 2417 } 2418 // Emit primary opcode and set sign-extend bit 2419 // Check for 8-bit immediate, and set sign extend bit in opcode 2420 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2421 emit_opcode(cbuf, $primary | 0x02); 2422 } else { 2423 // 32-bit immediate 2424 emit_opcode(cbuf, $primary); 2425 } 2426 // Emit r/m byte with secondary opcode, after primary opcode. 2427 emit_rm(cbuf, 0x3, $secondary, dstenc); 2428 %} 2429 2430 enc_class OpcSErm_wide(rRegL dst, immI imm) 2431 %{ 2432 // OpcSEr/m 2433 int dstenc = $dst$$reg; 2434 if (dstenc < 8) { 2435 emit_opcode(cbuf, Assembler::REX_W); 2436 } else { 2437 emit_opcode(cbuf, Assembler::REX_WB); 2438 dstenc -= 8; 2439 } 2440 // Emit primary opcode and set sign-extend bit 2441 // Check for 8-bit immediate, and set sign extend bit in opcode 2442 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2443 emit_opcode(cbuf, $primary | 0x02); 2444 } else { 2445 // 32-bit immediate 2446 emit_opcode(cbuf, $primary); 2447 } 2448 // Emit r/m byte with secondary opcode, after primary opcode. 2449 emit_rm(cbuf, 0x3, $secondary, dstenc); 2450 %} 2451 2452 enc_class Con8or32(immI imm) 2453 %{ 2454 // Check for 8-bit immediate, and set sign extend bit in opcode 2455 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2456 $$$emit8$imm$$constant; 2457 } else { 2458 // 32-bit immediate 2459 $$$emit32$imm$$constant; 2460 } 2461 %} 2462 2463 enc_class Lbl(label labl) 2464 %{ 2465 // JMP, CALL 2466 Label* l = $labl$$label; 2467 emit_d32(cbuf, l ? (l->loc_pos() - (cbuf.code_size() + 4)) : 0); 2468 %} 2469 2470 enc_class LblShort(label labl) 2471 %{ 2472 // JMP, CALL 2473 Label* l = $labl$$label; 2474 int disp = l ? (l->loc_pos() - (cbuf.code_size() + 1)) : 0; 2475 assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp"); 2476 emit_d8(cbuf, disp); 2477 %} 2478 2479 enc_class opc2_reg(rRegI dst) 2480 %{ 2481 // BSWAP 2482 emit_cc(cbuf, $secondary, $dst$$reg); 2483 %} 2484 2485 enc_class opc3_reg(rRegI dst) 2486 %{ 2487 // BSWAP 2488 emit_cc(cbuf, $tertiary, $dst$$reg); 2489 %} 2490 2491 enc_class reg_opc(rRegI div) 2492 %{ 2493 // INC, DEC, IDIV, IMOD, JMP indirect, ... 2494 emit_rm(cbuf, 0x3, $secondary, $div$$reg & 7); 2495 %} 2496 2497 enc_class Jcc(cmpOp cop, label labl) 2498 %{ 2499 // JCC 2500 Label* l = $labl$$label; 2501 $$$emit8$primary; 2502 emit_cc(cbuf, $secondary, $cop$$cmpcode); 2503 emit_d32(cbuf, l ? (l->loc_pos() - (cbuf.code_size() + 4)) : 0); 2504 %} 2505 2506 enc_class JccShort (cmpOp cop, label labl) 2507 %{ 2508 // JCC 2509 Label *l = $labl$$label; 2510 emit_cc(cbuf, $primary, $cop$$cmpcode); 2511 int disp = l ? (l->loc_pos() - (cbuf.code_size() + 1)) : 0; 2512 assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp"); 2513 emit_d8(cbuf, disp); 2514 %} 2515 2516 enc_class enc_cmov(cmpOp cop) 2517 %{ 2518 // CMOV 2519 $$$emit8$primary; 2520 emit_cc(cbuf, $secondary, $cop$$cmpcode); 2521 %} 2522 2523 enc_class enc_cmovf_branch(cmpOp cop, regF dst, regF src) 2524 %{ 2525 // Invert sense of branch from sense of cmov 2526 emit_cc(cbuf, 0x70, $cop$$cmpcode ^ 1); 2527 emit_d8(cbuf, ($dst$$reg < 8 && $src$$reg < 8) 2528 ? (UseXmmRegToRegMoveAll ? 3 : 4) 2529 : (UseXmmRegToRegMoveAll ? 4 : 5) ); // REX 2530 // UseXmmRegToRegMoveAll ? movaps(dst, src) : movss(dst, src) 2531 if (!UseXmmRegToRegMoveAll) emit_opcode(cbuf, 0xF3); 2532 if ($dst$$reg < 8) { 2533 if ($src$$reg >= 8) { 2534 emit_opcode(cbuf, Assembler::REX_B); 2535 } 2536 } else { 2537 if ($src$$reg < 8) { 2538 emit_opcode(cbuf, Assembler::REX_R); 2539 } else { 2540 emit_opcode(cbuf, Assembler::REX_RB); 2541 } 2542 } 2543 emit_opcode(cbuf, 0x0F); 2544 emit_opcode(cbuf, UseXmmRegToRegMoveAll ? 0x28 : 0x10); 2545 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); 2546 %} 2547 2548 enc_class enc_cmovd_branch(cmpOp cop, regD dst, regD src) 2549 %{ 2550 // Invert sense of branch from sense of cmov 2551 emit_cc(cbuf, 0x70, $cop$$cmpcode ^ 1); 2552 emit_d8(cbuf, $dst$$reg < 8 && $src$$reg < 8 ? 4 : 5); // REX 2553 2554 // UseXmmRegToRegMoveAll ? movapd(dst, src) : movsd(dst, src) 2555 emit_opcode(cbuf, UseXmmRegToRegMoveAll ? 0x66 : 0xF2); 2556 if ($dst$$reg < 8) { 2557 if ($src$$reg >= 8) { 2558 emit_opcode(cbuf, Assembler::REX_B); 2559 } 2560 } else { 2561 if ($src$$reg < 8) { 2562 emit_opcode(cbuf, Assembler::REX_R); 2563 } else { 2564 emit_opcode(cbuf, Assembler::REX_RB); 2565 } 2566 } 2567 emit_opcode(cbuf, 0x0F); 2568 emit_opcode(cbuf, UseXmmRegToRegMoveAll ? 0x28 : 0x10); 2569 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); 2570 %} 2571 2572 enc_class enc_PartialSubtypeCheck() 2573 %{ 2574 Register Rrdi = as_Register(RDI_enc); // result register 2575 Register Rrax = as_Register(RAX_enc); // super class 2576 Register Rrcx = as_Register(RCX_enc); // killed 2577 Register Rrsi = as_Register(RSI_enc); // sub class 2578 Label hit, miss, cmiss; 2579 2580 MacroAssembler _masm(&cbuf); 2581 // Compare super with sub directly, since super is not in its own SSA. 2582 // The compiler used to emit this test, but we fold it in here, 2583 // to allow platform-specific tweaking on sparc. 2584 __ cmpptr(Rrax, Rrsi); 2585 __ jcc(Assembler::equal, hit); 2586#ifndef PRODUCT 2587 __ lea(Rrcx, ExternalAddress((address)&SharedRuntime::_partial_subtype_ctr)); 2588 __ incrementl(Address(Rrcx, 0)); 2589#endif //PRODUCT 2590 __ movptr(Rrdi, Address(Rrsi, 2591 sizeof(oopDesc) + 2592 Klass::secondary_supers_offset_in_bytes())); 2593 __ movl(Rrcx, Address(Rrdi, arrayOopDesc::length_offset_in_bytes())); 2594 __ addptr(Rrdi, arrayOopDesc::base_offset_in_bytes(T_OBJECT)); 2595 if (UseCompressedOops) { 2596 __ encode_heap_oop(Rrax); 2597 __ repne_scanl(); 2598 __ jcc(Assembler::notEqual, cmiss); 2599 __ decode_heap_oop(Rrax); 2600 __ movptr(Address(Rrsi, 2601 sizeof(oopDesc) + 2602 Klass::secondary_super_cache_offset_in_bytes()), 2603 Rrax); 2604 __ jmp(hit); 2605 __ bind(cmiss); 2606 __ decode_heap_oop(Rrax); 2607 __ jmp(miss); 2608 } else { 2609 __ repne_scan(); 2610 __ jcc(Assembler::notEqual, miss); 2611 __ movptr(Address(Rrsi, 2612 sizeof(oopDesc) + 2613 Klass::secondary_super_cache_offset_in_bytes()), 2614 Rrax); 2615 } 2616 __ bind(hit); 2617 if ($primary) { 2618 __ xorptr(Rrdi, Rrdi); 2619 } 2620 __ bind(miss); 2621 %} 2622 2623 enc_class Java_To_Interpreter(method meth) 2624 %{ 2625 // CALL Java_To_Interpreter 2626 // This is the instruction starting address for relocation info. 2627 cbuf.set_inst_mark(); 2628 $$$emit8$primary; 2629 // CALL directly to the runtime 2630 emit_d32_reloc(cbuf, 2631 (int) ($meth$$method - ((intptr_t) cbuf.code_end()) - 4), 2632 runtime_call_Relocation::spec(), 2633 RELOC_DISP32); 2634 %} 2635 2636 enc_class Java_Static_Call(method meth) 2637 %{ 2638 // JAVA STATIC CALL 2639 // CALL to fixup routine. Fixup routine uses ScopeDesc info to 2640 // determine who we intended to call. 2641 cbuf.set_inst_mark(); 2642 $$$emit8$primary; 2643 2644 if (!_method) { 2645 emit_d32_reloc(cbuf, 2646 (int) ($meth$$method - ((intptr_t) cbuf.code_end()) - 4), 2647 runtime_call_Relocation::spec(), 2648 RELOC_DISP32); 2649 } else if (_optimized_virtual) { 2650 emit_d32_reloc(cbuf, 2651 (int) ($meth$$method - ((intptr_t) cbuf.code_end()) - 4), 2652 opt_virtual_call_Relocation::spec(), 2653 RELOC_DISP32); 2654 } else { 2655 emit_d32_reloc(cbuf, 2656 (int) ($meth$$method - ((intptr_t) cbuf.code_end()) - 4), 2657 static_call_Relocation::spec(), 2658 RELOC_DISP32); 2659 } 2660 if (_method) { 2661 // Emit stub for static call 2662 emit_java_to_interp(cbuf); 2663 } 2664 %} 2665 2666 enc_class Java_Dynamic_Call(method meth) 2667 %{ 2668 // JAVA DYNAMIC CALL 2669 // !!!!! 2670 // Generate "movq rax, -1", placeholder instruction to load oop-info 2671 // emit_call_dynamic_prologue( cbuf ); 2672 cbuf.set_inst_mark(); 2673 2674 // movq rax, -1 2675 emit_opcode(cbuf, Assembler::REX_W); 2676 emit_opcode(cbuf, 0xB8 | RAX_enc); 2677 emit_d64_reloc(cbuf, 2678 (int64_t) Universe::non_oop_word(), 2679 oop_Relocation::spec_for_immediate(), RELOC_IMM64); 2680 address virtual_call_oop_addr = cbuf.inst_mark(); 2681 // CALL to fixup routine. Fixup routine uses ScopeDesc info to determine 2682 // who we intended to call. 2683 cbuf.set_inst_mark(); 2684 $$$emit8$primary; 2685 emit_d32_reloc(cbuf, 2686 (int) ($meth$$method - ((intptr_t) cbuf.code_end()) - 4), 2687 virtual_call_Relocation::spec(virtual_call_oop_addr), 2688 RELOC_DISP32); 2689 %} 2690 2691 enc_class Java_Compiled_Call(method meth) 2692 %{ 2693 // JAVA COMPILED CALL 2694 int disp = in_bytes(methodOopDesc:: from_compiled_offset()); 2695 2696 // XXX XXX offset is 128 is 1.5 NON-PRODUCT !!! 2697 // assert(-0x80 <= disp && disp < 0x80, "compiled_code_offset isn't small"); 2698 2699 // callq *disp(%rax) 2700 cbuf.set_inst_mark(); 2701 $$$emit8$primary; 2702 if (disp < 0x80) { 2703 emit_rm(cbuf, 0x01, $secondary, RAX_enc); // R/M byte 2704 emit_d8(cbuf, disp); // Displacement 2705 } else { 2706 emit_rm(cbuf, 0x02, $secondary, RAX_enc); // R/M byte 2707 emit_d32(cbuf, disp); // Displacement 2708 } 2709 %} 2710 2711 enc_class reg_opc_imm(rRegI dst, immI8 shift) 2712 %{ 2713 // SAL, SAR, SHR 2714 int dstenc = $dst$$reg; 2715 if (dstenc >= 8) { 2716 emit_opcode(cbuf, Assembler::REX_B); 2717 dstenc -= 8; 2718 } 2719 $$$emit8$primary; 2720 emit_rm(cbuf, 0x3, $secondary, dstenc); 2721 $$$emit8$shift$$constant; 2722 %} 2723 2724 enc_class reg_opc_imm_wide(rRegL dst, immI8 shift) 2725 %{ 2726 // SAL, SAR, SHR 2727 int dstenc = $dst$$reg; 2728 if (dstenc < 8) { 2729 emit_opcode(cbuf, Assembler::REX_W); 2730 } else { 2731 emit_opcode(cbuf, Assembler::REX_WB); 2732 dstenc -= 8; 2733 } 2734 $$$emit8$primary; 2735 emit_rm(cbuf, 0x3, $secondary, dstenc); 2736 $$$emit8$shift$$constant; 2737 %} 2738 2739 enc_class load_immI(rRegI dst, immI src) 2740 %{ 2741 int dstenc = $dst$$reg; 2742 if (dstenc >= 8) { 2743 emit_opcode(cbuf, Assembler::REX_B); 2744 dstenc -= 8; 2745 } 2746 emit_opcode(cbuf, 0xB8 | dstenc); 2747 $$$emit32$src$$constant; 2748 %} 2749 2750 enc_class load_immL(rRegL dst, immL src) 2751 %{ 2752 int dstenc = $dst$$reg; 2753 if (dstenc < 8) { 2754 emit_opcode(cbuf, Assembler::REX_W); 2755 } else { 2756 emit_opcode(cbuf, Assembler::REX_WB); 2757 dstenc -= 8; 2758 } 2759 emit_opcode(cbuf, 0xB8 | dstenc); 2760 emit_d64(cbuf, $src$$constant); 2761 %} 2762 2763 enc_class load_immUL32(rRegL dst, immUL32 src) 2764 %{ 2765 // same as load_immI, but this time we care about zeroes in the high word 2766 int dstenc = $dst$$reg; 2767 if (dstenc >= 8) { 2768 emit_opcode(cbuf, Assembler::REX_B); 2769 dstenc -= 8; 2770 } 2771 emit_opcode(cbuf, 0xB8 | dstenc); 2772 $$$emit32$src$$constant; 2773 %} 2774 2775 enc_class load_immL32(rRegL dst, immL32 src) 2776 %{ 2777 int dstenc = $dst$$reg; 2778 if (dstenc < 8) { 2779 emit_opcode(cbuf, Assembler::REX_W); 2780 } else { 2781 emit_opcode(cbuf, Assembler::REX_WB); 2782 dstenc -= 8; 2783 } 2784 emit_opcode(cbuf, 0xC7); 2785 emit_rm(cbuf, 0x03, 0x00, dstenc); 2786 $$$emit32$src$$constant; 2787 %} 2788 2789 enc_class load_immP31(rRegP dst, immP32 src) 2790 %{ 2791 // same as load_immI, but this time we care about zeroes in the high word 2792 int dstenc = $dst$$reg; 2793 if (dstenc >= 8) { 2794 emit_opcode(cbuf, Assembler::REX_B); 2795 dstenc -= 8; 2796 } 2797 emit_opcode(cbuf, 0xB8 | dstenc); 2798 $$$emit32$src$$constant; 2799 %} 2800 2801 enc_class load_immP(rRegP dst, immP src) 2802 %{ 2803 int dstenc = $dst$$reg; 2804 if (dstenc < 8) { 2805 emit_opcode(cbuf, Assembler::REX_W); 2806 } else { 2807 emit_opcode(cbuf, Assembler::REX_WB); 2808 dstenc -= 8; 2809 } 2810 emit_opcode(cbuf, 0xB8 | dstenc); 2811 // This next line should be generated from ADLC 2812 if ($src->constant_is_oop()) { 2813 emit_d64_reloc(cbuf, $src$$constant, relocInfo::oop_type, RELOC_IMM64); 2814 } else { 2815 emit_d64(cbuf, $src$$constant); 2816 } 2817 %} 2818 2819 enc_class load_immF(regF dst, immF con) 2820 %{ 2821 // XXX reg_mem doesn't support RIP-relative addressing yet 2822 emit_rm(cbuf, 0x0, $dst$$reg & 7, 0x5); // 00 reg 101 2823 emit_float_constant(cbuf, $con$$constant); 2824 %} 2825 2826 enc_class load_immD(regD dst, immD con) 2827 %{ 2828 // XXX reg_mem doesn't support RIP-relative addressing yet 2829 emit_rm(cbuf, 0x0, $dst$$reg & 7, 0x5); // 00 reg 101 2830 emit_double_constant(cbuf, $con$$constant); 2831 %} 2832 2833 enc_class load_conF (regF dst, immF con) %{ // Load float constant 2834 emit_opcode(cbuf, 0xF3); 2835 if ($dst$$reg >= 8) { 2836 emit_opcode(cbuf, Assembler::REX_R); 2837 } 2838 emit_opcode(cbuf, 0x0F); 2839 emit_opcode(cbuf, 0x10); 2840 emit_rm(cbuf, 0x0, $dst$$reg & 7, 0x5); // 00 reg 101 2841 emit_float_constant(cbuf, $con$$constant); 2842 %} 2843 2844 enc_class load_conD (regD dst, immD con) %{ // Load double constant 2845 // UseXmmLoadAndClearUpper ? movsd(dst, con) : movlpd(dst, con) 2846 emit_opcode(cbuf, UseXmmLoadAndClearUpper ? 0xF2 : 0x66); 2847 if ($dst$$reg >= 8) { 2848 emit_opcode(cbuf, Assembler::REX_R); 2849 } 2850 emit_opcode(cbuf, 0x0F); 2851 emit_opcode(cbuf, UseXmmLoadAndClearUpper ? 0x10 : 0x12); 2852 emit_rm(cbuf, 0x0, $dst$$reg & 7, 0x5); // 00 reg 101 2853 emit_double_constant(cbuf, $con$$constant); 2854 %} 2855 2856 // Encode a reg-reg copy. If it is useless, then empty encoding. 2857 enc_class enc_copy(rRegI dst, rRegI src) 2858 %{ 2859 encode_copy(cbuf, $dst$$reg, $src$$reg); 2860 %} 2861 2862 // Encode xmm reg-reg copy. If it is useless, then empty encoding. 2863 enc_class enc_CopyXD( RegD dst, RegD src ) %{ 2864 encode_CopyXD( cbuf, $dst$$reg, $src$$reg ); 2865 %} 2866 2867 enc_class enc_copy_always(rRegI dst, rRegI src) 2868 %{ 2869 int srcenc = $src$$reg; 2870 int dstenc = $dst$$reg; 2871 2872 if (dstenc < 8) { 2873 if (srcenc >= 8) { 2874 emit_opcode(cbuf, Assembler::REX_B); 2875 srcenc -= 8; 2876 } 2877 } else { 2878 if (srcenc < 8) { 2879 emit_opcode(cbuf, Assembler::REX_R); 2880 } else { 2881 emit_opcode(cbuf, Assembler::REX_RB); 2882 srcenc -= 8; 2883 } 2884 dstenc -= 8; 2885 } 2886 2887 emit_opcode(cbuf, 0x8B); 2888 emit_rm(cbuf, 0x3, dstenc, srcenc); 2889 %} 2890 2891 enc_class enc_copy_wide(rRegL dst, rRegL src) 2892 %{ 2893 int srcenc = $src$$reg; 2894 int dstenc = $dst$$reg; 2895 2896 if (dstenc != srcenc) { 2897 if (dstenc < 8) { 2898 if (srcenc < 8) { 2899 emit_opcode(cbuf, Assembler::REX_W); 2900 } else { 2901 emit_opcode(cbuf, Assembler::REX_WB); 2902 srcenc -= 8; 2903 } 2904 } else { 2905 if (srcenc < 8) { 2906 emit_opcode(cbuf, Assembler::REX_WR); 2907 } else { 2908 emit_opcode(cbuf, Assembler::REX_WRB); 2909 srcenc -= 8; 2910 } 2911 dstenc -= 8; 2912 } 2913 emit_opcode(cbuf, 0x8B); 2914 emit_rm(cbuf, 0x3, dstenc, srcenc); 2915 } 2916 %} 2917 2918 enc_class Con32(immI src) 2919 %{ 2920 // Output immediate 2921 $$$emit32$src$$constant; 2922 %} 2923 2924 enc_class Con64(immL src) 2925 %{ 2926 // Output immediate 2927 emit_d64($src$$constant); 2928 %} 2929 2930 enc_class Con32F_as_bits(immF src) 2931 %{ 2932 // Output Float immediate bits 2933 jfloat jf = $src$$constant; 2934 jint jf_as_bits = jint_cast(jf); 2935 emit_d32(cbuf, jf_as_bits); 2936 %} 2937 2938 enc_class Con16(immI src) 2939 %{ 2940 // Output immediate 2941 $$$emit16$src$$constant; 2942 %} 2943 2944 // How is this different from Con32??? XXX 2945 enc_class Con_d32(immI src) 2946 %{ 2947 emit_d32(cbuf,$src$$constant); 2948 %} 2949 2950 enc_class conmemref (rRegP t1) %{ // Con32(storeImmI) 2951 // Output immediate memory reference 2952 emit_rm(cbuf, 0x00, $t1$$reg, 0x05 ); 2953 emit_d32(cbuf, 0x00); 2954 %} 2955 2956 enc_class jump_enc(rRegL switch_val, rRegI dest) %{ 2957 MacroAssembler masm(&cbuf); 2958 2959 Register switch_reg = as_Register($switch_val$$reg); 2960 Register dest_reg = as_Register($dest$$reg); 2961 address table_base = masm.address_table_constant(_index2label); 2962 2963 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 2964 // to do that and the compiler is using that register as one it can allocate. 2965 // So we build it all by hand. 2966 // Address index(noreg, switch_reg, Address::times_1); 2967 // ArrayAddress dispatch(table, index); 2968 2969 Address dispatch(dest_reg, switch_reg, Address::times_1); 2970 2971 masm.lea(dest_reg, InternalAddress(table_base)); 2972 masm.jmp(dispatch); 2973 %} 2974 2975 enc_class jump_enc_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{ 2976 MacroAssembler masm(&cbuf); 2977 2978 Register switch_reg = as_Register($switch_val$$reg); 2979 Register dest_reg = as_Register($dest$$reg); 2980 address table_base = masm.address_table_constant(_index2label); 2981 2982 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 2983 // to do that and the compiler is using that register as one it can allocate. 2984 // So we build it all by hand. 2985 // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant, (int)$offset$$constant); 2986 // ArrayAddress dispatch(table, index); 2987 2988 Address dispatch(dest_reg, switch_reg, (Address::ScaleFactor)$shift$$constant, (int)$offset$$constant); 2989 2990 masm.lea(dest_reg, InternalAddress(table_base)); 2991 masm.jmp(dispatch); 2992 %} 2993 2994 enc_class jump_enc_offset(rRegL switch_val, immI2 shift, rRegI dest) %{ 2995 MacroAssembler masm(&cbuf); 2996 2997 Register switch_reg = as_Register($switch_val$$reg); 2998 Register dest_reg = as_Register($dest$$reg); 2999 address table_base = masm.address_table_constant(_index2label); 3000 3001 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 3002 // to do that and the compiler is using that register as one it can allocate. 3003 // So we build it all by hand. 3004 // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant); 3005 // ArrayAddress dispatch(table, index); 3006 3007 Address dispatch(dest_reg, switch_reg, (Address::ScaleFactor)$shift$$constant); 3008 masm.lea(dest_reg, InternalAddress(table_base)); 3009 masm.jmp(dispatch); 3010 3011 %} 3012 3013 enc_class lock_prefix() 3014 %{ 3015 if (os::is_MP()) { 3016 emit_opcode(cbuf, 0xF0); // lock 3017 } 3018 %} 3019 3020 enc_class REX_mem(memory mem) 3021 %{ 3022 if ($mem$$base >= 8) { 3023 if ($mem$$index < 8) { 3024 emit_opcode(cbuf, Assembler::REX_B); 3025 } else { 3026 emit_opcode(cbuf, Assembler::REX_XB); 3027 } 3028 } else { 3029 if ($mem$$index >= 8) { 3030 emit_opcode(cbuf, Assembler::REX_X); 3031 } 3032 } 3033 %} 3034 3035 enc_class REX_mem_wide(memory mem) 3036 %{ 3037 if ($mem$$base >= 8) { 3038 if ($mem$$index < 8) { 3039 emit_opcode(cbuf, Assembler::REX_WB); 3040 } else { 3041 emit_opcode(cbuf, Assembler::REX_WXB); 3042 } 3043 } else { 3044 if ($mem$$index < 8) { 3045 emit_opcode(cbuf, Assembler::REX_W); 3046 } else { 3047 emit_opcode(cbuf, Assembler::REX_WX); 3048 } 3049 } 3050 %} 3051 3052 // for byte regs 3053 enc_class REX_breg(rRegI reg) 3054 %{ 3055 if ($reg$$reg >= 4) { 3056 emit_opcode(cbuf, $reg$$reg < 8 ? Assembler::REX : Assembler::REX_B); 3057 } 3058 %} 3059 3060 // for byte regs 3061 enc_class REX_reg_breg(rRegI dst, rRegI src) 3062 %{ 3063 if ($dst$$reg < 8) { 3064 if ($src$$reg >= 4) { 3065 emit_opcode(cbuf, $src$$reg < 8 ? Assembler::REX : Assembler::REX_B); 3066 } 3067 } else { 3068 if ($src$$reg < 8) { 3069 emit_opcode(cbuf, Assembler::REX_R); 3070 } else { 3071 emit_opcode(cbuf, Assembler::REX_RB); 3072 } 3073 } 3074 %} 3075 3076 // for byte regs 3077 enc_class REX_breg_mem(rRegI reg, memory mem) 3078 %{ 3079 if ($reg$$reg < 8) { 3080 if ($mem$$base < 8) { 3081 if ($mem$$index >= 8) { 3082 emit_opcode(cbuf, Assembler::REX_X); 3083 } else if ($reg$$reg >= 4) { 3084 emit_opcode(cbuf, Assembler::REX); 3085 } 3086 } else { 3087 if ($mem$$index < 8) { 3088 emit_opcode(cbuf, Assembler::REX_B); 3089 } else { 3090 emit_opcode(cbuf, Assembler::REX_XB); 3091 } 3092 } 3093 } else { 3094 if ($mem$$base < 8) { 3095 if ($mem$$index < 8) { 3096 emit_opcode(cbuf, Assembler::REX_R); 3097 } else { 3098 emit_opcode(cbuf, Assembler::REX_RX); 3099 } 3100 } else { 3101 if ($mem$$index < 8) { 3102 emit_opcode(cbuf, Assembler::REX_RB); 3103 } else { 3104 emit_opcode(cbuf, Assembler::REX_RXB); 3105 } 3106 } 3107 } 3108 %} 3109 3110 enc_class REX_reg(rRegI reg) 3111 %{ 3112 if ($reg$$reg >= 8) { 3113 emit_opcode(cbuf, Assembler::REX_B); 3114 } 3115 %} 3116 3117 enc_class REX_reg_wide(rRegI reg) 3118 %{ 3119 if ($reg$$reg < 8) { 3120 emit_opcode(cbuf, Assembler::REX_W); 3121 } else { 3122 emit_opcode(cbuf, Assembler::REX_WB); 3123 } 3124 %} 3125 3126 enc_class REX_reg_reg(rRegI dst, rRegI src) 3127 %{ 3128 if ($dst$$reg < 8) { 3129 if ($src$$reg >= 8) { 3130 emit_opcode(cbuf, Assembler::REX_B); 3131 } 3132 } else { 3133 if ($src$$reg < 8) { 3134 emit_opcode(cbuf, Assembler::REX_R); 3135 } else { 3136 emit_opcode(cbuf, Assembler::REX_RB); 3137 } 3138 } 3139 %} 3140 3141 enc_class REX_reg_reg_wide(rRegI dst, rRegI src) 3142 %{ 3143 if ($dst$$reg < 8) { 3144 if ($src$$reg < 8) { 3145 emit_opcode(cbuf, Assembler::REX_W); 3146 } else { 3147 emit_opcode(cbuf, Assembler::REX_WB); 3148 } 3149 } else { 3150 if ($src$$reg < 8) { 3151 emit_opcode(cbuf, Assembler::REX_WR); 3152 } else { 3153 emit_opcode(cbuf, Assembler::REX_WRB); 3154 } 3155 } 3156 %} 3157 3158 enc_class REX_reg_mem(rRegI reg, memory mem) 3159 %{ 3160 if ($reg$$reg < 8) { 3161 if ($mem$$base < 8) { 3162 if ($mem$$index >= 8) { 3163 emit_opcode(cbuf, Assembler::REX_X); 3164 } 3165 } else { 3166 if ($mem$$index < 8) { 3167 emit_opcode(cbuf, Assembler::REX_B); 3168 } else { 3169 emit_opcode(cbuf, Assembler::REX_XB); 3170 } 3171 } 3172 } else { 3173 if ($mem$$base < 8) { 3174 if ($mem$$index < 8) { 3175 emit_opcode(cbuf, Assembler::REX_R); 3176 } else { 3177 emit_opcode(cbuf, Assembler::REX_RX); 3178 } 3179 } else { 3180 if ($mem$$index < 8) { 3181 emit_opcode(cbuf, Assembler::REX_RB); 3182 } else { 3183 emit_opcode(cbuf, Assembler::REX_RXB); 3184 } 3185 } 3186 } 3187 %} 3188 3189 enc_class REX_reg_mem_wide(rRegL reg, memory mem) 3190 %{ 3191 if ($reg$$reg < 8) { 3192 if ($mem$$base < 8) { 3193 if ($mem$$index < 8) { 3194 emit_opcode(cbuf, Assembler::REX_W); 3195 } else { 3196 emit_opcode(cbuf, Assembler::REX_WX); 3197 } 3198 } else { 3199 if ($mem$$index < 8) { 3200 emit_opcode(cbuf, Assembler::REX_WB); 3201 } else { 3202 emit_opcode(cbuf, Assembler::REX_WXB); 3203 } 3204 } 3205 } else { 3206 if ($mem$$base < 8) { 3207 if ($mem$$index < 8) { 3208 emit_opcode(cbuf, Assembler::REX_WR); 3209 } else { 3210 emit_opcode(cbuf, Assembler::REX_WRX); 3211 } 3212 } else { 3213 if ($mem$$index < 8) { 3214 emit_opcode(cbuf, Assembler::REX_WRB); 3215 } else { 3216 emit_opcode(cbuf, Assembler::REX_WRXB); 3217 } 3218 } 3219 } 3220 %} 3221 3222 enc_class reg_mem(rRegI ereg, memory mem) 3223 %{ 3224 // High registers handle in encode_RegMem 3225 int reg = $ereg$$reg; 3226 int base = $mem$$base; 3227 int index = $mem$$index; 3228 int scale = $mem$$scale; 3229 int disp = $mem$$disp; 3230 bool disp_is_oop = $mem->disp_is_oop(); 3231 3232 encode_RegMem(cbuf, reg, base, index, scale, disp, disp_is_oop); 3233 %} 3234 3235 enc_class RM_opc_mem(immI rm_opcode, memory mem) 3236 %{ 3237 int rm_byte_opcode = $rm_opcode$$constant; 3238 3239 // High registers handle in encode_RegMem 3240 int base = $mem$$base; 3241 int index = $mem$$index; 3242 int scale = $mem$$scale; 3243 int displace = $mem$$disp; 3244 3245 bool disp_is_oop = $mem->disp_is_oop(); // disp-as-oop when 3246 // working with static 3247 // globals 3248 encode_RegMem(cbuf, rm_byte_opcode, base, index, scale, displace, 3249 disp_is_oop); 3250 %} 3251 3252 enc_class reg_lea(rRegI dst, rRegI src0, immI src1) 3253 %{ 3254 int reg_encoding = $dst$$reg; 3255 int base = $src0$$reg; // 0xFFFFFFFF indicates no base 3256 int index = 0x04; // 0x04 indicates no index 3257 int scale = 0x00; // 0x00 indicates no scale 3258 int displace = $src1$$constant; // 0x00 indicates no displacement 3259 bool disp_is_oop = false; 3260 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, 3261 disp_is_oop); 3262 %} 3263 3264 enc_class neg_reg(rRegI dst) 3265 %{ 3266 int dstenc = $dst$$reg; 3267 if (dstenc >= 8) { 3268 emit_opcode(cbuf, Assembler::REX_B); 3269 dstenc -= 8; 3270 } 3271 // NEG $dst 3272 emit_opcode(cbuf, 0xF7); 3273 emit_rm(cbuf, 0x3, 0x03, dstenc); 3274 %} 3275 3276 enc_class neg_reg_wide(rRegI dst) 3277 %{ 3278 int dstenc = $dst$$reg; 3279 if (dstenc < 8) { 3280 emit_opcode(cbuf, Assembler::REX_W); 3281 } else { 3282 emit_opcode(cbuf, Assembler::REX_WB); 3283 dstenc -= 8; 3284 } 3285 // NEG $dst 3286 emit_opcode(cbuf, 0xF7); 3287 emit_rm(cbuf, 0x3, 0x03, dstenc); 3288 %} 3289 3290 enc_class setLT_reg(rRegI dst) 3291 %{ 3292 int dstenc = $dst$$reg; 3293 if (dstenc >= 8) { 3294 emit_opcode(cbuf, Assembler::REX_B); 3295 dstenc -= 8; 3296 } else if (dstenc >= 4) { 3297 emit_opcode(cbuf, Assembler::REX); 3298 } 3299 // SETLT $dst 3300 emit_opcode(cbuf, 0x0F); 3301 emit_opcode(cbuf, 0x9C); 3302 emit_rm(cbuf, 0x3, 0x0, dstenc); 3303 %} 3304 3305 enc_class setNZ_reg(rRegI dst) 3306 %{ 3307 int dstenc = $dst$$reg; 3308 if (dstenc >= 8) { 3309 emit_opcode(cbuf, Assembler::REX_B); 3310 dstenc -= 8; 3311 } else if (dstenc >= 4) { 3312 emit_opcode(cbuf, Assembler::REX); 3313 } 3314 // SETNZ $dst 3315 emit_opcode(cbuf, 0x0F); 3316 emit_opcode(cbuf, 0x95); 3317 emit_rm(cbuf, 0x3, 0x0, dstenc); 3318 %} 3319 3320 enc_class enc_cmpLTP(no_rcx_RegI p, no_rcx_RegI q, no_rcx_RegI y, 3321 rcx_RegI tmp) 3322 %{ 3323 // cadd_cmpLT 3324 3325 int tmpReg = $tmp$$reg; 3326 3327 int penc = $p$$reg; 3328 int qenc = $q$$reg; 3329 int yenc = $y$$reg; 3330 3331 // subl $p,$q 3332 if (penc < 8) { 3333 if (qenc >= 8) { 3334 emit_opcode(cbuf, Assembler::REX_B); 3335 } 3336 } else { 3337 if (qenc < 8) { 3338 emit_opcode(cbuf, Assembler::REX_R); 3339 } else { 3340 emit_opcode(cbuf, Assembler::REX_RB); 3341 } 3342 } 3343 emit_opcode(cbuf, 0x2B); 3344 emit_rm(cbuf, 0x3, penc & 7, qenc & 7); 3345 3346 // sbbl $tmp, $tmp 3347 emit_opcode(cbuf, 0x1B); 3348 emit_rm(cbuf, 0x3, tmpReg, tmpReg); 3349 3350 // andl $tmp, $y 3351 if (yenc >= 8) { 3352 emit_opcode(cbuf, Assembler::REX_B); 3353 } 3354 emit_opcode(cbuf, 0x23); 3355 emit_rm(cbuf, 0x3, tmpReg, yenc & 7); 3356 3357 // addl $p,$tmp 3358 if (penc >= 8) { 3359 emit_opcode(cbuf, Assembler::REX_R); 3360 } 3361 emit_opcode(cbuf, 0x03); 3362 emit_rm(cbuf, 0x3, penc & 7, tmpReg); 3363 %} 3364 3365 // Compare the lonogs and set -1, 0, or 1 into dst 3366 enc_class cmpl3_flag(rRegL src1, rRegL src2, rRegI dst) 3367 %{ 3368 int src1enc = $src1$$reg; 3369 int src2enc = $src2$$reg; 3370 int dstenc = $dst$$reg; 3371 3372 // cmpq $src1, $src2 3373 if (src1enc < 8) { 3374 if (src2enc < 8) { 3375 emit_opcode(cbuf, Assembler::REX_W); 3376 } else { 3377 emit_opcode(cbuf, Assembler::REX_WB); 3378 } 3379 } else { 3380 if (src2enc < 8) { 3381 emit_opcode(cbuf, Assembler::REX_WR); 3382 } else { 3383 emit_opcode(cbuf, Assembler::REX_WRB); 3384 } 3385 } 3386 emit_opcode(cbuf, 0x3B); 3387 emit_rm(cbuf, 0x3, src1enc & 7, src2enc & 7); 3388 3389 // movl $dst, -1 3390 if (dstenc >= 8) { 3391 emit_opcode(cbuf, Assembler::REX_B); 3392 } 3393 emit_opcode(cbuf, 0xB8 | (dstenc & 7)); 3394 emit_d32(cbuf, -1); 3395 3396 // jl,s done 3397 emit_opcode(cbuf, 0x7C); 3398 emit_d8(cbuf, dstenc < 4 ? 0x06 : 0x08); 3399 3400 // setne $dst 3401 if (dstenc >= 4) { 3402 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_B); 3403 } 3404 emit_opcode(cbuf, 0x0F); 3405 emit_opcode(cbuf, 0x95); 3406 emit_opcode(cbuf, 0xC0 | (dstenc & 7)); 3407 3408 // movzbl $dst, $dst 3409 if (dstenc >= 4) { 3410 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_RB); 3411 } 3412 emit_opcode(cbuf, 0x0F); 3413 emit_opcode(cbuf, 0xB6); 3414 emit_rm(cbuf, 0x3, dstenc & 7, dstenc & 7); 3415 %} 3416 3417 enc_class Push_ResultXD(regD dst) %{ 3418 int dstenc = $dst$$reg; 3419 3420 store_to_stackslot( cbuf, 0xDD, 0x03, 0 ); //FSTP [RSP] 3421 3422 // UseXmmLoadAndClearUpper ? movsd dst,[rsp] : movlpd dst,[rsp] 3423 emit_opcode (cbuf, UseXmmLoadAndClearUpper ? 0xF2 : 0x66); 3424 if (dstenc >= 8) { 3425 emit_opcode(cbuf, Assembler::REX_R); 3426 } 3427 emit_opcode (cbuf, 0x0F ); 3428 emit_opcode (cbuf, UseXmmLoadAndClearUpper ? 0x10 : 0x12 ); 3429 encode_RegMem(cbuf, dstenc, RSP_enc, 0x4, 0, 0, false); 3430 3431 // add rsp,8 3432 emit_opcode(cbuf, Assembler::REX_W); 3433 emit_opcode(cbuf,0x83); 3434 emit_rm(cbuf,0x3, 0x0, RSP_enc); 3435 emit_d8(cbuf,0x08); 3436 %} 3437 3438 enc_class Push_SrcXD(regD src) %{ 3439 int srcenc = $src$$reg; 3440 3441 // subq rsp,#8 3442 emit_opcode(cbuf, Assembler::REX_W); 3443 emit_opcode(cbuf, 0x83); 3444 emit_rm(cbuf, 0x3, 0x5, RSP_enc); 3445 emit_d8(cbuf, 0x8); 3446 3447 // movsd [rsp],src 3448 emit_opcode(cbuf, 0xF2); 3449 if (srcenc >= 8) { 3450 emit_opcode(cbuf, Assembler::REX_R); 3451 } 3452 emit_opcode(cbuf, 0x0F); 3453 emit_opcode(cbuf, 0x11); 3454 encode_RegMem(cbuf, srcenc, RSP_enc, 0x4, 0, 0, false); 3455 3456 // fldd [rsp] 3457 emit_opcode(cbuf, 0x66); 3458 emit_opcode(cbuf, 0xDD); 3459 encode_RegMem(cbuf, 0x0, RSP_enc, 0x4, 0, 0, false); 3460 %} 3461 3462 3463 enc_class movq_ld(regD dst, memory mem) %{ 3464 MacroAssembler _masm(&cbuf); 3465 Address madr = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp); 3466 __ movq(as_XMMRegister($dst$$reg), madr); 3467 %} 3468 3469 enc_class movq_st(memory mem, regD src) %{ 3470 MacroAssembler _masm(&cbuf); 3471 Address madr = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp); 3472 __ movq(madr, as_XMMRegister($src$$reg)); 3473 %} 3474 3475 enc_class pshufd_8x8(regF dst, regF src) %{ 3476 MacroAssembler _masm(&cbuf); 3477 3478 encode_CopyXD(cbuf, $dst$$reg, $src$$reg); 3479 __ punpcklbw(as_XMMRegister($dst$$reg), as_XMMRegister($dst$$reg)); 3480 __ pshuflw(as_XMMRegister($dst$$reg), as_XMMRegister($dst$$reg), 0x00); 3481 %} 3482 3483 enc_class pshufd_4x16(regF dst, regF src) %{ 3484 MacroAssembler _masm(&cbuf); 3485 3486 __ pshuflw(as_XMMRegister($dst$$reg), as_XMMRegister($src$$reg), 0x00); 3487 %} 3488 3489 enc_class pshufd(regD dst, regD src, int mode) %{ 3490 MacroAssembler _masm(&cbuf); 3491 3492 __ pshufd(as_XMMRegister($dst$$reg), as_XMMRegister($src$$reg), $mode); 3493 %} 3494 3495 enc_class pxor(regD dst, regD src) %{ 3496 MacroAssembler _masm(&cbuf); 3497 3498 __ pxor(as_XMMRegister($dst$$reg), as_XMMRegister($src$$reg)); 3499 %} 3500 3501 enc_class mov_i2x(regD dst, rRegI src) %{ 3502 MacroAssembler _masm(&cbuf); 3503 3504 __ movdl(as_XMMRegister($dst$$reg), as_Register($src$$reg)); 3505 %} 3506 3507 // obj: object to lock 3508 // box: box address (header location) -- killed 3509 // tmp: rax -- killed 3510 // scr: rbx -- killed 3511 // 3512 // What follows is a direct transliteration of fast_lock() and fast_unlock() 3513 // from i486.ad. See that file for comments. 3514 // TODO: where possible switch from movq (r, 0) to movl(r,0) and 3515 // use the shorter encoding. (Movl clears the high-order 32-bits). 3516 3517 3518 enc_class Fast_Lock(rRegP obj, rRegP box, rax_RegI tmp, rRegP scr) 3519 %{ 3520 Register objReg = as_Register((int)$obj$$reg); 3521 Register boxReg = as_Register((int)$box$$reg); 3522 Register tmpReg = as_Register($tmp$$reg); 3523 Register scrReg = as_Register($scr$$reg); 3524 MacroAssembler masm(&cbuf); 3525 3526 // Verify uniqueness of register assignments -- necessary but not sufficient 3527 assert (objReg != boxReg && objReg != tmpReg && 3528 objReg != scrReg && tmpReg != scrReg, "invariant") ; 3529 3530 if (_counters != NULL) { 3531 masm.atomic_incl(ExternalAddress((address) _counters->total_entry_count_addr())); 3532 } 3533 if (EmitSync & 1) { 3534 // Without cast to int32_t a movptr will destroy r10 which is typically obj 3535 masm.movptr (Address(boxReg, 0), (int32_t)intptr_t(markOopDesc::unused_mark())) ; 3536 masm.cmpptr(rsp, (int32_t)NULL_WORD) ; 3537 } else 3538 if (EmitSync & 2) { 3539 Label DONE_LABEL; 3540 if (UseBiasedLocking) { 3541 // Note: tmpReg maps to the swap_reg argument and scrReg to the tmp_reg argument. 3542 masm.biased_locking_enter(boxReg, objReg, tmpReg, scrReg, false, DONE_LABEL, NULL, _counters); 3543 } 3544 // QQQ was movl... 3545 masm.movptr(tmpReg, 0x1); 3546 masm.orptr(tmpReg, Address(objReg, 0)); 3547 masm.movptr(Address(boxReg, 0), tmpReg); 3548 if (os::is_MP()) { 3549 masm.lock(); 3550 } 3551 masm.cmpxchgptr(boxReg, Address(objReg, 0)); // Updates tmpReg 3552 masm.jcc(Assembler::equal, DONE_LABEL); 3553 3554 // Recursive locking 3555 masm.subptr(tmpReg, rsp); 3556 masm.andptr(tmpReg, 7 - os::vm_page_size()); 3557 masm.movptr(Address(boxReg, 0), tmpReg); 3558 3559 masm.bind(DONE_LABEL); 3560 masm.nop(); // avoid branch to branch 3561 } else { 3562 Label DONE_LABEL, IsInflated, Egress; 3563 3564 masm.movptr(tmpReg, Address(objReg, 0)) ; 3565 masm.testl (tmpReg, 0x02) ; // inflated vs stack-locked|neutral|biased 3566 masm.jcc (Assembler::notZero, IsInflated) ; 3567 3568 // it's stack-locked, biased or neutral 3569 // TODO: optimize markword triage order to reduce the number of 3570 // conditional branches in the most common cases. 3571 // Beware -- there's a subtle invariant that fetch of the markword 3572 // at [FETCH], below, will never observe a biased encoding (*101b). 3573 // If this invariant is not held we'll suffer exclusion (safety) failure. 3574 3575 if (UseBiasedLocking && !UseOptoBiasInlining) { 3576 masm.biased_locking_enter(boxReg, objReg, tmpReg, scrReg, true, DONE_LABEL, NULL, _counters); 3577 masm.movptr(tmpReg, Address(objReg, 0)) ; // [FETCH] 3578 } 3579 3580 // was q will it destroy high? 3581 masm.orl (tmpReg, 1) ; 3582 masm.movptr(Address(boxReg, 0), tmpReg) ; 3583 if (os::is_MP()) { masm.lock(); } 3584 masm.cmpxchgptr(boxReg, Address(objReg, 0)); // Updates tmpReg 3585 if (_counters != NULL) { 3586 masm.cond_inc32(Assembler::equal, 3587 ExternalAddress((address) _counters->fast_path_entry_count_addr())); 3588 } 3589 masm.jcc (Assembler::equal, DONE_LABEL); 3590 3591 // Recursive locking 3592 masm.subptr(tmpReg, rsp); 3593 masm.andptr(tmpReg, 7 - os::vm_page_size()); 3594 masm.movptr(Address(boxReg, 0), tmpReg); 3595 if (_counters != NULL) { 3596 masm.cond_inc32(Assembler::equal, 3597 ExternalAddress((address) _counters->fast_path_entry_count_addr())); 3598 } 3599 masm.jmp (DONE_LABEL) ; 3600 3601 masm.bind (IsInflated) ; 3602 // It's inflated 3603 3604 // TODO: someday avoid the ST-before-CAS penalty by 3605 // relocating (deferring) the following ST. 3606 // We should also think about trying a CAS without having 3607 // fetched _owner. If the CAS is successful we may 3608 // avoid an RTO->RTS upgrade on the $line. 3609 // Without cast to int32_t a movptr will destroy r10 which is typically obj 3610 masm.movptr(Address(boxReg, 0), (int32_t)intptr_t(markOopDesc::unused_mark())) ; 3611 3612 masm.mov (boxReg, tmpReg) ; 3613 masm.movptr (tmpReg, Address(tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; 3614 masm.testptr(tmpReg, tmpReg) ; 3615 masm.jcc (Assembler::notZero, DONE_LABEL) ; 3616 3617 // It's inflated and appears unlocked 3618 if (os::is_MP()) { masm.lock(); } 3619 masm.cmpxchgptr(r15_thread, Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; 3620 // Intentional fall-through into DONE_LABEL ... 3621 3622 masm.bind (DONE_LABEL) ; 3623 masm.nop () ; // avoid jmp to jmp 3624 } 3625 %} 3626 3627 // obj: object to unlock 3628 // box: box address (displaced header location), killed 3629 // RBX: killed tmp; cannot be obj nor box 3630 enc_class Fast_Unlock(rRegP obj, rax_RegP box, rRegP tmp) 3631 %{ 3632 3633 Register objReg = as_Register($obj$$reg); 3634 Register boxReg = as_Register($box$$reg); 3635 Register tmpReg = as_Register($tmp$$reg); 3636 MacroAssembler masm(&cbuf); 3637 3638 if (EmitSync & 4) { 3639 masm.cmpptr(rsp, 0) ; 3640 } else 3641 if (EmitSync & 8) { 3642 Label DONE_LABEL; 3643 if (UseBiasedLocking) { 3644 masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL); 3645 } 3646 3647 // Check whether the displaced header is 0 3648 //(=> recursive unlock) 3649 masm.movptr(tmpReg, Address(boxReg, 0)); 3650 masm.testptr(tmpReg, tmpReg); 3651 masm.jcc(Assembler::zero, DONE_LABEL); 3652 3653 // If not recursive lock, reset the header to displaced header 3654 if (os::is_MP()) { 3655 masm.lock(); 3656 } 3657 masm.cmpxchgptr(tmpReg, Address(objReg, 0)); // Uses RAX which is box 3658 masm.bind(DONE_LABEL); 3659 masm.nop(); // avoid branch to branch 3660 } else { 3661 Label DONE_LABEL, Stacked, CheckSucc ; 3662 3663 if (UseBiasedLocking && !UseOptoBiasInlining) { 3664 masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL); 3665 } 3666 3667 masm.movptr(tmpReg, Address(objReg, 0)) ; 3668 masm.cmpptr(Address(boxReg, 0), (int32_t)NULL_WORD) ; 3669 masm.jcc (Assembler::zero, DONE_LABEL) ; 3670 masm.testl (tmpReg, 0x02) ; 3671 masm.jcc (Assembler::zero, Stacked) ; 3672 3673 // It's inflated 3674 masm.movptr(boxReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; 3675 masm.xorptr(boxReg, r15_thread) ; 3676 masm.orptr (boxReg, Address (tmpReg, ObjectMonitor::recursions_offset_in_bytes()-2)) ; 3677 masm.jcc (Assembler::notZero, DONE_LABEL) ; 3678 masm.movptr(boxReg, Address (tmpReg, ObjectMonitor::cxq_offset_in_bytes()-2)) ; 3679 masm.orptr (boxReg, Address (tmpReg, ObjectMonitor::EntryList_offset_in_bytes()-2)) ; 3680 masm.jcc (Assembler::notZero, CheckSucc) ; 3681 masm.movptr(Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), (int32_t)NULL_WORD) ; 3682 masm.jmp (DONE_LABEL) ; 3683 3684 if ((EmitSync & 65536) == 0) { 3685 Label LSuccess, LGoSlowPath ; 3686 masm.bind (CheckSucc) ; 3687 masm.cmpptr(Address (tmpReg, ObjectMonitor::succ_offset_in_bytes()-2), (int32_t)NULL_WORD) ; 3688 masm.jcc (Assembler::zero, LGoSlowPath) ; 3689 3690 // I'd much rather use lock:andl m->_owner, 0 as it's faster than the 3691 // the explicit ST;MEMBAR combination, but masm doesn't currently support 3692 // "ANDQ M,IMM". Don't use MFENCE here. lock:add to TOS, xchg, etc 3693 // are all faster when the write buffer is populated. 3694 masm.movptr (Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), (int32_t)NULL_WORD) ; 3695 if (os::is_MP()) { 3696 masm.lock () ; masm.addl (Address(rsp, 0), 0) ; 3697 } 3698 masm.cmpptr(Address (tmpReg, ObjectMonitor::succ_offset_in_bytes()-2), (int32_t)NULL_WORD) ; 3699 masm.jcc (Assembler::notZero, LSuccess) ; 3700 3701 masm.movptr (boxReg, (int32_t)NULL_WORD) ; // box is really EAX 3702 if (os::is_MP()) { masm.lock(); } 3703 masm.cmpxchgptr(r15_thread, Address(tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)); 3704 masm.jcc (Assembler::notEqual, LSuccess) ; 3705 // Intentional fall-through into slow-path 3706 3707 masm.bind (LGoSlowPath) ; 3708 masm.orl (boxReg, 1) ; // set ICC.ZF=0 to indicate failure 3709 masm.jmp (DONE_LABEL) ; 3710 3711 masm.bind (LSuccess) ; 3712 masm.testl (boxReg, 0) ; // set ICC.ZF=1 to indicate success 3713 masm.jmp (DONE_LABEL) ; 3714 } 3715 3716 masm.bind (Stacked) ; 3717 masm.movptr(tmpReg, Address (boxReg, 0)) ; // re-fetch 3718 if (os::is_MP()) { masm.lock(); } 3719 masm.cmpxchgptr(tmpReg, Address(objReg, 0)); // Uses RAX which is box 3720 3721 if (EmitSync & 65536) { 3722 masm.bind (CheckSucc) ; 3723 } 3724 masm.bind(DONE_LABEL); 3725 if (EmitSync & 32768) { 3726 masm.nop(); // avoid branch to branch 3727 } 3728 } 3729 %} 3730 3731 enc_class enc_String_Compare() 3732 %{ 3733 Label RCX_GOOD_LABEL, LENGTH_DIFF_LABEL, 3734 POP_LABEL, DONE_LABEL, CONT_LABEL, 3735 WHILE_HEAD_LABEL; 3736 MacroAssembler masm(&cbuf); 3737 3738 // Get the first character position in both strings 3739 // [8] char array, [12] offset, [16] count 3740 int value_offset = java_lang_String::value_offset_in_bytes(); 3741 int offset_offset = java_lang_String::offset_offset_in_bytes(); 3742 int count_offset = java_lang_String::count_offset_in_bytes(); 3743 int base_offset = arrayOopDesc::base_offset_in_bytes(T_CHAR); 3744 3745 masm.load_heap_oop(rax, Address(rsi, value_offset)); 3746 masm.movl(rcx, Address(rsi, offset_offset)); 3747 masm.lea(rax, Address(rax, rcx, Address::times_2, base_offset)); 3748 masm.load_heap_oop(rbx, Address(rdi, value_offset)); 3749 masm.movl(rcx, Address(rdi, offset_offset)); 3750 masm.lea(rbx, Address(rbx, rcx, Address::times_2, base_offset)); 3751 3752 // Compute the minimum of the string lengths(rsi) and the 3753 // difference of the string lengths (stack) 3754 3755 masm.movl(rdi, Address(rdi, count_offset)); 3756 masm.movl(rsi, Address(rsi, count_offset)); 3757 masm.movl(rcx, rdi); 3758 masm.subl(rdi, rsi); 3759 masm.push(rdi); 3760 masm.cmov(Assembler::lessEqual, rsi, rcx); 3761 3762 // Is the minimum length zero? 3763 masm.bind(RCX_GOOD_LABEL); 3764 masm.testl(rsi, rsi); 3765 masm.jcc(Assembler::zero, LENGTH_DIFF_LABEL); 3766 3767 // Load first characters 3768 masm.load_unsigned_word(rcx, Address(rbx, 0)); 3769 masm.load_unsigned_word(rdi, Address(rax, 0)); 3770 3771 // Compare first characters 3772 masm.subl(rcx, rdi); 3773 masm.jcc(Assembler::notZero, POP_LABEL); 3774 masm.decrementl(rsi); 3775 masm.jcc(Assembler::zero, LENGTH_DIFF_LABEL); 3776 3777 { 3778 // Check after comparing first character to see if strings are equivalent 3779 Label LSkip2; 3780 // Check if the strings start at same location 3781 masm.cmpptr(rbx, rax); 3782 masm.jcc(Assembler::notEqual, LSkip2); 3783 3784 // Check if the length difference is zero (from stack) 3785 masm.cmpl(Address(rsp, 0), 0x0); 3786 masm.jcc(Assembler::equal, LENGTH_DIFF_LABEL); 3787 3788 // Strings might not be equivalent 3789 masm.bind(LSkip2); 3790 } 3791 3792 // Shift RAX and RBX to the end of the arrays, negate min 3793 masm.lea(rax, Address(rax, rsi, Address::times_2, 2)); 3794 masm.lea(rbx, Address(rbx, rsi, Address::times_2, 2)); 3795 masm.negptr(rsi); 3796 3797 // Compare the rest of the characters 3798 masm.bind(WHILE_HEAD_LABEL); 3799 masm.load_unsigned_word(rcx, Address(rbx, rsi, Address::times_2, 0)); 3800 masm.load_unsigned_word(rdi, Address(rax, rsi, Address::times_2, 0)); 3801 masm.subl(rcx, rdi); 3802 masm.jcc(Assembler::notZero, POP_LABEL); 3803 masm.increment(rsi); 3804 masm.jcc(Assembler::notZero, WHILE_HEAD_LABEL); 3805 3806 // Strings are equal up to min length. Return the length difference. 3807 masm.bind(LENGTH_DIFF_LABEL); 3808 masm.pop(rcx); 3809 masm.jmp(DONE_LABEL); 3810 3811 // Discard the stored length difference 3812 masm.bind(POP_LABEL); 3813 masm.addptr(rsp, 8); 3814 3815 // That's it 3816 masm.bind(DONE_LABEL); 3817 %} 3818 3819 enc_class enc_Array_Equals(rdi_RegP ary1, rsi_RegP ary2, rax_RegI tmp1, rbx_RegI tmp2, rcx_RegI result) %{ 3820 Label TRUE_LABEL, FALSE_LABEL, DONE_LABEL, COMPARE_LOOP_HDR, COMPARE_LOOP; 3821 MacroAssembler masm(&cbuf); 3822 3823 Register ary1Reg = as_Register($ary1$$reg); 3824 Register ary2Reg = as_Register($ary2$$reg); 3825 Register tmp1Reg = as_Register($tmp1$$reg); 3826 Register tmp2Reg = as_Register($tmp2$$reg); 3827 Register resultReg = as_Register($result$$reg); 3828 3829 int length_offset = arrayOopDesc::length_offset_in_bytes(); 3830 int base_offset = arrayOopDesc::base_offset_in_bytes(T_CHAR); 3831 3832 // Check the input args 3833 masm.cmpq(ary1Reg, ary2Reg); 3834 masm.jcc(Assembler::equal, TRUE_LABEL); 3835 masm.testq(ary1Reg, ary1Reg); 3836 masm.jcc(Assembler::zero, FALSE_LABEL); 3837 masm.testq(ary2Reg, ary2Reg); 3838 masm.jcc(Assembler::zero, FALSE_LABEL); 3839 3840 // Check the lengths 3841 masm.movl(tmp2Reg, Address(ary1Reg, length_offset)); 3842 masm.movl(resultReg, Address(ary2Reg, length_offset)); 3843 masm.cmpl(tmp2Reg, resultReg); 3844 masm.jcc(Assembler::notEqual, FALSE_LABEL); 3845 masm.testl(resultReg, resultReg); 3846 masm.jcc(Assembler::zero, TRUE_LABEL); 3847 3848 // Get the number of 4 byte vectors to compare 3849 masm.shrl(resultReg, 1); 3850 3851 // Check for odd-length arrays 3852 masm.andl(tmp2Reg, 1); 3853 masm.testl(tmp2Reg, tmp2Reg); 3854 masm.jcc(Assembler::zero, COMPARE_LOOP_HDR); 3855 3856 // Compare 2-byte "tail" at end of arrays 3857 masm.load_unsigned_word(tmp1Reg, Address(ary1Reg, resultReg, Address::times_4, base_offset)); 3858 masm.load_unsigned_word(tmp2Reg, Address(ary2Reg, resultReg, Address::times_4, base_offset)); 3859 masm.cmpl(tmp1Reg, tmp2Reg); 3860 masm.jcc(Assembler::notEqual, FALSE_LABEL); 3861 masm.testl(resultReg, resultReg); 3862 masm.jcc(Assembler::zero, TRUE_LABEL); 3863 3864 // Setup compare loop 3865 masm.bind(COMPARE_LOOP_HDR); 3866 // Shift tmp1Reg and tmp2Reg to the last 4-byte boundary of the arrays 3867 masm.leaq(tmp1Reg, Address(ary1Reg, resultReg, Address::times_4, base_offset)); 3868 masm.leaq(tmp2Reg, Address(ary2Reg, resultReg, Address::times_4, base_offset)); 3869 masm.negq(resultReg); 3870 3871 // 4-byte-wide compare loop 3872 masm.bind(COMPARE_LOOP); 3873 masm.movl(ary1Reg, Address(tmp1Reg, resultReg, Address::times_4, 0)); 3874 masm.movl(ary2Reg, Address(tmp2Reg, resultReg, Address::times_4, 0)); 3875 masm.cmpl(ary1Reg, ary2Reg); 3876 masm.jcc(Assembler::notEqual, FALSE_LABEL); 3877 masm.incrementq(resultReg); 3878 masm.jcc(Assembler::notZero, COMPARE_LOOP); 3879 3880 masm.bind(TRUE_LABEL); 3881 masm.movl(resultReg, 1); // return true 3882 masm.jmp(DONE_LABEL); 3883 3884 masm.bind(FALSE_LABEL); 3885 masm.xorl(resultReg, resultReg); // return false 3886 3887 // That's it 3888 masm.bind(DONE_LABEL); 3889 %} 3890 3891 enc_class enc_rethrow() 3892 %{ 3893 cbuf.set_inst_mark(); 3894 emit_opcode(cbuf, 0xE9); // jmp entry 3895 emit_d32_reloc(cbuf, 3896 (int) (OptoRuntime::rethrow_stub() - cbuf.code_end() - 4), 3897 runtime_call_Relocation::spec(), 3898 RELOC_DISP32); 3899 %} 3900 3901 enc_class absF_encoding(regF dst) 3902 %{ 3903 int dstenc = $dst$$reg; 3904 address signmask_address = (address) StubRoutines::x86::float_sign_mask(); 3905 3906 cbuf.set_inst_mark(); 3907 if (dstenc >= 8) { 3908 emit_opcode(cbuf, Assembler::REX_R); 3909 dstenc -= 8; 3910 } 3911 // XXX reg_mem doesn't support RIP-relative addressing yet 3912 emit_opcode(cbuf, 0x0F); 3913 emit_opcode(cbuf, 0x54); 3914 emit_rm(cbuf, 0x0, dstenc, 0x5); // 00 reg 101 3915 emit_d32_reloc(cbuf, signmask_address); 3916 %} 3917 3918 enc_class absD_encoding(regD dst) 3919 %{ 3920 int dstenc = $dst$$reg; 3921 address signmask_address = (address) StubRoutines::x86::double_sign_mask(); 3922 3923 cbuf.set_inst_mark(); 3924 emit_opcode(cbuf, 0x66); 3925 if (dstenc >= 8) { 3926 emit_opcode(cbuf, Assembler::REX_R); 3927 dstenc -= 8; 3928 } 3929 // XXX reg_mem doesn't support RIP-relative addressing yet 3930 emit_opcode(cbuf, 0x0F); 3931 emit_opcode(cbuf, 0x54); 3932 emit_rm(cbuf, 0x0, dstenc, 0x5); // 00 reg 101 3933 emit_d32_reloc(cbuf, signmask_address); 3934 %} 3935 3936 enc_class negF_encoding(regF dst) 3937 %{ 3938 int dstenc = $dst$$reg; 3939 address signflip_address = (address) StubRoutines::x86::float_sign_flip(); 3940 3941 cbuf.set_inst_mark(); 3942 if (dstenc >= 8) { 3943 emit_opcode(cbuf, Assembler::REX_R); 3944 dstenc -= 8; 3945 } 3946 // XXX reg_mem doesn't support RIP-relative addressing yet 3947 emit_opcode(cbuf, 0x0F); 3948 emit_opcode(cbuf, 0x57); 3949 emit_rm(cbuf, 0x0, dstenc, 0x5); // 00 reg 101 3950 emit_d32_reloc(cbuf, signflip_address); 3951 %} 3952 3953 enc_class negD_encoding(regD dst) 3954 %{ 3955 int dstenc = $dst$$reg; 3956 address signflip_address = (address) StubRoutines::x86::double_sign_flip(); 3957 3958 cbuf.set_inst_mark(); 3959 emit_opcode(cbuf, 0x66); 3960 if (dstenc >= 8) { 3961 emit_opcode(cbuf, Assembler::REX_R); 3962 dstenc -= 8; 3963 } 3964 // XXX reg_mem doesn't support RIP-relative addressing yet 3965 emit_opcode(cbuf, 0x0F); 3966 emit_opcode(cbuf, 0x57); 3967 emit_rm(cbuf, 0x0, dstenc, 0x5); // 00 reg 101 3968 emit_d32_reloc(cbuf, signflip_address); 3969 %} 3970 3971 enc_class f2i_fixup(rRegI dst, regF src) 3972 %{ 3973 int dstenc = $dst$$reg; 3974 int srcenc = $src$$reg; 3975 3976 // cmpl $dst, #0x80000000 3977 if (dstenc >= 8) { 3978 emit_opcode(cbuf, Assembler::REX_B); 3979 } 3980 emit_opcode(cbuf, 0x81); 3981 emit_rm(cbuf, 0x3, 0x7, dstenc & 7); 3982 emit_d32(cbuf, 0x80000000); 3983 3984 // jne,s done 3985 emit_opcode(cbuf, 0x75); 3986 if (srcenc < 8 && dstenc < 8) { 3987 emit_d8(cbuf, 0xF); 3988 } else if (srcenc >= 8 && dstenc >= 8) { 3989 emit_d8(cbuf, 0x11); 3990 } else { 3991 emit_d8(cbuf, 0x10); 3992 } 3993 3994 // subq rsp, #8 3995 emit_opcode(cbuf, Assembler::REX_W); 3996 emit_opcode(cbuf, 0x83); 3997 emit_rm(cbuf, 0x3, 0x5, RSP_enc); 3998 emit_d8(cbuf, 8); 3999 4000 // movss [rsp], $src 4001 emit_opcode(cbuf, 0xF3); 4002 if (srcenc >= 8) { 4003 emit_opcode(cbuf, Assembler::REX_R); 4004 } 4005 emit_opcode(cbuf, 0x0F); 4006 emit_opcode(cbuf, 0x11); 4007 encode_RegMem(cbuf, srcenc, RSP_enc, 0x4, 0, 0, false); // 2 bytes 4008 4009 // call f2i_fixup 4010 cbuf.set_inst_mark(); 4011 emit_opcode(cbuf, 0xE8); 4012 emit_d32_reloc(cbuf, 4013 (int) 4014 (StubRoutines::x86::f2i_fixup() - cbuf.code_end() - 4), 4015 runtime_call_Relocation::spec(), 4016 RELOC_DISP32); 4017 4018 // popq $dst 4019 if (dstenc >= 8) { 4020 emit_opcode(cbuf, Assembler::REX_B); 4021 } 4022 emit_opcode(cbuf, 0x58 | (dstenc & 7)); 4023 4024 // done: 4025 %} 4026 4027 enc_class f2l_fixup(rRegL dst, regF src) 4028 %{ 4029 int dstenc = $dst$$reg; 4030 int srcenc = $src$$reg; 4031 address const_address = (address) StubRoutines::x86::double_sign_flip(); 4032 4033 // cmpq $dst, [0x8000000000000000] 4034 cbuf.set_inst_mark(); 4035 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX_W : Assembler::REX_WR); 4036 emit_opcode(cbuf, 0x39); 4037 // XXX reg_mem doesn't support RIP-relative addressing yet 4038 emit_rm(cbuf, 0x0, dstenc & 7, 0x5); // 00 reg 101 4039 emit_d32_reloc(cbuf, const_address); 4040 4041 4042 // jne,s done 4043 emit_opcode(cbuf, 0x75); 4044 if (srcenc < 8 && dstenc < 8) { 4045 emit_d8(cbuf, 0xF); 4046 } else if (srcenc >= 8 && dstenc >= 8) { 4047 emit_d8(cbuf, 0x11); 4048 } else { 4049 emit_d8(cbuf, 0x10); 4050 } 4051 4052 // subq rsp, #8 4053 emit_opcode(cbuf, Assembler::REX_W); 4054 emit_opcode(cbuf, 0x83); 4055 emit_rm(cbuf, 0x3, 0x5, RSP_enc); 4056 emit_d8(cbuf, 8); 4057 4058 // movss [rsp], $src 4059 emit_opcode(cbuf, 0xF3); 4060 if (srcenc >= 8) { 4061 emit_opcode(cbuf, Assembler::REX_R); 4062 } 4063 emit_opcode(cbuf, 0x0F); 4064 emit_opcode(cbuf, 0x11); 4065 encode_RegMem(cbuf, srcenc, RSP_enc, 0x4, 0, 0, false); // 2 bytes 4066 4067 // call f2l_fixup 4068 cbuf.set_inst_mark(); 4069 emit_opcode(cbuf, 0xE8); 4070 emit_d32_reloc(cbuf, 4071 (int) 4072 (StubRoutines::x86::f2l_fixup() - cbuf.code_end() - 4), 4073 runtime_call_Relocation::spec(), 4074 RELOC_DISP32); 4075 4076 // popq $dst 4077 if (dstenc >= 8) { 4078 emit_opcode(cbuf, Assembler::REX_B); 4079 } 4080 emit_opcode(cbuf, 0x58 | (dstenc & 7)); 4081 4082 // done: 4083 %} 4084 4085 enc_class d2i_fixup(rRegI dst, regD src) 4086 %{ 4087 int dstenc = $dst$$reg; 4088 int srcenc = $src$$reg; 4089 4090 // cmpl $dst, #0x80000000 4091 if (dstenc >= 8) { 4092 emit_opcode(cbuf, Assembler::REX_B); 4093 } 4094 emit_opcode(cbuf, 0x81); 4095 emit_rm(cbuf, 0x3, 0x7, dstenc & 7); 4096 emit_d32(cbuf, 0x80000000); 4097 4098 // jne,s done 4099 emit_opcode(cbuf, 0x75); 4100 if (srcenc < 8 && dstenc < 8) { 4101 emit_d8(cbuf, 0xF); 4102 } else if (srcenc >= 8 && dstenc >= 8) { 4103 emit_d8(cbuf, 0x11); 4104 } else { 4105 emit_d8(cbuf, 0x10); 4106 } 4107 4108 // subq rsp, #8 4109 emit_opcode(cbuf, Assembler::REX_W); 4110 emit_opcode(cbuf, 0x83); 4111 emit_rm(cbuf, 0x3, 0x5, RSP_enc); 4112 emit_d8(cbuf, 8); 4113 4114 // movsd [rsp], $src 4115 emit_opcode(cbuf, 0xF2); 4116 if (srcenc >= 8) { 4117 emit_opcode(cbuf, Assembler::REX_R); 4118 } 4119 emit_opcode(cbuf, 0x0F); 4120 emit_opcode(cbuf, 0x11); 4121 encode_RegMem(cbuf, srcenc, RSP_enc, 0x4, 0, 0, false); // 2 bytes 4122 4123 // call d2i_fixup 4124 cbuf.set_inst_mark(); 4125 emit_opcode(cbuf, 0xE8); 4126 emit_d32_reloc(cbuf, 4127 (int) 4128 (StubRoutines::x86::d2i_fixup() - cbuf.code_end() - 4), 4129 runtime_call_Relocation::spec(), 4130 RELOC_DISP32); 4131 4132 // popq $dst 4133 if (dstenc >= 8) { 4134 emit_opcode(cbuf, Assembler::REX_B); 4135 } 4136 emit_opcode(cbuf, 0x58 | (dstenc & 7)); 4137 4138 // done: 4139 %} 4140 4141 enc_class d2l_fixup(rRegL dst, regD src) 4142 %{ 4143 int dstenc = $dst$$reg; 4144 int srcenc = $src$$reg; 4145 address const_address = (address) StubRoutines::x86::double_sign_flip(); 4146 4147 // cmpq $dst, [0x8000000000000000] 4148 cbuf.set_inst_mark(); 4149 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX_W : Assembler::REX_WR); 4150 emit_opcode(cbuf, 0x39); 4151 // XXX reg_mem doesn't support RIP-relative addressing yet 4152 emit_rm(cbuf, 0x0, dstenc & 7, 0x5); // 00 reg 101 4153 emit_d32_reloc(cbuf, const_address); 4154 4155 4156 // jne,s done 4157 emit_opcode(cbuf, 0x75); 4158 if (srcenc < 8 && dstenc < 8) { 4159 emit_d8(cbuf, 0xF); 4160 } else if (srcenc >= 8 && dstenc >= 8) { 4161 emit_d8(cbuf, 0x11); 4162 } else { 4163 emit_d8(cbuf, 0x10); 4164 } 4165 4166 // subq rsp, #8 4167 emit_opcode(cbuf, Assembler::REX_W); 4168 emit_opcode(cbuf, 0x83); 4169 emit_rm(cbuf, 0x3, 0x5, RSP_enc); 4170 emit_d8(cbuf, 8); 4171 4172 // movsd [rsp], $src 4173 emit_opcode(cbuf, 0xF2); 4174 if (srcenc >= 8) { 4175 emit_opcode(cbuf, Assembler::REX_R); 4176 } 4177 emit_opcode(cbuf, 0x0F); 4178 emit_opcode(cbuf, 0x11); 4179 encode_RegMem(cbuf, srcenc, RSP_enc, 0x4, 0, 0, false); // 2 bytes 4180 4181 // call d2l_fixup 4182 cbuf.set_inst_mark(); 4183 emit_opcode(cbuf, 0xE8); 4184 emit_d32_reloc(cbuf, 4185 (int) 4186 (StubRoutines::x86::d2l_fixup() - cbuf.code_end() - 4), 4187 runtime_call_Relocation::spec(), 4188 RELOC_DISP32); 4189 4190 // popq $dst 4191 if (dstenc >= 8) { 4192 emit_opcode(cbuf, Assembler::REX_B); 4193 } 4194 emit_opcode(cbuf, 0x58 | (dstenc & 7)); 4195 4196 // done: 4197 %} 4198 4199 enc_class enc_membar_acquire 4200 %{ 4201 // [jk] not needed currently, if you enable this and it really 4202 // emits code don't forget to the remove the "size(0)" line in 4203 // membar_acquire() 4204 // MacroAssembler masm(&cbuf); 4205 // masm.membar(Assembler::Membar_mask_bits(Assembler::LoadStore | 4206 // Assembler::LoadLoad)); 4207 %} 4208 4209 enc_class enc_membar_release 4210 %{ 4211 // [jk] not needed currently, if you enable this and it really 4212 // emits code don't forget to the remove the "size(0)" line in 4213 // membar_release() 4214 // MacroAssembler masm(&cbuf); 4215 // masm.membar(Assembler::Membar_mask_bits(Assembler::LoadStore | 4216 // Assembler::StoreStore)); 4217 %} 4218 4219 enc_class enc_membar_volatile 4220 %{ 4221 MacroAssembler masm(&cbuf); 4222 masm.membar(Assembler::Membar_mask_bits(Assembler::StoreLoad | 4223 Assembler::StoreStore)); 4224 %} 4225 4226 // Safepoint Poll. This polls the safepoint page, and causes an 4227 // exception if it is not readable. Unfortunately, it kills 4228 // RFLAGS in the process. 4229 enc_class enc_safepoint_poll 4230 %{ 4231 // testl %rax, off(%rip) // Opcode + ModRM + Disp32 == 6 bytes 4232 // XXX reg_mem doesn't support RIP-relative addressing yet 4233 cbuf.set_inst_mark(); 4234 cbuf.relocate(cbuf.inst_mark(), relocInfo::poll_type, 0); // XXX 4235 emit_opcode(cbuf, 0x85); // testl 4236 emit_rm(cbuf, 0x0, RAX_enc, 0x5); // 00 rax 101 == 0x5 4237 // cbuf.inst_mark() is beginning of instruction 4238 emit_d32_reloc(cbuf, os::get_polling_page()); 4239// relocInfo::poll_type, 4240 %} 4241%} 4242 4243 4244 4245//----------FRAME-------------------------------------------------------------- 4246// Definition of frame structure and management information. 4247// 4248// S T A C K L A Y O U T Allocators stack-slot number 4249// | (to get allocators register number 4250// G Owned by | | v add OptoReg::stack0()) 4251// r CALLER | | 4252// o | +--------+ pad to even-align allocators stack-slot 4253// w V | pad0 | numbers; owned by CALLER 4254// t -----------+--------+----> Matcher::_in_arg_limit, unaligned 4255// h ^ | in | 5 4256// | | args | 4 Holes in incoming args owned by SELF 4257// | | | | 3 4258// | | +--------+ 4259// V | | old out| Empty on Intel, window on Sparc 4260// | old |preserve| Must be even aligned. 4261// | SP-+--------+----> Matcher::_old_SP, even aligned 4262// | | in | 3 area for Intel ret address 4263// Owned by |preserve| Empty on Sparc. 4264// SELF +--------+ 4265// | | pad2 | 2 pad to align old SP 4266// | +--------+ 1 4267// | | locks | 0 4268// | +--------+----> OptoReg::stack0(), even aligned 4269// | | pad1 | 11 pad to align new SP 4270// | +--------+ 4271// | | | 10 4272// | | spills | 9 spills 4273// V | | 8 (pad0 slot for callee) 4274// -----------+--------+----> Matcher::_out_arg_limit, unaligned 4275// ^ | out | 7 4276// | | args | 6 Holes in outgoing args owned by CALLEE 4277// Owned by +--------+ 4278// CALLEE | new out| 6 Empty on Intel, window on Sparc 4279// | new |preserve| Must be even-aligned. 4280// | SP-+--------+----> Matcher::_new_SP, even aligned 4281// | | | 4282// 4283// Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 4284// known from SELF's arguments and the Java calling convention. 4285// Region 6-7 is determined per call site. 4286// Note 2: If the calling convention leaves holes in the incoming argument 4287// area, those holes are owned by SELF. Holes in the outgoing area 4288// are owned by the CALLEE. Holes should not be nessecary in the 4289// incoming area, as the Java calling convention is completely under 4290// the control of the AD file. Doubles can be sorted and packed to 4291// avoid holes. Holes in the outgoing arguments may be nessecary for 4292// varargs C calling conventions. 4293// Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 4294// even aligned with pad0 as needed. 4295// Region 6 is even aligned. Region 6-7 is NOT even aligned; 4296// region 6-11 is even aligned; it may be padded out more so that 4297// the region from SP to FP meets the minimum stack alignment. 4298// Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 4299// alignment. Region 11, pad1, may be dynamically extended so that 4300// SP meets the minimum alignment. 4301 4302frame 4303%{ 4304 // What direction does stack grow in (assumed to be same for C & Java) 4305 stack_direction(TOWARDS_LOW); 4306 4307 // These three registers define part of the calling convention 4308 // between compiled code and the interpreter. 4309 inline_cache_reg(RAX); // Inline Cache Register 4310 interpreter_method_oop_reg(RBX); // Method Oop Register when 4311 // calling interpreter 4312 4313 // Optional: name the operand used by cisc-spilling to access 4314 // [stack_pointer + offset] 4315 cisc_spilling_operand_name(indOffset32); 4316 4317 // Number of stack slots consumed by locking an object 4318 sync_stack_slots(2); 4319 4320 // Compiled code's Frame Pointer 4321 frame_pointer(RSP); 4322 4323 // Interpreter stores its frame pointer in a register which is 4324 // stored to the stack by I2CAdaptors. 4325 // I2CAdaptors convert from interpreted java to compiled java. 4326 interpreter_frame_pointer(RBP); 4327 4328 // Stack alignment requirement 4329 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 4330 4331 // Number of stack slots between incoming argument block and the start of 4332 // a new frame. The PROLOG must add this many slots to the stack. The 4333 // EPILOG must remove this many slots. amd64 needs two slots for 4334 // return address. 4335 in_preserve_stack_slots(4 + 2 * VerifyStackAtCalls); 4336 4337 // Number of outgoing stack slots killed above the out_preserve_stack_slots 4338 // for calls to C. Supports the var-args backing area for register parms. 4339 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 4340 4341 // The after-PROLOG location of the return address. Location of 4342 // return address specifies a type (REG or STACK) and a number 4343 // representing the register number (i.e. - use a register name) or 4344 // stack slot. 4345 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 4346 // Otherwise, it is above the locks and verification slot and alignment word 4347 return_addr(STACK - 2 + 4348 round_to(2 + 2 * VerifyStackAtCalls + 4349 Compile::current()->fixed_slots(), 4350 WordsPerLong * 2)); 4351 4352 // Body of function which returns an integer array locating 4353 // arguments either in registers or in stack slots. Passed an array 4354 // of ideal registers called "sig" and a "length" count. Stack-slot 4355 // offsets are based on outgoing arguments, i.e. a CALLER setting up 4356 // arguments for a CALLEE. Incoming stack arguments are 4357 // automatically biased by the preserve_stack_slots field above. 4358 4359 calling_convention 4360 %{ 4361 // No difference between ingoing/outgoing just pass false 4362 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 4363 %} 4364 4365 c_calling_convention 4366 %{ 4367 // This is obviously always outgoing 4368 (void) SharedRuntime::c_calling_convention(sig_bt, regs, length); 4369 %} 4370 4371 // Location of compiled Java return values. Same as C for now. 4372 return_value 4373 %{ 4374 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 4375 "only return normal values"); 4376 4377 static const int lo[Op_RegL + 1] = { 4378 0, 4379 0, 4380 RAX_num, // Op_RegN 4381 RAX_num, // Op_RegI 4382 RAX_num, // Op_RegP 4383 XMM0_num, // Op_RegF 4384 XMM0_num, // Op_RegD 4385 RAX_num // Op_RegL 4386 }; 4387 static const int hi[Op_RegL + 1] = { 4388 0, 4389 0, 4390 OptoReg::Bad, // Op_RegN 4391 OptoReg::Bad, // Op_RegI 4392 RAX_H_num, // Op_RegP 4393 OptoReg::Bad, // Op_RegF 4394 XMM0_H_num, // Op_RegD 4395 RAX_H_num // Op_RegL 4396 }; 4397 assert(ARRAY_SIZE(hi) == _last_machine_leaf - 1, "missing type"); 4398 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 4399 %} 4400%} 4401 4402//----------ATTRIBUTES--------------------------------------------------------- 4403//----------Operand Attributes------------------------------------------------- 4404op_attrib op_cost(0); // Required cost attribute 4405 4406//----------Instruction Attributes--------------------------------------------- 4407ins_attrib ins_cost(100); // Required cost attribute 4408ins_attrib ins_size(8); // Required size attribute (in bits) 4409ins_attrib ins_pc_relative(0); // Required PC Relative flag 4410ins_attrib ins_short_branch(0); // Required flag: is this instruction 4411 // a non-matching short branch variant 4412 // of some long branch? 4413ins_attrib ins_alignment(1); // Required alignment attribute (must 4414 // be a power of 2) specifies the 4415 // alignment that some part of the 4416 // instruction (not necessarily the 4417 // start) requires. If > 1, a 4418 // compute_padding() function must be 4419 // provided for the instruction 4420 4421//----------OPERANDS----------------------------------------------------------- 4422// Operand definitions must precede instruction definitions for correct parsing 4423// in the ADLC because operands constitute user defined types which are used in 4424// instruction definitions. 4425 4426//----------Simple Operands---------------------------------------------------- 4427// Immediate Operands 4428// Integer Immediate 4429operand immI() 4430%{ 4431 match(ConI); 4432 4433 op_cost(10); 4434 format %{ %} 4435 interface(CONST_INTER); 4436%} 4437 4438// Constant for test vs zero 4439operand immI0() 4440%{ 4441 predicate(n->get_int() == 0); 4442 match(ConI); 4443 4444 op_cost(0); 4445 format %{ %} 4446 interface(CONST_INTER); 4447%} 4448 4449// Constant for increment 4450operand immI1() 4451%{ 4452 predicate(n->get_int() == 1); 4453 match(ConI); 4454 4455 op_cost(0); 4456 format %{ %} 4457 interface(CONST_INTER); 4458%} 4459 4460// Constant for decrement 4461operand immI_M1() 4462%{ 4463 predicate(n->get_int() == -1); 4464 match(ConI); 4465 4466 op_cost(0); 4467 format %{ %} 4468 interface(CONST_INTER); 4469%} 4470 4471// Valid scale values for addressing modes 4472operand immI2() 4473%{ 4474 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 4475 match(ConI); 4476 4477 format %{ %} 4478 interface(CONST_INTER); 4479%} 4480 4481operand immI8() 4482%{ 4483 predicate((-0x80 <= n->get_int()) && (n->get_int() < 0x80)); 4484 match(ConI); 4485 4486 op_cost(5); 4487 format %{ %} 4488 interface(CONST_INTER); 4489%} 4490 4491operand immI16() 4492%{ 4493 predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767)); 4494 match(ConI); 4495 4496 op_cost(10); 4497 format %{ %} 4498 interface(CONST_INTER); 4499%} 4500 4501// Constant for long shifts 4502operand immI_32() 4503%{ 4504 predicate( n->get_int() == 32 ); 4505 match(ConI); 4506 4507 op_cost(0); 4508 format %{ %} 4509 interface(CONST_INTER); 4510%} 4511 4512// Constant for long shifts 4513operand immI_64() 4514%{ 4515 predicate( n->get_int() == 64 ); 4516 match(ConI); 4517 4518 op_cost(0); 4519 format %{ %} 4520 interface(CONST_INTER); 4521%} 4522 4523// Pointer Immediate 4524operand immP() 4525%{ 4526 match(ConP); 4527 4528 op_cost(10); 4529 format %{ %} 4530 interface(CONST_INTER); 4531%} 4532 4533// NULL Pointer Immediate 4534operand immP0() 4535%{ 4536 predicate(n->get_ptr() == 0); 4537 match(ConP); 4538 4539 op_cost(5); 4540 format %{ %} 4541 interface(CONST_INTER); 4542%} 4543 4544// Pointer Immediate 4545operand immN() %{ 4546 match(ConN); 4547 4548 op_cost(10); 4549 format %{ %} 4550 interface(CONST_INTER); 4551%} 4552 4553// NULL Pointer Immediate 4554operand immN0() %{ 4555 predicate(n->get_narrowcon() == 0); 4556 match(ConN); 4557 4558 op_cost(5); 4559 format %{ %} 4560 interface(CONST_INTER); 4561%} 4562 4563operand immP31() 4564%{ 4565 predicate(!n->as_Type()->type()->isa_oopptr() 4566 && (n->get_ptr() >> 31) == 0); 4567 match(ConP); 4568 4569 op_cost(5); 4570 format %{ %} 4571 interface(CONST_INTER); 4572%} 4573 4574 4575// Long Immediate 4576operand immL() 4577%{ 4578 match(ConL); 4579 4580 op_cost(20); 4581 format %{ %} 4582 interface(CONST_INTER); 4583%} 4584 4585// Long Immediate 8-bit 4586operand immL8() 4587%{ 4588 predicate(-0x80L <= n->get_long() && n->get_long() < 0x80L); 4589 match(ConL); 4590 4591 op_cost(5); 4592 format %{ %} 4593 interface(CONST_INTER); 4594%} 4595 4596// Long Immediate 32-bit unsigned 4597operand immUL32() 4598%{ 4599 predicate(n->get_long() == (unsigned int) (n->get_long())); 4600 match(ConL); 4601 4602 op_cost(10); 4603 format %{ %} 4604 interface(CONST_INTER); 4605%} 4606 4607// Long Immediate 32-bit signed 4608operand immL32() 4609%{ 4610 predicate(n->get_long() == (int) (n->get_long())); 4611 match(ConL); 4612 4613 op_cost(15); 4614 format %{ %} 4615 interface(CONST_INTER); 4616%} 4617 4618// Long Immediate zero 4619operand immL0() 4620%{ 4621 predicate(n->get_long() == 0L); 4622 match(ConL); 4623 4624 op_cost(10); 4625 format %{ %} 4626 interface(CONST_INTER); 4627%} 4628 4629// Constant for increment 4630operand immL1() 4631%{ 4632 predicate(n->get_long() == 1); 4633 match(ConL); 4634 4635 format %{ %} 4636 interface(CONST_INTER); 4637%} 4638 4639// Constant for decrement 4640operand immL_M1() 4641%{ 4642 predicate(n->get_long() == -1); 4643 match(ConL); 4644 4645 format %{ %} 4646 interface(CONST_INTER); 4647%} 4648 4649// Long Immediate: the value 10 4650operand immL10() 4651%{ 4652 predicate(n->get_long() == 10); 4653 match(ConL); 4654 4655 format %{ %} 4656 interface(CONST_INTER); 4657%} 4658 4659// Long immediate from 0 to 127. 4660// Used for a shorter form of long mul by 10. 4661operand immL_127() 4662%{ 4663 predicate(0 <= n->get_long() && n->get_long() < 0x80); 4664 match(ConL); 4665 4666 op_cost(10); 4667 format %{ %} 4668 interface(CONST_INTER); 4669%} 4670 4671// Long Immediate: low 32-bit mask 4672operand immL_32bits() 4673%{ 4674 predicate(n->get_long() == 0xFFFFFFFFL); 4675 match(ConL); 4676 op_cost(20); 4677 4678 format %{ %} 4679 interface(CONST_INTER); 4680%} 4681 4682// Float Immediate zero 4683operand immF0() 4684%{ 4685 predicate(jint_cast(n->getf()) == 0); 4686 match(ConF); 4687 4688 op_cost(5); 4689 format %{ %} 4690 interface(CONST_INTER); 4691%} 4692 4693// Float Immediate 4694operand immF() 4695%{ 4696 match(ConF); 4697 4698 op_cost(15); 4699 format %{ %} 4700 interface(CONST_INTER); 4701%} 4702 4703// Double Immediate zero 4704operand immD0() 4705%{ 4706 predicate(jlong_cast(n->getd()) == 0); 4707 match(ConD); 4708 4709 op_cost(5); 4710 format %{ %} 4711 interface(CONST_INTER); 4712%} 4713 4714// Double Immediate 4715operand immD() 4716%{ 4717 match(ConD); 4718 4719 op_cost(15); 4720 format %{ %} 4721 interface(CONST_INTER); 4722%} 4723 4724// Immediates for special shifts (sign extend) 4725 4726// Constants for increment 4727operand immI_16() 4728%{ 4729 predicate(n->get_int() == 16); 4730 match(ConI); 4731 4732 format %{ %} 4733 interface(CONST_INTER); 4734%} 4735 4736operand immI_24() 4737%{ 4738 predicate(n->get_int() == 24); 4739 match(ConI); 4740 4741 format %{ %} 4742 interface(CONST_INTER); 4743%} 4744 4745// Constant for byte-wide masking 4746operand immI_255() 4747%{ 4748 predicate(n->get_int() == 255); 4749 match(ConI); 4750 4751 format %{ %} 4752 interface(CONST_INTER); 4753%} 4754 4755// Constant for short-wide masking 4756operand immI_65535() 4757%{ 4758 predicate(n->get_int() == 65535); 4759 match(ConI); 4760 4761 format %{ %} 4762 interface(CONST_INTER); 4763%} 4764 4765// Constant for byte-wide masking 4766operand immL_255() 4767%{ 4768 predicate(n->get_long() == 255); 4769 match(ConL); 4770 4771 format %{ %} 4772 interface(CONST_INTER); 4773%} 4774 4775// Constant for short-wide masking 4776operand immL_65535() 4777%{ 4778 predicate(n->get_long() == 65535); 4779 match(ConL); 4780 4781 format %{ %} 4782 interface(CONST_INTER); 4783%} 4784 4785// Register Operands 4786// Integer Register 4787operand rRegI() 4788%{ 4789 constraint(ALLOC_IN_RC(int_reg)); 4790 match(RegI); 4791 4792 match(rax_RegI); 4793 match(rbx_RegI); 4794 match(rcx_RegI); 4795 match(rdx_RegI); 4796 match(rdi_RegI); 4797 4798 format %{ %} 4799 interface(REG_INTER); 4800%} 4801 4802// Special Registers 4803operand rax_RegI() 4804%{ 4805 constraint(ALLOC_IN_RC(int_rax_reg)); 4806 match(RegI); 4807 match(rRegI); 4808 4809 format %{ "RAX" %} 4810 interface(REG_INTER); 4811%} 4812 4813// Special Registers 4814operand rbx_RegI() 4815%{ 4816 constraint(ALLOC_IN_RC(int_rbx_reg)); 4817 match(RegI); 4818 match(rRegI); 4819 4820 format %{ "RBX" %} 4821 interface(REG_INTER); 4822%} 4823 4824operand rcx_RegI() 4825%{ 4826 constraint(ALLOC_IN_RC(int_rcx_reg)); 4827 match(RegI); 4828 match(rRegI); 4829 4830 format %{ "RCX" %} 4831 interface(REG_INTER); 4832%} 4833 4834operand rdx_RegI() 4835%{ 4836 constraint(ALLOC_IN_RC(int_rdx_reg)); 4837 match(RegI); 4838 match(rRegI); 4839 4840 format %{ "RDX" %} 4841 interface(REG_INTER); 4842%} 4843 4844operand rdi_RegI() 4845%{ 4846 constraint(ALLOC_IN_RC(int_rdi_reg)); 4847 match(RegI); 4848 match(rRegI); 4849 4850 format %{ "RDI" %} 4851 interface(REG_INTER); 4852%} 4853 4854operand no_rcx_RegI() 4855%{ 4856 constraint(ALLOC_IN_RC(int_no_rcx_reg)); 4857 match(RegI); 4858 match(rax_RegI); 4859 match(rbx_RegI); 4860 match(rdx_RegI); 4861 match(rdi_RegI); 4862 4863 format %{ %} 4864 interface(REG_INTER); 4865%} 4866 4867operand no_rax_rdx_RegI() 4868%{ 4869 constraint(ALLOC_IN_RC(int_no_rax_rdx_reg)); 4870 match(RegI); 4871 match(rbx_RegI); 4872 match(rcx_RegI); 4873 match(rdi_RegI); 4874 4875 format %{ %} 4876 interface(REG_INTER); 4877%} 4878 4879// Pointer Register 4880operand any_RegP() 4881%{ 4882 constraint(ALLOC_IN_RC(any_reg)); 4883 match(RegP); 4884 match(rax_RegP); 4885 match(rbx_RegP); 4886 match(rdi_RegP); 4887 match(rsi_RegP); 4888 match(rbp_RegP); 4889 match(r15_RegP); 4890 match(rRegP); 4891 4892 format %{ %} 4893 interface(REG_INTER); 4894%} 4895 4896operand rRegP() 4897%{ 4898 constraint(ALLOC_IN_RC(ptr_reg)); 4899 match(RegP); 4900 match(rax_RegP); 4901 match(rbx_RegP); 4902 match(rdi_RegP); 4903 match(rsi_RegP); 4904 match(rbp_RegP); 4905 match(r15_RegP); // See Q&A below about r15_RegP. 4906 4907 format %{ %} 4908 interface(REG_INTER); 4909%} 4910 4911 4912operand r12RegL() %{ 4913 constraint(ALLOC_IN_RC(long_r12_reg)); 4914 match(RegL); 4915 4916 format %{ %} 4917 interface(REG_INTER); 4918%} 4919 4920operand rRegN() %{ 4921 constraint(ALLOC_IN_RC(int_reg)); 4922 match(RegN); 4923 4924 format %{ %} 4925 interface(REG_INTER); 4926%} 4927 4928// Question: Why is r15_RegP (the read-only TLS register) a match for rRegP? 4929// Answer: Operand match rules govern the DFA as it processes instruction inputs. 4930// It's fine for an instruction input which expects rRegP to match a r15_RegP. 4931// The output of an instruction is controlled by the allocator, which respects 4932// register class masks, not match rules. Unless an instruction mentions 4933// r15_RegP or any_RegP explicitly as its output, r15 will not be considered 4934// by the allocator as an input. 4935 4936operand no_rax_RegP() 4937%{ 4938 constraint(ALLOC_IN_RC(ptr_no_rax_reg)); 4939 match(RegP); 4940 match(rbx_RegP); 4941 match(rsi_RegP); 4942 match(rdi_RegP); 4943 4944 format %{ %} 4945 interface(REG_INTER); 4946%} 4947 4948operand no_rbp_RegP() 4949%{ 4950 constraint(ALLOC_IN_RC(ptr_no_rbp_reg)); 4951 match(RegP); 4952 match(rbx_RegP); 4953 match(rsi_RegP); 4954 match(rdi_RegP); 4955 4956 format %{ %} 4957 interface(REG_INTER); 4958%} 4959 4960operand no_rax_rbx_RegP() 4961%{ 4962 constraint(ALLOC_IN_RC(ptr_no_rax_rbx_reg)); 4963 match(RegP); 4964 match(rsi_RegP); 4965 match(rdi_RegP); 4966 4967 format %{ %} 4968 interface(REG_INTER); 4969%} 4970 4971// Special Registers 4972// Return a pointer value 4973operand rax_RegP() 4974%{ 4975 constraint(ALLOC_IN_RC(ptr_rax_reg)); 4976 match(RegP); 4977 match(rRegP); 4978 4979 format %{ %} 4980 interface(REG_INTER); 4981%} 4982 4983// Special Registers 4984// Return a compressed pointer value 4985operand rax_RegN() 4986%{ 4987 constraint(ALLOC_IN_RC(int_rax_reg)); 4988 match(RegN); 4989 match(rRegN); 4990 4991 format %{ %} 4992 interface(REG_INTER); 4993%} 4994 4995// Used in AtomicAdd 4996operand rbx_RegP() 4997%{ 4998 constraint(ALLOC_IN_RC(ptr_rbx_reg)); 4999 match(RegP); 5000 match(rRegP); 5001 5002 format %{ %} 5003 interface(REG_INTER); 5004%} 5005 5006operand rsi_RegP() 5007%{ 5008 constraint(ALLOC_IN_RC(ptr_rsi_reg)); 5009 match(RegP); 5010 match(rRegP); 5011 5012 format %{ %} 5013 interface(REG_INTER); 5014%} 5015 5016// Used in rep stosq 5017operand rdi_RegP() 5018%{ 5019 constraint(ALLOC_IN_RC(ptr_rdi_reg)); 5020 match(RegP); 5021 match(rRegP); 5022 5023 format %{ %} 5024 interface(REG_INTER); 5025%} 5026 5027operand rbp_RegP() 5028%{ 5029 constraint(ALLOC_IN_RC(ptr_rbp_reg)); 5030 match(RegP); 5031 match(rRegP); 5032 5033 format %{ %} 5034 interface(REG_INTER); 5035%} 5036 5037operand r15_RegP() 5038%{ 5039 constraint(ALLOC_IN_RC(ptr_r15_reg)); 5040 match(RegP); 5041 match(rRegP); 5042 5043 format %{ %} 5044 interface(REG_INTER); 5045%} 5046 5047operand rRegL() 5048%{ 5049 constraint(ALLOC_IN_RC(long_reg)); 5050 match(RegL); 5051 match(rax_RegL); 5052 match(rdx_RegL); 5053 5054 format %{ %} 5055 interface(REG_INTER); 5056%} 5057 5058// Special Registers 5059operand no_rax_rdx_RegL() 5060%{ 5061 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 5062 match(RegL); 5063 match(rRegL); 5064 5065 format %{ %} 5066 interface(REG_INTER); 5067%} 5068 5069operand no_rax_RegL() 5070%{ 5071 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 5072 match(RegL); 5073 match(rRegL); 5074 match(rdx_RegL); 5075 5076 format %{ %} 5077 interface(REG_INTER); 5078%} 5079 5080operand no_rcx_RegL() 5081%{ 5082 constraint(ALLOC_IN_RC(long_no_rcx_reg)); 5083 match(RegL); 5084 match(rRegL); 5085 5086 format %{ %} 5087 interface(REG_INTER); 5088%} 5089 5090operand rax_RegL() 5091%{ 5092 constraint(ALLOC_IN_RC(long_rax_reg)); 5093 match(RegL); 5094 match(rRegL); 5095 5096 format %{ "RAX" %} 5097 interface(REG_INTER); 5098%} 5099 5100operand rcx_RegL() 5101%{ 5102 constraint(ALLOC_IN_RC(long_rcx_reg)); 5103 match(RegL); 5104 match(rRegL); 5105 5106 format %{ %} 5107 interface(REG_INTER); 5108%} 5109 5110operand rdx_RegL() 5111%{ 5112 constraint(ALLOC_IN_RC(long_rdx_reg)); 5113 match(RegL); 5114 match(rRegL); 5115 5116 format %{ %} 5117 interface(REG_INTER); 5118%} 5119 5120// Flags register, used as output of compare instructions 5121operand rFlagsReg() 5122%{ 5123 constraint(ALLOC_IN_RC(int_flags)); 5124 match(RegFlags); 5125 5126 format %{ "RFLAGS" %} 5127 interface(REG_INTER); 5128%} 5129 5130// Flags register, used as output of FLOATING POINT compare instructions 5131operand rFlagsRegU() 5132%{ 5133 constraint(ALLOC_IN_RC(int_flags)); 5134 match(RegFlags); 5135 5136 format %{ "RFLAGS_U" %} 5137 interface(REG_INTER); 5138%} 5139 5140operand rFlagsRegUCF() %{ 5141 constraint(ALLOC_IN_RC(int_flags)); 5142 match(RegFlags); 5143 predicate(false); 5144 5145 format %{ "RFLAGS_U_CF" %} 5146 interface(REG_INTER); 5147%} 5148 5149// Float register operands 5150operand regF() 5151%{ 5152 constraint(ALLOC_IN_RC(float_reg)); 5153 match(RegF); 5154 5155 format %{ %} 5156 interface(REG_INTER); 5157%} 5158 5159// Double register operands 5160operand regD() 5161%{ 5162 constraint(ALLOC_IN_RC(double_reg)); 5163 match(RegD); 5164 5165 format %{ %} 5166 interface(REG_INTER); 5167%} 5168 5169 5170//----------Memory Operands---------------------------------------------------- 5171// Direct Memory Operand 5172// operand direct(immP addr) 5173// %{ 5174// match(addr); 5175 5176// format %{ "[$addr]" %} 5177// interface(MEMORY_INTER) %{ 5178// base(0xFFFFFFFF); 5179// index(0x4); 5180// scale(0x0); 5181// disp($addr); 5182// %} 5183// %} 5184 5185// Indirect Memory Operand 5186operand indirect(any_RegP reg) 5187%{ 5188 constraint(ALLOC_IN_RC(ptr_reg)); 5189 match(reg); 5190 5191 format %{ "[$reg]" %} 5192 interface(MEMORY_INTER) %{ 5193 base($reg); 5194 index(0x4); 5195 scale(0x0); 5196 disp(0x0); 5197 %} 5198%} 5199 5200// Indirect Memory Plus Short Offset Operand 5201operand indOffset8(any_RegP reg, immL8 off) 5202%{ 5203 constraint(ALLOC_IN_RC(ptr_reg)); 5204 match(AddP reg off); 5205 5206 format %{ "[$reg + $off (8-bit)]" %} 5207 interface(MEMORY_INTER) %{ 5208 base($reg); 5209 index(0x4); 5210 scale(0x0); 5211 disp($off); 5212 %} 5213%} 5214 5215// Indirect Memory Plus Long Offset Operand 5216operand indOffset32(any_RegP reg, immL32 off) 5217%{ 5218 constraint(ALLOC_IN_RC(ptr_reg)); 5219 match(AddP reg off); 5220 5221 format %{ "[$reg + $off (32-bit)]" %} 5222 interface(MEMORY_INTER) %{ 5223 base($reg); 5224 index(0x4); 5225 scale(0x0); 5226 disp($off); 5227 %} 5228%} 5229 5230// Indirect Memory Plus Index Register Plus Offset Operand 5231operand indIndexOffset(any_RegP reg, rRegL lreg, immL32 off) 5232%{ 5233 constraint(ALLOC_IN_RC(ptr_reg)); 5234 match(AddP (AddP reg lreg) off); 5235 5236 op_cost(10); 5237 format %{"[$reg + $off + $lreg]" %} 5238 interface(MEMORY_INTER) %{ 5239 base($reg); 5240 index($lreg); 5241 scale(0x0); 5242 disp($off); 5243 %} 5244%} 5245 5246// Indirect Memory Plus Index Register Plus Offset Operand 5247operand indIndex(any_RegP reg, rRegL lreg) 5248%{ 5249 constraint(ALLOC_IN_RC(ptr_reg)); 5250 match(AddP reg lreg); 5251 5252 op_cost(10); 5253 format %{"[$reg + $lreg]" %} 5254 interface(MEMORY_INTER) %{ 5255 base($reg); 5256 index($lreg); 5257 scale(0x0); 5258 disp(0x0); 5259 %} 5260%} 5261 5262// Indirect Memory Times Scale Plus Index Register 5263operand indIndexScale(any_RegP reg, rRegL lreg, immI2 scale) 5264%{ 5265 constraint(ALLOC_IN_RC(ptr_reg)); 5266 match(AddP reg (LShiftL lreg scale)); 5267 5268 op_cost(10); 5269 format %{"[$reg + $lreg << $scale]" %} 5270 interface(MEMORY_INTER) %{ 5271 base($reg); 5272 index($lreg); 5273 scale($scale); 5274 disp(0x0); 5275 %} 5276%} 5277 5278// Indirect Memory Times Scale Plus Index Register Plus Offset Operand 5279operand indIndexScaleOffset(any_RegP reg, immL32 off, rRegL lreg, immI2 scale) 5280%{ 5281 constraint(ALLOC_IN_RC(ptr_reg)); 5282 match(AddP (AddP reg (LShiftL lreg scale)) off); 5283 5284 op_cost(10); 5285 format %{"[$reg + $off + $lreg << $scale]" %} 5286 interface(MEMORY_INTER) %{ 5287 base($reg); 5288 index($lreg); 5289 scale($scale); 5290 disp($off); 5291 %} 5292%} 5293 5294// Indirect Narrow Oop Plus Offset Operand 5295operand indNarrowOopOffset(rRegN src, immL32 off) %{ 5296 constraint(ALLOC_IN_RC(ptr_reg)); 5297 match(AddP (DecodeN src) off); 5298 5299 op_cost(10); 5300 format %{"[R12 + $src << 3 + $off] (compressed oop addressing)" %} 5301 interface(MEMORY_INTER) %{ 5302 base(0xc); // R12 5303 index($src); 5304 scale(0x3); 5305 disp($off); 5306 %} 5307%} 5308 5309// Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 5310operand indPosIndexScaleOffset(any_RegP reg, immL32 off, rRegI idx, immI2 scale) 5311%{ 5312 constraint(ALLOC_IN_RC(ptr_reg)); 5313 predicate(n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 5314 match(AddP (AddP reg (LShiftL (ConvI2L idx) scale)) off); 5315 5316 op_cost(10); 5317 format %{"[$reg + $off + $idx << $scale]" %} 5318 interface(MEMORY_INTER) %{ 5319 base($reg); 5320 index($idx); 5321 scale($scale); 5322 disp($off); 5323 %} 5324%} 5325 5326//----------Special Memory Operands-------------------------------------------- 5327// Stack Slot Operand - This operand is used for loading and storing temporary 5328// values on the stack where a match requires a value to 5329// flow through memory. 5330operand stackSlotP(sRegP reg) 5331%{ 5332 constraint(ALLOC_IN_RC(stack_slots)); 5333 // No match rule because this operand is only generated in matching 5334 5335 format %{ "[$reg]" %} 5336 interface(MEMORY_INTER) %{ 5337 base(0x4); // RSP 5338 index(0x4); // No Index 5339 scale(0x0); // No Scale 5340 disp($reg); // Stack Offset 5341 %} 5342%} 5343 5344operand stackSlotI(sRegI reg) 5345%{ 5346 constraint(ALLOC_IN_RC(stack_slots)); 5347 // No match rule because this operand is only generated in matching 5348 5349 format %{ "[$reg]" %} 5350 interface(MEMORY_INTER) %{ 5351 base(0x4); // RSP 5352 index(0x4); // No Index 5353 scale(0x0); // No Scale 5354 disp($reg); // Stack Offset 5355 %} 5356%} 5357 5358operand stackSlotF(sRegF reg) 5359%{ 5360 constraint(ALLOC_IN_RC(stack_slots)); 5361 // No match rule because this operand is only generated in matching 5362 5363 format %{ "[$reg]" %} 5364 interface(MEMORY_INTER) %{ 5365 base(0x4); // RSP 5366 index(0x4); // No Index 5367 scale(0x0); // No Scale 5368 disp($reg); // Stack Offset 5369 %} 5370%} 5371 5372operand stackSlotD(sRegD reg) 5373%{ 5374 constraint(ALLOC_IN_RC(stack_slots)); 5375 // No match rule because this operand is only generated in matching 5376 5377 format %{ "[$reg]" %} 5378 interface(MEMORY_INTER) %{ 5379 base(0x4); // RSP 5380 index(0x4); // No Index 5381 scale(0x0); // No Scale 5382 disp($reg); // Stack Offset 5383 %} 5384%} 5385operand stackSlotL(sRegL reg) 5386%{ 5387 constraint(ALLOC_IN_RC(stack_slots)); 5388 // No match rule because this operand is only generated in matching 5389 5390 format %{ "[$reg]" %} 5391 interface(MEMORY_INTER) %{ 5392 base(0x4); // RSP 5393 index(0x4); // No Index 5394 scale(0x0); // No Scale 5395 disp($reg); // Stack Offset 5396 %} 5397%} 5398 5399//----------Conditional Branch Operands---------------------------------------- 5400// Comparison Op - This is the operation of the comparison, and is limited to 5401// the following set of codes: 5402// L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 5403// 5404// Other attributes of the comparison, such as unsignedness, are specified 5405// by the comparison instruction that sets a condition code flags register. 5406// That result is represented by a flags operand whose subtype is appropriate 5407// to the unsignedness (etc.) of the comparison. 5408// 5409// Later, the instruction which matches both the Comparison Op (a Bool) and 5410// the flags (produced by the Cmp) specifies the coding of the comparison op 5411// by matching a specific subtype of Bool operand below, such as cmpOpU. 5412 5413// Comparision Code 5414operand cmpOp() 5415%{ 5416 match(Bool); 5417 5418 format %{ "" %} 5419 interface(COND_INTER) %{ 5420 equal(0x4, "e"); 5421 not_equal(0x5, "ne"); 5422 less(0xC, "l"); 5423 greater_equal(0xD, "ge"); 5424 less_equal(0xE, "le"); 5425 greater(0xF, "g"); 5426 %} 5427%} 5428 5429// Comparison Code, unsigned compare. Used by FP also, with 5430// C2 (unordered) turned into GT or LT already. The other bits 5431// C0 and C3 are turned into Carry & Zero flags. 5432operand cmpOpU() 5433%{ 5434 match(Bool); 5435 5436 format %{ "" %} 5437 interface(COND_INTER) %{ 5438 equal(0x4, "e"); 5439 not_equal(0x5, "ne"); 5440 less(0x2, "b"); 5441 greater_equal(0x3, "nb"); 5442 less_equal(0x6, "be"); 5443 greater(0x7, "nbe"); 5444 %} 5445%} 5446 5447 5448// Floating comparisons that don't require any fixup for the unordered case 5449operand cmpOpUCF() %{ 5450 match(Bool); 5451 predicate(n->as_Bool()->_test._test == BoolTest::lt || 5452 n->as_Bool()->_test._test == BoolTest::ge || 5453 n->as_Bool()->_test._test == BoolTest::le || 5454 n->as_Bool()->_test._test == BoolTest::gt); 5455 format %{ "" %} 5456 interface(COND_INTER) %{ 5457 equal(0x4, "e"); 5458 not_equal(0x5, "ne"); 5459 less(0x2, "b"); 5460 greater_equal(0x3, "nb"); 5461 less_equal(0x6, "be"); 5462 greater(0x7, "nbe"); 5463 %} 5464%} 5465 5466 5467// Floating comparisons that can be fixed up with extra conditional jumps 5468operand cmpOpUCF2() %{ 5469 match(Bool); 5470 predicate(n->as_Bool()->_test._test == BoolTest::ne || 5471 n->as_Bool()->_test._test == BoolTest::eq); 5472 format %{ "" %} 5473 interface(COND_INTER) %{ 5474 equal(0x4, "e"); 5475 not_equal(0x5, "ne"); 5476 less(0x2, "b"); 5477 greater_equal(0x3, "nb"); 5478 less_equal(0x6, "be"); 5479 greater(0x7, "nbe"); 5480 %} 5481%} 5482 5483 5484//----------OPERAND CLASSES---------------------------------------------------- 5485// Operand Classes are groups of operands that are used as to simplify 5486// instruction definitions by not requiring the AD writer to specify seperate 5487// instructions for every form of operand when the instruction accepts 5488// multiple operand types with the same basic encoding and format. The classic 5489// case of this is memory operands. 5490 5491opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex, 5492 indIndexScale, indIndexScaleOffset, indPosIndexScaleOffset, 5493 indNarrowOopOffset); 5494 5495//----------PIPELINE----------------------------------------------------------- 5496// Rules which define the behavior of the target architectures pipeline. 5497pipeline %{ 5498 5499//----------ATTRIBUTES--------------------------------------------------------- 5500attributes %{ 5501 variable_size_instructions; // Fixed size instructions 5502 max_instructions_per_bundle = 3; // Up to 3 instructions per bundle 5503 instruction_unit_size = 1; // An instruction is 1 bytes long 5504 instruction_fetch_unit_size = 16; // The processor fetches one line 5505 instruction_fetch_units = 1; // of 16 bytes 5506 5507 // List of nop instructions 5508 nops( MachNop ); 5509%} 5510 5511//----------RESOURCES---------------------------------------------------------- 5512// Resources are the functional units available to the machine 5513 5514// Generic P2/P3 pipeline 5515// 3 decoders, only D0 handles big operands; a "bundle" is the limit of 5516// 3 instructions decoded per cycle. 5517// 2 load/store ops per cycle, 1 branch, 1 FPU, 5518// 3 ALU op, only ALU0 handles mul instructions. 5519resources( D0, D1, D2, DECODE = D0 | D1 | D2, 5520 MS0, MS1, MS2, MEM = MS0 | MS1 | MS2, 5521 BR, FPU, 5522 ALU0, ALU1, ALU2, ALU = ALU0 | ALU1 | ALU2); 5523 5524//----------PIPELINE DESCRIPTION----------------------------------------------- 5525// Pipeline Description specifies the stages in the machine's pipeline 5526 5527// Generic P2/P3 pipeline 5528pipe_desc(S0, S1, S2, S3, S4, S5); 5529 5530//----------PIPELINE CLASSES--------------------------------------------------- 5531// Pipeline Classes describe the stages in which input and output are 5532// referenced by the hardware pipeline. 5533 5534// Naming convention: ialu or fpu 5535// Then: _reg 5536// Then: _reg if there is a 2nd register 5537// Then: _long if it's a pair of instructions implementing a long 5538// Then: _fat if it requires the big decoder 5539// Or: _mem if it requires the big decoder and a memory unit. 5540 5541// Integer ALU reg operation 5542pipe_class ialu_reg(rRegI dst) 5543%{ 5544 single_instruction; 5545 dst : S4(write); 5546 dst : S3(read); 5547 DECODE : S0; // any decoder 5548 ALU : S3; // any alu 5549%} 5550 5551// Long ALU reg operation 5552pipe_class ialu_reg_long(rRegL dst) 5553%{ 5554 instruction_count(2); 5555 dst : S4(write); 5556 dst : S3(read); 5557 DECODE : S0(2); // any 2 decoders 5558 ALU : S3(2); // both alus 5559%} 5560 5561// Integer ALU reg operation using big decoder 5562pipe_class ialu_reg_fat(rRegI dst) 5563%{ 5564 single_instruction; 5565 dst : S4(write); 5566 dst : S3(read); 5567 D0 : S0; // big decoder only 5568 ALU : S3; // any alu 5569%} 5570 5571// Long ALU reg operation using big decoder 5572pipe_class ialu_reg_long_fat(rRegL dst) 5573%{ 5574 instruction_count(2); 5575 dst : S4(write); 5576 dst : S3(read); 5577 D0 : S0(2); // big decoder only; twice 5578 ALU : S3(2); // any 2 alus 5579%} 5580 5581// Integer ALU reg-reg operation 5582pipe_class ialu_reg_reg(rRegI dst, rRegI src) 5583%{ 5584 single_instruction; 5585 dst : S4(write); 5586 src : S3(read); 5587 DECODE : S0; // any decoder 5588 ALU : S3; // any alu 5589%} 5590 5591// Long ALU reg-reg operation 5592pipe_class ialu_reg_reg_long(rRegL dst, rRegL src) 5593%{ 5594 instruction_count(2); 5595 dst : S4(write); 5596 src : S3(read); 5597 DECODE : S0(2); // any 2 decoders 5598 ALU : S3(2); // both alus 5599%} 5600 5601// Integer ALU reg-reg operation 5602pipe_class ialu_reg_reg_fat(rRegI dst, memory src) 5603%{ 5604 single_instruction; 5605 dst : S4(write); 5606 src : S3(read); 5607 D0 : S0; // big decoder only 5608 ALU : S3; // any alu 5609%} 5610 5611// Long ALU reg-reg operation 5612pipe_class ialu_reg_reg_long_fat(rRegL dst, rRegL src) 5613%{ 5614 instruction_count(2); 5615 dst : S4(write); 5616 src : S3(read); 5617 D0 : S0(2); // big decoder only; twice 5618 ALU : S3(2); // both alus 5619%} 5620 5621// Integer ALU reg-mem operation 5622pipe_class ialu_reg_mem(rRegI dst, memory mem) 5623%{ 5624 single_instruction; 5625 dst : S5(write); 5626 mem : S3(read); 5627 D0 : S0; // big decoder only 5628 ALU : S4; // any alu 5629 MEM : S3; // any mem 5630%} 5631 5632// Integer mem operation (prefetch) 5633pipe_class ialu_mem(memory mem) 5634%{ 5635 single_instruction; 5636 mem : S3(read); 5637 D0 : S0; // big decoder only 5638 MEM : S3; // any mem 5639%} 5640 5641// Integer Store to Memory 5642pipe_class ialu_mem_reg(memory mem, rRegI src) 5643%{ 5644 single_instruction; 5645 mem : S3(read); 5646 src : S5(read); 5647 D0 : S0; // big decoder only 5648 ALU : S4; // any alu 5649 MEM : S3; 5650%} 5651 5652// // Long Store to Memory 5653// pipe_class ialu_mem_long_reg(memory mem, rRegL src) 5654// %{ 5655// instruction_count(2); 5656// mem : S3(read); 5657// src : S5(read); 5658// D0 : S0(2); // big decoder only; twice 5659// ALU : S4(2); // any 2 alus 5660// MEM : S3(2); // Both mems 5661// %} 5662 5663// Integer Store to Memory 5664pipe_class ialu_mem_imm(memory mem) 5665%{ 5666 single_instruction; 5667 mem : S3(read); 5668 D0 : S0; // big decoder only 5669 ALU : S4; // any alu 5670 MEM : S3; 5671%} 5672 5673// Integer ALU0 reg-reg operation 5674pipe_class ialu_reg_reg_alu0(rRegI dst, rRegI src) 5675%{ 5676 single_instruction; 5677 dst : S4(write); 5678 src : S3(read); 5679 D0 : S0; // Big decoder only 5680 ALU0 : S3; // only alu0 5681%} 5682 5683// Integer ALU0 reg-mem operation 5684pipe_class ialu_reg_mem_alu0(rRegI dst, memory mem) 5685%{ 5686 single_instruction; 5687 dst : S5(write); 5688 mem : S3(read); 5689 D0 : S0; // big decoder only 5690 ALU0 : S4; // ALU0 only 5691 MEM : S3; // any mem 5692%} 5693 5694// Integer ALU reg-reg operation 5695pipe_class ialu_cr_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2) 5696%{ 5697 single_instruction; 5698 cr : S4(write); 5699 src1 : S3(read); 5700 src2 : S3(read); 5701 DECODE : S0; // any decoder 5702 ALU : S3; // any alu 5703%} 5704 5705// Integer ALU reg-imm operation 5706pipe_class ialu_cr_reg_imm(rFlagsReg cr, rRegI src1) 5707%{ 5708 single_instruction; 5709 cr : S4(write); 5710 src1 : S3(read); 5711 DECODE : S0; // any decoder 5712 ALU : S3; // any alu 5713%} 5714 5715// Integer ALU reg-mem operation 5716pipe_class ialu_cr_reg_mem(rFlagsReg cr, rRegI src1, memory src2) 5717%{ 5718 single_instruction; 5719 cr : S4(write); 5720 src1 : S3(read); 5721 src2 : S3(read); 5722 D0 : S0; // big decoder only 5723 ALU : S4; // any alu 5724 MEM : S3; 5725%} 5726 5727// Conditional move reg-reg 5728pipe_class pipe_cmplt( rRegI p, rRegI q, rRegI y) 5729%{ 5730 instruction_count(4); 5731 y : S4(read); 5732 q : S3(read); 5733 p : S3(read); 5734 DECODE : S0(4); // any decoder 5735%} 5736 5737// Conditional move reg-reg 5738pipe_class pipe_cmov_reg( rRegI dst, rRegI src, rFlagsReg cr) 5739%{ 5740 single_instruction; 5741 dst : S4(write); 5742 src : S3(read); 5743 cr : S3(read); 5744 DECODE : S0; // any decoder 5745%} 5746 5747// Conditional move reg-mem 5748pipe_class pipe_cmov_mem( rFlagsReg cr, rRegI dst, memory src) 5749%{ 5750 single_instruction; 5751 dst : S4(write); 5752 src : S3(read); 5753 cr : S3(read); 5754 DECODE : S0; // any decoder 5755 MEM : S3; 5756%} 5757 5758// Conditional move reg-reg long 5759pipe_class pipe_cmov_reg_long( rFlagsReg cr, rRegL dst, rRegL src) 5760%{ 5761 single_instruction; 5762 dst : S4(write); 5763 src : S3(read); 5764 cr : S3(read); 5765 DECODE : S0(2); // any 2 decoders 5766%} 5767 5768// XXX 5769// // Conditional move double reg-reg 5770// pipe_class pipe_cmovD_reg( rFlagsReg cr, regDPR1 dst, regD src) 5771// %{ 5772// single_instruction; 5773// dst : S4(write); 5774// src : S3(read); 5775// cr : S3(read); 5776// DECODE : S0; // any decoder 5777// %} 5778 5779// Float reg-reg operation 5780pipe_class fpu_reg(regD dst) 5781%{ 5782 instruction_count(2); 5783 dst : S3(read); 5784 DECODE : S0(2); // any 2 decoders 5785 FPU : S3; 5786%} 5787 5788// Float reg-reg operation 5789pipe_class fpu_reg_reg(regD dst, regD src) 5790%{ 5791 instruction_count(2); 5792 dst : S4(write); 5793 src : S3(read); 5794 DECODE : S0(2); // any 2 decoders 5795 FPU : S3; 5796%} 5797 5798// Float reg-reg operation 5799pipe_class fpu_reg_reg_reg(regD dst, regD src1, regD src2) 5800%{ 5801 instruction_count(3); 5802 dst : S4(write); 5803 src1 : S3(read); 5804 src2 : S3(read); 5805 DECODE : S0(3); // any 3 decoders 5806 FPU : S3(2); 5807%} 5808 5809// Float reg-reg operation 5810pipe_class fpu_reg_reg_reg_reg(regD dst, regD src1, regD src2, regD src3) 5811%{ 5812 instruction_count(4); 5813 dst : S4(write); 5814 src1 : S3(read); 5815 src2 : S3(read); 5816 src3 : S3(read); 5817 DECODE : S0(4); // any 3 decoders 5818 FPU : S3(2); 5819%} 5820 5821// Float reg-reg operation 5822pipe_class fpu_reg_mem_reg_reg(regD dst, memory src1, regD src2, regD src3) 5823%{ 5824 instruction_count(4); 5825 dst : S4(write); 5826 src1 : S3(read); 5827 src2 : S3(read); 5828 src3 : S3(read); 5829 DECODE : S1(3); // any 3 decoders 5830 D0 : S0; // Big decoder only 5831 FPU : S3(2); 5832 MEM : S3; 5833%} 5834 5835// Float reg-mem operation 5836pipe_class fpu_reg_mem(regD dst, memory mem) 5837%{ 5838 instruction_count(2); 5839 dst : S5(write); 5840 mem : S3(read); 5841 D0 : S0; // big decoder only 5842 DECODE : S1; // any decoder for FPU POP 5843 FPU : S4; 5844 MEM : S3; // any mem 5845%} 5846 5847// Float reg-mem operation 5848pipe_class fpu_reg_reg_mem(regD dst, regD src1, memory mem) 5849%{ 5850 instruction_count(3); 5851 dst : S5(write); 5852 src1 : S3(read); 5853 mem : S3(read); 5854 D0 : S0; // big decoder only 5855 DECODE : S1(2); // any decoder for FPU POP 5856 FPU : S4; 5857 MEM : S3; // any mem 5858%} 5859 5860// Float mem-reg operation 5861pipe_class fpu_mem_reg(memory mem, regD src) 5862%{ 5863 instruction_count(2); 5864 src : S5(read); 5865 mem : S3(read); 5866 DECODE : S0; // any decoder for FPU PUSH 5867 D0 : S1; // big decoder only 5868 FPU : S4; 5869 MEM : S3; // any mem 5870%} 5871 5872pipe_class fpu_mem_reg_reg(memory mem, regD src1, regD src2) 5873%{ 5874 instruction_count(3); 5875 src1 : S3(read); 5876 src2 : S3(read); 5877 mem : S3(read); 5878 DECODE : S0(2); // any decoder for FPU PUSH 5879 D0 : S1; // big decoder only 5880 FPU : S4; 5881 MEM : S3; // any mem 5882%} 5883 5884pipe_class fpu_mem_reg_mem(memory mem, regD src1, memory src2) 5885%{ 5886 instruction_count(3); 5887 src1 : S3(read); 5888 src2 : S3(read); 5889 mem : S4(read); 5890 DECODE : S0; // any decoder for FPU PUSH 5891 D0 : S0(2); // big decoder only 5892 FPU : S4; 5893 MEM : S3(2); // any mem 5894%} 5895 5896pipe_class fpu_mem_mem(memory dst, memory src1) 5897%{ 5898 instruction_count(2); 5899 src1 : S3(read); 5900 dst : S4(read); 5901 D0 : S0(2); // big decoder only 5902 MEM : S3(2); // any mem 5903%} 5904 5905pipe_class fpu_mem_mem_mem(memory dst, memory src1, memory src2) 5906%{ 5907 instruction_count(3); 5908 src1 : S3(read); 5909 src2 : S3(read); 5910 dst : S4(read); 5911 D0 : S0(3); // big decoder only 5912 FPU : S4; 5913 MEM : S3(3); // any mem 5914%} 5915 5916pipe_class fpu_mem_reg_con(memory mem, regD src1) 5917%{ 5918 instruction_count(3); 5919 src1 : S4(read); 5920 mem : S4(read); 5921 DECODE : S0; // any decoder for FPU PUSH 5922 D0 : S0(2); // big decoder only 5923 FPU : S4; 5924 MEM : S3(2); // any mem 5925%} 5926 5927// Float load constant 5928pipe_class fpu_reg_con(regD dst) 5929%{ 5930 instruction_count(2); 5931 dst : S5(write); 5932 D0 : S0; // big decoder only for the load 5933 DECODE : S1; // any decoder for FPU POP 5934 FPU : S4; 5935 MEM : S3; // any mem 5936%} 5937 5938// Float load constant 5939pipe_class fpu_reg_reg_con(regD dst, regD src) 5940%{ 5941 instruction_count(3); 5942 dst : S5(write); 5943 src : S3(read); 5944 D0 : S0; // big decoder only for the load 5945 DECODE : S1(2); // any decoder for FPU POP 5946 FPU : S4; 5947 MEM : S3; // any mem 5948%} 5949 5950// UnConditional branch 5951pipe_class pipe_jmp(label labl) 5952%{ 5953 single_instruction; 5954 BR : S3; 5955%} 5956 5957// Conditional branch 5958pipe_class pipe_jcc(cmpOp cmp, rFlagsReg cr, label labl) 5959%{ 5960 single_instruction; 5961 cr : S1(read); 5962 BR : S3; 5963%} 5964 5965// Allocation idiom 5966pipe_class pipe_cmpxchg(rRegP dst, rRegP heap_ptr) 5967%{ 5968 instruction_count(1); force_serialization; 5969 fixed_latency(6); 5970 heap_ptr : S3(read); 5971 DECODE : S0(3); 5972 D0 : S2; 5973 MEM : S3; 5974 ALU : S3(2); 5975 dst : S5(write); 5976 BR : S5; 5977%} 5978 5979// Generic big/slow expanded idiom 5980pipe_class pipe_slow() 5981%{ 5982 instruction_count(10); multiple_bundles; force_serialization; 5983 fixed_latency(100); 5984 D0 : S0(2); 5985 MEM : S3(2); 5986%} 5987 5988// The real do-nothing guy 5989pipe_class empty() 5990%{ 5991 instruction_count(0); 5992%} 5993 5994// Define the class for the Nop node 5995define 5996%{ 5997 MachNop = empty; 5998%} 5999 6000%} 6001 6002//----------INSTRUCTIONS------------------------------------------------------- 6003// 6004// match -- States which machine-independent subtree may be replaced 6005// by this instruction. 6006// ins_cost -- The estimated cost of this instruction is used by instruction 6007// selection to identify a minimum cost tree of machine 6008// instructions that matches a tree of machine-independent 6009// instructions. 6010// format -- A string providing the disassembly for this instruction. 6011// The value of an instruction's operand may be inserted 6012// by referring to it with a '$' prefix. 6013// opcode -- Three instruction opcodes may be provided. These are referred 6014// to within an encode class as $primary, $secondary, and $tertiary 6015// rrspectively. The primary opcode is commonly used to 6016// indicate the type of machine instruction, while secondary 6017// and tertiary are often used for prefix options or addressing 6018// modes. 6019// ins_encode -- A list of encode classes with parameters. The encode class 6020// name must have been defined in an 'enc_class' specification 6021// in the encode section of the architecture description. 6022 6023 6024//----------Load/Store/Move Instructions--------------------------------------- 6025//----------Load Instructions-------------------------------------------------- 6026 6027// Load Byte (8 bit signed) 6028instruct loadB(rRegI dst, memory mem) 6029%{ 6030 match(Set dst (LoadB mem)); 6031 6032 ins_cost(125); 6033 format %{ "movsbl $dst, $mem\t# byte" %} 6034 opcode(0x0F, 0xBE); 6035 ins_encode(REX_reg_mem(dst, mem), OpcP, OpcS, reg_mem(dst, mem)); 6036 ins_pipe(ialu_reg_mem); 6037%} 6038 6039// Load Byte (8 bit signed) into long 6040// instruct loadB2L(rRegL dst, memory mem) 6041// %{ 6042// match(Set dst (ConvI2L (LoadB mem))); 6043 6044// ins_cost(125); 6045// format %{ "movsbq $dst, $mem\t# byte -> long" %} 6046// opcode(0x0F, 0xBE); 6047// ins_encode(REX_reg_mem_wide(dst, mem), OpcP, OpcS, reg_mem(dst, mem)); 6048// ins_pipe(ialu_reg_mem); 6049// %} 6050 6051// Load Byte (8 bit UNsigned) 6052instruct loadUB(rRegI dst, memory mem, immI_255 bytemask) 6053%{ 6054 match(Set dst (AndI (LoadB mem) bytemask)); 6055 6056 ins_cost(125); 6057 format %{ "movzbl $dst, $mem\t# ubyte" %} 6058 opcode(0x0F, 0xB6); 6059 ins_encode(REX_reg_mem(dst, mem), OpcP, OpcS, reg_mem(dst, mem)); 6060 ins_pipe(ialu_reg_mem); 6061%} 6062 6063// Load Byte (8 bit UNsigned) into long 6064// instruct loadUB2L(rRegL dst, memory mem, immI_255 bytemask) 6065// %{ 6066// match(Set dst (ConvI2L (AndI (LoadB mem) bytemask))); 6067 6068// ins_cost(125); 6069// format %{ "movzbl $dst, $mem\t# ubyte -> long" %} 6070// opcode(0x0F, 0xB6); 6071// ins_encode(REX_reg_mem(dst, mem), OpcP, OpcS, reg_mem(dst, mem)); 6072// ins_pipe(ialu_reg_mem); 6073// %} 6074 6075// Load Short (16 bit signed) 6076instruct loadS(rRegI dst, memory mem) 6077%{ 6078 match(Set dst (LoadS mem)); 6079 6080 ins_cost(125); // XXX 6081 format %{ "movswl $dst, $mem\t# short" %} 6082 opcode(0x0F, 0xBF); 6083 ins_encode(REX_reg_mem(dst, mem), OpcP, OpcS, reg_mem(dst, mem)); 6084 ins_pipe(ialu_reg_mem); 6085%} 6086 6087// Load Short (16 bit signed) into long 6088// instruct loadS2L(rRegL dst, memory mem) 6089// %{ 6090// match(Set dst (ConvI2L (LoadS mem))); 6091 6092// ins_cost(125); // XXX 6093// format %{ "movswq $dst, $mem\t# short -> long" %} 6094// opcode(0x0F, 0xBF); 6095// ins_encode(REX_reg_mem_wide(dst, mem), OpcP, OpcS, reg_mem(dst, mem)); 6096// ins_pipe(ialu_reg_mem); 6097// %} 6098 6099// Load Unsigned Short/Char (16 bit UNsigned) 6100instruct loadUS(rRegI dst, memory mem) 6101%{ 6102 match(Set dst (LoadUS mem)); 6103 6104 ins_cost(125); 6105 format %{ "movzwl $dst, $mem\t# ushort/char" %} 6106 opcode(0x0F, 0xB7); 6107 ins_encode(REX_reg_mem(dst, mem), OpcP, OpcS, reg_mem(dst, mem)); 6108 ins_pipe(ialu_reg_mem); 6109%} 6110 6111// Load Unsigned Short/Char (16 bit UNsigned) into long 6112// instruct loadUS2L(rRegL dst, memory mem) 6113// %{ 6114// match(Set dst (ConvI2L (LoadUS mem))); 6115 6116// ins_cost(125); 6117// format %{ "movzwl $dst, $mem\t# ushort/char -> long" %} 6118// opcode(0x0F, 0xB7); 6119// ins_encode(REX_reg_mem(dst, mem), OpcP, OpcS, reg_mem(dst, mem)); 6120// ins_pipe(ialu_reg_mem); 6121// %} 6122 6123// Load Integer 6124instruct loadI(rRegI dst, memory mem) 6125%{ 6126 match(Set dst (LoadI mem)); 6127 6128 ins_cost(125); // XXX 6129 format %{ "movl $dst, $mem\t# int" %} 6130 opcode(0x8B); 6131 ins_encode(REX_reg_mem(dst, mem), OpcP, reg_mem(dst, mem)); 6132 ins_pipe(ialu_reg_mem); 6133%} 6134 6135// Load Long 6136instruct loadL(rRegL dst, memory mem) 6137%{ 6138 match(Set dst (LoadL mem)); 6139 6140 ins_cost(125); // XXX 6141 format %{ "movq $dst, $mem\t# long" %} 6142 opcode(0x8B); 6143 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 6144 ins_pipe(ialu_reg_mem); // XXX 6145%} 6146 6147// Load Range 6148instruct loadRange(rRegI dst, memory mem) 6149%{ 6150 match(Set dst (LoadRange mem)); 6151 6152 ins_cost(125); // XXX 6153 format %{ "movl $dst, $mem\t# range" %} 6154 opcode(0x8B); 6155 ins_encode(REX_reg_mem(dst, mem), OpcP, reg_mem(dst, mem)); 6156 ins_pipe(ialu_reg_mem); 6157%} 6158 6159// Load Pointer 6160instruct loadP(rRegP dst, memory mem) 6161%{ 6162 match(Set dst (LoadP mem)); 6163 6164 ins_cost(125); // XXX 6165 format %{ "movq $dst, $mem\t# ptr" %} 6166 opcode(0x8B); 6167 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 6168 ins_pipe(ialu_reg_mem); // XXX 6169%} 6170 6171// Load Compressed Pointer 6172instruct loadN(rRegN dst, memory mem) 6173%{ 6174 match(Set dst (LoadN mem)); 6175 6176 ins_cost(125); // XXX 6177 format %{ "movl $dst, $mem\t# compressed ptr" %} 6178 ins_encode %{ 6179 Address addr = build_address($mem$$base, $mem$$index, $mem$$scale, $mem$$disp); 6180 Register dst = as_Register($dst$$reg); 6181 __ movl(dst, addr); 6182 %} 6183 ins_pipe(ialu_reg_mem); // XXX 6184%} 6185 6186 6187// Load Klass Pointer 6188instruct loadKlass(rRegP dst, memory mem) 6189%{ 6190 match(Set dst (LoadKlass mem)); 6191 6192 ins_cost(125); // XXX 6193 format %{ "movq $dst, $mem\t# class" %} 6194 opcode(0x8B); 6195 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 6196 ins_pipe(ialu_reg_mem); // XXX 6197%} 6198 6199// Load narrow Klass Pointer 6200instruct loadNKlass(rRegN dst, memory mem) 6201%{ 6202 match(Set dst (LoadNKlass mem)); 6203 6204 ins_cost(125); // XXX 6205 format %{ "movl $dst, $mem\t# compressed klass ptr" %} 6206 ins_encode %{ 6207 Address addr = build_address($mem$$base, $mem$$index, $mem$$scale, $mem$$disp); 6208 Register dst = as_Register($dst$$reg); 6209 __ movl(dst, addr); 6210 %} 6211 ins_pipe(ialu_reg_mem); // XXX 6212%} 6213 6214// Load Float 6215instruct loadF(regF dst, memory mem) 6216%{ 6217 match(Set dst (LoadF mem)); 6218 6219 ins_cost(145); // XXX 6220 format %{ "movss $dst, $mem\t# float" %} 6221 opcode(0xF3, 0x0F, 0x10); 6222 ins_encode(OpcP, REX_reg_mem(dst, mem), OpcS, OpcT, reg_mem(dst, mem)); 6223 ins_pipe(pipe_slow); // XXX 6224%} 6225 6226// Load Double 6227instruct loadD_partial(regD dst, memory mem) 6228%{ 6229 predicate(!UseXmmLoadAndClearUpper); 6230 match(Set dst (LoadD mem)); 6231 6232 ins_cost(145); // XXX 6233 format %{ "movlpd $dst, $mem\t# double" %} 6234 opcode(0x66, 0x0F, 0x12); 6235 ins_encode(OpcP, REX_reg_mem(dst, mem), OpcS, OpcT, reg_mem(dst, mem)); 6236 ins_pipe(pipe_slow); // XXX 6237%} 6238 6239instruct loadD(regD dst, memory mem) 6240%{ 6241 predicate(UseXmmLoadAndClearUpper); 6242 match(Set dst (LoadD mem)); 6243 6244 ins_cost(145); // XXX 6245 format %{ "movsd $dst, $mem\t# double" %} 6246 opcode(0xF2, 0x0F, 0x10); 6247 ins_encode(OpcP, REX_reg_mem(dst, mem), OpcS, OpcT, reg_mem(dst, mem)); 6248 ins_pipe(pipe_slow); // XXX 6249%} 6250 6251// Load Aligned Packed Byte to XMM register 6252instruct loadA8B(regD dst, memory mem) %{ 6253 match(Set dst (Load8B mem)); 6254 ins_cost(125); 6255 format %{ "MOVQ $dst,$mem\t! packed8B" %} 6256 ins_encode( movq_ld(dst, mem)); 6257 ins_pipe( pipe_slow ); 6258%} 6259 6260// Load Aligned Packed Short to XMM register 6261instruct loadA4S(regD dst, memory mem) %{ 6262 match(Set dst (Load4S mem)); 6263 ins_cost(125); 6264 format %{ "MOVQ $dst,$mem\t! packed4S" %} 6265 ins_encode( movq_ld(dst, mem)); 6266 ins_pipe( pipe_slow ); 6267%} 6268 6269// Load Aligned Packed Char to XMM register 6270instruct loadA4C(regD dst, memory mem) %{ 6271 match(Set dst (Load4C mem)); 6272 ins_cost(125); 6273 format %{ "MOVQ $dst,$mem\t! packed4C" %} 6274 ins_encode( movq_ld(dst, mem)); 6275 ins_pipe( pipe_slow ); 6276%} 6277 6278// Load Aligned Packed Integer to XMM register 6279instruct load2IU(regD dst, memory mem) %{ 6280 match(Set dst (Load2I mem)); 6281 ins_cost(125); 6282 format %{ "MOVQ $dst,$mem\t! packed2I" %} 6283 ins_encode( movq_ld(dst, mem)); 6284 ins_pipe( pipe_slow ); 6285%} 6286 6287// Load Aligned Packed Single to XMM 6288instruct loadA2F(regD dst, memory mem) %{ 6289 match(Set dst (Load2F mem)); 6290 ins_cost(145); 6291 format %{ "MOVQ $dst,$mem\t! packed2F" %} 6292 ins_encode( movq_ld(dst, mem)); 6293 ins_pipe( pipe_slow ); 6294%} 6295 6296// Load Effective Address 6297instruct leaP8(rRegP dst, indOffset8 mem) 6298%{ 6299 match(Set dst mem); 6300 6301 ins_cost(110); // XXX 6302 format %{ "leaq $dst, $mem\t# ptr 8" %} 6303 opcode(0x8D); 6304 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 6305 ins_pipe(ialu_reg_reg_fat); 6306%} 6307 6308instruct leaP32(rRegP dst, indOffset32 mem) 6309%{ 6310 match(Set dst mem); 6311 6312 ins_cost(110); 6313 format %{ "leaq $dst, $mem\t# ptr 32" %} 6314 opcode(0x8D); 6315 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 6316 ins_pipe(ialu_reg_reg_fat); 6317%} 6318 6319// instruct leaPIdx(rRegP dst, indIndex mem) 6320// %{ 6321// match(Set dst mem); 6322 6323// ins_cost(110); 6324// format %{ "leaq $dst, $mem\t# ptr idx" %} 6325// opcode(0x8D); 6326// ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 6327// ins_pipe(ialu_reg_reg_fat); 6328// %} 6329 6330instruct leaPIdxOff(rRegP dst, indIndexOffset mem) 6331%{ 6332 match(Set dst mem); 6333 6334 ins_cost(110); 6335 format %{ "leaq $dst, $mem\t# ptr idxoff" %} 6336 opcode(0x8D); 6337 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 6338 ins_pipe(ialu_reg_reg_fat); 6339%} 6340 6341instruct leaPIdxScale(rRegP dst, indIndexScale mem) 6342%{ 6343 match(Set dst mem); 6344 6345 ins_cost(110); 6346 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 6347 opcode(0x8D); 6348 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 6349 ins_pipe(ialu_reg_reg_fat); 6350%} 6351 6352instruct leaPIdxScaleOff(rRegP dst, indIndexScaleOffset mem) 6353%{ 6354 match(Set dst mem); 6355 6356 ins_cost(110); 6357 format %{ "leaq $dst, $mem\t# ptr idxscaleoff" %} 6358 opcode(0x8D); 6359 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 6360 ins_pipe(ialu_reg_reg_fat); 6361%} 6362 6363instruct loadConI(rRegI dst, immI src) 6364%{ 6365 match(Set dst src); 6366 6367 format %{ "movl $dst, $src\t# int" %} 6368 ins_encode(load_immI(dst, src)); 6369 ins_pipe(ialu_reg_fat); // XXX 6370%} 6371 6372instruct loadConI0(rRegI dst, immI0 src, rFlagsReg cr) 6373%{ 6374 match(Set dst src); 6375 effect(KILL cr); 6376 6377 ins_cost(50); 6378 format %{ "xorl $dst, $dst\t# int" %} 6379 opcode(0x33); /* + rd */ 6380 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 6381 ins_pipe(ialu_reg); 6382%} 6383 6384instruct loadConL(rRegL dst, immL src) 6385%{ 6386 match(Set dst src); 6387 6388 ins_cost(150); 6389 format %{ "movq $dst, $src\t# long" %} 6390 ins_encode(load_immL(dst, src)); 6391 ins_pipe(ialu_reg); 6392%} 6393 6394instruct loadConL0(rRegL dst, immL0 src, rFlagsReg cr) 6395%{ 6396 match(Set dst src); 6397 effect(KILL cr); 6398 6399 ins_cost(50); 6400 format %{ "xorl $dst, $dst\t# long" %} 6401 opcode(0x33); /* + rd */ 6402 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 6403 ins_pipe(ialu_reg); // XXX 6404%} 6405 6406instruct loadConUL32(rRegL dst, immUL32 src) 6407%{ 6408 match(Set dst src); 6409 6410 ins_cost(60); 6411 format %{ "movl $dst, $src\t# long (unsigned 32-bit)" %} 6412 ins_encode(load_immUL32(dst, src)); 6413 ins_pipe(ialu_reg); 6414%} 6415 6416instruct loadConL32(rRegL dst, immL32 src) 6417%{ 6418 match(Set dst src); 6419 6420 ins_cost(70); 6421 format %{ "movq $dst, $src\t# long (32-bit)" %} 6422 ins_encode(load_immL32(dst, src)); 6423 ins_pipe(ialu_reg); 6424%} 6425 6426instruct loadConP(rRegP dst, immP src) 6427%{ 6428 match(Set dst src); 6429 6430 format %{ "movq $dst, $src\t# ptr" %} 6431 ins_encode(load_immP(dst, src)); 6432 ins_pipe(ialu_reg_fat); // XXX 6433%} 6434 6435instruct loadConP0(rRegP dst, immP0 src, rFlagsReg cr) 6436%{ 6437 match(Set dst src); 6438 effect(KILL cr); 6439 6440 ins_cost(50); 6441 format %{ "xorl $dst, $dst\t# ptr" %} 6442 opcode(0x33); /* + rd */ 6443 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 6444 ins_pipe(ialu_reg); 6445%} 6446 6447instruct loadConP31(rRegP dst, immP31 src, rFlagsReg cr) 6448%{ 6449 match(Set dst src); 6450 effect(KILL cr); 6451 6452 ins_cost(60); 6453 format %{ "movl $dst, $src\t# ptr (positive 32-bit)" %} 6454 ins_encode(load_immP31(dst, src)); 6455 ins_pipe(ialu_reg); 6456%} 6457 6458instruct loadConF(regF dst, immF src) 6459%{ 6460 match(Set dst src); 6461 ins_cost(125); 6462 6463 format %{ "movss $dst, [$src]" %} 6464 ins_encode(load_conF(dst, src)); 6465 ins_pipe(pipe_slow); 6466%} 6467 6468instruct loadConN0(rRegN dst, immN0 src, rFlagsReg cr) %{ 6469 match(Set dst src); 6470 effect(KILL cr); 6471 format %{ "xorq $dst, $src\t# compressed NULL ptr" %} 6472 ins_encode %{ 6473 Register dst = $dst$$Register; 6474 __ xorq(dst, dst); 6475 %} 6476 ins_pipe(ialu_reg); 6477%} 6478 6479instruct loadConN(rRegN dst, immN src) %{ 6480 match(Set dst src); 6481 6482 ins_cost(125); 6483 format %{ "movl $dst, $src\t# compressed ptr" %} 6484 ins_encode %{ 6485 address con = (address)$src$$constant; 6486 Register dst = $dst$$Register; 6487 if (con == NULL) { 6488 ShouldNotReachHere(); 6489 } else { 6490 __ set_narrow_oop(dst, (jobject)$src$$constant); 6491 } 6492 %} 6493 ins_pipe(ialu_reg_fat); // XXX 6494%} 6495 6496instruct loadConF0(regF dst, immF0 src) 6497%{ 6498 match(Set dst src); 6499 ins_cost(100); 6500 6501 format %{ "xorps $dst, $dst\t# float 0.0" %} 6502 opcode(0x0F, 0x57); 6503 ins_encode(REX_reg_reg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 6504 ins_pipe(pipe_slow); 6505%} 6506 6507// Use the same format since predicate() can not be used here. 6508instruct loadConD(regD dst, immD src) 6509%{ 6510 match(Set dst src); 6511 ins_cost(125); 6512 6513 format %{ "movsd $dst, [$src]" %} 6514 ins_encode(load_conD(dst, src)); 6515 ins_pipe(pipe_slow); 6516%} 6517 6518instruct loadConD0(regD dst, immD0 src) 6519%{ 6520 match(Set dst src); 6521 ins_cost(100); 6522 6523 format %{ "xorpd $dst, $dst\t# double 0.0" %} 6524 opcode(0x66, 0x0F, 0x57); 6525 ins_encode(OpcP, REX_reg_reg(dst, dst), OpcS, OpcT, reg_reg(dst, dst)); 6526 ins_pipe(pipe_slow); 6527%} 6528 6529instruct loadSSI(rRegI dst, stackSlotI src) 6530%{ 6531 match(Set dst src); 6532 6533 ins_cost(125); 6534 format %{ "movl $dst, $src\t# int stk" %} 6535 opcode(0x8B); 6536 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 6537 ins_pipe(ialu_reg_mem); 6538%} 6539 6540instruct loadSSL(rRegL dst, stackSlotL src) 6541%{ 6542 match(Set dst src); 6543 6544 ins_cost(125); 6545 format %{ "movq $dst, $src\t# long stk" %} 6546 opcode(0x8B); 6547 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 6548 ins_pipe(ialu_reg_mem); 6549%} 6550 6551instruct loadSSP(rRegP dst, stackSlotP src) 6552%{ 6553 match(Set dst src); 6554 6555 ins_cost(125); 6556 format %{ "movq $dst, $src\t# ptr stk" %} 6557 opcode(0x8B); 6558 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 6559 ins_pipe(ialu_reg_mem); 6560%} 6561 6562instruct loadSSF(regF dst, stackSlotF src) 6563%{ 6564 match(Set dst src); 6565 6566 ins_cost(125); 6567 format %{ "movss $dst, $src\t# float stk" %} 6568 opcode(0xF3, 0x0F, 0x10); 6569 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 6570 ins_pipe(pipe_slow); // XXX 6571%} 6572 6573// Use the same format since predicate() can not be used here. 6574instruct loadSSD(regD dst, stackSlotD src) 6575%{ 6576 match(Set dst src); 6577 6578 ins_cost(125); 6579 format %{ "movsd $dst, $src\t# double stk" %} 6580 ins_encode %{ 6581 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 6582 %} 6583 ins_pipe(pipe_slow); // XXX 6584%} 6585 6586// Prefetch instructions. 6587// Must be safe to execute with invalid address (cannot fault). 6588 6589instruct prefetchr( memory mem ) %{ 6590 predicate(ReadPrefetchInstr==3); 6591 match(PrefetchRead mem); 6592 ins_cost(125); 6593 6594 format %{ "PREFETCHR $mem\t# Prefetch into level 1 cache" %} 6595 opcode(0x0F, 0x0D); /* Opcode 0F 0D /0 */ 6596 ins_encode(REX_mem(mem), OpcP, OpcS, RM_opc_mem(0x00, mem)); 6597 ins_pipe(ialu_mem); 6598%} 6599 6600instruct prefetchrNTA( memory mem ) %{ 6601 predicate(ReadPrefetchInstr==0); 6602 match(PrefetchRead mem); 6603 ins_cost(125); 6604 6605 format %{ "PREFETCHNTA $mem\t# Prefetch into non-temporal cache for read" %} 6606 opcode(0x0F, 0x18); /* Opcode 0F 18 /0 */ 6607 ins_encode(REX_mem(mem), OpcP, OpcS, RM_opc_mem(0x00, mem)); 6608 ins_pipe(ialu_mem); 6609%} 6610 6611instruct prefetchrT0( memory mem ) %{ 6612 predicate(ReadPrefetchInstr==1); 6613 match(PrefetchRead mem); 6614 ins_cost(125); 6615 6616 format %{ "PREFETCHT0 $mem\t# prefetch into L1 and L2 caches for read" %} 6617 opcode(0x0F, 0x18); /* Opcode 0F 18 /1 */ 6618 ins_encode(REX_mem(mem), OpcP, OpcS, RM_opc_mem(0x01, mem)); 6619 ins_pipe(ialu_mem); 6620%} 6621 6622instruct prefetchrT2( memory mem ) %{ 6623 predicate(ReadPrefetchInstr==2); 6624 match(PrefetchRead mem); 6625 ins_cost(125); 6626 6627 format %{ "PREFETCHT2 $mem\t# prefetch into L2 caches for read" %} 6628 opcode(0x0F, 0x18); /* Opcode 0F 18 /3 */ 6629 ins_encode(REX_mem(mem), OpcP, OpcS, RM_opc_mem(0x03, mem)); 6630 ins_pipe(ialu_mem); 6631%} 6632 6633instruct prefetchw( memory mem ) %{ 6634 predicate(AllocatePrefetchInstr==3); 6635 match(PrefetchWrite mem); 6636 ins_cost(125); 6637 6638 format %{ "PREFETCHW $mem\t# Prefetch into level 1 cache and mark modified" %} 6639 opcode(0x0F, 0x0D); /* Opcode 0F 0D /1 */ 6640 ins_encode(REX_mem(mem), OpcP, OpcS, RM_opc_mem(0x01, mem)); 6641 ins_pipe(ialu_mem); 6642%} 6643 6644instruct prefetchwNTA( memory mem ) %{ 6645 predicate(AllocatePrefetchInstr==0); 6646 match(PrefetchWrite mem); 6647 ins_cost(125); 6648 6649 format %{ "PREFETCHNTA $mem\t# Prefetch to non-temporal cache for write" %} 6650 opcode(0x0F, 0x18); /* Opcode 0F 18 /0 */ 6651 ins_encode(REX_mem(mem), OpcP, OpcS, RM_opc_mem(0x00, mem)); 6652 ins_pipe(ialu_mem); 6653%} 6654 6655instruct prefetchwT0( memory mem ) %{ 6656 predicate(AllocatePrefetchInstr==1); 6657 match(PrefetchWrite mem); 6658 ins_cost(125); 6659 6660 format %{ "PREFETCHT0 $mem\t# Prefetch to level 1 and 2 caches for write" %} 6661 opcode(0x0F, 0x18); /* Opcode 0F 18 /1 */ 6662 ins_encode(REX_mem(mem), OpcP, OpcS, RM_opc_mem(0x01, mem)); 6663 ins_pipe(ialu_mem); 6664%} 6665 6666instruct prefetchwT2( memory mem ) %{ 6667 predicate(AllocatePrefetchInstr==2); 6668 match(PrefetchWrite mem); 6669 ins_cost(125); 6670 6671 format %{ "PREFETCHT2 $mem\t# Prefetch to level 2 cache for write" %} 6672 opcode(0x0F, 0x18); /* Opcode 0F 18 /3 */ 6673 ins_encode(REX_mem(mem), OpcP, OpcS, RM_opc_mem(0x03, mem)); 6674 ins_pipe(ialu_mem); 6675%} 6676 6677//----------Store Instructions------------------------------------------------- 6678 6679// Store Byte 6680instruct storeB(memory mem, rRegI src) 6681%{ 6682 match(Set mem (StoreB mem src)); 6683 6684 ins_cost(125); // XXX 6685 format %{ "movb $mem, $src\t# byte" %} 6686 opcode(0x88); 6687 ins_encode(REX_breg_mem(src, mem), OpcP, reg_mem(src, mem)); 6688 ins_pipe(ialu_mem_reg); 6689%} 6690 6691// Store Char/Short 6692instruct storeC(memory mem, rRegI src) 6693%{ 6694 match(Set mem (StoreC mem src)); 6695 6696 ins_cost(125); // XXX 6697 format %{ "movw $mem, $src\t# char/short" %} 6698 opcode(0x89); 6699 ins_encode(SizePrefix, REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 6700 ins_pipe(ialu_mem_reg); 6701%} 6702 6703// Store Integer 6704instruct storeI(memory mem, rRegI src) 6705%{ 6706 match(Set mem (StoreI mem src)); 6707 6708 ins_cost(125); // XXX 6709 format %{ "movl $mem, $src\t# int" %} 6710 opcode(0x89); 6711 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 6712 ins_pipe(ialu_mem_reg); 6713%} 6714 6715// Store Long 6716instruct storeL(memory mem, rRegL src) 6717%{ 6718 match(Set mem (StoreL mem src)); 6719 6720 ins_cost(125); // XXX 6721 format %{ "movq $mem, $src\t# long" %} 6722 opcode(0x89); 6723 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 6724 ins_pipe(ialu_mem_reg); // XXX 6725%} 6726 6727// Store Pointer 6728instruct storeP(memory mem, any_RegP src) 6729%{ 6730 match(Set mem (StoreP mem src)); 6731 6732 ins_cost(125); // XXX 6733 format %{ "movq $mem, $src\t# ptr" %} 6734 opcode(0x89); 6735 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 6736 ins_pipe(ialu_mem_reg); 6737%} 6738 6739// Store NULL Pointer, mark word, or other simple pointer constant. 6740instruct storeImmP(memory mem, immP31 src) 6741%{ 6742 match(Set mem (StoreP mem src)); 6743 6744 ins_cost(125); // XXX 6745 format %{ "movq $mem, $src\t# ptr" %} 6746 opcode(0xC7); /* C7 /0 */ 6747 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 6748 ins_pipe(ialu_mem_imm); 6749%} 6750 6751// Store Compressed Pointer 6752instruct storeN(memory mem, rRegN src) 6753%{ 6754 match(Set mem (StoreN mem src)); 6755 6756 ins_cost(125); // XXX 6757 format %{ "movl $mem, $src\t# compressed ptr" %} 6758 ins_encode %{ 6759 Address addr = build_address($mem$$base, $mem$$index, $mem$$scale, $mem$$disp); 6760 Register src = as_Register($src$$reg); 6761 __ movl(addr, src); 6762 %} 6763 ins_pipe(ialu_mem_reg); 6764%} 6765 6766// Store Integer Immediate 6767instruct storeImmI(memory mem, immI src) 6768%{ 6769 match(Set mem (StoreI mem src)); 6770 6771 ins_cost(150); 6772 format %{ "movl $mem, $src\t# int" %} 6773 opcode(0xC7); /* C7 /0 */ 6774 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 6775 ins_pipe(ialu_mem_imm); 6776%} 6777 6778// Store Long Immediate 6779instruct storeImmL(memory mem, immL32 src) 6780%{ 6781 match(Set mem (StoreL mem src)); 6782 6783 ins_cost(150); 6784 format %{ "movq $mem, $src\t# long" %} 6785 opcode(0xC7); /* C7 /0 */ 6786 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 6787 ins_pipe(ialu_mem_imm); 6788%} 6789 6790// Store Short/Char Immediate 6791instruct storeImmI16(memory mem, immI16 src) 6792%{ 6793 predicate(UseStoreImmI16); 6794 match(Set mem (StoreC mem src)); 6795 6796 ins_cost(150); 6797 format %{ "movw $mem, $src\t# short/char" %} 6798 opcode(0xC7); /* C7 /0 Same as 32 store immediate with prefix */ 6799 ins_encode(SizePrefix, REX_mem(mem), OpcP, RM_opc_mem(0x00, mem),Con16(src)); 6800 ins_pipe(ialu_mem_imm); 6801%} 6802 6803// Store Byte Immediate 6804instruct storeImmB(memory mem, immI8 src) 6805%{ 6806 match(Set mem (StoreB mem src)); 6807 6808 ins_cost(150); // XXX 6809 format %{ "movb $mem, $src\t# byte" %} 6810 opcode(0xC6); /* C6 /0 */ 6811 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src)); 6812 ins_pipe(ialu_mem_imm); 6813%} 6814 6815// Store Aligned Packed Byte XMM register to memory 6816instruct storeA8B(memory mem, regD src) %{ 6817 match(Set mem (Store8B mem src)); 6818 ins_cost(145); 6819 format %{ "MOVQ $mem,$src\t! packed8B" %} 6820 ins_encode( movq_st(mem, src)); 6821 ins_pipe( pipe_slow ); 6822%} 6823 6824// Store Aligned Packed Char/Short XMM register to memory 6825instruct storeA4C(memory mem, regD src) %{ 6826 match(Set mem (Store4C mem src)); 6827 ins_cost(145); 6828 format %{ "MOVQ $mem,$src\t! packed4C" %} 6829 ins_encode( movq_st(mem, src)); 6830 ins_pipe( pipe_slow ); 6831%} 6832 6833// Store Aligned Packed Integer XMM register to memory 6834instruct storeA2I(memory mem, regD src) %{ 6835 match(Set mem (Store2I mem src)); 6836 ins_cost(145); 6837 format %{ "MOVQ $mem,$src\t! packed2I" %} 6838 ins_encode( movq_st(mem, src)); 6839 ins_pipe( pipe_slow ); 6840%} 6841 6842// Store CMS card-mark Immediate 6843instruct storeImmCM0(memory mem, immI0 src) 6844%{ 6845 match(Set mem (StoreCM mem src)); 6846 6847 ins_cost(150); // XXX 6848 format %{ "movb $mem, $src\t# CMS card-mark byte 0" %} 6849 opcode(0xC6); /* C6 /0 */ 6850 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src)); 6851 ins_pipe(ialu_mem_imm); 6852%} 6853 6854// Store Aligned Packed Single Float XMM register to memory 6855instruct storeA2F(memory mem, regD src) %{ 6856 match(Set mem (Store2F mem src)); 6857 ins_cost(145); 6858 format %{ "MOVQ $mem,$src\t! packed2F" %} 6859 ins_encode( movq_st(mem, src)); 6860 ins_pipe( pipe_slow ); 6861%} 6862 6863// Store Float 6864instruct storeF(memory mem, regF src) 6865%{ 6866 match(Set mem (StoreF mem src)); 6867 6868 ins_cost(95); // XXX 6869 format %{ "movss $mem, $src\t# float" %} 6870 opcode(0xF3, 0x0F, 0x11); 6871 ins_encode(OpcP, REX_reg_mem(src, mem), OpcS, OpcT, reg_mem(src, mem)); 6872 ins_pipe(pipe_slow); // XXX 6873%} 6874 6875// Store immediate Float value (it is faster than store from XMM register) 6876instruct storeF_imm(memory mem, immF src) 6877%{ 6878 match(Set mem (StoreF mem src)); 6879 6880 ins_cost(50); 6881 format %{ "movl $mem, $src\t# float" %} 6882 opcode(0xC7); /* C7 /0 */ 6883 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src)); 6884 ins_pipe(ialu_mem_imm); 6885%} 6886 6887// Store Double 6888instruct storeD(memory mem, regD src) 6889%{ 6890 match(Set mem (StoreD mem src)); 6891 6892 ins_cost(95); // XXX 6893 format %{ "movsd $mem, $src\t# double" %} 6894 opcode(0xF2, 0x0F, 0x11); 6895 ins_encode(OpcP, REX_reg_mem(src, mem), OpcS, OpcT, reg_mem(src, mem)); 6896 ins_pipe(pipe_slow); // XXX 6897%} 6898 6899// Store immediate double 0.0 (it is faster than store from XMM register) 6900instruct storeD0_imm(memory mem, immD0 src) 6901%{ 6902 match(Set mem (StoreD mem src)); 6903 6904 ins_cost(50); 6905 format %{ "movq $mem, $src\t# double 0." %} 6906 opcode(0xC7); /* C7 /0 */ 6907 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src)); 6908 ins_pipe(ialu_mem_imm); 6909%} 6910 6911instruct storeSSI(stackSlotI dst, rRegI src) 6912%{ 6913 match(Set dst src); 6914 6915 ins_cost(100); 6916 format %{ "movl $dst, $src\t# int stk" %} 6917 opcode(0x89); 6918 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 6919 ins_pipe( ialu_mem_reg ); 6920%} 6921 6922instruct storeSSL(stackSlotL dst, rRegL src) 6923%{ 6924 match(Set dst src); 6925 6926 ins_cost(100); 6927 format %{ "movq $dst, $src\t# long stk" %} 6928 opcode(0x89); 6929 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 6930 ins_pipe(ialu_mem_reg); 6931%} 6932 6933instruct storeSSP(stackSlotP dst, rRegP src) 6934%{ 6935 match(Set dst src); 6936 6937 ins_cost(100); 6938 format %{ "movq $dst, $src\t# ptr stk" %} 6939 opcode(0x89); 6940 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 6941 ins_pipe(ialu_mem_reg); 6942%} 6943 6944instruct storeSSF(stackSlotF dst, regF src) 6945%{ 6946 match(Set dst src); 6947 6948 ins_cost(95); // XXX 6949 format %{ "movss $dst, $src\t# float stk" %} 6950 opcode(0xF3, 0x0F, 0x11); 6951 ins_encode(OpcP, REX_reg_mem(src, dst), OpcS, OpcT, reg_mem(src, dst)); 6952 ins_pipe(pipe_slow); // XXX 6953%} 6954 6955instruct storeSSD(stackSlotD dst, regD src) 6956%{ 6957 match(Set dst src); 6958 6959 ins_cost(95); // XXX 6960 format %{ "movsd $dst, $src\t# double stk" %} 6961 opcode(0xF2, 0x0F, 0x11); 6962 ins_encode(OpcP, REX_reg_mem(src, dst), OpcS, OpcT, reg_mem(src, dst)); 6963 ins_pipe(pipe_slow); // XXX 6964%} 6965 6966//----------BSWAP Instructions------------------------------------------------- 6967instruct bytes_reverse_int(rRegI dst) %{ 6968 match(Set dst (ReverseBytesI dst)); 6969 6970 format %{ "bswapl $dst" %} 6971 opcode(0x0F, 0xC8); /*Opcode 0F /C8 */ 6972 ins_encode( REX_reg(dst), OpcP, opc2_reg(dst) ); 6973 ins_pipe( ialu_reg ); 6974%} 6975 6976instruct bytes_reverse_long(rRegL dst) %{ 6977 match(Set dst (ReverseBytesL dst)); 6978 6979 format %{ "bswapq $dst" %} 6980 6981 opcode(0x0F, 0xC8); /* Opcode 0F /C8 */ 6982 ins_encode( REX_reg_wide(dst), OpcP, opc2_reg(dst) ); 6983 ins_pipe( ialu_reg); 6984%} 6985 6986instruct loadI_reversed(rRegI dst, memory src) %{ 6987 match(Set dst (ReverseBytesI (LoadI src))); 6988 6989 format %{ "bswap_movl $dst, $src" %} 6990 opcode(0x8B, 0x0F, 0xC8); /* Opcode 8B 0F C8 */ 6991 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src), REX_reg(dst), OpcS, opc3_reg(dst)); 6992 ins_pipe( ialu_reg_mem ); 6993%} 6994 6995instruct loadL_reversed(rRegL dst, memory src) %{ 6996 match(Set dst (ReverseBytesL (LoadL src))); 6997 6998 format %{ "bswap_movq $dst, $src" %} 6999 opcode(0x8B, 0x0F, 0xC8); /* Opcode 8B 0F C8 */ 7000 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src), REX_reg_wide(dst), OpcS, opc3_reg(dst)); 7001 ins_pipe( ialu_reg_mem ); 7002%} 7003 7004instruct storeI_reversed(memory dst, rRegI src) %{ 7005 match(Set dst (StoreI dst (ReverseBytesI src))); 7006 7007 format %{ "movl_bswap $dst, $src" %} 7008 opcode(0x0F, 0xC8, 0x89); /* Opcode 0F C8 89 */ 7009 ins_encode( REX_reg(src), OpcP, opc2_reg(src), REX_reg_mem(src, dst), OpcT, reg_mem(src, dst) ); 7010 ins_pipe( ialu_mem_reg ); 7011%} 7012 7013instruct storeL_reversed(memory dst, rRegL src) %{ 7014 match(Set dst (StoreL dst (ReverseBytesL src))); 7015 7016 format %{ "movq_bswap $dst, $src" %} 7017 opcode(0x0F, 0xC8, 0x89); /* Opcode 0F C8 89 */ 7018 ins_encode( REX_reg_wide(src), OpcP, opc2_reg(src), REX_reg_mem_wide(src, dst), OpcT, reg_mem(src, dst) ); 7019 ins_pipe( ialu_mem_reg ); 7020%} 7021 7022//----------MemBar Instructions----------------------------------------------- 7023// Memory barrier flavors 7024 7025instruct membar_acquire() 7026%{ 7027 match(MemBarAcquire); 7028 ins_cost(0); 7029 7030 size(0); 7031 format %{ "MEMBAR-acquire" %} 7032 ins_encode(); 7033 ins_pipe(empty); 7034%} 7035 7036instruct membar_acquire_lock() 7037%{ 7038 match(MemBarAcquire); 7039 predicate(Matcher::prior_fast_lock(n)); 7040 ins_cost(0); 7041 7042 size(0); 7043 format %{ "MEMBAR-acquire (prior CMPXCHG in FastLock so empty encoding)" %} 7044 ins_encode(); 7045 ins_pipe(empty); 7046%} 7047 7048instruct membar_release() 7049%{ 7050 match(MemBarRelease); 7051 ins_cost(0); 7052 7053 size(0); 7054 format %{ "MEMBAR-release" %} 7055 ins_encode(); 7056 ins_pipe(empty); 7057%} 7058 7059instruct membar_release_lock() 7060%{ 7061 match(MemBarRelease); 7062 predicate(Matcher::post_fast_unlock(n)); 7063 ins_cost(0); 7064 7065 size(0); 7066 format %{ "MEMBAR-release (a FastUnlock follows so empty encoding)" %} 7067 ins_encode(); 7068 ins_pipe(empty); 7069%} 7070 7071instruct membar_volatile() 7072%{ 7073 match(MemBarVolatile); 7074 ins_cost(400); 7075 7076 format %{ "MEMBAR-volatile" %} 7077 ins_encode(enc_membar_volatile); 7078 ins_pipe(pipe_slow); 7079%} 7080 7081instruct unnecessary_membar_volatile() 7082%{ 7083 match(MemBarVolatile); 7084 predicate(Matcher::post_store_load_barrier(n)); 7085 ins_cost(0); 7086 7087 size(0); 7088 format %{ "MEMBAR-volatile (unnecessary so empty encoding)" %} 7089 ins_encode(); 7090 ins_pipe(empty); 7091%} 7092 7093//----------Move Instructions-------------------------------------------------- 7094 7095instruct castX2P(rRegP dst, rRegL src) 7096%{ 7097 match(Set dst (CastX2P src)); 7098 7099 format %{ "movq $dst, $src\t# long->ptr" %} 7100 ins_encode(enc_copy_wide(dst, src)); 7101 ins_pipe(ialu_reg_reg); // XXX 7102%} 7103 7104instruct castP2X(rRegL dst, rRegP src) 7105%{ 7106 match(Set dst (CastP2X src)); 7107 7108 format %{ "movq $dst, $src\t# ptr -> long" %} 7109 ins_encode(enc_copy_wide(dst, src)); 7110 ins_pipe(ialu_reg_reg); // XXX 7111%} 7112 7113 7114// Convert oop pointer into compressed form 7115instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{ 7116 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 7117 match(Set dst (EncodeP src)); 7118 effect(KILL cr); 7119 format %{ "encode_heap_oop $dst,$src" %} 7120 ins_encode %{ 7121 Register s = $src$$Register; 7122 Register d = $dst$$Register; 7123 if (s != d) { 7124 __ movq(d, s); 7125 } 7126 __ encode_heap_oop(d); 7127 %} 7128 ins_pipe(ialu_reg_long); 7129%} 7130 7131instruct encodeHeapOop_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 7132 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 7133 match(Set dst (EncodeP src)); 7134 effect(KILL cr); 7135 format %{ "encode_heap_oop_not_null $dst,$src" %} 7136 ins_encode %{ 7137 Register s = $src$$Register; 7138 Register d = $dst$$Register; 7139 __ encode_heap_oop_not_null(d, s); 7140 %} 7141 ins_pipe(ialu_reg_long); 7142%} 7143 7144instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{ 7145 predicate(n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull && 7146 n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant); 7147 match(Set dst (DecodeN src)); 7148 effect(KILL cr); 7149 format %{ "decode_heap_oop $dst,$src" %} 7150 ins_encode %{ 7151 Register s = $src$$Register; 7152 Register d = $dst$$Register; 7153 if (s != d) { 7154 __ movq(d, s); 7155 } 7156 __ decode_heap_oop(d); 7157 %} 7158 ins_pipe(ialu_reg_long); 7159%} 7160 7161instruct decodeHeapOop_not_null(rRegP dst, rRegN src) %{ 7162 predicate(n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull || 7163 n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant); 7164 match(Set dst (DecodeN src)); 7165 format %{ "decode_heap_oop_not_null $dst,$src" %} 7166 ins_encode %{ 7167 Register s = $src$$Register; 7168 Register d = $dst$$Register; 7169 __ decode_heap_oop_not_null(d, s); 7170 %} 7171 ins_pipe(ialu_reg_long); 7172%} 7173 7174 7175//----------Conditional Move--------------------------------------------------- 7176// Jump 7177// dummy instruction for generating temp registers 7178instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{ 7179 match(Jump (LShiftL switch_val shift)); 7180 ins_cost(350); 7181 predicate(false); 7182 effect(TEMP dest); 7183 7184 format %{ "leaq $dest, table_base\n\t" 7185 "jmp [$dest + $switch_val << $shift]\n\t" %} 7186 ins_encode(jump_enc_offset(switch_val, shift, dest)); 7187 ins_pipe(pipe_jmp); 7188 ins_pc_relative(1); 7189%} 7190 7191instruct jumpXtnd_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{ 7192 match(Jump (AddL (LShiftL switch_val shift) offset)); 7193 ins_cost(350); 7194 effect(TEMP dest); 7195 7196 format %{ "leaq $dest, table_base\n\t" 7197 "jmp [$dest + $switch_val << $shift + $offset]\n\t" %} 7198 ins_encode(jump_enc_addr(switch_val, shift, offset, dest)); 7199 ins_pipe(pipe_jmp); 7200 ins_pc_relative(1); 7201%} 7202 7203instruct jumpXtnd(rRegL switch_val, rRegI dest) %{ 7204 match(Jump switch_val); 7205 ins_cost(350); 7206 effect(TEMP dest); 7207 7208 format %{ "leaq $dest, table_base\n\t" 7209 "jmp [$dest + $switch_val]\n\t" %} 7210 ins_encode(jump_enc(switch_val, dest)); 7211 ins_pipe(pipe_jmp); 7212 ins_pc_relative(1); 7213%} 7214 7215// Conditional move 7216instruct cmovI_reg(rRegI dst, rRegI src, rFlagsReg cr, cmpOp cop) 7217%{ 7218 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 7219 7220 ins_cost(200); // XXX 7221 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 7222 opcode(0x0F, 0x40); 7223 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7224 ins_pipe(pipe_cmov_reg); 7225%} 7226 7227instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{ 7228 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 7229 7230 ins_cost(200); // XXX 7231 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 7232 opcode(0x0F, 0x40); 7233 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7234 ins_pipe(pipe_cmov_reg); 7235%} 7236 7237instruct cmovI_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 7238 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 7239 ins_cost(200); 7240 expand %{ 7241 cmovI_regU(cop, cr, dst, src); 7242 %} 7243%} 7244 7245// Conditional move 7246instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{ 7247 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 7248 7249 ins_cost(250); // XXX 7250 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 7251 opcode(0x0F, 0x40); 7252 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src)); 7253 ins_pipe(pipe_cmov_mem); 7254%} 7255 7256// Conditional move 7257instruct cmovI_memU(cmpOpU cop, rFlagsRegU cr, rRegI dst, memory src) 7258%{ 7259 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 7260 7261 ins_cost(250); // XXX 7262 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 7263 opcode(0x0F, 0x40); 7264 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src)); 7265 ins_pipe(pipe_cmov_mem); 7266%} 7267 7268instruct cmovI_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, memory src) %{ 7269 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 7270 ins_cost(250); 7271 expand %{ 7272 cmovI_memU(cop, cr, dst, src); 7273 %} 7274%} 7275 7276// Conditional move 7277instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop) 7278%{ 7279 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 7280 7281 ins_cost(200); // XXX 7282 format %{ "cmovl$cop $dst, $src\t# signed, compressed ptr" %} 7283 opcode(0x0F, 0x40); 7284 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7285 ins_pipe(pipe_cmov_reg); 7286%} 7287 7288// Conditional move 7289instruct cmovN_regU(cmpOpU cop, rFlagsRegU cr, rRegN dst, rRegN src) 7290%{ 7291 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 7292 7293 ins_cost(200); // XXX 7294 format %{ "cmovl$cop $dst, $src\t# unsigned, compressed ptr" %} 7295 opcode(0x0F, 0x40); 7296 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7297 ins_pipe(pipe_cmov_reg); 7298%} 7299 7300instruct cmovN_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 7301 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 7302 ins_cost(200); 7303 expand %{ 7304 cmovN_regU(cop, cr, dst, src); 7305 %} 7306%} 7307 7308// Conditional move 7309instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop) 7310%{ 7311 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 7312 7313 ins_cost(200); // XXX 7314 format %{ "cmovq$cop $dst, $src\t# signed, ptr" %} 7315 opcode(0x0F, 0x40); 7316 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7317 ins_pipe(pipe_cmov_reg); // XXX 7318%} 7319 7320// Conditional move 7321instruct cmovP_regU(cmpOpU cop, rFlagsRegU cr, rRegP dst, rRegP src) 7322%{ 7323 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 7324 7325 ins_cost(200); // XXX 7326 format %{ "cmovq$cop $dst, $src\t# unsigned, ptr" %} 7327 opcode(0x0F, 0x40); 7328 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7329 ins_pipe(pipe_cmov_reg); // XXX 7330%} 7331 7332instruct cmovP_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 7333 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 7334 ins_cost(200); 7335 expand %{ 7336 cmovP_regU(cop, cr, dst, src); 7337 %} 7338%} 7339 7340// DISABLED: Requires the ADLC to emit a bottom_type call that 7341// correctly meets the two pointer arguments; one is an incoming 7342// register but the other is a memory operand. ALSO appears to 7343// be buggy with implicit null checks. 7344// 7345//// Conditional move 7346//instruct cmovP_mem(cmpOp cop, rFlagsReg cr, rRegP dst, memory src) 7347//%{ 7348// match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); 7349// ins_cost(250); 7350// format %{ "CMOV$cop $dst,$src\t# ptr" %} 7351// opcode(0x0F,0x40); 7352// ins_encode( enc_cmov(cop), reg_mem( dst, src ) ); 7353// ins_pipe( pipe_cmov_mem ); 7354//%} 7355// 7356//// Conditional move 7357//instruct cmovP_memU(cmpOpU cop, rFlagsRegU cr, rRegP dst, memory src) 7358//%{ 7359// match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); 7360// ins_cost(250); 7361// format %{ "CMOV$cop $dst,$src\t# ptr" %} 7362// opcode(0x0F,0x40); 7363// ins_encode( enc_cmov(cop), reg_mem( dst, src ) ); 7364// ins_pipe( pipe_cmov_mem ); 7365//%} 7366 7367instruct cmovL_reg(cmpOp cop, rFlagsReg cr, rRegL dst, rRegL src) 7368%{ 7369 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 7370 7371 ins_cost(200); // XXX 7372 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 7373 opcode(0x0F, 0x40); 7374 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7375 ins_pipe(pipe_cmov_reg); // XXX 7376%} 7377 7378instruct cmovL_mem(cmpOp cop, rFlagsReg cr, rRegL dst, memory src) 7379%{ 7380 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 7381 7382 ins_cost(200); // XXX 7383 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 7384 opcode(0x0F, 0x40); 7385 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src)); 7386 ins_pipe(pipe_cmov_mem); // XXX 7387%} 7388 7389instruct cmovL_regU(cmpOpU cop, rFlagsRegU cr, rRegL dst, rRegL src) 7390%{ 7391 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 7392 7393 ins_cost(200); // XXX 7394 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 7395 opcode(0x0F, 0x40); 7396 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7397 ins_pipe(pipe_cmov_reg); // XXX 7398%} 7399 7400instruct cmovL_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 7401 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 7402 ins_cost(200); 7403 expand %{ 7404 cmovL_regU(cop, cr, dst, src); 7405 %} 7406%} 7407 7408instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src) 7409%{ 7410 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 7411 7412 ins_cost(200); // XXX 7413 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 7414 opcode(0x0F, 0x40); 7415 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src)); 7416 ins_pipe(pipe_cmov_mem); // XXX 7417%} 7418 7419instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{ 7420 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 7421 ins_cost(200); 7422 expand %{ 7423 cmovL_memU(cop, cr, dst, src); 7424 %} 7425%} 7426 7427instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src) 7428%{ 7429 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7430 7431 ins_cost(200); // XXX 7432 format %{ "jn$cop skip\t# signed cmove float\n\t" 7433 "movss $dst, $src\n" 7434 "skip:" %} 7435 ins_encode(enc_cmovf_branch(cop, dst, src)); 7436 ins_pipe(pipe_slow); 7437%} 7438 7439// instruct cmovF_mem(cmpOp cop, rFlagsReg cr, regF dst, memory src) 7440// %{ 7441// match(Set dst (CMoveF (Binary cop cr) (Binary dst (LoadL src)))); 7442 7443// ins_cost(200); // XXX 7444// format %{ "jn$cop skip\t# signed cmove float\n\t" 7445// "movss $dst, $src\n" 7446// "skip:" %} 7447// ins_encode(enc_cmovf_mem_branch(cop, dst, src)); 7448// ins_pipe(pipe_slow); 7449// %} 7450 7451instruct cmovF_regU(cmpOpU cop, rFlagsRegU cr, regF dst, regF src) 7452%{ 7453 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7454 7455 ins_cost(200); // XXX 7456 format %{ "jn$cop skip\t# unsigned cmove float\n\t" 7457 "movss $dst, $src\n" 7458 "skip:" %} 7459 ins_encode(enc_cmovf_branch(cop, dst, src)); 7460 ins_pipe(pipe_slow); 7461%} 7462 7463instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{ 7464 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7465 ins_cost(200); 7466 expand %{ 7467 cmovF_regU(cop, cr, dst, src); 7468 %} 7469%} 7470 7471instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src) 7472%{ 7473 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7474 7475 ins_cost(200); // XXX 7476 format %{ "jn$cop skip\t# signed cmove double\n\t" 7477 "movsd $dst, $src\n" 7478 "skip:" %} 7479 ins_encode(enc_cmovd_branch(cop, dst, src)); 7480 ins_pipe(pipe_slow); 7481%} 7482 7483instruct cmovD_regU(cmpOpU cop, rFlagsRegU cr, regD dst, regD src) 7484%{ 7485 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7486 7487 ins_cost(200); // XXX 7488 format %{ "jn$cop skip\t# unsigned cmove double\n\t" 7489 "movsd $dst, $src\n" 7490 "skip:" %} 7491 ins_encode(enc_cmovd_branch(cop, dst, src)); 7492 ins_pipe(pipe_slow); 7493%} 7494 7495instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{ 7496 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7497 ins_cost(200); 7498 expand %{ 7499 cmovD_regU(cop, cr, dst, src); 7500 %} 7501%} 7502 7503//----------Arithmetic Instructions-------------------------------------------- 7504//----------Addition Instructions---------------------------------------------- 7505 7506instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7507%{ 7508 match(Set dst (AddI dst src)); 7509 effect(KILL cr); 7510 7511 format %{ "addl $dst, $src\t# int" %} 7512 opcode(0x03); 7513 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 7514 ins_pipe(ialu_reg_reg); 7515%} 7516 7517instruct addI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 7518%{ 7519 match(Set dst (AddI dst src)); 7520 effect(KILL cr); 7521 7522 format %{ "addl $dst, $src\t# int" %} 7523 opcode(0x81, 0x00); /* /0 id */ 7524 ins_encode(OpcSErm(dst, src), Con8or32(src)); 7525 ins_pipe( ialu_reg ); 7526%} 7527 7528instruct addI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 7529%{ 7530 match(Set dst (AddI dst (LoadI src))); 7531 effect(KILL cr); 7532 7533 ins_cost(125); // XXX 7534 format %{ "addl $dst, $src\t# int" %} 7535 opcode(0x03); 7536 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 7537 ins_pipe(ialu_reg_mem); 7538%} 7539 7540instruct addI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 7541%{ 7542 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7543 effect(KILL cr); 7544 7545 ins_cost(150); // XXX 7546 format %{ "addl $dst, $src\t# int" %} 7547 opcode(0x01); /* Opcode 01 /r */ 7548 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 7549 ins_pipe(ialu_mem_reg); 7550%} 7551 7552instruct addI_mem_imm(memory dst, immI src, rFlagsReg cr) 7553%{ 7554 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7555 effect(KILL cr); 7556 7557 ins_cost(125); // XXX 7558 format %{ "addl $dst, $src\t# int" %} 7559 opcode(0x81); /* Opcode 81 /0 id */ 7560 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src)); 7561 ins_pipe(ialu_mem_imm); 7562%} 7563 7564instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr) 7565%{ 7566 predicate(UseIncDec); 7567 match(Set dst (AddI dst src)); 7568 effect(KILL cr); 7569 7570 format %{ "incl $dst\t# int" %} 7571 opcode(0xFF, 0x00); // FF /0 7572 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7573 ins_pipe(ialu_reg); 7574%} 7575 7576instruct incI_mem(memory dst, immI1 src, rFlagsReg cr) 7577%{ 7578 predicate(UseIncDec); 7579 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7580 effect(KILL cr); 7581 7582 ins_cost(125); // XXX 7583 format %{ "incl $dst\t# int" %} 7584 opcode(0xFF); /* Opcode FF /0 */ 7585 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x00, dst)); 7586 ins_pipe(ialu_mem_imm); 7587%} 7588 7589// XXX why does that use AddI 7590instruct decI_rReg(rRegI dst, immI_M1 src, rFlagsReg cr) 7591%{ 7592 predicate(UseIncDec); 7593 match(Set dst (AddI dst src)); 7594 effect(KILL cr); 7595 7596 format %{ "decl $dst\t# int" %} 7597 opcode(0xFF, 0x01); // FF /1 7598 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7599 ins_pipe(ialu_reg); 7600%} 7601 7602// XXX why does that use AddI 7603instruct decI_mem(memory dst, immI_M1 src, rFlagsReg cr) 7604%{ 7605 predicate(UseIncDec); 7606 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7607 effect(KILL cr); 7608 7609 ins_cost(125); // XXX 7610 format %{ "decl $dst\t# int" %} 7611 opcode(0xFF); /* Opcode FF /1 */ 7612 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x01, dst)); 7613 ins_pipe(ialu_mem_imm); 7614%} 7615 7616instruct leaI_rReg_immI(rRegI dst, rRegI src0, immI src1) 7617%{ 7618 match(Set dst (AddI src0 src1)); 7619 7620 ins_cost(110); 7621 format %{ "addr32 leal $dst, [$src0 + $src1]\t# int" %} 7622 opcode(0x8D); /* 0x8D /r */ 7623 ins_encode(Opcode(0x67), REX_reg_reg(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX 7624 ins_pipe(ialu_reg_reg); 7625%} 7626 7627instruct addL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7628%{ 7629 match(Set dst (AddL dst src)); 7630 effect(KILL cr); 7631 7632 format %{ "addq $dst, $src\t# long" %} 7633 opcode(0x03); 7634 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7635 ins_pipe(ialu_reg_reg); 7636%} 7637 7638instruct addL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 7639%{ 7640 match(Set dst (AddL dst src)); 7641 effect(KILL cr); 7642 7643 format %{ "addq $dst, $src\t# long" %} 7644 opcode(0x81, 0x00); /* /0 id */ 7645 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7646 ins_pipe( ialu_reg ); 7647%} 7648 7649instruct addL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 7650%{ 7651 match(Set dst (AddL dst (LoadL src))); 7652 effect(KILL cr); 7653 7654 ins_cost(125); // XXX 7655 format %{ "addq $dst, $src\t# long" %} 7656 opcode(0x03); 7657 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 7658 ins_pipe(ialu_reg_mem); 7659%} 7660 7661instruct addL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 7662%{ 7663 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7664 effect(KILL cr); 7665 7666 ins_cost(150); // XXX 7667 format %{ "addq $dst, $src\t# long" %} 7668 opcode(0x01); /* Opcode 01 /r */ 7669 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 7670 ins_pipe(ialu_mem_reg); 7671%} 7672 7673instruct addL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 7674%{ 7675 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7676 effect(KILL cr); 7677 7678 ins_cost(125); // XXX 7679 format %{ "addq $dst, $src\t# long" %} 7680 opcode(0x81); /* Opcode 81 /0 id */ 7681 ins_encode(REX_mem_wide(dst), 7682 OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src)); 7683 ins_pipe(ialu_mem_imm); 7684%} 7685 7686instruct incL_rReg(rRegI dst, immL1 src, rFlagsReg cr) 7687%{ 7688 predicate(UseIncDec); 7689 match(Set dst (AddL dst src)); 7690 effect(KILL cr); 7691 7692 format %{ "incq $dst\t# long" %} 7693 opcode(0xFF, 0x00); // FF /0 7694 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 7695 ins_pipe(ialu_reg); 7696%} 7697 7698instruct incL_mem(memory dst, immL1 src, rFlagsReg cr) 7699%{ 7700 predicate(UseIncDec); 7701 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7702 effect(KILL cr); 7703 7704 ins_cost(125); // XXX 7705 format %{ "incq $dst\t# long" %} 7706 opcode(0xFF); /* Opcode FF /0 */ 7707 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x00, dst)); 7708 ins_pipe(ialu_mem_imm); 7709%} 7710 7711// XXX why does that use AddL 7712instruct decL_rReg(rRegL dst, immL_M1 src, rFlagsReg cr) 7713%{ 7714 predicate(UseIncDec); 7715 match(Set dst (AddL dst src)); 7716 effect(KILL cr); 7717 7718 format %{ "decq $dst\t# long" %} 7719 opcode(0xFF, 0x01); // FF /1 7720 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 7721 ins_pipe(ialu_reg); 7722%} 7723 7724// XXX why does that use AddL 7725instruct decL_mem(memory dst, immL_M1 src, rFlagsReg cr) 7726%{ 7727 predicate(UseIncDec); 7728 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7729 effect(KILL cr); 7730 7731 ins_cost(125); // XXX 7732 format %{ "decq $dst\t# long" %} 7733 opcode(0xFF); /* Opcode FF /1 */ 7734 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x01, dst)); 7735 ins_pipe(ialu_mem_imm); 7736%} 7737 7738instruct leaL_rReg_immL(rRegL dst, rRegL src0, immL32 src1) 7739%{ 7740 match(Set dst (AddL src0 src1)); 7741 7742 ins_cost(110); 7743 format %{ "leaq $dst, [$src0 + $src1]\t# long" %} 7744 opcode(0x8D); /* 0x8D /r */ 7745 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX 7746 ins_pipe(ialu_reg_reg); 7747%} 7748 7749instruct addP_rReg(rRegP dst, rRegL src, rFlagsReg cr) 7750%{ 7751 match(Set dst (AddP dst src)); 7752 effect(KILL cr); 7753 7754 format %{ "addq $dst, $src\t# ptr" %} 7755 opcode(0x03); 7756 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7757 ins_pipe(ialu_reg_reg); 7758%} 7759 7760instruct addP_rReg_imm(rRegP dst, immL32 src, rFlagsReg cr) 7761%{ 7762 match(Set dst (AddP dst src)); 7763 effect(KILL cr); 7764 7765 format %{ "addq $dst, $src\t# ptr" %} 7766 opcode(0x81, 0x00); /* /0 id */ 7767 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7768 ins_pipe( ialu_reg ); 7769%} 7770 7771// XXX addP mem ops ???? 7772 7773instruct leaP_rReg_imm(rRegP dst, rRegP src0, immL32 src1) 7774%{ 7775 match(Set dst (AddP src0 src1)); 7776 7777 ins_cost(110); 7778 format %{ "leaq $dst, [$src0 + $src1]\t# ptr" %} 7779 opcode(0x8D); /* 0x8D /r */ 7780 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1));// XXX 7781 ins_pipe(ialu_reg_reg); 7782%} 7783 7784instruct checkCastPP(rRegP dst) 7785%{ 7786 match(Set dst (CheckCastPP dst)); 7787 7788 size(0); 7789 format %{ "# checkcastPP of $dst" %} 7790 ins_encode(/* empty encoding */); 7791 ins_pipe(empty); 7792%} 7793 7794instruct castPP(rRegP dst) 7795%{ 7796 match(Set dst (CastPP dst)); 7797 7798 size(0); 7799 format %{ "# castPP of $dst" %} 7800 ins_encode(/* empty encoding */); 7801 ins_pipe(empty); 7802%} 7803 7804instruct castII(rRegI dst) 7805%{ 7806 match(Set dst (CastII dst)); 7807 7808 size(0); 7809 format %{ "# castII of $dst" %} 7810 ins_encode(/* empty encoding */); 7811 ins_cost(0); 7812 ins_pipe(empty); 7813%} 7814 7815// LoadP-locked same as a regular LoadP when used with compare-swap 7816instruct loadPLocked(rRegP dst, memory mem) 7817%{ 7818 match(Set dst (LoadPLocked mem)); 7819 7820 ins_cost(125); // XXX 7821 format %{ "movq $dst, $mem\t# ptr locked" %} 7822 opcode(0x8B); 7823 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 7824 ins_pipe(ialu_reg_mem); // XXX 7825%} 7826 7827// LoadL-locked - same as a regular LoadL when used with compare-swap 7828instruct loadLLocked(rRegL dst, memory mem) 7829%{ 7830 match(Set dst (LoadLLocked mem)); 7831 7832 ins_cost(125); // XXX 7833 format %{ "movq $dst, $mem\t# long locked" %} 7834 opcode(0x8B); 7835 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 7836 ins_pipe(ialu_reg_mem); // XXX 7837%} 7838 7839// Conditional-store of the updated heap-top. 7840// Used during allocation of the shared heap. 7841// Sets flags (EQ) on success. Implemented with a CMPXCHG on Intel. 7842 7843instruct storePConditional(memory heap_top_ptr, 7844 rax_RegP oldval, rRegP newval, 7845 rFlagsReg cr) 7846%{ 7847 match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval))); 7848 7849 format %{ "cmpxchgq $heap_top_ptr, $newval\t# (ptr) " 7850 "If rax == $heap_top_ptr then store $newval into $heap_top_ptr" %} 7851 opcode(0x0F, 0xB1); 7852 ins_encode(lock_prefix, 7853 REX_reg_mem_wide(newval, heap_top_ptr), 7854 OpcP, OpcS, 7855 reg_mem(newval, heap_top_ptr)); 7856 ins_pipe(pipe_cmpxchg); 7857%} 7858 7859// Conditional-store of an int value. 7860// ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG. 7861instruct storeIConditional(memory mem, rax_RegI oldval, rRegI newval, rFlagsReg cr) 7862%{ 7863 match(Set cr (StoreIConditional mem (Binary oldval newval))); 7864 effect(KILL oldval); 7865 7866 format %{ "cmpxchgl $mem, $newval\t# If rax == $mem then store $newval into $mem" %} 7867 opcode(0x0F, 0xB1); 7868 ins_encode(lock_prefix, 7869 REX_reg_mem(newval, mem), 7870 OpcP, OpcS, 7871 reg_mem(newval, mem)); 7872 ins_pipe(pipe_cmpxchg); 7873%} 7874 7875// Conditional-store of a long value. 7876// ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG. 7877instruct storeLConditional(memory mem, rax_RegL oldval, rRegL newval, rFlagsReg cr) 7878%{ 7879 match(Set cr (StoreLConditional mem (Binary oldval newval))); 7880 effect(KILL oldval); 7881 7882 format %{ "cmpxchgq $mem, $newval\t# If rax == $mem then store $newval into $mem" %} 7883 opcode(0x0F, 0xB1); 7884 ins_encode(lock_prefix, 7885 REX_reg_mem_wide(newval, mem), 7886 OpcP, OpcS, 7887 reg_mem(newval, mem)); 7888 ins_pipe(pipe_cmpxchg); 7889%} 7890 7891 7892// XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them 7893instruct compareAndSwapP(rRegI res, 7894 memory mem_ptr, 7895 rax_RegP oldval, rRegP newval, 7896 rFlagsReg cr) 7897%{ 7898 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); 7899 effect(KILL cr, KILL oldval); 7900 7901 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7902 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7903 "sete $res\n\t" 7904 "movzbl $res, $res" %} 7905 opcode(0x0F, 0xB1); 7906 ins_encode(lock_prefix, 7907 REX_reg_mem_wide(newval, mem_ptr), 7908 OpcP, OpcS, 7909 reg_mem(newval, mem_ptr), 7910 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7911 REX_reg_breg(res, res), // movzbl 7912 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7913 ins_pipe( pipe_cmpxchg ); 7914%} 7915 7916instruct compareAndSwapL(rRegI res, 7917 memory mem_ptr, 7918 rax_RegL oldval, rRegL newval, 7919 rFlagsReg cr) 7920%{ 7921 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval))); 7922 effect(KILL cr, KILL oldval); 7923 7924 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7925 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7926 "sete $res\n\t" 7927 "movzbl $res, $res" %} 7928 opcode(0x0F, 0xB1); 7929 ins_encode(lock_prefix, 7930 REX_reg_mem_wide(newval, mem_ptr), 7931 OpcP, OpcS, 7932 reg_mem(newval, mem_ptr), 7933 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7934 REX_reg_breg(res, res), // movzbl 7935 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7936 ins_pipe( pipe_cmpxchg ); 7937%} 7938 7939instruct compareAndSwapI(rRegI res, 7940 memory mem_ptr, 7941 rax_RegI oldval, rRegI newval, 7942 rFlagsReg cr) 7943%{ 7944 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval))); 7945 effect(KILL cr, KILL oldval); 7946 7947 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7948 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7949 "sete $res\n\t" 7950 "movzbl $res, $res" %} 7951 opcode(0x0F, 0xB1); 7952 ins_encode(lock_prefix, 7953 REX_reg_mem(newval, mem_ptr), 7954 OpcP, OpcS, 7955 reg_mem(newval, mem_ptr), 7956 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7957 REX_reg_breg(res, res), // movzbl 7958 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7959 ins_pipe( pipe_cmpxchg ); 7960%} 7961 7962 7963instruct compareAndSwapN(rRegI res, 7964 memory mem_ptr, 7965 rax_RegN oldval, rRegN newval, 7966 rFlagsReg cr) %{ 7967 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval))); 7968 effect(KILL cr, KILL oldval); 7969 7970 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7971 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7972 "sete $res\n\t" 7973 "movzbl $res, $res" %} 7974 opcode(0x0F, 0xB1); 7975 ins_encode(lock_prefix, 7976 REX_reg_mem(newval, mem_ptr), 7977 OpcP, OpcS, 7978 reg_mem(newval, mem_ptr), 7979 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7980 REX_reg_breg(res, res), // movzbl 7981 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7982 ins_pipe( pipe_cmpxchg ); 7983%} 7984 7985//----------Subtraction Instructions------------------------------------------- 7986 7987// Integer Subtraction Instructions 7988instruct subI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7989%{ 7990 match(Set dst (SubI dst src)); 7991 effect(KILL cr); 7992 7993 format %{ "subl $dst, $src\t# int" %} 7994 opcode(0x2B); 7995 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 7996 ins_pipe(ialu_reg_reg); 7997%} 7998 7999instruct subI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 8000%{ 8001 match(Set dst (SubI dst src)); 8002 effect(KILL cr); 8003 8004 format %{ "subl $dst, $src\t# int" %} 8005 opcode(0x81, 0x05); /* Opcode 81 /5 */ 8006 ins_encode(OpcSErm(dst, src), Con8or32(src)); 8007 ins_pipe(ialu_reg); 8008%} 8009 8010instruct subI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 8011%{ 8012 match(Set dst (SubI dst (LoadI src))); 8013 effect(KILL cr); 8014 8015 ins_cost(125); 8016 format %{ "subl $dst, $src\t# int" %} 8017 opcode(0x2B); 8018 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 8019 ins_pipe(ialu_reg_mem); 8020%} 8021 8022instruct subI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 8023%{ 8024 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 8025 effect(KILL cr); 8026 8027 ins_cost(150); 8028 format %{ "subl $dst, $src\t# int" %} 8029 opcode(0x29); /* Opcode 29 /r */ 8030 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 8031 ins_pipe(ialu_mem_reg); 8032%} 8033 8034instruct subI_mem_imm(memory dst, immI src, rFlagsReg cr) 8035%{ 8036 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 8037 effect(KILL cr); 8038 8039 ins_cost(125); // XXX 8040 format %{ "subl $dst, $src\t# int" %} 8041 opcode(0x81); /* Opcode 81 /5 id */ 8042 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); 8043 ins_pipe(ialu_mem_imm); 8044%} 8045 8046instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 8047%{ 8048 match(Set dst (SubL dst src)); 8049 effect(KILL cr); 8050 8051 format %{ "subq $dst, $src\t# long" %} 8052 opcode(0x2B); 8053 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 8054 ins_pipe(ialu_reg_reg); 8055%} 8056 8057instruct subL_rReg_imm(rRegI dst, immL32 src, rFlagsReg cr) 8058%{ 8059 match(Set dst (SubL dst src)); 8060 effect(KILL cr); 8061 8062 format %{ "subq $dst, $src\t# long" %} 8063 opcode(0x81, 0x05); /* Opcode 81 /5 */ 8064 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 8065 ins_pipe(ialu_reg); 8066%} 8067 8068instruct subL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 8069%{ 8070 match(Set dst (SubL dst (LoadL src))); 8071 effect(KILL cr); 8072 8073 ins_cost(125); 8074 format %{ "subq $dst, $src\t# long" %} 8075 opcode(0x2B); 8076 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 8077 ins_pipe(ialu_reg_mem); 8078%} 8079 8080instruct subL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 8081%{ 8082 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 8083 effect(KILL cr); 8084 8085 ins_cost(150); 8086 format %{ "subq $dst, $src\t# long" %} 8087 opcode(0x29); /* Opcode 29 /r */ 8088 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 8089 ins_pipe(ialu_mem_reg); 8090%} 8091 8092instruct subL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 8093%{ 8094 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 8095 effect(KILL cr); 8096 8097 ins_cost(125); // XXX 8098 format %{ "subq $dst, $src\t# long" %} 8099 opcode(0x81); /* Opcode 81 /5 id */ 8100 ins_encode(REX_mem_wide(dst), 8101 OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); 8102 ins_pipe(ialu_mem_imm); 8103%} 8104 8105// Subtract from a pointer 8106// XXX hmpf??? 8107instruct subP_rReg(rRegP dst, rRegI src, immI0 zero, rFlagsReg cr) 8108%{ 8109 match(Set dst (AddP dst (SubI zero src))); 8110 effect(KILL cr); 8111 8112 format %{ "subq $dst, $src\t# ptr - int" %} 8113 opcode(0x2B); 8114 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 8115 ins_pipe(ialu_reg_reg); 8116%} 8117 8118instruct negI_rReg(rRegI dst, immI0 zero, rFlagsReg cr) 8119%{ 8120 match(Set dst (SubI zero dst)); 8121 effect(KILL cr); 8122 8123 format %{ "negl $dst\t# int" %} 8124 opcode(0xF7, 0x03); // Opcode F7 /3 8125 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8126 ins_pipe(ialu_reg); 8127%} 8128 8129instruct negI_mem(memory dst, immI0 zero, rFlagsReg cr) 8130%{ 8131 match(Set dst (StoreI dst (SubI zero (LoadI dst)))); 8132 effect(KILL cr); 8133 8134 format %{ "negl $dst\t# int" %} 8135 opcode(0xF7, 0x03); // Opcode F7 /3 8136 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8137 ins_pipe(ialu_reg); 8138%} 8139 8140instruct negL_rReg(rRegL dst, immL0 zero, rFlagsReg cr) 8141%{ 8142 match(Set dst (SubL zero dst)); 8143 effect(KILL cr); 8144 8145 format %{ "negq $dst\t# long" %} 8146 opcode(0xF7, 0x03); // Opcode F7 /3 8147 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8148 ins_pipe(ialu_reg); 8149%} 8150 8151instruct negL_mem(memory dst, immL0 zero, rFlagsReg cr) 8152%{ 8153 match(Set dst (StoreL dst (SubL zero (LoadL dst)))); 8154 effect(KILL cr); 8155 8156 format %{ "negq $dst\t# long" %} 8157 opcode(0xF7, 0x03); // Opcode F7 /3 8158 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8159 ins_pipe(ialu_reg); 8160%} 8161 8162 8163//----------Multiplication/Division Instructions------------------------------- 8164// Integer Multiplication Instructions 8165// Multiply Register 8166 8167instruct mulI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8168%{ 8169 match(Set dst (MulI dst src)); 8170 effect(KILL cr); 8171 8172 ins_cost(300); 8173 format %{ "imull $dst, $src\t# int" %} 8174 opcode(0x0F, 0xAF); 8175 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8176 ins_pipe(ialu_reg_reg_alu0); 8177%} 8178 8179instruct mulI_rReg_imm(rRegI dst, rRegI src, immI imm, rFlagsReg cr) 8180%{ 8181 match(Set dst (MulI src imm)); 8182 effect(KILL cr); 8183 8184 ins_cost(300); 8185 format %{ "imull $dst, $src, $imm\t# int" %} 8186 opcode(0x69); /* 69 /r id */ 8187 ins_encode(REX_reg_reg(dst, src), 8188 OpcSE(imm), reg_reg(dst, src), Con8or32(imm)); 8189 ins_pipe(ialu_reg_reg_alu0); 8190%} 8191 8192instruct mulI_mem(rRegI dst, memory src, rFlagsReg cr) 8193%{ 8194 match(Set dst (MulI dst (LoadI src))); 8195 effect(KILL cr); 8196 8197 ins_cost(350); 8198 format %{ "imull $dst, $src\t# int" %} 8199 opcode(0x0F, 0xAF); 8200 ins_encode(REX_reg_mem(dst, src), OpcP, OpcS, reg_mem(dst, src)); 8201 ins_pipe(ialu_reg_mem_alu0); 8202%} 8203 8204instruct mulI_mem_imm(rRegI dst, memory src, immI imm, rFlagsReg cr) 8205%{ 8206 match(Set dst (MulI (LoadI src) imm)); 8207 effect(KILL cr); 8208 8209 ins_cost(300); 8210 format %{ "imull $dst, $src, $imm\t# int" %} 8211 opcode(0x69); /* 69 /r id */ 8212 ins_encode(REX_reg_mem(dst, src), 8213 OpcSE(imm), reg_mem(dst, src), Con8or32(imm)); 8214 ins_pipe(ialu_reg_mem_alu0); 8215%} 8216 8217instruct mulL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 8218%{ 8219 match(Set dst (MulL dst src)); 8220 effect(KILL cr); 8221 8222 ins_cost(300); 8223 format %{ "imulq $dst, $src\t# long" %} 8224 opcode(0x0F, 0xAF); 8225 ins_encode(REX_reg_reg_wide(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8226 ins_pipe(ialu_reg_reg_alu0); 8227%} 8228 8229instruct mulL_rReg_imm(rRegL dst, rRegL src, immL32 imm, rFlagsReg cr) 8230%{ 8231 match(Set dst (MulL src imm)); 8232 effect(KILL cr); 8233 8234 ins_cost(300); 8235 format %{ "imulq $dst, $src, $imm\t# long" %} 8236 opcode(0x69); /* 69 /r id */ 8237 ins_encode(REX_reg_reg_wide(dst, src), 8238 OpcSE(imm), reg_reg(dst, src), Con8or32(imm)); 8239 ins_pipe(ialu_reg_reg_alu0); 8240%} 8241 8242instruct mulL_mem(rRegL dst, memory src, rFlagsReg cr) 8243%{ 8244 match(Set dst (MulL dst (LoadL src))); 8245 effect(KILL cr); 8246 8247 ins_cost(350); 8248 format %{ "imulq $dst, $src\t# long" %} 8249 opcode(0x0F, 0xAF); 8250 ins_encode(REX_reg_mem_wide(dst, src), OpcP, OpcS, reg_mem(dst, src)); 8251 ins_pipe(ialu_reg_mem_alu0); 8252%} 8253 8254instruct mulL_mem_imm(rRegL dst, memory src, immL32 imm, rFlagsReg cr) 8255%{ 8256 match(Set dst (MulL (LoadL src) imm)); 8257 effect(KILL cr); 8258 8259 ins_cost(300); 8260 format %{ "imulq $dst, $src, $imm\t# long" %} 8261 opcode(0x69); /* 69 /r id */ 8262 ins_encode(REX_reg_mem_wide(dst, src), 8263 OpcSE(imm), reg_mem(dst, src), Con8or32(imm)); 8264 ins_pipe(ialu_reg_mem_alu0); 8265%} 8266 8267instruct mulHiL_rReg(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr) 8268%{ 8269 match(Set dst (MulHiL src rax)); 8270 effect(USE_KILL rax, KILL cr); 8271 8272 ins_cost(300); 8273 format %{ "imulq RDX:RAX, RAX, $src\t# mulhi" %} 8274 opcode(0xF7, 0x5); /* Opcode F7 /5 */ 8275 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); 8276 ins_pipe(ialu_reg_reg_alu0); 8277%} 8278 8279instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 8280 rFlagsReg cr) 8281%{ 8282 match(Set rax (DivI rax div)); 8283 effect(KILL rdx, KILL cr); 8284 8285 ins_cost(30*100+10*100); // XXX 8286 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 8287 "jne,s normal\n\t" 8288 "xorl rdx, rdx\n\t" 8289 "cmpl $div, -1\n\t" 8290 "je,s done\n" 8291 "normal: cdql\n\t" 8292 "idivl $div\n" 8293 "done:" %} 8294 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8295 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8296 ins_pipe(ialu_reg_reg_alu0); 8297%} 8298 8299instruct divL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 8300 rFlagsReg cr) 8301%{ 8302 match(Set rax (DivL rax div)); 8303 effect(KILL rdx, KILL cr); 8304 8305 ins_cost(30*100+10*100); // XXX 8306 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 8307 "cmpq rax, rdx\n\t" 8308 "jne,s normal\n\t" 8309 "xorl rdx, rdx\n\t" 8310 "cmpq $div, -1\n\t" 8311 "je,s done\n" 8312 "normal: cdqq\n\t" 8313 "idivq $div\n" 8314 "done:" %} 8315 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8316 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8317 ins_pipe(ialu_reg_reg_alu0); 8318%} 8319 8320// Integer DIVMOD with Register, both quotient and mod results 8321instruct divModI_rReg_divmod(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 8322 rFlagsReg cr) 8323%{ 8324 match(DivModI rax div); 8325 effect(KILL cr); 8326 8327 ins_cost(30*100+10*100); // XXX 8328 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 8329 "jne,s normal\n\t" 8330 "xorl rdx, rdx\n\t" 8331 "cmpl $div, -1\n\t" 8332 "je,s done\n" 8333 "normal: cdql\n\t" 8334 "idivl $div\n" 8335 "done:" %} 8336 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8337 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8338 ins_pipe(pipe_slow); 8339%} 8340 8341// Long DIVMOD with Register, both quotient and mod results 8342instruct divModL_rReg_divmod(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 8343 rFlagsReg cr) 8344%{ 8345 match(DivModL rax div); 8346 effect(KILL cr); 8347 8348 ins_cost(30*100+10*100); // XXX 8349 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 8350 "cmpq rax, rdx\n\t" 8351 "jne,s normal\n\t" 8352 "xorl rdx, rdx\n\t" 8353 "cmpq $div, -1\n\t" 8354 "je,s done\n" 8355 "normal: cdqq\n\t" 8356 "idivq $div\n" 8357 "done:" %} 8358 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8359 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8360 ins_pipe(pipe_slow); 8361%} 8362 8363//----------- DivL-By-Constant-Expansions-------------------------------------- 8364// DivI cases are handled by the compiler 8365 8366// Magic constant, reciprical of 10 8367instruct loadConL_0x6666666666666667(rRegL dst) 8368%{ 8369 effect(DEF dst); 8370 8371 format %{ "movq $dst, #0x666666666666667\t# Used in div-by-10" %} 8372 ins_encode(load_immL(dst, 0x6666666666666667)); 8373 ins_pipe(ialu_reg); 8374%} 8375 8376instruct mul_hi(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr) 8377%{ 8378 effect(DEF dst, USE src, USE_KILL rax, KILL cr); 8379 8380 format %{ "imulq rdx:rax, rax, $src\t# Used in div-by-10" %} 8381 opcode(0xF7, 0x5); /* Opcode F7 /5 */ 8382 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); 8383 ins_pipe(ialu_reg_reg_alu0); 8384%} 8385 8386instruct sarL_rReg_63(rRegL dst, rFlagsReg cr) 8387%{ 8388 effect(USE_DEF dst, KILL cr); 8389 8390 format %{ "sarq $dst, #63\t# Used in div-by-10" %} 8391 opcode(0xC1, 0x7); /* C1 /7 ib */ 8392 ins_encode(reg_opc_imm_wide(dst, 0x3F)); 8393 ins_pipe(ialu_reg); 8394%} 8395 8396instruct sarL_rReg_2(rRegL dst, rFlagsReg cr) 8397%{ 8398 effect(USE_DEF dst, KILL cr); 8399 8400 format %{ "sarq $dst, #2\t# Used in div-by-10" %} 8401 opcode(0xC1, 0x7); /* C1 /7 ib */ 8402 ins_encode(reg_opc_imm_wide(dst, 0x2)); 8403 ins_pipe(ialu_reg); 8404%} 8405 8406instruct divL_10(rdx_RegL dst, no_rax_RegL src, immL10 div) 8407%{ 8408 match(Set dst (DivL src div)); 8409 8410 ins_cost((5+8)*100); 8411 expand %{ 8412 rax_RegL rax; // Killed temp 8413 rFlagsReg cr; // Killed 8414 loadConL_0x6666666666666667(rax); // movq rax, 0x6666666666666667 8415 mul_hi(dst, src, rax, cr); // mulq rdx:rax <= rax * $src 8416 sarL_rReg_63(src, cr); // sarq src, 63 8417 sarL_rReg_2(dst, cr); // sarq rdx, 2 8418 subL_rReg(dst, src, cr); // subl rdx, src 8419 %} 8420%} 8421 8422//----------------------------------------------------------------------------- 8423 8424instruct modI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, 8425 rFlagsReg cr) 8426%{ 8427 match(Set rdx (ModI rax div)); 8428 effect(KILL rax, KILL cr); 8429 8430 ins_cost(300); // XXX 8431 format %{ "cmpl rax, 0x80000000\t# irem\n\t" 8432 "jne,s normal\n\t" 8433 "xorl rdx, rdx\n\t" 8434 "cmpl $div, -1\n\t" 8435 "je,s done\n" 8436 "normal: cdql\n\t" 8437 "idivl $div\n" 8438 "done:" %} 8439 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8440 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8441 ins_pipe(ialu_reg_reg_alu0); 8442%} 8443 8444instruct modL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, 8445 rFlagsReg cr) 8446%{ 8447 match(Set rdx (ModL rax div)); 8448 effect(KILL rax, KILL cr); 8449 8450 ins_cost(300); // XXX 8451 format %{ "movq rdx, 0x8000000000000000\t# lrem\n\t" 8452 "cmpq rax, rdx\n\t" 8453 "jne,s normal\n\t" 8454 "xorl rdx, rdx\n\t" 8455 "cmpq $div, -1\n\t" 8456 "je,s done\n" 8457 "normal: cdqq\n\t" 8458 "idivq $div\n" 8459 "done:" %} 8460 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8461 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8462 ins_pipe(ialu_reg_reg_alu0); 8463%} 8464 8465// Integer Shift Instructions 8466// Shift Left by one 8467instruct salI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8468%{ 8469 match(Set dst (LShiftI dst shift)); 8470 effect(KILL cr); 8471 8472 format %{ "sall $dst, $shift" %} 8473 opcode(0xD1, 0x4); /* D1 /4 */ 8474 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8475 ins_pipe(ialu_reg); 8476%} 8477 8478// Shift Left by one 8479instruct salI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8480%{ 8481 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8482 effect(KILL cr); 8483 8484 format %{ "sall $dst, $shift\t" %} 8485 opcode(0xD1, 0x4); /* D1 /4 */ 8486 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8487 ins_pipe(ialu_mem_imm); 8488%} 8489 8490// Shift Left by 8-bit immediate 8491instruct salI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8492%{ 8493 match(Set dst (LShiftI dst shift)); 8494 effect(KILL cr); 8495 8496 format %{ "sall $dst, $shift" %} 8497 opcode(0xC1, 0x4); /* C1 /4 ib */ 8498 ins_encode(reg_opc_imm(dst, shift)); 8499 ins_pipe(ialu_reg); 8500%} 8501 8502// Shift Left by 8-bit immediate 8503instruct salI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8504%{ 8505 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8506 effect(KILL cr); 8507 8508 format %{ "sall $dst, $shift" %} 8509 opcode(0xC1, 0x4); /* C1 /4 ib */ 8510 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8511 ins_pipe(ialu_mem_imm); 8512%} 8513 8514// Shift Left by variable 8515instruct salI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8516%{ 8517 match(Set dst (LShiftI dst shift)); 8518 effect(KILL cr); 8519 8520 format %{ "sall $dst, $shift" %} 8521 opcode(0xD3, 0x4); /* D3 /4 */ 8522 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8523 ins_pipe(ialu_reg_reg); 8524%} 8525 8526// Shift Left by variable 8527instruct salI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8528%{ 8529 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8530 effect(KILL cr); 8531 8532 format %{ "sall $dst, $shift" %} 8533 opcode(0xD3, 0x4); /* D3 /4 */ 8534 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8535 ins_pipe(ialu_mem_reg); 8536%} 8537 8538// Arithmetic shift right by one 8539instruct sarI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8540%{ 8541 match(Set dst (RShiftI dst shift)); 8542 effect(KILL cr); 8543 8544 format %{ "sarl $dst, $shift" %} 8545 opcode(0xD1, 0x7); /* D1 /7 */ 8546 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8547 ins_pipe(ialu_reg); 8548%} 8549 8550// Arithmetic shift right by one 8551instruct sarI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8552%{ 8553 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8554 effect(KILL cr); 8555 8556 format %{ "sarl $dst, $shift" %} 8557 opcode(0xD1, 0x7); /* D1 /7 */ 8558 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8559 ins_pipe(ialu_mem_imm); 8560%} 8561 8562// Arithmetic Shift Right by 8-bit immediate 8563instruct sarI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8564%{ 8565 match(Set dst (RShiftI dst shift)); 8566 effect(KILL cr); 8567 8568 format %{ "sarl $dst, $shift" %} 8569 opcode(0xC1, 0x7); /* C1 /7 ib */ 8570 ins_encode(reg_opc_imm(dst, shift)); 8571 ins_pipe(ialu_mem_imm); 8572%} 8573 8574// Arithmetic Shift Right by 8-bit immediate 8575instruct sarI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8576%{ 8577 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8578 effect(KILL cr); 8579 8580 format %{ "sarl $dst, $shift" %} 8581 opcode(0xC1, 0x7); /* C1 /7 ib */ 8582 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8583 ins_pipe(ialu_mem_imm); 8584%} 8585 8586// Arithmetic Shift Right by variable 8587instruct sarI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8588%{ 8589 match(Set dst (RShiftI dst shift)); 8590 effect(KILL cr); 8591 8592 format %{ "sarl $dst, $shift" %} 8593 opcode(0xD3, 0x7); /* D3 /7 */ 8594 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8595 ins_pipe(ialu_reg_reg); 8596%} 8597 8598// Arithmetic Shift Right by variable 8599instruct sarI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8600%{ 8601 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8602 effect(KILL cr); 8603 8604 format %{ "sarl $dst, $shift" %} 8605 opcode(0xD3, 0x7); /* D3 /7 */ 8606 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8607 ins_pipe(ialu_mem_reg); 8608%} 8609 8610// Logical shift right by one 8611instruct shrI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8612%{ 8613 match(Set dst (URShiftI dst shift)); 8614 effect(KILL cr); 8615 8616 format %{ "shrl $dst, $shift" %} 8617 opcode(0xD1, 0x5); /* D1 /5 */ 8618 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8619 ins_pipe(ialu_reg); 8620%} 8621 8622// Logical shift right by one 8623instruct shrI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8624%{ 8625 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8626 effect(KILL cr); 8627 8628 format %{ "shrl $dst, $shift" %} 8629 opcode(0xD1, 0x5); /* D1 /5 */ 8630 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8631 ins_pipe(ialu_mem_imm); 8632%} 8633 8634// Logical Shift Right by 8-bit immediate 8635instruct shrI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8636%{ 8637 match(Set dst (URShiftI dst shift)); 8638 effect(KILL cr); 8639 8640 format %{ "shrl $dst, $shift" %} 8641 opcode(0xC1, 0x5); /* C1 /5 ib */ 8642 ins_encode(reg_opc_imm(dst, shift)); 8643 ins_pipe(ialu_reg); 8644%} 8645 8646// Logical Shift Right by 8-bit immediate 8647instruct shrI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8648%{ 8649 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8650 effect(KILL cr); 8651 8652 format %{ "shrl $dst, $shift" %} 8653 opcode(0xC1, 0x5); /* C1 /5 ib */ 8654 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8655 ins_pipe(ialu_mem_imm); 8656%} 8657 8658// Logical Shift Right by variable 8659instruct shrI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8660%{ 8661 match(Set dst (URShiftI dst shift)); 8662 effect(KILL cr); 8663 8664 format %{ "shrl $dst, $shift" %} 8665 opcode(0xD3, 0x5); /* D3 /5 */ 8666 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8667 ins_pipe(ialu_reg_reg); 8668%} 8669 8670// Logical Shift Right by variable 8671instruct shrI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8672%{ 8673 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8674 effect(KILL cr); 8675 8676 format %{ "shrl $dst, $shift" %} 8677 opcode(0xD3, 0x5); /* D3 /5 */ 8678 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8679 ins_pipe(ialu_mem_reg); 8680%} 8681 8682// Long Shift Instructions 8683// Shift Left by one 8684instruct salL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8685%{ 8686 match(Set dst (LShiftL dst shift)); 8687 effect(KILL cr); 8688 8689 format %{ "salq $dst, $shift" %} 8690 opcode(0xD1, 0x4); /* D1 /4 */ 8691 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8692 ins_pipe(ialu_reg); 8693%} 8694 8695// Shift Left by one 8696instruct salL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8697%{ 8698 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8699 effect(KILL cr); 8700 8701 format %{ "salq $dst, $shift" %} 8702 opcode(0xD1, 0x4); /* D1 /4 */ 8703 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8704 ins_pipe(ialu_mem_imm); 8705%} 8706 8707// Shift Left by 8-bit immediate 8708instruct salL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8709%{ 8710 match(Set dst (LShiftL dst shift)); 8711 effect(KILL cr); 8712 8713 format %{ "salq $dst, $shift" %} 8714 opcode(0xC1, 0x4); /* C1 /4 ib */ 8715 ins_encode(reg_opc_imm_wide(dst, shift)); 8716 ins_pipe(ialu_reg); 8717%} 8718 8719// Shift Left by 8-bit immediate 8720instruct salL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8721%{ 8722 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8723 effect(KILL cr); 8724 8725 format %{ "salq $dst, $shift" %} 8726 opcode(0xC1, 0x4); /* C1 /4 ib */ 8727 ins_encode(REX_mem_wide(dst), OpcP, 8728 RM_opc_mem(secondary, dst), Con8or32(shift)); 8729 ins_pipe(ialu_mem_imm); 8730%} 8731 8732// Shift Left by variable 8733instruct salL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8734%{ 8735 match(Set dst (LShiftL dst shift)); 8736 effect(KILL cr); 8737 8738 format %{ "salq $dst, $shift" %} 8739 opcode(0xD3, 0x4); /* D3 /4 */ 8740 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8741 ins_pipe(ialu_reg_reg); 8742%} 8743 8744// Shift Left by variable 8745instruct salL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8746%{ 8747 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8748 effect(KILL cr); 8749 8750 format %{ "salq $dst, $shift" %} 8751 opcode(0xD3, 0x4); /* D3 /4 */ 8752 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8753 ins_pipe(ialu_mem_reg); 8754%} 8755 8756// Arithmetic shift right by one 8757instruct sarL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8758%{ 8759 match(Set dst (RShiftL dst shift)); 8760 effect(KILL cr); 8761 8762 format %{ "sarq $dst, $shift" %} 8763 opcode(0xD1, 0x7); /* D1 /7 */ 8764 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8765 ins_pipe(ialu_reg); 8766%} 8767 8768// Arithmetic shift right by one 8769instruct sarL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8770%{ 8771 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8772 effect(KILL cr); 8773 8774 format %{ "sarq $dst, $shift" %} 8775 opcode(0xD1, 0x7); /* D1 /7 */ 8776 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8777 ins_pipe(ialu_mem_imm); 8778%} 8779 8780// Arithmetic Shift Right by 8-bit immediate 8781instruct sarL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8782%{ 8783 match(Set dst (RShiftL dst shift)); 8784 effect(KILL cr); 8785 8786 format %{ "sarq $dst, $shift" %} 8787 opcode(0xC1, 0x7); /* C1 /7 ib */ 8788 ins_encode(reg_opc_imm_wide(dst, shift)); 8789 ins_pipe(ialu_mem_imm); 8790%} 8791 8792// Arithmetic Shift Right by 8-bit immediate 8793instruct sarL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8794%{ 8795 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8796 effect(KILL cr); 8797 8798 format %{ "sarq $dst, $shift" %} 8799 opcode(0xC1, 0x7); /* C1 /7 ib */ 8800 ins_encode(REX_mem_wide(dst), OpcP, 8801 RM_opc_mem(secondary, dst), Con8or32(shift)); 8802 ins_pipe(ialu_mem_imm); 8803%} 8804 8805// Arithmetic Shift Right by variable 8806instruct sarL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8807%{ 8808 match(Set dst (RShiftL dst shift)); 8809 effect(KILL cr); 8810 8811 format %{ "sarq $dst, $shift" %} 8812 opcode(0xD3, 0x7); /* D3 /7 */ 8813 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8814 ins_pipe(ialu_reg_reg); 8815%} 8816 8817// Arithmetic Shift Right by variable 8818instruct sarL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8819%{ 8820 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8821 effect(KILL cr); 8822 8823 format %{ "sarq $dst, $shift" %} 8824 opcode(0xD3, 0x7); /* D3 /7 */ 8825 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8826 ins_pipe(ialu_mem_reg); 8827%} 8828 8829// Logical shift right by one 8830instruct shrL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8831%{ 8832 match(Set dst (URShiftL dst shift)); 8833 effect(KILL cr); 8834 8835 format %{ "shrq $dst, $shift" %} 8836 opcode(0xD1, 0x5); /* D1 /5 */ 8837 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst )); 8838 ins_pipe(ialu_reg); 8839%} 8840 8841// Logical shift right by one 8842instruct shrL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8843%{ 8844 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8845 effect(KILL cr); 8846 8847 format %{ "shrq $dst, $shift" %} 8848 opcode(0xD1, 0x5); /* D1 /5 */ 8849 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8850 ins_pipe(ialu_mem_imm); 8851%} 8852 8853// Logical Shift Right by 8-bit immediate 8854instruct shrL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8855%{ 8856 match(Set dst (URShiftL dst shift)); 8857 effect(KILL cr); 8858 8859 format %{ "shrq $dst, $shift" %} 8860 opcode(0xC1, 0x5); /* C1 /5 ib */ 8861 ins_encode(reg_opc_imm_wide(dst, shift)); 8862 ins_pipe(ialu_reg); 8863%} 8864 8865 8866// Logical Shift Right by 8-bit immediate 8867instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8868%{ 8869 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8870 effect(KILL cr); 8871 8872 format %{ "shrq $dst, $shift" %} 8873 opcode(0xC1, 0x5); /* C1 /5 ib */ 8874 ins_encode(REX_mem_wide(dst), OpcP, 8875 RM_opc_mem(secondary, dst), Con8or32(shift)); 8876 ins_pipe(ialu_mem_imm); 8877%} 8878 8879// Logical Shift Right by variable 8880instruct shrL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8881%{ 8882 match(Set dst (URShiftL dst shift)); 8883 effect(KILL cr); 8884 8885 format %{ "shrq $dst, $shift" %} 8886 opcode(0xD3, 0x5); /* D3 /5 */ 8887 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8888 ins_pipe(ialu_reg_reg); 8889%} 8890 8891// Logical Shift Right by variable 8892instruct shrL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8893%{ 8894 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8895 effect(KILL cr); 8896 8897 format %{ "shrq $dst, $shift" %} 8898 opcode(0xD3, 0x5); /* D3 /5 */ 8899 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8900 ins_pipe(ialu_mem_reg); 8901%} 8902 8903// Logical Shift Right by 24, followed by Arithmetic Shift Left by 24. 8904// This idiom is used by the compiler for the i2b bytecode. 8905instruct i2b(rRegI dst, rRegI src, immI_24 twentyfour) 8906%{ 8907 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour)); 8908 8909 format %{ "movsbl $dst, $src\t# i2b" %} 8910 opcode(0x0F, 0xBE); 8911 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8912 ins_pipe(ialu_reg_reg); 8913%} 8914 8915// Logical Shift Right by 16, followed by Arithmetic Shift Left by 16. 8916// This idiom is used by the compiler the i2s bytecode. 8917instruct i2s(rRegI dst, rRegI src, immI_16 sixteen) 8918%{ 8919 match(Set dst (RShiftI (LShiftI src sixteen) sixteen)); 8920 8921 format %{ "movswl $dst, $src\t# i2s" %} 8922 opcode(0x0F, 0xBF); 8923 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8924 ins_pipe(ialu_reg_reg); 8925%} 8926 8927// ROL/ROR instructions 8928 8929// ROL expand 8930instruct rolI_rReg_imm1(rRegI dst, rFlagsReg cr) %{ 8931 effect(KILL cr, USE_DEF dst); 8932 8933 format %{ "roll $dst" %} 8934 opcode(0xD1, 0x0); /* Opcode D1 /0 */ 8935 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8936 ins_pipe(ialu_reg); 8937%} 8938 8939instruct rolI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) %{ 8940 effect(USE_DEF dst, USE shift, KILL cr); 8941 8942 format %{ "roll $dst, $shift" %} 8943 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */ 8944 ins_encode( reg_opc_imm(dst, shift) ); 8945 ins_pipe(ialu_reg); 8946%} 8947 8948instruct rolI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr) 8949%{ 8950 effect(USE_DEF dst, USE shift, KILL cr); 8951 8952 format %{ "roll $dst, $shift" %} 8953 opcode(0xD3, 0x0); /* Opcode D3 /0 */ 8954 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8955 ins_pipe(ialu_reg_reg); 8956%} 8957// end of ROL expand 8958 8959// Rotate Left by one 8960instruct rolI_rReg_i1(rRegI dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr) 8961%{ 8962 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift))); 8963 8964 expand %{ 8965 rolI_rReg_imm1(dst, cr); 8966 %} 8967%} 8968 8969// Rotate Left by 8-bit immediate 8970instruct rolI_rReg_i8(rRegI dst, immI8 lshift, immI8 rshift, rFlagsReg cr) 8971%{ 8972 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 8973 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift))); 8974 8975 expand %{ 8976 rolI_rReg_imm8(dst, lshift, cr); 8977 %} 8978%} 8979 8980// Rotate Left by variable 8981instruct rolI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 8982%{ 8983 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI zero shift)))); 8984 8985 expand %{ 8986 rolI_rReg_CL(dst, shift, cr); 8987 %} 8988%} 8989 8990// Rotate Left by variable 8991instruct rolI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr) 8992%{ 8993 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI c32 shift)))); 8994 8995 expand %{ 8996 rolI_rReg_CL(dst, shift, cr); 8997 %} 8998%} 8999 9000// ROR expand 9001instruct rorI_rReg_imm1(rRegI dst, rFlagsReg cr) 9002%{ 9003 effect(USE_DEF dst, KILL cr); 9004 9005 format %{ "rorl $dst" %} 9006 opcode(0xD1, 0x1); /* D1 /1 */ 9007 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 9008 ins_pipe(ialu_reg); 9009%} 9010 9011instruct rorI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) 9012%{ 9013 effect(USE_DEF dst, USE shift, KILL cr); 9014 9015 format %{ "rorl $dst, $shift" %} 9016 opcode(0xC1, 0x1); /* C1 /1 ib */ 9017 ins_encode(reg_opc_imm(dst, shift)); 9018 ins_pipe(ialu_reg); 9019%} 9020 9021instruct rorI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr) 9022%{ 9023 effect(USE_DEF dst, USE shift, KILL cr); 9024 9025 format %{ "rorl $dst, $shift" %} 9026 opcode(0xD3, 0x1); /* D3 /1 */ 9027 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 9028 ins_pipe(ialu_reg_reg); 9029%} 9030// end of ROR expand 9031 9032// Rotate Right by one 9033instruct rorI_rReg_i1(rRegI dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr) 9034%{ 9035 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift))); 9036 9037 expand %{ 9038 rorI_rReg_imm1(dst, cr); 9039 %} 9040%} 9041 9042// Rotate Right by 8-bit immediate 9043instruct rorI_rReg_i8(rRegI dst, immI8 rshift, immI8 lshift, rFlagsReg cr) 9044%{ 9045 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9046 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift))); 9047 9048 expand %{ 9049 rorI_rReg_imm8(dst, rshift, cr); 9050 %} 9051%} 9052 9053// Rotate Right by variable 9054instruct rorI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 9055%{ 9056 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI zero shift)))); 9057 9058 expand %{ 9059 rorI_rReg_CL(dst, shift, cr); 9060 %} 9061%} 9062 9063// Rotate Right by variable 9064instruct rorI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr) 9065%{ 9066 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI c32 shift)))); 9067 9068 expand %{ 9069 rorI_rReg_CL(dst, shift, cr); 9070 %} 9071%} 9072 9073// for long rotate 9074// ROL expand 9075instruct rolL_rReg_imm1(rRegL dst, rFlagsReg cr) %{ 9076 effect(USE_DEF dst, KILL cr); 9077 9078 format %{ "rolq $dst" %} 9079 opcode(0xD1, 0x0); /* Opcode D1 /0 */ 9080 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9081 ins_pipe(ialu_reg); 9082%} 9083 9084instruct rolL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) %{ 9085 effect(USE_DEF dst, USE shift, KILL cr); 9086 9087 format %{ "rolq $dst, $shift" %} 9088 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */ 9089 ins_encode( reg_opc_imm_wide(dst, shift) ); 9090 ins_pipe(ialu_reg); 9091%} 9092 9093instruct rolL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr) 9094%{ 9095 effect(USE_DEF dst, USE shift, KILL cr); 9096 9097 format %{ "rolq $dst, $shift" %} 9098 opcode(0xD3, 0x0); /* Opcode D3 /0 */ 9099 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9100 ins_pipe(ialu_reg_reg); 9101%} 9102// end of ROL expand 9103 9104// Rotate Left by one 9105instruct rolL_rReg_i1(rRegL dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr) 9106%{ 9107 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift))); 9108 9109 expand %{ 9110 rolL_rReg_imm1(dst, cr); 9111 %} 9112%} 9113 9114// Rotate Left by 8-bit immediate 9115instruct rolL_rReg_i8(rRegL dst, immI8 lshift, immI8 rshift, rFlagsReg cr) 9116%{ 9117 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f)); 9118 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift))); 9119 9120 expand %{ 9121 rolL_rReg_imm8(dst, lshift, cr); 9122 %} 9123%} 9124 9125// Rotate Left by variable 9126instruct rolL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 9127%{ 9128 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI zero shift)))); 9129 9130 expand %{ 9131 rolL_rReg_CL(dst, shift, cr); 9132 %} 9133%} 9134 9135// Rotate Left by variable 9136instruct rolL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr) 9137%{ 9138 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI c64 shift)))); 9139 9140 expand %{ 9141 rolL_rReg_CL(dst, shift, cr); 9142 %} 9143%} 9144 9145// ROR expand 9146instruct rorL_rReg_imm1(rRegL dst, rFlagsReg cr) 9147%{ 9148 effect(USE_DEF dst, KILL cr); 9149 9150 format %{ "rorq $dst" %} 9151 opcode(0xD1, 0x1); /* D1 /1 */ 9152 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9153 ins_pipe(ialu_reg); 9154%} 9155 9156instruct rorL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) 9157%{ 9158 effect(USE_DEF dst, USE shift, KILL cr); 9159 9160 format %{ "rorq $dst, $shift" %} 9161 opcode(0xC1, 0x1); /* C1 /1 ib */ 9162 ins_encode(reg_opc_imm_wide(dst, shift)); 9163 ins_pipe(ialu_reg); 9164%} 9165 9166instruct rorL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr) 9167%{ 9168 effect(USE_DEF dst, USE shift, KILL cr); 9169 9170 format %{ "rorq $dst, $shift" %} 9171 opcode(0xD3, 0x1); /* D3 /1 */ 9172 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9173 ins_pipe(ialu_reg_reg); 9174%} 9175// end of ROR expand 9176 9177// Rotate Right by one 9178instruct rorL_rReg_i1(rRegL dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr) 9179%{ 9180 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift))); 9181 9182 expand %{ 9183 rorL_rReg_imm1(dst, cr); 9184 %} 9185%} 9186 9187// Rotate Right by 8-bit immediate 9188instruct rorL_rReg_i8(rRegL dst, immI8 rshift, immI8 lshift, rFlagsReg cr) 9189%{ 9190 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f)); 9191 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift))); 9192 9193 expand %{ 9194 rorL_rReg_imm8(dst, rshift, cr); 9195 %} 9196%} 9197 9198// Rotate Right by variable 9199instruct rorL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 9200%{ 9201 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI zero shift)))); 9202 9203 expand %{ 9204 rorL_rReg_CL(dst, shift, cr); 9205 %} 9206%} 9207 9208// Rotate Right by variable 9209instruct rorL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr) 9210%{ 9211 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI c64 shift)))); 9212 9213 expand %{ 9214 rorL_rReg_CL(dst, shift, cr); 9215 %} 9216%} 9217 9218// Logical Instructions 9219 9220// Integer Logical Instructions 9221 9222// And Instructions 9223// And Register with Register 9224instruct andI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9225%{ 9226 match(Set dst (AndI dst src)); 9227 effect(KILL cr); 9228 9229 format %{ "andl $dst, $src\t# int" %} 9230 opcode(0x23); 9231 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9232 ins_pipe(ialu_reg_reg); 9233%} 9234 9235// And Register with Immediate 255 9236instruct andI_rReg_imm255(rRegI dst, immI_255 src) 9237%{ 9238 match(Set dst (AndI dst src)); 9239 9240 format %{ "movzbl $dst, $dst\t# int & 0xFF" %} 9241 opcode(0x0F, 0xB6); 9242 ins_encode(REX_reg_breg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9243 ins_pipe(ialu_reg); 9244%} 9245 9246// And Register with Immediate 255 and promote to long 9247instruct andI2L_rReg_imm255(rRegL dst, rRegI src, immI_255 mask) 9248%{ 9249 match(Set dst (ConvI2L (AndI src mask))); 9250 9251 format %{ "movzbl $dst, $src\t# int & 0xFF -> long" %} 9252 opcode(0x0F, 0xB6); 9253 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 9254 ins_pipe(ialu_reg); 9255%} 9256 9257// And Register with Immediate 65535 9258instruct andI_rReg_imm65535(rRegI dst, immI_65535 src) 9259%{ 9260 match(Set dst (AndI dst src)); 9261 9262 format %{ "movzwl $dst, $dst\t# int & 0xFFFF" %} 9263 opcode(0x0F, 0xB7); 9264 ins_encode(REX_reg_reg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9265 ins_pipe(ialu_reg); 9266%} 9267 9268// And Register with Immediate 65535 and promote to long 9269instruct andI2L_rReg_imm65535(rRegL dst, rRegI src, immI_65535 mask) 9270%{ 9271 match(Set dst (ConvI2L (AndI src mask))); 9272 9273 format %{ "movzwl $dst, $src\t# int & 0xFFFF -> long" %} 9274 opcode(0x0F, 0xB7); 9275 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 9276 ins_pipe(ialu_reg); 9277%} 9278 9279// And Register with Immediate 9280instruct andI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9281%{ 9282 match(Set dst (AndI dst src)); 9283 effect(KILL cr); 9284 9285 format %{ "andl $dst, $src\t# int" %} 9286 opcode(0x81, 0x04); /* Opcode 81 /4 */ 9287 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9288 ins_pipe(ialu_reg); 9289%} 9290 9291// And Register with Memory 9292instruct andI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9293%{ 9294 match(Set dst (AndI dst (LoadI src))); 9295 effect(KILL cr); 9296 9297 ins_cost(125); 9298 format %{ "andl $dst, $src\t# int" %} 9299 opcode(0x23); 9300 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9301 ins_pipe(ialu_reg_mem); 9302%} 9303 9304// And Memory with Register 9305instruct andI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9306%{ 9307 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 9308 effect(KILL cr); 9309 9310 ins_cost(150); 9311 format %{ "andl $dst, $src\t# int" %} 9312 opcode(0x21); /* Opcode 21 /r */ 9313 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9314 ins_pipe(ialu_mem_reg); 9315%} 9316 9317// And Memory with Immediate 9318instruct andI_mem_imm(memory dst, immI src, rFlagsReg cr) 9319%{ 9320 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 9321 effect(KILL cr); 9322 9323 ins_cost(125); 9324 format %{ "andl $dst, $src\t# int" %} 9325 opcode(0x81, 0x4); /* Opcode 81 /4 id */ 9326 ins_encode(REX_mem(dst), OpcSE(src), 9327 RM_opc_mem(secondary, dst), Con8or32(src)); 9328 ins_pipe(ialu_mem_imm); 9329%} 9330 9331// Or Instructions 9332// Or Register with Register 9333instruct orI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9334%{ 9335 match(Set dst (OrI dst src)); 9336 effect(KILL cr); 9337 9338 format %{ "orl $dst, $src\t# int" %} 9339 opcode(0x0B); 9340 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9341 ins_pipe(ialu_reg_reg); 9342%} 9343 9344// Or Register with Immediate 9345instruct orI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9346%{ 9347 match(Set dst (OrI dst src)); 9348 effect(KILL cr); 9349 9350 format %{ "orl $dst, $src\t# int" %} 9351 opcode(0x81, 0x01); /* Opcode 81 /1 id */ 9352 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9353 ins_pipe(ialu_reg); 9354%} 9355 9356// Or Register with Memory 9357instruct orI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9358%{ 9359 match(Set dst (OrI dst (LoadI src))); 9360 effect(KILL cr); 9361 9362 ins_cost(125); 9363 format %{ "orl $dst, $src\t# int" %} 9364 opcode(0x0B); 9365 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9366 ins_pipe(ialu_reg_mem); 9367%} 9368 9369// Or Memory with Register 9370instruct orI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9371%{ 9372 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9373 effect(KILL cr); 9374 9375 ins_cost(150); 9376 format %{ "orl $dst, $src\t# int" %} 9377 opcode(0x09); /* Opcode 09 /r */ 9378 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9379 ins_pipe(ialu_mem_reg); 9380%} 9381 9382// Or Memory with Immediate 9383instruct orI_mem_imm(memory dst, immI src, rFlagsReg cr) 9384%{ 9385 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9386 effect(KILL cr); 9387 9388 ins_cost(125); 9389 format %{ "orl $dst, $src\t# int" %} 9390 opcode(0x81, 0x1); /* Opcode 81 /1 id */ 9391 ins_encode(REX_mem(dst), OpcSE(src), 9392 RM_opc_mem(secondary, dst), Con8or32(src)); 9393 ins_pipe(ialu_mem_imm); 9394%} 9395 9396// Xor Instructions 9397// Xor Register with Register 9398instruct xorI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9399%{ 9400 match(Set dst (XorI dst src)); 9401 effect(KILL cr); 9402 9403 format %{ "xorl $dst, $src\t# int" %} 9404 opcode(0x33); 9405 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9406 ins_pipe(ialu_reg_reg); 9407%} 9408 9409// Xor Register with Immediate -1 9410instruct xorI_rReg_im1(rRegI dst, immI_M1 imm) %{ 9411 match(Set dst (XorI dst imm)); 9412 9413 format %{ "not $dst" %} 9414 ins_encode %{ 9415 __ notl($dst$$Register); 9416 %} 9417 ins_pipe(ialu_reg); 9418%} 9419 9420// Xor Register with Immediate 9421instruct xorI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9422%{ 9423 match(Set dst (XorI dst src)); 9424 effect(KILL cr); 9425 9426 format %{ "xorl $dst, $src\t# int" %} 9427 opcode(0x81, 0x06); /* Opcode 81 /6 id */ 9428 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9429 ins_pipe(ialu_reg); 9430%} 9431 9432// Xor Register with Memory 9433instruct xorI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9434%{ 9435 match(Set dst (XorI dst (LoadI src))); 9436 effect(KILL cr); 9437 9438 ins_cost(125); 9439 format %{ "xorl $dst, $src\t# int" %} 9440 opcode(0x33); 9441 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9442 ins_pipe(ialu_reg_mem); 9443%} 9444 9445// Xor Memory with Register 9446instruct xorI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9447%{ 9448 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9449 effect(KILL cr); 9450 9451 ins_cost(150); 9452 format %{ "xorl $dst, $src\t# int" %} 9453 opcode(0x31); /* Opcode 31 /r */ 9454 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9455 ins_pipe(ialu_mem_reg); 9456%} 9457 9458// Xor Memory with Immediate 9459instruct xorI_mem_imm(memory dst, immI src, rFlagsReg cr) 9460%{ 9461 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9462 effect(KILL cr); 9463 9464 ins_cost(125); 9465 format %{ "xorl $dst, $src\t# int" %} 9466 opcode(0x81, 0x6); /* Opcode 81 /6 id */ 9467 ins_encode(REX_mem(dst), OpcSE(src), 9468 RM_opc_mem(secondary, dst), Con8or32(src)); 9469 ins_pipe(ialu_mem_imm); 9470%} 9471 9472 9473// Long Logical Instructions 9474 9475// And Instructions 9476// And Register with Register 9477instruct andL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9478%{ 9479 match(Set dst (AndL dst src)); 9480 effect(KILL cr); 9481 9482 format %{ "andq $dst, $src\t# long" %} 9483 opcode(0x23); 9484 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9485 ins_pipe(ialu_reg_reg); 9486%} 9487 9488// And Register with Immediate 255 9489instruct andL_rReg_imm255(rRegL dst, immL_255 src) 9490%{ 9491 match(Set dst (AndL dst src)); 9492 9493 format %{ "movzbq $dst, $dst\t# long & 0xFF" %} 9494 opcode(0x0F, 0xB6); 9495 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9496 ins_pipe(ialu_reg); 9497%} 9498 9499// And Register with Immediate 65535 9500instruct andL_rReg_imm65535(rRegL dst, immL_65535 src) 9501%{ 9502 match(Set dst (AndL dst src)); 9503 9504 format %{ "movzwq $dst, $dst\t# long & 0xFFFF" %} 9505 opcode(0x0F, 0xB7); 9506 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9507 ins_pipe(ialu_reg); 9508%} 9509 9510// And Register with Immediate 9511instruct andL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9512%{ 9513 match(Set dst (AndL dst src)); 9514 effect(KILL cr); 9515 9516 format %{ "andq $dst, $src\t# long" %} 9517 opcode(0x81, 0x04); /* Opcode 81 /4 */ 9518 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9519 ins_pipe(ialu_reg); 9520%} 9521 9522// And Register with Memory 9523instruct andL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9524%{ 9525 match(Set dst (AndL dst (LoadL src))); 9526 effect(KILL cr); 9527 9528 ins_cost(125); 9529 format %{ "andq $dst, $src\t# long" %} 9530 opcode(0x23); 9531 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9532 ins_pipe(ialu_reg_mem); 9533%} 9534 9535// And Memory with Register 9536instruct andL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9537%{ 9538 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9539 effect(KILL cr); 9540 9541 ins_cost(150); 9542 format %{ "andq $dst, $src\t# long" %} 9543 opcode(0x21); /* Opcode 21 /r */ 9544 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9545 ins_pipe(ialu_mem_reg); 9546%} 9547 9548// And Memory with Immediate 9549instruct andL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9550%{ 9551 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9552 effect(KILL cr); 9553 9554 ins_cost(125); 9555 format %{ "andq $dst, $src\t# long" %} 9556 opcode(0x81, 0x4); /* Opcode 81 /4 id */ 9557 ins_encode(REX_mem_wide(dst), OpcSE(src), 9558 RM_opc_mem(secondary, dst), Con8or32(src)); 9559 ins_pipe(ialu_mem_imm); 9560%} 9561 9562// Or Instructions 9563// Or Register with Register 9564instruct orL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9565%{ 9566 match(Set dst (OrL dst src)); 9567 effect(KILL cr); 9568 9569 format %{ "orq $dst, $src\t# long" %} 9570 opcode(0x0B); 9571 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9572 ins_pipe(ialu_reg_reg); 9573%} 9574 9575// Use any_RegP to match R15 (TLS register) without spilling. 9576instruct orL_rReg_castP2X(rRegL dst, any_RegP src, rFlagsReg cr) %{ 9577 match(Set dst (OrL dst (CastP2X src))); 9578 effect(KILL cr); 9579 9580 format %{ "orq $dst, $src\t# long" %} 9581 opcode(0x0B); 9582 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9583 ins_pipe(ialu_reg_reg); 9584%} 9585 9586 9587// Or Register with Immediate 9588instruct orL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9589%{ 9590 match(Set dst (OrL dst src)); 9591 effect(KILL cr); 9592 9593 format %{ "orq $dst, $src\t# long" %} 9594 opcode(0x81, 0x01); /* Opcode 81 /1 id */ 9595 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9596 ins_pipe(ialu_reg); 9597%} 9598 9599// Or Register with Memory 9600instruct orL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9601%{ 9602 match(Set dst (OrL dst (LoadL src))); 9603 effect(KILL cr); 9604 9605 ins_cost(125); 9606 format %{ "orq $dst, $src\t# long" %} 9607 opcode(0x0B); 9608 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9609 ins_pipe(ialu_reg_mem); 9610%} 9611 9612// Or Memory with Register 9613instruct orL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9614%{ 9615 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9616 effect(KILL cr); 9617 9618 ins_cost(150); 9619 format %{ "orq $dst, $src\t# long" %} 9620 opcode(0x09); /* Opcode 09 /r */ 9621 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9622 ins_pipe(ialu_mem_reg); 9623%} 9624 9625// Or Memory with Immediate 9626instruct orL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9627%{ 9628 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9629 effect(KILL cr); 9630 9631 ins_cost(125); 9632 format %{ "orq $dst, $src\t# long" %} 9633 opcode(0x81, 0x1); /* Opcode 81 /1 id */ 9634 ins_encode(REX_mem_wide(dst), OpcSE(src), 9635 RM_opc_mem(secondary, dst), Con8or32(src)); 9636 ins_pipe(ialu_mem_imm); 9637%} 9638 9639// Xor Instructions 9640// Xor Register with Register 9641instruct xorL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9642%{ 9643 match(Set dst (XorL dst src)); 9644 effect(KILL cr); 9645 9646 format %{ "xorq $dst, $src\t# long" %} 9647 opcode(0x33); 9648 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9649 ins_pipe(ialu_reg_reg); 9650%} 9651 9652// Xor Register with Immediate -1 9653instruct xorL_rReg_im1(rRegL dst, immL_M1 imm) %{ 9654 match(Set dst (XorL dst imm)); 9655 9656 format %{ "notq $dst" %} 9657 ins_encode %{ 9658 __ notq($dst$$Register); 9659 %} 9660 ins_pipe(ialu_reg); 9661%} 9662 9663// Xor Register with Immediate 9664instruct xorL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9665%{ 9666 match(Set dst (XorL dst src)); 9667 effect(KILL cr); 9668 9669 format %{ "xorq $dst, $src\t# long" %} 9670 opcode(0x81, 0x06); /* Opcode 81 /6 id */ 9671 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9672 ins_pipe(ialu_reg); 9673%} 9674 9675// Xor Register with Memory 9676instruct xorL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9677%{ 9678 match(Set dst (XorL dst (LoadL src))); 9679 effect(KILL cr); 9680 9681 ins_cost(125); 9682 format %{ "xorq $dst, $src\t# long" %} 9683 opcode(0x33); 9684 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9685 ins_pipe(ialu_reg_mem); 9686%} 9687 9688// Xor Memory with Register 9689instruct xorL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9690%{ 9691 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 9692 effect(KILL cr); 9693 9694 ins_cost(150); 9695 format %{ "xorq $dst, $src\t# long" %} 9696 opcode(0x31); /* Opcode 31 /r */ 9697 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9698 ins_pipe(ialu_mem_reg); 9699%} 9700 9701// Xor Memory with Immediate 9702instruct xorL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9703%{ 9704 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 9705 effect(KILL cr); 9706 9707 ins_cost(125); 9708 format %{ "xorq $dst, $src\t# long" %} 9709 opcode(0x81, 0x6); /* Opcode 81 /6 id */ 9710 ins_encode(REX_mem_wide(dst), OpcSE(src), 9711 RM_opc_mem(secondary, dst), Con8or32(src)); 9712 ins_pipe(ialu_mem_imm); 9713%} 9714 9715// Convert Int to Boolean 9716instruct convI2B(rRegI dst, rRegI src, rFlagsReg cr) 9717%{ 9718 match(Set dst (Conv2B src)); 9719 effect(KILL cr); 9720 9721 format %{ "testl $src, $src\t# ci2b\n\t" 9722 "setnz $dst\n\t" 9723 "movzbl $dst, $dst" %} 9724 ins_encode(REX_reg_reg(src, src), opc_reg_reg(0x85, src, src), // testl 9725 setNZ_reg(dst), 9726 REX_reg_breg(dst, dst), // movzbl 9727 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst)); 9728 ins_pipe(pipe_slow); // XXX 9729%} 9730 9731// Convert Pointer to Boolean 9732instruct convP2B(rRegI dst, rRegP src, rFlagsReg cr) 9733%{ 9734 match(Set dst (Conv2B src)); 9735 effect(KILL cr); 9736 9737 format %{ "testq $src, $src\t# cp2b\n\t" 9738 "setnz $dst\n\t" 9739 "movzbl $dst, $dst" %} 9740 ins_encode(REX_reg_reg_wide(src, src), opc_reg_reg(0x85, src, src), // testq 9741 setNZ_reg(dst), 9742 REX_reg_breg(dst, dst), // movzbl 9743 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst)); 9744 ins_pipe(pipe_slow); // XXX 9745%} 9746 9747instruct cmpLTMask(rRegI dst, rRegI p, rRegI q, rFlagsReg cr) 9748%{ 9749 match(Set dst (CmpLTMask p q)); 9750 effect(KILL cr); 9751 9752 ins_cost(400); // XXX 9753 format %{ "cmpl $p, $q\t# cmpLTMask\n\t" 9754 "setlt $dst\n\t" 9755 "movzbl $dst, $dst\n\t" 9756 "negl $dst" %} 9757 ins_encode(REX_reg_reg(p, q), opc_reg_reg(0x3B, p, q), // cmpl 9758 setLT_reg(dst), 9759 REX_reg_breg(dst, dst), // movzbl 9760 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst), 9761 neg_reg(dst)); 9762 ins_pipe(pipe_slow); 9763%} 9764 9765instruct cmpLTMask0(rRegI dst, immI0 zero, rFlagsReg cr) 9766%{ 9767 match(Set dst (CmpLTMask dst zero)); 9768 effect(KILL cr); 9769 9770 ins_cost(100); // XXX 9771 format %{ "sarl $dst, #31\t# cmpLTMask0" %} 9772 opcode(0xC1, 0x7); /* C1 /7 ib */ 9773 ins_encode(reg_opc_imm(dst, 0x1F)); 9774 ins_pipe(ialu_reg); 9775%} 9776 9777 9778instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y, 9779 rRegI tmp, 9780 rFlagsReg cr) 9781%{ 9782 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q))); 9783 effect(TEMP tmp, KILL cr); 9784 9785 ins_cost(400); // XXX 9786 format %{ "subl $p, $q\t# cadd_cmpLTMask1\n\t" 9787 "sbbl $tmp, $tmp\n\t" 9788 "andl $tmp, $y\n\t" 9789 "addl $p, $tmp" %} 9790 ins_encode(enc_cmpLTP(p, q, y, tmp)); 9791 ins_pipe(pipe_cmplt); 9792%} 9793 9794/* If I enable this, I encourage spilling in the inner loop of compress. 9795instruct cadd_cmpLTMask_mem( rRegI p, rRegI q, memory y, rRegI tmp, rFlagsReg cr ) 9796%{ 9797 match(Set p (AddI (AndI (CmpLTMask p q) (LoadI y)) (SubI p q))); 9798 effect( TEMP tmp, KILL cr ); 9799 ins_cost(400); 9800 9801 format %{ "SUB $p,$q\n\t" 9802 "SBB RCX,RCX\n\t" 9803 "AND RCX,$y\n\t" 9804 "ADD $p,RCX" %} 9805 ins_encode( enc_cmpLTP_mem(p,q,y,tmp) ); 9806%} 9807*/ 9808 9809//---------- FP Instructions------------------------------------------------ 9810 9811instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2) 9812%{ 9813 match(Set cr (CmpF src1 src2)); 9814 9815 ins_cost(145); 9816 format %{ "ucomiss $src1, $src2\n\t" 9817 "jnp,s exit\n\t" 9818 "pushfq\t# saw NaN, set CF\n\t" 9819 "andq [rsp], #0xffffff2b\n\t" 9820 "popfq\n" 9821 "exit: nop\t# avoid branch to branch" %} 9822 opcode(0x0F, 0x2E); 9823 ins_encode(REX_reg_reg(src1, src2), OpcP, OpcS, reg_reg(src1, src2), 9824 cmpfp_fixup); 9825 ins_pipe(pipe_slow); 9826%} 9827 9828instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{ 9829 match(Set cr (CmpF src1 src2)); 9830 9831 ins_cost(145); 9832 format %{ "ucomiss $src1, $src2" %} 9833 ins_encode %{ 9834 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9835 %} 9836 ins_pipe(pipe_slow); 9837%} 9838 9839instruct cmpF_cc_mem(rFlagsRegU cr, regF src1, memory src2) 9840%{ 9841 match(Set cr (CmpF src1 (LoadF src2))); 9842 9843 ins_cost(145); 9844 format %{ "ucomiss $src1, $src2\n\t" 9845 "jnp,s exit\n\t" 9846 "pushfq\t# saw NaN, set CF\n\t" 9847 "andq [rsp], #0xffffff2b\n\t" 9848 "popfq\n" 9849 "exit: nop\t# avoid branch to branch" %} 9850 opcode(0x0F, 0x2E); 9851 ins_encode(REX_reg_mem(src1, src2), OpcP, OpcS, reg_mem(src1, src2), 9852 cmpfp_fixup); 9853 ins_pipe(pipe_slow); 9854%} 9855 9856instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{ 9857 match(Set cr (CmpF src1 (LoadF src2))); 9858 9859 ins_cost(100); 9860 format %{ "ucomiss $src1, $src2" %} 9861 opcode(0x0F, 0x2E); 9862 ins_encode(REX_reg_mem(src1, src2), OpcP, OpcS, reg_mem(src1, src2)); 9863 ins_pipe(pipe_slow); 9864%} 9865 9866instruct cmpF_cc_imm(rFlagsRegU cr, regF src1, immF src2) 9867%{ 9868 match(Set cr (CmpF src1 src2)); 9869 9870 ins_cost(145); 9871 format %{ "ucomiss $src1, $src2\n\t" 9872 "jnp,s exit\n\t" 9873 "pushfq\t# saw NaN, set CF\n\t" 9874 "andq [rsp], #0xffffff2b\n\t" 9875 "popfq\n" 9876 "exit: nop\t# avoid branch to branch" %} 9877 opcode(0x0F, 0x2E); 9878 ins_encode(REX_reg_mem(src1, src2), OpcP, OpcS, load_immF(src1, src2), 9879 cmpfp_fixup); 9880 ins_pipe(pipe_slow); 9881%} 9882 9883instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src1, immF src2) %{ 9884 match(Set cr (CmpF src1 src2)); 9885 9886 ins_cost(100); 9887 format %{ "ucomiss $src1, $src2" %} 9888 opcode(0x0F, 0x2E); 9889 ins_encode(REX_reg_mem(src1, src2), OpcP, OpcS, load_immF(src1, src2)); 9890 ins_pipe(pipe_slow); 9891%} 9892 9893instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2) 9894%{ 9895 match(Set cr (CmpD src1 src2)); 9896 9897 ins_cost(145); 9898 format %{ "ucomisd $src1, $src2\n\t" 9899 "jnp,s exit\n\t" 9900 "pushfq\t# saw NaN, set CF\n\t" 9901 "andq [rsp], #0xffffff2b\n\t" 9902 "popfq\n" 9903 "exit: nop\t# avoid branch to branch" %} 9904 opcode(0x66, 0x0F, 0x2E); 9905 ins_encode(OpcP, REX_reg_reg(src1, src2), OpcS, OpcT, reg_reg(src1, src2), 9906 cmpfp_fixup); 9907 ins_pipe(pipe_slow); 9908%} 9909 9910instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{ 9911 match(Set cr (CmpD src1 src2)); 9912 9913 ins_cost(100); 9914 format %{ "ucomisd $src1, $src2 test" %} 9915 ins_encode %{ 9916 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9917 %} 9918 ins_pipe(pipe_slow); 9919%} 9920 9921instruct cmpD_cc_mem(rFlagsRegU cr, regD src1, memory src2) 9922%{ 9923 match(Set cr (CmpD src1 (LoadD src2))); 9924 9925 ins_cost(145); 9926 format %{ "ucomisd $src1, $src2\n\t" 9927 "jnp,s exit\n\t" 9928 "pushfq\t# saw NaN, set CF\n\t" 9929 "andq [rsp], #0xffffff2b\n\t" 9930 "popfq\n" 9931 "exit: nop\t# avoid branch to branch" %} 9932 opcode(0x66, 0x0F, 0x2E); 9933 ins_encode(OpcP, REX_reg_mem(src1, src2), OpcS, OpcT, reg_mem(src1, src2), 9934 cmpfp_fixup); 9935 ins_pipe(pipe_slow); 9936%} 9937 9938instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{ 9939 match(Set cr (CmpD src1 (LoadD src2))); 9940 9941 ins_cost(100); 9942 format %{ "ucomisd $src1, $src2" %} 9943 opcode(0x66, 0x0F, 0x2E); 9944 ins_encode(OpcP, REX_reg_mem(src1, src2), OpcS, OpcT, reg_mem(src1, src2)); 9945 ins_pipe(pipe_slow); 9946%} 9947 9948instruct cmpD_cc_imm(rFlagsRegU cr, regD src1, immD src2) 9949%{ 9950 match(Set cr (CmpD src1 src2)); 9951 9952 ins_cost(145); 9953 format %{ "ucomisd $src1, [$src2]\n\t" 9954 "jnp,s exit\n\t" 9955 "pushfq\t# saw NaN, set CF\n\t" 9956 "andq [rsp], #0xffffff2b\n\t" 9957 "popfq\n" 9958 "exit: nop\t# avoid branch to branch" %} 9959 opcode(0x66, 0x0F, 0x2E); 9960 ins_encode(OpcP, REX_reg_mem(src1, src2), OpcS, OpcT, load_immD(src1, src2), 9961 cmpfp_fixup); 9962 ins_pipe(pipe_slow); 9963%} 9964 9965instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src1, immD src2) %{ 9966 match(Set cr (CmpD src1 src2)); 9967 9968 ins_cost(100); 9969 format %{ "ucomisd $src1, [$src2]" %} 9970 opcode(0x66, 0x0F, 0x2E); 9971 ins_encode(OpcP, REX_reg_mem(src1, src2), OpcS, OpcT, load_immD(src1, src2)); 9972 ins_pipe(pipe_slow); 9973%} 9974 9975// Compare into -1,0,1 9976instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr) 9977%{ 9978 match(Set dst (CmpF3 src1 src2)); 9979 effect(KILL cr); 9980 9981 ins_cost(275); 9982 format %{ "ucomiss $src1, $src2\n\t" 9983 "movl $dst, #-1\n\t" 9984 "jp,s done\n\t" 9985 "jb,s done\n\t" 9986 "setne $dst\n\t" 9987 "movzbl $dst, $dst\n" 9988 "done:" %} 9989 9990 opcode(0x0F, 0x2E); 9991 ins_encode(REX_reg_reg(src1, src2), OpcP, OpcS, reg_reg(src1, src2), 9992 cmpfp3(dst)); 9993 ins_pipe(pipe_slow); 9994%} 9995 9996// Compare into -1,0,1 9997instruct cmpF_mem(rRegI dst, regF src1, memory src2, rFlagsReg cr) 9998%{ 9999 match(Set dst (CmpF3 src1 (LoadF src2))); 10000 effect(KILL cr); 10001 10002 ins_cost(275); 10003 format %{ "ucomiss $src1, $src2\n\t" 10004 "movl $dst, #-1\n\t" 10005 "jp,s done\n\t" 10006 "jb,s done\n\t" 10007 "setne $dst\n\t" 10008 "movzbl $dst, $dst\n" 10009 "done:" %} 10010 10011 opcode(0x0F, 0x2E); 10012 ins_encode(REX_reg_mem(src1, src2), OpcP, OpcS, reg_mem(src1, src2), 10013 cmpfp3(dst)); 10014 ins_pipe(pipe_slow); 10015%} 10016 10017// Compare into -1,0,1 10018instruct cmpF_imm(rRegI dst, regF src1, immF src2, rFlagsReg cr) 10019%{ 10020 match(Set dst (CmpF3 src1 src2)); 10021 effect(KILL cr); 10022 10023 ins_cost(275); 10024 format %{ "ucomiss $src1, [$src2]\n\t" 10025 "movl $dst, #-1\n\t" 10026 "jp,s done\n\t" 10027 "jb,s done\n\t" 10028 "setne $dst\n\t" 10029 "movzbl $dst, $dst\n" 10030 "done:" %} 10031 10032 opcode(0x0F, 0x2E); 10033 ins_encode(REX_reg_mem(src1, src2), OpcP, OpcS, load_immF(src1, src2), 10034 cmpfp3(dst)); 10035 ins_pipe(pipe_slow); 10036%} 10037 10038// Compare into -1,0,1 10039instruct cmpD_reg(rRegI dst, regD src1, regD src2, rFlagsReg cr) 10040%{ 10041 match(Set dst (CmpD3 src1 src2)); 10042 effect(KILL cr); 10043 10044 ins_cost(275); 10045 format %{ "ucomisd $src1, $src2\n\t" 10046 "movl $dst, #-1\n\t" 10047 "jp,s done\n\t" 10048 "jb,s done\n\t" 10049 "setne $dst\n\t" 10050 "movzbl $dst, $dst\n" 10051 "done:" %} 10052 10053 opcode(0x66, 0x0F, 0x2E); 10054 ins_encode(OpcP, REX_reg_reg(src1, src2), OpcS, OpcT, reg_reg(src1, src2), 10055 cmpfp3(dst)); 10056 ins_pipe(pipe_slow); 10057%} 10058 10059// Compare into -1,0,1 10060instruct cmpD_mem(rRegI dst, regD src1, memory src2, rFlagsReg cr) 10061%{ 10062 match(Set dst (CmpD3 src1 (LoadD src2))); 10063 effect(KILL cr); 10064 10065 ins_cost(275); 10066 format %{ "ucomisd $src1, $src2\n\t" 10067 "movl $dst, #-1\n\t" 10068 "jp,s done\n\t" 10069 "jb,s done\n\t" 10070 "setne $dst\n\t" 10071 "movzbl $dst, $dst\n" 10072 "done:" %} 10073 10074 opcode(0x66, 0x0F, 0x2E); 10075 ins_encode(OpcP, REX_reg_mem(src1, src2), OpcS, OpcT, reg_mem(src1, src2), 10076 cmpfp3(dst)); 10077 ins_pipe(pipe_slow); 10078%} 10079 10080// Compare into -1,0,1 10081instruct cmpD_imm(rRegI dst, regD src1, immD src2, rFlagsReg cr) 10082%{ 10083 match(Set dst (CmpD3 src1 src2)); 10084 effect(KILL cr); 10085 10086 ins_cost(275); 10087 format %{ "ucomisd $src1, [$src2]\n\t" 10088 "movl $dst, #-1\n\t" 10089 "jp,s done\n\t" 10090 "jb,s done\n\t" 10091 "setne $dst\n\t" 10092 "movzbl $dst, $dst\n" 10093 "done:" %} 10094 10095 opcode(0x66, 0x0F, 0x2E); 10096 ins_encode(OpcP, REX_reg_mem(src1, src2), OpcS, OpcT, load_immD(src1, src2), 10097 cmpfp3(dst)); 10098 ins_pipe(pipe_slow); 10099%} 10100 10101instruct addF_reg(regF dst, regF src) 10102%{ 10103 match(Set dst (AddF dst src)); 10104 10105 format %{ "addss $dst, $src" %} 10106 ins_cost(150); // XXX 10107 opcode(0xF3, 0x0F, 0x58); 10108 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src)); 10109 ins_pipe(pipe_slow); 10110%} 10111 10112instruct addF_mem(regF dst, memory src) 10113%{ 10114 match(Set dst (AddF dst (LoadF src))); 10115 10116 format %{ "addss $dst, $src" %} 10117 ins_cost(150); // XXX 10118 opcode(0xF3, 0x0F, 0x58); 10119 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 10120 ins_pipe(pipe_slow); 10121%} 10122 10123instruct addF_imm(regF dst, immF src) 10124%{ 10125 match(Set dst (AddF dst src)); 10126 10127 format %{ "addss $dst, [$src]" %} 10128 ins_cost(150); // XXX 10129 opcode(0xF3, 0x0F, 0x58); 10130 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immF(dst, src)); 10131 ins_pipe(pipe_slow); 10132%} 10133 10134instruct addD_reg(regD dst, regD src) 10135%{ 10136 match(Set dst (AddD dst src)); 10137 10138 format %{ "addsd $dst, $src" %} 10139 ins_cost(150); // XXX 10140 opcode(0xF2, 0x0F, 0x58); 10141 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src)); 10142 ins_pipe(pipe_slow); 10143%} 10144 10145instruct addD_mem(regD dst, memory src) 10146%{ 10147 match(Set dst (AddD dst (LoadD src))); 10148 10149 format %{ "addsd $dst, $src" %} 10150 ins_cost(150); // XXX 10151 opcode(0xF2, 0x0F, 0x58); 10152 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 10153 ins_pipe(pipe_slow); 10154%} 10155 10156instruct addD_imm(regD dst, immD src) 10157%{ 10158 match(Set dst (AddD dst src)); 10159 10160 format %{ "addsd $dst, [$src]" %} 10161 ins_cost(150); // XXX 10162 opcode(0xF2, 0x0F, 0x58); 10163 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immD(dst, src)); 10164 ins_pipe(pipe_slow); 10165%} 10166 10167instruct subF_reg(regF dst, regF src) 10168%{ 10169 match(Set dst (SubF dst src)); 10170 10171 format %{ "subss $dst, $src" %} 10172 ins_cost(150); // XXX 10173 opcode(0xF3, 0x0F, 0x5C); 10174 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src)); 10175 ins_pipe(pipe_slow); 10176%} 10177 10178instruct subF_mem(regF dst, memory src) 10179%{ 10180 match(Set dst (SubF dst (LoadF src))); 10181 10182 format %{ "subss $dst, $src" %} 10183 ins_cost(150); // XXX 10184 opcode(0xF3, 0x0F, 0x5C); 10185 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 10186 ins_pipe(pipe_slow); 10187%} 10188 10189instruct subF_imm(regF dst, immF src) 10190%{ 10191 match(Set dst (SubF dst src)); 10192 10193 format %{ "subss $dst, [$src]" %} 10194 ins_cost(150); // XXX 10195 opcode(0xF3, 0x0F, 0x5C); 10196 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immF(dst, src)); 10197 ins_pipe(pipe_slow); 10198%} 10199 10200instruct subD_reg(regD dst, regD src) 10201%{ 10202 match(Set dst (SubD dst src)); 10203 10204 format %{ "subsd $dst, $src" %} 10205 ins_cost(150); // XXX 10206 opcode(0xF2, 0x0F, 0x5C); 10207 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src)); 10208 ins_pipe(pipe_slow); 10209%} 10210 10211instruct subD_mem(regD dst, memory src) 10212%{ 10213 match(Set dst (SubD dst (LoadD src))); 10214 10215 format %{ "subsd $dst, $src" %} 10216 ins_cost(150); // XXX 10217 opcode(0xF2, 0x0F, 0x5C); 10218 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 10219 ins_pipe(pipe_slow); 10220%} 10221 10222instruct subD_imm(regD dst, immD src) 10223%{ 10224 match(Set dst (SubD dst src)); 10225 10226 format %{ "subsd $dst, [$src]" %} 10227 ins_cost(150); // XXX 10228 opcode(0xF2, 0x0F, 0x5C); 10229 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immD(dst, src)); 10230 ins_pipe(pipe_slow); 10231%} 10232 10233instruct mulF_reg(regF dst, regF src) 10234%{ 10235 match(Set dst (MulF dst src)); 10236 10237 format %{ "mulss $dst, $src" %} 10238 ins_cost(150); // XXX 10239 opcode(0xF3, 0x0F, 0x59); 10240 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src)); 10241 ins_pipe(pipe_slow); 10242%} 10243 10244instruct mulF_mem(regF dst, memory src) 10245%{ 10246 match(Set dst (MulF dst (LoadF src))); 10247 10248 format %{ "mulss $dst, $src" %} 10249 ins_cost(150); // XXX 10250 opcode(0xF3, 0x0F, 0x59); 10251 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 10252 ins_pipe(pipe_slow); 10253%} 10254 10255instruct mulF_imm(regF dst, immF src) 10256%{ 10257 match(Set dst (MulF dst src)); 10258 10259 format %{ "mulss $dst, [$src]" %} 10260 ins_cost(150); // XXX 10261 opcode(0xF3, 0x0F, 0x59); 10262 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immF(dst, src)); 10263 ins_pipe(pipe_slow); 10264%} 10265 10266instruct mulD_reg(regD dst, regD src) 10267%{ 10268 match(Set dst (MulD dst src)); 10269 10270 format %{ "mulsd $dst, $src" %} 10271 ins_cost(150); // XXX 10272 opcode(0xF2, 0x0F, 0x59); 10273 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src)); 10274 ins_pipe(pipe_slow); 10275%} 10276 10277instruct mulD_mem(regD dst, memory src) 10278%{ 10279 match(Set dst (MulD dst (LoadD src))); 10280 10281 format %{ "mulsd $dst, $src" %} 10282 ins_cost(150); // XXX 10283 opcode(0xF2, 0x0F, 0x59); 10284 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 10285 ins_pipe(pipe_slow); 10286%} 10287 10288instruct mulD_imm(regD dst, immD src) 10289%{ 10290 match(Set dst (MulD dst src)); 10291 10292 format %{ "mulsd $dst, [$src]" %} 10293 ins_cost(150); // XXX 10294 opcode(0xF2, 0x0F, 0x59); 10295 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immD(dst, src)); 10296 ins_pipe(pipe_slow); 10297%} 10298 10299instruct divF_reg(regF dst, regF src) 10300%{ 10301 match(Set dst (DivF dst src)); 10302 10303 format %{ "divss $dst, $src" %} 10304 ins_cost(150); // XXX 10305 opcode(0xF3, 0x0F, 0x5E); 10306 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src)); 10307 ins_pipe(pipe_slow); 10308%} 10309 10310instruct divF_mem(regF dst, memory src) 10311%{ 10312 match(Set dst (DivF dst (LoadF src))); 10313 10314 format %{ "divss $dst, $src" %} 10315 ins_cost(150); // XXX 10316 opcode(0xF3, 0x0F, 0x5E); 10317 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 10318 ins_pipe(pipe_slow); 10319%} 10320 10321instruct divF_imm(regF dst, immF src) 10322%{ 10323 match(Set dst (DivF dst src)); 10324 10325 format %{ "divss $dst, [$src]" %} 10326 ins_cost(150); // XXX 10327 opcode(0xF3, 0x0F, 0x5E); 10328 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immF(dst, src)); 10329 ins_pipe(pipe_slow); 10330%} 10331 10332instruct divD_reg(regD dst, regD src) 10333%{ 10334 match(Set dst (DivD dst src)); 10335 10336 format %{ "divsd $dst, $src" %} 10337 ins_cost(150); // XXX 10338 opcode(0xF2, 0x0F, 0x5E); 10339 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src)); 10340 ins_pipe(pipe_slow); 10341%} 10342 10343instruct divD_mem(regD dst, memory src) 10344%{ 10345 match(Set dst (DivD dst (LoadD src))); 10346 10347 format %{ "divsd $dst, $src" %} 10348 ins_cost(150); // XXX 10349 opcode(0xF2, 0x0F, 0x5E); 10350 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 10351 ins_pipe(pipe_slow); 10352%} 10353 10354instruct divD_imm(regD dst, immD src) 10355%{ 10356 match(Set dst (DivD dst src)); 10357 10358 format %{ "divsd $dst, [$src]" %} 10359 ins_cost(150); // XXX 10360 opcode(0xF2, 0x0F, 0x5E); 10361 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immD(dst, src)); 10362 ins_pipe(pipe_slow); 10363%} 10364 10365instruct sqrtF_reg(regF dst, regF src) 10366%{ 10367 match(Set dst (ConvD2F (SqrtD (ConvF2D src)))); 10368 10369 format %{ "sqrtss $dst, $src" %} 10370 ins_cost(150); // XXX 10371 opcode(0xF3, 0x0F, 0x51); 10372 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src)); 10373 ins_pipe(pipe_slow); 10374%} 10375 10376instruct sqrtF_mem(regF dst, memory src) 10377%{ 10378 match(Set dst (ConvD2F (SqrtD (ConvF2D (LoadF src))))); 10379 10380 format %{ "sqrtss $dst, $src" %} 10381 ins_cost(150); // XXX 10382 opcode(0xF3, 0x0F, 0x51); 10383 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 10384 ins_pipe(pipe_slow); 10385%} 10386 10387instruct sqrtF_imm(regF dst, immF src) 10388%{ 10389 match(Set dst (ConvD2F (SqrtD (ConvF2D src)))); 10390 10391 format %{ "sqrtss $dst, [$src]" %} 10392 ins_cost(150); // XXX 10393 opcode(0xF3, 0x0F, 0x51); 10394 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immF(dst, src)); 10395 ins_pipe(pipe_slow); 10396%} 10397 10398instruct sqrtD_reg(regD dst, regD src) 10399%{ 10400 match(Set dst (SqrtD src)); 10401 10402 format %{ "sqrtsd $dst, $src" %} 10403 ins_cost(150); // XXX 10404 opcode(0xF2, 0x0F, 0x51); 10405 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src)); 10406 ins_pipe(pipe_slow); 10407%} 10408 10409instruct sqrtD_mem(regD dst, memory src) 10410%{ 10411 match(Set dst (SqrtD (LoadD src))); 10412 10413 format %{ "sqrtsd $dst, $src" %} 10414 ins_cost(150); // XXX 10415 opcode(0xF2, 0x0F, 0x51); 10416 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 10417 ins_pipe(pipe_slow); 10418%} 10419 10420instruct sqrtD_imm(regD dst, immD src) 10421%{ 10422 match(Set dst (SqrtD src)); 10423 10424 format %{ "sqrtsd $dst, [$src]" %} 10425 ins_cost(150); // XXX 10426 opcode(0xF2, 0x0F, 0x51); 10427 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, load_immD(dst, src)); 10428 ins_pipe(pipe_slow); 10429%} 10430 10431instruct absF_reg(regF dst) 10432%{ 10433 match(Set dst (AbsF dst)); 10434 10435 format %{ "andps $dst, [0x7fffffff]\t# abs float by sign masking" %} 10436 ins_encode(absF_encoding(dst)); 10437 ins_pipe(pipe_slow); 10438%} 10439 10440instruct absD_reg(regD dst) 10441%{ 10442 match(Set dst (AbsD dst)); 10443 10444 format %{ "andpd $dst, [0x7fffffffffffffff]\t" 10445 "# abs double by sign masking" %} 10446 ins_encode(absD_encoding(dst)); 10447 ins_pipe(pipe_slow); 10448%} 10449 10450instruct negF_reg(regF dst) 10451%{ 10452 match(Set dst (NegF dst)); 10453 10454 format %{ "xorps $dst, [0x80000000]\t# neg float by sign flipping" %} 10455 ins_encode(negF_encoding(dst)); 10456 ins_pipe(pipe_slow); 10457%} 10458 10459instruct negD_reg(regD dst) 10460%{ 10461 match(Set dst (NegD dst)); 10462 10463 format %{ "xorpd $dst, [0x8000000000000000]\t" 10464 "# neg double by sign flipping" %} 10465 ins_encode(negD_encoding(dst)); 10466 ins_pipe(pipe_slow); 10467%} 10468 10469// -----------Trig and Trancendental Instructions------------------------------ 10470instruct cosD_reg(regD dst) %{ 10471 match(Set dst (CosD dst)); 10472 10473 format %{ "dcos $dst\n\t" %} 10474 opcode(0xD9, 0xFF); 10475 ins_encode( Push_SrcXD(dst), OpcP, OpcS, Push_ResultXD(dst) ); 10476 ins_pipe( pipe_slow ); 10477%} 10478 10479instruct sinD_reg(regD dst) %{ 10480 match(Set dst (SinD dst)); 10481 10482 format %{ "dsin $dst\n\t" %} 10483 opcode(0xD9, 0xFE); 10484 ins_encode( Push_SrcXD(dst), OpcP, OpcS, Push_ResultXD(dst) ); 10485 ins_pipe( pipe_slow ); 10486%} 10487 10488instruct tanD_reg(regD dst) %{ 10489 match(Set dst (TanD dst)); 10490 10491 format %{ "dtan $dst\n\t" %} 10492 ins_encode( Push_SrcXD(dst), 10493 Opcode(0xD9), Opcode(0xF2), //fptan 10494 Opcode(0xDD), Opcode(0xD8), //fstp st 10495 Push_ResultXD(dst) ); 10496 ins_pipe( pipe_slow ); 10497%} 10498 10499instruct log10D_reg(regD dst) %{ 10500 // The source and result Double operands in XMM registers 10501 match(Set dst (Log10D dst)); 10502 // fldlg2 ; push log_10(2) on the FPU stack; full 80-bit number 10503 // fyl2x ; compute log_10(2) * log_2(x) 10504 format %{ "fldlg2\t\t\t#Log10\n\t" 10505 "fyl2x\t\t\t# Q=Log10*Log_2(x)\n\t" 10506 %} 10507 ins_encode(Opcode(0xD9), Opcode(0xEC), // fldlg2 10508 Push_SrcXD(dst), 10509 Opcode(0xD9), Opcode(0xF1), // fyl2x 10510 Push_ResultXD(dst)); 10511 10512 ins_pipe( pipe_slow ); 10513%} 10514 10515instruct logD_reg(regD dst) %{ 10516 // The source and result Double operands in XMM registers 10517 match(Set dst (LogD dst)); 10518 // fldln2 ; push log_e(2) on the FPU stack; full 80-bit number 10519 // fyl2x ; compute log_e(2) * log_2(x) 10520 format %{ "fldln2\t\t\t#Log_e\n\t" 10521 "fyl2x\t\t\t# Q=Log_e*Log_2(x)\n\t" 10522 %} 10523 ins_encode( Opcode(0xD9), Opcode(0xED), // fldln2 10524 Push_SrcXD(dst), 10525 Opcode(0xD9), Opcode(0xF1), // fyl2x 10526 Push_ResultXD(dst)); 10527 ins_pipe( pipe_slow ); 10528%} 10529 10530 10531 10532//----------Arithmetic Conversion Instructions--------------------------------- 10533 10534instruct roundFloat_nop(regF dst) 10535%{ 10536 match(Set dst (RoundFloat dst)); 10537 10538 ins_cost(0); 10539 ins_encode(); 10540 ins_pipe(empty); 10541%} 10542 10543instruct roundDouble_nop(regD dst) 10544%{ 10545 match(Set dst (RoundDouble dst)); 10546 10547 ins_cost(0); 10548 ins_encode(); 10549 ins_pipe(empty); 10550%} 10551 10552instruct convF2D_reg_reg(regD dst, regF src) 10553%{ 10554 match(Set dst (ConvF2D src)); 10555 10556 format %{ "cvtss2sd $dst, $src" %} 10557 opcode(0xF3, 0x0F, 0x5A); 10558 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src)); 10559 ins_pipe(pipe_slow); // XXX 10560%} 10561 10562instruct convF2D_reg_mem(regD dst, memory src) 10563%{ 10564 match(Set dst (ConvF2D (LoadF src))); 10565 10566 format %{ "cvtss2sd $dst, $src" %} 10567 opcode(0xF3, 0x0F, 0x5A); 10568 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 10569 ins_pipe(pipe_slow); // XXX 10570%} 10571 10572instruct convD2F_reg_reg(regF dst, regD src) 10573%{ 10574 match(Set dst (ConvD2F src)); 10575 10576 format %{ "cvtsd2ss $dst, $src" %} 10577 opcode(0xF2, 0x0F, 0x5A); 10578 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src)); 10579 ins_pipe(pipe_slow); // XXX 10580%} 10581 10582instruct convD2F_reg_mem(regF dst, memory src) 10583%{ 10584 match(Set dst (ConvD2F (LoadD src))); 10585 10586 format %{ "cvtsd2ss $dst, $src" %} 10587 opcode(0xF2, 0x0F, 0x5A); 10588 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 10589 ins_pipe(pipe_slow); // XXX 10590%} 10591 10592// XXX do mem variants 10593instruct convF2I_reg_reg(rRegI dst, regF src, rFlagsReg cr) 10594%{ 10595 match(Set dst (ConvF2I src)); 10596 effect(KILL cr); 10597 10598 format %{ "cvttss2sil $dst, $src\t# f2i\n\t" 10599 "cmpl $dst, #0x80000000\n\t" 10600 "jne,s done\n\t" 10601 "subq rsp, #8\n\t" 10602 "movss [rsp], $src\n\t" 10603 "call f2i_fixup\n\t" 10604 "popq $dst\n" 10605 "done: "%} 10606 opcode(0xF3, 0x0F, 0x2C); 10607 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src), 10608 f2i_fixup(dst, src)); 10609 ins_pipe(pipe_slow); 10610%} 10611 10612instruct convF2L_reg_reg(rRegL dst, regF src, rFlagsReg cr) 10613%{ 10614 match(Set dst (ConvF2L src)); 10615 effect(KILL cr); 10616 10617 format %{ "cvttss2siq $dst, $src\t# f2l\n\t" 10618 "cmpq $dst, [0x8000000000000000]\n\t" 10619 "jne,s done\n\t" 10620 "subq rsp, #8\n\t" 10621 "movss [rsp], $src\n\t" 10622 "call f2l_fixup\n\t" 10623 "popq $dst\n" 10624 "done: "%} 10625 opcode(0xF3, 0x0F, 0x2C); 10626 ins_encode(OpcP, REX_reg_reg_wide(dst, src), OpcS, OpcT, reg_reg(dst, src), 10627 f2l_fixup(dst, src)); 10628 ins_pipe(pipe_slow); 10629%} 10630 10631instruct convD2I_reg_reg(rRegI dst, regD src, rFlagsReg cr) 10632%{ 10633 match(Set dst (ConvD2I src)); 10634 effect(KILL cr); 10635 10636 format %{ "cvttsd2sil $dst, $src\t# d2i\n\t" 10637 "cmpl $dst, #0x80000000\n\t" 10638 "jne,s done\n\t" 10639 "subq rsp, #8\n\t" 10640 "movsd [rsp], $src\n\t" 10641 "call d2i_fixup\n\t" 10642 "popq $dst\n" 10643 "done: "%} 10644 opcode(0xF2, 0x0F, 0x2C); 10645 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src), 10646 d2i_fixup(dst, src)); 10647 ins_pipe(pipe_slow); 10648%} 10649 10650instruct convD2L_reg_reg(rRegL dst, regD src, rFlagsReg cr) 10651%{ 10652 match(Set dst (ConvD2L src)); 10653 effect(KILL cr); 10654 10655 format %{ "cvttsd2siq $dst, $src\t# d2l\n\t" 10656 "cmpq $dst, [0x8000000000000000]\n\t" 10657 "jne,s done\n\t" 10658 "subq rsp, #8\n\t" 10659 "movsd [rsp], $src\n\t" 10660 "call d2l_fixup\n\t" 10661 "popq $dst\n" 10662 "done: "%} 10663 opcode(0xF2, 0x0F, 0x2C); 10664 ins_encode(OpcP, REX_reg_reg_wide(dst, src), OpcS, OpcT, reg_reg(dst, src), 10665 d2l_fixup(dst, src)); 10666 ins_pipe(pipe_slow); 10667%} 10668 10669instruct convI2F_reg_reg(regF dst, rRegI src) 10670%{ 10671 predicate(!UseXmmI2F); 10672 match(Set dst (ConvI2F src)); 10673 10674 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10675 opcode(0xF3, 0x0F, 0x2A); 10676 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src)); 10677 ins_pipe(pipe_slow); // XXX 10678%} 10679 10680instruct convI2F_reg_mem(regF dst, memory src) 10681%{ 10682 match(Set dst (ConvI2F (LoadI src))); 10683 10684 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10685 opcode(0xF3, 0x0F, 0x2A); 10686 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 10687 ins_pipe(pipe_slow); // XXX 10688%} 10689 10690instruct convI2D_reg_reg(regD dst, rRegI src) 10691%{ 10692 predicate(!UseXmmI2D); 10693 match(Set dst (ConvI2D src)); 10694 10695 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10696 opcode(0xF2, 0x0F, 0x2A); 10697 ins_encode(OpcP, REX_reg_reg(dst, src), OpcS, OpcT, reg_reg(dst, src)); 10698 ins_pipe(pipe_slow); // XXX 10699%} 10700 10701instruct convI2D_reg_mem(regD dst, memory src) 10702%{ 10703 match(Set dst (ConvI2D (LoadI src))); 10704 10705 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10706 opcode(0xF2, 0x0F, 0x2A); 10707 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 10708 ins_pipe(pipe_slow); // XXX 10709%} 10710 10711instruct convXI2F_reg(regF dst, rRegI src) 10712%{ 10713 predicate(UseXmmI2F); 10714 match(Set dst (ConvI2F src)); 10715 10716 format %{ "movdl $dst, $src\n\t" 10717 "cvtdq2psl $dst, $dst\t# i2f" %} 10718 ins_encode %{ 10719 __ movdl($dst$$XMMRegister, $src$$Register); 10720 __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister); 10721 %} 10722 ins_pipe(pipe_slow); // XXX 10723%} 10724 10725instruct convXI2D_reg(regD dst, rRegI src) 10726%{ 10727 predicate(UseXmmI2D); 10728 match(Set dst (ConvI2D src)); 10729 10730 format %{ "movdl $dst, $src\n\t" 10731 "cvtdq2pdl $dst, $dst\t# i2d" %} 10732 ins_encode %{ 10733 __ movdl($dst$$XMMRegister, $src$$Register); 10734 __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister); 10735 %} 10736 ins_pipe(pipe_slow); // XXX 10737%} 10738 10739instruct convL2F_reg_reg(regF dst, rRegL src) 10740%{ 10741 match(Set dst (ConvL2F src)); 10742 10743 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10744 opcode(0xF3, 0x0F, 0x2A); 10745 ins_encode(OpcP, REX_reg_reg_wide(dst, src), OpcS, OpcT, reg_reg(dst, src)); 10746 ins_pipe(pipe_slow); // XXX 10747%} 10748 10749instruct convL2F_reg_mem(regF dst, memory src) 10750%{ 10751 match(Set dst (ConvL2F (LoadL src))); 10752 10753 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10754 opcode(0xF3, 0x0F, 0x2A); 10755 ins_encode(OpcP, REX_reg_mem_wide(dst, src), OpcS, OpcT, reg_mem(dst, src)); 10756 ins_pipe(pipe_slow); // XXX 10757%} 10758 10759instruct convL2D_reg_reg(regD dst, rRegL src) 10760%{ 10761 match(Set dst (ConvL2D src)); 10762 10763 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10764 opcode(0xF2, 0x0F, 0x2A); 10765 ins_encode(OpcP, REX_reg_reg_wide(dst, src), OpcS, OpcT, reg_reg(dst, src)); 10766 ins_pipe(pipe_slow); // XXX 10767%} 10768 10769instruct convL2D_reg_mem(regD dst, memory src) 10770%{ 10771 match(Set dst (ConvL2D (LoadL src))); 10772 10773 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10774 opcode(0xF2, 0x0F, 0x2A); 10775 ins_encode(OpcP, REX_reg_mem_wide(dst, src), OpcS, OpcT, reg_mem(dst, src)); 10776 ins_pipe(pipe_slow); // XXX 10777%} 10778 10779instruct convI2L_reg_reg(rRegL dst, rRegI src) 10780%{ 10781 match(Set dst (ConvI2L src)); 10782 10783 ins_cost(125); 10784 format %{ "movslq $dst, $src\t# i2l" %} 10785 opcode(0x63); // needs REX.W 10786 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst,src)); 10787 ins_pipe(ialu_reg_reg); 10788%} 10789 10790// instruct convI2L_reg_reg_foo(rRegL dst, rRegI src) 10791// %{ 10792// match(Set dst (ConvI2L src)); 10793// // predicate(_kids[0]->_leaf->as_Type()->type()->is_int()->_lo >= 0 && 10794// // _kids[0]->_leaf->as_Type()->type()->is_int()->_hi >= 0); 10795// predicate(((const TypeNode*) n)->type()->is_long()->_hi == 10796// (unsigned int) ((const TypeNode*) n)->type()->is_long()->_hi && 10797// ((const TypeNode*) n)->type()->is_long()->_lo == 10798// (unsigned int) ((const TypeNode*) n)->type()->is_long()->_lo); 10799 10800// format %{ "movl $dst, $src\t# unsigned i2l" %} 10801// ins_encode(enc_copy(dst, src)); 10802// // opcode(0x63); // needs REX.W 10803// // ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst,src)); 10804// ins_pipe(ialu_reg_reg); 10805// %} 10806 10807instruct convI2L_reg_mem(rRegL dst, memory src) 10808%{ 10809 match(Set dst (ConvI2L (LoadI src))); 10810 10811 format %{ "movslq $dst, $src\t# i2l" %} 10812 opcode(0x63); // needs REX.W 10813 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst,src)); 10814 ins_pipe(ialu_reg_mem); 10815%} 10816 10817// Zero-extend convert int to long 10818instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask) 10819%{ 10820 match(Set dst (AndL (ConvI2L src) mask)); 10821 10822 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10823 ins_encode(enc_copy(dst, src)); 10824 ins_pipe(ialu_reg_reg); 10825%} 10826 10827// Zero-extend convert int to long 10828instruct convI2L_reg_mem_zex(rRegL dst, memory src, immL_32bits mask) 10829%{ 10830 match(Set dst (AndL (ConvI2L (LoadI src)) mask)); 10831 10832 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10833 opcode(0x8B); 10834 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 10835 ins_pipe(ialu_reg_mem); 10836%} 10837 10838instruct zerox_long_reg_reg(rRegL dst, rRegL src, immL_32bits mask) 10839%{ 10840 match(Set dst (AndL src mask)); 10841 10842 format %{ "movl $dst, $src\t# zero-extend long" %} 10843 ins_encode(enc_copy_always(dst, src)); 10844 ins_pipe(ialu_reg_reg); 10845%} 10846 10847instruct convL2I_reg_reg(rRegI dst, rRegL src) 10848%{ 10849 match(Set dst (ConvL2I src)); 10850 10851 format %{ "movl $dst, $src\t# l2i" %} 10852 ins_encode(enc_copy_always(dst, src)); 10853 ins_pipe(ialu_reg_reg); 10854%} 10855 10856 10857instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{ 10858 match(Set dst (MoveF2I src)); 10859 effect(DEF dst, USE src); 10860 10861 ins_cost(125); 10862 format %{ "movl $dst, $src\t# MoveF2I_stack_reg" %} 10863 opcode(0x8B); 10864 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 10865 ins_pipe(ialu_reg_mem); 10866%} 10867 10868instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{ 10869 match(Set dst (MoveI2F src)); 10870 effect(DEF dst, USE src); 10871 10872 ins_cost(125); 10873 format %{ "movss $dst, $src\t# MoveI2F_stack_reg" %} 10874 opcode(0xF3, 0x0F, 0x10); 10875 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 10876 ins_pipe(pipe_slow); 10877%} 10878 10879instruct MoveD2L_stack_reg(rRegL dst, stackSlotD src) %{ 10880 match(Set dst (MoveD2L src)); 10881 effect(DEF dst, USE src); 10882 10883 ins_cost(125); 10884 format %{ "movq $dst, $src\t# MoveD2L_stack_reg" %} 10885 opcode(0x8B); 10886 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 10887 ins_pipe(ialu_reg_mem); 10888%} 10889 10890instruct MoveL2D_stack_reg_partial(regD dst, stackSlotL src) %{ 10891 predicate(!UseXmmLoadAndClearUpper); 10892 match(Set dst (MoveL2D src)); 10893 effect(DEF dst, USE src); 10894 10895 ins_cost(125); 10896 format %{ "movlpd $dst, $src\t# MoveL2D_stack_reg" %} 10897 opcode(0x66, 0x0F, 0x12); 10898 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 10899 ins_pipe(pipe_slow); 10900%} 10901 10902instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{ 10903 predicate(UseXmmLoadAndClearUpper); 10904 match(Set dst (MoveL2D src)); 10905 effect(DEF dst, USE src); 10906 10907 ins_cost(125); 10908 format %{ "movsd $dst, $src\t# MoveL2D_stack_reg" %} 10909 opcode(0xF2, 0x0F, 0x10); 10910 ins_encode(OpcP, REX_reg_mem(dst, src), OpcS, OpcT, reg_mem(dst, src)); 10911 ins_pipe(pipe_slow); 10912%} 10913 10914 10915instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{ 10916 match(Set dst (MoveF2I src)); 10917 effect(DEF dst, USE src); 10918 10919 ins_cost(95); // XXX 10920 format %{ "movss $dst, $src\t# MoveF2I_reg_stack" %} 10921 opcode(0xF3, 0x0F, 0x11); 10922 ins_encode(OpcP, REX_reg_mem(src, dst), OpcS, OpcT, reg_mem(src, dst)); 10923 ins_pipe(pipe_slow); 10924%} 10925 10926instruct MoveI2F_reg_stack(stackSlotF dst, rRegI src) %{ 10927 match(Set dst (MoveI2F src)); 10928 effect(DEF dst, USE src); 10929 10930 ins_cost(100); 10931 format %{ "movl $dst, $src\t# MoveI2F_reg_stack" %} 10932 opcode(0x89); 10933 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 10934 ins_pipe( ialu_mem_reg ); 10935%} 10936 10937instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{ 10938 match(Set dst (MoveD2L src)); 10939 effect(DEF dst, USE src); 10940 10941 ins_cost(95); // XXX 10942 format %{ "movsd $dst, $src\t# MoveL2D_reg_stack" %} 10943 opcode(0xF2, 0x0F, 0x11); 10944 ins_encode(OpcP, REX_reg_mem(src, dst), OpcS, OpcT, reg_mem(src, dst)); 10945 ins_pipe(pipe_slow); 10946%} 10947 10948instruct MoveL2D_reg_stack(stackSlotD dst, rRegL src) %{ 10949 match(Set dst (MoveL2D src)); 10950 effect(DEF dst, USE src); 10951 10952 ins_cost(100); 10953 format %{ "movq $dst, $src\t# MoveL2D_reg_stack" %} 10954 opcode(0x89); 10955 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 10956 ins_pipe(ialu_mem_reg); 10957%} 10958 10959instruct MoveF2I_reg_reg(rRegI dst, regF src) %{ 10960 match(Set dst (MoveF2I src)); 10961 effect(DEF dst, USE src); 10962 ins_cost(85); 10963 format %{ "movd $dst,$src\t# MoveF2I" %} 10964 ins_encode %{ __ movdl($dst$$Register, $src$$XMMRegister); %} 10965 ins_pipe( pipe_slow ); 10966%} 10967 10968instruct MoveD2L_reg_reg(rRegL dst, regD src) %{ 10969 match(Set dst (MoveD2L src)); 10970 effect(DEF dst, USE src); 10971 ins_cost(85); 10972 format %{ "movd $dst,$src\t# MoveD2L" %} 10973 ins_encode %{ __ movdq($dst$$Register, $src$$XMMRegister); %} 10974 ins_pipe( pipe_slow ); 10975%} 10976 10977// The next instructions have long latency and use Int unit. Set high cost. 10978instruct MoveI2F_reg_reg(regF dst, rRegI src) %{ 10979 match(Set dst (MoveI2F src)); 10980 effect(DEF dst, USE src); 10981 ins_cost(300); 10982 format %{ "movd $dst,$src\t# MoveI2F" %} 10983 ins_encode %{ __ movdl($dst$$XMMRegister, $src$$Register); %} 10984 ins_pipe( pipe_slow ); 10985%} 10986 10987instruct MoveL2D_reg_reg(regD dst, rRegL src) %{ 10988 match(Set dst (MoveL2D src)); 10989 effect(DEF dst, USE src); 10990 ins_cost(300); 10991 format %{ "movd $dst,$src\t# MoveL2D" %} 10992 ins_encode %{ __ movdq($dst$$XMMRegister, $src$$Register); %} 10993 ins_pipe( pipe_slow ); 10994%} 10995 10996// Replicate scalar to packed byte (1 byte) values in xmm 10997instruct Repl8B_reg(regD dst, regD src) %{ 10998 match(Set dst (Replicate8B src)); 10999 format %{ "MOVDQA $dst,$src\n\t" 11000 "PUNPCKLBW $dst,$dst\n\t" 11001 "PSHUFLW $dst,$dst,0x00\t! replicate8B" %} 11002 ins_encode( pshufd_8x8(dst, src)); 11003 ins_pipe( pipe_slow ); 11004%} 11005 11006// Replicate scalar to packed byte (1 byte) values in xmm 11007instruct Repl8B_rRegI(regD dst, rRegI src) %{ 11008 match(Set dst (Replicate8B src)); 11009 format %{ "MOVD $dst,$src\n\t" 11010 "PUNPCKLBW $dst,$dst\n\t" 11011 "PSHUFLW $dst,$dst,0x00\t! replicate8B" %} 11012 ins_encode( mov_i2x(dst, src), pshufd_8x8(dst, dst)); 11013 ins_pipe( pipe_slow ); 11014%} 11015 11016// Replicate scalar zero to packed byte (1 byte) values in xmm 11017instruct Repl8B_immI0(regD dst, immI0 zero) %{ 11018 match(Set dst (Replicate8B zero)); 11019 format %{ "PXOR $dst,$dst\t! replicate8B" %} 11020 ins_encode( pxor(dst, dst)); 11021 ins_pipe( fpu_reg_reg ); 11022%} 11023 11024// Replicate scalar to packed shore (2 byte) values in xmm 11025instruct Repl4S_reg(regD dst, regD src) %{ 11026 match(Set dst (Replicate4S src)); 11027 format %{ "PSHUFLW $dst,$src,0x00\t! replicate4S" %} 11028 ins_encode( pshufd_4x16(dst, src)); 11029 ins_pipe( fpu_reg_reg ); 11030%} 11031 11032// Replicate scalar to packed shore (2 byte) values in xmm 11033instruct Repl4S_rRegI(regD dst, rRegI src) %{ 11034 match(Set dst (Replicate4S src)); 11035 format %{ "MOVD $dst,$src\n\t" 11036 "PSHUFLW $dst,$dst,0x00\t! replicate4S" %} 11037 ins_encode( mov_i2x(dst, src), pshufd_4x16(dst, dst)); 11038 ins_pipe( fpu_reg_reg ); 11039%} 11040 11041// Replicate scalar zero to packed short (2 byte) values in xmm 11042instruct Repl4S_immI0(regD dst, immI0 zero) %{ 11043 match(Set dst (Replicate4S zero)); 11044 format %{ "PXOR $dst,$dst\t! replicate4S" %} 11045 ins_encode( pxor(dst, dst)); 11046 ins_pipe( fpu_reg_reg ); 11047%} 11048 11049// Replicate scalar to packed char (2 byte) values in xmm 11050instruct Repl4C_reg(regD dst, regD src) %{ 11051 match(Set dst (Replicate4C src)); 11052 format %{ "PSHUFLW $dst,$src,0x00\t! replicate4C" %} 11053 ins_encode( pshufd_4x16(dst, src)); 11054 ins_pipe( fpu_reg_reg ); 11055%} 11056 11057// Replicate scalar to packed char (2 byte) values in xmm 11058instruct Repl4C_rRegI(regD dst, rRegI src) %{ 11059 match(Set dst (Replicate4C src)); 11060 format %{ "MOVD $dst,$src\n\t" 11061 "PSHUFLW $dst,$dst,0x00\t! replicate4C" %} 11062 ins_encode( mov_i2x(dst, src), pshufd_4x16(dst, dst)); 11063 ins_pipe( fpu_reg_reg ); 11064%} 11065 11066// Replicate scalar zero to packed char (2 byte) values in xmm 11067instruct Repl4C_immI0(regD dst, immI0 zero) %{ 11068 match(Set dst (Replicate4C zero)); 11069 format %{ "PXOR $dst,$dst\t! replicate4C" %} 11070 ins_encode( pxor(dst, dst)); 11071 ins_pipe( fpu_reg_reg ); 11072%} 11073 11074// Replicate scalar to packed integer (4 byte) values in xmm 11075instruct Repl2I_reg(regD dst, regD src) %{ 11076 match(Set dst (Replicate2I src)); 11077 format %{ "PSHUFD $dst,$src,0x00\t! replicate2I" %} 11078 ins_encode( pshufd(dst, src, 0x00)); 11079 ins_pipe( fpu_reg_reg ); 11080%} 11081 11082// Replicate scalar to packed integer (4 byte) values in xmm 11083instruct Repl2I_rRegI(regD dst, rRegI src) %{ 11084 match(Set dst (Replicate2I src)); 11085 format %{ "MOVD $dst,$src\n\t" 11086 "PSHUFD $dst,$dst,0x00\t! replicate2I" %} 11087 ins_encode( mov_i2x(dst, src), pshufd(dst, dst, 0x00)); 11088 ins_pipe( fpu_reg_reg ); 11089%} 11090 11091// Replicate scalar zero to packed integer (2 byte) values in xmm 11092instruct Repl2I_immI0(regD dst, immI0 zero) %{ 11093 match(Set dst (Replicate2I zero)); 11094 format %{ "PXOR $dst,$dst\t! replicate2I" %} 11095 ins_encode( pxor(dst, dst)); 11096 ins_pipe( fpu_reg_reg ); 11097%} 11098 11099// Replicate scalar to packed single precision floating point values in xmm 11100instruct Repl2F_reg(regD dst, regD src) %{ 11101 match(Set dst (Replicate2F src)); 11102 format %{ "PSHUFD $dst,$src,0xe0\t! replicate2F" %} 11103 ins_encode( pshufd(dst, src, 0xe0)); 11104 ins_pipe( fpu_reg_reg ); 11105%} 11106 11107// Replicate scalar to packed single precision floating point values in xmm 11108instruct Repl2F_regF(regD dst, regF src) %{ 11109 match(Set dst (Replicate2F src)); 11110 format %{ "PSHUFD $dst,$src,0xe0\t! replicate2F" %} 11111 ins_encode( pshufd(dst, src, 0xe0)); 11112 ins_pipe( fpu_reg_reg ); 11113%} 11114 11115// Replicate scalar to packed single precision floating point values in xmm 11116instruct Repl2F_immF0(regD dst, immF0 zero) %{ 11117 match(Set dst (Replicate2F zero)); 11118 format %{ "PXOR $dst,$dst\t! replicate2F" %} 11119 ins_encode( pxor(dst, dst)); 11120 ins_pipe( fpu_reg_reg ); 11121%} 11122 11123 11124// ======================================================================= 11125// fast clearing of an array 11126instruct rep_stos(rcx_RegL cnt, rdi_RegP base, rax_RegI zero, Universe dummy, 11127 rFlagsReg cr) 11128%{ 11129 match(Set dummy (ClearArray cnt base)); 11130 effect(USE_KILL cnt, USE_KILL base, KILL zero, KILL cr); 11131 11132 format %{ "xorl rax, rax\t# ClearArray:\n\t" 11133 "rep stosq\t# Store rax to *rdi++ while rcx--" %} 11134 ins_encode(opc_reg_reg(0x33, RAX, RAX), // xorl %eax, %eax 11135 Opcode(0xF3), Opcode(0x48), Opcode(0xAB)); // rep REX_W stos 11136 ins_pipe(pipe_slow); 11137%} 11138 11139instruct string_compare(rdi_RegP str1, rsi_RegP str2, rax_RegI tmp1, 11140 rbx_RegI tmp2, rcx_RegI result, rFlagsReg cr) 11141%{ 11142 match(Set result (StrComp str1 str2)); 11143 effect(USE_KILL str1, USE_KILL str2, KILL tmp1, KILL tmp2, KILL cr); 11144 //ins_cost(300); 11145 11146 format %{ "String Compare $str1, $str2 -> $result // XXX KILL RAX, RBX" %} 11147 ins_encode( enc_String_Compare() ); 11148 ins_pipe( pipe_slow ); 11149%} 11150 11151// fast array equals 11152instruct array_equals(rdi_RegP ary1, rsi_RegP ary2, rax_RegI tmp1, 11153 rbx_RegI tmp2, rcx_RegI result, rFlagsReg cr) %{ 11154 match(Set result (AryEq ary1 ary2)); 11155 effect(USE_KILL ary1, USE_KILL ary2, KILL tmp1, KILL tmp2, KILL cr); 11156 //ins_cost(300); 11157 11158 format %{ "Array Equals $ary1,$ary2 -> $result // KILL RAX, RBX" %} 11159 ins_encode( enc_Array_Equals(ary1, ary2, tmp1, tmp2, result) ); 11160 ins_pipe( pipe_slow ); 11161%} 11162 11163//----------Control Flow Instructions------------------------------------------ 11164// Signed compare Instructions 11165 11166// XXX more variants!! 11167instruct compI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 11168%{ 11169 match(Set cr (CmpI op1 op2)); 11170 effect(DEF cr, USE op1, USE op2); 11171 11172 format %{ "cmpl $op1, $op2" %} 11173 opcode(0x3B); /* Opcode 3B /r */ 11174 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2)); 11175 ins_pipe(ialu_cr_reg_reg); 11176%} 11177 11178instruct compI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 11179%{ 11180 match(Set cr (CmpI op1 op2)); 11181 11182 format %{ "cmpl $op1, $op2" %} 11183 opcode(0x81, 0x07); /* Opcode 81 /7 */ 11184 ins_encode(OpcSErm(op1, op2), Con8or32(op2)); 11185 ins_pipe(ialu_cr_reg_imm); 11186%} 11187 11188instruct compI_rReg_mem(rFlagsReg cr, rRegI op1, memory op2) 11189%{ 11190 match(Set cr (CmpI op1 (LoadI op2))); 11191 11192 ins_cost(500); // XXX 11193 format %{ "cmpl $op1, $op2" %} 11194 opcode(0x3B); /* Opcode 3B /r */ 11195 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2)); 11196 ins_pipe(ialu_cr_reg_mem); 11197%} 11198 11199instruct testI_reg(rFlagsReg cr, rRegI src, immI0 zero) 11200%{ 11201 match(Set cr (CmpI src zero)); 11202 11203 format %{ "testl $src, $src" %} 11204 opcode(0x85); 11205 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src)); 11206 ins_pipe(ialu_cr_reg_imm); 11207%} 11208 11209instruct testI_reg_imm(rFlagsReg cr, rRegI src, immI con, immI0 zero) 11210%{ 11211 match(Set cr (CmpI (AndI src con) zero)); 11212 11213 format %{ "testl $src, $con" %} 11214 opcode(0xF7, 0x00); 11215 ins_encode(REX_reg(src), OpcP, reg_opc(src), Con32(con)); 11216 ins_pipe(ialu_cr_reg_imm); 11217%} 11218 11219instruct testI_reg_mem(rFlagsReg cr, rRegI src, memory mem, immI0 zero) 11220%{ 11221 match(Set cr (CmpI (AndI src (LoadI mem)) zero)); 11222 11223 format %{ "testl $src, $mem" %} 11224 opcode(0x85); 11225 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 11226 ins_pipe(ialu_cr_reg_mem); 11227%} 11228 11229// Unsigned compare Instructions; really, same as signed except they 11230// produce an rFlagsRegU instead of rFlagsReg. 11231instruct compU_rReg(rFlagsRegU cr, rRegI op1, rRegI op2) 11232%{ 11233 match(Set cr (CmpU op1 op2)); 11234 11235 format %{ "cmpl $op1, $op2\t# unsigned" %} 11236 opcode(0x3B); /* Opcode 3B /r */ 11237 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2)); 11238 ins_pipe(ialu_cr_reg_reg); 11239%} 11240 11241instruct compU_rReg_imm(rFlagsRegU cr, rRegI op1, immI op2) 11242%{ 11243 match(Set cr (CmpU op1 op2)); 11244 11245 format %{ "cmpl $op1, $op2\t# unsigned" %} 11246 opcode(0x81,0x07); /* Opcode 81 /7 */ 11247 ins_encode(OpcSErm(op1, op2), Con8or32(op2)); 11248 ins_pipe(ialu_cr_reg_imm); 11249%} 11250 11251instruct compU_rReg_mem(rFlagsRegU cr, rRegI op1, memory op2) 11252%{ 11253 match(Set cr (CmpU op1 (LoadI op2))); 11254 11255 ins_cost(500); // XXX 11256 format %{ "cmpl $op1, $op2\t# unsigned" %} 11257 opcode(0x3B); /* Opcode 3B /r */ 11258 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2)); 11259 ins_pipe(ialu_cr_reg_mem); 11260%} 11261 11262// // // Cisc-spilled version of cmpU_rReg 11263// //instruct compU_mem_rReg(rFlagsRegU cr, memory op1, rRegI op2) 11264// //%{ 11265// // match(Set cr (CmpU (LoadI op1) op2)); 11266// // 11267// // format %{ "CMPu $op1,$op2" %} 11268// // ins_cost(500); 11269// // opcode(0x39); /* Opcode 39 /r */ 11270// // ins_encode( OpcP, reg_mem( op1, op2) ); 11271// //%} 11272 11273instruct testU_reg(rFlagsRegU cr, rRegI src, immI0 zero) 11274%{ 11275 match(Set cr (CmpU src zero)); 11276 11277 format %{ "testl $src, $src\t# unsigned" %} 11278 opcode(0x85); 11279 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src)); 11280 ins_pipe(ialu_cr_reg_imm); 11281%} 11282 11283instruct compP_rReg(rFlagsRegU cr, rRegP op1, rRegP op2) 11284%{ 11285 match(Set cr (CmpP op1 op2)); 11286 11287 format %{ "cmpq $op1, $op2\t# ptr" %} 11288 opcode(0x3B); /* Opcode 3B /r */ 11289 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 11290 ins_pipe(ialu_cr_reg_reg); 11291%} 11292 11293instruct compP_rReg_mem(rFlagsRegU cr, rRegP op1, memory op2) 11294%{ 11295 match(Set cr (CmpP op1 (LoadP op2))); 11296 11297 ins_cost(500); // XXX 11298 format %{ "cmpq $op1, $op2\t# ptr" %} 11299 opcode(0x3B); /* Opcode 3B /r */ 11300 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11301 ins_pipe(ialu_cr_reg_mem); 11302%} 11303 11304// // // Cisc-spilled version of cmpP_rReg 11305// //instruct compP_mem_rReg(rFlagsRegU cr, memory op1, rRegP op2) 11306// //%{ 11307// // match(Set cr (CmpP (LoadP op1) op2)); 11308// // 11309// // format %{ "CMPu $op1,$op2" %} 11310// // ins_cost(500); 11311// // opcode(0x39); /* Opcode 39 /r */ 11312// // ins_encode( OpcP, reg_mem( op1, op2) ); 11313// //%} 11314 11315// XXX this is generalized by compP_rReg_mem??? 11316// Compare raw pointer (used in out-of-heap check). 11317// Only works because non-oop pointers must be raw pointers 11318// and raw pointers have no anti-dependencies. 11319instruct compP_mem_rReg(rFlagsRegU cr, rRegP op1, memory op2) 11320%{ 11321 predicate(!n->in(2)->in(2)->bottom_type()->isa_oop_ptr()); 11322 match(Set cr (CmpP op1 (LoadP op2))); 11323 11324 format %{ "cmpq $op1, $op2\t# raw ptr" %} 11325 opcode(0x3B); /* Opcode 3B /r */ 11326 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11327 ins_pipe(ialu_cr_reg_mem); 11328%} 11329 11330// This will generate a signed flags result. This should be OK since 11331// any compare to a zero should be eq/neq. 11332instruct testP_reg(rFlagsReg cr, rRegP src, immP0 zero) 11333%{ 11334 match(Set cr (CmpP src zero)); 11335 11336 format %{ "testq $src, $src\t# ptr" %} 11337 opcode(0x85); 11338 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 11339 ins_pipe(ialu_cr_reg_imm); 11340%} 11341 11342// This will generate a signed flags result. This should be OK since 11343// any compare to a zero should be eq/neq. 11344instruct testP_reg_mem(rFlagsReg cr, memory op, immP0 zero) 11345%{ 11346 match(Set cr (CmpP (LoadP op) zero)); 11347 11348 ins_cost(500); // XXX 11349 format %{ "testq $op, 0xffffffffffffffff\t# ptr" %} 11350 opcode(0xF7); /* Opcode F7 /0 */ 11351 ins_encode(REX_mem_wide(op), 11352 OpcP, RM_opc_mem(0x00, op), Con_d32(0xFFFFFFFF)); 11353 ins_pipe(ialu_cr_reg_imm); 11354%} 11355 11356 11357instruct compN_rReg(rFlagsRegU cr, rRegN op1, rRegN op2) 11358%{ 11359 match(Set cr (CmpN op1 op2)); 11360 11361 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 11362 ins_encode %{ __ cmpl(as_Register($op1$$reg), as_Register($op2$$reg)); %} 11363 ins_pipe(ialu_cr_reg_reg); 11364%} 11365 11366instruct compN_rReg_mem(rFlagsRegU cr, rRegN src, memory mem) 11367%{ 11368 match(Set cr (CmpN src (LoadN mem))); 11369 11370 ins_cost(500); // XXX 11371 format %{ "cmpl $src, mem\t# compressed ptr" %} 11372 ins_encode %{ 11373 Address adr = build_address($mem$$base, $mem$$index, $mem$$scale, $mem$$disp); 11374 __ cmpl(as_Register($src$$reg), adr); 11375 %} 11376 ins_pipe(ialu_cr_reg_mem); 11377%} 11378 11379instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{ 11380 match(Set cr (CmpN src zero)); 11381 11382 format %{ "testl $src, $src\t# compressed ptr" %} 11383 ins_encode %{ __ testl($src$$Register, $src$$Register); %} 11384 ins_pipe(ialu_cr_reg_imm); 11385%} 11386 11387instruct testN_reg_mem(rFlagsReg cr, memory mem, immN0 zero) 11388%{ 11389 match(Set cr (CmpN (LoadN mem) zero)); 11390 11391 ins_cost(500); // XXX 11392 format %{ "testl $mem, 0xffffffff\t# compressed ptr" %} 11393 ins_encode %{ 11394 Address addr = build_address($mem$$base, $mem$$index, $mem$$scale, $mem$$disp); 11395 __ cmpl(addr, (int)0xFFFFFFFF); 11396 %} 11397 ins_pipe(ialu_cr_reg_mem); 11398%} 11399 11400// Yanked all unsigned pointer compare operations. 11401// Pointer compares are done with CmpP which is already unsigned. 11402 11403instruct compL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 11404%{ 11405 match(Set cr (CmpL op1 op2)); 11406 11407 format %{ "cmpq $op1, $op2" %} 11408 opcode(0x3B); /* Opcode 3B /r */ 11409 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 11410 ins_pipe(ialu_cr_reg_reg); 11411%} 11412 11413instruct compL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 11414%{ 11415 match(Set cr (CmpL op1 op2)); 11416 11417 format %{ "cmpq $op1, $op2" %} 11418 opcode(0x81, 0x07); /* Opcode 81 /7 */ 11419 ins_encode(OpcSErm_wide(op1, op2), Con8or32(op2)); 11420 ins_pipe(ialu_cr_reg_imm); 11421%} 11422 11423instruct compL_rReg_mem(rFlagsReg cr, rRegL op1, memory op2) 11424%{ 11425 match(Set cr (CmpL op1 (LoadL op2))); 11426 11427 ins_cost(500); // XXX 11428 format %{ "cmpq $op1, $op2" %} 11429 opcode(0x3B); /* Opcode 3B /r */ 11430 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11431 ins_pipe(ialu_cr_reg_mem); 11432%} 11433 11434instruct testL_reg(rFlagsReg cr, rRegL src, immL0 zero) 11435%{ 11436 match(Set cr (CmpL src zero)); 11437 11438 format %{ "testq $src, $src" %} 11439 opcode(0x85); 11440 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 11441 ins_pipe(ialu_cr_reg_imm); 11442%} 11443 11444instruct testL_reg_imm(rFlagsReg cr, rRegL src, immL32 con, immL0 zero) 11445%{ 11446 match(Set cr (CmpL (AndL src con) zero)); 11447 11448 format %{ "testq $src, $con\t# long" %} 11449 opcode(0xF7, 0x00); 11450 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src), Con32(con)); 11451 ins_pipe(ialu_cr_reg_imm); 11452%} 11453 11454instruct testL_reg_mem(rFlagsReg cr, rRegL src, memory mem, immL0 zero) 11455%{ 11456 match(Set cr (CmpL (AndL src (LoadL mem)) zero)); 11457 11458 format %{ "testq $src, $mem" %} 11459 opcode(0x85); 11460 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 11461 ins_pipe(ialu_cr_reg_mem); 11462%} 11463 11464// Manifest a CmpL result in an integer register. Very painful. 11465// This is the test to avoid. 11466instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 11467%{ 11468 match(Set dst (CmpL3 src1 src2)); 11469 effect(KILL flags); 11470 11471 ins_cost(275); // XXX 11472 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 11473 "movl $dst, -1\n\t" 11474 "jl,s done\n\t" 11475 "setne $dst\n\t" 11476 "movzbl $dst, $dst\n\t" 11477 "done:" %} 11478 ins_encode(cmpl3_flag(src1, src2, dst)); 11479 ins_pipe(pipe_slow); 11480%} 11481 11482//----------Max and Min-------------------------------------------------------- 11483// Min Instructions 11484 11485instruct cmovI_reg_g(rRegI dst, rRegI src, rFlagsReg cr) 11486%{ 11487 effect(USE_DEF dst, USE src, USE cr); 11488 11489 format %{ "cmovlgt $dst, $src\t# min" %} 11490 opcode(0x0F, 0x4F); 11491 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 11492 ins_pipe(pipe_cmov_reg); 11493%} 11494 11495 11496instruct minI_rReg(rRegI dst, rRegI src) 11497%{ 11498 match(Set dst (MinI dst src)); 11499 11500 ins_cost(200); 11501 expand %{ 11502 rFlagsReg cr; 11503 compI_rReg(cr, dst, src); 11504 cmovI_reg_g(dst, src, cr); 11505 %} 11506%} 11507 11508instruct cmovI_reg_l(rRegI dst, rRegI src, rFlagsReg cr) 11509%{ 11510 effect(USE_DEF dst, USE src, USE cr); 11511 11512 format %{ "cmovllt $dst, $src\t# max" %} 11513 opcode(0x0F, 0x4C); 11514 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 11515 ins_pipe(pipe_cmov_reg); 11516%} 11517 11518 11519instruct maxI_rReg(rRegI dst, rRegI src) 11520%{ 11521 match(Set dst (MaxI dst src)); 11522 11523 ins_cost(200); 11524 expand %{ 11525 rFlagsReg cr; 11526 compI_rReg(cr, dst, src); 11527 cmovI_reg_l(dst, src, cr); 11528 %} 11529%} 11530 11531// ============================================================================ 11532// Branch Instructions 11533 11534// Jump Direct - Label defines a relative address from JMP+1 11535instruct jmpDir(label labl) 11536%{ 11537 match(Goto); 11538 effect(USE labl); 11539 11540 ins_cost(300); 11541 format %{ "jmp $labl" %} 11542 size(5); 11543 opcode(0xE9); 11544 ins_encode(OpcP, Lbl(labl)); 11545 ins_pipe(pipe_jmp); 11546 ins_pc_relative(1); 11547%} 11548 11549// Jump Direct Conditional - Label defines a relative address from Jcc+1 11550instruct jmpCon(cmpOp cop, rFlagsReg cr, label labl) 11551%{ 11552 match(If cop cr); 11553 effect(USE labl); 11554 11555 ins_cost(300); 11556 format %{ "j$cop $labl" %} 11557 size(6); 11558 opcode(0x0F, 0x80); 11559 ins_encode(Jcc(cop, labl)); 11560 ins_pipe(pipe_jcc); 11561 ins_pc_relative(1); 11562%} 11563 11564// Jump Direct Conditional - Label defines a relative address from Jcc+1 11565instruct jmpLoopEnd(cmpOp cop, rFlagsReg cr, label labl) 11566%{ 11567 match(CountedLoopEnd cop cr); 11568 effect(USE labl); 11569 11570 ins_cost(300); 11571 format %{ "j$cop $labl\t# loop end" %} 11572 size(6); 11573 opcode(0x0F, 0x80); 11574 ins_encode(Jcc(cop, labl)); 11575 ins_pipe(pipe_jcc); 11576 ins_pc_relative(1); 11577%} 11578 11579// Jump Direct Conditional - Label defines a relative address from Jcc+1 11580instruct jmpLoopEndU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 11581 match(CountedLoopEnd cop cmp); 11582 effect(USE labl); 11583 11584 ins_cost(300); 11585 format %{ "j$cop,u $labl\t# loop end" %} 11586 size(6); 11587 opcode(0x0F, 0x80); 11588 ins_encode(Jcc(cop, labl)); 11589 ins_pipe(pipe_jcc); 11590 ins_pc_relative(1); 11591%} 11592 11593instruct jmpLoopEndUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 11594 match(CountedLoopEnd cop cmp); 11595 effect(USE labl); 11596 11597 ins_cost(200); 11598 format %{ "j$cop,u $labl\t# loop end" %} 11599 size(6); 11600 opcode(0x0F, 0x80); 11601 ins_encode(Jcc(cop, labl)); 11602 ins_pipe(pipe_jcc); 11603 ins_pc_relative(1); 11604%} 11605 11606// Jump Direct Conditional - using unsigned comparison 11607instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 11608 match(If cop cmp); 11609 effect(USE labl); 11610 11611 ins_cost(300); 11612 format %{ "j$cop,u $labl" %} 11613 size(6); 11614 opcode(0x0F, 0x80); 11615 ins_encode(Jcc(cop, labl)); 11616 ins_pipe(pipe_jcc); 11617 ins_pc_relative(1); 11618%} 11619 11620instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 11621 match(If cop cmp); 11622 effect(USE labl); 11623 11624 ins_cost(200); 11625 format %{ "j$cop,u $labl" %} 11626 size(6); 11627 opcode(0x0F, 0x80); 11628 ins_encode(Jcc(cop, labl)); 11629 ins_pipe(pipe_jcc); 11630 ins_pc_relative(1); 11631%} 11632 11633instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 11634 match(If cop cmp); 11635 effect(USE labl); 11636 11637 ins_cost(200); 11638 format %{ $$template 11639 if ($cop$$cmpcode == Assembler::notEqual) { 11640 $$emit$$"jp,u $labl\n\t" 11641 $$emit$$"j$cop,u $labl" 11642 } else { 11643 $$emit$$"jp,u done\n\t" 11644 $$emit$$"j$cop,u $labl\n\t" 11645 $$emit$$"done:" 11646 } 11647 %} 11648 size(12); 11649 opcode(0x0F, 0x80); 11650 ins_encode %{ 11651 Label* l = $labl$$label; 11652 $$$emit8$primary; 11653 emit_cc(cbuf, $secondary, Assembler::parity); 11654 int parity_disp = -1; 11655 if ($cop$$cmpcode == Assembler::notEqual) { 11656 // the two jumps 6 bytes apart so the jump distances are too 11657 parity_disp = l ? (l->loc_pos() - (cbuf.code_size() + 4)) : 0; 11658 } else if ($cop$$cmpcode == Assembler::equal) { 11659 parity_disp = 6; 11660 } else { 11661 ShouldNotReachHere(); 11662 } 11663 emit_d32(cbuf, parity_disp); 11664 $$$emit8$primary; 11665 emit_cc(cbuf, $secondary, $cop$$cmpcode); 11666 int disp = l ? (l->loc_pos() - (cbuf.code_size() + 4)) : 0; 11667 emit_d32(cbuf, disp); 11668 %} 11669 ins_pipe(pipe_jcc); 11670 ins_pc_relative(1); 11671%} 11672 11673// ============================================================================ 11674// The 2nd slow-half of a subtype check. Scan the subklass's 2ndary 11675// superklass array for an instance of the superklass. Set a hidden 11676// internal cache on a hit (cache is checked with exposed code in 11677// gen_subtype_check()). Return NZ for a miss or zero for a hit. The 11678// encoding ALSO sets flags. 11679 11680instruct partialSubtypeCheck(rdi_RegP result, 11681 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 11682 rFlagsReg cr) 11683%{ 11684 match(Set result (PartialSubtypeCheck sub super)); 11685 effect(KILL rcx, KILL cr); 11686 11687 ins_cost(1100); // slightly larger than the next version 11688 format %{ "cmpq rax, rsi\n\t" 11689 "jeq,s hit\n\t" 11690 "movq rdi, [$sub + (sizeof(oopDesc) + Klass::secondary_supers_offset_in_bytes())]\n\t" 11691 "movl rcx, [rdi + arrayOopDesc::length_offset_in_bytes()]\t# length to scan\n\t" 11692 "addq rdi, arrayOopDex::base_offset_in_bytes(T_OBJECT)\t# Skip to start of data; set NZ in case count is zero\n\t" 11693 "repne scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t" 11694 "jne,s miss\t\t# Missed: rdi not-zero\n\t" 11695 "movq [$sub + (sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes())], $super\t# Hit: update cache\n\t" 11696 "hit:\n\t" 11697 "xorq $result, $result\t\t Hit: rdi zero\n\t" 11698 "miss:\t" %} 11699 11700 opcode(0x1); // Force a XOR of RDI 11701 ins_encode(enc_PartialSubtypeCheck()); 11702 ins_pipe(pipe_slow); 11703%} 11704 11705instruct partialSubtypeCheck_vs_Zero(rFlagsReg cr, 11706 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 11707 immP0 zero, 11708 rdi_RegP result) 11709%{ 11710 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 11711 predicate(!UseCompressedOops); // decoding oop kills condition codes 11712 effect(KILL rcx, KILL result); 11713 11714 ins_cost(1000); 11715 format %{ "cmpq rax, rsi\n\t" 11716 "jeq,s miss\t# Actually a hit; we are done.\n\t" 11717 "movq rdi, [$sub + (sizeof(oopDesc) + Klass::secondary_supers_offset_in_bytes())]\n\t" 11718 "movl rcx, [rdi + arrayOopDesc::length_offset_in_bytes()]\t# length to scan\n\t" 11719 "addq rdi, arrayOopDex::base_offset_in_bytes(T_OBJECT)\t# Skip to start of data; set NZ in case count is zero\n\t" 11720 "repne scasq\t# Scan *rdi++ for a match with rax while cx-- != 0\n\t" 11721 "jne,s miss\t\t# Missed: flags nz\n\t" 11722 "movq [$sub + (sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes())], $super\t# Hit: update cache\n\t" 11723 "miss:\t" %} 11724 11725 opcode(0x0); // No need to XOR RDI 11726 ins_encode(enc_PartialSubtypeCheck()); 11727 ins_pipe(pipe_slow); 11728%} 11729 11730// ============================================================================ 11731// Branch Instructions -- short offset versions 11732// 11733// These instructions are used to replace jumps of a long offset (the default 11734// match) with jumps of a shorter offset. These instructions are all tagged 11735// with the ins_short_branch attribute, which causes the ADLC to suppress the 11736// match rules in general matching. Instead, the ADLC generates a conversion 11737// method in the MachNode which can be used to do in-place replacement of the 11738// long variant with the shorter variant. The compiler will determine if a 11739// branch can be taken by the is_short_branch_offset() predicate in the machine 11740// specific code section of the file. 11741 11742// Jump Direct - Label defines a relative address from JMP+1 11743instruct jmpDir_short(label labl) %{ 11744 match(Goto); 11745 effect(USE labl); 11746 11747 ins_cost(300); 11748 format %{ "jmp,s $labl" %} 11749 size(2); 11750 opcode(0xEB); 11751 ins_encode(OpcP, LblShort(labl)); 11752 ins_pipe(pipe_jmp); 11753 ins_pc_relative(1); 11754 ins_short_branch(1); 11755%} 11756 11757// Jump Direct Conditional - Label defines a relative address from Jcc+1 11758instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{ 11759 match(If cop cr); 11760 effect(USE labl); 11761 11762 ins_cost(300); 11763 format %{ "j$cop,s $labl" %} 11764 size(2); 11765 opcode(0x70); 11766 ins_encode(JccShort(cop, labl)); 11767 ins_pipe(pipe_jcc); 11768 ins_pc_relative(1); 11769 ins_short_branch(1); 11770%} 11771 11772// Jump Direct Conditional - Label defines a relative address from Jcc+1 11773instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{ 11774 match(CountedLoopEnd cop cr); 11775 effect(USE labl); 11776 11777 ins_cost(300); 11778 format %{ "j$cop,s $labl\t# loop end" %} 11779 size(2); 11780 opcode(0x70); 11781 ins_encode(JccShort(cop, labl)); 11782 ins_pipe(pipe_jcc); 11783 ins_pc_relative(1); 11784 ins_short_branch(1); 11785%} 11786 11787// Jump Direct Conditional - Label defines a relative address from Jcc+1 11788instruct jmpLoopEndU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 11789 match(CountedLoopEnd cop cmp); 11790 effect(USE labl); 11791 11792 ins_cost(300); 11793 format %{ "j$cop,us $labl\t# loop end" %} 11794 size(2); 11795 opcode(0x70); 11796 ins_encode(JccShort(cop, labl)); 11797 ins_pipe(pipe_jcc); 11798 ins_pc_relative(1); 11799 ins_short_branch(1); 11800%} 11801 11802instruct jmpLoopEndUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 11803 match(CountedLoopEnd cop cmp); 11804 effect(USE labl); 11805 11806 ins_cost(300); 11807 format %{ "j$cop,us $labl\t# loop end" %} 11808 size(2); 11809 opcode(0x70); 11810 ins_encode(JccShort(cop, labl)); 11811 ins_pipe(pipe_jcc); 11812 ins_pc_relative(1); 11813 ins_short_branch(1); 11814%} 11815 11816// Jump Direct Conditional - using unsigned comparison 11817instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 11818 match(If cop cmp); 11819 effect(USE labl); 11820 11821 ins_cost(300); 11822 format %{ "j$cop,us $labl" %} 11823 size(2); 11824 opcode(0x70); 11825 ins_encode(JccShort(cop, labl)); 11826 ins_pipe(pipe_jcc); 11827 ins_pc_relative(1); 11828 ins_short_branch(1); 11829%} 11830 11831instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 11832 match(If cop cmp); 11833 effect(USE labl); 11834 11835 ins_cost(300); 11836 format %{ "j$cop,us $labl" %} 11837 size(2); 11838 opcode(0x70); 11839 ins_encode(JccShort(cop, labl)); 11840 ins_pipe(pipe_jcc); 11841 ins_pc_relative(1); 11842 ins_short_branch(1); 11843%} 11844 11845instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 11846 match(If cop cmp); 11847 effect(USE labl); 11848 11849 ins_cost(300); 11850 format %{ $$template 11851 if ($cop$$cmpcode == Assembler::notEqual) { 11852 $$emit$$"jp,u,s $labl\n\t" 11853 $$emit$$"j$cop,u,s $labl" 11854 } else { 11855 $$emit$$"jp,u,s done\n\t" 11856 $$emit$$"j$cop,u,s $labl\n\t" 11857 $$emit$$"done:" 11858 } 11859 %} 11860 size(4); 11861 opcode(0x70); 11862 ins_encode %{ 11863 Label* l = $labl$$label; 11864 emit_cc(cbuf, $primary, Assembler::parity); 11865 int parity_disp = -1; 11866 if ($cop$$cmpcode == Assembler::notEqual) { 11867 parity_disp = l ? (l->loc_pos() - (cbuf.code_size() + 1)) : 0; 11868 } else if ($cop$$cmpcode == Assembler::equal) { 11869 parity_disp = 2; 11870 } else { 11871 ShouldNotReachHere(); 11872 } 11873 emit_d8(cbuf, parity_disp); 11874 emit_cc(cbuf, $primary, $cop$$cmpcode); 11875 int disp = l ? (l->loc_pos() - (cbuf.code_size() + 1)) : 0; 11876 emit_d8(cbuf, disp); 11877 assert(-128 <= disp && disp <= 127, "Displacement too large for short jmp"); 11878 assert(-128 <= parity_disp && parity_disp <= 127, "Displacement too large for short jmp"); 11879 %} 11880 ins_pipe(pipe_jcc); 11881 ins_pc_relative(1); 11882 ins_short_branch(1); 11883%} 11884 11885// ============================================================================ 11886// inlined locking and unlocking 11887 11888instruct cmpFastLock(rFlagsReg cr, 11889 rRegP object, rRegP box, rax_RegI tmp, rRegP scr) 11890%{ 11891 match(Set cr (FastLock object box)); 11892 effect(TEMP tmp, TEMP scr); 11893 11894 ins_cost(300); 11895 format %{ "fastlock $object,$box,$tmp,$scr" %} 11896 ins_encode(Fast_Lock(object, box, tmp, scr)); 11897 ins_pipe(pipe_slow); 11898 ins_pc_relative(1); 11899%} 11900 11901instruct cmpFastUnlock(rFlagsReg cr, 11902 rRegP object, rax_RegP box, rRegP tmp) 11903%{ 11904 match(Set cr (FastUnlock object box)); 11905 effect(TEMP tmp); 11906 11907 ins_cost(300); 11908 format %{ "fastunlock $object, $box, $tmp" %} 11909 ins_encode(Fast_Unlock(object, box, tmp)); 11910 ins_pipe(pipe_slow); 11911 ins_pc_relative(1); 11912%} 11913 11914 11915// ============================================================================ 11916// Safepoint Instructions 11917instruct safePoint_poll(rFlagsReg cr) 11918%{ 11919 match(SafePoint); 11920 effect(KILL cr); 11921 11922 format %{ "testl rax, [rip + #offset_to_poll_page]\t" 11923 "# Safepoint: poll for GC" %} 11924 size(6); // Opcode + ModRM + Disp32 == 6 bytes 11925 ins_cost(125); 11926 ins_encode(enc_safepoint_poll); 11927 ins_pipe(ialu_reg_mem); 11928%} 11929 11930// ============================================================================ 11931// Procedure Call/Return Instructions 11932// Call Java Static Instruction 11933// Note: If this code changes, the corresponding ret_addr_offset() and 11934// compute_padding() functions will have to be adjusted. 11935instruct CallStaticJavaDirect(method meth) 11936%{ 11937 match(CallStaticJava); 11938 effect(USE meth); 11939 11940 ins_cost(300); 11941 format %{ "call,static " %} 11942 opcode(0xE8); /* E8 cd */ 11943 ins_encode(Java_Static_Call(meth), call_epilog); 11944 ins_pipe(pipe_slow); 11945 ins_pc_relative(1); 11946 ins_alignment(4); 11947%} 11948 11949// Call Java Dynamic Instruction 11950// Note: If this code changes, the corresponding ret_addr_offset() and 11951// compute_padding() functions will have to be adjusted. 11952instruct CallDynamicJavaDirect(method meth) 11953%{ 11954 match(CallDynamicJava); 11955 effect(USE meth); 11956 11957 ins_cost(300); 11958 format %{ "movq rax, #Universe::non_oop_word()\n\t" 11959 "call,dynamic " %} 11960 opcode(0xE8); /* E8 cd */ 11961 ins_encode(Java_Dynamic_Call(meth), call_epilog); 11962 ins_pipe(pipe_slow); 11963 ins_pc_relative(1); 11964 ins_alignment(4); 11965%} 11966 11967// Call Runtime Instruction 11968instruct CallRuntimeDirect(method meth) 11969%{ 11970 match(CallRuntime); 11971 effect(USE meth); 11972 11973 ins_cost(300); 11974 format %{ "call,runtime " %} 11975 opcode(0xE8); /* E8 cd */ 11976 ins_encode(Java_To_Runtime(meth)); 11977 ins_pipe(pipe_slow); 11978 ins_pc_relative(1); 11979%} 11980 11981// Call runtime without safepoint 11982instruct CallLeafDirect(method meth) 11983%{ 11984 match(CallLeaf); 11985 effect(USE meth); 11986 11987 ins_cost(300); 11988 format %{ "call_leaf,runtime " %} 11989 opcode(0xE8); /* E8 cd */ 11990 ins_encode(Java_To_Runtime(meth)); 11991 ins_pipe(pipe_slow); 11992 ins_pc_relative(1); 11993%} 11994 11995// Call runtime without safepoint 11996instruct CallLeafNoFPDirect(method meth) 11997%{ 11998 match(CallLeafNoFP); 11999 effect(USE meth); 12000 12001 ins_cost(300); 12002 format %{ "call_leaf_nofp,runtime " %} 12003 opcode(0xE8); /* E8 cd */ 12004 ins_encode(Java_To_Runtime(meth)); 12005 ins_pipe(pipe_slow); 12006 ins_pc_relative(1); 12007%} 12008 12009// Return Instruction 12010// Remove the return address & jump to it. 12011// Notice: We always emit a nop after a ret to make sure there is room 12012// for safepoint patching 12013instruct Ret() 12014%{ 12015 match(Return); 12016 12017 format %{ "ret" %} 12018 opcode(0xC3); 12019 ins_encode(OpcP); 12020 ins_pipe(pipe_jmp); 12021%} 12022 12023// Tail Call; Jump from runtime stub to Java code. 12024// Also known as an 'interprocedural jump'. 12025// Target of jump will eventually return to caller. 12026// TailJump below removes the return address. 12027instruct TailCalljmpInd(no_rbp_RegP jump_target, rbx_RegP method_oop) 12028%{ 12029 match(TailCall jump_target method_oop); 12030 12031 ins_cost(300); 12032 format %{ "jmp $jump_target\t# rbx holds method oop" %} 12033 opcode(0xFF, 0x4); /* Opcode FF /4 */ 12034 ins_encode(REX_reg(jump_target), OpcP, reg_opc(jump_target)); 12035 ins_pipe(pipe_jmp); 12036%} 12037 12038// Tail Jump; remove the return address; jump to target. 12039// TailCall above leaves the return address around. 12040instruct tailjmpInd(no_rbp_RegP jump_target, rax_RegP ex_oop) 12041%{ 12042 match(TailJump jump_target ex_oop); 12043 12044 ins_cost(300); 12045 format %{ "popq rdx\t# pop return address\n\t" 12046 "jmp $jump_target" %} 12047 opcode(0xFF, 0x4); /* Opcode FF /4 */ 12048 ins_encode(Opcode(0x5a), // popq rdx 12049 REX_reg(jump_target), OpcP, reg_opc(jump_target)); 12050 ins_pipe(pipe_jmp); 12051%} 12052 12053// Create exception oop: created by stack-crawling runtime code. 12054// Created exception is now available to this handler, and is setup 12055// just prior to jumping to this handler. No code emitted. 12056instruct CreateException(rax_RegP ex_oop) 12057%{ 12058 match(Set ex_oop (CreateEx)); 12059 12060 size(0); 12061 // use the following format syntax 12062 format %{ "# exception oop is in rax; no code emitted" %} 12063 ins_encode(); 12064 ins_pipe(empty); 12065%} 12066 12067// Rethrow exception: 12068// The exception oop will come in the first argument position. 12069// Then JUMP (not call) to the rethrow stub code. 12070instruct RethrowException() 12071%{ 12072 match(Rethrow); 12073 12074 // use the following format syntax 12075 format %{ "jmp rethrow_stub" %} 12076 ins_encode(enc_rethrow); 12077 ins_pipe(pipe_jmp); 12078%} 12079 12080 12081//----------PEEPHOLE RULES----------------------------------------------------- 12082// These must follow all instruction definitions as they use the names 12083// defined in the instructions definitions. 12084// 12085// peepmatch ( root_instr_name [precerding_instruction]* ); 12086// 12087// peepconstraint %{ 12088// (instruction_number.operand_name relational_op instruction_number.operand_name 12089// [, ...] ); 12090// // instruction numbers are zero-based using left to right order in peepmatch 12091// 12092// peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 12093// // provide an instruction_number.operand_name for each operand that appears 12094// // in the replacement instruction's match rule 12095// 12096// ---------VM FLAGS--------------------------------------------------------- 12097// 12098// All peephole optimizations can be turned off using -XX:-OptoPeephole 12099// 12100// Each peephole rule is given an identifying number starting with zero and 12101// increasing by one in the order seen by the parser. An individual peephole 12102// can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 12103// on the command-line. 12104// 12105// ---------CURRENT LIMITATIONS---------------------------------------------- 12106// 12107// Only match adjacent instructions in same basic block 12108// Only equality constraints 12109// Only constraints between operands, not (0.dest_reg == RAX_enc) 12110// Only one replacement instruction 12111// 12112// ---------EXAMPLE---------------------------------------------------------- 12113// 12114// // pertinent parts of existing instructions in architecture description 12115// instruct movI(rRegI dst, rRegI src) 12116// %{ 12117// match(Set dst (CopyI src)); 12118// %} 12119// 12120// instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr) 12121// %{ 12122// match(Set dst (AddI dst src)); 12123// effect(KILL cr); 12124// %} 12125// 12126// // Change (inc mov) to lea 12127// peephole %{ 12128// // increment preceeded by register-register move 12129// peepmatch ( incI_rReg movI ); 12130// // require that the destination register of the increment 12131// // match the destination register of the move 12132// peepconstraint ( 0.dst == 1.dst ); 12133// // construct a replacement instruction that sets 12134// // the destination to ( move's source register + one ) 12135// peepreplace ( leaI_rReg_immI( 0.dst 1.src 0.src ) ); 12136// %} 12137// 12138 12139// Implementation no longer uses movX instructions since 12140// machine-independent system no longer uses CopyX nodes. 12141// 12142// peephole 12143// %{ 12144// peepmatch (incI_rReg movI); 12145// peepconstraint (0.dst == 1.dst); 12146// peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 12147// %} 12148 12149// peephole 12150// %{ 12151// peepmatch (decI_rReg movI); 12152// peepconstraint (0.dst == 1.dst); 12153// peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 12154// %} 12155 12156// peephole 12157// %{ 12158// peepmatch (addI_rReg_imm movI); 12159// peepconstraint (0.dst == 1.dst); 12160// peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 12161// %} 12162 12163// peephole 12164// %{ 12165// peepmatch (incL_rReg movL); 12166// peepconstraint (0.dst == 1.dst); 12167// peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 12168// %} 12169 12170// peephole 12171// %{ 12172// peepmatch (decL_rReg movL); 12173// peepconstraint (0.dst == 1.dst); 12174// peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 12175// %} 12176 12177// peephole 12178// %{ 12179// peepmatch (addL_rReg_imm movL); 12180// peepconstraint (0.dst == 1.dst); 12181// peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 12182// %} 12183 12184// peephole 12185// %{ 12186// peepmatch (addP_rReg_imm movP); 12187// peepconstraint (0.dst == 1.dst); 12188// peepreplace (leaP_rReg_imm(0.dst 1.src 0.src)); 12189// %} 12190 12191// // Change load of spilled value to only a spill 12192// instruct storeI(memory mem, rRegI src) 12193// %{ 12194// match(Set mem (StoreI mem src)); 12195// %} 12196// 12197// instruct loadI(rRegI dst, memory mem) 12198// %{ 12199// match(Set dst (LoadI mem)); 12200// %} 12201// 12202 12203peephole 12204%{ 12205 peepmatch (loadI storeI); 12206 peepconstraint (1.src == 0.dst, 1.mem == 0.mem); 12207 peepreplace (storeI(1.mem 1.mem 1.src)); 12208%} 12209 12210peephole 12211%{ 12212 peepmatch (loadL storeL); 12213 peepconstraint (1.src == 0.dst, 1.mem == 0.mem); 12214 peepreplace (storeL(1.mem 1.mem 1.src)); 12215%} 12216 12217//----------SMARTSPILL RULES--------------------------------------------------- 12218// These must follow all instruction definitions as they use the names 12219// defined in the instructions definitions. 12220