x86_64.ad revision 3602:da91efe96a93
1281843Sdteske// 2222417Sjulian// Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. 3222417Sjulian// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4222417Sjulian// 5222417Sjulian// This code is free software; you can redistribute it and/or modify it 6222417Sjulian// under the terms of the GNU General Public License version 2 only, as 7222417Sjulian// published by the Free Software Foundation. 8222417Sjulian// 9222417Sjulian// This code is distributed in the hope that it will be useful, but WITHOUT 10222417Sjulian// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11222417Sjulian// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12222417Sjulian// version 2 for more details (a copy is included in the LICENSE file that 13222417Sjulian// accompanied this code). 14222417Sjulian// 15222417Sjulian// You should have received a copy of the GNU General Public License version 16222417Sjulian// 2 along with this work; if not, write to the Free Software Foundation, 17222417Sjulian// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18222417Sjulian// 19222417Sjulian// Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20222417Sjulian// or visit www.oracle.com if you need additional information or have any 21222417Sjulian// questions. 22222417Sjulian// 23222417Sjulian// 24222417Sjulian 25222417Sjulian// AMD64 Architecture Description File 26222417Sjulian 27222417Sjulian//----------REGISTER DEFINITION BLOCK------------------------------------------ 28222417Sjulian// This information is used by the matcher and the register allocator to 29242667Sdteske// describe individual registers and classes of registers within the target 30242667Sdteske// archtecture. 31281843Sdteske 32281843Sdteskeregister %{ 33241523Sdteske//----------Architecture Description Register Definitions---------------------- 34241523Sdteske// General Registers 35262701Sdteske// "reg_def" name ( register save type, C convention save type, 36262701Sdteske// ideal register type, encoding ); 37241523Sdteske// Register Save Types: 38281843Sdteske// 39281843Sdteske// NS = No-Save: The register allocator assumes that these registers 40243114Sdteske// can be used without saving upon entry to the method, & 41243660Sdteske// that they do not need to be saved at call sites. 42243660Sdteske// 43243660Sdteske// SOC = Save-On-Call: The register allocator assumes that these registers 44243660Sdteske// can be used without saving upon entry to the method, 45243660Sdteske// but that they must be saved at call sites. 46243660Sdteske// 47243660Sdteske// SOE = Save-On-Entry: The register allocator assumes that these registers 48243660Sdteske// must be saved before using them upon entry to the 49243660Sdteske// method, but they do not need to be saved at call 50243660Sdteske// sites. 51243660Sdteske// 52243660Sdteske// AS = Always-Save: The register allocator assumes that these registers 53243660Sdteske// must be saved before using them upon entry to the 54243660Sdteske// method, & that they must be saved at call sites. 55243660Sdteske// 56243660Sdteske// Ideal Register Type is used to determine how to save & restore a 57243660Sdteske// register. Op_RegI will get spilled with LoadI/StoreI, Op_RegP will get 58243660Sdteske// spilled with LoadP/StoreP. If the register supports both, use Op_RegI. 59243660Sdteske// 60243660Sdteske// The encoding number is the actual bit-pattern placed into the opcodes. 61243660Sdteske 62243660Sdteske// General Registers 63243660Sdteske// R8-R15 must be encoded with REX. (RSP, RBP, RSI, RDI need REX when 64243660Sdteske// used as byte registers) 65243660Sdteske 66243660Sdteske// Previously set RBX, RSI, and RDI as save-on-entry for java code 67243660Sdteske// Turn off SOE in java-code due to frequent use of uncommon-traps. 68243660Sdteske// Now that allocator is better, turn on RSI and RDI as SOE registers. 69243660Sdteske 70243660Sdteskereg_def RAX (SOC, SOC, Op_RegI, 0, rax->as_VMReg()); 71243660Sdteskereg_def RAX_H(SOC, SOC, Op_RegI, 0, rax->as_VMReg()->next()); 72243660Sdteske 73243660Sdteskereg_def RCX (SOC, SOC, Op_RegI, 1, rcx->as_VMReg()); 74281843Sdteskereg_def RCX_H(SOC, SOC, Op_RegI, 1, rcx->as_VMReg()->next()); 75243660Sdteske 76243660Sdteskereg_def RDX (SOC, SOC, Op_RegI, 2, rdx->as_VMReg()); 77243660Sdteskereg_def RDX_H(SOC, SOC, Op_RegI, 2, rdx->as_VMReg()->next()); 78243660Sdteske 79243660Sdteskereg_def RBX (SOC, SOE, Op_RegI, 3, rbx->as_VMReg()); 80243660Sdteskereg_def RBX_H(SOC, SOE, Op_RegI, 3, rbx->as_VMReg()->next()); 81243660Sdteske 82243660Sdteskereg_def RSP (NS, NS, Op_RegI, 4, rsp->as_VMReg()); 83243660Sdteskereg_def RSP_H(NS, NS, Op_RegI, 4, rsp->as_VMReg()->next()); 84243660Sdteske 85243660Sdteske// now that adapter frames are gone RBP is always saved and restored by the prolog/epilog code 86243114Sdteskereg_def RBP (NS, SOE, Op_RegI, 5, rbp->as_VMReg()); 87243114Sdteskereg_def RBP_H(NS, SOE, Op_RegI, 5, rbp->as_VMReg()->next()); 88243114Sdteske 89222417Sjulian#ifdef _WIN64 90222417Sjulian 91222417Sjulianreg_def RSI (SOC, SOE, Op_RegI, 6, rsi->as_VMReg()); 92222417Sjulianreg_def RSI_H(SOC, SOE, Op_RegI, 6, rsi->as_VMReg()->next()); 93222417Sjulian 94222417Sjulianreg_def RDI (SOC, SOE, Op_RegI, 7, rdi->as_VMReg()); 95222417Sjulianreg_def RDI_H(SOC, SOE, Op_RegI, 7, rdi->as_VMReg()->next()); 96222417Sjulian 97222417Sjulian#else 98222417Sjulian 99222417Sjulianreg_def RSI (SOC, SOC, Op_RegI, 6, rsi->as_VMReg()); 100222417Sjulianreg_def RSI_H(SOC, SOC, Op_RegI, 6, rsi->as_VMReg()->next()); 101222417Sjulian 102222417Sjulianreg_def RDI (SOC, SOC, Op_RegI, 7, rdi->as_VMReg()); 103222417Sjulianreg_def RDI_H(SOC, SOC, Op_RegI, 7, rdi->as_VMReg()->next()); 104222417Sjulian 105222417Sjulian#endif 106222417Sjulian 107222417Sjulianreg_def R8 (SOC, SOC, Op_RegI, 8, r8->as_VMReg()); 108222417Sjulianreg_def R8_H (SOC, SOC, Op_RegI, 8, r8->as_VMReg()->next()); 109222417Sjulian 110222417Sjulianreg_def R9 (SOC, SOC, Op_RegI, 9, r9->as_VMReg()); 111222417Sjulianreg_def R9_H (SOC, SOC, Op_RegI, 9, r9->as_VMReg()->next()); 112222417Sjulian 113222417Sjulianreg_def R10 (SOC, SOC, Op_RegI, 10, r10->as_VMReg()); 114222417Sjulianreg_def R10_H(SOC, SOC, Op_RegI, 10, r10->as_VMReg()->next()); 115222417Sjulian 116243114Sdteskereg_def R11 (SOC, SOC, Op_RegI, 11, r11->as_VMReg()); 117243114Sdteskereg_def R11_H(SOC, SOC, Op_RegI, 11, r11->as_VMReg()->next()); 118243114Sdteske 119243114Sdteskereg_def R12 (SOC, SOE, Op_RegI, 12, r12->as_VMReg()); 120243114Sdteskereg_def R12_H(SOC, SOE, Op_RegI, 12, r12->as_VMReg()->next()); 121243114Sdteske 122243114Sdteskereg_def R13 (SOC, SOE, Op_RegI, 13, r13->as_VMReg()); 123243114Sdteskereg_def R13_H(SOC, SOE, Op_RegI, 13, r13->as_VMReg()->next()); 124243114Sdteske 125243114Sdteskereg_def R14 (SOC, SOE, Op_RegI, 14, r14->as_VMReg()); 126243114Sdteskereg_def R14_H(SOC, SOE, Op_RegI, 14, r14->as_VMReg()->next()); 127243114Sdteske 128243114Sdteskereg_def R15 (SOC, SOE, Op_RegI, 15, r15->as_VMReg()); 129243114Sdteskereg_def R15_H(SOC, SOE, Op_RegI, 15, r15->as_VMReg()->next()); 130243114Sdteske 131243114Sdteske 132243114Sdteske// Floating Point Registers 133243114Sdteske 134243114Sdteske// Specify priority of register selection within phases of register 135243114Sdteske// allocation. Highest priority is first. A useful heuristic is to 136243114Sdteske// give registers a low priority when they are required by machine 137243114Sdteske// instructions, like EAX and EDX on I486, and choose no-save registers 138243114Sdteske// before save-on-call, & save-on-call before save-on-entry. Registers 139243114Sdteske// which participate in fixed calling sequences should come last. 140243114Sdteske// Registers which are used as pairs must fall on an even boundary. 141243114Sdteske 142243114Sdteskealloc_class chunk0(R10, R10_H, 143243114Sdteske R11, R11_H, 144243114Sdteske R8, R8_H, 145243114Sdteske R9, R9_H, 146241523Sdteske R12, R12_H, 147243114Sdteske RCX, RCX_H, 148241523Sdteske RBX, RBX_H, 149241523Sdteske RDI, RDI_H, 150241523Sdteske RDX, RDX_H, 151241523Sdteske RSI, RSI_H, 152222417Sjulian RAX, RAX_H, 153222417Sjulian RBP, RBP_H, 154222417Sjulian R13, R13_H, 155222417Sjulian R14, R14_H, 156222417Sjulian R15, R15_H, 157243114Sdteske RSP, RSP_H); 158243114Sdteske 159222417Sjulian 160243114Sdteske//----------Architecture Description Register Classes-------------------------- 161222417Sjulian// Several register classes are automatically defined based upon information in 162222417Sjulian// this architecture description. 163222417Sjulian// 1) reg_class inline_cache_reg ( /* as def'd in frame section */ ) 164222417Sjulian// 2) reg_class compiler_method_oop_reg ( /* as def'd in frame section */ ) 165222417Sjulian// 2) reg_class interpreter_method_oop_reg ( /* as def'd in frame section */ ) 166222417Sjulian// 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ ) 167222417Sjulian// 168243114Sdteske 169243114Sdteske// Class for all pointer registers (including RSP) 170243114Sdteskereg_class any_reg(RAX, RAX_H, 171243114Sdteske RDX, RDX_H, 172243114Sdteske RBP, RBP_H, 173243114Sdteske RDI, RDI_H, 174243114Sdteske RSI, RSI_H, 175243114Sdteske RCX, RCX_H, 176243114Sdteske RBX, RBX_H, 177243114Sdteske RSP, RSP_H, 178243114Sdteske R8, R8_H, 179243114Sdteske R9, R9_H, 180243114Sdteske R10, R10_H, 181243114Sdteske R11, R11_H, 182243114Sdteske R12, R12_H, 183243114Sdteske R13, R13_H, 184243114Sdteske R14, R14_H, 185243114Sdteske R15, R15_H); 186241523Sdteske 187243114Sdteske// Class for all pointer registers except RSP 188241523Sdteskereg_class ptr_reg(RAX, RAX_H, 189241523Sdteske RDX, RDX_H, 190241523Sdteske RBP, RBP_H, 191241523Sdteske RDI, RDI_H, 192222417Sjulian RSI, RSI_H, 193222417Sjulian RCX, RCX_H, 194222417Sjulian RBX, RBX_H, 195222417Sjulian R8, R8_H, 196222417Sjulian R9, R9_H, 197222417Sjulian R10, R10_H, 198243114Sdteske R11, R11_H, 199243114Sdteske R13, R13_H, 200222417Sjulian R14, R14_H); 201243114Sdteske 202222417Sjulian// Class for all pointer registers except RAX and RSP 203222417Sjulianreg_class ptr_no_rax_reg(RDX, RDX_H, 204222417Sjulian RBP, RBP_H, 205222417Sjulian RDI, RDI_H, 206222417Sjulian RSI, RSI_H, 207243114Sdteske RCX, RCX_H, 208243114Sdteske RBX, RBX_H, 209243114Sdteske R8, R8_H, 210243114Sdteske R9, R9_H, 211243114Sdteske R10, R10_H, 212243114Sdteske R11, R11_H, 213243114Sdteske R13, R13_H, 214243114Sdteske R14, R14_H); 215243114Sdteske 216243114Sdteskereg_class ptr_no_rbp_reg(RDX, RDX_H, 217243114Sdteske RAX, RAX_H, 218243114Sdteske RDI, RDI_H, 219243114Sdteske RSI, RSI_H, 220243114Sdteske RCX, RCX_H, 221243114Sdteske RBX, RBX_H, 222243114Sdteske R8, R8_H, 223243114Sdteske R9, R9_H, 224243114Sdteske R10, R10_H, 225241523Sdteske R11, R11_H, 226243114Sdteske R13, R13_H, 227241523Sdteske R14, R14_H); 228241523Sdteske 229241523Sdteske// Class for all pointer registers except RAX, RBX and RSP 230241523Sdteskereg_class ptr_no_rax_rbx_reg(RDX, RDX_H, 231222417Sjulian RBP, RBP_H, 232222417Sjulian RDI, RDI_H, 233222417Sjulian RSI, RSI_H, 234222417Sjulian RCX, RCX_H, 235222417Sjulian R8, R8_H, 236222417Sjulian R9, R9_H, 237243114Sdteske R10, R10_H, 238243114Sdteske R11, R11_H, 239222417Sjulian R13, R13_H, 240243114Sdteske R14, R14_H); 241222417Sjulian 242222417Sjulian// Singleton class for RAX pointer register 243222417Sjulianreg_class ptr_rax_reg(RAX, RAX_H); 244222417Sjulian 245222417Sjulian// Singleton class for RBX pointer register 246243114Sdteskereg_class ptr_rbx_reg(RBX, RBX_H); 247243114Sdteske 248243114Sdteske// Singleton class for RSI pointer register 249243114Sdteskereg_class ptr_rsi_reg(RSI, RSI_H); 250222417Sjulian 251222417Sjulian// Singleton class for RDI pointer register 252222417Sjulianreg_class ptr_rdi_reg(RDI, RDI_H); 253222417Sjulian 254222417Sjulian// Singleton class for RBP pointer register 255222417Sjulianreg_class ptr_rbp_reg(RBP, RBP_H); 256222417Sjulian 257222417Sjulian// Singleton class for stack pointer 258222417Sjulianreg_class ptr_rsp_reg(RSP, RSP_H); 259222417Sjulian 260222417Sjulian// Singleton class for TLS pointer 261222417Sjulianreg_class ptr_r15_reg(R15, R15_H); 262243114Sdteske 263243114Sdteske// Class for all long registers (except RSP) 264243114Sdteskereg_class long_reg(RAX, RAX_H, 265243114Sdteske RDX, RDX_H, 266241523Sdteske RBP, RBP_H, 267243114Sdteske RDI, RDI_H, 268241523Sdteske RSI, RSI_H, 269241523Sdteske RCX, RCX_H, 270241523Sdteske RBX, RBX_H, 271241523Sdteske R8, R8_H, 272241523Sdteske R9, R9_H, 273241523Sdteske R10, R10_H, 274241523Sdteske R11, R11_H, 275241523Sdteske R13, R13_H, 276241523Sdteske R14, R14_H); 277241523Sdteske 278241523Sdteske// Class for all long registers except RAX, RDX (and RSP) 279243114Sdteskereg_class long_no_rax_rdx_reg(RBP, RBP_H, 280243114Sdteske RDI, RDI_H, 281243114Sdteske RSI, RSI_H, 282243114Sdteske RCX, RCX_H, 283241523Sdteske RBX, RBX_H, 284241523Sdteske R8, R8_H, 285241523Sdteske R9, R9_H, 286241523Sdteske R10, R10_H, 287241523Sdteske R11, R11_H, 288262701Sdteske R13, R13_H, 289262701Sdteske R14, R14_H); 290262701Sdteske 291262701Sdteske// Class for all long registers except RCX (and RSP) 292222417Sjulianreg_class long_no_rcx_reg(RBP, RBP_H, 293222417Sjulian RDI, RDI_H, 294262701Sdteske RSI, RSI_H, 295262701Sdteske RAX, RAX_H, 296262701Sdteske RDX, RDX_H, 297222417Sjulian RBX, RBX_H, 298262701Sdteske R8, R8_H, 299262701Sdteske R9, R9_H, 300262701Sdteske R10, R10_H, 301262701Sdteske R11, R11_H, 302262701Sdteske R13, R13_H, 303222417Sjulian R14, R14_H); 304222417Sjulian 305243114Sdteske// Class for all long registers except RAX (and RSP) 306243114Sdteskereg_class long_no_rax_reg(RBP, RBP_H, 307243114Sdteske RDX, RDX_H, 308243114Sdteske RDI, RDI_H, 309241523Sdteske RSI, RSI_H, 310241523Sdteske RCX, RCX_H, 311241523Sdteske RBX, RBX_H, 312241523Sdteske R8, R8_H, 313241523Sdteske R9, R9_H, 314262701Sdteske R10, R10_H, 315262701Sdteske R11, R11_H, 316262701Sdteske R13, R13_H, 317262701Sdteske R14, R14_H); 318222417Sjulian 319241367Sdteske// Singleton class for RAX long register 320262701Sdteskereg_class long_rax_reg(RAX, RAX_H); 321262701Sdteske 322262701Sdteske// Singleton class for RCX long register 323222417Sjulianreg_class long_rcx_reg(RCX, RCX_H); 324262701Sdteske 325262701Sdteske// Singleton class for RDX long register 326262701Sdteskereg_class long_rdx_reg(RDX, RDX_H); 327262701Sdteske 328262701Sdteske// Class for all int registers (except RSP) 329222417Sjulianreg_class int_reg(RAX, 330242667Sdteske RDX, 331243114Sdteske RBP, 332243114Sdteske RDI, 333243114Sdteske RSI, 334243114Sdteske RCX, 335242667Sdteske RBX, 336242667Sdteske R8, 337242667Sdteske R9, 338242667Sdteske R10, 339242667Sdteske R11, 340242667Sdteske R13, 341243660Sdteske R14); 342243660Sdteske 343243660Sdteske// Class for all int registers except RCX (and RSP) 344243660Sdteskereg_class int_no_rcx_reg(RAX, 345243660Sdteske RDX, 346243660Sdteske RBP, 347243660Sdteske RDI, 348243660Sdteske RSI, 349243660Sdteske RBX, 350243660Sdteske R8, 351243660Sdteske R9, 352243660Sdteske R10, 353281843Sdteske R11, 354281843Sdteske R13, 355 R14); 356 357// Class for all int registers except RAX, RDX (and RSP) 358reg_class int_no_rax_rdx_reg(RBP, 359 RDI, 360 RSI, 361 RCX, 362 RBX, 363 R8, 364 R9, 365 R10, 366 R11, 367 R13, 368 R14); 369 370// Singleton class for RAX int register 371reg_class int_rax_reg(RAX); 372 373// Singleton class for RBX int register 374reg_class int_rbx_reg(RBX); 375 376// Singleton class for RCX int register 377reg_class int_rcx_reg(RCX); 378 379// Singleton class for RCX int register 380reg_class int_rdx_reg(RDX); 381 382// Singleton class for RCX int register 383reg_class int_rdi_reg(RDI); 384 385// Singleton class for instruction pointer 386// reg_class ip_reg(RIP); 387 388%} 389 390//----------SOURCE BLOCK------------------------------------------------------- 391// This is a block of C++ code which provides values, functions, and 392// definitions necessary in the rest of the architecture description 393source %{ 394#define RELOC_IMM64 Assembler::imm_operand 395#define RELOC_DISP32 Assembler::disp32_operand 396 397#define __ _masm. 398 399static int preserve_SP_size() { 400 return 3; // rex.w, op, rm(reg/reg) 401} 402 403// !!!!! Special hack to get all types of calls to specify the byte offset 404// from the start of the call to the point where the return address 405// will point. 406int MachCallStaticJavaNode::ret_addr_offset() 407{ 408 int offset = 5; // 5 bytes from start of call to where return address points 409 if (_method_handle_invoke) 410 offset += preserve_SP_size(); 411 return offset; 412} 413 414int MachCallDynamicJavaNode::ret_addr_offset() 415{ 416 return 15; // 15 bytes from start of call to where return address points 417} 418 419// In os_cpu .ad file 420// int MachCallRuntimeNode::ret_addr_offset() 421 422// Indicate if the safepoint node needs the polling page as an input, 423// it does if the polling page is more than disp32 away. 424bool SafePointNode::needs_polling_address_input() 425{ 426 return Assembler::is_polling_page_far(); 427} 428 429// 430// Compute padding required for nodes which need alignment 431// 432 433// The address of the call instruction needs to be 4-byte aligned to 434// ensure that it does not span a cache line so that it can be patched. 435int CallStaticJavaDirectNode::compute_padding(int current_offset) const 436{ 437 current_offset += 1; // skip call opcode byte 438 return round_to(current_offset, alignment_required()) - current_offset; 439} 440 441// The address of the call instruction needs to be 4-byte aligned to 442// ensure that it does not span a cache line so that it can be patched. 443int CallStaticJavaHandleNode::compute_padding(int current_offset) const 444{ 445 current_offset += preserve_SP_size(); // skip mov rbp, rsp 446 current_offset += 1; // skip call opcode byte 447 return round_to(current_offset, alignment_required()) - current_offset; 448} 449 450// The address of the call instruction needs to be 4-byte aligned to 451// ensure that it does not span a cache line so that it can be patched. 452int CallDynamicJavaDirectNode::compute_padding(int current_offset) const 453{ 454 current_offset += 11; // skip movq instruction + call opcode byte 455 return round_to(current_offset, alignment_required()) - current_offset; 456} 457 458// EMIT_RM() 459void emit_rm(CodeBuffer &cbuf, int f1, int f2, int f3) { 460 unsigned char c = (unsigned char) ((f1 << 6) | (f2 << 3) | f3); 461 cbuf.insts()->emit_int8(c); 462} 463 464// EMIT_CC() 465void emit_cc(CodeBuffer &cbuf, int f1, int f2) { 466 unsigned char c = (unsigned char) (f1 | f2); 467 cbuf.insts()->emit_int8(c); 468} 469 470// EMIT_OPCODE() 471void emit_opcode(CodeBuffer &cbuf, int code) { 472 cbuf.insts()->emit_int8((unsigned char) code); 473} 474 475// EMIT_OPCODE() w/ relocation information 476void emit_opcode(CodeBuffer &cbuf, 477 int code, relocInfo::relocType reloc, int offset, int format) 478{ 479 cbuf.relocate(cbuf.insts_mark() + offset, reloc, format); 480 emit_opcode(cbuf, code); 481} 482 483// EMIT_D8() 484void emit_d8(CodeBuffer &cbuf, int d8) { 485 cbuf.insts()->emit_int8((unsigned char) d8); 486} 487 488// EMIT_D16() 489void emit_d16(CodeBuffer &cbuf, int d16) { 490 cbuf.insts()->emit_int16(d16); 491} 492 493// EMIT_D32() 494void emit_d32(CodeBuffer &cbuf, int d32) { 495 cbuf.insts()->emit_int32(d32); 496} 497 498// EMIT_D64() 499void emit_d64(CodeBuffer &cbuf, int64_t d64) { 500 cbuf.insts()->emit_int64(d64); 501} 502 503// emit 32 bit value and construct relocation entry from relocInfo::relocType 504void emit_d32_reloc(CodeBuffer& cbuf, 505 int d32, 506 relocInfo::relocType reloc, 507 int format) 508{ 509 assert(reloc != relocInfo::external_word_type, "use 2-arg emit_d32_reloc"); 510 cbuf.relocate(cbuf.insts_mark(), reloc, format); 511 cbuf.insts()->emit_int32(d32); 512} 513 514// emit 32 bit value and construct relocation entry from RelocationHolder 515void emit_d32_reloc(CodeBuffer& cbuf, int d32, RelocationHolder const& rspec, int format) { 516#ifdef ASSERT 517 if (rspec.reloc()->type() == relocInfo::oop_type && 518 d32 != 0 && d32 != (intptr_t) Universe::non_oop_word()) { 519 assert(Universe::heap()->is_in_reserved((address)(intptr_t)d32), "should be real oop"); 520 assert(oop((intptr_t)d32)->is_oop() && (ScavengeRootsInCode || !oop((intptr_t)d32)->is_scavengable()), "cannot embed scavengable oops in code"); 521 } 522#endif 523 cbuf.relocate(cbuf.insts_mark(), rspec, format); 524 cbuf.insts()->emit_int32(d32); 525} 526 527void emit_d32_reloc(CodeBuffer& cbuf, address addr) { 528 address next_ip = cbuf.insts_end() + 4; 529 emit_d32_reloc(cbuf, (int) (addr - next_ip), 530 external_word_Relocation::spec(addr), 531 RELOC_DISP32); 532} 533 534 535// emit 64 bit value and construct relocation entry from relocInfo::relocType 536void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, relocInfo::relocType reloc, int format) { 537 cbuf.relocate(cbuf.insts_mark(), reloc, format); 538 cbuf.insts()->emit_int64(d64); 539} 540 541// emit 64 bit value and construct relocation entry from RelocationHolder 542void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, RelocationHolder const& rspec, int format) { 543#ifdef ASSERT 544 if (rspec.reloc()->type() == relocInfo::oop_type && 545 d64 != 0 && d64 != (int64_t) Universe::non_oop_word()) { 546 assert(Universe::heap()->is_in_reserved((address)d64), "should be real oop"); 547 assert(oop(d64)->is_oop() && (ScavengeRootsInCode || !oop(d64)->is_scavengable()), 548 "cannot embed scavengable oops in code"); 549 } 550#endif 551 cbuf.relocate(cbuf.insts_mark(), rspec, format); 552 cbuf.insts()->emit_int64(d64); 553} 554 555// Access stack slot for load or store 556void store_to_stackslot(CodeBuffer &cbuf, int opcode, int rm_field, int disp) 557{ 558 emit_opcode(cbuf, opcode); // (e.g., FILD [RSP+src]) 559 if (-0x80 <= disp && disp < 0x80) { 560 emit_rm(cbuf, 0x01, rm_field, RSP_enc); // R/M byte 561 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte 562 emit_d8(cbuf, disp); // Displacement // R/M byte 563 } else { 564 emit_rm(cbuf, 0x02, rm_field, RSP_enc); // R/M byte 565 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte 566 emit_d32(cbuf, disp); // Displacement // R/M byte 567 } 568} 569 570 // rRegI ereg, memory mem) %{ // emit_reg_mem 571void encode_RegMem(CodeBuffer &cbuf, 572 int reg, 573 int base, int index, int scale, int disp, relocInfo::relocType disp_reloc) 574{ 575 assert(disp_reloc == relocInfo::none, "cannot have disp"); 576 int regenc = reg & 7; 577 int baseenc = base & 7; 578 int indexenc = index & 7; 579 580 // There is no index & no scale, use form without SIB byte 581 if (index == 0x4 && scale == 0 && base != RSP_enc && base != R12_enc) { 582 // If no displacement, mode is 0x0; unless base is [RBP] or [R13] 583 if (disp == 0 && base != RBP_enc && base != R13_enc) { 584 emit_rm(cbuf, 0x0, regenc, baseenc); // * 585 } else if (-0x80 <= disp && disp < 0x80 && disp_reloc == relocInfo::none) { 586 // If 8-bit displacement, mode 0x1 587 emit_rm(cbuf, 0x1, regenc, baseenc); // * 588 emit_d8(cbuf, disp); 589 } else { 590 // If 32-bit displacement 591 if (base == -1) { // Special flag for absolute address 592 emit_rm(cbuf, 0x0, regenc, 0x5); // * 593 if (disp_reloc != relocInfo::none) { 594 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 595 } else { 596 emit_d32(cbuf, disp); 597 } 598 } else { 599 // Normal base + offset 600 emit_rm(cbuf, 0x2, regenc, baseenc); // * 601 if (disp_reloc != relocInfo::none) { 602 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 603 } else { 604 emit_d32(cbuf, disp); 605 } 606 } 607 } 608 } else { 609 // Else, encode with the SIB byte 610 // If no displacement, mode is 0x0; unless base is [RBP] or [R13] 611 if (disp == 0 && base != RBP_enc && base != R13_enc) { 612 // If no displacement 613 emit_rm(cbuf, 0x0, regenc, 0x4); // * 614 emit_rm(cbuf, scale, indexenc, baseenc); 615 } else { 616 if (-0x80 <= disp && disp < 0x80 && disp_reloc == relocInfo::none) { 617 // If 8-bit displacement, mode 0x1 618 emit_rm(cbuf, 0x1, regenc, 0x4); // * 619 emit_rm(cbuf, scale, indexenc, baseenc); 620 emit_d8(cbuf, disp); 621 } else { 622 // If 32-bit displacement 623 if (base == 0x04 ) { 624 emit_rm(cbuf, 0x2, regenc, 0x4); 625 emit_rm(cbuf, scale, indexenc, 0x04); // XXX is this valid??? 626 } else { 627 emit_rm(cbuf, 0x2, regenc, 0x4); 628 emit_rm(cbuf, scale, indexenc, baseenc); // * 629 } 630 if (disp_reloc != relocInfo::none) { 631 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 632 } else { 633 emit_d32(cbuf, disp); 634 } 635 } 636 } 637 } 638} 639 640// This could be in MacroAssembler but it's fairly C2 specific 641void emit_cmpfp_fixup(MacroAssembler& _masm) { 642 Label exit; 643 __ jccb(Assembler::noParity, exit); 644 __ pushf(); 645 // 646 // comiss/ucomiss instructions set ZF,PF,CF flags and 647 // zero OF,AF,SF for NaN values. 648 // Fixup flags by zeroing ZF,PF so that compare of NaN 649 // values returns 'less than' result (CF is set). 650 // Leave the rest of flags unchanged. 651 // 652 // 7 6 5 4 3 2 1 0 653 // |S|Z|r|A|r|P|r|C| (r - reserved bit) 654 // 0 0 1 0 1 0 1 1 (0x2B) 655 // 656 __ andq(Address(rsp, 0), 0xffffff2b); 657 __ popf(); 658 __ bind(exit); 659} 660 661void emit_cmpfp3(MacroAssembler& _masm, Register dst) { 662 Label done; 663 __ movl(dst, -1); 664 __ jcc(Assembler::parity, done); 665 __ jcc(Assembler::below, done); 666 __ setb(Assembler::notEqual, dst); 667 __ movzbl(dst, dst); 668 __ bind(done); 669} 670 671 672//============================================================================= 673const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; 674 675int Compile::ConstantTable::calculate_table_base_offset() const { 676 return 0; // absolute addressing, no offset 677} 678 679void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 680 // Empty encoding 681} 682 683uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 684 return 0; 685} 686 687#ifndef PRODUCT 688void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 689 st->print("# MachConstantBaseNode (empty encoding)"); 690} 691#endif 692 693 694//============================================================================= 695#ifndef PRODUCT 696void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 697 Compile* C = ra_->C; 698 699 int framesize = C->frame_slots() << LogBytesPerInt; 700 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 701 // Remove wordSize for return addr which is already pushed. 702 framesize -= wordSize; 703 704 if (C->need_stack_bang(framesize)) { 705 framesize -= wordSize; 706 st->print("# stack bang"); 707 st->print("\n\t"); 708 st->print("pushq rbp\t# Save rbp"); 709 if (framesize) { 710 st->print("\n\t"); 711 st->print("subq rsp, #%d\t# Create frame",framesize); 712 } 713 } else { 714 st->print("subq rsp, #%d\t# Create frame",framesize); 715 st->print("\n\t"); 716 framesize -= wordSize; 717 st->print("movq [rsp + #%d], rbp\t# Save rbp",framesize); 718 } 719 720 if (VerifyStackAtCalls) { 721 st->print("\n\t"); 722 framesize -= wordSize; 723 st->print("movq [rsp + #%d], 0xbadb100d\t# Majik cookie for stack depth check",framesize); 724#ifdef ASSERT 725 st->print("\n\t"); 726 st->print("# stack alignment check"); 727#endif 728 } 729 st->cr(); 730} 731#endif 732 733void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 734 Compile* C = ra_->C; 735 MacroAssembler _masm(&cbuf); 736 737 int framesize = C->frame_slots() << LogBytesPerInt; 738 739 __ verified_entry(framesize, C->need_stack_bang(framesize), false); 740 741 C->set_frame_complete(cbuf.insts_size()); 742 743 if (C->has_mach_constant_base_node()) { 744 // NOTE: We set the table base offset here because users might be 745 // emitted before MachConstantBaseNode. 746 Compile::ConstantTable& constant_table = C->constant_table(); 747 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset()); 748 } 749} 750 751uint MachPrologNode::size(PhaseRegAlloc* ra_) const 752{ 753 return MachNode::size(ra_); // too many variables; just compute it 754 // the hard way 755} 756 757int MachPrologNode::reloc() const 758{ 759 return 0; // a large enough number 760} 761 762//============================================================================= 763#ifndef PRODUCT 764void MachEpilogNode::format(PhaseRegAlloc* ra_, outputStream* st) const 765{ 766 Compile* C = ra_->C; 767 int framesize = C->frame_slots() << LogBytesPerInt; 768 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 769 // Remove word for return adr already pushed 770 // and RBP 771 framesize -= 2*wordSize; 772 773 if (framesize) { 774 st->print_cr("addq rsp, %d\t# Destroy frame", framesize); 775 st->print("\t"); 776 } 777 778 st->print_cr("popq rbp"); 779 if (do_polling() && C->is_method_compilation()) { 780 st->print("\t"); 781 if (Assembler::is_polling_page_far()) { 782 st->print_cr("movq rscratch1, #polling_page_address\n\t" 783 "testl rax, [rscratch1]\t" 784 "# Safepoint: poll for GC"); 785 } else { 786 st->print_cr("testl rax, [rip + #offset_to_poll_page]\t" 787 "# Safepoint: poll for GC"); 788 } 789 } 790} 791#endif 792 793void MachEpilogNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 794{ 795 Compile* C = ra_->C; 796 int framesize = C->frame_slots() << LogBytesPerInt; 797 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 798 // Remove word for return adr already pushed 799 // and RBP 800 framesize -= 2*wordSize; 801 802 // Note that VerifyStackAtCalls' Majik cookie does not change the frame size popped here 803 804 if (framesize) { 805 emit_opcode(cbuf, Assembler::REX_W); 806 if (framesize < 0x80) { 807 emit_opcode(cbuf, 0x83); // addq rsp, #framesize 808 emit_rm(cbuf, 0x3, 0x00, RSP_enc); 809 emit_d8(cbuf, framesize); 810 } else { 811 emit_opcode(cbuf, 0x81); // addq rsp, #framesize 812 emit_rm(cbuf, 0x3, 0x00, RSP_enc); 813 emit_d32(cbuf, framesize); 814 } 815 } 816 817 // popq rbp 818 emit_opcode(cbuf, 0x58 | RBP_enc); 819 820 if (do_polling() && C->is_method_compilation()) { 821 MacroAssembler _masm(&cbuf); 822 AddressLiteral polling_page(os::get_polling_page(), relocInfo::poll_return_type); 823 if (Assembler::is_polling_page_far()) { 824 __ lea(rscratch1, polling_page); 825 __ relocate(relocInfo::poll_return_type); 826 __ testl(rax, Address(rscratch1, 0)); 827 } else { 828 __ testl(rax, polling_page); 829 } 830 } 831} 832 833uint MachEpilogNode::size(PhaseRegAlloc* ra_) const 834{ 835 return MachNode::size(ra_); // too many variables; just compute it 836 // the hard way 837} 838 839int MachEpilogNode::reloc() const 840{ 841 return 2; // a large enough number 842} 843 844const Pipeline* MachEpilogNode::pipeline() const 845{ 846 return MachNode::pipeline_class(); 847} 848 849int MachEpilogNode::safepoint_offset() const 850{ 851 return 0; 852} 853 854//============================================================================= 855 856enum RC { 857 rc_bad, 858 rc_int, 859 rc_float, 860 rc_stack 861}; 862 863static enum RC rc_class(OptoReg::Name reg) 864{ 865 if( !OptoReg::is_valid(reg) ) return rc_bad; 866 867 if (OptoReg::is_stack(reg)) return rc_stack; 868 869 VMReg r = OptoReg::as_VMReg(reg); 870 871 if (r->is_Register()) return rc_int; 872 873 assert(r->is_XMMRegister(), "must be"); 874 return rc_float; 875} 876 877// Next two methods are shared by 32- and 64-bit VM. They are defined in x86.ad. 878static int vec_mov_helper(CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo, 879 int src_hi, int dst_hi, uint ireg, outputStream* st); 880 881static int vec_spill_helper(CodeBuffer *cbuf, bool do_size, bool is_load, 882 int stack_offset, int reg, uint ireg, outputStream* st); 883 884static void vec_stack_to_stack_helper(CodeBuffer *cbuf, int src_offset, 885 int dst_offset, uint ireg, outputStream* st) { 886 if (cbuf) { 887 MacroAssembler _masm(cbuf); 888 switch (ireg) { 889 case Op_VecS: 890 __ movq(Address(rsp, -8), rax); 891 __ movl(rax, Address(rsp, src_offset)); 892 __ movl(Address(rsp, dst_offset), rax); 893 __ movq(rax, Address(rsp, -8)); 894 break; 895 case Op_VecD: 896 __ pushq(Address(rsp, src_offset)); 897 __ popq (Address(rsp, dst_offset)); 898 break; 899 case Op_VecX: 900 __ pushq(Address(rsp, src_offset)); 901 __ popq (Address(rsp, dst_offset)); 902 __ pushq(Address(rsp, src_offset+8)); 903 __ popq (Address(rsp, dst_offset+8)); 904 break; 905 case Op_VecY: 906 __ vmovdqu(Address(rsp, -32), xmm0); 907 __ vmovdqu(xmm0, Address(rsp, src_offset)); 908 __ vmovdqu(Address(rsp, dst_offset), xmm0); 909 __ vmovdqu(xmm0, Address(rsp, -32)); 910 break; 911 default: 912 ShouldNotReachHere(); 913 } 914#ifndef PRODUCT 915 } else { 916 switch (ireg) { 917 case Op_VecS: 918 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 919 "movl rax, [rsp + #%d]\n\t" 920 "movl [rsp + #%d], rax\n\t" 921 "movq rax, [rsp - #8]", 922 src_offset, dst_offset); 923 break; 924 case Op_VecD: 925 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 926 "popq [rsp + #%d]", 927 src_offset, dst_offset); 928 break; 929 case Op_VecX: 930 st->print("pushq [rsp + #%d]\t# 128-bit mem-mem spill\n\t" 931 "popq [rsp + #%d]\n\t" 932 "pushq [rsp + #%d]\n\t" 933 "popq [rsp + #%d]", 934 src_offset, dst_offset, src_offset+8, dst_offset+8); 935 break; 936 case Op_VecY: 937 st->print("vmovdqu [rsp - #32], xmm0\t# 256-bit mem-mem spill\n\t" 938 "vmovdqu xmm0, [rsp + #%d]\n\t" 939 "vmovdqu [rsp + #%d], xmm0\n\t" 940 "vmovdqu xmm0, [rsp - #32]", 941 src_offset, dst_offset); 942 break; 943 default: 944 ShouldNotReachHere(); 945 } 946#endif 947 } 948} 949 950uint MachSpillCopyNode::implementation(CodeBuffer* cbuf, 951 PhaseRegAlloc* ra_, 952 bool do_size, 953 outputStream* st) const { 954 assert(cbuf != NULL || st != NULL, "sanity"); 955 // Get registers to move 956 OptoReg::Name src_second = ra_->get_reg_second(in(1)); 957 OptoReg::Name src_first = ra_->get_reg_first(in(1)); 958 OptoReg::Name dst_second = ra_->get_reg_second(this); 959 OptoReg::Name dst_first = ra_->get_reg_first(this); 960 961 enum RC src_second_rc = rc_class(src_second); 962 enum RC src_first_rc = rc_class(src_first); 963 enum RC dst_second_rc = rc_class(dst_second); 964 enum RC dst_first_rc = rc_class(dst_first); 965 966 assert(OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), 967 "must move at least 1 register" ); 968 969 if (src_first == dst_first && src_second == dst_second) { 970 // Self copy, no move 971 return 0; 972 } 973 if (bottom_type()->isa_vect() != NULL) { 974 uint ireg = ideal_reg(); 975 assert((src_first_rc != rc_int && dst_first_rc != rc_int), "sanity"); 976 assert((ireg == Op_VecS || ireg == Op_VecD || ireg == Op_VecX || ireg == Op_VecY), "sanity"); 977 if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) { 978 // mem -> mem 979 int src_offset = ra_->reg2offset(src_first); 980 int dst_offset = ra_->reg2offset(dst_first); 981 vec_stack_to_stack_helper(cbuf, src_offset, dst_offset, ireg, st); 982 } else if (src_first_rc == rc_float && dst_first_rc == rc_float ) { 983 vec_mov_helper(cbuf, false, src_first, dst_first, src_second, dst_second, ireg, st); 984 } else if (src_first_rc == rc_float && dst_first_rc == rc_stack ) { 985 int stack_offset = ra_->reg2offset(dst_first); 986 vec_spill_helper(cbuf, false, false, stack_offset, src_first, ireg, st); 987 } else if (src_first_rc == rc_stack && dst_first_rc == rc_float ) { 988 int stack_offset = ra_->reg2offset(src_first); 989 vec_spill_helper(cbuf, false, true, stack_offset, dst_first, ireg, st); 990 } else { 991 ShouldNotReachHere(); 992 } 993 return 0; 994 } 995 if (src_first_rc == rc_stack) { 996 // mem -> 997 if (dst_first_rc == rc_stack) { 998 // mem -> mem 999 assert(src_second != dst_first, "overlap"); 1000 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1001 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1002 // 64-bit 1003 int src_offset = ra_->reg2offset(src_first); 1004 int dst_offset = ra_->reg2offset(dst_first); 1005 if (cbuf) { 1006 MacroAssembler _masm(cbuf); 1007 __ pushq(Address(rsp, src_offset)); 1008 __ popq (Address(rsp, dst_offset)); 1009#ifndef PRODUCT 1010 } else { 1011 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1012 "popq [rsp + #%d]", 1013 src_offset, dst_offset); 1014#endif 1015 } 1016 } else { 1017 // 32-bit 1018 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1019 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1020 // No pushl/popl, so: 1021 int src_offset = ra_->reg2offset(src_first); 1022 int dst_offset = ra_->reg2offset(dst_first); 1023 if (cbuf) { 1024 MacroAssembler _masm(cbuf); 1025 __ movq(Address(rsp, -8), rax); 1026 __ movl(rax, Address(rsp, src_offset)); 1027 __ movl(Address(rsp, dst_offset), rax); 1028 __ movq(rax, Address(rsp, -8)); 1029#ifndef PRODUCT 1030 } else { 1031 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1032 "movl rax, [rsp + #%d]\n\t" 1033 "movl [rsp + #%d], rax\n\t" 1034 "movq rax, [rsp - #8]", 1035 src_offset, dst_offset); 1036#endif 1037 } 1038 } 1039 return 0; 1040 } else if (dst_first_rc == rc_int) { 1041 // mem -> gpr 1042 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1043 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1044 // 64-bit 1045 int offset = ra_->reg2offset(src_first); 1046 if (cbuf) { 1047 MacroAssembler _masm(cbuf); 1048 __ movq(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1049#ifndef PRODUCT 1050 } else { 1051 st->print("movq %s, [rsp + #%d]\t# spill", 1052 Matcher::regName[dst_first], 1053 offset); 1054#endif 1055 } 1056 } else { 1057 // 32-bit 1058 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1059 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1060 int offset = ra_->reg2offset(src_first); 1061 if (cbuf) { 1062 MacroAssembler _masm(cbuf); 1063 __ movl(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1064#ifndef PRODUCT 1065 } else { 1066 st->print("movl %s, [rsp + #%d]\t# spill", 1067 Matcher::regName[dst_first], 1068 offset); 1069#endif 1070 } 1071 } 1072 return 0; 1073 } else if (dst_first_rc == rc_float) { 1074 // mem-> xmm 1075 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1076 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1077 // 64-bit 1078 int offset = ra_->reg2offset(src_first); 1079 if (cbuf) { 1080 MacroAssembler _masm(cbuf); 1081 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1082#ifndef PRODUCT 1083 } else { 1084 st->print("%s %s, [rsp + #%d]\t# spill", 1085 UseXmmLoadAndClearUpper ? "movsd " : "movlpd", 1086 Matcher::regName[dst_first], 1087 offset); 1088#endif 1089 } 1090 } else { 1091 // 32-bit 1092 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1093 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1094 int offset = ra_->reg2offset(src_first); 1095 if (cbuf) { 1096 MacroAssembler _masm(cbuf); 1097 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1098#ifndef PRODUCT 1099 } else { 1100 st->print("movss %s, [rsp + #%d]\t# spill", 1101 Matcher::regName[dst_first], 1102 offset); 1103#endif 1104 } 1105 } 1106 return 0; 1107 } 1108 } else if (src_first_rc == rc_int) { 1109 // gpr -> 1110 if (dst_first_rc == rc_stack) { 1111 // gpr -> mem 1112 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1113 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1114 // 64-bit 1115 int offset = ra_->reg2offset(dst_first); 1116 if (cbuf) { 1117 MacroAssembler _masm(cbuf); 1118 __ movq(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1119#ifndef PRODUCT 1120 } else { 1121 st->print("movq [rsp + #%d], %s\t# spill", 1122 offset, 1123 Matcher::regName[src_first]); 1124#endif 1125 } 1126 } else { 1127 // 32-bit 1128 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1129 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1130 int offset = ra_->reg2offset(dst_first); 1131 if (cbuf) { 1132 MacroAssembler _masm(cbuf); 1133 __ movl(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1134#ifndef PRODUCT 1135 } else { 1136 st->print("movl [rsp + #%d], %s\t# spill", 1137 offset, 1138 Matcher::regName[src_first]); 1139#endif 1140 } 1141 } 1142 return 0; 1143 } else if (dst_first_rc == rc_int) { 1144 // gpr -> gpr 1145 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1146 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1147 // 64-bit 1148 if (cbuf) { 1149 MacroAssembler _masm(cbuf); 1150 __ movq(as_Register(Matcher::_regEncode[dst_first]), 1151 as_Register(Matcher::_regEncode[src_first])); 1152#ifndef PRODUCT 1153 } else { 1154 st->print("movq %s, %s\t# spill", 1155 Matcher::regName[dst_first], 1156 Matcher::regName[src_first]); 1157#endif 1158 } 1159 return 0; 1160 } else { 1161 // 32-bit 1162 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1163 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1164 if (cbuf) { 1165 MacroAssembler _masm(cbuf); 1166 __ movl(as_Register(Matcher::_regEncode[dst_first]), 1167 as_Register(Matcher::_regEncode[src_first])); 1168#ifndef PRODUCT 1169 } else { 1170 st->print("movl %s, %s\t# spill", 1171 Matcher::regName[dst_first], 1172 Matcher::regName[src_first]); 1173#endif 1174 } 1175 return 0; 1176 } 1177 } else if (dst_first_rc == rc_float) { 1178 // gpr -> xmm 1179 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1180 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1181 // 64-bit 1182 if (cbuf) { 1183 MacroAssembler _masm(cbuf); 1184 __ movdq( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1185#ifndef PRODUCT 1186 } else { 1187 st->print("movdq %s, %s\t# spill", 1188 Matcher::regName[dst_first], 1189 Matcher::regName[src_first]); 1190#endif 1191 } 1192 } else { 1193 // 32-bit 1194 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1195 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1196 if (cbuf) { 1197 MacroAssembler _masm(cbuf); 1198 __ movdl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1199#ifndef PRODUCT 1200 } else { 1201 st->print("movdl %s, %s\t# spill", 1202 Matcher::regName[dst_first], 1203 Matcher::regName[src_first]); 1204#endif 1205 } 1206 } 1207 return 0; 1208 } 1209 } else if (src_first_rc == rc_float) { 1210 // xmm -> 1211 if (dst_first_rc == rc_stack) { 1212 // xmm -> mem 1213 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1214 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1215 // 64-bit 1216 int offset = ra_->reg2offset(dst_first); 1217 if (cbuf) { 1218 MacroAssembler _masm(cbuf); 1219 __ movdbl( Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1220#ifndef PRODUCT 1221 } else { 1222 st->print("movsd [rsp + #%d], %s\t# spill", 1223 offset, 1224 Matcher::regName[src_first]); 1225#endif 1226 } 1227 } else { 1228 // 32-bit 1229 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1230 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1231 int offset = ra_->reg2offset(dst_first); 1232 if (cbuf) { 1233 MacroAssembler _masm(cbuf); 1234 __ movflt(Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1235#ifndef PRODUCT 1236 } else { 1237 st->print("movss [rsp + #%d], %s\t# spill", 1238 offset, 1239 Matcher::regName[src_first]); 1240#endif 1241 } 1242 } 1243 return 0; 1244 } else if (dst_first_rc == rc_int) { 1245 // xmm -> gpr 1246 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1247 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1248 // 64-bit 1249 if (cbuf) { 1250 MacroAssembler _masm(cbuf); 1251 __ movdq( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1252#ifndef PRODUCT 1253 } else { 1254 st->print("movdq %s, %s\t# spill", 1255 Matcher::regName[dst_first], 1256 Matcher::regName[src_first]); 1257#endif 1258 } 1259 } else { 1260 // 32-bit 1261 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1262 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1263 if (cbuf) { 1264 MacroAssembler _masm(cbuf); 1265 __ movdl( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1266#ifndef PRODUCT 1267 } else { 1268 st->print("movdl %s, %s\t# spill", 1269 Matcher::regName[dst_first], 1270 Matcher::regName[src_first]); 1271#endif 1272 } 1273 } 1274 return 0; 1275 } else if (dst_first_rc == rc_float) { 1276 // xmm -> xmm 1277 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1278 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1279 // 64-bit 1280 if (cbuf) { 1281 MacroAssembler _masm(cbuf); 1282 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1283#ifndef PRODUCT 1284 } else { 1285 st->print("%s %s, %s\t# spill", 1286 UseXmmRegToRegMoveAll ? "movapd" : "movsd ", 1287 Matcher::regName[dst_first], 1288 Matcher::regName[src_first]); 1289#endif 1290 } 1291 } else { 1292 // 32-bit 1293 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1294 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1295 if (cbuf) { 1296 MacroAssembler _masm(cbuf); 1297 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1298#ifndef PRODUCT 1299 } else { 1300 st->print("%s %s, %s\t# spill", 1301 UseXmmRegToRegMoveAll ? "movaps" : "movss ", 1302 Matcher::regName[dst_first], 1303 Matcher::regName[src_first]); 1304#endif 1305 } 1306 } 1307 return 0; 1308 } 1309 } 1310 1311 assert(0," foo "); 1312 Unimplemented(); 1313 return 0; 1314} 1315 1316#ifndef PRODUCT 1317void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream* st) const { 1318 implementation(NULL, ra_, false, st); 1319} 1320#endif 1321 1322void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1323 implementation(&cbuf, ra_, false, NULL); 1324} 1325 1326uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1327 return MachNode::size(ra_); 1328} 1329 1330//============================================================================= 1331#ifndef PRODUCT 1332void BoxLockNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1333{ 1334 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1335 int reg = ra_->get_reg_first(this); 1336 st->print("leaq %s, [rsp + #%d]\t# box lock", 1337 Matcher::regName[reg], offset); 1338} 1339#endif 1340 1341void BoxLockNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1342{ 1343 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1344 int reg = ra_->get_encode(this); 1345 if (offset >= 0x80) { 1346 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR); 1347 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset] 1348 emit_rm(cbuf, 0x2, reg & 7, 0x04); 1349 emit_rm(cbuf, 0x0, 0x04, RSP_enc); 1350 emit_d32(cbuf, offset); 1351 } else { 1352 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR); 1353 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset] 1354 emit_rm(cbuf, 0x1, reg & 7, 0x04); 1355 emit_rm(cbuf, 0x0, 0x04, RSP_enc); 1356 emit_d8(cbuf, offset); 1357 } 1358} 1359 1360uint BoxLockNode::size(PhaseRegAlloc *ra_) const 1361{ 1362 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1363 return (offset < 0x80) ? 5 : 8; // REX 1364} 1365 1366//============================================================================= 1367 1368// emit call stub, compiled java to interpreter 1369void emit_java_to_interp(CodeBuffer& cbuf) 1370{ 1371 // Stub is fixed up when the corresponding call is converted from 1372 // calling compiled code to calling interpreted code. 1373 // movq rbx, 0 1374 // jmp -5 # to self 1375 1376 address mark = cbuf.insts_mark(); // get mark within main instrs section 1377 1378 // Note that the code buffer's insts_mark is always relative to insts. 1379 // That's why we must use the macroassembler to generate a stub. 1380 MacroAssembler _masm(&cbuf); 1381 1382 address base = 1383 __ start_a_stub(Compile::MAX_stubs_size); 1384 if (base == NULL) return; // CodeBuffer::expand failed 1385 // static stub relocation stores the instruction address of the call 1386 __ relocate(static_stub_Relocation::spec(mark), RELOC_IMM64); 1387 // static stub relocation also tags the Method* in the code-stream. 1388 __ mov_metadata(rbx, (Metadata*) NULL); // method is zapped till fixup time 1389 // This is recognized as unresolved by relocs/nativeinst/ic code 1390 __ jump(RuntimeAddress(__ pc())); 1391 1392 // Update current stubs pointer and restore insts_end. 1393 __ end_a_stub(); 1394} 1395 1396// size of call stub, compiled java to interpretor 1397uint size_java_to_interp() 1398{ 1399 return 15; // movq (1+1+8); jmp (1+4) 1400} 1401 1402// relocation entries for call stub, compiled java to interpretor 1403uint reloc_java_to_interp() 1404{ 1405 return 4; // 3 in emit_java_to_interp + 1 in Java_Static_Call 1406} 1407 1408//============================================================================= 1409#ifndef PRODUCT 1410void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1411{ 1412 if (UseCompressedOops) { 1413 st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1414 if (Universe::narrow_oop_shift() != 0) { 1415 st->print_cr("\tdecode_heap_oop_not_null rscratch1, rscratch1"); 1416 } 1417 st->print_cr("\tcmpq rax, rscratch1\t # Inline cache check"); 1418 } else { 1419 st->print_cr("\tcmpq rax, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t" 1420 "# Inline cache check"); 1421 } 1422 st->print_cr("\tjne SharedRuntime::_ic_miss_stub"); 1423 st->print_cr("\tnop\t# nops to align entry point"); 1424} 1425#endif 1426 1427void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1428{ 1429 MacroAssembler masm(&cbuf); 1430 uint insts_size = cbuf.insts_size(); 1431 if (UseCompressedOops) { 1432 masm.load_klass(rscratch1, j_rarg0); 1433 masm.cmpptr(rax, rscratch1); 1434 } else { 1435 masm.cmpptr(rax, Address(j_rarg0, oopDesc::klass_offset_in_bytes())); 1436 } 1437 1438 masm.jump_cc(Assembler::notEqual, RuntimeAddress(SharedRuntime::get_ic_miss_stub())); 1439 1440 /* WARNING these NOPs are critical so that verified entry point is properly 1441 4 bytes aligned for patching by NativeJump::patch_verified_entry() */ 1442 int nops_cnt = 4 - ((cbuf.insts_size() - insts_size) & 0x3); 1443 if (OptoBreakpoint) { 1444 // Leave space for int3 1445 nops_cnt -= 1; 1446 } 1447 nops_cnt &= 0x3; // Do not add nops if code is aligned. 1448 if (nops_cnt > 0) 1449 masm.nop(nops_cnt); 1450} 1451 1452uint MachUEPNode::size(PhaseRegAlloc* ra_) const 1453{ 1454 return MachNode::size(ra_); // too many variables; just compute it 1455 // the hard way 1456} 1457 1458 1459//============================================================================= 1460uint size_exception_handler() 1461{ 1462 // NativeCall instruction size is the same as NativeJump. 1463 // Note that this value is also credited (in output.cpp) to 1464 // the size of the code section. 1465 return NativeJump::instruction_size; 1466} 1467 1468// Emit exception handler code. 1469int emit_exception_handler(CodeBuffer& cbuf) 1470{ 1471 1472 // Note that the code buffer's insts_mark is always relative to insts. 1473 // That's why we must use the macroassembler to generate a handler. 1474 MacroAssembler _masm(&cbuf); 1475 address base = 1476 __ start_a_stub(size_exception_handler()); 1477 if (base == NULL) return 0; // CodeBuffer::expand failed 1478 int offset = __ offset(); 1479 __ jump(RuntimeAddress(OptoRuntime::exception_blob()->entry_point())); 1480 assert(__ offset() - offset <= (int) size_exception_handler(), "overflow"); 1481 __ end_a_stub(); 1482 return offset; 1483} 1484 1485uint size_deopt_handler() 1486{ 1487 // three 5 byte instructions 1488 return 15; 1489} 1490 1491// Emit deopt handler code. 1492int emit_deopt_handler(CodeBuffer& cbuf) 1493{ 1494 1495 // Note that the code buffer's insts_mark is always relative to insts. 1496 // That's why we must use the macroassembler to generate a handler. 1497 MacroAssembler _masm(&cbuf); 1498 address base = 1499 __ start_a_stub(size_deopt_handler()); 1500 if (base == NULL) return 0; // CodeBuffer::expand failed 1501 int offset = __ offset(); 1502 address the_pc = (address) __ pc(); 1503 Label next; 1504 // push a "the_pc" on the stack without destroying any registers 1505 // as they all may be live. 1506 1507 // push address of "next" 1508 __ call(next, relocInfo::none); // reloc none is fine since it is a disp32 1509 __ bind(next); 1510 // adjust it so it matches "the_pc" 1511 __ subptr(Address(rsp, 0), __ offset() - offset); 1512 __ jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack())); 1513 assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow"); 1514 __ end_a_stub(); 1515 return offset; 1516} 1517 1518int Matcher::regnum_to_fpu_offset(int regnum) 1519{ 1520 return regnum - 32; // The FP registers are in the second chunk 1521} 1522 1523// This is UltraSparc specific, true just means we have fast l2f conversion 1524const bool Matcher::convL2FSupported(void) { 1525 return true; 1526} 1527 1528// Is this branch offset short enough that a short branch can be used? 1529// 1530// NOTE: If the platform does not provide any short branch variants, then 1531// this method should return false for offset 0. 1532bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 1533 // The passed offset is relative to address of the branch. 1534 // On 86 a branch displacement is calculated relative to address 1535 // of a next instruction. 1536 offset -= br_size; 1537 1538 // the short version of jmpConUCF2 contains multiple branches, 1539 // making the reach slightly less 1540 if (rule == jmpConUCF2_rule) 1541 return (-126 <= offset && offset <= 125); 1542 return (-128 <= offset && offset <= 127); 1543} 1544 1545const bool Matcher::isSimpleConstant64(jlong value) { 1546 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?. 1547 //return value == (int) value; // Cf. storeImmL and immL32. 1548 1549 // Probably always true, even if a temp register is required. 1550 return true; 1551} 1552 1553// The ecx parameter to rep stosq for the ClearArray node is in words. 1554const bool Matcher::init_array_count_is_in_bytes = false; 1555 1556// Threshold size for cleararray. 1557const int Matcher::init_array_short_size = 8 * BytesPerLong; 1558 1559// No additional cost for CMOVL. 1560const int Matcher::long_cmove_cost() { return 0; } 1561 1562// No CMOVF/CMOVD with SSE2 1563const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; } 1564 1565// Should the Matcher clone shifts on addressing modes, expecting them 1566// to be subsumed into complex addressing expressions or compute them 1567// into registers? True for Intel but false for most RISCs 1568const bool Matcher::clone_shift_expressions = true; 1569 1570// Do we need to mask the count passed to shift instructions or does 1571// the cpu only look at the lower 5/6 bits anyway? 1572const bool Matcher::need_masked_shift_count = false; 1573 1574bool Matcher::narrow_oop_use_complex_address() { 1575 assert(UseCompressedOops, "only for compressed oops code"); 1576 return (LogMinObjAlignmentInBytes <= 3); 1577} 1578 1579// Is it better to copy float constants, or load them directly from 1580// memory? Intel can load a float constant from a direct address, 1581// requiring no extra registers. Most RISCs will have to materialize 1582// an address into a register first, so they would do better to copy 1583// the constant from stack. 1584const bool Matcher::rematerialize_float_constants = true; // XXX 1585 1586// If CPU can load and store mis-aligned doubles directly then no 1587// fixup is needed. Else we split the double into 2 integer pieces 1588// and move it piece-by-piece. Only happens when passing doubles into 1589// C code as the Java calling convention forces doubles to be aligned. 1590const bool Matcher::misaligned_doubles_ok = true; 1591 1592// No-op on amd64 1593void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) {} 1594 1595// Advertise here if the CPU requires explicit rounding operations to 1596// implement the UseStrictFP mode. 1597const bool Matcher::strict_fp_requires_explicit_rounding = true; 1598 1599// Are floats conerted to double when stored to stack during deoptimization? 1600// On x64 it is stored without convertion so we can use normal access. 1601bool Matcher::float_in_double() { return false; } 1602 1603// Do ints take an entire long register or just half? 1604const bool Matcher::int_in_long = true; 1605 1606// Return whether or not this register is ever used as an argument. 1607// This function is used on startup to build the trampoline stubs in 1608// generateOptoStub. Registers not mentioned will be killed by the VM 1609// call in the trampoline, and arguments in those registers not be 1610// available to the callee. 1611bool Matcher::can_be_java_arg(int reg) 1612{ 1613 return 1614 reg == RDI_num || reg == RDI_H_num || 1615 reg == RSI_num || reg == RSI_H_num || 1616 reg == RDX_num || reg == RDX_H_num || 1617 reg == RCX_num || reg == RCX_H_num || 1618 reg == R8_num || reg == R8_H_num || 1619 reg == R9_num || reg == R9_H_num || 1620 reg == R12_num || reg == R12_H_num || 1621 reg == XMM0_num || reg == XMM0b_num || 1622 reg == XMM1_num || reg == XMM1b_num || 1623 reg == XMM2_num || reg == XMM2b_num || 1624 reg == XMM3_num || reg == XMM3b_num || 1625 reg == XMM4_num || reg == XMM4b_num || 1626 reg == XMM5_num || reg == XMM5b_num || 1627 reg == XMM6_num || reg == XMM6b_num || 1628 reg == XMM7_num || reg == XMM7b_num; 1629} 1630 1631bool Matcher::is_spillable_arg(int reg) 1632{ 1633 return can_be_java_arg(reg); 1634} 1635 1636bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) { 1637 // In 64 bit mode a code which use multiply when 1638 // devisor is constant is faster than hardware 1639 // DIV instruction (it uses MulHiL). 1640 return false; 1641} 1642 1643// Register for DIVI projection of divmodI 1644RegMask Matcher::divI_proj_mask() { 1645 return INT_RAX_REG_mask(); 1646} 1647 1648// Register for MODI projection of divmodI 1649RegMask Matcher::modI_proj_mask() { 1650 return INT_RDX_REG_mask(); 1651} 1652 1653// Register for DIVL projection of divmodL 1654RegMask Matcher::divL_proj_mask() { 1655 return LONG_RAX_REG_mask(); 1656} 1657 1658// Register for MODL projection of divmodL 1659RegMask Matcher::modL_proj_mask() { 1660 return LONG_RDX_REG_mask(); 1661} 1662 1663const RegMask Matcher::method_handle_invoke_SP_save_mask() { 1664 return PTR_RBP_REG_mask(); 1665} 1666 1667static Address build_address(int b, int i, int s, int d) { 1668 Register index = as_Register(i); 1669 Address::ScaleFactor scale = (Address::ScaleFactor)s; 1670 if (index == rsp) { 1671 index = noreg; 1672 scale = Address::no_scale; 1673 } 1674 Address addr(as_Register(b), index, scale, d); 1675 return addr; 1676} 1677 1678%} 1679 1680//----------ENCODING BLOCK----------------------------------------------------- 1681// This block specifies the encoding classes used by the compiler to 1682// output byte streams. Encoding classes are parameterized macros 1683// used by Machine Instruction Nodes in order to generate the bit 1684// encoding of the instruction. Operands specify their base encoding 1685// interface with the interface keyword. There are currently 1686// supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & 1687// COND_INTER. REG_INTER causes an operand to generate a function 1688// which returns its register number when queried. CONST_INTER causes 1689// an operand to generate a function which returns the value of the 1690// constant when queried. MEMORY_INTER causes an operand to generate 1691// four functions which return the Base Register, the Index Register, 1692// the Scale Value, and the Offset Value of the operand when queried. 1693// COND_INTER causes an operand to generate six functions which return 1694// the encoding code (ie - encoding bits for the instruction) 1695// associated with each basic boolean condition for a conditional 1696// instruction. 1697// 1698// Instructions specify two basic values for encoding. Again, a 1699// function is available to check if the constant displacement is an 1700// oop. They use the ins_encode keyword to specify their encoding 1701// classes (which must be a sequence of enc_class names, and their 1702// parameters, specified in the encoding block), and they use the 1703// opcode keyword to specify, in order, their primary, secondary, and 1704// tertiary opcode. Only the opcode sections which a particular 1705// instruction needs for encoding need to be specified. 1706encode %{ 1707 // Build emit functions for each basic byte or larger field in the 1708 // intel encoding scheme (opcode, rm, sib, immediate), and call them 1709 // from C++ code in the enc_class source block. Emit functions will 1710 // live in the main source block for now. In future, we can 1711 // generalize this by adding a syntax that specifies the sizes of 1712 // fields in an order, so that the adlc can build the emit functions 1713 // automagically 1714 1715 // Emit primary opcode 1716 enc_class OpcP 1717 %{ 1718 emit_opcode(cbuf, $primary); 1719 %} 1720 1721 // Emit secondary opcode 1722 enc_class OpcS 1723 %{ 1724 emit_opcode(cbuf, $secondary); 1725 %} 1726 1727 // Emit tertiary opcode 1728 enc_class OpcT 1729 %{ 1730 emit_opcode(cbuf, $tertiary); 1731 %} 1732 1733 // Emit opcode directly 1734 enc_class Opcode(immI d8) 1735 %{ 1736 emit_opcode(cbuf, $d8$$constant); 1737 %} 1738 1739 // Emit size prefix 1740 enc_class SizePrefix 1741 %{ 1742 emit_opcode(cbuf, 0x66); 1743 %} 1744 1745 enc_class reg(rRegI reg) 1746 %{ 1747 emit_rm(cbuf, 0x3, 0, $reg$$reg & 7); 1748 %} 1749 1750 enc_class reg_reg(rRegI dst, rRegI src) 1751 %{ 1752 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); 1753 %} 1754 1755 enc_class opc_reg_reg(immI opcode, rRegI dst, rRegI src) 1756 %{ 1757 emit_opcode(cbuf, $opcode$$constant); 1758 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); 1759 %} 1760 1761 enc_class cdql_enc(no_rax_rdx_RegI div) 1762 %{ 1763 // Full implementation of Java idiv and irem; checks for 1764 // special case as described in JVM spec., p.243 & p.271. 1765 // 1766 // normal case special case 1767 // 1768 // input : rax: dividend min_int 1769 // reg: divisor -1 1770 // 1771 // output: rax: quotient (= rax idiv reg) min_int 1772 // rdx: remainder (= rax irem reg) 0 1773 // 1774 // Code sequnce: 1775 // 1776 // 0: 3d 00 00 00 80 cmp $0x80000000,%eax 1777 // 5: 75 07/08 jne e <normal> 1778 // 7: 33 d2 xor %edx,%edx 1779 // [div >= 8 -> offset + 1] 1780 // [REX_B] 1781 // 9: 83 f9 ff cmp $0xffffffffffffffff,$div 1782 // c: 74 03/04 je 11 <done> 1783 // 000000000000000e <normal>: 1784 // e: 99 cltd 1785 // [div >= 8 -> offset + 1] 1786 // [REX_B] 1787 // f: f7 f9 idiv $div 1788 // 0000000000000011 <done>: 1789 1790 // cmp $0x80000000,%eax 1791 emit_opcode(cbuf, 0x3d); 1792 emit_d8(cbuf, 0x00); 1793 emit_d8(cbuf, 0x00); 1794 emit_d8(cbuf, 0x00); 1795 emit_d8(cbuf, 0x80); 1796 1797 // jne e <normal> 1798 emit_opcode(cbuf, 0x75); 1799 emit_d8(cbuf, $div$$reg < 8 ? 0x07 : 0x08); 1800 1801 // xor %edx,%edx 1802 emit_opcode(cbuf, 0x33); 1803 emit_d8(cbuf, 0xD2); 1804 1805 // cmp $0xffffffffffffffff,%ecx 1806 if ($div$$reg >= 8) { 1807 emit_opcode(cbuf, Assembler::REX_B); 1808 } 1809 emit_opcode(cbuf, 0x83); 1810 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7); 1811 emit_d8(cbuf, 0xFF); 1812 1813 // je 11 <done> 1814 emit_opcode(cbuf, 0x74); 1815 emit_d8(cbuf, $div$$reg < 8 ? 0x03 : 0x04); 1816 1817 // <normal> 1818 // cltd 1819 emit_opcode(cbuf, 0x99); 1820 1821 // idivl (note: must be emitted by the user of this rule) 1822 // <done> 1823 %} 1824 1825 enc_class cdqq_enc(no_rax_rdx_RegL div) 1826 %{ 1827 // Full implementation of Java ldiv and lrem; checks for 1828 // special case as described in JVM spec., p.243 & p.271. 1829 // 1830 // normal case special case 1831 // 1832 // input : rax: dividend min_long 1833 // reg: divisor -1 1834 // 1835 // output: rax: quotient (= rax idiv reg) min_long 1836 // rdx: remainder (= rax irem reg) 0 1837 // 1838 // Code sequnce: 1839 // 1840 // 0: 48 ba 00 00 00 00 00 mov $0x8000000000000000,%rdx 1841 // 7: 00 00 80 1842 // a: 48 39 d0 cmp %rdx,%rax 1843 // d: 75 08 jne 17 <normal> 1844 // f: 33 d2 xor %edx,%edx 1845 // 11: 48 83 f9 ff cmp $0xffffffffffffffff,$div 1846 // 15: 74 05 je 1c <done> 1847 // 0000000000000017 <normal>: 1848 // 17: 48 99 cqto 1849 // 19: 48 f7 f9 idiv $div 1850 // 000000000000001c <done>: 1851 1852 // mov $0x8000000000000000,%rdx 1853 emit_opcode(cbuf, Assembler::REX_W); 1854 emit_opcode(cbuf, 0xBA); 1855 emit_d8(cbuf, 0x00); 1856 emit_d8(cbuf, 0x00); 1857 emit_d8(cbuf, 0x00); 1858 emit_d8(cbuf, 0x00); 1859 emit_d8(cbuf, 0x00); 1860 emit_d8(cbuf, 0x00); 1861 emit_d8(cbuf, 0x00); 1862 emit_d8(cbuf, 0x80); 1863 1864 // cmp %rdx,%rax 1865 emit_opcode(cbuf, Assembler::REX_W); 1866 emit_opcode(cbuf, 0x39); 1867 emit_d8(cbuf, 0xD0); 1868 1869 // jne 17 <normal> 1870 emit_opcode(cbuf, 0x75); 1871 emit_d8(cbuf, 0x08); 1872 1873 // xor %edx,%edx 1874 emit_opcode(cbuf, 0x33); 1875 emit_d8(cbuf, 0xD2); 1876 1877 // cmp $0xffffffffffffffff,$div 1878 emit_opcode(cbuf, $div$$reg < 8 ? Assembler::REX_W : Assembler::REX_WB); 1879 emit_opcode(cbuf, 0x83); 1880 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7); 1881 emit_d8(cbuf, 0xFF); 1882 1883 // je 1e <done> 1884 emit_opcode(cbuf, 0x74); 1885 emit_d8(cbuf, 0x05); 1886 1887 // <normal> 1888 // cqto 1889 emit_opcode(cbuf, Assembler::REX_W); 1890 emit_opcode(cbuf, 0x99); 1891 1892 // idivq (note: must be emitted by the user of this rule) 1893 // <done> 1894 %} 1895 1896 // Opcde enc_class for 8/32 bit immediate instructions with sign-extension 1897 enc_class OpcSE(immI imm) 1898 %{ 1899 // Emit primary opcode and set sign-extend bit 1900 // Check for 8-bit immediate, and set sign extend bit in opcode 1901 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 1902 emit_opcode(cbuf, $primary | 0x02); 1903 } else { 1904 // 32-bit immediate 1905 emit_opcode(cbuf, $primary); 1906 } 1907 %} 1908 1909 enc_class OpcSErm(rRegI dst, immI imm) 1910 %{ 1911 // OpcSEr/m 1912 int dstenc = $dst$$reg; 1913 if (dstenc >= 8) { 1914 emit_opcode(cbuf, Assembler::REX_B); 1915 dstenc -= 8; 1916 } 1917 // Emit primary opcode and set sign-extend bit 1918 // Check for 8-bit immediate, and set sign extend bit in opcode 1919 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 1920 emit_opcode(cbuf, $primary | 0x02); 1921 } else { 1922 // 32-bit immediate 1923 emit_opcode(cbuf, $primary); 1924 } 1925 // Emit r/m byte with secondary opcode, after primary opcode. 1926 emit_rm(cbuf, 0x3, $secondary, dstenc); 1927 %} 1928 1929 enc_class OpcSErm_wide(rRegL dst, immI imm) 1930 %{ 1931 // OpcSEr/m 1932 int dstenc = $dst$$reg; 1933 if (dstenc < 8) { 1934 emit_opcode(cbuf, Assembler::REX_W); 1935 } else { 1936 emit_opcode(cbuf, Assembler::REX_WB); 1937 dstenc -= 8; 1938 } 1939 // Emit primary opcode and set sign-extend bit 1940 // Check for 8-bit immediate, and set sign extend bit in opcode 1941 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 1942 emit_opcode(cbuf, $primary | 0x02); 1943 } else { 1944 // 32-bit immediate 1945 emit_opcode(cbuf, $primary); 1946 } 1947 // Emit r/m byte with secondary opcode, after primary opcode. 1948 emit_rm(cbuf, 0x3, $secondary, dstenc); 1949 %} 1950 1951 enc_class Con8or32(immI imm) 1952 %{ 1953 // Check for 8-bit immediate, and set sign extend bit in opcode 1954 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 1955 $$$emit8$imm$$constant; 1956 } else { 1957 // 32-bit immediate 1958 $$$emit32$imm$$constant; 1959 } 1960 %} 1961 1962 enc_class opc2_reg(rRegI dst) 1963 %{ 1964 // BSWAP 1965 emit_cc(cbuf, $secondary, $dst$$reg); 1966 %} 1967 1968 enc_class opc3_reg(rRegI dst) 1969 %{ 1970 // BSWAP 1971 emit_cc(cbuf, $tertiary, $dst$$reg); 1972 %} 1973 1974 enc_class reg_opc(rRegI div) 1975 %{ 1976 // INC, DEC, IDIV, IMOD, JMP indirect, ... 1977 emit_rm(cbuf, 0x3, $secondary, $div$$reg & 7); 1978 %} 1979 1980 enc_class enc_cmov(cmpOp cop) 1981 %{ 1982 // CMOV 1983 $$$emit8$primary; 1984 emit_cc(cbuf, $secondary, $cop$$cmpcode); 1985 %} 1986 1987 enc_class enc_PartialSubtypeCheck() 1988 %{ 1989 Register Rrdi = as_Register(RDI_enc); // result register 1990 Register Rrax = as_Register(RAX_enc); // super class 1991 Register Rrcx = as_Register(RCX_enc); // killed 1992 Register Rrsi = as_Register(RSI_enc); // sub class 1993 Label miss; 1994 const bool set_cond_codes = true; 1995 1996 MacroAssembler _masm(&cbuf); 1997 __ check_klass_subtype_slow_path(Rrsi, Rrax, Rrcx, Rrdi, 1998 NULL, &miss, 1999 /*set_cond_codes:*/ true); 2000 if ($primary) { 2001 __ xorptr(Rrdi, Rrdi); 2002 } 2003 __ bind(miss); 2004 %} 2005 2006 enc_class Java_To_Interpreter(method meth) 2007 %{ 2008 // CALL Java_To_Interpreter 2009 // This is the instruction starting address for relocation info. 2010 cbuf.set_insts_mark(); 2011 $$$emit8$primary; 2012 // CALL directly to the runtime 2013 emit_d32_reloc(cbuf, 2014 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2015 runtime_call_Relocation::spec(), 2016 RELOC_DISP32); 2017 %} 2018 2019 enc_class Java_Static_Call(method meth) 2020 %{ 2021 // JAVA STATIC CALL 2022 // CALL to fixup routine. Fixup routine uses ScopeDesc info to 2023 // determine who we intended to call. 2024 cbuf.set_insts_mark(); 2025 $$$emit8$primary; 2026 2027 if (!_method) { 2028 emit_d32_reloc(cbuf, 2029 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2030 runtime_call_Relocation::spec(), 2031 RELOC_DISP32); 2032 } else if (_optimized_virtual) { 2033 emit_d32_reloc(cbuf, 2034 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2035 opt_virtual_call_Relocation::spec(), 2036 RELOC_DISP32); 2037 } else { 2038 emit_d32_reloc(cbuf, 2039 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2040 static_call_Relocation::spec(), 2041 RELOC_DISP32); 2042 } 2043 if (_method) { 2044 // Emit stub for static call 2045 emit_java_to_interp(cbuf); 2046 } 2047 %} 2048 2049 enc_class Java_Dynamic_Call(method meth) %{ 2050 MacroAssembler _masm(&cbuf); 2051 __ ic_call((address)$meth$$method); 2052 %} 2053 2054 enc_class Java_Compiled_Call(method meth) 2055 %{ 2056 // JAVA COMPILED CALL 2057 int disp = in_bytes(Method:: from_compiled_offset()); 2058 2059 // XXX XXX offset is 128 is 1.5 NON-PRODUCT !!! 2060 // assert(-0x80 <= disp && disp < 0x80, "compiled_code_offset isn't small"); 2061 2062 // callq *disp(%rax) 2063 cbuf.set_insts_mark(); 2064 $$$emit8$primary; 2065 if (disp < 0x80) { 2066 emit_rm(cbuf, 0x01, $secondary, RAX_enc); // R/M byte 2067 emit_d8(cbuf, disp); // Displacement 2068 } else { 2069 emit_rm(cbuf, 0x02, $secondary, RAX_enc); // R/M byte 2070 emit_d32(cbuf, disp); // Displacement 2071 } 2072 %} 2073 2074 enc_class reg_opc_imm(rRegI dst, immI8 shift) 2075 %{ 2076 // SAL, SAR, SHR 2077 int dstenc = $dst$$reg; 2078 if (dstenc >= 8) { 2079 emit_opcode(cbuf, Assembler::REX_B); 2080 dstenc -= 8; 2081 } 2082 $$$emit8$primary; 2083 emit_rm(cbuf, 0x3, $secondary, dstenc); 2084 $$$emit8$shift$$constant; 2085 %} 2086 2087 enc_class reg_opc_imm_wide(rRegL dst, immI8 shift) 2088 %{ 2089 // SAL, SAR, SHR 2090 int dstenc = $dst$$reg; 2091 if (dstenc < 8) { 2092 emit_opcode(cbuf, Assembler::REX_W); 2093 } else { 2094 emit_opcode(cbuf, Assembler::REX_WB); 2095 dstenc -= 8; 2096 } 2097 $$$emit8$primary; 2098 emit_rm(cbuf, 0x3, $secondary, dstenc); 2099 $$$emit8$shift$$constant; 2100 %} 2101 2102 enc_class load_immI(rRegI dst, immI src) 2103 %{ 2104 int dstenc = $dst$$reg; 2105 if (dstenc >= 8) { 2106 emit_opcode(cbuf, Assembler::REX_B); 2107 dstenc -= 8; 2108 } 2109 emit_opcode(cbuf, 0xB8 | dstenc); 2110 $$$emit32$src$$constant; 2111 %} 2112 2113 enc_class load_immL(rRegL dst, immL src) 2114 %{ 2115 int dstenc = $dst$$reg; 2116 if (dstenc < 8) { 2117 emit_opcode(cbuf, Assembler::REX_W); 2118 } else { 2119 emit_opcode(cbuf, Assembler::REX_WB); 2120 dstenc -= 8; 2121 } 2122 emit_opcode(cbuf, 0xB8 | dstenc); 2123 emit_d64(cbuf, $src$$constant); 2124 %} 2125 2126 enc_class load_immUL32(rRegL dst, immUL32 src) 2127 %{ 2128 // same as load_immI, but this time we care about zeroes in the high word 2129 int dstenc = $dst$$reg; 2130 if (dstenc >= 8) { 2131 emit_opcode(cbuf, Assembler::REX_B); 2132 dstenc -= 8; 2133 } 2134 emit_opcode(cbuf, 0xB8 | dstenc); 2135 $$$emit32$src$$constant; 2136 %} 2137 2138 enc_class load_immL32(rRegL dst, immL32 src) 2139 %{ 2140 int dstenc = $dst$$reg; 2141 if (dstenc < 8) { 2142 emit_opcode(cbuf, Assembler::REX_W); 2143 } else { 2144 emit_opcode(cbuf, Assembler::REX_WB); 2145 dstenc -= 8; 2146 } 2147 emit_opcode(cbuf, 0xC7); 2148 emit_rm(cbuf, 0x03, 0x00, dstenc); 2149 $$$emit32$src$$constant; 2150 %} 2151 2152 enc_class load_immP31(rRegP dst, immP32 src) 2153 %{ 2154 // same as load_immI, but this time we care about zeroes in the high word 2155 int dstenc = $dst$$reg; 2156 if (dstenc >= 8) { 2157 emit_opcode(cbuf, Assembler::REX_B); 2158 dstenc -= 8; 2159 } 2160 emit_opcode(cbuf, 0xB8 | dstenc); 2161 $$$emit32$src$$constant; 2162 %} 2163 2164 enc_class load_immP(rRegP dst, immP src) 2165 %{ 2166 int dstenc = $dst$$reg; 2167 if (dstenc < 8) { 2168 emit_opcode(cbuf, Assembler::REX_W); 2169 } else { 2170 emit_opcode(cbuf, Assembler::REX_WB); 2171 dstenc -= 8; 2172 } 2173 emit_opcode(cbuf, 0xB8 | dstenc); 2174 // This next line should be generated from ADLC 2175 if ($src->constant_reloc() != relocInfo::none) { 2176 emit_d64_reloc(cbuf, $src$$constant, $src->constant_reloc(), RELOC_IMM64); 2177 } else { 2178 emit_d64(cbuf, $src$$constant); 2179 } 2180 %} 2181 2182 enc_class Con32(immI src) 2183 %{ 2184 // Output immediate 2185 $$$emit32$src$$constant; 2186 %} 2187 2188 enc_class Con64(immL src) 2189 %{ 2190 // Output immediate 2191 emit_d64($src$$constant); 2192 %} 2193 2194 enc_class Con32F_as_bits(immF src) 2195 %{ 2196 // Output Float immediate bits 2197 jfloat jf = $src$$constant; 2198 jint jf_as_bits = jint_cast(jf); 2199 emit_d32(cbuf, jf_as_bits); 2200 %} 2201 2202 enc_class Con16(immI src) 2203 %{ 2204 // Output immediate 2205 $$$emit16$src$$constant; 2206 %} 2207 2208 // How is this different from Con32??? XXX 2209 enc_class Con_d32(immI src) 2210 %{ 2211 emit_d32(cbuf,$src$$constant); 2212 %} 2213 2214 enc_class conmemref (rRegP t1) %{ // Con32(storeImmI) 2215 // Output immediate memory reference 2216 emit_rm(cbuf, 0x00, $t1$$reg, 0x05 ); 2217 emit_d32(cbuf, 0x00); 2218 %} 2219 2220 enc_class lock_prefix() 2221 %{ 2222 if (os::is_MP()) { 2223 emit_opcode(cbuf, 0xF0); // lock 2224 } 2225 %} 2226 2227 enc_class REX_mem(memory mem) 2228 %{ 2229 if ($mem$$base >= 8) { 2230 if ($mem$$index < 8) { 2231 emit_opcode(cbuf, Assembler::REX_B); 2232 } else { 2233 emit_opcode(cbuf, Assembler::REX_XB); 2234 } 2235 } else { 2236 if ($mem$$index >= 8) { 2237 emit_opcode(cbuf, Assembler::REX_X); 2238 } 2239 } 2240 %} 2241 2242 enc_class REX_mem_wide(memory mem) 2243 %{ 2244 if ($mem$$base >= 8) { 2245 if ($mem$$index < 8) { 2246 emit_opcode(cbuf, Assembler::REX_WB); 2247 } else { 2248 emit_opcode(cbuf, Assembler::REX_WXB); 2249 } 2250 } else { 2251 if ($mem$$index < 8) { 2252 emit_opcode(cbuf, Assembler::REX_W); 2253 } else { 2254 emit_opcode(cbuf, Assembler::REX_WX); 2255 } 2256 } 2257 %} 2258 2259 // for byte regs 2260 enc_class REX_breg(rRegI reg) 2261 %{ 2262 if ($reg$$reg >= 4) { 2263 emit_opcode(cbuf, $reg$$reg < 8 ? Assembler::REX : Assembler::REX_B); 2264 } 2265 %} 2266 2267 // for byte regs 2268 enc_class REX_reg_breg(rRegI dst, rRegI src) 2269 %{ 2270 if ($dst$$reg < 8) { 2271 if ($src$$reg >= 4) { 2272 emit_opcode(cbuf, $src$$reg < 8 ? Assembler::REX : Assembler::REX_B); 2273 } 2274 } else { 2275 if ($src$$reg < 8) { 2276 emit_opcode(cbuf, Assembler::REX_R); 2277 } else { 2278 emit_opcode(cbuf, Assembler::REX_RB); 2279 } 2280 } 2281 %} 2282 2283 // for byte regs 2284 enc_class REX_breg_mem(rRegI reg, memory mem) 2285 %{ 2286 if ($reg$$reg < 8) { 2287 if ($mem$$base < 8) { 2288 if ($mem$$index >= 8) { 2289 emit_opcode(cbuf, Assembler::REX_X); 2290 } else if ($reg$$reg >= 4) { 2291 emit_opcode(cbuf, Assembler::REX); 2292 } 2293 } else { 2294 if ($mem$$index < 8) { 2295 emit_opcode(cbuf, Assembler::REX_B); 2296 } else { 2297 emit_opcode(cbuf, Assembler::REX_XB); 2298 } 2299 } 2300 } else { 2301 if ($mem$$base < 8) { 2302 if ($mem$$index < 8) { 2303 emit_opcode(cbuf, Assembler::REX_R); 2304 } else { 2305 emit_opcode(cbuf, Assembler::REX_RX); 2306 } 2307 } else { 2308 if ($mem$$index < 8) { 2309 emit_opcode(cbuf, Assembler::REX_RB); 2310 } else { 2311 emit_opcode(cbuf, Assembler::REX_RXB); 2312 } 2313 } 2314 } 2315 %} 2316 2317 enc_class REX_reg(rRegI reg) 2318 %{ 2319 if ($reg$$reg >= 8) { 2320 emit_opcode(cbuf, Assembler::REX_B); 2321 } 2322 %} 2323 2324 enc_class REX_reg_wide(rRegI reg) 2325 %{ 2326 if ($reg$$reg < 8) { 2327 emit_opcode(cbuf, Assembler::REX_W); 2328 } else { 2329 emit_opcode(cbuf, Assembler::REX_WB); 2330 } 2331 %} 2332 2333 enc_class REX_reg_reg(rRegI dst, rRegI src) 2334 %{ 2335 if ($dst$$reg < 8) { 2336 if ($src$$reg >= 8) { 2337 emit_opcode(cbuf, Assembler::REX_B); 2338 } 2339 } else { 2340 if ($src$$reg < 8) { 2341 emit_opcode(cbuf, Assembler::REX_R); 2342 } else { 2343 emit_opcode(cbuf, Assembler::REX_RB); 2344 } 2345 } 2346 %} 2347 2348 enc_class REX_reg_reg_wide(rRegI dst, rRegI src) 2349 %{ 2350 if ($dst$$reg < 8) { 2351 if ($src$$reg < 8) { 2352 emit_opcode(cbuf, Assembler::REX_W); 2353 } else { 2354 emit_opcode(cbuf, Assembler::REX_WB); 2355 } 2356 } else { 2357 if ($src$$reg < 8) { 2358 emit_opcode(cbuf, Assembler::REX_WR); 2359 } else { 2360 emit_opcode(cbuf, Assembler::REX_WRB); 2361 } 2362 } 2363 %} 2364 2365 enc_class REX_reg_mem(rRegI reg, memory mem) 2366 %{ 2367 if ($reg$$reg < 8) { 2368 if ($mem$$base < 8) { 2369 if ($mem$$index >= 8) { 2370 emit_opcode(cbuf, Assembler::REX_X); 2371 } 2372 } else { 2373 if ($mem$$index < 8) { 2374 emit_opcode(cbuf, Assembler::REX_B); 2375 } else { 2376 emit_opcode(cbuf, Assembler::REX_XB); 2377 } 2378 } 2379 } else { 2380 if ($mem$$base < 8) { 2381 if ($mem$$index < 8) { 2382 emit_opcode(cbuf, Assembler::REX_R); 2383 } else { 2384 emit_opcode(cbuf, Assembler::REX_RX); 2385 } 2386 } else { 2387 if ($mem$$index < 8) { 2388 emit_opcode(cbuf, Assembler::REX_RB); 2389 } else { 2390 emit_opcode(cbuf, Assembler::REX_RXB); 2391 } 2392 } 2393 } 2394 %} 2395 2396 enc_class REX_reg_mem_wide(rRegL reg, memory mem) 2397 %{ 2398 if ($reg$$reg < 8) { 2399 if ($mem$$base < 8) { 2400 if ($mem$$index < 8) { 2401 emit_opcode(cbuf, Assembler::REX_W); 2402 } else { 2403 emit_opcode(cbuf, Assembler::REX_WX); 2404 } 2405 } else { 2406 if ($mem$$index < 8) { 2407 emit_opcode(cbuf, Assembler::REX_WB); 2408 } else { 2409 emit_opcode(cbuf, Assembler::REX_WXB); 2410 } 2411 } 2412 } else { 2413 if ($mem$$base < 8) { 2414 if ($mem$$index < 8) { 2415 emit_opcode(cbuf, Assembler::REX_WR); 2416 } else { 2417 emit_opcode(cbuf, Assembler::REX_WRX); 2418 } 2419 } else { 2420 if ($mem$$index < 8) { 2421 emit_opcode(cbuf, Assembler::REX_WRB); 2422 } else { 2423 emit_opcode(cbuf, Assembler::REX_WRXB); 2424 } 2425 } 2426 } 2427 %} 2428 2429 enc_class reg_mem(rRegI ereg, memory mem) 2430 %{ 2431 // High registers handle in encode_RegMem 2432 int reg = $ereg$$reg; 2433 int base = $mem$$base; 2434 int index = $mem$$index; 2435 int scale = $mem$$scale; 2436 int disp = $mem$$disp; 2437 relocInfo::relocType disp_reloc = $mem->disp_reloc(); 2438 2439 encode_RegMem(cbuf, reg, base, index, scale, disp, disp_reloc); 2440 %} 2441 2442 enc_class RM_opc_mem(immI rm_opcode, memory mem) 2443 %{ 2444 int rm_byte_opcode = $rm_opcode$$constant; 2445 2446 // High registers handle in encode_RegMem 2447 int base = $mem$$base; 2448 int index = $mem$$index; 2449 int scale = $mem$$scale; 2450 int displace = $mem$$disp; 2451 2452 relocInfo::relocType disp_reloc = $mem->disp_reloc(); // disp-as-oop when 2453 // working with static 2454 // globals 2455 encode_RegMem(cbuf, rm_byte_opcode, base, index, scale, displace, 2456 disp_reloc); 2457 %} 2458 2459 enc_class reg_lea(rRegI dst, rRegI src0, immI src1) 2460 %{ 2461 int reg_encoding = $dst$$reg; 2462 int base = $src0$$reg; // 0xFFFFFFFF indicates no base 2463 int index = 0x04; // 0x04 indicates no index 2464 int scale = 0x00; // 0x00 indicates no scale 2465 int displace = $src1$$constant; // 0x00 indicates no displacement 2466 relocInfo::relocType disp_reloc = relocInfo::none; 2467 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, 2468 disp_reloc); 2469 %} 2470 2471 enc_class neg_reg(rRegI dst) 2472 %{ 2473 int dstenc = $dst$$reg; 2474 if (dstenc >= 8) { 2475 emit_opcode(cbuf, Assembler::REX_B); 2476 dstenc -= 8; 2477 } 2478 // NEG $dst 2479 emit_opcode(cbuf, 0xF7); 2480 emit_rm(cbuf, 0x3, 0x03, dstenc); 2481 %} 2482 2483 enc_class neg_reg_wide(rRegI dst) 2484 %{ 2485 int dstenc = $dst$$reg; 2486 if (dstenc < 8) { 2487 emit_opcode(cbuf, Assembler::REX_W); 2488 } else { 2489 emit_opcode(cbuf, Assembler::REX_WB); 2490 dstenc -= 8; 2491 } 2492 // NEG $dst 2493 emit_opcode(cbuf, 0xF7); 2494 emit_rm(cbuf, 0x3, 0x03, dstenc); 2495 %} 2496 2497 enc_class setLT_reg(rRegI dst) 2498 %{ 2499 int dstenc = $dst$$reg; 2500 if (dstenc >= 8) { 2501 emit_opcode(cbuf, Assembler::REX_B); 2502 dstenc -= 8; 2503 } else if (dstenc >= 4) { 2504 emit_opcode(cbuf, Assembler::REX); 2505 } 2506 // SETLT $dst 2507 emit_opcode(cbuf, 0x0F); 2508 emit_opcode(cbuf, 0x9C); 2509 emit_rm(cbuf, 0x3, 0x0, dstenc); 2510 %} 2511 2512 enc_class setNZ_reg(rRegI dst) 2513 %{ 2514 int dstenc = $dst$$reg; 2515 if (dstenc >= 8) { 2516 emit_opcode(cbuf, Assembler::REX_B); 2517 dstenc -= 8; 2518 } else if (dstenc >= 4) { 2519 emit_opcode(cbuf, Assembler::REX); 2520 } 2521 // SETNZ $dst 2522 emit_opcode(cbuf, 0x0F); 2523 emit_opcode(cbuf, 0x95); 2524 emit_rm(cbuf, 0x3, 0x0, dstenc); 2525 %} 2526 2527 2528 // Compare the lonogs and set -1, 0, or 1 into dst 2529 enc_class cmpl3_flag(rRegL src1, rRegL src2, rRegI dst) 2530 %{ 2531 int src1enc = $src1$$reg; 2532 int src2enc = $src2$$reg; 2533 int dstenc = $dst$$reg; 2534 2535 // cmpq $src1, $src2 2536 if (src1enc < 8) { 2537 if (src2enc < 8) { 2538 emit_opcode(cbuf, Assembler::REX_W); 2539 } else { 2540 emit_opcode(cbuf, Assembler::REX_WB); 2541 } 2542 } else { 2543 if (src2enc < 8) { 2544 emit_opcode(cbuf, Assembler::REX_WR); 2545 } else { 2546 emit_opcode(cbuf, Assembler::REX_WRB); 2547 } 2548 } 2549 emit_opcode(cbuf, 0x3B); 2550 emit_rm(cbuf, 0x3, src1enc & 7, src2enc & 7); 2551 2552 // movl $dst, -1 2553 if (dstenc >= 8) { 2554 emit_opcode(cbuf, Assembler::REX_B); 2555 } 2556 emit_opcode(cbuf, 0xB8 | (dstenc & 7)); 2557 emit_d32(cbuf, -1); 2558 2559 // jl,s done 2560 emit_opcode(cbuf, 0x7C); 2561 emit_d8(cbuf, dstenc < 4 ? 0x06 : 0x08); 2562 2563 // setne $dst 2564 if (dstenc >= 4) { 2565 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_B); 2566 } 2567 emit_opcode(cbuf, 0x0F); 2568 emit_opcode(cbuf, 0x95); 2569 emit_opcode(cbuf, 0xC0 | (dstenc & 7)); 2570 2571 // movzbl $dst, $dst 2572 if (dstenc >= 4) { 2573 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_RB); 2574 } 2575 emit_opcode(cbuf, 0x0F); 2576 emit_opcode(cbuf, 0xB6); 2577 emit_rm(cbuf, 0x3, dstenc & 7, dstenc & 7); 2578 %} 2579 2580 enc_class Push_ResultXD(regD dst) %{ 2581 MacroAssembler _masm(&cbuf); 2582 __ fstp_d(Address(rsp, 0)); 2583 __ movdbl($dst$$XMMRegister, Address(rsp, 0)); 2584 __ addptr(rsp, 8); 2585 %} 2586 2587 enc_class Push_SrcXD(regD src) %{ 2588 MacroAssembler _masm(&cbuf); 2589 __ subptr(rsp, 8); 2590 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 2591 __ fld_d(Address(rsp, 0)); 2592 %} 2593 2594 2595 // obj: object to lock 2596 // box: box address (header location) -- killed 2597 // tmp: rax -- killed 2598 // scr: rbx -- killed 2599 // 2600 // What follows is a direct transliteration of fast_lock() and fast_unlock() 2601 // from i486.ad. See that file for comments. 2602 // TODO: where possible switch from movq (r, 0) to movl(r,0) and 2603 // use the shorter encoding. (Movl clears the high-order 32-bits). 2604 2605 2606 enc_class Fast_Lock(rRegP obj, rRegP box, rax_RegI tmp, rRegP scr) 2607 %{ 2608 Register objReg = as_Register((int)$obj$$reg); 2609 Register boxReg = as_Register((int)$box$$reg); 2610 Register tmpReg = as_Register($tmp$$reg); 2611 Register scrReg = as_Register($scr$$reg); 2612 MacroAssembler masm(&cbuf); 2613 2614 // Verify uniqueness of register assignments -- necessary but not sufficient 2615 assert (objReg != boxReg && objReg != tmpReg && 2616 objReg != scrReg && tmpReg != scrReg, "invariant") ; 2617 2618 if (_counters != NULL) { 2619 masm.atomic_incl(ExternalAddress((address) _counters->total_entry_count_addr())); 2620 } 2621 if (EmitSync & 1) { 2622 // Without cast to int32_t a movptr will destroy r10 which is typically obj 2623 masm.movptr (Address(boxReg, 0), (int32_t)intptr_t(markOopDesc::unused_mark())) ; 2624 masm.cmpptr(rsp, (int32_t)NULL_WORD) ; 2625 } else 2626 if (EmitSync & 2) { 2627 Label DONE_LABEL; 2628 if (UseBiasedLocking) { 2629 // Note: tmpReg maps to the swap_reg argument and scrReg to the tmp_reg argument. 2630 masm.biased_locking_enter(boxReg, objReg, tmpReg, scrReg, false, DONE_LABEL, NULL, _counters); 2631 } 2632 // QQQ was movl... 2633 masm.movptr(tmpReg, 0x1); 2634 masm.orptr(tmpReg, Address(objReg, 0)); 2635 masm.movptr(Address(boxReg, 0), tmpReg); 2636 if (os::is_MP()) { 2637 masm.lock(); 2638 } 2639 masm.cmpxchgptr(boxReg, Address(objReg, 0)); // Updates tmpReg 2640 masm.jcc(Assembler::equal, DONE_LABEL); 2641 2642 // Recursive locking 2643 masm.subptr(tmpReg, rsp); 2644 masm.andptr(tmpReg, 7 - os::vm_page_size()); 2645 masm.movptr(Address(boxReg, 0), tmpReg); 2646 2647 masm.bind(DONE_LABEL); 2648 masm.nop(); // avoid branch to branch 2649 } else { 2650 Label DONE_LABEL, IsInflated, Egress; 2651 2652 masm.movptr(tmpReg, Address(objReg, 0)) ; 2653 masm.testl (tmpReg, 0x02) ; // inflated vs stack-locked|neutral|biased 2654 masm.jcc (Assembler::notZero, IsInflated) ; 2655 2656 // it's stack-locked, biased or neutral 2657 // TODO: optimize markword triage order to reduce the number of 2658 // conditional branches in the most common cases. 2659 // Beware -- there's a subtle invariant that fetch of the markword 2660 // at [FETCH], below, will never observe a biased encoding (*101b). 2661 // If this invariant is not held we'll suffer exclusion (safety) failure. 2662 2663 if (UseBiasedLocking && !UseOptoBiasInlining) { 2664 masm.biased_locking_enter(boxReg, objReg, tmpReg, scrReg, true, DONE_LABEL, NULL, _counters); 2665 masm.movptr(tmpReg, Address(objReg, 0)) ; // [FETCH] 2666 } 2667 2668 // was q will it destroy high? 2669 masm.orl (tmpReg, 1) ; 2670 masm.movptr(Address(boxReg, 0), tmpReg) ; 2671 if (os::is_MP()) { masm.lock(); } 2672 masm.cmpxchgptr(boxReg, Address(objReg, 0)); // Updates tmpReg 2673 if (_counters != NULL) { 2674 masm.cond_inc32(Assembler::equal, 2675 ExternalAddress((address) _counters->fast_path_entry_count_addr())); 2676 } 2677 masm.jcc (Assembler::equal, DONE_LABEL); 2678 2679 // Recursive locking 2680 masm.subptr(tmpReg, rsp); 2681 masm.andptr(tmpReg, 7 - os::vm_page_size()); 2682 masm.movptr(Address(boxReg, 0), tmpReg); 2683 if (_counters != NULL) { 2684 masm.cond_inc32(Assembler::equal, 2685 ExternalAddress((address) _counters->fast_path_entry_count_addr())); 2686 } 2687 masm.jmp (DONE_LABEL) ; 2688 2689 masm.bind (IsInflated) ; 2690 // It's inflated 2691 2692 // TODO: someday avoid the ST-before-CAS penalty by 2693 // relocating (deferring) the following ST. 2694 // We should also think about trying a CAS without having 2695 // fetched _owner. If the CAS is successful we may 2696 // avoid an RTO->RTS upgrade on the $line. 2697 // Without cast to int32_t a movptr will destroy r10 which is typically obj 2698 masm.movptr(Address(boxReg, 0), (int32_t)intptr_t(markOopDesc::unused_mark())) ; 2699 2700 masm.mov (boxReg, tmpReg) ; 2701 masm.movptr (tmpReg, Address(tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; 2702 masm.testptr(tmpReg, tmpReg) ; 2703 masm.jcc (Assembler::notZero, DONE_LABEL) ; 2704 2705 // It's inflated and appears unlocked 2706 if (os::is_MP()) { masm.lock(); } 2707 masm.cmpxchgptr(r15_thread, Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; 2708 // Intentional fall-through into DONE_LABEL ... 2709 2710 masm.bind (DONE_LABEL) ; 2711 masm.nop () ; // avoid jmp to jmp 2712 } 2713 %} 2714 2715 // obj: object to unlock 2716 // box: box address (displaced header location), killed 2717 // RBX: killed tmp; cannot be obj nor box 2718 enc_class Fast_Unlock(rRegP obj, rax_RegP box, rRegP tmp) 2719 %{ 2720 2721 Register objReg = as_Register($obj$$reg); 2722 Register boxReg = as_Register($box$$reg); 2723 Register tmpReg = as_Register($tmp$$reg); 2724 MacroAssembler masm(&cbuf); 2725 2726 if (EmitSync & 4) { 2727 masm.cmpptr(rsp, 0) ; 2728 } else 2729 if (EmitSync & 8) { 2730 Label DONE_LABEL; 2731 if (UseBiasedLocking) { 2732 masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL); 2733 } 2734 2735 // Check whether the displaced header is 0 2736 //(=> recursive unlock) 2737 masm.movptr(tmpReg, Address(boxReg, 0)); 2738 masm.testptr(tmpReg, tmpReg); 2739 masm.jcc(Assembler::zero, DONE_LABEL); 2740 2741 // If not recursive lock, reset the header to displaced header 2742 if (os::is_MP()) { 2743 masm.lock(); 2744 } 2745 masm.cmpxchgptr(tmpReg, Address(objReg, 0)); // Uses RAX which is box 2746 masm.bind(DONE_LABEL); 2747 masm.nop(); // avoid branch to branch 2748 } else { 2749 Label DONE_LABEL, Stacked, CheckSucc ; 2750 2751 if (UseBiasedLocking && !UseOptoBiasInlining) { 2752 masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL); 2753 } 2754 2755 masm.movptr(tmpReg, Address(objReg, 0)) ; 2756 masm.cmpptr(Address(boxReg, 0), (int32_t)NULL_WORD) ; 2757 masm.jcc (Assembler::zero, DONE_LABEL) ; 2758 masm.testl (tmpReg, 0x02) ; 2759 masm.jcc (Assembler::zero, Stacked) ; 2760 2761 // It's inflated 2762 masm.movptr(boxReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; 2763 masm.xorptr(boxReg, r15_thread) ; 2764 masm.orptr (boxReg, Address (tmpReg, ObjectMonitor::recursions_offset_in_bytes()-2)) ; 2765 masm.jcc (Assembler::notZero, DONE_LABEL) ; 2766 masm.movptr(boxReg, Address (tmpReg, ObjectMonitor::cxq_offset_in_bytes()-2)) ; 2767 masm.orptr (boxReg, Address (tmpReg, ObjectMonitor::EntryList_offset_in_bytes()-2)) ; 2768 masm.jcc (Assembler::notZero, CheckSucc) ; 2769 masm.movptr(Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), (int32_t)NULL_WORD) ; 2770 masm.jmp (DONE_LABEL) ; 2771 2772 if ((EmitSync & 65536) == 0) { 2773 Label LSuccess, LGoSlowPath ; 2774 masm.bind (CheckSucc) ; 2775 masm.cmpptr(Address (tmpReg, ObjectMonitor::succ_offset_in_bytes()-2), (int32_t)NULL_WORD) ; 2776 masm.jcc (Assembler::zero, LGoSlowPath) ; 2777 2778 // I'd much rather use lock:andl m->_owner, 0 as it's faster than the 2779 // the explicit ST;MEMBAR combination, but masm doesn't currently support 2780 // "ANDQ M,IMM". Don't use MFENCE here. lock:add to TOS, xchg, etc 2781 // are all faster when the write buffer is populated. 2782 masm.movptr (Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), (int32_t)NULL_WORD) ; 2783 if (os::is_MP()) { 2784 masm.lock () ; masm.addl (Address(rsp, 0), 0) ; 2785 } 2786 masm.cmpptr(Address (tmpReg, ObjectMonitor::succ_offset_in_bytes()-2), (int32_t)NULL_WORD) ; 2787 masm.jcc (Assembler::notZero, LSuccess) ; 2788 2789 masm.movptr (boxReg, (int32_t)NULL_WORD) ; // box is really EAX 2790 if (os::is_MP()) { masm.lock(); } 2791 masm.cmpxchgptr(r15_thread, Address(tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)); 2792 masm.jcc (Assembler::notEqual, LSuccess) ; 2793 // Intentional fall-through into slow-path 2794 2795 masm.bind (LGoSlowPath) ; 2796 masm.orl (boxReg, 1) ; // set ICC.ZF=0 to indicate failure 2797 masm.jmp (DONE_LABEL) ; 2798 2799 masm.bind (LSuccess) ; 2800 masm.testl (boxReg, 0) ; // set ICC.ZF=1 to indicate success 2801 masm.jmp (DONE_LABEL) ; 2802 } 2803 2804 masm.bind (Stacked) ; 2805 masm.movptr(tmpReg, Address (boxReg, 0)) ; // re-fetch 2806 if (os::is_MP()) { masm.lock(); } 2807 masm.cmpxchgptr(tmpReg, Address(objReg, 0)); // Uses RAX which is box 2808 2809 if (EmitSync & 65536) { 2810 masm.bind (CheckSucc) ; 2811 } 2812 masm.bind(DONE_LABEL); 2813 if (EmitSync & 32768) { 2814 masm.nop(); // avoid branch to branch 2815 } 2816 } 2817 %} 2818 2819 2820 enc_class enc_rethrow() 2821 %{ 2822 cbuf.set_insts_mark(); 2823 emit_opcode(cbuf, 0xE9); // jmp entry 2824 emit_d32_reloc(cbuf, 2825 (int) (OptoRuntime::rethrow_stub() - cbuf.insts_end() - 4), 2826 runtime_call_Relocation::spec(), 2827 RELOC_DISP32); 2828 %} 2829 2830%} 2831 2832 2833 2834//----------FRAME-------------------------------------------------------------- 2835// Definition of frame structure and management information. 2836// 2837// S T A C K L A Y O U T Allocators stack-slot number 2838// | (to get allocators register number 2839// G Owned by | | v add OptoReg::stack0()) 2840// r CALLER | | 2841// o | +--------+ pad to even-align allocators stack-slot 2842// w V | pad0 | numbers; owned by CALLER 2843// t -----------+--------+----> Matcher::_in_arg_limit, unaligned 2844// h ^ | in | 5 2845// | | args | 4 Holes in incoming args owned by SELF 2846// | | | | 3 2847// | | +--------+ 2848// V | | old out| Empty on Intel, window on Sparc 2849// | old |preserve| Must be even aligned. 2850// | SP-+--------+----> Matcher::_old_SP, even aligned 2851// | | in | 3 area for Intel ret address 2852// Owned by |preserve| Empty on Sparc. 2853// SELF +--------+ 2854// | | pad2 | 2 pad to align old SP 2855// | +--------+ 1 2856// | | locks | 0 2857// | +--------+----> OptoReg::stack0(), even aligned 2858// | | pad1 | 11 pad to align new SP 2859// | +--------+ 2860// | | | 10 2861// | | spills | 9 spills 2862// V | | 8 (pad0 slot for callee) 2863// -----------+--------+----> Matcher::_out_arg_limit, unaligned 2864// ^ | out | 7 2865// | | args | 6 Holes in outgoing args owned by CALLEE 2866// Owned by +--------+ 2867// CALLEE | new out| 6 Empty on Intel, window on Sparc 2868// | new |preserve| Must be even-aligned. 2869// | SP-+--------+----> Matcher::_new_SP, even aligned 2870// | | | 2871// 2872// Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 2873// known from SELF's arguments and the Java calling convention. 2874// Region 6-7 is determined per call site. 2875// Note 2: If the calling convention leaves holes in the incoming argument 2876// area, those holes are owned by SELF. Holes in the outgoing area 2877// are owned by the CALLEE. Holes should not be nessecary in the 2878// incoming area, as the Java calling convention is completely under 2879// the control of the AD file. Doubles can be sorted and packed to 2880// avoid holes. Holes in the outgoing arguments may be nessecary for 2881// varargs C calling conventions. 2882// Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 2883// even aligned with pad0 as needed. 2884// Region 6 is even aligned. Region 6-7 is NOT even aligned; 2885// region 6-11 is even aligned; it may be padded out more so that 2886// the region from SP to FP meets the minimum stack alignment. 2887// Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 2888// alignment. Region 11, pad1, may be dynamically extended so that 2889// SP meets the minimum alignment. 2890 2891frame 2892%{ 2893 // What direction does stack grow in (assumed to be same for C & Java) 2894 stack_direction(TOWARDS_LOW); 2895 2896 // These three registers define part of the calling convention 2897 // between compiled code and the interpreter. 2898 inline_cache_reg(RAX); // Inline Cache Register 2899 interpreter_method_oop_reg(RBX); // Method Oop Register when 2900 // calling interpreter 2901 2902 // Optional: name the operand used by cisc-spilling to access 2903 // [stack_pointer + offset] 2904 cisc_spilling_operand_name(indOffset32); 2905 2906 // Number of stack slots consumed by locking an object 2907 sync_stack_slots(2); 2908 2909 // Compiled code's Frame Pointer 2910 frame_pointer(RSP); 2911 2912 // Interpreter stores its frame pointer in a register which is 2913 // stored to the stack by I2CAdaptors. 2914 // I2CAdaptors convert from interpreted java to compiled java. 2915 interpreter_frame_pointer(RBP); 2916 2917 // Stack alignment requirement 2918 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 2919 2920 // Number of stack slots between incoming argument block and the start of 2921 // a new frame. The PROLOG must add this many slots to the stack. The 2922 // EPILOG must remove this many slots. amd64 needs two slots for 2923 // return address. 2924 in_preserve_stack_slots(4 + 2 * VerifyStackAtCalls); 2925 2926 // Number of outgoing stack slots killed above the out_preserve_stack_slots 2927 // for calls to C. Supports the var-args backing area for register parms. 2928 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 2929 2930 // The after-PROLOG location of the return address. Location of 2931 // return address specifies a type (REG or STACK) and a number 2932 // representing the register number (i.e. - use a register name) or 2933 // stack slot. 2934 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 2935 // Otherwise, it is above the locks and verification slot and alignment word 2936 return_addr(STACK - 2 + 2937 round_to((Compile::current()->in_preserve_stack_slots() + 2938 Compile::current()->fixed_slots()), 2939 stack_alignment_in_slots())); 2940 2941 // Body of function which returns an integer array locating 2942 // arguments either in registers or in stack slots. Passed an array 2943 // of ideal registers called "sig" and a "length" count. Stack-slot 2944 // offsets are based on outgoing arguments, i.e. a CALLER setting up 2945 // arguments for a CALLEE. Incoming stack arguments are 2946 // automatically biased by the preserve_stack_slots field above. 2947 2948 calling_convention 2949 %{ 2950 // No difference between ingoing/outgoing just pass false 2951 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 2952 %} 2953 2954 c_calling_convention 2955 %{ 2956 // This is obviously always outgoing 2957 (void) SharedRuntime::c_calling_convention(sig_bt, regs, length); 2958 %} 2959 2960 // Location of compiled Java return values. Same as C for now. 2961 return_value 2962 %{ 2963 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 2964 "only return normal values"); 2965 2966 static const int lo[Op_RegL + 1] = { 2967 0, 2968 0, 2969 RAX_num, // Op_RegN 2970 RAX_num, // Op_RegI 2971 RAX_num, // Op_RegP 2972 XMM0_num, // Op_RegF 2973 XMM0_num, // Op_RegD 2974 RAX_num // Op_RegL 2975 }; 2976 static const int hi[Op_RegL + 1] = { 2977 0, 2978 0, 2979 OptoReg::Bad, // Op_RegN 2980 OptoReg::Bad, // Op_RegI 2981 RAX_H_num, // Op_RegP 2982 OptoReg::Bad, // Op_RegF 2983 XMM0b_num, // Op_RegD 2984 RAX_H_num // Op_RegL 2985 }; 2986 // Excluded flags and vector registers. 2987 assert(ARRAY_SIZE(hi) == _last_machine_leaf - 5, "missing type"); 2988 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 2989 %} 2990%} 2991 2992//----------ATTRIBUTES--------------------------------------------------------- 2993//----------Operand Attributes------------------------------------------------- 2994op_attrib op_cost(0); // Required cost attribute 2995 2996//----------Instruction Attributes--------------------------------------------- 2997ins_attrib ins_cost(100); // Required cost attribute 2998ins_attrib ins_size(8); // Required size attribute (in bits) 2999ins_attrib ins_short_branch(0); // Required flag: is this instruction 3000 // a non-matching short branch variant 3001 // of some long branch? 3002ins_attrib ins_alignment(1); // Required alignment attribute (must 3003 // be a power of 2) specifies the 3004 // alignment that some part of the 3005 // instruction (not necessarily the 3006 // start) requires. If > 1, a 3007 // compute_padding() function must be 3008 // provided for the instruction 3009 3010//----------OPERANDS----------------------------------------------------------- 3011// Operand definitions must precede instruction definitions for correct parsing 3012// in the ADLC because operands constitute user defined types which are used in 3013// instruction definitions. 3014 3015//----------Simple Operands---------------------------------------------------- 3016// Immediate Operands 3017// Integer Immediate 3018operand immI() 3019%{ 3020 match(ConI); 3021 3022 op_cost(10); 3023 format %{ %} 3024 interface(CONST_INTER); 3025%} 3026 3027// Constant for test vs zero 3028operand immI0() 3029%{ 3030 predicate(n->get_int() == 0); 3031 match(ConI); 3032 3033 op_cost(0); 3034 format %{ %} 3035 interface(CONST_INTER); 3036%} 3037 3038// Constant for increment 3039operand immI1() 3040%{ 3041 predicate(n->get_int() == 1); 3042 match(ConI); 3043 3044 op_cost(0); 3045 format %{ %} 3046 interface(CONST_INTER); 3047%} 3048 3049// Constant for decrement 3050operand immI_M1() 3051%{ 3052 predicate(n->get_int() == -1); 3053 match(ConI); 3054 3055 op_cost(0); 3056 format %{ %} 3057 interface(CONST_INTER); 3058%} 3059 3060// Valid scale values for addressing modes 3061operand immI2() 3062%{ 3063 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 3064 match(ConI); 3065 3066 format %{ %} 3067 interface(CONST_INTER); 3068%} 3069 3070operand immI8() 3071%{ 3072 predicate((-0x80 <= n->get_int()) && (n->get_int() < 0x80)); 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// Constant for long shifts 3091operand immI_32() 3092%{ 3093 predicate( n->get_int() == 32 ); 3094 match(ConI); 3095 3096 op_cost(0); 3097 format %{ %} 3098 interface(CONST_INTER); 3099%} 3100 3101// Constant for long shifts 3102operand immI_64() 3103%{ 3104 predicate( n->get_int() == 64 ); 3105 match(ConI); 3106 3107 op_cost(0); 3108 format %{ %} 3109 interface(CONST_INTER); 3110%} 3111 3112// Pointer Immediate 3113operand immP() 3114%{ 3115 match(ConP); 3116 3117 op_cost(10); 3118 format %{ %} 3119 interface(CONST_INTER); 3120%} 3121 3122// NULL Pointer Immediate 3123operand immP0() 3124%{ 3125 predicate(n->get_ptr() == 0); 3126 match(ConP); 3127 3128 op_cost(5); 3129 format %{ %} 3130 interface(CONST_INTER); 3131%} 3132 3133// Pointer Immediate 3134operand immN() %{ 3135 match(ConN); 3136 3137 op_cost(10); 3138 format %{ %} 3139 interface(CONST_INTER); 3140%} 3141 3142// NULL Pointer Immediate 3143operand immN0() %{ 3144 predicate(n->get_narrowcon() == 0); 3145 match(ConN); 3146 3147 op_cost(5); 3148 format %{ %} 3149 interface(CONST_INTER); 3150%} 3151 3152operand immP31() 3153%{ 3154 predicate(n->as_Type()->type()->reloc() == relocInfo::none 3155 && (n->get_ptr() >> 31) == 0); 3156 match(ConP); 3157 3158 op_cost(5); 3159 format %{ %} 3160 interface(CONST_INTER); 3161%} 3162 3163 3164// Long Immediate 3165operand immL() 3166%{ 3167 match(ConL); 3168 3169 op_cost(20); 3170 format %{ %} 3171 interface(CONST_INTER); 3172%} 3173 3174// Long Immediate 8-bit 3175operand immL8() 3176%{ 3177 predicate(-0x80L <= n->get_long() && n->get_long() < 0x80L); 3178 match(ConL); 3179 3180 op_cost(5); 3181 format %{ %} 3182 interface(CONST_INTER); 3183%} 3184 3185// Long Immediate 32-bit unsigned 3186operand immUL32() 3187%{ 3188 predicate(n->get_long() == (unsigned int) (n->get_long())); 3189 match(ConL); 3190 3191 op_cost(10); 3192 format %{ %} 3193 interface(CONST_INTER); 3194%} 3195 3196// Long Immediate 32-bit signed 3197operand immL32() 3198%{ 3199 predicate(n->get_long() == (int) (n->get_long())); 3200 match(ConL); 3201 3202 op_cost(15); 3203 format %{ %} 3204 interface(CONST_INTER); 3205%} 3206 3207// Long Immediate zero 3208operand immL0() 3209%{ 3210 predicate(n->get_long() == 0L); 3211 match(ConL); 3212 3213 op_cost(10); 3214 format %{ %} 3215 interface(CONST_INTER); 3216%} 3217 3218// Constant for increment 3219operand immL1() 3220%{ 3221 predicate(n->get_long() == 1); 3222 match(ConL); 3223 3224 format %{ %} 3225 interface(CONST_INTER); 3226%} 3227 3228// Constant for decrement 3229operand immL_M1() 3230%{ 3231 predicate(n->get_long() == -1); 3232 match(ConL); 3233 3234 format %{ %} 3235 interface(CONST_INTER); 3236%} 3237 3238// Long Immediate: the value 10 3239operand immL10() 3240%{ 3241 predicate(n->get_long() == 10); 3242 match(ConL); 3243 3244 format %{ %} 3245 interface(CONST_INTER); 3246%} 3247 3248// Long immediate from 0 to 127. 3249// Used for a shorter form of long mul by 10. 3250operand immL_127() 3251%{ 3252 predicate(0 <= n->get_long() && n->get_long() < 0x80); 3253 match(ConL); 3254 3255 op_cost(10); 3256 format %{ %} 3257 interface(CONST_INTER); 3258%} 3259 3260// Long Immediate: low 32-bit mask 3261operand immL_32bits() 3262%{ 3263 predicate(n->get_long() == 0xFFFFFFFFL); 3264 match(ConL); 3265 op_cost(20); 3266 3267 format %{ %} 3268 interface(CONST_INTER); 3269%} 3270 3271// Float Immediate zero 3272operand immF0() 3273%{ 3274 predicate(jint_cast(n->getf()) == 0); 3275 match(ConF); 3276 3277 op_cost(5); 3278 format %{ %} 3279 interface(CONST_INTER); 3280%} 3281 3282// Float Immediate 3283operand immF() 3284%{ 3285 match(ConF); 3286 3287 op_cost(15); 3288 format %{ %} 3289 interface(CONST_INTER); 3290%} 3291 3292// Double Immediate zero 3293operand immD0() 3294%{ 3295 predicate(jlong_cast(n->getd()) == 0); 3296 match(ConD); 3297 3298 op_cost(5); 3299 format %{ %} 3300 interface(CONST_INTER); 3301%} 3302 3303// Double Immediate 3304operand immD() 3305%{ 3306 match(ConD); 3307 3308 op_cost(15); 3309 format %{ %} 3310 interface(CONST_INTER); 3311%} 3312 3313// Immediates for special shifts (sign extend) 3314 3315// Constants for increment 3316operand immI_16() 3317%{ 3318 predicate(n->get_int() == 16); 3319 match(ConI); 3320 3321 format %{ %} 3322 interface(CONST_INTER); 3323%} 3324 3325operand immI_24() 3326%{ 3327 predicate(n->get_int() == 24); 3328 match(ConI); 3329 3330 format %{ %} 3331 interface(CONST_INTER); 3332%} 3333 3334// Constant for byte-wide masking 3335operand immI_255() 3336%{ 3337 predicate(n->get_int() == 255); 3338 match(ConI); 3339 3340 format %{ %} 3341 interface(CONST_INTER); 3342%} 3343 3344// Constant for short-wide masking 3345operand immI_65535() 3346%{ 3347 predicate(n->get_int() == 65535); 3348 match(ConI); 3349 3350 format %{ %} 3351 interface(CONST_INTER); 3352%} 3353 3354// Constant for byte-wide masking 3355operand immL_255() 3356%{ 3357 predicate(n->get_long() == 255); 3358 match(ConL); 3359 3360 format %{ %} 3361 interface(CONST_INTER); 3362%} 3363 3364// Constant for short-wide masking 3365operand immL_65535() 3366%{ 3367 predicate(n->get_long() == 65535); 3368 match(ConL); 3369 3370 format %{ %} 3371 interface(CONST_INTER); 3372%} 3373 3374// Register Operands 3375// Integer Register 3376operand rRegI() 3377%{ 3378 constraint(ALLOC_IN_RC(int_reg)); 3379 match(RegI); 3380 3381 match(rax_RegI); 3382 match(rbx_RegI); 3383 match(rcx_RegI); 3384 match(rdx_RegI); 3385 match(rdi_RegI); 3386 3387 format %{ %} 3388 interface(REG_INTER); 3389%} 3390 3391// Special Registers 3392operand rax_RegI() 3393%{ 3394 constraint(ALLOC_IN_RC(int_rax_reg)); 3395 match(RegI); 3396 match(rRegI); 3397 3398 format %{ "RAX" %} 3399 interface(REG_INTER); 3400%} 3401 3402// Special Registers 3403operand rbx_RegI() 3404%{ 3405 constraint(ALLOC_IN_RC(int_rbx_reg)); 3406 match(RegI); 3407 match(rRegI); 3408 3409 format %{ "RBX" %} 3410 interface(REG_INTER); 3411%} 3412 3413operand rcx_RegI() 3414%{ 3415 constraint(ALLOC_IN_RC(int_rcx_reg)); 3416 match(RegI); 3417 match(rRegI); 3418 3419 format %{ "RCX" %} 3420 interface(REG_INTER); 3421%} 3422 3423operand rdx_RegI() 3424%{ 3425 constraint(ALLOC_IN_RC(int_rdx_reg)); 3426 match(RegI); 3427 match(rRegI); 3428 3429 format %{ "RDX" %} 3430 interface(REG_INTER); 3431%} 3432 3433operand rdi_RegI() 3434%{ 3435 constraint(ALLOC_IN_RC(int_rdi_reg)); 3436 match(RegI); 3437 match(rRegI); 3438 3439 format %{ "RDI" %} 3440 interface(REG_INTER); 3441%} 3442 3443operand no_rcx_RegI() 3444%{ 3445 constraint(ALLOC_IN_RC(int_no_rcx_reg)); 3446 match(RegI); 3447 match(rax_RegI); 3448 match(rbx_RegI); 3449 match(rdx_RegI); 3450 match(rdi_RegI); 3451 3452 format %{ %} 3453 interface(REG_INTER); 3454%} 3455 3456operand no_rax_rdx_RegI() 3457%{ 3458 constraint(ALLOC_IN_RC(int_no_rax_rdx_reg)); 3459 match(RegI); 3460 match(rbx_RegI); 3461 match(rcx_RegI); 3462 match(rdi_RegI); 3463 3464 format %{ %} 3465 interface(REG_INTER); 3466%} 3467 3468// Pointer Register 3469operand any_RegP() 3470%{ 3471 constraint(ALLOC_IN_RC(any_reg)); 3472 match(RegP); 3473 match(rax_RegP); 3474 match(rbx_RegP); 3475 match(rdi_RegP); 3476 match(rsi_RegP); 3477 match(rbp_RegP); 3478 match(r15_RegP); 3479 match(rRegP); 3480 3481 format %{ %} 3482 interface(REG_INTER); 3483%} 3484 3485operand rRegP() 3486%{ 3487 constraint(ALLOC_IN_RC(ptr_reg)); 3488 match(RegP); 3489 match(rax_RegP); 3490 match(rbx_RegP); 3491 match(rdi_RegP); 3492 match(rsi_RegP); 3493 match(rbp_RegP); 3494 match(r15_RegP); // See Q&A below about r15_RegP. 3495 3496 format %{ %} 3497 interface(REG_INTER); 3498%} 3499 3500operand rRegN() %{ 3501 constraint(ALLOC_IN_RC(int_reg)); 3502 match(RegN); 3503 3504 format %{ %} 3505 interface(REG_INTER); 3506%} 3507 3508// Question: Why is r15_RegP (the read-only TLS register) a match for rRegP? 3509// Answer: Operand match rules govern the DFA as it processes instruction inputs. 3510// It's fine for an instruction input which expects rRegP to match a r15_RegP. 3511// The output of an instruction is controlled by the allocator, which respects 3512// register class masks, not match rules. Unless an instruction mentions 3513// r15_RegP or any_RegP explicitly as its output, r15 will not be considered 3514// by the allocator as an input. 3515 3516operand no_rax_RegP() 3517%{ 3518 constraint(ALLOC_IN_RC(ptr_no_rax_reg)); 3519 match(RegP); 3520 match(rbx_RegP); 3521 match(rsi_RegP); 3522 match(rdi_RegP); 3523 3524 format %{ %} 3525 interface(REG_INTER); 3526%} 3527 3528operand no_rbp_RegP() 3529%{ 3530 constraint(ALLOC_IN_RC(ptr_no_rbp_reg)); 3531 match(RegP); 3532 match(rbx_RegP); 3533 match(rsi_RegP); 3534 match(rdi_RegP); 3535 3536 format %{ %} 3537 interface(REG_INTER); 3538%} 3539 3540operand no_rax_rbx_RegP() 3541%{ 3542 constraint(ALLOC_IN_RC(ptr_no_rax_rbx_reg)); 3543 match(RegP); 3544 match(rsi_RegP); 3545 match(rdi_RegP); 3546 3547 format %{ %} 3548 interface(REG_INTER); 3549%} 3550 3551// Special Registers 3552// Return a pointer value 3553operand rax_RegP() 3554%{ 3555 constraint(ALLOC_IN_RC(ptr_rax_reg)); 3556 match(RegP); 3557 match(rRegP); 3558 3559 format %{ %} 3560 interface(REG_INTER); 3561%} 3562 3563// Special Registers 3564// Return a compressed pointer value 3565operand rax_RegN() 3566%{ 3567 constraint(ALLOC_IN_RC(int_rax_reg)); 3568 match(RegN); 3569 match(rRegN); 3570 3571 format %{ %} 3572 interface(REG_INTER); 3573%} 3574 3575// Used in AtomicAdd 3576operand rbx_RegP() 3577%{ 3578 constraint(ALLOC_IN_RC(ptr_rbx_reg)); 3579 match(RegP); 3580 match(rRegP); 3581 3582 format %{ %} 3583 interface(REG_INTER); 3584%} 3585 3586operand rsi_RegP() 3587%{ 3588 constraint(ALLOC_IN_RC(ptr_rsi_reg)); 3589 match(RegP); 3590 match(rRegP); 3591 3592 format %{ %} 3593 interface(REG_INTER); 3594%} 3595 3596// Used in rep stosq 3597operand rdi_RegP() 3598%{ 3599 constraint(ALLOC_IN_RC(ptr_rdi_reg)); 3600 match(RegP); 3601 match(rRegP); 3602 3603 format %{ %} 3604 interface(REG_INTER); 3605%} 3606 3607operand rbp_RegP() 3608%{ 3609 constraint(ALLOC_IN_RC(ptr_rbp_reg)); 3610 match(RegP); 3611 match(rRegP); 3612 3613 format %{ %} 3614 interface(REG_INTER); 3615%} 3616 3617operand r15_RegP() 3618%{ 3619 constraint(ALLOC_IN_RC(ptr_r15_reg)); 3620 match(RegP); 3621 match(rRegP); 3622 3623 format %{ %} 3624 interface(REG_INTER); 3625%} 3626 3627operand rRegL() 3628%{ 3629 constraint(ALLOC_IN_RC(long_reg)); 3630 match(RegL); 3631 match(rax_RegL); 3632 match(rdx_RegL); 3633 3634 format %{ %} 3635 interface(REG_INTER); 3636%} 3637 3638// Special Registers 3639operand no_rax_rdx_RegL() 3640%{ 3641 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 3642 match(RegL); 3643 match(rRegL); 3644 3645 format %{ %} 3646 interface(REG_INTER); 3647%} 3648 3649operand no_rax_RegL() 3650%{ 3651 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 3652 match(RegL); 3653 match(rRegL); 3654 match(rdx_RegL); 3655 3656 format %{ %} 3657 interface(REG_INTER); 3658%} 3659 3660operand no_rcx_RegL() 3661%{ 3662 constraint(ALLOC_IN_RC(long_no_rcx_reg)); 3663 match(RegL); 3664 match(rRegL); 3665 3666 format %{ %} 3667 interface(REG_INTER); 3668%} 3669 3670operand rax_RegL() 3671%{ 3672 constraint(ALLOC_IN_RC(long_rax_reg)); 3673 match(RegL); 3674 match(rRegL); 3675 3676 format %{ "RAX" %} 3677 interface(REG_INTER); 3678%} 3679 3680operand rcx_RegL() 3681%{ 3682 constraint(ALLOC_IN_RC(long_rcx_reg)); 3683 match(RegL); 3684 match(rRegL); 3685 3686 format %{ %} 3687 interface(REG_INTER); 3688%} 3689 3690operand rdx_RegL() 3691%{ 3692 constraint(ALLOC_IN_RC(long_rdx_reg)); 3693 match(RegL); 3694 match(rRegL); 3695 3696 format %{ %} 3697 interface(REG_INTER); 3698%} 3699 3700// Flags register, used as output of compare instructions 3701operand rFlagsReg() 3702%{ 3703 constraint(ALLOC_IN_RC(int_flags)); 3704 match(RegFlags); 3705 3706 format %{ "RFLAGS" %} 3707 interface(REG_INTER); 3708%} 3709 3710// Flags register, used as output of FLOATING POINT compare instructions 3711operand rFlagsRegU() 3712%{ 3713 constraint(ALLOC_IN_RC(int_flags)); 3714 match(RegFlags); 3715 3716 format %{ "RFLAGS_U" %} 3717 interface(REG_INTER); 3718%} 3719 3720operand rFlagsRegUCF() %{ 3721 constraint(ALLOC_IN_RC(int_flags)); 3722 match(RegFlags); 3723 predicate(false); 3724 3725 format %{ "RFLAGS_U_CF" %} 3726 interface(REG_INTER); 3727%} 3728 3729// Float register operands 3730operand regF() 3731%{ 3732 constraint(ALLOC_IN_RC(float_reg)); 3733 match(RegF); 3734 3735 format %{ %} 3736 interface(REG_INTER); 3737%} 3738 3739// Double register operands 3740operand regD() 3741%{ 3742 constraint(ALLOC_IN_RC(double_reg)); 3743 match(RegD); 3744 3745 format %{ %} 3746 interface(REG_INTER); 3747%} 3748 3749//----------Memory Operands---------------------------------------------------- 3750// Direct Memory Operand 3751// operand direct(immP addr) 3752// %{ 3753// match(addr); 3754 3755// format %{ "[$addr]" %} 3756// interface(MEMORY_INTER) %{ 3757// base(0xFFFFFFFF); 3758// index(0x4); 3759// scale(0x0); 3760// disp($addr); 3761// %} 3762// %} 3763 3764// Indirect Memory Operand 3765operand indirect(any_RegP reg) 3766%{ 3767 constraint(ALLOC_IN_RC(ptr_reg)); 3768 match(reg); 3769 3770 format %{ "[$reg]" %} 3771 interface(MEMORY_INTER) %{ 3772 base($reg); 3773 index(0x4); 3774 scale(0x0); 3775 disp(0x0); 3776 %} 3777%} 3778 3779// Indirect Memory Plus Short Offset Operand 3780operand indOffset8(any_RegP reg, immL8 off) 3781%{ 3782 constraint(ALLOC_IN_RC(ptr_reg)); 3783 match(AddP reg off); 3784 3785 format %{ "[$reg + $off (8-bit)]" %} 3786 interface(MEMORY_INTER) %{ 3787 base($reg); 3788 index(0x4); 3789 scale(0x0); 3790 disp($off); 3791 %} 3792%} 3793 3794// Indirect Memory Plus Long Offset Operand 3795operand indOffset32(any_RegP reg, immL32 off) 3796%{ 3797 constraint(ALLOC_IN_RC(ptr_reg)); 3798 match(AddP reg off); 3799 3800 format %{ "[$reg + $off (32-bit)]" %} 3801 interface(MEMORY_INTER) %{ 3802 base($reg); 3803 index(0x4); 3804 scale(0x0); 3805 disp($off); 3806 %} 3807%} 3808 3809// Indirect Memory Plus Index Register Plus Offset Operand 3810operand indIndexOffset(any_RegP reg, rRegL lreg, immL32 off) 3811%{ 3812 constraint(ALLOC_IN_RC(ptr_reg)); 3813 match(AddP (AddP reg lreg) off); 3814 3815 op_cost(10); 3816 format %{"[$reg + $off + $lreg]" %} 3817 interface(MEMORY_INTER) %{ 3818 base($reg); 3819 index($lreg); 3820 scale(0x0); 3821 disp($off); 3822 %} 3823%} 3824 3825// Indirect Memory Plus Index Register Plus Offset Operand 3826operand indIndex(any_RegP reg, rRegL lreg) 3827%{ 3828 constraint(ALLOC_IN_RC(ptr_reg)); 3829 match(AddP reg lreg); 3830 3831 op_cost(10); 3832 format %{"[$reg + $lreg]" %} 3833 interface(MEMORY_INTER) %{ 3834 base($reg); 3835 index($lreg); 3836 scale(0x0); 3837 disp(0x0); 3838 %} 3839%} 3840 3841// Indirect Memory Times Scale Plus Index Register 3842operand indIndexScale(any_RegP reg, rRegL lreg, immI2 scale) 3843%{ 3844 constraint(ALLOC_IN_RC(ptr_reg)); 3845 match(AddP reg (LShiftL lreg scale)); 3846 3847 op_cost(10); 3848 format %{"[$reg + $lreg << $scale]" %} 3849 interface(MEMORY_INTER) %{ 3850 base($reg); 3851 index($lreg); 3852 scale($scale); 3853 disp(0x0); 3854 %} 3855%} 3856 3857// Indirect Memory Times Scale Plus Index Register Plus Offset Operand 3858operand indIndexScaleOffset(any_RegP reg, immL32 off, rRegL lreg, immI2 scale) 3859%{ 3860 constraint(ALLOC_IN_RC(ptr_reg)); 3861 match(AddP (AddP reg (LShiftL lreg scale)) off); 3862 3863 op_cost(10); 3864 format %{"[$reg + $off + $lreg << $scale]" %} 3865 interface(MEMORY_INTER) %{ 3866 base($reg); 3867 index($lreg); 3868 scale($scale); 3869 disp($off); 3870 %} 3871%} 3872 3873// Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 3874operand indPosIndexScaleOffset(any_RegP reg, immL32 off, rRegI idx, immI2 scale) 3875%{ 3876 constraint(ALLOC_IN_RC(ptr_reg)); 3877 predicate(n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3878 match(AddP (AddP reg (LShiftL (ConvI2L idx) scale)) off); 3879 3880 op_cost(10); 3881 format %{"[$reg + $off + $idx << $scale]" %} 3882 interface(MEMORY_INTER) %{ 3883 base($reg); 3884 index($idx); 3885 scale($scale); 3886 disp($off); 3887 %} 3888%} 3889 3890// Indirect Narrow Oop Plus Offset Operand 3891// Note: x86 architecture doesn't support "scale * index + offset" without a base 3892// we can't free r12 even with Universe::narrow_oop_base() == NULL. 3893operand indCompressedOopOffset(rRegN reg, immL32 off) %{ 3894 predicate(UseCompressedOops && (Universe::narrow_oop_shift() == Address::times_8)); 3895 constraint(ALLOC_IN_RC(ptr_reg)); 3896 match(AddP (DecodeN reg) off); 3897 3898 op_cost(10); 3899 format %{"[R12 + $reg << 3 + $off] (compressed oop addressing)" %} 3900 interface(MEMORY_INTER) %{ 3901 base(0xc); // R12 3902 index($reg); 3903 scale(0x3); 3904 disp($off); 3905 %} 3906%} 3907 3908// Indirect Memory Operand 3909operand indirectNarrow(rRegN reg) 3910%{ 3911 predicate(Universe::narrow_oop_shift() == 0); 3912 constraint(ALLOC_IN_RC(ptr_reg)); 3913 match(DecodeN reg); 3914 3915 format %{ "[$reg]" %} 3916 interface(MEMORY_INTER) %{ 3917 base($reg); 3918 index(0x4); 3919 scale(0x0); 3920 disp(0x0); 3921 %} 3922%} 3923 3924// Indirect Memory Plus Short Offset Operand 3925operand indOffset8Narrow(rRegN reg, immL8 off) 3926%{ 3927 predicate(Universe::narrow_oop_shift() == 0); 3928 constraint(ALLOC_IN_RC(ptr_reg)); 3929 match(AddP (DecodeN reg) off); 3930 3931 format %{ "[$reg + $off (8-bit)]" %} 3932 interface(MEMORY_INTER) %{ 3933 base($reg); 3934 index(0x4); 3935 scale(0x0); 3936 disp($off); 3937 %} 3938%} 3939 3940// Indirect Memory Plus Long Offset Operand 3941operand indOffset32Narrow(rRegN reg, immL32 off) 3942%{ 3943 predicate(Universe::narrow_oop_shift() == 0); 3944 constraint(ALLOC_IN_RC(ptr_reg)); 3945 match(AddP (DecodeN reg) off); 3946 3947 format %{ "[$reg + $off (32-bit)]" %} 3948 interface(MEMORY_INTER) %{ 3949 base($reg); 3950 index(0x4); 3951 scale(0x0); 3952 disp($off); 3953 %} 3954%} 3955 3956// Indirect Memory Plus Index Register Plus Offset Operand 3957operand indIndexOffsetNarrow(rRegN reg, rRegL lreg, immL32 off) 3958%{ 3959 predicate(Universe::narrow_oop_shift() == 0); 3960 constraint(ALLOC_IN_RC(ptr_reg)); 3961 match(AddP (AddP (DecodeN reg) lreg) off); 3962 3963 op_cost(10); 3964 format %{"[$reg + $off + $lreg]" %} 3965 interface(MEMORY_INTER) %{ 3966 base($reg); 3967 index($lreg); 3968 scale(0x0); 3969 disp($off); 3970 %} 3971%} 3972 3973// Indirect Memory Plus Index Register Plus Offset Operand 3974operand indIndexNarrow(rRegN reg, rRegL lreg) 3975%{ 3976 predicate(Universe::narrow_oop_shift() == 0); 3977 constraint(ALLOC_IN_RC(ptr_reg)); 3978 match(AddP (DecodeN reg) lreg); 3979 3980 op_cost(10); 3981 format %{"[$reg + $lreg]" %} 3982 interface(MEMORY_INTER) %{ 3983 base($reg); 3984 index($lreg); 3985 scale(0x0); 3986 disp(0x0); 3987 %} 3988%} 3989 3990// Indirect Memory Times Scale Plus Index Register 3991operand indIndexScaleNarrow(rRegN reg, rRegL lreg, immI2 scale) 3992%{ 3993 predicate(Universe::narrow_oop_shift() == 0); 3994 constraint(ALLOC_IN_RC(ptr_reg)); 3995 match(AddP (DecodeN reg) (LShiftL lreg scale)); 3996 3997 op_cost(10); 3998 format %{"[$reg + $lreg << $scale]" %} 3999 interface(MEMORY_INTER) %{ 4000 base($reg); 4001 index($lreg); 4002 scale($scale); 4003 disp(0x0); 4004 %} 4005%} 4006 4007// Indirect Memory Times Scale Plus Index Register Plus Offset Operand 4008operand indIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegL lreg, immI2 scale) 4009%{ 4010 predicate(Universe::narrow_oop_shift() == 0); 4011 constraint(ALLOC_IN_RC(ptr_reg)); 4012 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off); 4013 4014 op_cost(10); 4015 format %{"[$reg + $off + $lreg << $scale]" %} 4016 interface(MEMORY_INTER) %{ 4017 base($reg); 4018 index($lreg); 4019 scale($scale); 4020 disp($off); 4021 %} 4022%} 4023 4024// Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 4025operand indPosIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegI idx, immI2 scale) 4026%{ 4027 constraint(ALLOC_IN_RC(ptr_reg)); 4028 predicate(Universe::narrow_oop_shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 4029 match(AddP (AddP (DecodeN reg) (LShiftL (ConvI2L idx) scale)) off); 4030 4031 op_cost(10); 4032 format %{"[$reg + $off + $idx << $scale]" %} 4033 interface(MEMORY_INTER) %{ 4034 base($reg); 4035 index($idx); 4036 scale($scale); 4037 disp($off); 4038 %} 4039%} 4040 4041 4042//----------Special Memory Operands-------------------------------------------- 4043// Stack Slot Operand - This operand is used for loading and storing temporary 4044// values on the stack where a match requires a value to 4045// flow through memory. 4046operand stackSlotP(sRegP reg) 4047%{ 4048 constraint(ALLOC_IN_RC(stack_slots)); 4049 // No match rule because this operand is only generated in matching 4050 4051 format %{ "[$reg]" %} 4052 interface(MEMORY_INTER) %{ 4053 base(0x4); // RSP 4054 index(0x4); // No Index 4055 scale(0x0); // No Scale 4056 disp($reg); // Stack Offset 4057 %} 4058%} 4059 4060operand stackSlotI(sRegI reg) 4061%{ 4062 constraint(ALLOC_IN_RC(stack_slots)); 4063 // No match rule because this operand is only generated in matching 4064 4065 format %{ "[$reg]" %} 4066 interface(MEMORY_INTER) %{ 4067 base(0x4); // RSP 4068 index(0x4); // No Index 4069 scale(0x0); // No Scale 4070 disp($reg); // Stack Offset 4071 %} 4072%} 4073 4074operand stackSlotF(sRegF reg) 4075%{ 4076 constraint(ALLOC_IN_RC(stack_slots)); 4077 // No match rule because this operand is only generated in matching 4078 4079 format %{ "[$reg]" %} 4080 interface(MEMORY_INTER) %{ 4081 base(0x4); // RSP 4082 index(0x4); // No Index 4083 scale(0x0); // No Scale 4084 disp($reg); // Stack Offset 4085 %} 4086%} 4087 4088operand stackSlotD(sRegD reg) 4089%{ 4090 constraint(ALLOC_IN_RC(stack_slots)); 4091 // No match rule because this operand is only generated in matching 4092 4093 format %{ "[$reg]" %} 4094 interface(MEMORY_INTER) %{ 4095 base(0x4); // RSP 4096 index(0x4); // No Index 4097 scale(0x0); // No Scale 4098 disp($reg); // Stack Offset 4099 %} 4100%} 4101operand stackSlotL(sRegL reg) 4102%{ 4103 constraint(ALLOC_IN_RC(stack_slots)); 4104 // No match rule because this operand is only generated in matching 4105 4106 format %{ "[$reg]" %} 4107 interface(MEMORY_INTER) %{ 4108 base(0x4); // RSP 4109 index(0x4); // No Index 4110 scale(0x0); // No Scale 4111 disp($reg); // Stack Offset 4112 %} 4113%} 4114 4115//----------Conditional Branch Operands---------------------------------------- 4116// Comparison Op - This is the operation of the comparison, and is limited to 4117// the following set of codes: 4118// L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 4119// 4120// Other attributes of the comparison, such as unsignedness, are specified 4121// by the comparison instruction that sets a condition code flags register. 4122// That result is represented by a flags operand whose subtype is appropriate 4123// to the unsignedness (etc.) of the comparison. 4124// 4125// Later, the instruction which matches both the Comparison Op (a Bool) and 4126// the flags (produced by the Cmp) specifies the coding of the comparison op 4127// by matching a specific subtype of Bool operand below, such as cmpOpU. 4128 4129// Comparision Code 4130operand cmpOp() 4131%{ 4132 match(Bool); 4133 4134 format %{ "" %} 4135 interface(COND_INTER) %{ 4136 equal(0x4, "e"); 4137 not_equal(0x5, "ne"); 4138 less(0xC, "l"); 4139 greater_equal(0xD, "ge"); 4140 less_equal(0xE, "le"); 4141 greater(0xF, "g"); 4142 %} 4143%} 4144 4145// Comparison Code, unsigned compare. Used by FP also, with 4146// C2 (unordered) turned into GT or LT already. The other bits 4147// C0 and C3 are turned into Carry & Zero flags. 4148operand cmpOpU() 4149%{ 4150 match(Bool); 4151 4152 format %{ "" %} 4153 interface(COND_INTER) %{ 4154 equal(0x4, "e"); 4155 not_equal(0x5, "ne"); 4156 less(0x2, "b"); 4157 greater_equal(0x3, "nb"); 4158 less_equal(0x6, "be"); 4159 greater(0x7, "nbe"); 4160 %} 4161%} 4162 4163 4164// Floating comparisons that don't require any fixup for the unordered case 4165operand cmpOpUCF() %{ 4166 match(Bool); 4167 predicate(n->as_Bool()->_test._test == BoolTest::lt || 4168 n->as_Bool()->_test._test == BoolTest::ge || 4169 n->as_Bool()->_test._test == BoolTest::le || 4170 n->as_Bool()->_test._test == BoolTest::gt); 4171 format %{ "" %} 4172 interface(COND_INTER) %{ 4173 equal(0x4, "e"); 4174 not_equal(0x5, "ne"); 4175 less(0x2, "b"); 4176 greater_equal(0x3, "nb"); 4177 less_equal(0x6, "be"); 4178 greater(0x7, "nbe"); 4179 %} 4180%} 4181 4182 4183// Floating comparisons that can be fixed up with extra conditional jumps 4184operand cmpOpUCF2() %{ 4185 match(Bool); 4186 predicate(n->as_Bool()->_test._test == BoolTest::ne || 4187 n->as_Bool()->_test._test == BoolTest::eq); 4188 format %{ "" %} 4189 interface(COND_INTER) %{ 4190 equal(0x4, "e"); 4191 not_equal(0x5, "ne"); 4192 less(0x2, "b"); 4193 greater_equal(0x3, "nb"); 4194 less_equal(0x6, "be"); 4195 greater(0x7, "nbe"); 4196 %} 4197%} 4198 4199 4200//----------OPERAND CLASSES---------------------------------------------------- 4201// Operand Classes are groups of operands that are used as to simplify 4202// instruction definitions by not requiring the AD writer to specify separate 4203// instructions for every form of operand when the instruction accepts 4204// multiple operand types with the same basic encoding and format. The classic 4205// case of this is memory operands. 4206 4207opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex, 4208 indIndexScale, indIndexScaleOffset, indPosIndexScaleOffset, 4209 indCompressedOopOffset, 4210 indirectNarrow, indOffset8Narrow, indOffset32Narrow, 4211 indIndexOffsetNarrow, indIndexNarrow, indIndexScaleNarrow, 4212 indIndexScaleOffsetNarrow, indPosIndexScaleOffsetNarrow); 4213 4214//----------PIPELINE----------------------------------------------------------- 4215// Rules which define the behavior of the target architectures pipeline. 4216pipeline %{ 4217 4218//----------ATTRIBUTES--------------------------------------------------------- 4219attributes %{ 4220 variable_size_instructions; // Fixed size instructions 4221 max_instructions_per_bundle = 3; // Up to 3 instructions per bundle 4222 instruction_unit_size = 1; // An instruction is 1 bytes long 4223 instruction_fetch_unit_size = 16; // The processor fetches one line 4224 instruction_fetch_units = 1; // of 16 bytes 4225 4226 // List of nop instructions 4227 nops( MachNop ); 4228%} 4229 4230//----------RESOURCES---------------------------------------------------------- 4231// Resources are the functional units available to the machine 4232 4233// Generic P2/P3 pipeline 4234// 3 decoders, only D0 handles big operands; a "bundle" is the limit of 4235// 3 instructions decoded per cycle. 4236// 2 load/store ops per cycle, 1 branch, 1 FPU, 4237// 3 ALU op, only ALU0 handles mul instructions. 4238resources( D0, D1, D2, DECODE = D0 | D1 | D2, 4239 MS0, MS1, MS2, MEM = MS0 | MS1 | MS2, 4240 BR, FPU, 4241 ALU0, ALU1, ALU2, ALU = ALU0 | ALU1 | ALU2); 4242 4243//----------PIPELINE DESCRIPTION----------------------------------------------- 4244// Pipeline Description specifies the stages in the machine's pipeline 4245 4246// Generic P2/P3 pipeline 4247pipe_desc(S0, S1, S2, S3, S4, S5); 4248 4249//----------PIPELINE CLASSES--------------------------------------------------- 4250// Pipeline Classes describe the stages in which input and output are 4251// referenced by the hardware pipeline. 4252 4253// Naming convention: ialu or fpu 4254// Then: _reg 4255// Then: _reg if there is a 2nd register 4256// Then: _long if it's a pair of instructions implementing a long 4257// Then: _fat if it requires the big decoder 4258// Or: _mem if it requires the big decoder and a memory unit. 4259 4260// Integer ALU reg operation 4261pipe_class ialu_reg(rRegI dst) 4262%{ 4263 single_instruction; 4264 dst : S4(write); 4265 dst : S3(read); 4266 DECODE : S0; // any decoder 4267 ALU : S3; // any alu 4268%} 4269 4270// Long ALU reg operation 4271pipe_class ialu_reg_long(rRegL dst) 4272%{ 4273 instruction_count(2); 4274 dst : S4(write); 4275 dst : S3(read); 4276 DECODE : S0(2); // any 2 decoders 4277 ALU : S3(2); // both alus 4278%} 4279 4280// Integer ALU reg operation using big decoder 4281pipe_class ialu_reg_fat(rRegI dst) 4282%{ 4283 single_instruction; 4284 dst : S4(write); 4285 dst : S3(read); 4286 D0 : S0; // big decoder only 4287 ALU : S3; // any alu 4288%} 4289 4290// Long ALU reg operation using big decoder 4291pipe_class ialu_reg_long_fat(rRegL dst) 4292%{ 4293 instruction_count(2); 4294 dst : S4(write); 4295 dst : S3(read); 4296 D0 : S0(2); // big decoder only; twice 4297 ALU : S3(2); // any 2 alus 4298%} 4299 4300// Integer ALU reg-reg operation 4301pipe_class ialu_reg_reg(rRegI dst, rRegI src) 4302%{ 4303 single_instruction; 4304 dst : S4(write); 4305 src : S3(read); 4306 DECODE : S0; // any decoder 4307 ALU : S3; // any alu 4308%} 4309 4310// Long ALU reg-reg operation 4311pipe_class ialu_reg_reg_long(rRegL dst, rRegL src) 4312%{ 4313 instruction_count(2); 4314 dst : S4(write); 4315 src : S3(read); 4316 DECODE : S0(2); // any 2 decoders 4317 ALU : S3(2); // both alus 4318%} 4319 4320// Integer ALU reg-reg operation 4321pipe_class ialu_reg_reg_fat(rRegI dst, memory src) 4322%{ 4323 single_instruction; 4324 dst : S4(write); 4325 src : S3(read); 4326 D0 : S0; // big decoder only 4327 ALU : S3; // any alu 4328%} 4329 4330// Long ALU reg-reg operation 4331pipe_class ialu_reg_reg_long_fat(rRegL dst, rRegL src) 4332%{ 4333 instruction_count(2); 4334 dst : S4(write); 4335 src : S3(read); 4336 D0 : S0(2); // big decoder only; twice 4337 ALU : S3(2); // both alus 4338%} 4339 4340// Integer ALU reg-mem operation 4341pipe_class ialu_reg_mem(rRegI dst, memory mem) 4342%{ 4343 single_instruction; 4344 dst : S5(write); 4345 mem : S3(read); 4346 D0 : S0; // big decoder only 4347 ALU : S4; // any alu 4348 MEM : S3; // any mem 4349%} 4350 4351// Integer mem operation (prefetch) 4352pipe_class ialu_mem(memory mem) 4353%{ 4354 single_instruction; 4355 mem : S3(read); 4356 D0 : S0; // big decoder only 4357 MEM : S3; // any mem 4358%} 4359 4360// Integer Store to Memory 4361pipe_class ialu_mem_reg(memory mem, rRegI src) 4362%{ 4363 single_instruction; 4364 mem : S3(read); 4365 src : S5(read); 4366 D0 : S0; // big decoder only 4367 ALU : S4; // any alu 4368 MEM : S3; 4369%} 4370 4371// // Long Store to Memory 4372// pipe_class ialu_mem_long_reg(memory mem, rRegL src) 4373// %{ 4374// instruction_count(2); 4375// mem : S3(read); 4376// src : S5(read); 4377// D0 : S0(2); // big decoder only; twice 4378// ALU : S4(2); // any 2 alus 4379// MEM : S3(2); // Both mems 4380// %} 4381 4382// Integer Store to Memory 4383pipe_class ialu_mem_imm(memory mem) 4384%{ 4385 single_instruction; 4386 mem : S3(read); 4387 D0 : S0; // big decoder only 4388 ALU : S4; // any alu 4389 MEM : S3; 4390%} 4391 4392// Integer ALU0 reg-reg operation 4393pipe_class ialu_reg_reg_alu0(rRegI dst, rRegI src) 4394%{ 4395 single_instruction; 4396 dst : S4(write); 4397 src : S3(read); 4398 D0 : S0; // Big decoder only 4399 ALU0 : S3; // only alu0 4400%} 4401 4402// Integer ALU0 reg-mem operation 4403pipe_class ialu_reg_mem_alu0(rRegI dst, memory mem) 4404%{ 4405 single_instruction; 4406 dst : S5(write); 4407 mem : S3(read); 4408 D0 : S0; // big decoder only 4409 ALU0 : S4; // ALU0 only 4410 MEM : S3; // any mem 4411%} 4412 4413// Integer ALU reg-reg operation 4414pipe_class ialu_cr_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2) 4415%{ 4416 single_instruction; 4417 cr : S4(write); 4418 src1 : S3(read); 4419 src2 : S3(read); 4420 DECODE : S0; // any decoder 4421 ALU : S3; // any alu 4422%} 4423 4424// Integer ALU reg-imm operation 4425pipe_class ialu_cr_reg_imm(rFlagsReg cr, rRegI src1) 4426%{ 4427 single_instruction; 4428 cr : S4(write); 4429 src1 : S3(read); 4430 DECODE : S0; // any decoder 4431 ALU : S3; // any alu 4432%} 4433 4434// Integer ALU reg-mem operation 4435pipe_class ialu_cr_reg_mem(rFlagsReg cr, rRegI src1, memory src2) 4436%{ 4437 single_instruction; 4438 cr : S4(write); 4439 src1 : S3(read); 4440 src2 : S3(read); 4441 D0 : S0; // big decoder only 4442 ALU : S4; // any alu 4443 MEM : S3; 4444%} 4445 4446// Conditional move reg-reg 4447pipe_class pipe_cmplt( rRegI p, rRegI q, rRegI y) 4448%{ 4449 instruction_count(4); 4450 y : S4(read); 4451 q : S3(read); 4452 p : S3(read); 4453 DECODE : S0(4); // any decoder 4454%} 4455 4456// Conditional move reg-reg 4457pipe_class pipe_cmov_reg( rRegI dst, rRegI src, rFlagsReg cr) 4458%{ 4459 single_instruction; 4460 dst : S4(write); 4461 src : S3(read); 4462 cr : S3(read); 4463 DECODE : S0; // any decoder 4464%} 4465 4466// Conditional move reg-mem 4467pipe_class pipe_cmov_mem( rFlagsReg cr, rRegI dst, memory src) 4468%{ 4469 single_instruction; 4470 dst : S4(write); 4471 src : S3(read); 4472 cr : S3(read); 4473 DECODE : S0; // any decoder 4474 MEM : S3; 4475%} 4476 4477// Conditional move reg-reg long 4478pipe_class pipe_cmov_reg_long( rFlagsReg cr, rRegL dst, rRegL src) 4479%{ 4480 single_instruction; 4481 dst : S4(write); 4482 src : S3(read); 4483 cr : S3(read); 4484 DECODE : S0(2); // any 2 decoders 4485%} 4486 4487// XXX 4488// // Conditional move double reg-reg 4489// pipe_class pipe_cmovD_reg( rFlagsReg cr, regDPR1 dst, regD src) 4490// %{ 4491// single_instruction; 4492// dst : S4(write); 4493// src : S3(read); 4494// cr : S3(read); 4495// DECODE : S0; // any decoder 4496// %} 4497 4498// Float reg-reg operation 4499pipe_class fpu_reg(regD dst) 4500%{ 4501 instruction_count(2); 4502 dst : S3(read); 4503 DECODE : S0(2); // any 2 decoders 4504 FPU : S3; 4505%} 4506 4507// Float reg-reg operation 4508pipe_class fpu_reg_reg(regD dst, regD src) 4509%{ 4510 instruction_count(2); 4511 dst : S4(write); 4512 src : S3(read); 4513 DECODE : S0(2); // any 2 decoders 4514 FPU : S3; 4515%} 4516 4517// Float reg-reg operation 4518pipe_class fpu_reg_reg_reg(regD dst, regD src1, regD src2) 4519%{ 4520 instruction_count(3); 4521 dst : S4(write); 4522 src1 : S3(read); 4523 src2 : S3(read); 4524 DECODE : S0(3); // any 3 decoders 4525 FPU : S3(2); 4526%} 4527 4528// Float reg-reg operation 4529pipe_class fpu_reg_reg_reg_reg(regD dst, regD src1, regD src2, regD src3) 4530%{ 4531 instruction_count(4); 4532 dst : S4(write); 4533 src1 : S3(read); 4534 src2 : S3(read); 4535 src3 : S3(read); 4536 DECODE : S0(4); // any 3 decoders 4537 FPU : S3(2); 4538%} 4539 4540// Float reg-reg operation 4541pipe_class fpu_reg_mem_reg_reg(regD dst, memory src1, regD src2, regD src3) 4542%{ 4543 instruction_count(4); 4544 dst : S4(write); 4545 src1 : S3(read); 4546 src2 : S3(read); 4547 src3 : S3(read); 4548 DECODE : S1(3); // any 3 decoders 4549 D0 : S0; // Big decoder only 4550 FPU : S3(2); 4551 MEM : S3; 4552%} 4553 4554// Float reg-mem operation 4555pipe_class fpu_reg_mem(regD dst, memory mem) 4556%{ 4557 instruction_count(2); 4558 dst : S5(write); 4559 mem : S3(read); 4560 D0 : S0; // big decoder only 4561 DECODE : S1; // any decoder for FPU POP 4562 FPU : S4; 4563 MEM : S3; // any mem 4564%} 4565 4566// Float reg-mem operation 4567pipe_class fpu_reg_reg_mem(regD dst, regD src1, memory mem) 4568%{ 4569 instruction_count(3); 4570 dst : S5(write); 4571 src1 : S3(read); 4572 mem : S3(read); 4573 D0 : S0; // big decoder only 4574 DECODE : S1(2); // any decoder for FPU POP 4575 FPU : S4; 4576 MEM : S3; // any mem 4577%} 4578 4579// Float mem-reg operation 4580pipe_class fpu_mem_reg(memory mem, regD src) 4581%{ 4582 instruction_count(2); 4583 src : S5(read); 4584 mem : S3(read); 4585 DECODE : S0; // any decoder for FPU PUSH 4586 D0 : S1; // big decoder only 4587 FPU : S4; 4588 MEM : S3; // any mem 4589%} 4590 4591pipe_class fpu_mem_reg_reg(memory mem, regD src1, regD src2) 4592%{ 4593 instruction_count(3); 4594 src1 : S3(read); 4595 src2 : S3(read); 4596 mem : S3(read); 4597 DECODE : S0(2); // any decoder for FPU PUSH 4598 D0 : S1; // big decoder only 4599 FPU : S4; 4600 MEM : S3; // any mem 4601%} 4602 4603pipe_class fpu_mem_reg_mem(memory mem, regD src1, memory src2) 4604%{ 4605 instruction_count(3); 4606 src1 : S3(read); 4607 src2 : S3(read); 4608 mem : S4(read); 4609 DECODE : S0; // any decoder for FPU PUSH 4610 D0 : S0(2); // big decoder only 4611 FPU : S4; 4612 MEM : S3(2); // any mem 4613%} 4614 4615pipe_class fpu_mem_mem(memory dst, memory src1) 4616%{ 4617 instruction_count(2); 4618 src1 : S3(read); 4619 dst : S4(read); 4620 D0 : S0(2); // big decoder only 4621 MEM : S3(2); // any mem 4622%} 4623 4624pipe_class fpu_mem_mem_mem(memory dst, memory src1, memory src2) 4625%{ 4626 instruction_count(3); 4627 src1 : S3(read); 4628 src2 : S3(read); 4629 dst : S4(read); 4630 D0 : S0(3); // big decoder only 4631 FPU : S4; 4632 MEM : S3(3); // any mem 4633%} 4634 4635pipe_class fpu_mem_reg_con(memory mem, regD src1) 4636%{ 4637 instruction_count(3); 4638 src1 : S4(read); 4639 mem : S4(read); 4640 DECODE : S0; // any decoder for FPU PUSH 4641 D0 : S0(2); // big decoder only 4642 FPU : S4; 4643 MEM : S3(2); // any mem 4644%} 4645 4646// Float load constant 4647pipe_class fpu_reg_con(regD dst) 4648%{ 4649 instruction_count(2); 4650 dst : S5(write); 4651 D0 : S0; // big decoder only for the load 4652 DECODE : S1; // any decoder for FPU POP 4653 FPU : S4; 4654 MEM : S3; // any mem 4655%} 4656 4657// Float load constant 4658pipe_class fpu_reg_reg_con(regD dst, regD src) 4659%{ 4660 instruction_count(3); 4661 dst : S5(write); 4662 src : S3(read); 4663 D0 : S0; // big decoder only for the load 4664 DECODE : S1(2); // any decoder for FPU POP 4665 FPU : S4; 4666 MEM : S3; // any mem 4667%} 4668 4669// UnConditional branch 4670pipe_class pipe_jmp(label labl) 4671%{ 4672 single_instruction; 4673 BR : S3; 4674%} 4675 4676// Conditional branch 4677pipe_class pipe_jcc(cmpOp cmp, rFlagsReg cr, label labl) 4678%{ 4679 single_instruction; 4680 cr : S1(read); 4681 BR : S3; 4682%} 4683 4684// Allocation idiom 4685pipe_class pipe_cmpxchg(rRegP dst, rRegP heap_ptr) 4686%{ 4687 instruction_count(1); force_serialization; 4688 fixed_latency(6); 4689 heap_ptr : S3(read); 4690 DECODE : S0(3); 4691 D0 : S2; 4692 MEM : S3; 4693 ALU : S3(2); 4694 dst : S5(write); 4695 BR : S5; 4696%} 4697 4698// Generic big/slow expanded idiom 4699pipe_class pipe_slow() 4700%{ 4701 instruction_count(10); multiple_bundles; force_serialization; 4702 fixed_latency(100); 4703 D0 : S0(2); 4704 MEM : S3(2); 4705%} 4706 4707// The real do-nothing guy 4708pipe_class empty() 4709%{ 4710 instruction_count(0); 4711%} 4712 4713// Define the class for the Nop node 4714define 4715%{ 4716 MachNop = empty; 4717%} 4718 4719%} 4720 4721//----------INSTRUCTIONS------------------------------------------------------- 4722// 4723// match -- States which machine-independent subtree may be replaced 4724// by this instruction. 4725// ins_cost -- The estimated cost of this instruction is used by instruction 4726// selection to identify a minimum cost tree of machine 4727// instructions that matches a tree of machine-independent 4728// instructions. 4729// format -- A string providing the disassembly for this instruction. 4730// The value of an instruction's operand may be inserted 4731// by referring to it with a '$' prefix. 4732// opcode -- Three instruction opcodes may be provided. These are referred 4733// to within an encode class as $primary, $secondary, and $tertiary 4734// rrspectively. The primary opcode is commonly used to 4735// indicate the type of machine instruction, while secondary 4736// and tertiary are often used for prefix options or addressing 4737// modes. 4738// ins_encode -- A list of encode classes with parameters. The encode class 4739// name must have been defined in an 'enc_class' specification 4740// in the encode section of the architecture description. 4741 4742 4743//----------Load/Store/Move Instructions--------------------------------------- 4744//----------Load Instructions-------------------------------------------------- 4745 4746// Load Byte (8 bit signed) 4747instruct loadB(rRegI dst, memory mem) 4748%{ 4749 match(Set dst (LoadB mem)); 4750 4751 ins_cost(125); 4752 format %{ "movsbl $dst, $mem\t# byte" %} 4753 4754 ins_encode %{ 4755 __ movsbl($dst$$Register, $mem$$Address); 4756 %} 4757 4758 ins_pipe(ialu_reg_mem); 4759%} 4760 4761// Load Byte (8 bit signed) into Long Register 4762instruct loadB2L(rRegL dst, memory mem) 4763%{ 4764 match(Set dst (ConvI2L (LoadB mem))); 4765 4766 ins_cost(125); 4767 format %{ "movsbq $dst, $mem\t# byte -> long" %} 4768 4769 ins_encode %{ 4770 __ movsbq($dst$$Register, $mem$$Address); 4771 %} 4772 4773 ins_pipe(ialu_reg_mem); 4774%} 4775 4776// Load Unsigned Byte (8 bit UNsigned) 4777instruct loadUB(rRegI dst, memory mem) 4778%{ 4779 match(Set dst (LoadUB mem)); 4780 4781 ins_cost(125); 4782 format %{ "movzbl $dst, $mem\t# ubyte" %} 4783 4784 ins_encode %{ 4785 __ movzbl($dst$$Register, $mem$$Address); 4786 %} 4787 4788 ins_pipe(ialu_reg_mem); 4789%} 4790 4791// Load Unsigned Byte (8 bit UNsigned) into Long Register 4792instruct loadUB2L(rRegL dst, memory mem) 4793%{ 4794 match(Set dst (ConvI2L (LoadUB mem))); 4795 4796 ins_cost(125); 4797 format %{ "movzbq $dst, $mem\t# ubyte -> long" %} 4798 4799 ins_encode %{ 4800 __ movzbq($dst$$Register, $mem$$Address); 4801 %} 4802 4803 ins_pipe(ialu_reg_mem); 4804%} 4805 4806// Load Unsigned Byte (8 bit UNsigned) with a 8-bit mask into Long Register 4807instruct loadUB2L_immI8(rRegL dst, memory mem, immI8 mask, rFlagsReg cr) %{ 4808 match(Set dst (ConvI2L (AndI (LoadUB mem) mask))); 4809 effect(KILL cr); 4810 4811 format %{ "movzbq $dst, $mem\t# ubyte & 8-bit mask -> long\n\t" 4812 "andl $dst, $mask" %} 4813 ins_encode %{ 4814 Register Rdst = $dst$$Register; 4815 __ movzbq(Rdst, $mem$$Address); 4816 __ andl(Rdst, $mask$$constant); 4817 %} 4818 ins_pipe(ialu_reg_mem); 4819%} 4820 4821// Load Short (16 bit signed) 4822instruct loadS(rRegI dst, memory mem) 4823%{ 4824 match(Set dst (LoadS mem)); 4825 4826 ins_cost(125); 4827 format %{ "movswl $dst, $mem\t# short" %} 4828 4829 ins_encode %{ 4830 __ movswl($dst$$Register, $mem$$Address); 4831 %} 4832 4833 ins_pipe(ialu_reg_mem); 4834%} 4835 4836// Load Short (16 bit signed) to Byte (8 bit signed) 4837instruct loadS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4838 match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour)); 4839 4840 ins_cost(125); 4841 format %{ "movsbl $dst, $mem\t# short -> byte" %} 4842 ins_encode %{ 4843 __ movsbl($dst$$Register, $mem$$Address); 4844 %} 4845 ins_pipe(ialu_reg_mem); 4846%} 4847 4848// Load Short (16 bit signed) into Long Register 4849instruct loadS2L(rRegL dst, memory mem) 4850%{ 4851 match(Set dst (ConvI2L (LoadS mem))); 4852 4853 ins_cost(125); 4854 format %{ "movswq $dst, $mem\t# short -> long" %} 4855 4856 ins_encode %{ 4857 __ movswq($dst$$Register, $mem$$Address); 4858 %} 4859 4860 ins_pipe(ialu_reg_mem); 4861%} 4862 4863// Load Unsigned Short/Char (16 bit UNsigned) 4864instruct loadUS(rRegI dst, memory mem) 4865%{ 4866 match(Set dst (LoadUS mem)); 4867 4868 ins_cost(125); 4869 format %{ "movzwl $dst, $mem\t# ushort/char" %} 4870 4871 ins_encode %{ 4872 __ movzwl($dst$$Register, $mem$$Address); 4873 %} 4874 4875 ins_pipe(ialu_reg_mem); 4876%} 4877 4878// Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed) 4879instruct loadUS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4880 match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour)); 4881 4882 ins_cost(125); 4883 format %{ "movsbl $dst, $mem\t# ushort -> byte" %} 4884 ins_encode %{ 4885 __ movsbl($dst$$Register, $mem$$Address); 4886 %} 4887 ins_pipe(ialu_reg_mem); 4888%} 4889 4890// Load Unsigned Short/Char (16 bit UNsigned) into Long Register 4891instruct loadUS2L(rRegL dst, memory mem) 4892%{ 4893 match(Set dst (ConvI2L (LoadUS mem))); 4894 4895 ins_cost(125); 4896 format %{ "movzwq $dst, $mem\t# ushort/char -> long" %} 4897 4898 ins_encode %{ 4899 __ movzwq($dst$$Register, $mem$$Address); 4900 %} 4901 4902 ins_pipe(ialu_reg_mem); 4903%} 4904 4905// Load Unsigned Short/Char (16 bit UNsigned) with mask 0xFF into Long Register 4906instruct loadUS2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 4907 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 4908 4909 format %{ "movzbq $dst, $mem\t# ushort/char & 0xFF -> long" %} 4910 ins_encode %{ 4911 __ movzbq($dst$$Register, $mem$$Address); 4912 %} 4913 ins_pipe(ialu_reg_mem); 4914%} 4915 4916// Load Unsigned Short/Char (16 bit UNsigned) with mask into Long Register 4917instruct loadUS2L_immI16(rRegL dst, memory mem, immI16 mask, rFlagsReg cr) %{ 4918 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 4919 effect(KILL cr); 4920 4921 format %{ "movzwq $dst, $mem\t# ushort/char & 16-bit mask -> long\n\t" 4922 "andl $dst, $mask" %} 4923 ins_encode %{ 4924 Register Rdst = $dst$$Register; 4925 __ movzwq(Rdst, $mem$$Address); 4926 __ andl(Rdst, $mask$$constant); 4927 %} 4928 ins_pipe(ialu_reg_mem); 4929%} 4930 4931// Load Integer 4932instruct loadI(rRegI dst, memory mem) 4933%{ 4934 match(Set dst (LoadI mem)); 4935 4936 ins_cost(125); 4937 format %{ "movl $dst, $mem\t# int" %} 4938 4939 ins_encode %{ 4940 __ movl($dst$$Register, $mem$$Address); 4941 %} 4942 4943 ins_pipe(ialu_reg_mem); 4944%} 4945 4946// Load Integer (32 bit signed) to Byte (8 bit signed) 4947instruct loadI2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4948 match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour)); 4949 4950 ins_cost(125); 4951 format %{ "movsbl $dst, $mem\t# int -> byte" %} 4952 ins_encode %{ 4953 __ movsbl($dst$$Register, $mem$$Address); 4954 %} 4955 ins_pipe(ialu_reg_mem); 4956%} 4957 4958// Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned) 4959instruct loadI2UB(rRegI dst, memory mem, immI_255 mask) %{ 4960 match(Set dst (AndI (LoadI mem) mask)); 4961 4962 ins_cost(125); 4963 format %{ "movzbl $dst, $mem\t# int -> ubyte" %} 4964 ins_encode %{ 4965 __ movzbl($dst$$Register, $mem$$Address); 4966 %} 4967 ins_pipe(ialu_reg_mem); 4968%} 4969 4970// Load Integer (32 bit signed) to Short (16 bit signed) 4971instruct loadI2S(rRegI dst, memory mem, immI_16 sixteen) %{ 4972 match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen)); 4973 4974 ins_cost(125); 4975 format %{ "movswl $dst, $mem\t# int -> short" %} 4976 ins_encode %{ 4977 __ movswl($dst$$Register, $mem$$Address); 4978 %} 4979 ins_pipe(ialu_reg_mem); 4980%} 4981 4982// Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned) 4983instruct loadI2US(rRegI dst, memory mem, immI_65535 mask) %{ 4984 match(Set dst (AndI (LoadI mem) mask)); 4985 4986 ins_cost(125); 4987 format %{ "movzwl $dst, $mem\t# int -> ushort/char" %} 4988 ins_encode %{ 4989 __ movzwl($dst$$Register, $mem$$Address); 4990 %} 4991 ins_pipe(ialu_reg_mem); 4992%} 4993 4994// Load Integer into Long Register 4995instruct loadI2L(rRegL dst, memory mem) 4996%{ 4997 match(Set dst (ConvI2L (LoadI mem))); 4998 4999 ins_cost(125); 5000 format %{ "movslq $dst, $mem\t# int -> long" %} 5001 5002 ins_encode %{ 5003 __ movslq($dst$$Register, $mem$$Address); 5004 %} 5005 5006 ins_pipe(ialu_reg_mem); 5007%} 5008 5009// Load Integer with mask 0xFF into Long Register 5010instruct loadI2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 5011 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 5012 5013 format %{ "movzbq $dst, $mem\t# int & 0xFF -> long" %} 5014 ins_encode %{ 5015 __ movzbq($dst$$Register, $mem$$Address); 5016 %} 5017 ins_pipe(ialu_reg_mem); 5018%} 5019 5020// Load Integer with mask 0xFFFF into Long Register 5021instruct loadI2L_immI_65535(rRegL dst, memory mem, immI_65535 mask) %{ 5022 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 5023 5024 format %{ "movzwq $dst, $mem\t# int & 0xFFFF -> long" %} 5025 ins_encode %{ 5026 __ movzwq($dst$$Register, $mem$$Address); 5027 %} 5028 ins_pipe(ialu_reg_mem); 5029%} 5030 5031// Load Integer with a 32-bit mask into Long Register 5032instruct loadI2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 5033 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 5034 effect(KILL cr); 5035 5036 format %{ "movl $dst, $mem\t# int & 32-bit mask -> long\n\t" 5037 "andl $dst, $mask" %} 5038 ins_encode %{ 5039 Register Rdst = $dst$$Register; 5040 __ movl(Rdst, $mem$$Address); 5041 __ andl(Rdst, $mask$$constant); 5042 %} 5043 ins_pipe(ialu_reg_mem); 5044%} 5045 5046// Load Unsigned Integer into Long Register 5047instruct loadUI2L(rRegL dst, memory mem) 5048%{ 5049 match(Set dst (LoadUI2L mem)); 5050 5051 ins_cost(125); 5052 format %{ "movl $dst, $mem\t# uint -> long" %} 5053 5054 ins_encode %{ 5055 __ movl($dst$$Register, $mem$$Address); 5056 %} 5057 5058 ins_pipe(ialu_reg_mem); 5059%} 5060 5061// Load Long 5062instruct loadL(rRegL dst, memory mem) 5063%{ 5064 match(Set dst (LoadL mem)); 5065 5066 ins_cost(125); 5067 format %{ "movq $dst, $mem\t# long" %} 5068 5069 ins_encode %{ 5070 __ movq($dst$$Register, $mem$$Address); 5071 %} 5072 5073 ins_pipe(ialu_reg_mem); // XXX 5074%} 5075 5076// Load Range 5077instruct loadRange(rRegI dst, memory mem) 5078%{ 5079 match(Set dst (LoadRange mem)); 5080 5081 ins_cost(125); // XXX 5082 format %{ "movl $dst, $mem\t# range" %} 5083 opcode(0x8B); 5084 ins_encode(REX_reg_mem(dst, mem), OpcP, reg_mem(dst, mem)); 5085 ins_pipe(ialu_reg_mem); 5086%} 5087 5088// Load Pointer 5089instruct loadP(rRegP dst, memory mem) 5090%{ 5091 match(Set dst (LoadP mem)); 5092 5093 ins_cost(125); // XXX 5094 format %{ "movq $dst, $mem\t# ptr" %} 5095 opcode(0x8B); 5096 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5097 ins_pipe(ialu_reg_mem); // XXX 5098%} 5099 5100// Load Compressed Pointer 5101instruct loadN(rRegN dst, memory mem) 5102%{ 5103 match(Set dst (LoadN mem)); 5104 5105 ins_cost(125); // XXX 5106 format %{ "movl $dst, $mem\t# compressed ptr" %} 5107 ins_encode %{ 5108 __ movl($dst$$Register, $mem$$Address); 5109 %} 5110 ins_pipe(ialu_reg_mem); // XXX 5111%} 5112 5113 5114// Load Klass Pointer 5115instruct loadKlass(rRegP dst, memory mem) 5116%{ 5117 match(Set dst (LoadKlass mem)); 5118 5119 ins_cost(125); // XXX 5120 format %{ "movq $dst, $mem\t# class" %} 5121 opcode(0x8B); 5122 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5123 ins_pipe(ialu_reg_mem); // XXX 5124%} 5125 5126// Load narrow Klass Pointer 5127instruct loadNKlass(rRegN dst, memory mem) 5128%{ 5129 match(Set dst (LoadNKlass mem)); 5130 5131 ins_cost(125); // XXX 5132 format %{ "movl $dst, $mem\t# compressed klass ptr" %} 5133 ins_encode %{ 5134 __ movl($dst$$Register, $mem$$Address); 5135 %} 5136 ins_pipe(ialu_reg_mem); // XXX 5137%} 5138 5139// Load Float 5140instruct loadF(regF dst, memory mem) 5141%{ 5142 match(Set dst (LoadF mem)); 5143 5144 ins_cost(145); // XXX 5145 format %{ "movss $dst, $mem\t# float" %} 5146 ins_encode %{ 5147 __ movflt($dst$$XMMRegister, $mem$$Address); 5148 %} 5149 ins_pipe(pipe_slow); // XXX 5150%} 5151 5152// Load Double 5153instruct loadD_partial(regD dst, memory mem) 5154%{ 5155 predicate(!UseXmmLoadAndClearUpper); 5156 match(Set dst (LoadD mem)); 5157 5158 ins_cost(145); // XXX 5159 format %{ "movlpd $dst, $mem\t# double" %} 5160 ins_encode %{ 5161 __ movdbl($dst$$XMMRegister, $mem$$Address); 5162 %} 5163 ins_pipe(pipe_slow); // XXX 5164%} 5165 5166instruct loadD(regD dst, memory mem) 5167%{ 5168 predicate(UseXmmLoadAndClearUpper); 5169 match(Set dst (LoadD mem)); 5170 5171 ins_cost(145); // XXX 5172 format %{ "movsd $dst, $mem\t# double" %} 5173 ins_encode %{ 5174 __ movdbl($dst$$XMMRegister, $mem$$Address); 5175 %} 5176 ins_pipe(pipe_slow); // XXX 5177%} 5178 5179// Load Effective Address 5180instruct leaP8(rRegP dst, indOffset8 mem) 5181%{ 5182 match(Set dst mem); 5183 5184 ins_cost(110); // XXX 5185 format %{ "leaq $dst, $mem\t# ptr 8" %} 5186 opcode(0x8D); 5187 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5188 ins_pipe(ialu_reg_reg_fat); 5189%} 5190 5191instruct leaP32(rRegP dst, indOffset32 mem) 5192%{ 5193 match(Set dst mem); 5194 5195 ins_cost(110); 5196 format %{ "leaq $dst, $mem\t# ptr 32" %} 5197 opcode(0x8D); 5198 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5199 ins_pipe(ialu_reg_reg_fat); 5200%} 5201 5202// instruct leaPIdx(rRegP dst, indIndex mem) 5203// %{ 5204// match(Set dst mem); 5205 5206// ins_cost(110); 5207// format %{ "leaq $dst, $mem\t# ptr idx" %} 5208// opcode(0x8D); 5209// ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5210// ins_pipe(ialu_reg_reg_fat); 5211// %} 5212 5213instruct leaPIdxOff(rRegP dst, indIndexOffset mem) 5214%{ 5215 match(Set dst mem); 5216 5217 ins_cost(110); 5218 format %{ "leaq $dst, $mem\t# ptr idxoff" %} 5219 opcode(0x8D); 5220 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5221 ins_pipe(ialu_reg_reg_fat); 5222%} 5223 5224instruct leaPIdxScale(rRegP dst, indIndexScale mem) 5225%{ 5226 match(Set dst mem); 5227 5228 ins_cost(110); 5229 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 5230 opcode(0x8D); 5231 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5232 ins_pipe(ialu_reg_reg_fat); 5233%} 5234 5235instruct leaPIdxScaleOff(rRegP dst, indIndexScaleOffset mem) 5236%{ 5237 match(Set dst mem); 5238 5239 ins_cost(110); 5240 format %{ "leaq $dst, $mem\t# ptr idxscaleoff" %} 5241 opcode(0x8D); 5242 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5243 ins_pipe(ialu_reg_reg_fat); 5244%} 5245 5246instruct leaPPosIdxScaleOff(rRegP dst, indPosIndexScaleOffset mem) 5247%{ 5248 match(Set dst mem); 5249 5250 ins_cost(110); 5251 format %{ "leaq $dst, $mem\t# ptr posidxscaleoff" %} 5252 opcode(0x8D); 5253 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5254 ins_pipe(ialu_reg_reg_fat); 5255%} 5256 5257// Load Effective Address which uses Narrow (32-bits) oop 5258instruct leaPCompressedOopOffset(rRegP dst, indCompressedOopOffset mem) 5259%{ 5260 predicate(UseCompressedOops && (Universe::narrow_oop_shift() != 0)); 5261 match(Set dst mem); 5262 5263 ins_cost(110); 5264 format %{ "leaq $dst, $mem\t# ptr compressedoopoff32" %} 5265 opcode(0x8D); 5266 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5267 ins_pipe(ialu_reg_reg_fat); 5268%} 5269 5270instruct leaP8Narrow(rRegP dst, indOffset8Narrow mem) 5271%{ 5272 predicate(Universe::narrow_oop_shift() == 0); 5273 match(Set dst mem); 5274 5275 ins_cost(110); // XXX 5276 format %{ "leaq $dst, $mem\t# ptr off8narrow" %} 5277 opcode(0x8D); 5278 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5279 ins_pipe(ialu_reg_reg_fat); 5280%} 5281 5282instruct leaP32Narrow(rRegP dst, indOffset32Narrow mem) 5283%{ 5284 predicate(Universe::narrow_oop_shift() == 0); 5285 match(Set dst mem); 5286 5287 ins_cost(110); 5288 format %{ "leaq $dst, $mem\t# ptr off32narrow" %} 5289 opcode(0x8D); 5290 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5291 ins_pipe(ialu_reg_reg_fat); 5292%} 5293 5294instruct leaPIdxOffNarrow(rRegP dst, indIndexOffsetNarrow mem) 5295%{ 5296 predicate(Universe::narrow_oop_shift() == 0); 5297 match(Set dst mem); 5298 5299 ins_cost(110); 5300 format %{ "leaq $dst, $mem\t# ptr idxoffnarrow" %} 5301 opcode(0x8D); 5302 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5303 ins_pipe(ialu_reg_reg_fat); 5304%} 5305 5306instruct leaPIdxScaleNarrow(rRegP dst, indIndexScaleNarrow mem) 5307%{ 5308 predicate(Universe::narrow_oop_shift() == 0); 5309 match(Set dst mem); 5310 5311 ins_cost(110); 5312 format %{ "leaq $dst, $mem\t# ptr idxscalenarrow" %} 5313 opcode(0x8D); 5314 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5315 ins_pipe(ialu_reg_reg_fat); 5316%} 5317 5318instruct leaPIdxScaleOffNarrow(rRegP dst, indIndexScaleOffsetNarrow mem) 5319%{ 5320 predicate(Universe::narrow_oop_shift() == 0); 5321 match(Set dst mem); 5322 5323 ins_cost(110); 5324 format %{ "leaq $dst, $mem\t# ptr idxscaleoffnarrow" %} 5325 opcode(0x8D); 5326 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5327 ins_pipe(ialu_reg_reg_fat); 5328%} 5329 5330instruct leaPPosIdxScaleOffNarrow(rRegP dst, indPosIndexScaleOffsetNarrow mem) 5331%{ 5332 predicate(Universe::narrow_oop_shift() == 0); 5333 match(Set dst mem); 5334 5335 ins_cost(110); 5336 format %{ "leaq $dst, $mem\t# ptr posidxscaleoffnarrow" %} 5337 opcode(0x8D); 5338 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5339 ins_pipe(ialu_reg_reg_fat); 5340%} 5341 5342instruct loadConI(rRegI dst, immI src) 5343%{ 5344 match(Set dst src); 5345 5346 format %{ "movl $dst, $src\t# int" %} 5347 ins_encode(load_immI(dst, src)); 5348 ins_pipe(ialu_reg_fat); // XXX 5349%} 5350 5351instruct loadConI0(rRegI dst, immI0 src, rFlagsReg cr) 5352%{ 5353 match(Set dst src); 5354 effect(KILL cr); 5355 5356 ins_cost(50); 5357 format %{ "xorl $dst, $dst\t# int" %} 5358 opcode(0x33); /* + rd */ 5359 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5360 ins_pipe(ialu_reg); 5361%} 5362 5363instruct loadConL(rRegL dst, immL src) 5364%{ 5365 match(Set dst src); 5366 5367 ins_cost(150); 5368 format %{ "movq $dst, $src\t# long" %} 5369 ins_encode(load_immL(dst, src)); 5370 ins_pipe(ialu_reg); 5371%} 5372 5373instruct loadConL0(rRegL dst, immL0 src, rFlagsReg cr) 5374%{ 5375 match(Set dst src); 5376 effect(KILL cr); 5377 5378 ins_cost(50); 5379 format %{ "xorl $dst, $dst\t# long" %} 5380 opcode(0x33); /* + rd */ 5381 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5382 ins_pipe(ialu_reg); // XXX 5383%} 5384 5385instruct loadConUL32(rRegL dst, immUL32 src) 5386%{ 5387 match(Set dst src); 5388 5389 ins_cost(60); 5390 format %{ "movl $dst, $src\t# long (unsigned 32-bit)" %} 5391 ins_encode(load_immUL32(dst, src)); 5392 ins_pipe(ialu_reg); 5393%} 5394 5395instruct loadConL32(rRegL dst, immL32 src) 5396%{ 5397 match(Set dst src); 5398 5399 ins_cost(70); 5400 format %{ "movq $dst, $src\t# long (32-bit)" %} 5401 ins_encode(load_immL32(dst, src)); 5402 ins_pipe(ialu_reg); 5403%} 5404 5405instruct loadConP(rRegP dst, immP con) %{ 5406 match(Set dst con); 5407 5408 format %{ "movq $dst, $con\t# ptr" %} 5409 ins_encode(load_immP(dst, con)); 5410 ins_pipe(ialu_reg_fat); // XXX 5411%} 5412 5413instruct loadConP0(rRegP dst, immP0 src, rFlagsReg cr) 5414%{ 5415 match(Set dst src); 5416 effect(KILL cr); 5417 5418 ins_cost(50); 5419 format %{ "xorl $dst, $dst\t# ptr" %} 5420 opcode(0x33); /* + rd */ 5421 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5422 ins_pipe(ialu_reg); 5423%} 5424 5425instruct loadConP31(rRegP dst, immP31 src, rFlagsReg cr) 5426%{ 5427 match(Set dst src); 5428 effect(KILL cr); 5429 5430 ins_cost(60); 5431 format %{ "movl $dst, $src\t# ptr (positive 32-bit)" %} 5432 ins_encode(load_immP31(dst, src)); 5433 ins_pipe(ialu_reg); 5434%} 5435 5436instruct loadConF(regF dst, immF con) %{ 5437 match(Set dst con); 5438 ins_cost(125); 5439 format %{ "movss $dst, [$constantaddress]\t# load from constant table: float=$con" %} 5440 ins_encode %{ 5441 __ movflt($dst$$XMMRegister, $constantaddress($con)); 5442 %} 5443 ins_pipe(pipe_slow); 5444%} 5445 5446instruct loadConN0(rRegN dst, immN0 src, rFlagsReg cr) %{ 5447 match(Set dst src); 5448 effect(KILL cr); 5449 format %{ "xorq $dst, $src\t# compressed NULL ptr" %} 5450 ins_encode %{ 5451 __ xorq($dst$$Register, $dst$$Register); 5452 %} 5453 ins_pipe(ialu_reg); 5454%} 5455 5456instruct loadConN(rRegN dst, immN src) %{ 5457 match(Set dst src); 5458 5459 ins_cost(125); 5460 format %{ "movl $dst, $src\t# compressed ptr" %} 5461 ins_encode %{ 5462 address con = (address)$src$$constant; 5463 if (con == NULL) { 5464 ShouldNotReachHere(); 5465 } else { 5466 __ set_narrow_oop($dst$$Register, (jobject)$src$$constant); 5467 } 5468 %} 5469 ins_pipe(ialu_reg_fat); // XXX 5470%} 5471 5472instruct loadConF0(regF dst, immF0 src) 5473%{ 5474 match(Set dst src); 5475 ins_cost(100); 5476 5477 format %{ "xorps $dst, $dst\t# float 0.0" %} 5478 ins_encode %{ 5479 __ xorps($dst$$XMMRegister, $dst$$XMMRegister); 5480 %} 5481 ins_pipe(pipe_slow); 5482%} 5483 5484// Use the same format since predicate() can not be used here. 5485instruct loadConD(regD dst, immD con) %{ 5486 match(Set dst con); 5487 ins_cost(125); 5488 format %{ "movsd $dst, [$constantaddress]\t# load from constant table: double=$con" %} 5489 ins_encode %{ 5490 __ movdbl($dst$$XMMRegister, $constantaddress($con)); 5491 %} 5492 ins_pipe(pipe_slow); 5493%} 5494 5495instruct loadConD0(regD dst, immD0 src) 5496%{ 5497 match(Set dst src); 5498 ins_cost(100); 5499 5500 format %{ "xorpd $dst, $dst\t# double 0.0" %} 5501 ins_encode %{ 5502 __ xorpd ($dst$$XMMRegister, $dst$$XMMRegister); 5503 %} 5504 ins_pipe(pipe_slow); 5505%} 5506 5507instruct loadSSI(rRegI dst, stackSlotI src) 5508%{ 5509 match(Set dst src); 5510 5511 ins_cost(125); 5512 format %{ "movl $dst, $src\t# int stk" %} 5513 opcode(0x8B); 5514 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 5515 ins_pipe(ialu_reg_mem); 5516%} 5517 5518instruct loadSSL(rRegL dst, stackSlotL src) 5519%{ 5520 match(Set dst src); 5521 5522 ins_cost(125); 5523 format %{ "movq $dst, $src\t# long stk" %} 5524 opcode(0x8B); 5525 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 5526 ins_pipe(ialu_reg_mem); 5527%} 5528 5529instruct loadSSP(rRegP dst, stackSlotP src) 5530%{ 5531 match(Set dst src); 5532 5533 ins_cost(125); 5534 format %{ "movq $dst, $src\t# ptr stk" %} 5535 opcode(0x8B); 5536 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 5537 ins_pipe(ialu_reg_mem); 5538%} 5539 5540instruct loadSSF(regF dst, stackSlotF src) 5541%{ 5542 match(Set dst src); 5543 5544 ins_cost(125); 5545 format %{ "movss $dst, $src\t# float stk" %} 5546 ins_encode %{ 5547 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 5548 %} 5549 ins_pipe(pipe_slow); // XXX 5550%} 5551 5552// Use the same format since predicate() can not be used here. 5553instruct loadSSD(regD dst, stackSlotD src) 5554%{ 5555 match(Set dst src); 5556 5557 ins_cost(125); 5558 format %{ "movsd $dst, $src\t# double stk" %} 5559 ins_encode %{ 5560 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 5561 %} 5562 ins_pipe(pipe_slow); // XXX 5563%} 5564 5565// Prefetch instructions. 5566// Must be safe to execute with invalid address (cannot fault). 5567 5568instruct prefetchr( memory mem ) %{ 5569 predicate(ReadPrefetchInstr==3); 5570 match(PrefetchRead mem); 5571 ins_cost(125); 5572 5573 format %{ "PREFETCHR $mem\t# Prefetch into level 1 cache" %} 5574 ins_encode %{ 5575 __ prefetchr($mem$$Address); 5576 %} 5577 ins_pipe(ialu_mem); 5578%} 5579 5580instruct prefetchrNTA( memory mem ) %{ 5581 predicate(ReadPrefetchInstr==0); 5582 match(PrefetchRead mem); 5583 ins_cost(125); 5584 5585 format %{ "PREFETCHNTA $mem\t# Prefetch into non-temporal cache for read" %} 5586 ins_encode %{ 5587 __ prefetchnta($mem$$Address); 5588 %} 5589 ins_pipe(ialu_mem); 5590%} 5591 5592instruct prefetchrT0( memory mem ) %{ 5593 predicate(ReadPrefetchInstr==1); 5594 match(PrefetchRead mem); 5595 ins_cost(125); 5596 5597 format %{ "PREFETCHT0 $mem\t# prefetch into L1 and L2 caches for read" %} 5598 ins_encode %{ 5599 __ prefetcht0($mem$$Address); 5600 %} 5601 ins_pipe(ialu_mem); 5602%} 5603 5604instruct prefetchrT2( memory mem ) %{ 5605 predicate(ReadPrefetchInstr==2); 5606 match(PrefetchRead mem); 5607 ins_cost(125); 5608 5609 format %{ "PREFETCHT2 $mem\t# prefetch into L2 caches for read" %} 5610 ins_encode %{ 5611 __ prefetcht2($mem$$Address); 5612 %} 5613 ins_pipe(ialu_mem); 5614%} 5615 5616instruct prefetchwNTA( memory mem ) %{ 5617 match(PrefetchWrite mem); 5618 ins_cost(125); 5619 5620 format %{ "PREFETCHNTA $mem\t# Prefetch to non-temporal cache for write" %} 5621 ins_encode %{ 5622 __ prefetchnta($mem$$Address); 5623 %} 5624 ins_pipe(ialu_mem); 5625%} 5626 5627// Prefetch instructions for allocation. 5628 5629instruct prefetchAlloc( memory mem ) %{ 5630 predicate(AllocatePrefetchInstr==3); 5631 match(PrefetchAllocation mem); 5632 ins_cost(125); 5633 5634 format %{ "PREFETCHW $mem\t# Prefetch allocation into level 1 cache and mark modified" %} 5635 ins_encode %{ 5636 __ prefetchw($mem$$Address); 5637 %} 5638 ins_pipe(ialu_mem); 5639%} 5640 5641instruct prefetchAllocNTA( memory mem ) %{ 5642 predicate(AllocatePrefetchInstr==0); 5643 match(PrefetchAllocation mem); 5644 ins_cost(125); 5645 5646 format %{ "PREFETCHNTA $mem\t# Prefetch allocation to non-temporal cache for write" %} 5647 ins_encode %{ 5648 __ prefetchnta($mem$$Address); 5649 %} 5650 ins_pipe(ialu_mem); 5651%} 5652 5653instruct prefetchAllocT0( memory mem ) %{ 5654 predicate(AllocatePrefetchInstr==1); 5655 match(PrefetchAllocation mem); 5656 ins_cost(125); 5657 5658 format %{ "PREFETCHT0 $mem\t# Prefetch allocation to level 1 and 2 caches for write" %} 5659 ins_encode %{ 5660 __ prefetcht0($mem$$Address); 5661 %} 5662 ins_pipe(ialu_mem); 5663%} 5664 5665instruct prefetchAllocT2( memory mem ) %{ 5666 predicate(AllocatePrefetchInstr==2); 5667 match(PrefetchAllocation mem); 5668 ins_cost(125); 5669 5670 format %{ "PREFETCHT2 $mem\t# Prefetch allocation to level 2 cache for write" %} 5671 ins_encode %{ 5672 __ prefetcht2($mem$$Address); 5673 %} 5674 ins_pipe(ialu_mem); 5675%} 5676 5677//----------Store Instructions------------------------------------------------- 5678 5679// Store Byte 5680instruct storeB(memory mem, rRegI src) 5681%{ 5682 match(Set mem (StoreB mem src)); 5683 5684 ins_cost(125); // XXX 5685 format %{ "movb $mem, $src\t# byte" %} 5686 opcode(0x88); 5687 ins_encode(REX_breg_mem(src, mem), OpcP, reg_mem(src, mem)); 5688 ins_pipe(ialu_mem_reg); 5689%} 5690 5691// Store Char/Short 5692instruct storeC(memory mem, rRegI src) 5693%{ 5694 match(Set mem (StoreC mem src)); 5695 5696 ins_cost(125); // XXX 5697 format %{ "movw $mem, $src\t# char/short" %} 5698 opcode(0x89); 5699 ins_encode(SizePrefix, REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 5700 ins_pipe(ialu_mem_reg); 5701%} 5702 5703// Store Integer 5704instruct storeI(memory mem, rRegI src) 5705%{ 5706 match(Set mem (StoreI mem src)); 5707 5708 ins_cost(125); // XXX 5709 format %{ "movl $mem, $src\t# int" %} 5710 opcode(0x89); 5711 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 5712 ins_pipe(ialu_mem_reg); 5713%} 5714 5715// Store Long 5716instruct storeL(memory mem, rRegL src) 5717%{ 5718 match(Set mem (StoreL mem src)); 5719 5720 ins_cost(125); // XXX 5721 format %{ "movq $mem, $src\t# long" %} 5722 opcode(0x89); 5723 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 5724 ins_pipe(ialu_mem_reg); // XXX 5725%} 5726 5727// Store Pointer 5728instruct storeP(memory mem, any_RegP src) 5729%{ 5730 match(Set mem (StoreP mem src)); 5731 5732 ins_cost(125); // XXX 5733 format %{ "movq $mem, $src\t# ptr" %} 5734 opcode(0x89); 5735 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 5736 ins_pipe(ialu_mem_reg); 5737%} 5738 5739instruct storeImmP0(memory mem, immP0 zero) 5740%{ 5741 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL)); 5742 match(Set mem (StoreP mem zero)); 5743 5744 ins_cost(125); // XXX 5745 format %{ "movq $mem, R12\t# ptr (R12_heapbase==0)" %} 5746 ins_encode %{ 5747 __ movq($mem$$Address, r12); 5748 %} 5749 ins_pipe(ialu_mem_reg); 5750%} 5751 5752// Store NULL Pointer, mark word, or other simple pointer constant. 5753instruct storeImmP(memory mem, immP31 src) 5754%{ 5755 match(Set mem (StoreP mem src)); 5756 5757 ins_cost(150); // XXX 5758 format %{ "movq $mem, $src\t# ptr" %} 5759 opcode(0xC7); /* C7 /0 */ 5760 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 5761 ins_pipe(ialu_mem_imm); 5762%} 5763 5764// Store Compressed Pointer 5765instruct storeN(memory mem, rRegN src) 5766%{ 5767 match(Set mem (StoreN mem src)); 5768 5769 ins_cost(125); // XXX 5770 format %{ "movl $mem, $src\t# compressed ptr" %} 5771 ins_encode %{ 5772 __ movl($mem$$Address, $src$$Register); 5773 %} 5774 ins_pipe(ialu_mem_reg); 5775%} 5776 5777instruct storeImmN0(memory mem, immN0 zero) 5778%{ 5779 predicate(Universe::narrow_oop_base() == NULL); 5780 match(Set mem (StoreN mem zero)); 5781 5782 ins_cost(125); // XXX 5783 format %{ "movl $mem, R12\t# compressed ptr (R12_heapbase==0)" %} 5784 ins_encode %{ 5785 __ movl($mem$$Address, r12); 5786 %} 5787 ins_pipe(ialu_mem_reg); 5788%} 5789 5790instruct storeImmN(memory mem, immN src) 5791%{ 5792 match(Set mem (StoreN mem src)); 5793 5794 ins_cost(150); // XXX 5795 format %{ "movl $mem, $src\t# compressed ptr" %} 5796 ins_encode %{ 5797 address con = (address)$src$$constant; 5798 if (con == NULL) { 5799 __ movl($mem$$Address, (int32_t)0); 5800 } else { 5801 __ set_narrow_oop($mem$$Address, (jobject)$src$$constant); 5802 } 5803 %} 5804 ins_pipe(ialu_mem_imm); 5805%} 5806 5807// Store Integer Immediate 5808instruct storeImmI0(memory mem, immI0 zero) 5809%{ 5810 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL)); 5811 match(Set mem (StoreI mem zero)); 5812 5813 ins_cost(125); // XXX 5814 format %{ "movl $mem, R12\t# int (R12_heapbase==0)" %} 5815 ins_encode %{ 5816 __ movl($mem$$Address, r12); 5817 %} 5818 ins_pipe(ialu_mem_reg); 5819%} 5820 5821instruct storeImmI(memory mem, immI src) 5822%{ 5823 match(Set mem (StoreI mem src)); 5824 5825 ins_cost(150); 5826 format %{ "movl $mem, $src\t# int" %} 5827 opcode(0xC7); /* C7 /0 */ 5828 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 5829 ins_pipe(ialu_mem_imm); 5830%} 5831 5832// Store Long Immediate 5833instruct storeImmL0(memory mem, immL0 zero) 5834%{ 5835 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL)); 5836 match(Set mem (StoreL mem zero)); 5837 5838 ins_cost(125); // XXX 5839 format %{ "movq $mem, R12\t# long (R12_heapbase==0)" %} 5840 ins_encode %{ 5841 __ movq($mem$$Address, r12); 5842 %} 5843 ins_pipe(ialu_mem_reg); 5844%} 5845 5846instruct storeImmL(memory mem, immL32 src) 5847%{ 5848 match(Set mem (StoreL mem src)); 5849 5850 ins_cost(150); 5851 format %{ "movq $mem, $src\t# long" %} 5852 opcode(0xC7); /* C7 /0 */ 5853 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 5854 ins_pipe(ialu_mem_imm); 5855%} 5856 5857// Store Short/Char Immediate 5858instruct storeImmC0(memory mem, immI0 zero) 5859%{ 5860 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL)); 5861 match(Set mem (StoreC mem zero)); 5862 5863 ins_cost(125); // XXX 5864 format %{ "movw $mem, R12\t# short/char (R12_heapbase==0)" %} 5865 ins_encode %{ 5866 __ movw($mem$$Address, r12); 5867 %} 5868 ins_pipe(ialu_mem_reg); 5869%} 5870 5871instruct storeImmI16(memory mem, immI16 src) 5872%{ 5873 predicate(UseStoreImmI16); 5874 match(Set mem (StoreC mem src)); 5875 5876 ins_cost(150); 5877 format %{ "movw $mem, $src\t# short/char" %} 5878 opcode(0xC7); /* C7 /0 Same as 32 store immediate with prefix */ 5879 ins_encode(SizePrefix, REX_mem(mem), OpcP, RM_opc_mem(0x00, mem),Con16(src)); 5880 ins_pipe(ialu_mem_imm); 5881%} 5882 5883// Store Byte Immediate 5884instruct storeImmB0(memory mem, immI0 zero) 5885%{ 5886 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL)); 5887 match(Set mem (StoreB mem zero)); 5888 5889 ins_cost(125); // XXX 5890 format %{ "movb $mem, R12\t# short/char (R12_heapbase==0)" %} 5891 ins_encode %{ 5892 __ movb($mem$$Address, r12); 5893 %} 5894 ins_pipe(ialu_mem_reg); 5895%} 5896 5897instruct storeImmB(memory mem, immI8 src) 5898%{ 5899 match(Set mem (StoreB mem src)); 5900 5901 ins_cost(150); // XXX 5902 format %{ "movb $mem, $src\t# byte" %} 5903 opcode(0xC6); /* C6 /0 */ 5904 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src)); 5905 ins_pipe(ialu_mem_imm); 5906%} 5907 5908// Store CMS card-mark Immediate 5909instruct storeImmCM0_reg(memory mem, immI0 zero) 5910%{ 5911 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL)); 5912 match(Set mem (StoreCM mem zero)); 5913 5914 ins_cost(125); // XXX 5915 format %{ "movb $mem, R12\t# CMS card-mark byte 0 (R12_heapbase==0)" %} 5916 ins_encode %{ 5917 __ movb($mem$$Address, r12); 5918 %} 5919 ins_pipe(ialu_mem_reg); 5920%} 5921 5922instruct storeImmCM0(memory mem, immI0 src) 5923%{ 5924 match(Set mem (StoreCM mem src)); 5925 5926 ins_cost(150); // XXX 5927 format %{ "movb $mem, $src\t# CMS card-mark byte 0" %} 5928 opcode(0xC6); /* C6 /0 */ 5929 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src)); 5930 ins_pipe(ialu_mem_imm); 5931%} 5932 5933// Store Float 5934instruct storeF(memory mem, regF src) 5935%{ 5936 match(Set mem (StoreF mem src)); 5937 5938 ins_cost(95); // XXX 5939 format %{ "movss $mem, $src\t# float" %} 5940 ins_encode %{ 5941 __ movflt($mem$$Address, $src$$XMMRegister); 5942 %} 5943 ins_pipe(pipe_slow); // XXX 5944%} 5945 5946// Store immediate Float value (it is faster than store from XMM register) 5947instruct storeF0(memory mem, immF0 zero) 5948%{ 5949 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL)); 5950 match(Set mem (StoreF mem zero)); 5951 5952 ins_cost(25); // XXX 5953 format %{ "movl $mem, R12\t# float 0. (R12_heapbase==0)" %} 5954 ins_encode %{ 5955 __ movl($mem$$Address, r12); 5956 %} 5957 ins_pipe(ialu_mem_reg); 5958%} 5959 5960instruct storeF_imm(memory mem, immF src) 5961%{ 5962 match(Set mem (StoreF mem src)); 5963 5964 ins_cost(50); 5965 format %{ "movl $mem, $src\t# float" %} 5966 opcode(0xC7); /* C7 /0 */ 5967 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src)); 5968 ins_pipe(ialu_mem_imm); 5969%} 5970 5971// Store Double 5972instruct storeD(memory mem, regD src) 5973%{ 5974 match(Set mem (StoreD mem src)); 5975 5976 ins_cost(95); // XXX 5977 format %{ "movsd $mem, $src\t# double" %} 5978 ins_encode %{ 5979 __ movdbl($mem$$Address, $src$$XMMRegister); 5980 %} 5981 ins_pipe(pipe_slow); // XXX 5982%} 5983 5984// Store immediate double 0.0 (it is faster than store from XMM register) 5985instruct storeD0_imm(memory mem, immD0 src) 5986%{ 5987 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL)); 5988 match(Set mem (StoreD mem src)); 5989 5990 ins_cost(50); 5991 format %{ "movq $mem, $src\t# double 0." %} 5992 opcode(0xC7); /* C7 /0 */ 5993 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src)); 5994 ins_pipe(ialu_mem_imm); 5995%} 5996 5997instruct storeD0(memory mem, immD0 zero) 5998%{ 5999 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL)); 6000 match(Set mem (StoreD mem zero)); 6001 6002 ins_cost(25); // XXX 6003 format %{ "movq $mem, R12\t# double 0. (R12_heapbase==0)" %} 6004 ins_encode %{ 6005 __ movq($mem$$Address, r12); 6006 %} 6007 ins_pipe(ialu_mem_reg); 6008%} 6009 6010instruct storeSSI(stackSlotI dst, rRegI src) 6011%{ 6012 match(Set dst src); 6013 6014 ins_cost(100); 6015 format %{ "movl $dst, $src\t# int stk" %} 6016 opcode(0x89); 6017 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 6018 ins_pipe( ialu_mem_reg ); 6019%} 6020 6021instruct storeSSL(stackSlotL dst, rRegL src) 6022%{ 6023 match(Set dst src); 6024 6025 ins_cost(100); 6026 format %{ "movq $dst, $src\t# long stk" %} 6027 opcode(0x89); 6028 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 6029 ins_pipe(ialu_mem_reg); 6030%} 6031 6032instruct storeSSP(stackSlotP dst, rRegP src) 6033%{ 6034 match(Set dst src); 6035 6036 ins_cost(100); 6037 format %{ "movq $dst, $src\t# ptr stk" %} 6038 opcode(0x89); 6039 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 6040 ins_pipe(ialu_mem_reg); 6041%} 6042 6043instruct storeSSF(stackSlotF dst, regF src) 6044%{ 6045 match(Set dst src); 6046 6047 ins_cost(95); // XXX 6048 format %{ "movss $dst, $src\t# float stk" %} 6049 ins_encode %{ 6050 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 6051 %} 6052 ins_pipe(pipe_slow); // XXX 6053%} 6054 6055instruct storeSSD(stackSlotD dst, regD src) 6056%{ 6057 match(Set dst src); 6058 6059 ins_cost(95); // XXX 6060 format %{ "movsd $dst, $src\t# double stk" %} 6061 ins_encode %{ 6062 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 6063 %} 6064 ins_pipe(pipe_slow); // XXX 6065%} 6066 6067//----------BSWAP Instructions------------------------------------------------- 6068instruct bytes_reverse_int(rRegI dst) %{ 6069 match(Set dst (ReverseBytesI dst)); 6070 6071 format %{ "bswapl $dst" %} 6072 opcode(0x0F, 0xC8); /*Opcode 0F /C8 */ 6073 ins_encode( REX_reg(dst), OpcP, opc2_reg(dst) ); 6074 ins_pipe( ialu_reg ); 6075%} 6076 6077instruct bytes_reverse_long(rRegL dst) %{ 6078 match(Set dst (ReverseBytesL dst)); 6079 6080 format %{ "bswapq $dst" %} 6081 opcode(0x0F, 0xC8); /* Opcode 0F /C8 */ 6082 ins_encode( REX_reg_wide(dst), OpcP, opc2_reg(dst) ); 6083 ins_pipe( ialu_reg); 6084%} 6085 6086instruct bytes_reverse_unsigned_short(rRegI dst, rFlagsReg cr) %{ 6087 match(Set dst (ReverseBytesUS dst)); 6088 effect(KILL cr); 6089 6090 format %{ "bswapl $dst\n\t" 6091 "shrl $dst,16\n\t" %} 6092 ins_encode %{ 6093 __ bswapl($dst$$Register); 6094 __ shrl($dst$$Register, 16); 6095 %} 6096 ins_pipe( ialu_reg ); 6097%} 6098 6099instruct bytes_reverse_short(rRegI dst, rFlagsReg cr) %{ 6100 match(Set dst (ReverseBytesS dst)); 6101 effect(KILL cr); 6102 6103 format %{ "bswapl $dst\n\t" 6104 "sar $dst,16\n\t" %} 6105 ins_encode %{ 6106 __ bswapl($dst$$Register); 6107 __ sarl($dst$$Register, 16); 6108 %} 6109 ins_pipe( ialu_reg ); 6110%} 6111 6112//---------- Zeros Count Instructions ------------------------------------------ 6113 6114instruct countLeadingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6115 predicate(UseCountLeadingZerosInstruction); 6116 match(Set dst (CountLeadingZerosI src)); 6117 effect(KILL cr); 6118 6119 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 6120 ins_encode %{ 6121 __ lzcntl($dst$$Register, $src$$Register); 6122 %} 6123 ins_pipe(ialu_reg); 6124%} 6125 6126instruct countLeadingZerosI_bsr(rRegI dst, rRegI src, rFlagsReg cr) %{ 6127 predicate(!UseCountLeadingZerosInstruction); 6128 match(Set dst (CountLeadingZerosI src)); 6129 effect(KILL cr); 6130 6131 format %{ "bsrl $dst, $src\t# count leading zeros (int)\n\t" 6132 "jnz skip\n\t" 6133 "movl $dst, -1\n" 6134 "skip:\n\t" 6135 "negl $dst\n\t" 6136 "addl $dst, 31" %} 6137 ins_encode %{ 6138 Register Rdst = $dst$$Register; 6139 Register Rsrc = $src$$Register; 6140 Label skip; 6141 __ bsrl(Rdst, Rsrc); 6142 __ jccb(Assembler::notZero, skip); 6143 __ movl(Rdst, -1); 6144 __ bind(skip); 6145 __ negl(Rdst); 6146 __ addl(Rdst, BitsPerInt - 1); 6147 %} 6148 ins_pipe(ialu_reg); 6149%} 6150 6151instruct countLeadingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6152 predicate(UseCountLeadingZerosInstruction); 6153 match(Set dst (CountLeadingZerosL src)); 6154 effect(KILL cr); 6155 6156 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 6157 ins_encode %{ 6158 __ lzcntq($dst$$Register, $src$$Register); 6159 %} 6160 ins_pipe(ialu_reg); 6161%} 6162 6163instruct countLeadingZerosL_bsr(rRegI dst, rRegL src, rFlagsReg cr) %{ 6164 predicate(!UseCountLeadingZerosInstruction); 6165 match(Set dst (CountLeadingZerosL src)); 6166 effect(KILL cr); 6167 6168 format %{ "bsrq $dst, $src\t# count leading zeros (long)\n\t" 6169 "jnz skip\n\t" 6170 "movl $dst, -1\n" 6171 "skip:\n\t" 6172 "negl $dst\n\t" 6173 "addl $dst, 63" %} 6174 ins_encode %{ 6175 Register Rdst = $dst$$Register; 6176 Register Rsrc = $src$$Register; 6177 Label skip; 6178 __ bsrq(Rdst, Rsrc); 6179 __ jccb(Assembler::notZero, skip); 6180 __ movl(Rdst, -1); 6181 __ bind(skip); 6182 __ negl(Rdst); 6183 __ addl(Rdst, BitsPerLong - 1); 6184 %} 6185 ins_pipe(ialu_reg); 6186%} 6187 6188instruct countTrailingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6189 match(Set dst (CountTrailingZerosI src)); 6190 effect(KILL cr); 6191 6192 format %{ "bsfl $dst, $src\t# count trailing zeros (int)\n\t" 6193 "jnz done\n\t" 6194 "movl $dst, 32\n" 6195 "done:" %} 6196 ins_encode %{ 6197 Register Rdst = $dst$$Register; 6198 Label done; 6199 __ bsfl(Rdst, $src$$Register); 6200 __ jccb(Assembler::notZero, done); 6201 __ movl(Rdst, BitsPerInt); 6202 __ bind(done); 6203 %} 6204 ins_pipe(ialu_reg); 6205%} 6206 6207instruct countTrailingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6208 match(Set dst (CountTrailingZerosL src)); 6209 effect(KILL cr); 6210 6211 format %{ "bsfq $dst, $src\t# count trailing zeros (long)\n\t" 6212 "jnz done\n\t" 6213 "movl $dst, 64\n" 6214 "done:" %} 6215 ins_encode %{ 6216 Register Rdst = $dst$$Register; 6217 Label done; 6218 __ bsfq(Rdst, $src$$Register); 6219 __ jccb(Assembler::notZero, done); 6220 __ movl(Rdst, BitsPerLong); 6221 __ bind(done); 6222 %} 6223 ins_pipe(ialu_reg); 6224%} 6225 6226 6227//---------- Population Count Instructions ------------------------------------- 6228 6229instruct popCountI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6230 predicate(UsePopCountInstruction); 6231 match(Set dst (PopCountI src)); 6232 effect(KILL cr); 6233 6234 format %{ "popcnt $dst, $src" %} 6235 ins_encode %{ 6236 __ popcntl($dst$$Register, $src$$Register); 6237 %} 6238 ins_pipe(ialu_reg); 6239%} 6240 6241instruct popCountI_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 6242 predicate(UsePopCountInstruction); 6243 match(Set dst (PopCountI (LoadI mem))); 6244 effect(KILL cr); 6245 6246 format %{ "popcnt $dst, $mem" %} 6247 ins_encode %{ 6248 __ popcntl($dst$$Register, $mem$$Address); 6249 %} 6250 ins_pipe(ialu_reg); 6251%} 6252 6253// Note: Long.bitCount(long) returns an int. 6254instruct popCountL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6255 predicate(UsePopCountInstruction); 6256 match(Set dst (PopCountL src)); 6257 effect(KILL cr); 6258 6259 format %{ "popcnt $dst, $src" %} 6260 ins_encode %{ 6261 __ popcntq($dst$$Register, $src$$Register); 6262 %} 6263 ins_pipe(ialu_reg); 6264%} 6265 6266// Note: Long.bitCount(long) returns an int. 6267instruct popCountL_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 6268 predicate(UsePopCountInstruction); 6269 match(Set dst (PopCountL (LoadL mem))); 6270 effect(KILL cr); 6271 6272 format %{ "popcnt $dst, $mem" %} 6273 ins_encode %{ 6274 __ popcntq($dst$$Register, $mem$$Address); 6275 %} 6276 ins_pipe(ialu_reg); 6277%} 6278 6279 6280//----------MemBar Instructions----------------------------------------------- 6281// Memory barrier flavors 6282 6283instruct membar_acquire() 6284%{ 6285 match(MemBarAcquire); 6286 ins_cost(0); 6287 6288 size(0); 6289 format %{ "MEMBAR-acquire ! (empty encoding)" %} 6290 ins_encode(); 6291 ins_pipe(empty); 6292%} 6293 6294instruct membar_acquire_lock() 6295%{ 6296 match(MemBarAcquireLock); 6297 ins_cost(0); 6298 6299 size(0); 6300 format %{ "MEMBAR-acquire (prior CMPXCHG in FastLock so empty encoding)" %} 6301 ins_encode(); 6302 ins_pipe(empty); 6303%} 6304 6305instruct membar_release() 6306%{ 6307 match(MemBarRelease); 6308 ins_cost(0); 6309 6310 size(0); 6311 format %{ "MEMBAR-release ! (empty encoding)" %} 6312 ins_encode(); 6313 ins_pipe(empty); 6314%} 6315 6316instruct membar_release_lock() 6317%{ 6318 match(MemBarReleaseLock); 6319 ins_cost(0); 6320 6321 size(0); 6322 format %{ "MEMBAR-release (a FastUnlock follows so empty encoding)" %} 6323 ins_encode(); 6324 ins_pipe(empty); 6325%} 6326 6327instruct membar_volatile(rFlagsReg cr) %{ 6328 match(MemBarVolatile); 6329 effect(KILL cr); 6330 ins_cost(400); 6331 6332 format %{ 6333 $$template 6334 if (os::is_MP()) { 6335 $$emit$$"lock addl [rsp + #0], 0\t! membar_volatile" 6336 } else { 6337 $$emit$$"MEMBAR-volatile ! (empty encoding)" 6338 } 6339 %} 6340 ins_encode %{ 6341 __ membar(Assembler::StoreLoad); 6342 %} 6343 ins_pipe(pipe_slow); 6344%} 6345 6346instruct unnecessary_membar_volatile() 6347%{ 6348 match(MemBarVolatile); 6349 predicate(Matcher::post_store_load_barrier(n)); 6350 ins_cost(0); 6351 6352 size(0); 6353 format %{ "MEMBAR-volatile (unnecessary so empty encoding)" %} 6354 ins_encode(); 6355 ins_pipe(empty); 6356%} 6357 6358instruct membar_storestore() %{ 6359 match(MemBarStoreStore); 6360 ins_cost(0); 6361 6362 size(0); 6363 format %{ "MEMBAR-storestore (empty encoding)" %} 6364 ins_encode( ); 6365 ins_pipe(empty); 6366%} 6367 6368//----------Move Instructions-------------------------------------------------- 6369 6370instruct castX2P(rRegP dst, rRegL src) 6371%{ 6372 match(Set dst (CastX2P src)); 6373 6374 format %{ "movq $dst, $src\t# long->ptr" %} 6375 ins_encode %{ 6376 if ($dst$$reg != $src$$reg) { 6377 __ movptr($dst$$Register, $src$$Register); 6378 } 6379 %} 6380 ins_pipe(ialu_reg_reg); // XXX 6381%} 6382 6383instruct castP2X(rRegL dst, rRegP src) 6384%{ 6385 match(Set dst (CastP2X src)); 6386 6387 format %{ "movq $dst, $src\t# ptr -> long" %} 6388 ins_encode %{ 6389 if ($dst$$reg != $src$$reg) { 6390 __ movptr($dst$$Register, $src$$Register); 6391 } 6392 %} 6393 ins_pipe(ialu_reg_reg); // XXX 6394%} 6395 6396// Convert oop into int for vectors alignment masking 6397instruct convP2I(rRegI dst, rRegP src) 6398%{ 6399 match(Set dst (ConvL2I (CastP2X src))); 6400 6401 format %{ "movl $dst, $src\t# ptr -> int" %} 6402 ins_encode %{ 6403 __ movl($dst$$Register, $src$$Register); 6404 %} 6405 ins_pipe(ialu_reg_reg); // XXX 6406%} 6407 6408// Convert compressed oop into int for vectors alignment masking 6409// in case of 32bit oops (heap < 4Gb). 6410instruct convN2I(rRegI dst, rRegN src) 6411%{ 6412 predicate(Universe::narrow_oop_shift() == 0); 6413 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 6414 6415 format %{ "movl $dst, $src\t# compressed ptr -> int" %} 6416 ins_encode %{ 6417 __ movl($dst$$Register, $src$$Register); 6418 %} 6419 ins_pipe(ialu_reg_reg); // XXX 6420%} 6421 6422// Convert oop pointer into compressed form 6423instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{ 6424 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 6425 match(Set dst (EncodeP src)); 6426 effect(KILL cr); 6427 format %{ "encode_heap_oop $dst,$src" %} 6428 ins_encode %{ 6429 Register s = $src$$Register; 6430 Register d = $dst$$Register; 6431 if (s != d) { 6432 __ movq(d, s); 6433 } 6434 __ encode_heap_oop(d); 6435 %} 6436 ins_pipe(ialu_reg_long); 6437%} 6438 6439instruct encodeHeapOop_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6440 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 6441 match(Set dst (EncodeP src)); 6442 effect(KILL cr); 6443 format %{ "encode_heap_oop_not_null $dst,$src" %} 6444 ins_encode %{ 6445 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 6446 %} 6447 ins_pipe(ialu_reg_long); 6448%} 6449 6450instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{ 6451 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 6452 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 6453 match(Set dst (DecodeN src)); 6454 effect(KILL cr); 6455 format %{ "decode_heap_oop $dst,$src" %} 6456 ins_encode %{ 6457 Register s = $src$$Register; 6458 Register d = $dst$$Register; 6459 if (s != d) { 6460 __ movq(d, s); 6461 } 6462 __ decode_heap_oop(d); 6463 %} 6464 ins_pipe(ialu_reg_long); 6465%} 6466 6467instruct decodeHeapOop_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6468 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 6469 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 6470 match(Set dst (DecodeN src)); 6471 effect(KILL cr); 6472 format %{ "decode_heap_oop_not_null $dst,$src" %} 6473 ins_encode %{ 6474 Register s = $src$$Register; 6475 Register d = $dst$$Register; 6476 if (s != d) { 6477 __ decode_heap_oop_not_null(d, s); 6478 } else { 6479 __ decode_heap_oop_not_null(d); 6480 } 6481 %} 6482 ins_pipe(ialu_reg_long); 6483%} 6484 6485 6486//----------Conditional Move--------------------------------------------------- 6487// Jump 6488// dummy instruction for generating temp registers 6489instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{ 6490 match(Jump (LShiftL switch_val shift)); 6491 ins_cost(350); 6492 predicate(false); 6493 effect(TEMP dest); 6494 6495 format %{ "leaq $dest, [$constantaddress]\n\t" 6496 "jmp [$dest + $switch_val << $shift]\n\t" %} 6497 ins_encode %{ 6498 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6499 // to do that and the compiler is using that register as one it can allocate. 6500 // So we build it all by hand. 6501 // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant); 6502 // ArrayAddress dispatch(table, index); 6503 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant); 6504 __ lea($dest$$Register, $constantaddress); 6505 __ jmp(dispatch); 6506 %} 6507 ins_pipe(pipe_jmp); 6508%} 6509 6510instruct jumpXtnd_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{ 6511 match(Jump (AddL (LShiftL switch_val shift) offset)); 6512 ins_cost(350); 6513 effect(TEMP dest); 6514 6515 format %{ "leaq $dest, [$constantaddress]\n\t" 6516 "jmp [$dest + $switch_val << $shift + $offset]\n\t" %} 6517 ins_encode %{ 6518 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6519 // to do that and the compiler is using that register as one it can allocate. 6520 // So we build it all by hand. 6521 // Address index(noreg, switch_reg, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6522 // ArrayAddress dispatch(table, index); 6523 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6524 __ lea($dest$$Register, $constantaddress); 6525 __ jmp(dispatch); 6526 %} 6527 ins_pipe(pipe_jmp); 6528%} 6529 6530instruct jumpXtnd(rRegL switch_val, rRegI dest) %{ 6531 match(Jump switch_val); 6532 ins_cost(350); 6533 effect(TEMP dest); 6534 6535 format %{ "leaq $dest, [$constantaddress]\n\t" 6536 "jmp [$dest + $switch_val]\n\t" %} 6537 ins_encode %{ 6538 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6539 // to do that and the compiler is using that register as one it can allocate. 6540 // So we build it all by hand. 6541 // Address index(noreg, switch_reg, Address::times_1); 6542 // ArrayAddress dispatch(table, index); 6543 Address dispatch($dest$$Register, $switch_val$$Register, Address::times_1); 6544 __ lea($dest$$Register, $constantaddress); 6545 __ jmp(dispatch); 6546 %} 6547 ins_pipe(pipe_jmp); 6548%} 6549 6550// Conditional move 6551instruct cmovI_reg(rRegI dst, rRegI src, rFlagsReg cr, cmpOp cop) 6552%{ 6553 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6554 6555 ins_cost(200); // XXX 6556 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6557 opcode(0x0F, 0x40); 6558 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6559 ins_pipe(pipe_cmov_reg); 6560%} 6561 6562instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{ 6563 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6564 6565 ins_cost(200); // XXX 6566 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6567 opcode(0x0F, 0x40); 6568 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6569 ins_pipe(pipe_cmov_reg); 6570%} 6571 6572instruct cmovI_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6573 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6574 ins_cost(200); 6575 expand %{ 6576 cmovI_regU(cop, cr, dst, src); 6577 %} 6578%} 6579 6580// Conditional move 6581instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{ 6582 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6583 6584 ins_cost(250); // XXX 6585 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6586 opcode(0x0F, 0x40); 6587 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6588 ins_pipe(pipe_cmov_mem); 6589%} 6590 6591// Conditional move 6592instruct cmovI_memU(cmpOpU cop, rFlagsRegU cr, rRegI dst, memory src) 6593%{ 6594 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6595 6596 ins_cost(250); // XXX 6597 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6598 opcode(0x0F, 0x40); 6599 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6600 ins_pipe(pipe_cmov_mem); 6601%} 6602 6603instruct cmovI_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, memory src) %{ 6604 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6605 ins_cost(250); 6606 expand %{ 6607 cmovI_memU(cop, cr, dst, src); 6608 %} 6609%} 6610 6611// Conditional move 6612instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop) 6613%{ 6614 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6615 6616 ins_cost(200); // XXX 6617 format %{ "cmovl$cop $dst, $src\t# signed, compressed ptr" %} 6618 opcode(0x0F, 0x40); 6619 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6620 ins_pipe(pipe_cmov_reg); 6621%} 6622 6623// Conditional move 6624instruct cmovN_regU(cmpOpU cop, rFlagsRegU cr, rRegN dst, rRegN src) 6625%{ 6626 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6627 6628 ins_cost(200); // XXX 6629 format %{ "cmovl$cop $dst, $src\t# unsigned, compressed ptr" %} 6630 opcode(0x0F, 0x40); 6631 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6632 ins_pipe(pipe_cmov_reg); 6633%} 6634 6635instruct cmovN_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6636 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6637 ins_cost(200); 6638 expand %{ 6639 cmovN_regU(cop, cr, dst, src); 6640 %} 6641%} 6642 6643// Conditional move 6644instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop) 6645%{ 6646 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6647 6648 ins_cost(200); // XXX 6649 format %{ "cmovq$cop $dst, $src\t# signed, ptr" %} 6650 opcode(0x0F, 0x40); 6651 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6652 ins_pipe(pipe_cmov_reg); // XXX 6653%} 6654 6655// Conditional move 6656instruct cmovP_regU(cmpOpU cop, rFlagsRegU cr, rRegP dst, rRegP src) 6657%{ 6658 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6659 6660 ins_cost(200); // XXX 6661 format %{ "cmovq$cop $dst, $src\t# unsigned, ptr" %} 6662 opcode(0x0F, 0x40); 6663 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6664 ins_pipe(pipe_cmov_reg); // XXX 6665%} 6666 6667instruct cmovP_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6668 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6669 ins_cost(200); 6670 expand %{ 6671 cmovP_regU(cop, cr, dst, src); 6672 %} 6673%} 6674 6675// DISABLED: Requires the ADLC to emit a bottom_type call that 6676// correctly meets the two pointer arguments; one is an incoming 6677// register but the other is a memory operand. ALSO appears to 6678// be buggy with implicit null checks. 6679// 6680//// Conditional move 6681//instruct cmovP_mem(cmpOp cop, rFlagsReg cr, rRegP dst, memory src) 6682//%{ 6683// match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); 6684// ins_cost(250); 6685// format %{ "CMOV$cop $dst,$src\t# ptr" %} 6686// opcode(0x0F,0x40); 6687// ins_encode( enc_cmov(cop), reg_mem( dst, src ) ); 6688// ins_pipe( pipe_cmov_mem ); 6689//%} 6690// 6691//// Conditional move 6692//instruct cmovP_memU(cmpOpU cop, rFlagsRegU cr, rRegP dst, memory src) 6693//%{ 6694// match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); 6695// ins_cost(250); 6696// format %{ "CMOV$cop $dst,$src\t# ptr" %} 6697// opcode(0x0F,0x40); 6698// ins_encode( enc_cmov(cop), reg_mem( dst, src ) ); 6699// ins_pipe( pipe_cmov_mem ); 6700//%} 6701 6702instruct cmovL_reg(cmpOp cop, rFlagsReg cr, rRegL dst, rRegL src) 6703%{ 6704 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6705 6706 ins_cost(200); // XXX 6707 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6708 opcode(0x0F, 0x40); 6709 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6710 ins_pipe(pipe_cmov_reg); // XXX 6711%} 6712 6713instruct cmovL_mem(cmpOp cop, rFlagsReg cr, rRegL dst, memory src) 6714%{ 6715 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6716 6717 ins_cost(200); // XXX 6718 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6719 opcode(0x0F, 0x40); 6720 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6721 ins_pipe(pipe_cmov_mem); // XXX 6722%} 6723 6724instruct cmovL_regU(cmpOpU cop, rFlagsRegU cr, rRegL dst, rRegL src) 6725%{ 6726 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6727 6728 ins_cost(200); // XXX 6729 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 6730 opcode(0x0F, 0x40); 6731 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6732 ins_pipe(pipe_cmov_reg); // XXX 6733%} 6734 6735instruct cmovL_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6736 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6737 ins_cost(200); 6738 expand %{ 6739 cmovL_regU(cop, cr, dst, src); 6740 %} 6741%} 6742 6743instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src) 6744%{ 6745 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6746 6747 ins_cost(200); // XXX 6748 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 6749 opcode(0x0F, 0x40); 6750 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6751 ins_pipe(pipe_cmov_mem); // XXX 6752%} 6753 6754instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{ 6755 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6756 ins_cost(200); 6757 expand %{ 6758 cmovL_memU(cop, cr, dst, src); 6759 %} 6760%} 6761 6762instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src) 6763%{ 6764 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6765 6766 ins_cost(200); // XXX 6767 format %{ "jn$cop skip\t# signed cmove float\n\t" 6768 "movss $dst, $src\n" 6769 "skip:" %} 6770 ins_encode %{ 6771 Label Lskip; 6772 // Invert sense of branch from sense of CMOV 6773 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6774 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 6775 __ bind(Lskip); 6776 %} 6777 ins_pipe(pipe_slow); 6778%} 6779 6780// instruct cmovF_mem(cmpOp cop, rFlagsReg cr, regF dst, memory src) 6781// %{ 6782// match(Set dst (CMoveF (Binary cop cr) (Binary dst (LoadL src)))); 6783 6784// ins_cost(200); // XXX 6785// format %{ "jn$cop skip\t# signed cmove float\n\t" 6786// "movss $dst, $src\n" 6787// "skip:" %} 6788// ins_encode(enc_cmovf_mem_branch(cop, dst, src)); 6789// ins_pipe(pipe_slow); 6790// %} 6791 6792instruct cmovF_regU(cmpOpU cop, rFlagsRegU cr, regF dst, regF src) 6793%{ 6794 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6795 6796 ins_cost(200); // XXX 6797 format %{ "jn$cop skip\t# unsigned cmove float\n\t" 6798 "movss $dst, $src\n" 6799 "skip:" %} 6800 ins_encode %{ 6801 Label Lskip; 6802 // Invert sense of branch from sense of CMOV 6803 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6804 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 6805 __ bind(Lskip); 6806 %} 6807 ins_pipe(pipe_slow); 6808%} 6809 6810instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{ 6811 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6812 ins_cost(200); 6813 expand %{ 6814 cmovF_regU(cop, cr, dst, src); 6815 %} 6816%} 6817 6818instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src) 6819%{ 6820 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6821 6822 ins_cost(200); // XXX 6823 format %{ "jn$cop skip\t# signed cmove double\n\t" 6824 "movsd $dst, $src\n" 6825 "skip:" %} 6826 ins_encode %{ 6827 Label Lskip; 6828 // Invert sense of branch from sense of CMOV 6829 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6830 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 6831 __ bind(Lskip); 6832 %} 6833 ins_pipe(pipe_slow); 6834%} 6835 6836instruct cmovD_regU(cmpOpU cop, rFlagsRegU cr, regD dst, regD src) 6837%{ 6838 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6839 6840 ins_cost(200); // XXX 6841 format %{ "jn$cop skip\t# unsigned cmove double\n\t" 6842 "movsd $dst, $src\n" 6843 "skip:" %} 6844 ins_encode %{ 6845 Label Lskip; 6846 // Invert sense of branch from sense of CMOV 6847 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6848 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 6849 __ bind(Lskip); 6850 %} 6851 ins_pipe(pipe_slow); 6852%} 6853 6854instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{ 6855 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6856 ins_cost(200); 6857 expand %{ 6858 cmovD_regU(cop, cr, dst, src); 6859 %} 6860%} 6861 6862//----------Arithmetic Instructions-------------------------------------------- 6863//----------Addition Instructions---------------------------------------------- 6864 6865instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 6866%{ 6867 match(Set dst (AddI dst src)); 6868 effect(KILL cr); 6869 6870 format %{ "addl $dst, $src\t# int" %} 6871 opcode(0x03); 6872 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 6873 ins_pipe(ialu_reg_reg); 6874%} 6875 6876instruct addI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 6877%{ 6878 match(Set dst (AddI dst src)); 6879 effect(KILL cr); 6880 6881 format %{ "addl $dst, $src\t# int" %} 6882 opcode(0x81, 0x00); /* /0 id */ 6883 ins_encode(OpcSErm(dst, src), Con8or32(src)); 6884 ins_pipe( ialu_reg ); 6885%} 6886 6887instruct addI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 6888%{ 6889 match(Set dst (AddI dst (LoadI src))); 6890 effect(KILL cr); 6891 6892 ins_cost(125); // XXX 6893 format %{ "addl $dst, $src\t# int" %} 6894 opcode(0x03); 6895 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 6896 ins_pipe(ialu_reg_mem); 6897%} 6898 6899instruct addI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 6900%{ 6901 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6902 effect(KILL cr); 6903 6904 ins_cost(150); // XXX 6905 format %{ "addl $dst, $src\t# int" %} 6906 opcode(0x01); /* Opcode 01 /r */ 6907 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 6908 ins_pipe(ialu_mem_reg); 6909%} 6910 6911instruct addI_mem_imm(memory dst, immI src, rFlagsReg cr) 6912%{ 6913 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6914 effect(KILL cr); 6915 6916 ins_cost(125); // XXX 6917 format %{ "addl $dst, $src\t# int" %} 6918 opcode(0x81); /* Opcode 81 /0 id */ 6919 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src)); 6920 ins_pipe(ialu_mem_imm); 6921%} 6922 6923instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr) 6924%{ 6925 predicate(UseIncDec); 6926 match(Set dst (AddI dst src)); 6927 effect(KILL cr); 6928 6929 format %{ "incl $dst\t# int" %} 6930 opcode(0xFF, 0x00); // FF /0 6931 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 6932 ins_pipe(ialu_reg); 6933%} 6934 6935instruct incI_mem(memory dst, immI1 src, rFlagsReg cr) 6936%{ 6937 predicate(UseIncDec); 6938 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6939 effect(KILL cr); 6940 6941 ins_cost(125); // XXX 6942 format %{ "incl $dst\t# int" %} 6943 opcode(0xFF); /* Opcode FF /0 */ 6944 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x00, dst)); 6945 ins_pipe(ialu_mem_imm); 6946%} 6947 6948// XXX why does that use AddI 6949instruct decI_rReg(rRegI dst, immI_M1 src, rFlagsReg cr) 6950%{ 6951 predicate(UseIncDec); 6952 match(Set dst (AddI dst src)); 6953 effect(KILL cr); 6954 6955 format %{ "decl $dst\t# int" %} 6956 opcode(0xFF, 0x01); // FF /1 6957 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 6958 ins_pipe(ialu_reg); 6959%} 6960 6961// XXX why does that use AddI 6962instruct decI_mem(memory dst, immI_M1 src, rFlagsReg cr) 6963%{ 6964 predicate(UseIncDec); 6965 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6966 effect(KILL cr); 6967 6968 ins_cost(125); // XXX 6969 format %{ "decl $dst\t# int" %} 6970 opcode(0xFF); /* Opcode FF /1 */ 6971 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x01, dst)); 6972 ins_pipe(ialu_mem_imm); 6973%} 6974 6975instruct leaI_rReg_immI(rRegI dst, rRegI src0, immI src1) 6976%{ 6977 match(Set dst (AddI src0 src1)); 6978 6979 ins_cost(110); 6980 format %{ "addr32 leal $dst, [$src0 + $src1]\t# int" %} 6981 opcode(0x8D); /* 0x8D /r */ 6982 ins_encode(Opcode(0x67), REX_reg_reg(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX 6983 ins_pipe(ialu_reg_reg); 6984%} 6985 6986instruct addL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 6987%{ 6988 match(Set dst (AddL dst src)); 6989 effect(KILL cr); 6990 6991 format %{ "addq $dst, $src\t# long" %} 6992 opcode(0x03); 6993 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 6994 ins_pipe(ialu_reg_reg); 6995%} 6996 6997instruct addL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 6998%{ 6999 match(Set dst (AddL dst src)); 7000 effect(KILL cr); 7001 7002 format %{ "addq $dst, $src\t# long" %} 7003 opcode(0x81, 0x00); /* /0 id */ 7004 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7005 ins_pipe( ialu_reg ); 7006%} 7007 7008instruct addL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 7009%{ 7010 match(Set dst (AddL dst (LoadL src))); 7011 effect(KILL cr); 7012 7013 ins_cost(125); // XXX 7014 format %{ "addq $dst, $src\t# long" %} 7015 opcode(0x03); 7016 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 7017 ins_pipe(ialu_reg_mem); 7018%} 7019 7020instruct addL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 7021%{ 7022 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7023 effect(KILL cr); 7024 7025 ins_cost(150); // XXX 7026 format %{ "addq $dst, $src\t# long" %} 7027 opcode(0x01); /* Opcode 01 /r */ 7028 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 7029 ins_pipe(ialu_mem_reg); 7030%} 7031 7032instruct addL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 7033%{ 7034 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7035 effect(KILL cr); 7036 7037 ins_cost(125); // XXX 7038 format %{ "addq $dst, $src\t# long" %} 7039 opcode(0x81); /* Opcode 81 /0 id */ 7040 ins_encode(REX_mem_wide(dst), 7041 OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src)); 7042 ins_pipe(ialu_mem_imm); 7043%} 7044 7045instruct incL_rReg(rRegI dst, immL1 src, rFlagsReg cr) 7046%{ 7047 predicate(UseIncDec); 7048 match(Set dst (AddL dst src)); 7049 effect(KILL cr); 7050 7051 format %{ "incq $dst\t# long" %} 7052 opcode(0xFF, 0x00); // FF /0 7053 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 7054 ins_pipe(ialu_reg); 7055%} 7056 7057instruct incL_mem(memory dst, immL1 src, rFlagsReg cr) 7058%{ 7059 predicate(UseIncDec); 7060 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7061 effect(KILL cr); 7062 7063 ins_cost(125); // XXX 7064 format %{ "incq $dst\t# long" %} 7065 opcode(0xFF); /* Opcode FF /0 */ 7066 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x00, dst)); 7067 ins_pipe(ialu_mem_imm); 7068%} 7069 7070// XXX why does that use AddL 7071instruct decL_rReg(rRegL dst, immL_M1 src, rFlagsReg cr) 7072%{ 7073 predicate(UseIncDec); 7074 match(Set dst (AddL dst src)); 7075 effect(KILL cr); 7076 7077 format %{ "decq $dst\t# long" %} 7078 opcode(0xFF, 0x01); // FF /1 7079 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 7080 ins_pipe(ialu_reg); 7081%} 7082 7083// XXX why does that use AddL 7084instruct decL_mem(memory dst, immL_M1 src, rFlagsReg cr) 7085%{ 7086 predicate(UseIncDec); 7087 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7088 effect(KILL cr); 7089 7090 ins_cost(125); // XXX 7091 format %{ "decq $dst\t# long" %} 7092 opcode(0xFF); /* Opcode FF /1 */ 7093 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x01, dst)); 7094 ins_pipe(ialu_mem_imm); 7095%} 7096 7097instruct leaL_rReg_immL(rRegL dst, rRegL src0, immL32 src1) 7098%{ 7099 match(Set dst (AddL src0 src1)); 7100 7101 ins_cost(110); 7102 format %{ "leaq $dst, [$src0 + $src1]\t# long" %} 7103 opcode(0x8D); /* 0x8D /r */ 7104 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX 7105 ins_pipe(ialu_reg_reg); 7106%} 7107 7108instruct addP_rReg(rRegP dst, rRegL src, rFlagsReg cr) 7109%{ 7110 match(Set dst (AddP dst src)); 7111 effect(KILL cr); 7112 7113 format %{ "addq $dst, $src\t# ptr" %} 7114 opcode(0x03); 7115 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7116 ins_pipe(ialu_reg_reg); 7117%} 7118 7119instruct addP_rReg_imm(rRegP dst, immL32 src, rFlagsReg cr) 7120%{ 7121 match(Set dst (AddP dst src)); 7122 effect(KILL cr); 7123 7124 format %{ "addq $dst, $src\t# ptr" %} 7125 opcode(0x81, 0x00); /* /0 id */ 7126 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7127 ins_pipe( ialu_reg ); 7128%} 7129 7130// XXX addP mem ops ???? 7131 7132instruct leaP_rReg_imm(rRegP dst, rRegP src0, immL32 src1) 7133%{ 7134 match(Set dst (AddP src0 src1)); 7135 7136 ins_cost(110); 7137 format %{ "leaq $dst, [$src0 + $src1]\t# ptr" %} 7138 opcode(0x8D); /* 0x8D /r */ 7139 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1));// XXX 7140 ins_pipe(ialu_reg_reg); 7141%} 7142 7143instruct checkCastPP(rRegP dst) 7144%{ 7145 match(Set dst (CheckCastPP dst)); 7146 7147 size(0); 7148 format %{ "# checkcastPP of $dst" %} 7149 ins_encode(/* empty encoding */); 7150 ins_pipe(empty); 7151%} 7152 7153instruct castPP(rRegP dst) 7154%{ 7155 match(Set dst (CastPP dst)); 7156 7157 size(0); 7158 format %{ "# castPP of $dst" %} 7159 ins_encode(/* empty encoding */); 7160 ins_pipe(empty); 7161%} 7162 7163instruct castII(rRegI dst) 7164%{ 7165 match(Set dst (CastII dst)); 7166 7167 size(0); 7168 format %{ "# castII of $dst" %} 7169 ins_encode(/* empty encoding */); 7170 ins_cost(0); 7171 ins_pipe(empty); 7172%} 7173 7174// LoadP-locked same as a regular LoadP when used with compare-swap 7175instruct loadPLocked(rRegP dst, memory mem) 7176%{ 7177 match(Set dst (LoadPLocked mem)); 7178 7179 ins_cost(125); // XXX 7180 format %{ "movq $dst, $mem\t# ptr locked" %} 7181 opcode(0x8B); 7182 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 7183 ins_pipe(ialu_reg_mem); // XXX 7184%} 7185 7186// Conditional-store of the updated heap-top. 7187// Used during allocation of the shared heap. 7188// Sets flags (EQ) on success. Implemented with a CMPXCHG on Intel. 7189 7190instruct storePConditional(memory heap_top_ptr, 7191 rax_RegP oldval, rRegP newval, 7192 rFlagsReg cr) 7193%{ 7194 match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval))); 7195 7196 format %{ "cmpxchgq $heap_top_ptr, $newval\t# (ptr) " 7197 "If rax == $heap_top_ptr then store $newval into $heap_top_ptr" %} 7198 opcode(0x0F, 0xB1); 7199 ins_encode(lock_prefix, 7200 REX_reg_mem_wide(newval, heap_top_ptr), 7201 OpcP, OpcS, 7202 reg_mem(newval, heap_top_ptr)); 7203 ins_pipe(pipe_cmpxchg); 7204%} 7205 7206// Conditional-store of an int value. 7207// ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG. 7208instruct storeIConditional(memory mem, rax_RegI oldval, rRegI newval, rFlagsReg cr) 7209%{ 7210 match(Set cr (StoreIConditional mem (Binary oldval newval))); 7211 effect(KILL oldval); 7212 7213 format %{ "cmpxchgl $mem, $newval\t# If rax == $mem then store $newval into $mem" %} 7214 opcode(0x0F, 0xB1); 7215 ins_encode(lock_prefix, 7216 REX_reg_mem(newval, mem), 7217 OpcP, OpcS, 7218 reg_mem(newval, mem)); 7219 ins_pipe(pipe_cmpxchg); 7220%} 7221 7222// Conditional-store of a long value. 7223// ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG. 7224instruct storeLConditional(memory mem, rax_RegL oldval, rRegL newval, rFlagsReg cr) 7225%{ 7226 match(Set cr (StoreLConditional mem (Binary oldval newval))); 7227 effect(KILL oldval); 7228 7229 format %{ "cmpxchgq $mem, $newval\t# If rax == $mem then store $newval into $mem" %} 7230 opcode(0x0F, 0xB1); 7231 ins_encode(lock_prefix, 7232 REX_reg_mem_wide(newval, mem), 7233 OpcP, OpcS, 7234 reg_mem(newval, mem)); 7235 ins_pipe(pipe_cmpxchg); 7236%} 7237 7238 7239// XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them 7240instruct compareAndSwapP(rRegI res, 7241 memory mem_ptr, 7242 rax_RegP oldval, rRegP newval, 7243 rFlagsReg cr) 7244%{ 7245 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); 7246 effect(KILL cr, KILL oldval); 7247 7248 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7249 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7250 "sete $res\n\t" 7251 "movzbl $res, $res" %} 7252 opcode(0x0F, 0xB1); 7253 ins_encode(lock_prefix, 7254 REX_reg_mem_wide(newval, mem_ptr), 7255 OpcP, OpcS, 7256 reg_mem(newval, mem_ptr), 7257 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7258 REX_reg_breg(res, res), // movzbl 7259 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7260 ins_pipe( pipe_cmpxchg ); 7261%} 7262 7263instruct compareAndSwapL(rRegI res, 7264 memory mem_ptr, 7265 rax_RegL oldval, rRegL newval, 7266 rFlagsReg cr) 7267%{ 7268 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval))); 7269 effect(KILL cr, KILL oldval); 7270 7271 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7272 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7273 "sete $res\n\t" 7274 "movzbl $res, $res" %} 7275 opcode(0x0F, 0xB1); 7276 ins_encode(lock_prefix, 7277 REX_reg_mem_wide(newval, mem_ptr), 7278 OpcP, OpcS, 7279 reg_mem(newval, mem_ptr), 7280 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7281 REX_reg_breg(res, res), // movzbl 7282 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7283 ins_pipe( pipe_cmpxchg ); 7284%} 7285 7286instruct compareAndSwapI(rRegI res, 7287 memory mem_ptr, 7288 rax_RegI oldval, rRegI newval, 7289 rFlagsReg cr) 7290%{ 7291 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval))); 7292 effect(KILL cr, KILL oldval); 7293 7294 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7295 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7296 "sete $res\n\t" 7297 "movzbl $res, $res" %} 7298 opcode(0x0F, 0xB1); 7299 ins_encode(lock_prefix, 7300 REX_reg_mem(newval, mem_ptr), 7301 OpcP, OpcS, 7302 reg_mem(newval, mem_ptr), 7303 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7304 REX_reg_breg(res, res), // movzbl 7305 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7306 ins_pipe( pipe_cmpxchg ); 7307%} 7308 7309 7310instruct compareAndSwapN(rRegI res, 7311 memory mem_ptr, 7312 rax_RegN oldval, rRegN newval, 7313 rFlagsReg cr) %{ 7314 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval))); 7315 effect(KILL cr, KILL oldval); 7316 7317 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7318 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7319 "sete $res\n\t" 7320 "movzbl $res, $res" %} 7321 opcode(0x0F, 0xB1); 7322 ins_encode(lock_prefix, 7323 REX_reg_mem(newval, mem_ptr), 7324 OpcP, OpcS, 7325 reg_mem(newval, mem_ptr), 7326 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7327 REX_reg_breg(res, res), // movzbl 7328 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7329 ins_pipe( pipe_cmpxchg ); 7330%} 7331 7332//----------Subtraction Instructions------------------------------------------- 7333 7334// Integer Subtraction Instructions 7335instruct subI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7336%{ 7337 match(Set dst (SubI dst src)); 7338 effect(KILL cr); 7339 7340 format %{ "subl $dst, $src\t# int" %} 7341 opcode(0x2B); 7342 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 7343 ins_pipe(ialu_reg_reg); 7344%} 7345 7346instruct subI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 7347%{ 7348 match(Set dst (SubI dst src)); 7349 effect(KILL cr); 7350 7351 format %{ "subl $dst, $src\t# int" %} 7352 opcode(0x81, 0x05); /* Opcode 81 /5 */ 7353 ins_encode(OpcSErm(dst, src), Con8or32(src)); 7354 ins_pipe(ialu_reg); 7355%} 7356 7357instruct subI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 7358%{ 7359 match(Set dst (SubI dst (LoadI src))); 7360 effect(KILL cr); 7361 7362 ins_cost(125); 7363 format %{ "subl $dst, $src\t# int" %} 7364 opcode(0x2B); 7365 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 7366 ins_pipe(ialu_reg_mem); 7367%} 7368 7369instruct subI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 7370%{ 7371 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 7372 effect(KILL cr); 7373 7374 ins_cost(150); 7375 format %{ "subl $dst, $src\t# int" %} 7376 opcode(0x29); /* Opcode 29 /r */ 7377 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 7378 ins_pipe(ialu_mem_reg); 7379%} 7380 7381instruct subI_mem_imm(memory dst, immI src, rFlagsReg cr) 7382%{ 7383 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 7384 effect(KILL cr); 7385 7386 ins_cost(125); // XXX 7387 format %{ "subl $dst, $src\t# int" %} 7388 opcode(0x81); /* Opcode 81 /5 id */ 7389 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); 7390 ins_pipe(ialu_mem_imm); 7391%} 7392 7393instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7394%{ 7395 match(Set dst (SubL dst src)); 7396 effect(KILL cr); 7397 7398 format %{ "subq $dst, $src\t# long" %} 7399 opcode(0x2B); 7400 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7401 ins_pipe(ialu_reg_reg); 7402%} 7403 7404instruct subL_rReg_imm(rRegI dst, immL32 src, rFlagsReg cr) 7405%{ 7406 match(Set dst (SubL dst src)); 7407 effect(KILL cr); 7408 7409 format %{ "subq $dst, $src\t# long" %} 7410 opcode(0x81, 0x05); /* Opcode 81 /5 */ 7411 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7412 ins_pipe(ialu_reg); 7413%} 7414 7415instruct subL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 7416%{ 7417 match(Set dst (SubL dst (LoadL src))); 7418 effect(KILL cr); 7419 7420 ins_cost(125); 7421 format %{ "subq $dst, $src\t# long" %} 7422 opcode(0x2B); 7423 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 7424 ins_pipe(ialu_reg_mem); 7425%} 7426 7427instruct subL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 7428%{ 7429 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 7430 effect(KILL cr); 7431 7432 ins_cost(150); 7433 format %{ "subq $dst, $src\t# long" %} 7434 opcode(0x29); /* Opcode 29 /r */ 7435 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 7436 ins_pipe(ialu_mem_reg); 7437%} 7438 7439instruct subL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 7440%{ 7441 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 7442 effect(KILL cr); 7443 7444 ins_cost(125); // XXX 7445 format %{ "subq $dst, $src\t# long" %} 7446 opcode(0x81); /* Opcode 81 /5 id */ 7447 ins_encode(REX_mem_wide(dst), 7448 OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); 7449 ins_pipe(ialu_mem_imm); 7450%} 7451 7452// Subtract from a pointer 7453// XXX hmpf??? 7454instruct subP_rReg(rRegP dst, rRegI src, immI0 zero, rFlagsReg cr) 7455%{ 7456 match(Set dst (AddP dst (SubI zero src))); 7457 effect(KILL cr); 7458 7459 format %{ "subq $dst, $src\t# ptr - int" %} 7460 opcode(0x2B); 7461 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7462 ins_pipe(ialu_reg_reg); 7463%} 7464 7465instruct negI_rReg(rRegI dst, immI0 zero, rFlagsReg cr) 7466%{ 7467 match(Set dst (SubI zero dst)); 7468 effect(KILL cr); 7469 7470 format %{ "negl $dst\t# int" %} 7471 opcode(0xF7, 0x03); // Opcode F7 /3 7472 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7473 ins_pipe(ialu_reg); 7474%} 7475 7476instruct negI_mem(memory dst, immI0 zero, rFlagsReg cr) 7477%{ 7478 match(Set dst (StoreI dst (SubI zero (LoadI dst)))); 7479 effect(KILL cr); 7480 7481 format %{ "negl $dst\t# int" %} 7482 opcode(0xF7, 0x03); // Opcode F7 /3 7483 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 7484 ins_pipe(ialu_reg); 7485%} 7486 7487instruct negL_rReg(rRegL dst, immL0 zero, rFlagsReg cr) 7488%{ 7489 match(Set dst (SubL zero dst)); 7490 effect(KILL cr); 7491 7492 format %{ "negq $dst\t# long" %} 7493 opcode(0xF7, 0x03); // Opcode F7 /3 7494 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 7495 ins_pipe(ialu_reg); 7496%} 7497 7498instruct negL_mem(memory dst, immL0 zero, rFlagsReg cr) 7499%{ 7500 match(Set dst (StoreL dst (SubL zero (LoadL dst)))); 7501 effect(KILL cr); 7502 7503 format %{ "negq $dst\t# long" %} 7504 opcode(0xF7, 0x03); // Opcode F7 /3 7505 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 7506 ins_pipe(ialu_reg); 7507%} 7508 7509 7510//----------Multiplication/Division Instructions------------------------------- 7511// Integer Multiplication Instructions 7512// Multiply Register 7513 7514instruct mulI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7515%{ 7516 match(Set dst (MulI dst src)); 7517 effect(KILL cr); 7518 7519 ins_cost(300); 7520 format %{ "imull $dst, $src\t# int" %} 7521 opcode(0x0F, 0xAF); 7522 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 7523 ins_pipe(ialu_reg_reg_alu0); 7524%} 7525 7526instruct mulI_rReg_imm(rRegI dst, rRegI src, immI imm, rFlagsReg cr) 7527%{ 7528 match(Set dst (MulI src imm)); 7529 effect(KILL cr); 7530 7531 ins_cost(300); 7532 format %{ "imull $dst, $src, $imm\t# int" %} 7533 opcode(0x69); /* 69 /r id */ 7534 ins_encode(REX_reg_reg(dst, src), 7535 OpcSE(imm), reg_reg(dst, src), Con8or32(imm)); 7536 ins_pipe(ialu_reg_reg_alu0); 7537%} 7538 7539instruct mulI_mem(rRegI dst, memory src, rFlagsReg cr) 7540%{ 7541 match(Set dst (MulI dst (LoadI src))); 7542 effect(KILL cr); 7543 7544 ins_cost(350); 7545 format %{ "imull $dst, $src\t# int" %} 7546 opcode(0x0F, 0xAF); 7547 ins_encode(REX_reg_mem(dst, src), OpcP, OpcS, reg_mem(dst, src)); 7548 ins_pipe(ialu_reg_mem_alu0); 7549%} 7550 7551instruct mulI_mem_imm(rRegI dst, memory src, immI imm, rFlagsReg cr) 7552%{ 7553 match(Set dst (MulI (LoadI src) imm)); 7554 effect(KILL cr); 7555 7556 ins_cost(300); 7557 format %{ "imull $dst, $src, $imm\t# int" %} 7558 opcode(0x69); /* 69 /r id */ 7559 ins_encode(REX_reg_mem(dst, src), 7560 OpcSE(imm), reg_mem(dst, src), Con8or32(imm)); 7561 ins_pipe(ialu_reg_mem_alu0); 7562%} 7563 7564instruct mulL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7565%{ 7566 match(Set dst (MulL dst src)); 7567 effect(KILL cr); 7568 7569 ins_cost(300); 7570 format %{ "imulq $dst, $src\t# long" %} 7571 opcode(0x0F, 0xAF); 7572 ins_encode(REX_reg_reg_wide(dst, src), OpcP, OpcS, reg_reg(dst, src)); 7573 ins_pipe(ialu_reg_reg_alu0); 7574%} 7575 7576instruct mulL_rReg_imm(rRegL dst, rRegL src, immL32 imm, rFlagsReg cr) 7577%{ 7578 match(Set dst (MulL src imm)); 7579 effect(KILL cr); 7580 7581 ins_cost(300); 7582 format %{ "imulq $dst, $src, $imm\t# long" %} 7583 opcode(0x69); /* 69 /r id */ 7584 ins_encode(REX_reg_reg_wide(dst, src), 7585 OpcSE(imm), reg_reg(dst, src), Con8or32(imm)); 7586 ins_pipe(ialu_reg_reg_alu0); 7587%} 7588 7589instruct mulL_mem(rRegL dst, memory src, rFlagsReg cr) 7590%{ 7591 match(Set dst (MulL dst (LoadL src))); 7592 effect(KILL cr); 7593 7594 ins_cost(350); 7595 format %{ "imulq $dst, $src\t# long" %} 7596 opcode(0x0F, 0xAF); 7597 ins_encode(REX_reg_mem_wide(dst, src), OpcP, OpcS, reg_mem(dst, src)); 7598 ins_pipe(ialu_reg_mem_alu0); 7599%} 7600 7601instruct mulL_mem_imm(rRegL dst, memory src, immL32 imm, rFlagsReg cr) 7602%{ 7603 match(Set dst (MulL (LoadL src) imm)); 7604 effect(KILL cr); 7605 7606 ins_cost(300); 7607 format %{ "imulq $dst, $src, $imm\t# long" %} 7608 opcode(0x69); /* 69 /r id */ 7609 ins_encode(REX_reg_mem_wide(dst, src), 7610 OpcSE(imm), reg_mem(dst, src), Con8or32(imm)); 7611 ins_pipe(ialu_reg_mem_alu0); 7612%} 7613 7614instruct mulHiL_rReg(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr) 7615%{ 7616 match(Set dst (MulHiL src rax)); 7617 effect(USE_KILL rax, KILL cr); 7618 7619 ins_cost(300); 7620 format %{ "imulq RDX:RAX, RAX, $src\t# mulhi" %} 7621 opcode(0xF7, 0x5); /* Opcode F7 /5 */ 7622 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); 7623 ins_pipe(ialu_reg_reg_alu0); 7624%} 7625 7626instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 7627 rFlagsReg cr) 7628%{ 7629 match(Set rax (DivI rax div)); 7630 effect(KILL rdx, KILL cr); 7631 7632 ins_cost(30*100+10*100); // XXX 7633 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 7634 "jne,s normal\n\t" 7635 "xorl rdx, rdx\n\t" 7636 "cmpl $div, -1\n\t" 7637 "je,s done\n" 7638 "normal: cdql\n\t" 7639 "idivl $div\n" 7640 "done:" %} 7641 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 7642 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 7643 ins_pipe(ialu_reg_reg_alu0); 7644%} 7645 7646instruct divL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 7647 rFlagsReg cr) 7648%{ 7649 match(Set rax (DivL rax div)); 7650 effect(KILL rdx, KILL cr); 7651 7652 ins_cost(30*100+10*100); // XXX 7653 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 7654 "cmpq rax, rdx\n\t" 7655 "jne,s normal\n\t" 7656 "xorl rdx, rdx\n\t" 7657 "cmpq $div, -1\n\t" 7658 "je,s done\n" 7659 "normal: cdqq\n\t" 7660 "idivq $div\n" 7661 "done:" %} 7662 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 7663 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 7664 ins_pipe(ialu_reg_reg_alu0); 7665%} 7666 7667// Integer DIVMOD with Register, both quotient and mod results 7668instruct divModI_rReg_divmod(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 7669 rFlagsReg cr) 7670%{ 7671 match(DivModI rax div); 7672 effect(KILL cr); 7673 7674 ins_cost(30*100+10*100); // XXX 7675 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 7676 "jne,s normal\n\t" 7677 "xorl rdx, rdx\n\t" 7678 "cmpl $div, -1\n\t" 7679 "je,s done\n" 7680 "normal: cdql\n\t" 7681 "idivl $div\n" 7682 "done:" %} 7683 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 7684 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 7685 ins_pipe(pipe_slow); 7686%} 7687 7688// Long DIVMOD with Register, both quotient and mod results 7689instruct divModL_rReg_divmod(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 7690 rFlagsReg cr) 7691%{ 7692 match(DivModL rax div); 7693 effect(KILL cr); 7694 7695 ins_cost(30*100+10*100); // XXX 7696 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 7697 "cmpq rax, rdx\n\t" 7698 "jne,s normal\n\t" 7699 "xorl rdx, rdx\n\t" 7700 "cmpq $div, -1\n\t" 7701 "je,s done\n" 7702 "normal: cdqq\n\t" 7703 "idivq $div\n" 7704 "done:" %} 7705 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 7706 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 7707 ins_pipe(pipe_slow); 7708%} 7709 7710//----------- DivL-By-Constant-Expansions-------------------------------------- 7711// DivI cases are handled by the compiler 7712 7713// Magic constant, reciprocal of 10 7714instruct loadConL_0x6666666666666667(rRegL dst) 7715%{ 7716 effect(DEF dst); 7717 7718 format %{ "movq $dst, #0x666666666666667\t# Used in div-by-10" %} 7719 ins_encode(load_immL(dst, 0x6666666666666667)); 7720 ins_pipe(ialu_reg); 7721%} 7722 7723instruct mul_hi(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr) 7724%{ 7725 effect(DEF dst, USE src, USE_KILL rax, KILL cr); 7726 7727 format %{ "imulq rdx:rax, rax, $src\t# Used in div-by-10" %} 7728 opcode(0xF7, 0x5); /* Opcode F7 /5 */ 7729 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); 7730 ins_pipe(ialu_reg_reg_alu0); 7731%} 7732 7733instruct sarL_rReg_63(rRegL dst, rFlagsReg cr) 7734%{ 7735 effect(USE_DEF dst, KILL cr); 7736 7737 format %{ "sarq $dst, #63\t# Used in div-by-10" %} 7738 opcode(0xC1, 0x7); /* C1 /7 ib */ 7739 ins_encode(reg_opc_imm_wide(dst, 0x3F)); 7740 ins_pipe(ialu_reg); 7741%} 7742 7743instruct sarL_rReg_2(rRegL dst, rFlagsReg cr) 7744%{ 7745 effect(USE_DEF dst, KILL cr); 7746 7747 format %{ "sarq $dst, #2\t# Used in div-by-10" %} 7748 opcode(0xC1, 0x7); /* C1 /7 ib */ 7749 ins_encode(reg_opc_imm_wide(dst, 0x2)); 7750 ins_pipe(ialu_reg); 7751%} 7752 7753instruct divL_10(rdx_RegL dst, no_rax_RegL src, immL10 div) 7754%{ 7755 match(Set dst (DivL src div)); 7756 7757 ins_cost((5+8)*100); 7758 expand %{ 7759 rax_RegL rax; // Killed temp 7760 rFlagsReg cr; // Killed 7761 loadConL_0x6666666666666667(rax); // movq rax, 0x6666666666666667 7762 mul_hi(dst, src, rax, cr); // mulq rdx:rax <= rax * $src 7763 sarL_rReg_63(src, cr); // sarq src, 63 7764 sarL_rReg_2(dst, cr); // sarq rdx, 2 7765 subL_rReg(dst, src, cr); // subl rdx, src 7766 %} 7767%} 7768 7769//----------------------------------------------------------------------------- 7770 7771instruct modI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, 7772 rFlagsReg cr) 7773%{ 7774 match(Set rdx (ModI rax div)); 7775 effect(KILL rax, KILL cr); 7776 7777 ins_cost(300); // XXX 7778 format %{ "cmpl rax, 0x80000000\t# irem\n\t" 7779 "jne,s normal\n\t" 7780 "xorl rdx, rdx\n\t" 7781 "cmpl $div, -1\n\t" 7782 "je,s done\n" 7783 "normal: cdql\n\t" 7784 "idivl $div\n" 7785 "done:" %} 7786 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 7787 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 7788 ins_pipe(ialu_reg_reg_alu0); 7789%} 7790 7791instruct modL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, 7792 rFlagsReg cr) 7793%{ 7794 match(Set rdx (ModL rax div)); 7795 effect(KILL rax, KILL cr); 7796 7797 ins_cost(300); // XXX 7798 format %{ "movq rdx, 0x8000000000000000\t# lrem\n\t" 7799 "cmpq rax, rdx\n\t" 7800 "jne,s normal\n\t" 7801 "xorl rdx, rdx\n\t" 7802 "cmpq $div, -1\n\t" 7803 "je,s done\n" 7804 "normal: cdqq\n\t" 7805 "idivq $div\n" 7806 "done:" %} 7807 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 7808 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 7809 ins_pipe(ialu_reg_reg_alu0); 7810%} 7811 7812// Integer Shift Instructions 7813// Shift Left by one 7814instruct salI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 7815%{ 7816 match(Set dst (LShiftI dst shift)); 7817 effect(KILL cr); 7818 7819 format %{ "sall $dst, $shift" %} 7820 opcode(0xD1, 0x4); /* D1 /4 */ 7821 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7822 ins_pipe(ialu_reg); 7823%} 7824 7825// Shift Left by one 7826instruct salI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 7827%{ 7828 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 7829 effect(KILL cr); 7830 7831 format %{ "sall $dst, $shift\t" %} 7832 opcode(0xD1, 0x4); /* D1 /4 */ 7833 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 7834 ins_pipe(ialu_mem_imm); 7835%} 7836 7837// Shift Left by 8-bit immediate 7838instruct salI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 7839%{ 7840 match(Set dst (LShiftI dst shift)); 7841 effect(KILL cr); 7842 7843 format %{ "sall $dst, $shift" %} 7844 opcode(0xC1, 0x4); /* C1 /4 ib */ 7845 ins_encode(reg_opc_imm(dst, shift)); 7846 ins_pipe(ialu_reg); 7847%} 7848 7849// Shift Left by 8-bit immediate 7850instruct salI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 7851%{ 7852 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 7853 effect(KILL cr); 7854 7855 format %{ "sall $dst, $shift" %} 7856 opcode(0xC1, 0x4); /* C1 /4 ib */ 7857 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 7858 ins_pipe(ialu_mem_imm); 7859%} 7860 7861// Shift Left by variable 7862instruct salI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 7863%{ 7864 match(Set dst (LShiftI dst shift)); 7865 effect(KILL cr); 7866 7867 format %{ "sall $dst, $shift" %} 7868 opcode(0xD3, 0x4); /* D3 /4 */ 7869 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7870 ins_pipe(ialu_reg_reg); 7871%} 7872 7873// Shift Left by variable 7874instruct salI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 7875%{ 7876 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 7877 effect(KILL cr); 7878 7879 format %{ "sall $dst, $shift" %} 7880 opcode(0xD3, 0x4); /* D3 /4 */ 7881 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 7882 ins_pipe(ialu_mem_reg); 7883%} 7884 7885// Arithmetic shift right by one 7886instruct sarI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 7887%{ 7888 match(Set dst (RShiftI dst shift)); 7889 effect(KILL cr); 7890 7891 format %{ "sarl $dst, $shift" %} 7892 opcode(0xD1, 0x7); /* D1 /7 */ 7893 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7894 ins_pipe(ialu_reg); 7895%} 7896 7897// Arithmetic shift right by one 7898instruct sarI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 7899%{ 7900 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 7901 effect(KILL cr); 7902 7903 format %{ "sarl $dst, $shift" %} 7904 opcode(0xD1, 0x7); /* D1 /7 */ 7905 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 7906 ins_pipe(ialu_mem_imm); 7907%} 7908 7909// Arithmetic Shift Right by 8-bit immediate 7910instruct sarI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 7911%{ 7912 match(Set dst (RShiftI dst shift)); 7913 effect(KILL cr); 7914 7915 format %{ "sarl $dst, $shift" %} 7916 opcode(0xC1, 0x7); /* C1 /7 ib */ 7917 ins_encode(reg_opc_imm(dst, shift)); 7918 ins_pipe(ialu_mem_imm); 7919%} 7920 7921// Arithmetic Shift Right by 8-bit immediate 7922instruct sarI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 7923%{ 7924 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 7925 effect(KILL cr); 7926 7927 format %{ "sarl $dst, $shift" %} 7928 opcode(0xC1, 0x7); /* C1 /7 ib */ 7929 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 7930 ins_pipe(ialu_mem_imm); 7931%} 7932 7933// Arithmetic Shift Right by variable 7934instruct sarI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 7935%{ 7936 match(Set dst (RShiftI dst shift)); 7937 effect(KILL cr); 7938 7939 format %{ "sarl $dst, $shift" %} 7940 opcode(0xD3, 0x7); /* D3 /7 */ 7941 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7942 ins_pipe(ialu_reg_reg); 7943%} 7944 7945// Arithmetic Shift Right by variable 7946instruct sarI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 7947%{ 7948 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 7949 effect(KILL cr); 7950 7951 format %{ "sarl $dst, $shift" %} 7952 opcode(0xD3, 0x7); /* D3 /7 */ 7953 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 7954 ins_pipe(ialu_mem_reg); 7955%} 7956 7957// Logical shift right by one 7958instruct shrI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 7959%{ 7960 match(Set dst (URShiftI dst shift)); 7961 effect(KILL cr); 7962 7963 format %{ "shrl $dst, $shift" %} 7964 opcode(0xD1, 0x5); /* D1 /5 */ 7965 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7966 ins_pipe(ialu_reg); 7967%} 7968 7969// Logical shift right by one 7970instruct shrI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 7971%{ 7972 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 7973 effect(KILL cr); 7974 7975 format %{ "shrl $dst, $shift" %} 7976 opcode(0xD1, 0x5); /* D1 /5 */ 7977 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 7978 ins_pipe(ialu_mem_imm); 7979%} 7980 7981// Logical Shift Right by 8-bit immediate 7982instruct shrI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 7983%{ 7984 match(Set dst (URShiftI dst shift)); 7985 effect(KILL cr); 7986 7987 format %{ "shrl $dst, $shift" %} 7988 opcode(0xC1, 0x5); /* C1 /5 ib */ 7989 ins_encode(reg_opc_imm(dst, shift)); 7990 ins_pipe(ialu_reg); 7991%} 7992 7993// Logical Shift Right by 8-bit immediate 7994instruct shrI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 7995%{ 7996 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 7997 effect(KILL cr); 7998 7999 format %{ "shrl $dst, $shift" %} 8000 opcode(0xC1, 0x5); /* C1 /5 ib */ 8001 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8002 ins_pipe(ialu_mem_imm); 8003%} 8004 8005// Logical Shift Right by variable 8006instruct shrI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8007%{ 8008 match(Set dst (URShiftI dst shift)); 8009 effect(KILL cr); 8010 8011 format %{ "shrl $dst, $shift" %} 8012 opcode(0xD3, 0x5); /* D3 /5 */ 8013 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8014 ins_pipe(ialu_reg_reg); 8015%} 8016 8017// Logical Shift Right by variable 8018instruct shrI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8019%{ 8020 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8021 effect(KILL cr); 8022 8023 format %{ "shrl $dst, $shift" %} 8024 opcode(0xD3, 0x5); /* D3 /5 */ 8025 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8026 ins_pipe(ialu_mem_reg); 8027%} 8028 8029// Long Shift Instructions 8030// Shift Left by one 8031instruct salL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8032%{ 8033 match(Set dst (LShiftL dst shift)); 8034 effect(KILL cr); 8035 8036 format %{ "salq $dst, $shift" %} 8037 opcode(0xD1, 0x4); /* D1 /4 */ 8038 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8039 ins_pipe(ialu_reg); 8040%} 8041 8042// Shift Left by one 8043instruct salL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8044%{ 8045 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8046 effect(KILL cr); 8047 8048 format %{ "salq $dst, $shift" %} 8049 opcode(0xD1, 0x4); /* D1 /4 */ 8050 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8051 ins_pipe(ialu_mem_imm); 8052%} 8053 8054// Shift Left by 8-bit immediate 8055instruct salL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8056%{ 8057 match(Set dst (LShiftL dst shift)); 8058 effect(KILL cr); 8059 8060 format %{ "salq $dst, $shift" %} 8061 opcode(0xC1, 0x4); /* C1 /4 ib */ 8062 ins_encode(reg_opc_imm_wide(dst, shift)); 8063 ins_pipe(ialu_reg); 8064%} 8065 8066// Shift Left by 8-bit immediate 8067instruct salL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8068%{ 8069 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8070 effect(KILL cr); 8071 8072 format %{ "salq $dst, $shift" %} 8073 opcode(0xC1, 0x4); /* C1 /4 ib */ 8074 ins_encode(REX_mem_wide(dst), OpcP, 8075 RM_opc_mem(secondary, dst), Con8or32(shift)); 8076 ins_pipe(ialu_mem_imm); 8077%} 8078 8079// Shift Left by variable 8080instruct salL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8081%{ 8082 match(Set dst (LShiftL dst shift)); 8083 effect(KILL cr); 8084 8085 format %{ "salq $dst, $shift" %} 8086 opcode(0xD3, 0x4); /* D3 /4 */ 8087 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8088 ins_pipe(ialu_reg_reg); 8089%} 8090 8091// Shift Left by variable 8092instruct salL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8093%{ 8094 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8095 effect(KILL cr); 8096 8097 format %{ "salq $dst, $shift" %} 8098 opcode(0xD3, 0x4); /* D3 /4 */ 8099 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8100 ins_pipe(ialu_mem_reg); 8101%} 8102 8103// Arithmetic shift right by one 8104instruct sarL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8105%{ 8106 match(Set dst (RShiftL dst shift)); 8107 effect(KILL cr); 8108 8109 format %{ "sarq $dst, $shift" %} 8110 opcode(0xD1, 0x7); /* D1 /7 */ 8111 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8112 ins_pipe(ialu_reg); 8113%} 8114 8115// Arithmetic shift right by one 8116instruct sarL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8117%{ 8118 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8119 effect(KILL cr); 8120 8121 format %{ "sarq $dst, $shift" %} 8122 opcode(0xD1, 0x7); /* D1 /7 */ 8123 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8124 ins_pipe(ialu_mem_imm); 8125%} 8126 8127// Arithmetic Shift Right by 8-bit immediate 8128instruct sarL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8129%{ 8130 match(Set dst (RShiftL dst shift)); 8131 effect(KILL cr); 8132 8133 format %{ "sarq $dst, $shift" %} 8134 opcode(0xC1, 0x7); /* C1 /7 ib */ 8135 ins_encode(reg_opc_imm_wide(dst, shift)); 8136 ins_pipe(ialu_mem_imm); 8137%} 8138 8139// Arithmetic Shift Right by 8-bit immediate 8140instruct sarL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8141%{ 8142 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8143 effect(KILL cr); 8144 8145 format %{ "sarq $dst, $shift" %} 8146 opcode(0xC1, 0x7); /* C1 /7 ib */ 8147 ins_encode(REX_mem_wide(dst), OpcP, 8148 RM_opc_mem(secondary, dst), Con8or32(shift)); 8149 ins_pipe(ialu_mem_imm); 8150%} 8151 8152// Arithmetic Shift Right by variable 8153instruct sarL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8154%{ 8155 match(Set dst (RShiftL dst shift)); 8156 effect(KILL cr); 8157 8158 format %{ "sarq $dst, $shift" %} 8159 opcode(0xD3, 0x7); /* D3 /7 */ 8160 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8161 ins_pipe(ialu_reg_reg); 8162%} 8163 8164// Arithmetic Shift Right by variable 8165instruct sarL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8166%{ 8167 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8168 effect(KILL cr); 8169 8170 format %{ "sarq $dst, $shift" %} 8171 opcode(0xD3, 0x7); /* D3 /7 */ 8172 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8173 ins_pipe(ialu_mem_reg); 8174%} 8175 8176// Logical shift right by one 8177instruct shrL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8178%{ 8179 match(Set dst (URShiftL dst shift)); 8180 effect(KILL cr); 8181 8182 format %{ "shrq $dst, $shift" %} 8183 opcode(0xD1, 0x5); /* D1 /5 */ 8184 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst )); 8185 ins_pipe(ialu_reg); 8186%} 8187 8188// Logical shift right by one 8189instruct shrL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8190%{ 8191 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8192 effect(KILL cr); 8193 8194 format %{ "shrq $dst, $shift" %} 8195 opcode(0xD1, 0x5); /* D1 /5 */ 8196 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8197 ins_pipe(ialu_mem_imm); 8198%} 8199 8200// Logical Shift Right by 8-bit immediate 8201instruct shrL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8202%{ 8203 match(Set dst (URShiftL dst shift)); 8204 effect(KILL cr); 8205 8206 format %{ "shrq $dst, $shift" %} 8207 opcode(0xC1, 0x5); /* C1 /5 ib */ 8208 ins_encode(reg_opc_imm_wide(dst, shift)); 8209 ins_pipe(ialu_reg); 8210%} 8211 8212 8213// Logical Shift Right by 8-bit immediate 8214instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8215%{ 8216 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8217 effect(KILL cr); 8218 8219 format %{ "shrq $dst, $shift" %} 8220 opcode(0xC1, 0x5); /* C1 /5 ib */ 8221 ins_encode(REX_mem_wide(dst), OpcP, 8222 RM_opc_mem(secondary, dst), Con8or32(shift)); 8223 ins_pipe(ialu_mem_imm); 8224%} 8225 8226// Logical Shift Right by variable 8227instruct shrL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8228%{ 8229 match(Set dst (URShiftL dst shift)); 8230 effect(KILL cr); 8231 8232 format %{ "shrq $dst, $shift" %} 8233 opcode(0xD3, 0x5); /* D3 /5 */ 8234 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8235 ins_pipe(ialu_reg_reg); 8236%} 8237 8238// Logical Shift Right by variable 8239instruct shrL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8240%{ 8241 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8242 effect(KILL cr); 8243 8244 format %{ "shrq $dst, $shift" %} 8245 opcode(0xD3, 0x5); /* D3 /5 */ 8246 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8247 ins_pipe(ialu_mem_reg); 8248%} 8249 8250// Logical Shift Right by 24, followed by Arithmetic Shift Left by 24. 8251// This idiom is used by the compiler for the i2b bytecode. 8252instruct i2b(rRegI dst, rRegI src, immI_24 twentyfour) 8253%{ 8254 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour)); 8255 8256 format %{ "movsbl $dst, $src\t# i2b" %} 8257 opcode(0x0F, 0xBE); 8258 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8259 ins_pipe(ialu_reg_reg); 8260%} 8261 8262// Logical Shift Right by 16, followed by Arithmetic Shift Left by 16. 8263// This idiom is used by the compiler the i2s bytecode. 8264instruct i2s(rRegI dst, rRegI src, immI_16 sixteen) 8265%{ 8266 match(Set dst (RShiftI (LShiftI src sixteen) sixteen)); 8267 8268 format %{ "movswl $dst, $src\t# i2s" %} 8269 opcode(0x0F, 0xBF); 8270 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8271 ins_pipe(ialu_reg_reg); 8272%} 8273 8274// ROL/ROR instructions 8275 8276// ROL expand 8277instruct rolI_rReg_imm1(rRegI dst, rFlagsReg cr) %{ 8278 effect(KILL cr, USE_DEF dst); 8279 8280 format %{ "roll $dst" %} 8281 opcode(0xD1, 0x0); /* Opcode D1 /0 */ 8282 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8283 ins_pipe(ialu_reg); 8284%} 8285 8286instruct rolI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) %{ 8287 effect(USE_DEF dst, USE shift, KILL cr); 8288 8289 format %{ "roll $dst, $shift" %} 8290 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */ 8291 ins_encode( reg_opc_imm(dst, shift) ); 8292 ins_pipe(ialu_reg); 8293%} 8294 8295instruct rolI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr) 8296%{ 8297 effect(USE_DEF dst, USE shift, KILL cr); 8298 8299 format %{ "roll $dst, $shift" %} 8300 opcode(0xD3, 0x0); /* Opcode D3 /0 */ 8301 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8302 ins_pipe(ialu_reg_reg); 8303%} 8304// end of ROL expand 8305 8306// Rotate Left by one 8307instruct rolI_rReg_i1(rRegI dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr) 8308%{ 8309 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift))); 8310 8311 expand %{ 8312 rolI_rReg_imm1(dst, cr); 8313 %} 8314%} 8315 8316// Rotate Left by 8-bit immediate 8317instruct rolI_rReg_i8(rRegI dst, immI8 lshift, immI8 rshift, rFlagsReg cr) 8318%{ 8319 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 8320 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift))); 8321 8322 expand %{ 8323 rolI_rReg_imm8(dst, lshift, cr); 8324 %} 8325%} 8326 8327// Rotate Left by variable 8328instruct rolI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 8329%{ 8330 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI zero shift)))); 8331 8332 expand %{ 8333 rolI_rReg_CL(dst, shift, cr); 8334 %} 8335%} 8336 8337// Rotate Left by variable 8338instruct rolI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr) 8339%{ 8340 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI c32 shift)))); 8341 8342 expand %{ 8343 rolI_rReg_CL(dst, shift, cr); 8344 %} 8345%} 8346 8347// ROR expand 8348instruct rorI_rReg_imm1(rRegI dst, rFlagsReg cr) 8349%{ 8350 effect(USE_DEF dst, KILL cr); 8351 8352 format %{ "rorl $dst" %} 8353 opcode(0xD1, 0x1); /* D1 /1 */ 8354 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8355 ins_pipe(ialu_reg); 8356%} 8357 8358instruct rorI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) 8359%{ 8360 effect(USE_DEF dst, USE shift, KILL cr); 8361 8362 format %{ "rorl $dst, $shift" %} 8363 opcode(0xC1, 0x1); /* C1 /1 ib */ 8364 ins_encode(reg_opc_imm(dst, shift)); 8365 ins_pipe(ialu_reg); 8366%} 8367 8368instruct rorI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr) 8369%{ 8370 effect(USE_DEF dst, USE shift, KILL cr); 8371 8372 format %{ "rorl $dst, $shift" %} 8373 opcode(0xD3, 0x1); /* D3 /1 */ 8374 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8375 ins_pipe(ialu_reg_reg); 8376%} 8377// end of ROR expand 8378 8379// Rotate Right by one 8380instruct rorI_rReg_i1(rRegI dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr) 8381%{ 8382 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift))); 8383 8384 expand %{ 8385 rorI_rReg_imm1(dst, cr); 8386 %} 8387%} 8388 8389// Rotate Right by 8-bit immediate 8390instruct rorI_rReg_i8(rRegI dst, immI8 rshift, immI8 lshift, rFlagsReg cr) 8391%{ 8392 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 8393 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift))); 8394 8395 expand %{ 8396 rorI_rReg_imm8(dst, rshift, cr); 8397 %} 8398%} 8399 8400// Rotate Right by variable 8401instruct rorI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 8402%{ 8403 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI zero shift)))); 8404 8405 expand %{ 8406 rorI_rReg_CL(dst, shift, cr); 8407 %} 8408%} 8409 8410// Rotate Right by variable 8411instruct rorI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr) 8412%{ 8413 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI c32 shift)))); 8414 8415 expand %{ 8416 rorI_rReg_CL(dst, shift, cr); 8417 %} 8418%} 8419 8420// for long rotate 8421// ROL expand 8422instruct rolL_rReg_imm1(rRegL dst, rFlagsReg cr) %{ 8423 effect(USE_DEF dst, KILL cr); 8424 8425 format %{ "rolq $dst" %} 8426 opcode(0xD1, 0x0); /* Opcode D1 /0 */ 8427 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8428 ins_pipe(ialu_reg); 8429%} 8430 8431instruct rolL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) %{ 8432 effect(USE_DEF dst, USE shift, KILL cr); 8433 8434 format %{ "rolq $dst, $shift" %} 8435 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */ 8436 ins_encode( reg_opc_imm_wide(dst, shift) ); 8437 ins_pipe(ialu_reg); 8438%} 8439 8440instruct rolL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr) 8441%{ 8442 effect(USE_DEF dst, USE shift, KILL cr); 8443 8444 format %{ "rolq $dst, $shift" %} 8445 opcode(0xD3, 0x0); /* Opcode D3 /0 */ 8446 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8447 ins_pipe(ialu_reg_reg); 8448%} 8449// end of ROL expand 8450 8451// Rotate Left by one 8452instruct rolL_rReg_i1(rRegL dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr) 8453%{ 8454 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift))); 8455 8456 expand %{ 8457 rolL_rReg_imm1(dst, cr); 8458 %} 8459%} 8460 8461// Rotate Left by 8-bit immediate 8462instruct rolL_rReg_i8(rRegL dst, immI8 lshift, immI8 rshift, rFlagsReg cr) 8463%{ 8464 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f)); 8465 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift))); 8466 8467 expand %{ 8468 rolL_rReg_imm8(dst, lshift, cr); 8469 %} 8470%} 8471 8472// Rotate Left by variable 8473instruct rolL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 8474%{ 8475 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI zero shift)))); 8476 8477 expand %{ 8478 rolL_rReg_CL(dst, shift, cr); 8479 %} 8480%} 8481 8482// Rotate Left by variable 8483instruct rolL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr) 8484%{ 8485 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI c64 shift)))); 8486 8487 expand %{ 8488 rolL_rReg_CL(dst, shift, cr); 8489 %} 8490%} 8491 8492// ROR expand 8493instruct rorL_rReg_imm1(rRegL dst, rFlagsReg cr) 8494%{ 8495 effect(USE_DEF dst, KILL cr); 8496 8497 format %{ "rorq $dst" %} 8498 opcode(0xD1, 0x1); /* D1 /1 */ 8499 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8500 ins_pipe(ialu_reg); 8501%} 8502 8503instruct rorL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) 8504%{ 8505 effect(USE_DEF dst, USE shift, KILL cr); 8506 8507 format %{ "rorq $dst, $shift" %} 8508 opcode(0xC1, 0x1); /* C1 /1 ib */ 8509 ins_encode(reg_opc_imm_wide(dst, shift)); 8510 ins_pipe(ialu_reg); 8511%} 8512 8513instruct rorL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr) 8514%{ 8515 effect(USE_DEF dst, USE shift, KILL cr); 8516 8517 format %{ "rorq $dst, $shift" %} 8518 opcode(0xD3, 0x1); /* D3 /1 */ 8519 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8520 ins_pipe(ialu_reg_reg); 8521%} 8522// end of ROR expand 8523 8524// Rotate Right by one 8525instruct rorL_rReg_i1(rRegL dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr) 8526%{ 8527 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift))); 8528 8529 expand %{ 8530 rorL_rReg_imm1(dst, cr); 8531 %} 8532%} 8533 8534// Rotate Right by 8-bit immediate 8535instruct rorL_rReg_i8(rRegL dst, immI8 rshift, immI8 lshift, rFlagsReg cr) 8536%{ 8537 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f)); 8538 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift))); 8539 8540 expand %{ 8541 rorL_rReg_imm8(dst, rshift, cr); 8542 %} 8543%} 8544 8545// Rotate Right by variable 8546instruct rorL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 8547%{ 8548 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI zero shift)))); 8549 8550 expand %{ 8551 rorL_rReg_CL(dst, shift, cr); 8552 %} 8553%} 8554 8555// Rotate Right by variable 8556instruct rorL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr) 8557%{ 8558 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI c64 shift)))); 8559 8560 expand %{ 8561 rorL_rReg_CL(dst, shift, cr); 8562 %} 8563%} 8564 8565// Logical Instructions 8566 8567// Integer Logical Instructions 8568 8569// And Instructions 8570// And Register with Register 8571instruct andI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8572%{ 8573 match(Set dst (AndI dst src)); 8574 effect(KILL cr); 8575 8576 format %{ "andl $dst, $src\t# int" %} 8577 opcode(0x23); 8578 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 8579 ins_pipe(ialu_reg_reg); 8580%} 8581 8582// And Register with Immediate 255 8583instruct andI_rReg_imm255(rRegI dst, immI_255 src) 8584%{ 8585 match(Set dst (AndI dst src)); 8586 8587 format %{ "movzbl $dst, $dst\t# int & 0xFF" %} 8588 opcode(0x0F, 0xB6); 8589 ins_encode(REX_reg_breg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 8590 ins_pipe(ialu_reg); 8591%} 8592 8593// And Register with Immediate 255 and promote to long 8594instruct andI2L_rReg_imm255(rRegL dst, rRegI src, immI_255 mask) 8595%{ 8596 match(Set dst (ConvI2L (AndI src mask))); 8597 8598 format %{ "movzbl $dst, $src\t# int & 0xFF -> long" %} 8599 opcode(0x0F, 0xB6); 8600 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8601 ins_pipe(ialu_reg); 8602%} 8603 8604// And Register with Immediate 65535 8605instruct andI_rReg_imm65535(rRegI dst, immI_65535 src) 8606%{ 8607 match(Set dst (AndI dst src)); 8608 8609 format %{ "movzwl $dst, $dst\t# int & 0xFFFF" %} 8610 opcode(0x0F, 0xB7); 8611 ins_encode(REX_reg_reg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 8612 ins_pipe(ialu_reg); 8613%} 8614 8615// And Register with Immediate 65535 and promote to long 8616instruct andI2L_rReg_imm65535(rRegL dst, rRegI src, immI_65535 mask) 8617%{ 8618 match(Set dst (ConvI2L (AndI src mask))); 8619 8620 format %{ "movzwl $dst, $src\t# int & 0xFFFF -> long" %} 8621 opcode(0x0F, 0xB7); 8622 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8623 ins_pipe(ialu_reg); 8624%} 8625 8626// And Register with Immediate 8627instruct andI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 8628%{ 8629 match(Set dst (AndI dst src)); 8630 effect(KILL cr); 8631 8632 format %{ "andl $dst, $src\t# int" %} 8633 opcode(0x81, 0x04); /* Opcode 81 /4 */ 8634 ins_encode(OpcSErm(dst, src), Con8or32(src)); 8635 ins_pipe(ialu_reg); 8636%} 8637 8638// And Register with Memory 8639instruct andI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 8640%{ 8641 match(Set dst (AndI dst (LoadI src))); 8642 effect(KILL cr); 8643 8644 ins_cost(125); 8645 format %{ "andl $dst, $src\t# int" %} 8646 opcode(0x23); 8647 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 8648 ins_pipe(ialu_reg_mem); 8649%} 8650 8651// And Memory with Register 8652instruct andI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 8653%{ 8654 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 8655 effect(KILL cr); 8656 8657 ins_cost(150); 8658 format %{ "andl $dst, $src\t# int" %} 8659 opcode(0x21); /* Opcode 21 /r */ 8660 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 8661 ins_pipe(ialu_mem_reg); 8662%} 8663 8664// And Memory with Immediate 8665instruct andI_mem_imm(memory dst, immI src, rFlagsReg cr) 8666%{ 8667 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 8668 effect(KILL cr); 8669 8670 ins_cost(125); 8671 format %{ "andl $dst, $src\t# int" %} 8672 opcode(0x81, 0x4); /* Opcode 81 /4 id */ 8673 ins_encode(REX_mem(dst), OpcSE(src), 8674 RM_opc_mem(secondary, dst), Con8or32(src)); 8675 ins_pipe(ialu_mem_imm); 8676%} 8677 8678// Or Instructions 8679// Or Register with Register 8680instruct orI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8681%{ 8682 match(Set dst (OrI dst src)); 8683 effect(KILL cr); 8684 8685 format %{ "orl $dst, $src\t# int" %} 8686 opcode(0x0B); 8687 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 8688 ins_pipe(ialu_reg_reg); 8689%} 8690 8691// Or Register with Immediate 8692instruct orI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 8693%{ 8694 match(Set dst (OrI dst src)); 8695 effect(KILL cr); 8696 8697 format %{ "orl $dst, $src\t# int" %} 8698 opcode(0x81, 0x01); /* Opcode 81 /1 id */ 8699 ins_encode(OpcSErm(dst, src), Con8or32(src)); 8700 ins_pipe(ialu_reg); 8701%} 8702 8703// Or Register with Memory 8704instruct orI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 8705%{ 8706 match(Set dst (OrI dst (LoadI src))); 8707 effect(KILL cr); 8708 8709 ins_cost(125); 8710 format %{ "orl $dst, $src\t# int" %} 8711 opcode(0x0B); 8712 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 8713 ins_pipe(ialu_reg_mem); 8714%} 8715 8716// Or Memory with Register 8717instruct orI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 8718%{ 8719 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 8720 effect(KILL cr); 8721 8722 ins_cost(150); 8723 format %{ "orl $dst, $src\t# int" %} 8724 opcode(0x09); /* Opcode 09 /r */ 8725 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 8726 ins_pipe(ialu_mem_reg); 8727%} 8728 8729// Or Memory with Immediate 8730instruct orI_mem_imm(memory dst, immI src, rFlagsReg cr) 8731%{ 8732 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 8733 effect(KILL cr); 8734 8735 ins_cost(125); 8736 format %{ "orl $dst, $src\t# int" %} 8737 opcode(0x81, 0x1); /* Opcode 81 /1 id */ 8738 ins_encode(REX_mem(dst), OpcSE(src), 8739 RM_opc_mem(secondary, dst), Con8or32(src)); 8740 ins_pipe(ialu_mem_imm); 8741%} 8742 8743// Xor Instructions 8744// Xor Register with Register 8745instruct xorI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8746%{ 8747 match(Set dst (XorI dst src)); 8748 effect(KILL cr); 8749 8750 format %{ "xorl $dst, $src\t# int" %} 8751 opcode(0x33); 8752 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 8753 ins_pipe(ialu_reg_reg); 8754%} 8755 8756// Xor Register with Immediate -1 8757instruct xorI_rReg_im1(rRegI dst, immI_M1 imm) %{ 8758 match(Set dst (XorI dst imm)); 8759 8760 format %{ "not $dst" %} 8761 ins_encode %{ 8762 __ notl($dst$$Register); 8763 %} 8764 ins_pipe(ialu_reg); 8765%} 8766 8767// Xor Register with Immediate 8768instruct xorI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 8769%{ 8770 match(Set dst (XorI dst src)); 8771 effect(KILL cr); 8772 8773 format %{ "xorl $dst, $src\t# int" %} 8774 opcode(0x81, 0x06); /* Opcode 81 /6 id */ 8775 ins_encode(OpcSErm(dst, src), Con8or32(src)); 8776 ins_pipe(ialu_reg); 8777%} 8778 8779// Xor Register with Memory 8780instruct xorI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 8781%{ 8782 match(Set dst (XorI dst (LoadI src))); 8783 effect(KILL cr); 8784 8785 ins_cost(125); 8786 format %{ "xorl $dst, $src\t# int" %} 8787 opcode(0x33); 8788 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 8789 ins_pipe(ialu_reg_mem); 8790%} 8791 8792// Xor Memory with Register 8793instruct xorI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 8794%{ 8795 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 8796 effect(KILL cr); 8797 8798 ins_cost(150); 8799 format %{ "xorl $dst, $src\t# int" %} 8800 opcode(0x31); /* Opcode 31 /r */ 8801 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 8802 ins_pipe(ialu_mem_reg); 8803%} 8804 8805// Xor Memory with Immediate 8806instruct xorI_mem_imm(memory dst, immI src, rFlagsReg cr) 8807%{ 8808 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 8809 effect(KILL cr); 8810 8811 ins_cost(125); 8812 format %{ "xorl $dst, $src\t# int" %} 8813 opcode(0x81, 0x6); /* Opcode 81 /6 id */ 8814 ins_encode(REX_mem(dst), OpcSE(src), 8815 RM_opc_mem(secondary, dst), Con8or32(src)); 8816 ins_pipe(ialu_mem_imm); 8817%} 8818 8819 8820// Long Logical Instructions 8821 8822// And Instructions 8823// And Register with Register 8824instruct andL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 8825%{ 8826 match(Set dst (AndL dst src)); 8827 effect(KILL cr); 8828 8829 format %{ "andq $dst, $src\t# long" %} 8830 opcode(0x23); 8831 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 8832 ins_pipe(ialu_reg_reg); 8833%} 8834 8835// And Register with Immediate 255 8836instruct andL_rReg_imm255(rRegL dst, immL_255 src) 8837%{ 8838 match(Set dst (AndL dst src)); 8839 8840 format %{ "movzbq $dst, $dst\t# long & 0xFF" %} 8841 opcode(0x0F, 0xB6); 8842 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 8843 ins_pipe(ialu_reg); 8844%} 8845 8846// And Register with Immediate 65535 8847instruct andL_rReg_imm65535(rRegL dst, immL_65535 src) 8848%{ 8849 match(Set dst (AndL dst src)); 8850 8851 format %{ "movzwq $dst, $dst\t# long & 0xFFFF" %} 8852 opcode(0x0F, 0xB7); 8853 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 8854 ins_pipe(ialu_reg); 8855%} 8856 8857// And Register with Immediate 8858instruct andL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 8859%{ 8860 match(Set dst (AndL dst src)); 8861 effect(KILL cr); 8862 8863 format %{ "andq $dst, $src\t# long" %} 8864 opcode(0x81, 0x04); /* Opcode 81 /4 */ 8865 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 8866 ins_pipe(ialu_reg); 8867%} 8868 8869// And Register with Memory 8870instruct andL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 8871%{ 8872 match(Set dst (AndL dst (LoadL src))); 8873 effect(KILL cr); 8874 8875 ins_cost(125); 8876 format %{ "andq $dst, $src\t# long" %} 8877 opcode(0x23); 8878 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 8879 ins_pipe(ialu_reg_mem); 8880%} 8881 8882// And Memory with Register 8883instruct andL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 8884%{ 8885 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 8886 effect(KILL cr); 8887 8888 ins_cost(150); 8889 format %{ "andq $dst, $src\t# long" %} 8890 opcode(0x21); /* Opcode 21 /r */ 8891 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 8892 ins_pipe(ialu_mem_reg); 8893%} 8894 8895// And Memory with Immediate 8896instruct andL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 8897%{ 8898 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 8899 effect(KILL cr); 8900 8901 ins_cost(125); 8902 format %{ "andq $dst, $src\t# long" %} 8903 opcode(0x81, 0x4); /* Opcode 81 /4 id */ 8904 ins_encode(REX_mem_wide(dst), OpcSE(src), 8905 RM_opc_mem(secondary, dst), Con8or32(src)); 8906 ins_pipe(ialu_mem_imm); 8907%} 8908 8909// Or Instructions 8910// Or Register with Register 8911instruct orL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 8912%{ 8913 match(Set dst (OrL dst src)); 8914 effect(KILL cr); 8915 8916 format %{ "orq $dst, $src\t# long" %} 8917 opcode(0x0B); 8918 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 8919 ins_pipe(ialu_reg_reg); 8920%} 8921 8922// Use any_RegP to match R15 (TLS register) without spilling. 8923instruct orL_rReg_castP2X(rRegL dst, any_RegP src, rFlagsReg cr) %{ 8924 match(Set dst (OrL dst (CastP2X src))); 8925 effect(KILL cr); 8926 8927 format %{ "orq $dst, $src\t# long" %} 8928 opcode(0x0B); 8929 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 8930 ins_pipe(ialu_reg_reg); 8931%} 8932 8933 8934// Or Register with Immediate 8935instruct orL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 8936%{ 8937 match(Set dst (OrL dst src)); 8938 effect(KILL cr); 8939 8940 format %{ "orq $dst, $src\t# long" %} 8941 opcode(0x81, 0x01); /* Opcode 81 /1 id */ 8942 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 8943 ins_pipe(ialu_reg); 8944%} 8945 8946// Or Register with Memory 8947instruct orL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 8948%{ 8949 match(Set dst (OrL dst (LoadL src))); 8950 effect(KILL cr); 8951 8952 ins_cost(125); 8953 format %{ "orq $dst, $src\t# long" %} 8954 opcode(0x0B); 8955 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 8956 ins_pipe(ialu_reg_mem); 8957%} 8958 8959// Or Memory with Register 8960instruct orL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 8961%{ 8962 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 8963 effect(KILL cr); 8964 8965 ins_cost(150); 8966 format %{ "orq $dst, $src\t# long" %} 8967 opcode(0x09); /* Opcode 09 /r */ 8968 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 8969 ins_pipe(ialu_mem_reg); 8970%} 8971 8972// Or Memory with Immediate 8973instruct orL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 8974%{ 8975 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 8976 effect(KILL cr); 8977 8978 ins_cost(125); 8979 format %{ "orq $dst, $src\t# long" %} 8980 opcode(0x81, 0x1); /* Opcode 81 /1 id */ 8981 ins_encode(REX_mem_wide(dst), OpcSE(src), 8982 RM_opc_mem(secondary, dst), Con8or32(src)); 8983 ins_pipe(ialu_mem_imm); 8984%} 8985 8986// Xor Instructions 8987// Xor Register with Register 8988instruct xorL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 8989%{ 8990 match(Set dst (XorL dst src)); 8991 effect(KILL cr); 8992 8993 format %{ "xorq $dst, $src\t# long" %} 8994 opcode(0x33); 8995 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 8996 ins_pipe(ialu_reg_reg); 8997%} 8998 8999// Xor Register with Immediate -1 9000instruct xorL_rReg_im1(rRegL dst, immL_M1 imm) %{ 9001 match(Set dst (XorL dst imm)); 9002 9003 format %{ "notq $dst" %} 9004 ins_encode %{ 9005 __ notq($dst$$Register); 9006 %} 9007 ins_pipe(ialu_reg); 9008%} 9009 9010// Xor Register with Immediate 9011instruct xorL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9012%{ 9013 match(Set dst (XorL dst src)); 9014 effect(KILL cr); 9015 9016 format %{ "xorq $dst, $src\t# long" %} 9017 opcode(0x81, 0x06); /* Opcode 81 /6 id */ 9018 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9019 ins_pipe(ialu_reg); 9020%} 9021 9022// Xor Register with Memory 9023instruct xorL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9024%{ 9025 match(Set dst (XorL dst (LoadL src))); 9026 effect(KILL cr); 9027 9028 ins_cost(125); 9029 format %{ "xorq $dst, $src\t# long" %} 9030 opcode(0x33); 9031 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9032 ins_pipe(ialu_reg_mem); 9033%} 9034 9035// Xor Memory with Register 9036instruct xorL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9037%{ 9038 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 9039 effect(KILL cr); 9040 9041 ins_cost(150); 9042 format %{ "xorq $dst, $src\t# long" %} 9043 opcode(0x31); /* Opcode 31 /r */ 9044 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9045 ins_pipe(ialu_mem_reg); 9046%} 9047 9048// Xor Memory with Immediate 9049instruct xorL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9050%{ 9051 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 9052 effect(KILL cr); 9053 9054 ins_cost(125); 9055 format %{ "xorq $dst, $src\t# long" %} 9056 opcode(0x81, 0x6); /* Opcode 81 /6 id */ 9057 ins_encode(REX_mem_wide(dst), OpcSE(src), 9058 RM_opc_mem(secondary, dst), Con8or32(src)); 9059 ins_pipe(ialu_mem_imm); 9060%} 9061 9062// Convert Int to Boolean 9063instruct convI2B(rRegI dst, rRegI src, rFlagsReg cr) 9064%{ 9065 match(Set dst (Conv2B src)); 9066 effect(KILL cr); 9067 9068 format %{ "testl $src, $src\t# ci2b\n\t" 9069 "setnz $dst\n\t" 9070 "movzbl $dst, $dst" %} 9071 ins_encode(REX_reg_reg(src, src), opc_reg_reg(0x85, src, src), // testl 9072 setNZ_reg(dst), 9073 REX_reg_breg(dst, dst), // movzbl 9074 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst)); 9075 ins_pipe(pipe_slow); // XXX 9076%} 9077 9078// Convert Pointer to Boolean 9079instruct convP2B(rRegI dst, rRegP src, rFlagsReg cr) 9080%{ 9081 match(Set dst (Conv2B src)); 9082 effect(KILL cr); 9083 9084 format %{ "testq $src, $src\t# cp2b\n\t" 9085 "setnz $dst\n\t" 9086 "movzbl $dst, $dst" %} 9087 ins_encode(REX_reg_reg_wide(src, src), opc_reg_reg(0x85, src, src), // testq 9088 setNZ_reg(dst), 9089 REX_reg_breg(dst, dst), // movzbl 9090 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst)); 9091 ins_pipe(pipe_slow); // XXX 9092%} 9093 9094instruct cmpLTMask(rRegI dst, rRegI p, rRegI q, rFlagsReg cr) 9095%{ 9096 match(Set dst (CmpLTMask p q)); 9097 effect(KILL cr); 9098 9099 ins_cost(400); // XXX 9100 format %{ "cmpl $p, $q\t# cmpLTMask\n\t" 9101 "setlt $dst\n\t" 9102 "movzbl $dst, $dst\n\t" 9103 "negl $dst" %} 9104 ins_encode(REX_reg_reg(p, q), opc_reg_reg(0x3B, p, q), // cmpl 9105 setLT_reg(dst), 9106 REX_reg_breg(dst, dst), // movzbl 9107 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst), 9108 neg_reg(dst)); 9109 ins_pipe(pipe_slow); 9110%} 9111 9112instruct cmpLTMask0(rRegI dst, immI0 zero, rFlagsReg cr) 9113%{ 9114 match(Set dst (CmpLTMask dst zero)); 9115 effect(KILL cr); 9116 9117 ins_cost(100); // XXX 9118 format %{ "sarl $dst, #31\t# cmpLTMask0" %} 9119 opcode(0xC1, 0x7); /* C1 /7 ib */ 9120 ins_encode(reg_opc_imm(dst, 0x1F)); 9121 ins_pipe(ialu_reg); 9122%} 9123 9124 9125instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y, rRegI tmp, rFlagsReg cr) 9126%{ 9127 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q))); 9128 effect(TEMP tmp, KILL cr); 9129 9130 ins_cost(400); // XXX 9131 format %{ "subl $p, $q\t# cadd_cmpLTMask1\n\t" 9132 "sbbl $tmp, $tmp\n\t" 9133 "andl $tmp, $y\n\t" 9134 "addl $p, $tmp" %} 9135 ins_encode %{ 9136 Register Rp = $p$$Register; 9137 Register Rq = $q$$Register; 9138 Register Ry = $y$$Register; 9139 Register Rt = $tmp$$Register; 9140 __ subl(Rp, Rq); 9141 __ sbbl(Rt, Rt); 9142 __ andl(Rt, Ry); 9143 __ addl(Rp, Rt); 9144 %} 9145 ins_pipe(pipe_cmplt); 9146%} 9147 9148//---------- FP Instructions------------------------------------------------ 9149 9150instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2) 9151%{ 9152 match(Set cr (CmpF src1 src2)); 9153 9154 ins_cost(145); 9155 format %{ "ucomiss $src1, $src2\n\t" 9156 "jnp,s exit\n\t" 9157 "pushfq\t# saw NaN, set CF\n\t" 9158 "andq [rsp], #0xffffff2b\n\t" 9159 "popfq\n" 9160 "exit:" %} 9161 ins_encode %{ 9162 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9163 emit_cmpfp_fixup(_masm); 9164 %} 9165 ins_pipe(pipe_slow); 9166%} 9167 9168instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{ 9169 match(Set cr (CmpF src1 src2)); 9170 9171 ins_cost(100); 9172 format %{ "ucomiss $src1, $src2" %} 9173 ins_encode %{ 9174 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9175 %} 9176 ins_pipe(pipe_slow); 9177%} 9178 9179instruct cmpF_cc_mem(rFlagsRegU cr, regF src1, memory src2) 9180%{ 9181 match(Set cr (CmpF src1 (LoadF src2))); 9182 9183 ins_cost(145); 9184 format %{ "ucomiss $src1, $src2\n\t" 9185 "jnp,s exit\n\t" 9186 "pushfq\t# saw NaN, set CF\n\t" 9187 "andq [rsp], #0xffffff2b\n\t" 9188 "popfq\n" 9189 "exit:" %} 9190 ins_encode %{ 9191 __ ucomiss($src1$$XMMRegister, $src2$$Address); 9192 emit_cmpfp_fixup(_masm); 9193 %} 9194 ins_pipe(pipe_slow); 9195%} 9196 9197instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{ 9198 match(Set cr (CmpF src1 (LoadF src2))); 9199 9200 ins_cost(100); 9201 format %{ "ucomiss $src1, $src2" %} 9202 ins_encode %{ 9203 __ ucomiss($src1$$XMMRegister, $src2$$Address); 9204 %} 9205 ins_pipe(pipe_slow); 9206%} 9207 9208instruct cmpF_cc_imm(rFlagsRegU cr, regF src, immF con) %{ 9209 match(Set cr (CmpF src con)); 9210 9211 ins_cost(145); 9212 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 9213 "jnp,s exit\n\t" 9214 "pushfq\t# saw NaN, set CF\n\t" 9215 "andq [rsp], #0xffffff2b\n\t" 9216 "popfq\n" 9217 "exit:" %} 9218 ins_encode %{ 9219 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 9220 emit_cmpfp_fixup(_masm); 9221 %} 9222 ins_pipe(pipe_slow); 9223%} 9224 9225instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src, immF con) %{ 9226 match(Set cr (CmpF src con)); 9227 ins_cost(100); 9228 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con" %} 9229 ins_encode %{ 9230 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 9231 %} 9232 ins_pipe(pipe_slow); 9233%} 9234 9235instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2) 9236%{ 9237 match(Set cr (CmpD src1 src2)); 9238 9239 ins_cost(145); 9240 format %{ "ucomisd $src1, $src2\n\t" 9241 "jnp,s exit\n\t" 9242 "pushfq\t# saw NaN, set CF\n\t" 9243 "andq [rsp], #0xffffff2b\n\t" 9244 "popfq\n" 9245 "exit:" %} 9246 ins_encode %{ 9247 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9248 emit_cmpfp_fixup(_masm); 9249 %} 9250 ins_pipe(pipe_slow); 9251%} 9252 9253instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{ 9254 match(Set cr (CmpD src1 src2)); 9255 9256 ins_cost(100); 9257 format %{ "ucomisd $src1, $src2 test" %} 9258 ins_encode %{ 9259 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9260 %} 9261 ins_pipe(pipe_slow); 9262%} 9263 9264instruct cmpD_cc_mem(rFlagsRegU cr, regD src1, memory src2) 9265%{ 9266 match(Set cr (CmpD src1 (LoadD src2))); 9267 9268 ins_cost(145); 9269 format %{ "ucomisd $src1, $src2\n\t" 9270 "jnp,s exit\n\t" 9271 "pushfq\t# saw NaN, set CF\n\t" 9272 "andq [rsp], #0xffffff2b\n\t" 9273 "popfq\n" 9274 "exit:" %} 9275 ins_encode %{ 9276 __ ucomisd($src1$$XMMRegister, $src2$$Address); 9277 emit_cmpfp_fixup(_masm); 9278 %} 9279 ins_pipe(pipe_slow); 9280%} 9281 9282instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{ 9283 match(Set cr (CmpD src1 (LoadD src2))); 9284 9285 ins_cost(100); 9286 format %{ "ucomisd $src1, $src2" %} 9287 ins_encode %{ 9288 __ ucomisd($src1$$XMMRegister, $src2$$Address); 9289 %} 9290 ins_pipe(pipe_slow); 9291%} 9292 9293instruct cmpD_cc_imm(rFlagsRegU cr, regD src, immD con) %{ 9294 match(Set cr (CmpD src con)); 9295 9296 ins_cost(145); 9297 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 9298 "jnp,s exit\n\t" 9299 "pushfq\t# saw NaN, set CF\n\t" 9300 "andq [rsp], #0xffffff2b\n\t" 9301 "popfq\n" 9302 "exit:" %} 9303 ins_encode %{ 9304 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 9305 emit_cmpfp_fixup(_masm); 9306 %} 9307 ins_pipe(pipe_slow); 9308%} 9309 9310instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src, immD con) %{ 9311 match(Set cr (CmpD src con)); 9312 ins_cost(100); 9313 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con" %} 9314 ins_encode %{ 9315 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 9316 %} 9317 ins_pipe(pipe_slow); 9318%} 9319 9320// Compare into -1,0,1 9321instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr) 9322%{ 9323 match(Set dst (CmpF3 src1 src2)); 9324 effect(KILL cr); 9325 9326 ins_cost(275); 9327 format %{ "ucomiss $src1, $src2\n\t" 9328 "movl $dst, #-1\n\t" 9329 "jp,s done\n\t" 9330 "jb,s done\n\t" 9331 "setne $dst\n\t" 9332 "movzbl $dst, $dst\n" 9333 "done:" %} 9334 ins_encode %{ 9335 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9336 emit_cmpfp3(_masm, $dst$$Register); 9337 %} 9338 ins_pipe(pipe_slow); 9339%} 9340 9341// Compare into -1,0,1 9342instruct cmpF_mem(rRegI dst, regF src1, memory src2, rFlagsReg cr) 9343%{ 9344 match(Set dst (CmpF3 src1 (LoadF src2))); 9345 effect(KILL cr); 9346 9347 ins_cost(275); 9348 format %{ "ucomiss $src1, $src2\n\t" 9349 "movl $dst, #-1\n\t" 9350 "jp,s done\n\t" 9351 "jb,s done\n\t" 9352 "setne $dst\n\t" 9353 "movzbl $dst, $dst\n" 9354 "done:" %} 9355 ins_encode %{ 9356 __ ucomiss($src1$$XMMRegister, $src2$$Address); 9357 emit_cmpfp3(_masm, $dst$$Register); 9358 %} 9359 ins_pipe(pipe_slow); 9360%} 9361 9362// Compare into -1,0,1 9363instruct cmpF_imm(rRegI dst, regF src, immF con, rFlagsReg cr) %{ 9364 match(Set dst (CmpF3 src con)); 9365 effect(KILL cr); 9366 9367 ins_cost(275); 9368 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 9369 "movl $dst, #-1\n\t" 9370 "jp,s done\n\t" 9371 "jb,s done\n\t" 9372 "setne $dst\n\t" 9373 "movzbl $dst, $dst\n" 9374 "done:" %} 9375 ins_encode %{ 9376 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 9377 emit_cmpfp3(_masm, $dst$$Register); 9378 %} 9379 ins_pipe(pipe_slow); 9380%} 9381 9382// Compare into -1,0,1 9383instruct cmpD_reg(rRegI dst, regD src1, regD src2, rFlagsReg cr) 9384%{ 9385 match(Set dst (CmpD3 src1 src2)); 9386 effect(KILL cr); 9387 9388 ins_cost(275); 9389 format %{ "ucomisd $src1, $src2\n\t" 9390 "movl $dst, #-1\n\t" 9391 "jp,s done\n\t" 9392 "jb,s done\n\t" 9393 "setne $dst\n\t" 9394 "movzbl $dst, $dst\n" 9395 "done:" %} 9396 ins_encode %{ 9397 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9398 emit_cmpfp3(_masm, $dst$$Register); 9399 %} 9400 ins_pipe(pipe_slow); 9401%} 9402 9403// Compare into -1,0,1 9404instruct cmpD_mem(rRegI dst, regD src1, memory src2, rFlagsReg cr) 9405%{ 9406 match(Set dst (CmpD3 src1 (LoadD src2))); 9407 effect(KILL cr); 9408 9409 ins_cost(275); 9410 format %{ "ucomisd $src1, $src2\n\t" 9411 "movl $dst, #-1\n\t" 9412 "jp,s done\n\t" 9413 "jb,s done\n\t" 9414 "setne $dst\n\t" 9415 "movzbl $dst, $dst\n" 9416 "done:" %} 9417 ins_encode %{ 9418 __ ucomisd($src1$$XMMRegister, $src2$$Address); 9419 emit_cmpfp3(_masm, $dst$$Register); 9420 %} 9421 ins_pipe(pipe_slow); 9422%} 9423 9424// Compare into -1,0,1 9425instruct cmpD_imm(rRegI dst, regD src, immD con, rFlagsReg cr) %{ 9426 match(Set dst (CmpD3 src con)); 9427 effect(KILL cr); 9428 9429 ins_cost(275); 9430 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 9431 "movl $dst, #-1\n\t" 9432 "jp,s done\n\t" 9433 "jb,s done\n\t" 9434 "setne $dst\n\t" 9435 "movzbl $dst, $dst\n" 9436 "done:" %} 9437 ins_encode %{ 9438 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 9439 emit_cmpfp3(_masm, $dst$$Register); 9440 %} 9441 ins_pipe(pipe_slow); 9442%} 9443 9444// -----------Trig and Trancendental Instructions------------------------------ 9445instruct cosD_reg(regD dst) %{ 9446 match(Set dst (CosD dst)); 9447 9448 format %{ "dcos $dst\n\t" %} 9449 opcode(0xD9, 0xFF); 9450 ins_encode( Push_SrcXD(dst), OpcP, OpcS, Push_ResultXD(dst) ); 9451 ins_pipe( pipe_slow ); 9452%} 9453 9454instruct sinD_reg(regD dst) %{ 9455 match(Set dst (SinD dst)); 9456 9457 format %{ "dsin $dst\n\t" %} 9458 opcode(0xD9, 0xFE); 9459 ins_encode( Push_SrcXD(dst), OpcP, OpcS, Push_ResultXD(dst) ); 9460 ins_pipe( pipe_slow ); 9461%} 9462 9463instruct tanD_reg(regD dst) %{ 9464 match(Set dst (TanD dst)); 9465 9466 format %{ "dtan $dst\n\t" %} 9467 ins_encode( Push_SrcXD(dst), 9468 Opcode(0xD9), Opcode(0xF2), //fptan 9469 Opcode(0xDD), Opcode(0xD8), //fstp st 9470 Push_ResultXD(dst) ); 9471 ins_pipe( pipe_slow ); 9472%} 9473 9474instruct log10D_reg(regD dst) %{ 9475 // The source and result Double operands in XMM registers 9476 match(Set dst (Log10D dst)); 9477 // fldlg2 ; push log_10(2) on the FPU stack; full 80-bit number 9478 // fyl2x ; compute log_10(2) * log_2(x) 9479 format %{ "fldlg2\t\t\t#Log10\n\t" 9480 "fyl2x\t\t\t# Q=Log10*Log_2(x)\n\t" 9481 %} 9482 ins_encode(Opcode(0xD9), Opcode(0xEC), // fldlg2 9483 Push_SrcXD(dst), 9484 Opcode(0xD9), Opcode(0xF1), // fyl2x 9485 Push_ResultXD(dst)); 9486 9487 ins_pipe( pipe_slow ); 9488%} 9489 9490instruct logD_reg(regD dst) %{ 9491 // The source and result Double operands in XMM registers 9492 match(Set dst (LogD dst)); 9493 // fldln2 ; push log_e(2) on the FPU stack; full 80-bit number 9494 // fyl2x ; compute log_e(2) * log_2(x) 9495 format %{ "fldln2\t\t\t#Log_e\n\t" 9496 "fyl2x\t\t\t# Q=Log_e*Log_2(x)\n\t" 9497 %} 9498 ins_encode( Opcode(0xD9), Opcode(0xED), // fldln2 9499 Push_SrcXD(dst), 9500 Opcode(0xD9), Opcode(0xF1), // fyl2x 9501 Push_ResultXD(dst)); 9502 ins_pipe( pipe_slow ); 9503%} 9504 9505instruct powD_reg(regD dst, regD src0, regD src1, rax_RegI rax, rdx_RegI rdx, rcx_RegI rcx, rFlagsReg cr) %{ 9506 match(Set dst (PowD src0 src1)); // Raise src0 to the src1'th power 9507 effect(KILL rax, KILL rdx, KILL rcx, KILL cr); 9508 format %{ "fast_pow $src0 $src1 -> $dst // KILL $rax, $rcx, $rdx" %} 9509 ins_encode %{ 9510 __ subptr(rsp, 8); 9511 __ movdbl(Address(rsp, 0), $src1$$XMMRegister); 9512 __ fld_d(Address(rsp, 0)); 9513 __ movdbl(Address(rsp, 0), $src0$$XMMRegister); 9514 __ fld_d(Address(rsp, 0)); 9515 __ fast_pow(); 9516 __ fstp_d(Address(rsp, 0)); 9517 __ movdbl($dst$$XMMRegister, Address(rsp, 0)); 9518 __ addptr(rsp, 8); 9519 %} 9520 ins_pipe( pipe_slow ); 9521%} 9522 9523instruct expD_reg(regD dst, regD src, rax_RegI rax, rdx_RegI rdx, rcx_RegI rcx, rFlagsReg cr) %{ 9524 match(Set dst (ExpD src)); 9525 effect(KILL rax, KILL rcx, KILL rdx, KILL cr); 9526 format %{ "fast_exp $dst -> $src // KILL $rax, $rcx, $rdx" %} 9527 ins_encode %{ 9528 __ subptr(rsp, 8); 9529 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 9530 __ fld_d(Address(rsp, 0)); 9531 __ fast_exp(); 9532 __ fstp_d(Address(rsp, 0)); 9533 __ movdbl($dst$$XMMRegister, Address(rsp, 0)); 9534 __ addptr(rsp, 8); 9535 %} 9536 ins_pipe( pipe_slow ); 9537%} 9538 9539//----------Arithmetic Conversion Instructions--------------------------------- 9540 9541instruct roundFloat_nop(regF dst) 9542%{ 9543 match(Set dst (RoundFloat dst)); 9544 9545 ins_cost(0); 9546 ins_encode(); 9547 ins_pipe(empty); 9548%} 9549 9550instruct roundDouble_nop(regD dst) 9551%{ 9552 match(Set dst (RoundDouble dst)); 9553 9554 ins_cost(0); 9555 ins_encode(); 9556 ins_pipe(empty); 9557%} 9558 9559instruct convF2D_reg_reg(regD dst, regF src) 9560%{ 9561 match(Set dst (ConvF2D src)); 9562 9563 format %{ "cvtss2sd $dst, $src" %} 9564 ins_encode %{ 9565 __ cvtss2sd ($dst$$XMMRegister, $src$$XMMRegister); 9566 %} 9567 ins_pipe(pipe_slow); // XXX 9568%} 9569 9570instruct convF2D_reg_mem(regD dst, memory src) 9571%{ 9572 match(Set dst (ConvF2D (LoadF src))); 9573 9574 format %{ "cvtss2sd $dst, $src" %} 9575 ins_encode %{ 9576 __ cvtss2sd ($dst$$XMMRegister, $src$$Address); 9577 %} 9578 ins_pipe(pipe_slow); // XXX 9579%} 9580 9581instruct convD2F_reg_reg(regF dst, regD src) 9582%{ 9583 match(Set dst (ConvD2F src)); 9584 9585 format %{ "cvtsd2ss $dst, $src" %} 9586 ins_encode %{ 9587 __ cvtsd2ss ($dst$$XMMRegister, $src$$XMMRegister); 9588 %} 9589 ins_pipe(pipe_slow); // XXX 9590%} 9591 9592instruct convD2F_reg_mem(regF dst, memory src) 9593%{ 9594 match(Set dst (ConvD2F (LoadD src))); 9595 9596 format %{ "cvtsd2ss $dst, $src" %} 9597 ins_encode %{ 9598 __ cvtsd2ss ($dst$$XMMRegister, $src$$Address); 9599 %} 9600 ins_pipe(pipe_slow); // XXX 9601%} 9602 9603// XXX do mem variants 9604instruct convF2I_reg_reg(rRegI dst, regF src, rFlagsReg cr) 9605%{ 9606 match(Set dst (ConvF2I src)); 9607 effect(KILL cr); 9608 9609 format %{ "cvttss2sil $dst, $src\t# f2i\n\t" 9610 "cmpl $dst, #0x80000000\n\t" 9611 "jne,s done\n\t" 9612 "subq rsp, #8\n\t" 9613 "movss [rsp], $src\n\t" 9614 "call f2i_fixup\n\t" 9615 "popq $dst\n" 9616 "done: "%} 9617 ins_encode %{ 9618 Label done; 9619 __ cvttss2sil($dst$$Register, $src$$XMMRegister); 9620 __ cmpl($dst$$Register, 0x80000000); 9621 __ jccb(Assembler::notEqual, done); 9622 __ subptr(rsp, 8); 9623 __ movflt(Address(rsp, 0), $src$$XMMRegister); 9624 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::f2i_fixup()))); 9625 __ pop($dst$$Register); 9626 __ bind(done); 9627 %} 9628 ins_pipe(pipe_slow); 9629%} 9630 9631instruct convF2L_reg_reg(rRegL dst, regF src, rFlagsReg cr) 9632%{ 9633 match(Set dst (ConvF2L src)); 9634 effect(KILL cr); 9635 9636 format %{ "cvttss2siq $dst, $src\t# f2l\n\t" 9637 "cmpq $dst, [0x8000000000000000]\n\t" 9638 "jne,s done\n\t" 9639 "subq rsp, #8\n\t" 9640 "movss [rsp], $src\n\t" 9641 "call f2l_fixup\n\t" 9642 "popq $dst\n" 9643 "done: "%} 9644 ins_encode %{ 9645 Label done; 9646 __ cvttss2siq($dst$$Register, $src$$XMMRegister); 9647 __ cmp64($dst$$Register, 9648 ExternalAddress((address) StubRoutines::x86::double_sign_flip())); 9649 __ jccb(Assembler::notEqual, done); 9650 __ subptr(rsp, 8); 9651 __ movflt(Address(rsp, 0), $src$$XMMRegister); 9652 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::f2l_fixup()))); 9653 __ pop($dst$$Register); 9654 __ bind(done); 9655 %} 9656 ins_pipe(pipe_slow); 9657%} 9658 9659instruct convD2I_reg_reg(rRegI dst, regD src, rFlagsReg cr) 9660%{ 9661 match(Set dst (ConvD2I src)); 9662 effect(KILL cr); 9663 9664 format %{ "cvttsd2sil $dst, $src\t# d2i\n\t" 9665 "cmpl $dst, #0x80000000\n\t" 9666 "jne,s done\n\t" 9667 "subq rsp, #8\n\t" 9668 "movsd [rsp], $src\n\t" 9669 "call d2i_fixup\n\t" 9670 "popq $dst\n" 9671 "done: "%} 9672 ins_encode %{ 9673 Label done; 9674 __ cvttsd2sil($dst$$Register, $src$$XMMRegister); 9675 __ cmpl($dst$$Register, 0x80000000); 9676 __ jccb(Assembler::notEqual, done); 9677 __ subptr(rsp, 8); 9678 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 9679 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::d2i_fixup()))); 9680 __ pop($dst$$Register); 9681 __ bind(done); 9682 %} 9683 ins_pipe(pipe_slow); 9684%} 9685 9686instruct convD2L_reg_reg(rRegL dst, regD src, rFlagsReg cr) 9687%{ 9688 match(Set dst (ConvD2L src)); 9689 effect(KILL cr); 9690 9691 format %{ "cvttsd2siq $dst, $src\t# d2l\n\t" 9692 "cmpq $dst, [0x8000000000000000]\n\t" 9693 "jne,s done\n\t" 9694 "subq rsp, #8\n\t" 9695 "movsd [rsp], $src\n\t" 9696 "call d2l_fixup\n\t" 9697 "popq $dst\n" 9698 "done: "%} 9699 ins_encode %{ 9700 Label done; 9701 __ cvttsd2siq($dst$$Register, $src$$XMMRegister); 9702 __ cmp64($dst$$Register, 9703 ExternalAddress((address) StubRoutines::x86::double_sign_flip())); 9704 __ jccb(Assembler::notEqual, done); 9705 __ subptr(rsp, 8); 9706 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 9707 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::d2l_fixup()))); 9708 __ pop($dst$$Register); 9709 __ bind(done); 9710 %} 9711 ins_pipe(pipe_slow); 9712%} 9713 9714instruct convI2F_reg_reg(regF dst, rRegI src) 9715%{ 9716 predicate(!UseXmmI2F); 9717 match(Set dst (ConvI2F src)); 9718 9719 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 9720 ins_encode %{ 9721 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Register); 9722 %} 9723 ins_pipe(pipe_slow); // XXX 9724%} 9725 9726instruct convI2F_reg_mem(regF dst, memory src) 9727%{ 9728 match(Set dst (ConvI2F (LoadI src))); 9729 9730 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 9731 ins_encode %{ 9732 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Address); 9733 %} 9734 ins_pipe(pipe_slow); // XXX 9735%} 9736 9737instruct convI2D_reg_reg(regD dst, rRegI src) 9738%{ 9739 predicate(!UseXmmI2D); 9740 match(Set dst (ConvI2D src)); 9741 9742 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 9743 ins_encode %{ 9744 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Register); 9745 %} 9746 ins_pipe(pipe_slow); // XXX 9747%} 9748 9749instruct convI2D_reg_mem(regD dst, memory src) 9750%{ 9751 match(Set dst (ConvI2D (LoadI src))); 9752 9753 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 9754 ins_encode %{ 9755 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Address); 9756 %} 9757 ins_pipe(pipe_slow); // XXX 9758%} 9759 9760instruct convXI2F_reg(regF dst, rRegI src) 9761%{ 9762 predicate(UseXmmI2F); 9763 match(Set dst (ConvI2F src)); 9764 9765 format %{ "movdl $dst, $src\n\t" 9766 "cvtdq2psl $dst, $dst\t# i2f" %} 9767 ins_encode %{ 9768 __ movdl($dst$$XMMRegister, $src$$Register); 9769 __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister); 9770 %} 9771 ins_pipe(pipe_slow); // XXX 9772%} 9773 9774instruct convXI2D_reg(regD dst, rRegI src) 9775%{ 9776 predicate(UseXmmI2D); 9777 match(Set dst (ConvI2D src)); 9778 9779 format %{ "movdl $dst, $src\n\t" 9780 "cvtdq2pdl $dst, $dst\t# i2d" %} 9781 ins_encode %{ 9782 __ movdl($dst$$XMMRegister, $src$$Register); 9783 __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister); 9784 %} 9785 ins_pipe(pipe_slow); // XXX 9786%} 9787 9788instruct convL2F_reg_reg(regF dst, rRegL src) 9789%{ 9790 match(Set dst (ConvL2F src)); 9791 9792 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 9793 ins_encode %{ 9794 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Register); 9795 %} 9796 ins_pipe(pipe_slow); // XXX 9797%} 9798 9799instruct convL2F_reg_mem(regF dst, memory src) 9800%{ 9801 match(Set dst (ConvL2F (LoadL src))); 9802 9803 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 9804 ins_encode %{ 9805 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Address); 9806 %} 9807 ins_pipe(pipe_slow); // XXX 9808%} 9809 9810instruct convL2D_reg_reg(regD dst, rRegL src) 9811%{ 9812 match(Set dst (ConvL2D src)); 9813 9814 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 9815 ins_encode %{ 9816 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Register); 9817 %} 9818 ins_pipe(pipe_slow); // XXX 9819%} 9820 9821instruct convL2D_reg_mem(regD dst, memory src) 9822%{ 9823 match(Set dst (ConvL2D (LoadL src))); 9824 9825 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 9826 ins_encode %{ 9827 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Address); 9828 %} 9829 ins_pipe(pipe_slow); // XXX 9830%} 9831 9832instruct convI2L_reg_reg(rRegL dst, rRegI src) 9833%{ 9834 match(Set dst (ConvI2L src)); 9835 9836 ins_cost(125); 9837 format %{ "movslq $dst, $src\t# i2l" %} 9838 ins_encode %{ 9839 __ movslq($dst$$Register, $src$$Register); 9840 %} 9841 ins_pipe(ialu_reg_reg); 9842%} 9843 9844// instruct convI2L_reg_reg_foo(rRegL dst, rRegI src) 9845// %{ 9846// match(Set dst (ConvI2L src)); 9847// // predicate(_kids[0]->_leaf->as_Type()->type()->is_int()->_lo >= 0 && 9848// // _kids[0]->_leaf->as_Type()->type()->is_int()->_hi >= 0); 9849// predicate(((const TypeNode*) n)->type()->is_long()->_hi == 9850// (unsigned int) ((const TypeNode*) n)->type()->is_long()->_hi && 9851// ((const TypeNode*) n)->type()->is_long()->_lo == 9852// (unsigned int) ((const TypeNode*) n)->type()->is_long()->_lo); 9853 9854// format %{ "movl $dst, $src\t# unsigned i2l" %} 9855// ins_encode(enc_copy(dst, src)); 9856// // opcode(0x63); // needs REX.W 9857// // ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst,src)); 9858// ins_pipe(ialu_reg_reg); 9859// %} 9860 9861// Zero-extend convert int to long 9862instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask) 9863%{ 9864 match(Set dst (AndL (ConvI2L src) mask)); 9865 9866 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 9867 ins_encode %{ 9868 if ($dst$$reg != $src$$reg) { 9869 __ movl($dst$$Register, $src$$Register); 9870 } 9871 %} 9872 ins_pipe(ialu_reg_reg); 9873%} 9874 9875// Zero-extend convert int to long 9876instruct convI2L_reg_mem_zex(rRegL dst, memory src, immL_32bits mask) 9877%{ 9878 match(Set dst (AndL (ConvI2L (LoadI src)) mask)); 9879 9880 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 9881 ins_encode %{ 9882 __ movl($dst$$Register, $src$$Address); 9883 %} 9884 ins_pipe(ialu_reg_mem); 9885%} 9886 9887instruct zerox_long_reg_reg(rRegL dst, rRegL src, immL_32bits mask) 9888%{ 9889 match(Set dst (AndL src mask)); 9890 9891 format %{ "movl $dst, $src\t# zero-extend long" %} 9892 ins_encode %{ 9893 __ movl($dst$$Register, $src$$Register); 9894 %} 9895 ins_pipe(ialu_reg_reg); 9896%} 9897 9898instruct convL2I_reg_reg(rRegI dst, rRegL src) 9899%{ 9900 match(Set dst (ConvL2I src)); 9901 9902 format %{ "movl $dst, $src\t# l2i" %} 9903 ins_encode %{ 9904 __ movl($dst$$Register, $src$$Register); 9905 %} 9906 ins_pipe(ialu_reg_reg); 9907%} 9908 9909 9910instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{ 9911 match(Set dst (MoveF2I src)); 9912 effect(DEF dst, USE src); 9913 9914 ins_cost(125); 9915 format %{ "movl $dst, $src\t# MoveF2I_stack_reg" %} 9916 ins_encode %{ 9917 __ movl($dst$$Register, Address(rsp, $src$$disp)); 9918 %} 9919 ins_pipe(ialu_reg_mem); 9920%} 9921 9922instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{ 9923 match(Set dst (MoveI2F src)); 9924 effect(DEF dst, USE src); 9925 9926 ins_cost(125); 9927 format %{ "movss $dst, $src\t# MoveI2F_stack_reg" %} 9928 ins_encode %{ 9929 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 9930 %} 9931 ins_pipe(pipe_slow); 9932%} 9933 9934instruct MoveD2L_stack_reg(rRegL dst, stackSlotD src) %{ 9935 match(Set dst (MoveD2L src)); 9936 effect(DEF dst, USE src); 9937 9938 ins_cost(125); 9939 format %{ "movq $dst, $src\t# MoveD2L_stack_reg" %} 9940 ins_encode %{ 9941 __ movq($dst$$Register, Address(rsp, $src$$disp)); 9942 %} 9943 ins_pipe(ialu_reg_mem); 9944%} 9945 9946instruct MoveL2D_stack_reg_partial(regD dst, stackSlotL src) %{ 9947 predicate(!UseXmmLoadAndClearUpper); 9948 match(Set dst (MoveL2D src)); 9949 effect(DEF dst, USE src); 9950 9951 ins_cost(125); 9952 format %{ "movlpd $dst, $src\t# MoveL2D_stack_reg" %} 9953 ins_encode %{ 9954 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 9955 %} 9956 ins_pipe(pipe_slow); 9957%} 9958 9959instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{ 9960 predicate(UseXmmLoadAndClearUpper); 9961 match(Set dst (MoveL2D src)); 9962 effect(DEF dst, USE src); 9963 9964 ins_cost(125); 9965 format %{ "movsd $dst, $src\t# MoveL2D_stack_reg" %} 9966 ins_encode %{ 9967 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 9968 %} 9969 ins_pipe(pipe_slow); 9970%} 9971 9972 9973instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{ 9974 match(Set dst (MoveF2I src)); 9975 effect(DEF dst, USE src); 9976 9977 ins_cost(95); // XXX 9978 format %{ "movss $dst, $src\t# MoveF2I_reg_stack" %} 9979 ins_encode %{ 9980 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 9981 %} 9982 ins_pipe(pipe_slow); 9983%} 9984 9985instruct MoveI2F_reg_stack(stackSlotF dst, rRegI src) %{ 9986 match(Set dst (MoveI2F src)); 9987 effect(DEF dst, USE src); 9988 9989 ins_cost(100); 9990 format %{ "movl $dst, $src\t# MoveI2F_reg_stack" %} 9991 ins_encode %{ 9992 __ movl(Address(rsp, $dst$$disp), $src$$Register); 9993 %} 9994 ins_pipe( ialu_mem_reg ); 9995%} 9996 9997instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{ 9998 match(Set dst (MoveD2L src)); 9999 effect(DEF dst, USE src); 10000 10001 ins_cost(95); // XXX 10002 format %{ "movsd $dst, $src\t# MoveL2D_reg_stack" %} 10003 ins_encode %{ 10004 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 10005 %} 10006 ins_pipe(pipe_slow); 10007%} 10008 10009instruct MoveL2D_reg_stack(stackSlotD dst, rRegL src) %{ 10010 match(Set dst (MoveL2D src)); 10011 effect(DEF dst, USE src); 10012 10013 ins_cost(100); 10014 format %{ "movq $dst, $src\t# MoveL2D_reg_stack" %} 10015 ins_encode %{ 10016 __ movq(Address(rsp, $dst$$disp), $src$$Register); 10017 %} 10018 ins_pipe(ialu_mem_reg); 10019%} 10020 10021instruct MoveF2I_reg_reg(rRegI dst, regF src) %{ 10022 match(Set dst (MoveF2I src)); 10023 effect(DEF dst, USE src); 10024 ins_cost(85); 10025 format %{ "movd $dst,$src\t# MoveF2I" %} 10026 ins_encode %{ 10027 __ movdl($dst$$Register, $src$$XMMRegister); 10028 %} 10029 ins_pipe( pipe_slow ); 10030%} 10031 10032instruct MoveD2L_reg_reg(rRegL dst, regD src) %{ 10033 match(Set dst (MoveD2L src)); 10034 effect(DEF dst, USE src); 10035 ins_cost(85); 10036 format %{ "movd $dst,$src\t# MoveD2L" %} 10037 ins_encode %{ 10038 __ movdq($dst$$Register, $src$$XMMRegister); 10039 %} 10040 ins_pipe( pipe_slow ); 10041%} 10042 10043instruct MoveI2F_reg_reg(regF dst, rRegI src) %{ 10044 match(Set dst (MoveI2F src)); 10045 effect(DEF dst, USE src); 10046 ins_cost(100); 10047 format %{ "movd $dst,$src\t# MoveI2F" %} 10048 ins_encode %{ 10049 __ movdl($dst$$XMMRegister, $src$$Register); 10050 %} 10051 ins_pipe( pipe_slow ); 10052%} 10053 10054instruct MoveL2D_reg_reg(regD dst, rRegL src) %{ 10055 match(Set dst (MoveL2D src)); 10056 effect(DEF dst, USE src); 10057 ins_cost(100); 10058 format %{ "movd $dst,$src\t# MoveL2D" %} 10059 ins_encode %{ 10060 __ movdq($dst$$XMMRegister, $src$$Register); 10061 %} 10062 ins_pipe( pipe_slow ); 10063%} 10064 10065 10066// ======================================================================= 10067// fast clearing of an array 10068instruct rep_stos(rcx_RegL cnt, rdi_RegP base, rax_RegI zero, Universe dummy, 10069 rFlagsReg cr) 10070%{ 10071 match(Set dummy (ClearArray cnt base)); 10072 effect(USE_KILL cnt, USE_KILL base, KILL zero, KILL cr); 10073 10074 format %{ "xorl rax, rax\t# ClearArray:\n\t" 10075 "rep stosq\t# Store rax to *rdi++ while rcx--" %} 10076 ins_encode(opc_reg_reg(0x33, RAX, RAX), // xorl %eax, %eax 10077 Opcode(0xF3), Opcode(0x48), Opcode(0xAB)); // rep REX_W stos 10078 ins_pipe(pipe_slow); 10079%} 10080 10081instruct string_compare(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10082 rax_RegI result, regD tmp1, rFlagsReg cr) 10083%{ 10084 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10085 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10086 10087 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10088 ins_encode %{ 10089 __ string_compare($str1$$Register, $str2$$Register, 10090 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10091 $tmp1$$XMMRegister); 10092 %} 10093 ins_pipe( pipe_slow ); 10094%} 10095 10096// fast search of substring with known size. 10097instruct string_indexof_con(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 10098 rbx_RegI result, regD vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 10099%{ 10100 predicate(UseSSE42Intrinsics); 10101 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 10102 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 10103 10104 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 10105 ins_encode %{ 10106 int icnt2 = (int)$int_cnt2$$constant; 10107 if (icnt2 >= 8) { 10108 // IndexOf for constant substrings with size >= 8 elements 10109 // which don't need to be loaded through stack. 10110 __ string_indexofC8($str1$$Register, $str2$$Register, 10111 $cnt1$$Register, $cnt2$$Register, 10112 icnt2, $result$$Register, 10113 $vec$$XMMRegister, $tmp$$Register); 10114 } else { 10115 // Small strings are loaded through stack if they cross page boundary. 10116 __ string_indexof($str1$$Register, $str2$$Register, 10117 $cnt1$$Register, $cnt2$$Register, 10118 icnt2, $result$$Register, 10119 $vec$$XMMRegister, $tmp$$Register); 10120 } 10121 %} 10122 ins_pipe( pipe_slow ); 10123%} 10124 10125instruct string_indexof(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 10126 rbx_RegI result, regD vec, rcx_RegI tmp, rFlagsReg cr) 10127%{ 10128 predicate(UseSSE42Intrinsics); 10129 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 10130 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 10131 10132 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 10133 ins_encode %{ 10134 __ string_indexof($str1$$Register, $str2$$Register, 10135 $cnt1$$Register, $cnt2$$Register, 10136 (-1), $result$$Register, 10137 $vec$$XMMRegister, $tmp$$Register); 10138 %} 10139 ins_pipe( pipe_slow ); 10140%} 10141 10142// fast string equals 10143instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 10144 regD tmp1, regD tmp2, rbx_RegI tmp3, rFlagsReg cr) 10145%{ 10146 match(Set result (StrEquals (Binary str1 str2) cnt)); 10147 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 10148 10149 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 10150 ins_encode %{ 10151 __ char_arrays_equals(false, $str1$$Register, $str2$$Register, 10152 $cnt$$Register, $result$$Register, $tmp3$$Register, 10153 $tmp1$$XMMRegister, $tmp2$$XMMRegister); 10154 %} 10155 ins_pipe( pipe_slow ); 10156%} 10157 10158// fast array equals 10159instruct array_equals(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 10160 regD tmp1, regD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 10161%{ 10162 match(Set result (AryEq ary1 ary2)); 10163 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 10164 //ins_cost(300); 10165 10166 format %{ "Array Equals $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 10167 ins_encode %{ 10168 __ char_arrays_equals(true, $ary1$$Register, $ary2$$Register, 10169 $tmp3$$Register, $result$$Register, $tmp4$$Register, 10170 $tmp1$$XMMRegister, $tmp2$$XMMRegister); 10171 %} 10172 ins_pipe( pipe_slow ); 10173%} 10174 10175//----------Control Flow Instructions------------------------------------------ 10176// Signed compare Instructions 10177 10178// XXX more variants!! 10179instruct compI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 10180%{ 10181 match(Set cr (CmpI op1 op2)); 10182 effect(DEF cr, USE op1, USE op2); 10183 10184 format %{ "cmpl $op1, $op2" %} 10185 opcode(0x3B); /* Opcode 3B /r */ 10186 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2)); 10187 ins_pipe(ialu_cr_reg_reg); 10188%} 10189 10190instruct compI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 10191%{ 10192 match(Set cr (CmpI op1 op2)); 10193 10194 format %{ "cmpl $op1, $op2" %} 10195 opcode(0x81, 0x07); /* Opcode 81 /7 */ 10196 ins_encode(OpcSErm(op1, op2), Con8or32(op2)); 10197 ins_pipe(ialu_cr_reg_imm); 10198%} 10199 10200instruct compI_rReg_mem(rFlagsReg cr, rRegI op1, memory op2) 10201%{ 10202 match(Set cr (CmpI op1 (LoadI op2))); 10203 10204 ins_cost(500); // XXX 10205 format %{ "cmpl $op1, $op2" %} 10206 opcode(0x3B); /* Opcode 3B /r */ 10207 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2)); 10208 ins_pipe(ialu_cr_reg_mem); 10209%} 10210 10211instruct testI_reg(rFlagsReg cr, rRegI src, immI0 zero) 10212%{ 10213 match(Set cr (CmpI src zero)); 10214 10215 format %{ "testl $src, $src" %} 10216 opcode(0x85); 10217 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src)); 10218 ins_pipe(ialu_cr_reg_imm); 10219%} 10220 10221instruct testI_reg_imm(rFlagsReg cr, rRegI src, immI con, immI0 zero) 10222%{ 10223 match(Set cr (CmpI (AndI src con) zero)); 10224 10225 format %{ "testl $src, $con" %} 10226 opcode(0xF7, 0x00); 10227 ins_encode(REX_reg(src), OpcP, reg_opc(src), Con32(con)); 10228 ins_pipe(ialu_cr_reg_imm); 10229%} 10230 10231instruct testI_reg_mem(rFlagsReg cr, rRegI src, memory mem, immI0 zero) 10232%{ 10233 match(Set cr (CmpI (AndI src (LoadI mem)) zero)); 10234 10235 format %{ "testl $src, $mem" %} 10236 opcode(0x85); 10237 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 10238 ins_pipe(ialu_cr_reg_mem); 10239%} 10240 10241// Unsigned compare Instructions; really, same as signed except they 10242// produce an rFlagsRegU instead of rFlagsReg. 10243instruct compU_rReg(rFlagsRegU cr, rRegI op1, rRegI op2) 10244%{ 10245 match(Set cr (CmpU op1 op2)); 10246 10247 format %{ "cmpl $op1, $op2\t# unsigned" %} 10248 opcode(0x3B); /* Opcode 3B /r */ 10249 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2)); 10250 ins_pipe(ialu_cr_reg_reg); 10251%} 10252 10253instruct compU_rReg_imm(rFlagsRegU cr, rRegI op1, immI op2) 10254%{ 10255 match(Set cr (CmpU op1 op2)); 10256 10257 format %{ "cmpl $op1, $op2\t# unsigned" %} 10258 opcode(0x81,0x07); /* Opcode 81 /7 */ 10259 ins_encode(OpcSErm(op1, op2), Con8or32(op2)); 10260 ins_pipe(ialu_cr_reg_imm); 10261%} 10262 10263instruct compU_rReg_mem(rFlagsRegU cr, rRegI op1, memory op2) 10264%{ 10265 match(Set cr (CmpU op1 (LoadI op2))); 10266 10267 ins_cost(500); // XXX 10268 format %{ "cmpl $op1, $op2\t# unsigned" %} 10269 opcode(0x3B); /* Opcode 3B /r */ 10270 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2)); 10271 ins_pipe(ialu_cr_reg_mem); 10272%} 10273 10274// // // Cisc-spilled version of cmpU_rReg 10275// //instruct compU_mem_rReg(rFlagsRegU cr, memory op1, rRegI op2) 10276// //%{ 10277// // match(Set cr (CmpU (LoadI op1) op2)); 10278// // 10279// // format %{ "CMPu $op1,$op2" %} 10280// // ins_cost(500); 10281// // opcode(0x39); /* Opcode 39 /r */ 10282// // ins_encode( OpcP, reg_mem( op1, op2) ); 10283// //%} 10284 10285instruct testU_reg(rFlagsRegU cr, rRegI src, immI0 zero) 10286%{ 10287 match(Set cr (CmpU src zero)); 10288 10289 format %{ "testl $src, $src\t# unsigned" %} 10290 opcode(0x85); 10291 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src)); 10292 ins_pipe(ialu_cr_reg_imm); 10293%} 10294 10295instruct compP_rReg(rFlagsRegU cr, rRegP op1, rRegP op2) 10296%{ 10297 match(Set cr (CmpP op1 op2)); 10298 10299 format %{ "cmpq $op1, $op2\t# ptr" %} 10300 opcode(0x3B); /* Opcode 3B /r */ 10301 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 10302 ins_pipe(ialu_cr_reg_reg); 10303%} 10304 10305instruct compP_rReg_mem(rFlagsRegU cr, rRegP op1, memory op2) 10306%{ 10307 match(Set cr (CmpP op1 (LoadP op2))); 10308 10309 ins_cost(500); // XXX 10310 format %{ "cmpq $op1, $op2\t# ptr" %} 10311 opcode(0x3B); /* Opcode 3B /r */ 10312 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 10313 ins_pipe(ialu_cr_reg_mem); 10314%} 10315 10316// // // Cisc-spilled version of cmpP_rReg 10317// //instruct compP_mem_rReg(rFlagsRegU cr, memory op1, rRegP op2) 10318// //%{ 10319// // match(Set cr (CmpP (LoadP op1) op2)); 10320// // 10321// // format %{ "CMPu $op1,$op2" %} 10322// // ins_cost(500); 10323// // opcode(0x39); /* Opcode 39 /r */ 10324// // ins_encode( OpcP, reg_mem( op1, op2) ); 10325// //%} 10326 10327// XXX this is generalized by compP_rReg_mem??? 10328// Compare raw pointer (used in out-of-heap check). 10329// Only works because non-oop pointers must be raw pointers 10330// and raw pointers have no anti-dependencies. 10331instruct compP_mem_rReg(rFlagsRegU cr, rRegP op1, memory op2) 10332%{ 10333 predicate(n->in(2)->in(2)->bottom_type()->reloc() == relocInfo::none); 10334 match(Set cr (CmpP op1 (LoadP op2))); 10335 10336 format %{ "cmpq $op1, $op2\t# raw ptr" %} 10337 opcode(0x3B); /* Opcode 3B /r */ 10338 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 10339 ins_pipe(ialu_cr_reg_mem); 10340%} 10341 10342// This will generate a signed flags result. This should be OK since 10343// any compare to a zero should be eq/neq. 10344instruct testP_reg(rFlagsReg cr, rRegP src, immP0 zero) 10345%{ 10346 match(Set cr (CmpP src zero)); 10347 10348 format %{ "testq $src, $src\t# ptr" %} 10349 opcode(0x85); 10350 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 10351 ins_pipe(ialu_cr_reg_imm); 10352%} 10353 10354// This will generate a signed flags result. This should be OK since 10355// any compare to a zero should be eq/neq. 10356instruct testP_mem(rFlagsReg cr, memory op, immP0 zero) 10357%{ 10358 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL)); 10359 match(Set cr (CmpP (LoadP op) zero)); 10360 10361 ins_cost(500); // XXX 10362 format %{ "testq $op, 0xffffffffffffffff\t# ptr" %} 10363 opcode(0xF7); /* Opcode F7 /0 */ 10364 ins_encode(REX_mem_wide(op), 10365 OpcP, RM_opc_mem(0x00, op), Con_d32(0xFFFFFFFF)); 10366 ins_pipe(ialu_cr_reg_imm); 10367%} 10368 10369instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero) 10370%{ 10371 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL)); 10372 match(Set cr (CmpP (LoadP mem) zero)); 10373 10374 format %{ "cmpq R12, $mem\t# ptr (R12_heapbase==0)" %} 10375 ins_encode %{ 10376 __ cmpq(r12, $mem$$Address); 10377 %} 10378 ins_pipe(ialu_cr_reg_mem); 10379%} 10380 10381instruct compN_rReg(rFlagsRegU cr, rRegN op1, rRegN op2) 10382%{ 10383 match(Set cr (CmpN op1 op2)); 10384 10385 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 10386 ins_encode %{ __ cmpl($op1$$Register, $op2$$Register); %} 10387 ins_pipe(ialu_cr_reg_reg); 10388%} 10389 10390instruct compN_rReg_mem(rFlagsRegU cr, rRegN src, memory mem) 10391%{ 10392 match(Set cr (CmpN src (LoadN mem))); 10393 10394 format %{ "cmpl $src, $mem\t# compressed ptr" %} 10395 ins_encode %{ 10396 __ cmpl($src$$Register, $mem$$Address); 10397 %} 10398 ins_pipe(ialu_cr_reg_mem); 10399%} 10400 10401instruct compN_rReg_imm(rFlagsRegU cr, rRegN op1, immN op2) %{ 10402 match(Set cr (CmpN op1 op2)); 10403 10404 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 10405 ins_encode %{ 10406 __ cmp_narrow_oop($op1$$Register, (jobject)$op2$$constant); 10407 %} 10408 ins_pipe(ialu_cr_reg_imm); 10409%} 10410 10411instruct compN_mem_imm(rFlagsRegU cr, memory mem, immN src) 10412%{ 10413 match(Set cr (CmpN src (LoadN mem))); 10414 10415 format %{ "cmpl $mem, $src\t# compressed ptr" %} 10416 ins_encode %{ 10417 __ cmp_narrow_oop($mem$$Address, (jobject)$src$$constant); 10418 %} 10419 ins_pipe(ialu_cr_reg_mem); 10420%} 10421 10422instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{ 10423 match(Set cr (CmpN src zero)); 10424 10425 format %{ "testl $src, $src\t# compressed ptr" %} 10426 ins_encode %{ __ testl($src$$Register, $src$$Register); %} 10427 ins_pipe(ialu_cr_reg_imm); 10428%} 10429 10430instruct testN_mem(rFlagsReg cr, memory mem, immN0 zero) 10431%{ 10432 predicate(Universe::narrow_oop_base() != NULL); 10433 match(Set cr (CmpN (LoadN mem) zero)); 10434 10435 ins_cost(500); // XXX 10436 format %{ "testl $mem, 0xffffffff\t# compressed ptr" %} 10437 ins_encode %{ 10438 __ cmpl($mem$$Address, (int)0xFFFFFFFF); 10439 %} 10440 ins_pipe(ialu_cr_reg_mem); 10441%} 10442 10443instruct testN_mem_reg0(rFlagsReg cr, memory mem, immN0 zero) 10444%{ 10445 predicate(Universe::narrow_oop_base() == NULL); 10446 match(Set cr (CmpN (LoadN mem) zero)); 10447 10448 format %{ "cmpl R12, $mem\t# compressed ptr (R12_heapbase==0)" %} 10449 ins_encode %{ 10450 __ cmpl(r12, $mem$$Address); 10451 %} 10452 ins_pipe(ialu_cr_reg_mem); 10453%} 10454 10455// Yanked all unsigned pointer compare operations. 10456// Pointer compares are done with CmpP which is already unsigned. 10457 10458instruct compL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 10459%{ 10460 match(Set cr (CmpL op1 op2)); 10461 10462 format %{ "cmpq $op1, $op2" %} 10463 opcode(0x3B); /* Opcode 3B /r */ 10464 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 10465 ins_pipe(ialu_cr_reg_reg); 10466%} 10467 10468instruct compL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 10469%{ 10470 match(Set cr (CmpL op1 op2)); 10471 10472 format %{ "cmpq $op1, $op2" %} 10473 opcode(0x81, 0x07); /* Opcode 81 /7 */ 10474 ins_encode(OpcSErm_wide(op1, op2), Con8or32(op2)); 10475 ins_pipe(ialu_cr_reg_imm); 10476%} 10477 10478instruct compL_rReg_mem(rFlagsReg cr, rRegL op1, memory op2) 10479%{ 10480 match(Set cr (CmpL op1 (LoadL op2))); 10481 10482 format %{ "cmpq $op1, $op2" %} 10483 opcode(0x3B); /* Opcode 3B /r */ 10484 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 10485 ins_pipe(ialu_cr_reg_mem); 10486%} 10487 10488instruct testL_reg(rFlagsReg cr, rRegL src, immL0 zero) 10489%{ 10490 match(Set cr (CmpL src zero)); 10491 10492 format %{ "testq $src, $src" %} 10493 opcode(0x85); 10494 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 10495 ins_pipe(ialu_cr_reg_imm); 10496%} 10497 10498instruct testL_reg_imm(rFlagsReg cr, rRegL src, immL32 con, immL0 zero) 10499%{ 10500 match(Set cr (CmpL (AndL src con) zero)); 10501 10502 format %{ "testq $src, $con\t# long" %} 10503 opcode(0xF7, 0x00); 10504 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src), Con32(con)); 10505 ins_pipe(ialu_cr_reg_imm); 10506%} 10507 10508instruct testL_reg_mem(rFlagsReg cr, rRegL src, memory mem, immL0 zero) 10509%{ 10510 match(Set cr (CmpL (AndL src (LoadL mem)) zero)); 10511 10512 format %{ "testq $src, $mem" %} 10513 opcode(0x85); 10514 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 10515 ins_pipe(ialu_cr_reg_mem); 10516%} 10517 10518// Manifest a CmpL result in an integer register. Very painful. 10519// This is the test to avoid. 10520instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 10521%{ 10522 match(Set dst (CmpL3 src1 src2)); 10523 effect(KILL flags); 10524 10525 ins_cost(275); // XXX 10526 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 10527 "movl $dst, -1\n\t" 10528 "jl,s done\n\t" 10529 "setne $dst\n\t" 10530 "movzbl $dst, $dst\n\t" 10531 "done:" %} 10532 ins_encode(cmpl3_flag(src1, src2, dst)); 10533 ins_pipe(pipe_slow); 10534%} 10535 10536//----------Max and Min-------------------------------------------------------- 10537// Min Instructions 10538 10539instruct cmovI_reg_g(rRegI dst, rRegI src, rFlagsReg cr) 10540%{ 10541 effect(USE_DEF dst, USE src, USE cr); 10542 10543 format %{ "cmovlgt $dst, $src\t# min" %} 10544 opcode(0x0F, 0x4F); 10545 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 10546 ins_pipe(pipe_cmov_reg); 10547%} 10548 10549 10550instruct minI_rReg(rRegI dst, rRegI src) 10551%{ 10552 match(Set dst (MinI dst src)); 10553 10554 ins_cost(200); 10555 expand %{ 10556 rFlagsReg cr; 10557 compI_rReg(cr, dst, src); 10558 cmovI_reg_g(dst, src, cr); 10559 %} 10560%} 10561 10562instruct cmovI_reg_l(rRegI dst, rRegI src, rFlagsReg cr) 10563%{ 10564 effect(USE_DEF dst, USE src, USE cr); 10565 10566 format %{ "cmovllt $dst, $src\t# max" %} 10567 opcode(0x0F, 0x4C); 10568 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 10569 ins_pipe(pipe_cmov_reg); 10570%} 10571 10572 10573instruct maxI_rReg(rRegI dst, rRegI src) 10574%{ 10575 match(Set dst (MaxI dst src)); 10576 10577 ins_cost(200); 10578 expand %{ 10579 rFlagsReg cr; 10580 compI_rReg(cr, dst, src); 10581 cmovI_reg_l(dst, src, cr); 10582 %} 10583%} 10584 10585// ============================================================================ 10586// Branch Instructions 10587 10588// Jump Direct - Label defines a relative address from JMP+1 10589instruct jmpDir(label labl) 10590%{ 10591 match(Goto); 10592 effect(USE labl); 10593 10594 ins_cost(300); 10595 format %{ "jmp $labl" %} 10596 size(5); 10597 ins_encode %{ 10598 Label* L = $labl$$label; 10599 __ jmp(*L, false); // Always long jump 10600 %} 10601 ins_pipe(pipe_jmp); 10602%} 10603 10604// Jump Direct Conditional - Label defines a relative address from Jcc+1 10605instruct jmpCon(cmpOp cop, rFlagsReg cr, label labl) 10606%{ 10607 match(If cop cr); 10608 effect(USE labl); 10609 10610 ins_cost(300); 10611 format %{ "j$cop $labl" %} 10612 size(6); 10613 ins_encode %{ 10614 Label* L = $labl$$label; 10615 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 10616 %} 10617 ins_pipe(pipe_jcc); 10618%} 10619 10620// Jump Direct Conditional - Label defines a relative address from Jcc+1 10621instruct jmpLoopEnd(cmpOp cop, rFlagsReg cr, label labl) 10622%{ 10623 match(CountedLoopEnd cop cr); 10624 effect(USE labl); 10625 10626 ins_cost(300); 10627 format %{ "j$cop $labl\t# loop end" %} 10628 size(6); 10629 ins_encode %{ 10630 Label* L = $labl$$label; 10631 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 10632 %} 10633 ins_pipe(pipe_jcc); 10634%} 10635 10636// Jump Direct Conditional - Label defines a relative address from Jcc+1 10637instruct jmpLoopEndU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 10638 match(CountedLoopEnd cop cmp); 10639 effect(USE labl); 10640 10641 ins_cost(300); 10642 format %{ "j$cop,u $labl\t# loop end" %} 10643 size(6); 10644 ins_encode %{ 10645 Label* L = $labl$$label; 10646 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 10647 %} 10648 ins_pipe(pipe_jcc); 10649%} 10650 10651instruct jmpLoopEndUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 10652 match(CountedLoopEnd cop cmp); 10653 effect(USE labl); 10654 10655 ins_cost(200); 10656 format %{ "j$cop,u $labl\t# loop end" %} 10657 size(6); 10658 ins_encode %{ 10659 Label* L = $labl$$label; 10660 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 10661 %} 10662 ins_pipe(pipe_jcc); 10663%} 10664 10665// Jump Direct Conditional - using unsigned comparison 10666instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 10667 match(If cop cmp); 10668 effect(USE labl); 10669 10670 ins_cost(300); 10671 format %{ "j$cop,u $labl" %} 10672 size(6); 10673 ins_encode %{ 10674 Label* L = $labl$$label; 10675 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 10676 %} 10677 ins_pipe(pipe_jcc); 10678%} 10679 10680instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 10681 match(If cop cmp); 10682 effect(USE labl); 10683 10684 ins_cost(200); 10685 format %{ "j$cop,u $labl" %} 10686 size(6); 10687 ins_encode %{ 10688 Label* L = $labl$$label; 10689 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 10690 %} 10691 ins_pipe(pipe_jcc); 10692%} 10693 10694instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 10695 match(If cop cmp); 10696 effect(USE labl); 10697 10698 ins_cost(200); 10699 format %{ $$template 10700 if ($cop$$cmpcode == Assembler::notEqual) { 10701 $$emit$$"jp,u $labl\n\t" 10702 $$emit$$"j$cop,u $labl" 10703 } else { 10704 $$emit$$"jp,u done\n\t" 10705 $$emit$$"j$cop,u $labl\n\t" 10706 $$emit$$"done:" 10707 } 10708 %} 10709 ins_encode %{ 10710 Label* l = $labl$$label; 10711 if ($cop$$cmpcode == Assembler::notEqual) { 10712 __ jcc(Assembler::parity, *l, false); 10713 __ jcc(Assembler::notEqual, *l, false); 10714 } else if ($cop$$cmpcode == Assembler::equal) { 10715 Label done; 10716 __ jccb(Assembler::parity, done); 10717 __ jcc(Assembler::equal, *l, false); 10718 __ bind(done); 10719 } else { 10720 ShouldNotReachHere(); 10721 } 10722 %} 10723 ins_pipe(pipe_jcc); 10724%} 10725 10726// ============================================================================ 10727// The 2nd slow-half of a subtype check. Scan the subklass's 2ndary 10728// superklass array for an instance of the superklass. Set a hidden 10729// internal cache on a hit (cache is checked with exposed code in 10730// gen_subtype_check()). Return NZ for a miss or zero for a hit. The 10731// encoding ALSO sets flags. 10732 10733instruct partialSubtypeCheck(rdi_RegP result, 10734 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 10735 rFlagsReg cr) 10736%{ 10737 match(Set result (PartialSubtypeCheck sub super)); 10738 effect(KILL rcx, KILL cr); 10739 10740 ins_cost(1100); // slightly larger than the next version 10741 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 10742 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 10743 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 10744 "repne scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t" 10745 "jne,s miss\t\t# Missed: rdi not-zero\n\t" 10746 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 10747 "xorq $result, $result\t\t Hit: rdi zero\n\t" 10748 "miss:\t" %} 10749 10750 opcode(0x1); // Force a XOR of RDI 10751 ins_encode(enc_PartialSubtypeCheck()); 10752 ins_pipe(pipe_slow); 10753%} 10754 10755instruct partialSubtypeCheck_vs_Zero(rFlagsReg cr, 10756 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 10757 immP0 zero, 10758 rdi_RegP result) 10759%{ 10760 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 10761 effect(KILL rcx, KILL result); 10762 10763 ins_cost(1000); 10764 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 10765 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 10766 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 10767 "repne scasq\t# Scan *rdi++ for a match with rax while cx-- != 0\n\t" 10768 "jne,s miss\t\t# Missed: flags nz\n\t" 10769 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 10770 "miss:\t" %} 10771 10772 opcode(0x0); // No need to XOR RDI 10773 ins_encode(enc_PartialSubtypeCheck()); 10774 ins_pipe(pipe_slow); 10775%} 10776 10777// ============================================================================ 10778// Branch Instructions -- short offset versions 10779// 10780// These instructions are used to replace jumps of a long offset (the default 10781// match) with jumps of a shorter offset. These instructions are all tagged 10782// with the ins_short_branch attribute, which causes the ADLC to suppress the 10783// match rules in general matching. Instead, the ADLC generates a conversion 10784// method in the MachNode which can be used to do in-place replacement of the 10785// long variant with the shorter variant. The compiler will determine if a 10786// branch can be taken by the is_short_branch_offset() predicate in the machine 10787// specific code section of the file. 10788 10789// Jump Direct - Label defines a relative address from JMP+1 10790instruct jmpDir_short(label labl) %{ 10791 match(Goto); 10792 effect(USE labl); 10793 10794 ins_cost(300); 10795 format %{ "jmp,s $labl" %} 10796 size(2); 10797 ins_encode %{ 10798 Label* L = $labl$$label; 10799 __ jmpb(*L); 10800 %} 10801 ins_pipe(pipe_jmp); 10802 ins_short_branch(1); 10803%} 10804 10805// Jump Direct Conditional - Label defines a relative address from Jcc+1 10806instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{ 10807 match(If cop cr); 10808 effect(USE labl); 10809 10810 ins_cost(300); 10811 format %{ "j$cop,s $labl" %} 10812 size(2); 10813 ins_encode %{ 10814 Label* L = $labl$$label; 10815 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 10816 %} 10817 ins_pipe(pipe_jcc); 10818 ins_short_branch(1); 10819%} 10820 10821// Jump Direct Conditional - Label defines a relative address from Jcc+1 10822instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{ 10823 match(CountedLoopEnd cop cr); 10824 effect(USE labl); 10825 10826 ins_cost(300); 10827 format %{ "j$cop,s $labl\t# loop end" %} 10828 size(2); 10829 ins_encode %{ 10830 Label* L = $labl$$label; 10831 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 10832 %} 10833 ins_pipe(pipe_jcc); 10834 ins_short_branch(1); 10835%} 10836 10837// Jump Direct Conditional - Label defines a relative address from Jcc+1 10838instruct jmpLoopEndU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 10839 match(CountedLoopEnd cop cmp); 10840 effect(USE labl); 10841 10842 ins_cost(300); 10843 format %{ "j$cop,us $labl\t# loop end" %} 10844 size(2); 10845 ins_encode %{ 10846 Label* L = $labl$$label; 10847 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 10848 %} 10849 ins_pipe(pipe_jcc); 10850 ins_short_branch(1); 10851%} 10852 10853instruct jmpLoopEndUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 10854 match(CountedLoopEnd cop cmp); 10855 effect(USE labl); 10856 10857 ins_cost(300); 10858 format %{ "j$cop,us $labl\t# loop end" %} 10859 size(2); 10860 ins_encode %{ 10861 Label* L = $labl$$label; 10862 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 10863 %} 10864 ins_pipe(pipe_jcc); 10865 ins_short_branch(1); 10866%} 10867 10868// Jump Direct Conditional - using unsigned comparison 10869instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 10870 match(If cop cmp); 10871 effect(USE labl); 10872 10873 ins_cost(300); 10874 format %{ "j$cop,us $labl" %} 10875 size(2); 10876 ins_encode %{ 10877 Label* L = $labl$$label; 10878 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 10879 %} 10880 ins_pipe(pipe_jcc); 10881 ins_short_branch(1); 10882%} 10883 10884instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 10885 match(If cop cmp); 10886 effect(USE labl); 10887 10888 ins_cost(300); 10889 format %{ "j$cop,us $labl" %} 10890 size(2); 10891 ins_encode %{ 10892 Label* L = $labl$$label; 10893 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 10894 %} 10895 ins_pipe(pipe_jcc); 10896 ins_short_branch(1); 10897%} 10898 10899instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 10900 match(If cop cmp); 10901 effect(USE labl); 10902 10903 ins_cost(300); 10904 format %{ $$template 10905 if ($cop$$cmpcode == Assembler::notEqual) { 10906 $$emit$$"jp,u,s $labl\n\t" 10907 $$emit$$"j$cop,u,s $labl" 10908 } else { 10909 $$emit$$"jp,u,s done\n\t" 10910 $$emit$$"j$cop,u,s $labl\n\t" 10911 $$emit$$"done:" 10912 } 10913 %} 10914 size(4); 10915 ins_encode %{ 10916 Label* l = $labl$$label; 10917 if ($cop$$cmpcode == Assembler::notEqual) { 10918 __ jccb(Assembler::parity, *l); 10919 __ jccb(Assembler::notEqual, *l); 10920 } else if ($cop$$cmpcode == Assembler::equal) { 10921 Label done; 10922 __ jccb(Assembler::parity, done); 10923 __ jccb(Assembler::equal, *l); 10924 __ bind(done); 10925 } else { 10926 ShouldNotReachHere(); 10927 } 10928 %} 10929 ins_pipe(pipe_jcc); 10930 ins_short_branch(1); 10931%} 10932 10933// ============================================================================ 10934// inlined locking and unlocking 10935 10936instruct cmpFastLock(rFlagsReg cr, 10937 rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr) 10938%{ 10939 match(Set cr (FastLock object box)); 10940 effect(TEMP tmp, TEMP scr, USE_KILL box); 10941 10942 ins_cost(300); 10943 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr" %} 10944 ins_encode(Fast_Lock(object, box, tmp, scr)); 10945 ins_pipe(pipe_slow); 10946%} 10947 10948instruct cmpFastUnlock(rFlagsReg cr, 10949 rRegP object, rax_RegP box, rRegP tmp) 10950%{ 10951 match(Set cr (FastUnlock object box)); 10952 effect(TEMP tmp, USE_KILL box); 10953 10954 ins_cost(300); 10955 format %{ "fastunlock $object,$box\t! kills $box,$tmp" %} 10956 ins_encode(Fast_Unlock(object, box, tmp)); 10957 ins_pipe(pipe_slow); 10958%} 10959 10960 10961// ============================================================================ 10962// Safepoint Instructions 10963instruct safePoint_poll(rFlagsReg cr) 10964%{ 10965 predicate(!Assembler::is_polling_page_far()); 10966 match(SafePoint); 10967 effect(KILL cr); 10968 10969 format %{ "testl rax, [rip + #offset_to_poll_page]\t" 10970 "# Safepoint: poll for GC" %} 10971 ins_cost(125); 10972 ins_encode %{ 10973 AddressLiteral addr(os::get_polling_page(), relocInfo::poll_type); 10974 __ testl(rax, addr); 10975 %} 10976 ins_pipe(ialu_reg_mem); 10977%} 10978 10979instruct safePoint_poll_far(rFlagsReg cr, rRegP poll) 10980%{ 10981 predicate(Assembler::is_polling_page_far()); 10982 match(SafePoint poll); 10983 effect(KILL cr, USE poll); 10984 10985 format %{ "testl rax, [$poll]\t" 10986 "# Safepoint: poll for GC" %} 10987 ins_cost(125); 10988 ins_encode %{ 10989 __ relocate(relocInfo::poll_type); 10990 __ testl(rax, Address($poll$$Register, 0)); 10991 %} 10992 ins_pipe(ialu_reg_mem); 10993%} 10994 10995// ============================================================================ 10996// Procedure Call/Return Instructions 10997// Call Java Static Instruction 10998// Note: If this code changes, the corresponding ret_addr_offset() and 10999// compute_padding() functions will have to be adjusted. 11000instruct CallStaticJavaDirect(method meth) %{ 11001 match(CallStaticJava); 11002 predicate(!((CallStaticJavaNode*) n)->is_method_handle_invoke()); 11003 effect(USE meth); 11004 11005 ins_cost(300); 11006 format %{ "call,static " %} 11007 opcode(0xE8); /* E8 cd */ 11008 ins_encode(Java_Static_Call(meth), call_epilog); 11009 ins_pipe(pipe_slow); 11010 ins_alignment(4); 11011%} 11012 11013// Call Java Static Instruction (method handle version) 11014// Note: If this code changes, the corresponding ret_addr_offset() and 11015// compute_padding() functions will have to be adjusted. 11016instruct CallStaticJavaHandle(method meth, rbp_RegP rbp_mh_SP_save) %{ 11017 match(CallStaticJava); 11018 predicate(((CallStaticJavaNode*) n)->is_method_handle_invoke()); 11019 effect(USE meth); 11020 // RBP is saved by all callees (for interpreter stack correction). 11021 // We use it here for a similar purpose, in {preserve,restore}_SP. 11022 11023 ins_cost(300); 11024 format %{ "call,static/MethodHandle " %} 11025 opcode(0xE8); /* E8 cd */ 11026 ins_encode(preserve_SP, 11027 Java_Static_Call(meth), 11028 restore_SP, 11029 call_epilog); 11030 ins_pipe(pipe_slow); 11031 ins_alignment(4); 11032%} 11033 11034// Call Java Dynamic Instruction 11035// Note: If this code changes, the corresponding ret_addr_offset() and 11036// compute_padding() functions will have to be adjusted. 11037instruct CallDynamicJavaDirect(method meth) 11038%{ 11039 match(CallDynamicJava); 11040 effect(USE meth); 11041 11042 ins_cost(300); 11043 format %{ "movq rax, #Universe::non_oop_word()\n\t" 11044 "call,dynamic " %} 11045 ins_encode(Java_Dynamic_Call(meth), call_epilog); 11046 ins_pipe(pipe_slow); 11047 ins_alignment(4); 11048%} 11049 11050// Call Runtime Instruction 11051instruct CallRuntimeDirect(method meth) 11052%{ 11053 match(CallRuntime); 11054 effect(USE meth); 11055 11056 ins_cost(300); 11057 format %{ "call,runtime " %} 11058 opcode(0xE8); /* E8 cd */ 11059 ins_encode(Java_To_Runtime(meth)); 11060 ins_pipe(pipe_slow); 11061%} 11062 11063// Call runtime without safepoint 11064instruct CallLeafDirect(method meth) 11065%{ 11066 match(CallLeaf); 11067 effect(USE meth); 11068 11069 ins_cost(300); 11070 format %{ "call_leaf,runtime " %} 11071 opcode(0xE8); /* E8 cd */ 11072 ins_encode(Java_To_Runtime(meth)); 11073 ins_pipe(pipe_slow); 11074%} 11075 11076// Call runtime without safepoint 11077instruct CallLeafNoFPDirect(method meth) 11078%{ 11079 match(CallLeafNoFP); 11080 effect(USE meth); 11081 11082 ins_cost(300); 11083 format %{ "call_leaf_nofp,runtime " %} 11084 opcode(0xE8); /* E8 cd */ 11085 ins_encode(Java_To_Runtime(meth)); 11086 ins_pipe(pipe_slow); 11087%} 11088 11089// Return Instruction 11090// Remove the return address & jump to it. 11091// Notice: We always emit a nop after a ret to make sure there is room 11092// for safepoint patching 11093instruct Ret() 11094%{ 11095 match(Return); 11096 11097 format %{ "ret" %} 11098 opcode(0xC3); 11099 ins_encode(OpcP); 11100 ins_pipe(pipe_jmp); 11101%} 11102 11103// Tail Call; Jump from runtime stub to Java code. 11104// Also known as an 'interprocedural jump'. 11105// Target of jump will eventually return to caller. 11106// TailJump below removes the return address. 11107instruct TailCalljmpInd(no_rbp_RegP jump_target, rbx_RegP method_oop) 11108%{ 11109 match(TailCall jump_target method_oop); 11110 11111 ins_cost(300); 11112 format %{ "jmp $jump_target\t# rbx holds method oop" %} 11113 opcode(0xFF, 0x4); /* Opcode FF /4 */ 11114 ins_encode(REX_reg(jump_target), OpcP, reg_opc(jump_target)); 11115 ins_pipe(pipe_jmp); 11116%} 11117 11118// Tail Jump; remove the return address; jump to target. 11119// TailCall above leaves the return address around. 11120instruct tailjmpInd(no_rbp_RegP jump_target, rax_RegP ex_oop) 11121%{ 11122 match(TailJump jump_target ex_oop); 11123 11124 ins_cost(300); 11125 format %{ "popq rdx\t# pop return address\n\t" 11126 "jmp $jump_target" %} 11127 opcode(0xFF, 0x4); /* Opcode FF /4 */ 11128 ins_encode(Opcode(0x5a), // popq rdx 11129 REX_reg(jump_target), OpcP, reg_opc(jump_target)); 11130 ins_pipe(pipe_jmp); 11131%} 11132 11133// Create exception oop: created by stack-crawling runtime code. 11134// Created exception is now available to this handler, and is setup 11135// just prior to jumping to this handler. No code emitted. 11136instruct CreateException(rax_RegP ex_oop) 11137%{ 11138 match(Set ex_oop (CreateEx)); 11139 11140 size(0); 11141 // use the following format syntax 11142 format %{ "# exception oop is in rax; no code emitted" %} 11143 ins_encode(); 11144 ins_pipe(empty); 11145%} 11146 11147// Rethrow exception: 11148// The exception oop will come in the first argument position. 11149// Then JUMP (not call) to the rethrow stub code. 11150instruct RethrowException() 11151%{ 11152 match(Rethrow); 11153 11154 // use the following format syntax 11155 format %{ "jmp rethrow_stub" %} 11156 ins_encode(enc_rethrow); 11157 ins_pipe(pipe_jmp); 11158%} 11159 11160 11161// ============================================================================ 11162// This name is KNOWN by the ADLC and cannot be changed. 11163// The ADLC forces a 'TypeRawPtr::BOTTOM' output type 11164// for this guy. 11165instruct tlsLoadP(r15_RegP dst) %{ 11166 match(Set dst (ThreadLocal)); 11167 effect(DEF dst); 11168 11169 size(0); 11170 format %{ "# TLS is in R15" %} 11171 ins_encode( /*empty encoding*/ ); 11172 ins_pipe(ialu_reg_reg); 11173%} 11174 11175 11176//----------PEEPHOLE RULES----------------------------------------------------- 11177// These must follow all instruction definitions as they use the names 11178// defined in the instructions definitions. 11179// 11180// peepmatch ( root_instr_name [preceding_instruction]* ); 11181// 11182// peepconstraint %{ 11183// (instruction_number.operand_name relational_op instruction_number.operand_name 11184// [, ...] ); 11185// // instruction numbers are zero-based using left to right order in peepmatch 11186// 11187// peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 11188// // provide an instruction_number.operand_name for each operand that appears 11189// // in the replacement instruction's match rule 11190// 11191// ---------VM FLAGS--------------------------------------------------------- 11192// 11193// All peephole optimizations can be turned off using -XX:-OptoPeephole 11194// 11195// Each peephole rule is given an identifying number starting with zero and 11196// increasing by one in the order seen by the parser. An individual peephole 11197// can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 11198// on the command-line. 11199// 11200// ---------CURRENT LIMITATIONS---------------------------------------------- 11201// 11202// Only match adjacent instructions in same basic block 11203// Only equality constraints 11204// Only constraints between operands, not (0.dest_reg == RAX_enc) 11205// Only one replacement instruction 11206// 11207// ---------EXAMPLE---------------------------------------------------------- 11208// 11209// // pertinent parts of existing instructions in architecture description 11210// instruct movI(rRegI dst, rRegI src) 11211// %{ 11212// match(Set dst (CopyI src)); 11213// %} 11214// 11215// instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr) 11216// %{ 11217// match(Set dst (AddI dst src)); 11218// effect(KILL cr); 11219// %} 11220// 11221// // Change (inc mov) to lea 11222// peephole %{ 11223// // increment preceeded by register-register move 11224// peepmatch ( incI_rReg movI ); 11225// // require that the destination register of the increment 11226// // match the destination register of the move 11227// peepconstraint ( 0.dst == 1.dst ); 11228// // construct a replacement instruction that sets 11229// // the destination to ( move's source register + one ) 11230// peepreplace ( leaI_rReg_immI( 0.dst 1.src 0.src ) ); 11231// %} 11232// 11233 11234// Implementation no longer uses movX instructions since 11235// machine-independent system no longer uses CopyX nodes. 11236// 11237// peephole 11238// %{ 11239// peepmatch (incI_rReg movI); 11240// peepconstraint (0.dst == 1.dst); 11241// peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 11242// %} 11243 11244// peephole 11245// %{ 11246// peepmatch (decI_rReg movI); 11247// peepconstraint (0.dst == 1.dst); 11248// peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 11249// %} 11250 11251// peephole 11252// %{ 11253// peepmatch (addI_rReg_imm movI); 11254// peepconstraint (0.dst == 1.dst); 11255// peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 11256// %} 11257 11258// peephole 11259// %{ 11260// peepmatch (incL_rReg movL); 11261// peepconstraint (0.dst == 1.dst); 11262// peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 11263// %} 11264 11265// peephole 11266// %{ 11267// peepmatch (decL_rReg movL); 11268// peepconstraint (0.dst == 1.dst); 11269// peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 11270// %} 11271 11272// peephole 11273// %{ 11274// peepmatch (addL_rReg_imm movL); 11275// peepconstraint (0.dst == 1.dst); 11276// peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 11277// %} 11278 11279// peephole 11280// %{ 11281// peepmatch (addP_rReg_imm movP); 11282// peepconstraint (0.dst == 1.dst); 11283// peepreplace (leaP_rReg_imm(0.dst 1.src 0.src)); 11284// %} 11285 11286// // Change load of spilled value to only a spill 11287// instruct storeI(memory mem, rRegI src) 11288// %{ 11289// match(Set mem (StoreI mem src)); 11290// %} 11291// 11292// instruct loadI(rRegI dst, memory mem) 11293// %{ 11294// match(Set dst (LoadI mem)); 11295// %} 11296// 11297 11298peephole 11299%{ 11300 peepmatch (loadI storeI); 11301 peepconstraint (1.src == 0.dst, 1.mem == 0.mem); 11302 peepreplace (storeI(1.mem 1.mem 1.src)); 11303%} 11304 11305peephole 11306%{ 11307 peepmatch (loadL storeL); 11308 peepconstraint (1.src == 0.dst, 1.mem == 0.mem); 11309 peepreplace (storeL(1.mem 1.mem 1.src)); 11310%} 11311 11312//----------SMARTSPILL RULES--------------------------------------------------- 11313// These must follow all instruction definitions as they use the names 11314// defined in the instructions definitions. 11315