1// 2// Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved. 3// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4// 5// This code is free software; you can redistribute it and/or modify it 6// under the terms of the GNU General Public License version 2 only, as 7// published by the Free Software Foundation. 8// 9// This code is distributed in the hope that it will be useful, but WITHOUT 10// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12// version 2 for more details (a copy is included in the LICENSE file that 13// accompanied this code). 14// 15// You should have received a copy of the GNU General Public License version 16// 2 along with this work; if not, write to the Free Software Foundation, 17// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18// 19// Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20// or visit www.oracle.com if you need additional information or have any 21// questions. 22// 23// 24 25// AMD64 Architecture Description File 26 27//----------REGISTER DEFINITION BLOCK------------------------------------------ 28// This information is used by the matcher and the register allocator to 29// describe individual registers and classes of registers within the target 30// archtecture. 31 32register %{ 33//----------Architecture Description Register Definitions---------------------- 34// General Registers 35// "reg_def" name ( register save type, C convention save type, 36// ideal register type, encoding ); 37// Register Save Types: 38// 39// NS = No-Save: The register allocator assumes that these registers 40// can be used without saving upon entry to the method, & 41// that they do not need to be saved at call sites. 42// 43// SOC = Save-On-Call: The register allocator assumes that these registers 44// can be used without saving upon entry to the method, 45// but that they must be saved at call sites. 46// 47// SOE = Save-On-Entry: The register allocator assumes that these registers 48// must be saved before using them upon entry to the 49// method, but they do not need to be saved at call 50// sites. 51// 52// AS = Always-Save: The register allocator assumes that these registers 53// must be saved before using them upon entry to the 54// method, & that they must be saved at call sites. 55// 56// Ideal Register Type is used to determine how to save & restore a 57// register. Op_RegI will get spilled with LoadI/StoreI, Op_RegP will get 58// spilled with LoadP/StoreP. If the register supports both, use Op_RegI. 59// 60// The encoding number is the actual bit-pattern placed into the opcodes. 61 62// General Registers 63// R8-R15 must be encoded with REX. (RSP, RBP, RSI, RDI need REX when 64// used as byte registers) 65 66// Previously set RBX, RSI, and RDI as save-on-entry for java code 67// Turn off SOE in java-code due to frequent use of uncommon-traps. 68// Now that allocator is better, turn on RSI and RDI as SOE registers. 69 70reg_def RAX (SOC, SOC, Op_RegI, 0, rax->as_VMReg()); 71reg_def RAX_H(SOC, SOC, Op_RegI, 0, rax->as_VMReg()->next()); 72 73reg_def RCX (SOC, SOC, Op_RegI, 1, rcx->as_VMReg()); 74reg_def RCX_H(SOC, SOC, Op_RegI, 1, rcx->as_VMReg()->next()); 75 76reg_def RDX (SOC, SOC, Op_RegI, 2, rdx->as_VMReg()); 77reg_def RDX_H(SOC, SOC, Op_RegI, 2, rdx->as_VMReg()->next()); 78 79reg_def RBX (SOC, SOE, Op_RegI, 3, rbx->as_VMReg()); 80reg_def RBX_H(SOC, SOE, Op_RegI, 3, rbx->as_VMReg()->next()); 81 82reg_def RSP (NS, NS, Op_RegI, 4, rsp->as_VMReg()); 83reg_def RSP_H(NS, NS, Op_RegI, 4, rsp->as_VMReg()->next()); 84 85// now that adapter frames are gone RBP is always saved and restored by the prolog/epilog code 86reg_def RBP (NS, SOE, Op_RegI, 5, rbp->as_VMReg()); 87reg_def RBP_H(NS, SOE, Op_RegI, 5, rbp->as_VMReg()->next()); 88 89#ifdef _WIN64 90 91reg_def RSI (SOC, SOE, Op_RegI, 6, rsi->as_VMReg()); 92reg_def RSI_H(SOC, SOE, Op_RegI, 6, rsi->as_VMReg()->next()); 93 94reg_def RDI (SOC, SOE, Op_RegI, 7, rdi->as_VMReg()); 95reg_def RDI_H(SOC, SOE, Op_RegI, 7, rdi->as_VMReg()->next()); 96 97#else 98 99reg_def RSI (SOC, SOC, Op_RegI, 6, rsi->as_VMReg()); 100reg_def RSI_H(SOC, SOC, Op_RegI, 6, rsi->as_VMReg()->next()); 101 102reg_def RDI (SOC, SOC, Op_RegI, 7, rdi->as_VMReg()); 103reg_def RDI_H(SOC, SOC, Op_RegI, 7, rdi->as_VMReg()->next()); 104 105#endif 106 107reg_def R8 (SOC, SOC, Op_RegI, 8, r8->as_VMReg()); 108reg_def R8_H (SOC, SOC, Op_RegI, 8, r8->as_VMReg()->next()); 109 110reg_def R9 (SOC, SOC, Op_RegI, 9, r9->as_VMReg()); 111reg_def R9_H (SOC, SOC, Op_RegI, 9, r9->as_VMReg()->next()); 112 113reg_def R10 (SOC, SOC, Op_RegI, 10, r10->as_VMReg()); 114reg_def R10_H(SOC, SOC, Op_RegI, 10, r10->as_VMReg()->next()); 115 116reg_def R11 (SOC, SOC, Op_RegI, 11, r11->as_VMReg()); 117reg_def R11_H(SOC, SOC, Op_RegI, 11, r11->as_VMReg()->next()); 118 119reg_def R12 (SOC, SOE, Op_RegI, 12, r12->as_VMReg()); 120reg_def R12_H(SOC, SOE, Op_RegI, 12, r12->as_VMReg()->next()); 121 122reg_def R13 (SOC, SOE, Op_RegI, 13, r13->as_VMReg()); 123reg_def R13_H(SOC, SOE, Op_RegI, 13, r13->as_VMReg()->next()); 124 125reg_def R14 (SOC, SOE, Op_RegI, 14, r14->as_VMReg()); 126reg_def R14_H(SOC, SOE, Op_RegI, 14, r14->as_VMReg()->next()); 127 128reg_def R15 (SOC, SOE, Op_RegI, 15, r15->as_VMReg()); 129reg_def R15_H(SOC, SOE, Op_RegI, 15, r15->as_VMReg()->next()); 130 131 132// Floating Point Registers 133 134// Specify priority of register selection within phases of register 135// allocation. Highest priority is first. A useful heuristic is to 136// give registers a low priority when they are required by machine 137// instructions, like EAX and EDX on I486, and choose no-save registers 138// before save-on-call, & save-on-call before save-on-entry. Registers 139// which participate in fixed calling sequences should come last. 140// Registers which are used as pairs must fall on an even boundary. 141 142alloc_class chunk0(R10, R10_H, 143 R11, R11_H, 144 R8, R8_H, 145 R9, R9_H, 146 R12, R12_H, 147 RCX, RCX_H, 148 RBX, RBX_H, 149 RDI, RDI_H, 150 RDX, RDX_H, 151 RSI, RSI_H, 152 RAX, RAX_H, 153 RBP, RBP_H, 154 R13, R13_H, 155 R14, R14_H, 156 R15, R15_H, 157 RSP, RSP_H); 158 159 160//----------Architecture Description Register Classes-------------------------- 161// Several register classes are automatically defined based upon information in 162// this architecture description. 163// 1) reg_class inline_cache_reg ( /* as def'd in frame section */ ) 164// 2) reg_class compiler_method_oop_reg ( /* as def'd in frame section */ ) 165// 2) reg_class interpreter_method_oop_reg ( /* as def'd in frame section */ ) 166// 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ ) 167// 168 169// Empty register class. 170reg_class no_reg(); 171 172// Class for all pointer registers (including RSP and RBP) 173reg_class any_reg_with_rbp(RAX, RAX_H, 174 RDX, RDX_H, 175 RBP, RBP_H, 176 RDI, RDI_H, 177 RSI, RSI_H, 178 RCX, RCX_H, 179 RBX, RBX_H, 180 RSP, RSP_H, 181 R8, R8_H, 182 R9, R9_H, 183 R10, R10_H, 184 R11, R11_H, 185 R12, R12_H, 186 R13, R13_H, 187 R14, R14_H, 188 R15, R15_H); 189 190// Class for all pointer registers (including RSP, but excluding RBP) 191reg_class any_reg_no_rbp(RAX, RAX_H, 192 RDX, RDX_H, 193 RDI, RDI_H, 194 RSI, RSI_H, 195 RCX, RCX_H, 196 RBX, RBX_H, 197 RSP, RSP_H, 198 R8, R8_H, 199 R9, R9_H, 200 R10, R10_H, 201 R11, R11_H, 202 R12, R12_H, 203 R13, R13_H, 204 R14, R14_H, 205 R15, R15_H); 206 207// Dynamic register class that selects at runtime between register classes 208// any_reg_no_rbp and any_reg_with_rbp (depending on the value of the flag PreserveFramePointer). 209// Equivalent to: return PreserveFramePointer ? any_reg_no_rbp : any_reg_with_rbp; 210reg_class_dynamic any_reg(any_reg_no_rbp, any_reg_with_rbp, %{ PreserveFramePointer %}); 211 212// Class for all pointer registers (excluding RSP) 213reg_class ptr_reg_with_rbp(RAX, RAX_H, 214 RDX, RDX_H, 215 RBP, RBP_H, 216 RDI, RDI_H, 217 RSI, RSI_H, 218 RCX, RCX_H, 219 RBX, RBX_H, 220 R8, R8_H, 221 R9, R9_H, 222 R10, R10_H, 223 R11, R11_H, 224 R13, R13_H, 225 R14, R14_H); 226 227// Class for all pointer registers (excluding RSP and RBP) 228reg_class ptr_reg_no_rbp(RAX, RAX_H, 229 RDX, RDX_H, 230 RDI, RDI_H, 231 RSI, RSI_H, 232 RCX, RCX_H, 233 RBX, RBX_H, 234 R8, R8_H, 235 R9, R9_H, 236 R10, R10_H, 237 R11, R11_H, 238 R13, R13_H, 239 R14, R14_H); 240 241// Dynamic register class that selects between ptr_reg_no_rbp and ptr_reg_with_rbp. 242reg_class_dynamic ptr_reg(ptr_reg_no_rbp, ptr_reg_with_rbp, %{ PreserveFramePointer %}); 243 244// Class for all pointer registers (excluding RAX and RSP) 245reg_class ptr_no_rax_reg_with_rbp(RDX, RDX_H, 246 RBP, RBP_H, 247 RDI, RDI_H, 248 RSI, RSI_H, 249 RCX, RCX_H, 250 RBX, RBX_H, 251 R8, R8_H, 252 R9, R9_H, 253 R10, R10_H, 254 R11, R11_H, 255 R13, R13_H, 256 R14, R14_H); 257 258// Class for all pointer registers (excluding RAX, RSP, and RBP) 259reg_class ptr_no_rax_reg_no_rbp(RDX, RDX_H, 260 RDI, RDI_H, 261 RSI, RSI_H, 262 RCX, RCX_H, 263 RBX, RBX_H, 264 R8, R8_H, 265 R9, R9_H, 266 R10, R10_H, 267 R11, R11_H, 268 R13, R13_H, 269 R14, R14_H); 270 271// Dynamic register class that selects between ptr_no_rax_reg_no_rbp and ptr_no_rax_reg_with_rbp. 272reg_class_dynamic ptr_no_rax_reg(ptr_no_rax_reg_no_rbp, ptr_no_rax_reg_with_rbp, %{ PreserveFramePointer %}); 273 274// Class for all pointer registers (excluding RAX, RBX, and RSP) 275reg_class ptr_no_rax_rbx_reg_with_rbp(RDX, RDX_H, 276 RBP, RBP_H, 277 RDI, RDI_H, 278 RSI, RSI_H, 279 RCX, RCX_H, 280 R8, R8_H, 281 R9, R9_H, 282 R10, R10_H, 283 R11, R11_H, 284 R13, R13_H, 285 R14, R14_H); 286 287// Class for all pointer registers (excluding RAX, RBX, RSP, and RBP) 288reg_class ptr_no_rax_rbx_reg_no_rbp(RDX, RDX_H, 289 RDI, RDI_H, 290 RSI, RSI_H, 291 RCX, RCX_H, 292 R8, R8_H, 293 R9, R9_H, 294 R10, R10_H, 295 R11, R11_H, 296 R13, R13_H, 297 R14, R14_H); 298 299// Dynamic register class that selects between ptr_no_rax_rbx_reg_no_rbp and ptr_no_rax_rbx_reg_with_rbp. 300reg_class_dynamic ptr_no_rax_rbx_reg(ptr_no_rax_rbx_reg_no_rbp, ptr_no_rax_rbx_reg_with_rbp, %{ PreserveFramePointer %}); 301 302// Singleton class for RAX pointer register 303reg_class ptr_rax_reg(RAX, RAX_H); 304 305// Singleton class for RBX pointer register 306reg_class ptr_rbx_reg(RBX, RBX_H); 307 308// Singleton class for RSI pointer register 309reg_class ptr_rsi_reg(RSI, RSI_H); 310 311// Singleton class for RDI pointer register 312reg_class ptr_rdi_reg(RDI, RDI_H); 313 314// Singleton class for stack pointer 315reg_class ptr_rsp_reg(RSP, RSP_H); 316 317// Singleton class for TLS pointer 318reg_class ptr_r15_reg(R15, R15_H); 319 320// The registers which can be used for 321// a thread local safepoint poll 322// * R12 is reserved for heap base 323// * R13 cannot be encoded for addressing without an offset byte 324// * R15 is reserved for the JavaThread 325reg_class ptr_rex_reg(R8, R8_H, 326 R9, R9_H, 327 R10, R10_H, 328 R11, R11_H, 329 R14, R14_H); 330 331 332// Class for all long registers (excluding RSP) 333reg_class long_reg_with_rbp(RAX, RAX_H, 334 RDX, RDX_H, 335 RBP, RBP_H, 336 RDI, RDI_H, 337 RSI, RSI_H, 338 RCX, RCX_H, 339 RBX, RBX_H, 340 R8, R8_H, 341 R9, R9_H, 342 R10, R10_H, 343 R11, R11_H, 344 R13, R13_H, 345 R14, R14_H); 346 347// Class for all long registers (excluding RSP and RBP) 348reg_class long_reg_no_rbp(RAX, RAX_H, 349 RDX, RDX_H, 350 RDI, RDI_H, 351 RSI, RSI_H, 352 RCX, RCX_H, 353 RBX, RBX_H, 354 R8, R8_H, 355 R9, R9_H, 356 R10, R10_H, 357 R11, R11_H, 358 R13, R13_H, 359 R14, R14_H); 360 361// Dynamic register class that selects between long_reg_no_rbp and long_reg_with_rbp. 362reg_class_dynamic long_reg(long_reg_no_rbp, long_reg_with_rbp, %{ PreserveFramePointer %}); 363 364// Class for all long registers (excluding RAX, RDX and RSP) 365reg_class long_no_rax_rdx_reg_with_rbp(RBP, RBP_H, 366 RDI, RDI_H, 367 RSI, RSI_H, 368 RCX, RCX_H, 369 RBX, RBX_H, 370 R8, R8_H, 371 R9, R9_H, 372 R10, R10_H, 373 R11, R11_H, 374 R13, R13_H, 375 R14, R14_H); 376 377// Class for all long registers (excluding RAX, RDX, RSP, and RBP) 378reg_class long_no_rax_rdx_reg_no_rbp(RDI, RDI_H, 379 RSI, RSI_H, 380 RCX, RCX_H, 381 RBX, RBX_H, 382 R8, R8_H, 383 R9, R9_H, 384 R10, R10_H, 385 R11, R11_H, 386 R13, R13_H, 387 R14, R14_H); 388 389// Dynamic register class that selects between long_no_rax_rdx_reg_no_rbp and long_no_rax_rdx_reg_with_rbp. 390reg_class_dynamic long_no_rax_rdx_reg(long_no_rax_rdx_reg_no_rbp, long_no_rax_rdx_reg_with_rbp, %{ PreserveFramePointer %}); 391 392// Class for all long registers (excluding RCX and RSP) 393reg_class long_no_rcx_reg_with_rbp(RBP, RBP_H, 394 RDI, RDI_H, 395 RSI, RSI_H, 396 RAX, RAX_H, 397 RDX, RDX_H, 398 RBX, RBX_H, 399 R8, R8_H, 400 R9, R9_H, 401 R10, R10_H, 402 R11, R11_H, 403 R13, R13_H, 404 R14, R14_H); 405 406// Class for all long registers (excluding RCX, RSP, and RBP) 407reg_class long_no_rcx_reg_no_rbp(RDI, RDI_H, 408 RSI, RSI_H, 409 RAX, RAX_H, 410 RDX, RDX_H, 411 RBX, RBX_H, 412 R8, R8_H, 413 R9, R9_H, 414 R10, R10_H, 415 R11, R11_H, 416 R13, R13_H, 417 R14, R14_H); 418 419// Dynamic register class that selects between long_no_rcx_reg_no_rbp and long_no_rcx_reg_with_rbp. 420reg_class_dynamic long_no_rcx_reg(long_no_rcx_reg_no_rbp, long_no_rcx_reg_with_rbp, %{ PreserveFramePointer %}); 421 422// Singleton class for RAX long register 423reg_class long_rax_reg(RAX, RAX_H); 424 425// Singleton class for RCX long register 426reg_class long_rcx_reg(RCX, RCX_H); 427 428// Singleton class for RDX long register 429reg_class long_rdx_reg(RDX, RDX_H); 430 431// Class for all int registers (excluding RSP) 432reg_class int_reg_with_rbp(RAX, 433 RDX, 434 RBP, 435 RDI, 436 RSI, 437 RCX, 438 RBX, 439 R8, 440 R9, 441 R10, 442 R11, 443 R13, 444 R14); 445 446// Class for all int registers (excluding RSP and RBP) 447reg_class int_reg_no_rbp(RAX, 448 RDX, 449 RDI, 450 RSI, 451 RCX, 452 RBX, 453 R8, 454 R9, 455 R10, 456 R11, 457 R13, 458 R14); 459 460// Dynamic register class that selects between int_reg_no_rbp and int_reg_with_rbp. 461reg_class_dynamic int_reg(int_reg_no_rbp, int_reg_with_rbp, %{ PreserveFramePointer %}); 462 463// Class for all int registers (excluding RCX and RSP) 464reg_class int_no_rcx_reg_with_rbp(RAX, 465 RDX, 466 RBP, 467 RDI, 468 RSI, 469 RBX, 470 R8, 471 R9, 472 R10, 473 R11, 474 R13, 475 R14); 476 477// Class for all int registers (excluding RCX, RSP, and RBP) 478reg_class int_no_rcx_reg_no_rbp(RAX, 479 RDX, 480 RDI, 481 RSI, 482 RBX, 483 R8, 484 R9, 485 R10, 486 R11, 487 R13, 488 R14); 489 490// Dynamic register class that selects between int_no_rcx_reg_no_rbp and int_no_rcx_reg_with_rbp. 491reg_class_dynamic int_no_rcx_reg(int_no_rcx_reg_no_rbp, int_no_rcx_reg_with_rbp, %{ PreserveFramePointer %}); 492 493// Class for all int registers (excluding RAX, RDX, and RSP) 494reg_class int_no_rax_rdx_reg_with_rbp(RBP, 495 RDI, 496 RSI, 497 RCX, 498 RBX, 499 R8, 500 R9, 501 R10, 502 R11, 503 R13, 504 R14); 505 506// Class for all int registers (excluding RAX, RDX, RSP, and RBP) 507reg_class int_no_rax_rdx_reg_no_rbp(RDI, 508 RSI, 509 RCX, 510 RBX, 511 R8, 512 R9, 513 R10, 514 R11, 515 R13, 516 R14); 517 518// Dynamic register class that selects between int_no_rax_rdx_reg_no_rbp and int_no_rax_rdx_reg_with_rbp. 519reg_class_dynamic int_no_rax_rdx_reg(int_no_rax_rdx_reg_no_rbp, int_no_rax_rdx_reg_with_rbp, %{ PreserveFramePointer %}); 520 521// Singleton class for RAX int register 522reg_class int_rax_reg(RAX); 523 524// Singleton class for RBX int register 525reg_class int_rbx_reg(RBX); 526 527// Singleton class for RCX int register 528reg_class int_rcx_reg(RCX); 529 530// Singleton class for RCX int register 531reg_class int_rdx_reg(RDX); 532 533// Singleton class for RCX int register 534reg_class int_rdi_reg(RDI); 535 536// Singleton class for instruction pointer 537// reg_class ip_reg(RIP); 538 539%} 540 541source_hpp %{ 542#if INCLUDE_ZGC 543#include "gc/z/zBarrierSetAssembler.hpp" 544#endif 545%} 546 547//----------SOURCE BLOCK------------------------------------------------------- 548// This is a block of C++ code which provides values, functions, and 549// definitions necessary in the rest of the architecture description 550source %{ 551#define RELOC_IMM64 Assembler::imm_operand 552#define RELOC_DISP32 Assembler::disp32_operand 553 554#define __ _masm. 555 556static bool generate_vzeroupper(Compile* C) { 557 return (VM_Version::supports_vzeroupper() && (C->max_vector_size() > 16 || C->clear_upper_avx() == true)) ? true: false; // Generate vzeroupper 558} 559 560static int clear_avx_size() { 561 return generate_vzeroupper(Compile::current()) ? 3: 0; // vzeroupper 562} 563 564// !!!!! Special hack to get all types of calls to specify the byte offset 565// from the start of the call to the point where the return address 566// will point. 567int MachCallStaticJavaNode::ret_addr_offset() 568{ 569 int offset = 5; // 5 bytes from start of call to where return address points 570 offset += clear_avx_size(); 571 return offset; 572} 573 574int MachCallDynamicJavaNode::ret_addr_offset() 575{ 576 int offset = 15; // 15 bytes from start of call to where return address points 577 offset += clear_avx_size(); 578 return offset; 579} 580 581int MachCallRuntimeNode::ret_addr_offset() { 582 int offset = 13; // movq r10,#addr; callq (r10) 583 offset += clear_avx_size(); 584 return offset; 585} 586 587// Indicate if the safepoint node needs the polling page as an input, 588// it does if the polling page is more than disp32 away. 589bool SafePointNode::needs_polling_address_input() 590{ 591 return SafepointMechanism::uses_thread_local_poll() || Assembler::is_polling_page_far(); 592} 593 594// 595// Compute padding required for nodes which need alignment 596// 597 598// The address of the call instruction needs to be 4-byte aligned to 599// ensure that it does not span a cache line so that it can be patched. 600int CallStaticJavaDirectNode::compute_padding(int current_offset) const 601{ 602 current_offset += clear_avx_size(); // skip vzeroupper 603 current_offset += 1; // skip call opcode byte 604 return align_up(current_offset, alignment_required()) - current_offset; 605} 606 607// The address of the call instruction needs to be 4-byte aligned to 608// ensure that it does not span a cache line so that it can be patched. 609int CallDynamicJavaDirectNode::compute_padding(int current_offset) const 610{ 611 current_offset += clear_avx_size(); // skip vzeroupper 612 current_offset += 11; // skip movq instruction + call opcode byte 613 return align_up(current_offset, alignment_required()) - current_offset; 614} 615 616// EMIT_RM() 617void emit_rm(CodeBuffer &cbuf, int f1, int f2, int f3) { 618 unsigned char c = (unsigned char) ((f1 << 6) | (f2 << 3) | f3); 619 cbuf.insts()->emit_int8(c); 620} 621 622// EMIT_CC() 623void emit_cc(CodeBuffer &cbuf, int f1, int f2) { 624 unsigned char c = (unsigned char) (f1 | f2); 625 cbuf.insts()->emit_int8(c); 626} 627 628// EMIT_OPCODE() 629void emit_opcode(CodeBuffer &cbuf, int code) { 630 cbuf.insts()->emit_int8((unsigned char) code); 631} 632 633// EMIT_OPCODE() w/ relocation information 634void emit_opcode(CodeBuffer &cbuf, 635 int code, relocInfo::relocType reloc, int offset, int format) 636{ 637 cbuf.relocate(cbuf.insts_mark() + offset, reloc, format); 638 emit_opcode(cbuf, code); 639} 640 641// EMIT_D8() 642void emit_d8(CodeBuffer &cbuf, int d8) { 643 cbuf.insts()->emit_int8((unsigned char) d8); 644} 645 646// EMIT_D16() 647void emit_d16(CodeBuffer &cbuf, int d16) { 648 cbuf.insts()->emit_int16(d16); 649} 650 651// EMIT_D32() 652void emit_d32(CodeBuffer &cbuf, int d32) { 653 cbuf.insts()->emit_int32(d32); 654} 655 656// EMIT_D64() 657void emit_d64(CodeBuffer &cbuf, int64_t d64) { 658 cbuf.insts()->emit_int64(d64); 659} 660 661// emit 32 bit value and construct relocation entry from relocInfo::relocType 662void emit_d32_reloc(CodeBuffer& cbuf, 663 int d32, 664 relocInfo::relocType reloc, 665 int format) 666{ 667 assert(reloc != relocInfo::external_word_type, "use 2-arg emit_d32_reloc"); 668 cbuf.relocate(cbuf.insts_mark(), reloc, format); 669 cbuf.insts()->emit_int32(d32); 670} 671 672// emit 32 bit value and construct relocation entry from RelocationHolder 673void emit_d32_reloc(CodeBuffer& cbuf, int d32, RelocationHolder const& rspec, int format) { 674#ifdef ASSERT 675 if (rspec.reloc()->type() == relocInfo::oop_type && 676 d32 != 0 && d32 != (intptr_t) Universe::non_oop_word()) { 677 assert(Universe::heap()->is_in_reserved((address)(intptr_t)d32), "should be real oop"); 678 assert(oopDesc::is_oop(cast_to_oop((intptr_t)d32)) && (ScavengeRootsInCode || !Universe::heap()->is_scavengable(cast_to_oop((intptr_t)d32))), "cannot embed scavengable oops in code"); 679 } 680#endif 681 cbuf.relocate(cbuf.insts_mark(), rspec, format); 682 cbuf.insts()->emit_int32(d32); 683} 684 685void emit_d32_reloc(CodeBuffer& cbuf, address addr) { 686 address next_ip = cbuf.insts_end() + 4; 687 emit_d32_reloc(cbuf, (int) (addr - next_ip), 688 external_word_Relocation::spec(addr), 689 RELOC_DISP32); 690} 691 692 693// emit 64 bit value and construct relocation entry from relocInfo::relocType 694void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, relocInfo::relocType reloc, int format) { 695 cbuf.relocate(cbuf.insts_mark(), reloc, format); 696 cbuf.insts()->emit_int64(d64); 697} 698 699// emit 64 bit value and construct relocation entry from RelocationHolder 700void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, RelocationHolder const& rspec, int format) { 701#ifdef ASSERT 702 if (rspec.reloc()->type() == relocInfo::oop_type && 703 d64 != 0 && d64 != (int64_t) Universe::non_oop_word()) { 704 assert(Universe::heap()->is_in_reserved((address)d64), "should be real oop"); 705 assert(oopDesc::is_oop(cast_to_oop(d64)) && (ScavengeRootsInCode || !Universe::heap()->is_scavengable(cast_to_oop(d64))), 706 "cannot embed scavengable oops in code"); 707 } 708#endif 709 cbuf.relocate(cbuf.insts_mark(), rspec, format); 710 cbuf.insts()->emit_int64(d64); 711} 712 713// Access stack slot for load or store 714void store_to_stackslot(CodeBuffer &cbuf, int opcode, int rm_field, int disp) 715{ 716 emit_opcode(cbuf, opcode); // (e.g., FILD [RSP+src]) 717 if (-0x80 <= disp && disp < 0x80) { 718 emit_rm(cbuf, 0x01, rm_field, RSP_enc); // R/M byte 719 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte 720 emit_d8(cbuf, disp); // Displacement // R/M byte 721 } else { 722 emit_rm(cbuf, 0x02, rm_field, RSP_enc); // R/M byte 723 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte 724 emit_d32(cbuf, disp); // Displacement // R/M byte 725 } 726} 727 728 // rRegI ereg, memory mem) %{ // emit_reg_mem 729void encode_RegMem(CodeBuffer &cbuf, 730 int reg, 731 int base, int index, int scale, int disp, relocInfo::relocType disp_reloc) 732{ 733 assert(disp_reloc == relocInfo::none, "cannot have disp"); 734 int regenc = reg & 7; 735 int baseenc = base & 7; 736 int indexenc = index & 7; 737 738 // There is no index & no scale, use form without SIB byte 739 if (index == 0x4 && scale == 0 && base != RSP_enc && base != R12_enc) { 740 // If no displacement, mode is 0x0; unless base is [RBP] or [R13] 741 if (disp == 0 && base != RBP_enc && base != R13_enc) { 742 emit_rm(cbuf, 0x0, regenc, baseenc); // * 743 } else if (-0x80 <= disp && disp < 0x80 && disp_reloc == relocInfo::none) { 744 // If 8-bit displacement, mode 0x1 745 emit_rm(cbuf, 0x1, regenc, baseenc); // * 746 emit_d8(cbuf, disp); 747 } else { 748 // If 32-bit displacement 749 if (base == -1) { // Special flag for absolute address 750 emit_rm(cbuf, 0x0, regenc, 0x5); // * 751 if (disp_reloc != relocInfo::none) { 752 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 753 } else { 754 emit_d32(cbuf, disp); 755 } 756 } else { 757 // Normal base + offset 758 emit_rm(cbuf, 0x2, regenc, baseenc); // * 759 if (disp_reloc != relocInfo::none) { 760 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 761 } else { 762 emit_d32(cbuf, disp); 763 } 764 } 765 } 766 } else { 767 // Else, encode with the SIB byte 768 // If no displacement, mode is 0x0; unless base is [RBP] or [R13] 769 if (disp == 0 && base != RBP_enc && base != R13_enc) { 770 // If no displacement 771 emit_rm(cbuf, 0x0, regenc, 0x4); // * 772 emit_rm(cbuf, scale, indexenc, baseenc); 773 } else { 774 if (-0x80 <= disp && disp < 0x80 && disp_reloc == relocInfo::none) { 775 // If 8-bit displacement, mode 0x1 776 emit_rm(cbuf, 0x1, regenc, 0x4); // * 777 emit_rm(cbuf, scale, indexenc, baseenc); 778 emit_d8(cbuf, disp); 779 } else { 780 // If 32-bit displacement 781 if (base == 0x04 ) { 782 emit_rm(cbuf, 0x2, regenc, 0x4); 783 emit_rm(cbuf, scale, indexenc, 0x04); // XXX is this valid??? 784 } else { 785 emit_rm(cbuf, 0x2, regenc, 0x4); 786 emit_rm(cbuf, scale, indexenc, baseenc); // * 787 } 788 if (disp_reloc != relocInfo::none) { 789 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 790 } else { 791 emit_d32(cbuf, disp); 792 } 793 } 794 } 795 } 796} 797 798// This could be in MacroAssembler but it's fairly C2 specific 799void emit_cmpfp_fixup(MacroAssembler& _masm) { 800 Label exit; 801 __ jccb(Assembler::noParity, exit); 802 __ pushf(); 803 // 804 // comiss/ucomiss instructions set ZF,PF,CF flags and 805 // zero OF,AF,SF for NaN values. 806 // Fixup flags by zeroing ZF,PF so that compare of NaN 807 // values returns 'less than' result (CF is set). 808 // Leave the rest of flags unchanged. 809 // 810 // 7 6 5 4 3 2 1 0 811 // |S|Z|r|A|r|P|r|C| (r - reserved bit) 812 // 0 0 1 0 1 0 1 1 (0x2B) 813 // 814 __ andq(Address(rsp, 0), 0xffffff2b); 815 __ popf(); 816 __ bind(exit); 817} 818 819void emit_cmpfp3(MacroAssembler& _masm, Register dst) { 820 Label done; 821 __ movl(dst, -1); 822 __ jcc(Assembler::parity, done); 823 __ jcc(Assembler::below, done); 824 __ setb(Assembler::notEqual, dst); 825 __ movzbl(dst, dst); 826 __ bind(done); 827} 828 829// Math.min() # Math.max() 830// -------------------------- 831// ucomis[s/d] # 832// ja -> b # a 833// jp -> NaN # NaN 834// jb -> a # b 835// je # 836// |-jz -> a | b # a & b 837// | -> a # 838void emit_fp_min_max(MacroAssembler& _masm, XMMRegister dst, 839 XMMRegister a, XMMRegister b, 840 XMMRegister xmmt, Register rt, 841 bool min, bool single) { 842 843 Label nan, zero, below, above, done; 844 845 if (single) 846 __ ucomiss(a, b); 847 else 848 __ ucomisd(a, b); 849 850 if (dst->encoding() != (min ? b : a)->encoding()) 851 __ jccb(Assembler::above, above); // CF=0 & ZF=0 852 else 853 __ jccb(Assembler::above, done); 854 855 __ jccb(Assembler::parity, nan); // PF=1 856 __ jccb(Assembler::below, below); // CF=1 857 858 // equal 859 __ vpxor(xmmt, xmmt, xmmt, Assembler::AVX_128bit); 860 if (single) { 861 __ ucomiss(a, xmmt); 862 __ jccb(Assembler::equal, zero); 863 864 __ movflt(dst, a); 865 __ jmp(done); 866 } 867 else { 868 __ ucomisd(a, xmmt); 869 __ jccb(Assembler::equal, zero); 870 871 __ movdbl(dst, a); 872 __ jmp(done); 873 } 874 875 __ bind(zero); 876 if (min) 877 __ vpor(dst, a, b, Assembler::AVX_128bit); 878 else 879 __ vpand(dst, a, b, Assembler::AVX_128bit); 880 881 __ jmp(done); 882 883 __ bind(above); 884 if (single) 885 __ movflt(dst, min ? b : a); 886 else 887 __ movdbl(dst, min ? b : a); 888 889 __ jmp(done); 890 891 __ bind(nan); 892 if (single) { 893 __ movl(rt, 0x7fc00000); // Float.NaN 894 __ movdl(dst, rt); 895 } 896 else { 897 __ mov64(rt, 0x7ff8000000000000L); // Double.NaN 898 __ movdq(dst, rt); 899 } 900 __ jmp(done); 901 902 __ bind(below); 903 if (single) 904 __ movflt(dst, min ? a : b); 905 else 906 __ movdbl(dst, min ? a : b); 907 908 __ bind(done); 909} 910 911//============================================================================= 912const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; 913 914int Compile::ConstantTable::calculate_table_base_offset() const { 915 return 0; // absolute addressing, no offset 916} 917 918bool MachConstantBaseNode::requires_postalloc_expand() const { return false; } 919void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 920 ShouldNotReachHere(); 921} 922 923void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 924 // Empty encoding 925} 926 927uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 928 return 0; 929} 930 931#ifndef PRODUCT 932void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 933 st->print("# MachConstantBaseNode (empty encoding)"); 934} 935#endif 936 937 938//============================================================================= 939#ifndef PRODUCT 940void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 941 Compile* C = ra_->C; 942 943 int framesize = C->frame_size_in_bytes(); 944 int bangsize = C->bang_size_in_bytes(); 945 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 946 // Remove wordSize for return addr which is already pushed. 947 framesize -= wordSize; 948 949 if (C->need_stack_bang(bangsize)) { 950 framesize -= wordSize; 951 st->print("# stack bang (%d bytes)", bangsize); 952 st->print("\n\t"); 953 st->print("pushq rbp\t# Save rbp"); 954 if (PreserveFramePointer) { 955 st->print("\n\t"); 956 st->print("movq rbp, rsp\t# Save the caller's SP into rbp"); 957 } 958 if (framesize) { 959 st->print("\n\t"); 960 st->print("subq rsp, #%d\t# Create frame",framesize); 961 } 962 } else { 963 st->print("subq rsp, #%d\t# Create frame",framesize); 964 st->print("\n\t"); 965 framesize -= wordSize; 966 st->print("movq [rsp + #%d], rbp\t# Save rbp",framesize); 967 if (PreserveFramePointer) { 968 st->print("\n\t"); 969 st->print("movq rbp, rsp\t# Save the caller's SP into rbp"); 970 if (framesize > 0) { 971 st->print("\n\t"); 972 st->print("addq rbp, #%d", framesize); 973 } 974 } 975 } 976 977 if (VerifyStackAtCalls) { 978 st->print("\n\t"); 979 framesize -= wordSize; 980 st->print("movq [rsp + #%d], 0xbadb100d\t# Majik cookie for stack depth check",framesize); 981#ifdef ASSERT 982 st->print("\n\t"); 983 st->print("# stack alignment check"); 984#endif 985 } 986 st->cr(); 987} 988#endif 989 990void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 991 Compile* C = ra_->C; 992 MacroAssembler _masm(&cbuf); 993 994 int framesize = C->frame_size_in_bytes(); 995 int bangsize = C->bang_size_in_bytes(); 996 997 __ verified_entry(framesize, C->need_stack_bang(bangsize)?bangsize:0, false); 998 999 C->set_frame_complete(cbuf.insts_size()); 1000 1001 if (C->has_mach_constant_base_node()) { 1002 // NOTE: We set the table base offset here because users might be 1003 // emitted before MachConstantBaseNode. 1004 Compile::ConstantTable& constant_table = C->constant_table(); 1005 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset()); 1006 } 1007} 1008 1009uint MachPrologNode::size(PhaseRegAlloc* ra_) const 1010{ 1011 return MachNode::size(ra_); // too many variables; just compute it 1012 // the hard way 1013} 1014 1015int MachPrologNode::reloc() const 1016{ 1017 return 0; // a large enough number 1018} 1019 1020//============================================================================= 1021#ifndef PRODUCT 1022void MachEpilogNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1023{ 1024 Compile* C = ra_->C; 1025 if (generate_vzeroupper(C)) { 1026 st->print("vzeroupper"); 1027 st->cr(); st->print("\t"); 1028 } 1029 1030 int framesize = C->frame_size_in_bytes(); 1031 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 1032 // Remove word for return adr already pushed 1033 // and RBP 1034 framesize -= 2*wordSize; 1035 1036 if (framesize) { 1037 st->print_cr("addq rsp, %d\t# Destroy frame", framesize); 1038 st->print("\t"); 1039 } 1040 1041 st->print_cr("popq rbp"); 1042 if (do_polling() && C->is_method_compilation()) { 1043 st->print("\t"); 1044 if (SafepointMechanism::uses_thread_local_poll()) { 1045 st->print_cr("movq rscratch1, poll_offset[r15_thread] #polling_page_address\n\t" 1046 "testl rax, [rscratch1]\t" 1047 "# Safepoint: poll for GC"); 1048 } else if (Assembler::is_polling_page_far()) { 1049 st->print_cr("movq rscratch1, #polling_page_address\n\t" 1050 "testl rax, [rscratch1]\t" 1051 "# Safepoint: poll for GC"); 1052 } else { 1053 st->print_cr("testl rax, [rip + #offset_to_poll_page]\t" 1054 "# Safepoint: poll for GC"); 1055 } 1056 } 1057} 1058#endif 1059 1060void MachEpilogNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1061{ 1062 Compile* C = ra_->C; 1063 MacroAssembler _masm(&cbuf); 1064 1065 if (generate_vzeroupper(C)) { 1066 // Clear upper bits of YMM registers when current compiled code uses 1067 // wide vectors to avoid AVX <-> SSE transition penalty during call. 1068 __ vzeroupper(); 1069 } 1070 1071 int framesize = C->frame_size_in_bytes(); 1072 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 1073 // Remove word for return adr already pushed 1074 // and RBP 1075 framesize -= 2*wordSize; 1076 1077 // Note that VerifyStackAtCalls' Majik cookie does not change the frame size popped here 1078 1079 if (framesize) { 1080 emit_opcode(cbuf, Assembler::REX_W); 1081 if (framesize < 0x80) { 1082 emit_opcode(cbuf, 0x83); // addq rsp, #framesize 1083 emit_rm(cbuf, 0x3, 0x00, RSP_enc); 1084 emit_d8(cbuf, framesize); 1085 } else { 1086 emit_opcode(cbuf, 0x81); // addq rsp, #framesize 1087 emit_rm(cbuf, 0x3, 0x00, RSP_enc); 1088 emit_d32(cbuf, framesize); 1089 } 1090 } 1091 1092 // popq rbp 1093 emit_opcode(cbuf, 0x58 | RBP_enc); 1094 1095 if (StackReservedPages > 0 && C->has_reserved_stack_access()) { 1096 __ reserved_stack_check(); 1097 } 1098 1099 if (do_polling() && C->is_method_compilation()) { 1100 MacroAssembler _masm(&cbuf); 1101 if (SafepointMechanism::uses_thread_local_poll()) { 1102 __ movq(rscratch1, Address(r15_thread, Thread::polling_page_offset())); 1103 __ relocate(relocInfo::poll_return_type); 1104 __ testl(rax, Address(rscratch1, 0)); 1105 } else { 1106 AddressLiteral polling_page(os::get_polling_page(), relocInfo::poll_return_type); 1107 if (Assembler::is_polling_page_far()) { 1108 __ lea(rscratch1, polling_page); 1109 __ relocate(relocInfo::poll_return_type); 1110 __ testl(rax, Address(rscratch1, 0)); 1111 } else { 1112 __ testl(rax, polling_page); 1113 } 1114 } 1115 } 1116} 1117 1118uint MachEpilogNode::size(PhaseRegAlloc* ra_) const 1119{ 1120 return MachNode::size(ra_); // too many variables; just compute it 1121 // the hard way 1122} 1123 1124int MachEpilogNode::reloc() const 1125{ 1126 return 2; // a large enough number 1127} 1128 1129const Pipeline* MachEpilogNode::pipeline() const 1130{ 1131 return MachNode::pipeline_class(); 1132} 1133 1134int MachEpilogNode::safepoint_offset() const 1135{ 1136 return 0; 1137} 1138 1139//============================================================================= 1140 1141enum RC { 1142 rc_bad, 1143 rc_int, 1144 rc_float, 1145 rc_stack 1146}; 1147 1148static enum RC rc_class(OptoReg::Name reg) 1149{ 1150 if( !OptoReg::is_valid(reg) ) return rc_bad; 1151 1152 if (OptoReg::is_stack(reg)) return rc_stack; 1153 1154 VMReg r = OptoReg::as_VMReg(reg); 1155 1156 if (r->is_Register()) return rc_int; 1157 1158 assert(r->is_XMMRegister(), "must be"); 1159 return rc_float; 1160} 1161 1162// Next two methods are shared by 32- and 64-bit VM. They are defined in x86.ad. 1163static int vec_mov_helper(CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo, 1164 int src_hi, int dst_hi, uint ireg, outputStream* st); 1165 1166static int vec_spill_helper(CodeBuffer *cbuf, bool do_size, bool is_load, 1167 int stack_offset, int reg, uint ireg, outputStream* st); 1168 1169static void vec_stack_to_stack_helper(CodeBuffer *cbuf, int src_offset, 1170 int dst_offset, uint ireg, outputStream* st) { 1171 if (cbuf) { 1172 MacroAssembler _masm(cbuf); 1173 switch (ireg) { 1174 case Op_VecS: 1175 __ movq(Address(rsp, -8), rax); 1176 __ movl(rax, Address(rsp, src_offset)); 1177 __ movl(Address(rsp, dst_offset), rax); 1178 __ movq(rax, Address(rsp, -8)); 1179 break; 1180 case Op_VecD: 1181 __ pushq(Address(rsp, src_offset)); 1182 __ popq (Address(rsp, dst_offset)); 1183 break; 1184 case Op_VecX: 1185 __ pushq(Address(rsp, src_offset)); 1186 __ popq (Address(rsp, dst_offset)); 1187 __ pushq(Address(rsp, src_offset+8)); 1188 __ popq (Address(rsp, dst_offset+8)); 1189 break; 1190 case Op_VecY: 1191 __ vmovdqu(Address(rsp, -32), xmm0); 1192 __ vmovdqu(xmm0, Address(rsp, src_offset)); 1193 __ vmovdqu(Address(rsp, dst_offset), xmm0); 1194 __ vmovdqu(xmm0, Address(rsp, -32)); 1195 break; 1196 case Op_VecZ: 1197 __ evmovdquq(Address(rsp, -64), xmm0, 2); 1198 __ evmovdquq(xmm0, Address(rsp, src_offset), 2); 1199 __ evmovdquq(Address(rsp, dst_offset), xmm0, 2); 1200 __ evmovdquq(xmm0, Address(rsp, -64), 2); 1201 break; 1202 default: 1203 ShouldNotReachHere(); 1204 } 1205#ifndef PRODUCT 1206 } else { 1207 switch (ireg) { 1208 case Op_VecS: 1209 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1210 "movl rax, [rsp + #%d]\n\t" 1211 "movl [rsp + #%d], rax\n\t" 1212 "movq rax, [rsp - #8]", 1213 src_offset, dst_offset); 1214 break; 1215 case Op_VecD: 1216 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1217 "popq [rsp + #%d]", 1218 src_offset, dst_offset); 1219 break; 1220 case Op_VecX: 1221 st->print("pushq [rsp + #%d]\t# 128-bit mem-mem spill\n\t" 1222 "popq [rsp + #%d]\n\t" 1223 "pushq [rsp + #%d]\n\t" 1224 "popq [rsp + #%d]", 1225 src_offset, dst_offset, src_offset+8, dst_offset+8); 1226 break; 1227 case Op_VecY: 1228 st->print("vmovdqu [rsp - #32], xmm0\t# 256-bit mem-mem spill\n\t" 1229 "vmovdqu xmm0, [rsp + #%d]\n\t" 1230 "vmovdqu [rsp + #%d], xmm0\n\t" 1231 "vmovdqu xmm0, [rsp - #32]", 1232 src_offset, dst_offset); 1233 break; 1234 case Op_VecZ: 1235 st->print("vmovdqu [rsp - #64], xmm0\t# 512-bit mem-mem spill\n\t" 1236 "vmovdqu xmm0, [rsp + #%d]\n\t" 1237 "vmovdqu [rsp + #%d], xmm0\n\t" 1238 "vmovdqu xmm0, [rsp - #64]", 1239 src_offset, dst_offset); 1240 break; 1241 default: 1242 ShouldNotReachHere(); 1243 } 1244#endif 1245 } 1246} 1247 1248uint MachSpillCopyNode::implementation(CodeBuffer* cbuf, 1249 PhaseRegAlloc* ra_, 1250 bool do_size, 1251 outputStream* st) const { 1252 assert(cbuf != NULL || st != NULL, "sanity"); 1253 // Get registers to move 1254 OptoReg::Name src_second = ra_->get_reg_second(in(1)); 1255 OptoReg::Name src_first = ra_->get_reg_first(in(1)); 1256 OptoReg::Name dst_second = ra_->get_reg_second(this); 1257 OptoReg::Name dst_first = ra_->get_reg_first(this); 1258 1259 enum RC src_second_rc = rc_class(src_second); 1260 enum RC src_first_rc = rc_class(src_first); 1261 enum RC dst_second_rc = rc_class(dst_second); 1262 enum RC dst_first_rc = rc_class(dst_first); 1263 1264 assert(OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), 1265 "must move at least 1 register" ); 1266 1267 if (src_first == dst_first && src_second == dst_second) { 1268 // Self copy, no move 1269 return 0; 1270 } 1271 if (bottom_type()->isa_vect() != NULL) { 1272 uint ireg = ideal_reg(); 1273 assert((src_first_rc != rc_int && dst_first_rc != rc_int), "sanity"); 1274 assert((ireg == Op_VecS || ireg == Op_VecD || ireg == Op_VecX || ireg == Op_VecY || ireg == Op_VecZ ), "sanity"); 1275 if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) { 1276 // mem -> mem 1277 int src_offset = ra_->reg2offset(src_first); 1278 int dst_offset = ra_->reg2offset(dst_first); 1279 vec_stack_to_stack_helper(cbuf, src_offset, dst_offset, ireg, st); 1280 } else if (src_first_rc == rc_float && dst_first_rc == rc_float ) { 1281 vec_mov_helper(cbuf, false, src_first, dst_first, src_second, dst_second, ireg, st); 1282 } else if (src_first_rc == rc_float && dst_first_rc == rc_stack ) { 1283 int stack_offset = ra_->reg2offset(dst_first); 1284 vec_spill_helper(cbuf, false, false, stack_offset, src_first, ireg, st); 1285 } else if (src_first_rc == rc_stack && dst_first_rc == rc_float ) { 1286 int stack_offset = ra_->reg2offset(src_first); 1287 vec_spill_helper(cbuf, false, true, stack_offset, dst_first, ireg, st); 1288 } else { 1289 ShouldNotReachHere(); 1290 } 1291 return 0; 1292 } 1293 if (src_first_rc == rc_stack) { 1294 // mem -> 1295 if (dst_first_rc == rc_stack) { 1296 // mem -> mem 1297 assert(src_second != dst_first, "overlap"); 1298 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1299 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1300 // 64-bit 1301 int src_offset = ra_->reg2offset(src_first); 1302 int dst_offset = ra_->reg2offset(dst_first); 1303 if (cbuf) { 1304 MacroAssembler _masm(cbuf); 1305 __ pushq(Address(rsp, src_offset)); 1306 __ popq (Address(rsp, dst_offset)); 1307#ifndef PRODUCT 1308 } else { 1309 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1310 "popq [rsp + #%d]", 1311 src_offset, dst_offset); 1312#endif 1313 } 1314 } else { 1315 // 32-bit 1316 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1317 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1318 // No pushl/popl, so: 1319 int src_offset = ra_->reg2offset(src_first); 1320 int dst_offset = ra_->reg2offset(dst_first); 1321 if (cbuf) { 1322 MacroAssembler _masm(cbuf); 1323 __ movq(Address(rsp, -8), rax); 1324 __ movl(rax, Address(rsp, src_offset)); 1325 __ movl(Address(rsp, dst_offset), rax); 1326 __ movq(rax, Address(rsp, -8)); 1327#ifndef PRODUCT 1328 } else { 1329 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1330 "movl rax, [rsp + #%d]\n\t" 1331 "movl [rsp + #%d], rax\n\t" 1332 "movq rax, [rsp - #8]", 1333 src_offset, dst_offset); 1334#endif 1335 } 1336 } 1337 return 0; 1338 } else if (dst_first_rc == rc_int) { 1339 // mem -> gpr 1340 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1341 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1342 // 64-bit 1343 int offset = ra_->reg2offset(src_first); 1344 if (cbuf) { 1345 MacroAssembler _masm(cbuf); 1346 __ movq(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1347#ifndef PRODUCT 1348 } else { 1349 st->print("movq %s, [rsp + #%d]\t# spill", 1350 Matcher::regName[dst_first], 1351 offset); 1352#endif 1353 } 1354 } else { 1355 // 32-bit 1356 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1357 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1358 int offset = ra_->reg2offset(src_first); 1359 if (cbuf) { 1360 MacroAssembler _masm(cbuf); 1361 __ movl(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1362#ifndef PRODUCT 1363 } else { 1364 st->print("movl %s, [rsp + #%d]\t# spill", 1365 Matcher::regName[dst_first], 1366 offset); 1367#endif 1368 } 1369 } 1370 return 0; 1371 } else if (dst_first_rc == rc_float) { 1372 // mem-> xmm 1373 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1374 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1375 // 64-bit 1376 int offset = ra_->reg2offset(src_first); 1377 if (cbuf) { 1378 MacroAssembler _masm(cbuf); 1379 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1380#ifndef PRODUCT 1381 } else { 1382 st->print("%s %s, [rsp + #%d]\t# spill", 1383 UseXmmLoadAndClearUpper ? "movsd " : "movlpd", 1384 Matcher::regName[dst_first], 1385 offset); 1386#endif 1387 } 1388 } else { 1389 // 32-bit 1390 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1391 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1392 int offset = ra_->reg2offset(src_first); 1393 if (cbuf) { 1394 MacroAssembler _masm(cbuf); 1395 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1396#ifndef PRODUCT 1397 } else { 1398 st->print("movss %s, [rsp + #%d]\t# spill", 1399 Matcher::regName[dst_first], 1400 offset); 1401#endif 1402 } 1403 } 1404 return 0; 1405 } 1406 } else if (src_first_rc == rc_int) { 1407 // gpr -> 1408 if (dst_first_rc == rc_stack) { 1409 // gpr -> mem 1410 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1411 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1412 // 64-bit 1413 int offset = ra_->reg2offset(dst_first); 1414 if (cbuf) { 1415 MacroAssembler _masm(cbuf); 1416 __ movq(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1417#ifndef PRODUCT 1418 } else { 1419 st->print("movq [rsp + #%d], %s\t# spill", 1420 offset, 1421 Matcher::regName[src_first]); 1422#endif 1423 } 1424 } else { 1425 // 32-bit 1426 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1427 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1428 int offset = ra_->reg2offset(dst_first); 1429 if (cbuf) { 1430 MacroAssembler _masm(cbuf); 1431 __ movl(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1432#ifndef PRODUCT 1433 } else { 1434 st->print("movl [rsp + #%d], %s\t# spill", 1435 offset, 1436 Matcher::regName[src_first]); 1437#endif 1438 } 1439 } 1440 return 0; 1441 } else if (dst_first_rc == rc_int) { 1442 // gpr -> gpr 1443 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1444 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1445 // 64-bit 1446 if (cbuf) { 1447 MacroAssembler _masm(cbuf); 1448 __ movq(as_Register(Matcher::_regEncode[dst_first]), 1449 as_Register(Matcher::_regEncode[src_first])); 1450#ifndef PRODUCT 1451 } else { 1452 st->print("movq %s, %s\t# spill", 1453 Matcher::regName[dst_first], 1454 Matcher::regName[src_first]); 1455#endif 1456 } 1457 return 0; 1458 } else { 1459 // 32-bit 1460 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1461 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1462 if (cbuf) { 1463 MacroAssembler _masm(cbuf); 1464 __ movl(as_Register(Matcher::_regEncode[dst_first]), 1465 as_Register(Matcher::_regEncode[src_first])); 1466#ifndef PRODUCT 1467 } else { 1468 st->print("movl %s, %s\t# spill", 1469 Matcher::regName[dst_first], 1470 Matcher::regName[src_first]); 1471#endif 1472 } 1473 return 0; 1474 } 1475 } else if (dst_first_rc == rc_float) { 1476 // gpr -> xmm 1477 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1478 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1479 // 64-bit 1480 if (cbuf) { 1481 MacroAssembler _masm(cbuf); 1482 __ movdq( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1483#ifndef PRODUCT 1484 } else { 1485 st->print("movdq %s, %s\t# spill", 1486 Matcher::regName[dst_first], 1487 Matcher::regName[src_first]); 1488#endif 1489 } 1490 } else { 1491 // 32-bit 1492 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1493 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1494 if (cbuf) { 1495 MacroAssembler _masm(cbuf); 1496 __ movdl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1497#ifndef PRODUCT 1498 } else { 1499 st->print("movdl %s, %s\t# spill", 1500 Matcher::regName[dst_first], 1501 Matcher::regName[src_first]); 1502#endif 1503 } 1504 } 1505 return 0; 1506 } 1507 } else if (src_first_rc == rc_float) { 1508 // xmm -> 1509 if (dst_first_rc == rc_stack) { 1510 // xmm -> mem 1511 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1512 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1513 // 64-bit 1514 int offset = ra_->reg2offset(dst_first); 1515 if (cbuf) { 1516 MacroAssembler _masm(cbuf); 1517 __ movdbl( Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1518#ifndef PRODUCT 1519 } else { 1520 st->print("movsd [rsp + #%d], %s\t# spill", 1521 offset, 1522 Matcher::regName[src_first]); 1523#endif 1524 } 1525 } else { 1526 // 32-bit 1527 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1528 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1529 int offset = ra_->reg2offset(dst_first); 1530 if (cbuf) { 1531 MacroAssembler _masm(cbuf); 1532 __ movflt(Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1533#ifndef PRODUCT 1534 } else { 1535 st->print("movss [rsp + #%d], %s\t# spill", 1536 offset, 1537 Matcher::regName[src_first]); 1538#endif 1539 } 1540 } 1541 return 0; 1542 } else if (dst_first_rc == rc_int) { 1543 // xmm -> gpr 1544 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1545 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1546 // 64-bit 1547 if (cbuf) { 1548 MacroAssembler _masm(cbuf); 1549 __ movdq( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1550#ifndef PRODUCT 1551 } else { 1552 st->print("movdq %s, %s\t# spill", 1553 Matcher::regName[dst_first], 1554 Matcher::regName[src_first]); 1555#endif 1556 } 1557 } else { 1558 // 32-bit 1559 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1560 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1561 if (cbuf) { 1562 MacroAssembler _masm(cbuf); 1563 __ movdl( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1564#ifndef PRODUCT 1565 } else { 1566 st->print("movdl %s, %s\t# spill", 1567 Matcher::regName[dst_first], 1568 Matcher::regName[src_first]); 1569#endif 1570 } 1571 } 1572 return 0; 1573 } else if (dst_first_rc == rc_float) { 1574 // xmm -> xmm 1575 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1576 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1577 // 64-bit 1578 if (cbuf) { 1579 MacroAssembler _masm(cbuf); 1580 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1581#ifndef PRODUCT 1582 } else { 1583 st->print("%s %s, %s\t# spill", 1584 UseXmmRegToRegMoveAll ? "movapd" : "movsd ", 1585 Matcher::regName[dst_first], 1586 Matcher::regName[src_first]); 1587#endif 1588 } 1589 } else { 1590 // 32-bit 1591 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1592 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1593 if (cbuf) { 1594 MacroAssembler _masm(cbuf); 1595 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1596#ifndef PRODUCT 1597 } else { 1598 st->print("%s %s, %s\t# spill", 1599 UseXmmRegToRegMoveAll ? "movaps" : "movss ", 1600 Matcher::regName[dst_first], 1601 Matcher::regName[src_first]); 1602#endif 1603 } 1604 } 1605 return 0; 1606 } 1607 } 1608 1609 assert(0," foo "); 1610 Unimplemented(); 1611 return 0; 1612} 1613 1614#ifndef PRODUCT 1615void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream* st) const { 1616 implementation(NULL, ra_, false, st); 1617} 1618#endif 1619 1620void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1621 implementation(&cbuf, ra_, false, NULL); 1622} 1623 1624uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1625 return MachNode::size(ra_); 1626} 1627 1628//============================================================================= 1629#ifndef PRODUCT 1630void BoxLockNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1631{ 1632 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1633 int reg = ra_->get_reg_first(this); 1634 st->print("leaq %s, [rsp + #%d]\t# box lock", 1635 Matcher::regName[reg], offset); 1636} 1637#endif 1638 1639void BoxLockNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1640{ 1641 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1642 int reg = ra_->get_encode(this); 1643 if (offset >= 0x80) { 1644 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR); 1645 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset] 1646 emit_rm(cbuf, 0x2, reg & 7, 0x04); 1647 emit_rm(cbuf, 0x0, 0x04, RSP_enc); 1648 emit_d32(cbuf, offset); 1649 } else { 1650 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR); 1651 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset] 1652 emit_rm(cbuf, 0x1, reg & 7, 0x04); 1653 emit_rm(cbuf, 0x0, 0x04, RSP_enc); 1654 emit_d8(cbuf, offset); 1655 } 1656} 1657 1658uint BoxLockNode::size(PhaseRegAlloc *ra_) const 1659{ 1660 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1661 return (offset < 0x80) ? 5 : 8; // REX 1662} 1663 1664//============================================================================= 1665#ifndef PRODUCT 1666void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1667{ 1668 if (UseCompressedClassPointers) { 1669 st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1670 st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1"); 1671 st->print_cr("\tcmpq rax, rscratch1\t # Inline cache check"); 1672 } else { 1673 st->print_cr("\tcmpq rax, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t" 1674 "# Inline cache check"); 1675 } 1676 st->print_cr("\tjne SharedRuntime::_ic_miss_stub"); 1677 st->print_cr("\tnop\t# nops to align entry point"); 1678} 1679#endif 1680 1681void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1682{ 1683 MacroAssembler masm(&cbuf); 1684 uint insts_size = cbuf.insts_size(); 1685 if (UseCompressedClassPointers) { 1686 masm.load_klass(rscratch1, j_rarg0); 1687 masm.cmpptr(rax, rscratch1); 1688 } else { 1689 masm.cmpptr(rax, Address(j_rarg0, oopDesc::klass_offset_in_bytes())); 1690 } 1691 1692 masm.jump_cc(Assembler::notEqual, RuntimeAddress(SharedRuntime::get_ic_miss_stub())); 1693 1694 /* WARNING these NOPs are critical so that verified entry point is properly 1695 4 bytes aligned for patching by NativeJump::patch_verified_entry() */ 1696 int nops_cnt = 4 - ((cbuf.insts_size() - insts_size) & 0x3); 1697 if (OptoBreakpoint) { 1698 // Leave space for int3 1699 nops_cnt -= 1; 1700 } 1701 nops_cnt &= 0x3; // Do not add nops if code is aligned. 1702 if (nops_cnt > 0) 1703 masm.nop(nops_cnt); 1704} 1705 1706uint MachUEPNode::size(PhaseRegAlloc* ra_) const 1707{ 1708 return MachNode::size(ra_); // too many variables; just compute it 1709 // the hard way 1710} 1711 1712 1713//============================================================================= 1714 1715int Matcher::regnum_to_fpu_offset(int regnum) 1716{ 1717 return regnum - 32; // The FP registers are in the second chunk 1718} 1719 1720// This is UltraSparc specific, true just means we have fast l2f conversion 1721const bool Matcher::convL2FSupported(void) { 1722 return true; 1723} 1724 1725// Is this branch offset short enough that a short branch can be used? 1726// 1727// NOTE: If the platform does not provide any short branch variants, then 1728// this method should return false for offset 0. 1729bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 1730 // The passed offset is relative to address of the branch. 1731 // On 86 a branch displacement is calculated relative to address 1732 // of a next instruction. 1733 offset -= br_size; 1734 1735 // the short version of jmpConUCF2 contains multiple branches, 1736 // making the reach slightly less 1737 if (rule == jmpConUCF2_rule) 1738 return (-126 <= offset && offset <= 125); 1739 return (-128 <= offset && offset <= 127); 1740} 1741 1742const bool Matcher::isSimpleConstant64(jlong value) { 1743 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?. 1744 //return value == (int) value; // Cf. storeImmL and immL32. 1745 1746 // Probably always true, even if a temp register is required. 1747 return true; 1748} 1749 1750// The ecx parameter to rep stosq for the ClearArray node is in words. 1751const bool Matcher::init_array_count_is_in_bytes = false; 1752 1753// No additional cost for CMOVL. 1754const int Matcher::long_cmove_cost() { return 0; } 1755 1756// No CMOVF/CMOVD with SSE2 1757const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; } 1758 1759// Does the CPU require late expand (see block.cpp for description of late expand)? 1760const bool Matcher::require_postalloc_expand = false; 1761 1762// Do we need to mask the count passed to shift instructions or does 1763// the cpu only look at the lower 5/6 bits anyway? 1764const bool Matcher::need_masked_shift_count = false; 1765 1766bool Matcher::narrow_oop_use_complex_address() { 1767 assert(UseCompressedOops, "only for compressed oops code"); 1768 return (LogMinObjAlignmentInBytes <= 3); 1769} 1770 1771bool Matcher::narrow_klass_use_complex_address() { 1772 assert(UseCompressedClassPointers, "only for compressed klass code"); 1773 return (LogKlassAlignmentInBytes <= 3); 1774} 1775 1776bool Matcher::const_oop_prefer_decode() { 1777 // Prefer ConN+DecodeN over ConP. 1778 return true; 1779} 1780 1781bool Matcher::const_klass_prefer_decode() { 1782 // TODO: Either support matching DecodeNKlass (heap-based) in operand 1783 // or condisider the following: 1784 // Prefer ConNKlass+DecodeNKlass over ConP in simple compressed klass mode. 1785 //return Universe::narrow_klass_base() == NULL; 1786 return true; 1787} 1788 1789// Is it better to copy float constants, or load them directly from 1790// memory? Intel can load a float constant from a direct address, 1791// requiring no extra registers. Most RISCs will have to materialize 1792// an address into a register first, so they would do better to copy 1793// the constant from stack. 1794const bool Matcher::rematerialize_float_constants = true; // XXX 1795 1796// If CPU can load and store mis-aligned doubles directly then no 1797// fixup is needed. Else we split the double into 2 integer pieces 1798// and move it piece-by-piece. Only happens when passing doubles into 1799// C code as the Java calling convention forces doubles to be aligned. 1800const bool Matcher::misaligned_doubles_ok = true; 1801 1802// No-op on amd64 1803void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) {} 1804 1805// Advertise here if the CPU requires explicit rounding operations to 1806// implement the UseStrictFP mode. 1807const bool Matcher::strict_fp_requires_explicit_rounding = true; 1808 1809// Are floats conerted to double when stored to stack during deoptimization? 1810// On x64 it is stored without convertion so we can use normal access. 1811bool Matcher::float_in_double() { return false; } 1812 1813// Do ints take an entire long register or just half? 1814const bool Matcher::int_in_long = true; 1815 1816// Return whether or not this register is ever used as an argument. 1817// This function is used on startup to build the trampoline stubs in 1818// generateOptoStub. Registers not mentioned will be killed by the VM 1819// call in the trampoline, and arguments in those registers not be 1820// available to the callee. 1821bool Matcher::can_be_java_arg(int reg) 1822{ 1823 return 1824 reg == RDI_num || reg == RDI_H_num || 1825 reg == RSI_num || reg == RSI_H_num || 1826 reg == RDX_num || reg == RDX_H_num || 1827 reg == RCX_num || reg == RCX_H_num || 1828 reg == R8_num || reg == R8_H_num || 1829 reg == R9_num || reg == R9_H_num || 1830 reg == R12_num || reg == R12_H_num || 1831 reg == XMM0_num || reg == XMM0b_num || 1832 reg == XMM1_num || reg == XMM1b_num || 1833 reg == XMM2_num || reg == XMM2b_num || 1834 reg == XMM3_num || reg == XMM3b_num || 1835 reg == XMM4_num || reg == XMM4b_num || 1836 reg == XMM5_num || reg == XMM5b_num || 1837 reg == XMM6_num || reg == XMM6b_num || 1838 reg == XMM7_num || reg == XMM7b_num; 1839} 1840 1841bool Matcher::is_spillable_arg(int reg) 1842{ 1843 return can_be_java_arg(reg); 1844} 1845 1846bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) { 1847 // In 64 bit mode a code which use multiply when 1848 // devisor is constant is faster than hardware 1849 // DIV instruction (it uses MulHiL). 1850 return false; 1851} 1852 1853// Register for DIVI projection of divmodI 1854RegMask Matcher::divI_proj_mask() { 1855 return INT_RAX_REG_mask(); 1856} 1857 1858// Register for MODI projection of divmodI 1859RegMask Matcher::modI_proj_mask() { 1860 return INT_RDX_REG_mask(); 1861} 1862 1863// Register for DIVL projection of divmodL 1864RegMask Matcher::divL_proj_mask() { 1865 return LONG_RAX_REG_mask(); 1866} 1867 1868// Register for MODL projection of divmodL 1869RegMask Matcher::modL_proj_mask() { 1870 return LONG_RDX_REG_mask(); 1871} 1872 1873// Register for saving SP into on method handle invokes. Not used on x86_64. 1874const RegMask Matcher::method_handle_invoke_SP_save_mask() { 1875 return NO_REG_mask(); 1876} 1877 1878%} 1879 1880//----------ENCODING BLOCK----------------------------------------------------- 1881// This block specifies the encoding classes used by the compiler to 1882// output byte streams. Encoding classes are parameterized macros 1883// used by Machine Instruction Nodes in order to generate the bit 1884// encoding of the instruction. Operands specify their base encoding 1885// interface with the interface keyword. There are currently 1886// supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & 1887// COND_INTER. REG_INTER causes an operand to generate a function 1888// which returns its register number when queried. CONST_INTER causes 1889// an operand to generate a function which returns the value of the 1890// constant when queried. MEMORY_INTER causes an operand to generate 1891// four functions which return the Base Register, the Index Register, 1892// the Scale Value, and the Offset Value of the operand when queried. 1893// COND_INTER causes an operand to generate six functions which return 1894// the encoding code (ie - encoding bits for the instruction) 1895// associated with each basic boolean condition for a conditional 1896// instruction. 1897// 1898// Instructions specify two basic values for encoding. Again, a 1899// function is available to check if the constant displacement is an 1900// oop. They use the ins_encode keyword to specify their encoding 1901// classes (which must be a sequence of enc_class names, and their 1902// parameters, specified in the encoding block), and they use the 1903// opcode keyword to specify, in order, their primary, secondary, and 1904// tertiary opcode. Only the opcode sections which a particular 1905// instruction needs for encoding need to be specified. 1906encode %{ 1907 // Build emit functions for each basic byte or larger field in the 1908 // intel encoding scheme (opcode, rm, sib, immediate), and call them 1909 // from C++ code in the enc_class source block. Emit functions will 1910 // live in the main source block for now. In future, we can 1911 // generalize this by adding a syntax that specifies the sizes of 1912 // fields in an order, so that the adlc can build the emit functions 1913 // automagically 1914 1915 // Emit primary opcode 1916 enc_class OpcP 1917 %{ 1918 emit_opcode(cbuf, $primary); 1919 %} 1920 1921 // Emit secondary opcode 1922 enc_class OpcS 1923 %{ 1924 emit_opcode(cbuf, $secondary); 1925 %} 1926 1927 // Emit tertiary opcode 1928 enc_class OpcT 1929 %{ 1930 emit_opcode(cbuf, $tertiary); 1931 %} 1932 1933 // Emit opcode directly 1934 enc_class Opcode(immI d8) 1935 %{ 1936 emit_opcode(cbuf, $d8$$constant); 1937 %} 1938 1939 // Emit size prefix 1940 enc_class SizePrefix 1941 %{ 1942 emit_opcode(cbuf, 0x66); 1943 %} 1944 1945 enc_class reg(rRegI reg) 1946 %{ 1947 emit_rm(cbuf, 0x3, 0, $reg$$reg & 7); 1948 %} 1949 1950 enc_class reg_reg(rRegI dst, rRegI src) 1951 %{ 1952 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); 1953 %} 1954 1955 enc_class opc_reg_reg(immI opcode, rRegI dst, rRegI src) 1956 %{ 1957 emit_opcode(cbuf, $opcode$$constant); 1958 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); 1959 %} 1960 1961 enc_class cdql_enc(no_rax_rdx_RegI div) 1962 %{ 1963 // Full implementation of Java idiv and irem; checks for 1964 // special case as described in JVM spec., p.243 & p.271. 1965 // 1966 // normal case special case 1967 // 1968 // input : rax: dividend min_int 1969 // reg: divisor -1 1970 // 1971 // output: rax: quotient (= rax idiv reg) min_int 1972 // rdx: remainder (= rax irem reg) 0 1973 // 1974 // Code sequnce: 1975 // 1976 // 0: 3d 00 00 00 80 cmp $0x80000000,%eax 1977 // 5: 75 07/08 jne e <normal> 1978 // 7: 33 d2 xor %edx,%edx 1979 // [div >= 8 -> offset + 1] 1980 // [REX_B] 1981 // 9: 83 f9 ff cmp $0xffffffffffffffff,$div 1982 // c: 74 03/04 je 11 <done> 1983 // 000000000000000e <normal>: 1984 // e: 99 cltd 1985 // [div >= 8 -> offset + 1] 1986 // [REX_B] 1987 // f: f7 f9 idiv $div 1988 // 0000000000000011 <done>: 1989 1990 // cmp $0x80000000,%eax 1991 emit_opcode(cbuf, 0x3d); 1992 emit_d8(cbuf, 0x00); 1993 emit_d8(cbuf, 0x00); 1994 emit_d8(cbuf, 0x00); 1995 emit_d8(cbuf, 0x80); 1996 1997 // jne e <normal> 1998 emit_opcode(cbuf, 0x75); 1999 emit_d8(cbuf, $div$$reg < 8 ? 0x07 : 0x08); 2000 2001 // xor %edx,%edx 2002 emit_opcode(cbuf, 0x33); 2003 emit_d8(cbuf, 0xD2); 2004 2005 // cmp $0xffffffffffffffff,%ecx 2006 if ($div$$reg >= 8) { 2007 emit_opcode(cbuf, Assembler::REX_B); 2008 } 2009 emit_opcode(cbuf, 0x83); 2010 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7); 2011 emit_d8(cbuf, 0xFF); 2012 2013 // je 11 <done> 2014 emit_opcode(cbuf, 0x74); 2015 emit_d8(cbuf, $div$$reg < 8 ? 0x03 : 0x04); 2016 2017 // <normal> 2018 // cltd 2019 emit_opcode(cbuf, 0x99); 2020 2021 // idivl (note: must be emitted by the user of this rule) 2022 // <done> 2023 %} 2024 2025 enc_class cdqq_enc(no_rax_rdx_RegL div) 2026 %{ 2027 // Full implementation of Java ldiv and lrem; checks for 2028 // special case as described in JVM spec., p.243 & p.271. 2029 // 2030 // normal case special case 2031 // 2032 // input : rax: dividend min_long 2033 // reg: divisor -1 2034 // 2035 // output: rax: quotient (= rax idiv reg) min_long 2036 // rdx: remainder (= rax irem reg) 0 2037 // 2038 // Code sequnce: 2039 // 2040 // 0: 48 ba 00 00 00 00 00 mov $0x8000000000000000,%rdx 2041 // 7: 00 00 80 2042 // a: 48 39 d0 cmp %rdx,%rax 2043 // d: 75 08 jne 17 <normal> 2044 // f: 33 d2 xor %edx,%edx 2045 // 11: 48 83 f9 ff cmp $0xffffffffffffffff,$div 2046 // 15: 74 05 je 1c <done> 2047 // 0000000000000017 <normal>: 2048 // 17: 48 99 cqto 2049 // 19: 48 f7 f9 idiv $div 2050 // 000000000000001c <done>: 2051 2052 // mov $0x8000000000000000,%rdx 2053 emit_opcode(cbuf, Assembler::REX_W); 2054 emit_opcode(cbuf, 0xBA); 2055 emit_d8(cbuf, 0x00); 2056 emit_d8(cbuf, 0x00); 2057 emit_d8(cbuf, 0x00); 2058 emit_d8(cbuf, 0x00); 2059 emit_d8(cbuf, 0x00); 2060 emit_d8(cbuf, 0x00); 2061 emit_d8(cbuf, 0x00); 2062 emit_d8(cbuf, 0x80); 2063 2064 // cmp %rdx,%rax 2065 emit_opcode(cbuf, Assembler::REX_W); 2066 emit_opcode(cbuf, 0x39); 2067 emit_d8(cbuf, 0xD0); 2068 2069 // jne 17 <normal> 2070 emit_opcode(cbuf, 0x75); 2071 emit_d8(cbuf, 0x08); 2072 2073 // xor %edx,%edx 2074 emit_opcode(cbuf, 0x33); 2075 emit_d8(cbuf, 0xD2); 2076 2077 // cmp $0xffffffffffffffff,$div 2078 emit_opcode(cbuf, $div$$reg < 8 ? Assembler::REX_W : Assembler::REX_WB); 2079 emit_opcode(cbuf, 0x83); 2080 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7); 2081 emit_d8(cbuf, 0xFF); 2082 2083 // je 1e <done> 2084 emit_opcode(cbuf, 0x74); 2085 emit_d8(cbuf, 0x05); 2086 2087 // <normal> 2088 // cqto 2089 emit_opcode(cbuf, Assembler::REX_W); 2090 emit_opcode(cbuf, 0x99); 2091 2092 // idivq (note: must be emitted by the user of this rule) 2093 // <done> 2094 %} 2095 2096 // Opcde enc_class for 8/32 bit immediate instructions with sign-extension 2097 enc_class OpcSE(immI imm) 2098 %{ 2099 // Emit primary opcode and set sign-extend bit 2100 // Check for 8-bit immediate, and set sign extend bit in opcode 2101 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2102 emit_opcode(cbuf, $primary | 0x02); 2103 } else { 2104 // 32-bit immediate 2105 emit_opcode(cbuf, $primary); 2106 } 2107 %} 2108 2109 enc_class OpcSErm(rRegI dst, immI imm) 2110 %{ 2111 // OpcSEr/m 2112 int dstenc = $dst$$reg; 2113 if (dstenc >= 8) { 2114 emit_opcode(cbuf, Assembler::REX_B); 2115 dstenc -= 8; 2116 } 2117 // Emit primary opcode and set sign-extend bit 2118 // Check for 8-bit immediate, and set sign extend bit in opcode 2119 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2120 emit_opcode(cbuf, $primary | 0x02); 2121 } else { 2122 // 32-bit immediate 2123 emit_opcode(cbuf, $primary); 2124 } 2125 // Emit r/m byte with secondary opcode, after primary opcode. 2126 emit_rm(cbuf, 0x3, $secondary, dstenc); 2127 %} 2128 2129 enc_class OpcSErm_wide(rRegL dst, immI imm) 2130 %{ 2131 // OpcSEr/m 2132 int dstenc = $dst$$reg; 2133 if (dstenc < 8) { 2134 emit_opcode(cbuf, Assembler::REX_W); 2135 } else { 2136 emit_opcode(cbuf, Assembler::REX_WB); 2137 dstenc -= 8; 2138 } 2139 // Emit primary opcode and set sign-extend bit 2140 // Check for 8-bit immediate, and set sign extend bit in opcode 2141 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2142 emit_opcode(cbuf, $primary | 0x02); 2143 } else { 2144 // 32-bit immediate 2145 emit_opcode(cbuf, $primary); 2146 } 2147 // Emit r/m byte with secondary opcode, after primary opcode. 2148 emit_rm(cbuf, 0x3, $secondary, dstenc); 2149 %} 2150 2151 enc_class Con8or32(immI imm) 2152 %{ 2153 // Check for 8-bit immediate, and set sign extend bit in opcode 2154 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 2155 $$$emit8$imm$$constant; 2156 } else { 2157 // 32-bit immediate 2158 $$$emit32$imm$$constant; 2159 } 2160 %} 2161 2162 enc_class opc2_reg(rRegI dst) 2163 %{ 2164 // BSWAP 2165 emit_cc(cbuf, $secondary, $dst$$reg); 2166 %} 2167 2168 enc_class opc3_reg(rRegI dst) 2169 %{ 2170 // BSWAP 2171 emit_cc(cbuf, $tertiary, $dst$$reg); 2172 %} 2173 2174 enc_class reg_opc(rRegI div) 2175 %{ 2176 // INC, DEC, IDIV, IMOD, JMP indirect, ... 2177 emit_rm(cbuf, 0x3, $secondary, $div$$reg & 7); 2178 %} 2179 2180 enc_class enc_cmov(cmpOp cop) 2181 %{ 2182 // CMOV 2183 $$$emit8$primary; 2184 emit_cc(cbuf, $secondary, $cop$$cmpcode); 2185 %} 2186 2187 enc_class enc_PartialSubtypeCheck() 2188 %{ 2189 Register Rrdi = as_Register(RDI_enc); // result register 2190 Register Rrax = as_Register(RAX_enc); // super class 2191 Register Rrcx = as_Register(RCX_enc); // killed 2192 Register Rrsi = as_Register(RSI_enc); // sub class 2193 Label miss; 2194 const bool set_cond_codes = true; 2195 2196 MacroAssembler _masm(&cbuf); 2197 __ check_klass_subtype_slow_path(Rrsi, Rrax, Rrcx, Rrdi, 2198 NULL, &miss, 2199 /*set_cond_codes:*/ true); 2200 if ($primary) { 2201 __ xorptr(Rrdi, Rrdi); 2202 } 2203 __ bind(miss); 2204 %} 2205 2206 enc_class clear_avx %{ 2207 debug_only(int off0 = cbuf.insts_size()); 2208 if (generate_vzeroupper(Compile::current())) { 2209 // Clear upper bits of YMM registers to avoid AVX <-> SSE transition penalty 2210 // Clear upper bits of YMM registers when current compiled code uses 2211 // wide vectors to avoid AVX <-> SSE transition penalty during call. 2212 MacroAssembler _masm(&cbuf); 2213 __ vzeroupper(); 2214 } 2215 debug_only(int off1 = cbuf.insts_size()); 2216 assert(off1 - off0 == clear_avx_size(), "correct size prediction"); 2217 %} 2218 2219 enc_class Java_To_Runtime(method meth) %{ 2220 // No relocation needed 2221 MacroAssembler _masm(&cbuf); 2222 __ mov64(r10, (int64_t) $meth$$method); 2223 __ call(r10); 2224 %} 2225 2226 enc_class Java_To_Interpreter(method meth) 2227 %{ 2228 // CALL Java_To_Interpreter 2229 // This is the instruction starting address for relocation info. 2230 cbuf.set_insts_mark(); 2231 $$$emit8$primary; 2232 // CALL directly to the runtime 2233 emit_d32_reloc(cbuf, 2234 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2235 runtime_call_Relocation::spec(), 2236 RELOC_DISP32); 2237 %} 2238 2239 enc_class Java_Static_Call(method meth) 2240 %{ 2241 // JAVA STATIC CALL 2242 // CALL to fixup routine. Fixup routine uses ScopeDesc info to 2243 // determine who we intended to call. 2244 cbuf.set_insts_mark(); 2245 $$$emit8$primary; 2246 2247 if (!_method) { 2248 emit_d32_reloc(cbuf, (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2249 runtime_call_Relocation::spec(), 2250 RELOC_DISP32); 2251 } else { 2252 int method_index = resolved_method_index(cbuf); 2253 RelocationHolder rspec = _optimized_virtual ? opt_virtual_call_Relocation::spec(method_index) 2254 : static_call_Relocation::spec(method_index); 2255 emit_d32_reloc(cbuf, (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2256 rspec, RELOC_DISP32); 2257 // Emit stubs for static call. 2258 address mark = cbuf.insts_mark(); 2259 address stub = CompiledStaticCall::emit_to_interp_stub(cbuf, mark); 2260 if (stub == NULL) { 2261 ciEnv::current()->record_failure("CodeCache is full"); 2262 return; 2263 } 2264#if INCLUDE_AOT 2265 CompiledStaticCall::emit_to_aot_stub(cbuf, mark); 2266#endif 2267 } 2268 %} 2269 2270 enc_class Java_Dynamic_Call(method meth) %{ 2271 MacroAssembler _masm(&cbuf); 2272 __ ic_call((address)$meth$$method, resolved_method_index(cbuf)); 2273 %} 2274 2275 enc_class Java_Compiled_Call(method meth) 2276 %{ 2277 // JAVA COMPILED CALL 2278 int disp = in_bytes(Method:: from_compiled_offset()); 2279 2280 // XXX XXX offset is 128 is 1.5 NON-PRODUCT !!! 2281 // assert(-0x80 <= disp && disp < 0x80, "compiled_code_offset isn't small"); 2282 2283 // callq *disp(%rax) 2284 cbuf.set_insts_mark(); 2285 $$$emit8$primary; 2286 if (disp < 0x80) { 2287 emit_rm(cbuf, 0x01, $secondary, RAX_enc); // R/M byte 2288 emit_d8(cbuf, disp); // Displacement 2289 } else { 2290 emit_rm(cbuf, 0x02, $secondary, RAX_enc); // R/M byte 2291 emit_d32(cbuf, disp); // Displacement 2292 } 2293 %} 2294 2295 enc_class reg_opc_imm(rRegI dst, immI8 shift) 2296 %{ 2297 // SAL, SAR, SHR 2298 int dstenc = $dst$$reg; 2299 if (dstenc >= 8) { 2300 emit_opcode(cbuf, Assembler::REX_B); 2301 dstenc -= 8; 2302 } 2303 $$$emit8$primary; 2304 emit_rm(cbuf, 0x3, $secondary, dstenc); 2305 $$$emit8$shift$$constant; 2306 %} 2307 2308 enc_class reg_opc_imm_wide(rRegL dst, immI8 shift) 2309 %{ 2310 // SAL, SAR, SHR 2311 int dstenc = $dst$$reg; 2312 if (dstenc < 8) { 2313 emit_opcode(cbuf, Assembler::REX_W); 2314 } else { 2315 emit_opcode(cbuf, Assembler::REX_WB); 2316 dstenc -= 8; 2317 } 2318 $$$emit8$primary; 2319 emit_rm(cbuf, 0x3, $secondary, dstenc); 2320 $$$emit8$shift$$constant; 2321 %} 2322 2323 enc_class load_immI(rRegI dst, immI src) 2324 %{ 2325 int dstenc = $dst$$reg; 2326 if (dstenc >= 8) { 2327 emit_opcode(cbuf, Assembler::REX_B); 2328 dstenc -= 8; 2329 } 2330 emit_opcode(cbuf, 0xB8 | dstenc); 2331 $$$emit32$src$$constant; 2332 %} 2333 2334 enc_class load_immL(rRegL dst, immL src) 2335 %{ 2336 int dstenc = $dst$$reg; 2337 if (dstenc < 8) { 2338 emit_opcode(cbuf, Assembler::REX_W); 2339 } else { 2340 emit_opcode(cbuf, Assembler::REX_WB); 2341 dstenc -= 8; 2342 } 2343 emit_opcode(cbuf, 0xB8 | dstenc); 2344 emit_d64(cbuf, $src$$constant); 2345 %} 2346 2347 enc_class load_immUL32(rRegL dst, immUL32 src) 2348 %{ 2349 // same as load_immI, but this time we care about zeroes in the high word 2350 int dstenc = $dst$$reg; 2351 if (dstenc >= 8) { 2352 emit_opcode(cbuf, Assembler::REX_B); 2353 dstenc -= 8; 2354 } 2355 emit_opcode(cbuf, 0xB8 | dstenc); 2356 $$$emit32$src$$constant; 2357 %} 2358 2359 enc_class load_immL32(rRegL dst, immL32 src) 2360 %{ 2361 int dstenc = $dst$$reg; 2362 if (dstenc < 8) { 2363 emit_opcode(cbuf, Assembler::REX_W); 2364 } else { 2365 emit_opcode(cbuf, Assembler::REX_WB); 2366 dstenc -= 8; 2367 } 2368 emit_opcode(cbuf, 0xC7); 2369 emit_rm(cbuf, 0x03, 0x00, dstenc); 2370 $$$emit32$src$$constant; 2371 %} 2372 2373 enc_class load_immP31(rRegP dst, immP32 src) 2374 %{ 2375 // same as load_immI, but this time we care about zeroes in the high word 2376 int dstenc = $dst$$reg; 2377 if (dstenc >= 8) { 2378 emit_opcode(cbuf, Assembler::REX_B); 2379 dstenc -= 8; 2380 } 2381 emit_opcode(cbuf, 0xB8 | dstenc); 2382 $$$emit32$src$$constant; 2383 %} 2384 2385 enc_class load_immP(rRegP dst, immP src) 2386 %{ 2387 int dstenc = $dst$$reg; 2388 if (dstenc < 8) { 2389 emit_opcode(cbuf, Assembler::REX_W); 2390 } else { 2391 emit_opcode(cbuf, Assembler::REX_WB); 2392 dstenc -= 8; 2393 } 2394 emit_opcode(cbuf, 0xB8 | dstenc); 2395 // This next line should be generated from ADLC 2396 if ($src->constant_reloc() != relocInfo::none) { 2397 emit_d64_reloc(cbuf, $src$$constant, $src->constant_reloc(), RELOC_IMM64); 2398 } else { 2399 emit_d64(cbuf, $src$$constant); 2400 } 2401 %} 2402 2403 enc_class Con32(immI src) 2404 %{ 2405 // Output immediate 2406 $$$emit32$src$$constant; 2407 %} 2408 2409 enc_class Con32F_as_bits(immF src) 2410 %{ 2411 // Output Float immediate bits 2412 jfloat jf = $src$$constant; 2413 jint jf_as_bits = jint_cast(jf); 2414 emit_d32(cbuf, jf_as_bits); 2415 %} 2416 2417 enc_class Con16(immI src) 2418 %{ 2419 // Output immediate 2420 $$$emit16$src$$constant; 2421 %} 2422 2423 // How is this different from Con32??? XXX 2424 enc_class Con_d32(immI src) 2425 %{ 2426 emit_d32(cbuf,$src$$constant); 2427 %} 2428 2429 enc_class conmemref (rRegP t1) %{ // Con32(storeImmI) 2430 // Output immediate memory reference 2431 emit_rm(cbuf, 0x00, $t1$$reg, 0x05 ); 2432 emit_d32(cbuf, 0x00); 2433 %} 2434 2435 enc_class lock_prefix() 2436 %{ 2437 if (os::is_MP()) { 2438 emit_opcode(cbuf, 0xF0); // lock 2439 } 2440 %} 2441 2442 enc_class REX_mem(memory mem) 2443 %{ 2444 if ($mem$$base >= 8) { 2445 if ($mem$$index < 8) { 2446 emit_opcode(cbuf, Assembler::REX_B); 2447 } else { 2448 emit_opcode(cbuf, Assembler::REX_XB); 2449 } 2450 } else { 2451 if ($mem$$index >= 8) { 2452 emit_opcode(cbuf, Assembler::REX_X); 2453 } 2454 } 2455 %} 2456 2457 enc_class REX_mem_wide(memory mem) 2458 %{ 2459 if ($mem$$base >= 8) { 2460 if ($mem$$index < 8) { 2461 emit_opcode(cbuf, Assembler::REX_WB); 2462 } else { 2463 emit_opcode(cbuf, Assembler::REX_WXB); 2464 } 2465 } else { 2466 if ($mem$$index < 8) { 2467 emit_opcode(cbuf, Assembler::REX_W); 2468 } else { 2469 emit_opcode(cbuf, Assembler::REX_WX); 2470 } 2471 } 2472 %} 2473 2474 // for byte regs 2475 enc_class REX_breg(rRegI reg) 2476 %{ 2477 if ($reg$$reg >= 4) { 2478 emit_opcode(cbuf, $reg$$reg < 8 ? Assembler::REX : Assembler::REX_B); 2479 } 2480 %} 2481 2482 // for byte regs 2483 enc_class REX_reg_breg(rRegI dst, rRegI src) 2484 %{ 2485 if ($dst$$reg < 8) { 2486 if ($src$$reg >= 4) { 2487 emit_opcode(cbuf, $src$$reg < 8 ? Assembler::REX : Assembler::REX_B); 2488 } 2489 } else { 2490 if ($src$$reg < 8) { 2491 emit_opcode(cbuf, Assembler::REX_R); 2492 } else { 2493 emit_opcode(cbuf, Assembler::REX_RB); 2494 } 2495 } 2496 %} 2497 2498 // for byte regs 2499 enc_class REX_breg_mem(rRegI reg, memory mem) 2500 %{ 2501 if ($reg$$reg < 8) { 2502 if ($mem$$base < 8) { 2503 if ($mem$$index >= 8) { 2504 emit_opcode(cbuf, Assembler::REX_X); 2505 } else if ($reg$$reg >= 4) { 2506 emit_opcode(cbuf, Assembler::REX); 2507 } 2508 } else { 2509 if ($mem$$index < 8) { 2510 emit_opcode(cbuf, Assembler::REX_B); 2511 } else { 2512 emit_opcode(cbuf, Assembler::REX_XB); 2513 } 2514 } 2515 } else { 2516 if ($mem$$base < 8) { 2517 if ($mem$$index < 8) { 2518 emit_opcode(cbuf, Assembler::REX_R); 2519 } else { 2520 emit_opcode(cbuf, Assembler::REX_RX); 2521 } 2522 } else { 2523 if ($mem$$index < 8) { 2524 emit_opcode(cbuf, Assembler::REX_RB); 2525 } else { 2526 emit_opcode(cbuf, Assembler::REX_RXB); 2527 } 2528 } 2529 } 2530 %} 2531 2532 enc_class REX_reg(rRegI reg) 2533 %{ 2534 if ($reg$$reg >= 8) { 2535 emit_opcode(cbuf, Assembler::REX_B); 2536 } 2537 %} 2538 2539 enc_class REX_reg_wide(rRegI reg) 2540 %{ 2541 if ($reg$$reg < 8) { 2542 emit_opcode(cbuf, Assembler::REX_W); 2543 } else { 2544 emit_opcode(cbuf, Assembler::REX_WB); 2545 } 2546 %} 2547 2548 enc_class REX_reg_reg(rRegI dst, rRegI src) 2549 %{ 2550 if ($dst$$reg < 8) { 2551 if ($src$$reg >= 8) { 2552 emit_opcode(cbuf, Assembler::REX_B); 2553 } 2554 } else { 2555 if ($src$$reg < 8) { 2556 emit_opcode(cbuf, Assembler::REX_R); 2557 } else { 2558 emit_opcode(cbuf, Assembler::REX_RB); 2559 } 2560 } 2561 %} 2562 2563 enc_class REX_reg_reg_wide(rRegI dst, rRegI src) 2564 %{ 2565 if ($dst$$reg < 8) { 2566 if ($src$$reg < 8) { 2567 emit_opcode(cbuf, Assembler::REX_W); 2568 } else { 2569 emit_opcode(cbuf, Assembler::REX_WB); 2570 } 2571 } else { 2572 if ($src$$reg < 8) { 2573 emit_opcode(cbuf, Assembler::REX_WR); 2574 } else { 2575 emit_opcode(cbuf, Assembler::REX_WRB); 2576 } 2577 } 2578 %} 2579 2580 enc_class REX_reg_mem(rRegI reg, memory mem) 2581 %{ 2582 if ($reg$$reg < 8) { 2583 if ($mem$$base < 8) { 2584 if ($mem$$index >= 8) { 2585 emit_opcode(cbuf, Assembler::REX_X); 2586 } 2587 } else { 2588 if ($mem$$index < 8) { 2589 emit_opcode(cbuf, Assembler::REX_B); 2590 } else { 2591 emit_opcode(cbuf, Assembler::REX_XB); 2592 } 2593 } 2594 } else { 2595 if ($mem$$base < 8) { 2596 if ($mem$$index < 8) { 2597 emit_opcode(cbuf, Assembler::REX_R); 2598 } else { 2599 emit_opcode(cbuf, Assembler::REX_RX); 2600 } 2601 } else { 2602 if ($mem$$index < 8) { 2603 emit_opcode(cbuf, Assembler::REX_RB); 2604 } else { 2605 emit_opcode(cbuf, Assembler::REX_RXB); 2606 } 2607 } 2608 } 2609 %} 2610 2611 enc_class REX_reg_mem_wide(rRegL reg, memory mem) 2612 %{ 2613 if ($reg$$reg < 8) { 2614 if ($mem$$base < 8) { 2615 if ($mem$$index < 8) { 2616 emit_opcode(cbuf, Assembler::REX_W); 2617 } else { 2618 emit_opcode(cbuf, Assembler::REX_WX); 2619 } 2620 } else { 2621 if ($mem$$index < 8) { 2622 emit_opcode(cbuf, Assembler::REX_WB); 2623 } else { 2624 emit_opcode(cbuf, Assembler::REX_WXB); 2625 } 2626 } 2627 } else { 2628 if ($mem$$base < 8) { 2629 if ($mem$$index < 8) { 2630 emit_opcode(cbuf, Assembler::REX_WR); 2631 } else { 2632 emit_opcode(cbuf, Assembler::REX_WRX); 2633 } 2634 } else { 2635 if ($mem$$index < 8) { 2636 emit_opcode(cbuf, Assembler::REX_WRB); 2637 } else { 2638 emit_opcode(cbuf, Assembler::REX_WRXB); 2639 } 2640 } 2641 } 2642 %} 2643 2644 enc_class reg_mem(rRegI ereg, memory mem) 2645 %{ 2646 // High registers handle in encode_RegMem 2647 int reg = $ereg$$reg; 2648 int base = $mem$$base; 2649 int index = $mem$$index; 2650 int scale = $mem$$scale; 2651 int disp = $mem$$disp; 2652 relocInfo::relocType disp_reloc = $mem->disp_reloc(); 2653 2654 encode_RegMem(cbuf, reg, base, index, scale, disp, disp_reloc); 2655 %} 2656 2657 enc_class RM_opc_mem(immI rm_opcode, memory mem) 2658 %{ 2659 int rm_byte_opcode = $rm_opcode$$constant; 2660 2661 // High registers handle in encode_RegMem 2662 int base = $mem$$base; 2663 int index = $mem$$index; 2664 int scale = $mem$$scale; 2665 int displace = $mem$$disp; 2666 2667 relocInfo::relocType disp_reloc = $mem->disp_reloc(); // disp-as-oop when 2668 // working with static 2669 // globals 2670 encode_RegMem(cbuf, rm_byte_opcode, base, index, scale, displace, 2671 disp_reloc); 2672 %} 2673 2674 enc_class reg_lea(rRegI dst, rRegI src0, immI src1) 2675 %{ 2676 int reg_encoding = $dst$$reg; 2677 int base = $src0$$reg; // 0xFFFFFFFF indicates no base 2678 int index = 0x04; // 0x04 indicates no index 2679 int scale = 0x00; // 0x00 indicates no scale 2680 int displace = $src1$$constant; // 0x00 indicates no displacement 2681 relocInfo::relocType disp_reloc = relocInfo::none; 2682 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, 2683 disp_reloc); 2684 %} 2685 2686 enc_class neg_reg(rRegI dst) 2687 %{ 2688 int dstenc = $dst$$reg; 2689 if (dstenc >= 8) { 2690 emit_opcode(cbuf, Assembler::REX_B); 2691 dstenc -= 8; 2692 } 2693 // NEG $dst 2694 emit_opcode(cbuf, 0xF7); 2695 emit_rm(cbuf, 0x3, 0x03, dstenc); 2696 %} 2697 2698 enc_class neg_reg_wide(rRegI dst) 2699 %{ 2700 int dstenc = $dst$$reg; 2701 if (dstenc < 8) { 2702 emit_opcode(cbuf, Assembler::REX_W); 2703 } else { 2704 emit_opcode(cbuf, Assembler::REX_WB); 2705 dstenc -= 8; 2706 } 2707 // NEG $dst 2708 emit_opcode(cbuf, 0xF7); 2709 emit_rm(cbuf, 0x3, 0x03, dstenc); 2710 %} 2711 2712 enc_class setLT_reg(rRegI dst) 2713 %{ 2714 int dstenc = $dst$$reg; 2715 if (dstenc >= 8) { 2716 emit_opcode(cbuf, Assembler::REX_B); 2717 dstenc -= 8; 2718 } else if (dstenc >= 4) { 2719 emit_opcode(cbuf, Assembler::REX); 2720 } 2721 // SETLT $dst 2722 emit_opcode(cbuf, 0x0F); 2723 emit_opcode(cbuf, 0x9C); 2724 emit_rm(cbuf, 0x3, 0x0, dstenc); 2725 %} 2726 2727 enc_class setNZ_reg(rRegI dst) 2728 %{ 2729 int dstenc = $dst$$reg; 2730 if (dstenc >= 8) { 2731 emit_opcode(cbuf, Assembler::REX_B); 2732 dstenc -= 8; 2733 } else if (dstenc >= 4) { 2734 emit_opcode(cbuf, Assembler::REX); 2735 } 2736 // SETNZ $dst 2737 emit_opcode(cbuf, 0x0F); 2738 emit_opcode(cbuf, 0x95); 2739 emit_rm(cbuf, 0x3, 0x0, dstenc); 2740 %} 2741 2742 2743 // Compare the lonogs and set -1, 0, or 1 into dst 2744 enc_class cmpl3_flag(rRegL src1, rRegL src2, rRegI dst) 2745 %{ 2746 int src1enc = $src1$$reg; 2747 int src2enc = $src2$$reg; 2748 int dstenc = $dst$$reg; 2749 2750 // cmpq $src1, $src2 2751 if (src1enc < 8) { 2752 if (src2enc < 8) { 2753 emit_opcode(cbuf, Assembler::REX_W); 2754 } else { 2755 emit_opcode(cbuf, Assembler::REX_WB); 2756 } 2757 } else { 2758 if (src2enc < 8) { 2759 emit_opcode(cbuf, Assembler::REX_WR); 2760 } else { 2761 emit_opcode(cbuf, Assembler::REX_WRB); 2762 } 2763 } 2764 emit_opcode(cbuf, 0x3B); 2765 emit_rm(cbuf, 0x3, src1enc & 7, src2enc & 7); 2766 2767 // movl $dst, -1 2768 if (dstenc >= 8) { 2769 emit_opcode(cbuf, Assembler::REX_B); 2770 } 2771 emit_opcode(cbuf, 0xB8 | (dstenc & 7)); 2772 emit_d32(cbuf, -1); 2773 2774 // jl,s done 2775 emit_opcode(cbuf, 0x7C); 2776 emit_d8(cbuf, dstenc < 4 ? 0x06 : 0x08); 2777 2778 // setne $dst 2779 if (dstenc >= 4) { 2780 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_B); 2781 } 2782 emit_opcode(cbuf, 0x0F); 2783 emit_opcode(cbuf, 0x95); 2784 emit_opcode(cbuf, 0xC0 | (dstenc & 7)); 2785 2786 // movzbl $dst, $dst 2787 if (dstenc >= 4) { 2788 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_RB); 2789 } 2790 emit_opcode(cbuf, 0x0F); 2791 emit_opcode(cbuf, 0xB6); 2792 emit_rm(cbuf, 0x3, dstenc & 7, dstenc & 7); 2793 %} 2794 2795 enc_class Push_ResultXD(regD dst) %{ 2796 MacroAssembler _masm(&cbuf); 2797 __ fstp_d(Address(rsp, 0)); 2798 __ movdbl($dst$$XMMRegister, Address(rsp, 0)); 2799 __ addptr(rsp, 8); 2800 %} 2801 2802 enc_class Push_SrcXD(regD src) %{ 2803 MacroAssembler _masm(&cbuf); 2804 __ subptr(rsp, 8); 2805 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 2806 __ fld_d(Address(rsp, 0)); 2807 %} 2808 2809 2810 enc_class enc_rethrow() 2811 %{ 2812 cbuf.set_insts_mark(); 2813 emit_opcode(cbuf, 0xE9); // jmp entry 2814 emit_d32_reloc(cbuf, 2815 (int) (OptoRuntime::rethrow_stub() - cbuf.insts_end() - 4), 2816 runtime_call_Relocation::spec(), 2817 RELOC_DISP32); 2818 %} 2819 2820%} 2821 2822 2823 2824//----------FRAME-------------------------------------------------------------- 2825// Definition of frame structure and management information. 2826// 2827// S T A C K L A Y O U T Allocators stack-slot number 2828// | (to get allocators register number 2829// G Owned by | | v add OptoReg::stack0()) 2830// r CALLER | | 2831// o | +--------+ pad to even-align allocators stack-slot 2832// w V | pad0 | numbers; owned by CALLER 2833// t -----------+--------+----> Matcher::_in_arg_limit, unaligned 2834// h ^ | in | 5 2835// | | args | 4 Holes in incoming args owned by SELF 2836// | | | | 3 2837// | | +--------+ 2838// V | | old out| Empty on Intel, window on Sparc 2839// | old |preserve| Must be even aligned. 2840// | SP-+--------+----> Matcher::_old_SP, even aligned 2841// | | in | 3 area for Intel ret address 2842// Owned by |preserve| Empty on Sparc. 2843// SELF +--------+ 2844// | | pad2 | 2 pad to align old SP 2845// | +--------+ 1 2846// | | locks | 0 2847// | +--------+----> OptoReg::stack0(), even aligned 2848// | | pad1 | 11 pad to align new SP 2849// | +--------+ 2850// | | | 10 2851// | | spills | 9 spills 2852// V | | 8 (pad0 slot for callee) 2853// -----------+--------+----> Matcher::_out_arg_limit, unaligned 2854// ^ | out | 7 2855// | | args | 6 Holes in outgoing args owned by CALLEE 2856// Owned by +--------+ 2857// CALLEE | new out| 6 Empty on Intel, window on Sparc 2858// | new |preserve| Must be even-aligned. 2859// | SP-+--------+----> Matcher::_new_SP, even aligned 2860// | | | 2861// 2862// Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 2863// known from SELF's arguments and the Java calling convention. 2864// Region 6-7 is determined per call site. 2865// Note 2: If the calling convention leaves holes in the incoming argument 2866// area, those holes are owned by SELF. Holes in the outgoing area 2867// are owned by the CALLEE. Holes should not be nessecary in the 2868// incoming area, as the Java calling convention is completely under 2869// the control of the AD file. Doubles can be sorted and packed to 2870// avoid holes. Holes in the outgoing arguments may be nessecary for 2871// varargs C calling conventions. 2872// Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 2873// even aligned with pad0 as needed. 2874// Region 6 is even aligned. Region 6-7 is NOT even aligned; 2875// region 6-11 is even aligned; it may be padded out more so that 2876// the region from SP to FP meets the minimum stack alignment. 2877// Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 2878// alignment. Region 11, pad1, may be dynamically extended so that 2879// SP meets the minimum alignment. 2880 2881frame 2882%{ 2883 // What direction does stack grow in (assumed to be same for C & Java) 2884 stack_direction(TOWARDS_LOW); 2885 2886 // These three registers define part of the calling convention 2887 // between compiled code and the interpreter. 2888 inline_cache_reg(RAX); // Inline Cache Register 2889 interpreter_method_oop_reg(RBX); // Method Oop Register when 2890 // calling interpreter 2891 2892 // Optional: name the operand used by cisc-spilling to access 2893 // [stack_pointer + offset] 2894 cisc_spilling_operand_name(indOffset32); 2895 2896 // Number of stack slots consumed by locking an object 2897 sync_stack_slots(2); 2898 2899 // Compiled code's Frame Pointer 2900 frame_pointer(RSP); 2901 2902 // Interpreter stores its frame pointer in a register which is 2903 // stored to the stack by I2CAdaptors. 2904 // I2CAdaptors convert from interpreted java to compiled java. 2905 interpreter_frame_pointer(RBP); 2906 2907 // Stack alignment requirement 2908 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 2909 2910 // Number of stack slots between incoming argument block and the start of 2911 // a new frame. The PROLOG must add this many slots to the stack. The 2912 // EPILOG must remove this many slots. amd64 needs two slots for 2913 // return address. 2914 in_preserve_stack_slots(4 + 2 * VerifyStackAtCalls); 2915 2916 // Number of outgoing stack slots killed above the out_preserve_stack_slots 2917 // for calls to C. Supports the var-args backing area for register parms. 2918 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 2919 2920 // The after-PROLOG location of the return address. Location of 2921 // return address specifies a type (REG or STACK) and a number 2922 // representing the register number (i.e. - use a register name) or 2923 // stack slot. 2924 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 2925 // Otherwise, it is above the locks and verification slot and alignment word 2926 return_addr(STACK - 2 + 2927 align_up((Compile::current()->in_preserve_stack_slots() + 2928 Compile::current()->fixed_slots()), 2929 stack_alignment_in_slots())); 2930 2931 // Body of function which returns an integer array locating 2932 // arguments either in registers or in stack slots. Passed an array 2933 // of ideal registers called "sig" and a "length" count. Stack-slot 2934 // offsets are based on outgoing arguments, i.e. a CALLER setting up 2935 // arguments for a CALLEE. Incoming stack arguments are 2936 // automatically biased by the preserve_stack_slots field above. 2937 2938 calling_convention 2939 %{ 2940 // No difference between ingoing/outgoing just pass false 2941 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 2942 %} 2943 2944 c_calling_convention 2945 %{ 2946 // This is obviously always outgoing 2947 (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length); 2948 %} 2949 2950 // Location of compiled Java return values. Same as C for now. 2951 return_value 2952 %{ 2953 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 2954 "only return normal values"); 2955 2956 static const int lo[Op_RegL + 1] = { 2957 0, 2958 0, 2959 RAX_num, // Op_RegN 2960 RAX_num, // Op_RegI 2961 RAX_num, // Op_RegP 2962 XMM0_num, // Op_RegF 2963 XMM0_num, // Op_RegD 2964 RAX_num // Op_RegL 2965 }; 2966 static const int hi[Op_RegL + 1] = { 2967 0, 2968 0, 2969 OptoReg::Bad, // Op_RegN 2970 OptoReg::Bad, // Op_RegI 2971 RAX_H_num, // Op_RegP 2972 OptoReg::Bad, // Op_RegF 2973 XMM0b_num, // Op_RegD 2974 RAX_H_num // Op_RegL 2975 }; 2976 // Excluded flags and vector registers. 2977 assert(ARRAY_SIZE(hi) == _last_machine_leaf - 6, "missing type"); 2978 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 2979 %} 2980%} 2981 2982//----------ATTRIBUTES--------------------------------------------------------- 2983//----------Operand Attributes------------------------------------------------- 2984op_attrib op_cost(0); // Required cost attribute 2985 2986//----------Instruction Attributes--------------------------------------------- 2987ins_attrib ins_cost(100); // Required cost attribute 2988ins_attrib ins_size(8); // Required size attribute (in bits) 2989ins_attrib ins_short_branch(0); // Required flag: is this instruction 2990 // a non-matching short branch variant 2991 // of some long branch? 2992ins_attrib ins_alignment(1); // Required alignment attribute (must 2993 // be a power of 2) specifies the 2994 // alignment that some part of the 2995 // instruction (not necessarily the 2996 // start) requires. If > 1, a 2997 // compute_padding() function must be 2998 // provided for the instruction 2999 3000//----------OPERANDS----------------------------------------------------------- 3001// Operand definitions must precede instruction definitions for correct parsing 3002// in the ADLC because operands constitute user defined types which are used in 3003// instruction definitions. 3004 3005//----------Simple Operands---------------------------------------------------- 3006// Immediate Operands 3007// Integer Immediate 3008operand immI() 3009%{ 3010 match(ConI); 3011 3012 op_cost(10); 3013 format %{ %} 3014 interface(CONST_INTER); 3015%} 3016 3017// Constant for test vs zero 3018operand immI0() 3019%{ 3020 predicate(n->get_int() == 0); 3021 match(ConI); 3022 3023 op_cost(0); 3024 format %{ %} 3025 interface(CONST_INTER); 3026%} 3027 3028// Constant for increment 3029operand immI1() 3030%{ 3031 predicate(n->get_int() == 1); 3032 match(ConI); 3033 3034 op_cost(0); 3035 format %{ %} 3036 interface(CONST_INTER); 3037%} 3038 3039// Constant for decrement 3040operand immI_M1() 3041%{ 3042 predicate(n->get_int() == -1); 3043 match(ConI); 3044 3045 op_cost(0); 3046 format %{ %} 3047 interface(CONST_INTER); 3048%} 3049 3050// Valid scale values for addressing modes 3051operand immI2() 3052%{ 3053 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 3054 match(ConI); 3055 3056 format %{ %} 3057 interface(CONST_INTER); 3058%} 3059 3060operand immI8() 3061%{ 3062 predicate((-0x80 <= n->get_int()) && (n->get_int() < 0x80)); 3063 match(ConI); 3064 3065 op_cost(5); 3066 format %{ %} 3067 interface(CONST_INTER); 3068%} 3069 3070operand immU8() 3071%{ 3072 predicate((0 <= n->get_int()) && (n->get_int() <= 255)); 3073 match(ConI); 3074 3075 op_cost(5); 3076 format %{ %} 3077 interface(CONST_INTER); 3078%} 3079 3080operand immI16() 3081%{ 3082 predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767)); 3083 match(ConI); 3084 3085 op_cost(10); 3086 format %{ %} 3087 interface(CONST_INTER); 3088%} 3089 3090// Int Immediate non-negative 3091operand immU31() 3092%{ 3093 predicate(n->get_int() >= 0); 3094 match(ConI); 3095 3096 op_cost(0); 3097 format %{ %} 3098 interface(CONST_INTER); 3099%} 3100 3101// Constant for long shifts 3102operand immI_32() 3103%{ 3104 predicate( n->get_int() == 32 ); 3105 match(ConI); 3106 3107 op_cost(0); 3108 format %{ %} 3109 interface(CONST_INTER); 3110%} 3111 3112// Constant for long shifts 3113operand immI_64() 3114%{ 3115 predicate( n->get_int() == 64 ); 3116 match(ConI); 3117 3118 op_cost(0); 3119 format %{ %} 3120 interface(CONST_INTER); 3121%} 3122 3123// Pointer Immediate 3124operand immP() 3125%{ 3126 match(ConP); 3127 3128 op_cost(10); 3129 format %{ %} 3130 interface(CONST_INTER); 3131%} 3132 3133// NULL Pointer Immediate 3134operand immP0() 3135%{ 3136 predicate(n->get_ptr() == 0); 3137 match(ConP); 3138 3139 op_cost(5); 3140 format %{ %} 3141 interface(CONST_INTER); 3142%} 3143 3144// Pointer Immediate 3145operand immN() %{ 3146 match(ConN); 3147 3148 op_cost(10); 3149 format %{ %} 3150 interface(CONST_INTER); 3151%} 3152 3153operand immNKlass() %{ 3154 match(ConNKlass); 3155 3156 op_cost(10); 3157 format %{ %} 3158 interface(CONST_INTER); 3159%} 3160 3161// NULL Pointer Immediate 3162operand immN0() %{ 3163 predicate(n->get_narrowcon() == 0); 3164 match(ConN); 3165 3166 op_cost(5); 3167 format %{ %} 3168 interface(CONST_INTER); 3169%} 3170 3171operand immP31() 3172%{ 3173 predicate(n->as_Type()->type()->reloc() == relocInfo::none 3174 && (n->get_ptr() >> 31) == 0); 3175 match(ConP); 3176 3177 op_cost(5); 3178 format %{ %} 3179 interface(CONST_INTER); 3180%} 3181 3182 3183// Long Immediate 3184operand immL() 3185%{ 3186 match(ConL); 3187 3188 op_cost(20); 3189 format %{ %} 3190 interface(CONST_INTER); 3191%} 3192 3193// Long Immediate 8-bit 3194operand immL8() 3195%{ 3196 predicate(-0x80L <= n->get_long() && n->get_long() < 0x80L); 3197 match(ConL); 3198 3199 op_cost(5); 3200 format %{ %} 3201 interface(CONST_INTER); 3202%} 3203 3204// Long Immediate 32-bit unsigned 3205operand immUL32() 3206%{ 3207 predicate(n->get_long() == (unsigned int) (n->get_long())); 3208 match(ConL); 3209 3210 op_cost(10); 3211 format %{ %} 3212 interface(CONST_INTER); 3213%} 3214 3215// Long Immediate 32-bit signed 3216operand immL32() 3217%{ 3218 predicate(n->get_long() == (int) (n->get_long())); 3219 match(ConL); 3220 3221 op_cost(15); 3222 format %{ %} 3223 interface(CONST_INTER); 3224%} 3225 3226// Long Immediate zero 3227operand immL0() 3228%{ 3229 predicate(n->get_long() == 0L); 3230 match(ConL); 3231 3232 op_cost(10); 3233 format %{ %} 3234 interface(CONST_INTER); 3235%} 3236 3237// Constant for increment 3238operand immL1() 3239%{ 3240 predicate(n->get_long() == 1); 3241 match(ConL); 3242 3243 format %{ %} 3244 interface(CONST_INTER); 3245%} 3246 3247// Constant for decrement 3248operand immL_M1() 3249%{ 3250 predicate(n->get_long() == -1); 3251 match(ConL); 3252 3253 format %{ %} 3254 interface(CONST_INTER); 3255%} 3256 3257// Long Immediate: the value 10 3258operand immL10() 3259%{ 3260 predicate(n->get_long() == 10); 3261 match(ConL); 3262 3263 format %{ %} 3264 interface(CONST_INTER); 3265%} 3266 3267// Long immediate from 0 to 127. 3268// Used for a shorter form of long mul by 10. 3269operand immL_127() 3270%{ 3271 predicate(0 <= n->get_long() && n->get_long() < 0x80); 3272 match(ConL); 3273 3274 op_cost(10); 3275 format %{ %} 3276 interface(CONST_INTER); 3277%} 3278 3279// Long Immediate: low 32-bit mask 3280operand immL_32bits() 3281%{ 3282 predicate(n->get_long() == 0xFFFFFFFFL); 3283 match(ConL); 3284 op_cost(20); 3285 3286 format %{ %} 3287 interface(CONST_INTER); 3288%} 3289 3290// Float Immediate zero 3291operand immF0() 3292%{ 3293 predicate(jint_cast(n->getf()) == 0); 3294 match(ConF); 3295 3296 op_cost(5); 3297 format %{ %} 3298 interface(CONST_INTER); 3299%} 3300 3301// Float Immediate 3302operand immF() 3303%{ 3304 match(ConF); 3305 3306 op_cost(15); 3307 format %{ %} 3308 interface(CONST_INTER); 3309%} 3310 3311// Double Immediate zero 3312operand immD0() 3313%{ 3314 predicate(jlong_cast(n->getd()) == 0); 3315 match(ConD); 3316 3317 op_cost(5); 3318 format %{ %} 3319 interface(CONST_INTER); 3320%} 3321 3322// Double Immediate 3323operand immD() 3324%{ 3325 match(ConD); 3326 3327 op_cost(15); 3328 format %{ %} 3329 interface(CONST_INTER); 3330%} 3331 3332// Immediates for special shifts (sign extend) 3333 3334// Constants for increment 3335operand immI_16() 3336%{ 3337 predicate(n->get_int() == 16); 3338 match(ConI); 3339 3340 format %{ %} 3341 interface(CONST_INTER); 3342%} 3343 3344operand immI_24() 3345%{ 3346 predicate(n->get_int() == 24); 3347 match(ConI); 3348 3349 format %{ %} 3350 interface(CONST_INTER); 3351%} 3352 3353// Constant for byte-wide masking 3354operand immI_255() 3355%{ 3356 predicate(n->get_int() == 255); 3357 match(ConI); 3358 3359 format %{ %} 3360 interface(CONST_INTER); 3361%} 3362 3363// Constant for short-wide masking 3364operand immI_65535() 3365%{ 3366 predicate(n->get_int() == 65535); 3367 match(ConI); 3368 3369 format %{ %} 3370 interface(CONST_INTER); 3371%} 3372 3373// Constant for byte-wide masking 3374operand immL_255() 3375%{ 3376 predicate(n->get_long() == 255); 3377 match(ConL); 3378 3379 format %{ %} 3380 interface(CONST_INTER); 3381%} 3382 3383// Constant for short-wide masking 3384operand immL_65535() 3385%{ 3386 predicate(n->get_long() == 65535); 3387 match(ConL); 3388 3389 format %{ %} 3390 interface(CONST_INTER); 3391%} 3392 3393// Register Operands 3394// Integer Register 3395operand rRegI() 3396%{ 3397 constraint(ALLOC_IN_RC(int_reg)); 3398 match(RegI); 3399 3400 match(rax_RegI); 3401 match(rbx_RegI); 3402 match(rcx_RegI); 3403 match(rdx_RegI); 3404 match(rdi_RegI); 3405 3406 format %{ %} 3407 interface(REG_INTER); 3408%} 3409 3410// Special Registers 3411operand rax_RegI() 3412%{ 3413 constraint(ALLOC_IN_RC(int_rax_reg)); 3414 match(RegI); 3415 match(rRegI); 3416 3417 format %{ "RAX" %} 3418 interface(REG_INTER); 3419%} 3420 3421// Special Registers 3422operand rbx_RegI() 3423%{ 3424 constraint(ALLOC_IN_RC(int_rbx_reg)); 3425 match(RegI); 3426 match(rRegI); 3427 3428 format %{ "RBX" %} 3429 interface(REG_INTER); 3430%} 3431 3432operand rcx_RegI() 3433%{ 3434 constraint(ALLOC_IN_RC(int_rcx_reg)); 3435 match(RegI); 3436 match(rRegI); 3437 3438 format %{ "RCX" %} 3439 interface(REG_INTER); 3440%} 3441 3442operand rdx_RegI() 3443%{ 3444 constraint(ALLOC_IN_RC(int_rdx_reg)); 3445 match(RegI); 3446 match(rRegI); 3447 3448 format %{ "RDX" %} 3449 interface(REG_INTER); 3450%} 3451 3452operand rdi_RegI() 3453%{ 3454 constraint(ALLOC_IN_RC(int_rdi_reg)); 3455 match(RegI); 3456 match(rRegI); 3457 3458 format %{ "RDI" %} 3459 interface(REG_INTER); 3460%} 3461 3462operand no_rcx_RegI() 3463%{ 3464 constraint(ALLOC_IN_RC(int_no_rcx_reg)); 3465 match(RegI); 3466 match(rax_RegI); 3467 match(rbx_RegI); 3468 match(rdx_RegI); 3469 match(rdi_RegI); 3470 3471 format %{ %} 3472 interface(REG_INTER); 3473%} 3474 3475operand no_rax_rdx_RegI() 3476%{ 3477 constraint(ALLOC_IN_RC(int_no_rax_rdx_reg)); 3478 match(RegI); 3479 match(rbx_RegI); 3480 match(rcx_RegI); 3481 match(rdi_RegI); 3482 3483 format %{ %} 3484 interface(REG_INTER); 3485%} 3486 3487// Pointer Register 3488operand any_RegP() 3489%{ 3490 constraint(ALLOC_IN_RC(any_reg)); 3491 match(RegP); 3492 match(rax_RegP); 3493 match(rbx_RegP); 3494 match(rdi_RegP); 3495 match(rsi_RegP); 3496 match(rbp_RegP); 3497 match(r15_RegP); 3498 match(rRegP); 3499 3500 format %{ %} 3501 interface(REG_INTER); 3502%} 3503 3504operand rRegP() 3505%{ 3506 constraint(ALLOC_IN_RC(ptr_reg)); 3507 match(RegP); 3508 match(rax_RegP); 3509 match(rbx_RegP); 3510 match(rdi_RegP); 3511 match(rsi_RegP); 3512 match(rbp_RegP); // See Q&A below about 3513 match(r15_RegP); // r15_RegP and rbp_RegP. 3514 3515 format %{ %} 3516 interface(REG_INTER); 3517%} 3518 3519operand rRegN() %{ 3520 constraint(ALLOC_IN_RC(int_reg)); 3521 match(RegN); 3522 3523 format %{ %} 3524 interface(REG_INTER); 3525%} 3526 3527// Question: Why is r15_RegP (the read-only TLS register) a match for rRegP? 3528// Answer: Operand match rules govern the DFA as it processes instruction inputs. 3529// It's fine for an instruction input that expects rRegP to match a r15_RegP. 3530// The output of an instruction is controlled by the allocator, which respects 3531// register class masks, not match rules. Unless an instruction mentions 3532// r15_RegP or any_RegP explicitly as its output, r15 will not be considered 3533// by the allocator as an input. 3534// The same logic applies to rbp_RegP being a match for rRegP: If PreserveFramePointer==true, 3535// the RBP is used as a proper frame pointer and is not included in ptr_reg. As a 3536// result, RBP is not included in the output of the instruction either. 3537 3538operand no_rax_RegP() 3539%{ 3540 constraint(ALLOC_IN_RC(ptr_no_rax_reg)); 3541 match(RegP); 3542 match(rbx_RegP); 3543 match(rsi_RegP); 3544 match(rdi_RegP); 3545 3546 format %{ %} 3547 interface(REG_INTER); 3548%} 3549 3550// This operand is not allowed to use RBP even if 3551// RBP is not used to hold the frame pointer. 3552operand no_rbp_RegP() 3553%{ 3554 constraint(ALLOC_IN_RC(ptr_reg_no_rbp)); 3555 match(RegP); 3556 match(rbx_RegP); 3557 match(rsi_RegP); 3558 match(rdi_RegP); 3559 3560 format %{ %} 3561 interface(REG_INTER); 3562%} 3563 3564operand no_rax_rbx_RegP() 3565%{ 3566 constraint(ALLOC_IN_RC(ptr_no_rax_rbx_reg)); 3567 match(RegP); 3568 match(rsi_RegP); 3569 match(rdi_RegP); 3570 3571 format %{ %} 3572 interface(REG_INTER); 3573%} 3574 3575// Special Registers 3576// Return a pointer value 3577operand rax_RegP() 3578%{ 3579 constraint(ALLOC_IN_RC(ptr_rax_reg)); 3580 match(RegP); 3581 match(rRegP); 3582 3583 format %{ %} 3584 interface(REG_INTER); 3585%} 3586 3587// Special Registers 3588// Return a compressed pointer value 3589operand rax_RegN() 3590%{ 3591 constraint(ALLOC_IN_RC(int_rax_reg)); 3592 match(RegN); 3593 match(rRegN); 3594 3595 format %{ %} 3596 interface(REG_INTER); 3597%} 3598 3599// Used in AtomicAdd 3600operand rbx_RegP() 3601%{ 3602 constraint(ALLOC_IN_RC(ptr_rbx_reg)); 3603 match(RegP); 3604 match(rRegP); 3605 3606 format %{ %} 3607 interface(REG_INTER); 3608%} 3609 3610operand rsi_RegP() 3611%{ 3612 constraint(ALLOC_IN_RC(ptr_rsi_reg)); 3613 match(RegP); 3614 match(rRegP); 3615 3616 format %{ %} 3617 interface(REG_INTER); 3618%} 3619 3620// Used in rep stosq 3621operand rdi_RegP() 3622%{ 3623 constraint(ALLOC_IN_RC(ptr_rdi_reg)); 3624 match(RegP); 3625 match(rRegP); 3626 3627 format %{ %} 3628 interface(REG_INTER); 3629%} 3630 3631operand r15_RegP() 3632%{ 3633 constraint(ALLOC_IN_RC(ptr_r15_reg)); 3634 match(RegP); 3635 match(rRegP); 3636 3637 format %{ %} 3638 interface(REG_INTER); 3639%} 3640 3641operand rex_RegP() 3642%{ 3643 constraint(ALLOC_IN_RC(ptr_rex_reg)); 3644 match(RegP); 3645 match(rRegP); 3646 3647 format %{ %} 3648 interface(REG_INTER); 3649%} 3650 3651operand rRegL() 3652%{ 3653 constraint(ALLOC_IN_RC(long_reg)); 3654 match(RegL); 3655 match(rax_RegL); 3656 match(rdx_RegL); 3657 3658 format %{ %} 3659 interface(REG_INTER); 3660%} 3661 3662// Special Registers 3663operand no_rax_rdx_RegL() 3664%{ 3665 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 3666 match(RegL); 3667 match(rRegL); 3668 3669 format %{ %} 3670 interface(REG_INTER); 3671%} 3672 3673operand no_rax_RegL() 3674%{ 3675 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 3676 match(RegL); 3677 match(rRegL); 3678 match(rdx_RegL); 3679 3680 format %{ %} 3681 interface(REG_INTER); 3682%} 3683 3684operand no_rcx_RegL() 3685%{ 3686 constraint(ALLOC_IN_RC(long_no_rcx_reg)); 3687 match(RegL); 3688 match(rRegL); 3689 3690 format %{ %} 3691 interface(REG_INTER); 3692%} 3693 3694operand rax_RegL() 3695%{ 3696 constraint(ALLOC_IN_RC(long_rax_reg)); 3697 match(RegL); 3698 match(rRegL); 3699 3700 format %{ "RAX" %} 3701 interface(REG_INTER); 3702%} 3703 3704operand rcx_RegL() 3705%{ 3706 constraint(ALLOC_IN_RC(long_rcx_reg)); 3707 match(RegL); 3708 match(rRegL); 3709 3710 format %{ %} 3711 interface(REG_INTER); 3712%} 3713 3714operand rdx_RegL() 3715%{ 3716 constraint(ALLOC_IN_RC(long_rdx_reg)); 3717 match(RegL); 3718 match(rRegL); 3719 3720 format %{ %} 3721 interface(REG_INTER); 3722%} 3723 3724// Flags register, used as output of compare instructions 3725operand rFlagsReg() 3726%{ 3727 constraint(ALLOC_IN_RC(int_flags)); 3728 match(RegFlags); 3729 3730 format %{ "RFLAGS" %} 3731 interface(REG_INTER); 3732%} 3733 3734// Flags register, used as output of FLOATING POINT compare instructions 3735operand rFlagsRegU() 3736%{ 3737 constraint(ALLOC_IN_RC(int_flags)); 3738 match(RegFlags); 3739 3740 format %{ "RFLAGS_U" %} 3741 interface(REG_INTER); 3742%} 3743 3744operand rFlagsRegUCF() %{ 3745 constraint(ALLOC_IN_RC(int_flags)); 3746 match(RegFlags); 3747 predicate(false); 3748 3749 format %{ "RFLAGS_U_CF" %} 3750 interface(REG_INTER); 3751%} 3752 3753// Float register operands 3754operand regF() %{ 3755 constraint(ALLOC_IN_RC(float_reg)); 3756 match(RegF); 3757 3758 format %{ %} 3759 interface(REG_INTER); 3760%} 3761 3762// Float register operands 3763operand legRegF() %{ 3764 constraint(ALLOC_IN_RC(float_reg_legacy)); 3765 match(RegF); 3766 3767 format %{ %} 3768 interface(REG_INTER); 3769%} 3770 3771// Float register operands 3772operand vlRegF() %{ 3773 constraint(ALLOC_IN_RC(float_reg_vl)); 3774 match(RegF); 3775 3776 format %{ %} 3777 interface(REG_INTER); 3778%} 3779 3780// Double register operands 3781operand regD() %{ 3782 constraint(ALLOC_IN_RC(double_reg)); 3783 match(RegD); 3784 3785 format %{ %} 3786 interface(REG_INTER); 3787%} 3788 3789// Double register operands 3790operand legRegD() %{ 3791 constraint(ALLOC_IN_RC(double_reg_legacy)); 3792 match(RegD); 3793 3794 format %{ %} 3795 interface(REG_INTER); 3796%} 3797 3798// Double register operands 3799operand vlRegD() %{ 3800 constraint(ALLOC_IN_RC(double_reg_vl)); 3801 match(RegD); 3802 3803 format %{ %} 3804 interface(REG_INTER); 3805%} 3806 3807// Vectors 3808operand vecS() %{ 3809 constraint(ALLOC_IN_RC(vectors_reg_vlbwdq)); 3810 match(VecS); 3811 3812 format %{ %} 3813 interface(REG_INTER); 3814%} 3815 3816// Vectors 3817operand legVecS() %{ 3818 constraint(ALLOC_IN_RC(vectors_reg_legacy)); 3819 match(VecS); 3820 3821 format %{ %} 3822 interface(REG_INTER); 3823%} 3824 3825operand vecD() %{ 3826 constraint(ALLOC_IN_RC(vectord_reg_vlbwdq)); 3827 match(VecD); 3828 3829 format %{ %} 3830 interface(REG_INTER); 3831%} 3832 3833operand legVecD() %{ 3834 constraint(ALLOC_IN_RC(vectord_reg_legacy)); 3835 match(VecD); 3836 3837 format %{ %} 3838 interface(REG_INTER); 3839%} 3840 3841operand vecX() %{ 3842 constraint(ALLOC_IN_RC(vectorx_reg_vlbwdq)); 3843 match(VecX); 3844 3845 format %{ %} 3846 interface(REG_INTER); 3847%} 3848 3849operand legVecX() %{ 3850 constraint(ALLOC_IN_RC(vectorx_reg_legacy)); 3851 match(VecX); 3852 3853 format %{ %} 3854 interface(REG_INTER); 3855%} 3856 3857operand vecY() %{ 3858 constraint(ALLOC_IN_RC(vectory_reg_vlbwdq)); 3859 match(VecY); 3860 3861 format %{ %} 3862 interface(REG_INTER); 3863%} 3864 3865operand legVecY() %{ 3866 constraint(ALLOC_IN_RC(vectory_reg_legacy)); 3867 match(VecY); 3868 3869 format %{ %} 3870 interface(REG_INTER); 3871%} 3872 3873//----------Memory Operands---------------------------------------------------- 3874// Direct Memory Operand 3875// operand direct(immP addr) 3876// %{ 3877// match(addr); 3878 3879// format %{ "[$addr]" %} 3880// interface(MEMORY_INTER) %{ 3881// base(0xFFFFFFFF); 3882// index(0x4); 3883// scale(0x0); 3884// disp($addr); 3885// %} 3886// %} 3887 3888// Indirect Memory Operand 3889operand indirect(any_RegP reg) 3890%{ 3891 constraint(ALLOC_IN_RC(ptr_reg)); 3892 match(reg); 3893 3894 format %{ "[$reg]" %} 3895 interface(MEMORY_INTER) %{ 3896 base($reg); 3897 index(0x4); 3898 scale(0x0); 3899 disp(0x0); 3900 %} 3901%} 3902 3903// Indirect Memory Plus Short Offset Operand 3904operand indOffset8(any_RegP reg, immL8 off) 3905%{ 3906 constraint(ALLOC_IN_RC(ptr_reg)); 3907 match(AddP reg off); 3908 3909 format %{ "[$reg + $off (8-bit)]" %} 3910 interface(MEMORY_INTER) %{ 3911 base($reg); 3912 index(0x4); 3913 scale(0x0); 3914 disp($off); 3915 %} 3916%} 3917 3918// Indirect Memory Plus Long Offset Operand 3919operand indOffset32(any_RegP reg, immL32 off) 3920%{ 3921 constraint(ALLOC_IN_RC(ptr_reg)); 3922 match(AddP reg off); 3923 3924 format %{ "[$reg + $off (32-bit)]" %} 3925 interface(MEMORY_INTER) %{ 3926 base($reg); 3927 index(0x4); 3928 scale(0x0); 3929 disp($off); 3930 %} 3931%} 3932 3933// Indirect Memory Plus Index Register Plus Offset Operand 3934operand indIndexOffset(any_RegP reg, rRegL lreg, immL32 off) 3935%{ 3936 constraint(ALLOC_IN_RC(ptr_reg)); 3937 match(AddP (AddP reg lreg) off); 3938 3939 op_cost(10); 3940 format %{"[$reg + $off + $lreg]" %} 3941 interface(MEMORY_INTER) %{ 3942 base($reg); 3943 index($lreg); 3944 scale(0x0); 3945 disp($off); 3946 %} 3947%} 3948 3949// Indirect Memory Plus Index Register Plus Offset Operand 3950operand indIndex(any_RegP reg, rRegL lreg) 3951%{ 3952 constraint(ALLOC_IN_RC(ptr_reg)); 3953 match(AddP reg lreg); 3954 3955 op_cost(10); 3956 format %{"[$reg + $lreg]" %} 3957 interface(MEMORY_INTER) %{ 3958 base($reg); 3959 index($lreg); 3960 scale(0x0); 3961 disp(0x0); 3962 %} 3963%} 3964 3965// Indirect Memory Times Scale Plus Index Register 3966operand indIndexScale(any_RegP reg, rRegL lreg, immI2 scale) 3967%{ 3968 constraint(ALLOC_IN_RC(ptr_reg)); 3969 match(AddP reg (LShiftL lreg scale)); 3970 3971 op_cost(10); 3972 format %{"[$reg + $lreg << $scale]" %} 3973 interface(MEMORY_INTER) %{ 3974 base($reg); 3975 index($lreg); 3976 scale($scale); 3977 disp(0x0); 3978 %} 3979%} 3980 3981operand indPosIndexScale(any_RegP reg, rRegI idx, immI2 scale) 3982%{ 3983 constraint(ALLOC_IN_RC(ptr_reg)); 3984 predicate(n->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3985 match(AddP reg (LShiftL (ConvI2L idx) scale)); 3986 3987 op_cost(10); 3988 format %{"[$reg + pos $idx << $scale]" %} 3989 interface(MEMORY_INTER) %{ 3990 base($reg); 3991 index($idx); 3992 scale($scale); 3993 disp(0x0); 3994 %} 3995%} 3996 3997// Indirect Memory Times Scale Plus Index Register Plus Offset Operand 3998operand indIndexScaleOffset(any_RegP reg, immL32 off, rRegL lreg, immI2 scale) 3999%{ 4000 constraint(ALLOC_IN_RC(ptr_reg)); 4001 match(AddP (AddP reg (LShiftL lreg scale)) off); 4002 4003 op_cost(10); 4004 format %{"[$reg + $off + $lreg << $scale]" %} 4005 interface(MEMORY_INTER) %{ 4006 base($reg); 4007 index($lreg); 4008 scale($scale); 4009 disp($off); 4010 %} 4011%} 4012 4013// Indirect Memory Plus Positive Index Register Plus Offset Operand 4014operand indPosIndexOffset(any_RegP reg, immL32 off, rRegI idx) 4015%{ 4016 constraint(ALLOC_IN_RC(ptr_reg)); 4017 predicate(n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 4018 match(AddP (AddP reg (ConvI2L idx)) off); 4019 4020 op_cost(10); 4021 format %{"[$reg + $off + $idx]" %} 4022 interface(MEMORY_INTER) %{ 4023 base($reg); 4024 index($idx); 4025 scale(0x0); 4026 disp($off); 4027 %} 4028%} 4029 4030// Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 4031operand indPosIndexScaleOffset(any_RegP reg, immL32 off, rRegI idx, immI2 scale) 4032%{ 4033 constraint(ALLOC_IN_RC(ptr_reg)); 4034 predicate(n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 4035 match(AddP (AddP reg (LShiftL (ConvI2L idx) scale)) off); 4036 4037 op_cost(10); 4038 format %{"[$reg + $off + $idx << $scale]" %} 4039 interface(MEMORY_INTER) %{ 4040 base($reg); 4041 index($idx); 4042 scale($scale); 4043 disp($off); 4044 %} 4045%} 4046 4047// Indirect Narrow Oop Plus Offset Operand 4048// Note: x86 architecture doesn't support "scale * index + offset" without a base 4049// we can't free r12 even with Universe::narrow_oop_base() == NULL. 4050operand indCompressedOopOffset(rRegN reg, immL32 off) %{ 4051 predicate(UseCompressedOops && (Universe::narrow_oop_shift() == Address::times_8)); 4052 constraint(ALLOC_IN_RC(ptr_reg)); 4053 match(AddP (DecodeN reg) off); 4054 4055 op_cost(10); 4056 format %{"[R12 + $reg << 3 + $off] (compressed oop addressing)" %} 4057 interface(MEMORY_INTER) %{ 4058 base(0xc); // R12 4059 index($reg); 4060 scale(0x3); 4061 disp($off); 4062 %} 4063%} 4064 4065// Indirect Memory Operand 4066operand indirectNarrow(rRegN reg) 4067%{ 4068 predicate(Universe::narrow_oop_shift() == 0); 4069 constraint(ALLOC_IN_RC(ptr_reg)); 4070 match(DecodeN reg); 4071 4072 format %{ "[$reg]" %} 4073 interface(MEMORY_INTER) %{ 4074 base($reg); 4075 index(0x4); 4076 scale(0x0); 4077 disp(0x0); 4078 %} 4079%} 4080 4081// Indirect Memory Plus Short Offset Operand 4082operand indOffset8Narrow(rRegN reg, immL8 off) 4083%{ 4084 predicate(Universe::narrow_oop_shift() == 0); 4085 constraint(ALLOC_IN_RC(ptr_reg)); 4086 match(AddP (DecodeN reg) off); 4087 4088 format %{ "[$reg + $off (8-bit)]" %} 4089 interface(MEMORY_INTER) %{ 4090 base($reg); 4091 index(0x4); 4092 scale(0x0); 4093 disp($off); 4094 %} 4095%} 4096 4097// Indirect Memory Plus Long Offset Operand 4098operand indOffset32Narrow(rRegN reg, immL32 off) 4099%{ 4100 predicate(Universe::narrow_oop_shift() == 0); 4101 constraint(ALLOC_IN_RC(ptr_reg)); 4102 match(AddP (DecodeN reg) off); 4103 4104 format %{ "[$reg + $off (32-bit)]" %} 4105 interface(MEMORY_INTER) %{ 4106 base($reg); 4107 index(0x4); 4108 scale(0x0); 4109 disp($off); 4110 %} 4111%} 4112 4113// Indirect Memory Plus Index Register Plus Offset Operand 4114operand indIndexOffsetNarrow(rRegN reg, rRegL lreg, immL32 off) 4115%{ 4116 predicate(Universe::narrow_oop_shift() == 0); 4117 constraint(ALLOC_IN_RC(ptr_reg)); 4118 match(AddP (AddP (DecodeN reg) lreg) off); 4119 4120 op_cost(10); 4121 format %{"[$reg + $off + $lreg]" %} 4122 interface(MEMORY_INTER) %{ 4123 base($reg); 4124 index($lreg); 4125 scale(0x0); 4126 disp($off); 4127 %} 4128%} 4129 4130// Indirect Memory Plus Index Register Plus Offset Operand 4131operand indIndexNarrow(rRegN reg, rRegL lreg) 4132%{ 4133 predicate(Universe::narrow_oop_shift() == 0); 4134 constraint(ALLOC_IN_RC(ptr_reg)); 4135 match(AddP (DecodeN reg) lreg); 4136 4137 op_cost(10); 4138 format %{"[$reg + $lreg]" %} 4139 interface(MEMORY_INTER) %{ 4140 base($reg); 4141 index($lreg); 4142 scale(0x0); 4143 disp(0x0); 4144 %} 4145%} 4146 4147// Indirect Memory Times Scale Plus Index Register 4148operand indIndexScaleNarrow(rRegN reg, rRegL lreg, immI2 scale) 4149%{ 4150 predicate(Universe::narrow_oop_shift() == 0); 4151 constraint(ALLOC_IN_RC(ptr_reg)); 4152 match(AddP (DecodeN reg) (LShiftL lreg scale)); 4153 4154 op_cost(10); 4155 format %{"[$reg + $lreg << $scale]" %} 4156 interface(MEMORY_INTER) %{ 4157 base($reg); 4158 index($lreg); 4159 scale($scale); 4160 disp(0x0); 4161 %} 4162%} 4163 4164// Indirect Memory Times Scale Plus Index Register Plus Offset Operand 4165operand indIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegL lreg, immI2 scale) 4166%{ 4167 predicate(Universe::narrow_oop_shift() == 0); 4168 constraint(ALLOC_IN_RC(ptr_reg)); 4169 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off); 4170 4171 op_cost(10); 4172 format %{"[$reg + $off + $lreg << $scale]" %} 4173 interface(MEMORY_INTER) %{ 4174 base($reg); 4175 index($lreg); 4176 scale($scale); 4177 disp($off); 4178 %} 4179%} 4180 4181// Indirect Memory Times Plus Positive Index Register Plus Offset Operand 4182operand indPosIndexOffsetNarrow(rRegN reg, immL32 off, rRegI idx) 4183%{ 4184 constraint(ALLOC_IN_RC(ptr_reg)); 4185 predicate(Universe::narrow_oop_shift() == 0 && n->in(2)->in(3)->as_Type()->type()->is_long()->_lo >= 0); 4186 match(AddP (AddP (DecodeN reg) (ConvI2L idx)) off); 4187 4188 op_cost(10); 4189 format %{"[$reg + $off + $idx]" %} 4190 interface(MEMORY_INTER) %{ 4191 base($reg); 4192 index($idx); 4193 scale(0x0); 4194 disp($off); 4195 %} 4196%} 4197 4198// Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 4199operand indPosIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegI idx, immI2 scale) 4200%{ 4201 constraint(ALLOC_IN_RC(ptr_reg)); 4202 predicate(Universe::narrow_oop_shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 4203 match(AddP (AddP (DecodeN reg) (LShiftL (ConvI2L idx) scale)) off); 4204 4205 op_cost(10); 4206 format %{"[$reg + $off + $idx << $scale]" %} 4207 interface(MEMORY_INTER) %{ 4208 base($reg); 4209 index($idx); 4210 scale($scale); 4211 disp($off); 4212 %} 4213%} 4214 4215//----------Special Memory Operands-------------------------------------------- 4216// Stack Slot Operand - This operand is used for loading and storing temporary 4217// values on the stack where a match requires a value to 4218// flow through memory. 4219operand stackSlotP(sRegP reg) 4220%{ 4221 constraint(ALLOC_IN_RC(stack_slots)); 4222 // No match rule because this operand is only generated in matching 4223 4224 format %{ "[$reg]" %} 4225 interface(MEMORY_INTER) %{ 4226 base(0x4); // RSP 4227 index(0x4); // No Index 4228 scale(0x0); // No Scale 4229 disp($reg); // Stack Offset 4230 %} 4231%} 4232 4233operand stackSlotI(sRegI reg) 4234%{ 4235 constraint(ALLOC_IN_RC(stack_slots)); 4236 // No match rule because this operand is only generated in matching 4237 4238 format %{ "[$reg]" %} 4239 interface(MEMORY_INTER) %{ 4240 base(0x4); // RSP 4241 index(0x4); // No Index 4242 scale(0x0); // No Scale 4243 disp($reg); // Stack Offset 4244 %} 4245%} 4246 4247operand stackSlotF(sRegF reg) 4248%{ 4249 constraint(ALLOC_IN_RC(stack_slots)); 4250 // No match rule because this operand is only generated in matching 4251 4252 format %{ "[$reg]" %} 4253 interface(MEMORY_INTER) %{ 4254 base(0x4); // RSP 4255 index(0x4); // No Index 4256 scale(0x0); // No Scale 4257 disp($reg); // Stack Offset 4258 %} 4259%} 4260 4261operand stackSlotD(sRegD reg) 4262%{ 4263 constraint(ALLOC_IN_RC(stack_slots)); 4264 // No match rule because this operand is only generated in matching 4265 4266 format %{ "[$reg]" %} 4267 interface(MEMORY_INTER) %{ 4268 base(0x4); // RSP 4269 index(0x4); // No Index 4270 scale(0x0); // No Scale 4271 disp($reg); // Stack Offset 4272 %} 4273%} 4274operand stackSlotL(sRegL reg) 4275%{ 4276 constraint(ALLOC_IN_RC(stack_slots)); 4277 // No match rule because this operand is only generated in matching 4278 4279 format %{ "[$reg]" %} 4280 interface(MEMORY_INTER) %{ 4281 base(0x4); // RSP 4282 index(0x4); // No Index 4283 scale(0x0); // No Scale 4284 disp($reg); // Stack Offset 4285 %} 4286%} 4287 4288//----------Conditional Branch Operands---------------------------------------- 4289// Comparison Op - This is the operation of the comparison, and is limited to 4290// the following set of codes: 4291// L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 4292// 4293// Other attributes of the comparison, such as unsignedness, are specified 4294// by the comparison instruction that sets a condition code flags register. 4295// That result is represented by a flags operand whose subtype is appropriate 4296// to the unsignedness (etc.) of the comparison. 4297// 4298// Later, the instruction which matches both the Comparison Op (a Bool) and 4299// the flags (produced by the Cmp) specifies the coding of the comparison op 4300// by matching a specific subtype of Bool operand below, such as cmpOpU. 4301 4302// Comparision Code 4303operand cmpOp() 4304%{ 4305 match(Bool); 4306 4307 format %{ "" %} 4308 interface(COND_INTER) %{ 4309 equal(0x4, "e"); 4310 not_equal(0x5, "ne"); 4311 less(0xC, "l"); 4312 greater_equal(0xD, "ge"); 4313 less_equal(0xE, "le"); 4314 greater(0xF, "g"); 4315 overflow(0x0, "o"); 4316 no_overflow(0x1, "no"); 4317 %} 4318%} 4319 4320// Comparison Code, unsigned compare. Used by FP also, with 4321// C2 (unordered) turned into GT or LT already. The other bits 4322// C0 and C3 are turned into Carry & Zero flags. 4323operand cmpOpU() 4324%{ 4325 match(Bool); 4326 4327 format %{ "" %} 4328 interface(COND_INTER) %{ 4329 equal(0x4, "e"); 4330 not_equal(0x5, "ne"); 4331 less(0x2, "b"); 4332 greater_equal(0x3, "nb"); 4333 less_equal(0x6, "be"); 4334 greater(0x7, "nbe"); 4335 overflow(0x0, "o"); 4336 no_overflow(0x1, "no"); 4337 %} 4338%} 4339 4340 4341// Floating comparisons that don't require any fixup for the unordered case 4342operand cmpOpUCF() %{ 4343 match(Bool); 4344 predicate(n->as_Bool()->_test._test == BoolTest::lt || 4345 n->as_Bool()->_test._test == BoolTest::ge || 4346 n->as_Bool()->_test._test == BoolTest::le || 4347 n->as_Bool()->_test._test == BoolTest::gt); 4348 format %{ "" %} 4349 interface(COND_INTER) %{ 4350 equal(0x4, "e"); 4351 not_equal(0x5, "ne"); 4352 less(0x2, "b"); 4353 greater_equal(0x3, "nb"); 4354 less_equal(0x6, "be"); 4355 greater(0x7, "nbe"); 4356 overflow(0x0, "o"); 4357 no_overflow(0x1, "no"); 4358 %} 4359%} 4360 4361 4362// Floating comparisons that can be fixed up with extra conditional jumps 4363operand cmpOpUCF2() %{ 4364 match(Bool); 4365 predicate(n->as_Bool()->_test._test == BoolTest::ne || 4366 n->as_Bool()->_test._test == BoolTest::eq); 4367 format %{ "" %} 4368 interface(COND_INTER) %{ 4369 equal(0x4, "e"); 4370 not_equal(0x5, "ne"); 4371 less(0x2, "b"); 4372 greater_equal(0x3, "nb"); 4373 less_equal(0x6, "be"); 4374 greater(0x7, "nbe"); 4375 overflow(0x0, "o"); 4376 no_overflow(0x1, "no"); 4377 %} 4378%} 4379 4380// Operands for bound floating pointer register arguments 4381operand rxmm0() %{ 4382 constraint(ALLOC_IN_RC(xmm0_reg)); match(VecX); 4383 predicate((UseSSE > 0) && (UseAVX<= 2)); format%{%} interface(REG_INTER); 4384%} 4385operand rxmm1() %{ 4386 constraint(ALLOC_IN_RC(xmm1_reg)); match(VecX); 4387 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4388%} 4389operand rxmm2() %{ 4390 constraint(ALLOC_IN_RC(xmm2_reg)); match(VecX); 4391 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4392%} 4393operand rxmm3() %{ 4394 constraint(ALLOC_IN_RC(xmm3_reg)); match(VecX); 4395 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4396%} 4397operand rxmm4() %{ 4398 constraint(ALLOC_IN_RC(xmm4_reg)); match(VecX); 4399 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4400%} 4401operand rxmm5() %{ 4402 constraint(ALLOC_IN_RC(xmm5_reg)); match(VecX); 4403 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4404%} 4405operand rxmm6() %{ 4406 constraint(ALLOC_IN_RC(xmm6_reg)); match(VecX); 4407 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4408%} 4409operand rxmm7() %{ 4410 constraint(ALLOC_IN_RC(xmm7_reg)); match(VecX); 4411 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4412%} 4413operand rxmm8() %{ 4414 constraint(ALLOC_IN_RC(xmm8_reg)); match(VecX); 4415 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4416%} 4417operand rxmm9() %{ 4418 constraint(ALLOC_IN_RC(xmm9_reg)); match(VecX); 4419 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4420%} 4421operand rxmm10() %{ 4422 constraint(ALLOC_IN_RC(xmm10_reg)); match(VecX); 4423 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4424%} 4425operand rxmm11() %{ 4426 constraint(ALLOC_IN_RC(xmm11_reg)); match(VecX); 4427 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4428%} 4429operand rxmm12() %{ 4430 constraint(ALLOC_IN_RC(xmm12_reg)); match(VecX); 4431 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4432%} 4433operand rxmm13() %{ 4434 constraint(ALLOC_IN_RC(xmm13_reg)); match(VecX); 4435 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4436%} 4437operand rxmm14() %{ 4438 constraint(ALLOC_IN_RC(xmm14_reg)); match(VecX); 4439 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4440%} 4441operand rxmm15() %{ 4442 constraint(ALLOC_IN_RC(xmm15_reg)); match(VecX); 4443 predicate((UseSSE > 0) && (UseAVX <= 2)); format%{%} interface(REG_INTER); 4444%} 4445operand rxmm16() %{ 4446 constraint(ALLOC_IN_RC(xmm16_reg)); match(VecX); 4447 predicate(UseAVX == 3); format%{%} interface(REG_INTER); 4448%} 4449operand rxmm17() %{ 4450 constraint(ALLOC_IN_RC(xmm17_reg)); match(VecX); 4451 predicate(UseAVX == 3); format%{%} interface(REG_INTER); 4452%} 4453operand rxmm18() %{ 4454 constraint(ALLOC_IN_RC(xmm18_reg)); match(VecX); 4455 predicate(UseAVX == 3); format%{%} interface(REG_INTER); 4456%} 4457operand rxmm19() %{ 4458 constraint(ALLOC_IN_RC(xmm19_reg)); match(VecX); 4459 predicate(UseAVX == 3); format%{%} interface(REG_INTER); 4460%} 4461operand rxmm20() %{ 4462 constraint(ALLOC_IN_RC(xmm20_reg)); match(VecX); 4463 predicate(UseAVX == 3); format%{%} interface(REG_INTER); 4464%} 4465operand rxmm21() %{ 4466 constraint(ALLOC_IN_RC(xmm21_reg)); match(VecX); 4467 predicate(UseAVX == 3); format%{%} interface(REG_INTER); 4468%} 4469operand rxmm22() %{ 4470 constraint(ALLOC_IN_RC(xmm22_reg)); match(VecX); 4471 predicate(UseAVX == 3); format%{%} interface(REG_INTER); 4472%} 4473operand rxmm23() %{ 4474 constraint(ALLOC_IN_RC(xmm23_reg)); match(VecX); 4475 predicate(UseAVX == 3); format%{%} interface(REG_INTER); 4476%} 4477operand rxmm24() %{ 4478 constraint(ALLOC_IN_RC(xmm24_reg)); match(VecX); 4479 predicate(UseAVX == 3); format%{%} interface(REG_INTER); 4480%} 4481operand rxmm25() %{ 4482 constraint(ALLOC_IN_RC(xmm25_reg)); match(VecX); 4483 predicate(UseAVX == 3); format%{%} interface(REG_INTER); 4484%} 4485operand rxmm26() %{ 4486 constraint(ALLOC_IN_RC(xmm26_reg)); match(VecX); 4487 predicate(UseAVX == 3); format%{%} interface(REG_INTER); 4488%} 4489operand rxmm27() %{ 4490 constraint(ALLOC_IN_RC(xmm27_reg)); match(VecX); 4491 predicate(UseAVX == 3); format%{%} interface(REG_INTER); 4492%} 4493operand rxmm28() %{ 4494 constraint(ALLOC_IN_RC(xmm28_reg)); match(VecX); 4495 predicate(UseAVX == 3); format%{%} interface(REG_INTER); 4496%} 4497operand rxmm29() %{ 4498 constraint(ALLOC_IN_RC(xmm29_reg)); match(VecX); 4499 predicate(UseAVX == 3); format%{%} interface(REG_INTER); 4500%} 4501operand rxmm30() %{ 4502 constraint(ALLOC_IN_RC(xmm30_reg)); match(VecX); 4503 predicate(UseAVX == 3); format%{%} interface(REG_INTER); 4504%} 4505operand rxmm31() %{ 4506 constraint(ALLOC_IN_RC(xmm31_reg)); match(VecX); 4507 predicate(UseAVX == 3); format%{%} interface(REG_INTER); 4508%} 4509 4510//----------OPERAND CLASSES---------------------------------------------------- 4511// Operand Classes are groups of operands that are used as to simplify 4512// instruction definitions by not requiring the AD writer to specify separate 4513// instructions for every form of operand when the instruction accepts 4514// multiple operand types with the same basic encoding and format. The classic 4515// case of this is memory operands. 4516 4517opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex, 4518 indIndexScale, indPosIndexScale, indIndexScaleOffset, indPosIndexOffset, indPosIndexScaleOffset, 4519 indCompressedOopOffset, 4520 indirectNarrow, indOffset8Narrow, indOffset32Narrow, 4521 indIndexOffsetNarrow, indIndexNarrow, indIndexScaleNarrow, 4522 indIndexScaleOffsetNarrow, indPosIndexOffsetNarrow, indPosIndexScaleOffsetNarrow); 4523 4524//----------PIPELINE----------------------------------------------------------- 4525// Rules which define the behavior of the target architectures pipeline. 4526pipeline %{ 4527 4528//----------ATTRIBUTES--------------------------------------------------------- 4529attributes %{ 4530 variable_size_instructions; // Fixed size instructions 4531 max_instructions_per_bundle = 3; // Up to 3 instructions per bundle 4532 instruction_unit_size = 1; // An instruction is 1 bytes long 4533 instruction_fetch_unit_size = 16; // The processor fetches one line 4534 instruction_fetch_units = 1; // of 16 bytes 4535 4536 // List of nop instructions 4537 nops( MachNop ); 4538%} 4539 4540//----------RESOURCES---------------------------------------------------------- 4541// Resources are the functional units available to the machine 4542 4543// Generic P2/P3 pipeline 4544// 3 decoders, only D0 handles big operands; a "bundle" is the limit of 4545// 3 instructions decoded per cycle. 4546// 2 load/store ops per cycle, 1 branch, 1 FPU, 4547// 3 ALU op, only ALU0 handles mul instructions. 4548resources( D0, D1, D2, DECODE = D0 | D1 | D2, 4549 MS0, MS1, MS2, MEM = MS0 | MS1 | MS2, 4550 BR, FPU, 4551 ALU0, ALU1, ALU2, ALU = ALU0 | ALU1 | ALU2); 4552 4553//----------PIPELINE DESCRIPTION----------------------------------------------- 4554// Pipeline Description specifies the stages in the machine's pipeline 4555 4556// Generic P2/P3 pipeline 4557pipe_desc(S0, S1, S2, S3, S4, S5); 4558 4559//----------PIPELINE CLASSES--------------------------------------------------- 4560// Pipeline Classes describe the stages in which input and output are 4561// referenced by the hardware pipeline. 4562 4563// Naming convention: ialu or fpu 4564// Then: _reg 4565// Then: _reg if there is a 2nd register 4566// Then: _long if it's a pair of instructions implementing a long 4567// Then: _fat if it requires the big decoder 4568// Or: _mem if it requires the big decoder and a memory unit. 4569 4570// Integer ALU reg operation 4571pipe_class ialu_reg(rRegI dst) 4572%{ 4573 single_instruction; 4574 dst : S4(write); 4575 dst : S3(read); 4576 DECODE : S0; // any decoder 4577 ALU : S3; // any alu 4578%} 4579 4580// Long ALU reg operation 4581pipe_class ialu_reg_long(rRegL dst) 4582%{ 4583 instruction_count(2); 4584 dst : S4(write); 4585 dst : S3(read); 4586 DECODE : S0(2); // any 2 decoders 4587 ALU : S3(2); // both alus 4588%} 4589 4590// Integer ALU reg operation using big decoder 4591pipe_class ialu_reg_fat(rRegI dst) 4592%{ 4593 single_instruction; 4594 dst : S4(write); 4595 dst : S3(read); 4596 D0 : S0; // big decoder only 4597 ALU : S3; // any alu 4598%} 4599 4600// Long ALU reg operation using big decoder 4601pipe_class ialu_reg_long_fat(rRegL dst) 4602%{ 4603 instruction_count(2); 4604 dst : S4(write); 4605 dst : S3(read); 4606 D0 : S0(2); // big decoder only; twice 4607 ALU : S3(2); // any 2 alus 4608%} 4609 4610// Integer ALU reg-reg operation 4611pipe_class ialu_reg_reg(rRegI dst, rRegI src) 4612%{ 4613 single_instruction; 4614 dst : S4(write); 4615 src : S3(read); 4616 DECODE : S0; // any decoder 4617 ALU : S3; // any alu 4618%} 4619 4620// Long ALU reg-reg operation 4621pipe_class ialu_reg_reg_long(rRegL dst, rRegL src) 4622%{ 4623 instruction_count(2); 4624 dst : S4(write); 4625 src : S3(read); 4626 DECODE : S0(2); // any 2 decoders 4627 ALU : S3(2); // both alus 4628%} 4629 4630// Integer ALU reg-reg operation 4631pipe_class ialu_reg_reg_fat(rRegI dst, memory src) 4632%{ 4633 single_instruction; 4634 dst : S4(write); 4635 src : S3(read); 4636 D0 : S0; // big decoder only 4637 ALU : S3; // any alu 4638%} 4639 4640// Long ALU reg-reg operation 4641pipe_class ialu_reg_reg_long_fat(rRegL dst, rRegL src) 4642%{ 4643 instruction_count(2); 4644 dst : S4(write); 4645 src : S3(read); 4646 D0 : S0(2); // big decoder only; twice 4647 ALU : S3(2); // both alus 4648%} 4649 4650// Integer ALU reg-mem operation 4651pipe_class ialu_reg_mem(rRegI dst, memory mem) 4652%{ 4653 single_instruction; 4654 dst : S5(write); 4655 mem : S3(read); 4656 D0 : S0; // big decoder only 4657 ALU : S4; // any alu 4658 MEM : S3; // any mem 4659%} 4660 4661// Integer mem operation (prefetch) 4662pipe_class ialu_mem(memory mem) 4663%{ 4664 single_instruction; 4665 mem : S3(read); 4666 D0 : S0; // big decoder only 4667 MEM : S3; // any mem 4668%} 4669 4670// Integer Store to Memory 4671pipe_class ialu_mem_reg(memory mem, rRegI src) 4672%{ 4673 single_instruction; 4674 mem : S3(read); 4675 src : S5(read); 4676 D0 : S0; // big decoder only 4677 ALU : S4; // any alu 4678 MEM : S3; 4679%} 4680 4681// // Long Store to Memory 4682// pipe_class ialu_mem_long_reg(memory mem, rRegL src) 4683// %{ 4684// instruction_count(2); 4685// mem : S3(read); 4686// src : S5(read); 4687// D0 : S0(2); // big decoder only; twice 4688// ALU : S4(2); // any 2 alus 4689// MEM : S3(2); // Both mems 4690// %} 4691 4692// Integer Store to Memory 4693pipe_class ialu_mem_imm(memory mem) 4694%{ 4695 single_instruction; 4696 mem : S3(read); 4697 D0 : S0; // big decoder only 4698 ALU : S4; // any alu 4699 MEM : S3; 4700%} 4701 4702// Integer ALU0 reg-reg operation 4703pipe_class ialu_reg_reg_alu0(rRegI dst, rRegI src) 4704%{ 4705 single_instruction; 4706 dst : S4(write); 4707 src : S3(read); 4708 D0 : S0; // Big decoder only 4709 ALU0 : S3; // only alu0 4710%} 4711 4712// Integer ALU0 reg-mem operation 4713pipe_class ialu_reg_mem_alu0(rRegI dst, memory mem) 4714%{ 4715 single_instruction; 4716 dst : S5(write); 4717 mem : S3(read); 4718 D0 : S0; // big decoder only 4719 ALU0 : S4; // ALU0 only 4720 MEM : S3; // any mem 4721%} 4722 4723// Integer ALU reg-reg operation 4724pipe_class ialu_cr_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2) 4725%{ 4726 single_instruction; 4727 cr : S4(write); 4728 src1 : S3(read); 4729 src2 : S3(read); 4730 DECODE : S0; // any decoder 4731 ALU : S3; // any alu 4732%} 4733 4734// Integer ALU reg-imm operation 4735pipe_class ialu_cr_reg_imm(rFlagsReg cr, rRegI src1) 4736%{ 4737 single_instruction; 4738 cr : S4(write); 4739 src1 : S3(read); 4740 DECODE : S0; // any decoder 4741 ALU : S3; // any alu 4742%} 4743 4744// Integer ALU reg-mem operation 4745pipe_class ialu_cr_reg_mem(rFlagsReg cr, rRegI src1, memory src2) 4746%{ 4747 single_instruction; 4748 cr : S4(write); 4749 src1 : S3(read); 4750 src2 : S3(read); 4751 D0 : S0; // big decoder only 4752 ALU : S4; // any alu 4753 MEM : S3; 4754%} 4755 4756// Conditional move reg-reg 4757pipe_class pipe_cmplt( rRegI p, rRegI q, rRegI y) 4758%{ 4759 instruction_count(4); 4760 y : S4(read); 4761 q : S3(read); 4762 p : S3(read); 4763 DECODE : S0(4); // any decoder 4764%} 4765 4766// Conditional move reg-reg 4767pipe_class pipe_cmov_reg( rRegI dst, rRegI src, rFlagsReg cr) 4768%{ 4769 single_instruction; 4770 dst : S4(write); 4771 src : S3(read); 4772 cr : S3(read); 4773 DECODE : S0; // any decoder 4774%} 4775 4776// Conditional move reg-mem 4777pipe_class pipe_cmov_mem( rFlagsReg cr, rRegI dst, memory src) 4778%{ 4779 single_instruction; 4780 dst : S4(write); 4781 src : S3(read); 4782 cr : S3(read); 4783 DECODE : S0; // any decoder 4784 MEM : S3; 4785%} 4786 4787// Conditional move reg-reg long 4788pipe_class pipe_cmov_reg_long( rFlagsReg cr, rRegL dst, rRegL src) 4789%{ 4790 single_instruction; 4791 dst : S4(write); 4792 src : S3(read); 4793 cr : S3(read); 4794 DECODE : S0(2); // any 2 decoders 4795%} 4796 4797// XXX 4798// // Conditional move double reg-reg 4799// pipe_class pipe_cmovD_reg( rFlagsReg cr, regDPR1 dst, regD src) 4800// %{ 4801// single_instruction; 4802// dst : S4(write); 4803// src : S3(read); 4804// cr : S3(read); 4805// DECODE : S0; // any decoder 4806// %} 4807 4808// Float reg-reg operation 4809pipe_class fpu_reg(regD dst) 4810%{ 4811 instruction_count(2); 4812 dst : S3(read); 4813 DECODE : S0(2); // any 2 decoders 4814 FPU : S3; 4815%} 4816 4817// Float reg-reg operation 4818pipe_class fpu_reg_reg(regD dst, regD src) 4819%{ 4820 instruction_count(2); 4821 dst : S4(write); 4822 src : S3(read); 4823 DECODE : S0(2); // any 2 decoders 4824 FPU : S3; 4825%} 4826 4827// Float reg-reg operation 4828pipe_class fpu_reg_reg_reg(regD dst, regD src1, regD src2) 4829%{ 4830 instruction_count(3); 4831 dst : S4(write); 4832 src1 : S3(read); 4833 src2 : S3(read); 4834 DECODE : S0(3); // any 3 decoders 4835 FPU : S3(2); 4836%} 4837 4838// Float reg-reg operation 4839pipe_class fpu_reg_reg_reg_reg(regD dst, regD src1, regD src2, regD src3) 4840%{ 4841 instruction_count(4); 4842 dst : S4(write); 4843 src1 : S3(read); 4844 src2 : S3(read); 4845 src3 : S3(read); 4846 DECODE : S0(4); // any 3 decoders 4847 FPU : S3(2); 4848%} 4849 4850// Float reg-reg operation 4851pipe_class fpu_reg_mem_reg_reg(regD dst, memory src1, regD src2, regD src3) 4852%{ 4853 instruction_count(4); 4854 dst : S4(write); 4855 src1 : S3(read); 4856 src2 : S3(read); 4857 src3 : S3(read); 4858 DECODE : S1(3); // any 3 decoders 4859 D0 : S0; // Big decoder only 4860 FPU : S3(2); 4861 MEM : S3; 4862%} 4863 4864// Float reg-mem operation 4865pipe_class fpu_reg_mem(regD dst, memory mem) 4866%{ 4867 instruction_count(2); 4868 dst : S5(write); 4869 mem : S3(read); 4870 D0 : S0; // big decoder only 4871 DECODE : S1; // any decoder for FPU POP 4872 FPU : S4; 4873 MEM : S3; // any mem 4874%} 4875 4876// Float reg-mem operation 4877pipe_class fpu_reg_reg_mem(regD dst, regD src1, memory mem) 4878%{ 4879 instruction_count(3); 4880 dst : S5(write); 4881 src1 : S3(read); 4882 mem : S3(read); 4883 D0 : S0; // big decoder only 4884 DECODE : S1(2); // any decoder for FPU POP 4885 FPU : S4; 4886 MEM : S3; // any mem 4887%} 4888 4889// Float mem-reg operation 4890pipe_class fpu_mem_reg(memory mem, regD src) 4891%{ 4892 instruction_count(2); 4893 src : S5(read); 4894 mem : S3(read); 4895 DECODE : S0; // any decoder for FPU PUSH 4896 D0 : S1; // big decoder only 4897 FPU : S4; 4898 MEM : S3; // any mem 4899%} 4900 4901pipe_class fpu_mem_reg_reg(memory mem, regD src1, regD src2) 4902%{ 4903 instruction_count(3); 4904 src1 : S3(read); 4905 src2 : S3(read); 4906 mem : S3(read); 4907 DECODE : S0(2); // any decoder for FPU PUSH 4908 D0 : S1; // big decoder only 4909 FPU : S4; 4910 MEM : S3; // any mem 4911%} 4912 4913pipe_class fpu_mem_reg_mem(memory mem, regD src1, memory src2) 4914%{ 4915 instruction_count(3); 4916 src1 : S3(read); 4917 src2 : S3(read); 4918 mem : S4(read); 4919 DECODE : S0; // any decoder for FPU PUSH 4920 D0 : S0(2); // big decoder only 4921 FPU : S4; 4922 MEM : S3(2); // any mem 4923%} 4924 4925pipe_class fpu_mem_mem(memory dst, memory src1) 4926%{ 4927 instruction_count(2); 4928 src1 : S3(read); 4929 dst : S4(read); 4930 D0 : S0(2); // big decoder only 4931 MEM : S3(2); // any mem 4932%} 4933 4934pipe_class fpu_mem_mem_mem(memory dst, memory src1, memory src2) 4935%{ 4936 instruction_count(3); 4937 src1 : S3(read); 4938 src2 : S3(read); 4939 dst : S4(read); 4940 D0 : S0(3); // big decoder only 4941 FPU : S4; 4942 MEM : S3(3); // any mem 4943%} 4944 4945pipe_class fpu_mem_reg_con(memory mem, regD src1) 4946%{ 4947 instruction_count(3); 4948 src1 : S4(read); 4949 mem : S4(read); 4950 DECODE : S0; // any decoder for FPU PUSH 4951 D0 : S0(2); // big decoder only 4952 FPU : S4; 4953 MEM : S3(2); // any mem 4954%} 4955 4956// Float load constant 4957pipe_class fpu_reg_con(regD dst) 4958%{ 4959 instruction_count(2); 4960 dst : S5(write); 4961 D0 : S0; // big decoder only for the load 4962 DECODE : S1; // any decoder for FPU POP 4963 FPU : S4; 4964 MEM : S3; // any mem 4965%} 4966 4967// Float load constant 4968pipe_class fpu_reg_reg_con(regD dst, regD src) 4969%{ 4970 instruction_count(3); 4971 dst : S5(write); 4972 src : S3(read); 4973 D0 : S0; // big decoder only for the load 4974 DECODE : S1(2); // any decoder for FPU POP 4975 FPU : S4; 4976 MEM : S3; // any mem 4977%} 4978 4979// UnConditional branch 4980pipe_class pipe_jmp(label labl) 4981%{ 4982 single_instruction; 4983 BR : S3; 4984%} 4985 4986// Conditional branch 4987pipe_class pipe_jcc(cmpOp cmp, rFlagsReg cr, label labl) 4988%{ 4989 single_instruction; 4990 cr : S1(read); 4991 BR : S3; 4992%} 4993 4994// Allocation idiom 4995pipe_class pipe_cmpxchg(rRegP dst, rRegP heap_ptr) 4996%{ 4997 instruction_count(1); force_serialization; 4998 fixed_latency(6); 4999 heap_ptr : S3(read); 5000 DECODE : S0(3); 5001 D0 : S2; 5002 MEM : S3; 5003 ALU : S3(2); 5004 dst : S5(write); 5005 BR : S5; 5006%} 5007 5008// Generic big/slow expanded idiom 5009pipe_class pipe_slow() 5010%{ 5011 instruction_count(10); multiple_bundles; force_serialization; 5012 fixed_latency(100); 5013 D0 : S0(2); 5014 MEM : S3(2); 5015%} 5016 5017// The real do-nothing guy 5018pipe_class empty() 5019%{ 5020 instruction_count(0); 5021%} 5022 5023// Define the class for the Nop node 5024define 5025%{ 5026 MachNop = empty; 5027%} 5028 5029%} 5030 5031//----------INSTRUCTIONS------------------------------------------------------- 5032// 5033// match -- States which machine-independent subtree may be replaced 5034// by this instruction. 5035// ins_cost -- The estimated cost of this instruction is used by instruction 5036// selection to identify a minimum cost tree of machine 5037// instructions that matches a tree of machine-independent 5038// instructions. 5039// format -- A string providing the disassembly for this instruction. 5040// The value of an instruction's operand may be inserted 5041// by referring to it with a '$' prefix. 5042// opcode -- Three instruction opcodes may be provided. These are referred 5043// to within an encode class as $primary, $secondary, and $tertiary 5044// rrspectively. The primary opcode is commonly used to 5045// indicate the type of machine instruction, while secondary 5046// and tertiary are often used for prefix options or addressing 5047// modes. 5048// ins_encode -- A list of encode classes with parameters. The encode class 5049// name must have been defined in an 'enc_class' specification 5050// in the encode section of the architecture description. 5051 5052 5053//----------Load/Store/Move Instructions--------------------------------------- 5054//----------Load Instructions-------------------------------------------------- 5055 5056// Load Byte (8 bit signed) 5057instruct loadB(rRegI dst, memory mem) 5058%{ 5059 match(Set dst (LoadB mem)); 5060 5061 ins_cost(125); 5062 format %{ "movsbl $dst, $mem\t# byte" %} 5063 5064 ins_encode %{ 5065 __ movsbl($dst$$Register, $mem$$Address); 5066 %} 5067 5068 ins_pipe(ialu_reg_mem); 5069%} 5070 5071// Load Byte (8 bit signed) into Long Register 5072instruct loadB2L(rRegL dst, memory mem) 5073%{ 5074 match(Set dst (ConvI2L (LoadB mem))); 5075 5076 ins_cost(125); 5077 format %{ "movsbq $dst, $mem\t# byte -> long" %} 5078 5079 ins_encode %{ 5080 __ movsbq($dst$$Register, $mem$$Address); 5081 %} 5082 5083 ins_pipe(ialu_reg_mem); 5084%} 5085 5086// Load Unsigned Byte (8 bit UNsigned) 5087instruct loadUB(rRegI dst, memory mem) 5088%{ 5089 match(Set dst (LoadUB mem)); 5090 5091 ins_cost(125); 5092 format %{ "movzbl $dst, $mem\t# ubyte" %} 5093 5094 ins_encode %{ 5095 __ movzbl($dst$$Register, $mem$$Address); 5096 %} 5097 5098 ins_pipe(ialu_reg_mem); 5099%} 5100 5101// Load Unsigned Byte (8 bit UNsigned) into Long Register 5102instruct loadUB2L(rRegL dst, memory mem) 5103%{ 5104 match(Set dst (ConvI2L (LoadUB mem))); 5105 5106 ins_cost(125); 5107 format %{ "movzbq $dst, $mem\t# ubyte -> long" %} 5108 5109 ins_encode %{ 5110 __ movzbq($dst$$Register, $mem$$Address); 5111 %} 5112 5113 ins_pipe(ialu_reg_mem); 5114%} 5115 5116// Load Unsigned Byte (8 bit UNsigned) with 32-bit mask into Long Register 5117instruct loadUB2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 5118 match(Set dst (ConvI2L (AndI (LoadUB mem) mask))); 5119 effect(KILL cr); 5120 5121 format %{ "movzbq $dst, $mem\t# ubyte & 32-bit mask -> long\n\t" 5122 "andl $dst, right_n_bits($mask, 8)" %} 5123 ins_encode %{ 5124 Register Rdst = $dst$$Register; 5125 __ movzbq(Rdst, $mem$$Address); 5126 __ andl(Rdst, $mask$$constant & right_n_bits(8)); 5127 %} 5128 ins_pipe(ialu_reg_mem); 5129%} 5130 5131// Load Short (16 bit signed) 5132instruct loadS(rRegI dst, memory mem) 5133%{ 5134 match(Set dst (LoadS mem)); 5135 5136 ins_cost(125); 5137 format %{ "movswl $dst, $mem\t# short" %} 5138 5139 ins_encode %{ 5140 __ movswl($dst$$Register, $mem$$Address); 5141 %} 5142 5143 ins_pipe(ialu_reg_mem); 5144%} 5145 5146// Load Short (16 bit signed) to Byte (8 bit signed) 5147instruct loadS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 5148 match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour)); 5149 5150 ins_cost(125); 5151 format %{ "movsbl $dst, $mem\t# short -> byte" %} 5152 ins_encode %{ 5153 __ movsbl($dst$$Register, $mem$$Address); 5154 %} 5155 ins_pipe(ialu_reg_mem); 5156%} 5157 5158// Load Short (16 bit signed) into Long Register 5159instruct loadS2L(rRegL dst, memory mem) 5160%{ 5161 match(Set dst (ConvI2L (LoadS mem))); 5162 5163 ins_cost(125); 5164 format %{ "movswq $dst, $mem\t# short -> long" %} 5165 5166 ins_encode %{ 5167 __ movswq($dst$$Register, $mem$$Address); 5168 %} 5169 5170 ins_pipe(ialu_reg_mem); 5171%} 5172 5173// Load Unsigned Short/Char (16 bit UNsigned) 5174instruct loadUS(rRegI dst, memory mem) 5175%{ 5176 match(Set dst (LoadUS mem)); 5177 5178 ins_cost(125); 5179 format %{ "movzwl $dst, $mem\t# ushort/char" %} 5180 5181 ins_encode %{ 5182 __ movzwl($dst$$Register, $mem$$Address); 5183 %} 5184 5185 ins_pipe(ialu_reg_mem); 5186%} 5187 5188// Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed) 5189instruct loadUS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 5190 match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour)); 5191 5192 ins_cost(125); 5193 format %{ "movsbl $dst, $mem\t# ushort -> byte" %} 5194 ins_encode %{ 5195 __ movsbl($dst$$Register, $mem$$Address); 5196 %} 5197 ins_pipe(ialu_reg_mem); 5198%} 5199 5200// Load Unsigned Short/Char (16 bit UNsigned) into Long Register 5201instruct loadUS2L(rRegL dst, memory mem) 5202%{ 5203 match(Set dst (ConvI2L (LoadUS mem))); 5204 5205 ins_cost(125); 5206 format %{ "movzwq $dst, $mem\t# ushort/char -> long" %} 5207 5208 ins_encode %{ 5209 __ movzwq($dst$$Register, $mem$$Address); 5210 %} 5211 5212 ins_pipe(ialu_reg_mem); 5213%} 5214 5215// Load Unsigned Short/Char (16 bit UNsigned) with mask 0xFF into Long Register 5216instruct loadUS2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 5217 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 5218 5219 format %{ "movzbq $dst, $mem\t# ushort/char & 0xFF -> long" %} 5220 ins_encode %{ 5221 __ movzbq($dst$$Register, $mem$$Address); 5222 %} 5223 ins_pipe(ialu_reg_mem); 5224%} 5225 5226// Load Unsigned Short/Char (16 bit UNsigned) with 32-bit mask into Long Register 5227instruct loadUS2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 5228 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 5229 effect(KILL cr); 5230 5231 format %{ "movzwq $dst, $mem\t# ushort/char & 32-bit mask -> long\n\t" 5232 "andl $dst, right_n_bits($mask, 16)" %} 5233 ins_encode %{ 5234 Register Rdst = $dst$$Register; 5235 __ movzwq(Rdst, $mem$$Address); 5236 __ andl(Rdst, $mask$$constant & right_n_bits(16)); 5237 %} 5238 ins_pipe(ialu_reg_mem); 5239%} 5240 5241// Load Integer 5242instruct loadI(rRegI dst, memory mem) 5243%{ 5244 match(Set dst (LoadI mem)); 5245 5246 ins_cost(125); 5247 format %{ "movl $dst, $mem\t# int" %} 5248 5249 ins_encode %{ 5250 __ movl($dst$$Register, $mem$$Address); 5251 %} 5252 5253 ins_pipe(ialu_reg_mem); 5254%} 5255 5256// Load Integer (32 bit signed) to Byte (8 bit signed) 5257instruct loadI2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 5258 match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour)); 5259 5260 ins_cost(125); 5261 format %{ "movsbl $dst, $mem\t# int -> byte" %} 5262 ins_encode %{ 5263 __ movsbl($dst$$Register, $mem$$Address); 5264 %} 5265 ins_pipe(ialu_reg_mem); 5266%} 5267 5268// Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned) 5269instruct loadI2UB(rRegI dst, memory mem, immI_255 mask) %{ 5270 match(Set dst (AndI (LoadI mem) mask)); 5271 5272 ins_cost(125); 5273 format %{ "movzbl $dst, $mem\t# int -> ubyte" %} 5274 ins_encode %{ 5275 __ movzbl($dst$$Register, $mem$$Address); 5276 %} 5277 ins_pipe(ialu_reg_mem); 5278%} 5279 5280// Load Integer (32 bit signed) to Short (16 bit signed) 5281instruct loadI2S(rRegI dst, memory mem, immI_16 sixteen) %{ 5282 match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen)); 5283 5284 ins_cost(125); 5285 format %{ "movswl $dst, $mem\t# int -> short" %} 5286 ins_encode %{ 5287 __ movswl($dst$$Register, $mem$$Address); 5288 %} 5289 ins_pipe(ialu_reg_mem); 5290%} 5291 5292// Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned) 5293instruct loadI2US(rRegI dst, memory mem, immI_65535 mask) %{ 5294 match(Set dst (AndI (LoadI mem) mask)); 5295 5296 ins_cost(125); 5297 format %{ "movzwl $dst, $mem\t# int -> ushort/char" %} 5298 ins_encode %{ 5299 __ movzwl($dst$$Register, $mem$$Address); 5300 %} 5301 ins_pipe(ialu_reg_mem); 5302%} 5303 5304// Load Integer into Long Register 5305instruct loadI2L(rRegL dst, memory mem) 5306%{ 5307 match(Set dst (ConvI2L (LoadI mem))); 5308 5309 ins_cost(125); 5310 format %{ "movslq $dst, $mem\t# int -> long" %} 5311 5312 ins_encode %{ 5313 __ movslq($dst$$Register, $mem$$Address); 5314 %} 5315 5316 ins_pipe(ialu_reg_mem); 5317%} 5318 5319// Load Integer with mask 0xFF into Long Register 5320instruct loadI2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 5321 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 5322 5323 format %{ "movzbq $dst, $mem\t# int & 0xFF -> long" %} 5324 ins_encode %{ 5325 __ movzbq($dst$$Register, $mem$$Address); 5326 %} 5327 ins_pipe(ialu_reg_mem); 5328%} 5329 5330// Load Integer with mask 0xFFFF into Long Register 5331instruct loadI2L_immI_65535(rRegL dst, memory mem, immI_65535 mask) %{ 5332 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 5333 5334 format %{ "movzwq $dst, $mem\t# int & 0xFFFF -> long" %} 5335 ins_encode %{ 5336 __ movzwq($dst$$Register, $mem$$Address); 5337 %} 5338 ins_pipe(ialu_reg_mem); 5339%} 5340 5341// Load Integer with a 31-bit mask into Long Register 5342instruct loadI2L_immU31(rRegL dst, memory mem, immU31 mask, rFlagsReg cr) %{ 5343 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 5344 effect(KILL cr); 5345 5346 format %{ "movl $dst, $mem\t# int & 31-bit mask -> long\n\t" 5347 "andl $dst, $mask" %} 5348 ins_encode %{ 5349 Register Rdst = $dst$$Register; 5350 __ movl(Rdst, $mem$$Address); 5351 __ andl(Rdst, $mask$$constant); 5352 %} 5353 ins_pipe(ialu_reg_mem); 5354%} 5355 5356// Load Unsigned Integer into Long Register 5357instruct loadUI2L(rRegL dst, memory mem, immL_32bits mask) 5358%{ 5359 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 5360 5361 ins_cost(125); 5362 format %{ "movl $dst, $mem\t# uint -> long" %} 5363 5364 ins_encode %{ 5365 __ movl($dst$$Register, $mem$$Address); 5366 %} 5367 5368 ins_pipe(ialu_reg_mem); 5369%} 5370 5371// Load Long 5372instruct loadL(rRegL dst, memory mem) 5373%{ 5374 match(Set dst (LoadL mem)); 5375 5376 ins_cost(125); 5377 format %{ "movq $dst, $mem\t# long" %} 5378 5379 ins_encode %{ 5380 __ movq($dst$$Register, $mem$$Address); 5381 %} 5382 5383 ins_pipe(ialu_reg_mem); // XXX 5384%} 5385 5386// Load Range 5387instruct loadRange(rRegI dst, memory mem) 5388%{ 5389 match(Set dst (LoadRange mem)); 5390 5391 ins_cost(125); // XXX 5392 format %{ "movl $dst, $mem\t# range" %} 5393 opcode(0x8B); 5394 ins_encode(REX_reg_mem(dst, mem), OpcP, reg_mem(dst, mem)); 5395 ins_pipe(ialu_reg_mem); 5396%} 5397 5398// Load Pointer 5399instruct loadP(rRegP dst, memory mem) 5400%{ 5401 match(Set dst (LoadP mem)); 5402 5403 ins_cost(125); // XXX 5404 format %{ "movq $dst, $mem\t# ptr" %} 5405 opcode(0x8B); 5406 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5407 ins_pipe(ialu_reg_mem); // XXX 5408%} 5409 5410// Load Compressed Pointer 5411instruct loadN(rRegN dst, memory mem) 5412%{ 5413 match(Set dst (LoadN mem)); 5414 5415 ins_cost(125); // XXX 5416 format %{ "movl $dst, $mem\t# compressed ptr" %} 5417 ins_encode %{ 5418 __ movl($dst$$Register, $mem$$Address); 5419 %} 5420 ins_pipe(ialu_reg_mem); // XXX 5421%} 5422 5423 5424// Load Klass Pointer 5425instruct loadKlass(rRegP dst, memory mem) 5426%{ 5427 match(Set dst (LoadKlass mem)); 5428 5429 ins_cost(125); // XXX 5430 format %{ "movq $dst, $mem\t# class" %} 5431 opcode(0x8B); 5432 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5433 ins_pipe(ialu_reg_mem); // XXX 5434%} 5435 5436// Load narrow Klass Pointer 5437instruct loadNKlass(rRegN dst, memory mem) 5438%{ 5439 match(Set dst (LoadNKlass mem)); 5440 5441 ins_cost(125); // XXX 5442 format %{ "movl $dst, $mem\t# compressed klass ptr" %} 5443 ins_encode %{ 5444 __ movl($dst$$Register, $mem$$Address); 5445 %} 5446 ins_pipe(ialu_reg_mem); // XXX 5447%} 5448 5449// Load Float 5450instruct loadF(regF dst, memory mem) 5451%{ 5452 match(Set dst (LoadF mem)); 5453 5454 ins_cost(145); // XXX 5455 format %{ "movss $dst, $mem\t# float" %} 5456 ins_encode %{ 5457 __ movflt($dst$$XMMRegister, $mem$$Address); 5458 %} 5459 ins_pipe(pipe_slow); // XXX 5460%} 5461 5462// Load Float 5463instruct MoveF2VL(vlRegF dst, regF src) %{ 5464 match(Set dst src); 5465 format %{ "movss $dst,$src\t! load float (4 bytes)" %} 5466 ins_encode %{ 5467 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 5468 %} 5469 ins_pipe( fpu_reg_reg ); 5470%} 5471 5472// Load Float 5473instruct MoveF2LEG(legRegF dst, regF src) %{ 5474 match(Set dst src); 5475 format %{ "movss $dst,$src\t# if src != dst load float (4 bytes)" %} 5476 ins_encode %{ 5477 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 5478 %} 5479 ins_pipe( fpu_reg_reg ); 5480%} 5481 5482// Load Float 5483instruct MoveVL2F(regF dst, vlRegF src) %{ 5484 match(Set dst src); 5485 format %{ "movss $dst,$src\t! load float (4 bytes)" %} 5486 ins_encode %{ 5487 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 5488 %} 5489 ins_pipe( fpu_reg_reg ); 5490%} 5491 5492// Load Float 5493instruct MoveLEG2F(regF dst, legRegF src) %{ 5494 match(Set dst src); 5495 format %{ "movss $dst,$src\t# if src != dst load float (4 bytes)" %} 5496 ins_encode %{ 5497 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 5498 %} 5499 ins_pipe( fpu_reg_reg ); 5500%} 5501 5502// Load Double 5503instruct loadD_partial(regD dst, memory mem) 5504%{ 5505 predicate(!UseXmmLoadAndClearUpper); 5506 match(Set dst (LoadD mem)); 5507 5508 ins_cost(145); // XXX 5509 format %{ "movlpd $dst, $mem\t# double" %} 5510 ins_encode %{ 5511 __ movdbl($dst$$XMMRegister, $mem$$Address); 5512 %} 5513 ins_pipe(pipe_slow); // XXX 5514%} 5515 5516instruct loadD(regD dst, memory mem) 5517%{ 5518 predicate(UseXmmLoadAndClearUpper); 5519 match(Set dst (LoadD mem)); 5520 5521 ins_cost(145); // XXX 5522 format %{ "movsd $dst, $mem\t# double" %} 5523 ins_encode %{ 5524 __ movdbl($dst$$XMMRegister, $mem$$Address); 5525 %} 5526 ins_pipe(pipe_slow); // XXX 5527%} 5528 5529// Load Double 5530instruct MoveD2VL(vlRegD dst, regD src) %{ 5531 match(Set dst src); 5532 format %{ "movsd $dst,$src\t! load double (8 bytes)" %} 5533 ins_encode %{ 5534 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 5535 %} 5536 ins_pipe( fpu_reg_reg ); 5537%} 5538 5539// Load Double 5540instruct MoveD2LEG(legRegD dst, regD src) %{ 5541 match(Set dst src); 5542 format %{ "movsd $dst,$src\t# if src != dst load double (8 bytes)" %} 5543 ins_encode %{ 5544 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 5545 %} 5546 ins_pipe( fpu_reg_reg ); 5547%} 5548 5549// Load Double 5550instruct MoveVL2D(regD dst, vlRegD src) %{ 5551 match(Set dst src); 5552 format %{ "movsd $dst,$src\t! load double (8 bytes)" %} 5553 ins_encode %{ 5554 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 5555 %} 5556 ins_pipe( fpu_reg_reg ); 5557%} 5558 5559// Load Double 5560instruct MoveLEG2D(regD dst, legRegD src) %{ 5561 match(Set dst src); 5562 format %{ "movsd $dst,$src\t# if src != dst load double (8 bytes)" %} 5563 ins_encode %{ 5564 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 5565 %} 5566 ins_pipe( fpu_reg_reg ); 5567%} 5568 5569// Following pseudo code describes the algorithm for max[FD]: 5570// Min algorithm is on similar lines 5571// btmp = (b < +0.0) ? a : b 5572// atmp = (b < +0.0) ? b : a 5573// Tmp = Max_Float(atmp , btmp) 5574// Res = (atmp == NaN) ? atmp : Tmp 5575 5576// max = java.lang.Math.max(float a, float b) 5577instruct maxF_reg(legRegF dst, legRegF a, legRegF b, legRegF tmp, legRegF atmp, legRegF btmp) %{ 5578 predicate(UseAVX > 0 && !n->is_reduction()); 5579 match(Set dst (MaxF a b)); 5580 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 5581 format %{ 5582 "blendvps $btmp,$b,$a,$b \n\t" 5583 "blendvps $atmp,$a,$b,$b \n\t" 5584 "vmaxss $tmp,$atmp,$btmp \n\t" 5585 "cmpps.unordered $btmp,$atmp,$atmp \n\t" 5586 "blendvps $dst,$tmp,$atmp,$btmp \n\t" 5587 %} 5588 ins_encode %{ 5589 int vector_len = Assembler::AVX_128bit; 5590 __ blendvps($btmp$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, vector_len); 5591 __ blendvps($atmp$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $b$$XMMRegister, vector_len); 5592 __ vmaxss($tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister); 5593 __ cmpps($btmp$$XMMRegister, $atmp$$XMMRegister, $atmp$$XMMRegister, Assembler::_false, vector_len); 5594 __ blendvps($dst$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, vector_len); 5595 %} 5596 ins_pipe( pipe_slow ); 5597%} 5598 5599instruct maxF_reduction_reg(legRegF dst, legRegF a, legRegF b, legRegF xmmt, rRegI tmp, rFlagsReg cr) %{ 5600 predicate(UseAVX > 0 && n->is_reduction()); 5601 match(Set dst (MaxF a b)); 5602 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr); 5603 5604 format %{ "$dst = max($a, $b)\t# intrinsic (float)" %} 5605 ins_encode %{ 5606 emit_fp_min_max(_masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register, 5607 false /*min*/, true /*single*/); 5608 %} 5609 ins_pipe( pipe_slow ); 5610%} 5611 5612// max = java.lang.Math.max(double a, double b) 5613instruct maxD_reg(legRegD dst, legRegD a, legRegD b, legRegD tmp, legRegD atmp, legRegD btmp) %{ 5614 predicate(UseAVX > 0 && !n->is_reduction()); 5615 match(Set dst (MaxD a b)); 5616 effect(USE a, USE b, TEMP atmp, TEMP btmp, TEMP tmp); 5617 format %{ 5618 "blendvpd $btmp,$b,$a,$b \n\t" 5619 "blendvpd $atmp,$a,$b,$b \n\t" 5620 "vmaxsd $tmp,$atmp,$btmp \n\t" 5621 "cmppd.unordered $btmp,$atmp,$atmp \n\t" 5622 "blendvpd $dst,$tmp,$atmp,$btmp \n\t" 5623 %} 5624 ins_encode %{ 5625 int vector_len = Assembler::AVX_128bit; 5626 __ blendvpd($btmp$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, vector_len); 5627 __ blendvpd($atmp$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $b$$XMMRegister, vector_len); 5628 __ vmaxsd($tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister); 5629 __ cmppd($btmp$$XMMRegister, $atmp$$XMMRegister, $atmp$$XMMRegister, Assembler::_false, vector_len); 5630 __ blendvpd($dst$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, vector_len); 5631 %} 5632 ins_pipe( pipe_slow ); 5633%} 5634 5635instruct maxD_reduction_reg(legRegD dst, legRegD a, legRegD b, legRegD xmmt, rRegL tmp, rFlagsReg cr) %{ 5636 predicate(UseAVX > 0 && n->is_reduction()); 5637 match(Set dst (MaxD a b)); 5638 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr); 5639 5640 format %{ "$dst = max($a, $b)\t# intrinsic (double)" %} 5641 ins_encode %{ 5642 emit_fp_min_max(_masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register, 5643 false /*min*/, false /*single*/); 5644 %} 5645 ins_pipe( pipe_slow ); 5646%} 5647 5648// min = java.lang.Math.min(float a, float b) 5649instruct minF_reg(legRegF dst, legRegF a, legRegF b, legRegF tmp, legRegF atmp, legRegF btmp) %{ 5650 predicate(UseAVX > 0 && !n->is_reduction()); 5651 match(Set dst (MinF a b)); 5652 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 5653 format %{ 5654 "blendvps $atmp,$a,$b,$a \n\t" 5655 "blendvps $btmp,$b,$a,$a \n\t" 5656 "vminss $tmp,$atmp,$btmp \n\t" 5657 "cmpps.unordered $btmp,$atmp,$atmp \n\t" 5658 "blendvps $dst,$tmp,$atmp,$btmp \n\t" 5659 %} 5660 ins_encode %{ 5661 int vector_len = Assembler::AVX_128bit; 5662 __ blendvps($atmp$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, vector_len); 5663 __ blendvps($btmp$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, $a$$XMMRegister, vector_len); 5664 __ vminss($tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister); 5665 __ cmpps($btmp$$XMMRegister, $atmp$$XMMRegister, $atmp$$XMMRegister, Assembler::_false, vector_len); 5666 __ blendvps($dst$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, vector_len); 5667 %} 5668 ins_pipe( pipe_slow ); 5669%} 5670 5671instruct minF_reduction_reg(legRegF dst, legRegF a, legRegF b, legRegF xmmt, rRegI tmp, rFlagsReg cr) %{ 5672 predicate(UseAVX > 0 && n->is_reduction()); 5673 match(Set dst (MinF a b)); 5674 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr); 5675 5676 format %{ "$dst = min($a, $b)\t# intrinsic (float)" %} 5677 ins_encode %{ 5678 emit_fp_min_max(_masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register, 5679 true /*min*/, true /*single*/); 5680 %} 5681 ins_pipe( pipe_slow ); 5682%} 5683 5684// min = java.lang.Math.min(double a, double b) 5685instruct minD_reg(legRegD dst, legRegD a, legRegD b, legRegD tmp, legRegD atmp, legRegD btmp) %{ 5686 predicate(UseAVX > 0 && !n->is_reduction()); 5687 match(Set dst (MinD a b)); 5688 effect(USE a, USE b, TEMP tmp, TEMP atmp, TEMP btmp); 5689 format %{ 5690 "blendvpd $atmp,$a,$b,$a \n\t" 5691 "blendvpd $btmp,$b,$a,$a \n\t" 5692 "vminsd $tmp,$atmp,$btmp \n\t" 5693 "cmppd.unordered $btmp,$atmp,$atmp \n\t" 5694 "blendvpd $dst,$tmp,$atmp,$btmp \n\t" 5695 %} 5696 ins_encode %{ 5697 int vector_len = Assembler::AVX_128bit; 5698 __ blendvpd($atmp$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, vector_len); 5699 __ blendvpd($btmp$$XMMRegister, $b$$XMMRegister, $a$$XMMRegister, $a$$XMMRegister, vector_len); 5700 __ vminsd($tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister); 5701 __ cmppd($btmp$$XMMRegister, $atmp$$XMMRegister, $atmp$$XMMRegister, Assembler::_false, vector_len); 5702 __ blendvpd($dst$$XMMRegister, $tmp$$XMMRegister, $atmp$$XMMRegister, $btmp$$XMMRegister, vector_len); 5703 %} 5704 ins_pipe( pipe_slow ); 5705%} 5706 5707instruct minD_reduction_reg(legRegD dst, legRegD a, legRegD b, legRegD xmmt, rRegL tmp, rFlagsReg cr) %{ 5708 predicate(UseAVX > 0 && n->is_reduction()); 5709 match(Set dst (MinD a b)); 5710 effect(USE a, USE b, TEMP xmmt, TEMP tmp, KILL cr); 5711 5712 format %{ "$dst = min($a, $b)\t# intrinsic (double)" %} 5713 ins_encode %{ 5714 emit_fp_min_max(_masm, $dst$$XMMRegister, $a$$XMMRegister, $b$$XMMRegister, $xmmt$$XMMRegister, $tmp$$Register, 5715 true /*min*/, false /*single*/); 5716 %} 5717 ins_pipe( pipe_slow ); 5718%} 5719 5720// Load Effective Address 5721instruct leaP8(rRegP dst, indOffset8 mem) 5722%{ 5723 match(Set dst mem); 5724 5725 ins_cost(110); // XXX 5726 format %{ "leaq $dst, $mem\t# ptr 8" %} 5727 opcode(0x8D); 5728 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5729 ins_pipe(ialu_reg_reg_fat); 5730%} 5731 5732instruct leaP32(rRegP dst, indOffset32 mem) 5733%{ 5734 match(Set dst mem); 5735 5736 ins_cost(110); 5737 format %{ "leaq $dst, $mem\t# ptr 32" %} 5738 opcode(0x8D); 5739 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5740 ins_pipe(ialu_reg_reg_fat); 5741%} 5742 5743// instruct leaPIdx(rRegP dst, indIndex mem) 5744// %{ 5745// match(Set dst mem); 5746 5747// ins_cost(110); 5748// format %{ "leaq $dst, $mem\t# ptr idx" %} 5749// opcode(0x8D); 5750// ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5751// ins_pipe(ialu_reg_reg_fat); 5752// %} 5753 5754instruct leaPIdxOff(rRegP dst, indIndexOffset mem) 5755%{ 5756 match(Set dst mem); 5757 5758 ins_cost(110); 5759 format %{ "leaq $dst, $mem\t# ptr idxoff" %} 5760 opcode(0x8D); 5761 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5762 ins_pipe(ialu_reg_reg_fat); 5763%} 5764 5765instruct leaPIdxScale(rRegP dst, indIndexScale mem) 5766%{ 5767 match(Set dst mem); 5768 5769 ins_cost(110); 5770 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 5771 opcode(0x8D); 5772 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5773 ins_pipe(ialu_reg_reg_fat); 5774%} 5775 5776instruct leaPPosIdxScale(rRegP dst, indPosIndexScale mem) 5777%{ 5778 match(Set dst mem); 5779 5780 ins_cost(110); 5781 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 5782 opcode(0x8D); 5783 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5784 ins_pipe(ialu_reg_reg_fat); 5785%} 5786 5787instruct leaPIdxScaleOff(rRegP dst, indIndexScaleOffset mem) 5788%{ 5789 match(Set dst mem); 5790 5791 ins_cost(110); 5792 format %{ "leaq $dst, $mem\t# ptr idxscaleoff" %} 5793 opcode(0x8D); 5794 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5795 ins_pipe(ialu_reg_reg_fat); 5796%} 5797 5798instruct leaPPosIdxOff(rRegP dst, indPosIndexOffset mem) 5799%{ 5800 match(Set dst mem); 5801 5802 ins_cost(110); 5803 format %{ "leaq $dst, $mem\t# ptr posidxoff" %} 5804 opcode(0x8D); 5805 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5806 ins_pipe(ialu_reg_reg_fat); 5807%} 5808 5809instruct leaPPosIdxScaleOff(rRegP dst, indPosIndexScaleOffset mem) 5810%{ 5811 match(Set dst mem); 5812 5813 ins_cost(110); 5814 format %{ "leaq $dst, $mem\t# ptr posidxscaleoff" %} 5815 opcode(0x8D); 5816 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5817 ins_pipe(ialu_reg_reg_fat); 5818%} 5819 5820// Load Effective Address which uses Narrow (32-bits) oop 5821instruct leaPCompressedOopOffset(rRegP dst, indCompressedOopOffset mem) 5822%{ 5823 predicate(UseCompressedOops && (Universe::narrow_oop_shift() != 0)); 5824 match(Set dst mem); 5825 5826 ins_cost(110); 5827 format %{ "leaq $dst, $mem\t# ptr compressedoopoff32" %} 5828 opcode(0x8D); 5829 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5830 ins_pipe(ialu_reg_reg_fat); 5831%} 5832 5833instruct leaP8Narrow(rRegP dst, indOffset8Narrow mem) 5834%{ 5835 predicate(Universe::narrow_oop_shift() == 0); 5836 match(Set dst mem); 5837 5838 ins_cost(110); // XXX 5839 format %{ "leaq $dst, $mem\t# ptr off8narrow" %} 5840 opcode(0x8D); 5841 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5842 ins_pipe(ialu_reg_reg_fat); 5843%} 5844 5845instruct leaP32Narrow(rRegP dst, indOffset32Narrow mem) 5846%{ 5847 predicate(Universe::narrow_oop_shift() == 0); 5848 match(Set dst mem); 5849 5850 ins_cost(110); 5851 format %{ "leaq $dst, $mem\t# ptr off32narrow" %} 5852 opcode(0x8D); 5853 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5854 ins_pipe(ialu_reg_reg_fat); 5855%} 5856 5857instruct leaPIdxOffNarrow(rRegP dst, indIndexOffsetNarrow mem) 5858%{ 5859 predicate(Universe::narrow_oop_shift() == 0); 5860 match(Set dst mem); 5861 5862 ins_cost(110); 5863 format %{ "leaq $dst, $mem\t# ptr idxoffnarrow" %} 5864 opcode(0x8D); 5865 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5866 ins_pipe(ialu_reg_reg_fat); 5867%} 5868 5869instruct leaPIdxScaleNarrow(rRegP dst, indIndexScaleNarrow mem) 5870%{ 5871 predicate(Universe::narrow_oop_shift() == 0); 5872 match(Set dst mem); 5873 5874 ins_cost(110); 5875 format %{ "leaq $dst, $mem\t# ptr idxscalenarrow" %} 5876 opcode(0x8D); 5877 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5878 ins_pipe(ialu_reg_reg_fat); 5879%} 5880 5881instruct leaPIdxScaleOffNarrow(rRegP dst, indIndexScaleOffsetNarrow mem) 5882%{ 5883 predicate(Universe::narrow_oop_shift() == 0); 5884 match(Set dst mem); 5885 5886 ins_cost(110); 5887 format %{ "leaq $dst, $mem\t# ptr idxscaleoffnarrow" %} 5888 opcode(0x8D); 5889 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5890 ins_pipe(ialu_reg_reg_fat); 5891%} 5892 5893instruct leaPPosIdxOffNarrow(rRegP dst, indPosIndexOffsetNarrow mem) 5894%{ 5895 predicate(Universe::narrow_oop_shift() == 0); 5896 match(Set dst mem); 5897 5898 ins_cost(110); 5899 format %{ "leaq $dst, $mem\t# ptr posidxoffnarrow" %} 5900 opcode(0x8D); 5901 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5902 ins_pipe(ialu_reg_reg_fat); 5903%} 5904 5905instruct leaPPosIdxScaleOffNarrow(rRegP dst, indPosIndexScaleOffsetNarrow mem) 5906%{ 5907 predicate(Universe::narrow_oop_shift() == 0); 5908 match(Set dst mem); 5909 5910 ins_cost(110); 5911 format %{ "leaq $dst, $mem\t# ptr posidxscaleoffnarrow" %} 5912 opcode(0x8D); 5913 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5914 ins_pipe(ialu_reg_reg_fat); 5915%} 5916 5917instruct loadConI(rRegI dst, immI src) 5918%{ 5919 match(Set dst src); 5920 5921 format %{ "movl $dst, $src\t# int" %} 5922 ins_encode(load_immI(dst, src)); 5923 ins_pipe(ialu_reg_fat); // XXX 5924%} 5925 5926instruct loadConI0(rRegI dst, immI0 src, rFlagsReg cr) 5927%{ 5928 match(Set dst src); 5929 effect(KILL cr); 5930 5931 ins_cost(50); 5932 format %{ "xorl $dst, $dst\t# int" %} 5933 opcode(0x33); /* + rd */ 5934 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5935 ins_pipe(ialu_reg); 5936%} 5937 5938instruct loadConL(rRegL dst, immL src) 5939%{ 5940 match(Set dst src); 5941 5942 ins_cost(150); 5943 format %{ "movq $dst, $src\t# long" %} 5944 ins_encode(load_immL(dst, src)); 5945 ins_pipe(ialu_reg); 5946%} 5947 5948instruct loadConL0(rRegL dst, immL0 src, rFlagsReg cr) 5949%{ 5950 match(Set dst src); 5951 effect(KILL cr); 5952 5953 ins_cost(50); 5954 format %{ "xorl $dst, $dst\t# long" %} 5955 opcode(0x33); /* + rd */ 5956 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5957 ins_pipe(ialu_reg); // XXX 5958%} 5959 5960instruct loadConUL32(rRegL dst, immUL32 src) 5961%{ 5962 match(Set dst src); 5963 5964 ins_cost(60); 5965 format %{ "movl $dst, $src\t# long (unsigned 32-bit)" %} 5966 ins_encode(load_immUL32(dst, src)); 5967 ins_pipe(ialu_reg); 5968%} 5969 5970instruct loadConL32(rRegL dst, immL32 src) 5971%{ 5972 match(Set dst src); 5973 5974 ins_cost(70); 5975 format %{ "movq $dst, $src\t# long (32-bit)" %} 5976 ins_encode(load_immL32(dst, src)); 5977 ins_pipe(ialu_reg); 5978%} 5979 5980instruct loadConP(rRegP dst, immP con) %{ 5981 match(Set dst con); 5982 5983 format %{ "movq $dst, $con\t# ptr" %} 5984 ins_encode(load_immP(dst, con)); 5985 ins_pipe(ialu_reg_fat); // XXX 5986%} 5987 5988instruct loadConP0(rRegP dst, immP0 src, rFlagsReg cr) 5989%{ 5990 match(Set dst src); 5991 effect(KILL cr); 5992 5993 ins_cost(50); 5994 format %{ "xorl $dst, $dst\t# ptr" %} 5995 opcode(0x33); /* + rd */ 5996 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5997 ins_pipe(ialu_reg); 5998%} 5999 6000instruct loadConP31(rRegP dst, immP31 src, rFlagsReg cr) 6001%{ 6002 match(Set dst src); 6003 effect(KILL cr); 6004 6005 ins_cost(60); 6006 format %{ "movl $dst, $src\t# ptr (positive 32-bit)" %} 6007 ins_encode(load_immP31(dst, src)); 6008 ins_pipe(ialu_reg); 6009%} 6010 6011instruct loadConF(regF dst, immF con) %{ 6012 match(Set dst con); 6013 ins_cost(125); 6014 format %{ "movss $dst, [$constantaddress]\t# load from constant table: float=$con" %} 6015 ins_encode %{ 6016 __ movflt($dst$$XMMRegister, $constantaddress($con)); 6017 %} 6018 ins_pipe(pipe_slow); 6019%} 6020 6021instruct loadConN0(rRegN dst, immN0 src, rFlagsReg cr) %{ 6022 match(Set dst src); 6023 effect(KILL cr); 6024 format %{ "xorq $dst, $src\t# compressed NULL ptr" %} 6025 ins_encode %{ 6026 __ xorq($dst$$Register, $dst$$Register); 6027 %} 6028 ins_pipe(ialu_reg); 6029%} 6030 6031instruct loadConN(rRegN dst, immN src) %{ 6032 match(Set dst src); 6033 6034 ins_cost(125); 6035 format %{ "movl $dst, $src\t# compressed ptr" %} 6036 ins_encode %{ 6037 address con = (address)$src$$constant; 6038 if (con == NULL) { 6039 ShouldNotReachHere(); 6040 } else { 6041 __ set_narrow_oop($dst$$Register, (jobject)$src$$constant); 6042 } 6043 %} 6044 ins_pipe(ialu_reg_fat); // XXX 6045%} 6046 6047instruct loadConNKlass(rRegN dst, immNKlass src) %{ 6048 match(Set dst src); 6049 6050 ins_cost(125); 6051 format %{ "movl $dst, $src\t# compressed klass ptr" %} 6052 ins_encode %{ 6053 address con = (address)$src$$constant; 6054 if (con == NULL) { 6055 ShouldNotReachHere(); 6056 } else { 6057 __ set_narrow_klass($dst$$Register, (Klass*)$src$$constant); 6058 } 6059 %} 6060 ins_pipe(ialu_reg_fat); // XXX 6061%} 6062 6063instruct loadConF0(regF dst, immF0 src) 6064%{ 6065 match(Set dst src); 6066 ins_cost(100); 6067 6068 format %{ "xorps $dst, $dst\t# float 0.0" %} 6069 ins_encode %{ 6070 __ xorps($dst$$XMMRegister, $dst$$XMMRegister); 6071 %} 6072 ins_pipe(pipe_slow); 6073%} 6074 6075// Use the same format since predicate() can not be used here. 6076instruct loadConD(regD dst, immD con) %{ 6077 match(Set dst con); 6078 ins_cost(125); 6079 format %{ "movsd $dst, [$constantaddress]\t# load from constant table: double=$con" %} 6080 ins_encode %{ 6081 __ movdbl($dst$$XMMRegister, $constantaddress($con)); 6082 %} 6083 ins_pipe(pipe_slow); 6084%} 6085 6086instruct loadConD0(regD dst, immD0 src) 6087%{ 6088 match(Set dst src); 6089 ins_cost(100); 6090 6091 format %{ "xorpd $dst, $dst\t# double 0.0" %} 6092 ins_encode %{ 6093 __ xorpd ($dst$$XMMRegister, $dst$$XMMRegister); 6094 %} 6095 ins_pipe(pipe_slow); 6096%} 6097 6098instruct loadSSI(rRegI dst, stackSlotI src) 6099%{ 6100 match(Set dst src); 6101 6102 ins_cost(125); 6103 format %{ "movl $dst, $src\t# int stk" %} 6104 opcode(0x8B); 6105 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 6106 ins_pipe(ialu_reg_mem); 6107%} 6108 6109instruct loadSSL(rRegL dst, stackSlotL src) 6110%{ 6111 match(Set dst src); 6112 6113 ins_cost(125); 6114 format %{ "movq $dst, $src\t# long stk" %} 6115 opcode(0x8B); 6116 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 6117 ins_pipe(ialu_reg_mem); 6118%} 6119 6120instruct loadSSP(rRegP dst, stackSlotP src) 6121%{ 6122 match(Set dst src); 6123 6124 ins_cost(125); 6125 format %{ "movq $dst, $src\t# ptr stk" %} 6126 opcode(0x8B); 6127 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 6128 ins_pipe(ialu_reg_mem); 6129%} 6130 6131instruct loadSSF(regF dst, stackSlotF src) 6132%{ 6133 match(Set dst src); 6134 6135 ins_cost(125); 6136 format %{ "movss $dst, $src\t# float stk" %} 6137 ins_encode %{ 6138 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 6139 %} 6140 ins_pipe(pipe_slow); // XXX 6141%} 6142 6143// Use the same format since predicate() can not be used here. 6144instruct loadSSD(regD dst, stackSlotD src) 6145%{ 6146 match(Set dst src); 6147 6148 ins_cost(125); 6149 format %{ "movsd $dst, $src\t# double stk" %} 6150 ins_encode %{ 6151 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 6152 %} 6153 ins_pipe(pipe_slow); // XXX 6154%} 6155 6156// Prefetch instructions for allocation. 6157// Must be safe to execute with invalid address (cannot fault). 6158 6159instruct prefetchAlloc( memory mem ) %{ 6160 predicate(AllocatePrefetchInstr==3); 6161 match(PrefetchAllocation mem); 6162 ins_cost(125); 6163 6164 format %{ "PREFETCHW $mem\t# Prefetch allocation into level 1 cache and mark modified" %} 6165 ins_encode %{ 6166 __ prefetchw($mem$$Address); 6167 %} 6168 ins_pipe(ialu_mem); 6169%} 6170 6171instruct prefetchAllocNTA( memory mem ) %{ 6172 predicate(AllocatePrefetchInstr==0); 6173 match(PrefetchAllocation mem); 6174 ins_cost(125); 6175 6176 format %{ "PREFETCHNTA $mem\t# Prefetch allocation to non-temporal cache for write" %} 6177 ins_encode %{ 6178 __ prefetchnta($mem$$Address); 6179 %} 6180 ins_pipe(ialu_mem); 6181%} 6182 6183instruct prefetchAllocT0( memory mem ) %{ 6184 predicate(AllocatePrefetchInstr==1); 6185 match(PrefetchAllocation mem); 6186 ins_cost(125); 6187 6188 format %{ "PREFETCHT0 $mem\t# Prefetch allocation to level 1 and 2 caches for write" %} 6189 ins_encode %{ 6190 __ prefetcht0($mem$$Address); 6191 %} 6192 ins_pipe(ialu_mem); 6193%} 6194 6195instruct prefetchAllocT2( memory mem ) %{ 6196 predicate(AllocatePrefetchInstr==2); 6197 match(PrefetchAllocation mem); 6198 ins_cost(125); 6199 6200 format %{ "PREFETCHT2 $mem\t# Prefetch allocation to level 2 cache for write" %} 6201 ins_encode %{ 6202 __ prefetcht2($mem$$Address); 6203 %} 6204 ins_pipe(ialu_mem); 6205%} 6206 6207//----------Store Instructions------------------------------------------------- 6208 6209// Store Byte 6210instruct storeB(memory mem, rRegI src) 6211%{ 6212 match(Set mem (StoreB mem src)); 6213 6214 ins_cost(125); // XXX 6215 format %{ "movb $mem, $src\t# byte" %} 6216 opcode(0x88); 6217 ins_encode(REX_breg_mem(src, mem), OpcP, reg_mem(src, mem)); 6218 ins_pipe(ialu_mem_reg); 6219%} 6220 6221// Store Char/Short 6222instruct storeC(memory mem, rRegI src) 6223%{ 6224 match(Set mem (StoreC mem src)); 6225 6226 ins_cost(125); // XXX 6227 format %{ "movw $mem, $src\t# char/short" %} 6228 opcode(0x89); 6229 ins_encode(SizePrefix, REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 6230 ins_pipe(ialu_mem_reg); 6231%} 6232 6233// Store Integer 6234instruct storeI(memory mem, rRegI src) 6235%{ 6236 match(Set mem (StoreI mem src)); 6237 6238 ins_cost(125); // XXX 6239 format %{ "movl $mem, $src\t# int" %} 6240 opcode(0x89); 6241 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 6242 ins_pipe(ialu_mem_reg); 6243%} 6244 6245// Store Long 6246instruct storeL(memory mem, rRegL src) 6247%{ 6248 match(Set mem (StoreL mem src)); 6249 6250 ins_cost(125); // XXX 6251 format %{ "movq $mem, $src\t# long" %} 6252 opcode(0x89); 6253 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 6254 ins_pipe(ialu_mem_reg); // XXX 6255%} 6256 6257// Store Pointer 6258instruct storeP(memory mem, any_RegP src) 6259%{ 6260 match(Set mem (StoreP mem src)); 6261 6262 ins_cost(125); // XXX 6263 format %{ "movq $mem, $src\t# ptr" %} 6264 opcode(0x89); 6265 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 6266 ins_pipe(ialu_mem_reg); 6267%} 6268 6269instruct storeImmP0(memory mem, immP0 zero) 6270%{ 6271 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6272 match(Set mem (StoreP mem zero)); 6273 6274 ins_cost(125); // XXX 6275 format %{ "movq $mem, R12\t# ptr (R12_heapbase==0)" %} 6276 ins_encode %{ 6277 __ movq($mem$$Address, r12); 6278 %} 6279 ins_pipe(ialu_mem_reg); 6280%} 6281 6282// Store NULL Pointer, mark word, or other simple pointer constant. 6283instruct storeImmP(memory mem, immP31 src) 6284%{ 6285 match(Set mem (StoreP mem src)); 6286 6287 ins_cost(150); // XXX 6288 format %{ "movq $mem, $src\t# ptr" %} 6289 opcode(0xC7); /* C7 /0 */ 6290 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 6291 ins_pipe(ialu_mem_imm); 6292%} 6293 6294// Store Compressed Pointer 6295instruct storeN(memory mem, rRegN src) 6296%{ 6297 match(Set mem (StoreN mem src)); 6298 6299 ins_cost(125); // XXX 6300 format %{ "movl $mem, $src\t# compressed ptr" %} 6301 ins_encode %{ 6302 __ movl($mem$$Address, $src$$Register); 6303 %} 6304 ins_pipe(ialu_mem_reg); 6305%} 6306 6307instruct storeNKlass(memory mem, rRegN src) 6308%{ 6309 match(Set mem (StoreNKlass mem src)); 6310 6311 ins_cost(125); // XXX 6312 format %{ "movl $mem, $src\t# compressed klass ptr" %} 6313 ins_encode %{ 6314 __ movl($mem$$Address, $src$$Register); 6315 %} 6316 ins_pipe(ialu_mem_reg); 6317%} 6318 6319instruct storeImmN0(memory mem, immN0 zero) 6320%{ 6321 predicate(Universe::narrow_oop_base() == NULL && Universe::narrow_klass_base() == NULL); 6322 match(Set mem (StoreN mem zero)); 6323 6324 ins_cost(125); // XXX 6325 format %{ "movl $mem, R12\t# compressed ptr (R12_heapbase==0)" %} 6326 ins_encode %{ 6327 __ movl($mem$$Address, r12); 6328 %} 6329 ins_pipe(ialu_mem_reg); 6330%} 6331 6332instruct storeImmN(memory mem, immN src) 6333%{ 6334 match(Set mem (StoreN mem src)); 6335 6336 ins_cost(150); // XXX 6337 format %{ "movl $mem, $src\t# compressed ptr" %} 6338 ins_encode %{ 6339 address con = (address)$src$$constant; 6340 if (con == NULL) { 6341 __ movl($mem$$Address, (int32_t)0); 6342 } else { 6343 __ set_narrow_oop($mem$$Address, (jobject)$src$$constant); 6344 } 6345 %} 6346 ins_pipe(ialu_mem_imm); 6347%} 6348 6349instruct storeImmNKlass(memory mem, immNKlass src) 6350%{ 6351 match(Set mem (StoreNKlass mem src)); 6352 6353 ins_cost(150); // XXX 6354 format %{ "movl $mem, $src\t# compressed klass ptr" %} 6355 ins_encode %{ 6356 __ set_narrow_klass($mem$$Address, (Klass*)$src$$constant); 6357 %} 6358 ins_pipe(ialu_mem_imm); 6359%} 6360 6361// Store Integer Immediate 6362instruct storeImmI0(memory mem, immI0 zero) 6363%{ 6364 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6365 match(Set mem (StoreI mem zero)); 6366 6367 ins_cost(125); // XXX 6368 format %{ "movl $mem, R12\t# int (R12_heapbase==0)" %} 6369 ins_encode %{ 6370 __ movl($mem$$Address, r12); 6371 %} 6372 ins_pipe(ialu_mem_reg); 6373%} 6374 6375instruct storeImmI(memory mem, immI src) 6376%{ 6377 match(Set mem (StoreI mem src)); 6378 6379 ins_cost(150); 6380 format %{ "movl $mem, $src\t# int" %} 6381 opcode(0xC7); /* C7 /0 */ 6382 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 6383 ins_pipe(ialu_mem_imm); 6384%} 6385 6386// Store Long Immediate 6387instruct storeImmL0(memory mem, immL0 zero) 6388%{ 6389 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6390 match(Set mem (StoreL mem zero)); 6391 6392 ins_cost(125); // XXX 6393 format %{ "movq $mem, R12\t# long (R12_heapbase==0)" %} 6394 ins_encode %{ 6395 __ movq($mem$$Address, r12); 6396 %} 6397 ins_pipe(ialu_mem_reg); 6398%} 6399 6400instruct storeImmL(memory mem, immL32 src) 6401%{ 6402 match(Set mem (StoreL mem src)); 6403 6404 ins_cost(150); 6405 format %{ "movq $mem, $src\t# long" %} 6406 opcode(0xC7); /* C7 /0 */ 6407 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 6408 ins_pipe(ialu_mem_imm); 6409%} 6410 6411// Store Short/Char Immediate 6412instruct storeImmC0(memory mem, immI0 zero) 6413%{ 6414 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6415 match(Set mem (StoreC mem zero)); 6416 6417 ins_cost(125); // XXX 6418 format %{ "movw $mem, R12\t# short/char (R12_heapbase==0)" %} 6419 ins_encode %{ 6420 __ movw($mem$$Address, r12); 6421 %} 6422 ins_pipe(ialu_mem_reg); 6423%} 6424 6425instruct storeImmI16(memory mem, immI16 src) 6426%{ 6427 predicate(UseStoreImmI16); 6428 match(Set mem (StoreC mem src)); 6429 6430 ins_cost(150); 6431 format %{ "movw $mem, $src\t# short/char" %} 6432 opcode(0xC7); /* C7 /0 Same as 32 store immediate with prefix */ 6433 ins_encode(SizePrefix, REX_mem(mem), OpcP, RM_opc_mem(0x00, mem),Con16(src)); 6434 ins_pipe(ialu_mem_imm); 6435%} 6436 6437// Store Byte Immediate 6438instruct storeImmB0(memory mem, immI0 zero) 6439%{ 6440 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6441 match(Set mem (StoreB mem zero)); 6442 6443 ins_cost(125); // XXX 6444 format %{ "movb $mem, R12\t# short/char (R12_heapbase==0)" %} 6445 ins_encode %{ 6446 __ movb($mem$$Address, r12); 6447 %} 6448 ins_pipe(ialu_mem_reg); 6449%} 6450 6451instruct storeImmB(memory mem, immI8 src) 6452%{ 6453 match(Set mem (StoreB mem src)); 6454 6455 ins_cost(150); // XXX 6456 format %{ "movb $mem, $src\t# byte" %} 6457 opcode(0xC6); /* C6 /0 */ 6458 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src)); 6459 ins_pipe(ialu_mem_imm); 6460%} 6461 6462// Store CMS card-mark Immediate 6463instruct storeImmCM0_reg(memory mem, immI0 zero) 6464%{ 6465 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6466 match(Set mem (StoreCM mem zero)); 6467 6468 ins_cost(125); // XXX 6469 format %{ "movb $mem, R12\t# CMS card-mark byte 0 (R12_heapbase==0)" %} 6470 ins_encode %{ 6471 __ movb($mem$$Address, r12); 6472 %} 6473 ins_pipe(ialu_mem_reg); 6474%} 6475 6476instruct storeImmCM0(memory mem, immI0 src) 6477%{ 6478 match(Set mem (StoreCM mem src)); 6479 6480 ins_cost(150); // XXX 6481 format %{ "movb $mem, $src\t# CMS card-mark byte 0" %} 6482 opcode(0xC6); /* C6 /0 */ 6483 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src)); 6484 ins_pipe(ialu_mem_imm); 6485%} 6486 6487// Store Float 6488instruct storeF(memory mem, regF src) 6489%{ 6490 match(Set mem (StoreF mem src)); 6491 6492 ins_cost(95); // XXX 6493 format %{ "movss $mem, $src\t# float" %} 6494 ins_encode %{ 6495 __ movflt($mem$$Address, $src$$XMMRegister); 6496 %} 6497 ins_pipe(pipe_slow); // XXX 6498%} 6499 6500// Store immediate Float value (it is faster than store from XMM register) 6501instruct storeF0(memory mem, immF0 zero) 6502%{ 6503 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6504 match(Set mem (StoreF mem zero)); 6505 6506 ins_cost(25); // XXX 6507 format %{ "movl $mem, R12\t# float 0. (R12_heapbase==0)" %} 6508 ins_encode %{ 6509 __ movl($mem$$Address, r12); 6510 %} 6511 ins_pipe(ialu_mem_reg); 6512%} 6513 6514instruct storeF_imm(memory mem, immF src) 6515%{ 6516 match(Set mem (StoreF mem src)); 6517 6518 ins_cost(50); 6519 format %{ "movl $mem, $src\t# float" %} 6520 opcode(0xC7); /* C7 /0 */ 6521 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src)); 6522 ins_pipe(ialu_mem_imm); 6523%} 6524 6525// Store Double 6526instruct storeD(memory mem, regD src) 6527%{ 6528 match(Set mem (StoreD mem src)); 6529 6530 ins_cost(95); // XXX 6531 format %{ "movsd $mem, $src\t# double" %} 6532 ins_encode %{ 6533 __ movdbl($mem$$Address, $src$$XMMRegister); 6534 %} 6535 ins_pipe(pipe_slow); // XXX 6536%} 6537 6538// Store immediate double 0.0 (it is faster than store from XMM register) 6539instruct storeD0_imm(memory mem, immD0 src) 6540%{ 6541 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL)); 6542 match(Set mem (StoreD mem src)); 6543 6544 ins_cost(50); 6545 format %{ "movq $mem, $src\t# double 0." %} 6546 opcode(0xC7); /* C7 /0 */ 6547 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src)); 6548 ins_pipe(ialu_mem_imm); 6549%} 6550 6551instruct storeD0(memory mem, immD0 zero) 6552%{ 6553 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6554 match(Set mem (StoreD mem zero)); 6555 6556 ins_cost(25); // XXX 6557 format %{ "movq $mem, R12\t# double 0. (R12_heapbase==0)" %} 6558 ins_encode %{ 6559 __ movq($mem$$Address, r12); 6560 %} 6561 ins_pipe(ialu_mem_reg); 6562%} 6563 6564instruct storeSSI(stackSlotI dst, rRegI src) 6565%{ 6566 match(Set dst src); 6567 6568 ins_cost(100); 6569 format %{ "movl $dst, $src\t# int stk" %} 6570 opcode(0x89); 6571 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 6572 ins_pipe( ialu_mem_reg ); 6573%} 6574 6575instruct storeSSL(stackSlotL dst, rRegL src) 6576%{ 6577 match(Set dst src); 6578 6579 ins_cost(100); 6580 format %{ "movq $dst, $src\t# long stk" %} 6581 opcode(0x89); 6582 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 6583 ins_pipe(ialu_mem_reg); 6584%} 6585 6586instruct storeSSP(stackSlotP dst, rRegP src) 6587%{ 6588 match(Set dst src); 6589 6590 ins_cost(100); 6591 format %{ "movq $dst, $src\t# ptr stk" %} 6592 opcode(0x89); 6593 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 6594 ins_pipe(ialu_mem_reg); 6595%} 6596 6597instruct storeSSF(stackSlotF dst, regF src) 6598%{ 6599 match(Set dst src); 6600 6601 ins_cost(95); // XXX 6602 format %{ "movss $dst, $src\t# float stk" %} 6603 ins_encode %{ 6604 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 6605 %} 6606 ins_pipe(pipe_slow); // XXX 6607%} 6608 6609instruct storeSSD(stackSlotD dst, regD src) 6610%{ 6611 match(Set dst src); 6612 6613 ins_cost(95); // XXX 6614 format %{ "movsd $dst, $src\t# double stk" %} 6615 ins_encode %{ 6616 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 6617 %} 6618 ins_pipe(pipe_slow); // XXX 6619%} 6620 6621//----------BSWAP Instructions------------------------------------------------- 6622instruct bytes_reverse_int(rRegI dst) %{ 6623 match(Set dst (ReverseBytesI dst)); 6624 6625 format %{ "bswapl $dst" %} 6626 opcode(0x0F, 0xC8); /*Opcode 0F /C8 */ 6627 ins_encode( REX_reg(dst), OpcP, opc2_reg(dst) ); 6628 ins_pipe( ialu_reg ); 6629%} 6630 6631instruct bytes_reverse_long(rRegL dst) %{ 6632 match(Set dst (ReverseBytesL dst)); 6633 6634 format %{ "bswapq $dst" %} 6635 opcode(0x0F, 0xC8); /* Opcode 0F /C8 */ 6636 ins_encode( REX_reg_wide(dst), OpcP, opc2_reg(dst) ); 6637 ins_pipe( ialu_reg); 6638%} 6639 6640instruct bytes_reverse_unsigned_short(rRegI dst, rFlagsReg cr) %{ 6641 match(Set dst (ReverseBytesUS dst)); 6642 effect(KILL cr); 6643 6644 format %{ "bswapl $dst\n\t" 6645 "shrl $dst,16\n\t" %} 6646 ins_encode %{ 6647 __ bswapl($dst$$Register); 6648 __ shrl($dst$$Register, 16); 6649 %} 6650 ins_pipe( ialu_reg ); 6651%} 6652 6653instruct bytes_reverse_short(rRegI dst, rFlagsReg cr) %{ 6654 match(Set dst (ReverseBytesS dst)); 6655 effect(KILL cr); 6656 6657 format %{ "bswapl $dst\n\t" 6658 "sar $dst,16\n\t" %} 6659 ins_encode %{ 6660 __ bswapl($dst$$Register); 6661 __ sarl($dst$$Register, 16); 6662 %} 6663 ins_pipe( ialu_reg ); 6664%} 6665 6666//---------- Zeros Count Instructions ------------------------------------------ 6667 6668instruct countLeadingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6669 predicate(UseCountLeadingZerosInstruction); 6670 match(Set dst (CountLeadingZerosI src)); 6671 effect(KILL cr); 6672 6673 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 6674 ins_encode %{ 6675 __ lzcntl($dst$$Register, $src$$Register); 6676 %} 6677 ins_pipe(ialu_reg); 6678%} 6679 6680instruct countLeadingZerosI_bsr(rRegI dst, rRegI src, rFlagsReg cr) %{ 6681 predicate(!UseCountLeadingZerosInstruction); 6682 match(Set dst (CountLeadingZerosI src)); 6683 effect(KILL cr); 6684 6685 format %{ "bsrl $dst, $src\t# count leading zeros (int)\n\t" 6686 "jnz skip\n\t" 6687 "movl $dst, -1\n" 6688 "skip:\n\t" 6689 "negl $dst\n\t" 6690 "addl $dst, 31" %} 6691 ins_encode %{ 6692 Register Rdst = $dst$$Register; 6693 Register Rsrc = $src$$Register; 6694 Label skip; 6695 __ bsrl(Rdst, Rsrc); 6696 __ jccb(Assembler::notZero, skip); 6697 __ movl(Rdst, -1); 6698 __ bind(skip); 6699 __ negl(Rdst); 6700 __ addl(Rdst, BitsPerInt - 1); 6701 %} 6702 ins_pipe(ialu_reg); 6703%} 6704 6705instruct countLeadingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6706 predicate(UseCountLeadingZerosInstruction); 6707 match(Set dst (CountLeadingZerosL src)); 6708 effect(KILL cr); 6709 6710 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 6711 ins_encode %{ 6712 __ lzcntq($dst$$Register, $src$$Register); 6713 %} 6714 ins_pipe(ialu_reg); 6715%} 6716 6717instruct countLeadingZerosL_bsr(rRegI dst, rRegL src, rFlagsReg cr) %{ 6718 predicate(!UseCountLeadingZerosInstruction); 6719 match(Set dst (CountLeadingZerosL src)); 6720 effect(KILL cr); 6721 6722 format %{ "bsrq $dst, $src\t# count leading zeros (long)\n\t" 6723 "jnz skip\n\t" 6724 "movl $dst, -1\n" 6725 "skip:\n\t" 6726 "negl $dst\n\t" 6727 "addl $dst, 63" %} 6728 ins_encode %{ 6729 Register Rdst = $dst$$Register; 6730 Register Rsrc = $src$$Register; 6731 Label skip; 6732 __ bsrq(Rdst, Rsrc); 6733 __ jccb(Assembler::notZero, skip); 6734 __ movl(Rdst, -1); 6735 __ bind(skip); 6736 __ negl(Rdst); 6737 __ addl(Rdst, BitsPerLong - 1); 6738 %} 6739 ins_pipe(ialu_reg); 6740%} 6741 6742instruct countTrailingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6743 predicate(UseCountTrailingZerosInstruction); 6744 match(Set dst (CountTrailingZerosI src)); 6745 effect(KILL cr); 6746 6747 format %{ "tzcntl $dst, $src\t# count trailing zeros (int)" %} 6748 ins_encode %{ 6749 __ tzcntl($dst$$Register, $src$$Register); 6750 %} 6751 ins_pipe(ialu_reg); 6752%} 6753 6754instruct countTrailingZerosI_bsf(rRegI dst, rRegI src, rFlagsReg cr) %{ 6755 predicate(!UseCountTrailingZerosInstruction); 6756 match(Set dst (CountTrailingZerosI src)); 6757 effect(KILL cr); 6758 6759 format %{ "bsfl $dst, $src\t# count trailing zeros (int)\n\t" 6760 "jnz done\n\t" 6761 "movl $dst, 32\n" 6762 "done:" %} 6763 ins_encode %{ 6764 Register Rdst = $dst$$Register; 6765 Label done; 6766 __ bsfl(Rdst, $src$$Register); 6767 __ jccb(Assembler::notZero, done); 6768 __ movl(Rdst, BitsPerInt); 6769 __ bind(done); 6770 %} 6771 ins_pipe(ialu_reg); 6772%} 6773 6774instruct countTrailingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6775 predicate(UseCountTrailingZerosInstruction); 6776 match(Set dst (CountTrailingZerosL src)); 6777 effect(KILL cr); 6778 6779 format %{ "tzcntq $dst, $src\t# count trailing zeros (long)" %} 6780 ins_encode %{ 6781 __ tzcntq($dst$$Register, $src$$Register); 6782 %} 6783 ins_pipe(ialu_reg); 6784%} 6785 6786instruct countTrailingZerosL_bsf(rRegI dst, rRegL src, rFlagsReg cr) %{ 6787 predicate(!UseCountTrailingZerosInstruction); 6788 match(Set dst (CountTrailingZerosL src)); 6789 effect(KILL cr); 6790 6791 format %{ "bsfq $dst, $src\t# count trailing zeros (long)\n\t" 6792 "jnz done\n\t" 6793 "movl $dst, 64\n" 6794 "done:" %} 6795 ins_encode %{ 6796 Register Rdst = $dst$$Register; 6797 Label done; 6798 __ bsfq(Rdst, $src$$Register); 6799 __ jccb(Assembler::notZero, done); 6800 __ movl(Rdst, BitsPerLong); 6801 __ bind(done); 6802 %} 6803 ins_pipe(ialu_reg); 6804%} 6805 6806 6807//---------- Population Count Instructions ------------------------------------- 6808 6809instruct popCountI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6810 predicate(UsePopCountInstruction); 6811 match(Set dst (PopCountI src)); 6812 effect(KILL cr); 6813 6814 format %{ "popcnt $dst, $src" %} 6815 ins_encode %{ 6816 __ popcntl($dst$$Register, $src$$Register); 6817 %} 6818 ins_pipe(ialu_reg); 6819%} 6820 6821instruct popCountI_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 6822 predicate(UsePopCountInstruction); 6823 match(Set dst (PopCountI (LoadI mem))); 6824 effect(KILL cr); 6825 6826 format %{ "popcnt $dst, $mem" %} 6827 ins_encode %{ 6828 __ popcntl($dst$$Register, $mem$$Address); 6829 %} 6830 ins_pipe(ialu_reg); 6831%} 6832 6833// Note: Long.bitCount(long) returns an int. 6834instruct popCountL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6835 predicate(UsePopCountInstruction); 6836 match(Set dst (PopCountL src)); 6837 effect(KILL cr); 6838 6839 format %{ "popcnt $dst, $src" %} 6840 ins_encode %{ 6841 __ popcntq($dst$$Register, $src$$Register); 6842 %} 6843 ins_pipe(ialu_reg); 6844%} 6845 6846// Note: Long.bitCount(long) returns an int. 6847instruct popCountL_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 6848 predicate(UsePopCountInstruction); 6849 match(Set dst (PopCountL (LoadL mem))); 6850 effect(KILL cr); 6851 6852 format %{ "popcnt $dst, $mem" %} 6853 ins_encode %{ 6854 __ popcntq($dst$$Register, $mem$$Address); 6855 %} 6856 ins_pipe(ialu_reg); 6857%} 6858 6859 6860//----------MemBar Instructions----------------------------------------------- 6861// Memory barrier flavors 6862 6863instruct membar_acquire() 6864%{ 6865 match(MemBarAcquire); 6866 match(LoadFence); 6867 ins_cost(0); 6868 6869 size(0); 6870 format %{ "MEMBAR-acquire ! (empty encoding)" %} 6871 ins_encode(); 6872 ins_pipe(empty); 6873%} 6874 6875instruct membar_acquire_lock() 6876%{ 6877 match(MemBarAcquireLock); 6878 ins_cost(0); 6879 6880 size(0); 6881 format %{ "MEMBAR-acquire (prior CMPXCHG in FastLock so empty encoding)" %} 6882 ins_encode(); 6883 ins_pipe(empty); 6884%} 6885 6886instruct membar_release() 6887%{ 6888 match(MemBarRelease); 6889 match(StoreFence); 6890 ins_cost(0); 6891 6892 size(0); 6893 format %{ "MEMBAR-release ! (empty encoding)" %} 6894 ins_encode(); 6895 ins_pipe(empty); 6896%} 6897 6898instruct membar_release_lock() 6899%{ 6900 match(MemBarReleaseLock); 6901 ins_cost(0); 6902 6903 size(0); 6904 format %{ "MEMBAR-release (a FastUnlock follows so empty encoding)" %} 6905 ins_encode(); 6906 ins_pipe(empty); 6907%} 6908 6909instruct membar_volatile(rFlagsReg cr) %{ 6910 match(MemBarVolatile); 6911 effect(KILL cr); 6912 ins_cost(400); 6913 6914 format %{ 6915 $$template 6916 if (os::is_MP()) { 6917 $$emit$$"lock addl [rsp + #0], 0\t! membar_volatile" 6918 } else { 6919 $$emit$$"MEMBAR-volatile ! (empty encoding)" 6920 } 6921 %} 6922 ins_encode %{ 6923 __ membar(Assembler::StoreLoad); 6924 %} 6925 ins_pipe(pipe_slow); 6926%} 6927 6928instruct unnecessary_membar_volatile() 6929%{ 6930 match(MemBarVolatile); 6931 predicate(Matcher::post_store_load_barrier(n)); 6932 ins_cost(0); 6933 6934 size(0); 6935 format %{ "MEMBAR-volatile (unnecessary so empty encoding)" %} 6936 ins_encode(); 6937 ins_pipe(empty); 6938%} 6939 6940instruct membar_storestore() %{ 6941 match(MemBarStoreStore); 6942 ins_cost(0); 6943 6944 size(0); 6945 format %{ "MEMBAR-storestore (empty encoding)" %} 6946 ins_encode( ); 6947 ins_pipe(empty); 6948%} 6949 6950//----------Move Instructions-------------------------------------------------- 6951 6952instruct castX2P(rRegP dst, rRegL src) 6953%{ 6954 match(Set dst (CastX2P src)); 6955 6956 format %{ "movq $dst, $src\t# long->ptr" %} 6957 ins_encode %{ 6958 if ($dst$$reg != $src$$reg) { 6959 __ movptr($dst$$Register, $src$$Register); 6960 } 6961 %} 6962 ins_pipe(ialu_reg_reg); // XXX 6963%} 6964 6965instruct castP2X(rRegL dst, rRegP src) 6966%{ 6967 match(Set dst (CastP2X src)); 6968 6969 format %{ "movq $dst, $src\t# ptr -> long" %} 6970 ins_encode %{ 6971 if ($dst$$reg != $src$$reg) { 6972 __ movptr($dst$$Register, $src$$Register); 6973 } 6974 %} 6975 ins_pipe(ialu_reg_reg); // XXX 6976%} 6977 6978// Convert oop into int for vectors alignment masking 6979instruct convP2I(rRegI dst, rRegP src) 6980%{ 6981 match(Set dst (ConvL2I (CastP2X src))); 6982 6983 format %{ "movl $dst, $src\t# ptr -> int" %} 6984 ins_encode %{ 6985 __ movl($dst$$Register, $src$$Register); 6986 %} 6987 ins_pipe(ialu_reg_reg); // XXX 6988%} 6989 6990// Convert compressed oop into int for vectors alignment masking 6991// in case of 32bit oops (heap < 4Gb). 6992instruct convN2I(rRegI dst, rRegN src) 6993%{ 6994 predicate(Universe::narrow_oop_shift() == 0); 6995 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 6996 6997 format %{ "movl $dst, $src\t# compressed ptr -> int" %} 6998 ins_encode %{ 6999 __ movl($dst$$Register, $src$$Register); 7000 %} 7001 ins_pipe(ialu_reg_reg); // XXX 7002%} 7003 7004// Convert oop pointer into compressed form 7005instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{ 7006 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 7007 match(Set dst (EncodeP src)); 7008 effect(KILL cr); 7009 format %{ "encode_heap_oop $dst,$src" %} 7010 ins_encode %{ 7011 Register s = $src$$Register; 7012 Register d = $dst$$Register; 7013 if (s != d) { 7014 __ movq(d, s); 7015 } 7016 __ encode_heap_oop(d); 7017 %} 7018 ins_pipe(ialu_reg_long); 7019%} 7020 7021instruct encodeHeapOop_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 7022 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 7023 match(Set dst (EncodeP src)); 7024 effect(KILL cr); 7025 format %{ "encode_heap_oop_not_null $dst,$src" %} 7026 ins_encode %{ 7027 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 7028 %} 7029 ins_pipe(ialu_reg_long); 7030%} 7031 7032instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{ 7033 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 7034 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 7035 match(Set dst (DecodeN src)); 7036 effect(KILL cr); 7037 format %{ "decode_heap_oop $dst,$src" %} 7038 ins_encode %{ 7039 Register s = $src$$Register; 7040 Register d = $dst$$Register; 7041 if (s != d) { 7042 __ movq(d, s); 7043 } 7044 __ decode_heap_oop(d); 7045 %} 7046 ins_pipe(ialu_reg_long); 7047%} 7048 7049instruct decodeHeapOop_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 7050 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 7051 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 7052 match(Set dst (DecodeN src)); 7053 effect(KILL cr); 7054 format %{ "decode_heap_oop_not_null $dst,$src" %} 7055 ins_encode %{ 7056 Register s = $src$$Register; 7057 Register d = $dst$$Register; 7058 if (s != d) { 7059 __ decode_heap_oop_not_null(d, s); 7060 } else { 7061 __ decode_heap_oop_not_null(d); 7062 } 7063 %} 7064 ins_pipe(ialu_reg_long); 7065%} 7066 7067instruct encodeKlass_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 7068 match(Set dst (EncodePKlass src)); 7069 effect(KILL cr); 7070 format %{ "encode_klass_not_null $dst,$src" %} 7071 ins_encode %{ 7072 __ encode_klass_not_null($dst$$Register, $src$$Register); 7073 %} 7074 ins_pipe(ialu_reg_long); 7075%} 7076 7077instruct decodeKlass_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 7078 match(Set dst (DecodeNKlass src)); 7079 effect(KILL cr); 7080 format %{ "decode_klass_not_null $dst,$src" %} 7081 ins_encode %{ 7082 Register s = $src$$Register; 7083 Register d = $dst$$Register; 7084 if (s != d) { 7085 __ decode_klass_not_null(d, s); 7086 } else { 7087 __ decode_klass_not_null(d); 7088 } 7089 %} 7090 ins_pipe(ialu_reg_long); 7091%} 7092 7093 7094//----------Conditional Move--------------------------------------------------- 7095// Jump 7096// dummy instruction for generating temp registers 7097instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{ 7098 match(Jump (LShiftL switch_val shift)); 7099 ins_cost(350); 7100 predicate(false); 7101 effect(TEMP dest); 7102 7103 format %{ "leaq $dest, [$constantaddress]\n\t" 7104 "jmp [$dest + $switch_val << $shift]\n\t" %} 7105 ins_encode %{ 7106 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 7107 // to do that and the compiler is using that register as one it can allocate. 7108 // So we build it all by hand. 7109 // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant); 7110 // ArrayAddress dispatch(table, index); 7111 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant); 7112 __ lea($dest$$Register, $constantaddress); 7113 __ jmp(dispatch); 7114 %} 7115 ins_pipe(pipe_jmp); 7116%} 7117 7118instruct jumpXtnd_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{ 7119 match(Jump (AddL (LShiftL switch_val shift) offset)); 7120 ins_cost(350); 7121 effect(TEMP dest); 7122 7123 format %{ "leaq $dest, [$constantaddress]\n\t" 7124 "jmp [$dest + $switch_val << $shift + $offset]\n\t" %} 7125 ins_encode %{ 7126 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 7127 // to do that and the compiler is using that register as one it can allocate. 7128 // So we build it all by hand. 7129 // Address index(noreg, switch_reg, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 7130 // ArrayAddress dispatch(table, index); 7131 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 7132 __ lea($dest$$Register, $constantaddress); 7133 __ jmp(dispatch); 7134 %} 7135 ins_pipe(pipe_jmp); 7136%} 7137 7138instruct jumpXtnd(rRegL switch_val, rRegI dest) %{ 7139 match(Jump switch_val); 7140 ins_cost(350); 7141 effect(TEMP dest); 7142 7143 format %{ "leaq $dest, [$constantaddress]\n\t" 7144 "jmp [$dest + $switch_val]\n\t" %} 7145 ins_encode %{ 7146 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 7147 // to do that and the compiler is using that register as one it can allocate. 7148 // So we build it all by hand. 7149 // Address index(noreg, switch_reg, Address::times_1); 7150 // ArrayAddress dispatch(table, index); 7151 Address dispatch($dest$$Register, $switch_val$$Register, Address::times_1); 7152 __ lea($dest$$Register, $constantaddress); 7153 __ jmp(dispatch); 7154 %} 7155 ins_pipe(pipe_jmp); 7156%} 7157 7158// Conditional move 7159instruct cmovI_reg(rRegI dst, rRegI src, rFlagsReg cr, cmpOp cop) 7160%{ 7161 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 7162 7163 ins_cost(200); // XXX 7164 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 7165 opcode(0x0F, 0x40); 7166 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7167 ins_pipe(pipe_cmov_reg); 7168%} 7169 7170instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{ 7171 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 7172 7173 ins_cost(200); // XXX 7174 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 7175 opcode(0x0F, 0x40); 7176 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7177 ins_pipe(pipe_cmov_reg); 7178%} 7179 7180instruct cmovI_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 7181 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 7182 ins_cost(200); 7183 expand %{ 7184 cmovI_regU(cop, cr, dst, src); 7185 %} 7186%} 7187 7188// Conditional move 7189instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{ 7190 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 7191 7192 ins_cost(250); // XXX 7193 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 7194 opcode(0x0F, 0x40); 7195 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src)); 7196 ins_pipe(pipe_cmov_mem); 7197%} 7198 7199// Conditional move 7200instruct cmovI_memU(cmpOpU cop, rFlagsRegU cr, rRegI dst, memory src) 7201%{ 7202 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 7203 7204 ins_cost(250); // XXX 7205 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 7206 opcode(0x0F, 0x40); 7207 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src)); 7208 ins_pipe(pipe_cmov_mem); 7209%} 7210 7211instruct cmovI_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, memory src) %{ 7212 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 7213 ins_cost(250); 7214 expand %{ 7215 cmovI_memU(cop, cr, dst, src); 7216 %} 7217%} 7218 7219// Conditional move 7220instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop) 7221%{ 7222 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 7223 7224 ins_cost(200); // XXX 7225 format %{ "cmovl$cop $dst, $src\t# signed, compressed ptr" %} 7226 opcode(0x0F, 0x40); 7227 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7228 ins_pipe(pipe_cmov_reg); 7229%} 7230 7231// Conditional move 7232instruct cmovN_regU(cmpOpU cop, rFlagsRegU cr, rRegN dst, rRegN src) 7233%{ 7234 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 7235 7236 ins_cost(200); // XXX 7237 format %{ "cmovl$cop $dst, $src\t# unsigned, compressed ptr" %} 7238 opcode(0x0F, 0x40); 7239 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7240 ins_pipe(pipe_cmov_reg); 7241%} 7242 7243instruct cmovN_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 7244 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 7245 ins_cost(200); 7246 expand %{ 7247 cmovN_regU(cop, cr, dst, src); 7248 %} 7249%} 7250 7251// Conditional move 7252instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop) 7253%{ 7254 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 7255 7256 ins_cost(200); // XXX 7257 format %{ "cmovq$cop $dst, $src\t# signed, ptr" %} 7258 opcode(0x0F, 0x40); 7259 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7260 ins_pipe(pipe_cmov_reg); // XXX 7261%} 7262 7263// Conditional move 7264instruct cmovP_regU(cmpOpU cop, rFlagsRegU cr, rRegP dst, rRegP src) 7265%{ 7266 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 7267 7268 ins_cost(200); // XXX 7269 format %{ "cmovq$cop $dst, $src\t# unsigned, ptr" %} 7270 opcode(0x0F, 0x40); 7271 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7272 ins_pipe(pipe_cmov_reg); // XXX 7273%} 7274 7275instruct cmovP_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 7276 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 7277 ins_cost(200); 7278 expand %{ 7279 cmovP_regU(cop, cr, dst, src); 7280 %} 7281%} 7282 7283// DISABLED: Requires the ADLC to emit a bottom_type call that 7284// correctly meets the two pointer arguments; one is an incoming 7285// register but the other is a memory operand. ALSO appears to 7286// be buggy with implicit null checks. 7287// 7288//// Conditional move 7289//instruct cmovP_mem(cmpOp cop, rFlagsReg cr, rRegP dst, memory src) 7290//%{ 7291// match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); 7292// ins_cost(250); 7293// format %{ "CMOV$cop $dst,$src\t# ptr" %} 7294// opcode(0x0F,0x40); 7295// ins_encode( enc_cmov(cop), reg_mem( dst, src ) ); 7296// ins_pipe( pipe_cmov_mem ); 7297//%} 7298// 7299//// Conditional move 7300//instruct cmovP_memU(cmpOpU cop, rFlagsRegU cr, rRegP dst, memory src) 7301//%{ 7302// match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); 7303// ins_cost(250); 7304// format %{ "CMOV$cop $dst,$src\t# ptr" %} 7305// opcode(0x0F,0x40); 7306// ins_encode( enc_cmov(cop), reg_mem( dst, src ) ); 7307// ins_pipe( pipe_cmov_mem ); 7308//%} 7309 7310instruct cmovL_reg(cmpOp cop, rFlagsReg cr, rRegL dst, rRegL src) 7311%{ 7312 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 7313 7314 ins_cost(200); // XXX 7315 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 7316 opcode(0x0F, 0x40); 7317 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7318 ins_pipe(pipe_cmov_reg); // XXX 7319%} 7320 7321instruct cmovL_mem(cmpOp cop, rFlagsReg cr, rRegL dst, memory src) 7322%{ 7323 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 7324 7325 ins_cost(200); // XXX 7326 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 7327 opcode(0x0F, 0x40); 7328 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src)); 7329 ins_pipe(pipe_cmov_mem); // XXX 7330%} 7331 7332instruct cmovL_regU(cmpOpU cop, rFlagsRegU cr, rRegL dst, rRegL src) 7333%{ 7334 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 7335 7336 ins_cost(200); // XXX 7337 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 7338 opcode(0x0F, 0x40); 7339 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 7340 ins_pipe(pipe_cmov_reg); // XXX 7341%} 7342 7343instruct cmovL_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 7344 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 7345 ins_cost(200); 7346 expand %{ 7347 cmovL_regU(cop, cr, dst, src); 7348 %} 7349%} 7350 7351instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src) 7352%{ 7353 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 7354 7355 ins_cost(200); // XXX 7356 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 7357 opcode(0x0F, 0x40); 7358 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src)); 7359 ins_pipe(pipe_cmov_mem); // XXX 7360%} 7361 7362instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{ 7363 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 7364 ins_cost(200); 7365 expand %{ 7366 cmovL_memU(cop, cr, dst, src); 7367 %} 7368%} 7369 7370instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src) 7371%{ 7372 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7373 7374 ins_cost(200); // XXX 7375 format %{ "jn$cop skip\t# signed cmove float\n\t" 7376 "movss $dst, $src\n" 7377 "skip:" %} 7378 ins_encode %{ 7379 Label Lskip; 7380 // Invert sense of branch from sense of CMOV 7381 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7382 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 7383 __ bind(Lskip); 7384 %} 7385 ins_pipe(pipe_slow); 7386%} 7387 7388// instruct cmovF_mem(cmpOp cop, rFlagsReg cr, regF dst, memory src) 7389// %{ 7390// match(Set dst (CMoveF (Binary cop cr) (Binary dst (LoadL src)))); 7391 7392// ins_cost(200); // XXX 7393// format %{ "jn$cop skip\t# signed cmove float\n\t" 7394// "movss $dst, $src\n" 7395// "skip:" %} 7396// ins_encode(enc_cmovf_mem_branch(cop, dst, src)); 7397// ins_pipe(pipe_slow); 7398// %} 7399 7400instruct cmovF_regU(cmpOpU cop, rFlagsRegU cr, regF dst, regF src) 7401%{ 7402 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7403 7404 ins_cost(200); // XXX 7405 format %{ "jn$cop skip\t# unsigned cmove float\n\t" 7406 "movss $dst, $src\n" 7407 "skip:" %} 7408 ins_encode %{ 7409 Label Lskip; 7410 // Invert sense of branch from sense of CMOV 7411 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7412 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 7413 __ bind(Lskip); 7414 %} 7415 ins_pipe(pipe_slow); 7416%} 7417 7418instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{ 7419 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7420 ins_cost(200); 7421 expand %{ 7422 cmovF_regU(cop, cr, dst, src); 7423 %} 7424%} 7425 7426instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src) 7427%{ 7428 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7429 7430 ins_cost(200); // XXX 7431 format %{ "jn$cop skip\t# signed cmove double\n\t" 7432 "movsd $dst, $src\n" 7433 "skip:" %} 7434 ins_encode %{ 7435 Label Lskip; 7436 // Invert sense of branch from sense of CMOV 7437 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7438 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 7439 __ bind(Lskip); 7440 %} 7441 ins_pipe(pipe_slow); 7442%} 7443 7444instruct cmovD_regU(cmpOpU cop, rFlagsRegU cr, regD dst, regD src) 7445%{ 7446 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7447 7448 ins_cost(200); // XXX 7449 format %{ "jn$cop skip\t# unsigned cmove double\n\t" 7450 "movsd $dst, $src\n" 7451 "skip:" %} 7452 ins_encode %{ 7453 Label Lskip; 7454 // Invert sense of branch from sense of CMOV 7455 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7456 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 7457 __ bind(Lskip); 7458 %} 7459 ins_pipe(pipe_slow); 7460%} 7461 7462instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{ 7463 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7464 ins_cost(200); 7465 expand %{ 7466 cmovD_regU(cop, cr, dst, src); 7467 %} 7468%} 7469 7470//----------Arithmetic Instructions-------------------------------------------- 7471//----------Addition Instructions---------------------------------------------- 7472 7473instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7474%{ 7475 match(Set dst (AddI dst src)); 7476 effect(KILL cr); 7477 7478 format %{ "addl $dst, $src\t# int" %} 7479 opcode(0x03); 7480 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 7481 ins_pipe(ialu_reg_reg); 7482%} 7483 7484instruct addI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 7485%{ 7486 match(Set dst (AddI dst src)); 7487 effect(KILL cr); 7488 7489 format %{ "addl $dst, $src\t# int" %} 7490 opcode(0x81, 0x00); /* /0 id */ 7491 ins_encode(OpcSErm(dst, src), Con8or32(src)); 7492 ins_pipe( ialu_reg ); 7493%} 7494 7495instruct addI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 7496%{ 7497 match(Set dst (AddI dst (LoadI src))); 7498 effect(KILL cr); 7499 7500 ins_cost(125); // XXX 7501 format %{ "addl $dst, $src\t# int" %} 7502 opcode(0x03); 7503 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 7504 ins_pipe(ialu_reg_mem); 7505%} 7506 7507instruct addI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 7508%{ 7509 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7510 effect(KILL cr); 7511 7512 ins_cost(150); // XXX 7513 format %{ "addl $dst, $src\t# int" %} 7514 opcode(0x01); /* Opcode 01 /r */ 7515 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 7516 ins_pipe(ialu_mem_reg); 7517%} 7518 7519instruct addI_mem_imm(memory dst, immI src, rFlagsReg cr) 7520%{ 7521 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7522 effect(KILL cr); 7523 7524 ins_cost(125); // XXX 7525 format %{ "addl $dst, $src\t# int" %} 7526 opcode(0x81); /* Opcode 81 /0 id */ 7527 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src)); 7528 ins_pipe(ialu_mem_imm); 7529%} 7530 7531instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr) 7532%{ 7533 predicate(UseIncDec); 7534 match(Set dst (AddI dst src)); 7535 effect(KILL cr); 7536 7537 format %{ "incl $dst\t# int" %} 7538 opcode(0xFF, 0x00); // FF /0 7539 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7540 ins_pipe(ialu_reg); 7541%} 7542 7543instruct incI_mem(memory dst, immI1 src, rFlagsReg cr) 7544%{ 7545 predicate(UseIncDec); 7546 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7547 effect(KILL cr); 7548 7549 ins_cost(125); // XXX 7550 format %{ "incl $dst\t# int" %} 7551 opcode(0xFF); /* Opcode FF /0 */ 7552 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x00, dst)); 7553 ins_pipe(ialu_mem_imm); 7554%} 7555 7556// XXX why does that use AddI 7557instruct decI_rReg(rRegI dst, immI_M1 src, rFlagsReg cr) 7558%{ 7559 predicate(UseIncDec); 7560 match(Set dst (AddI dst src)); 7561 effect(KILL cr); 7562 7563 format %{ "decl $dst\t# int" %} 7564 opcode(0xFF, 0x01); // FF /1 7565 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7566 ins_pipe(ialu_reg); 7567%} 7568 7569// XXX why does that use AddI 7570instruct decI_mem(memory dst, immI_M1 src, rFlagsReg cr) 7571%{ 7572 predicate(UseIncDec); 7573 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7574 effect(KILL cr); 7575 7576 ins_cost(125); // XXX 7577 format %{ "decl $dst\t# int" %} 7578 opcode(0xFF); /* Opcode FF /1 */ 7579 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x01, dst)); 7580 ins_pipe(ialu_mem_imm); 7581%} 7582 7583instruct leaI_rReg_immI(rRegI dst, rRegI src0, immI src1) 7584%{ 7585 match(Set dst (AddI src0 src1)); 7586 7587 ins_cost(110); 7588 format %{ "addr32 leal $dst, [$src0 + $src1]\t# int" %} 7589 opcode(0x8D); /* 0x8D /r */ 7590 ins_encode(Opcode(0x67), REX_reg_reg(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX 7591 ins_pipe(ialu_reg_reg); 7592%} 7593 7594instruct addL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7595%{ 7596 match(Set dst (AddL dst src)); 7597 effect(KILL cr); 7598 7599 format %{ "addq $dst, $src\t# long" %} 7600 opcode(0x03); 7601 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7602 ins_pipe(ialu_reg_reg); 7603%} 7604 7605instruct addL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 7606%{ 7607 match(Set dst (AddL dst src)); 7608 effect(KILL cr); 7609 7610 format %{ "addq $dst, $src\t# long" %} 7611 opcode(0x81, 0x00); /* /0 id */ 7612 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7613 ins_pipe( ialu_reg ); 7614%} 7615 7616instruct addL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 7617%{ 7618 match(Set dst (AddL dst (LoadL src))); 7619 effect(KILL cr); 7620 7621 ins_cost(125); // XXX 7622 format %{ "addq $dst, $src\t# long" %} 7623 opcode(0x03); 7624 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 7625 ins_pipe(ialu_reg_mem); 7626%} 7627 7628instruct addL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 7629%{ 7630 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7631 effect(KILL cr); 7632 7633 ins_cost(150); // XXX 7634 format %{ "addq $dst, $src\t# long" %} 7635 opcode(0x01); /* Opcode 01 /r */ 7636 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 7637 ins_pipe(ialu_mem_reg); 7638%} 7639 7640instruct addL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 7641%{ 7642 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7643 effect(KILL cr); 7644 7645 ins_cost(125); // XXX 7646 format %{ "addq $dst, $src\t# long" %} 7647 opcode(0x81); /* Opcode 81 /0 id */ 7648 ins_encode(REX_mem_wide(dst), 7649 OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src)); 7650 ins_pipe(ialu_mem_imm); 7651%} 7652 7653instruct incL_rReg(rRegI dst, immL1 src, rFlagsReg cr) 7654%{ 7655 predicate(UseIncDec); 7656 match(Set dst (AddL dst src)); 7657 effect(KILL cr); 7658 7659 format %{ "incq $dst\t# long" %} 7660 opcode(0xFF, 0x00); // FF /0 7661 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 7662 ins_pipe(ialu_reg); 7663%} 7664 7665instruct incL_mem(memory dst, immL1 src, rFlagsReg cr) 7666%{ 7667 predicate(UseIncDec); 7668 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7669 effect(KILL cr); 7670 7671 ins_cost(125); // XXX 7672 format %{ "incq $dst\t# long" %} 7673 opcode(0xFF); /* Opcode FF /0 */ 7674 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x00, dst)); 7675 ins_pipe(ialu_mem_imm); 7676%} 7677 7678// XXX why does that use AddL 7679instruct decL_rReg(rRegL dst, immL_M1 src, rFlagsReg cr) 7680%{ 7681 predicate(UseIncDec); 7682 match(Set dst (AddL dst src)); 7683 effect(KILL cr); 7684 7685 format %{ "decq $dst\t# long" %} 7686 opcode(0xFF, 0x01); // FF /1 7687 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 7688 ins_pipe(ialu_reg); 7689%} 7690 7691// XXX why does that use AddL 7692instruct decL_mem(memory dst, immL_M1 src, rFlagsReg cr) 7693%{ 7694 predicate(UseIncDec); 7695 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7696 effect(KILL cr); 7697 7698 ins_cost(125); // XXX 7699 format %{ "decq $dst\t# long" %} 7700 opcode(0xFF); /* Opcode FF /1 */ 7701 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x01, dst)); 7702 ins_pipe(ialu_mem_imm); 7703%} 7704 7705instruct leaL_rReg_immL(rRegL dst, rRegL src0, immL32 src1) 7706%{ 7707 match(Set dst (AddL src0 src1)); 7708 7709 ins_cost(110); 7710 format %{ "leaq $dst, [$src0 + $src1]\t# long" %} 7711 opcode(0x8D); /* 0x8D /r */ 7712 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX 7713 ins_pipe(ialu_reg_reg); 7714%} 7715 7716instruct addP_rReg(rRegP dst, rRegL src, rFlagsReg cr) 7717%{ 7718 match(Set dst (AddP dst src)); 7719 effect(KILL cr); 7720 7721 format %{ "addq $dst, $src\t# ptr" %} 7722 opcode(0x03); 7723 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7724 ins_pipe(ialu_reg_reg); 7725%} 7726 7727instruct addP_rReg_imm(rRegP dst, immL32 src, rFlagsReg cr) 7728%{ 7729 match(Set dst (AddP dst src)); 7730 effect(KILL cr); 7731 7732 format %{ "addq $dst, $src\t# ptr" %} 7733 opcode(0x81, 0x00); /* /0 id */ 7734 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7735 ins_pipe( ialu_reg ); 7736%} 7737 7738// XXX addP mem ops ???? 7739 7740instruct leaP_rReg_imm(rRegP dst, rRegP src0, immL32 src1) 7741%{ 7742 match(Set dst (AddP src0 src1)); 7743 7744 ins_cost(110); 7745 format %{ "leaq $dst, [$src0 + $src1]\t# ptr" %} 7746 opcode(0x8D); /* 0x8D /r */ 7747 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1));// XXX 7748 ins_pipe(ialu_reg_reg); 7749%} 7750 7751instruct checkCastPP(rRegP dst) 7752%{ 7753 match(Set dst (CheckCastPP dst)); 7754 7755 size(0); 7756 format %{ "# checkcastPP of $dst" %} 7757 ins_encode(/* empty encoding */); 7758 ins_pipe(empty); 7759%} 7760 7761instruct castPP(rRegP dst) 7762%{ 7763 match(Set dst (CastPP dst)); 7764 7765 size(0); 7766 format %{ "# castPP of $dst" %} 7767 ins_encode(/* empty encoding */); 7768 ins_pipe(empty); 7769%} 7770 7771instruct castII(rRegI dst) 7772%{ 7773 match(Set dst (CastII dst)); 7774 7775 size(0); 7776 format %{ "# castII of $dst" %} 7777 ins_encode(/* empty encoding */); 7778 ins_cost(0); 7779 ins_pipe(empty); 7780%} 7781 7782// LoadP-locked same as a regular LoadP when used with compare-swap 7783instruct loadPLocked(rRegP dst, memory mem) 7784%{ 7785 match(Set dst (LoadPLocked mem)); 7786 7787 ins_cost(125); // XXX 7788 format %{ "movq $dst, $mem\t# ptr locked" %} 7789 opcode(0x8B); 7790 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 7791 ins_pipe(ialu_reg_mem); // XXX 7792%} 7793 7794// Conditional-store of the updated heap-top. 7795// Used during allocation of the shared heap. 7796// Sets flags (EQ) on success. Implemented with a CMPXCHG on Intel. 7797 7798instruct storePConditional(memory heap_top_ptr, 7799 rax_RegP oldval, rRegP newval, 7800 rFlagsReg cr) 7801%{ 7802 match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval))); 7803 7804 format %{ "cmpxchgq $heap_top_ptr, $newval\t# (ptr) " 7805 "If rax == $heap_top_ptr then store $newval into $heap_top_ptr" %} 7806 opcode(0x0F, 0xB1); 7807 ins_encode(lock_prefix, 7808 REX_reg_mem_wide(newval, heap_top_ptr), 7809 OpcP, OpcS, 7810 reg_mem(newval, heap_top_ptr)); 7811 ins_pipe(pipe_cmpxchg); 7812%} 7813 7814// Conditional-store of an int value. 7815// ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG. 7816instruct storeIConditional(memory mem, rax_RegI oldval, rRegI newval, rFlagsReg cr) 7817%{ 7818 match(Set cr (StoreIConditional mem (Binary oldval newval))); 7819 effect(KILL oldval); 7820 7821 format %{ "cmpxchgl $mem, $newval\t# If rax == $mem then store $newval into $mem" %} 7822 opcode(0x0F, 0xB1); 7823 ins_encode(lock_prefix, 7824 REX_reg_mem(newval, mem), 7825 OpcP, OpcS, 7826 reg_mem(newval, mem)); 7827 ins_pipe(pipe_cmpxchg); 7828%} 7829 7830// Conditional-store of a long value. 7831// ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG. 7832instruct storeLConditional(memory mem, rax_RegL oldval, rRegL newval, rFlagsReg cr) 7833%{ 7834 match(Set cr (StoreLConditional mem (Binary oldval newval))); 7835 effect(KILL oldval); 7836 7837 format %{ "cmpxchgq $mem, $newval\t# If rax == $mem then store $newval into $mem" %} 7838 opcode(0x0F, 0xB1); 7839 ins_encode(lock_prefix, 7840 REX_reg_mem_wide(newval, mem), 7841 OpcP, OpcS, 7842 reg_mem(newval, mem)); 7843 ins_pipe(pipe_cmpxchg); 7844%} 7845 7846 7847// XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them 7848instruct compareAndSwapP(rRegI res, 7849 memory mem_ptr, 7850 rax_RegP oldval, rRegP newval, 7851 rFlagsReg cr) 7852%{ 7853 predicate(VM_Version::supports_cx8()); 7854 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); 7855 match(Set res (WeakCompareAndSwapP mem_ptr (Binary oldval newval))); 7856 effect(KILL cr, KILL oldval); 7857 7858 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7859 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7860 "sete $res\n\t" 7861 "movzbl $res, $res" %} 7862 opcode(0x0F, 0xB1); 7863 ins_encode(lock_prefix, 7864 REX_reg_mem_wide(newval, mem_ptr), 7865 OpcP, OpcS, 7866 reg_mem(newval, mem_ptr), 7867 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7868 REX_reg_breg(res, res), // movzbl 7869 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7870 ins_pipe( pipe_cmpxchg ); 7871%} 7872 7873instruct compareAndSwapL(rRegI res, 7874 memory mem_ptr, 7875 rax_RegL oldval, rRegL newval, 7876 rFlagsReg cr) 7877%{ 7878 predicate(VM_Version::supports_cx8()); 7879 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval))); 7880 match(Set res (WeakCompareAndSwapL mem_ptr (Binary oldval newval))); 7881 effect(KILL cr, KILL oldval); 7882 7883 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7884 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7885 "sete $res\n\t" 7886 "movzbl $res, $res" %} 7887 opcode(0x0F, 0xB1); 7888 ins_encode(lock_prefix, 7889 REX_reg_mem_wide(newval, mem_ptr), 7890 OpcP, OpcS, 7891 reg_mem(newval, mem_ptr), 7892 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7893 REX_reg_breg(res, res), // movzbl 7894 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7895 ins_pipe( pipe_cmpxchg ); 7896%} 7897 7898instruct compareAndSwapI(rRegI res, 7899 memory mem_ptr, 7900 rax_RegI oldval, rRegI newval, 7901 rFlagsReg cr) 7902%{ 7903 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval))); 7904 match(Set res (WeakCompareAndSwapI mem_ptr (Binary oldval newval))); 7905 effect(KILL cr, KILL oldval); 7906 7907 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7908 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7909 "sete $res\n\t" 7910 "movzbl $res, $res" %} 7911 opcode(0x0F, 0xB1); 7912 ins_encode(lock_prefix, 7913 REX_reg_mem(newval, mem_ptr), 7914 OpcP, OpcS, 7915 reg_mem(newval, mem_ptr), 7916 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7917 REX_reg_breg(res, res), // movzbl 7918 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7919 ins_pipe( pipe_cmpxchg ); 7920%} 7921 7922instruct compareAndSwapB(rRegI res, 7923 memory mem_ptr, 7924 rax_RegI oldval, rRegI newval, 7925 rFlagsReg cr) 7926%{ 7927 match(Set res (CompareAndSwapB mem_ptr (Binary oldval newval))); 7928 match(Set res (WeakCompareAndSwapB mem_ptr (Binary oldval newval))); 7929 effect(KILL cr, KILL oldval); 7930 7931 format %{ "cmpxchgb $mem_ptr,$newval\t# " 7932 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7933 "sete $res\n\t" 7934 "movzbl $res, $res" %} 7935 opcode(0x0F, 0xB0); 7936 ins_encode(lock_prefix, 7937 REX_breg_mem(newval, mem_ptr), 7938 OpcP, OpcS, 7939 reg_mem(newval, mem_ptr), 7940 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7941 REX_reg_breg(res, res), // movzbl 7942 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7943 ins_pipe( pipe_cmpxchg ); 7944%} 7945 7946instruct compareAndSwapS(rRegI res, 7947 memory mem_ptr, 7948 rax_RegI oldval, rRegI newval, 7949 rFlagsReg cr) 7950%{ 7951 match(Set res (CompareAndSwapS mem_ptr (Binary oldval newval))); 7952 match(Set res (WeakCompareAndSwapS mem_ptr (Binary oldval newval))); 7953 effect(KILL cr, KILL oldval); 7954 7955 format %{ "cmpxchgw $mem_ptr,$newval\t# " 7956 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7957 "sete $res\n\t" 7958 "movzbl $res, $res" %} 7959 opcode(0x0F, 0xB1); 7960 ins_encode(lock_prefix, 7961 SizePrefix, 7962 REX_reg_mem(newval, mem_ptr), 7963 OpcP, OpcS, 7964 reg_mem(newval, mem_ptr), 7965 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7966 REX_reg_breg(res, res), // movzbl 7967 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7968 ins_pipe( pipe_cmpxchg ); 7969%} 7970 7971instruct compareAndSwapN(rRegI res, 7972 memory mem_ptr, 7973 rax_RegN oldval, rRegN newval, 7974 rFlagsReg cr) %{ 7975 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval))); 7976 match(Set res (WeakCompareAndSwapN mem_ptr (Binary oldval newval))); 7977 effect(KILL cr, KILL oldval); 7978 7979 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7980 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7981 "sete $res\n\t" 7982 "movzbl $res, $res" %} 7983 opcode(0x0F, 0xB1); 7984 ins_encode(lock_prefix, 7985 REX_reg_mem(newval, mem_ptr), 7986 OpcP, OpcS, 7987 reg_mem(newval, mem_ptr), 7988 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7989 REX_reg_breg(res, res), // movzbl 7990 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7991 ins_pipe( pipe_cmpxchg ); 7992%} 7993 7994instruct compareAndExchangeB( 7995 memory mem_ptr, 7996 rax_RegI oldval, rRegI newval, 7997 rFlagsReg cr) 7998%{ 7999 match(Set oldval (CompareAndExchangeB mem_ptr (Binary oldval newval))); 8000 effect(KILL cr); 8001 8002 format %{ "cmpxchgb $mem_ptr,$newval\t# " 8003 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 8004 opcode(0x0F, 0xB0); 8005 ins_encode(lock_prefix, 8006 REX_breg_mem(newval, mem_ptr), 8007 OpcP, OpcS, 8008 reg_mem(newval, mem_ptr) // lock cmpxchg 8009 ); 8010 ins_pipe( pipe_cmpxchg ); 8011%} 8012 8013instruct compareAndExchangeS( 8014 memory mem_ptr, 8015 rax_RegI oldval, rRegI newval, 8016 rFlagsReg cr) 8017%{ 8018 match(Set oldval (CompareAndExchangeS mem_ptr (Binary oldval newval))); 8019 effect(KILL cr); 8020 8021 format %{ "cmpxchgw $mem_ptr,$newval\t# " 8022 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 8023 opcode(0x0F, 0xB1); 8024 ins_encode(lock_prefix, 8025 SizePrefix, 8026 REX_reg_mem(newval, mem_ptr), 8027 OpcP, OpcS, 8028 reg_mem(newval, mem_ptr) // lock cmpxchg 8029 ); 8030 ins_pipe( pipe_cmpxchg ); 8031%} 8032 8033instruct compareAndExchangeI( 8034 memory mem_ptr, 8035 rax_RegI oldval, rRegI newval, 8036 rFlagsReg cr) 8037%{ 8038 match(Set oldval (CompareAndExchangeI mem_ptr (Binary oldval newval))); 8039 effect(KILL cr); 8040 8041 format %{ "cmpxchgl $mem_ptr,$newval\t# " 8042 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 8043 opcode(0x0F, 0xB1); 8044 ins_encode(lock_prefix, 8045 REX_reg_mem(newval, mem_ptr), 8046 OpcP, OpcS, 8047 reg_mem(newval, mem_ptr) // lock cmpxchg 8048 ); 8049 ins_pipe( pipe_cmpxchg ); 8050%} 8051 8052instruct compareAndExchangeL( 8053 memory mem_ptr, 8054 rax_RegL oldval, rRegL newval, 8055 rFlagsReg cr) 8056%{ 8057 predicate(VM_Version::supports_cx8()); 8058 match(Set oldval (CompareAndExchangeL mem_ptr (Binary oldval newval))); 8059 effect(KILL cr); 8060 8061 format %{ "cmpxchgq $mem_ptr,$newval\t# " 8062 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 8063 opcode(0x0F, 0xB1); 8064 ins_encode(lock_prefix, 8065 REX_reg_mem_wide(newval, mem_ptr), 8066 OpcP, OpcS, 8067 reg_mem(newval, mem_ptr) // lock cmpxchg 8068 ); 8069 ins_pipe( pipe_cmpxchg ); 8070%} 8071 8072instruct compareAndExchangeN( 8073 memory mem_ptr, 8074 rax_RegN oldval, rRegN newval, 8075 rFlagsReg cr) %{ 8076 match(Set oldval (CompareAndExchangeN mem_ptr (Binary oldval newval))); 8077 effect(KILL cr); 8078 8079 format %{ "cmpxchgl $mem_ptr,$newval\t# " 8080 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 8081 opcode(0x0F, 0xB1); 8082 ins_encode(lock_prefix, 8083 REX_reg_mem(newval, mem_ptr), 8084 OpcP, OpcS, 8085 reg_mem(newval, mem_ptr) // lock cmpxchg 8086 ); 8087 ins_pipe( pipe_cmpxchg ); 8088%} 8089 8090instruct compareAndExchangeP( 8091 memory mem_ptr, 8092 rax_RegP oldval, rRegP newval, 8093 rFlagsReg cr) 8094%{ 8095 predicate(VM_Version::supports_cx8()); 8096 match(Set oldval (CompareAndExchangeP mem_ptr (Binary oldval newval))); 8097 effect(KILL cr); 8098 8099 format %{ "cmpxchgq $mem_ptr,$newval\t# " 8100 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %} 8101 opcode(0x0F, 0xB1); 8102 ins_encode(lock_prefix, 8103 REX_reg_mem_wide(newval, mem_ptr), 8104 OpcP, OpcS, 8105 reg_mem(newval, mem_ptr) // lock cmpxchg 8106 ); 8107 ins_pipe( pipe_cmpxchg ); 8108%} 8109 8110instruct xaddB_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 8111 predicate(n->as_LoadStore()->result_not_used()); 8112 match(Set dummy (GetAndAddB mem add)); 8113 effect(KILL cr); 8114 format %{ "ADDB [$mem],$add" %} 8115 ins_encode %{ 8116 if (os::is_MP()) { __ lock(); } 8117 __ addb($mem$$Address, $add$$constant); 8118 %} 8119 ins_pipe( pipe_cmpxchg ); 8120%} 8121 8122instruct xaddB( memory mem, rRegI newval, rFlagsReg cr) %{ 8123 match(Set newval (GetAndAddB mem newval)); 8124 effect(KILL cr); 8125 format %{ "XADDB [$mem],$newval" %} 8126 ins_encode %{ 8127 if (os::is_MP()) { __ lock(); } 8128 __ xaddb($mem$$Address, $newval$$Register); 8129 %} 8130 ins_pipe( pipe_cmpxchg ); 8131%} 8132 8133instruct xaddS_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 8134 predicate(n->as_LoadStore()->result_not_used()); 8135 match(Set dummy (GetAndAddS mem add)); 8136 effect(KILL cr); 8137 format %{ "ADDW [$mem],$add" %} 8138 ins_encode %{ 8139 if (os::is_MP()) { __ lock(); } 8140 __ addw($mem$$Address, $add$$constant); 8141 %} 8142 ins_pipe( pipe_cmpxchg ); 8143%} 8144 8145instruct xaddS( memory mem, rRegI newval, rFlagsReg cr) %{ 8146 match(Set newval (GetAndAddS mem newval)); 8147 effect(KILL cr); 8148 format %{ "XADDW [$mem],$newval" %} 8149 ins_encode %{ 8150 if (os::is_MP()) { __ lock(); } 8151 __ xaddw($mem$$Address, $newval$$Register); 8152 %} 8153 ins_pipe( pipe_cmpxchg ); 8154%} 8155 8156instruct xaddI_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 8157 predicate(n->as_LoadStore()->result_not_used()); 8158 match(Set dummy (GetAndAddI mem add)); 8159 effect(KILL cr); 8160 format %{ "ADDL [$mem],$add" %} 8161 ins_encode %{ 8162 if (os::is_MP()) { __ lock(); } 8163 __ addl($mem$$Address, $add$$constant); 8164 %} 8165 ins_pipe( pipe_cmpxchg ); 8166%} 8167 8168instruct xaddI( memory mem, rRegI newval, rFlagsReg cr) %{ 8169 match(Set newval (GetAndAddI mem newval)); 8170 effect(KILL cr); 8171 format %{ "XADDL [$mem],$newval" %} 8172 ins_encode %{ 8173 if (os::is_MP()) { __ lock(); } 8174 __ xaddl($mem$$Address, $newval$$Register); 8175 %} 8176 ins_pipe( pipe_cmpxchg ); 8177%} 8178 8179instruct xaddL_no_res( memory mem, Universe dummy, immL32 add, rFlagsReg cr) %{ 8180 predicate(n->as_LoadStore()->result_not_used()); 8181 match(Set dummy (GetAndAddL mem add)); 8182 effect(KILL cr); 8183 format %{ "ADDQ [$mem],$add" %} 8184 ins_encode %{ 8185 if (os::is_MP()) { __ lock(); } 8186 __ addq($mem$$Address, $add$$constant); 8187 %} 8188 ins_pipe( pipe_cmpxchg ); 8189%} 8190 8191instruct xaddL( memory mem, rRegL newval, rFlagsReg cr) %{ 8192 match(Set newval (GetAndAddL mem newval)); 8193 effect(KILL cr); 8194 format %{ "XADDQ [$mem],$newval" %} 8195 ins_encode %{ 8196 if (os::is_MP()) { __ lock(); } 8197 __ xaddq($mem$$Address, $newval$$Register); 8198 %} 8199 ins_pipe( pipe_cmpxchg ); 8200%} 8201 8202instruct xchgB( memory mem, rRegI newval) %{ 8203 match(Set newval (GetAndSetB mem newval)); 8204 format %{ "XCHGB $newval,[$mem]" %} 8205 ins_encode %{ 8206 __ xchgb($newval$$Register, $mem$$Address); 8207 %} 8208 ins_pipe( pipe_cmpxchg ); 8209%} 8210 8211instruct xchgS( memory mem, rRegI newval) %{ 8212 match(Set newval (GetAndSetS mem newval)); 8213 format %{ "XCHGW $newval,[$mem]" %} 8214 ins_encode %{ 8215 __ xchgw($newval$$Register, $mem$$Address); 8216 %} 8217 ins_pipe( pipe_cmpxchg ); 8218%} 8219 8220instruct xchgI( memory mem, rRegI newval) %{ 8221 match(Set newval (GetAndSetI mem newval)); 8222 format %{ "XCHGL $newval,[$mem]" %} 8223 ins_encode %{ 8224 __ xchgl($newval$$Register, $mem$$Address); 8225 %} 8226 ins_pipe( pipe_cmpxchg ); 8227%} 8228 8229instruct xchgL( memory mem, rRegL newval) %{ 8230 match(Set newval (GetAndSetL mem newval)); 8231 format %{ "XCHGL $newval,[$mem]" %} 8232 ins_encode %{ 8233 __ xchgq($newval$$Register, $mem$$Address); 8234 %} 8235 ins_pipe( pipe_cmpxchg ); 8236%} 8237 8238instruct xchgP( memory mem, rRegP newval) %{ 8239 match(Set newval (GetAndSetP mem newval)); 8240 format %{ "XCHGQ $newval,[$mem]" %} 8241 ins_encode %{ 8242 __ xchgq($newval$$Register, $mem$$Address); 8243 %} 8244 ins_pipe( pipe_cmpxchg ); 8245%} 8246 8247instruct xchgN( memory mem, rRegN newval) %{ 8248 match(Set newval (GetAndSetN mem newval)); 8249 format %{ "XCHGL $newval,$mem]" %} 8250 ins_encode %{ 8251 __ xchgl($newval$$Register, $mem$$Address); 8252 %} 8253 ins_pipe( pipe_cmpxchg ); 8254%} 8255 8256//----------Abs Instructions------------------------------------------- 8257 8258// Integer Absolute Instructions 8259instruct absI_rReg(rRegI dst, rRegI src, rRegI tmp, rFlagsReg cr) 8260%{ 8261 match(Set dst (AbsI src)); 8262 effect(TEMP dst, TEMP tmp, KILL cr); 8263 format %{ "movl $tmp, $src\n\t" 8264 "sarl $tmp, 31\n\t" 8265 "movl $dst, $src\n\t" 8266 "xorl $dst, $tmp\n\t" 8267 "subl $dst, $tmp\n" 8268 %} 8269 ins_encode %{ 8270 __ movl($tmp$$Register, $src$$Register); 8271 __ sarl($tmp$$Register, 31); 8272 __ movl($dst$$Register, $src$$Register); 8273 __ xorl($dst$$Register, $tmp$$Register); 8274 __ subl($dst$$Register, $tmp$$Register); 8275 %} 8276 8277 ins_pipe(ialu_reg_reg); 8278%} 8279 8280// Long Absolute Instructions 8281instruct absL_rReg(rRegL dst, rRegL src, rRegL tmp, rFlagsReg cr) 8282%{ 8283 match(Set dst (AbsL src)); 8284 effect(TEMP dst, TEMP tmp, KILL cr); 8285 format %{ "movq $tmp, $src\n\t" 8286 "sarq $tmp, 63\n\t" 8287 "movq $dst, $src\n\t" 8288 "xorq $dst, $tmp\n\t" 8289 "subq $dst, $tmp\n" 8290 %} 8291 ins_encode %{ 8292 __ movq($tmp$$Register, $src$$Register); 8293 __ sarq($tmp$$Register, 63); 8294 __ movq($dst$$Register, $src$$Register); 8295 __ xorq($dst$$Register, $tmp$$Register); 8296 __ subq($dst$$Register, $tmp$$Register); 8297 %} 8298 8299 ins_pipe(ialu_reg_reg); 8300%} 8301 8302//----------Subtraction Instructions------------------------------------------- 8303 8304// Integer Subtraction Instructions 8305instruct subI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8306%{ 8307 match(Set dst (SubI dst src)); 8308 effect(KILL cr); 8309 8310 format %{ "subl $dst, $src\t# int" %} 8311 opcode(0x2B); 8312 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 8313 ins_pipe(ialu_reg_reg); 8314%} 8315 8316instruct subI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 8317%{ 8318 match(Set dst (SubI dst src)); 8319 effect(KILL cr); 8320 8321 format %{ "subl $dst, $src\t# int" %} 8322 opcode(0x81, 0x05); /* Opcode 81 /5 */ 8323 ins_encode(OpcSErm(dst, src), Con8or32(src)); 8324 ins_pipe(ialu_reg); 8325%} 8326 8327instruct subI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 8328%{ 8329 match(Set dst (SubI dst (LoadI src))); 8330 effect(KILL cr); 8331 8332 ins_cost(125); 8333 format %{ "subl $dst, $src\t# int" %} 8334 opcode(0x2B); 8335 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 8336 ins_pipe(ialu_reg_mem); 8337%} 8338 8339instruct subI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 8340%{ 8341 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 8342 effect(KILL cr); 8343 8344 ins_cost(150); 8345 format %{ "subl $dst, $src\t# int" %} 8346 opcode(0x29); /* Opcode 29 /r */ 8347 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 8348 ins_pipe(ialu_mem_reg); 8349%} 8350 8351instruct subI_mem_imm(memory dst, immI src, rFlagsReg cr) 8352%{ 8353 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 8354 effect(KILL cr); 8355 8356 ins_cost(125); // XXX 8357 format %{ "subl $dst, $src\t# int" %} 8358 opcode(0x81); /* Opcode 81 /5 id */ 8359 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); 8360 ins_pipe(ialu_mem_imm); 8361%} 8362 8363instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 8364%{ 8365 match(Set dst (SubL dst src)); 8366 effect(KILL cr); 8367 8368 format %{ "subq $dst, $src\t# long" %} 8369 opcode(0x2B); 8370 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 8371 ins_pipe(ialu_reg_reg); 8372%} 8373 8374instruct subL_rReg_imm(rRegI dst, immL32 src, rFlagsReg cr) 8375%{ 8376 match(Set dst (SubL dst src)); 8377 effect(KILL cr); 8378 8379 format %{ "subq $dst, $src\t# long" %} 8380 opcode(0x81, 0x05); /* Opcode 81 /5 */ 8381 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 8382 ins_pipe(ialu_reg); 8383%} 8384 8385instruct subL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 8386%{ 8387 match(Set dst (SubL dst (LoadL src))); 8388 effect(KILL cr); 8389 8390 ins_cost(125); 8391 format %{ "subq $dst, $src\t# long" %} 8392 opcode(0x2B); 8393 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 8394 ins_pipe(ialu_reg_mem); 8395%} 8396 8397instruct subL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 8398%{ 8399 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 8400 effect(KILL cr); 8401 8402 ins_cost(150); 8403 format %{ "subq $dst, $src\t# long" %} 8404 opcode(0x29); /* Opcode 29 /r */ 8405 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 8406 ins_pipe(ialu_mem_reg); 8407%} 8408 8409instruct subL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 8410%{ 8411 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 8412 effect(KILL cr); 8413 8414 ins_cost(125); // XXX 8415 format %{ "subq $dst, $src\t# long" %} 8416 opcode(0x81); /* Opcode 81 /5 id */ 8417 ins_encode(REX_mem_wide(dst), 8418 OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); 8419 ins_pipe(ialu_mem_imm); 8420%} 8421 8422// Subtract from a pointer 8423// XXX hmpf??? 8424instruct subP_rReg(rRegP dst, rRegI src, immI0 zero, rFlagsReg cr) 8425%{ 8426 match(Set dst (AddP dst (SubI zero src))); 8427 effect(KILL cr); 8428 8429 format %{ "subq $dst, $src\t# ptr - int" %} 8430 opcode(0x2B); 8431 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 8432 ins_pipe(ialu_reg_reg); 8433%} 8434 8435instruct negI_rReg(rRegI dst, immI0 zero, rFlagsReg cr) 8436%{ 8437 match(Set dst (SubI zero dst)); 8438 effect(KILL cr); 8439 8440 format %{ "negl $dst\t# int" %} 8441 opcode(0xF7, 0x03); // Opcode F7 /3 8442 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8443 ins_pipe(ialu_reg); 8444%} 8445 8446instruct negI_mem(memory dst, immI0 zero, rFlagsReg cr) 8447%{ 8448 match(Set dst (StoreI dst (SubI zero (LoadI dst)))); 8449 effect(KILL cr); 8450 8451 format %{ "negl $dst\t# int" %} 8452 opcode(0xF7, 0x03); // Opcode F7 /3 8453 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8454 ins_pipe(ialu_reg); 8455%} 8456 8457instruct negL_rReg(rRegL dst, immL0 zero, rFlagsReg cr) 8458%{ 8459 match(Set dst (SubL zero dst)); 8460 effect(KILL cr); 8461 8462 format %{ "negq $dst\t# long" %} 8463 opcode(0xF7, 0x03); // Opcode F7 /3 8464 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8465 ins_pipe(ialu_reg); 8466%} 8467 8468instruct negL_mem(memory dst, immL0 zero, rFlagsReg cr) 8469%{ 8470 match(Set dst (StoreL dst (SubL zero (LoadL dst)))); 8471 effect(KILL cr); 8472 8473 format %{ "negq $dst\t# long" %} 8474 opcode(0xF7, 0x03); // Opcode F7 /3 8475 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8476 ins_pipe(ialu_reg); 8477%} 8478 8479//----------Multiplication/Division Instructions------------------------------- 8480// Integer Multiplication Instructions 8481// Multiply Register 8482 8483instruct mulI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8484%{ 8485 match(Set dst (MulI dst src)); 8486 effect(KILL cr); 8487 8488 ins_cost(300); 8489 format %{ "imull $dst, $src\t# int" %} 8490 opcode(0x0F, 0xAF); 8491 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8492 ins_pipe(ialu_reg_reg_alu0); 8493%} 8494 8495instruct mulI_rReg_imm(rRegI dst, rRegI src, immI imm, rFlagsReg cr) 8496%{ 8497 match(Set dst (MulI src imm)); 8498 effect(KILL cr); 8499 8500 ins_cost(300); 8501 format %{ "imull $dst, $src, $imm\t# int" %} 8502 opcode(0x69); /* 69 /r id */ 8503 ins_encode(REX_reg_reg(dst, src), 8504 OpcSE(imm), reg_reg(dst, src), Con8or32(imm)); 8505 ins_pipe(ialu_reg_reg_alu0); 8506%} 8507 8508instruct mulI_mem(rRegI dst, memory src, rFlagsReg cr) 8509%{ 8510 match(Set dst (MulI dst (LoadI src))); 8511 effect(KILL cr); 8512 8513 ins_cost(350); 8514 format %{ "imull $dst, $src\t# int" %} 8515 opcode(0x0F, 0xAF); 8516 ins_encode(REX_reg_mem(dst, src), OpcP, OpcS, reg_mem(dst, src)); 8517 ins_pipe(ialu_reg_mem_alu0); 8518%} 8519 8520instruct mulI_mem_imm(rRegI dst, memory src, immI imm, rFlagsReg cr) 8521%{ 8522 match(Set dst (MulI (LoadI src) imm)); 8523 effect(KILL cr); 8524 8525 ins_cost(300); 8526 format %{ "imull $dst, $src, $imm\t# int" %} 8527 opcode(0x69); /* 69 /r id */ 8528 ins_encode(REX_reg_mem(dst, src), 8529 OpcSE(imm), reg_mem(dst, src), Con8or32(imm)); 8530 ins_pipe(ialu_reg_mem_alu0); 8531%} 8532 8533instruct mulL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 8534%{ 8535 match(Set dst (MulL dst src)); 8536 effect(KILL cr); 8537 8538 ins_cost(300); 8539 format %{ "imulq $dst, $src\t# long" %} 8540 opcode(0x0F, 0xAF); 8541 ins_encode(REX_reg_reg_wide(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8542 ins_pipe(ialu_reg_reg_alu0); 8543%} 8544 8545instruct mulL_rReg_imm(rRegL dst, rRegL src, immL32 imm, rFlagsReg cr) 8546%{ 8547 match(Set dst (MulL src imm)); 8548 effect(KILL cr); 8549 8550 ins_cost(300); 8551 format %{ "imulq $dst, $src, $imm\t# long" %} 8552 opcode(0x69); /* 69 /r id */ 8553 ins_encode(REX_reg_reg_wide(dst, src), 8554 OpcSE(imm), reg_reg(dst, src), Con8or32(imm)); 8555 ins_pipe(ialu_reg_reg_alu0); 8556%} 8557 8558instruct mulL_mem(rRegL dst, memory src, rFlagsReg cr) 8559%{ 8560 match(Set dst (MulL dst (LoadL src))); 8561 effect(KILL cr); 8562 8563 ins_cost(350); 8564 format %{ "imulq $dst, $src\t# long" %} 8565 opcode(0x0F, 0xAF); 8566 ins_encode(REX_reg_mem_wide(dst, src), OpcP, OpcS, reg_mem(dst, src)); 8567 ins_pipe(ialu_reg_mem_alu0); 8568%} 8569 8570instruct mulL_mem_imm(rRegL dst, memory src, immL32 imm, rFlagsReg cr) 8571%{ 8572 match(Set dst (MulL (LoadL src) imm)); 8573 effect(KILL cr); 8574 8575 ins_cost(300); 8576 format %{ "imulq $dst, $src, $imm\t# long" %} 8577 opcode(0x69); /* 69 /r id */ 8578 ins_encode(REX_reg_mem_wide(dst, src), 8579 OpcSE(imm), reg_mem(dst, src), Con8or32(imm)); 8580 ins_pipe(ialu_reg_mem_alu0); 8581%} 8582 8583instruct mulHiL_rReg(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr) 8584%{ 8585 match(Set dst (MulHiL src rax)); 8586 effect(USE_KILL rax, KILL cr); 8587 8588 ins_cost(300); 8589 format %{ "imulq RDX:RAX, RAX, $src\t# mulhi" %} 8590 opcode(0xF7, 0x5); /* Opcode F7 /5 */ 8591 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); 8592 ins_pipe(ialu_reg_reg_alu0); 8593%} 8594 8595instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 8596 rFlagsReg cr) 8597%{ 8598 match(Set rax (DivI rax div)); 8599 effect(KILL rdx, KILL cr); 8600 8601 ins_cost(30*100+10*100); // XXX 8602 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 8603 "jne,s normal\n\t" 8604 "xorl rdx, rdx\n\t" 8605 "cmpl $div, -1\n\t" 8606 "je,s done\n" 8607 "normal: cdql\n\t" 8608 "idivl $div\n" 8609 "done:" %} 8610 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8611 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8612 ins_pipe(ialu_reg_reg_alu0); 8613%} 8614 8615instruct divL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 8616 rFlagsReg cr) 8617%{ 8618 match(Set rax (DivL rax div)); 8619 effect(KILL rdx, KILL cr); 8620 8621 ins_cost(30*100+10*100); // XXX 8622 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 8623 "cmpq rax, rdx\n\t" 8624 "jne,s normal\n\t" 8625 "xorl rdx, rdx\n\t" 8626 "cmpq $div, -1\n\t" 8627 "je,s done\n" 8628 "normal: cdqq\n\t" 8629 "idivq $div\n" 8630 "done:" %} 8631 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8632 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8633 ins_pipe(ialu_reg_reg_alu0); 8634%} 8635 8636// Integer DIVMOD with Register, both quotient and mod results 8637instruct divModI_rReg_divmod(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 8638 rFlagsReg cr) 8639%{ 8640 match(DivModI rax div); 8641 effect(KILL cr); 8642 8643 ins_cost(30*100+10*100); // XXX 8644 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 8645 "jne,s normal\n\t" 8646 "xorl rdx, rdx\n\t" 8647 "cmpl $div, -1\n\t" 8648 "je,s done\n" 8649 "normal: cdql\n\t" 8650 "idivl $div\n" 8651 "done:" %} 8652 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8653 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8654 ins_pipe(pipe_slow); 8655%} 8656 8657// Long DIVMOD with Register, both quotient and mod results 8658instruct divModL_rReg_divmod(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 8659 rFlagsReg cr) 8660%{ 8661 match(DivModL rax div); 8662 effect(KILL cr); 8663 8664 ins_cost(30*100+10*100); // XXX 8665 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 8666 "cmpq rax, rdx\n\t" 8667 "jne,s normal\n\t" 8668 "xorl rdx, rdx\n\t" 8669 "cmpq $div, -1\n\t" 8670 "je,s done\n" 8671 "normal: cdqq\n\t" 8672 "idivq $div\n" 8673 "done:" %} 8674 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8675 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8676 ins_pipe(pipe_slow); 8677%} 8678 8679//----------- DivL-By-Constant-Expansions-------------------------------------- 8680// DivI cases are handled by the compiler 8681 8682// Magic constant, reciprocal of 10 8683instruct loadConL_0x6666666666666667(rRegL dst) 8684%{ 8685 effect(DEF dst); 8686 8687 format %{ "movq $dst, #0x666666666666667\t# Used in div-by-10" %} 8688 ins_encode(load_immL(dst, 0x6666666666666667)); 8689 ins_pipe(ialu_reg); 8690%} 8691 8692instruct mul_hi(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr) 8693%{ 8694 effect(DEF dst, USE src, USE_KILL rax, KILL cr); 8695 8696 format %{ "imulq rdx:rax, rax, $src\t# Used in div-by-10" %} 8697 opcode(0xF7, 0x5); /* Opcode F7 /5 */ 8698 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); 8699 ins_pipe(ialu_reg_reg_alu0); 8700%} 8701 8702instruct sarL_rReg_63(rRegL dst, rFlagsReg cr) 8703%{ 8704 effect(USE_DEF dst, KILL cr); 8705 8706 format %{ "sarq $dst, #63\t# Used in div-by-10" %} 8707 opcode(0xC1, 0x7); /* C1 /7 ib */ 8708 ins_encode(reg_opc_imm_wide(dst, 0x3F)); 8709 ins_pipe(ialu_reg); 8710%} 8711 8712instruct sarL_rReg_2(rRegL dst, rFlagsReg cr) 8713%{ 8714 effect(USE_DEF dst, KILL cr); 8715 8716 format %{ "sarq $dst, #2\t# Used in div-by-10" %} 8717 opcode(0xC1, 0x7); /* C1 /7 ib */ 8718 ins_encode(reg_opc_imm_wide(dst, 0x2)); 8719 ins_pipe(ialu_reg); 8720%} 8721 8722instruct divL_10(rdx_RegL dst, no_rax_RegL src, immL10 div) 8723%{ 8724 match(Set dst (DivL src div)); 8725 8726 ins_cost((5+8)*100); 8727 expand %{ 8728 rax_RegL rax; // Killed temp 8729 rFlagsReg cr; // Killed 8730 loadConL_0x6666666666666667(rax); // movq rax, 0x6666666666666667 8731 mul_hi(dst, src, rax, cr); // mulq rdx:rax <= rax * $src 8732 sarL_rReg_63(src, cr); // sarq src, 63 8733 sarL_rReg_2(dst, cr); // sarq rdx, 2 8734 subL_rReg(dst, src, cr); // subl rdx, src 8735 %} 8736%} 8737 8738//----------------------------------------------------------------------------- 8739 8740instruct modI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, 8741 rFlagsReg cr) 8742%{ 8743 match(Set rdx (ModI rax div)); 8744 effect(KILL rax, KILL cr); 8745 8746 ins_cost(300); // XXX 8747 format %{ "cmpl rax, 0x80000000\t# irem\n\t" 8748 "jne,s normal\n\t" 8749 "xorl rdx, rdx\n\t" 8750 "cmpl $div, -1\n\t" 8751 "je,s done\n" 8752 "normal: cdql\n\t" 8753 "idivl $div\n" 8754 "done:" %} 8755 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8756 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8757 ins_pipe(ialu_reg_reg_alu0); 8758%} 8759 8760instruct modL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, 8761 rFlagsReg cr) 8762%{ 8763 match(Set rdx (ModL rax div)); 8764 effect(KILL rax, KILL cr); 8765 8766 ins_cost(300); // XXX 8767 format %{ "movq rdx, 0x8000000000000000\t# lrem\n\t" 8768 "cmpq rax, rdx\n\t" 8769 "jne,s normal\n\t" 8770 "xorl rdx, rdx\n\t" 8771 "cmpq $div, -1\n\t" 8772 "je,s done\n" 8773 "normal: cdqq\n\t" 8774 "idivq $div\n" 8775 "done:" %} 8776 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8777 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8778 ins_pipe(ialu_reg_reg_alu0); 8779%} 8780 8781// Integer Shift Instructions 8782// Shift Left by one 8783instruct salI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8784%{ 8785 match(Set dst (LShiftI dst shift)); 8786 effect(KILL cr); 8787 8788 format %{ "sall $dst, $shift" %} 8789 opcode(0xD1, 0x4); /* D1 /4 */ 8790 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8791 ins_pipe(ialu_reg); 8792%} 8793 8794// Shift Left by one 8795instruct salI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8796%{ 8797 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8798 effect(KILL cr); 8799 8800 format %{ "sall $dst, $shift\t" %} 8801 opcode(0xD1, 0x4); /* D1 /4 */ 8802 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8803 ins_pipe(ialu_mem_imm); 8804%} 8805 8806// Shift Left by 8-bit immediate 8807instruct salI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8808%{ 8809 match(Set dst (LShiftI dst shift)); 8810 effect(KILL cr); 8811 8812 format %{ "sall $dst, $shift" %} 8813 opcode(0xC1, 0x4); /* C1 /4 ib */ 8814 ins_encode(reg_opc_imm(dst, shift)); 8815 ins_pipe(ialu_reg); 8816%} 8817 8818// Shift Left by 8-bit immediate 8819instruct salI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8820%{ 8821 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8822 effect(KILL cr); 8823 8824 format %{ "sall $dst, $shift" %} 8825 opcode(0xC1, 0x4); /* C1 /4 ib */ 8826 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8827 ins_pipe(ialu_mem_imm); 8828%} 8829 8830// Shift Left by variable 8831instruct salI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8832%{ 8833 match(Set dst (LShiftI dst shift)); 8834 effect(KILL cr); 8835 8836 format %{ "sall $dst, $shift" %} 8837 opcode(0xD3, 0x4); /* D3 /4 */ 8838 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8839 ins_pipe(ialu_reg_reg); 8840%} 8841 8842// Shift Left by variable 8843instruct salI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8844%{ 8845 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8846 effect(KILL cr); 8847 8848 format %{ "sall $dst, $shift" %} 8849 opcode(0xD3, 0x4); /* D3 /4 */ 8850 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8851 ins_pipe(ialu_mem_reg); 8852%} 8853 8854// Arithmetic shift right by one 8855instruct sarI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8856%{ 8857 match(Set dst (RShiftI dst shift)); 8858 effect(KILL cr); 8859 8860 format %{ "sarl $dst, $shift" %} 8861 opcode(0xD1, 0x7); /* D1 /7 */ 8862 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8863 ins_pipe(ialu_reg); 8864%} 8865 8866// Arithmetic shift right by one 8867instruct sarI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8868%{ 8869 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8870 effect(KILL cr); 8871 8872 format %{ "sarl $dst, $shift" %} 8873 opcode(0xD1, 0x7); /* D1 /7 */ 8874 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8875 ins_pipe(ialu_mem_imm); 8876%} 8877 8878// Arithmetic Shift Right by 8-bit immediate 8879instruct sarI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8880%{ 8881 match(Set dst (RShiftI dst shift)); 8882 effect(KILL cr); 8883 8884 format %{ "sarl $dst, $shift" %} 8885 opcode(0xC1, 0x7); /* C1 /7 ib */ 8886 ins_encode(reg_opc_imm(dst, shift)); 8887 ins_pipe(ialu_mem_imm); 8888%} 8889 8890// Arithmetic Shift Right by 8-bit immediate 8891instruct sarI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8892%{ 8893 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8894 effect(KILL cr); 8895 8896 format %{ "sarl $dst, $shift" %} 8897 opcode(0xC1, 0x7); /* C1 /7 ib */ 8898 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8899 ins_pipe(ialu_mem_imm); 8900%} 8901 8902// Arithmetic Shift Right by variable 8903instruct sarI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8904%{ 8905 match(Set dst (RShiftI dst shift)); 8906 effect(KILL cr); 8907 8908 format %{ "sarl $dst, $shift" %} 8909 opcode(0xD3, 0x7); /* D3 /7 */ 8910 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8911 ins_pipe(ialu_reg_reg); 8912%} 8913 8914// Arithmetic Shift Right by variable 8915instruct sarI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8916%{ 8917 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8918 effect(KILL cr); 8919 8920 format %{ "sarl $dst, $shift" %} 8921 opcode(0xD3, 0x7); /* D3 /7 */ 8922 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8923 ins_pipe(ialu_mem_reg); 8924%} 8925 8926// Logical shift right by one 8927instruct shrI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8928%{ 8929 match(Set dst (URShiftI dst shift)); 8930 effect(KILL cr); 8931 8932 format %{ "shrl $dst, $shift" %} 8933 opcode(0xD1, 0x5); /* D1 /5 */ 8934 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8935 ins_pipe(ialu_reg); 8936%} 8937 8938// Logical shift right by one 8939instruct shrI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8940%{ 8941 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8942 effect(KILL cr); 8943 8944 format %{ "shrl $dst, $shift" %} 8945 opcode(0xD1, 0x5); /* D1 /5 */ 8946 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8947 ins_pipe(ialu_mem_imm); 8948%} 8949 8950// Logical Shift Right by 8-bit immediate 8951instruct shrI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8952%{ 8953 match(Set dst (URShiftI dst shift)); 8954 effect(KILL cr); 8955 8956 format %{ "shrl $dst, $shift" %} 8957 opcode(0xC1, 0x5); /* C1 /5 ib */ 8958 ins_encode(reg_opc_imm(dst, shift)); 8959 ins_pipe(ialu_reg); 8960%} 8961 8962// Logical Shift Right by 8-bit immediate 8963instruct shrI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8964%{ 8965 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8966 effect(KILL cr); 8967 8968 format %{ "shrl $dst, $shift" %} 8969 opcode(0xC1, 0x5); /* C1 /5 ib */ 8970 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8971 ins_pipe(ialu_mem_imm); 8972%} 8973 8974// Logical Shift Right by variable 8975instruct shrI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8976%{ 8977 match(Set dst (URShiftI dst shift)); 8978 effect(KILL cr); 8979 8980 format %{ "shrl $dst, $shift" %} 8981 opcode(0xD3, 0x5); /* D3 /5 */ 8982 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8983 ins_pipe(ialu_reg_reg); 8984%} 8985 8986// Logical Shift Right by variable 8987instruct shrI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8988%{ 8989 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8990 effect(KILL cr); 8991 8992 format %{ "shrl $dst, $shift" %} 8993 opcode(0xD3, 0x5); /* D3 /5 */ 8994 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8995 ins_pipe(ialu_mem_reg); 8996%} 8997 8998// Long Shift Instructions 8999// Shift Left by one 9000instruct salL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 9001%{ 9002 match(Set dst (LShiftL dst shift)); 9003 effect(KILL cr); 9004 9005 format %{ "salq $dst, $shift" %} 9006 opcode(0xD1, 0x4); /* D1 /4 */ 9007 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9008 ins_pipe(ialu_reg); 9009%} 9010 9011// Shift Left by one 9012instruct salL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 9013%{ 9014 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 9015 effect(KILL cr); 9016 9017 format %{ "salq $dst, $shift" %} 9018 opcode(0xD1, 0x4); /* D1 /4 */ 9019 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 9020 ins_pipe(ialu_mem_imm); 9021%} 9022 9023// Shift Left by 8-bit immediate 9024instruct salL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 9025%{ 9026 match(Set dst (LShiftL dst shift)); 9027 effect(KILL cr); 9028 9029 format %{ "salq $dst, $shift" %} 9030 opcode(0xC1, 0x4); /* C1 /4 ib */ 9031 ins_encode(reg_opc_imm_wide(dst, shift)); 9032 ins_pipe(ialu_reg); 9033%} 9034 9035// Shift Left by 8-bit immediate 9036instruct salL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 9037%{ 9038 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 9039 effect(KILL cr); 9040 9041 format %{ "salq $dst, $shift" %} 9042 opcode(0xC1, 0x4); /* C1 /4 ib */ 9043 ins_encode(REX_mem_wide(dst), OpcP, 9044 RM_opc_mem(secondary, dst), Con8or32(shift)); 9045 ins_pipe(ialu_mem_imm); 9046%} 9047 9048// Shift Left by variable 9049instruct salL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 9050%{ 9051 match(Set dst (LShiftL dst shift)); 9052 effect(KILL cr); 9053 9054 format %{ "salq $dst, $shift" %} 9055 opcode(0xD3, 0x4); /* D3 /4 */ 9056 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9057 ins_pipe(ialu_reg_reg); 9058%} 9059 9060// Shift Left by variable 9061instruct salL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 9062%{ 9063 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 9064 effect(KILL cr); 9065 9066 format %{ "salq $dst, $shift" %} 9067 opcode(0xD3, 0x4); /* D3 /4 */ 9068 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 9069 ins_pipe(ialu_mem_reg); 9070%} 9071 9072// Arithmetic shift right by one 9073instruct sarL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 9074%{ 9075 match(Set dst (RShiftL dst shift)); 9076 effect(KILL cr); 9077 9078 format %{ "sarq $dst, $shift" %} 9079 opcode(0xD1, 0x7); /* D1 /7 */ 9080 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9081 ins_pipe(ialu_reg); 9082%} 9083 9084// Arithmetic shift right by one 9085instruct sarL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 9086%{ 9087 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 9088 effect(KILL cr); 9089 9090 format %{ "sarq $dst, $shift" %} 9091 opcode(0xD1, 0x7); /* D1 /7 */ 9092 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 9093 ins_pipe(ialu_mem_imm); 9094%} 9095 9096// Arithmetic Shift Right by 8-bit immediate 9097instruct sarL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 9098%{ 9099 match(Set dst (RShiftL dst shift)); 9100 effect(KILL cr); 9101 9102 format %{ "sarq $dst, $shift" %} 9103 opcode(0xC1, 0x7); /* C1 /7 ib */ 9104 ins_encode(reg_opc_imm_wide(dst, shift)); 9105 ins_pipe(ialu_mem_imm); 9106%} 9107 9108// Arithmetic Shift Right by 8-bit immediate 9109instruct sarL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 9110%{ 9111 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 9112 effect(KILL cr); 9113 9114 format %{ "sarq $dst, $shift" %} 9115 opcode(0xC1, 0x7); /* C1 /7 ib */ 9116 ins_encode(REX_mem_wide(dst), OpcP, 9117 RM_opc_mem(secondary, dst), Con8or32(shift)); 9118 ins_pipe(ialu_mem_imm); 9119%} 9120 9121// Arithmetic Shift Right by variable 9122instruct sarL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 9123%{ 9124 match(Set dst (RShiftL dst shift)); 9125 effect(KILL cr); 9126 9127 format %{ "sarq $dst, $shift" %} 9128 opcode(0xD3, 0x7); /* D3 /7 */ 9129 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9130 ins_pipe(ialu_reg_reg); 9131%} 9132 9133// Arithmetic Shift Right by variable 9134instruct sarL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 9135%{ 9136 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 9137 effect(KILL cr); 9138 9139 format %{ "sarq $dst, $shift" %} 9140 opcode(0xD3, 0x7); /* D3 /7 */ 9141 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 9142 ins_pipe(ialu_mem_reg); 9143%} 9144 9145// Logical shift right by one 9146instruct shrL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 9147%{ 9148 match(Set dst (URShiftL dst shift)); 9149 effect(KILL cr); 9150 9151 format %{ "shrq $dst, $shift" %} 9152 opcode(0xD1, 0x5); /* D1 /5 */ 9153 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst )); 9154 ins_pipe(ialu_reg); 9155%} 9156 9157// Logical shift right by one 9158instruct shrL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 9159%{ 9160 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 9161 effect(KILL cr); 9162 9163 format %{ "shrq $dst, $shift" %} 9164 opcode(0xD1, 0x5); /* D1 /5 */ 9165 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 9166 ins_pipe(ialu_mem_imm); 9167%} 9168 9169// Logical Shift Right by 8-bit immediate 9170instruct shrL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 9171%{ 9172 match(Set dst (URShiftL dst shift)); 9173 effect(KILL cr); 9174 9175 format %{ "shrq $dst, $shift" %} 9176 opcode(0xC1, 0x5); /* C1 /5 ib */ 9177 ins_encode(reg_opc_imm_wide(dst, shift)); 9178 ins_pipe(ialu_reg); 9179%} 9180 9181 9182// Logical Shift Right by 8-bit immediate 9183instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 9184%{ 9185 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 9186 effect(KILL cr); 9187 9188 format %{ "shrq $dst, $shift" %} 9189 opcode(0xC1, 0x5); /* C1 /5 ib */ 9190 ins_encode(REX_mem_wide(dst), OpcP, 9191 RM_opc_mem(secondary, dst), Con8or32(shift)); 9192 ins_pipe(ialu_mem_imm); 9193%} 9194 9195// Logical Shift Right by variable 9196instruct shrL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 9197%{ 9198 match(Set dst (URShiftL dst shift)); 9199 effect(KILL cr); 9200 9201 format %{ "shrq $dst, $shift" %} 9202 opcode(0xD3, 0x5); /* D3 /5 */ 9203 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9204 ins_pipe(ialu_reg_reg); 9205%} 9206 9207// Logical Shift Right by variable 9208instruct shrL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 9209%{ 9210 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 9211 effect(KILL cr); 9212 9213 format %{ "shrq $dst, $shift" %} 9214 opcode(0xD3, 0x5); /* D3 /5 */ 9215 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 9216 ins_pipe(ialu_mem_reg); 9217%} 9218 9219// Logical Shift Right by 24, followed by Arithmetic Shift Left by 24. 9220// This idiom is used by the compiler for the i2b bytecode. 9221instruct i2b(rRegI dst, rRegI src, immI_24 twentyfour) 9222%{ 9223 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour)); 9224 9225 format %{ "movsbl $dst, $src\t# i2b" %} 9226 opcode(0x0F, 0xBE); 9227 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 9228 ins_pipe(ialu_reg_reg); 9229%} 9230 9231// Logical Shift Right by 16, followed by Arithmetic Shift Left by 16. 9232// This idiom is used by the compiler the i2s bytecode. 9233instruct i2s(rRegI dst, rRegI src, immI_16 sixteen) 9234%{ 9235 match(Set dst (RShiftI (LShiftI src sixteen) sixteen)); 9236 9237 format %{ "movswl $dst, $src\t# i2s" %} 9238 opcode(0x0F, 0xBF); 9239 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 9240 ins_pipe(ialu_reg_reg); 9241%} 9242 9243// ROL/ROR instructions 9244 9245// ROL expand 9246instruct rolI_rReg_imm1(rRegI dst, rFlagsReg cr) %{ 9247 effect(KILL cr, USE_DEF dst); 9248 9249 format %{ "roll $dst" %} 9250 opcode(0xD1, 0x0); /* Opcode D1 /0 */ 9251 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 9252 ins_pipe(ialu_reg); 9253%} 9254 9255instruct rolI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) %{ 9256 effect(USE_DEF dst, USE shift, KILL cr); 9257 9258 format %{ "roll $dst, $shift" %} 9259 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */ 9260 ins_encode( reg_opc_imm(dst, shift) ); 9261 ins_pipe(ialu_reg); 9262%} 9263 9264instruct rolI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr) 9265%{ 9266 effect(USE_DEF dst, USE shift, KILL cr); 9267 9268 format %{ "roll $dst, $shift" %} 9269 opcode(0xD3, 0x0); /* Opcode D3 /0 */ 9270 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 9271 ins_pipe(ialu_reg_reg); 9272%} 9273// end of ROL expand 9274 9275// Rotate Left by one 9276instruct rolI_rReg_i1(rRegI dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr) 9277%{ 9278 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift))); 9279 9280 expand %{ 9281 rolI_rReg_imm1(dst, cr); 9282 %} 9283%} 9284 9285// Rotate Left by 8-bit immediate 9286instruct rolI_rReg_i8(rRegI dst, immI8 lshift, immI8 rshift, rFlagsReg cr) 9287%{ 9288 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9289 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift))); 9290 9291 expand %{ 9292 rolI_rReg_imm8(dst, lshift, cr); 9293 %} 9294%} 9295 9296// Rotate Left by variable 9297instruct rolI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 9298%{ 9299 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI zero shift)))); 9300 9301 expand %{ 9302 rolI_rReg_CL(dst, shift, cr); 9303 %} 9304%} 9305 9306// Rotate Left by variable 9307instruct rolI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr) 9308%{ 9309 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI c32 shift)))); 9310 9311 expand %{ 9312 rolI_rReg_CL(dst, shift, cr); 9313 %} 9314%} 9315 9316// ROR expand 9317instruct rorI_rReg_imm1(rRegI dst, rFlagsReg cr) 9318%{ 9319 effect(USE_DEF dst, KILL cr); 9320 9321 format %{ "rorl $dst" %} 9322 opcode(0xD1, 0x1); /* D1 /1 */ 9323 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 9324 ins_pipe(ialu_reg); 9325%} 9326 9327instruct rorI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) 9328%{ 9329 effect(USE_DEF dst, USE shift, KILL cr); 9330 9331 format %{ "rorl $dst, $shift" %} 9332 opcode(0xC1, 0x1); /* C1 /1 ib */ 9333 ins_encode(reg_opc_imm(dst, shift)); 9334 ins_pipe(ialu_reg); 9335%} 9336 9337instruct rorI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr) 9338%{ 9339 effect(USE_DEF dst, USE shift, KILL cr); 9340 9341 format %{ "rorl $dst, $shift" %} 9342 opcode(0xD3, 0x1); /* D3 /1 */ 9343 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 9344 ins_pipe(ialu_reg_reg); 9345%} 9346// end of ROR expand 9347 9348// Rotate Right by one 9349instruct rorI_rReg_i1(rRegI dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr) 9350%{ 9351 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift))); 9352 9353 expand %{ 9354 rorI_rReg_imm1(dst, cr); 9355 %} 9356%} 9357 9358// Rotate Right by 8-bit immediate 9359instruct rorI_rReg_i8(rRegI dst, immI8 rshift, immI8 lshift, rFlagsReg cr) 9360%{ 9361 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9362 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift))); 9363 9364 expand %{ 9365 rorI_rReg_imm8(dst, rshift, cr); 9366 %} 9367%} 9368 9369// Rotate Right by variable 9370instruct rorI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 9371%{ 9372 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI zero shift)))); 9373 9374 expand %{ 9375 rorI_rReg_CL(dst, shift, cr); 9376 %} 9377%} 9378 9379// Rotate Right by variable 9380instruct rorI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr) 9381%{ 9382 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI c32 shift)))); 9383 9384 expand %{ 9385 rorI_rReg_CL(dst, shift, cr); 9386 %} 9387%} 9388 9389// for long rotate 9390// ROL expand 9391instruct rolL_rReg_imm1(rRegL dst, rFlagsReg cr) %{ 9392 effect(USE_DEF dst, KILL cr); 9393 9394 format %{ "rolq $dst" %} 9395 opcode(0xD1, 0x0); /* Opcode D1 /0 */ 9396 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9397 ins_pipe(ialu_reg); 9398%} 9399 9400instruct rolL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) %{ 9401 effect(USE_DEF dst, USE shift, KILL cr); 9402 9403 format %{ "rolq $dst, $shift" %} 9404 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */ 9405 ins_encode( reg_opc_imm_wide(dst, shift) ); 9406 ins_pipe(ialu_reg); 9407%} 9408 9409instruct rolL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr) 9410%{ 9411 effect(USE_DEF dst, USE shift, KILL cr); 9412 9413 format %{ "rolq $dst, $shift" %} 9414 opcode(0xD3, 0x0); /* Opcode D3 /0 */ 9415 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9416 ins_pipe(ialu_reg_reg); 9417%} 9418// end of ROL expand 9419 9420// Rotate Left by one 9421instruct rolL_rReg_i1(rRegL dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr) 9422%{ 9423 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift))); 9424 9425 expand %{ 9426 rolL_rReg_imm1(dst, cr); 9427 %} 9428%} 9429 9430// Rotate Left by 8-bit immediate 9431instruct rolL_rReg_i8(rRegL dst, immI8 lshift, immI8 rshift, rFlagsReg cr) 9432%{ 9433 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f)); 9434 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift))); 9435 9436 expand %{ 9437 rolL_rReg_imm8(dst, lshift, cr); 9438 %} 9439%} 9440 9441// Rotate Left by variable 9442instruct rolL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 9443%{ 9444 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI zero shift)))); 9445 9446 expand %{ 9447 rolL_rReg_CL(dst, shift, cr); 9448 %} 9449%} 9450 9451// Rotate Left by variable 9452instruct rolL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr) 9453%{ 9454 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI c64 shift)))); 9455 9456 expand %{ 9457 rolL_rReg_CL(dst, shift, cr); 9458 %} 9459%} 9460 9461// ROR expand 9462instruct rorL_rReg_imm1(rRegL dst, rFlagsReg cr) 9463%{ 9464 effect(USE_DEF dst, KILL cr); 9465 9466 format %{ "rorq $dst" %} 9467 opcode(0xD1, 0x1); /* D1 /1 */ 9468 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9469 ins_pipe(ialu_reg); 9470%} 9471 9472instruct rorL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) 9473%{ 9474 effect(USE_DEF dst, USE shift, KILL cr); 9475 9476 format %{ "rorq $dst, $shift" %} 9477 opcode(0xC1, 0x1); /* C1 /1 ib */ 9478 ins_encode(reg_opc_imm_wide(dst, shift)); 9479 ins_pipe(ialu_reg); 9480%} 9481 9482instruct rorL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr) 9483%{ 9484 effect(USE_DEF dst, USE shift, KILL cr); 9485 9486 format %{ "rorq $dst, $shift" %} 9487 opcode(0xD3, 0x1); /* D3 /1 */ 9488 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 9489 ins_pipe(ialu_reg_reg); 9490%} 9491// end of ROR expand 9492 9493// Rotate Right by one 9494instruct rorL_rReg_i1(rRegL dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr) 9495%{ 9496 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift))); 9497 9498 expand %{ 9499 rorL_rReg_imm1(dst, cr); 9500 %} 9501%} 9502 9503// Rotate Right by 8-bit immediate 9504instruct rorL_rReg_i8(rRegL dst, immI8 rshift, immI8 lshift, rFlagsReg cr) 9505%{ 9506 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f)); 9507 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift))); 9508 9509 expand %{ 9510 rorL_rReg_imm8(dst, rshift, cr); 9511 %} 9512%} 9513 9514// Rotate Right by variable 9515instruct rorL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 9516%{ 9517 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI zero shift)))); 9518 9519 expand %{ 9520 rorL_rReg_CL(dst, shift, cr); 9521 %} 9522%} 9523 9524// Rotate Right by variable 9525instruct rorL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr) 9526%{ 9527 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI c64 shift)))); 9528 9529 expand %{ 9530 rorL_rReg_CL(dst, shift, cr); 9531 %} 9532%} 9533 9534// Logical Instructions 9535 9536// Integer Logical Instructions 9537 9538// And Instructions 9539// And Register with Register 9540instruct andI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9541%{ 9542 match(Set dst (AndI dst src)); 9543 effect(KILL cr); 9544 9545 format %{ "andl $dst, $src\t# int" %} 9546 opcode(0x23); 9547 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9548 ins_pipe(ialu_reg_reg); 9549%} 9550 9551// And Register with Immediate 255 9552instruct andI_rReg_imm255(rRegI dst, immI_255 src) 9553%{ 9554 match(Set dst (AndI dst src)); 9555 9556 format %{ "movzbl $dst, $dst\t# int & 0xFF" %} 9557 opcode(0x0F, 0xB6); 9558 ins_encode(REX_reg_breg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9559 ins_pipe(ialu_reg); 9560%} 9561 9562// And Register with Immediate 255 and promote to long 9563instruct andI2L_rReg_imm255(rRegL dst, rRegI src, immI_255 mask) 9564%{ 9565 match(Set dst (ConvI2L (AndI src mask))); 9566 9567 format %{ "movzbl $dst, $src\t# int & 0xFF -> long" %} 9568 opcode(0x0F, 0xB6); 9569 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 9570 ins_pipe(ialu_reg); 9571%} 9572 9573// And Register with Immediate 65535 9574instruct andI_rReg_imm65535(rRegI dst, immI_65535 src) 9575%{ 9576 match(Set dst (AndI dst src)); 9577 9578 format %{ "movzwl $dst, $dst\t# int & 0xFFFF" %} 9579 opcode(0x0F, 0xB7); 9580 ins_encode(REX_reg_reg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9581 ins_pipe(ialu_reg); 9582%} 9583 9584// And Register with Immediate 65535 and promote to long 9585instruct andI2L_rReg_imm65535(rRegL dst, rRegI src, immI_65535 mask) 9586%{ 9587 match(Set dst (ConvI2L (AndI src mask))); 9588 9589 format %{ "movzwl $dst, $src\t# int & 0xFFFF -> long" %} 9590 opcode(0x0F, 0xB7); 9591 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 9592 ins_pipe(ialu_reg); 9593%} 9594 9595// And Register with Immediate 9596instruct andI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9597%{ 9598 match(Set dst (AndI dst src)); 9599 effect(KILL cr); 9600 9601 format %{ "andl $dst, $src\t# int" %} 9602 opcode(0x81, 0x04); /* Opcode 81 /4 */ 9603 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9604 ins_pipe(ialu_reg); 9605%} 9606 9607// And Register with Memory 9608instruct andI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9609%{ 9610 match(Set dst (AndI dst (LoadI src))); 9611 effect(KILL cr); 9612 9613 ins_cost(125); 9614 format %{ "andl $dst, $src\t# int" %} 9615 opcode(0x23); 9616 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9617 ins_pipe(ialu_reg_mem); 9618%} 9619 9620// And Memory with Register 9621instruct andI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9622%{ 9623 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 9624 effect(KILL cr); 9625 9626 ins_cost(150); 9627 format %{ "andl $dst, $src\t# int" %} 9628 opcode(0x21); /* Opcode 21 /r */ 9629 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9630 ins_pipe(ialu_mem_reg); 9631%} 9632 9633// And Memory with Immediate 9634instruct andI_mem_imm(memory dst, immI src, rFlagsReg cr) 9635%{ 9636 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 9637 effect(KILL cr); 9638 9639 ins_cost(125); 9640 format %{ "andl $dst, $src\t# int" %} 9641 opcode(0x81, 0x4); /* Opcode 81 /4 id */ 9642 ins_encode(REX_mem(dst), OpcSE(src), 9643 RM_opc_mem(secondary, dst), Con8or32(src)); 9644 ins_pipe(ialu_mem_imm); 9645%} 9646 9647// BMI1 instructions 9648instruct andnI_rReg_rReg_mem(rRegI dst, rRegI src1, memory src2, immI_M1 minus_1, rFlagsReg cr) %{ 9649 match(Set dst (AndI (XorI src1 minus_1) (LoadI src2))); 9650 predicate(UseBMI1Instructions); 9651 effect(KILL cr); 9652 9653 ins_cost(125); 9654 format %{ "andnl $dst, $src1, $src2" %} 9655 9656 ins_encode %{ 9657 __ andnl($dst$$Register, $src1$$Register, $src2$$Address); 9658 %} 9659 ins_pipe(ialu_reg_mem); 9660%} 9661 9662instruct andnI_rReg_rReg_rReg(rRegI dst, rRegI src1, rRegI src2, immI_M1 minus_1, rFlagsReg cr) %{ 9663 match(Set dst (AndI (XorI src1 minus_1) src2)); 9664 predicate(UseBMI1Instructions); 9665 effect(KILL cr); 9666 9667 format %{ "andnl $dst, $src1, $src2" %} 9668 9669 ins_encode %{ 9670 __ andnl($dst$$Register, $src1$$Register, $src2$$Register); 9671 %} 9672 ins_pipe(ialu_reg); 9673%} 9674 9675instruct blsiI_rReg_rReg(rRegI dst, rRegI src, immI0 imm_zero, rFlagsReg cr) %{ 9676 match(Set dst (AndI (SubI imm_zero src) src)); 9677 predicate(UseBMI1Instructions); 9678 effect(KILL cr); 9679 9680 format %{ "blsil $dst, $src" %} 9681 9682 ins_encode %{ 9683 __ blsil($dst$$Register, $src$$Register); 9684 %} 9685 ins_pipe(ialu_reg); 9686%} 9687 9688instruct blsiI_rReg_mem(rRegI dst, memory src, immI0 imm_zero, rFlagsReg cr) %{ 9689 match(Set dst (AndI (SubI imm_zero (LoadI src) ) (LoadI src) )); 9690 predicate(UseBMI1Instructions); 9691 effect(KILL cr); 9692 9693 ins_cost(125); 9694 format %{ "blsil $dst, $src" %} 9695 9696 ins_encode %{ 9697 __ blsil($dst$$Register, $src$$Address); 9698 %} 9699 ins_pipe(ialu_reg_mem); 9700%} 9701 9702instruct blsmskI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 9703%{ 9704 match(Set dst (XorI (AddI (LoadI src) minus_1) (LoadI src) ) ); 9705 predicate(UseBMI1Instructions); 9706 effect(KILL cr); 9707 9708 ins_cost(125); 9709 format %{ "blsmskl $dst, $src" %} 9710 9711 ins_encode %{ 9712 __ blsmskl($dst$$Register, $src$$Address); 9713 %} 9714 ins_pipe(ialu_reg_mem); 9715%} 9716 9717instruct blsmskI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 9718%{ 9719 match(Set dst (XorI (AddI src minus_1) src)); 9720 predicate(UseBMI1Instructions); 9721 effect(KILL cr); 9722 9723 format %{ "blsmskl $dst, $src" %} 9724 9725 ins_encode %{ 9726 __ blsmskl($dst$$Register, $src$$Register); 9727 %} 9728 9729 ins_pipe(ialu_reg); 9730%} 9731 9732instruct blsrI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 9733%{ 9734 match(Set dst (AndI (AddI src minus_1) src) ); 9735 predicate(UseBMI1Instructions); 9736 effect(KILL cr); 9737 9738 format %{ "blsrl $dst, $src" %} 9739 9740 ins_encode %{ 9741 __ blsrl($dst$$Register, $src$$Register); 9742 %} 9743 9744 ins_pipe(ialu_reg_mem); 9745%} 9746 9747instruct blsrI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 9748%{ 9749 match(Set dst (AndI (AddI (LoadI src) minus_1) (LoadI src) ) ); 9750 predicate(UseBMI1Instructions); 9751 effect(KILL cr); 9752 9753 ins_cost(125); 9754 format %{ "blsrl $dst, $src" %} 9755 9756 ins_encode %{ 9757 __ blsrl($dst$$Register, $src$$Address); 9758 %} 9759 9760 ins_pipe(ialu_reg); 9761%} 9762 9763// Or Instructions 9764// Or Register with Register 9765instruct orI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9766%{ 9767 match(Set dst (OrI dst src)); 9768 effect(KILL cr); 9769 9770 format %{ "orl $dst, $src\t# int" %} 9771 opcode(0x0B); 9772 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9773 ins_pipe(ialu_reg_reg); 9774%} 9775 9776// Or Register with Immediate 9777instruct orI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9778%{ 9779 match(Set dst (OrI dst src)); 9780 effect(KILL cr); 9781 9782 format %{ "orl $dst, $src\t# int" %} 9783 opcode(0x81, 0x01); /* Opcode 81 /1 id */ 9784 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9785 ins_pipe(ialu_reg); 9786%} 9787 9788// Or Register with Memory 9789instruct orI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9790%{ 9791 match(Set dst (OrI dst (LoadI src))); 9792 effect(KILL cr); 9793 9794 ins_cost(125); 9795 format %{ "orl $dst, $src\t# int" %} 9796 opcode(0x0B); 9797 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9798 ins_pipe(ialu_reg_mem); 9799%} 9800 9801// Or Memory with Register 9802instruct orI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9803%{ 9804 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9805 effect(KILL cr); 9806 9807 ins_cost(150); 9808 format %{ "orl $dst, $src\t# int" %} 9809 opcode(0x09); /* Opcode 09 /r */ 9810 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9811 ins_pipe(ialu_mem_reg); 9812%} 9813 9814// Or Memory with Immediate 9815instruct orI_mem_imm(memory dst, immI src, rFlagsReg cr) 9816%{ 9817 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9818 effect(KILL cr); 9819 9820 ins_cost(125); 9821 format %{ "orl $dst, $src\t# int" %} 9822 opcode(0x81, 0x1); /* Opcode 81 /1 id */ 9823 ins_encode(REX_mem(dst), OpcSE(src), 9824 RM_opc_mem(secondary, dst), Con8or32(src)); 9825 ins_pipe(ialu_mem_imm); 9826%} 9827 9828// Xor Instructions 9829// Xor Register with Register 9830instruct xorI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9831%{ 9832 match(Set dst (XorI dst src)); 9833 effect(KILL cr); 9834 9835 format %{ "xorl $dst, $src\t# int" %} 9836 opcode(0x33); 9837 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9838 ins_pipe(ialu_reg_reg); 9839%} 9840 9841// Xor Register with Immediate -1 9842instruct xorI_rReg_im1(rRegI dst, immI_M1 imm) %{ 9843 match(Set dst (XorI dst imm)); 9844 9845 format %{ "not $dst" %} 9846 ins_encode %{ 9847 __ notl($dst$$Register); 9848 %} 9849 ins_pipe(ialu_reg); 9850%} 9851 9852// Xor Register with Immediate 9853instruct xorI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9854%{ 9855 match(Set dst (XorI dst src)); 9856 effect(KILL cr); 9857 9858 format %{ "xorl $dst, $src\t# int" %} 9859 opcode(0x81, 0x06); /* Opcode 81 /6 id */ 9860 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9861 ins_pipe(ialu_reg); 9862%} 9863 9864// Xor Register with Memory 9865instruct xorI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9866%{ 9867 match(Set dst (XorI dst (LoadI src))); 9868 effect(KILL cr); 9869 9870 ins_cost(125); 9871 format %{ "xorl $dst, $src\t# int" %} 9872 opcode(0x33); 9873 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9874 ins_pipe(ialu_reg_mem); 9875%} 9876 9877// Xor Memory with Register 9878instruct xorI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9879%{ 9880 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9881 effect(KILL cr); 9882 9883 ins_cost(150); 9884 format %{ "xorl $dst, $src\t# int" %} 9885 opcode(0x31); /* Opcode 31 /r */ 9886 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9887 ins_pipe(ialu_mem_reg); 9888%} 9889 9890// Xor Memory with Immediate 9891instruct xorI_mem_imm(memory dst, immI src, rFlagsReg cr) 9892%{ 9893 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9894 effect(KILL cr); 9895 9896 ins_cost(125); 9897 format %{ "xorl $dst, $src\t# int" %} 9898 opcode(0x81, 0x6); /* Opcode 81 /6 id */ 9899 ins_encode(REX_mem(dst), OpcSE(src), 9900 RM_opc_mem(secondary, dst), Con8or32(src)); 9901 ins_pipe(ialu_mem_imm); 9902%} 9903 9904 9905// Long Logical Instructions 9906 9907// And Instructions 9908// And Register with Register 9909instruct andL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9910%{ 9911 match(Set dst (AndL dst src)); 9912 effect(KILL cr); 9913 9914 format %{ "andq $dst, $src\t# long" %} 9915 opcode(0x23); 9916 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9917 ins_pipe(ialu_reg_reg); 9918%} 9919 9920// And Register with Immediate 255 9921instruct andL_rReg_imm255(rRegL dst, immL_255 src) 9922%{ 9923 match(Set dst (AndL dst src)); 9924 9925 format %{ "movzbq $dst, $dst\t# long & 0xFF" %} 9926 opcode(0x0F, 0xB6); 9927 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9928 ins_pipe(ialu_reg); 9929%} 9930 9931// And Register with Immediate 65535 9932instruct andL_rReg_imm65535(rRegL dst, immL_65535 src) 9933%{ 9934 match(Set dst (AndL dst src)); 9935 9936 format %{ "movzwq $dst, $dst\t# long & 0xFFFF" %} 9937 opcode(0x0F, 0xB7); 9938 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9939 ins_pipe(ialu_reg); 9940%} 9941 9942// And Register with Immediate 9943instruct andL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9944%{ 9945 match(Set dst (AndL dst src)); 9946 effect(KILL cr); 9947 9948 format %{ "andq $dst, $src\t# long" %} 9949 opcode(0x81, 0x04); /* Opcode 81 /4 */ 9950 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9951 ins_pipe(ialu_reg); 9952%} 9953 9954// And Register with Memory 9955instruct andL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9956%{ 9957 match(Set dst (AndL dst (LoadL src))); 9958 effect(KILL cr); 9959 9960 ins_cost(125); 9961 format %{ "andq $dst, $src\t# long" %} 9962 opcode(0x23); 9963 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9964 ins_pipe(ialu_reg_mem); 9965%} 9966 9967// And Memory with Register 9968instruct andL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9969%{ 9970 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9971 effect(KILL cr); 9972 9973 ins_cost(150); 9974 format %{ "andq $dst, $src\t# long" %} 9975 opcode(0x21); /* Opcode 21 /r */ 9976 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9977 ins_pipe(ialu_mem_reg); 9978%} 9979 9980// And Memory with Immediate 9981instruct andL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9982%{ 9983 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9984 effect(KILL cr); 9985 9986 ins_cost(125); 9987 format %{ "andq $dst, $src\t# long" %} 9988 opcode(0x81, 0x4); /* Opcode 81 /4 id */ 9989 ins_encode(REX_mem_wide(dst), OpcSE(src), 9990 RM_opc_mem(secondary, dst), Con8or32(src)); 9991 ins_pipe(ialu_mem_imm); 9992%} 9993 9994// BMI1 instructions 9995instruct andnL_rReg_rReg_mem(rRegL dst, rRegL src1, memory src2, immL_M1 minus_1, rFlagsReg cr) %{ 9996 match(Set dst (AndL (XorL src1 minus_1) (LoadL src2))); 9997 predicate(UseBMI1Instructions); 9998 effect(KILL cr); 9999 10000 ins_cost(125); 10001 format %{ "andnq $dst, $src1, $src2" %} 10002 10003 ins_encode %{ 10004 __ andnq($dst$$Register, $src1$$Register, $src2$$Address); 10005 %} 10006 ins_pipe(ialu_reg_mem); 10007%} 10008 10009instruct andnL_rReg_rReg_rReg(rRegL dst, rRegL src1, rRegL src2, immL_M1 minus_1, rFlagsReg cr) %{ 10010 match(Set dst (AndL (XorL src1 minus_1) src2)); 10011 predicate(UseBMI1Instructions); 10012 effect(KILL cr); 10013 10014 format %{ "andnq $dst, $src1, $src2" %} 10015 10016 ins_encode %{ 10017 __ andnq($dst$$Register, $src1$$Register, $src2$$Register); 10018 %} 10019 ins_pipe(ialu_reg_mem); 10020%} 10021 10022instruct blsiL_rReg_rReg(rRegL dst, rRegL src, immL0 imm_zero, rFlagsReg cr) %{ 10023 match(Set dst (AndL (SubL imm_zero src) src)); 10024 predicate(UseBMI1Instructions); 10025 effect(KILL cr); 10026 10027 format %{ "blsiq $dst, $src" %} 10028 10029 ins_encode %{ 10030 __ blsiq($dst$$Register, $src$$Register); 10031 %} 10032 ins_pipe(ialu_reg); 10033%} 10034 10035instruct blsiL_rReg_mem(rRegL dst, memory src, immL0 imm_zero, rFlagsReg cr) %{ 10036 match(Set dst (AndL (SubL imm_zero (LoadL src) ) (LoadL src) )); 10037 predicate(UseBMI1Instructions); 10038 effect(KILL cr); 10039 10040 ins_cost(125); 10041 format %{ "blsiq $dst, $src" %} 10042 10043 ins_encode %{ 10044 __ blsiq($dst$$Register, $src$$Address); 10045 %} 10046 ins_pipe(ialu_reg_mem); 10047%} 10048 10049instruct blsmskL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 10050%{ 10051 match(Set dst (XorL (AddL (LoadL src) minus_1) (LoadL src) ) ); 10052 predicate(UseBMI1Instructions); 10053 effect(KILL cr); 10054 10055 ins_cost(125); 10056 format %{ "blsmskq $dst, $src" %} 10057 10058 ins_encode %{ 10059 __ blsmskq($dst$$Register, $src$$Address); 10060 %} 10061 ins_pipe(ialu_reg_mem); 10062%} 10063 10064instruct blsmskL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 10065%{ 10066 match(Set dst (XorL (AddL src minus_1) src)); 10067 predicate(UseBMI1Instructions); 10068 effect(KILL cr); 10069 10070 format %{ "blsmskq $dst, $src" %} 10071 10072 ins_encode %{ 10073 __ blsmskq($dst$$Register, $src$$Register); 10074 %} 10075 10076 ins_pipe(ialu_reg); 10077%} 10078 10079instruct blsrL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 10080%{ 10081 match(Set dst (AndL (AddL src minus_1) src) ); 10082 predicate(UseBMI1Instructions); 10083 effect(KILL cr); 10084 10085 format %{ "blsrq $dst, $src" %} 10086 10087 ins_encode %{ 10088 __ blsrq($dst$$Register, $src$$Register); 10089 %} 10090 10091 ins_pipe(ialu_reg); 10092%} 10093 10094instruct blsrL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 10095%{ 10096 match(Set dst (AndL (AddL (LoadL src) minus_1) (LoadL src)) ); 10097 predicate(UseBMI1Instructions); 10098 effect(KILL cr); 10099 10100 ins_cost(125); 10101 format %{ "blsrq $dst, $src" %} 10102 10103 ins_encode %{ 10104 __ blsrq($dst$$Register, $src$$Address); 10105 %} 10106 10107 ins_pipe(ialu_reg); 10108%} 10109 10110// Or Instructions 10111// Or Register with Register 10112instruct orL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 10113%{ 10114 match(Set dst (OrL dst src)); 10115 effect(KILL cr); 10116 10117 format %{ "orq $dst, $src\t# long" %} 10118 opcode(0x0B); 10119 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 10120 ins_pipe(ialu_reg_reg); 10121%} 10122 10123// Use any_RegP to match R15 (TLS register) without spilling. 10124instruct orL_rReg_castP2X(rRegL dst, any_RegP src, rFlagsReg cr) %{ 10125 match(Set dst (OrL dst (CastP2X src))); 10126 effect(KILL cr); 10127 10128 format %{ "orq $dst, $src\t# long" %} 10129 opcode(0x0B); 10130 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 10131 ins_pipe(ialu_reg_reg); 10132%} 10133 10134 10135// Or Register with Immediate 10136instruct orL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 10137%{ 10138 match(Set dst (OrL dst src)); 10139 effect(KILL cr); 10140 10141 format %{ "orq $dst, $src\t# long" %} 10142 opcode(0x81, 0x01); /* Opcode 81 /1 id */ 10143 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 10144 ins_pipe(ialu_reg); 10145%} 10146 10147// Or Register with Memory 10148instruct orL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 10149%{ 10150 match(Set dst (OrL dst (LoadL src))); 10151 effect(KILL cr); 10152 10153 ins_cost(125); 10154 format %{ "orq $dst, $src\t# long" %} 10155 opcode(0x0B); 10156 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 10157 ins_pipe(ialu_reg_mem); 10158%} 10159 10160// Or Memory with Register 10161instruct orL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 10162%{ 10163 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 10164 effect(KILL cr); 10165 10166 ins_cost(150); 10167 format %{ "orq $dst, $src\t# long" %} 10168 opcode(0x09); /* Opcode 09 /r */ 10169 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 10170 ins_pipe(ialu_mem_reg); 10171%} 10172 10173// Or Memory with Immediate 10174instruct orL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 10175%{ 10176 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 10177 effect(KILL cr); 10178 10179 ins_cost(125); 10180 format %{ "orq $dst, $src\t# long" %} 10181 opcode(0x81, 0x1); /* Opcode 81 /1 id */ 10182 ins_encode(REX_mem_wide(dst), OpcSE(src), 10183 RM_opc_mem(secondary, dst), Con8or32(src)); 10184 ins_pipe(ialu_mem_imm); 10185%} 10186 10187// Xor Instructions 10188// Xor Register with Register 10189instruct xorL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 10190%{ 10191 match(Set dst (XorL dst src)); 10192 effect(KILL cr); 10193 10194 format %{ "xorq $dst, $src\t# long" %} 10195 opcode(0x33); 10196 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 10197 ins_pipe(ialu_reg_reg); 10198%} 10199 10200// Xor Register with Immediate -1 10201instruct xorL_rReg_im1(rRegL dst, immL_M1 imm) %{ 10202 match(Set dst (XorL dst imm)); 10203 10204 format %{ "notq $dst" %} 10205 ins_encode %{ 10206 __ notq($dst$$Register); 10207 %} 10208 ins_pipe(ialu_reg); 10209%} 10210 10211// Xor Register with Immediate 10212instruct xorL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 10213%{ 10214 match(Set dst (XorL dst src)); 10215 effect(KILL cr); 10216 10217 format %{ "xorq $dst, $src\t# long" %} 10218 opcode(0x81, 0x06); /* Opcode 81 /6 id */ 10219 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 10220 ins_pipe(ialu_reg); 10221%} 10222 10223// Xor Register with Memory 10224instruct xorL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 10225%{ 10226 match(Set dst (XorL dst (LoadL src))); 10227 effect(KILL cr); 10228 10229 ins_cost(125); 10230 format %{ "xorq $dst, $src\t# long" %} 10231 opcode(0x33); 10232 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 10233 ins_pipe(ialu_reg_mem); 10234%} 10235 10236// Xor Memory with Register 10237instruct xorL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 10238%{ 10239 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 10240 effect(KILL cr); 10241 10242 ins_cost(150); 10243 format %{ "xorq $dst, $src\t# long" %} 10244 opcode(0x31); /* Opcode 31 /r */ 10245 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 10246 ins_pipe(ialu_mem_reg); 10247%} 10248 10249// Xor Memory with Immediate 10250instruct xorL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 10251%{ 10252 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 10253 effect(KILL cr); 10254 10255 ins_cost(125); 10256 format %{ "xorq $dst, $src\t# long" %} 10257 opcode(0x81, 0x6); /* Opcode 81 /6 id */ 10258 ins_encode(REX_mem_wide(dst), OpcSE(src), 10259 RM_opc_mem(secondary, dst), Con8or32(src)); 10260 ins_pipe(ialu_mem_imm); 10261%} 10262 10263// Convert Int to Boolean 10264instruct convI2B(rRegI dst, rRegI src, rFlagsReg cr) 10265%{ 10266 match(Set dst (Conv2B src)); 10267 effect(KILL cr); 10268 10269 format %{ "testl $src, $src\t# ci2b\n\t" 10270 "setnz $dst\n\t" 10271 "movzbl $dst, $dst" %} 10272 ins_encode(REX_reg_reg(src, src), opc_reg_reg(0x85, src, src), // testl 10273 setNZ_reg(dst), 10274 REX_reg_breg(dst, dst), // movzbl 10275 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst)); 10276 ins_pipe(pipe_slow); // XXX 10277%} 10278 10279// Convert Pointer to Boolean 10280instruct convP2B(rRegI dst, rRegP src, rFlagsReg cr) 10281%{ 10282 match(Set dst (Conv2B src)); 10283 effect(KILL cr); 10284 10285 format %{ "testq $src, $src\t# cp2b\n\t" 10286 "setnz $dst\n\t" 10287 "movzbl $dst, $dst" %} 10288 ins_encode(REX_reg_reg_wide(src, src), opc_reg_reg(0x85, src, src), // testq 10289 setNZ_reg(dst), 10290 REX_reg_breg(dst, dst), // movzbl 10291 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst)); 10292 ins_pipe(pipe_slow); // XXX 10293%} 10294 10295instruct cmpLTMask(rRegI dst, rRegI p, rRegI q, rFlagsReg cr) 10296%{ 10297 match(Set dst (CmpLTMask p q)); 10298 effect(KILL cr); 10299 10300 ins_cost(400); 10301 format %{ "cmpl $p, $q\t# cmpLTMask\n\t" 10302 "setlt $dst\n\t" 10303 "movzbl $dst, $dst\n\t" 10304 "negl $dst" %} 10305 ins_encode(REX_reg_reg(p, q), opc_reg_reg(0x3B, p, q), // cmpl 10306 setLT_reg(dst), 10307 REX_reg_breg(dst, dst), // movzbl 10308 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst), 10309 neg_reg(dst)); 10310 ins_pipe(pipe_slow); 10311%} 10312 10313instruct cmpLTMask0(rRegI dst, immI0 zero, rFlagsReg cr) 10314%{ 10315 match(Set dst (CmpLTMask dst zero)); 10316 effect(KILL cr); 10317 10318 ins_cost(100); 10319 format %{ "sarl $dst, #31\t# cmpLTMask0" %} 10320 ins_encode %{ 10321 __ sarl($dst$$Register, 31); 10322 %} 10323 ins_pipe(ialu_reg); 10324%} 10325 10326/* Better to save a register than avoid a branch */ 10327instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 10328%{ 10329 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q))); 10330 effect(KILL cr); 10331 ins_cost(300); 10332 format %{ "subl $p,$q\t# cadd_cmpLTMask\n\t" 10333 "jge done\n\t" 10334 "addl $p,$y\n" 10335 "done: " %} 10336 ins_encode %{ 10337 Register Rp = $p$$Register; 10338 Register Rq = $q$$Register; 10339 Register Ry = $y$$Register; 10340 Label done; 10341 __ subl(Rp, Rq); 10342 __ jccb(Assembler::greaterEqual, done); 10343 __ addl(Rp, Ry); 10344 __ bind(done); 10345 %} 10346 ins_pipe(pipe_cmplt); 10347%} 10348 10349/* Better to save a register than avoid a branch */ 10350instruct and_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 10351%{ 10352 match(Set y (AndI (CmpLTMask p q) y)); 10353 effect(KILL cr); 10354 10355 ins_cost(300); 10356 10357 format %{ "cmpl $p, $q\t# and_cmpLTMask\n\t" 10358 "jlt done\n\t" 10359 "xorl $y, $y\n" 10360 "done: " %} 10361 ins_encode %{ 10362 Register Rp = $p$$Register; 10363 Register Rq = $q$$Register; 10364 Register Ry = $y$$Register; 10365 Label done; 10366 __ cmpl(Rp, Rq); 10367 __ jccb(Assembler::less, done); 10368 __ xorl(Ry, Ry); 10369 __ bind(done); 10370 %} 10371 ins_pipe(pipe_cmplt); 10372%} 10373 10374 10375//---------- FP Instructions------------------------------------------------ 10376 10377instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2) 10378%{ 10379 match(Set cr (CmpF src1 src2)); 10380 10381 ins_cost(145); 10382 format %{ "ucomiss $src1, $src2\n\t" 10383 "jnp,s exit\n\t" 10384 "pushfq\t# saw NaN, set CF\n\t" 10385 "andq [rsp], #0xffffff2b\n\t" 10386 "popfq\n" 10387 "exit:" %} 10388 ins_encode %{ 10389 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 10390 emit_cmpfp_fixup(_masm); 10391 %} 10392 ins_pipe(pipe_slow); 10393%} 10394 10395instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{ 10396 match(Set cr (CmpF src1 src2)); 10397 10398 ins_cost(100); 10399 format %{ "ucomiss $src1, $src2" %} 10400 ins_encode %{ 10401 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 10402 %} 10403 ins_pipe(pipe_slow); 10404%} 10405 10406instruct cmpF_cc_mem(rFlagsRegU cr, regF src1, memory src2) 10407%{ 10408 match(Set cr (CmpF src1 (LoadF src2))); 10409 10410 ins_cost(145); 10411 format %{ "ucomiss $src1, $src2\n\t" 10412 "jnp,s exit\n\t" 10413 "pushfq\t# saw NaN, set CF\n\t" 10414 "andq [rsp], #0xffffff2b\n\t" 10415 "popfq\n" 10416 "exit:" %} 10417 ins_encode %{ 10418 __ ucomiss($src1$$XMMRegister, $src2$$Address); 10419 emit_cmpfp_fixup(_masm); 10420 %} 10421 ins_pipe(pipe_slow); 10422%} 10423 10424instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{ 10425 match(Set cr (CmpF src1 (LoadF src2))); 10426 10427 ins_cost(100); 10428 format %{ "ucomiss $src1, $src2" %} 10429 ins_encode %{ 10430 __ ucomiss($src1$$XMMRegister, $src2$$Address); 10431 %} 10432 ins_pipe(pipe_slow); 10433%} 10434 10435instruct cmpF_cc_imm(rFlagsRegU cr, regF src, immF con) %{ 10436 match(Set cr (CmpF src con)); 10437 10438 ins_cost(145); 10439 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 10440 "jnp,s exit\n\t" 10441 "pushfq\t# saw NaN, set CF\n\t" 10442 "andq [rsp], #0xffffff2b\n\t" 10443 "popfq\n" 10444 "exit:" %} 10445 ins_encode %{ 10446 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 10447 emit_cmpfp_fixup(_masm); 10448 %} 10449 ins_pipe(pipe_slow); 10450%} 10451 10452instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src, immF con) %{ 10453 match(Set cr (CmpF src con)); 10454 ins_cost(100); 10455 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con" %} 10456 ins_encode %{ 10457 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 10458 %} 10459 ins_pipe(pipe_slow); 10460%} 10461 10462instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2) 10463%{ 10464 match(Set cr (CmpD src1 src2)); 10465 10466 ins_cost(145); 10467 format %{ "ucomisd $src1, $src2\n\t" 10468 "jnp,s exit\n\t" 10469 "pushfq\t# saw NaN, set CF\n\t" 10470 "andq [rsp], #0xffffff2b\n\t" 10471 "popfq\n" 10472 "exit:" %} 10473 ins_encode %{ 10474 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 10475 emit_cmpfp_fixup(_masm); 10476 %} 10477 ins_pipe(pipe_slow); 10478%} 10479 10480instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{ 10481 match(Set cr (CmpD src1 src2)); 10482 10483 ins_cost(100); 10484 format %{ "ucomisd $src1, $src2 test" %} 10485 ins_encode %{ 10486 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 10487 %} 10488 ins_pipe(pipe_slow); 10489%} 10490 10491instruct cmpD_cc_mem(rFlagsRegU cr, regD src1, memory src2) 10492%{ 10493 match(Set cr (CmpD src1 (LoadD src2))); 10494 10495 ins_cost(145); 10496 format %{ "ucomisd $src1, $src2\n\t" 10497 "jnp,s exit\n\t" 10498 "pushfq\t# saw NaN, set CF\n\t" 10499 "andq [rsp], #0xffffff2b\n\t" 10500 "popfq\n" 10501 "exit:" %} 10502 ins_encode %{ 10503 __ ucomisd($src1$$XMMRegister, $src2$$Address); 10504 emit_cmpfp_fixup(_masm); 10505 %} 10506 ins_pipe(pipe_slow); 10507%} 10508 10509instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{ 10510 match(Set cr (CmpD src1 (LoadD src2))); 10511 10512 ins_cost(100); 10513 format %{ "ucomisd $src1, $src2" %} 10514 ins_encode %{ 10515 __ ucomisd($src1$$XMMRegister, $src2$$Address); 10516 %} 10517 ins_pipe(pipe_slow); 10518%} 10519 10520instruct cmpD_cc_imm(rFlagsRegU cr, regD src, immD con) %{ 10521 match(Set cr (CmpD src con)); 10522 10523 ins_cost(145); 10524 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 10525 "jnp,s exit\n\t" 10526 "pushfq\t# saw NaN, set CF\n\t" 10527 "andq [rsp], #0xffffff2b\n\t" 10528 "popfq\n" 10529 "exit:" %} 10530 ins_encode %{ 10531 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 10532 emit_cmpfp_fixup(_masm); 10533 %} 10534 ins_pipe(pipe_slow); 10535%} 10536 10537instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src, immD con) %{ 10538 match(Set cr (CmpD src con)); 10539 ins_cost(100); 10540 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con" %} 10541 ins_encode %{ 10542 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 10543 %} 10544 ins_pipe(pipe_slow); 10545%} 10546 10547// Compare into -1,0,1 10548instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr) 10549%{ 10550 match(Set dst (CmpF3 src1 src2)); 10551 effect(KILL cr); 10552 10553 ins_cost(275); 10554 format %{ "ucomiss $src1, $src2\n\t" 10555 "movl $dst, #-1\n\t" 10556 "jp,s done\n\t" 10557 "jb,s done\n\t" 10558 "setne $dst\n\t" 10559 "movzbl $dst, $dst\n" 10560 "done:" %} 10561 ins_encode %{ 10562 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 10563 emit_cmpfp3(_masm, $dst$$Register); 10564 %} 10565 ins_pipe(pipe_slow); 10566%} 10567 10568// Compare into -1,0,1 10569instruct cmpF_mem(rRegI dst, regF src1, memory src2, rFlagsReg cr) 10570%{ 10571 match(Set dst (CmpF3 src1 (LoadF src2))); 10572 effect(KILL cr); 10573 10574 ins_cost(275); 10575 format %{ "ucomiss $src1, $src2\n\t" 10576 "movl $dst, #-1\n\t" 10577 "jp,s done\n\t" 10578 "jb,s done\n\t" 10579 "setne $dst\n\t" 10580 "movzbl $dst, $dst\n" 10581 "done:" %} 10582 ins_encode %{ 10583 __ ucomiss($src1$$XMMRegister, $src2$$Address); 10584 emit_cmpfp3(_masm, $dst$$Register); 10585 %} 10586 ins_pipe(pipe_slow); 10587%} 10588 10589// Compare into -1,0,1 10590instruct cmpF_imm(rRegI dst, regF src, immF con, rFlagsReg cr) %{ 10591 match(Set dst (CmpF3 src con)); 10592 effect(KILL cr); 10593 10594 ins_cost(275); 10595 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 10596 "movl $dst, #-1\n\t" 10597 "jp,s done\n\t" 10598 "jb,s done\n\t" 10599 "setne $dst\n\t" 10600 "movzbl $dst, $dst\n" 10601 "done:" %} 10602 ins_encode %{ 10603 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 10604 emit_cmpfp3(_masm, $dst$$Register); 10605 %} 10606 ins_pipe(pipe_slow); 10607%} 10608 10609// Compare into -1,0,1 10610instruct cmpD_reg(rRegI dst, regD src1, regD src2, rFlagsReg cr) 10611%{ 10612 match(Set dst (CmpD3 src1 src2)); 10613 effect(KILL cr); 10614 10615 ins_cost(275); 10616 format %{ "ucomisd $src1, $src2\n\t" 10617 "movl $dst, #-1\n\t" 10618 "jp,s done\n\t" 10619 "jb,s done\n\t" 10620 "setne $dst\n\t" 10621 "movzbl $dst, $dst\n" 10622 "done:" %} 10623 ins_encode %{ 10624 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 10625 emit_cmpfp3(_masm, $dst$$Register); 10626 %} 10627 ins_pipe(pipe_slow); 10628%} 10629 10630// Compare into -1,0,1 10631instruct cmpD_mem(rRegI dst, regD src1, memory src2, rFlagsReg cr) 10632%{ 10633 match(Set dst (CmpD3 src1 (LoadD src2))); 10634 effect(KILL cr); 10635 10636 ins_cost(275); 10637 format %{ "ucomisd $src1, $src2\n\t" 10638 "movl $dst, #-1\n\t" 10639 "jp,s done\n\t" 10640 "jb,s done\n\t" 10641 "setne $dst\n\t" 10642 "movzbl $dst, $dst\n" 10643 "done:" %} 10644 ins_encode %{ 10645 __ ucomisd($src1$$XMMRegister, $src2$$Address); 10646 emit_cmpfp3(_masm, $dst$$Register); 10647 %} 10648 ins_pipe(pipe_slow); 10649%} 10650 10651// Compare into -1,0,1 10652instruct cmpD_imm(rRegI dst, regD src, immD con, rFlagsReg cr) %{ 10653 match(Set dst (CmpD3 src con)); 10654 effect(KILL cr); 10655 10656 ins_cost(275); 10657 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 10658 "movl $dst, #-1\n\t" 10659 "jp,s done\n\t" 10660 "jb,s done\n\t" 10661 "setne $dst\n\t" 10662 "movzbl $dst, $dst\n" 10663 "done:" %} 10664 ins_encode %{ 10665 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 10666 emit_cmpfp3(_masm, $dst$$Register); 10667 %} 10668 ins_pipe(pipe_slow); 10669%} 10670 10671//----------Arithmetic Conversion Instructions--------------------------------- 10672 10673instruct roundFloat_nop(regF dst) 10674%{ 10675 match(Set dst (RoundFloat dst)); 10676 10677 ins_cost(0); 10678 ins_encode(); 10679 ins_pipe(empty); 10680%} 10681 10682instruct roundDouble_nop(regD dst) 10683%{ 10684 match(Set dst (RoundDouble dst)); 10685 10686 ins_cost(0); 10687 ins_encode(); 10688 ins_pipe(empty); 10689%} 10690 10691instruct convF2D_reg_reg(regD dst, regF src) 10692%{ 10693 match(Set dst (ConvF2D src)); 10694 10695 format %{ "cvtss2sd $dst, $src" %} 10696 ins_encode %{ 10697 __ cvtss2sd ($dst$$XMMRegister, $src$$XMMRegister); 10698 %} 10699 ins_pipe(pipe_slow); // XXX 10700%} 10701 10702instruct convF2D_reg_mem(regD dst, memory src) 10703%{ 10704 match(Set dst (ConvF2D (LoadF src))); 10705 10706 format %{ "cvtss2sd $dst, $src" %} 10707 ins_encode %{ 10708 __ cvtss2sd ($dst$$XMMRegister, $src$$Address); 10709 %} 10710 ins_pipe(pipe_slow); // XXX 10711%} 10712 10713instruct convD2F_reg_reg(regF dst, regD src) 10714%{ 10715 match(Set dst (ConvD2F src)); 10716 10717 format %{ "cvtsd2ss $dst, $src" %} 10718 ins_encode %{ 10719 __ cvtsd2ss ($dst$$XMMRegister, $src$$XMMRegister); 10720 %} 10721 ins_pipe(pipe_slow); // XXX 10722%} 10723 10724instruct convD2F_reg_mem(regF dst, memory src) 10725%{ 10726 match(Set dst (ConvD2F (LoadD src))); 10727 10728 format %{ "cvtsd2ss $dst, $src" %} 10729 ins_encode %{ 10730 __ cvtsd2ss ($dst$$XMMRegister, $src$$Address); 10731 %} 10732 ins_pipe(pipe_slow); // XXX 10733%} 10734 10735// XXX do mem variants 10736instruct convF2I_reg_reg(rRegI dst, regF src, rFlagsReg cr) 10737%{ 10738 match(Set dst (ConvF2I src)); 10739 effect(KILL cr); 10740 10741 format %{ "cvttss2sil $dst, $src\t# f2i\n\t" 10742 "cmpl $dst, #0x80000000\n\t" 10743 "jne,s done\n\t" 10744 "subq rsp, #8\n\t" 10745 "movss [rsp], $src\n\t" 10746 "call f2i_fixup\n\t" 10747 "popq $dst\n" 10748 "done: "%} 10749 ins_encode %{ 10750 Label done; 10751 __ cvttss2sil($dst$$Register, $src$$XMMRegister); 10752 __ cmpl($dst$$Register, 0x80000000); 10753 __ jccb(Assembler::notEqual, done); 10754 __ subptr(rsp, 8); 10755 __ movflt(Address(rsp, 0), $src$$XMMRegister); 10756 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::f2i_fixup()))); 10757 __ pop($dst$$Register); 10758 __ bind(done); 10759 %} 10760 ins_pipe(pipe_slow); 10761%} 10762 10763instruct convF2L_reg_reg(rRegL dst, regF src, rFlagsReg cr) 10764%{ 10765 match(Set dst (ConvF2L src)); 10766 effect(KILL cr); 10767 10768 format %{ "cvttss2siq $dst, $src\t# f2l\n\t" 10769 "cmpq $dst, [0x8000000000000000]\n\t" 10770 "jne,s done\n\t" 10771 "subq rsp, #8\n\t" 10772 "movss [rsp], $src\n\t" 10773 "call f2l_fixup\n\t" 10774 "popq $dst\n" 10775 "done: "%} 10776 ins_encode %{ 10777 Label done; 10778 __ cvttss2siq($dst$$Register, $src$$XMMRegister); 10779 __ cmp64($dst$$Register, 10780 ExternalAddress((address) StubRoutines::x86::double_sign_flip())); 10781 __ jccb(Assembler::notEqual, done); 10782 __ subptr(rsp, 8); 10783 __ movflt(Address(rsp, 0), $src$$XMMRegister); 10784 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::f2l_fixup()))); 10785 __ pop($dst$$Register); 10786 __ bind(done); 10787 %} 10788 ins_pipe(pipe_slow); 10789%} 10790 10791instruct convD2I_reg_reg(rRegI dst, regD src, rFlagsReg cr) 10792%{ 10793 match(Set dst (ConvD2I src)); 10794 effect(KILL cr); 10795 10796 format %{ "cvttsd2sil $dst, $src\t# d2i\n\t" 10797 "cmpl $dst, #0x80000000\n\t" 10798 "jne,s done\n\t" 10799 "subq rsp, #8\n\t" 10800 "movsd [rsp], $src\n\t" 10801 "call d2i_fixup\n\t" 10802 "popq $dst\n" 10803 "done: "%} 10804 ins_encode %{ 10805 Label done; 10806 __ cvttsd2sil($dst$$Register, $src$$XMMRegister); 10807 __ cmpl($dst$$Register, 0x80000000); 10808 __ jccb(Assembler::notEqual, done); 10809 __ subptr(rsp, 8); 10810 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 10811 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::d2i_fixup()))); 10812 __ pop($dst$$Register); 10813 __ bind(done); 10814 %} 10815 ins_pipe(pipe_slow); 10816%} 10817 10818instruct convD2L_reg_reg(rRegL dst, regD src, rFlagsReg cr) 10819%{ 10820 match(Set dst (ConvD2L src)); 10821 effect(KILL cr); 10822 10823 format %{ "cvttsd2siq $dst, $src\t# d2l\n\t" 10824 "cmpq $dst, [0x8000000000000000]\n\t" 10825 "jne,s done\n\t" 10826 "subq rsp, #8\n\t" 10827 "movsd [rsp], $src\n\t" 10828 "call d2l_fixup\n\t" 10829 "popq $dst\n" 10830 "done: "%} 10831 ins_encode %{ 10832 Label done; 10833 __ cvttsd2siq($dst$$Register, $src$$XMMRegister); 10834 __ cmp64($dst$$Register, 10835 ExternalAddress((address) StubRoutines::x86::double_sign_flip())); 10836 __ jccb(Assembler::notEqual, done); 10837 __ subptr(rsp, 8); 10838 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 10839 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::d2l_fixup()))); 10840 __ pop($dst$$Register); 10841 __ bind(done); 10842 %} 10843 ins_pipe(pipe_slow); 10844%} 10845 10846instruct convI2F_reg_reg(regF dst, rRegI src) 10847%{ 10848 predicate(!UseXmmI2F); 10849 match(Set dst (ConvI2F src)); 10850 10851 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10852 ins_encode %{ 10853 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Register); 10854 %} 10855 ins_pipe(pipe_slow); // XXX 10856%} 10857 10858instruct convI2F_reg_mem(regF dst, memory src) 10859%{ 10860 match(Set dst (ConvI2F (LoadI src))); 10861 10862 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10863 ins_encode %{ 10864 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Address); 10865 %} 10866 ins_pipe(pipe_slow); // XXX 10867%} 10868 10869instruct convI2D_reg_reg(regD dst, rRegI src) 10870%{ 10871 predicate(!UseXmmI2D); 10872 match(Set dst (ConvI2D src)); 10873 10874 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10875 ins_encode %{ 10876 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Register); 10877 %} 10878 ins_pipe(pipe_slow); // XXX 10879%} 10880 10881instruct convI2D_reg_mem(regD dst, memory src) 10882%{ 10883 match(Set dst (ConvI2D (LoadI src))); 10884 10885 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10886 ins_encode %{ 10887 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Address); 10888 %} 10889 ins_pipe(pipe_slow); // XXX 10890%} 10891 10892instruct convXI2F_reg(regF dst, rRegI src) 10893%{ 10894 predicate(UseXmmI2F); 10895 match(Set dst (ConvI2F src)); 10896 10897 format %{ "movdl $dst, $src\n\t" 10898 "cvtdq2psl $dst, $dst\t# i2f" %} 10899 ins_encode %{ 10900 __ movdl($dst$$XMMRegister, $src$$Register); 10901 __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister); 10902 %} 10903 ins_pipe(pipe_slow); // XXX 10904%} 10905 10906instruct convXI2D_reg(regD dst, rRegI src) 10907%{ 10908 predicate(UseXmmI2D); 10909 match(Set dst (ConvI2D src)); 10910 10911 format %{ "movdl $dst, $src\n\t" 10912 "cvtdq2pdl $dst, $dst\t# i2d" %} 10913 ins_encode %{ 10914 __ movdl($dst$$XMMRegister, $src$$Register); 10915 __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister); 10916 %} 10917 ins_pipe(pipe_slow); // XXX 10918%} 10919 10920instruct convL2F_reg_reg(regF dst, rRegL src) 10921%{ 10922 match(Set dst (ConvL2F src)); 10923 10924 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10925 ins_encode %{ 10926 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Register); 10927 %} 10928 ins_pipe(pipe_slow); // XXX 10929%} 10930 10931instruct convL2F_reg_mem(regF dst, memory src) 10932%{ 10933 match(Set dst (ConvL2F (LoadL src))); 10934 10935 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10936 ins_encode %{ 10937 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Address); 10938 %} 10939 ins_pipe(pipe_slow); // XXX 10940%} 10941 10942instruct convL2D_reg_reg(regD dst, rRegL src) 10943%{ 10944 match(Set dst (ConvL2D src)); 10945 10946 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10947 ins_encode %{ 10948 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Register); 10949 %} 10950 ins_pipe(pipe_slow); // XXX 10951%} 10952 10953instruct convL2D_reg_mem(regD dst, memory src) 10954%{ 10955 match(Set dst (ConvL2D (LoadL src))); 10956 10957 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10958 ins_encode %{ 10959 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Address); 10960 %} 10961 ins_pipe(pipe_slow); // XXX 10962%} 10963 10964instruct convI2L_reg_reg(rRegL dst, rRegI src) 10965%{ 10966 match(Set dst (ConvI2L src)); 10967 10968 ins_cost(125); 10969 format %{ "movslq $dst, $src\t# i2l" %} 10970 ins_encode %{ 10971 __ movslq($dst$$Register, $src$$Register); 10972 %} 10973 ins_pipe(ialu_reg_reg); 10974%} 10975 10976// instruct convI2L_reg_reg_foo(rRegL dst, rRegI src) 10977// %{ 10978// match(Set dst (ConvI2L src)); 10979// // predicate(_kids[0]->_leaf->as_Type()->type()->is_int()->_lo >= 0 && 10980// // _kids[0]->_leaf->as_Type()->type()->is_int()->_hi >= 0); 10981// predicate(((const TypeNode*) n)->type()->is_long()->_hi == 10982// (unsigned int) ((const TypeNode*) n)->type()->is_long()->_hi && 10983// ((const TypeNode*) n)->type()->is_long()->_lo == 10984// (unsigned int) ((const TypeNode*) n)->type()->is_long()->_lo); 10985 10986// format %{ "movl $dst, $src\t# unsigned i2l" %} 10987// ins_encode(enc_copy(dst, src)); 10988// // opcode(0x63); // needs REX.W 10989// // ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst,src)); 10990// ins_pipe(ialu_reg_reg); 10991// %} 10992 10993// Zero-extend convert int to long 10994instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask) 10995%{ 10996 match(Set dst (AndL (ConvI2L src) mask)); 10997 10998 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10999 ins_encode %{ 11000 if ($dst$$reg != $src$$reg) { 11001 __ movl($dst$$Register, $src$$Register); 11002 } 11003 %} 11004 ins_pipe(ialu_reg_reg); 11005%} 11006 11007// Zero-extend convert int to long 11008instruct convI2L_reg_mem_zex(rRegL dst, memory src, immL_32bits mask) 11009%{ 11010 match(Set dst (AndL (ConvI2L (LoadI src)) mask)); 11011 11012 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 11013 ins_encode %{ 11014 __ movl($dst$$Register, $src$$Address); 11015 %} 11016 ins_pipe(ialu_reg_mem); 11017%} 11018 11019instruct zerox_long_reg_reg(rRegL dst, rRegL src, immL_32bits mask) 11020%{ 11021 match(Set dst (AndL src mask)); 11022 11023 format %{ "movl $dst, $src\t# zero-extend long" %} 11024 ins_encode %{ 11025 __ movl($dst$$Register, $src$$Register); 11026 %} 11027 ins_pipe(ialu_reg_reg); 11028%} 11029 11030instruct convL2I_reg_reg(rRegI dst, rRegL src) 11031%{ 11032 match(Set dst (ConvL2I src)); 11033 11034 format %{ "movl $dst, $src\t# l2i" %} 11035 ins_encode %{ 11036 __ movl($dst$$Register, $src$$Register); 11037 %} 11038 ins_pipe(ialu_reg_reg); 11039%} 11040 11041 11042instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{ 11043 match(Set dst (MoveF2I src)); 11044 effect(DEF dst, USE src); 11045 11046 ins_cost(125); 11047 format %{ "movl $dst, $src\t# MoveF2I_stack_reg" %} 11048 ins_encode %{ 11049 __ movl($dst$$Register, Address(rsp, $src$$disp)); 11050 %} 11051 ins_pipe(ialu_reg_mem); 11052%} 11053 11054instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{ 11055 match(Set dst (MoveI2F src)); 11056 effect(DEF dst, USE src); 11057 11058 ins_cost(125); 11059 format %{ "movss $dst, $src\t# MoveI2F_stack_reg" %} 11060 ins_encode %{ 11061 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 11062 %} 11063 ins_pipe(pipe_slow); 11064%} 11065 11066instruct MoveD2L_stack_reg(rRegL dst, stackSlotD src) %{ 11067 match(Set dst (MoveD2L src)); 11068 effect(DEF dst, USE src); 11069 11070 ins_cost(125); 11071 format %{ "movq $dst, $src\t# MoveD2L_stack_reg" %} 11072 ins_encode %{ 11073 __ movq($dst$$Register, Address(rsp, $src$$disp)); 11074 %} 11075 ins_pipe(ialu_reg_mem); 11076%} 11077 11078instruct MoveL2D_stack_reg_partial(regD dst, stackSlotL src) %{ 11079 predicate(!UseXmmLoadAndClearUpper); 11080 match(Set dst (MoveL2D src)); 11081 effect(DEF dst, USE src); 11082 11083 ins_cost(125); 11084 format %{ "movlpd $dst, $src\t# MoveL2D_stack_reg" %} 11085 ins_encode %{ 11086 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 11087 %} 11088 ins_pipe(pipe_slow); 11089%} 11090 11091instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{ 11092 predicate(UseXmmLoadAndClearUpper); 11093 match(Set dst (MoveL2D src)); 11094 effect(DEF dst, USE src); 11095 11096 ins_cost(125); 11097 format %{ "movsd $dst, $src\t# MoveL2D_stack_reg" %} 11098 ins_encode %{ 11099 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 11100 %} 11101 ins_pipe(pipe_slow); 11102%} 11103 11104 11105instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{ 11106 match(Set dst (MoveF2I src)); 11107 effect(DEF dst, USE src); 11108 11109 ins_cost(95); // XXX 11110 format %{ "movss $dst, $src\t# MoveF2I_reg_stack" %} 11111 ins_encode %{ 11112 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 11113 %} 11114 ins_pipe(pipe_slow); 11115%} 11116 11117instruct MoveI2F_reg_stack(stackSlotF dst, rRegI src) %{ 11118 match(Set dst (MoveI2F src)); 11119 effect(DEF dst, USE src); 11120 11121 ins_cost(100); 11122 format %{ "movl $dst, $src\t# MoveI2F_reg_stack" %} 11123 ins_encode %{ 11124 __ movl(Address(rsp, $dst$$disp), $src$$Register); 11125 %} 11126 ins_pipe( ialu_mem_reg ); 11127%} 11128 11129instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{ 11130 match(Set dst (MoveD2L src)); 11131 effect(DEF dst, USE src); 11132 11133 ins_cost(95); // XXX 11134 format %{ "movsd $dst, $src\t# MoveL2D_reg_stack" %} 11135 ins_encode %{ 11136 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 11137 %} 11138 ins_pipe(pipe_slow); 11139%} 11140 11141instruct MoveL2D_reg_stack(stackSlotD dst, rRegL src) %{ 11142 match(Set dst (MoveL2D src)); 11143 effect(DEF dst, USE src); 11144 11145 ins_cost(100); 11146 format %{ "movq $dst, $src\t# MoveL2D_reg_stack" %} 11147 ins_encode %{ 11148 __ movq(Address(rsp, $dst$$disp), $src$$Register); 11149 %} 11150 ins_pipe(ialu_mem_reg); 11151%} 11152 11153instruct MoveF2I_reg_reg(rRegI dst, regF src) %{ 11154 match(Set dst (MoveF2I src)); 11155 effect(DEF dst, USE src); 11156 ins_cost(85); 11157 format %{ "movd $dst,$src\t# MoveF2I" %} 11158 ins_encode %{ 11159 __ movdl($dst$$Register, $src$$XMMRegister); 11160 %} 11161 ins_pipe( pipe_slow ); 11162%} 11163 11164instruct MoveD2L_reg_reg(rRegL dst, regD src) %{ 11165 match(Set dst (MoveD2L src)); 11166 effect(DEF dst, USE src); 11167 ins_cost(85); 11168 format %{ "movd $dst,$src\t# MoveD2L" %} 11169 ins_encode %{ 11170 __ movdq($dst$$Register, $src$$XMMRegister); 11171 %} 11172 ins_pipe( pipe_slow ); 11173%} 11174 11175instruct MoveI2F_reg_reg(regF dst, rRegI src) %{ 11176 match(Set dst (MoveI2F src)); 11177 effect(DEF dst, USE src); 11178 ins_cost(100); 11179 format %{ "movd $dst,$src\t# MoveI2F" %} 11180 ins_encode %{ 11181 __ movdl($dst$$XMMRegister, $src$$Register); 11182 %} 11183 ins_pipe( pipe_slow ); 11184%} 11185 11186instruct MoveL2D_reg_reg(regD dst, rRegL src) %{ 11187 match(Set dst (MoveL2D src)); 11188 effect(DEF dst, USE src); 11189 ins_cost(100); 11190 format %{ "movd $dst,$src\t# MoveL2D" %} 11191 ins_encode %{ 11192 __ movdq($dst$$XMMRegister, $src$$Register); 11193 %} 11194 ins_pipe( pipe_slow ); 11195%} 11196 11197 11198// ======================================================================= 11199// fast clearing of an array 11200instruct rep_stos(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegI zero, 11201 Universe dummy, rFlagsReg cr) 11202%{ 11203 predicate(!((ClearArrayNode*)n)->is_large()); 11204 match(Set dummy (ClearArray cnt base)); 11205 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL zero, KILL cr); 11206 11207 format %{ $$template 11208 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 11209 $$emit$$"cmp InitArrayShortSize,rcx\n\t" 11210 $$emit$$"jg LARGE\n\t" 11211 $$emit$$"dec rcx\n\t" 11212 $$emit$$"js DONE\t# Zero length\n\t" 11213 $$emit$$"mov rax,(rdi,rcx,8)\t# LOOP\n\t" 11214 $$emit$$"dec rcx\n\t" 11215 $$emit$$"jge LOOP\n\t" 11216 $$emit$$"jmp DONE\n\t" 11217 $$emit$$"# LARGE:\n\t" 11218 if (UseFastStosb) { 11219 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 11220 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--\n\t" 11221 } else if (UseXMMForObjInit) { 11222 $$emit$$"mov rdi,rax\n\t" 11223 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 11224 $$emit$$"jmpq L_zero_64_bytes\n\t" 11225 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 11226 $$emit$$"vmovdqu ymm0,(rax)\n\t" 11227 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 11228 $$emit$$"add 0x40,rax\n\t" 11229 $$emit$$"# L_zero_64_bytes:\n\t" 11230 $$emit$$"sub 0x8,rcx\n\t" 11231 $$emit$$"jge L_loop\n\t" 11232 $$emit$$"add 0x4,rcx\n\t" 11233 $$emit$$"jl L_tail\n\t" 11234 $$emit$$"vmovdqu ymm0,(rax)\n\t" 11235 $$emit$$"add 0x20,rax\n\t" 11236 $$emit$$"sub 0x4,rcx\n\t" 11237 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 11238 $$emit$$"add 0x4,rcx\n\t" 11239 $$emit$$"jle L_end\n\t" 11240 $$emit$$"dec rcx\n\t" 11241 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 11242 $$emit$$"vmovq xmm0,(rax)\n\t" 11243 $$emit$$"add 0x8,rax\n\t" 11244 $$emit$$"dec rcx\n\t" 11245 $$emit$$"jge L_sloop\n\t" 11246 $$emit$$"# L_end:\n\t" 11247 } else { 11248 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--\n\t" 11249 } 11250 $$emit$$"# DONE" 11251 %} 11252 ins_encode %{ 11253 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 11254 $tmp$$XMMRegister, false); 11255 %} 11256 ins_pipe(pipe_slow); 11257%} 11258 11259instruct rep_stos_large(rcx_RegL cnt, rdi_RegP base, regD tmp, rax_RegI zero, 11260 Universe dummy, rFlagsReg cr) 11261%{ 11262 predicate(((ClearArrayNode*)n)->is_large()); 11263 match(Set dummy (ClearArray cnt base)); 11264 effect(USE_KILL cnt, USE_KILL base, TEMP tmp, KILL zero, KILL cr); 11265 11266 format %{ $$template 11267 if (UseFastStosb) { 11268 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 11269 $$emit$$"shlq rcx,3\t# Convert doublewords to bytes\n\t" 11270 $$emit$$"rep stosb\t# Store rax to *rdi++ while rcx--" 11271 } else if (UseXMMForObjInit) { 11272 $$emit$$"mov rdi,rax\t# ClearArray:\n\t" 11273 $$emit$$"vpxor ymm0,ymm0,ymm0\n\t" 11274 $$emit$$"jmpq L_zero_64_bytes\n\t" 11275 $$emit$$"# L_loop:\t# 64-byte LOOP\n\t" 11276 $$emit$$"vmovdqu ymm0,(rax)\n\t" 11277 $$emit$$"vmovdqu ymm0,0x20(rax)\n\t" 11278 $$emit$$"add 0x40,rax\n\t" 11279 $$emit$$"# L_zero_64_bytes:\n\t" 11280 $$emit$$"sub 0x8,rcx\n\t" 11281 $$emit$$"jge L_loop\n\t" 11282 $$emit$$"add 0x4,rcx\n\t" 11283 $$emit$$"jl L_tail\n\t" 11284 $$emit$$"vmovdqu ymm0,(rax)\n\t" 11285 $$emit$$"add 0x20,rax\n\t" 11286 $$emit$$"sub 0x4,rcx\n\t" 11287 $$emit$$"# L_tail:\t# Clearing tail bytes\n\t" 11288 $$emit$$"add 0x4,rcx\n\t" 11289 $$emit$$"jle L_end\n\t" 11290 $$emit$$"dec rcx\n\t" 11291 $$emit$$"# L_sloop:\t# 8-byte short loop\n\t" 11292 $$emit$$"vmovq xmm0,(rax)\n\t" 11293 $$emit$$"add 0x8,rax\n\t" 11294 $$emit$$"dec rcx\n\t" 11295 $$emit$$"jge L_sloop\n\t" 11296 $$emit$$"# L_end:\n\t" 11297 } else { 11298 $$emit$$"xorq rax, rax\t# ClearArray:\n\t" 11299 $$emit$$"rep stosq\t# Store rax to *rdi++ while rcx--" 11300 } 11301 %} 11302 ins_encode %{ 11303 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register, 11304 $tmp$$XMMRegister, true); 11305 %} 11306 ins_pipe(pipe_slow); 11307%} 11308 11309instruct string_compareL(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 11310 rax_RegI result, legVecS tmp1, rFlagsReg cr) 11311%{ 11312 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LL); 11313 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11314 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11315 11316 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11317 ins_encode %{ 11318 __ string_compare($str1$$Register, $str2$$Register, 11319 $cnt1$$Register, $cnt2$$Register, $result$$Register, 11320 $tmp1$$XMMRegister, StrIntrinsicNode::LL); 11321 %} 11322 ins_pipe( pipe_slow ); 11323%} 11324 11325instruct string_compareU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 11326 rax_RegI result, legVecS tmp1, rFlagsReg cr) 11327%{ 11328 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU); 11329 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11330 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11331 11332 format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11333 ins_encode %{ 11334 __ string_compare($str1$$Register, $str2$$Register, 11335 $cnt1$$Register, $cnt2$$Register, $result$$Register, 11336 $tmp1$$XMMRegister, StrIntrinsicNode::UU); 11337 %} 11338 ins_pipe( pipe_slow ); 11339%} 11340 11341instruct string_compareLU(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 11342 rax_RegI result, legVecS tmp1, rFlagsReg cr) 11343%{ 11344 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::LU); 11345 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11346 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11347 11348 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11349 ins_encode %{ 11350 __ string_compare($str1$$Register, $str2$$Register, 11351 $cnt1$$Register, $cnt2$$Register, $result$$Register, 11352 $tmp1$$XMMRegister, StrIntrinsicNode::LU); 11353 %} 11354 ins_pipe( pipe_slow ); 11355%} 11356 11357instruct string_compareUL(rsi_RegP str1, rdx_RegI cnt1, rdi_RegP str2, rcx_RegI cnt2, 11358 rax_RegI result, legVecS tmp1, rFlagsReg cr) 11359%{ 11360 predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UL); 11361 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11362 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11363 11364 format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11365 ins_encode %{ 11366 __ string_compare($str2$$Register, $str1$$Register, 11367 $cnt2$$Register, $cnt1$$Register, $result$$Register, 11368 $tmp1$$XMMRegister, StrIntrinsicNode::UL); 11369 %} 11370 ins_pipe( pipe_slow ); 11371%} 11372 11373// fast search of substring with known size. 11374instruct string_indexof_conL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 11375 rbx_RegI result, legVecS vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 11376%{ 11377 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 11378 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 11379 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 11380 11381 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 11382 ins_encode %{ 11383 int icnt2 = (int)$int_cnt2$$constant; 11384 if (icnt2 >= 16) { 11385 // IndexOf for constant substrings with size >= 16 elements 11386 // which don't need to be loaded through stack. 11387 __ string_indexofC8($str1$$Register, $str2$$Register, 11388 $cnt1$$Register, $cnt2$$Register, 11389 icnt2, $result$$Register, 11390 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 11391 } else { 11392 // Small strings are loaded through stack if they cross page boundary. 11393 __ string_indexof($str1$$Register, $str2$$Register, 11394 $cnt1$$Register, $cnt2$$Register, 11395 icnt2, $result$$Register, 11396 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 11397 } 11398 %} 11399 ins_pipe( pipe_slow ); 11400%} 11401 11402// fast search of substring with known size. 11403instruct string_indexof_conU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 11404 rbx_RegI result, legVecS vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 11405%{ 11406 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 11407 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 11408 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 11409 11410 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 11411 ins_encode %{ 11412 int icnt2 = (int)$int_cnt2$$constant; 11413 if (icnt2 >= 8) { 11414 // IndexOf for constant substrings with size >= 8 elements 11415 // which don't need to be loaded through stack. 11416 __ string_indexofC8($str1$$Register, $str2$$Register, 11417 $cnt1$$Register, $cnt2$$Register, 11418 icnt2, $result$$Register, 11419 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 11420 } else { 11421 // Small strings are loaded through stack if they cross page boundary. 11422 __ string_indexof($str1$$Register, $str2$$Register, 11423 $cnt1$$Register, $cnt2$$Register, 11424 icnt2, $result$$Register, 11425 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 11426 } 11427 %} 11428 ins_pipe( pipe_slow ); 11429%} 11430 11431// fast search of substring with known size. 11432instruct string_indexof_conUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 11433 rbx_RegI result, legVecS vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 11434%{ 11435 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 11436 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 11437 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 11438 11439 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 11440 ins_encode %{ 11441 int icnt2 = (int)$int_cnt2$$constant; 11442 if (icnt2 >= 8) { 11443 // IndexOf for constant substrings with size >= 8 elements 11444 // which don't need to be loaded through stack. 11445 __ string_indexofC8($str1$$Register, $str2$$Register, 11446 $cnt1$$Register, $cnt2$$Register, 11447 icnt2, $result$$Register, 11448 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 11449 } else { 11450 // Small strings are loaded through stack if they cross page boundary. 11451 __ string_indexof($str1$$Register, $str2$$Register, 11452 $cnt1$$Register, $cnt2$$Register, 11453 icnt2, $result$$Register, 11454 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 11455 } 11456 %} 11457 ins_pipe( pipe_slow ); 11458%} 11459 11460instruct string_indexofL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11461 rbx_RegI result, legVecS vec, rcx_RegI tmp, rFlagsReg cr) 11462%{ 11463 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::LL)); 11464 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11465 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11466 11467 format %{ "String IndexOf byte[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11468 ins_encode %{ 11469 __ string_indexof($str1$$Register, $str2$$Register, 11470 $cnt1$$Register, $cnt2$$Register, 11471 (-1), $result$$Register, 11472 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::LL); 11473 %} 11474 ins_pipe( pipe_slow ); 11475%} 11476 11477instruct string_indexofU(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11478 rbx_RegI result, legVecS vec, rcx_RegI tmp, rFlagsReg cr) 11479%{ 11480 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU)); 11481 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11482 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11483 11484 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11485 ins_encode %{ 11486 __ string_indexof($str1$$Register, $str2$$Register, 11487 $cnt1$$Register, $cnt2$$Register, 11488 (-1), $result$$Register, 11489 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UU); 11490 %} 11491 ins_pipe( pipe_slow ); 11492%} 11493 11494instruct string_indexofUL(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 11495 rbx_RegI result, legVecS vec, rcx_RegI tmp, rFlagsReg cr) 11496%{ 11497 predicate(UseSSE42Intrinsics && (((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UL)); 11498 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11499 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11500 11501 format %{ "String IndexOf char[] $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11502 ins_encode %{ 11503 __ string_indexof($str1$$Register, $str2$$Register, 11504 $cnt1$$Register, $cnt2$$Register, 11505 (-1), $result$$Register, 11506 $vec$$XMMRegister, $tmp$$Register, StrIntrinsicNode::UL); 11507 %} 11508 ins_pipe( pipe_slow ); 11509%} 11510 11511instruct string_indexofU_char(rdi_RegP str1, rdx_RegI cnt1, rax_RegI ch, 11512 rbx_RegI result, legVecS vec1, legVecS vec2, legVecS vec3, rcx_RegI tmp, rFlagsReg cr) 11513%{ 11514 predicate(UseSSE42Intrinsics); 11515 match(Set result (StrIndexOfChar (Binary str1 cnt1) ch)); 11516 effect(TEMP vec1, TEMP vec2, TEMP vec3, USE_KILL str1, USE_KILL cnt1, USE_KILL ch, TEMP tmp, KILL cr); 11517 format %{ "String IndexOf char[] $str1,$cnt1,$ch -> $result // KILL all" %} 11518 ins_encode %{ 11519 __ string_indexof_char($str1$$Register, $cnt1$$Register, $ch$$Register, $result$$Register, 11520 $vec1$$XMMRegister, $vec2$$XMMRegister, $vec3$$XMMRegister, $tmp$$Register); 11521 %} 11522 ins_pipe( pipe_slow ); 11523%} 11524 11525// fast string equals 11526instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 11527 legVecS tmp1, legVecS tmp2, rbx_RegI tmp3, rFlagsReg cr) 11528%{ 11529 match(Set result (StrEquals (Binary str1 str2) cnt)); 11530 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 11531 11532 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11533 ins_encode %{ 11534 __ arrays_equals(false, $str1$$Register, $str2$$Register, 11535 $cnt$$Register, $result$$Register, $tmp3$$Register, 11536 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */); 11537 %} 11538 ins_pipe( pipe_slow ); 11539%} 11540 11541// fast array equals 11542instruct array_equalsB(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11543 legVecS tmp1, legVecS tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11544%{ 11545 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::LL); 11546 match(Set result (AryEq ary1 ary2)); 11547 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11548 11549 format %{ "Array Equals byte[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11550 ins_encode %{ 11551 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11552 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11553 $tmp1$$XMMRegister, $tmp2$$XMMRegister, false /* char */); 11554 %} 11555 ins_pipe( pipe_slow ); 11556%} 11557 11558instruct array_equalsC(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 11559 legVecS tmp1, legVecS tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 11560%{ 11561 predicate(((AryEqNode*)n)->encoding() == StrIntrinsicNode::UU); 11562 match(Set result (AryEq ary1 ary2)); 11563 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11564 11565 format %{ "Array Equals char[] $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11566 ins_encode %{ 11567 __ arrays_equals(true, $ary1$$Register, $ary2$$Register, 11568 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11569 $tmp1$$XMMRegister, $tmp2$$XMMRegister, true /* char */); 11570 %} 11571 ins_pipe( pipe_slow ); 11572%} 11573 11574instruct has_negatives(rsi_RegP ary1, rcx_RegI len, rax_RegI result, 11575 legVecS tmp1, legVecS tmp2, rbx_RegI tmp3, rFlagsReg cr) 11576%{ 11577 match(Set result (HasNegatives ary1 len)); 11578 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL len, KILL tmp3, KILL cr); 11579 11580 format %{ "has negatives byte[] $ary1,$len -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11581 ins_encode %{ 11582 __ has_negatives($ary1$$Register, $len$$Register, 11583 $result$$Register, $tmp3$$Register, 11584 $tmp1$$XMMRegister, $tmp2$$XMMRegister); 11585 %} 11586 ins_pipe( pipe_slow ); 11587%} 11588 11589// fast char[] to byte[] compression 11590instruct string_compress(rsi_RegP src, rdi_RegP dst, rdx_RegI len, legVecS tmp1, legVecS tmp2, legVecS tmp3, legVecS tmp4, 11591 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11592 match(Set result (StrCompressedCopy src (Binary dst len))); 11593 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 11594 11595 format %{ "String Compress $src,$dst -> $result // KILL RAX, RCX, RDX" %} 11596 ins_encode %{ 11597 __ char_array_compress($src$$Register, $dst$$Register, $len$$Register, 11598 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11599 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register); 11600 %} 11601 ins_pipe( pipe_slow ); 11602%} 11603 11604// fast byte[] to char[] inflation 11605instruct string_inflate(Universe dummy, rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11606 legVecS tmp1, rcx_RegI tmp2, rFlagsReg cr) %{ 11607 match(Set dummy (StrInflatedCopy src (Binary dst len))); 11608 effect(TEMP tmp1, TEMP tmp2, USE_KILL src, USE_KILL dst, USE_KILL len, KILL cr); 11609 11610 format %{ "String Inflate $src,$dst // KILL $tmp1, $tmp2" %} 11611 ins_encode %{ 11612 __ byte_array_inflate($src$$Register, $dst$$Register, $len$$Register, 11613 $tmp1$$XMMRegister, $tmp2$$Register); 11614 %} 11615 ins_pipe( pipe_slow ); 11616%} 11617 11618// encode char[] to byte[] in ISO_8859_1 11619instruct encode_iso_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len, 11620 legVecS tmp1, legVecS tmp2, legVecS tmp3, legVecS tmp4, 11621 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 11622 match(Set result (EncodeISOArray src (Binary dst len))); 11623 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 11624 11625 format %{ "Encode array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %} 11626 ins_encode %{ 11627 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 11628 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11629 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register); 11630 %} 11631 ins_pipe( pipe_slow ); 11632%} 11633 11634//----------Overflow Math Instructions----------------------------------------- 11635 11636instruct overflowAddI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 11637%{ 11638 match(Set cr (OverflowAddI op1 op2)); 11639 effect(DEF cr, USE_KILL op1, USE op2); 11640 11641 format %{ "addl $op1, $op2\t# overflow check int" %} 11642 11643 ins_encode %{ 11644 __ addl($op1$$Register, $op2$$Register); 11645 %} 11646 ins_pipe(ialu_reg_reg); 11647%} 11648 11649instruct overflowAddI_rReg_imm(rFlagsReg cr, rax_RegI op1, immI op2) 11650%{ 11651 match(Set cr (OverflowAddI op1 op2)); 11652 effect(DEF cr, USE_KILL op1, USE op2); 11653 11654 format %{ "addl $op1, $op2\t# overflow check int" %} 11655 11656 ins_encode %{ 11657 __ addl($op1$$Register, $op2$$constant); 11658 %} 11659 ins_pipe(ialu_reg_reg); 11660%} 11661 11662instruct overflowAddL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 11663%{ 11664 match(Set cr (OverflowAddL op1 op2)); 11665 effect(DEF cr, USE_KILL op1, USE op2); 11666 11667 format %{ "addq $op1, $op2\t# overflow check long" %} 11668 ins_encode %{ 11669 __ addq($op1$$Register, $op2$$Register); 11670 %} 11671 ins_pipe(ialu_reg_reg); 11672%} 11673 11674instruct overflowAddL_rReg_imm(rFlagsReg cr, rax_RegL op1, immL32 op2) 11675%{ 11676 match(Set cr (OverflowAddL op1 op2)); 11677 effect(DEF cr, USE_KILL op1, USE op2); 11678 11679 format %{ "addq $op1, $op2\t# overflow check long" %} 11680 ins_encode %{ 11681 __ addq($op1$$Register, $op2$$constant); 11682 %} 11683 ins_pipe(ialu_reg_reg); 11684%} 11685 11686instruct overflowSubI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 11687%{ 11688 match(Set cr (OverflowSubI op1 op2)); 11689 11690 format %{ "cmpl $op1, $op2\t# overflow check int" %} 11691 ins_encode %{ 11692 __ cmpl($op1$$Register, $op2$$Register); 11693 %} 11694 ins_pipe(ialu_reg_reg); 11695%} 11696 11697instruct overflowSubI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 11698%{ 11699 match(Set cr (OverflowSubI op1 op2)); 11700 11701 format %{ "cmpl $op1, $op2\t# overflow check int" %} 11702 ins_encode %{ 11703 __ cmpl($op1$$Register, $op2$$constant); 11704 %} 11705 ins_pipe(ialu_reg_reg); 11706%} 11707 11708instruct overflowSubL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 11709%{ 11710 match(Set cr (OverflowSubL op1 op2)); 11711 11712 format %{ "cmpq $op1, $op2\t# overflow check long" %} 11713 ins_encode %{ 11714 __ cmpq($op1$$Register, $op2$$Register); 11715 %} 11716 ins_pipe(ialu_reg_reg); 11717%} 11718 11719instruct overflowSubL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 11720%{ 11721 match(Set cr (OverflowSubL op1 op2)); 11722 11723 format %{ "cmpq $op1, $op2\t# overflow check long" %} 11724 ins_encode %{ 11725 __ cmpq($op1$$Register, $op2$$constant); 11726 %} 11727 ins_pipe(ialu_reg_reg); 11728%} 11729 11730instruct overflowNegI_rReg(rFlagsReg cr, immI0 zero, rax_RegI op2) 11731%{ 11732 match(Set cr (OverflowSubI zero op2)); 11733 effect(DEF cr, USE_KILL op2); 11734 11735 format %{ "negl $op2\t# overflow check int" %} 11736 ins_encode %{ 11737 __ negl($op2$$Register); 11738 %} 11739 ins_pipe(ialu_reg_reg); 11740%} 11741 11742instruct overflowNegL_rReg(rFlagsReg cr, immL0 zero, rax_RegL op2) 11743%{ 11744 match(Set cr (OverflowSubL zero op2)); 11745 effect(DEF cr, USE_KILL op2); 11746 11747 format %{ "negq $op2\t# overflow check long" %} 11748 ins_encode %{ 11749 __ negq($op2$$Register); 11750 %} 11751 ins_pipe(ialu_reg_reg); 11752%} 11753 11754instruct overflowMulI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 11755%{ 11756 match(Set cr (OverflowMulI op1 op2)); 11757 effect(DEF cr, USE_KILL op1, USE op2); 11758 11759 format %{ "imull $op1, $op2\t# overflow check int" %} 11760 ins_encode %{ 11761 __ imull($op1$$Register, $op2$$Register); 11762 %} 11763 ins_pipe(ialu_reg_reg_alu0); 11764%} 11765 11766instruct overflowMulI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2, rRegI tmp) 11767%{ 11768 match(Set cr (OverflowMulI op1 op2)); 11769 effect(DEF cr, TEMP tmp, USE op1, USE op2); 11770 11771 format %{ "imull $tmp, $op1, $op2\t# overflow check int" %} 11772 ins_encode %{ 11773 __ imull($tmp$$Register, $op1$$Register, $op2$$constant); 11774 %} 11775 ins_pipe(ialu_reg_reg_alu0); 11776%} 11777 11778instruct overflowMulL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 11779%{ 11780 match(Set cr (OverflowMulL op1 op2)); 11781 effect(DEF cr, USE_KILL op1, USE op2); 11782 11783 format %{ "imulq $op1, $op2\t# overflow check long" %} 11784 ins_encode %{ 11785 __ imulq($op1$$Register, $op2$$Register); 11786 %} 11787 ins_pipe(ialu_reg_reg_alu0); 11788%} 11789 11790instruct overflowMulL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2, rRegL tmp) 11791%{ 11792 match(Set cr (OverflowMulL op1 op2)); 11793 effect(DEF cr, TEMP tmp, USE op1, USE op2); 11794 11795 format %{ "imulq $tmp, $op1, $op2\t# overflow check long" %} 11796 ins_encode %{ 11797 __ imulq($tmp$$Register, $op1$$Register, $op2$$constant); 11798 %} 11799 ins_pipe(ialu_reg_reg_alu0); 11800%} 11801 11802 11803//----------Control Flow Instructions------------------------------------------ 11804// Signed compare Instructions 11805 11806// XXX more variants!! 11807instruct compI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 11808%{ 11809 match(Set cr (CmpI op1 op2)); 11810 effect(DEF cr, USE op1, USE op2); 11811 11812 format %{ "cmpl $op1, $op2" %} 11813 opcode(0x3B); /* Opcode 3B /r */ 11814 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2)); 11815 ins_pipe(ialu_cr_reg_reg); 11816%} 11817 11818instruct compI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 11819%{ 11820 match(Set cr (CmpI op1 op2)); 11821 11822 format %{ "cmpl $op1, $op2" %} 11823 opcode(0x81, 0x07); /* Opcode 81 /7 */ 11824 ins_encode(OpcSErm(op1, op2), Con8or32(op2)); 11825 ins_pipe(ialu_cr_reg_imm); 11826%} 11827 11828instruct compI_rReg_mem(rFlagsReg cr, rRegI op1, memory op2) 11829%{ 11830 match(Set cr (CmpI op1 (LoadI op2))); 11831 11832 ins_cost(500); // XXX 11833 format %{ "cmpl $op1, $op2" %} 11834 opcode(0x3B); /* Opcode 3B /r */ 11835 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2)); 11836 ins_pipe(ialu_cr_reg_mem); 11837%} 11838 11839instruct testI_reg(rFlagsReg cr, rRegI src, immI0 zero) 11840%{ 11841 match(Set cr (CmpI src zero)); 11842 11843 format %{ "testl $src, $src" %} 11844 opcode(0x85); 11845 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src)); 11846 ins_pipe(ialu_cr_reg_imm); 11847%} 11848 11849instruct testI_reg_imm(rFlagsReg cr, rRegI src, immI con, immI0 zero) 11850%{ 11851 match(Set cr (CmpI (AndI src con) zero)); 11852 11853 format %{ "testl $src, $con" %} 11854 opcode(0xF7, 0x00); 11855 ins_encode(REX_reg(src), OpcP, reg_opc(src), Con32(con)); 11856 ins_pipe(ialu_cr_reg_imm); 11857%} 11858 11859instruct testI_reg_mem(rFlagsReg cr, rRegI src, memory mem, immI0 zero) 11860%{ 11861 match(Set cr (CmpI (AndI src (LoadI mem)) zero)); 11862 11863 format %{ "testl $src, $mem" %} 11864 opcode(0x85); 11865 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 11866 ins_pipe(ialu_cr_reg_mem); 11867%} 11868 11869// Unsigned compare Instructions; really, same as signed except they 11870// produce an rFlagsRegU instead of rFlagsReg. 11871instruct compU_rReg(rFlagsRegU cr, rRegI op1, rRegI op2) 11872%{ 11873 match(Set cr (CmpU op1 op2)); 11874 11875 format %{ "cmpl $op1, $op2\t# unsigned" %} 11876 opcode(0x3B); /* Opcode 3B /r */ 11877 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2)); 11878 ins_pipe(ialu_cr_reg_reg); 11879%} 11880 11881instruct compU_rReg_imm(rFlagsRegU cr, rRegI op1, immI op2) 11882%{ 11883 match(Set cr (CmpU op1 op2)); 11884 11885 format %{ "cmpl $op1, $op2\t# unsigned" %} 11886 opcode(0x81,0x07); /* Opcode 81 /7 */ 11887 ins_encode(OpcSErm(op1, op2), Con8or32(op2)); 11888 ins_pipe(ialu_cr_reg_imm); 11889%} 11890 11891instruct compU_rReg_mem(rFlagsRegU cr, rRegI op1, memory op2) 11892%{ 11893 match(Set cr (CmpU op1 (LoadI op2))); 11894 11895 ins_cost(500); // XXX 11896 format %{ "cmpl $op1, $op2\t# unsigned" %} 11897 opcode(0x3B); /* Opcode 3B /r */ 11898 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2)); 11899 ins_pipe(ialu_cr_reg_mem); 11900%} 11901 11902// // // Cisc-spilled version of cmpU_rReg 11903// //instruct compU_mem_rReg(rFlagsRegU cr, memory op1, rRegI op2) 11904// //%{ 11905// // match(Set cr (CmpU (LoadI op1) op2)); 11906// // 11907// // format %{ "CMPu $op1,$op2" %} 11908// // ins_cost(500); 11909// // opcode(0x39); /* Opcode 39 /r */ 11910// // ins_encode( OpcP, reg_mem( op1, op2) ); 11911// //%} 11912 11913instruct testU_reg(rFlagsRegU cr, rRegI src, immI0 zero) 11914%{ 11915 match(Set cr (CmpU src zero)); 11916 11917 format %{ "testl $src, $src\t# unsigned" %} 11918 opcode(0x85); 11919 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src)); 11920 ins_pipe(ialu_cr_reg_imm); 11921%} 11922 11923instruct compP_rReg(rFlagsRegU cr, rRegP op1, rRegP op2) 11924%{ 11925 match(Set cr (CmpP op1 op2)); 11926 11927 format %{ "cmpq $op1, $op2\t# ptr" %} 11928 opcode(0x3B); /* Opcode 3B /r */ 11929 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 11930 ins_pipe(ialu_cr_reg_reg); 11931%} 11932 11933instruct compP_rReg_mem(rFlagsRegU cr, rRegP op1, memory op2) 11934%{ 11935 match(Set cr (CmpP op1 (LoadP op2))); 11936 11937 ins_cost(500); // XXX 11938 format %{ "cmpq $op1, $op2\t# ptr" %} 11939 opcode(0x3B); /* Opcode 3B /r */ 11940 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11941 ins_pipe(ialu_cr_reg_mem); 11942%} 11943 11944// // // Cisc-spilled version of cmpP_rReg 11945// //instruct compP_mem_rReg(rFlagsRegU cr, memory op1, rRegP op2) 11946// //%{ 11947// // match(Set cr (CmpP (LoadP op1) op2)); 11948// // 11949// // format %{ "CMPu $op1,$op2" %} 11950// // ins_cost(500); 11951// // opcode(0x39); /* Opcode 39 /r */ 11952// // ins_encode( OpcP, reg_mem( op1, op2) ); 11953// //%} 11954 11955// XXX this is generalized by compP_rReg_mem??? 11956// Compare raw pointer (used in out-of-heap check). 11957// Only works because non-oop pointers must be raw pointers 11958// and raw pointers have no anti-dependencies. 11959instruct compP_mem_rReg(rFlagsRegU cr, rRegP op1, memory op2) 11960%{ 11961 predicate(n->in(2)->in(2)->bottom_type()->reloc() == relocInfo::none); 11962 match(Set cr (CmpP op1 (LoadP op2))); 11963 11964 format %{ "cmpq $op1, $op2\t# raw ptr" %} 11965 opcode(0x3B); /* Opcode 3B /r */ 11966 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 11967 ins_pipe(ialu_cr_reg_mem); 11968%} 11969 11970// This will generate a signed flags result. This should be OK since 11971// any compare to a zero should be eq/neq. 11972instruct testP_reg(rFlagsReg cr, rRegP src, immP0 zero) 11973%{ 11974 match(Set cr (CmpP src zero)); 11975 11976 format %{ "testq $src, $src\t# ptr" %} 11977 opcode(0x85); 11978 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 11979 ins_pipe(ialu_cr_reg_imm); 11980%} 11981 11982// This will generate a signed flags result. This should be OK since 11983// any compare to a zero should be eq/neq. 11984instruct testP_mem(rFlagsReg cr, memory op, immP0 zero) 11985%{ 11986 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL)); 11987 match(Set cr (CmpP (LoadP op) zero)); 11988 11989 ins_cost(500); // XXX 11990 format %{ "testq $op, 0xffffffffffffffff\t# ptr" %} 11991 opcode(0xF7); /* Opcode F7 /0 */ 11992 ins_encode(REX_mem_wide(op), 11993 OpcP, RM_opc_mem(0x00, op), Con_d32(0xFFFFFFFF)); 11994 ins_pipe(ialu_cr_reg_imm); 11995%} 11996 11997instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero) 11998%{ 11999 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 12000 match(Set cr (CmpP (LoadP mem) zero)); 12001 12002 format %{ "cmpq R12, $mem\t# ptr (R12_heapbase==0)" %} 12003 ins_encode %{ 12004 __ cmpq(r12, $mem$$Address); 12005 %} 12006 ins_pipe(ialu_cr_reg_mem); 12007%} 12008 12009instruct compN_rReg(rFlagsRegU cr, rRegN op1, rRegN op2) 12010%{ 12011 match(Set cr (CmpN op1 op2)); 12012 12013 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 12014 ins_encode %{ __ cmpl($op1$$Register, $op2$$Register); %} 12015 ins_pipe(ialu_cr_reg_reg); 12016%} 12017 12018instruct compN_rReg_mem(rFlagsRegU cr, rRegN src, memory mem) 12019%{ 12020 match(Set cr (CmpN src (LoadN mem))); 12021 12022 format %{ "cmpl $src, $mem\t# compressed ptr" %} 12023 ins_encode %{ 12024 __ cmpl($src$$Register, $mem$$Address); 12025 %} 12026 ins_pipe(ialu_cr_reg_mem); 12027%} 12028 12029instruct compN_rReg_imm(rFlagsRegU cr, rRegN op1, immN op2) %{ 12030 match(Set cr (CmpN op1 op2)); 12031 12032 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 12033 ins_encode %{ 12034 __ cmp_narrow_oop($op1$$Register, (jobject)$op2$$constant); 12035 %} 12036 ins_pipe(ialu_cr_reg_imm); 12037%} 12038 12039instruct compN_mem_imm(rFlagsRegU cr, memory mem, immN src) 12040%{ 12041 match(Set cr (CmpN src (LoadN mem))); 12042 12043 format %{ "cmpl $mem, $src\t# compressed ptr" %} 12044 ins_encode %{ 12045 __ cmp_narrow_oop($mem$$Address, (jobject)$src$$constant); 12046 %} 12047 ins_pipe(ialu_cr_reg_mem); 12048%} 12049 12050instruct compN_rReg_imm_klass(rFlagsRegU cr, rRegN op1, immNKlass op2) %{ 12051 match(Set cr (CmpN op1 op2)); 12052 12053 format %{ "cmpl $op1, $op2\t# compressed klass ptr" %} 12054 ins_encode %{ 12055 __ cmp_narrow_klass($op1$$Register, (Klass*)$op2$$constant); 12056 %} 12057 ins_pipe(ialu_cr_reg_imm); 12058%} 12059 12060instruct compN_mem_imm_klass(rFlagsRegU cr, memory mem, immNKlass src) 12061%{ 12062 match(Set cr (CmpN src (LoadNKlass mem))); 12063 12064 format %{ "cmpl $mem, $src\t# compressed klass ptr" %} 12065 ins_encode %{ 12066 __ cmp_narrow_klass($mem$$Address, (Klass*)$src$$constant); 12067 %} 12068 ins_pipe(ialu_cr_reg_mem); 12069%} 12070 12071instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{ 12072 match(Set cr (CmpN src zero)); 12073 12074 format %{ "testl $src, $src\t# compressed ptr" %} 12075 ins_encode %{ __ testl($src$$Register, $src$$Register); %} 12076 ins_pipe(ialu_cr_reg_imm); 12077%} 12078 12079instruct testN_mem(rFlagsReg cr, memory mem, immN0 zero) 12080%{ 12081 predicate(Universe::narrow_oop_base() != NULL); 12082 match(Set cr (CmpN (LoadN mem) zero)); 12083 12084 ins_cost(500); // XXX 12085 format %{ "testl $mem, 0xffffffff\t# compressed ptr" %} 12086 ins_encode %{ 12087 __ cmpl($mem$$Address, (int)0xFFFFFFFF); 12088 %} 12089 ins_pipe(ialu_cr_reg_mem); 12090%} 12091 12092instruct testN_mem_reg0(rFlagsReg cr, memory mem, immN0 zero) 12093%{ 12094 predicate(Universe::narrow_oop_base() == NULL && (Universe::narrow_klass_base() == NULL)); 12095 match(Set cr (CmpN (LoadN mem) zero)); 12096 12097 format %{ "cmpl R12, $mem\t# compressed ptr (R12_heapbase==0)" %} 12098 ins_encode %{ 12099 __ cmpl(r12, $mem$$Address); 12100 %} 12101 ins_pipe(ialu_cr_reg_mem); 12102%} 12103 12104// Yanked all unsigned pointer compare operations. 12105// Pointer compares are done with CmpP which is already unsigned. 12106 12107instruct compL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 12108%{ 12109 match(Set cr (CmpL op1 op2)); 12110 12111 format %{ "cmpq $op1, $op2" %} 12112 opcode(0x3B); /* Opcode 3B /r */ 12113 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 12114 ins_pipe(ialu_cr_reg_reg); 12115%} 12116 12117instruct compL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 12118%{ 12119 match(Set cr (CmpL op1 op2)); 12120 12121 format %{ "cmpq $op1, $op2" %} 12122 opcode(0x81, 0x07); /* Opcode 81 /7 */ 12123 ins_encode(OpcSErm_wide(op1, op2), Con8or32(op2)); 12124 ins_pipe(ialu_cr_reg_imm); 12125%} 12126 12127instruct compL_rReg_mem(rFlagsReg cr, rRegL op1, memory op2) 12128%{ 12129 match(Set cr (CmpL op1 (LoadL op2))); 12130 12131 format %{ "cmpq $op1, $op2" %} 12132 opcode(0x3B); /* Opcode 3B /r */ 12133 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 12134 ins_pipe(ialu_cr_reg_mem); 12135%} 12136 12137instruct testL_reg(rFlagsReg cr, rRegL src, immL0 zero) 12138%{ 12139 match(Set cr (CmpL src zero)); 12140 12141 format %{ "testq $src, $src" %} 12142 opcode(0x85); 12143 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 12144 ins_pipe(ialu_cr_reg_imm); 12145%} 12146 12147instruct testL_reg_imm(rFlagsReg cr, rRegL src, immL32 con, immL0 zero) 12148%{ 12149 match(Set cr (CmpL (AndL src con) zero)); 12150 12151 format %{ "testq $src, $con\t# long" %} 12152 opcode(0xF7, 0x00); 12153 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src), Con32(con)); 12154 ins_pipe(ialu_cr_reg_imm); 12155%} 12156 12157instruct testL_reg_mem(rFlagsReg cr, rRegL src, memory mem, immL0 zero) 12158%{ 12159 match(Set cr (CmpL (AndL src (LoadL mem)) zero)); 12160 12161 format %{ "testq $src, $mem" %} 12162 opcode(0x85); 12163 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 12164 ins_pipe(ialu_cr_reg_mem); 12165%} 12166 12167instruct testL_reg_mem2(rFlagsReg cr, rRegP src, memory mem, immL0 zero) 12168%{ 12169 match(Set cr (CmpL (AndL (CastP2X src) (LoadL mem)) zero)); 12170 12171 format %{ "testq $src, $mem" %} 12172 opcode(0x85); 12173 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 12174 ins_pipe(ialu_cr_reg_mem); 12175%} 12176 12177// Manifest a CmpL result in an integer register. Very painful. 12178// This is the test to avoid. 12179instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 12180%{ 12181 match(Set dst (CmpL3 src1 src2)); 12182 effect(KILL flags); 12183 12184 ins_cost(275); // XXX 12185 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 12186 "movl $dst, -1\n\t" 12187 "jl,s done\n\t" 12188 "setne $dst\n\t" 12189 "movzbl $dst, $dst\n\t" 12190 "done:" %} 12191 ins_encode(cmpl3_flag(src1, src2, dst)); 12192 ins_pipe(pipe_slow); 12193%} 12194 12195// Unsigned long compare Instructions; really, same as signed long except they 12196// produce an rFlagsRegU instead of rFlagsReg. 12197instruct compUL_rReg(rFlagsRegU cr, rRegL op1, rRegL op2) 12198%{ 12199 match(Set cr (CmpUL op1 op2)); 12200 12201 format %{ "cmpq $op1, $op2\t# unsigned" %} 12202 opcode(0x3B); /* Opcode 3B /r */ 12203 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 12204 ins_pipe(ialu_cr_reg_reg); 12205%} 12206 12207instruct compUL_rReg_imm(rFlagsRegU cr, rRegL op1, immL32 op2) 12208%{ 12209 match(Set cr (CmpUL op1 op2)); 12210 12211 format %{ "cmpq $op1, $op2\t# unsigned" %} 12212 opcode(0x81, 0x07); /* Opcode 81 /7 */ 12213 ins_encode(OpcSErm_wide(op1, op2), Con8or32(op2)); 12214 ins_pipe(ialu_cr_reg_imm); 12215%} 12216 12217instruct compUL_rReg_mem(rFlagsRegU cr, rRegL op1, memory op2) 12218%{ 12219 match(Set cr (CmpUL op1 (LoadL op2))); 12220 12221 format %{ "cmpq $op1, $op2\t# unsigned" %} 12222 opcode(0x3B); /* Opcode 3B /r */ 12223 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 12224 ins_pipe(ialu_cr_reg_mem); 12225%} 12226 12227instruct testUL_reg(rFlagsRegU cr, rRegL src, immL0 zero) 12228%{ 12229 match(Set cr (CmpUL src zero)); 12230 12231 format %{ "testq $src, $src\t# unsigned" %} 12232 opcode(0x85); 12233 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 12234 ins_pipe(ialu_cr_reg_imm); 12235%} 12236 12237instruct compB_mem_imm(rFlagsReg cr, memory mem, immI8 imm) 12238%{ 12239 match(Set cr (CmpI (LoadB mem) imm)); 12240 12241 ins_cost(125); 12242 format %{ "cmpb $mem, $imm" %} 12243 ins_encode %{ __ cmpb($mem$$Address, $imm$$constant); %} 12244 ins_pipe(ialu_cr_reg_mem); 12245%} 12246 12247instruct testB_mem_imm(rFlagsReg cr, memory mem, immI8 imm, immI0 zero) 12248%{ 12249 match(Set cr (CmpI (AndI (LoadB mem) imm) zero)); 12250 12251 ins_cost(125); 12252 format %{ "testb $mem, $imm" %} 12253 ins_encode %{ __ testb($mem$$Address, $imm$$constant); %} 12254 ins_pipe(ialu_cr_reg_mem); 12255%} 12256 12257//----------Max and Min-------------------------------------------------------- 12258// Min Instructions 12259 12260instruct cmovI_reg_g(rRegI dst, rRegI src, rFlagsReg cr) 12261%{ 12262 effect(USE_DEF dst, USE src, USE cr); 12263 12264 format %{ "cmovlgt $dst, $src\t# min" %} 12265 opcode(0x0F, 0x4F); 12266 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 12267 ins_pipe(pipe_cmov_reg); 12268%} 12269 12270 12271instruct minI_rReg(rRegI dst, rRegI src) 12272%{ 12273 match(Set dst (MinI dst src)); 12274 12275 ins_cost(200); 12276 expand %{ 12277 rFlagsReg cr; 12278 compI_rReg(cr, dst, src); 12279 cmovI_reg_g(dst, src, cr); 12280 %} 12281%} 12282 12283instruct cmovI_reg_l(rRegI dst, rRegI src, rFlagsReg cr) 12284%{ 12285 effect(USE_DEF dst, USE src, USE cr); 12286 12287 format %{ "cmovllt $dst, $src\t# max" %} 12288 opcode(0x0F, 0x4C); 12289 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 12290 ins_pipe(pipe_cmov_reg); 12291%} 12292 12293 12294instruct maxI_rReg(rRegI dst, rRegI src) 12295%{ 12296 match(Set dst (MaxI dst src)); 12297 12298 ins_cost(200); 12299 expand %{ 12300 rFlagsReg cr; 12301 compI_rReg(cr, dst, src); 12302 cmovI_reg_l(dst, src, cr); 12303 %} 12304%} 12305 12306// ============================================================================ 12307// Branch Instructions 12308 12309// Jump Direct - Label defines a relative address from JMP+1 12310instruct jmpDir(label labl) 12311%{ 12312 match(Goto); 12313 effect(USE labl); 12314 12315 ins_cost(300); 12316 format %{ "jmp $labl" %} 12317 size(5); 12318 ins_encode %{ 12319 Label* L = $labl$$label; 12320 __ jmp(*L, false); // Always long jump 12321 %} 12322 ins_pipe(pipe_jmp); 12323%} 12324 12325// Jump Direct Conditional - Label defines a relative address from Jcc+1 12326instruct jmpCon(cmpOp cop, rFlagsReg cr, label labl) 12327%{ 12328 match(If cop cr); 12329 effect(USE labl); 12330 12331 ins_cost(300); 12332 format %{ "j$cop $labl" %} 12333 size(6); 12334 ins_encode %{ 12335 Label* L = $labl$$label; 12336 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12337 %} 12338 ins_pipe(pipe_jcc); 12339%} 12340 12341// Jump Direct Conditional - Label defines a relative address from Jcc+1 12342instruct jmpLoopEnd(cmpOp cop, rFlagsReg cr, label labl) 12343%{ 12344 predicate(!n->has_vector_mask_set()); 12345 match(CountedLoopEnd cop cr); 12346 effect(USE labl); 12347 12348 ins_cost(300); 12349 format %{ "j$cop $labl\t# loop end" %} 12350 size(6); 12351 ins_encode %{ 12352 Label* L = $labl$$label; 12353 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12354 %} 12355 ins_pipe(pipe_jcc); 12356%} 12357 12358// Jump Direct Conditional - Label defines a relative address from Jcc+1 12359instruct jmpLoopEndU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12360 predicate(!n->has_vector_mask_set()); 12361 match(CountedLoopEnd cop cmp); 12362 effect(USE labl); 12363 12364 ins_cost(300); 12365 format %{ "j$cop,u $labl\t# loop end" %} 12366 size(6); 12367 ins_encode %{ 12368 Label* L = $labl$$label; 12369 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12370 %} 12371 ins_pipe(pipe_jcc); 12372%} 12373 12374instruct jmpLoopEndUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12375 predicate(!n->has_vector_mask_set()); 12376 match(CountedLoopEnd cop cmp); 12377 effect(USE labl); 12378 12379 ins_cost(200); 12380 format %{ "j$cop,u $labl\t# loop end" %} 12381 size(6); 12382 ins_encode %{ 12383 Label* L = $labl$$label; 12384 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12385 %} 12386 ins_pipe(pipe_jcc); 12387%} 12388 12389// mask version 12390// Jump Direct Conditional - Label defines a relative address from Jcc+1 12391instruct jmpLoopEnd_and_restoreMask(cmpOp cop, rFlagsReg cr, label labl) 12392%{ 12393 predicate(n->has_vector_mask_set()); 12394 match(CountedLoopEnd cop cr); 12395 effect(USE labl); 12396 12397 ins_cost(400); 12398 format %{ "j$cop $labl\t# loop end\n\t" 12399 "restorevectmask \t# vector mask restore for loops" %} 12400 size(10); 12401 ins_encode %{ 12402 Label* L = $labl$$label; 12403 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12404 __ restorevectmask(); 12405 %} 12406 ins_pipe(pipe_jcc); 12407%} 12408 12409// Jump Direct Conditional - Label defines a relative address from Jcc+1 12410instruct jmpLoopEndU_and_restoreMask(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12411 predicate(n->has_vector_mask_set()); 12412 match(CountedLoopEnd cop cmp); 12413 effect(USE labl); 12414 12415 ins_cost(400); 12416 format %{ "j$cop,u $labl\t# loop end\n\t" 12417 "restorevectmask \t# vector mask restore for loops" %} 12418 size(10); 12419 ins_encode %{ 12420 Label* L = $labl$$label; 12421 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12422 __ restorevectmask(); 12423 %} 12424 ins_pipe(pipe_jcc); 12425%} 12426 12427instruct jmpLoopEndUCF_and_restoreMask(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12428 predicate(n->has_vector_mask_set()); 12429 match(CountedLoopEnd cop cmp); 12430 effect(USE labl); 12431 12432 ins_cost(300); 12433 format %{ "j$cop,u $labl\t# loop end\n\t" 12434 "restorevectmask \t# vector mask restore for loops" %} 12435 size(10); 12436 ins_encode %{ 12437 Label* L = $labl$$label; 12438 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12439 __ restorevectmask(); 12440 %} 12441 ins_pipe(pipe_jcc); 12442%} 12443 12444// Jump Direct Conditional - using unsigned comparison 12445instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12446 match(If cop cmp); 12447 effect(USE labl); 12448 12449 ins_cost(300); 12450 format %{ "j$cop,u $labl" %} 12451 size(6); 12452 ins_encode %{ 12453 Label* L = $labl$$label; 12454 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12455 %} 12456 ins_pipe(pipe_jcc); 12457%} 12458 12459instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12460 match(If cop cmp); 12461 effect(USE labl); 12462 12463 ins_cost(200); 12464 format %{ "j$cop,u $labl" %} 12465 size(6); 12466 ins_encode %{ 12467 Label* L = $labl$$label; 12468 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12469 %} 12470 ins_pipe(pipe_jcc); 12471%} 12472 12473instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 12474 match(If cop cmp); 12475 effect(USE labl); 12476 12477 ins_cost(200); 12478 format %{ $$template 12479 if ($cop$$cmpcode == Assembler::notEqual) { 12480 $$emit$$"jp,u $labl\n\t" 12481 $$emit$$"j$cop,u $labl" 12482 } else { 12483 $$emit$$"jp,u done\n\t" 12484 $$emit$$"j$cop,u $labl\n\t" 12485 $$emit$$"done:" 12486 } 12487 %} 12488 ins_encode %{ 12489 Label* l = $labl$$label; 12490 if ($cop$$cmpcode == Assembler::notEqual) { 12491 __ jcc(Assembler::parity, *l, false); 12492 __ jcc(Assembler::notEqual, *l, false); 12493 } else if ($cop$$cmpcode == Assembler::equal) { 12494 Label done; 12495 __ jccb(Assembler::parity, done); 12496 __ jcc(Assembler::equal, *l, false); 12497 __ bind(done); 12498 } else { 12499 ShouldNotReachHere(); 12500 } 12501 %} 12502 ins_pipe(pipe_jcc); 12503%} 12504 12505// ============================================================================ 12506// The 2nd slow-half of a subtype check. Scan the subklass's 2ndary 12507// superklass array for an instance of the superklass. Set a hidden 12508// internal cache on a hit (cache is checked with exposed code in 12509// gen_subtype_check()). Return NZ for a miss or zero for a hit. The 12510// encoding ALSO sets flags. 12511 12512instruct partialSubtypeCheck(rdi_RegP result, 12513 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 12514 rFlagsReg cr) 12515%{ 12516 match(Set result (PartialSubtypeCheck sub super)); 12517 effect(KILL rcx, KILL cr); 12518 12519 ins_cost(1100); // slightly larger than the next version 12520 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 12521 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 12522 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 12523 "repne scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t" 12524 "jne,s miss\t\t# Missed: rdi not-zero\n\t" 12525 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 12526 "xorq $result, $result\t\t Hit: rdi zero\n\t" 12527 "miss:\t" %} 12528 12529 opcode(0x1); // Force a XOR of RDI 12530 ins_encode(enc_PartialSubtypeCheck()); 12531 ins_pipe(pipe_slow); 12532%} 12533 12534instruct partialSubtypeCheck_vs_Zero(rFlagsReg cr, 12535 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 12536 immP0 zero, 12537 rdi_RegP result) 12538%{ 12539 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 12540 effect(KILL rcx, KILL result); 12541 12542 ins_cost(1000); 12543 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 12544 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 12545 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 12546 "repne scasq\t# Scan *rdi++ for a match with rax while cx-- != 0\n\t" 12547 "jne,s miss\t\t# Missed: flags nz\n\t" 12548 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 12549 "miss:\t" %} 12550 12551 opcode(0x0); // No need to XOR RDI 12552 ins_encode(enc_PartialSubtypeCheck()); 12553 ins_pipe(pipe_slow); 12554%} 12555 12556// ============================================================================ 12557// Branch Instructions -- short offset versions 12558// 12559// These instructions are used to replace jumps of a long offset (the default 12560// match) with jumps of a shorter offset. These instructions are all tagged 12561// with the ins_short_branch attribute, which causes the ADLC to suppress the 12562// match rules in general matching. Instead, the ADLC generates a conversion 12563// method in the MachNode which can be used to do in-place replacement of the 12564// long variant with the shorter variant. The compiler will determine if a 12565// branch can be taken by the is_short_branch_offset() predicate in the machine 12566// specific code section of the file. 12567 12568// Jump Direct - Label defines a relative address from JMP+1 12569instruct jmpDir_short(label labl) %{ 12570 match(Goto); 12571 effect(USE labl); 12572 12573 ins_cost(300); 12574 format %{ "jmp,s $labl" %} 12575 size(2); 12576 ins_encode %{ 12577 Label* L = $labl$$label; 12578 __ jmpb(*L); 12579 %} 12580 ins_pipe(pipe_jmp); 12581 ins_short_branch(1); 12582%} 12583 12584// Jump Direct Conditional - Label defines a relative address from Jcc+1 12585instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{ 12586 match(If cop cr); 12587 effect(USE labl); 12588 12589 ins_cost(300); 12590 format %{ "j$cop,s $labl" %} 12591 size(2); 12592 ins_encode %{ 12593 Label* L = $labl$$label; 12594 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12595 %} 12596 ins_pipe(pipe_jcc); 12597 ins_short_branch(1); 12598%} 12599 12600// Jump Direct Conditional - Label defines a relative address from Jcc+1 12601instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{ 12602 match(CountedLoopEnd cop cr); 12603 effect(USE labl); 12604 12605 ins_cost(300); 12606 format %{ "j$cop,s $labl\t# loop end" %} 12607 size(2); 12608 ins_encode %{ 12609 Label* L = $labl$$label; 12610 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12611 %} 12612 ins_pipe(pipe_jcc); 12613 ins_short_branch(1); 12614%} 12615 12616// Jump Direct Conditional - Label defines a relative address from Jcc+1 12617instruct jmpLoopEndU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12618 match(CountedLoopEnd cop cmp); 12619 effect(USE labl); 12620 12621 ins_cost(300); 12622 format %{ "j$cop,us $labl\t# loop end" %} 12623 size(2); 12624 ins_encode %{ 12625 Label* L = $labl$$label; 12626 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12627 %} 12628 ins_pipe(pipe_jcc); 12629 ins_short_branch(1); 12630%} 12631 12632instruct jmpLoopEndUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12633 match(CountedLoopEnd cop cmp); 12634 effect(USE labl); 12635 12636 ins_cost(300); 12637 format %{ "j$cop,us $labl\t# loop end" %} 12638 size(2); 12639 ins_encode %{ 12640 Label* L = $labl$$label; 12641 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12642 %} 12643 ins_pipe(pipe_jcc); 12644 ins_short_branch(1); 12645%} 12646 12647// Jump Direct Conditional - using unsigned comparison 12648instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 12649 match(If cop cmp); 12650 effect(USE labl); 12651 12652 ins_cost(300); 12653 format %{ "j$cop,us $labl" %} 12654 size(2); 12655 ins_encode %{ 12656 Label* L = $labl$$label; 12657 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12658 %} 12659 ins_pipe(pipe_jcc); 12660 ins_short_branch(1); 12661%} 12662 12663instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 12664 match(If cop cmp); 12665 effect(USE labl); 12666 12667 ins_cost(300); 12668 format %{ "j$cop,us $labl" %} 12669 size(2); 12670 ins_encode %{ 12671 Label* L = $labl$$label; 12672 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12673 %} 12674 ins_pipe(pipe_jcc); 12675 ins_short_branch(1); 12676%} 12677 12678instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 12679 match(If cop cmp); 12680 effect(USE labl); 12681 12682 ins_cost(300); 12683 format %{ $$template 12684 if ($cop$$cmpcode == Assembler::notEqual) { 12685 $$emit$$"jp,u,s $labl\n\t" 12686 $$emit$$"j$cop,u,s $labl" 12687 } else { 12688 $$emit$$"jp,u,s done\n\t" 12689 $$emit$$"j$cop,u,s $labl\n\t" 12690 $$emit$$"done:" 12691 } 12692 %} 12693 size(4); 12694 ins_encode %{ 12695 Label* l = $labl$$label; 12696 if ($cop$$cmpcode == Assembler::notEqual) { 12697 __ jccb(Assembler::parity, *l); 12698 __ jccb(Assembler::notEqual, *l); 12699 } else if ($cop$$cmpcode == Assembler::equal) { 12700 Label done; 12701 __ jccb(Assembler::parity, done); 12702 __ jccb(Assembler::equal, *l); 12703 __ bind(done); 12704 } else { 12705 ShouldNotReachHere(); 12706 } 12707 %} 12708 ins_pipe(pipe_jcc); 12709 ins_short_branch(1); 12710%} 12711 12712// ============================================================================ 12713// inlined locking and unlocking 12714 12715instruct cmpFastLockRTM(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rdx_RegI scr, rRegI cx1, rRegI cx2) %{ 12716 predicate(Compile::current()->use_rtm()); 12717 match(Set cr (FastLock object box)); 12718 effect(TEMP tmp, TEMP scr, TEMP cx1, TEMP cx2, USE_KILL box); 12719 ins_cost(300); 12720 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr,$cx1,$cx2" %} 12721 ins_encode %{ 12722 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, 12723 $scr$$Register, $cx1$$Register, $cx2$$Register, 12724 _counters, _rtm_counters, _stack_rtm_counters, 12725 ((Method*)(ra_->C->method()->constant_encoding()))->method_data(), 12726 true, ra_->C->profile_rtm()); 12727 %} 12728 ins_pipe(pipe_slow); 12729%} 12730 12731instruct cmpFastLock(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr) %{ 12732 predicate(!Compile::current()->use_rtm()); 12733 match(Set cr (FastLock object box)); 12734 effect(TEMP tmp, TEMP scr, USE_KILL box); 12735 ins_cost(300); 12736 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr" %} 12737 ins_encode %{ 12738 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, 12739 $scr$$Register, noreg, noreg, _counters, NULL, NULL, NULL, false, false); 12740 %} 12741 ins_pipe(pipe_slow); 12742%} 12743 12744instruct cmpFastUnlock(rFlagsReg cr, rRegP object, rax_RegP box, rRegP tmp) %{ 12745 match(Set cr (FastUnlock object box)); 12746 effect(TEMP tmp, USE_KILL box); 12747 ins_cost(300); 12748 format %{ "fastunlock $object,$box\t! kills $box,$tmp" %} 12749 ins_encode %{ 12750 __ fast_unlock($object$$Register, $box$$Register, $tmp$$Register, ra_->C->use_rtm()); 12751 %} 12752 ins_pipe(pipe_slow); 12753%} 12754 12755 12756// ============================================================================ 12757// Safepoint Instructions 12758instruct safePoint_poll(rFlagsReg cr) 12759%{ 12760 predicate(!Assembler::is_polling_page_far() && SafepointMechanism::uses_global_page_poll()); 12761 match(SafePoint); 12762 effect(KILL cr); 12763 12764 format %{ "testl rax, [rip + #offset_to_poll_page]\t" 12765 "# Safepoint: poll for GC" %} 12766 ins_cost(125); 12767 ins_encode %{ 12768 AddressLiteral addr(os::get_polling_page(), relocInfo::poll_type); 12769 __ testl(rax, addr); 12770 %} 12771 ins_pipe(ialu_reg_mem); 12772%} 12773 12774instruct safePoint_poll_far(rFlagsReg cr, rRegP poll) 12775%{ 12776 predicate(Assembler::is_polling_page_far() && SafepointMechanism::uses_global_page_poll()); 12777 match(SafePoint poll); 12778 effect(KILL cr, USE poll); 12779 12780 format %{ "testl rax, [$poll]\t" 12781 "# Safepoint: poll for GC" %} 12782 ins_cost(125); 12783 ins_encode %{ 12784 __ relocate(relocInfo::poll_type); 12785 __ testl(rax, Address($poll$$Register, 0)); 12786 %} 12787 ins_pipe(ialu_reg_mem); 12788%} 12789 12790instruct safePoint_poll_tls(rFlagsReg cr, rex_RegP poll) 12791%{ 12792 predicate(SafepointMechanism::uses_thread_local_poll()); 12793 match(SafePoint poll); 12794 effect(KILL cr, USE poll); 12795 12796 format %{ "testl rax, [$poll]\t" 12797 "# Safepoint: poll for GC" %} 12798 ins_cost(125); 12799 size(3); /* setting an explicit size will cause debug builds to assert if size is incorrect */ 12800 ins_encode %{ 12801 __ relocate(relocInfo::poll_type); 12802 address pre_pc = __ pc(); 12803 __ testl(rax, Address($poll$$Register, 0)); 12804 address post_pc = __ pc(); 12805 guarantee(pre_pc[0] == 0x41 && pre_pc[1] == 0x85, "must emit #rex test-ax [reg]"); 12806 %} 12807 ins_pipe(ialu_reg_mem); 12808%} 12809 12810// ============================================================================ 12811// Procedure Call/Return Instructions 12812// Call Java Static Instruction 12813// Note: If this code changes, the corresponding ret_addr_offset() and 12814// compute_padding() functions will have to be adjusted. 12815instruct CallStaticJavaDirect(method meth) %{ 12816 match(CallStaticJava); 12817 effect(USE meth); 12818 12819 ins_cost(300); 12820 format %{ "call,static " %} 12821 opcode(0xE8); /* E8 cd */ 12822 ins_encode(clear_avx, Java_Static_Call(meth), call_epilog); 12823 ins_pipe(pipe_slow); 12824 ins_alignment(4); 12825%} 12826 12827// Call Java Dynamic Instruction 12828// Note: If this code changes, the corresponding ret_addr_offset() and 12829// compute_padding() functions will have to be adjusted. 12830instruct CallDynamicJavaDirect(method meth) 12831%{ 12832 match(CallDynamicJava); 12833 effect(USE meth); 12834 12835 ins_cost(300); 12836 format %{ "movq rax, #Universe::non_oop_word()\n\t" 12837 "call,dynamic " %} 12838 ins_encode(clear_avx, Java_Dynamic_Call(meth), call_epilog); 12839 ins_pipe(pipe_slow); 12840 ins_alignment(4); 12841%} 12842 12843// Call Runtime Instruction 12844instruct CallRuntimeDirect(method meth) 12845%{ 12846 match(CallRuntime); 12847 effect(USE meth); 12848 12849 ins_cost(300); 12850 format %{ "call,runtime " %} 12851 ins_encode(clear_avx, Java_To_Runtime(meth)); 12852 ins_pipe(pipe_slow); 12853%} 12854 12855// Call runtime without safepoint 12856instruct CallLeafDirect(method meth) 12857%{ 12858 match(CallLeaf); 12859 effect(USE meth); 12860 12861 ins_cost(300); 12862 format %{ "call_leaf,runtime " %} 12863 ins_encode(clear_avx, Java_To_Runtime(meth)); 12864 ins_pipe(pipe_slow); 12865%} 12866 12867// Call runtime without safepoint 12868instruct CallLeafNoFPDirect(method meth) 12869%{ 12870 match(CallLeafNoFP); 12871 effect(USE meth); 12872 12873 ins_cost(300); 12874 format %{ "call_leaf_nofp,runtime " %} 12875 ins_encode(clear_avx, Java_To_Runtime(meth)); 12876 ins_pipe(pipe_slow); 12877%} 12878 12879// Return Instruction 12880// Remove the return address & jump to it. 12881// Notice: We always emit a nop after a ret to make sure there is room 12882// for safepoint patching 12883instruct Ret() 12884%{ 12885 match(Return); 12886 12887 format %{ "ret" %} 12888 opcode(0xC3); 12889 ins_encode(OpcP); 12890 ins_pipe(pipe_jmp); 12891%} 12892 12893// Tail Call; Jump from runtime stub to Java code. 12894// Also known as an 'interprocedural jump'. 12895// Target of jump will eventually return to caller. 12896// TailJump below removes the return address. 12897instruct TailCalljmpInd(no_rbp_RegP jump_target, rbx_RegP method_oop) 12898%{ 12899 match(TailCall jump_target method_oop); 12900 12901 ins_cost(300); 12902 format %{ "jmp $jump_target\t# rbx holds method oop" %} 12903 opcode(0xFF, 0x4); /* Opcode FF /4 */ 12904 ins_encode(REX_reg(jump_target), OpcP, reg_opc(jump_target)); 12905 ins_pipe(pipe_jmp); 12906%} 12907 12908// Tail Jump; remove the return address; jump to target. 12909// TailCall above leaves the return address around. 12910instruct tailjmpInd(no_rbp_RegP jump_target, rax_RegP ex_oop) 12911%{ 12912 match(TailJump jump_target ex_oop); 12913 12914 ins_cost(300); 12915 format %{ "popq rdx\t# pop return address\n\t" 12916 "jmp $jump_target" %} 12917 opcode(0xFF, 0x4); /* Opcode FF /4 */ 12918 ins_encode(Opcode(0x5a), // popq rdx 12919 REX_reg(jump_target), OpcP, reg_opc(jump_target)); 12920 ins_pipe(pipe_jmp); 12921%} 12922 12923// Create exception oop: created by stack-crawling runtime code. 12924// Created exception is now available to this handler, and is setup 12925// just prior to jumping to this handler. No code emitted. 12926instruct CreateException(rax_RegP ex_oop) 12927%{ 12928 match(Set ex_oop (CreateEx)); 12929 12930 size(0); 12931 // use the following format syntax 12932 format %{ "# exception oop is in rax; no code emitted" %} 12933 ins_encode(); 12934 ins_pipe(empty); 12935%} 12936 12937// Rethrow exception: 12938// The exception oop will come in the first argument position. 12939// Then JUMP (not call) to the rethrow stub code. 12940instruct RethrowException() 12941%{ 12942 match(Rethrow); 12943 12944 // use the following format syntax 12945 format %{ "jmp rethrow_stub" %} 12946 ins_encode(enc_rethrow); 12947 ins_pipe(pipe_jmp); 12948%} 12949 12950// 12951// Execute ZGC load barrier (strong) slow path 12952// 12953 12954// When running without XMM regs 12955instruct loadBarrierSlowRegNoVec(rRegP dst, memory mem, rFlagsReg cr) %{ 12956 12957 match(Set dst (LoadBarrierSlowReg mem)); 12958 predicate(MaxVectorSize < 16); 12959 12960 effect(DEF dst, KILL cr); 12961 12962 format %{"LoadBarrierSlowRegNoVec $dst, $mem" %} 12963 ins_encode %{ 12964#if INCLUDE_ZGC 12965 Register d = $dst$$Register; 12966 ZBarrierSetAssembler* bs = (ZBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler(); 12967 12968 assert(d != r12, "Can't be R12!"); 12969 assert(d != r15, "Can't be R15!"); 12970 assert(d != rsp, "Can't be RSP!"); 12971 12972 __ lea(d, $mem$$Address); 12973 __ call(RuntimeAddress(bs->load_barrier_slow_stub(d))); 12974#else 12975 ShouldNotReachHere(); 12976#endif 12977 %} 12978 ins_pipe(pipe_slow); 12979%} 12980 12981// For XMM and YMM enabled processors 12982instruct loadBarrierSlowRegXmmAndYmm(rRegP dst, memory mem, rFlagsReg cr, 12983 rxmm0 x0, rxmm1 x1, rxmm2 x2,rxmm3 x3, 12984 rxmm4 x4, rxmm5 x5, rxmm6 x6, rxmm7 x7, 12985 rxmm8 x8, rxmm9 x9, rxmm10 x10, rxmm11 x11, 12986 rxmm12 x12, rxmm13 x13, rxmm14 x14, rxmm15 x15) %{ 12987 12988 match(Set dst (LoadBarrierSlowReg mem)); 12989 predicate((UseSSE > 0) && (UseAVX <= 2) && (MaxVectorSize >= 16)); 12990 12991 effect(DEF dst, KILL cr, 12992 KILL x0, KILL x1, KILL x2, KILL x3, 12993 KILL x4, KILL x5, KILL x6, KILL x7, 12994 KILL x8, KILL x9, KILL x10, KILL x11, 12995 KILL x12, KILL x13, KILL x14, KILL x15); 12996 12997 format %{"LoadBarrierSlowRegXmm $dst, $mem" %} 12998 ins_encode %{ 12999#if INCLUDE_ZGC 13000 Register d = $dst$$Register; 13001 ZBarrierSetAssembler* bs = (ZBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler(); 13002 13003 assert(d != r12, "Can't be R12!"); 13004 assert(d != r15, "Can't be R15!"); 13005 assert(d != rsp, "Can't be RSP!"); 13006 13007 __ lea(d, $mem$$Address); 13008 __ call(RuntimeAddress(bs->load_barrier_slow_stub(d))); 13009#else 13010 ShouldNotReachHere(); 13011#endif 13012 %} 13013 ins_pipe(pipe_slow); 13014%} 13015 13016// For ZMM enabled processors 13017instruct loadBarrierSlowRegZmm(rRegP dst, memory mem, rFlagsReg cr, 13018 rxmm0 x0, rxmm1 x1, rxmm2 x2,rxmm3 x3, 13019 rxmm4 x4, rxmm5 x5, rxmm6 x6, rxmm7 x7, 13020 rxmm8 x8, rxmm9 x9, rxmm10 x10, rxmm11 x11, 13021 rxmm12 x12, rxmm13 x13, rxmm14 x14, rxmm15 x15, 13022 rxmm16 x16, rxmm17 x17, rxmm18 x18, rxmm19 x19, 13023 rxmm20 x20, rxmm21 x21, rxmm22 x22, rxmm23 x23, 13024 rxmm24 x24, rxmm25 x25, rxmm26 x26, rxmm27 x27, 13025 rxmm28 x28, rxmm29 x29, rxmm30 x30, rxmm31 x31) %{ 13026 13027 match(Set dst (LoadBarrierSlowReg mem)); 13028 predicate((UseAVX == 3) && (MaxVectorSize >= 16)); 13029 13030 effect(DEF dst, KILL cr, 13031 KILL x0, KILL x1, KILL x2, KILL x3, 13032 KILL x4, KILL x5, KILL x6, KILL x7, 13033 KILL x8, KILL x9, KILL x10, KILL x11, 13034 KILL x12, KILL x13, KILL x14, KILL x15, 13035 KILL x16, KILL x17, KILL x18, KILL x19, 13036 KILL x20, KILL x21, KILL x22, KILL x23, 13037 KILL x24, KILL x25, KILL x26, KILL x27, 13038 KILL x28, KILL x29, KILL x30, KILL x31); 13039 13040 format %{"LoadBarrierSlowRegZmm $dst, $mem" %} 13041 ins_encode %{ 13042#if INCLUDE_ZGC 13043 Register d = $dst$$Register; 13044 ZBarrierSetAssembler* bs = (ZBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler(); 13045 13046 assert(d != r12, "Can't be R12!"); 13047 assert(d != r15, "Can't be R15!"); 13048 assert(d != rsp, "Can't be RSP!"); 13049 13050 __ lea(d, $mem$$Address); 13051 __ call(RuntimeAddress(bs->load_barrier_slow_stub(d))); 13052#else 13053 ShouldNotReachHere(); 13054#endif 13055 %} 13056 ins_pipe(pipe_slow); 13057%} 13058 13059// 13060// Execute ZGC load barrier (weak) slow path 13061// 13062 13063// When running without XMM regs 13064instruct loadBarrierWeakSlowRegNoVec(rRegP dst, memory mem, rFlagsReg cr) %{ 13065 13066 match(Set dst (LoadBarrierSlowReg mem)); 13067 predicate(MaxVectorSize < 16); 13068 13069 effect(DEF dst, KILL cr); 13070 13071 format %{"LoadBarrierSlowRegNoVec $dst, $mem" %} 13072 ins_encode %{ 13073#if INCLUDE_ZGC 13074 Register d = $dst$$Register; 13075 ZBarrierSetAssembler* bs = (ZBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler(); 13076 13077 assert(d != r12, "Can't be R12!"); 13078 assert(d != r15, "Can't be R15!"); 13079 assert(d != rsp, "Can't be RSP!"); 13080 13081 __ lea(d, $mem$$Address); 13082 __ call(RuntimeAddress(bs->load_barrier_weak_slow_stub(d))); 13083#else 13084 ShouldNotReachHere(); 13085#endif 13086 %} 13087 ins_pipe(pipe_slow); 13088%} 13089 13090// For XMM and YMM enabled processors 13091instruct loadBarrierWeakSlowRegXmmAndYmm(rRegP dst, memory mem, rFlagsReg cr, 13092 rxmm0 x0, rxmm1 x1, rxmm2 x2,rxmm3 x3, 13093 rxmm4 x4, rxmm5 x5, rxmm6 x6, rxmm7 x7, 13094 rxmm8 x8, rxmm9 x9, rxmm10 x10, rxmm11 x11, 13095 rxmm12 x12, rxmm13 x13, rxmm14 x14, rxmm15 x15) %{ 13096 13097 match(Set dst (LoadBarrierWeakSlowReg mem)); 13098 predicate((UseSSE > 0) && (UseAVX <= 2) && (MaxVectorSize >= 16)); 13099 13100 effect(DEF dst, KILL cr, 13101 KILL x0, KILL x1, KILL x2, KILL x3, 13102 KILL x4, KILL x5, KILL x6, KILL x7, 13103 KILL x8, KILL x9, KILL x10, KILL x11, 13104 KILL x12, KILL x13, KILL x14, KILL x15); 13105 13106 format %{"LoadBarrierWeakSlowRegXmm $dst, $mem" %} 13107 ins_encode %{ 13108#if INCLUDE_ZGC 13109 Register d = $dst$$Register; 13110 ZBarrierSetAssembler* bs = (ZBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler(); 13111 13112 assert(d != r12, "Can't be R12!"); 13113 assert(d != r15, "Can't be R15!"); 13114 assert(d != rsp, "Can't be RSP!"); 13115 13116 __ lea(d,$mem$$Address); 13117 __ call(RuntimeAddress(bs->load_barrier_weak_slow_stub(d))); 13118#else 13119 ShouldNotReachHere(); 13120#endif 13121 %} 13122 ins_pipe(pipe_slow); 13123%} 13124 13125// For ZMM enabled processors 13126instruct loadBarrierWeakSlowRegZmm(rRegP dst, memory mem, rFlagsReg cr, 13127 rxmm0 x0, rxmm1 x1, rxmm2 x2,rxmm3 x3, 13128 rxmm4 x4, rxmm5 x5, rxmm6 x6, rxmm7 x7, 13129 rxmm8 x8, rxmm9 x9, rxmm10 x10, rxmm11 x11, 13130 rxmm12 x12, rxmm13 x13, rxmm14 x14, rxmm15 x15, 13131 rxmm16 x16, rxmm17 x17, rxmm18 x18, rxmm19 x19, 13132 rxmm20 x20, rxmm21 x21, rxmm22 x22, rxmm23 x23, 13133 rxmm24 x24, rxmm25 x25, rxmm26 x26, rxmm27 x27, 13134 rxmm28 x28, rxmm29 x29, rxmm30 x30, rxmm31 x31) %{ 13135 13136 match(Set dst (LoadBarrierWeakSlowReg mem)); 13137 predicate((UseAVX == 3) && (MaxVectorSize >= 16)); 13138 13139 effect(DEF dst, KILL cr, 13140 KILL x0, KILL x1, KILL x2, KILL x3, 13141 KILL x4, KILL x5, KILL x6, KILL x7, 13142 KILL x8, KILL x9, KILL x10, KILL x11, 13143 KILL x12, KILL x13, KILL x14, KILL x15, 13144 KILL x16, KILL x17, KILL x18, KILL x19, 13145 KILL x20, KILL x21, KILL x22, KILL x23, 13146 KILL x24, KILL x25, KILL x26, KILL x27, 13147 KILL x28, KILL x29, KILL x30, KILL x31); 13148 13149 format %{"LoadBarrierWeakSlowRegZmm $dst, $mem" %} 13150 ins_encode %{ 13151#if INCLUDE_ZGC 13152 Register d = $dst$$Register; 13153 ZBarrierSetAssembler* bs = (ZBarrierSetAssembler*)BarrierSet::barrier_set()->barrier_set_assembler(); 13154 13155 assert(d != r12, "Can't be R12!"); 13156 assert(d != r15, "Can't be R15!"); 13157 assert(d != rsp, "Can't be RSP!"); 13158 13159 __ lea(d,$mem$$Address); 13160 __ call(RuntimeAddress(bs->load_barrier_weak_slow_stub(d))); 13161#else 13162 ShouldNotReachHere(); 13163#endif 13164 %} 13165 ins_pipe(pipe_slow); 13166%} 13167 13168// ============================================================================ 13169// This name is KNOWN by the ADLC and cannot be changed. 13170// The ADLC forces a 'TypeRawPtr::BOTTOM' output type 13171// for this guy. 13172instruct tlsLoadP(r15_RegP dst) %{ 13173 match(Set dst (ThreadLocal)); 13174 effect(DEF dst); 13175 13176 size(0); 13177 format %{ "# TLS is in R15" %} 13178 ins_encode( /*empty encoding*/ ); 13179 ins_pipe(ialu_reg_reg); 13180%} 13181 13182 13183//----------PEEPHOLE RULES----------------------------------------------------- 13184// These must follow all instruction definitions as they use the names 13185// defined in the instructions definitions. 13186// 13187// peepmatch ( root_instr_name [preceding_instruction]* ); 13188// 13189// peepconstraint %{ 13190// (instruction_number.operand_name relational_op instruction_number.operand_name 13191// [, ...] ); 13192// // instruction numbers are zero-based using left to right order in peepmatch 13193// 13194// peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 13195// // provide an instruction_number.operand_name for each operand that appears 13196// // in the replacement instruction's match rule 13197// 13198// ---------VM FLAGS--------------------------------------------------------- 13199// 13200// All peephole optimizations can be turned off using -XX:-OptoPeephole 13201// 13202// Each peephole rule is given an identifying number starting with zero and 13203// increasing by one in the order seen by the parser. An individual peephole 13204// can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 13205// on the command-line. 13206// 13207// ---------CURRENT LIMITATIONS---------------------------------------------- 13208// 13209// Only match adjacent instructions in same basic block 13210// Only equality constraints 13211// Only constraints between operands, not (0.dest_reg == RAX_enc) 13212// Only one replacement instruction 13213// 13214// ---------EXAMPLE---------------------------------------------------------- 13215// 13216// // pertinent parts of existing instructions in architecture description 13217// instruct movI(rRegI dst, rRegI src) 13218// %{ 13219// match(Set dst (CopyI src)); 13220// %} 13221// 13222// instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr) 13223// %{ 13224// match(Set dst (AddI dst src)); 13225// effect(KILL cr); 13226// %} 13227// 13228// // Change (inc mov) to lea 13229// peephole %{ 13230// // increment preceeded by register-register move 13231// peepmatch ( incI_rReg movI ); 13232// // require that the destination register of the increment 13233// // match the destination register of the move 13234// peepconstraint ( 0.dst == 1.dst ); 13235// // construct a replacement instruction that sets 13236// // the destination to ( move's source register + one ) 13237// peepreplace ( leaI_rReg_immI( 0.dst 1.src 0.src ) ); 13238// %} 13239// 13240 13241// Implementation no longer uses movX instructions since 13242// machine-independent system no longer uses CopyX nodes. 13243// 13244// peephole 13245// %{ 13246// peepmatch (incI_rReg movI); 13247// peepconstraint (0.dst == 1.dst); 13248// peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 13249// %} 13250 13251// peephole 13252// %{ 13253// peepmatch (decI_rReg movI); 13254// peepconstraint (0.dst == 1.dst); 13255// peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 13256// %} 13257 13258// peephole 13259// %{ 13260// peepmatch (addI_rReg_imm movI); 13261// peepconstraint (0.dst == 1.dst); 13262// peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 13263// %} 13264 13265// peephole 13266// %{ 13267// peepmatch (incL_rReg movL); 13268// peepconstraint (0.dst == 1.dst); 13269// peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 13270// %} 13271 13272// peephole 13273// %{ 13274// peepmatch (decL_rReg movL); 13275// peepconstraint (0.dst == 1.dst); 13276// peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 13277// %} 13278 13279// peephole 13280// %{ 13281// peepmatch (addL_rReg_imm movL); 13282// peepconstraint (0.dst == 1.dst); 13283// peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 13284// %} 13285 13286// peephole 13287// %{ 13288// peepmatch (addP_rReg_imm movP); 13289// peepconstraint (0.dst == 1.dst); 13290// peepreplace (leaP_rReg_imm(0.dst 1.src 0.src)); 13291// %} 13292 13293// // Change load of spilled value to only a spill 13294// instruct storeI(memory mem, rRegI src) 13295// %{ 13296// match(Set mem (StoreI mem src)); 13297// %} 13298// 13299// instruct loadI(rRegI dst, memory mem) 13300// %{ 13301// match(Set dst (LoadI mem)); 13302// %} 13303// 13304 13305peephole 13306%{ 13307 peepmatch (loadI storeI); 13308 peepconstraint (1.src == 0.dst, 1.mem == 0.mem); 13309 peepreplace (storeI(1.mem 1.mem 1.src)); 13310%} 13311 13312peephole 13313%{ 13314 peepmatch (loadL storeL); 13315 peepconstraint (1.src == 0.dst, 1.mem == 0.mem); 13316 peepreplace (storeL(1.mem 1.mem 1.src)); 13317%} 13318 13319//----------SMARTSPILL RULES--------------------------------------------------- 13320// These must follow all instruction definitions as they use the names 13321// defined in the instructions definitions. 13322