x86_64.ad revision 4438:e961c11b85fe
188758Sache// 288758Sache// Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. 388758Sache// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 488758Sache// 588758Sache// This code is free software; you can redistribute it and/or modify it 688758Sache// under the terms of the GNU General Public License version 2 only, as 788758Sache// published by the Free Software Foundation. 888758Sache// 988758Sache// This code is distributed in the hope that it will be useful, but WITHOUT 1088758Sache// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1188758Sache// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1288758Sache// version 2 for more details (a copy is included in the LICENSE file that 1388758Sache// accompanied this code). 1488758Sache// 1588758Sache// You should have received a copy of the GNU General Public License version 1688758Sache// 2 along with this work; if not, write to the Free Software Foundation, 1788758Sache// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1888758Sache// 1988758Sache// Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2088758Sache// or visit www.oracle.com if you need additional information or have any 2188758Sache// questions. 2288758Sache// 2388758Sache// 2488758Sache 2588758Sache// AMD64 Architecture Description File 2688758Sache 2788758Sache//----------REGISTER DEFINITION BLOCK------------------------------------------ 2888758Sache// This information is used by the matcher and the register allocator to 2988758Sache// describe individual registers and classes of registers within the target 3088758Sache// archtecture. 3188758Sache 3288758Sacheregister %{ 3388758Sache//----------Architecture Description Register Definitions---------------------- 3488758Sache// General Registers 3588758Sache// "reg_def" name ( register save type, C convention save type, 3688758Sache// ideal register type, encoding ); 3788758Sache// Register Save Types: 3888758Sache// 3988758Sache// NS = No-Save: The register allocator assumes that these registers 4088758Sache// can be used without saving upon entry to the method, & 4188758Sache// that they do not need to be saved at call sites. 4288758Sache// 4388758Sache// SOC = Save-On-Call: The register allocator assumes that these registers 4488758Sache// can be used without saving upon entry to the method, 4588758Sache// but that they must be saved at call sites. 4688758Sache// 4788758Sache// SOE = Save-On-Entry: The register allocator assumes that these registers 4888758Sache// must be saved before using them upon entry to the 4988758Sache// method, but they do not need to be saved at call 5088758Sache// sites. 5188758Sache// 5288758Sache// AS = Always-Save: The register allocator assumes that these registers 5388758Sache// must be saved before using them upon entry to the 5488758Sache// method, & that they must be saved at call sites. 5588758Sache// 5688758Sache// Ideal Register Type is used to determine how to save & restore a 5788758Sache// register. Op_RegI will get spilled with LoadI/StoreI, Op_RegP will get 5888758Sache// spilled with LoadP/StoreP. If the register supports both, use Op_RegI. 5988758Sache// 6088758Sache// The encoding number is the actual bit-pattern placed into the opcodes. 6188758Sache 6288758Sache// General Registers 6388758Sache// R8-R15 must be encoded with REX. (RSP, RBP, RSI, RDI need REX when 6488758Sache// used as byte registers) 6588758Sache 6688758Sache// Previously set RBX, RSI, and RDI as save-on-entry for java code 6788758Sache// Turn off SOE in java-code due to frequent use of uncommon-traps. 6888758Sache// Now that allocator is better, turn on RSI and RDI as SOE registers. 6988758Sache 7088758Sachereg_def RAX (SOC, SOC, Op_RegI, 0, rax->as_VMReg()); 7188758Sachereg_def RAX_H(SOC, SOC, Op_RegI, 0, rax->as_VMReg()->next()); 7288758Sache 7388758Sachereg_def RCX (SOC, SOC, Op_RegI, 1, rcx->as_VMReg()); 7488758Sachereg_def RCX_H(SOC, SOC, Op_RegI, 1, rcx->as_VMReg()->next()); 7588758Sache 7688758Sachereg_def RDX (SOC, SOC, Op_RegI, 2, rdx->as_VMReg()); 7788758Sachereg_def RDX_H(SOC, SOC, Op_RegI, 2, rdx->as_VMReg()->next()); 7888758Sache 7988758Sachereg_def RBX (SOC, SOE, Op_RegI, 3, rbx->as_VMReg()); 8088758Sachereg_def RBX_H(SOC, SOE, Op_RegI, 3, rbx->as_VMReg()->next()); 8188758Sache 8288758Sachereg_def RSP (NS, NS, Op_RegI, 4, rsp->as_VMReg()); 8388758Sachereg_def RSP_H(NS, NS, Op_RegI, 4, rsp->as_VMReg()->next()); 8488758Sache 8588758Sache// now that adapter frames are gone RBP is always saved and restored by the prolog/epilog code 8688758Sachereg_def RBP (NS, SOE, Op_RegI, 5, rbp->as_VMReg()); 8788758Sachereg_def RBP_H(NS, SOE, Op_RegI, 5, rbp->as_VMReg()->next()); 8888758Sache 8988758Sache#ifdef _WIN64 9088758Sache 9188758Sachereg_def RSI (SOC, SOE, Op_RegI, 6, rsi->as_VMReg()); 9288758Sachereg_def RSI_H(SOC, SOE, Op_RegI, 6, rsi->as_VMReg()->next()); 9388758Sache 9488758Sachereg_def RDI (SOC, SOE, Op_RegI, 7, rdi->as_VMReg()); 9588758Sachereg_def RDI_H(SOC, SOE, Op_RegI, 7, rdi->as_VMReg()->next()); 9688758Sache 9788758Sache#else 9888758Sache 9988758Sachereg_def RSI (SOC, SOC, Op_RegI, 6, rsi->as_VMReg()); 10088758Sachereg_def RSI_H(SOC, SOC, Op_RegI, 6, rsi->as_VMReg()->next()); 10188758Sache 10288758Sachereg_def RDI (SOC, SOC, Op_RegI, 7, rdi->as_VMReg()); 10388758Sachereg_def RDI_H(SOC, SOC, Op_RegI, 7, rdi->as_VMReg()->next()); 10488758Sache 10588758Sache#endif 10688758Sache 10788758Sachereg_def R8 (SOC, SOC, Op_RegI, 8, r8->as_VMReg()); 10888758Sachereg_def R8_H (SOC, SOC, Op_RegI, 8, r8->as_VMReg()->next()); 10988758Sache 11088758Sachereg_def R9 (SOC, SOC, Op_RegI, 9, r9->as_VMReg()); 11188758Sachereg_def R9_H (SOC, SOC, Op_RegI, 9, r9->as_VMReg()->next()); 11288758Sache 11388758Sachereg_def R10 (SOC, SOC, Op_RegI, 10, r10->as_VMReg()); 11488758Sachereg_def R10_H(SOC, SOC, Op_RegI, 10, r10->as_VMReg()->next()); 11588758Sache 11688758Sachereg_def R11 (SOC, SOC, Op_RegI, 11, r11->as_VMReg()); 11788758Sachereg_def R11_H(SOC, SOC, Op_RegI, 11, r11->as_VMReg()->next()); 11888758Sache 11988758Sachereg_def R12 (SOC, SOE, Op_RegI, 12, r12->as_VMReg()); 12088758Sachereg_def R12_H(SOC, SOE, Op_RegI, 12, r12->as_VMReg()->next()); 12188758Sache 12288758Sachereg_def R13 (SOC, SOE, Op_RegI, 13, r13->as_VMReg()); 12388758Sachereg_def R13_H(SOC, SOE, Op_RegI, 13, r13->as_VMReg()->next()); 12488758Sache 12588758Sachereg_def R14 (SOC, SOE, Op_RegI, 14, r14->as_VMReg()); 12688758Sachereg_def R14_H(SOC, SOE, Op_RegI, 14, r14->as_VMReg()->next()); 12788758Sache 12888758Sachereg_def R15 (SOC, SOE, Op_RegI, 15, r15->as_VMReg()); 12988758Sachereg_def R15_H(SOC, SOE, Op_RegI, 15, r15->as_VMReg()->next()); 13088758Sache 13188758Sache 13288758Sache// Floating Point Registers 13388758Sache 13488758Sache// Specify priority of register selection within phases of register 13588758Sache// allocation. Highest priority is first. A useful heuristic is to 13688758Sache// give registers a low priority when they are required by machine 13788758Sache// instructions, like EAX and EDX on I486, and choose no-save registers 13888758Sache// before save-on-call, & save-on-call before save-on-entry. Registers 13988758Sache// which participate in fixed calling sequences should come last. 14088758Sache// Registers which are used as pairs must fall on an even boundary. 14188758Sache 14288758Sachealloc_class chunk0(R10, R10_H, 14388758Sache R11, R11_H, 14488758Sache R8, R8_H, 14588758Sache R9, R9_H, 14688758Sache R12, R12_H, 14788758Sache RCX, RCX_H, 14888758Sache RBX, RBX_H, 14988758Sache RDI, RDI_H, 15088758Sache RDX, RDX_H, 15188758Sache RSI, RSI_H, 15288758Sache RAX, RAX_H, 15388758Sache RBP, RBP_H, 15488758Sache R13, R13_H, 15588758Sache R14, R14_H, 15688758Sache R15, R15_H, 15788758Sache RSP, RSP_H); 15888758Sache 15988758Sache 16088758Sache//----------Architecture Description Register Classes-------------------------- 16188758Sache// Several register classes are automatically defined based upon information in 16288758Sache// this architecture description. 16388758Sache// 1) reg_class inline_cache_reg ( /* as def'd in frame section */ ) 16488758Sache// 2) reg_class compiler_method_oop_reg ( /* as def'd in frame section */ ) 16588758Sache// 2) reg_class interpreter_method_oop_reg ( /* as def'd in frame section */ ) 16688758Sache// 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ ) 16788758Sache// 16888758Sache 16988758Sache// Class for all pointer registers (including RSP) 17088758Sachereg_class any_reg(RAX, RAX_H, 17188758Sache RDX, RDX_H, 17288758Sache RBP, RBP_H, 17388758Sache RDI, RDI_H, 17488758Sache RSI, RSI_H, 17588758Sache RCX, RCX_H, 17688758Sache RBX, RBX_H, 17788758Sache RSP, RSP_H, 17888758Sache R8, R8_H, 17988758Sache R9, R9_H, 18088758Sache R10, R10_H, 18188758Sache R11, R11_H, 18288758Sache R12, R12_H, 18388758Sache R13, R13_H, 18488758Sache R14, R14_H, 18588758Sache R15, R15_H); 18688758Sache 18788758Sache// Class for all pointer registers except RSP 18888758Sachereg_class ptr_reg(RAX, RAX_H, 18988758Sache RDX, RDX_H, 19088758Sache RBP, RBP_H, 19188758Sache RDI, RDI_H, 19288758Sache RSI, RSI_H, 19388758Sache RCX, RCX_H, 19488758Sache RBX, RBX_H, 19588758Sache R8, R8_H, 19688758Sache R9, R9_H, 19788758Sache R10, R10_H, 19888758Sache R11, R11_H, 19988758Sache R13, R13_H, 20088758Sache R14, R14_H); 20188758Sache 20288758Sache// Class for all pointer registers except RAX and RSP 20388758Sachereg_class ptr_no_rax_reg(RDX, RDX_H, 20488758Sache RBP, RBP_H, 20588758Sache RDI, RDI_H, 20688758Sache RSI, RSI_H, 20788758Sache RCX, RCX_H, 20888758Sache RBX, RBX_H, 20988758Sache R8, R8_H, 21088758Sache R9, R9_H, 21188758Sache R10, R10_H, 21288758Sache R11, R11_H, 21388758Sache R13, R13_H, 21488758Sache R14, R14_H); 21588758Sache 21688758Sachereg_class ptr_no_rbp_reg(RDX, RDX_H, 21788758Sache RAX, RAX_H, 21888758Sache RDI, RDI_H, 21988758Sache RSI, RSI_H, 22088758Sache RCX, RCX_H, 22188758Sache RBX, RBX_H, 22288758Sache R8, R8_H, 22388758Sache R9, R9_H, 22488758Sache R10, R10_H, 22588758Sache R11, R11_H, 22688758Sache R13, R13_H, 22788758Sache R14, R14_H); 22888758Sache 22988758Sache// Class for all pointer registers except RAX, RBX and RSP 23088758Sachereg_class ptr_no_rax_rbx_reg(RDX, RDX_H, 23188758Sache RBP, RBP_H, 23288758Sache RDI, RDI_H, 23388758Sache RSI, RSI_H, 23488758Sache RCX, RCX_H, 23588758Sache R8, R8_H, 23688758Sache R9, R9_H, 23788758Sache R10, R10_H, 23888758Sache R11, R11_H, 23988758Sache R13, R13_H, 24088758Sache R14, R14_H); 24188758Sache 24288758Sache// Singleton class for RAX pointer register 24388758Sachereg_class ptr_rax_reg(RAX, RAX_H); 244 245// Singleton class for RBX pointer register 246reg_class ptr_rbx_reg(RBX, RBX_H); 247 248// Singleton class for RSI pointer register 249reg_class ptr_rsi_reg(RSI, RSI_H); 250 251// Singleton class for RDI pointer register 252reg_class ptr_rdi_reg(RDI, RDI_H); 253 254// Singleton class for RBP pointer register 255reg_class ptr_rbp_reg(RBP, RBP_H); 256 257// Singleton class for stack pointer 258reg_class ptr_rsp_reg(RSP, RSP_H); 259 260// Singleton class for TLS pointer 261reg_class ptr_r15_reg(R15, R15_H); 262 263// Class for all long registers (except RSP) 264reg_class long_reg(RAX, RAX_H, 265 RDX, RDX_H, 266 RBP, RBP_H, 267 RDI, RDI_H, 268 RSI, RSI_H, 269 RCX, RCX_H, 270 RBX, RBX_H, 271 R8, R8_H, 272 R9, R9_H, 273 R10, R10_H, 274 R11, R11_H, 275 R13, R13_H, 276 R14, R14_H); 277 278// Class for all long registers except RAX, RDX (and RSP) 279reg_class long_no_rax_rdx_reg(RBP, RBP_H, 280 RDI, RDI_H, 281 RSI, RSI_H, 282 RCX, RCX_H, 283 RBX, RBX_H, 284 R8, R8_H, 285 R9, R9_H, 286 R10, R10_H, 287 R11, R11_H, 288 R13, R13_H, 289 R14, R14_H); 290 291// Class for all long registers except RCX (and RSP) 292reg_class long_no_rcx_reg(RBP, RBP_H, 293 RDI, RDI_H, 294 RSI, RSI_H, 295 RAX, RAX_H, 296 RDX, RDX_H, 297 RBX, RBX_H, 298 R8, R8_H, 299 R9, R9_H, 300 R10, R10_H, 301 R11, R11_H, 302 R13, R13_H, 303 R14, R14_H); 304 305// Class for all long registers except RAX (and RSP) 306reg_class long_no_rax_reg(RBP, RBP_H, 307 RDX, RDX_H, 308 RDI, RDI_H, 309 RSI, RSI_H, 310 RCX, RCX_H, 311 RBX, RBX_H, 312 R8, R8_H, 313 R9, R9_H, 314 R10, R10_H, 315 R11, R11_H, 316 R13, R13_H, 317 R14, R14_H); 318 319// Singleton class for RAX long register 320reg_class long_rax_reg(RAX, RAX_H); 321 322// Singleton class for RCX long register 323reg_class long_rcx_reg(RCX, RCX_H); 324 325// Singleton class for RDX long register 326reg_class long_rdx_reg(RDX, RDX_H); 327 328// Class for all int registers (except RSP) 329reg_class int_reg(RAX, 330 RDX, 331 RBP, 332 RDI, 333 RSI, 334 RCX, 335 RBX, 336 R8, 337 R9, 338 R10, 339 R11, 340 R13, 341 R14); 342 343// Class for all int registers except RCX (and RSP) 344reg_class int_no_rcx_reg(RAX, 345 RDX, 346 RBP, 347 RDI, 348 RSI, 349 RBX, 350 R8, 351 R9, 352 R10, 353 R11, 354 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} 402static int clear_avx_size() { 403 return (Compile::current()->max_vector_size() > 16) ? 3 : 0; // vzeroupper 404} 405 406// !!!!! Special hack to get all types of calls to specify the byte offset 407// from the start of the call to the point where the return address 408// will point. 409int MachCallStaticJavaNode::ret_addr_offset() 410{ 411 int offset = 5; // 5 bytes from start of call to where return address points 412 offset += clear_avx_size(); 413 if (_method_handle_invoke) 414 offset += preserve_SP_size(); 415 return offset; 416} 417 418int MachCallDynamicJavaNode::ret_addr_offset() 419{ 420 int offset = 15; // 15 bytes from start of call to where return address points 421 offset += clear_avx_size(); 422 return offset; 423} 424 425int MachCallRuntimeNode::ret_addr_offset() { 426 int offset = 13; // movq r10,#addr; callq (r10) 427 offset += clear_avx_size(); 428 return offset; 429} 430 431// Indicate if the safepoint node needs the polling page as an input, 432// it does if the polling page is more than disp32 away. 433bool SafePointNode::needs_polling_address_input() 434{ 435 return Assembler::is_polling_page_far(); 436} 437 438// 439// Compute padding required for nodes which need alignment 440// 441 442// The address of the call instruction needs to be 4-byte aligned to 443// ensure that it does not span a cache line so that it can be patched. 444int CallStaticJavaDirectNode::compute_padding(int current_offset) const 445{ 446 current_offset += clear_avx_size(); // skip vzeroupper 447 current_offset += 1; // skip call opcode byte 448 return round_to(current_offset, alignment_required()) - current_offset; 449} 450 451// The address of the call instruction needs to be 4-byte aligned to 452// ensure that it does not span a cache line so that it can be patched. 453int CallStaticJavaHandleNode::compute_padding(int current_offset) const 454{ 455 current_offset += preserve_SP_size(); // skip mov rbp, rsp 456 current_offset += clear_avx_size(); // skip vzeroupper 457 current_offset += 1; // skip call opcode byte 458 return round_to(current_offset, alignment_required()) - current_offset; 459} 460 461// The address of the call instruction needs to be 4-byte aligned to 462// ensure that it does not span a cache line so that it can be patched. 463int CallDynamicJavaDirectNode::compute_padding(int current_offset) const 464{ 465 current_offset += clear_avx_size(); // skip vzeroupper 466 current_offset += 11; // skip movq instruction + call opcode byte 467 return round_to(current_offset, alignment_required()) - current_offset; 468} 469 470// EMIT_RM() 471void emit_rm(CodeBuffer &cbuf, int f1, int f2, int f3) { 472 unsigned char c = (unsigned char) ((f1 << 6) | (f2 << 3) | f3); 473 cbuf.insts()->emit_int8(c); 474} 475 476// EMIT_CC() 477void emit_cc(CodeBuffer &cbuf, int f1, int f2) { 478 unsigned char c = (unsigned char) (f1 | f2); 479 cbuf.insts()->emit_int8(c); 480} 481 482// EMIT_OPCODE() 483void emit_opcode(CodeBuffer &cbuf, int code) { 484 cbuf.insts()->emit_int8((unsigned char) code); 485} 486 487// EMIT_OPCODE() w/ relocation information 488void emit_opcode(CodeBuffer &cbuf, 489 int code, relocInfo::relocType reloc, int offset, int format) 490{ 491 cbuf.relocate(cbuf.insts_mark() + offset, reloc, format); 492 emit_opcode(cbuf, code); 493} 494 495// EMIT_D8() 496void emit_d8(CodeBuffer &cbuf, int d8) { 497 cbuf.insts()->emit_int8((unsigned char) d8); 498} 499 500// EMIT_D16() 501void emit_d16(CodeBuffer &cbuf, int d16) { 502 cbuf.insts()->emit_int16(d16); 503} 504 505// EMIT_D32() 506void emit_d32(CodeBuffer &cbuf, int d32) { 507 cbuf.insts()->emit_int32(d32); 508} 509 510// EMIT_D64() 511void emit_d64(CodeBuffer &cbuf, int64_t d64) { 512 cbuf.insts()->emit_int64(d64); 513} 514 515// emit 32 bit value and construct relocation entry from relocInfo::relocType 516void emit_d32_reloc(CodeBuffer& cbuf, 517 int d32, 518 relocInfo::relocType reloc, 519 int format) 520{ 521 assert(reloc != relocInfo::external_word_type, "use 2-arg emit_d32_reloc"); 522 cbuf.relocate(cbuf.insts_mark(), reloc, format); 523 cbuf.insts()->emit_int32(d32); 524} 525 526// emit 32 bit value and construct relocation entry from RelocationHolder 527void emit_d32_reloc(CodeBuffer& cbuf, int d32, RelocationHolder const& rspec, int format) { 528#ifdef ASSERT 529 if (rspec.reloc()->type() == relocInfo::oop_type && 530 d32 != 0 && d32 != (intptr_t) Universe::non_oop_word()) { 531 assert(Universe::heap()->is_in_reserved((address)(intptr_t)d32), "should be real oop"); 532 assert(oop((intptr_t)d32)->is_oop() && (ScavengeRootsInCode || !oop((intptr_t)d32)->is_scavengable()), "cannot embed scavengable oops in code"); 533 } 534#endif 535 cbuf.relocate(cbuf.insts_mark(), rspec, format); 536 cbuf.insts()->emit_int32(d32); 537} 538 539void emit_d32_reloc(CodeBuffer& cbuf, address addr) { 540 address next_ip = cbuf.insts_end() + 4; 541 emit_d32_reloc(cbuf, (int) (addr - next_ip), 542 external_word_Relocation::spec(addr), 543 RELOC_DISP32); 544} 545 546 547// emit 64 bit value and construct relocation entry from relocInfo::relocType 548void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, relocInfo::relocType reloc, int format) { 549 cbuf.relocate(cbuf.insts_mark(), reloc, format); 550 cbuf.insts()->emit_int64(d64); 551} 552 553// emit 64 bit value and construct relocation entry from RelocationHolder 554void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, RelocationHolder const& rspec, int format) { 555#ifdef ASSERT 556 if (rspec.reloc()->type() == relocInfo::oop_type && 557 d64 != 0 && d64 != (int64_t) Universe::non_oop_word()) { 558 assert(Universe::heap()->is_in_reserved((address)d64), "should be real oop"); 559 assert(oop(d64)->is_oop() && (ScavengeRootsInCode || !oop(d64)->is_scavengable()), 560 "cannot embed scavengable oops in code"); 561 } 562#endif 563 cbuf.relocate(cbuf.insts_mark(), rspec, format); 564 cbuf.insts()->emit_int64(d64); 565} 566 567// Access stack slot for load or store 568void store_to_stackslot(CodeBuffer &cbuf, int opcode, int rm_field, int disp) 569{ 570 emit_opcode(cbuf, opcode); // (e.g., FILD [RSP+src]) 571 if (-0x80 <= disp && disp < 0x80) { 572 emit_rm(cbuf, 0x01, rm_field, RSP_enc); // R/M byte 573 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte 574 emit_d8(cbuf, disp); // Displacement // R/M byte 575 } else { 576 emit_rm(cbuf, 0x02, rm_field, RSP_enc); // R/M byte 577 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte 578 emit_d32(cbuf, disp); // Displacement // R/M byte 579 } 580} 581 582 // rRegI ereg, memory mem) %{ // emit_reg_mem 583void encode_RegMem(CodeBuffer &cbuf, 584 int reg, 585 int base, int index, int scale, int disp, relocInfo::relocType disp_reloc) 586{ 587 assert(disp_reloc == relocInfo::none, "cannot have disp"); 588 int regenc = reg & 7; 589 int baseenc = base & 7; 590 int indexenc = index & 7; 591 592 // There is no index & no scale, use form without SIB byte 593 if (index == 0x4 && scale == 0 && base != RSP_enc && base != R12_enc) { 594 // If no displacement, mode is 0x0; unless base is [RBP] or [R13] 595 if (disp == 0 && base != RBP_enc && base != R13_enc) { 596 emit_rm(cbuf, 0x0, regenc, baseenc); // * 597 } else if (-0x80 <= disp && disp < 0x80 && disp_reloc == relocInfo::none) { 598 // If 8-bit displacement, mode 0x1 599 emit_rm(cbuf, 0x1, regenc, baseenc); // * 600 emit_d8(cbuf, disp); 601 } else { 602 // If 32-bit displacement 603 if (base == -1) { // Special flag for absolute address 604 emit_rm(cbuf, 0x0, regenc, 0x5); // * 605 if (disp_reloc != relocInfo::none) { 606 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 607 } else { 608 emit_d32(cbuf, disp); 609 } 610 } else { 611 // Normal base + offset 612 emit_rm(cbuf, 0x2, regenc, baseenc); // * 613 if (disp_reloc != relocInfo::none) { 614 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 615 } else { 616 emit_d32(cbuf, disp); 617 } 618 } 619 } 620 } else { 621 // Else, encode with the SIB byte 622 // If no displacement, mode is 0x0; unless base is [RBP] or [R13] 623 if (disp == 0 && base != RBP_enc && base != R13_enc) { 624 // If no displacement 625 emit_rm(cbuf, 0x0, regenc, 0x4); // * 626 emit_rm(cbuf, scale, indexenc, baseenc); 627 } else { 628 if (-0x80 <= disp && disp < 0x80 && disp_reloc == relocInfo::none) { 629 // If 8-bit displacement, mode 0x1 630 emit_rm(cbuf, 0x1, regenc, 0x4); // * 631 emit_rm(cbuf, scale, indexenc, baseenc); 632 emit_d8(cbuf, disp); 633 } else { 634 // If 32-bit displacement 635 if (base == 0x04 ) { 636 emit_rm(cbuf, 0x2, regenc, 0x4); 637 emit_rm(cbuf, scale, indexenc, 0x04); // XXX is this valid??? 638 } else { 639 emit_rm(cbuf, 0x2, regenc, 0x4); 640 emit_rm(cbuf, scale, indexenc, baseenc); // * 641 } 642 if (disp_reloc != relocInfo::none) { 643 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 644 } else { 645 emit_d32(cbuf, disp); 646 } 647 } 648 } 649 } 650} 651 652// This could be in MacroAssembler but it's fairly C2 specific 653void emit_cmpfp_fixup(MacroAssembler& _masm) { 654 Label exit; 655 __ jccb(Assembler::noParity, exit); 656 __ pushf(); 657 // 658 // comiss/ucomiss instructions set ZF,PF,CF flags and 659 // zero OF,AF,SF for NaN values. 660 // Fixup flags by zeroing ZF,PF so that compare of NaN 661 // values returns 'less than' result (CF is set). 662 // Leave the rest of flags unchanged. 663 // 664 // 7 6 5 4 3 2 1 0 665 // |S|Z|r|A|r|P|r|C| (r - reserved bit) 666 // 0 0 1 0 1 0 1 1 (0x2B) 667 // 668 __ andq(Address(rsp, 0), 0xffffff2b); 669 __ popf(); 670 __ bind(exit); 671} 672 673void emit_cmpfp3(MacroAssembler& _masm, Register dst) { 674 Label done; 675 __ movl(dst, -1); 676 __ jcc(Assembler::parity, done); 677 __ jcc(Assembler::below, done); 678 __ setb(Assembler::notEqual, dst); 679 __ movzbl(dst, dst); 680 __ bind(done); 681} 682 683 684//============================================================================= 685const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; 686 687int Compile::ConstantTable::calculate_table_base_offset() const { 688 return 0; // absolute addressing, no offset 689} 690 691void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 692 // Empty encoding 693} 694 695uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 696 return 0; 697} 698 699#ifndef PRODUCT 700void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 701 st->print("# MachConstantBaseNode (empty encoding)"); 702} 703#endif 704 705 706//============================================================================= 707#ifndef PRODUCT 708void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 709 Compile* C = ra_->C; 710 711 int framesize = C->frame_slots() << LogBytesPerInt; 712 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 713 // Remove wordSize for return addr which is already pushed. 714 framesize -= wordSize; 715 716 if (C->need_stack_bang(framesize)) { 717 framesize -= wordSize; 718 st->print("# stack bang"); 719 st->print("\n\t"); 720 st->print("pushq rbp\t# Save rbp"); 721 if (framesize) { 722 st->print("\n\t"); 723 st->print("subq rsp, #%d\t# Create frame",framesize); 724 } 725 } else { 726 st->print("subq rsp, #%d\t# Create frame",framesize); 727 st->print("\n\t"); 728 framesize -= wordSize; 729 st->print("movq [rsp + #%d], rbp\t# Save rbp",framesize); 730 } 731 732 if (VerifyStackAtCalls) { 733 st->print("\n\t"); 734 framesize -= wordSize; 735 st->print("movq [rsp + #%d], 0xbadb100d\t# Majik cookie for stack depth check",framesize); 736#ifdef ASSERT 737 st->print("\n\t"); 738 st->print("# stack alignment check"); 739#endif 740 } 741 st->cr(); 742} 743#endif 744 745void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 746 Compile* C = ra_->C; 747 MacroAssembler _masm(&cbuf); 748 749 int framesize = C->frame_slots() << LogBytesPerInt; 750 751 __ verified_entry(framesize, C->need_stack_bang(framesize), false); 752 753 C->set_frame_complete(cbuf.insts_size()); 754 755 if (C->has_mach_constant_base_node()) { 756 // NOTE: We set the table base offset here because users might be 757 // emitted before MachConstantBaseNode. 758 Compile::ConstantTable& constant_table = C->constant_table(); 759 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset()); 760 } 761} 762 763uint MachPrologNode::size(PhaseRegAlloc* ra_) const 764{ 765 return MachNode::size(ra_); // too many variables; just compute it 766 // the hard way 767} 768 769int MachPrologNode::reloc() const 770{ 771 return 0; // a large enough number 772} 773 774//============================================================================= 775#ifndef PRODUCT 776void MachEpilogNode::format(PhaseRegAlloc* ra_, outputStream* st) const 777{ 778 Compile* C = ra_->C; 779 if (C->max_vector_size() > 16) { 780 st->print("vzeroupper"); 781 st->cr(); st->print("\t"); 782 } 783 784 int framesize = C->frame_slots() << LogBytesPerInt; 785 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 786 // Remove word for return adr already pushed 787 // and RBP 788 framesize -= 2*wordSize; 789 790 if (framesize) { 791 st->print_cr("addq rsp, %d\t# Destroy frame", framesize); 792 st->print("\t"); 793 } 794 795 st->print_cr("popq rbp"); 796 if (do_polling() && C->is_method_compilation()) { 797 st->print("\t"); 798 if (Assembler::is_polling_page_far()) { 799 st->print_cr("movq rscratch1, #polling_page_address\n\t" 800 "testl rax, [rscratch1]\t" 801 "# Safepoint: poll for GC"); 802 } else { 803 st->print_cr("testl rax, [rip + #offset_to_poll_page]\t" 804 "# Safepoint: poll for GC"); 805 } 806 } 807} 808#endif 809 810void MachEpilogNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 811{ 812 Compile* C = ra_->C; 813 if (C->max_vector_size() > 16) { 814 // Clear upper bits of YMM registers when current compiled code uses 815 // wide vectors to avoid AVX <-> SSE transition penalty during call. 816 MacroAssembler _masm(&cbuf); 817 __ vzeroupper(); 818 } 819 820 int framesize = C->frame_slots() << LogBytesPerInt; 821 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 822 // Remove word for return adr already pushed 823 // and RBP 824 framesize -= 2*wordSize; 825 826 // Note that VerifyStackAtCalls' Majik cookie does not change the frame size popped here 827 828 if (framesize) { 829 emit_opcode(cbuf, Assembler::REX_W); 830 if (framesize < 0x80) { 831 emit_opcode(cbuf, 0x83); // addq rsp, #framesize 832 emit_rm(cbuf, 0x3, 0x00, RSP_enc); 833 emit_d8(cbuf, framesize); 834 } else { 835 emit_opcode(cbuf, 0x81); // addq rsp, #framesize 836 emit_rm(cbuf, 0x3, 0x00, RSP_enc); 837 emit_d32(cbuf, framesize); 838 } 839 } 840 841 // popq rbp 842 emit_opcode(cbuf, 0x58 | RBP_enc); 843 844 if (do_polling() && C->is_method_compilation()) { 845 MacroAssembler _masm(&cbuf); 846 AddressLiteral polling_page(os::get_polling_page(), relocInfo::poll_return_type); 847 if (Assembler::is_polling_page_far()) { 848 __ lea(rscratch1, polling_page); 849 __ relocate(relocInfo::poll_return_type); 850 __ testl(rax, Address(rscratch1, 0)); 851 } else { 852 __ testl(rax, polling_page); 853 } 854 } 855} 856 857uint MachEpilogNode::size(PhaseRegAlloc* ra_) const 858{ 859 return MachNode::size(ra_); // too many variables; just compute it 860 // the hard way 861} 862 863int MachEpilogNode::reloc() const 864{ 865 return 2; // a large enough number 866} 867 868const Pipeline* MachEpilogNode::pipeline() const 869{ 870 return MachNode::pipeline_class(); 871} 872 873int MachEpilogNode::safepoint_offset() const 874{ 875 return 0; 876} 877 878//============================================================================= 879 880enum RC { 881 rc_bad, 882 rc_int, 883 rc_float, 884 rc_stack 885}; 886 887static enum RC rc_class(OptoReg::Name reg) 888{ 889 if( !OptoReg::is_valid(reg) ) return rc_bad; 890 891 if (OptoReg::is_stack(reg)) return rc_stack; 892 893 VMReg r = OptoReg::as_VMReg(reg); 894 895 if (r->is_Register()) return rc_int; 896 897 assert(r->is_XMMRegister(), "must be"); 898 return rc_float; 899} 900 901// Next two methods are shared by 32- and 64-bit VM. They are defined in x86.ad. 902static int vec_mov_helper(CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo, 903 int src_hi, int dst_hi, uint ireg, outputStream* st); 904 905static int vec_spill_helper(CodeBuffer *cbuf, bool do_size, bool is_load, 906 int stack_offset, int reg, uint ireg, outputStream* st); 907 908static void vec_stack_to_stack_helper(CodeBuffer *cbuf, int src_offset, 909 int dst_offset, uint ireg, outputStream* st) { 910 if (cbuf) { 911 MacroAssembler _masm(cbuf); 912 switch (ireg) { 913 case Op_VecS: 914 __ movq(Address(rsp, -8), rax); 915 __ movl(rax, Address(rsp, src_offset)); 916 __ movl(Address(rsp, dst_offset), rax); 917 __ movq(rax, Address(rsp, -8)); 918 break; 919 case Op_VecD: 920 __ pushq(Address(rsp, src_offset)); 921 __ popq (Address(rsp, dst_offset)); 922 break; 923 case Op_VecX: 924 __ pushq(Address(rsp, src_offset)); 925 __ popq (Address(rsp, dst_offset)); 926 __ pushq(Address(rsp, src_offset+8)); 927 __ popq (Address(rsp, dst_offset+8)); 928 break; 929 case Op_VecY: 930 __ vmovdqu(Address(rsp, -32), xmm0); 931 __ vmovdqu(xmm0, Address(rsp, src_offset)); 932 __ vmovdqu(Address(rsp, dst_offset), xmm0); 933 __ vmovdqu(xmm0, Address(rsp, -32)); 934 break; 935 default: 936 ShouldNotReachHere(); 937 } 938#ifndef PRODUCT 939 } else { 940 switch (ireg) { 941 case Op_VecS: 942 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 943 "movl rax, [rsp + #%d]\n\t" 944 "movl [rsp + #%d], rax\n\t" 945 "movq rax, [rsp - #8]", 946 src_offset, dst_offset); 947 break; 948 case Op_VecD: 949 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 950 "popq [rsp + #%d]", 951 src_offset, dst_offset); 952 break; 953 case Op_VecX: 954 st->print("pushq [rsp + #%d]\t# 128-bit mem-mem spill\n\t" 955 "popq [rsp + #%d]\n\t" 956 "pushq [rsp + #%d]\n\t" 957 "popq [rsp + #%d]", 958 src_offset, dst_offset, src_offset+8, dst_offset+8); 959 break; 960 case Op_VecY: 961 st->print("vmovdqu [rsp - #32], xmm0\t# 256-bit mem-mem spill\n\t" 962 "vmovdqu xmm0, [rsp + #%d]\n\t" 963 "vmovdqu [rsp + #%d], xmm0\n\t" 964 "vmovdqu xmm0, [rsp - #32]", 965 src_offset, dst_offset); 966 break; 967 default: 968 ShouldNotReachHere(); 969 } 970#endif 971 } 972} 973 974uint MachSpillCopyNode::implementation(CodeBuffer* cbuf, 975 PhaseRegAlloc* ra_, 976 bool do_size, 977 outputStream* st) const { 978 assert(cbuf != NULL || st != NULL, "sanity"); 979 // Get registers to move 980 OptoReg::Name src_second = ra_->get_reg_second(in(1)); 981 OptoReg::Name src_first = ra_->get_reg_first(in(1)); 982 OptoReg::Name dst_second = ra_->get_reg_second(this); 983 OptoReg::Name dst_first = ra_->get_reg_first(this); 984 985 enum RC src_second_rc = rc_class(src_second); 986 enum RC src_first_rc = rc_class(src_first); 987 enum RC dst_second_rc = rc_class(dst_second); 988 enum RC dst_first_rc = rc_class(dst_first); 989 990 assert(OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), 991 "must move at least 1 register" ); 992 993 if (src_first == dst_first && src_second == dst_second) { 994 // Self copy, no move 995 return 0; 996 } 997 if (bottom_type()->isa_vect() != NULL) { 998 uint ireg = ideal_reg(); 999 assert((src_first_rc != rc_int && dst_first_rc != rc_int), "sanity"); 1000 assert((ireg == Op_VecS || ireg == Op_VecD || ireg == Op_VecX || ireg == Op_VecY), "sanity"); 1001 if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) { 1002 // mem -> mem 1003 int src_offset = ra_->reg2offset(src_first); 1004 int dst_offset = ra_->reg2offset(dst_first); 1005 vec_stack_to_stack_helper(cbuf, src_offset, dst_offset, ireg, st); 1006 } else if (src_first_rc == rc_float && dst_first_rc == rc_float ) { 1007 vec_mov_helper(cbuf, false, src_first, dst_first, src_second, dst_second, ireg, st); 1008 } else if (src_first_rc == rc_float && dst_first_rc == rc_stack ) { 1009 int stack_offset = ra_->reg2offset(dst_first); 1010 vec_spill_helper(cbuf, false, false, stack_offset, src_first, ireg, st); 1011 } else if (src_first_rc == rc_stack && dst_first_rc == rc_float ) { 1012 int stack_offset = ra_->reg2offset(src_first); 1013 vec_spill_helper(cbuf, false, true, stack_offset, dst_first, ireg, st); 1014 } else { 1015 ShouldNotReachHere(); 1016 } 1017 return 0; 1018 } 1019 if (src_first_rc == rc_stack) { 1020 // mem -> 1021 if (dst_first_rc == rc_stack) { 1022 // mem -> mem 1023 assert(src_second != dst_first, "overlap"); 1024 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1025 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1026 // 64-bit 1027 int src_offset = ra_->reg2offset(src_first); 1028 int dst_offset = ra_->reg2offset(dst_first); 1029 if (cbuf) { 1030 MacroAssembler _masm(cbuf); 1031 __ pushq(Address(rsp, src_offset)); 1032 __ popq (Address(rsp, dst_offset)); 1033#ifndef PRODUCT 1034 } else { 1035 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1036 "popq [rsp + #%d]", 1037 src_offset, dst_offset); 1038#endif 1039 } 1040 } else { 1041 // 32-bit 1042 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1043 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1044 // No pushl/popl, so: 1045 int src_offset = ra_->reg2offset(src_first); 1046 int dst_offset = ra_->reg2offset(dst_first); 1047 if (cbuf) { 1048 MacroAssembler _masm(cbuf); 1049 __ movq(Address(rsp, -8), rax); 1050 __ movl(rax, Address(rsp, src_offset)); 1051 __ movl(Address(rsp, dst_offset), rax); 1052 __ movq(rax, Address(rsp, -8)); 1053#ifndef PRODUCT 1054 } else { 1055 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1056 "movl rax, [rsp + #%d]\n\t" 1057 "movl [rsp + #%d], rax\n\t" 1058 "movq rax, [rsp - #8]", 1059 src_offset, dst_offset); 1060#endif 1061 } 1062 } 1063 return 0; 1064 } else if (dst_first_rc == rc_int) { 1065 // mem -> gpr 1066 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1067 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1068 // 64-bit 1069 int offset = ra_->reg2offset(src_first); 1070 if (cbuf) { 1071 MacroAssembler _masm(cbuf); 1072 __ movq(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1073#ifndef PRODUCT 1074 } else { 1075 st->print("movq %s, [rsp + #%d]\t# spill", 1076 Matcher::regName[dst_first], 1077 offset); 1078#endif 1079 } 1080 } else { 1081 // 32-bit 1082 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1083 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1084 int offset = ra_->reg2offset(src_first); 1085 if (cbuf) { 1086 MacroAssembler _masm(cbuf); 1087 __ movl(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1088#ifndef PRODUCT 1089 } else { 1090 st->print("movl %s, [rsp + #%d]\t# spill", 1091 Matcher::regName[dst_first], 1092 offset); 1093#endif 1094 } 1095 } 1096 return 0; 1097 } else if (dst_first_rc == rc_float) { 1098 // mem-> xmm 1099 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1100 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1101 // 64-bit 1102 int offset = ra_->reg2offset(src_first); 1103 if (cbuf) { 1104 MacroAssembler _masm(cbuf); 1105 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1106#ifndef PRODUCT 1107 } else { 1108 st->print("%s %s, [rsp + #%d]\t# spill", 1109 UseXmmLoadAndClearUpper ? "movsd " : "movlpd", 1110 Matcher::regName[dst_first], 1111 offset); 1112#endif 1113 } 1114 } else { 1115 // 32-bit 1116 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1117 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1118 int offset = ra_->reg2offset(src_first); 1119 if (cbuf) { 1120 MacroAssembler _masm(cbuf); 1121 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1122#ifndef PRODUCT 1123 } else { 1124 st->print("movss %s, [rsp + #%d]\t# spill", 1125 Matcher::regName[dst_first], 1126 offset); 1127#endif 1128 } 1129 } 1130 return 0; 1131 } 1132 } else if (src_first_rc == rc_int) { 1133 // gpr -> 1134 if (dst_first_rc == rc_stack) { 1135 // gpr -> mem 1136 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1137 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1138 // 64-bit 1139 int offset = ra_->reg2offset(dst_first); 1140 if (cbuf) { 1141 MacroAssembler _masm(cbuf); 1142 __ movq(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1143#ifndef PRODUCT 1144 } else { 1145 st->print("movq [rsp + #%d], %s\t# spill", 1146 offset, 1147 Matcher::regName[src_first]); 1148#endif 1149 } 1150 } else { 1151 // 32-bit 1152 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1153 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1154 int offset = ra_->reg2offset(dst_first); 1155 if (cbuf) { 1156 MacroAssembler _masm(cbuf); 1157 __ movl(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1158#ifndef PRODUCT 1159 } else { 1160 st->print("movl [rsp + #%d], %s\t# spill", 1161 offset, 1162 Matcher::regName[src_first]); 1163#endif 1164 } 1165 } 1166 return 0; 1167 } else if (dst_first_rc == rc_int) { 1168 // gpr -> gpr 1169 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1170 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1171 // 64-bit 1172 if (cbuf) { 1173 MacroAssembler _masm(cbuf); 1174 __ movq(as_Register(Matcher::_regEncode[dst_first]), 1175 as_Register(Matcher::_regEncode[src_first])); 1176#ifndef PRODUCT 1177 } else { 1178 st->print("movq %s, %s\t# spill", 1179 Matcher::regName[dst_first], 1180 Matcher::regName[src_first]); 1181#endif 1182 } 1183 return 0; 1184 } else { 1185 // 32-bit 1186 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1187 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1188 if (cbuf) { 1189 MacroAssembler _masm(cbuf); 1190 __ movl(as_Register(Matcher::_regEncode[dst_first]), 1191 as_Register(Matcher::_regEncode[src_first])); 1192#ifndef PRODUCT 1193 } else { 1194 st->print("movl %s, %s\t# spill", 1195 Matcher::regName[dst_first], 1196 Matcher::regName[src_first]); 1197#endif 1198 } 1199 return 0; 1200 } 1201 } else if (dst_first_rc == rc_float) { 1202 // gpr -> xmm 1203 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1204 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1205 // 64-bit 1206 if (cbuf) { 1207 MacroAssembler _masm(cbuf); 1208 __ movdq( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1209#ifndef PRODUCT 1210 } else { 1211 st->print("movdq %s, %s\t# spill", 1212 Matcher::regName[dst_first], 1213 Matcher::regName[src_first]); 1214#endif 1215 } 1216 } else { 1217 // 32-bit 1218 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1219 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1220 if (cbuf) { 1221 MacroAssembler _masm(cbuf); 1222 __ movdl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1223#ifndef PRODUCT 1224 } else { 1225 st->print("movdl %s, %s\t# spill", 1226 Matcher::regName[dst_first], 1227 Matcher::regName[src_first]); 1228#endif 1229 } 1230 } 1231 return 0; 1232 } 1233 } else if (src_first_rc == rc_float) { 1234 // xmm -> 1235 if (dst_first_rc == rc_stack) { 1236 // xmm -> mem 1237 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1238 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1239 // 64-bit 1240 int offset = ra_->reg2offset(dst_first); 1241 if (cbuf) { 1242 MacroAssembler _masm(cbuf); 1243 __ movdbl( Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1244#ifndef PRODUCT 1245 } else { 1246 st->print("movsd [rsp + #%d], %s\t# spill", 1247 offset, 1248 Matcher::regName[src_first]); 1249#endif 1250 } 1251 } else { 1252 // 32-bit 1253 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1254 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1255 int offset = ra_->reg2offset(dst_first); 1256 if (cbuf) { 1257 MacroAssembler _masm(cbuf); 1258 __ movflt(Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1259#ifndef PRODUCT 1260 } else { 1261 st->print("movss [rsp + #%d], %s\t# spill", 1262 offset, 1263 Matcher::regName[src_first]); 1264#endif 1265 } 1266 } 1267 return 0; 1268 } else if (dst_first_rc == rc_int) { 1269 // xmm -> gpr 1270 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1271 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1272 // 64-bit 1273 if (cbuf) { 1274 MacroAssembler _masm(cbuf); 1275 __ movdq( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1276#ifndef PRODUCT 1277 } else { 1278 st->print("movdq %s, %s\t# spill", 1279 Matcher::regName[dst_first], 1280 Matcher::regName[src_first]); 1281#endif 1282 } 1283 } else { 1284 // 32-bit 1285 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1286 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1287 if (cbuf) { 1288 MacroAssembler _masm(cbuf); 1289 __ movdl( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1290#ifndef PRODUCT 1291 } else { 1292 st->print("movdl %s, %s\t# spill", 1293 Matcher::regName[dst_first], 1294 Matcher::regName[src_first]); 1295#endif 1296 } 1297 } 1298 return 0; 1299 } else if (dst_first_rc == rc_float) { 1300 // xmm -> xmm 1301 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1302 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1303 // 64-bit 1304 if (cbuf) { 1305 MacroAssembler _masm(cbuf); 1306 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1307#ifndef PRODUCT 1308 } else { 1309 st->print("%s %s, %s\t# spill", 1310 UseXmmRegToRegMoveAll ? "movapd" : "movsd ", 1311 Matcher::regName[dst_first], 1312 Matcher::regName[src_first]); 1313#endif 1314 } 1315 } else { 1316 // 32-bit 1317 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1318 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1319 if (cbuf) { 1320 MacroAssembler _masm(cbuf); 1321 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1322#ifndef PRODUCT 1323 } else { 1324 st->print("%s %s, %s\t# spill", 1325 UseXmmRegToRegMoveAll ? "movaps" : "movss ", 1326 Matcher::regName[dst_first], 1327 Matcher::regName[src_first]); 1328#endif 1329 } 1330 } 1331 return 0; 1332 } 1333 } 1334 1335 assert(0," foo "); 1336 Unimplemented(); 1337 return 0; 1338} 1339 1340#ifndef PRODUCT 1341void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream* st) const { 1342 implementation(NULL, ra_, false, st); 1343} 1344#endif 1345 1346void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1347 implementation(&cbuf, ra_, false, NULL); 1348} 1349 1350uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1351 return MachNode::size(ra_); 1352} 1353 1354//============================================================================= 1355#ifndef PRODUCT 1356void BoxLockNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1357{ 1358 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1359 int reg = ra_->get_reg_first(this); 1360 st->print("leaq %s, [rsp + #%d]\t# box lock", 1361 Matcher::regName[reg], offset); 1362} 1363#endif 1364 1365void BoxLockNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1366{ 1367 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1368 int reg = ra_->get_encode(this); 1369 if (offset >= 0x80) { 1370 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR); 1371 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset] 1372 emit_rm(cbuf, 0x2, reg & 7, 0x04); 1373 emit_rm(cbuf, 0x0, 0x04, RSP_enc); 1374 emit_d32(cbuf, offset); 1375 } else { 1376 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR); 1377 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset] 1378 emit_rm(cbuf, 0x1, reg & 7, 0x04); 1379 emit_rm(cbuf, 0x0, 0x04, RSP_enc); 1380 emit_d8(cbuf, offset); 1381 } 1382} 1383 1384uint BoxLockNode::size(PhaseRegAlloc *ra_) const 1385{ 1386 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1387 return (offset < 0x80) ? 5 : 8; // REX 1388} 1389 1390//============================================================================= 1391 1392// emit call stub, compiled java to interpreter 1393void emit_java_to_interp(CodeBuffer& cbuf) 1394{ 1395 // Stub is fixed up when the corresponding call is converted from 1396 // calling compiled code to calling interpreted code. 1397 // movq rbx, 0 1398 // jmp -5 # to self 1399 1400 address mark = cbuf.insts_mark(); // get mark within main instrs section 1401 1402 // Note that the code buffer's insts_mark is always relative to insts. 1403 // That's why we must use the macroassembler to generate a stub. 1404 MacroAssembler _masm(&cbuf); 1405 1406 address base = 1407 __ start_a_stub(Compile::MAX_stubs_size); 1408 if (base == NULL) return; // CodeBuffer::expand failed 1409 // static stub relocation stores the instruction address of the call 1410 __ relocate(static_stub_Relocation::spec(mark), RELOC_IMM64); 1411 // static stub relocation also tags the Method* in the code-stream. 1412 __ mov_metadata(rbx, (Metadata*) NULL); // method is zapped till fixup time 1413 // This is recognized as unresolved by relocs/nativeinst/ic code 1414 __ jump(RuntimeAddress(__ pc())); 1415 1416 // Update current stubs pointer and restore insts_end. 1417 __ end_a_stub(); 1418} 1419 1420// size of call stub, compiled java to interpretor 1421uint size_java_to_interp() 1422{ 1423 return 15; // movq (1+1+8); jmp (1+4) 1424} 1425 1426// relocation entries for call stub, compiled java to interpretor 1427uint reloc_java_to_interp() 1428{ 1429 return 4; // 3 in emit_java_to_interp + 1 in Java_Static_Call 1430} 1431 1432//============================================================================= 1433#ifndef PRODUCT 1434void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1435{ 1436 if (UseCompressedKlassPointers) { 1437 st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1438 if (Universe::narrow_klass_shift() != 0) { 1439 st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1"); 1440 } 1441 st->print_cr("\tcmpq rax, rscratch1\t # Inline cache check"); 1442 } else { 1443 st->print_cr("\tcmpq rax, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t" 1444 "# Inline cache check"); 1445 } 1446 st->print_cr("\tjne SharedRuntime::_ic_miss_stub"); 1447 st->print_cr("\tnop\t# nops to align entry point"); 1448} 1449#endif 1450 1451void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1452{ 1453 MacroAssembler masm(&cbuf); 1454 uint insts_size = cbuf.insts_size(); 1455 if (UseCompressedKlassPointers) { 1456 masm.load_klass(rscratch1, j_rarg0); 1457 masm.cmpptr(rax, rscratch1); 1458 } else { 1459 masm.cmpptr(rax, Address(j_rarg0, oopDesc::klass_offset_in_bytes())); 1460 } 1461 1462 masm.jump_cc(Assembler::notEqual, RuntimeAddress(SharedRuntime::get_ic_miss_stub())); 1463 1464 /* WARNING these NOPs are critical so that verified entry point is properly 1465 4 bytes aligned for patching by NativeJump::patch_verified_entry() */ 1466 int nops_cnt = 4 - ((cbuf.insts_size() - insts_size) & 0x3); 1467 if (OptoBreakpoint) { 1468 // Leave space for int3 1469 nops_cnt -= 1; 1470 } 1471 nops_cnt &= 0x3; // Do not add nops if code is aligned. 1472 if (nops_cnt > 0) 1473 masm.nop(nops_cnt); 1474} 1475 1476uint MachUEPNode::size(PhaseRegAlloc* ra_) const 1477{ 1478 return MachNode::size(ra_); // too many variables; just compute it 1479 // the hard way 1480} 1481 1482 1483//============================================================================= 1484uint size_exception_handler() 1485{ 1486 // NativeCall instruction size is the same as NativeJump. 1487 // Note that this value is also credited (in output.cpp) to 1488 // the size of the code section. 1489 return NativeJump::instruction_size; 1490} 1491 1492// Emit exception handler code. 1493int emit_exception_handler(CodeBuffer& cbuf) 1494{ 1495 1496 // Note that the code buffer's insts_mark is always relative to insts. 1497 // That's why we must use the macroassembler to generate a handler. 1498 MacroAssembler _masm(&cbuf); 1499 address base = 1500 __ start_a_stub(size_exception_handler()); 1501 if (base == NULL) return 0; // CodeBuffer::expand failed 1502 int offset = __ offset(); 1503 __ jump(RuntimeAddress(OptoRuntime::exception_blob()->entry_point())); 1504 assert(__ offset() - offset <= (int) size_exception_handler(), "overflow"); 1505 __ end_a_stub(); 1506 return offset; 1507} 1508 1509uint size_deopt_handler() 1510{ 1511 // three 5 byte instructions 1512 return 15; 1513} 1514 1515// Emit deopt handler code. 1516int emit_deopt_handler(CodeBuffer& cbuf) 1517{ 1518 1519 // Note that the code buffer's insts_mark is always relative to insts. 1520 // That's why we must use the macroassembler to generate a handler. 1521 MacroAssembler _masm(&cbuf); 1522 address base = 1523 __ start_a_stub(size_deopt_handler()); 1524 if (base == NULL) return 0; // CodeBuffer::expand failed 1525 int offset = __ offset(); 1526 address the_pc = (address) __ pc(); 1527 Label next; 1528 // push a "the_pc" on the stack without destroying any registers 1529 // as they all may be live. 1530 1531 // push address of "next" 1532 __ call(next, relocInfo::none); // reloc none is fine since it is a disp32 1533 __ bind(next); 1534 // adjust it so it matches "the_pc" 1535 __ subptr(Address(rsp, 0), __ offset() - offset); 1536 __ jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack())); 1537 assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow"); 1538 __ end_a_stub(); 1539 return offset; 1540} 1541 1542int Matcher::regnum_to_fpu_offset(int regnum) 1543{ 1544 return regnum - 32; // The FP registers are in the second chunk 1545} 1546 1547// This is UltraSparc specific, true just means we have fast l2f conversion 1548const bool Matcher::convL2FSupported(void) { 1549 return true; 1550} 1551 1552// Is this branch offset short enough that a short branch can be used? 1553// 1554// NOTE: If the platform does not provide any short branch variants, then 1555// this method should return false for offset 0. 1556bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 1557 // The passed offset is relative to address of the branch. 1558 // On 86 a branch displacement is calculated relative to address 1559 // of a next instruction. 1560 offset -= br_size; 1561 1562 // the short version of jmpConUCF2 contains multiple branches, 1563 // making the reach slightly less 1564 if (rule == jmpConUCF2_rule) 1565 return (-126 <= offset && offset <= 125); 1566 return (-128 <= offset && offset <= 127); 1567} 1568 1569const bool Matcher::isSimpleConstant64(jlong value) { 1570 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?. 1571 //return value == (int) value; // Cf. storeImmL and immL32. 1572 1573 // Probably always true, even if a temp register is required. 1574 return true; 1575} 1576 1577// The ecx parameter to rep stosq for the ClearArray node is in words. 1578const bool Matcher::init_array_count_is_in_bytes = false; 1579 1580// Threshold size for cleararray. 1581const int Matcher::init_array_short_size = 8 * BytesPerLong; 1582 1583// No additional cost for CMOVL. 1584const int Matcher::long_cmove_cost() { return 0; } 1585 1586// No CMOVF/CMOVD with SSE2 1587const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; } 1588 1589// Should the Matcher clone shifts on addressing modes, expecting them 1590// to be subsumed into complex addressing expressions or compute them 1591// into registers? True for Intel but false for most RISCs 1592const bool Matcher::clone_shift_expressions = true; 1593 1594// Do we need to mask the count passed to shift instructions or does 1595// the cpu only look at the lower 5/6 bits anyway? 1596const bool Matcher::need_masked_shift_count = false; 1597 1598bool Matcher::narrow_oop_use_complex_address() { 1599 assert(UseCompressedOops, "only for compressed oops code"); 1600 return (LogMinObjAlignmentInBytes <= 3); 1601} 1602 1603bool Matcher::narrow_klass_use_complex_address() { 1604 assert(UseCompressedKlassPointers, "only for compressed klass code"); 1605 return (LogKlassAlignmentInBytes <= 3); 1606} 1607 1608// Is it better to copy float constants, or load them directly from 1609// memory? Intel can load a float constant from a direct address, 1610// requiring no extra registers. Most RISCs will have to materialize 1611// an address into a register first, so they would do better to copy 1612// the constant from stack. 1613const bool Matcher::rematerialize_float_constants = true; // XXX 1614 1615// If CPU can load and store mis-aligned doubles directly then no 1616// fixup is needed. Else we split the double into 2 integer pieces 1617// and move it piece-by-piece. Only happens when passing doubles into 1618// C code as the Java calling convention forces doubles to be aligned. 1619const bool Matcher::misaligned_doubles_ok = true; 1620 1621// No-op on amd64 1622void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) {} 1623 1624// Advertise here if the CPU requires explicit rounding operations to 1625// implement the UseStrictFP mode. 1626const bool Matcher::strict_fp_requires_explicit_rounding = true; 1627 1628// Are floats conerted to double when stored to stack during deoptimization? 1629// On x64 it is stored without convertion so we can use normal access. 1630bool Matcher::float_in_double() { return false; } 1631 1632// Do ints take an entire long register or just half? 1633const bool Matcher::int_in_long = true; 1634 1635// Return whether or not this register is ever used as an argument. 1636// This function is used on startup to build the trampoline stubs in 1637// generateOptoStub. Registers not mentioned will be killed by the VM 1638// call in the trampoline, and arguments in those registers not be 1639// available to the callee. 1640bool Matcher::can_be_java_arg(int reg) 1641{ 1642 return 1643 reg == RDI_num || reg == RDI_H_num || 1644 reg == RSI_num || reg == RSI_H_num || 1645 reg == RDX_num || reg == RDX_H_num || 1646 reg == RCX_num || reg == RCX_H_num || 1647 reg == R8_num || reg == R8_H_num || 1648 reg == R9_num || reg == R9_H_num || 1649 reg == R12_num || reg == R12_H_num || 1650 reg == XMM0_num || reg == XMM0b_num || 1651 reg == XMM1_num || reg == XMM1b_num || 1652 reg == XMM2_num || reg == XMM2b_num || 1653 reg == XMM3_num || reg == XMM3b_num || 1654 reg == XMM4_num || reg == XMM4b_num || 1655 reg == XMM5_num || reg == XMM5b_num || 1656 reg == XMM6_num || reg == XMM6b_num || 1657 reg == XMM7_num || reg == XMM7b_num; 1658} 1659 1660bool Matcher::is_spillable_arg(int reg) 1661{ 1662 return can_be_java_arg(reg); 1663} 1664 1665bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) { 1666 // In 64 bit mode a code which use multiply when 1667 // devisor is constant is faster than hardware 1668 // DIV instruction (it uses MulHiL). 1669 return false; 1670} 1671 1672// Register for DIVI projection of divmodI 1673RegMask Matcher::divI_proj_mask() { 1674 return INT_RAX_REG_mask(); 1675} 1676 1677// Register for MODI projection of divmodI 1678RegMask Matcher::modI_proj_mask() { 1679 return INT_RDX_REG_mask(); 1680} 1681 1682// Register for DIVL projection of divmodL 1683RegMask Matcher::divL_proj_mask() { 1684 return LONG_RAX_REG_mask(); 1685} 1686 1687// Register for MODL projection of divmodL 1688RegMask Matcher::modL_proj_mask() { 1689 return LONG_RDX_REG_mask(); 1690} 1691 1692const RegMask Matcher::method_handle_invoke_SP_save_mask() { 1693 return PTR_RBP_REG_mask(); 1694} 1695 1696static Address build_address(int b, int i, int s, int d) { 1697 Register index = as_Register(i); 1698 Address::ScaleFactor scale = (Address::ScaleFactor)s; 1699 if (index == rsp) { 1700 index = noreg; 1701 scale = Address::no_scale; 1702 } 1703 Address addr(as_Register(b), index, scale, d); 1704 return addr; 1705} 1706 1707%} 1708 1709//----------ENCODING BLOCK----------------------------------------------------- 1710// This block specifies the encoding classes used by the compiler to 1711// output byte streams. Encoding classes are parameterized macros 1712// used by Machine Instruction Nodes in order to generate the bit 1713// encoding of the instruction. Operands specify their base encoding 1714// interface with the interface keyword. There are currently 1715// supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & 1716// COND_INTER. REG_INTER causes an operand to generate a function 1717// which returns its register number when queried. CONST_INTER causes 1718// an operand to generate a function which returns the value of the 1719// constant when queried. MEMORY_INTER causes an operand to generate 1720// four functions which return the Base Register, the Index Register, 1721// the Scale Value, and the Offset Value of the operand when queried. 1722// COND_INTER causes an operand to generate six functions which return 1723// the encoding code (ie - encoding bits for the instruction) 1724// associated with each basic boolean condition for a conditional 1725// instruction. 1726// 1727// Instructions specify two basic values for encoding. Again, a 1728// function is available to check if the constant displacement is an 1729// oop. They use the ins_encode keyword to specify their encoding 1730// classes (which must be a sequence of enc_class names, and their 1731// parameters, specified in the encoding block), and they use the 1732// opcode keyword to specify, in order, their primary, secondary, and 1733// tertiary opcode. Only the opcode sections which a particular 1734// instruction needs for encoding need to be specified. 1735encode %{ 1736 // Build emit functions for each basic byte or larger field in the 1737 // intel encoding scheme (opcode, rm, sib, immediate), and call them 1738 // from C++ code in the enc_class source block. Emit functions will 1739 // live in the main source block for now. In future, we can 1740 // generalize this by adding a syntax that specifies the sizes of 1741 // fields in an order, so that the adlc can build the emit functions 1742 // automagically 1743 1744 // Emit primary opcode 1745 enc_class OpcP 1746 %{ 1747 emit_opcode(cbuf, $primary); 1748 %} 1749 1750 // Emit secondary opcode 1751 enc_class OpcS 1752 %{ 1753 emit_opcode(cbuf, $secondary); 1754 %} 1755 1756 // Emit tertiary opcode 1757 enc_class OpcT 1758 %{ 1759 emit_opcode(cbuf, $tertiary); 1760 %} 1761 1762 // Emit opcode directly 1763 enc_class Opcode(immI d8) 1764 %{ 1765 emit_opcode(cbuf, $d8$$constant); 1766 %} 1767 1768 // Emit size prefix 1769 enc_class SizePrefix 1770 %{ 1771 emit_opcode(cbuf, 0x66); 1772 %} 1773 1774 enc_class reg(rRegI reg) 1775 %{ 1776 emit_rm(cbuf, 0x3, 0, $reg$$reg & 7); 1777 %} 1778 1779 enc_class reg_reg(rRegI dst, rRegI src) 1780 %{ 1781 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); 1782 %} 1783 1784 enc_class opc_reg_reg(immI opcode, rRegI dst, rRegI src) 1785 %{ 1786 emit_opcode(cbuf, $opcode$$constant); 1787 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); 1788 %} 1789 1790 enc_class cdql_enc(no_rax_rdx_RegI div) 1791 %{ 1792 // Full implementation of Java idiv and irem; checks for 1793 // special case as described in JVM spec., p.243 & p.271. 1794 // 1795 // normal case special case 1796 // 1797 // input : rax: dividend min_int 1798 // reg: divisor -1 1799 // 1800 // output: rax: quotient (= rax idiv reg) min_int 1801 // rdx: remainder (= rax irem reg) 0 1802 // 1803 // Code sequnce: 1804 // 1805 // 0: 3d 00 00 00 80 cmp $0x80000000,%eax 1806 // 5: 75 07/08 jne e <normal> 1807 // 7: 33 d2 xor %edx,%edx 1808 // [div >= 8 -> offset + 1] 1809 // [REX_B] 1810 // 9: 83 f9 ff cmp $0xffffffffffffffff,$div 1811 // c: 74 03/04 je 11 <done> 1812 // 000000000000000e <normal>: 1813 // e: 99 cltd 1814 // [div >= 8 -> offset + 1] 1815 // [REX_B] 1816 // f: f7 f9 idiv $div 1817 // 0000000000000011 <done>: 1818 1819 // cmp $0x80000000,%eax 1820 emit_opcode(cbuf, 0x3d); 1821 emit_d8(cbuf, 0x00); 1822 emit_d8(cbuf, 0x00); 1823 emit_d8(cbuf, 0x00); 1824 emit_d8(cbuf, 0x80); 1825 1826 // jne e <normal> 1827 emit_opcode(cbuf, 0x75); 1828 emit_d8(cbuf, $div$$reg < 8 ? 0x07 : 0x08); 1829 1830 // xor %edx,%edx 1831 emit_opcode(cbuf, 0x33); 1832 emit_d8(cbuf, 0xD2); 1833 1834 // cmp $0xffffffffffffffff,%ecx 1835 if ($div$$reg >= 8) { 1836 emit_opcode(cbuf, Assembler::REX_B); 1837 } 1838 emit_opcode(cbuf, 0x83); 1839 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7); 1840 emit_d8(cbuf, 0xFF); 1841 1842 // je 11 <done> 1843 emit_opcode(cbuf, 0x74); 1844 emit_d8(cbuf, $div$$reg < 8 ? 0x03 : 0x04); 1845 1846 // <normal> 1847 // cltd 1848 emit_opcode(cbuf, 0x99); 1849 1850 // idivl (note: must be emitted by the user of this rule) 1851 // <done> 1852 %} 1853 1854 enc_class cdqq_enc(no_rax_rdx_RegL div) 1855 %{ 1856 // Full implementation of Java ldiv and lrem; checks for 1857 // special case as described in JVM spec., p.243 & p.271. 1858 // 1859 // normal case special case 1860 // 1861 // input : rax: dividend min_long 1862 // reg: divisor -1 1863 // 1864 // output: rax: quotient (= rax idiv reg) min_long 1865 // rdx: remainder (= rax irem reg) 0 1866 // 1867 // Code sequnce: 1868 // 1869 // 0: 48 ba 00 00 00 00 00 mov $0x8000000000000000,%rdx 1870 // 7: 00 00 80 1871 // a: 48 39 d0 cmp %rdx,%rax 1872 // d: 75 08 jne 17 <normal> 1873 // f: 33 d2 xor %edx,%edx 1874 // 11: 48 83 f9 ff cmp $0xffffffffffffffff,$div 1875 // 15: 74 05 je 1c <done> 1876 // 0000000000000017 <normal>: 1877 // 17: 48 99 cqto 1878 // 19: 48 f7 f9 idiv $div 1879 // 000000000000001c <done>: 1880 1881 // mov $0x8000000000000000,%rdx 1882 emit_opcode(cbuf, Assembler::REX_W); 1883 emit_opcode(cbuf, 0xBA); 1884 emit_d8(cbuf, 0x00); 1885 emit_d8(cbuf, 0x00); 1886 emit_d8(cbuf, 0x00); 1887 emit_d8(cbuf, 0x00); 1888 emit_d8(cbuf, 0x00); 1889 emit_d8(cbuf, 0x00); 1890 emit_d8(cbuf, 0x00); 1891 emit_d8(cbuf, 0x80); 1892 1893 // cmp %rdx,%rax 1894 emit_opcode(cbuf, Assembler::REX_W); 1895 emit_opcode(cbuf, 0x39); 1896 emit_d8(cbuf, 0xD0); 1897 1898 // jne 17 <normal> 1899 emit_opcode(cbuf, 0x75); 1900 emit_d8(cbuf, 0x08); 1901 1902 // xor %edx,%edx 1903 emit_opcode(cbuf, 0x33); 1904 emit_d8(cbuf, 0xD2); 1905 1906 // cmp $0xffffffffffffffff,$div 1907 emit_opcode(cbuf, $div$$reg < 8 ? Assembler::REX_W : Assembler::REX_WB); 1908 emit_opcode(cbuf, 0x83); 1909 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7); 1910 emit_d8(cbuf, 0xFF); 1911 1912 // je 1e <done> 1913 emit_opcode(cbuf, 0x74); 1914 emit_d8(cbuf, 0x05); 1915 1916 // <normal> 1917 // cqto 1918 emit_opcode(cbuf, Assembler::REX_W); 1919 emit_opcode(cbuf, 0x99); 1920 1921 // idivq (note: must be emitted by the user of this rule) 1922 // <done> 1923 %} 1924 1925 // Opcde enc_class for 8/32 bit immediate instructions with sign-extension 1926 enc_class OpcSE(immI imm) 1927 %{ 1928 // Emit primary opcode and set sign-extend bit 1929 // Check for 8-bit immediate, and set sign extend bit in opcode 1930 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 1931 emit_opcode(cbuf, $primary | 0x02); 1932 } else { 1933 // 32-bit immediate 1934 emit_opcode(cbuf, $primary); 1935 } 1936 %} 1937 1938 enc_class OpcSErm(rRegI dst, immI imm) 1939 %{ 1940 // OpcSEr/m 1941 int dstenc = $dst$$reg; 1942 if (dstenc >= 8) { 1943 emit_opcode(cbuf, Assembler::REX_B); 1944 dstenc -= 8; 1945 } 1946 // Emit primary opcode and set sign-extend bit 1947 // Check for 8-bit immediate, and set sign extend bit in opcode 1948 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 1949 emit_opcode(cbuf, $primary | 0x02); 1950 } else { 1951 // 32-bit immediate 1952 emit_opcode(cbuf, $primary); 1953 } 1954 // Emit r/m byte with secondary opcode, after primary opcode. 1955 emit_rm(cbuf, 0x3, $secondary, dstenc); 1956 %} 1957 1958 enc_class OpcSErm_wide(rRegL dst, immI imm) 1959 %{ 1960 // OpcSEr/m 1961 int dstenc = $dst$$reg; 1962 if (dstenc < 8) { 1963 emit_opcode(cbuf, Assembler::REX_W); 1964 } else { 1965 emit_opcode(cbuf, Assembler::REX_WB); 1966 dstenc -= 8; 1967 } 1968 // Emit primary opcode and set sign-extend bit 1969 // Check for 8-bit immediate, and set sign extend bit in opcode 1970 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 1971 emit_opcode(cbuf, $primary | 0x02); 1972 } else { 1973 // 32-bit immediate 1974 emit_opcode(cbuf, $primary); 1975 } 1976 // Emit r/m byte with secondary opcode, after primary opcode. 1977 emit_rm(cbuf, 0x3, $secondary, dstenc); 1978 %} 1979 1980 enc_class Con8or32(immI imm) 1981 %{ 1982 // Check for 8-bit immediate, and set sign extend bit in opcode 1983 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 1984 $$$emit8$imm$$constant; 1985 } else { 1986 // 32-bit immediate 1987 $$$emit32$imm$$constant; 1988 } 1989 %} 1990 1991 enc_class opc2_reg(rRegI dst) 1992 %{ 1993 // BSWAP 1994 emit_cc(cbuf, $secondary, $dst$$reg); 1995 %} 1996 1997 enc_class opc3_reg(rRegI dst) 1998 %{ 1999 // BSWAP 2000 emit_cc(cbuf, $tertiary, $dst$$reg); 2001 %} 2002 2003 enc_class reg_opc(rRegI div) 2004 %{ 2005 // INC, DEC, IDIV, IMOD, JMP indirect, ... 2006 emit_rm(cbuf, 0x3, $secondary, $div$$reg & 7); 2007 %} 2008 2009 enc_class enc_cmov(cmpOp cop) 2010 %{ 2011 // CMOV 2012 $$$emit8$primary; 2013 emit_cc(cbuf, $secondary, $cop$$cmpcode); 2014 %} 2015 2016 enc_class enc_PartialSubtypeCheck() 2017 %{ 2018 Register Rrdi = as_Register(RDI_enc); // result register 2019 Register Rrax = as_Register(RAX_enc); // super class 2020 Register Rrcx = as_Register(RCX_enc); // killed 2021 Register Rrsi = as_Register(RSI_enc); // sub class 2022 Label miss; 2023 const bool set_cond_codes = true; 2024 2025 MacroAssembler _masm(&cbuf); 2026 __ check_klass_subtype_slow_path(Rrsi, Rrax, Rrcx, Rrdi, 2027 NULL, &miss, 2028 /*set_cond_codes:*/ true); 2029 if ($primary) { 2030 __ xorptr(Rrdi, Rrdi); 2031 } 2032 __ bind(miss); 2033 %} 2034 2035 enc_class clear_avx %{ 2036 debug_only(int off0 = cbuf.insts_size()); 2037 if (ra_->C->max_vector_size() > 16) { 2038 // Clear upper bits of YMM registers when current compiled code uses 2039 // wide vectors to avoid AVX <-> SSE transition penalty during call. 2040 MacroAssembler _masm(&cbuf); 2041 __ vzeroupper(); 2042 } 2043 debug_only(int off1 = cbuf.insts_size()); 2044 assert(off1 - off0 == clear_avx_size(), "correct size prediction"); 2045 %} 2046 2047 enc_class Java_To_Runtime(method meth) %{ 2048 // No relocation needed 2049 MacroAssembler _masm(&cbuf); 2050 __ mov64(r10, (int64_t) $meth$$method); 2051 __ call(r10); 2052 %} 2053 2054 enc_class Java_To_Interpreter(method meth) 2055 %{ 2056 // CALL Java_To_Interpreter 2057 // This is the instruction starting address for relocation info. 2058 cbuf.set_insts_mark(); 2059 $$$emit8$primary; 2060 // CALL directly to the runtime 2061 emit_d32_reloc(cbuf, 2062 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2063 runtime_call_Relocation::spec(), 2064 RELOC_DISP32); 2065 %} 2066 2067 enc_class Java_Static_Call(method meth) 2068 %{ 2069 // JAVA STATIC CALL 2070 // CALL to fixup routine. Fixup routine uses ScopeDesc info to 2071 // determine who we intended to call. 2072 cbuf.set_insts_mark(); 2073 $$$emit8$primary; 2074 2075 if (!_method) { 2076 emit_d32_reloc(cbuf, 2077 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2078 runtime_call_Relocation::spec(), 2079 RELOC_DISP32); 2080 } else if (_optimized_virtual) { 2081 emit_d32_reloc(cbuf, 2082 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2083 opt_virtual_call_Relocation::spec(), 2084 RELOC_DISP32); 2085 } else { 2086 emit_d32_reloc(cbuf, 2087 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2088 static_call_Relocation::spec(), 2089 RELOC_DISP32); 2090 } 2091 if (_method) { 2092 // Emit stub for static call 2093 emit_java_to_interp(cbuf); 2094 } 2095 %} 2096 2097 enc_class Java_Dynamic_Call(method meth) %{ 2098 MacroAssembler _masm(&cbuf); 2099 __ ic_call((address)$meth$$method); 2100 %} 2101 2102 enc_class Java_Compiled_Call(method meth) 2103 %{ 2104 // JAVA COMPILED CALL 2105 int disp = in_bytes(Method:: from_compiled_offset()); 2106 2107 // XXX XXX offset is 128 is 1.5 NON-PRODUCT !!! 2108 // assert(-0x80 <= disp && disp < 0x80, "compiled_code_offset isn't small"); 2109 2110 // callq *disp(%rax) 2111 cbuf.set_insts_mark(); 2112 $$$emit8$primary; 2113 if (disp < 0x80) { 2114 emit_rm(cbuf, 0x01, $secondary, RAX_enc); // R/M byte 2115 emit_d8(cbuf, disp); // Displacement 2116 } else { 2117 emit_rm(cbuf, 0x02, $secondary, RAX_enc); // R/M byte 2118 emit_d32(cbuf, disp); // Displacement 2119 } 2120 %} 2121 2122 enc_class reg_opc_imm(rRegI dst, immI8 shift) 2123 %{ 2124 // SAL, SAR, SHR 2125 int dstenc = $dst$$reg; 2126 if (dstenc >= 8) { 2127 emit_opcode(cbuf, Assembler::REX_B); 2128 dstenc -= 8; 2129 } 2130 $$$emit8$primary; 2131 emit_rm(cbuf, 0x3, $secondary, dstenc); 2132 $$$emit8$shift$$constant; 2133 %} 2134 2135 enc_class reg_opc_imm_wide(rRegL dst, immI8 shift) 2136 %{ 2137 // SAL, SAR, SHR 2138 int dstenc = $dst$$reg; 2139 if (dstenc < 8) { 2140 emit_opcode(cbuf, Assembler::REX_W); 2141 } else { 2142 emit_opcode(cbuf, Assembler::REX_WB); 2143 dstenc -= 8; 2144 } 2145 $$$emit8$primary; 2146 emit_rm(cbuf, 0x3, $secondary, dstenc); 2147 $$$emit8$shift$$constant; 2148 %} 2149 2150 enc_class load_immI(rRegI dst, immI src) 2151 %{ 2152 int dstenc = $dst$$reg; 2153 if (dstenc >= 8) { 2154 emit_opcode(cbuf, Assembler::REX_B); 2155 dstenc -= 8; 2156 } 2157 emit_opcode(cbuf, 0xB8 | dstenc); 2158 $$$emit32$src$$constant; 2159 %} 2160 2161 enc_class load_immL(rRegL dst, immL src) 2162 %{ 2163 int dstenc = $dst$$reg; 2164 if (dstenc < 8) { 2165 emit_opcode(cbuf, Assembler::REX_W); 2166 } else { 2167 emit_opcode(cbuf, Assembler::REX_WB); 2168 dstenc -= 8; 2169 } 2170 emit_opcode(cbuf, 0xB8 | dstenc); 2171 emit_d64(cbuf, $src$$constant); 2172 %} 2173 2174 enc_class load_immUL32(rRegL dst, immUL32 src) 2175 %{ 2176 // same as load_immI, but this time we care about zeroes in the high word 2177 int dstenc = $dst$$reg; 2178 if (dstenc >= 8) { 2179 emit_opcode(cbuf, Assembler::REX_B); 2180 dstenc -= 8; 2181 } 2182 emit_opcode(cbuf, 0xB8 | dstenc); 2183 $$$emit32$src$$constant; 2184 %} 2185 2186 enc_class load_immL32(rRegL dst, immL32 src) 2187 %{ 2188 int dstenc = $dst$$reg; 2189 if (dstenc < 8) { 2190 emit_opcode(cbuf, Assembler::REX_W); 2191 } else { 2192 emit_opcode(cbuf, Assembler::REX_WB); 2193 dstenc -= 8; 2194 } 2195 emit_opcode(cbuf, 0xC7); 2196 emit_rm(cbuf, 0x03, 0x00, dstenc); 2197 $$$emit32$src$$constant; 2198 %} 2199 2200 enc_class load_immP31(rRegP dst, immP32 src) 2201 %{ 2202 // same as load_immI, but this time we care about zeroes in the high word 2203 int dstenc = $dst$$reg; 2204 if (dstenc >= 8) { 2205 emit_opcode(cbuf, Assembler::REX_B); 2206 dstenc -= 8; 2207 } 2208 emit_opcode(cbuf, 0xB8 | dstenc); 2209 $$$emit32$src$$constant; 2210 %} 2211 2212 enc_class load_immP(rRegP dst, immP src) 2213 %{ 2214 int dstenc = $dst$$reg; 2215 if (dstenc < 8) { 2216 emit_opcode(cbuf, Assembler::REX_W); 2217 } else { 2218 emit_opcode(cbuf, Assembler::REX_WB); 2219 dstenc -= 8; 2220 } 2221 emit_opcode(cbuf, 0xB8 | dstenc); 2222 // This next line should be generated from ADLC 2223 if ($src->constant_reloc() != relocInfo::none) { 2224 emit_d64_reloc(cbuf, $src$$constant, $src->constant_reloc(), RELOC_IMM64); 2225 } else { 2226 emit_d64(cbuf, $src$$constant); 2227 } 2228 %} 2229 2230 enc_class Con32(immI src) 2231 %{ 2232 // Output immediate 2233 $$$emit32$src$$constant; 2234 %} 2235 2236 enc_class Con64(immL src) 2237 %{ 2238 // Output immediate 2239 emit_d64($src$$constant); 2240 %} 2241 2242 enc_class Con32F_as_bits(immF src) 2243 %{ 2244 // Output Float immediate bits 2245 jfloat jf = $src$$constant; 2246 jint jf_as_bits = jint_cast(jf); 2247 emit_d32(cbuf, jf_as_bits); 2248 %} 2249 2250 enc_class Con16(immI src) 2251 %{ 2252 // Output immediate 2253 $$$emit16$src$$constant; 2254 %} 2255 2256 // How is this different from Con32??? XXX 2257 enc_class Con_d32(immI src) 2258 %{ 2259 emit_d32(cbuf,$src$$constant); 2260 %} 2261 2262 enc_class conmemref (rRegP t1) %{ // Con32(storeImmI) 2263 // Output immediate memory reference 2264 emit_rm(cbuf, 0x00, $t1$$reg, 0x05 ); 2265 emit_d32(cbuf, 0x00); 2266 %} 2267 2268 enc_class lock_prefix() 2269 %{ 2270 if (os::is_MP()) { 2271 emit_opcode(cbuf, 0xF0); // lock 2272 } 2273 %} 2274 2275 enc_class REX_mem(memory mem) 2276 %{ 2277 if ($mem$$base >= 8) { 2278 if ($mem$$index < 8) { 2279 emit_opcode(cbuf, Assembler::REX_B); 2280 } else { 2281 emit_opcode(cbuf, Assembler::REX_XB); 2282 } 2283 } else { 2284 if ($mem$$index >= 8) { 2285 emit_opcode(cbuf, Assembler::REX_X); 2286 } 2287 } 2288 %} 2289 2290 enc_class REX_mem_wide(memory mem) 2291 %{ 2292 if ($mem$$base >= 8) { 2293 if ($mem$$index < 8) { 2294 emit_opcode(cbuf, Assembler::REX_WB); 2295 } else { 2296 emit_opcode(cbuf, Assembler::REX_WXB); 2297 } 2298 } else { 2299 if ($mem$$index < 8) { 2300 emit_opcode(cbuf, Assembler::REX_W); 2301 } else { 2302 emit_opcode(cbuf, Assembler::REX_WX); 2303 } 2304 } 2305 %} 2306 2307 // for byte regs 2308 enc_class REX_breg(rRegI reg) 2309 %{ 2310 if ($reg$$reg >= 4) { 2311 emit_opcode(cbuf, $reg$$reg < 8 ? Assembler::REX : Assembler::REX_B); 2312 } 2313 %} 2314 2315 // for byte regs 2316 enc_class REX_reg_breg(rRegI dst, rRegI src) 2317 %{ 2318 if ($dst$$reg < 8) { 2319 if ($src$$reg >= 4) { 2320 emit_opcode(cbuf, $src$$reg < 8 ? Assembler::REX : Assembler::REX_B); 2321 } 2322 } else { 2323 if ($src$$reg < 8) { 2324 emit_opcode(cbuf, Assembler::REX_R); 2325 } else { 2326 emit_opcode(cbuf, Assembler::REX_RB); 2327 } 2328 } 2329 %} 2330 2331 // for byte regs 2332 enc_class REX_breg_mem(rRegI reg, memory mem) 2333 %{ 2334 if ($reg$$reg < 8) { 2335 if ($mem$$base < 8) { 2336 if ($mem$$index >= 8) { 2337 emit_opcode(cbuf, Assembler::REX_X); 2338 } else if ($reg$$reg >= 4) { 2339 emit_opcode(cbuf, Assembler::REX); 2340 } 2341 } else { 2342 if ($mem$$index < 8) { 2343 emit_opcode(cbuf, Assembler::REX_B); 2344 } else { 2345 emit_opcode(cbuf, Assembler::REX_XB); 2346 } 2347 } 2348 } else { 2349 if ($mem$$base < 8) { 2350 if ($mem$$index < 8) { 2351 emit_opcode(cbuf, Assembler::REX_R); 2352 } else { 2353 emit_opcode(cbuf, Assembler::REX_RX); 2354 } 2355 } else { 2356 if ($mem$$index < 8) { 2357 emit_opcode(cbuf, Assembler::REX_RB); 2358 } else { 2359 emit_opcode(cbuf, Assembler::REX_RXB); 2360 } 2361 } 2362 } 2363 %} 2364 2365 enc_class REX_reg(rRegI reg) 2366 %{ 2367 if ($reg$$reg >= 8) { 2368 emit_opcode(cbuf, Assembler::REX_B); 2369 } 2370 %} 2371 2372 enc_class REX_reg_wide(rRegI reg) 2373 %{ 2374 if ($reg$$reg < 8) { 2375 emit_opcode(cbuf, Assembler::REX_W); 2376 } else { 2377 emit_opcode(cbuf, Assembler::REX_WB); 2378 } 2379 %} 2380 2381 enc_class REX_reg_reg(rRegI dst, rRegI src) 2382 %{ 2383 if ($dst$$reg < 8) { 2384 if ($src$$reg >= 8) { 2385 emit_opcode(cbuf, Assembler::REX_B); 2386 } 2387 } else { 2388 if ($src$$reg < 8) { 2389 emit_opcode(cbuf, Assembler::REX_R); 2390 } else { 2391 emit_opcode(cbuf, Assembler::REX_RB); 2392 } 2393 } 2394 %} 2395 2396 enc_class REX_reg_reg_wide(rRegI dst, rRegI src) 2397 %{ 2398 if ($dst$$reg < 8) { 2399 if ($src$$reg < 8) { 2400 emit_opcode(cbuf, Assembler::REX_W); 2401 } else { 2402 emit_opcode(cbuf, Assembler::REX_WB); 2403 } 2404 } else { 2405 if ($src$$reg < 8) { 2406 emit_opcode(cbuf, Assembler::REX_WR); 2407 } else { 2408 emit_opcode(cbuf, Assembler::REX_WRB); 2409 } 2410 } 2411 %} 2412 2413 enc_class REX_reg_mem(rRegI reg, memory mem) 2414 %{ 2415 if ($reg$$reg < 8) { 2416 if ($mem$$base < 8) { 2417 if ($mem$$index >= 8) { 2418 emit_opcode(cbuf, Assembler::REX_X); 2419 } 2420 } else { 2421 if ($mem$$index < 8) { 2422 emit_opcode(cbuf, Assembler::REX_B); 2423 } else { 2424 emit_opcode(cbuf, Assembler::REX_XB); 2425 } 2426 } 2427 } else { 2428 if ($mem$$base < 8) { 2429 if ($mem$$index < 8) { 2430 emit_opcode(cbuf, Assembler::REX_R); 2431 } else { 2432 emit_opcode(cbuf, Assembler::REX_RX); 2433 } 2434 } else { 2435 if ($mem$$index < 8) { 2436 emit_opcode(cbuf, Assembler::REX_RB); 2437 } else { 2438 emit_opcode(cbuf, Assembler::REX_RXB); 2439 } 2440 } 2441 } 2442 %} 2443 2444 enc_class REX_reg_mem_wide(rRegL reg, memory mem) 2445 %{ 2446 if ($reg$$reg < 8) { 2447 if ($mem$$base < 8) { 2448 if ($mem$$index < 8) { 2449 emit_opcode(cbuf, Assembler::REX_W); 2450 } else { 2451 emit_opcode(cbuf, Assembler::REX_WX); 2452 } 2453 } else { 2454 if ($mem$$index < 8) { 2455 emit_opcode(cbuf, Assembler::REX_WB); 2456 } else { 2457 emit_opcode(cbuf, Assembler::REX_WXB); 2458 } 2459 } 2460 } else { 2461 if ($mem$$base < 8) { 2462 if ($mem$$index < 8) { 2463 emit_opcode(cbuf, Assembler::REX_WR); 2464 } else { 2465 emit_opcode(cbuf, Assembler::REX_WRX); 2466 } 2467 } else { 2468 if ($mem$$index < 8) { 2469 emit_opcode(cbuf, Assembler::REX_WRB); 2470 } else { 2471 emit_opcode(cbuf, Assembler::REX_WRXB); 2472 } 2473 } 2474 } 2475 %} 2476 2477 enc_class reg_mem(rRegI ereg, memory mem) 2478 %{ 2479 // High registers handle in encode_RegMem 2480 int reg = $ereg$$reg; 2481 int base = $mem$$base; 2482 int index = $mem$$index; 2483 int scale = $mem$$scale; 2484 int disp = $mem$$disp; 2485 relocInfo::relocType disp_reloc = $mem->disp_reloc(); 2486 2487 encode_RegMem(cbuf, reg, base, index, scale, disp, disp_reloc); 2488 %} 2489 2490 enc_class RM_opc_mem(immI rm_opcode, memory mem) 2491 %{ 2492 int rm_byte_opcode = $rm_opcode$$constant; 2493 2494 // High registers handle in encode_RegMem 2495 int base = $mem$$base; 2496 int index = $mem$$index; 2497 int scale = $mem$$scale; 2498 int displace = $mem$$disp; 2499 2500 relocInfo::relocType disp_reloc = $mem->disp_reloc(); // disp-as-oop when 2501 // working with static 2502 // globals 2503 encode_RegMem(cbuf, rm_byte_opcode, base, index, scale, displace, 2504 disp_reloc); 2505 %} 2506 2507 enc_class reg_lea(rRegI dst, rRegI src0, immI src1) 2508 %{ 2509 int reg_encoding = $dst$$reg; 2510 int base = $src0$$reg; // 0xFFFFFFFF indicates no base 2511 int index = 0x04; // 0x04 indicates no index 2512 int scale = 0x00; // 0x00 indicates no scale 2513 int displace = $src1$$constant; // 0x00 indicates no displacement 2514 relocInfo::relocType disp_reloc = relocInfo::none; 2515 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, 2516 disp_reloc); 2517 %} 2518 2519 enc_class neg_reg(rRegI dst) 2520 %{ 2521 int dstenc = $dst$$reg; 2522 if (dstenc >= 8) { 2523 emit_opcode(cbuf, Assembler::REX_B); 2524 dstenc -= 8; 2525 } 2526 // NEG $dst 2527 emit_opcode(cbuf, 0xF7); 2528 emit_rm(cbuf, 0x3, 0x03, dstenc); 2529 %} 2530 2531 enc_class neg_reg_wide(rRegI dst) 2532 %{ 2533 int dstenc = $dst$$reg; 2534 if (dstenc < 8) { 2535 emit_opcode(cbuf, Assembler::REX_W); 2536 } else { 2537 emit_opcode(cbuf, Assembler::REX_WB); 2538 dstenc -= 8; 2539 } 2540 // NEG $dst 2541 emit_opcode(cbuf, 0xF7); 2542 emit_rm(cbuf, 0x3, 0x03, dstenc); 2543 %} 2544 2545 enc_class setLT_reg(rRegI dst) 2546 %{ 2547 int dstenc = $dst$$reg; 2548 if (dstenc >= 8) { 2549 emit_opcode(cbuf, Assembler::REX_B); 2550 dstenc -= 8; 2551 } else if (dstenc >= 4) { 2552 emit_opcode(cbuf, Assembler::REX); 2553 } 2554 // SETLT $dst 2555 emit_opcode(cbuf, 0x0F); 2556 emit_opcode(cbuf, 0x9C); 2557 emit_rm(cbuf, 0x3, 0x0, dstenc); 2558 %} 2559 2560 enc_class setNZ_reg(rRegI dst) 2561 %{ 2562 int dstenc = $dst$$reg; 2563 if (dstenc >= 8) { 2564 emit_opcode(cbuf, Assembler::REX_B); 2565 dstenc -= 8; 2566 } else if (dstenc >= 4) { 2567 emit_opcode(cbuf, Assembler::REX); 2568 } 2569 // SETNZ $dst 2570 emit_opcode(cbuf, 0x0F); 2571 emit_opcode(cbuf, 0x95); 2572 emit_rm(cbuf, 0x3, 0x0, dstenc); 2573 %} 2574 2575 2576 // Compare the lonogs and set -1, 0, or 1 into dst 2577 enc_class cmpl3_flag(rRegL src1, rRegL src2, rRegI dst) 2578 %{ 2579 int src1enc = $src1$$reg; 2580 int src2enc = $src2$$reg; 2581 int dstenc = $dst$$reg; 2582 2583 // cmpq $src1, $src2 2584 if (src1enc < 8) { 2585 if (src2enc < 8) { 2586 emit_opcode(cbuf, Assembler::REX_W); 2587 } else { 2588 emit_opcode(cbuf, Assembler::REX_WB); 2589 } 2590 } else { 2591 if (src2enc < 8) { 2592 emit_opcode(cbuf, Assembler::REX_WR); 2593 } else { 2594 emit_opcode(cbuf, Assembler::REX_WRB); 2595 } 2596 } 2597 emit_opcode(cbuf, 0x3B); 2598 emit_rm(cbuf, 0x3, src1enc & 7, src2enc & 7); 2599 2600 // movl $dst, -1 2601 if (dstenc >= 8) { 2602 emit_opcode(cbuf, Assembler::REX_B); 2603 } 2604 emit_opcode(cbuf, 0xB8 | (dstenc & 7)); 2605 emit_d32(cbuf, -1); 2606 2607 // jl,s done 2608 emit_opcode(cbuf, 0x7C); 2609 emit_d8(cbuf, dstenc < 4 ? 0x06 : 0x08); 2610 2611 // setne $dst 2612 if (dstenc >= 4) { 2613 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_B); 2614 } 2615 emit_opcode(cbuf, 0x0F); 2616 emit_opcode(cbuf, 0x95); 2617 emit_opcode(cbuf, 0xC0 | (dstenc & 7)); 2618 2619 // movzbl $dst, $dst 2620 if (dstenc >= 4) { 2621 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_RB); 2622 } 2623 emit_opcode(cbuf, 0x0F); 2624 emit_opcode(cbuf, 0xB6); 2625 emit_rm(cbuf, 0x3, dstenc & 7, dstenc & 7); 2626 %} 2627 2628 enc_class Push_ResultXD(regD dst) %{ 2629 MacroAssembler _masm(&cbuf); 2630 __ fstp_d(Address(rsp, 0)); 2631 __ movdbl($dst$$XMMRegister, Address(rsp, 0)); 2632 __ addptr(rsp, 8); 2633 %} 2634 2635 enc_class Push_SrcXD(regD src) %{ 2636 MacroAssembler _masm(&cbuf); 2637 __ subptr(rsp, 8); 2638 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 2639 __ fld_d(Address(rsp, 0)); 2640 %} 2641 2642 2643 // obj: object to lock 2644 // box: box address (header location) -- killed 2645 // tmp: rax -- killed 2646 // scr: rbx -- killed 2647 // 2648 // What follows is a direct transliteration of fast_lock() and fast_unlock() 2649 // from i486.ad. See that file for comments. 2650 // TODO: where possible switch from movq (r, 0) to movl(r,0) and 2651 // use the shorter encoding. (Movl clears the high-order 32-bits). 2652 2653 2654 enc_class Fast_Lock(rRegP obj, rRegP box, rax_RegI tmp, rRegP scr) 2655 %{ 2656 Register objReg = as_Register((int)$obj$$reg); 2657 Register boxReg = as_Register((int)$box$$reg); 2658 Register tmpReg = as_Register($tmp$$reg); 2659 Register scrReg = as_Register($scr$$reg); 2660 MacroAssembler masm(&cbuf); 2661 2662 // Verify uniqueness of register assignments -- necessary but not sufficient 2663 assert (objReg != boxReg && objReg != tmpReg && 2664 objReg != scrReg && tmpReg != scrReg, "invariant") ; 2665 2666 if (_counters != NULL) { 2667 masm.atomic_incl(ExternalAddress((address) _counters->total_entry_count_addr())); 2668 } 2669 if (EmitSync & 1) { 2670 // Without cast to int32_t a movptr will destroy r10 which is typically obj 2671 masm.movptr (Address(boxReg, 0), (int32_t)intptr_t(markOopDesc::unused_mark())) ; 2672 masm.cmpptr(rsp, (int32_t)NULL_WORD) ; 2673 } else 2674 if (EmitSync & 2) { 2675 Label DONE_LABEL; 2676 if (UseBiasedLocking) { 2677 // Note: tmpReg maps to the swap_reg argument and scrReg to the tmp_reg argument. 2678 masm.biased_locking_enter(boxReg, objReg, tmpReg, scrReg, false, DONE_LABEL, NULL, _counters); 2679 } 2680 // QQQ was movl... 2681 masm.movptr(tmpReg, 0x1); 2682 masm.orptr(tmpReg, Address(objReg, 0)); 2683 masm.movptr(Address(boxReg, 0), tmpReg); 2684 if (os::is_MP()) { 2685 masm.lock(); 2686 } 2687 masm.cmpxchgptr(boxReg, Address(objReg, 0)); // Updates tmpReg 2688 masm.jcc(Assembler::equal, DONE_LABEL); 2689 2690 // Recursive locking 2691 masm.subptr(tmpReg, rsp); 2692 masm.andptr(tmpReg, 7 - os::vm_page_size()); 2693 masm.movptr(Address(boxReg, 0), tmpReg); 2694 2695 masm.bind(DONE_LABEL); 2696 masm.nop(); // avoid branch to branch 2697 } else { 2698 Label DONE_LABEL, IsInflated, Egress; 2699 2700 masm.movptr(tmpReg, Address(objReg, 0)) ; 2701 masm.testl (tmpReg, 0x02) ; // inflated vs stack-locked|neutral|biased 2702 masm.jcc (Assembler::notZero, IsInflated) ; 2703 2704 // it's stack-locked, biased or neutral 2705 // TODO: optimize markword triage order to reduce the number of 2706 // conditional branches in the most common cases. 2707 // Beware -- there's a subtle invariant that fetch of the markword 2708 // at [FETCH], below, will never observe a biased encoding (*101b). 2709 // If this invariant is not held we'll suffer exclusion (safety) failure. 2710 2711 if (UseBiasedLocking && !UseOptoBiasInlining) { 2712 masm.biased_locking_enter(boxReg, objReg, tmpReg, scrReg, true, DONE_LABEL, NULL, _counters); 2713 masm.movptr(tmpReg, Address(objReg, 0)) ; // [FETCH] 2714 } 2715 2716 // was q will it destroy high? 2717 masm.orl (tmpReg, 1) ; 2718 masm.movptr(Address(boxReg, 0), tmpReg) ; 2719 if (os::is_MP()) { masm.lock(); } 2720 masm.cmpxchgptr(boxReg, Address(objReg, 0)); // Updates tmpReg 2721 if (_counters != NULL) { 2722 masm.cond_inc32(Assembler::equal, 2723 ExternalAddress((address) _counters->fast_path_entry_count_addr())); 2724 } 2725 masm.jcc (Assembler::equal, DONE_LABEL); 2726 2727 // Recursive locking 2728 masm.subptr(tmpReg, rsp); 2729 masm.andptr(tmpReg, 7 - os::vm_page_size()); 2730 masm.movptr(Address(boxReg, 0), tmpReg); 2731 if (_counters != NULL) { 2732 masm.cond_inc32(Assembler::equal, 2733 ExternalAddress((address) _counters->fast_path_entry_count_addr())); 2734 } 2735 masm.jmp (DONE_LABEL) ; 2736 2737 masm.bind (IsInflated) ; 2738 // It's inflated 2739 2740 // TODO: someday avoid the ST-before-CAS penalty by 2741 // relocating (deferring) the following ST. 2742 // We should also think about trying a CAS without having 2743 // fetched _owner. If the CAS is successful we may 2744 // avoid an RTO->RTS upgrade on the $line. 2745 // Without cast to int32_t a movptr will destroy r10 which is typically obj 2746 masm.movptr(Address(boxReg, 0), (int32_t)intptr_t(markOopDesc::unused_mark())) ; 2747 2748 masm.mov (boxReg, tmpReg) ; 2749 masm.movptr (tmpReg, Address(tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; 2750 masm.testptr(tmpReg, tmpReg) ; 2751 masm.jcc (Assembler::notZero, DONE_LABEL) ; 2752 2753 // It's inflated and appears unlocked 2754 if (os::is_MP()) { masm.lock(); } 2755 masm.cmpxchgptr(r15_thread, Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; 2756 // Intentional fall-through into DONE_LABEL ... 2757 2758 masm.bind (DONE_LABEL) ; 2759 masm.nop () ; // avoid jmp to jmp 2760 } 2761 %} 2762 2763 // obj: object to unlock 2764 // box: box address (displaced header location), killed 2765 // RBX: killed tmp; cannot be obj nor box 2766 enc_class Fast_Unlock(rRegP obj, rax_RegP box, rRegP tmp) 2767 %{ 2768 2769 Register objReg = as_Register($obj$$reg); 2770 Register boxReg = as_Register($box$$reg); 2771 Register tmpReg = as_Register($tmp$$reg); 2772 MacroAssembler masm(&cbuf); 2773 2774 if (EmitSync & 4) { 2775 masm.cmpptr(rsp, 0) ; 2776 } else 2777 if (EmitSync & 8) { 2778 Label DONE_LABEL; 2779 if (UseBiasedLocking) { 2780 masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL); 2781 } 2782 2783 // Check whether the displaced header is 0 2784 //(=> recursive unlock) 2785 masm.movptr(tmpReg, Address(boxReg, 0)); 2786 masm.testptr(tmpReg, tmpReg); 2787 masm.jcc(Assembler::zero, DONE_LABEL); 2788 2789 // If not recursive lock, reset the header to displaced header 2790 if (os::is_MP()) { 2791 masm.lock(); 2792 } 2793 masm.cmpxchgptr(tmpReg, Address(objReg, 0)); // Uses RAX which is box 2794 masm.bind(DONE_LABEL); 2795 masm.nop(); // avoid branch to branch 2796 } else { 2797 Label DONE_LABEL, Stacked, CheckSucc ; 2798 2799 if (UseBiasedLocking && !UseOptoBiasInlining) { 2800 masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL); 2801 } 2802 2803 masm.movptr(tmpReg, Address(objReg, 0)) ; 2804 masm.cmpptr(Address(boxReg, 0), (int32_t)NULL_WORD) ; 2805 masm.jcc (Assembler::zero, DONE_LABEL) ; 2806 masm.testl (tmpReg, 0x02) ; 2807 masm.jcc (Assembler::zero, Stacked) ; 2808 2809 // It's inflated 2810 masm.movptr(boxReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; 2811 masm.xorptr(boxReg, r15_thread) ; 2812 masm.orptr (boxReg, Address (tmpReg, ObjectMonitor::recursions_offset_in_bytes()-2)) ; 2813 masm.jcc (Assembler::notZero, DONE_LABEL) ; 2814 masm.movptr(boxReg, Address (tmpReg, ObjectMonitor::cxq_offset_in_bytes()-2)) ; 2815 masm.orptr (boxReg, Address (tmpReg, ObjectMonitor::EntryList_offset_in_bytes()-2)) ; 2816 masm.jcc (Assembler::notZero, CheckSucc) ; 2817 masm.movptr(Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), (int32_t)NULL_WORD) ; 2818 masm.jmp (DONE_LABEL) ; 2819 2820 if ((EmitSync & 65536) == 0) { 2821 Label LSuccess, LGoSlowPath ; 2822 masm.bind (CheckSucc) ; 2823 masm.cmpptr(Address (tmpReg, ObjectMonitor::succ_offset_in_bytes()-2), (int32_t)NULL_WORD) ; 2824 masm.jcc (Assembler::zero, LGoSlowPath) ; 2825 2826 // I'd much rather use lock:andl m->_owner, 0 as it's faster than the 2827 // the explicit ST;MEMBAR combination, but masm doesn't currently support 2828 // "ANDQ M,IMM". Don't use MFENCE here. lock:add to TOS, xchg, etc 2829 // are all faster when the write buffer is populated. 2830 masm.movptr (Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), (int32_t)NULL_WORD) ; 2831 if (os::is_MP()) { 2832 masm.lock () ; masm.addl (Address(rsp, 0), 0) ; 2833 } 2834 masm.cmpptr(Address (tmpReg, ObjectMonitor::succ_offset_in_bytes()-2), (int32_t)NULL_WORD) ; 2835 masm.jcc (Assembler::notZero, LSuccess) ; 2836 2837 masm.movptr (boxReg, (int32_t)NULL_WORD) ; // box is really EAX 2838 if (os::is_MP()) { masm.lock(); } 2839 masm.cmpxchgptr(r15_thread, Address(tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)); 2840 masm.jcc (Assembler::notEqual, LSuccess) ; 2841 // Intentional fall-through into slow-path 2842 2843 masm.bind (LGoSlowPath) ; 2844 masm.orl (boxReg, 1) ; // set ICC.ZF=0 to indicate failure 2845 masm.jmp (DONE_LABEL) ; 2846 2847 masm.bind (LSuccess) ; 2848 masm.testl (boxReg, 0) ; // set ICC.ZF=1 to indicate success 2849 masm.jmp (DONE_LABEL) ; 2850 } 2851 2852 masm.bind (Stacked) ; 2853 masm.movptr(tmpReg, Address (boxReg, 0)) ; // re-fetch 2854 if (os::is_MP()) { masm.lock(); } 2855 masm.cmpxchgptr(tmpReg, Address(objReg, 0)); // Uses RAX which is box 2856 2857 if (EmitSync & 65536) { 2858 masm.bind (CheckSucc) ; 2859 } 2860 masm.bind(DONE_LABEL); 2861 if (EmitSync & 32768) { 2862 masm.nop(); // avoid branch to branch 2863 } 2864 } 2865 %} 2866 2867 2868 enc_class enc_rethrow() 2869 %{ 2870 cbuf.set_insts_mark(); 2871 emit_opcode(cbuf, 0xE9); // jmp entry 2872 emit_d32_reloc(cbuf, 2873 (int) (OptoRuntime::rethrow_stub() - cbuf.insts_end() - 4), 2874 runtime_call_Relocation::spec(), 2875 RELOC_DISP32); 2876 %} 2877 2878%} 2879 2880 2881 2882//----------FRAME-------------------------------------------------------------- 2883// Definition of frame structure and management information. 2884// 2885// S T A C K L A Y O U T Allocators stack-slot number 2886// | (to get allocators register number 2887// G Owned by | | v add OptoReg::stack0()) 2888// r CALLER | | 2889// o | +--------+ pad to even-align allocators stack-slot 2890// w V | pad0 | numbers; owned by CALLER 2891// t -----------+--------+----> Matcher::_in_arg_limit, unaligned 2892// h ^ | in | 5 2893// | | args | 4 Holes in incoming args owned by SELF 2894// | | | | 3 2895// | | +--------+ 2896// V | | old out| Empty on Intel, window on Sparc 2897// | old |preserve| Must be even aligned. 2898// | SP-+--------+----> Matcher::_old_SP, even aligned 2899// | | in | 3 area for Intel ret address 2900// Owned by |preserve| Empty on Sparc. 2901// SELF +--------+ 2902// | | pad2 | 2 pad to align old SP 2903// | +--------+ 1 2904// | | locks | 0 2905// | +--------+----> OptoReg::stack0(), even aligned 2906// | | pad1 | 11 pad to align new SP 2907// | +--------+ 2908// | | | 10 2909// | | spills | 9 spills 2910// V | | 8 (pad0 slot for callee) 2911// -----------+--------+----> Matcher::_out_arg_limit, unaligned 2912// ^ | out | 7 2913// | | args | 6 Holes in outgoing args owned by CALLEE 2914// Owned by +--------+ 2915// CALLEE | new out| 6 Empty on Intel, window on Sparc 2916// | new |preserve| Must be even-aligned. 2917// | SP-+--------+----> Matcher::_new_SP, even aligned 2918// | | | 2919// 2920// Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 2921// known from SELF's arguments and the Java calling convention. 2922// Region 6-7 is determined per call site. 2923// Note 2: If the calling convention leaves holes in the incoming argument 2924// area, those holes are owned by SELF. Holes in the outgoing area 2925// are owned by the CALLEE. Holes should not be nessecary in the 2926// incoming area, as the Java calling convention is completely under 2927// the control of the AD file. Doubles can be sorted and packed to 2928// avoid holes. Holes in the outgoing arguments may be nessecary for 2929// varargs C calling conventions. 2930// Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 2931// even aligned with pad0 as needed. 2932// Region 6 is even aligned. Region 6-7 is NOT even aligned; 2933// region 6-11 is even aligned; it may be padded out more so that 2934// the region from SP to FP meets the minimum stack alignment. 2935// Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 2936// alignment. Region 11, pad1, may be dynamically extended so that 2937// SP meets the minimum alignment. 2938 2939frame 2940%{ 2941 // What direction does stack grow in (assumed to be same for C & Java) 2942 stack_direction(TOWARDS_LOW); 2943 2944 // These three registers define part of the calling convention 2945 // between compiled code and the interpreter. 2946 inline_cache_reg(RAX); // Inline Cache Register 2947 interpreter_method_oop_reg(RBX); // Method Oop Register when 2948 // calling interpreter 2949 2950 // Optional: name the operand used by cisc-spilling to access 2951 // [stack_pointer + offset] 2952 cisc_spilling_operand_name(indOffset32); 2953 2954 // Number of stack slots consumed by locking an object 2955 sync_stack_slots(2); 2956 2957 // Compiled code's Frame Pointer 2958 frame_pointer(RSP); 2959 2960 // Interpreter stores its frame pointer in a register which is 2961 // stored to the stack by I2CAdaptors. 2962 // I2CAdaptors convert from interpreted java to compiled java. 2963 interpreter_frame_pointer(RBP); 2964 2965 // Stack alignment requirement 2966 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 2967 2968 // Number of stack slots between incoming argument block and the start of 2969 // a new frame. The PROLOG must add this many slots to the stack. The 2970 // EPILOG must remove this many slots. amd64 needs two slots for 2971 // return address. 2972 in_preserve_stack_slots(4 + 2 * VerifyStackAtCalls); 2973 2974 // Number of outgoing stack slots killed above the out_preserve_stack_slots 2975 // for calls to C. Supports the var-args backing area for register parms. 2976 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 2977 2978 // The after-PROLOG location of the return address. Location of 2979 // return address specifies a type (REG or STACK) and a number 2980 // representing the register number (i.e. - use a register name) or 2981 // stack slot. 2982 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 2983 // Otherwise, it is above the locks and verification slot and alignment word 2984 return_addr(STACK - 2 + 2985 round_to((Compile::current()->in_preserve_stack_slots() + 2986 Compile::current()->fixed_slots()), 2987 stack_alignment_in_slots())); 2988 2989 // Body of function which returns an integer array locating 2990 // arguments either in registers or in stack slots. Passed an array 2991 // of ideal registers called "sig" and a "length" count. Stack-slot 2992 // offsets are based on outgoing arguments, i.e. a CALLER setting up 2993 // arguments for a CALLEE. Incoming stack arguments are 2994 // automatically biased by the preserve_stack_slots field above. 2995 2996 calling_convention 2997 %{ 2998 // No difference between ingoing/outgoing just pass false 2999 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 3000 %} 3001 3002 c_calling_convention 3003 %{ 3004 // This is obviously always outgoing 3005 (void) SharedRuntime::c_calling_convention(sig_bt, regs, length); 3006 %} 3007 3008 // Location of compiled Java return values. Same as C for now. 3009 return_value 3010 %{ 3011 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 3012 "only return normal values"); 3013 3014 static const int lo[Op_RegL + 1] = { 3015 0, 3016 0, 3017 RAX_num, // Op_RegN 3018 RAX_num, // Op_RegI 3019 RAX_num, // Op_RegP 3020 XMM0_num, // Op_RegF 3021 XMM0_num, // Op_RegD 3022 RAX_num // Op_RegL 3023 }; 3024 static const int hi[Op_RegL + 1] = { 3025 0, 3026 0, 3027 OptoReg::Bad, // Op_RegN 3028 OptoReg::Bad, // Op_RegI 3029 RAX_H_num, // Op_RegP 3030 OptoReg::Bad, // Op_RegF 3031 XMM0b_num, // Op_RegD 3032 RAX_H_num // Op_RegL 3033 }; 3034 // Excluded flags and vector registers. 3035 assert(ARRAY_SIZE(hi) == _last_machine_leaf - 5, "missing type"); 3036 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 3037 %} 3038%} 3039 3040//----------ATTRIBUTES--------------------------------------------------------- 3041//----------Operand Attributes------------------------------------------------- 3042op_attrib op_cost(0); // Required cost attribute 3043 3044//----------Instruction Attributes--------------------------------------------- 3045ins_attrib ins_cost(100); // Required cost attribute 3046ins_attrib ins_size(8); // Required size attribute (in bits) 3047ins_attrib ins_short_branch(0); // Required flag: is this instruction 3048 // a non-matching short branch variant 3049 // of some long branch? 3050ins_attrib ins_alignment(1); // Required alignment attribute (must 3051 // be a power of 2) specifies the 3052 // alignment that some part of the 3053 // instruction (not necessarily the 3054 // start) requires. If > 1, a 3055 // compute_padding() function must be 3056 // provided for the instruction 3057 3058//----------OPERANDS----------------------------------------------------------- 3059// Operand definitions must precede instruction definitions for correct parsing 3060// in the ADLC because operands constitute user defined types which are used in 3061// instruction definitions. 3062 3063//----------Simple Operands---------------------------------------------------- 3064// Immediate Operands 3065// Integer Immediate 3066operand immI() 3067%{ 3068 match(ConI); 3069 3070 op_cost(10); 3071 format %{ %} 3072 interface(CONST_INTER); 3073%} 3074 3075// Constant for test vs zero 3076operand immI0() 3077%{ 3078 predicate(n->get_int() == 0); 3079 match(ConI); 3080 3081 op_cost(0); 3082 format %{ %} 3083 interface(CONST_INTER); 3084%} 3085 3086// Constant for increment 3087operand immI1() 3088%{ 3089 predicate(n->get_int() == 1); 3090 match(ConI); 3091 3092 op_cost(0); 3093 format %{ %} 3094 interface(CONST_INTER); 3095%} 3096 3097// Constant for decrement 3098operand immI_M1() 3099%{ 3100 predicate(n->get_int() == -1); 3101 match(ConI); 3102 3103 op_cost(0); 3104 format %{ %} 3105 interface(CONST_INTER); 3106%} 3107 3108// Valid scale values for addressing modes 3109operand immI2() 3110%{ 3111 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 3112 match(ConI); 3113 3114 format %{ %} 3115 interface(CONST_INTER); 3116%} 3117 3118operand immI8() 3119%{ 3120 predicate((-0x80 <= n->get_int()) && (n->get_int() < 0x80)); 3121 match(ConI); 3122 3123 op_cost(5); 3124 format %{ %} 3125 interface(CONST_INTER); 3126%} 3127 3128operand immI16() 3129%{ 3130 predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767)); 3131 match(ConI); 3132 3133 op_cost(10); 3134 format %{ %} 3135 interface(CONST_INTER); 3136%} 3137 3138// Constant for long shifts 3139operand immI_32() 3140%{ 3141 predicate( n->get_int() == 32 ); 3142 match(ConI); 3143 3144 op_cost(0); 3145 format %{ %} 3146 interface(CONST_INTER); 3147%} 3148 3149// Constant for long shifts 3150operand immI_64() 3151%{ 3152 predicate( n->get_int() == 64 ); 3153 match(ConI); 3154 3155 op_cost(0); 3156 format %{ %} 3157 interface(CONST_INTER); 3158%} 3159 3160// Pointer Immediate 3161operand immP() 3162%{ 3163 match(ConP); 3164 3165 op_cost(10); 3166 format %{ %} 3167 interface(CONST_INTER); 3168%} 3169 3170// NULL Pointer Immediate 3171operand immP0() 3172%{ 3173 predicate(n->get_ptr() == 0); 3174 match(ConP); 3175 3176 op_cost(5); 3177 format %{ %} 3178 interface(CONST_INTER); 3179%} 3180 3181// Pointer Immediate 3182operand immN() %{ 3183 match(ConN); 3184 3185 op_cost(10); 3186 format %{ %} 3187 interface(CONST_INTER); 3188%} 3189 3190operand immNKlass() %{ 3191 match(ConNKlass); 3192 3193 op_cost(10); 3194 format %{ %} 3195 interface(CONST_INTER); 3196%} 3197 3198// NULL Pointer Immediate 3199operand immN0() %{ 3200 predicate(n->get_narrowcon() == 0); 3201 match(ConN); 3202 3203 op_cost(5); 3204 format %{ %} 3205 interface(CONST_INTER); 3206%} 3207 3208operand immP31() 3209%{ 3210 predicate(n->as_Type()->type()->reloc() == relocInfo::none 3211 && (n->get_ptr() >> 31) == 0); 3212 match(ConP); 3213 3214 op_cost(5); 3215 format %{ %} 3216 interface(CONST_INTER); 3217%} 3218 3219 3220// Long Immediate 3221operand immL() 3222%{ 3223 match(ConL); 3224 3225 op_cost(20); 3226 format %{ %} 3227 interface(CONST_INTER); 3228%} 3229 3230// Long Immediate 8-bit 3231operand immL8() 3232%{ 3233 predicate(-0x80L <= n->get_long() && n->get_long() < 0x80L); 3234 match(ConL); 3235 3236 op_cost(5); 3237 format %{ %} 3238 interface(CONST_INTER); 3239%} 3240 3241// Long Immediate 32-bit unsigned 3242operand immUL32() 3243%{ 3244 predicate(n->get_long() == (unsigned int) (n->get_long())); 3245 match(ConL); 3246 3247 op_cost(10); 3248 format %{ %} 3249 interface(CONST_INTER); 3250%} 3251 3252// Long Immediate 32-bit signed 3253operand immL32() 3254%{ 3255 predicate(n->get_long() == (int) (n->get_long())); 3256 match(ConL); 3257 3258 op_cost(15); 3259 format %{ %} 3260 interface(CONST_INTER); 3261%} 3262 3263// Long Immediate zero 3264operand immL0() 3265%{ 3266 predicate(n->get_long() == 0L); 3267 match(ConL); 3268 3269 op_cost(10); 3270 format %{ %} 3271 interface(CONST_INTER); 3272%} 3273 3274// Constant for increment 3275operand immL1() 3276%{ 3277 predicate(n->get_long() == 1); 3278 match(ConL); 3279 3280 format %{ %} 3281 interface(CONST_INTER); 3282%} 3283 3284// Constant for decrement 3285operand immL_M1() 3286%{ 3287 predicate(n->get_long() == -1); 3288 match(ConL); 3289 3290 format %{ %} 3291 interface(CONST_INTER); 3292%} 3293 3294// Long Immediate: the value 10 3295operand immL10() 3296%{ 3297 predicate(n->get_long() == 10); 3298 match(ConL); 3299 3300 format %{ %} 3301 interface(CONST_INTER); 3302%} 3303 3304// Long immediate from 0 to 127. 3305// Used for a shorter form of long mul by 10. 3306operand immL_127() 3307%{ 3308 predicate(0 <= n->get_long() && n->get_long() < 0x80); 3309 match(ConL); 3310 3311 op_cost(10); 3312 format %{ %} 3313 interface(CONST_INTER); 3314%} 3315 3316// Long Immediate: low 32-bit mask 3317operand immL_32bits() 3318%{ 3319 predicate(n->get_long() == 0xFFFFFFFFL); 3320 match(ConL); 3321 op_cost(20); 3322 3323 format %{ %} 3324 interface(CONST_INTER); 3325%} 3326 3327// Float Immediate zero 3328operand immF0() 3329%{ 3330 predicate(jint_cast(n->getf()) == 0); 3331 match(ConF); 3332 3333 op_cost(5); 3334 format %{ %} 3335 interface(CONST_INTER); 3336%} 3337 3338// Float Immediate 3339operand immF() 3340%{ 3341 match(ConF); 3342 3343 op_cost(15); 3344 format %{ %} 3345 interface(CONST_INTER); 3346%} 3347 3348// Double Immediate zero 3349operand immD0() 3350%{ 3351 predicate(jlong_cast(n->getd()) == 0); 3352 match(ConD); 3353 3354 op_cost(5); 3355 format %{ %} 3356 interface(CONST_INTER); 3357%} 3358 3359// Double Immediate 3360operand immD() 3361%{ 3362 match(ConD); 3363 3364 op_cost(15); 3365 format %{ %} 3366 interface(CONST_INTER); 3367%} 3368 3369// Immediates for special shifts (sign extend) 3370 3371// Constants for increment 3372operand immI_16() 3373%{ 3374 predicate(n->get_int() == 16); 3375 match(ConI); 3376 3377 format %{ %} 3378 interface(CONST_INTER); 3379%} 3380 3381operand immI_24() 3382%{ 3383 predicate(n->get_int() == 24); 3384 match(ConI); 3385 3386 format %{ %} 3387 interface(CONST_INTER); 3388%} 3389 3390// Constant for byte-wide masking 3391operand immI_255() 3392%{ 3393 predicate(n->get_int() == 255); 3394 match(ConI); 3395 3396 format %{ %} 3397 interface(CONST_INTER); 3398%} 3399 3400// Constant for short-wide masking 3401operand immI_65535() 3402%{ 3403 predicate(n->get_int() == 65535); 3404 match(ConI); 3405 3406 format %{ %} 3407 interface(CONST_INTER); 3408%} 3409 3410// Constant for byte-wide masking 3411operand immL_255() 3412%{ 3413 predicate(n->get_long() == 255); 3414 match(ConL); 3415 3416 format %{ %} 3417 interface(CONST_INTER); 3418%} 3419 3420// Constant for short-wide masking 3421operand immL_65535() 3422%{ 3423 predicate(n->get_long() == 65535); 3424 match(ConL); 3425 3426 format %{ %} 3427 interface(CONST_INTER); 3428%} 3429 3430// Register Operands 3431// Integer Register 3432operand rRegI() 3433%{ 3434 constraint(ALLOC_IN_RC(int_reg)); 3435 match(RegI); 3436 3437 match(rax_RegI); 3438 match(rbx_RegI); 3439 match(rcx_RegI); 3440 match(rdx_RegI); 3441 match(rdi_RegI); 3442 3443 format %{ %} 3444 interface(REG_INTER); 3445%} 3446 3447// Special Registers 3448operand rax_RegI() 3449%{ 3450 constraint(ALLOC_IN_RC(int_rax_reg)); 3451 match(RegI); 3452 match(rRegI); 3453 3454 format %{ "RAX" %} 3455 interface(REG_INTER); 3456%} 3457 3458// Special Registers 3459operand rbx_RegI() 3460%{ 3461 constraint(ALLOC_IN_RC(int_rbx_reg)); 3462 match(RegI); 3463 match(rRegI); 3464 3465 format %{ "RBX" %} 3466 interface(REG_INTER); 3467%} 3468 3469operand rcx_RegI() 3470%{ 3471 constraint(ALLOC_IN_RC(int_rcx_reg)); 3472 match(RegI); 3473 match(rRegI); 3474 3475 format %{ "RCX" %} 3476 interface(REG_INTER); 3477%} 3478 3479operand rdx_RegI() 3480%{ 3481 constraint(ALLOC_IN_RC(int_rdx_reg)); 3482 match(RegI); 3483 match(rRegI); 3484 3485 format %{ "RDX" %} 3486 interface(REG_INTER); 3487%} 3488 3489operand rdi_RegI() 3490%{ 3491 constraint(ALLOC_IN_RC(int_rdi_reg)); 3492 match(RegI); 3493 match(rRegI); 3494 3495 format %{ "RDI" %} 3496 interface(REG_INTER); 3497%} 3498 3499operand no_rcx_RegI() 3500%{ 3501 constraint(ALLOC_IN_RC(int_no_rcx_reg)); 3502 match(RegI); 3503 match(rax_RegI); 3504 match(rbx_RegI); 3505 match(rdx_RegI); 3506 match(rdi_RegI); 3507 3508 format %{ %} 3509 interface(REG_INTER); 3510%} 3511 3512operand no_rax_rdx_RegI() 3513%{ 3514 constraint(ALLOC_IN_RC(int_no_rax_rdx_reg)); 3515 match(RegI); 3516 match(rbx_RegI); 3517 match(rcx_RegI); 3518 match(rdi_RegI); 3519 3520 format %{ %} 3521 interface(REG_INTER); 3522%} 3523 3524// Pointer Register 3525operand any_RegP() 3526%{ 3527 constraint(ALLOC_IN_RC(any_reg)); 3528 match(RegP); 3529 match(rax_RegP); 3530 match(rbx_RegP); 3531 match(rdi_RegP); 3532 match(rsi_RegP); 3533 match(rbp_RegP); 3534 match(r15_RegP); 3535 match(rRegP); 3536 3537 format %{ %} 3538 interface(REG_INTER); 3539%} 3540 3541operand rRegP() 3542%{ 3543 constraint(ALLOC_IN_RC(ptr_reg)); 3544 match(RegP); 3545 match(rax_RegP); 3546 match(rbx_RegP); 3547 match(rdi_RegP); 3548 match(rsi_RegP); 3549 match(rbp_RegP); 3550 match(r15_RegP); // See Q&A below about r15_RegP. 3551 3552 format %{ %} 3553 interface(REG_INTER); 3554%} 3555 3556operand rRegN() %{ 3557 constraint(ALLOC_IN_RC(int_reg)); 3558 match(RegN); 3559 3560 format %{ %} 3561 interface(REG_INTER); 3562%} 3563 3564// Question: Why is r15_RegP (the read-only TLS register) a match for rRegP? 3565// Answer: Operand match rules govern the DFA as it processes instruction inputs. 3566// It's fine for an instruction input which expects rRegP to match a r15_RegP. 3567// The output of an instruction is controlled by the allocator, which respects 3568// register class masks, not match rules. Unless an instruction mentions 3569// r15_RegP or any_RegP explicitly as its output, r15 will not be considered 3570// by the allocator as an input. 3571 3572operand no_rax_RegP() 3573%{ 3574 constraint(ALLOC_IN_RC(ptr_no_rax_reg)); 3575 match(RegP); 3576 match(rbx_RegP); 3577 match(rsi_RegP); 3578 match(rdi_RegP); 3579 3580 format %{ %} 3581 interface(REG_INTER); 3582%} 3583 3584operand no_rbp_RegP() 3585%{ 3586 constraint(ALLOC_IN_RC(ptr_no_rbp_reg)); 3587 match(RegP); 3588 match(rbx_RegP); 3589 match(rsi_RegP); 3590 match(rdi_RegP); 3591 3592 format %{ %} 3593 interface(REG_INTER); 3594%} 3595 3596operand no_rax_rbx_RegP() 3597%{ 3598 constraint(ALLOC_IN_RC(ptr_no_rax_rbx_reg)); 3599 match(RegP); 3600 match(rsi_RegP); 3601 match(rdi_RegP); 3602 3603 format %{ %} 3604 interface(REG_INTER); 3605%} 3606 3607// Special Registers 3608// Return a pointer value 3609operand rax_RegP() 3610%{ 3611 constraint(ALLOC_IN_RC(ptr_rax_reg)); 3612 match(RegP); 3613 match(rRegP); 3614 3615 format %{ %} 3616 interface(REG_INTER); 3617%} 3618 3619// Special Registers 3620// Return a compressed pointer value 3621operand rax_RegN() 3622%{ 3623 constraint(ALLOC_IN_RC(int_rax_reg)); 3624 match(RegN); 3625 match(rRegN); 3626 3627 format %{ %} 3628 interface(REG_INTER); 3629%} 3630 3631// Used in AtomicAdd 3632operand rbx_RegP() 3633%{ 3634 constraint(ALLOC_IN_RC(ptr_rbx_reg)); 3635 match(RegP); 3636 match(rRegP); 3637 3638 format %{ %} 3639 interface(REG_INTER); 3640%} 3641 3642operand rsi_RegP() 3643%{ 3644 constraint(ALLOC_IN_RC(ptr_rsi_reg)); 3645 match(RegP); 3646 match(rRegP); 3647 3648 format %{ %} 3649 interface(REG_INTER); 3650%} 3651 3652// Used in rep stosq 3653operand rdi_RegP() 3654%{ 3655 constraint(ALLOC_IN_RC(ptr_rdi_reg)); 3656 match(RegP); 3657 match(rRegP); 3658 3659 format %{ %} 3660 interface(REG_INTER); 3661%} 3662 3663operand rbp_RegP() 3664%{ 3665 constraint(ALLOC_IN_RC(ptr_rbp_reg)); 3666 match(RegP); 3667 match(rRegP); 3668 3669 format %{ %} 3670 interface(REG_INTER); 3671%} 3672 3673operand r15_RegP() 3674%{ 3675 constraint(ALLOC_IN_RC(ptr_r15_reg)); 3676 match(RegP); 3677 match(rRegP); 3678 3679 format %{ %} 3680 interface(REG_INTER); 3681%} 3682 3683operand rRegL() 3684%{ 3685 constraint(ALLOC_IN_RC(long_reg)); 3686 match(RegL); 3687 match(rax_RegL); 3688 match(rdx_RegL); 3689 3690 format %{ %} 3691 interface(REG_INTER); 3692%} 3693 3694// Special Registers 3695operand no_rax_rdx_RegL() 3696%{ 3697 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 3698 match(RegL); 3699 match(rRegL); 3700 3701 format %{ %} 3702 interface(REG_INTER); 3703%} 3704 3705operand no_rax_RegL() 3706%{ 3707 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 3708 match(RegL); 3709 match(rRegL); 3710 match(rdx_RegL); 3711 3712 format %{ %} 3713 interface(REG_INTER); 3714%} 3715 3716operand no_rcx_RegL() 3717%{ 3718 constraint(ALLOC_IN_RC(long_no_rcx_reg)); 3719 match(RegL); 3720 match(rRegL); 3721 3722 format %{ %} 3723 interface(REG_INTER); 3724%} 3725 3726operand rax_RegL() 3727%{ 3728 constraint(ALLOC_IN_RC(long_rax_reg)); 3729 match(RegL); 3730 match(rRegL); 3731 3732 format %{ "RAX" %} 3733 interface(REG_INTER); 3734%} 3735 3736operand rcx_RegL() 3737%{ 3738 constraint(ALLOC_IN_RC(long_rcx_reg)); 3739 match(RegL); 3740 match(rRegL); 3741 3742 format %{ %} 3743 interface(REG_INTER); 3744%} 3745 3746operand rdx_RegL() 3747%{ 3748 constraint(ALLOC_IN_RC(long_rdx_reg)); 3749 match(RegL); 3750 match(rRegL); 3751 3752 format %{ %} 3753 interface(REG_INTER); 3754%} 3755 3756// Flags register, used as output of compare instructions 3757operand rFlagsReg() 3758%{ 3759 constraint(ALLOC_IN_RC(int_flags)); 3760 match(RegFlags); 3761 3762 format %{ "RFLAGS" %} 3763 interface(REG_INTER); 3764%} 3765 3766// Flags register, used as output of FLOATING POINT compare instructions 3767operand rFlagsRegU() 3768%{ 3769 constraint(ALLOC_IN_RC(int_flags)); 3770 match(RegFlags); 3771 3772 format %{ "RFLAGS_U" %} 3773 interface(REG_INTER); 3774%} 3775 3776operand rFlagsRegUCF() %{ 3777 constraint(ALLOC_IN_RC(int_flags)); 3778 match(RegFlags); 3779 predicate(false); 3780 3781 format %{ "RFLAGS_U_CF" %} 3782 interface(REG_INTER); 3783%} 3784 3785// Float register operands 3786operand regF() 3787%{ 3788 constraint(ALLOC_IN_RC(float_reg)); 3789 match(RegF); 3790 3791 format %{ %} 3792 interface(REG_INTER); 3793%} 3794 3795// Double register operands 3796operand regD() 3797%{ 3798 constraint(ALLOC_IN_RC(double_reg)); 3799 match(RegD); 3800 3801 format %{ %} 3802 interface(REG_INTER); 3803%} 3804 3805//----------Memory Operands---------------------------------------------------- 3806// Direct Memory Operand 3807// operand direct(immP addr) 3808// %{ 3809// match(addr); 3810 3811// format %{ "[$addr]" %} 3812// interface(MEMORY_INTER) %{ 3813// base(0xFFFFFFFF); 3814// index(0x4); 3815// scale(0x0); 3816// disp($addr); 3817// %} 3818// %} 3819 3820// Indirect Memory Operand 3821operand indirect(any_RegP reg) 3822%{ 3823 constraint(ALLOC_IN_RC(ptr_reg)); 3824 match(reg); 3825 3826 format %{ "[$reg]" %} 3827 interface(MEMORY_INTER) %{ 3828 base($reg); 3829 index(0x4); 3830 scale(0x0); 3831 disp(0x0); 3832 %} 3833%} 3834 3835// Indirect Memory Plus Short Offset Operand 3836operand indOffset8(any_RegP reg, immL8 off) 3837%{ 3838 constraint(ALLOC_IN_RC(ptr_reg)); 3839 match(AddP reg off); 3840 3841 format %{ "[$reg + $off (8-bit)]" %} 3842 interface(MEMORY_INTER) %{ 3843 base($reg); 3844 index(0x4); 3845 scale(0x0); 3846 disp($off); 3847 %} 3848%} 3849 3850// Indirect Memory Plus Long Offset Operand 3851operand indOffset32(any_RegP reg, immL32 off) 3852%{ 3853 constraint(ALLOC_IN_RC(ptr_reg)); 3854 match(AddP reg off); 3855 3856 format %{ "[$reg + $off (32-bit)]" %} 3857 interface(MEMORY_INTER) %{ 3858 base($reg); 3859 index(0x4); 3860 scale(0x0); 3861 disp($off); 3862 %} 3863%} 3864 3865// Indirect Memory Plus Index Register Plus Offset Operand 3866operand indIndexOffset(any_RegP reg, rRegL lreg, immL32 off) 3867%{ 3868 constraint(ALLOC_IN_RC(ptr_reg)); 3869 match(AddP (AddP reg lreg) off); 3870 3871 op_cost(10); 3872 format %{"[$reg + $off + $lreg]" %} 3873 interface(MEMORY_INTER) %{ 3874 base($reg); 3875 index($lreg); 3876 scale(0x0); 3877 disp($off); 3878 %} 3879%} 3880 3881// Indirect Memory Plus Index Register Plus Offset Operand 3882operand indIndex(any_RegP reg, rRegL lreg) 3883%{ 3884 constraint(ALLOC_IN_RC(ptr_reg)); 3885 match(AddP reg lreg); 3886 3887 op_cost(10); 3888 format %{"[$reg + $lreg]" %} 3889 interface(MEMORY_INTER) %{ 3890 base($reg); 3891 index($lreg); 3892 scale(0x0); 3893 disp(0x0); 3894 %} 3895%} 3896 3897// Indirect Memory Times Scale Plus Index Register 3898operand indIndexScale(any_RegP reg, rRegL lreg, immI2 scale) 3899%{ 3900 constraint(ALLOC_IN_RC(ptr_reg)); 3901 match(AddP reg (LShiftL lreg scale)); 3902 3903 op_cost(10); 3904 format %{"[$reg + $lreg << $scale]" %} 3905 interface(MEMORY_INTER) %{ 3906 base($reg); 3907 index($lreg); 3908 scale($scale); 3909 disp(0x0); 3910 %} 3911%} 3912 3913// Indirect Memory Times Scale Plus Index Register Plus Offset Operand 3914operand indIndexScaleOffset(any_RegP reg, immL32 off, rRegL lreg, immI2 scale) 3915%{ 3916 constraint(ALLOC_IN_RC(ptr_reg)); 3917 match(AddP (AddP reg (LShiftL lreg scale)) off); 3918 3919 op_cost(10); 3920 format %{"[$reg + $off + $lreg << $scale]" %} 3921 interface(MEMORY_INTER) %{ 3922 base($reg); 3923 index($lreg); 3924 scale($scale); 3925 disp($off); 3926 %} 3927%} 3928 3929// Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 3930operand indPosIndexScaleOffset(any_RegP reg, immL32 off, rRegI idx, immI2 scale) 3931%{ 3932 constraint(ALLOC_IN_RC(ptr_reg)); 3933 predicate(n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3934 match(AddP (AddP reg (LShiftL (ConvI2L idx) scale)) off); 3935 3936 op_cost(10); 3937 format %{"[$reg + $off + $idx << $scale]" %} 3938 interface(MEMORY_INTER) %{ 3939 base($reg); 3940 index($idx); 3941 scale($scale); 3942 disp($off); 3943 %} 3944%} 3945 3946// Indirect Narrow Oop Plus Offset Operand 3947// Note: x86 architecture doesn't support "scale * index + offset" without a base 3948// we can't free r12 even with Universe::narrow_oop_base() == NULL. 3949operand indCompressedOopOffset(rRegN reg, immL32 off) %{ 3950 predicate(UseCompressedOops && (Universe::narrow_oop_shift() == Address::times_8)); 3951 constraint(ALLOC_IN_RC(ptr_reg)); 3952 match(AddP (DecodeN reg) off); 3953 3954 op_cost(10); 3955 format %{"[R12 + $reg << 3 + $off] (compressed oop addressing)" %} 3956 interface(MEMORY_INTER) %{ 3957 base(0xc); // R12 3958 index($reg); 3959 scale(0x3); 3960 disp($off); 3961 %} 3962%} 3963 3964// Indirect Memory Operand 3965operand indirectNarrow(rRegN reg) 3966%{ 3967 predicate(Universe::narrow_oop_shift() == 0); 3968 constraint(ALLOC_IN_RC(ptr_reg)); 3969 match(DecodeN reg); 3970 3971 format %{ "[$reg]" %} 3972 interface(MEMORY_INTER) %{ 3973 base($reg); 3974 index(0x4); 3975 scale(0x0); 3976 disp(0x0); 3977 %} 3978%} 3979 3980// Indirect Memory Plus Short Offset Operand 3981operand indOffset8Narrow(rRegN reg, immL8 off) 3982%{ 3983 predicate(Universe::narrow_oop_shift() == 0); 3984 constraint(ALLOC_IN_RC(ptr_reg)); 3985 match(AddP (DecodeN reg) off); 3986 3987 format %{ "[$reg + $off (8-bit)]" %} 3988 interface(MEMORY_INTER) %{ 3989 base($reg); 3990 index(0x4); 3991 scale(0x0); 3992 disp($off); 3993 %} 3994%} 3995 3996// Indirect Memory Plus Long Offset Operand 3997operand indOffset32Narrow(rRegN reg, immL32 off) 3998%{ 3999 predicate(Universe::narrow_oop_shift() == 0); 4000 constraint(ALLOC_IN_RC(ptr_reg)); 4001 match(AddP (DecodeN reg) off); 4002 4003 format %{ "[$reg + $off (32-bit)]" %} 4004 interface(MEMORY_INTER) %{ 4005 base($reg); 4006 index(0x4); 4007 scale(0x0); 4008 disp($off); 4009 %} 4010%} 4011 4012// Indirect Memory Plus Index Register Plus Offset Operand 4013operand indIndexOffsetNarrow(rRegN reg, rRegL lreg, immL32 off) 4014%{ 4015 predicate(Universe::narrow_oop_shift() == 0); 4016 constraint(ALLOC_IN_RC(ptr_reg)); 4017 match(AddP (AddP (DecodeN reg) lreg) off); 4018 4019 op_cost(10); 4020 format %{"[$reg + $off + $lreg]" %} 4021 interface(MEMORY_INTER) %{ 4022 base($reg); 4023 index($lreg); 4024 scale(0x0); 4025 disp($off); 4026 %} 4027%} 4028 4029// Indirect Memory Plus Index Register Plus Offset Operand 4030operand indIndexNarrow(rRegN reg, rRegL lreg) 4031%{ 4032 predicate(Universe::narrow_oop_shift() == 0); 4033 constraint(ALLOC_IN_RC(ptr_reg)); 4034 match(AddP (DecodeN reg) lreg); 4035 4036 op_cost(10); 4037 format %{"[$reg + $lreg]" %} 4038 interface(MEMORY_INTER) %{ 4039 base($reg); 4040 index($lreg); 4041 scale(0x0); 4042 disp(0x0); 4043 %} 4044%} 4045 4046// Indirect Memory Times Scale Plus Index Register 4047operand indIndexScaleNarrow(rRegN reg, rRegL lreg, immI2 scale) 4048%{ 4049 predicate(Universe::narrow_oop_shift() == 0); 4050 constraint(ALLOC_IN_RC(ptr_reg)); 4051 match(AddP (DecodeN reg) (LShiftL lreg scale)); 4052 4053 op_cost(10); 4054 format %{"[$reg + $lreg << $scale]" %} 4055 interface(MEMORY_INTER) %{ 4056 base($reg); 4057 index($lreg); 4058 scale($scale); 4059 disp(0x0); 4060 %} 4061%} 4062 4063// Indirect Memory Times Scale Plus Index Register Plus Offset Operand 4064operand indIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegL lreg, immI2 scale) 4065%{ 4066 predicate(Universe::narrow_oop_shift() == 0); 4067 constraint(ALLOC_IN_RC(ptr_reg)); 4068 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off); 4069 4070 op_cost(10); 4071 format %{"[$reg + $off + $lreg << $scale]" %} 4072 interface(MEMORY_INTER) %{ 4073 base($reg); 4074 index($lreg); 4075 scale($scale); 4076 disp($off); 4077 %} 4078%} 4079 4080// Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 4081operand indPosIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegI idx, immI2 scale) 4082%{ 4083 constraint(ALLOC_IN_RC(ptr_reg)); 4084 predicate(Universe::narrow_oop_shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 4085 match(AddP (AddP (DecodeN reg) (LShiftL (ConvI2L idx) scale)) off); 4086 4087 op_cost(10); 4088 format %{"[$reg + $off + $idx << $scale]" %} 4089 interface(MEMORY_INTER) %{ 4090 base($reg); 4091 index($idx); 4092 scale($scale); 4093 disp($off); 4094 %} 4095%} 4096 4097operand indirectNarrowKlass(rRegN reg) 4098%{ 4099 predicate(Universe::narrow_klass_shift() == 0); 4100 constraint(ALLOC_IN_RC(ptr_reg)); 4101 match(DecodeNKlass reg); 4102 4103 format %{ "[$reg]" %} 4104 interface(MEMORY_INTER) %{ 4105 base($reg); 4106 index(0x4); 4107 scale(0x0); 4108 disp(0x0); 4109 %} 4110%} 4111 4112operand indOffset8NarrowKlass(rRegN reg, immL8 off) 4113%{ 4114 predicate(Universe::narrow_klass_shift() == 0); 4115 constraint(ALLOC_IN_RC(ptr_reg)); 4116 match(AddP (DecodeNKlass reg) off); 4117 4118 format %{ "[$reg + $off (8-bit)]" %} 4119 interface(MEMORY_INTER) %{ 4120 base($reg); 4121 index(0x4); 4122 scale(0x0); 4123 disp($off); 4124 %} 4125%} 4126 4127operand indOffset32NarrowKlass(rRegN reg, immL32 off) 4128%{ 4129 predicate(Universe::narrow_klass_shift() == 0); 4130 constraint(ALLOC_IN_RC(ptr_reg)); 4131 match(AddP (DecodeNKlass reg) off); 4132 4133 format %{ "[$reg + $off (32-bit)]" %} 4134 interface(MEMORY_INTER) %{ 4135 base($reg); 4136 index(0x4); 4137 scale(0x0); 4138 disp($off); 4139 %} 4140%} 4141 4142operand indIndexOffsetNarrowKlass(rRegN reg, rRegL lreg, immL32 off) 4143%{ 4144 predicate(Universe::narrow_klass_shift() == 0); 4145 constraint(ALLOC_IN_RC(ptr_reg)); 4146 match(AddP (AddP (DecodeNKlass reg) lreg) off); 4147 4148 op_cost(10); 4149 format %{"[$reg + $off + $lreg]" %} 4150 interface(MEMORY_INTER) %{ 4151 base($reg); 4152 index($lreg); 4153 scale(0x0); 4154 disp($off); 4155 %} 4156%} 4157 4158operand indIndexNarrowKlass(rRegN reg, rRegL lreg) 4159%{ 4160 predicate(Universe::narrow_klass_shift() == 0); 4161 constraint(ALLOC_IN_RC(ptr_reg)); 4162 match(AddP (DecodeNKlass reg) lreg); 4163 4164 op_cost(10); 4165 format %{"[$reg + $lreg]" %} 4166 interface(MEMORY_INTER) %{ 4167 base($reg); 4168 index($lreg); 4169 scale(0x0); 4170 disp(0x0); 4171 %} 4172%} 4173 4174operand indIndexScaleNarrowKlass(rRegN reg, rRegL lreg, immI2 scale) 4175%{ 4176 predicate(Universe::narrow_klass_shift() == 0); 4177 constraint(ALLOC_IN_RC(ptr_reg)); 4178 match(AddP (DecodeNKlass reg) (LShiftL lreg scale)); 4179 4180 op_cost(10); 4181 format %{"[$reg + $lreg << $scale]" %} 4182 interface(MEMORY_INTER) %{ 4183 base($reg); 4184 index($lreg); 4185 scale($scale); 4186 disp(0x0); 4187 %} 4188%} 4189 4190operand indIndexScaleOffsetNarrowKlass(rRegN reg, immL32 off, rRegL lreg, immI2 scale) 4191%{ 4192 predicate(Universe::narrow_klass_shift() == 0); 4193 constraint(ALLOC_IN_RC(ptr_reg)); 4194 match(AddP (AddP (DecodeNKlass reg) (LShiftL lreg scale)) off); 4195 4196 op_cost(10); 4197 format %{"[$reg + $off + $lreg << $scale]" %} 4198 interface(MEMORY_INTER) %{ 4199 base($reg); 4200 index($lreg); 4201 scale($scale); 4202 disp($off); 4203 %} 4204%} 4205 4206operand indCompressedKlassOffset(rRegN reg, immL32 off) %{ 4207 predicate(UseCompressedKlassPointers && (Universe::narrow_klass_shift() == Address::times_8)); 4208 constraint(ALLOC_IN_RC(ptr_reg)); 4209 match(AddP (DecodeNKlass reg) off); 4210 4211 op_cost(10); 4212 format %{"[R12 + $reg << 3 + $off] (compressed klass addressing)" %} 4213 interface(MEMORY_INTER) %{ 4214 base(0xc); // R12 4215 index($reg); 4216 scale(0x3); 4217 disp($off); 4218 %} 4219%} 4220 4221operand indPosIndexScaleOffsetNarrowKlass(rRegN reg, immL32 off, rRegI idx, immI2 scale) 4222%{ 4223 constraint(ALLOC_IN_RC(ptr_reg)); 4224 predicate(Universe::narrow_klass_shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 4225 match(AddP (AddP (DecodeNKlass reg) (LShiftL (ConvI2L idx) scale)) off); 4226 4227 op_cost(10); 4228 format %{"[$reg + $off + $idx << $scale]" %} 4229 interface(MEMORY_INTER) %{ 4230 base($reg); 4231 index($idx); 4232 scale($scale); 4233 disp($off); 4234 %} 4235%} 4236 4237//----------Special Memory Operands-------------------------------------------- 4238// Stack Slot Operand - This operand is used for loading and storing temporary 4239// values on the stack where a match requires a value to 4240// flow through memory. 4241operand stackSlotP(sRegP reg) 4242%{ 4243 constraint(ALLOC_IN_RC(stack_slots)); 4244 // No match rule because this operand is only generated in matching 4245 4246 format %{ "[$reg]" %} 4247 interface(MEMORY_INTER) %{ 4248 base(0x4); // RSP 4249 index(0x4); // No Index 4250 scale(0x0); // No Scale 4251 disp($reg); // Stack Offset 4252 %} 4253%} 4254 4255operand stackSlotI(sRegI reg) 4256%{ 4257 constraint(ALLOC_IN_RC(stack_slots)); 4258 // No match rule because this operand is only generated in matching 4259 4260 format %{ "[$reg]" %} 4261 interface(MEMORY_INTER) %{ 4262 base(0x4); // RSP 4263 index(0x4); // No Index 4264 scale(0x0); // No Scale 4265 disp($reg); // Stack Offset 4266 %} 4267%} 4268 4269operand stackSlotF(sRegF reg) 4270%{ 4271 constraint(ALLOC_IN_RC(stack_slots)); 4272 // No match rule because this operand is only generated in matching 4273 4274 format %{ "[$reg]" %} 4275 interface(MEMORY_INTER) %{ 4276 base(0x4); // RSP 4277 index(0x4); // No Index 4278 scale(0x0); // No Scale 4279 disp($reg); // Stack Offset 4280 %} 4281%} 4282 4283operand stackSlotD(sRegD reg) 4284%{ 4285 constraint(ALLOC_IN_RC(stack_slots)); 4286 // No match rule because this operand is only generated in matching 4287 4288 format %{ "[$reg]" %} 4289 interface(MEMORY_INTER) %{ 4290 base(0x4); // RSP 4291 index(0x4); // No Index 4292 scale(0x0); // No Scale 4293 disp($reg); // Stack Offset 4294 %} 4295%} 4296operand stackSlotL(sRegL reg) 4297%{ 4298 constraint(ALLOC_IN_RC(stack_slots)); 4299 // No match rule because this operand is only generated in matching 4300 4301 format %{ "[$reg]" %} 4302 interface(MEMORY_INTER) %{ 4303 base(0x4); // RSP 4304 index(0x4); // No Index 4305 scale(0x0); // No Scale 4306 disp($reg); // Stack Offset 4307 %} 4308%} 4309 4310//----------Conditional Branch Operands---------------------------------------- 4311// Comparison Op - This is the operation of the comparison, and is limited to 4312// the following set of codes: 4313// L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 4314// 4315// Other attributes of the comparison, such as unsignedness, are specified 4316// by the comparison instruction that sets a condition code flags register. 4317// That result is represented by a flags operand whose subtype is appropriate 4318// to the unsignedness (etc.) of the comparison. 4319// 4320// Later, the instruction which matches both the Comparison Op (a Bool) and 4321// the flags (produced by the Cmp) specifies the coding of the comparison op 4322// by matching a specific subtype of Bool operand below, such as cmpOpU. 4323 4324// Comparision Code 4325operand cmpOp() 4326%{ 4327 match(Bool); 4328 4329 format %{ "" %} 4330 interface(COND_INTER) %{ 4331 equal(0x4, "e"); 4332 not_equal(0x5, "ne"); 4333 less(0xC, "l"); 4334 greater_equal(0xD, "ge"); 4335 less_equal(0xE, "le"); 4336 greater(0xF, "g"); 4337 %} 4338%} 4339 4340// Comparison Code, unsigned compare. Used by FP also, with 4341// C2 (unordered) turned into GT or LT already. The other bits 4342// C0 and C3 are turned into Carry & Zero flags. 4343operand cmpOpU() 4344%{ 4345 match(Bool); 4346 4347 format %{ "" %} 4348 interface(COND_INTER) %{ 4349 equal(0x4, "e"); 4350 not_equal(0x5, "ne"); 4351 less(0x2, "b"); 4352 greater_equal(0x3, "nb"); 4353 less_equal(0x6, "be"); 4354 greater(0x7, "nbe"); 4355 %} 4356%} 4357 4358 4359// Floating comparisons that don't require any fixup for the unordered case 4360operand cmpOpUCF() %{ 4361 match(Bool); 4362 predicate(n->as_Bool()->_test._test == BoolTest::lt || 4363 n->as_Bool()->_test._test == BoolTest::ge || 4364 n->as_Bool()->_test._test == BoolTest::le || 4365 n->as_Bool()->_test._test == BoolTest::gt); 4366 format %{ "" %} 4367 interface(COND_INTER) %{ 4368 equal(0x4, "e"); 4369 not_equal(0x5, "ne"); 4370 less(0x2, "b"); 4371 greater_equal(0x3, "nb"); 4372 less_equal(0x6, "be"); 4373 greater(0x7, "nbe"); 4374 %} 4375%} 4376 4377 4378// Floating comparisons that can be fixed up with extra conditional jumps 4379operand cmpOpUCF2() %{ 4380 match(Bool); 4381 predicate(n->as_Bool()->_test._test == BoolTest::ne || 4382 n->as_Bool()->_test._test == BoolTest::eq); 4383 format %{ "" %} 4384 interface(COND_INTER) %{ 4385 equal(0x4, "e"); 4386 not_equal(0x5, "ne"); 4387 less(0x2, "b"); 4388 greater_equal(0x3, "nb"); 4389 less_equal(0x6, "be"); 4390 greater(0x7, "nbe"); 4391 %} 4392%} 4393 4394 4395//----------OPERAND CLASSES---------------------------------------------------- 4396// Operand Classes are groups of operands that are used as to simplify 4397// instruction definitions by not requiring the AD writer to specify separate 4398// instructions for every form of operand when the instruction accepts 4399// multiple operand types with the same basic encoding and format. The classic 4400// case of this is memory operands. 4401 4402opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex, 4403 indIndexScale, indIndexScaleOffset, indPosIndexScaleOffset, 4404 indCompressedOopOffset, 4405 indirectNarrow, indOffset8Narrow, indOffset32Narrow, 4406 indIndexOffsetNarrow, indIndexNarrow, indIndexScaleNarrow, 4407 indIndexScaleOffsetNarrow, indPosIndexScaleOffsetNarrow, 4408 indCompressedKlassOffset, 4409 indirectNarrowKlass, indOffset8NarrowKlass, indOffset32NarrowKlass, 4410 indIndexOffsetNarrowKlass, indIndexNarrowKlass, indIndexScaleNarrowKlass, 4411 indIndexScaleOffsetNarrowKlass, indPosIndexScaleOffsetNarrowKlass); 4412 4413//----------PIPELINE----------------------------------------------------------- 4414// Rules which define the behavior of the target architectures pipeline. 4415pipeline %{ 4416 4417//----------ATTRIBUTES--------------------------------------------------------- 4418attributes %{ 4419 variable_size_instructions; // Fixed size instructions 4420 max_instructions_per_bundle = 3; // Up to 3 instructions per bundle 4421 instruction_unit_size = 1; // An instruction is 1 bytes long 4422 instruction_fetch_unit_size = 16; // The processor fetches one line 4423 instruction_fetch_units = 1; // of 16 bytes 4424 4425 // List of nop instructions 4426 nops( MachNop ); 4427%} 4428 4429//----------RESOURCES---------------------------------------------------------- 4430// Resources are the functional units available to the machine 4431 4432// Generic P2/P3 pipeline 4433// 3 decoders, only D0 handles big operands; a "bundle" is the limit of 4434// 3 instructions decoded per cycle. 4435// 2 load/store ops per cycle, 1 branch, 1 FPU, 4436// 3 ALU op, only ALU0 handles mul instructions. 4437resources( D0, D1, D2, DECODE = D0 | D1 | D2, 4438 MS0, MS1, MS2, MEM = MS0 | MS1 | MS2, 4439 BR, FPU, 4440 ALU0, ALU1, ALU2, ALU = ALU0 | ALU1 | ALU2); 4441 4442//----------PIPELINE DESCRIPTION----------------------------------------------- 4443// Pipeline Description specifies the stages in the machine's pipeline 4444 4445// Generic P2/P3 pipeline 4446pipe_desc(S0, S1, S2, S3, S4, S5); 4447 4448//----------PIPELINE CLASSES--------------------------------------------------- 4449// Pipeline Classes describe the stages in which input and output are 4450// referenced by the hardware pipeline. 4451 4452// Naming convention: ialu or fpu 4453// Then: _reg 4454// Then: _reg if there is a 2nd register 4455// Then: _long if it's a pair of instructions implementing a long 4456// Then: _fat if it requires the big decoder 4457// Or: _mem if it requires the big decoder and a memory unit. 4458 4459// Integer ALU reg operation 4460pipe_class ialu_reg(rRegI dst) 4461%{ 4462 single_instruction; 4463 dst : S4(write); 4464 dst : S3(read); 4465 DECODE : S0; // any decoder 4466 ALU : S3; // any alu 4467%} 4468 4469// Long ALU reg operation 4470pipe_class ialu_reg_long(rRegL dst) 4471%{ 4472 instruction_count(2); 4473 dst : S4(write); 4474 dst : S3(read); 4475 DECODE : S0(2); // any 2 decoders 4476 ALU : S3(2); // both alus 4477%} 4478 4479// Integer ALU reg operation using big decoder 4480pipe_class ialu_reg_fat(rRegI dst) 4481%{ 4482 single_instruction; 4483 dst : S4(write); 4484 dst : S3(read); 4485 D0 : S0; // big decoder only 4486 ALU : S3; // any alu 4487%} 4488 4489// Long ALU reg operation using big decoder 4490pipe_class ialu_reg_long_fat(rRegL dst) 4491%{ 4492 instruction_count(2); 4493 dst : S4(write); 4494 dst : S3(read); 4495 D0 : S0(2); // big decoder only; twice 4496 ALU : S3(2); // any 2 alus 4497%} 4498 4499// Integer ALU reg-reg operation 4500pipe_class ialu_reg_reg(rRegI dst, rRegI src) 4501%{ 4502 single_instruction; 4503 dst : S4(write); 4504 src : S3(read); 4505 DECODE : S0; // any decoder 4506 ALU : S3; // any alu 4507%} 4508 4509// Long ALU reg-reg operation 4510pipe_class ialu_reg_reg_long(rRegL dst, rRegL src) 4511%{ 4512 instruction_count(2); 4513 dst : S4(write); 4514 src : S3(read); 4515 DECODE : S0(2); // any 2 decoders 4516 ALU : S3(2); // both alus 4517%} 4518 4519// Integer ALU reg-reg operation 4520pipe_class ialu_reg_reg_fat(rRegI dst, memory src) 4521%{ 4522 single_instruction; 4523 dst : S4(write); 4524 src : S3(read); 4525 D0 : S0; // big decoder only 4526 ALU : S3; // any alu 4527%} 4528 4529// Long ALU reg-reg operation 4530pipe_class ialu_reg_reg_long_fat(rRegL dst, rRegL src) 4531%{ 4532 instruction_count(2); 4533 dst : S4(write); 4534 src : S3(read); 4535 D0 : S0(2); // big decoder only; twice 4536 ALU : S3(2); // both alus 4537%} 4538 4539// Integer ALU reg-mem operation 4540pipe_class ialu_reg_mem(rRegI dst, memory mem) 4541%{ 4542 single_instruction; 4543 dst : S5(write); 4544 mem : S3(read); 4545 D0 : S0; // big decoder only 4546 ALU : S4; // any alu 4547 MEM : S3; // any mem 4548%} 4549 4550// Integer mem operation (prefetch) 4551pipe_class ialu_mem(memory mem) 4552%{ 4553 single_instruction; 4554 mem : S3(read); 4555 D0 : S0; // big decoder only 4556 MEM : S3; // any mem 4557%} 4558 4559// Integer Store to Memory 4560pipe_class ialu_mem_reg(memory mem, rRegI src) 4561%{ 4562 single_instruction; 4563 mem : S3(read); 4564 src : S5(read); 4565 D0 : S0; // big decoder only 4566 ALU : S4; // any alu 4567 MEM : S3; 4568%} 4569 4570// // Long Store to Memory 4571// pipe_class ialu_mem_long_reg(memory mem, rRegL src) 4572// %{ 4573// instruction_count(2); 4574// mem : S3(read); 4575// src : S5(read); 4576// D0 : S0(2); // big decoder only; twice 4577// ALU : S4(2); // any 2 alus 4578// MEM : S3(2); // Both mems 4579// %} 4580 4581// Integer Store to Memory 4582pipe_class ialu_mem_imm(memory mem) 4583%{ 4584 single_instruction; 4585 mem : S3(read); 4586 D0 : S0; // big decoder only 4587 ALU : S4; // any alu 4588 MEM : S3; 4589%} 4590 4591// Integer ALU0 reg-reg operation 4592pipe_class ialu_reg_reg_alu0(rRegI dst, rRegI src) 4593%{ 4594 single_instruction; 4595 dst : S4(write); 4596 src : S3(read); 4597 D0 : S0; // Big decoder only 4598 ALU0 : S3; // only alu0 4599%} 4600 4601// Integer ALU0 reg-mem operation 4602pipe_class ialu_reg_mem_alu0(rRegI dst, memory mem) 4603%{ 4604 single_instruction; 4605 dst : S5(write); 4606 mem : S3(read); 4607 D0 : S0; // big decoder only 4608 ALU0 : S4; // ALU0 only 4609 MEM : S3; // any mem 4610%} 4611 4612// Integer ALU reg-reg operation 4613pipe_class ialu_cr_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2) 4614%{ 4615 single_instruction; 4616 cr : S4(write); 4617 src1 : S3(read); 4618 src2 : S3(read); 4619 DECODE : S0; // any decoder 4620 ALU : S3; // any alu 4621%} 4622 4623// Integer ALU reg-imm operation 4624pipe_class ialu_cr_reg_imm(rFlagsReg cr, rRegI src1) 4625%{ 4626 single_instruction; 4627 cr : S4(write); 4628 src1 : S3(read); 4629 DECODE : S0; // any decoder 4630 ALU : S3; // any alu 4631%} 4632 4633// Integer ALU reg-mem operation 4634pipe_class ialu_cr_reg_mem(rFlagsReg cr, rRegI src1, memory src2) 4635%{ 4636 single_instruction; 4637 cr : S4(write); 4638 src1 : S3(read); 4639 src2 : S3(read); 4640 D0 : S0; // big decoder only 4641 ALU : S4; // any alu 4642 MEM : S3; 4643%} 4644 4645// Conditional move reg-reg 4646pipe_class pipe_cmplt( rRegI p, rRegI q, rRegI y) 4647%{ 4648 instruction_count(4); 4649 y : S4(read); 4650 q : S3(read); 4651 p : S3(read); 4652 DECODE : S0(4); // any decoder 4653%} 4654 4655// Conditional move reg-reg 4656pipe_class pipe_cmov_reg( rRegI dst, rRegI src, rFlagsReg cr) 4657%{ 4658 single_instruction; 4659 dst : S4(write); 4660 src : S3(read); 4661 cr : S3(read); 4662 DECODE : S0; // any decoder 4663%} 4664 4665// Conditional move reg-mem 4666pipe_class pipe_cmov_mem( rFlagsReg cr, rRegI dst, memory src) 4667%{ 4668 single_instruction; 4669 dst : S4(write); 4670 src : S3(read); 4671 cr : S3(read); 4672 DECODE : S0; // any decoder 4673 MEM : S3; 4674%} 4675 4676// Conditional move reg-reg long 4677pipe_class pipe_cmov_reg_long( rFlagsReg cr, rRegL dst, rRegL src) 4678%{ 4679 single_instruction; 4680 dst : S4(write); 4681 src : S3(read); 4682 cr : S3(read); 4683 DECODE : S0(2); // any 2 decoders 4684%} 4685 4686// XXX 4687// // Conditional move double reg-reg 4688// pipe_class pipe_cmovD_reg( rFlagsReg cr, regDPR1 dst, regD src) 4689// %{ 4690// single_instruction; 4691// dst : S4(write); 4692// src : S3(read); 4693// cr : S3(read); 4694// DECODE : S0; // any decoder 4695// %} 4696 4697// Float reg-reg operation 4698pipe_class fpu_reg(regD dst) 4699%{ 4700 instruction_count(2); 4701 dst : S3(read); 4702 DECODE : S0(2); // any 2 decoders 4703 FPU : S3; 4704%} 4705 4706// Float reg-reg operation 4707pipe_class fpu_reg_reg(regD dst, regD src) 4708%{ 4709 instruction_count(2); 4710 dst : S4(write); 4711 src : S3(read); 4712 DECODE : S0(2); // any 2 decoders 4713 FPU : S3; 4714%} 4715 4716// Float reg-reg operation 4717pipe_class fpu_reg_reg_reg(regD dst, regD src1, regD src2) 4718%{ 4719 instruction_count(3); 4720 dst : S4(write); 4721 src1 : S3(read); 4722 src2 : S3(read); 4723 DECODE : S0(3); // any 3 decoders 4724 FPU : S3(2); 4725%} 4726 4727// Float reg-reg operation 4728pipe_class fpu_reg_reg_reg_reg(regD dst, regD src1, regD src2, regD src3) 4729%{ 4730 instruction_count(4); 4731 dst : S4(write); 4732 src1 : S3(read); 4733 src2 : S3(read); 4734 src3 : S3(read); 4735 DECODE : S0(4); // any 3 decoders 4736 FPU : S3(2); 4737%} 4738 4739// Float reg-reg operation 4740pipe_class fpu_reg_mem_reg_reg(regD dst, memory src1, regD src2, regD src3) 4741%{ 4742 instruction_count(4); 4743 dst : S4(write); 4744 src1 : S3(read); 4745 src2 : S3(read); 4746 src3 : S3(read); 4747 DECODE : S1(3); // any 3 decoders 4748 D0 : S0; // Big decoder only 4749 FPU : S3(2); 4750 MEM : S3; 4751%} 4752 4753// Float reg-mem operation 4754pipe_class fpu_reg_mem(regD dst, memory mem) 4755%{ 4756 instruction_count(2); 4757 dst : S5(write); 4758 mem : S3(read); 4759 D0 : S0; // big decoder only 4760 DECODE : S1; // any decoder for FPU POP 4761 FPU : S4; 4762 MEM : S3; // any mem 4763%} 4764 4765// Float reg-mem operation 4766pipe_class fpu_reg_reg_mem(regD dst, regD src1, memory mem) 4767%{ 4768 instruction_count(3); 4769 dst : S5(write); 4770 src1 : S3(read); 4771 mem : S3(read); 4772 D0 : S0; // big decoder only 4773 DECODE : S1(2); // any decoder for FPU POP 4774 FPU : S4; 4775 MEM : S3; // any mem 4776%} 4777 4778// Float mem-reg operation 4779pipe_class fpu_mem_reg(memory mem, regD src) 4780%{ 4781 instruction_count(2); 4782 src : S5(read); 4783 mem : S3(read); 4784 DECODE : S0; // any decoder for FPU PUSH 4785 D0 : S1; // big decoder only 4786 FPU : S4; 4787 MEM : S3; // any mem 4788%} 4789 4790pipe_class fpu_mem_reg_reg(memory mem, regD src1, regD src2) 4791%{ 4792 instruction_count(3); 4793 src1 : S3(read); 4794 src2 : S3(read); 4795 mem : S3(read); 4796 DECODE : S0(2); // any decoder for FPU PUSH 4797 D0 : S1; // big decoder only 4798 FPU : S4; 4799 MEM : S3; // any mem 4800%} 4801 4802pipe_class fpu_mem_reg_mem(memory mem, regD src1, memory src2) 4803%{ 4804 instruction_count(3); 4805 src1 : S3(read); 4806 src2 : S3(read); 4807 mem : S4(read); 4808 DECODE : S0; // any decoder for FPU PUSH 4809 D0 : S0(2); // big decoder only 4810 FPU : S4; 4811 MEM : S3(2); // any mem 4812%} 4813 4814pipe_class fpu_mem_mem(memory dst, memory src1) 4815%{ 4816 instruction_count(2); 4817 src1 : S3(read); 4818 dst : S4(read); 4819 D0 : S0(2); // big decoder only 4820 MEM : S3(2); // any mem 4821%} 4822 4823pipe_class fpu_mem_mem_mem(memory dst, memory src1, memory src2) 4824%{ 4825 instruction_count(3); 4826 src1 : S3(read); 4827 src2 : S3(read); 4828 dst : S4(read); 4829 D0 : S0(3); // big decoder only 4830 FPU : S4; 4831 MEM : S3(3); // any mem 4832%} 4833 4834pipe_class fpu_mem_reg_con(memory mem, regD src1) 4835%{ 4836 instruction_count(3); 4837 src1 : S4(read); 4838 mem : S4(read); 4839 DECODE : S0; // any decoder for FPU PUSH 4840 D0 : S0(2); // big decoder only 4841 FPU : S4; 4842 MEM : S3(2); // any mem 4843%} 4844 4845// Float load constant 4846pipe_class fpu_reg_con(regD dst) 4847%{ 4848 instruction_count(2); 4849 dst : S5(write); 4850 D0 : S0; // big decoder only for the load 4851 DECODE : S1; // any decoder for FPU POP 4852 FPU : S4; 4853 MEM : S3; // any mem 4854%} 4855 4856// Float load constant 4857pipe_class fpu_reg_reg_con(regD dst, regD src) 4858%{ 4859 instruction_count(3); 4860 dst : S5(write); 4861 src : S3(read); 4862 D0 : S0; // big decoder only for the load 4863 DECODE : S1(2); // any decoder for FPU POP 4864 FPU : S4; 4865 MEM : S3; // any mem 4866%} 4867 4868// UnConditional branch 4869pipe_class pipe_jmp(label labl) 4870%{ 4871 single_instruction; 4872 BR : S3; 4873%} 4874 4875// Conditional branch 4876pipe_class pipe_jcc(cmpOp cmp, rFlagsReg cr, label labl) 4877%{ 4878 single_instruction; 4879 cr : S1(read); 4880 BR : S3; 4881%} 4882 4883// Allocation idiom 4884pipe_class pipe_cmpxchg(rRegP dst, rRegP heap_ptr) 4885%{ 4886 instruction_count(1); force_serialization; 4887 fixed_latency(6); 4888 heap_ptr : S3(read); 4889 DECODE : S0(3); 4890 D0 : S2; 4891 MEM : S3; 4892 ALU : S3(2); 4893 dst : S5(write); 4894 BR : S5; 4895%} 4896 4897// Generic big/slow expanded idiom 4898pipe_class pipe_slow() 4899%{ 4900 instruction_count(10); multiple_bundles; force_serialization; 4901 fixed_latency(100); 4902 D0 : S0(2); 4903 MEM : S3(2); 4904%} 4905 4906// The real do-nothing guy 4907pipe_class empty() 4908%{ 4909 instruction_count(0); 4910%} 4911 4912// Define the class for the Nop node 4913define 4914%{ 4915 MachNop = empty; 4916%} 4917 4918%} 4919 4920//----------INSTRUCTIONS------------------------------------------------------- 4921// 4922// match -- States which machine-independent subtree may be replaced 4923// by this instruction. 4924// ins_cost -- The estimated cost of this instruction is used by instruction 4925// selection to identify a minimum cost tree of machine 4926// instructions that matches a tree of machine-independent 4927// instructions. 4928// format -- A string providing the disassembly for this instruction. 4929// The value of an instruction's operand may be inserted 4930// by referring to it with a '$' prefix. 4931// opcode -- Three instruction opcodes may be provided. These are referred 4932// to within an encode class as $primary, $secondary, and $tertiary 4933// rrspectively. The primary opcode is commonly used to 4934// indicate the type of machine instruction, while secondary 4935// and tertiary are often used for prefix options or addressing 4936// modes. 4937// ins_encode -- A list of encode classes with parameters. The encode class 4938// name must have been defined in an 'enc_class' specification 4939// in the encode section of the architecture description. 4940 4941 4942//----------Load/Store/Move Instructions--------------------------------------- 4943//----------Load Instructions-------------------------------------------------- 4944 4945// Load Byte (8 bit signed) 4946instruct loadB(rRegI dst, memory mem) 4947%{ 4948 match(Set dst (LoadB mem)); 4949 4950 ins_cost(125); 4951 format %{ "movsbl $dst, $mem\t# byte" %} 4952 4953 ins_encode %{ 4954 __ movsbl($dst$$Register, $mem$$Address); 4955 %} 4956 4957 ins_pipe(ialu_reg_mem); 4958%} 4959 4960// Load Byte (8 bit signed) into Long Register 4961instruct loadB2L(rRegL dst, memory mem) 4962%{ 4963 match(Set dst (ConvI2L (LoadB mem))); 4964 4965 ins_cost(125); 4966 format %{ "movsbq $dst, $mem\t# byte -> long" %} 4967 4968 ins_encode %{ 4969 __ movsbq($dst$$Register, $mem$$Address); 4970 %} 4971 4972 ins_pipe(ialu_reg_mem); 4973%} 4974 4975// Load Unsigned Byte (8 bit UNsigned) 4976instruct loadUB(rRegI dst, memory mem) 4977%{ 4978 match(Set dst (LoadUB mem)); 4979 4980 ins_cost(125); 4981 format %{ "movzbl $dst, $mem\t# ubyte" %} 4982 4983 ins_encode %{ 4984 __ movzbl($dst$$Register, $mem$$Address); 4985 %} 4986 4987 ins_pipe(ialu_reg_mem); 4988%} 4989 4990// Load Unsigned Byte (8 bit UNsigned) into Long Register 4991instruct loadUB2L(rRegL dst, memory mem) 4992%{ 4993 match(Set dst (ConvI2L (LoadUB mem))); 4994 4995 ins_cost(125); 4996 format %{ "movzbq $dst, $mem\t# ubyte -> long" %} 4997 4998 ins_encode %{ 4999 __ movzbq($dst$$Register, $mem$$Address); 5000 %} 5001 5002 ins_pipe(ialu_reg_mem); 5003%} 5004 5005// Load Unsigned Byte (8 bit UNsigned) with a 8-bit mask into Long Register 5006instruct loadUB2L_immI8(rRegL dst, memory mem, immI8 mask, rFlagsReg cr) %{ 5007 match(Set dst (ConvI2L (AndI (LoadUB mem) mask))); 5008 effect(KILL cr); 5009 5010 format %{ "movzbq $dst, $mem\t# ubyte & 8-bit mask -> long\n\t" 5011 "andl $dst, $mask" %} 5012 ins_encode %{ 5013 Register Rdst = $dst$$Register; 5014 __ movzbq(Rdst, $mem$$Address); 5015 __ andl(Rdst, $mask$$constant); 5016 %} 5017 ins_pipe(ialu_reg_mem); 5018%} 5019 5020// Load Short (16 bit signed) 5021instruct loadS(rRegI dst, memory mem) 5022%{ 5023 match(Set dst (LoadS mem)); 5024 5025 ins_cost(125); 5026 format %{ "movswl $dst, $mem\t# short" %} 5027 5028 ins_encode %{ 5029 __ movswl($dst$$Register, $mem$$Address); 5030 %} 5031 5032 ins_pipe(ialu_reg_mem); 5033%} 5034 5035// Load Short (16 bit signed) to Byte (8 bit signed) 5036instruct loadS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 5037 match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour)); 5038 5039 ins_cost(125); 5040 format %{ "movsbl $dst, $mem\t# short -> byte" %} 5041 ins_encode %{ 5042 __ movsbl($dst$$Register, $mem$$Address); 5043 %} 5044 ins_pipe(ialu_reg_mem); 5045%} 5046 5047// Load Short (16 bit signed) into Long Register 5048instruct loadS2L(rRegL dst, memory mem) 5049%{ 5050 match(Set dst (ConvI2L (LoadS mem))); 5051 5052 ins_cost(125); 5053 format %{ "movswq $dst, $mem\t# short -> long" %} 5054 5055 ins_encode %{ 5056 __ movswq($dst$$Register, $mem$$Address); 5057 %} 5058 5059 ins_pipe(ialu_reg_mem); 5060%} 5061 5062// Load Unsigned Short/Char (16 bit UNsigned) 5063instruct loadUS(rRegI dst, memory mem) 5064%{ 5065 match(Set dst (LoadUS mem)); 5066 5067 ins_cost(125); 5068 format %{ "movzwl $dst, $mem\t# ushort/char" %} 5069 5070 ins_encode %{ 5071 __ movzwl($dst$$Register, $mem$$Address); 5072 %} 5073 5074 ins_pipe(ialu_reg_mem); 5075%} 5076 5077// Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed) 5078instruct loadUS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 5079 match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour)); 5080 5081 ins_cost(125); 5082 format %{ "movsbl $dst, $mem\t# ushort -> byte" %} 5083 ins_encode %{ 5084 __ movsbl($dst$$Register, $mem$$Address); 5085 %} 5086 ins_pipe(ialu_reg_mem); 5087%} 5088 5089// Load Unsigned Short/Char (16 bit UNsigned) into Long Register 5090instruct loadUS2L(rRegL dst, memory mem) 5091%{ 5092 match(Set dst (ConvI2L (LoadUS mem))); 5093 5094 ins_cost(125); 5095 format %{ "movzwq $dst, $mem\t# ushort/char -> long" %} 5096 5097 ins_encode %{ 5098 __ movzwq($dst$$Register, $mem$$Address); 5099 %} 5100 5101 ins_pipe(ialu_reg_mem); 5102%} 5103 5104// Load Unsigned Short/Char (16 bit UNsigned) with mask 0xFF into Long Register 5105instruct loadUS2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 5106 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 5107 5108 format %{ "movzbq $dst, $mem\t# ushort/char & 0xFF -> long" %} 5109 ins_encode %{ 5110 __ movzbq($dst$$Register, $mem$$Address); 5111 %} 5112 ins_pipe(ialu_reg_mem); 5113%} 5114 5115// Load Unsigned Short/Char (16 bit UNsigned) with mask into Long Register 5116instruct loadUS2L_immI16(rRegL dst, memory mem, immI16 mask, rFlagsReg cr) %{ 5117 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 5118 effect(KILL cr); 5119 5120 format %{ "movzwq $dst, $mem\t# ushort/char & 16-bit mask -> long\n\t" 5121 "andl $dst, $mask" %} 5122 ins_encode %{ 5123 Register Rdst = $dst$$Register; 5124 __ movzwq(Rdst, $mem$$Address); 5125 __ andl(Rdst, $mask$$constant); 5126 %} 5127 ins_pipe(ialu_reg_mem); 5128%} 5129 5130// Load Integer 5131instruct loadI(rRegI dst, memory mem) 5132%{ 5133 match(Set dst (LoadI mem)); 5134 5135 ins_cost(125); 5136 format %{ "movl $dst, $mem\t# int" %} 5137 5138 ins_encode %{ 5139 __ movl($dst$$Register, $mem$$Address); 5140 %} 5141 5142 ins_pipe(ialu_reg_mem); 5143%} 5144 5145// Load Integer (32 bit signed) to Byte (8 bit signed) 5146instruct loadI2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 5147 match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour)); 5148 5149 ins_cost(125); 5150 format %{ "movsbl $dst, $mem\t# int -> byte" %} 5151 ins_encode %{ 5152 __ movsbl($dst$$Register, $mem$$Address); 5153 %} 5154 ins_pipe(ialu_reg_mem); 5155%} 5156 5157// Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned) 5158instruct loadI2UB(rRegI dst, memory mem, immI_255 mask) %{ 5159 match(Set dst (AndI (LoadI mem) mask)); 5160 5161 ins_cost(125); 5162 format %{ "movzbl $dst, $mem\t# int -> ubyte" %} 5163 ins_encode %{ 5164 __ movzbl($dst$$Register, $mem$$Address); 5165 %} 5166 ins_pipe(ialu_reg_mem); 5167%} 5168 5169// Load Integer (32 bit signed) to Short (16 bit signed) 5170instruct loadI2S(rRegI dst, memory mem, immI_16 sixteen) %{ 5171 match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen)); 5172 5173 ins_cost(125); 5174 format %{ "movswl $dst, $mem\t# int -> short" %} 5175 ins_encode %{ 5176 __ movswl($dst$$Register, $mem$$Address); 5177 %} 5178 ins_pipe(ialu_reg_mem); 5179%} 5180 5181// Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned) 5182instruct loadI2US(rRegI dst, memory mem, immI_65535 mask) %{ 5183 match(Set dst (AndI (LoadI mem) mask)); 5184 5185 ins_cost(125); 5186 format %{ "movzwl $dst, $mem\t# int -> ushort/char" %} 5187 ins_encode %{ 5188 __ movzwl($dst$$Register, $mem$$Address); 5189 %} 5190 ins_pipe(ialu_reg_mem); 5191%} 5192 5193// Load Integer into Long Register 5194instruct loadI2L(rRegL dst, memory mem) 5195%{ 5196 match(Set dst (ConvI2L (LoadI mem))); 5197 5198 ins_cost(125); 5199 format %{ "movslq $dst, $mem\t# int -> long" %} 5200 5201 ins_encode %{ 5202 __ movslq($dst$$Register, $mem$$Address); 5203 %} 5204 5205 ins_pipe(ialu_reg_mem); 5206%} 5207 5208// Load Integer with mask 0xFF into Long Register 5209instruct loadI2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 5210 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 5211 5212 format %{ "movzbq $dst, $mem\t# int & 0xFF -> long" %} 5213 ins_encode %{ 5214 __ movzbq($dst$$Register, $mem$$Address); 5215 %} 5216 ins_pipe(ialu_reg_mem); 5217%} 5218 5219// Load Integer with mask 0xFFFF into Long Register 5220instruct loadI2L_immI_65535(rRegL dst, memory mem, immI_65535 mask) %{ 5221 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 5222 5223 format %{ "movzwq $dst, $mem\t# int & 0xFFFF -> long" %} 5224 ins_encode %{ 5225 __ movzwq($dst$$Register, $mem$$Address); 5226 %} 5227 ins_pipe(ialu_reg_mem); 5228%} 5229 5230// Load Integer with a 32-bit mask into Long Register 5231instruct loadI2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 5232 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 5233 effect(KILL cr); 5234 5235 format %{ "movl $dst, $mem\t# int & 32-bit mask -> long\n\t" 5236 "andl $dst, $mask" %} 5237 ins_encode %{ 5238 Register Rdst = $dst$$Register; 5239 __ movl(Rdst, $mem$$Address); 5240 __ andl(Rdst, $mask$$constant); 5241 %} 5242 ins_pipe(ialu_reg_mem); 5243%} 5244 5245// Load Unsigned Integer into Long Register 5246instruct loadUI2L(rRegL dst, memory mem, immL_32bits mask) 5247%{ 5248 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 5249 5250 ins_cost(125); 5251 format %{ "movl $dst, $mem\t# uint -> long" %} 5252 5253 ins_encode %{ 5254 __ movl($dst$$Register, $mem$$Address); 5255 %} 5256 5257 ins_pipe(ialu_reg_mem); 5258%} 5259 5260// Load Long 5261instruct loadL(rRegL dst, memory mem) 5262%{ 5263 match(Set dst (LoadL mem)); 5264 5265 ins_cost(125); 5266 format %{ "movq $dst, $mem\t# long" %} 5267 5268 ins_encode %{ 5269 __ movq($dst$$Register, $mem$$Address); 5270 %} 5271 5272 ins_pipe(ialu_reg_mem); // XXX 5273%} 5274 5275// Load Range 5276instruct loadRange(rRegI dst, memory mem) 5277%{ 5278 match(Set dst (LoadRange mem)); 5279 5280 ins_cost(125); // XXX 5281 format %{ "movl $dst, $mem\t# range" %} 5282 opcode(0x8B); 5283 ins_encode(REX_reg_mem(dst, mem), OpcP, reg_mem(dst, mem)); 5284 ins_pipe(ialu_reg_mem); 5285%} 5286 5287// Load Pointer 5288instruct loadP(rRegP dst, memory mem) 5289%{ 5290 match(Set dst (LoadP mem)); 5291 5292 ins_cost(125); // XXX 5293 format %{ "movq $dst, $mem\t# ptr" %} 5294 opcode(0x8B); 5295 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5296 ins_pipe(ialu_reg_mem); // XXX 5297%} 5298 5299// Load Compressed Pointer 5300instruct loadN(rRegN dst, memory mem) 5301%{ 5302 match(Set dst (LoadN mem)); 5303 5304 ins_cost(125); // XXX 5305 format %{ "movl $dst, $mem\t# compressed ptr" %} 5306 ins_encode %{ 5307 __ movl($dst$$Register, $mem$$Address); 5308 %} 5309 ins_pipe(ialu_reg_mem); // XXX 5310%} 5311 5312 5313// Load Klass Pointer 5314instruct loadKlass(rRegP dst, memory mem) 5315%{ 5316 match(Set dst (LoadKlass mem)); 5317 5318 ins_cost(125); // XXX 5319 format %{ "movq $dst, $mem\t# class" %} 5320 opcode(0x8B); 5321 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5322 ins_pipe(ialu_reg_mem); // XXX 5323%} 5324 5325// Load narrow Klass Pointer 5326instruct loadNKlass(rRegN dst, memory mem) 5327%{ 5328 match(Set dst (LoadNKlass mem)); 5329 5330 ins_cost(125); // XXX 5331 format %{ "movl $dst, $mem\t# compressed klass ptr" %} 5332 ins_encode %{ 5333 __ movl($dst$$Register, $mem$$Address); 5334 %} 5335 ins_pipe(ialu_reg_mem); // XXX 5336%} 5337 5338// Load Float 5339instruct loadF(regF dst, memory mem) 5340%{ 5341 match(Set dst (LoadF mem)); 5342 5343 ins_cost(145); // XXX 5344 format %{ "movss $dst, $mem\t# float" %} 5345 ins_encode %{ 5346 __ movflt($dst$$XMMRegister, $mem$$Address); 5347 %} 5348 ins_pipe(pipe_slow); // XXX 5349%} 5350 5351// Load Double 5352instruct loadD_partial(regD dst, memory mem) 5353%{ 5354 predicate(!UseXmmLoadAndClearUpper); 5355 match(Set dst (LoadD mem)); 5356 5357 ins_cost(145); // XXX 5358 format %{ "movlpd $dst, $mem\t# double" %} 5359 ins_encode %{ 5360 __ movdbl($dst$$XMMRegister, $mem$$Address); 5361 %} 5362 ins_pipe(pipe_slow); // XXX 5363%} 5364 5365instruct loadD(regD dst, memory mem) 5366%{ 5367 predicate(UseXmmLoadAndClearUpper); 5368 match(Set dst (LoadD mem)); 5369 5370 ins_cost(145); // XXX 5371 format %{ "movsd $dst, $mem\t# double" %} 5372 ins_encode %{ 5373 __ movdbl($dst$$XMMRegister, $mem$$Address); 5374 %} 5375 ins_pipe(pipe_slow); // XXX 5376%} 5377 5378// Load Effective Address 5379instruct leaP8(rRegP dst, indOffset8 mem) 5380%{ 5381 match(Set dst mem); 5382 5383 ins_cost(110); // XXX 5384 format %{ "leaq $dst, $mem\t# ptr 8" %} 5385 opcode(0x8D); 5386 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5387 ins_pipe(ialu_reg_reg_fat); 5388%} 5389 5390instruct leaP32(rRegP dst, indOffset32 mem) 5391%{ 5392 match(Set dst mem); 5393 5394 ins_cost(110); 5395 format %{ "leaq $dst, $mem\t# ptr 32" %} 5396 opcode(0x8D); 5397 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5398 ins_pipe(ialu_reg_reg_fat); 5399%} 5400 5401// instruct leaPIdx(rRegP dst, indIndex mem) 5402// %{ 5403// match(Set dst mem); 5404 5405// ins_cost(110); 5406// format %{ "leaq $dst, $mem\t# ptr idx" %} 5407// opcode(0x8D); 5408// ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5409// ins_pipe(ialu_reg_reg_fat); 5410// %} 5411 5412instruct leaPIdxOff(rRegP dst, indIndexOffset mem) 5413%{ 5414 match(Set dst mem); 5415 5416 ins_cost(110); 5417 format %{ "leaq $dst, $mem\t# ptr idxoff" %} 5418 opcode(0x8D); 5419 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5420 ins_pipe(ialu_reg_reg_fat); 5421%} 5422 5423instruct leaPIdxScale(rRegP dst, indIndexScale mem) 5424%{ 5425 match(Set dst mem); 5426 5427 ins_cost(110); 5428 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 5429 opcode(0x8D); 5430 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5431 ins_pipe(ialu_reg_reg_fat); 5432%} 5433 5434instruct leaPIdxScaleOff(rRegP dst, indIndexScaleOffset mem) 5435%{ 5436 match(Set dst mem); 5437 5438 ins_cost(110); 5439 format %{ "leaq $dst, $mem\t# ptr idxscaleoff" %} 5440 opcode(0x8D); 5441 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5442 ins_pipe(ialu_reg_reg_fat); 5443%} 5444 5445instruct leaPPosIdxScaleOff(rRegP dst, indPosIndexScaleOffset mem) 5446%{ 5447 match(Set dst mem); 5448 5449 ins_cost(110); 5450 format %{ "leaq $dst, $mem\t# ptr posidxscaleoff" %} 5451 opcode(0x8D); 5452 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5453 ins_pipe(ialu_reg_reg_fat); 5454%} 5455 5456// Load Effective Address which uses Narrow (32-bits) oop 5457instruct leaPCompressedOopOffset(rRegP dst, indCompressedOopOffset mem) 5458%{ 5459 predicate(UseCompressedOops && (Universe::narrow_oop_shift() != 0)); 5460 match(Set dst mem); 5461 5462 ins_cost(110); 5463 format %{ "leaq $dst, $mem\t# ptr compressedoopoff32" %} 5464 opcode(0x8D); 5465 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5466 ins_pipe(ialu_reg_reg_fat); 5467%} 5468 5469instruct leaP8Narrow(rRegP dst, indOffset8Narrow mem) 5470%{ 5471 predicate(Universe::narrow_oop_shift() == 0); 5472 match(Set dst mem); 5473 5474 ins_cost(110); // XXX 5475 format %{ "leaq $dst, $mem\t# ptr off8narrow" %} 5476 opcode(0x8D); 5477 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5478 ins_pipe(ialu_reg_reg_fat); 5479%} 5480 5481instruct leaP32Narrow(rRegP dst, indOffset32Narrow mem) 5482%{ 5483 predicate(Universe::narrow_oop_shift() == 0); 5484 match(Set dst mem); 5485 5486 ins_cost(110); 5487 format %{ "leaq $dst, $mem\t# ptr off32narrow" %} 5488 opcode(0x8D); 5489 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5490 ins_pipe(ialu_reg_reg_fat); 5491%} 5492 5493instruct leaPIdxOffNarrow(rRegP dst, indIndexOffsetNarrow mem) 5494%{ 5495 predicate(Universe::narrow_oop_shift() == 0); 5496 match(Set dst mem); 5497 5498 ins_cost(110); 5499 format %{ "leaq $dst, $mem\t# ptr idxoffnarrow" %} 5500 opcode(0x8D); 5501 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5502 ins_pipe(ialu_reg_reg_fat); 5503%} 5504 5505instruct leaPIdxScaleNarrow(rRegP dst, indIndexScaleNarrow mem) 5506%{ 5507 predicate(Universe::narrow_oop_shift() == 0); 5508 match(Set dst mem); 5509 5510 ins_cost(110); 5511 format %{ "leaq $dst, $mem\t# ptr idxscalenarrow" %} 5512 opcode(0x8D); 5513 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5514 ins_pipe(ialu_reg_reg_fat); 5515%} 5516 5517instruct leaPIdxScaleOffNarrow(rRegP dst, indIndexScaleOffsetNarrow mem) 5518%{ 5519 predicate(Universe::narrow_oop_shift() == 0); 5520 match(Set dst mem); 5521 5522 ins_cost(110); 5523 format %{ "leaq $dst, $mem\t# ptr idxscaleoffnarrow" %} 5524 opcode(0x8D); 5525 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5526 ins_pipe(ialu_reg_reg_fat); 5527%} 5528 5529instruct leaPPosIdxScaleOffNarrow(rRegP dst, indPosIndexScaleOffsetNarrow mem) 5530%{ 5531 predicate(Universe::narrow_oop_shift() == 0); 5532 match(Set dst mem); 5533 5534 ins_cost(110); 5535 format %{ "leaq $dst, $mem\t# ptr posidxscaleoffnarrow" %} 5536 opcode(0x8D); 5537 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5538 ins_pipe(ialu_reg_reg_fat); 5539%} 5540 5541instruct loadConI(rRegI dst, immI src) 5542%{ 5543 match(Set dst src); 5544 5545 format %{ "movl $dst, $src\t# int" %} 5546 ins_encode(load_immI(dst, src)); 5547 ins_pipe(ialu_reg_fat); // XXX 5548%} 5549 5550instruct loadConI0(rRegI dst, immI0 src, rFlagsReg cr) 5551%{ 5552 match(Set dst src); 5553 effect(KILL cr); 5554 5555 ins_cost(50); 5556 format %{ "xorl $dst, $dst\t# int" %} 5557 opcode(0x33); /* + rd */ 5558 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5559 ins_pipe(ialu_reg); 5560%} 5561 5562instruct loadConL(rRegL dst, immL src) 5563%{ 5564 match(Set dst src); 5565 5566 ins_cost(150); 5567 format %{ "movq $dst, $src\t# long" %} 5568 ins_encode(load_immL(dst, src)); 5569 ins_pipe(ialu_reg); 5570%} 5571 5572instruct loadConL0(rRegL dst, immL0 src, rFlagsReg cr) 5573%{ 5574 match(Set dst src); 5575 effect(KILL cr); 5576 5577 ins_cost(50); 5578 format %{ "xorl $dst, $dst\t# long" %} 5579 opcode(0x33); /* + rd */ 5580 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5581 ins_pipe(ialu_reg); // XXX 5582%} 5583 5584instruct loadConUL32(rRegL dst, immUL32 src) 5585%{ 5586 match(Set dst src); 5587 5588 ins_cost(60); 5589 format %{ "movl $dst, $src\t# long (unsigned 32-bit)" %} 5590 ins_encode(load_immUL32(dst, src)); 5591 ins_pipe(ialu_reg); 5592%} 5593 5594instruct loadConL32(rRegL dst, immL32 src) 5595%{ 5596 match(Set dst src); 5597 5598 ins_cost(70); 5599 format %{ "movq $dst, $src\t# long (32-bit)" %} 5600 ins_encode(load_immL32(dst, src)); 5601 ins_pipe(ialu_reg); 5602%} 5603 5604instruct loadConP(rRegP dst, immP con) %{ 5605 match(Set dst con); 5606 5607 format %{ "movq $dst, $con\t# ptr" %} 5608 ins_encode(load_immP(dst, con)); 5609 ins_pipe(ialu_reg_fat); // XXX 5610%} 5611 5612instruct loadConP0(rRegP dst, immP0 src, rFlagsReg cr) 5613%{ 5614 match(Set dst src); 5615 effect(KILL cr); 5616 5617 ins_cost(50); 5618 format %{ "xorl $dst, $dst\t# ptr" %} 5619 opcode(0x33); /* + rd */ 5620 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5621 ins_pipe(ialu_reg); 5622%} 5623 5624instruct loadConP31(rRegP dst, immP31 src, rFlagsReg cr) 5625%{ 5626 match(Set dst src); 5627 effect(KILL cr); 5628 5629 ins_cost(60); 5630 format %{ "movl $dst, $src\t# ptr (positive 32-bit)" %} 5631 ins_encode(load_immP31(dst, src)); 5632 ins_pipe(ialu_reg); 5633%} 5634 5635instruct loadConF(regF dst, immF con) %{ 5636 match(Set dst con); 5637 ins_cost(125); 5638 format %{ "movss $dst, [$constantaddress]\t# load from constant table: float=$con" %} 5639 ins_encode %{ 5640 __ movflt($dst$$XMMRegister, $constantaddress($con)); 5641 %} 5642 ins_pipe(pipe_slow); 5643%} 5644 5645instruct loadConN0(rRegN dst, immN0 src, rFlagsReg cr) %{ 5646 match(Set dst src); 5647 effect(KILL cr); 5648 format %{ "xorq $dst, $src\t# compressed NULL ptr" %} 5649 ins_encode %{ 5650 __ xorq($dst$$Register, $dst$$Register); 5651 %} 5652 ins_pipe(ialu_reg); 5653%} 5654 5655instruct loadConN(rRegN dst, immN src) %{ 5656 match(Set dst src); 5657 5658 ins_cost(125); 5659 format %{ "movl $dst, $src\t# compressed ptr" %} 5660 ins_encode %{ 5661 address con = (address)$src$$constant; 5662 if (con == NULL) { 5663 ShouldNotReachHere(); 5664 } else { 5665 __ set_narrow_oop($dst$$Register, (jobject)$src$$constant); 5666 } 5667 %} 5668 ins_pipe(ialu_reg_fat); // XXX 5669%} 5670 5671instruct loadConNKlass(rRegN dst, immNKlass src) %{ 5672 match(Set dst src); 5673 5674 ins_cost(125); 5675 format %{ "movl $dst, $src\t# compressed klass ptr" %} 5676 ins_encode %{ 5677 address con = (address)$src$$constant; 5678 if (con == NULL) { 5679 ShouldNotReachHere(); 5680 } else { 5681 __ set_narrow_klass($dst$$Register, (Klass*)$src$$constant); 5682 } 5683 %} 5684 ins_pipe(ialu_reg_fat); // XXX 5685%} 5686 5687instruct loadConF0(regF dst, immF0 src) 5688%{ 5689 match(Set dst src); 5690 ins_cost(100); 5691 5692 format %{ "xorps $dst, $dst\t# float 0.0" %} 5693 ins_encode %{ 5694 __ xorps($dst$$XMMRegister, $dst$$XMMRegister); 5695 %} 5696 ins_pipe(pipe_slow); 5697%} 5698 5699// Use the same format since predicate() can not be used here. 5700instruct loadConD(regD dst, immD con) %{ 5701 match(Set dst con); 5702 ins_cost(125); 5703 format %{ "movsd $dst, [$constantaddress]\t# load from constant table: double=$con" %} 5704 ins_encode %{ 5705 __ movdbl($dst$$XMMRegister, $constantaddress($con)); 5706 %} 5707 ins_pipe(pipe_slow); 5708%} 5709 5710instruct loadConD0(regD dst, immD0 src) 5711%{ 5712 match(Set dst src); 5713 ins_cost(100); 5714 5715 format %{ "xorpd $dst, $dst\t# double 0.0" %} 5716 ins_encode %{ 5717 __ xorpd ($dst$$XMMRegister, $dst$$XMMRegister); 5718 %} 5719 ins_pipe(pipe_slow); 5720%} 5721 5722instruct loadSSI(rRegI dst, stackSlotI src) 5723%{ 5724 match(Set dst src); 5725 5726 ins_cost(125); 5727 format %{ "movl $dst, $src\t# int stk" %} 5728 opcode(0x8B); 5729 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 5730 ins_pipe(ialu_reg_mem); 5731%} 5732 5733instruct loadSSL(rRegL dst, stackSlotL src) 5734%{ 5735 match(Set dst src); 5736 5737 ins_cost(125); 5738 format %{ "movq $dst, $src\t# long stk" %} 5739 opcode(0x8B); 5740 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 5741 ins_pipe(ialu_reg_mem); 5742%} 5743 5744instruct loadSSP(rRegP dst, stackSlotP src) 5745%{ 5746 match(Set dst src); 5747 5748 ins_cost(125); 5749 format %{ "movq $dst, $src\t# ptr stk" %} 5750 opcode(0x8B); 5751 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 5752 ins_pipe(ialu_reg_mem); 5753%} 5754 5755instruct loadSSF(regF dst, stackSlotF src) 5756%{ 5757 match(Set dst src); 5758 5759 ins_cost(125); 5760 format %{ "movss $dst, $src\t# float stk" %} 5761 ins_encode %{ 5762 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 5763 %} 5764 ins_pipe(pipe_slow); // XXX 5765%} 5766 5767// Use the same format since predicate() can not be used here. 5768instruct loadSSD(regD dst, stackSlotD src) 5769%{ 5770 match(Set dst src); 5771 5772 ins_cost(125); 5773 format %{ "movsd $dst, $src\t# double stk" %} 5774 ins_encode %{ 5775 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 5776 %} 5777 ins_pipe(pipe_slow); // XXX 5778%} 5779 5780// Prefetch instructions. 5781// Must be safe to execute with invalid address (cannot fault). 5782 5783instruct prefetchr( memory mem ) %{ 5784 predicate(ReadPrefetchInstr==3); 5785 match(PrefetchRead mem); 5786 ins_cost(125); 5787 5788 format %{ "PREFETCHR $mem\t# Prefetch into level 1 cache" %} 5789 ins_encode %{ 5790 __ prefetchr($mem$$Address); 5791 %} 5792 ins_pipe(ialu_mem); 5793%} 5794 5795instruct prefetchrNTA( memory mem ) %{ 5796 predicate(ReadPrefetchInstr==0); 5797 match(PrefetchRead mem); 5798 ins_cost(125); 5799 5800 format %{ "PREFETCHNTA $mem\t# Prefetch into non-temporal cache for read" %} 5801 ins_encode %{ 5802 __ prefetchnta($mem$$Address); 5803 %} 5804 ins_pipe(ialu_mem); 5805%} 5806 5807instruct prefetchrT0( memory mem ) %{ 5808 predicate(ReadPrefetchInstr==1); 5809 match(PrefetchRead mem); 5810 ins_cost(125); 5811 5812 format %{ "PREFETCHT0 $mem\t# prefetch into L1 and L2 caches for read" %} 5813 ins_encode %{ 5814 __ prefetcht0($mem$$Address); 5815 %} 5816 ins_pipe(ialu_mem); 5817%} 5818 5819instruct prefetchrT2( memory mem ) %{ 5820 predicate(ReadPrefetchInstr==2); 5821 match(PrefetchRead mem); 5822 ins_cost(125); 5823 5824 format %{ "PREFETCHT2 $mem\t# prefetch into L2 caches for read" %} 5825 ins_encode %{ 5826 __ prefetcht2($mem$$Address); 5827 %} 5828 ins_pipe(ialu_mem); 5829%} 5830 5831instruct prefetchwNTA( memory mem ) %{ 5832 match(PrefetchWrite mem); 5833 ins_cost(125); 5834 5835 format %{ "PREFETCHNTA $mem\t# Prefetch to non-temporal cache for write" %} 5836 ins_encode %{ 5837 __ prefetchnta($mem$$Address); 5838 %} 5839 ins_pipe(ialu_mem); 5840%} 5841 5842// Prefetch instructions for allocation. 5843 5844instruct prefetchAlloc( memory mem ) %{ 5845 predicate(AllocatePrefetchInstr==3); 5846 match(PrefetchAllocation mem); 5847 ins_cost(125); 5848 5849 format %{ "PREFETCHW $mem\t# Prefetch allocation into level 1 cache and mark modified" %} 5850 ins_encode %{ 5851 __ prefetchw($mem$$Address); 5852 %} 5853 ins_pipe(ialu_mem); 5854%} 5855 5856instruct prefetchAllocNTA( memory mem ) %{ 5857 predicate(AllocatePrefetchInstr==0); 5858 match(PrefetchAllocation mem); 5859 ins_cost(125); 5860 5861 format %{ "PREFETCHNTA $mem\t# Prefetch allocation to non-temporal cache for write" %} 5862 ins_encode %{ 5863 __ prefetchnta($mem$$Address); 5864 %} 5865 ins_pipe(ialu_mem); 5866%} 5867 5868instruct prefetchAllocT0( memory mem ) %{ 5869 predicate(AllocatePrefetchInstr==1); 5870 match(PrefetchAllocation mem); 5871 ins_cost(125); 5872 5873 format %{ "PREFETCHT0 $mem\t# Prefetch allocation to level 1 and 2 caches for write" %} 5874 ins_encode %{ 5875 __ prefetcht0($mem$$Address); 5876 %} 5877 ins_pipe(ialu_mem); 5878%} 5879 5880instruct prefetchAllocT2( memory mem ) %{ 5881 predicate(AllocatePrefetchInstr==2); 5882 match(PrefetchAllocation mem); 5883 ins_cost(125); 5884 5885 format %{ "PREFETCHT2 $mem\t# Prefetch allocation to level 2 cache for write" %} 5886 ins_encode %{ 5887 __ prefetcht2($mem$$Address); 5888 %} 5889 ins_pipe(ialu_mem); 5890%} 5891 5892//----------Store Instructions------------------------------------------------- 5893 5894// Store Byte 5895instruct storeB(memory mem, rRegI src) 5896%{ 5897 match(Set mem (StoreB mem src)); 5898 5899 ins_cost(125); // XXX 5900 format %{ "movb $mem, $src\t# byte" %} 5901 opcode(0x88); 5902 ins_encode(REX_breg_mem(src, mem), OpcP, reg_mem(src, mem)); 5903 ins_pipe(ialu_mem_reg); 5904%} 5905 5906// Store Char/Short 5907instruct storeC(memory mem, rRegI src) 5908%{ 5909 match(Set mem (StoreC mem src)); 5910 5911 ins_cost(125); // XXX 5912 format %{ "movw $mem, $src\t# char/short" %} 5913 opcode(0x89); 5914 ins_encode(SizePrefix, REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 5915 ins_pipe(ialu_mem_reg); 5916%} 5917 5918// Store Integer 5919instruct storeI(memory mem, rRegI src) 5920%{ 5921 match(Set mem (StoreI mem src)); 5922 5923 ins_cost(125); // XXX 5924 format %{ "movl $mem, $src\t# int" %} 5925 opcode(0x89); 5926 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 5927 ins_pipe(ialu_mem_reg); 5928%} 5929 5930// Store Long 5931instruct storeL(memory mem, rRegL src) 5932%{ 5933 match(Set mem (StoreL mem src)); 5934 5935 ins_cost(125); // XXX 5936 format %{ "movq $mem, $src\t# long" %} 5937 opcode(0x89); 5938 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 5939 ins_pipe(ialu_mem_reg); // XXX 5940%} 5941 5942// Store Pointer 5943instruct storeP(memory mem, any_RegP src) 5944%{ 5945 match(Set mem (StoreP mem src)); 5946 5947 ins_cost(125); // XXX 5948 format %{ "movq $mem, $src\t# ptr" %} 5949 opcode(0x89); 5950 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 5951 ins_pipe(ialu_mem_reg); 5952%} 5953 5954instruct storeImmP0(memory mem, immP0 zero) 5955%{ 5956 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5957 match(Set mem (StoreP mem zero)); 5958 5959 ins_cost(125); // XXX 5960 format %{ "movq $mem, R12\t# ptr (R12_heapbase==0)" %} 5961 ins_encode %{ 5962 __ movq($mem$$Address, r12); 5963 %} 5964 ins_pipe(ialu_mem_reg); 5965%} 5966 5967// Store NULL Pointer, mark word, or other simple pointer constant. 5968instruct storeImmP(memory mem, immP31 src) 5969%{ 5970 match(Set mem (StoreP mem src)); 5971 5972 ins_cost(150); // XXX 5973 format %{ "movq $mem, $src\t# ptr" %} 5974 opcode(0xC7); /* C7 /0 */ 5975 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 5976 ins_pipe(ialu_mem_imm); 5977%} 5978 5979// Store Compressed Pointer 5980instruct storeN(memory mem, rRegN src) 5981%{ 5982 match(Set mem (StoreN mem src)); 5983 5984 ins_cost(125); // XXX 5985 format %{ "movl $mem, $src\t# compressed ptr" %} 5986 ins_encode %{ 5987 __ movl($mem$$Address, $src$$Register); 5988 %} 5989 ins_pipe(ialu_mem_reg); 5990%} 5991 5992instruct storeNKlass(memory mem, rRegN src) 5993%{ 5994 match(Set mem (StoreNKlass mem src)); 5995 5996 ins_cost(125); // XXX 5997 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5998 ins_encode %{ 5999 __ movl($mem$$Address, $src$$Register); 6000 %} 6001 ins_pipe(ialu_mem_reg); 6002%} 6003 6004instruct storeImmN0(memory mem, immN0 zero) 6005%{ 6006 predicate(Universe::narrow_oop_base() == NULL && Universe::narrow_klass_base() == NULL); 6007 match(Set mem (StoreN mem zero)); 6008 6009 ins_cost(125); // XXX 6010 format %{ "movl $mem, R12\t# compressed ptr (R12_heapbase==0)" %} 6011 ins_encode %{ 6012 __ movl($mem$$Address, r12); 6013 %} 6014 ins_pipe(ialu_mem_reg); 6015%} 6016 6017instruct storeImmN(memory mem, immN src) 6018%{ 6019 match(Set mem (StoreN mem src)); 6020 6021 ins_cost(150); // XXX 6022 format %{ "movl $mem, $src\t# compressed ptr" %} 6023 ins_encode %{ 6024 address con = (address)$src$$constant; 6025 if (con == NULL) { 6026 __ movl($mem$$Address, (int32_t)0); 6027 } else { 6028 __ set_narrow_oop($mem$$Address, (jobject)$src$$constant); 6029 } 6030 %} 6031 ins_pipe(ialu_mem_imm); 6032%} 6033 6034instruct storeImmNKlass(memory mem, immNKlass src) 6035%{ 6036 match(Set mem (StoreNKlass mem src)); 6037 6038 ins_cost(150); // XXX 6039 format %{ "movl $mem, $src\t# compressed klass ptr" %} 6040 ins_encode %{ 6041 __ set_narrow_klass($mem$$Address, (Klass*)$src$$constant); 6042 %} 6043 ins_pipe(ialu_mem_imm); 6044%} 6045 6046// Store Integer Immediate 6047instruct storeImmI0(memory mem, immI0 zero) 6048%{ 6049 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6050 match(Set mem (StoreI mem zero)); 6051 6052 ins_cost(125); // XXX 6053 format %{ "movl $mem, R12\t# int (R12_heapbase==0)" %} 6054 ins_encode %{ 6055 __ movl($mem$$Address, r12); 6056 %} 6057 ins_pipe(ialu_mem_reg); 6058%} 6059 6060instruct storeImmI(memory mem, immI src) 6061%{ 6062 match(Set mem (StoreI mem src)); 6063 6064 ins_cost(150); 6065 format %{ "movl $mem, $src\t# int" %} 6066 opcode(0xC7); /* C7 /0 */ 6067 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 6068 ins_pipe(ialu_mem_imm); 6069%} 6070 6071// Store Long Immediate 6072instruct storeImmL0(memory mem, immL0 zero) 6073%{ 6074 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6075 match(Set mem (StoreL mem zero)); 6076 6077 ins_cost(125); // XXX 6078 format %{ "movq $mem, R12\t# long (R12_heapbase==0)" %} 6079 ins_encode %{ 6080 __ movq($mem$$Address, r12); 6081 %} 6082 ins_pipe(ialu_mem_reg); 6083%} 6084 6085instruct storeImmL(memory mem, immL32 src) 6086%{ 6087 match(Set mem (StoreL mem src)); 6088 6089 ins_cost(150); 6090 format %{ "movq $mem, $src\t# long" %} 6091 opcode(0xC7); /* C7 /0 */ 6092 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 6093 ins_pipe(ialu_mem_imm); 6094%} 6095 6096// Store Short/Char Immediate 6097instruct storeImmC0(memory mem, immI0 zero) 6098%{ 6099 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6100 match(Set mem (StoreC mem zero)); 6101 6102 ins_cost(125); // XXX 6103 format %{ "movw $mem, R12\t# short/char (R12_heapbase==0)" %} 6104 ins_encode %{ 6105 __ movw($mem$$Address, r12); 6106 %} 6107 ins_pipe(ialu_mem_reg); 6108%} 6109 6110instruct storeImmI16(memory mem, immI16 src) 6111%{ 6112 predicate(UseStoreImmI16); 6113 match(Set mem (StoreC mem src)); 6114 6115 ins_cost(150); 6116 format %{ "movw $mem, $src\t# short/char" %} 6117 opcode(0xC7); /* C7 /0 Same as 32 store immediate with prefix */ 6118 ins_encode(SizePrefix, REX_mem(mem), OpcP, RM_opc_mem(0x00, mem),Con16(src)); 6119 ins_pipe(ialu_mem_imm); 6120%} 6121 6122// Store Byte Immediate 6123instruct storeImmB0(memory mem, immI0 zero) 6124%{ 6125 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6126 match(Set mem (StoreB mem zero)); 6127 6128 ins_cost(125); // XXX 6129 format %{ "movb $mem, R12\t# short/char (R12_heapbase==0)" %} 6130 ins_encode %{ 6131 __ movb($mem$$Address, r12); 6132 %} 6133 ins_pipe(ialu_mem_reg); 6134%} 6135 6136instruct storeImmB(memory mem, immI8 src) 6137%{ 6138 match(Set mem (StoreB mem src)); 6139 6140 ins_cost(150); // XXX 6141 format %{ "movb $mem, $src\t# byte" %} 6142 opcode(0xC6); /* C6 /0 */ 6143 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src)); 6144 ins_pipe(ialu_mem_imm); 6145%} 6146 6147// Store CMS card-mark Immediate 6148instruct storeImmCM0_reg(memory mem, immI0 zero) 6149%{ 6150 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6151 match(Set mem (StoreCM mem zero)); 6152 6153 ins_cost(125); // XXX 6154 format %{ "movb $mem, R12\t# CMS card-mark byte 0 (R12_heapbase==0)" %} 6155 ins_encode %{ 6156 __ movb($mem$$Address, r12); 6157 %} 6158 ins_pipe(ialu_mem_reg); 6159%} 6160 6161instruct storeImmCM0(memory mem, immI0 src) 6162%{ 6163 match(Set mem (StoreCM mem src)); 6164 6165 ins_cost(150); // XXX 6166 format %{ "movb $mem, $src\t# CMS card-mark byte 0" %} 6167 opcode(0xC6); /* C6 /0 */ 6168 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src)); 6169 ins_pipe(ialu_mem_imm); 6170%} 6171 6172// Store Float 6173instruct storeF(memory mem, regF src) 6174%{ 6175 match(Set mem (StoreF mem src)); 6176 6177 ins_cost(95); // XXX 6178 format %{ "movss $mem, $src\t# float" %} 6179 ins_encode %{ 6180 __ movflt($mem$$Address, $src$$XMMRegister); 6181 %} 6182 ins_pipe(pipe_slow); // XXX 6183%} 6184 6185// Store immediate Float value (it is faster than store from XMM register) 6186instruct storeF0(memory mem, immF0 zero) 6187%{ 6188 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6189 match(Set mem (StoreF mem zero)); 6190 6191 ins_cost(25); // XXX 6192 format %{ "movl $mem, R12\t# float 0. (R12_heapbase==0)" %} 6193 ins_encode %{ 6194 __ movl($mem$$Address, r12); 6195 %} 6196 ins_pipe(ialu_mem_reg); 6197%} 6198 6199instruct storeF_imm(memory mem, immF src) 6200%{ 6201 match(Set mem (StoreF mem src)); 6202 6203 ins_cost(50); 6204 format %{ "movl $mem, $src\t# float" %} 6205 opcode(0xC7); /* C7 /0 */ 6206 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src)); 6207 ins_pipe(ialu_mem_imm); 6208%} 6209 6210// Store Double 6211instruct storeD(memory mem, regD src) 6212%{ 6213 match(Set mem (StoreD mem src)); 6214 6215 ins_cost(95); // XXX 6216 format %{ "movsd $mem, $src\t# double" %} 6217 ins_encode %{ 6218 __ movdbl($mem$$Address, $src$$XMMRegister); 6219 %} 6220 ins_pipe(pipe_slow); // XXX 6221%} 6222 6223// Store immediate double 0.0 (it is faster than store from XMM register) 6224instruct storeD0_imm(memory mem, immD0 src) 6225%{ 6226 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL)); 6227 match(Set mem (StoreD mem src)); 6228 6229 ins_cost(50); 6230 format %{ "movq $mem, $src\t# double 0." %} 6231 opcode(0xC7); /* C7 /0 */ 6232 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src)); 6233 ins_pipe(ialu_mem_imm); 6234%} 6235 6236instruct storeD0(memory mem, immD0 zero) 6237%{ 6238 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6239 match(Set mem (StoreD mem zero)); 6240 6241 ins_cost(25); // XXX 6242 format %{ "movq $mem, R12\t# double 0. (R12_heapbase==0)" %} 6243 ins_encode %{ 6244 __ movq($mem$$Address, r12); 6245 %} 6246 ins_pipe(ialu_mem_reg); 6247%} 6248 6249instruct storeSSI(stackSlotI dst, rRegI src) 6250%{ 6251 match(Set dst src); 6252 6253 ins_cost(100); 6254 format %{ "movl $dst, $src\t# int stk" %} 6255 opcode(0x89); 6256 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 6257 ins_pipe( ialu_mem_reg ); 6258%} 6259 6260instruct storeSSL(stackSlotL dst, rRegL src) 6261%{ 6262 match(Set dst src); 6263 6264 ins_cost(100); 6265 format %{ "movq $dst, $src\t# long stk" %} 6266 opcode(0x89); 6267 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 6268 ins_pipe(ialu_mem_reg); 6269%} 6270 6271instruct storeSSP(stackSlotP dst, rRegP src) 6272%{ 6273 match(Set dst src); 6274 6275 ins_cost(100); 6276 format %{ "movq $dst, $src\t# ptr stk" %} 6277 opcode(0x89); 6278 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 6279 ins_pipe(ialu_mem_reg); 6280%} 6281 6282instruct storeSSF(stackSlotF dst, regF src) 6283%{ 6284 match(Set dst src); 6285 6286 ins_cost(95); // XXX 6287 format %{ "movss $dst, $src\t# float stk" %} 6288 ins_encode %{ 6289 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 6290 %} 6291 ins_pipe(pipe_slow); // XXX 6292%} 6293 6294instruct storeSSD(stackSlotD dst, regD src) 6295%{ 6296 match(Set dst src); 6297 6298 ins_cost(95); // XXX 6299 format %{ "movsd $dst, $src\t# double stk" %} 6300 ins_encode %{ 6301 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 6302 %} 6303 ins_pipe(pipe_slow); // XXX 6304%} 6305 6306//----------BSWAP Instructions------------------------------------------------- 6307instruct bytes_reverse_int(rRegI dst) %{ 6308 match(Set dst (ReverseBytesI dst)); 6309 6310 format %{ "bswapl $dst" %} 6311 opcode(0x0F, 0xC8); /*Opcode 0F /C8 */ 6312 ins_encode( REX_reg(dst), OpcP, opc2_reg(dst) ); 6313 ins_pipe( ialu_reg ); 6314%} 6315 6316instruct bytes_reverse_long(rRegL dst) %{ 6317 match(Set dst (ReverseBytesL dst)); 6318 6319 format %{ "bswapq $dst" %} 6320 opcode(0x0F, 0xC8); /* Opcode 0F /C8 */ 6321 ins_encode( REX_reg_wide(dst), OpcP, opc2_reg(dst) ); 6322 ins_pipe( ialu_reg); 6323%} 6324 6325instruct bytes_reverse_unsigned_short(rRegI dst, rFlagsReg cr) %{ 6326 match(Set dst (ReverseBytesUS dst)); 6327 effect(KILL cr); 6328 6329 format %{ "bswapl $dst\n\t" 6330 "shrl $dst,16\n\t" %} 6331 ins_encode %{ 6332 __ bswapl($dst$$Register); 6333 __ shrl($dst$$Register, 16); 6334 %} 6335 ins_pipe( ialu_reg ); 6336%} 6337 6338instruct bytes_reverse_short(rRegI dst, rFlagsReg cr) %{ 6339 match(Set dst (ReverseBytesS dst)); 6340 effect(KILL cr); 6341 6342 format %{ "bswapl $dst\n\t" 6343 "sar $dst,16\n\t" %} 6344 ins_encode %{ 6345 __ bswapl($dst$$Register); 6346 __ sarl($dst$$Register, 16); 6347 %} 6348 ins_pipe( ialu_reg ); 6349%} 6350 6351//---------- Zeros Count Instructions ------------------------------------------ 6352 6353instruct countLeadingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6354 predicate(UseCountLeadingZerosInstruction); 6355 match(Set dst (CountLeadingZerosI src)); 6356 effect(KILL cr); 6357 6358 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 6359 ins_encode %{ 6360 __ lzcntl($dst$$Register, $src$$Register); 6361 %} 6362 ins_pipe(ialu_reg); 6363%} 6364 6365instruct countLeadingZerosI_bsr(rRegI dst, rRegI src, rFlagsReg cr) %{ 6366 predicate(!UseCountLeadingZerosInstruction); 6367 match(Set dst (CountLeadingZerosI src)); 6368 effect(KILL cr); 6369 6370 format %{ "bsrl $dst, $src\t# count leading zeros (int)\n\t" 6371 "jnz skip\n\t" 6372 "movl $dst, -1\n" 6373 "skip:\n\t" 6374 "negl $dst\n\t" 6375 "addl $dst, 31" %} 6376 ins_encode %{ 6377 Register Rdst = $dst$$Register; 6378 Register Rsrc = $src$$Register; 6379 Label skip; 6380 __ bsrl(Rdst, Rsrc); 6381 __ jccb(Assembler::notZero, skip); 6382 __ movl(Rdst, -1); 6383 __ bind(skip); 6384 __ negl(Rdst); 6385 __ addl(Rdst, BitsPerInt - 1); 6386 %} 6387 ins_pipe(ialu_reg); 6388%} 6389 6390instruct countLeadingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6391 predicate(UseCountLeadingZerosInstruction); 6392 match(Set dst (CountLeadingZerosL src)); 6393 effect(KILL cr); 6394 6395 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 6396 ins_encode %{ 6397 __ lzcntq($dst$$Register, $src$$Register); 6398 %} 6399 ins_pipe(ialu_reg); 6400%} 6401 6402instruct countLeadingZerosL_bsr(rRegI dst, rRegL src, rFlagsReg cr) %{ 6403 predicate(!UseCountLeadingZerosInstruction); 6404 match(Set dst (CountLeadingZerosL src)); 6405 effect(KILL cr); 6406 6407 format %{ "bsrq $dst, $src\t# count leading zeros (long)\n\t" 6408 "jnz skip\n\t" 6409 "movl $dst, -1\n" 6410 "skip:\n\t" 6411 "negl $dst\n\t" 6412 "addl $dst, 63" %} 6413 ins_encode %{ 6414 Register Rdst = $dst$$Register; 6415 Register Rsrc = $src$$Register; 6416 Label skip; 6417 __ bsrq(Rdst, Rsrc); 6418 __ jccb(Assembler::notZero, skip); 6419 __ movl(Rdst, -1); 6420 __ bind(skip); 6421 __ negl(Rdst); 6422 __ addl(Rdst, BitsPerLong - 1); 6423 %} 6424 ins_pipe(ialu_reg); 6425%} 6426 6427instruct countTrailingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6428 match(Set dst (CountTrailingZerosI src)); 6429 effect(KILL cr); 6430 6431 format %{ "bsfl $dst, $src\t# count trailing zeros (int)\n\t" 6432 "jnz done\n\t" 6433 "movl $dst, 32\n" 6434 "done:" %} 6435 ins_encode %{ 6436 Register Rdst = $dst$$Register; 6437 Label done; 6438 __ bsfl(Rdst, $src$$Register); 6439 __ jccb(Assembler::notZero, done); 6440 __ movl(Rdst, BitsPerInt); 6441 __ bind(done); 6442 %} 6443 ins_pipe(ialu_reg); 6444%} 6445 6446instruct countTrailingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6447 match(Set dst (CountTrailingZerosL src)); 6448 effect(KILL cr); 6449 6450 format %{ "bsfq $dst, $src\t# count trailing zeros (long)\n\t" 6451 "jnz done\n\t" 6452 "movl $dst, 64\n" 6453 "done:" %} 6454 ins_encode %{ 6455 Register Rdst = $dst$$Register; 6456 Label done; 6457 __ bsfq(Rdst, $src$$Register); 6458 __ jccb(Assembler::notZero, done); 6459 __ movl(Rdst, BitsPerLong); 6460 __ bind(done); 6461 %} 6462 ins_pipe(ialu_reg); 6463%} 6464 6465 6466//---------- Population Count Instructions ------------------------------------- 6467 6468instruct popCountI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6469 predicate(UsePopCountInstruction); 6470 match(Set dst (PopCountI src)); 6471 effect(KILL cr); 6472 6473 format %{ "popcnt $dst, $src" %} 6474 ins_encode %{ 6475 __ popcntl($dst$$Register, $src$$Register); 6476 %} 6477 ins_pipe(ialu_reg); 6478%} 6479 6480instruct popCountI_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 6481 predicate(UsePopCountInstruction); 6482 match(Set dst (PopCountI (LoadI mem))); 6483 effect(KILL cr); 6484 6485 format %{ "popcnt $dst, $mem" %} 6486 ins_encode %{ 6487 __ popcntl($dst$$Register, $mem$$Address); 6488 %} 6489 ins_pipe(ialu_reg); 6490%} 6491 6492// Note: Long.bitCount(long) returns an int. 6493instruct popCountL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6494 predicate(UsePopCountInstruction); 6495 match(Set dst (PopCountL src)); 6496 effect(KILL cr); 6497 6498 format %{ "popcnt $dst, $src" %} 6499 ins_encode %{ 6500 __ popcntq($dst$$Register, $src$$Register); 6501 %} 6502 ins_pipe(ialu_reg); 6503%} 6504 6505// Note: Long.bitCount(long) returns an int. 6506instruct popCountL_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 6507 predicate(UsePopCountInstruction); 6508 match(Set dst (PopCountL (LoadL mem))); 6509 effect(KILL cr); 6510 6511 format %{ "popcnt $dst, $mem" %} 6512 ins_encode %{ 6513 __ popcntq($dst$$Register, $mem$$Address); 6514 %} 6515 ins_pipe(ialu_reg); 6516%} 6517 6518 6519//----------MemBar Instructions----------------------------------------------- 6520// Memory barrier flavors 6521 6522instruct membar_acquire() 6523%{ 6524 match(MemBarAcquire); 6525 ins_cost(0); 6526 6527 size(0); 6528 format %{ "MEMBAR-acquire ! (empty encoding)" %} 6529 ins_encode(); 6530 ins_pipe(empty); 6531%} 6532 6533instruct membar_acquire_lock() 6534%{ 6535 match(MemBarAcquireLock); 6536 ins_cost(0); 6537 6538 size(0); 6539 format %{ "MEMBAR-acquire (prior CMPXCHG in FastLock so empty encoding)" %} 6540 ins_encode(); 6541 ins_pipe(empty); 6542%} 6543 6544instruct membar_release() 6545%{ 6546 match(MemBarRelease); 6547 ins_cost(0); 6548 6549 size(0); 6550 format %{ "MEMBAR-release ! (empty encoding)" %} 6551 ins_encode(); 6552 ins_pipe(empty); 6553%} 6554 6555instruct membar_release_lock() 6556%{ 6557 match(MemBarReleaseLock); 6558 ins_cost(0); 6559 6560 size(0); 6561 format %{ "MEMBAR-release (a FastUnlock follows so empty encoding)" %} 6562 ins_encode(); 6563 ins_pipe(empty); 6564%} 6565 6566instruct membar_volatile(rFlagsReg cr) %{ 6567 match(MemBarVolatile); 6568 effect(KILL cr); 6569 ins_cost(400); 6570 6571 format %{ 6572 $$template 6573 if (os::is_MP()) { 6574 $$emit$$"lock addl [rsp + #0], 0\t! membar_volatile" 6575 } else { 6576 $$emit$$"MEMBAR-volatile ! (empty encoding)" 6577 } 6578 %} 6579 ins_encode %{ 6580 __ membar(Assembler::StoreLoad); 6581 %} 6582 ins_pipe(pipe_slow); 6583%} 6584 6585instruct unnecessary_membar_volatile() 6586%{ 6587 match(MemBarVolatile); 6588 predicate(Matcher::post_store_load_barrier(n)); 6589 ins_cost(0); 6590 6591 size(0); 6592 format %{ "MEMBAR-volatile (unnecessary so empty encoding)" %} 6593 ins_encode(); 6594 ins_pipe(empty); 6595%} 6596 6597instruct membar_storestore() %{ 6598 match(MemBarStoreStore); 6599 ins_cost(0); 6600 6601 size(0); 6602 format %{ "MEMBAR-storestore (empty encoding)" %} 6603 ins_encode( ); 6604 ins_pipe(empty); 6605%} 6606 6607//----------Move Instructions-------------------------------------------------- 6608 6609instruct castX2P(rRegP dst, rRegL src) 6610%{ 6611 match(Set dst (CastX2P src)); 6612 6613 format %{ "movq $dst, $src\t# long->ptr" %} 6614 ins_encode %{ 6615 if ($dst$$reg != $src$$reg) { 6616 __ movptr($dst$$Register, $src$$Register); 6617 } 6618 %} 6619 ins_pipe(ialu_reg_reg); // XXX 6620%} 6621 6622instruct castP2X(rRegL dst, rRegP src) 6623%{ 6624 match(Set dst (CastP2X src)); 6625 6626 format %{ "movq $dst, $src\t# ptr -> long" %} 6627 ins_encode %{ 6628 if ($dst$$reg != $src$$reg) { 6629 __ movptr($dst$$Register, $src$$Register); 6630 } 6631 %} 6632 ins_pipe(ialu_reg_reg); // XXX 6633%} 6634 6635// Convert oop into int for vectors alignment masking 6636instruct convP2I(rRegI dst, rRegP src) 6637%{ 6638 match(Set dst (ConvL2I (CastP2X src))); 6639 6640 format %{ "movl $dst, $src\t# ptr -> int" %} 6641 ins_encode %{ 6642 __ movl($dst$$Register, $src$$Register); 6643 %} 6644 ins_pipe(ialu_reg_reg); // XXX 6645%} 6646 6647// Convert compressed oop into int for vectors alignment masking 6648// in case of 32bit oops (heap < 4Gb). 6649instruct convN2I(rRegI dst, rRegN src) 6650%{ 6651 predicate(Universe::narrow_oop_shift() == 0); 6652 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 6653 6654 format %{ "movl $dst, $src\t# compressed ptr -> int" %} 6655 ins_encode %{ 6656 __ movl($dst$$Register, $src$$Register); 6657 %} 6658 ins_pipe(ialu_reg_reg); // XXX 6659%} 6660 6661// Convert oop pointer into compressed form 6662instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{ 6663 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 6664 match(Set dst (EncodeP src)); 6665 effect(KILL cr); 6666 format %{ "encode_heap_oop $dst,$src" %} 6667 ins_encode %{ 6668 Register s = $src$$Register; 6669 Register d = $dst$$Register; 6670 if (s != d) { 6671 __ movq(d, s); 6672 } 6673 __ encode_heap_oop(d); 6674 %} 6675 ins_pipe(ialu_reg_long); 6676%} 6677 6678instruct encodeHeapOop_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6679 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 6680 match(Set dst (EncodeP src)); 6681 effect(KILL cr); 6682 format %{ "encode_heap_oop_not_null $dst,$src" %} 6683 ins_encode %{ 6684 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 6685 %} 6686 ins_pipe(ialu_reg_long); 6687%} 6688 6689instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{ 6690 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 6691 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 6692 match(Set dst (DecodeN src)); 6693 effect(KILL cr); 6694 format %{ "decode_heap_oop $dst,$src" %} 6695 ins_encode %{ 6696 Register s = $src$$Register; 6697 Register d = $dst$$Register; 6698 if (s != d) { 6699 __ movq(d, s); 6700 } 6701 __ decode_heap_oop(d); 6702 %} 6703 ins_pipe(ialu_reg_long); 6704%} 6705 6706instruct decodeHeapOop_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6707 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 6708 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 6709 match(Set dst (DecodeN src)); 6710 effect(KILL cr); 6711 format %{ "decode_heap_oop_not_null $dst,$src" %} 6712 ins_encode %{ 6713 Register s = $src$$Register; 6714 Register d = $dst$$Register; 6715 if (s != d) { 6716 __ decode_heap_oop_not_null(d, s); 6717 } else { 6718 __ decode_heap_oop_not_null(d); 6719 } 6720 %} 6721 ins_pipe(ialu_reg_long); 6722%} 6723 6724instruct encodeKlass_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6725 match(Set dst (EncodePKlass src)); 6726 effect(KILL cr); 6727 format %{ "encode_heap_oop_not_null $dst,$src" %} 6728 ins_encode %{ 6729 __ encode_klass_not_null($dst$$Register, $src$$Register); 6730 %} 6731 ins_pipe(ialu_reg_long); 6732%} 6733 6734instruct decodeKlass_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6735 match(Set dst (DecodeNKlass src)); 6736 effect(KILL cr); 6737 format %{ "decode_heap_oop_not_null $dst,$src" %} 6738 ins_encode %{ 6739 Register s = $src$$Register; 6740 Register d = $dst$$Register; 6741 if (s != d) { 6742 __ decode_klass_not_null(d, s); 6743 } else { 6744 __ decode_klass_not_null(d); 6745 } 6746 %} 6747 ins_pipe(ialu_reg_long); 6748%} 6749 6750 6751//----------Conditional Move--------------------------------------------------- 6752// Jump 6753// dummy instruction for generating temp registers 6754instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{ 6755 match(Jump (LShiftL switch_val shift)); 6756 ins_cost(350); 6757 predicate(false); 6758 effect(TEMP dest); 6759 6760 format %{ "leaq $dest, [$constantaddress]\n\t" 6761 "jmp [$dest + $switch_val << $shift]\n\t" %} 6762 ins_encode %{ 6763 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6764 // to do that and the compiler is using that register as one it can allocate. 6765 // So we build it all by hand. 6766 // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant); 6767 // ArrayAddress dispatch(table, index); 6768 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant); 6769 __ lea($dest$$Register, $constantaddress); 6770 __ jmp(dispatch); 6771 %} 6772 ins_pipe(pipe_jmp); 6773%} 6774 6775instruct jumpXtnd_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{ 6776 match(Jump (AddL (LShiftL switch_val shift) offset)); 6777 ins_cost(350); 6778 effect(TEMP dest); 6779 6780 format %{ "leaq $dest, [$constantaddress]\n\t" 6781 "jmp [$dest + $switch_val << $shift + $offset]\n\t" %} 6782 ins_encode %{ 6783 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6784 // to do that and the compiler is using that register as one it can allocate. 6785 // So we build it all by hand. 6786 // Address index(noreg, switch_reg, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6787 // ArrayAddress dispatch(table, index); 6788 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6789 __ lea($dest$$Register, $constantaddress); 6790 __ jmp(dispatch); 6791 %} 6792 ins_pipe(pipe_jmp); 6793%} 6794 6795instruct jumpXtnd(rRegL switch_val, rRegI dest) %{ 6796 match(Jump switch_val); 6797 ins_cost(350); 6798 effect(TEMP dest); 6799 6800 format %{ "leaq $dest, [$constantaddress]\n\t" 6801 "jmp [$dest + $switch_val]\n\t" %} 6802 ins_encode %{ 6803 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6804 // to do that and the compiler is using that register as one it can allocate. 6805 // So we build it all by hand. 6806 // Address index(noreg, switch_reg, Address::times_1); 6807 // ArrayAddress dispatch(table, index); 6808 Address dispatch($dest$$Register, $switch_val$$Register, Address::times_1); 6809 __ lea($dest$$Register, $constantaddress); 6810 __ jmp(dispatch); 6811 %} 6812 ins_pipe(pipe_jmp); 6813%} 6814 6815// Conditional move 6816instruct cmovI_reg(rRegI dst, rRegI src, rFlagsReg cr, cmpOp cop) 6817%{ 6818 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6819 6820 ins_cost(200); // XXX 6821 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6822 opcode(0x0F, 0x40); 6823 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6824 ins_pipe(pipe_cmov_reg); 6825%} 6826 6827instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{ 6828 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6829 6830 ins_cost(200); // XXX 6831 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6832 opcode(0x0F, 0x40); 6833 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6834 ins_pipe(pipe_cmov_reg); 6835%} 6836 6837instruct cmovI_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6838 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6839 ins_cost(200); 6840 expand %{ 6841 cmovI_regU(cop, cr, dst, src); 6842 %} 6843%} 6844 6845// Conditional move 6846instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{ 6847 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6848 6849 ins_cost(250); // XXX 6850 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6851 opcode(0x0F, 0x40); 6852 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6853 ins_pipe(pipe_cmov_mem); 6854%} 6855 6856// Conditional move 6857instruct cmovI_memU(cmpOpU cop, rFlagsRegU cr, rRegI dst, memory src) 6858%{ 6859 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6860 6861 ins_cost(250); // XXX 6862 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6863 opcode(0x0F, 0x40); 6864 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6865 ins_pipe(pipe_cmov_mem); 6866%} 6867 6868instruct cmovI_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, memory src) %{ 6869 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6870 ins_cost(250); 6871 expand %{ 6872 cmovI_memU(cop, cr, dst, src); 6873 %} 6874%} 6875 6876// Conditional move 6877instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop) 6878%{ 6879 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6880 6881 ins_cost(200); // XXX 6882 format %{ "cmovl$cop $dst, $src\t# signed, compressed ptr" %} 6883 opcode(0x0F, 0x40); 6884 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6885 ins_pipe(pipe_cmov_reg); 6886%} 6887 6888// Conditional move 6889instruct cmovN_regU(cmpOpU cop, rFlagsRegU cr, rRegN dst, rRegN src) 6890%{ 6891 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6892 6893 ins_cost(200); // XXX 6894 format %{ "cmovl$cop $dst, $src\t# unsigned, compressed ptr" %} 6895 opcode(0x0F, 0x40); 6896 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6897 ins_pipe(pipe_cmov_reg); 6898%} 6899 6900instruct cmovN_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6901 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6902 ins_cost(200); 6903 expand %{ 6904 cmovN_regU(cop, cr, dst, src); 6905 %} 6906%} 6907 6908// Conditional move 6909instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop) 6910%{ 6911 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6912 6913 ins_cost(200); // XXX 6914 format %{ "cmovq$cop $dst, $src\t# signed, ptr" %} 6915 opcode(0x0F, 0x40); 6916 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6917 ins_pipe(pipe_cmov_reg); // XXX 6918%} 6919 6920// Conditional move 6921instruct cmovP_regU(cmpOpU cop, rFlagsRegU cr, rRegP dst, rRegP src) 6922%{ 6923 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6924 6925 ins_cost(200); // XXX 6926 format %{ "cmovq$cop $dst, $src\t# unsigned, ptr" %} 6927 opcode(0x0F, 0x40); 6928 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6929 ins_pipe(pipe_cmov_reg); // XXX 6930%} 6931 6932instruct cmovP_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6933 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6934 ins_cost(200); 6935 expand %{ 6936 cmovP_regU(cop, cr, dst, src); 6937 %} 6938%} 6939 6940// DISABLED: Requires the ADLC to emit a bottom_type call that 6941// correctly meets the two pointer arguments; one is an incoming 6942// register but the other is a memory operand. ALSO appears to 6943// be buggy with implicit null checks. 6944// 6945//// Conditional move 6946//instruct cmovP_mem(cmpOp cop, rFlagsReg cr, rRegP dst, memory src) 6947//%{ 6948// match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); 6949// ins_cost(250); 6950// format %{ "CMOV$cop $dst,$src\t# ptr" %} 6951// opcode(0x0F,0x40); 6952// ins_encode( enc_cmov(cop), reg_mem( dst, src ) ); 6953// ins_pipe( pipe_cmov_mem ); 6954//%} 6955// 6956//// Conditional move 6957//instruct cmovP_memU(cmpOpU cop, rFlagsRegU cr, rRegP dst, memory src) 6958//%{ 6959// match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); 6960// ins_cost(250); 6961// format %{ "CMOV$cop $dst,$src\t# ptr" %} 6962// opcode(0x0F,0x40); 6963// ins_encode( enc_cmov(cop), reg_mem( dst, src ) ); 6964// ins_pipe( pipe_cmov_mem ); 6965//%} 6966 6967instruct cmovL_reg(cmpOp cop, rFlagsReg cr, rRegL dst, rRegL src) 6968%{ 6969 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6970 6971 ins_cost(200); // XXX 6972 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6973 opcode(0x0F, 0x40); 6974 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6975 ins_pipe(pipe_cmov_reg); // XXX 6976%} 6977 6978instruct cmovL_mem(cmpOp cop, rFlagsReg cr, rRegL dst, memory src) 6979%{ 6980 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6981 6982 ins_cost(200); // XXX 6983 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6984 opcode(0x0F, 0x40); 6985 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6986 ins_pipe(pipe_cmov_mem); // XXX 6987%} 6988 6989instruct cmovL_regU(cmpOpU cop, rFlagsRegU cr, rRegL dst, rRegL src) 6990%{ 6991 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6992 6993 ins_cost(200); // XXX 6994 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 6995 opcode(0x0F, 0x40); 6996 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6997 ins_pipe(pipe_cmov_reg); // XXX 6998%} 6999 7000instruct cmovL_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 7001 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 7002 ins_cost(200); 7003 expand %{ 7004 cmovL_regU(cop, cr, dst, src); 7005 %} 7006%} 7007 7008instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src) 7009%{ 7010 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 7011 7012 ins_cost(200); // XXX 7013 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 7014 opcode(0x0F, 0x40); 7015 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src)); 7016 ins_pipe(pipe_cmov_mem); // XXX 7017%} 7018 7019instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{ 7020 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 7021 ins_cost(200); 7022 expand %{ 7023 cmovL_memU(cop, cr, dst, src); 7024 %} 7025%} 7026 7027instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src) 7028%{ 7029 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7030 7031 ins_cost(200); // XXX 7032 format %{ "jn$cop skip\t# signed cmove float\n\t" 7033 "movss $dst, $src\n" 7034 "skip:" %} 7035 ins_encode %{ 7036 Label Lskip; 7037 // Invert sense of branch from sense of CMOV 7038 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7039 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 7040 __ bind(Lskip); 7041 %} 7042 ins_pipe(pipe_slow); 7043%} 7044 7045// instruct cmovF_mem(cmpOp cop, rFlagsReg cr, regF dst, memory src) 7046// %{ 7047// match(Set dst (CMoveF (Binary cop cr) (Binary dst (LoadL src)))); 7048 7049// ins_cost(200); // XXX 7050// format %{ "jn$cop skip\t# signed cmove float\n\t" 7051// "movss $dst, $src\n" 7052// "skip:" %} 7053// ins_encode(enc_cmovf_mem_branch(cop, dst, src)); 7054// ins_pipe(pipe_slow); 7055// %} 7056 7057instruct cmovF_regU(cmpOpU cop, rFlagsRegU cr, regF dst, regF src) 7058%{ 7059 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7060 7061 ins_cost(200); // XXX 7062 format %{ "jn$cop skip\t# unsigned cmove float\n\t" 7063 "movss $dst, $src\n" 7064 "skip:" %} 7065 ins_encode %{ 7066 Label Lskip; 7067 // Invert sense of branch from sense of CMOV 7068 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7069 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 7070 __ bind(Lskip); 7071 %} 7072 ins_pipe(pipe_slow); 7073%} 7074 7075instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{ 7076 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7077 ins_cost(200); 7078 expand %{ 7079 cmovF_regU(cop, cr, dst, src); 7080 %} 7081%} 7082 7083instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src) 7084%{ 7085 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7086 7087 ins_cost(200); // XXX 7088 format %{ "jn$cop skip\t# signed cmove double\n\t" 7089 "movsd $dst, $src\n" 7090 "skip:" %} 7091 ins_encode %{ 7092 Label Lskip; 7093 // Invert sense of branch from sense of CMOV 7094 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7095 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 7096 __ bind(Lskip); 7097 %} 7098 ins_pipe(pipe_slow); 7099%} 7100 7101instruct cmovD_regU(cmpOpU cop, rFlagsRegU cr, regD dst, regD src) 7102%{ 7103 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7104 7105 ins_cost(200); // XXX 7106 format %{ "jn$cop skip\t# unsigned cmove double\n\t" 7107 "movsd $dst, $src\n" 7108 "skip:" %} 7109 ins_encode %{ 7110 Label Lskip; 7111 // Invert sense of branch from sense of CMOV 7112 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7113 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 7114 __ bind(Lskip); 7115 %} 7116 ins_pipe(pipe_slow); 7117%} 7118 7119instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{ 7120 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7121 ins_cost(200); 7122 expand %{ 7123 cmovD_regU(cop, cr, dst, src); 7124 %} 7125%} 7126 7127//----------Arithmetic Instructions-------------------------------------------- 7128//----------Addition Instructions---------------------------------------------- 7129 7130instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7131%{ 7132 match(Set dst (AddI dst src)); 7133 effect(KILL cr); 7134 7135 format %{ "addl $dst, $src\t# int" %} 7136 opcode(0x03); 7137 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 7138 ins_pipe(ialu_reg_reg); 7139%} 7140 7141instruct addI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 7142%{ 7143 match(Set dst (AddI dst src)); 7144 effect(KILL cr); 7145 7146 format %{ "addl $dst, $src\t# int" %} 7147 opcode(0x81, 0x00); /* /0 id */ 7148 ins_encode(OpcSErm(dst, src), Con8or32(src)); 7149 ins_pipe( ialu_reg ); 7150%} 7151 7152instruct addI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 7153%{ 7154 match(Set dst (AddI dst (LoadI src))); 7155 effect(KILL cr); 7156 7157 ins_cost(125); // XXX 7158 format %{ "addl $dst, $src\t# int" %} 7159 opcode(0x03); 7160 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 7161 ins_pipe(ialu_reg_mem); 7162%} 7163 7164instruct addI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 7165%{ 7166 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7167 effect(KILL cr); 7168 7169 ins_cost(150); // XXX 7170 format %{ "addl $dst, $src\t# int" %} 7171 opcode(0x01); /* Opcode 01 /r */ 7172 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 7173 ins_pipe(ialu_mem_reg); 7174%} 7175 7176instruct addI_mem_imm(memory dst, immI src, rFlagsReg cr) 7177%{ 7178 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7179 effect(KILL cr); 7180 7181 ins_cost(125); // XXX 7182 format %{ "addl $dst, $src\t# int" %} 7183 opcode(0x81); /* Opcode 81 /0 id */ 7184 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src)); 7185 ins_pipe(ialu_mem_imm); 7186%} 7187 7188instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr) 7189%{ 7190 predicate(UseIncDec); 7191 match(Set dst (AddI dst src)); 7192 effect(KILL cr); 7193 7194 format %{ "incl $dst\t# int" %} 7195 opcode(0xFF, 0x00); // FF /0 7196 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7197 ins_pipe(ialu_reg); 7198%} 7199 7200instruct incI_mem(memory dst, immI1 src, rFlagsReg cr) 7201%{ 7202 predicate(UseIncDec); 7203 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7204 effect(KILL cr); 7205 7206 ins_cost(125); // XXX 7207 format %{ "incl $dst\t# int" %} 7208 opcode(0xFF); /* Opcode FF /0 */ 7209 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x00, dst)); 7210 ins_pipe(ialu_mem_imm); 7211%} 7212 7213// XXX why does that use AddI 7214instruct decI_rReg(rRegI dst, immI_M1 src, rFlagsReg cr) 7215%{ 7216 predicate(UseIncDec); 7217 match(Set dst (AddI dst src)); 7218 effect(KILL cr); 7219 7220 format %{ "decl $dst\t# int" %} 7221 opcode(0xFF, 0x01); // FF /1 7222 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7223 ins_pipe(ialu_reg); 7224%} 7225 7226// XXX why does that use AddI 7227instruct decI_mem(memory dst, immI_M1 src, rFlagsReg cr) 7228%{ 7229 predicate(UseIncDec); 7230 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7231 effect(KILL cr); 7232 7233 ins_cost(125); // XXX 7234 format %{ "decl $dst\t# int" %} 7235 opcode(0xFF); /* Opcode FF /1 */ 7236 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x01, dst)); 7237 ins_pipe(ialu_mem_imm); 7238%} 7239 7240instruct leaI_rReg_immI(rRegI dst, rRegI src0, immI src1) 7241%{ 7242 match(Set dst (AddI src0 src1)); 7243 7244 ins_cost(110); 7245 format %{ "addr32 leal $dst, [$src0 + $src1]\t# int" %} 7246 opcode(0x8D); /* 0x8D /r */ 7247 ins_encode(Opcode(0x67), REX_reg_reg(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX 7248 ins_pipe(ialu_reg_reg); 7249%} 7250 7251instruct addL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7252%{ 7253 match(Set dst (AddL dst src)); 7254 effect(KILL cr); 7255 7256 format %{ "addq $dst, $src\t# long" %} 7257 opcode(0x03); 7258 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7259 ins_pipe(ialu_reg_reg); 7260%} 7261 7262instruct addL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 7263%{ 7264 match(Set dst (AddL dst src)); 7265 effect(KILL cr); 7266 7267 format %{ "addq $dst, $src\t# long" %} 7268 opcode(0x81, 0x00); /* /0 id */ 7269 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7270 ins_pipe( ialu_reg ); 7271%} 7272 7273instruct addL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 7274%{ 7275 match(Set dst (AddL dst (LoadL src))); 7276 effect(KILL cr); 7277 7278 ins_cost(125); // XXX 7279 format %{ "addq $dst, $src\t# long" %} 7280 opcode(0x03); 7281 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 7282 ins_pipe(ialu_reg_mem); 7283%} 7284 7285instruct addL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 7286%{ 7287 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7288 effect(KILL cr); 7289 7290 ins_cost(150); // XXX 7291 format %{ "addq $dst, $src\t# long" %} 7292 opcode(0x01); /* Opcode 01 /r */ 7293 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 7294 ins_pipe(ialu_mem_reg); 7295%} 7296 7297instruct addL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 7298%{ 7299 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7300 effect(KILL cr); 7301 7302 ins_cost(125); // XXX 7303 format %{ "addq $dst, $src\t# long" %} 7304 opcode(0x81); /* Opcode 81 /0 id */ 7305 ins_encode(REX_mem_wide(dst), 7306 OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src)); 7307 ins_pipe(ialu_mem_imm); 7308%} 7309 7310instruct incL_rReg(rRegI dst, immL1 src, rFlagsReg cr) 7311%{ 7312 predicate(UseIncDec); 7313 match(Set dst (AddL dst src)); 7314 effect(KILL cr); 7315 7316 format %{ "incq $dst\t# long" %} 7317 opcode(0xFF, 0x00); // FF /0 7318 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 7319 ins_pipe(ialu_reg); 7320%} 7321 7322instruct incL_mem(memory dst, immL1 src, rFlagsReg cr) 7323%{ 7324 predicate(UseIncDec); 7325 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7326 effect(KILL cr); 7327 7328 ins_cost(125); // XXX 7329 format %{ "incq $dst\t# long" %} 7330 opcode(0xFF); /* Opcode FF /0 */ 7331 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x00, dst)); 7332 ins_pipe(ialu_mem_imm); 7333%} 7334 7335// XXX why does that use AddL 7336instruct decL_rReg(rRegL dst, immL_M1 src, rFlagsReg cr) 7337%{ 7338 predicate(UseIncDec); 7339 match(Set dst (AddL dst src)); 7340 effect(KILL cr); 7341 7342 format %{ "decq $dst\t# long" %} 7343 opcode(0xFF, 0x01); // FF /1 7344 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 7345 ins_pipe(ialu_reg); 7346%} 7347 7348// XXX why does that use AddL 7349instruct decL_mem(memory dst, immL_M1 src, rFlagsReg cr) 7350%{ 7351 predicate(UseIncDec); 7352 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7353 effect(KILL cr); 7354 7355 ins_cost(125); // XXX 7356 format %{ "decq $dst\t# long" %} 7357 opcode(0xFF); /* Opcode FF /1 */ 7358 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x01, dst)); 7359 ins_pipe(ialu_mem_imm); 7360%} 7361 7362instruct leaL_rReg_immL(rRegL dst, rRegL src0, immL32 src1) 7363%{ 7364 match(Set dst (AddL src0 src1)); 7365 7366 ins_cost(110); 7367 format %{ "leaq $dst, [$src0 + $src1]\t# long" %} 7368 opcode(0x8D); /* 0x8D /r */ 7369 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX 7370 ins_pipe(ialu_reg_reg); 7371%} 7372 7373instruct addP_rReg(rRegP dst, rRegL src, rFlagsReg cr) 7374%{ 7375 match(Set dst (AddP dst src)); 7376 effect(KILL cr); 7377 7378 format %{ "addq $dst, $src\t# ptr" %} 7379 opcode(0x03); 7380 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7381 ins_pipe(ialu_reg_reg); 7382%} 7383 7384instruct addP_rReg_imm(rRegP dst, immL32 src, rFlagsReg cr) 7385%{ 7386 match(Set dst (AddP dst src)); 7387 effect(KILL cr); 7388 7389 format %{ "addq $dst, $src\t# ptr" %} 7390 opcode(0x81, 0x00); /* /0 id */ 7391 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7392 ins_pipe( ialu_reg ); 7393%} 7394 7395// XXX addP mem ops ???? 7396 7397instruct leaP_rReg_imm(rRegP dst, rRegP src0, immL32 src1) 7398%{ 7399 match(Set dst (AddP src0 src1)); 7400 7401 ins_cost(110); 7402 format %{ "leaq $dst, [$src0 + $src1]\t# ptr" %} 7403 opcode(0x8D); /* 0x8D /r */ 7404 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1));// XXX 7405 ins_pipe(ialu_reg_reg); 7406%} 7407 7408instruct checkCastPP(rRegP dst) 7409%{ 7410 match(Set dst (CheckCastPP dst)); 7411 7412 size(0); 7413 format %{ "# checkcastPP of $dst" %} 7414 ins_encode(/* empty encoding */); 7415 ins_pipe(empty); 7416%} 7417 7418instruct castPP(rRegP dst) 7419%{ 7420 match(Set dst (CastPP dst)); 7421 7422 size(0); 7423 format %{ "# castPP of $dst" %} 7424 ins_encode(/* empty encoding */); 7425 ins_pipe(empty); 7426%} 7427 7428instruct castII(rRegI dst) 7429%{ 7430 match(Set dst (CastII dst)); 7431 7432 size(0); 7433 format %{ "# castII of $dst" %} 7434 ins_encode(/* empty encoding */); 7435 ins_cost(0); 7436 ins_pipe(empty); 7437%} 7438 7439// LoadP-locked same as a regular LoadP when used with compare-swap 7440instruct loadPLocked(rRegP dst, memory mem) 7441%{ 7442 match(Set dst (LoadPLocked mem)); 7443 7444 ins_cost(125); // XXX 7445 format %{ "movq $dst, $mem\t# ptr locked" %} 7446 opcode(0x8B); 7447 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 7448 ins_pipe(ialu_reg_mem); // XXX 7449%} 7450 7451// Conditional-store of the updated heap-top. 7452// Used during allocation of the shared heap. 7453// Sets flags (EQ) on success. Implemented with a CMPXCHG on Intel. 7454 7455instruct storePConditional(memory heap_top_ptr, 7456 rax_RegP oldval, rRegP newval, 7457 rFlagsReg cr) 7458%{ 7459 match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval))); 7460 7461 format %{ "cmpxchgq $heap_top_ptr, $newval\t# (ptr) " 7462 "If rax == $heap_top_ptr then store $newval into $heap_top_ptr" %} 7463 opcode(0x0F, 0xB1); 7464 ins_encode(lock_prefix, 7465 REX_reg_mem_wide(newval, heap_top_ptr), 7466 OpcP, OpcS, 7467 reg_mem(newval, heap_top_ptr)); 7468 ins_pipe(pipe_cmpxchg); 7469%} 7470 7471// Conditional-store of an int value. 7472// ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG. 7473instruct storeIConditional(memory mem, rax_RegI oldval, rRegI newval, rFlagsReg cr) 7474%{ 7475 match(Set cr (StoreIConditional mem (Binary oldval newval))); 7476 effect(KILL oldval); 7477 7478 format %{ "cmpxchgl $mem, $newval\t# If rax == $mem then store $newval into $mem" %} 7479 opcode(0x0F, 0xB1); 7480 ins_encode(lock_prefix, 7481 REX_reg_mem(newval, mem), 7482 OpcP, OpcS, 7483 reg_mem(newval, mem)); 7484 ins_pipe(pipe_cmpxchg); 7485%} 7486 7487// Conditional-store of a long value. 7488// ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG. 7489instruct storeLConditional(memory mem, rax_RegL oldval, rRegL newval, rFlagsReg cr) 7490%{ 7491 match(Set cr (StoreLConditional mem (Binary oldval newval))); 7492 effect(KILL oldval); 7493 7494 format %{ "cmpxchgq $mem, $newval\t# If rax == $mem then store $newval into $mem" %} 7495 opcode(0x0F, 0xB1); 7496 ins_encode(lock_prefix, 7497 REX_reg_mem_wide(newval, mem), 7498 OpcP, OpcS, 7499 reg_mem(newval, mem)); 7500 ins_pipe(pipe_cmpxchg); 7501%} 7502 7503 7504// XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them 7505instruct compareAndSwapP(rRegI res, 7506 memory mem_ptr, 7507 rax_RegP oldval, rRegP newval, 7508 rFlagsReg cr) 7509%{ 7510 predicate(VM_Version::supports_cx8()); 7511 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); 7512 effect(KILL cr, KILL oldval); 7513 7514 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7515 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7516 "sete $res\n\t" 7517 "movzbl $res, $res" %} 7518 opcode(0x0F, 0xB1); 7519 ins_encode(lock_prefix, 7520 REX_reg_mem_wide(newval, mem_ptr), 7521 OpcP, OpcS, 7522 reg_mem(newval, mem_ptr), 7523 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7524 REX_reg_breg(res, res), // movzbl 7525 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7526 ins_pipe( pipe_cmpxchg ); 7527%} 7528 7529instruct compareAndSwapL(rRegI res, 7530 memory mem_ptr, 7531 rax_RegL oldval, rRegL newval, 7532 rFlagsReg cr) 7533%{ 7534 predicate(VM_Version::supports_cx8()); 7535 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval))); 7536 effect(KILL cr, KILL oldval); 7537 7538 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7539 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7540 "sete $res\n\t" 7541 "movzbl $res, $res" %} 7542 opcode(0x0F, 0xB1); 7543 ins_encode(lock_prefix, 7544 REX_reg_mem_wide(newval, mem_ptr), 7545 OpcP, OpcS, 7546 reg_mem(newval, mem_ptr), 7547 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7548 REX_reg_breg(res, res), // movzbl 7549 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7550 ins_pipe( pipe_cmpxchg ); 7551%} 7552 7553instruct compareAndSwapI(rRegI res, 7554 memory mem_ptr, 7555 rax_RegI oldval, rRegI newval, 7556 rFlagsReg cr) 7557%{ 7558 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval))); 7559 effect(KILL cr, KILL oldval); 7560 7561 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7562 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7563 "sete $res\n\t" 7564 "movzbl $res, $res" %} 7565 opcode(0x0F, 0xB1); 7566 ins_encode(lock_prefix, 7567 REX_reg_mem(newval, mem_ptr), 7568 OpcP, OpcS, 7569 reg_mem(newval, mem_ptr), 7570 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7571 REX_reg_breg(res, res), // movzbl 7572 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7573 ins_pipe( pipe_cmpxchg ); 7574%} 7575 7576 7577instruct compareAndSwapN(rRegI res, 7578 memory mem_ptr, 7579 rax_RegN oldval, rRegN newval, 7580 rFlagsReg cr) %{ 7581 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval))); 7582 effect(KILL cr, KILL oldval); 7583 7584 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7585 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7586 "sete $res\n\t" 7587 "movzbl $res, $res" %} 7588 opcode(0x0F, 0xB1); 7589 ins_encode(lock_prefix, 7590 REX_reg_mem(newval, mem_ptr), 7591 OpcP, OpcS, 7592 reg_mem(newval, mem_ptr), 7593 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7594 REX_reg_breg(res, res), // movzbl 7595 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7596 ins_pipe( pipe_cmpxchg ); 7597%} 7598 7599instruct xaddI_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7600 predicate(n->as_LoadStore()->result_not_used()); 7601 match(Set dummy (GetAndAddI mem add)); 7602 effect(KILL cr); 7603 format %{ "ADDL [$mem],$add" %} 7604 ins_encode %{ 7605 if (os::is_MP()) { __ lock(); } 7606 __ addl($mem$$Address, $add$$constant); 7607 %} 7608 ins_pipe( pipe_cmpxchg ); 7609%} 7610 7611instruct xaddI( memory mem, rRegI newval, rFlagsReg cr) %{ 7612 match(Set newval (GetAndAddI mem newval)); 7613 effect(KILL cr); 7614 format %{ "XADDL [$mem],$newval" %} 7615 ins_encode %{ 7616 if (os::is_MP()) { __ lock(); } 7617 __ xaddl($mem$$Address, $newval$$Register); 7618 %} 7619 ins_pipe( pipe_cmpxchg ); 7620%} 7621 7622instruct xaddL_no_res( memory mem, Universe dummy, immL add, rFlagsReg cr) %{ 7623 predicate(n->as_LoadStore()->result_not_used()); 7624 match(Set dummy (GetAndAddL mem add)); 7625 effect(KILL cr); 7626 format %{ "ADDQ [$mem],$add" %} 7627 ins_encode %{ 7628 if (os::is_MP()) { __ lock(); } 7629 __ addq($mem$$Address, $add$$constant); 7630 %} 7631 ins_pipe( pipe_cmpxchg ); 7632%} 7633 7634instruct xaddL( memory mem, rRegL newval, rFlagsReg cr) %{ 7635 match(Set newval (GetAndAddL mem newval)); 7636 effect(KILL cr); 7637 format %{ "XADDQ [$mem],$newval" %} 7638 ins_encode %{ 7639 if (os::is_MP()) { __ lock(); } 7640 __ xaddq($mem$$Address, $newval$$Register); 7641 %} 7642 ins_pipe( pipe_cmpxchg ); 7643%} 7644 7645instruct xchgI( memory mem, rRegI newval) %{ 7646 match(Set newval (GetAndSetI mem newval)); 7647 format %{ "XCHGL $newval,[$mem]" %} 7648 ins_encode %{ 7649 __ xchgl($newval$$Register, $mem$$Address); 7650 %} 7651 ins_pipe( pipe_cmpxchg ); 7652%} 7653 7654instruct xchgL( memory mem, rRegL newval) %{ 7655 match(Set newval (GetAndSetL mem newval)); 7656 format %{ "XCHGL $newval,[$mem]" %} 7657 ins_encode %{ 7658 __ xchgq($newval$$Register, $mem$$Address); 7659 %} 7660 ins_pipe( pipe_cmpxchg ); 7661%} 7662 7663instruct xchgP( memory mem, rRegP newval) %{ 7664 match(Set newval (GetAndSetP mem newval)); 7665 format %{ "XCHGQ $newval,[$mem]" %} 7666 ins_encode %{ 7667 __ xchgq($newval$$Register, $mem$$Address); 7668 %} 7669 ins_pipe( pipe_cmpxchg ); 7670%} 7671 7672instruct xchgN( memory mem, rRegN newval) %{ 7673 match(Set newval (GetAndSetN mem newval)); 7674 format %{ "XCHGL $newval,$mem]" %} 7675 ins_encode %{ 7676 __ xchgl($newval$$Register, $mem$$Address); 7677 %} 7678 ins_pipe( pipe_cmpxchg ); 7679%} 7680 7681//----------Subtraction Instructions------------------------------------------- 7682 7683// Integer Subtraction Instructions 7684instruct subI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7685%{ 7686 match(Set dst (SubI dst src)); 7687 effect(KILL cr); 7688 7689 format %{ "subl $dst, $src\t# int" %} 7690 opcode(0x2B); 7691 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 7692 ins_pipe(ialu_reg_reg); 7693%} 7694 7695instruct subI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 7696%{ 7697 match(Set dst (SubI dst src)); 7698 effect(KILL cr); 7699 7700 format %{ "subl $dst, $src\t# int" %} 7701 opcode(0x81, 0x05); /* Opcode 81 /5 */ 7702 ins_encode(OpcSErm(dst, src), Con8or32(src)); 7703 ins_pipe(ialu_reg); 7704%} 7705 7706instruct subI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 7707%{ 7708 match(Set dst (SubI dst (LoadI src))); 7709 effect(KILL cr); 7710 7711 ins_cost(125); 7712 format %{ "subl $dst, $src\t# int" %} 7713 opcode(0x2B); 7714 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 7715 ins_pipe(ialu_reg_mem); 7716%} 7717 7718instruct subI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 7719%{ 7720 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 7721 effect(KILL cr); 7722 7723 ins_cost(150); 7724 format %{ "subl $dst, $src\t# int" %} 7725 opcode(0x29); /* Opcode 29 /r */ 7726 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 7727 ins_pipe(ialu_mem_reg); 7728%} 7729 7730instruct subI_mem_imm(memory dst, immI src, rFlagsReg cr) 7731%{ 7732 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 7733 effect(KILL cr); 7734 7735 ins_cost(125); // XXX 7736 format %{ "subl $dst, $src\t# int" %} 7737 opcode(0x81); /* Opcode 81 /5 id */ 7738 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); 7739 ins_pipe(ialu_mem_imm); 7740%} 7741 7742instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7743%{ 7744 match(Set dst (SubL dst src)); 7745 effect(KILL cr); 7746 7747 format %{ "subq $dst, $src\t# long" %} 7748 opcode(0x2B); 7749 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7750 ins_pipe(ialu_reg_reg); 7751%} 7752 7753instruct subL_rReg_imm(rRegI dst, immL32 src, rFlagsReg cr) 7754%{ 7755 match(Set dst (SubL dst src)); 7756 effect(KILL cr); 7757 7758 format %{ "subq $dst, $src\t# long" %} 7759 opcode(0x81, 0x05); /* Opcode 81 /5 */ 7760 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7761 ins_pipe(ialu_reg); 7762%} 7763 7764instruct subL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 7765%{ 7766 match(Set dst (SubL dst (LoadL src))); 7767 effect(KILL cr); 7768 7769 ins_cost(125); 7770 format %{ "subq $dst, $src\t# long" %} 7771 opcode(0x2B); 7772 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 7773 ins_pipe(ialu_reg_mem); 7774%} 7775 7776instruct subL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 7777%{ 7778 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 7779 effect(KILL cr); 7780 7781 ins_cost(150); 7782 format %{ "subq $dst, $src\t# long" %} 7783 opcode(0x29); /* Opcode 29 /r */ 7784 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 7785 ins_pipe(ialu_mem_reg); 7786%} 7787 7788instruct subL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 7789%{ 7790 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 7791 effect(KILL cr); 7792 7793 ins_cost(125); // XXX 7794 format %{ "subq $dst, $src\t# long" %} 7795 opcode(0x81); /* Opcode 81 /5 id */ 7796 ins_encode(REX_mem_wide(dst), 7797 OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); 7798 ins_pipe(ialu_mem_imm); 7799%} 7800 7801// Subtract from a pointer 7802// XXX hmpf??? 7803instruct subP_rReg(rRegP dst, rRegI src, immI0 zero, rFlagsReg cr) 7804%{ 7805 match(Set dst (AddP dst (SubI zero src))); 7806 effect(KILL cr); 7807 7808 format %{ "subq $dst, $src\t# ptr - int" %} 7809 opcode(0x2B); 7810 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7811 ins_pipe(ialu_reg_reg); 7812%} 7813 7814instruct negI_rReg(rRegI dst, immI0 zero, rFlagsReg cr) 7815%{ 7816 match(Set dst (SubI zero dst)); 7817 effect(KILL cr); 7818 7819 format %{ "negl $dst\t# int" %} 7820 opcode(0xF7, 0x03); // Opcode F7 /3 7821 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7822 ins_pipe(ialu_reg); 7823%} 7824 7825instruct negI_mem(memory dst, immI0 zero, rFlagsReg cr) 7826%{ 7827 match(Set dst (StoreI dst (SubI zero (LoadI dst)))); 7828 effect(KILL cr); 7829 7830 format %{ "negl $dst\t# int" %} 7831 opcode(0xF7, 0x03); // Opcode F7 /3 7832 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 7833 ins_pipe(ialu_reg); 7834%} 7835 7836instruct negL_rReg(rRegL dst, immL0 zero, rFlagsReg cr) 7837%{ 7838 match(Set dst (SubL zero dst)); 7839 effect(KILL cr); 7840 7841 format %{ "negq $dst\t# long" %} 7842 opcode(0xF7, 0x03); // Opcode F7 /3 7843 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 7844 ins_pipe(ialu_reg); 7845%} 7846 7847instruct negL_mem(memory dst, immL0 zero, rFlagsReg cr) 7848%{ 7849 match(Set dst (StoreL dst (SubL zero (LoadL dst)))); 7850 effect(KILL cr); 7851 7852 format %{ "negq $dst\t# long" %} 7853 opcode(0xF7, 0x03); // Opcode F7 /3 7854 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 7855 ins_pipe(ialu_reg); 7856%} 7857 7858 7859//----------Multiplication/Division Instructions------------------------------- 7860// Integer Multiplication Instructions 7861// Multiply Register 7862 7863instruct mulI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7864%{ 7865 match(Set dst (MulI dst src)); 7866 effect(KILL cr); 7867 7868 ins_cost(300); 7869 format %{ "imull $dst, $src\t# int" %} 7870 opcode(0x0F, 0xAF); 7871 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 7872 ins_pipe(ialu_reg_reg_alu0); 7873%} 7874 7875instruct mulI_rReg_imm(rRegI dst, rRegI src, immI imm, rFlagsReg cr) 7876%{ 7877 match(Set dst (MulI src imm)); 7878 effect(KILL cr); 7879 7880 ins_cost(300); 7881 format %{ "imull $dst, $src, $imm\t# int" %} 7882 opcode(0x69); /* 69 /r id */ 7883 ins_encode(REX_reg_reg(dst, src), 7884 OpcSE(imm), reg_reg(dst, src), Con8or32(imm)); 7885 ins_pipe(ialu_reg_reg_alu0); 7886%} 7887 7888instruct mulI_mem(rRegI dst, memory src, rFlagsReg cr) 7889%{ 7890 match(Set dst (MulI dst (LoadI src))); 7891 effect(KILL cr); 7892 7893 ins_cost(350); 7894 format %{ "imull $dst, $src\t# int" %} 7895 opcode(0x0F, 0xAF); 7896 ins_encode(REX_reg_mem(dst, src), OpcP, OpcS, reg_mem(dst, src)); 7897 ins_pipe(ialu_reg_mem_alu0); 7898%} 7899 7900instruct mulI_mem_imm(rRegI dst, memory src, immI imm, rFlagsReg cr) 7901%{ 7902 match(Set dst (MulI (LoadI src) imm)); 7903 effect(KILL cr); 7904 7905 ins_cost(300); 7906 format %{ "imull $dst, $src, $imm\t# int" %} 7907 opcode(0x69); /* 69 /r id */ 7908 ins_encode(REX_reg_mem(dst, src), 7909 OpcSE(imm), reg_mem(dst, src), Con8or32(imm)); 7910 ins_pipe(ialu_reg_mem_alu0); 7911%} 7912 7913instruct mulL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7914%{ 7915 match(Set dst (MulL dst src)); 7916 effect(KILL cr); 7917 7918 ins_cost(300); 7919 format %{ "imulq $dst, $src\t# long" %} 7920 opcode(0x0F, 0xAF); 7921 ins_encode(REX_reg_reg_wide(dst, src), OpcP, OpcS, reg_reg(dst, src)); 7922 ins_pipe(ialu_reg_reg_alu0); 7923%} 7924 7925instruct mulL_rReg_imm(rRegL dst, rRegL src, immL32 imm, rFlagsReg cr) 7926%{ 7927 match(Set dst (MulL src imm)); 7928 effect(KILL cr); 7929 7930 ins_cost(300); 7931 format %{ "imulq $dst, $src, $imm\t# long" %} 7932 opcode(0x69); /* 69 /r id */ 7933 ins_encode(REX_reg_reg_wide(dst, src), 7934 OpcSE(imm), reg_reg(dst, src), Con8or32(imm)); 7935 ins_pipe(ialu_reg_reg_alu0); 7936%} 7937 7938instruct mulL_mem(rRegL dst, memory src, rFlagsReg cr) 7939%{ 7940 match(Set dst (MulL dst (LoadL src))); 7941 effect(KILL cr); 7942 7943 ins_cost(350); 7944 format %{ "imulq $dst, $src\t# long" %} 7945 opcode(0x0F, 0xAF); 7946 ins_encode(REX_reg_mem_wide(dst, src), OpcP, OpcS, reg_mem(dst, src)); 7947 ins_pipe(ialu_reg_mem_alu0); 7948%} 7949 7950instruct mulL_mem_imm(rRegL dst, memory src, immL32 imm, rFlagsReg cr) 7951%{ 7952 match(Set dst (MulL (LoadL src) imm)); 7953 effect(KILL cr); 7954 7955 ins_cost(300); 7956 format %{ "imulq $dst, $src, $imm\t# long" %} 7957 opcode(0x69); /* 69 /r id */ 7958 ins_encode(REX_reg_mem_wide(dst, src), 7959 OpcSE(imm), reg_mem(dst, src), Con8or32(imm)); 7960 ins_pipe(ialu_reg_mem_alu0); 7961%} 7962 7963instruct mulHiL_rReg(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr) 7964%{ 7965 match(Set dst (MulHiL src rax)); 7966 effect(USE_KILL rax, KILL cr); 7967 7968 ins_cost(300); 7969 format %{ "imulq RDX:RAX, RAX, $src\t# mulhi" %} 7970 opcode(0xF7, 0x5); /* Opcode F7 /5 */ 7971 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); 7972 ins_pipe(ialu_reg_reg_alu0); 7973%} 7974 7975instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 7976 rFlagsReg cr) 7977%{ 7978 match(Set rax (DivI rax div)); 7979 effect(KILL rdx, KILL cr); 7980 7981 ins_cost(30*100+10*100); // XXX 7982 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 7983 "jne,s normal\n\t" 7984 "xorl rdx, rdx\n\t" 7985 "cmpl $div, -1\n\t" 7986 "je,s done\n" 7987 "normal: cdql\n\t" 7988 "idivl $div\n" 7989 "done:" %} 7990 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 7991 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 7992 ins_pipe(ialu_reg_reg_alu0); 7993%} 7994 7995instruct divL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 7996 rFlagsReg cr) 7997%{ 7998 match(Set rax (DivL rax div)); 7999 effect(KILL rdx, KILL cr); 8000 8001 ins_cost(30*100+10*100); // XXX 8002 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 8003 "cmpq rax, rdx\n\t" 8004 "jne,s normal\n\t" 8005 "xorl rdx, rdx\n\t" 8006 "cmpq $div, -1\n\t" 8007 "je,s done\n" 8008 "normal: cdqq\n\t" 8009 "idivq $div\n" 8010 "done:" %} 8011 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8012 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8013 ins_pipe(ialu_reg_reg_alu0); 8014%} 8015 8016// Integer DIVMOD with Register, both quotient and mod results 8017instruct divModI_rReg_divmod(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 8018 rFlagsReg cr) 8019%{ 8020 match(DivModI rax div); 8021 effect(KILL cr); 8022 8023 ins_cost(30*100+10*100); // XXX 8024 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 8025 "jne,s normal\n\t" 8026 "xorl rdx, rdx\n\t" 8027 "cmpl $div, -1\n\t" 8028 "je,s done\n" 8029 "normal: cdql\n\t" 8030 "idivl $div\n" 8031 "done:" %} 8032 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8033 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8034 ins_pipe(pipe_slow); 8035%} 8036 8037// Long DIVMOD with Register, both quotient and mod results 8038instruct divModL_rReg_divmod(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 8039 rFlagsReg cr) 8040%{ 8041 match(DivModL rax div); 8042 effect(KILL cr); 8043 8044 ins_cost(30*100+10*100); // XXX 8045 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 8046 "cmpq rax, rdx\n\t" 8047 "jne,s normal\n\t" 8048 "xorl rdx, rdx\n\t" 8049 "cmpq $div, -1\n\t" 8050 "je,s done\n" 8051 "normal: cdqq\n\t" 8052 "idivq $div\n" 8053 "done:" %} 8054 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8055 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8056 ins_pipe(pipe_slow); 8057%} 8058 8059//----------- DivL-By-Constant-Expansions-------------------------------------- 8060// DivI cases are handled by the compiler 8061 8062// Magic constant, reciprocal of 10 8063instruct loadConL_0x6666666666666667(rRegL dst) 8064%{ 8065 effect(DEF dst); 8066 8067 format %{ "movq $dst, #0x666666666666667\t# Used in div-by-10" %} 8068 ins_encode(load_immL(dst, 0x6666666666666667)); 8069 ins_pipe(ialu_reg); 8070%} 8071 8072instruct mul_hi(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr) 8073%{ 8074 effect(DEF dst, USE src, USE_KILL rax, KILL cr); 8075 8076 format %{ "imulq rdx:rax, rax, $src\t# Used in div-by-10" %} 8077 opcode(0xF7, 0x5); /* Opcode F7 /5 */ 8078 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); 8079 ins_pipe(ialu_reg_reg_alu0); 8080%} 8081 8082instruct sarL_rReg_63(rRegL dst, rFlagsReg cr) 8083%{ 8084 effect(USE_DEF dst, KILL cr); 8085 8086 format %{ "sarq $dst, #63\t# Used in div-by-10" %} 8087 opcode(0xC1, 0x7); /* C1 /7 ib */ 8088 ins_encode(reg_opc_imm_wide(dst, 0x3F)); 8089 ins_pipe(ialu_reg); 8090%} 8091 8092instruct sarL_rReg_2(rRegL dst, rFlagsReg cr) 8093%{ 8094 effect(USE_DEF dst, KILL cr); 8095 8096 format %{ "sarq $dst, #2\t# Used in div-by-10" %} 8097 opcode(0xC1, 0x7); /* C1 /7 ib */ 8098 ins_encode(reg_opc_imm_wide(dst, 0x2)); 8099 ins_pipe(ialu_reg); 8100%} 8101 8102instruct divL_10(rdx_RegL dst, no_rax_RegL src, immL10 div) 8103%{ 8104 match(Set dst (DivL src div)); 8105 8106 ins_cost((5+8)*100); 8107 expand %{ 8108 rax_RegL rax; // Killed temp 8109 rFlagsReg cr; // Killed 8110 loadConL_0x6666666666666667(rax); // movq rax, 0x6666666666666667 8111 mul_hi(dst, src, rax, cr); // mulq rdx:rax <= rax * $src 8112 sarL_rReg_63(src, cr); // sarq src, 63 8113 sarL_rReg_2(dst, cr); // sarq rdx, 2 8114 subL_rReg(dst, src, cr); // subl rdx, src 8115 %} 8116%} 8117 8118//----------------------------------------------------------------------------- 8119 8120instruct modI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, 8121 rFlagsReg cr) 8122%{ 8123 match(Set rdx (ModI rax div)); 8124 effect(KILL rax, KILL cr); 8125 8126 ins_cost(300); // XXX 8127 format %{ "cmpl rax, 0x80000000\t# irem\n\t" 8128 "jne,s normal\n\t" 8129 "xorl rdx, rdx\n\t" 8130 "cmpl $div, -1\n\t" 8131 "je,s done\n" 8132 "normal: cdql\n\t" 8133 "idivl $div\n" 8134 "done:" %} 8135 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8136 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8137 ins_pipe(ialu_reg_reg_alu0); 8138%} 8139 8140instruct modL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, 8141 rFlagsReg cr) 8142%{ 8143 match(Set rdx (ModL rax div)); 8144 effect(KILL rax, KILL cr); 8145 8146 ins_cost(300); // XXX 8147 format %{ "movq rdx, 0x8000000000000000\t# lrem\n\t" 8148 "cmpq rax, rdx\n\t" 8149 "jne,s normal\n\t" 8150 "xorl rdx, rdx\n\t" 8151 "cmpq $div, -1\n\t" 8152 "je,s done\n" 8153 "normal: cdqq\n\t" 8154 "idivq $div\n" 8155 "done:" %} 8156 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8157 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8158 ins_pipe(ialu_reg_reg_alu0); 8159%} 8160 8161// Integer Shift Instructions 8162// Shift Left by one 8163instruct salI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8164%{ 8165 match(Set dst (LShiftI dst shift)); 8166 effect(KILL cr); 8167 8168 format %{ "sall $dst, $shift" %} 8169 opcode(0xD1, 0x4); /* D1 /4 */ 8170 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8171 ins_pipe(ialu_reg); 8172%} 8173 8174// Shift Left by one 8175instruct salI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8176%{ 8177 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8178 effect(KILL cr); 8179 8180 format %{ "sall $dst, $shift\t" %} 8181 opcode(0xD1, 0x4); /* D1 /4 */ 8182 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8183 ins_pipe(ialu_mem_imm); 8184%} 8185 8186// Shift Left by 8-bit immediate 8187instruct salI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8188%{ 8189 match(Set dst (LShiftI dst shift)); 8190 effect(KILL cr); 8191 8192 format %{ "sall $dst, $shift" %} 8193 opcode(0xC1, 0x4); /* C1 /4 ib */ 8194 ins_encode(reg_opc_imm(dst, shift)); 8195 ins_pipe(ialu_reg); 8196%} 8197 8198// Shift Left by 8-bit immediate 8199instruct salI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8200%{ 8201 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8202 effect(KILL cr); 8203 8204 format %{ "sall $dst, $shift" %} 8205 opcode(0xC1, 0x4); /* C1 /4 ib */ 8206 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8207 ins_pipe(ialu_mem_imm); 8208%} 8209 8210// Shift Left by variable 8211instruct salI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8212%{ 8213 match(Set dst (LShiftI dst shift)); 8214 effect(KILL cr); 8215 8216 format %{ "sall $dst, $shift" %} 8217 opcode(0xD3, 0x4); /* D3 /4 */ 8218 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8219 ins_pipe(ialu_reg_reg); 8220%} 8221 8222// Shift Left by variable 8223instruct salI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8224%{ 8225 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8226 effect(KILL cr); 8227 8228 format %{ "sall $dst, $shift" %} 8229 opcode(0xD3, 0x4); /* D3 /4 */ 8230 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8231 ins_pipe(ialu_mem_reg); 8232%} 8233 8234// Arithmetic shift right by one 8235instruct sarI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8236%{ 8237 match(Set dst (RShiftI dst shift)); 8238 effect(KILL cr); 8239 8240 format %{ "sarl $dst, $shift" %} 8241 opcode(0xD1, 0x7); /* D1 /7 */ 8242 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8243 ins_pipe(ialu_reg); 8244%} 8245 8246// Arithmetic shift right by one 8247instruct sarI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8248%{ 8249 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8250 effect(KILL cr); 8251 8252 format %{ "sarl $dst, $shift" %} 8253 opcode(0xD1, 0x7); /* D1 /7 */ 8254 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8255 ins_pipe(ialu_mem_imm); 8256%} 8257 8258// Arithmetic Shift Right by 8-bit immediate 8259instruct sarI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8260%{ 8261 match(Set dst (RShiftI dst shift)); 8262 effect(KILL cr); 8263 8264 format %{ "sarl $dst, $shift" %} 8265 opcode(0xC1, 0x7); /* C1 /7 ib */ 8266 ins_encode(reg_opc_imm(dst, shift)); 8267 ins_pipe(ialu_mem_imm); 8268%} 8269 8270// Arithmetic Shift Right by 8-bit immediate 8271instruct sarI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8272%{ 8273 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8274 effect(KILL cr); 8275 8276 format %{ "sarl $dst, $shift" %} 8277 opcode(0xC1, 0x7); /* C1 /7 ib */ 8278 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8279 ins_pipe(ialu_mem_imm); 8280%} 8281 8282// Arithmetic Shift Right by variable 8283instruct sarI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8284%{ 8285 match(Set dst (RShiftI dst shift)); 8286 effect(KILL cr); 8287 8288 format %{ "sarl $dst, $shift" %} 8289 opcode(0xD3, 0x7); /* D3 /7 */ 8290 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8291 ins_pipe(ialu_reg_reg); 8292%} 8293 8294// Arithmetic Shift Right by variable 8295instruct sarI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8296%{ 8297 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8298 effect(KILL cr); 8299 8300 format %{ "sarl $dst, $shift" %} 8301 opcode(0xD3, 0x7); /* D3 /7 */ 8302 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8303 ins_pipe(ialu_mem_reg); 8304%} 8305 8306// Logical shift right by one 8307instruct shrI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8308%{ 8309 match(Set dst (URShiftI dst shift)); 8310 effect(KILL cr); 8311 8312 format %{ "shrl $dst, $shift" %} 8313 opcode(0xD1, 0x5); /* D1 /5 */ 8314 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8315 ins_pipe(ialu_reg); 8316%} 8317 8318// Logical shift right by one 8319instruct shrI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8320%{ 8321 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8322 effect(KILL cr); 8323 8324 format %{ "shrl $dst, $shift" %} 8325 opcode(0xD1, 0x5); /* D1 /5 */ 8326 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8327 ins_pipe(ialu_mem_imm); 8328%} 8329 8330// Logical Shift Right by 8-bit immediate 8331instruct shrI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8332%{ 8333 match(Set dst (URShiftI dst shift)); 8334 effect(KILL cr); 8335 8336 format %{ "shrl $dst, $shift" %} 8337 opcode(0xC1, 0x5); /* C1 /5 ib */ 8338 ins_encode(reg_opc_imm(dst, shift)); 8339 ins_pipe(ialu_reg); 8340%} 8341 8342// Logical Shift Right by 8-bit immediate 8343instruct shrI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8344%{ 8345 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8346 effect(KILL cr); 8347 8348 format %{ "shrl $dst, $shift" %} 8349 opcode(0xC1, 0x5); /* C1 /5 ib */ 8350 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8351 ins_pipe(ialu_mem_imm); 8352%} 8353 8354// Logical Shift Right by variable 8355instruct shrI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8356%{ 8357 match(Set dst (URShiftI dst shift)); 8358 effect(KILL cr); 8359 8360 format %{ "shrl $dst, $shift" %} 8361 opcode(0xD3, 0x5); /* D3 /5 */ 8362 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8363 ins_pipe(ialu_reg_reg); 8364%} 8365 8366// Logical Shift Right by variable 8367instruct shrI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8368%{ 8369 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8370 effect(KILL cr); 8371 8372 format %{ "shrl $dst, $shift" %} 8373 opcode(0xD3, 0x5); /* D3 /5 */ 8374 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8375 ins_pipe(ialu_mem_reg); 8376%} 8377 8378// Long Shift Instructions 8379// Shift Left by one 8380instruct salL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8381%{ 8382 match(Set dst (LShiftL dst shift)); 8383 effect(KILL cr); 8384 8385 format %{ "salq $dst, $shift" %} 8386 opcode(0xD1, 0x4); /* D1 /4 */ 8387 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8388 ins_pipe(ialu_reg); 8389%} 8390 8391// Shift Left by one 8392instruct salL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8393%{ 8394 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8395 effect(KILL cr); 8396 8397 format %{ "salq $dst, $shift" %} 8398 opcode(0xD1, 0x4); /* D1 /4 */ 8399 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8400 ins_pipe(ialu_mem_imm); 8401%} 8402 8403// Shift Left by 8-bit immediate 8404instruct salL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8405%{ 8406 match(Set dst (LShiftL dst shift)); 8407 effect(KILL cr); 8408 8409 format %{ "salq $dst, $shift" %} 8410 opcode(0xC1, 0x4); /* C1 /4 ib */ 8411 ins_encode(reg_opc_imm_wide(dst, shift)); 8412 ins_pipe(ialu_reg); 8413%} 8414 8415// Shift Left by 8-bit immediate 8416instruct salL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8417%{ 8418 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8419 effect(KILL cr); 8420 8421 format %{ "salq $dst, $shift" %} 8422 opcode(0xC1, 0x4); /* C1 /4 ib */ 8423 ins_encode(REX_mem_wide(dst), OpcP, 8424 RM_opc_mem(secondary, dst), Con8or32(shift)); 8425 ins_pipe(ialu_mem_imm); 8426%} 8427 8428// Shift Left by variable 8429instruct salL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8430%{ 8431 match(Set dst (LShiftL dst shift)); 8432 effect(KILL cr); 8433 8434 format %{ "salq $dst, $shift" %} 8435 opcode(0xD3, 0x4); /* D3 /4 */ 8436 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8437 ins_pipe(ialu_reg_reg); 8438%} 8439 8440// Shift Left by variable 8441instruct salL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8442%{ 8443 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8444 effect(KILL cr); 8445 8446 format %{ "salq $dst, $shift" %} 8447 opcode(0xD3, 0x4); /* D3 /4 */ 8448 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8449 ins_pipe(ialu_mem_reg); 8450%} 8451 8452// Arithmetic shift right by one 8453instruct sarL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8454%{ 8455 match(Set dst (RShiftL dst shift)); 8456 effect(KILL cr); 8457 8458 format %{ "sarq $dst, $shift" %} 8459 opcode(0xD1, 0x7); /* D1 /7 */ 8460 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8461 ins_pipe(ialu_reg); 8462%} 8463 8464// Arithmetic shift right by one 8465instruct sarL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8466%{ 8467 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8468 effect(KILL cr); 8469 8470 format %{ "sarq $dst, $shift" %} 8471 opcode(0xD1, 0x7); /* D1 /7 */ 8472 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8473 ins_pipe(ialu_mem_imm); 8474%} 8475 8476// Arithmetic Shift Right by 8-bit immediate 8477instruct sarL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8478%{ 8479 match(Set dst (RShiftL dst shift)); 8480 effect(KILL cr); 8481 8482 format %{ "sarq $dst, $shift" %} 8483 opcode(0xC1, 0x7); /* C1 /7 ib */ 8484 ins_encode(reg_opc_imm_wide(dst, shift)); 8485 ins_pipe(ialu_mem_imm); 8486%} 8487 8488// Arithmetic Shift Right by 8-bit immediate 8489instruct sarL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8490%{ 8491 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8492 effect(KILL cr); 8493 8494 format %{ "sarq $dst, $shift" %} 8495 opcode(0xC1, 0x7); /* C1 /7 ib */ 8496 ins_encode(REX_mem_wide(dst), OpcP, 8497 RM_opc_mem(secondary, dst), Con8or32(shift)); 8498 ins_pipe(ialu_mem_imm); 8499%} 8500 8501// Arithmetic Shift Right by variable 8502instruct sarL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8503%{ 8504 match(Set dst (RShiftL dst shift)); 8505 effect(KILL cr); 8506 8507 format %{ "sarq $dst, $shift" %} 8508 opcode(0xD3, 0x7); /* D3 /7 */ 8509 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8510 ins_pipe(ialu_reg_reg); 8511%} 8512 8513// Arithmetic Shift Right by variable 8514instruct sarL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8515%{ 8516 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8517 effect(KILL cr); 8518 8519 format %{ "sarq $dst, $shift" %} 8520 opcode(0xD3, 0x7); /* D3 /7 */ 8521 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8522 ins_pipe(ialu_mem_reg); 8523%} 8524 8525// Logical shift right by one 8526instruct shrL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8527%{ 8528 match(Set dst (URShiftL dst shift)); 8529 effect(KILL cr); 8530 8531 format %{ "shrq $dst, $shift" %} 8532 opcode(0xD1, 0x5); /* D1 /5 */ 8533 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst )); 8534 ins_pipe(ialu_reg); 8535%} 8536 8537// Logical shift right by one 8538instruct shrL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8539%{ 8540 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8541 effect(KILL cr); 8542 8543 format %{ "shrq $dst, $shift" %} 8544 opcode(0xD1, 0x5); /* D1 /5 */ 8545 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8546 ins_pipe(ialu_mem_imm); 8547%} 8548 8549// Logical Shift Right by 8-bit immediate 8550instruct shrL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8551%{ 8552 match(Set dst (URShiftL dst shift)); 8553 effect(KILL cr); 8554 8555 format %{ "shrq $dst, $shift" %} 8556 opcode(0xC1, 0x5); /* C1 /5 ib */ 8557 ins_encode(reg_opc_imm_wide(dst, shift)); 8558 ins_pipe(ialu_reg); 8559%} 8560 8561 8562// Logical Shift Right by 8-bit immediate 8563instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8564%{ 8565 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8566 effect(KILL cr); 8567 8568 format %{ "shrq $dst, $shift" %} 8569 opcode(0xC1, 0x5); /* C1 /5 ib */ 8570 ins_encode(REX_mem_wide(dst), OpcP, 8571 RM_opc_mem(secondary, dst), Con8or32(shift)); 8572 ins_pipe(ialu_mem_imm); 8573%} 8574 8575// Logical Shift Right by variable 8576instruct shrL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8577%{ 8578 match(Set dst (URShiftL dst shift)); 8579 effect(KILL cr); 8580 8581 format %{ "shrq $dst, $shift" %} 8582 opcode(0xD3, 0x5); /* D3 /5 */ 8583 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8584 ins_pipe(ialu_reg_reg); 8585%} 8586 8587// Logical Shift Right by variable 8588instruct shrL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8589%{ 8590 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8591 effect(KILL cr); 8592 8593 format %{ "shrq $dst, $shift" %} 8594 opcode(0xD3, 0x5); /* D3 /5 */ 8595 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8596 ins_pipe(ialu_mem_reg); 8597%} 8598 8599// Logical Shift Right by 24, followed by Arithmetic Shift Left by 24. 8600// This idiom is used by the compiler for the i2b bytecode. 8601instruct i2b(rRegI dst, rRegI src, immI_24 twentyfour) 8602%{ 8603 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour)); 8604 8605 format %{ "movsbl $dst, $src\t# i2b" %} 8606 opcode(0x0F, 0xBE); 8607 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8608 ins_pipe(ialu_reg_reg); 8609%} 8610 8611// Logical Shift Right by 16, followed by Arithmetic Shift Left by 16. 8612// This idiom is used by the compiler the i2s bytecode. 8613instruct i2s(rRegI dst, rRegI src, immI_16 sixteen) 8614%{ 8615 match(Set dst (RShiftI (LShiftI src sixteen) sixteen)); 8616 8617 format %{ "movswl $dst, $src\t# i2s" %} 8618 opcode(0x0F, 0xBF); 8619 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8620 ins_pipe(ialu_reg_reg); 8621%} 8622 8623// ROL/ROR instructions 8624 8625// ROL expand 8626instruct rolI_rReg_imm1(rRegI dst, rFlagsReg cr) %{ 8627 effect(KILL cr, USE_DEF dst); 8628 8629 format %{ "roll $dst" %} 8630 opcode(0xD1, 0x0); /* Opcode D1 /0 */ 8631 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8632 ins_pipe(ialu_reg); 8633%} 8634 8635instruct rolI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) %{ 8636 effect(USE_DEF dst, USE shift, KILL cr); 8637 8638 format %{ "roll $dst, $shift" %} 8639 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */ 8640 ins_encode( reg_opc_imm(dst, shift) ); 8641 ins_pipe(ialu_reg); 8642%} 8643 8644instruct rolI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr) 8645%{ 8646 effect(USE_DEF dst, USE shift, KILL cr); 8647 8648 format %{ "roll $dst, $shift" %} 8649 opcode(0xD3, 0x0); /* Opcode D3 /0 */ 8650 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8651 ins_pipe(ialu_reg_reg); 8652%} 8653// end of ROL expand 8654 8655// Rotate Left by one 8656instruct rolI_rReg_i1(rRegI dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr) 8657%{ 8658 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift))); 8659 8660 expand %{ 8661 rolI_rReg_imm1(dst, cr); 8662 %} 8663%} 8664 8665// Rotate Left by 8-bit immediate 8666instruct rolI_rReg_i8(rRegI dst, immI8 lshift, immI8 rshift, rFlagsReg cr) 8667%{ 8668 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 8669 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift))); 8670 8671 expand %{ 8672 rolI_rReg_imm8(dst, lshift, cr); 8673 %} 8674%} 8675 8676// Rotate Left by variable 8677instruct rolI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 8678%{ 8679 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI zero shift)))); 8680 8681 expand %{ 8682 rolI_rReg_CL(dst, shift, cr); 8683 %} 8684%} 8685 8686// Rotate Left by variable 8687instruct rolI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr) 8688%{ 8689 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI c32 shift)))); 8690 8691 expand %{ 8692 rolI_rReg_CL(dst, shift, cr); 8693 %} 8694%} 8695 8696// ROR expand 8697instruct rorI_rReg_imm1(rRegI dst, rFlagsReg cr) 8698%{ 8699 effect(USE_DEF dst, KILL cr); 8700 8701 format %{ "rorl $dst" %} 8702 opcode(0xD1, 0x1); /* D1 /1 */ 8703 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8704 ins_pipe(ialu_reg); 8705%} 8706 8707instruct rorI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) 8708%{ 8709 effect(USE_DEF dst, USE shift, KILL cr); 8710 8711 format %{ "rorl $dst, $shift" %} 8712 opcode(0xC1, 0x1); /* C1 /1 ib */ 8713 ins_encode(reg_opc_imm(dst, shift)); 8714 ins_pipe(ialu_reg); 8715%} 8716 8717instruct rorI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr) 8718%{ 8719 effect(USE_DEF dst, USE shift, KILL cr); 8720 8721 format %{ "rorl $dst, $shift" %} 8722 opcode(0xD3, 0x1); /* D3 /1 */ 8723 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8724 ins_pipe(ialu_reg_reg); 8725%} 8726// end of ROR expand 8727 8728// Rotate Right by one 8729instruct rorI_rReg_i1(rRegI dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr) 8730%{ 8731 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift))); 8732 8733 expand %{ 8734 rorI_rReg_imm1(dst, cr); 8735 %} 8736%} 8737 8738// Rotate Right by 8-bit immediate 8739instruct rorI_rReg_i8(rRegI dst, immI8 rshift, immI8 lshift, rFlagsReg cr) 8740%{ 8741 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 8742 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift))); 8743 8744 expand %{ 8745 rorI_rReg_imm8(dst, rshift, cr); 8746 %} 8747%} 8748 8749// Rotate Right by variable 8750instruct rorI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 8751%{ 8752 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI zero shift)))); 8753 8754 expand %{ 8755 rorI_rReg_CL(dst, shift, cr); 8756 %} 8757%} 8758 8759// Rotate Right by variable 8760instruct rorI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr) 8761%{ 8762 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI c32 shift)))); 8763 8764 expand %{ 8765 rorI_rReg_CL(dst, shift, cr); 8766 %} 8767%} 8768 8769// for long rotate 8770// ROL expand 8771instruct rolL_rReg_imm1(rRegL dst, rFlagsReg cr) %{ 8772 effect(USE_DEF dst, KILL cr); 8773 8774 format %{ "rolq $dst" %} 8775 opcode(0xD1, 0x0); /* Opcode D1 /0 */ 8776 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8777 ins_pipe(ialu_reg); 8778%} 8779 8780instruct rolL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) %{ 8781 effect(USE_DEF dst, USE shift, KILL cr); 8782 8783 format %{ "rolq $dst, $shift" %} 8784 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */ 8785 ins_encode( reg_opc_imm_wide(dst, shift) ); 8786 ins_pipe(ialu_reg); 8787%} 8788 8789instruct rolL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr) 8790%{ 8791 effect(USE_DEF dst, USE shift, KILL cr); 8792 8793 format %{ "rolq $dst, $shift" %} 8794 opcode(0xD3, 0x0); /* Opcode D3 /0 */ 8795 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8796 ins_pipe(ialu_reg_reg); 8797%} 8798// end of ROL expand 8799 8800// Rotate Left by one 8801instruct rolL_rReg_i1(rRegL dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr) 8802%{ 8803 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift))); 8804 8805 expand %{ 8806 rolL_rReg_imm1(dst, cr); 8807 %} 8808%} 8809 8810// Rotate Left by 8-bit immediate 8811instruct rolL_rReg_i8(rRegL dst, immI8 lshift, immI8 rshift, rFlagsReg cr) 8812%{ 8813 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f)); 8814 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift))); 8815 8816 expand %{ 8817 rolL_rReg_imm8(dst, lshift, cr); 8818 %} 8819%} 8820 8821// Rotate Left by variable 8822instruct rolL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 8823%{ 8824 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI zero shift)))); 8825 8826 expand %{ 8827 rolL_rReg_CL(dst, shift, cr); 8828 %} 8829%} 8830 8831// Rotate Left by variable 8832instruct rolL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr) 8833%{ 8834 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI c64 shift)))); 8835 8836 expand %{ 8837 rolL_rReg_CL(dst, shift, cr); 8838 %} 8839%} 8840 8841// ROR expand 8842instruct rorL_rReg_imm1(rRegL dst, rFlagsReg cr) 8843%{ 8844 effect(USE_DEF dst, KILL cr); 8845 8846 format %{ "rorq $dst" %} 8847 opcode(0xD1, 0x1); /* D1 /1 */ 8848 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8849 ins_pipe(ialu_reg); 8850%} 8851 8852instruct rorL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) 8853%{ 8854 effect(USE_DEF dst, USE shift, KILL cr); 8855 8856 format %{ "rorq $dst, $shift" %} 8857 opcode(0xC1, 0x1); /* C1 /1 ib */ 8858 ins_encode(reg_opc_imm_wide(dst, shift)); 8859 ins_pipe(ialu_reg); 8860%} 8861 8862instruct rorL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr) 8863%{ 8864 effect(USE_DEF dst, USE shift, KILL cr); 8865 8866 format %{ "rorq $dst, $shift" %} 8867 opcode(0xD3, 0x1); /* D3 /1 */ 8868 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8869 ins_pipe(ialu_reg_reg); 8870%} 8871// end of ROR expand 8872 8873// Rotate Right by one 8874instruct rorL_rReg_i1(rRegL dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr) 8875%{ 8876 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift))); 8877 8878 expand %{ 8879 rorL_rReg_imm1(dst, cr); 8880 %} 8881%} 8882 8883// Rotate Right by 8-bit immediate 8884instruct rorL_rReg_i8(rRegL dst, immI8 rshift, immI8 lshift, rFlagsReg cr) 8885%{ 8886 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f)); 8887 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift))); 8888 8889 expand %{ 8890 rorL_rReg_imm8(dst, rshift, cr); 8891 %} 8892%} 8893 8894// Rotate Right by variable 8895instruct rorL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 8896%{ 8897 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI zero shift)))); 8898 8899 expand %{ 8900 rorL_rReg_CL(dst, shift, cr); 8901 %} 8902%} 8903 8904// Rotate Right by variable 8905instruct rorL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr) 8906%{ 8907 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI c64 shift)))); 8908 8909 expand %{ 8910 rorL_rReg_CL(dst, shift, cr); 8911 %} 8912%} 8913 8914// Logical Instructions 8915 8916// Integer Logical Instructions 8917 8918// And Instructions 8919// And Register with Register 8920instruct andI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8921%{ 8922 match(Set dst (AndI dst src)); 8923 effect(KILL cr); 8924 8925 format %{ "andl $dst, $src\t# int" %} 8926 opcode(0x23); 8927 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 8928 ins_pipe(ialu_reg_reg); 8929%} 8930 8931// And Register with Immediate 255 8932instruct andI_rReg_imm255(rRegI dst, immI_255 src) 8933%{ 8934 match(Set dst (AndI dst src)); 8935 8936 format %{ "movzbl $dst, $dst\t# int & 0xFF" %} 8937 opcode(0x0F, 0xB6); 8938 ins_encode(REX_reg_breg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 8939 ins_pipe(ialu_reg); 8940%} 8941 8942// And Register with Immediate 255 and promote to long 8943instruct andI2L_rReg_imm255(rRegL dst, rRegI src, immI_255 mask) 8944%{ 8945 match(Set dst (ConvI2L (AndI src mask))); 8946 8947 format %{ "movzbl $dst, $src\t# int & 0xFF -> long" %} 8948 opcode(0x0F, 0xB6); 8949 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8950 ins_pipe(ialu_reg); 8951%} 8952 8953// And Register with Immediate 65535 8954instruct andI_rReg_imm65535(rRegI dst, immI_65535 src) 8955%{ 8956 match(Set dst (AndI dst src)); 8957 8958 format %{ "movzwl $dst, $dst\t# int & 0xFFFF" %} 8959 opcode(0x0F, 0xB7); 8960 ins_encode(REX_reg_reg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 8961 ins_pipe(ialu_reg); 8962%} 8963 8964// And Register with Immediate 65535 and promote to long 8965instruct andI2L_rReg_imm65535(rRegL dst, rRegI src, immI_65535 mask) 8966%{ 8967 match(Set dst (ConvI2L (AndI src mask))); 8968 8969 format %{ "movzwl $dst, $src\t# int & 0xFFFF -> long" %} 8970 opcode(0x0F, 0xB7); 8971 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8972 ins_pipe(ialu_reg); 8973%} 8974 8975// And Register with Immediate 8976instruct andI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 8977%{ 8978 match(Set dst (AndI dst src)); 8979 effect(KILL cr); 8980 8981 format %{ "andl $dst, $src\t# int" %} 8982 opcode(0x81, 0x04); /* Opcode 81 /4 */ 8983 ins_encode(OpcSErm(dst, src), Con8or32(src)); 8984 ins_pipe(ialu_reg); 8985%} 8986 8987// And Register with Memory 8988instruct andI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 8989%{ 8990 match(Set dst (AndI dst (LoadI src))); 8991 effect(KILL cr); 8992 8993 ins_cost(125); 8994 format %{ "andl $dst, $src\t# int" %} 8995 opcode(0x23); 8996 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 8997 ins_pipe(ialu_reg_mem); 8998%} 8999 9000// And Memory with Register 9001instruct andI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9002%{ 9003 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 9004 effect(KILL cr); 9005 9006 ins_cost(150); 9007 format %{ "andl $dst, $src\t# int" %} 9008 opcode(0x21); /* Opcode 21 /r */ 9009 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9010 ins_pipe(ialu_mem_reg); 9011%} 9012 9013// And Memory with Immediate 9014instruct andI_mem_imm(memory dst, immI src, rFlagsReg cr) 9015%{ 9016 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 9017 effect(KILL cr); 9018 9019 ins_cost(125); 9020 format %{ "andl $dst, $src\t# int" %} 9021 opcode(0x81, 0x4); /* Opcode 81 /4 id */ 9022 ins_encode(REX_mem(dst), OpcSE(src), 9023 RM_opc_mem(secondary, dst), Con8or32(src)); 9024 ins_pipe(ialu_mem_imm); 9025%} 9026 9027// Or Instructions 9028// Or Register with Register 9029instruct orI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9030%{ 9031 match(Set dst (OrI dst src)); 9032 effect(KILL cr); 9033 9034 format %{ "orl $dst, $src\t# int" %} 9035 opcode(0x0B); 9036 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9037 ins_pipe(ialu_reg_reg); 9038%} 9039 9040// Or Register with Immediate 9041instruct orI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9042%{ 9043 match(Set dst (OrI dst src)); 9044 effect(KILL cr); 9045 9046 format %{ "orl $dst, $src\t# int" %} 9047 opcode(0x81, 0x01); /* Opcode 81 /1 id */ 9048 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9049 ins_pipe(ialu_reg); 9050%} 9051 9052// Or Register with Memory 9053instruct orI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9054%{ 9055 match(Set dst (OrI dst (LoadI src))); 9056 effect(KILL cr); 9057 9058 ins_cost(125); 9059 format %{ "orl $dst, $src\t# int" %} 9060 opcode(0x0B); 9061 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9062 ins_pipe(ialu_reg_mem); 9063%} 9064 9065// Or Memory with Register 9066instruct orI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9067%{ 9068 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9069 effect(KILL cr); 9070 9071 ins_cost(150); 9072 format %{ "orl $dst, $src\t# int" %} 9073 opcode(0x09); /* Opcode 09 /r */ 9074 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9075 ins_pipe(ialu_mem_reg); 9076%} 9077 9078// Or Memory with Immediate 9079instruct orI_mem_imm(memory dst, immI src, rFlagsReg cr) 9080%{ 9081 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9082 effect(KILL cr); 9083 9084 ins_cost(125); 9085 format %{ "orl $dst, $src\t# int" %} 9086 opcode(0x81, 0x1); /* Opcode 81 /1 id */ 9087 ins_encode(REX_mem(dst), OpcSE(src), 9088 RM_opc_mem(secondary, dst), Con8or32(src)); 9089 ins_pipe(ialu_mem_imm); 9090%} 9091 9092// Xor Instructions 9093// Xor Register with Register 9094instruct xorI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9095%{ 9096 match(Set dst (XorI dst src)); 9097 effect(KILL cr); 9098 9099 format %{ "xorl $dst, $src\t# int" %} 9100 opcode(0x33); 9101 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9102 ins_pipe(ialu_reg_reg); 9103%} 9104 9105// Xor Register with Immediate -1 9106instruct xorI_rReg_im1(rRegI dst, immI_M1 imm) %{ 9107 match(Set dst (XorI dst imm)); 9108 9109 format %{ "not $dst" %} 9110 ins_encode %{ 9111 __ notl($dst$$Register); 9112 %} 9113 ins_pipe(ialu_reg); 9114%} 9115 9116// Xor Register with Immediate 9117instruct xorI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9118%{ 9119 match(Set dst (XorI dst src)); 9120 effect(KILL cr); 9121 9122 format %{ "xorl $dst, $src\t# int" %} 9123 opcode(0x81, 0x06); /* Opcode 81 /6 id */ 9124 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9125 ins_pipe(ialu_reg); 9126%} 9127 9128// Xor Register with Memory 9129instruct xorI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9130%{ 9131 match(Set dst (XorI dst (LoadI src))); 9132 effect(KILL cr); 9133 9134 ins_cost(125); 9135 format %{ "xorl $dst, $src\t# int" %} 9136 opcode(0x33); 9137 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9138 ins_pipe(ialu_reg_mem); 9139%} 9140 9141// Xor Memory with Register 9142instruct xorI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9143%{ 9144 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9145 effect(KILL cr); 9146 9147 ins_cost(150); 9148 format %{ "xorl $dst, $src\t# int" %} 9149 opcode(0x31); /* Opcode 31 /r */ 9150 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9151 ins_pipe(ialu_mem_reg); 9152%} 9153 9154// Xor Memory with Immediate 9155instruct xorI_mem_imm(memory dst, immI src, rFlagsReg cr) 9156%{ 9157 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9158 effect(KILL cr); 9159 9160 ins_cost(125); 9161 format %{ "xorl $dst, $src\t# int" %} 9162 opcode(0x81, 0x6); /* Opcode 81 /6 id */ 9163 ins_encode(REX_mem(dst), OpcSE(src), 9164 RM_opc_mem(secondary, dst), Con8or32(src)); 9165 ins_pipe(ialu_mem_imm); 9166%} 9167 9168 9169// Long Logical Instructions 9170 9171// And Instructions 9172// And Register with Register 9173instruct andL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9174%{ 9175 match(Set dst (AndL dst src)); 9176 effect(KILL cr); 9177 9178 format %{ "andq $dst, $src\t# long" %} 9179 opcode(0x23); 9180 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9181 ins_pipe(ialu_reg_reg); 9182%} 9183 9184// And Register with Immediate 255 9185instruct andL_rReg_imm255(rRegL dst, immL_255 src) 9186%{ 9187 match(Set dst (AndL dst src)); 9188 9189 format %{ "movzbq $dst, $dst\t# long & 0xFF" %} 9190 opcode(0x0F, 0xB6); 9191 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9192 ins_pipe(ialu_reg); 9193%} 9194 9195// And Register with Immediate 65535 9196instruct andL_rReg_imm65535(rRegL dst, immL_65535 src) 9197%{ 9198 match(Set dst (AndL dst src)); 9199 9200 format %{ "movzwq $dst, $dst\t# long & 0xFFFF" %} 9201 opcode(0x0F, 0xB7); 9202 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9203 ins_pipe(ialu_reg); 9204%} 9205 9206// And Register with Immediate 9207instruct andL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9208%{ 9209 match(Set dst (AndL dst src)); 9210 effect(KILL cr); 9211 9212 format %{ "andq $dst, $src\t# long" %} 9213 opcode(0x81, 0x04); /* Opcode 81 /4 */ 9214 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9215 ins_pipe(ialu_reg); 9216%} 9217 9218// And Register with Memory 9219instruct andL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9220%{ 9221 match(Set dst (AndL dst (LoadL src))); 9222 effect(KILL cr); 9223 9224 ins_cost(125); 9225 format %{ "andq $dst, $src\t# long" %} 9226 opcode(0x23); 9227 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9228 ins_pipe(ialu_reg_mem); 9229%} 9230 9231// And Memory with Register 9232instruct andL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9233%{ 9234 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9235 effect(KILL cr); 9236 9237 ins_cost(150); 9238 format %{ "andq $dst, $src\t# long" %} 9239 opcode(0x21); /* Opcode 21 /r */ 9240 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9241 ins_pipe(ialu_mem_reg); 9242%} 9243 9244// And Memory with Immediate 9245instruct andL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9246%{ 9247 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9248 effect(KILL cr); 9249 9250 ins_cost(125); 9251 format %{ "andq $dst, $src\t# long" %} 9252 opcode(0x81, 0x4); /* Opcode 81 /4 id */ 9253 ins_encode(REX_mem_wide(dst), OpcSE(src), 9254 RM_opc_mem(secondary, dst), Con8or32(src)); 9255 ins_pipe(ialu_mem_imm); 9256%} 9257 9258// Or Instructions 9259// Or Register with Register 9260instruct orL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9261%{ 9262 match(Set dst (OrL dst src)); 9263 effect(KILL cr); 9264 9265 format %{ "orq $dst, $src\t# long" %} 9266 opcode(0x0B); 9267 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9268 ins_pipe(ialu_reg_reg); 9269%} 9270 9271// Use any_RegP to match R15 (TLS register) without spilling. 9272instruct orL_rReg_castP2X(rRegL dst, any_RegP src, rFlagsReg cr) %{ 9273 match(Set dst (OrL dst (CastP2X src))); 9274 effect(KILL cr); 9275 9276 format %{ "orq $dst, $src\t# long" %} 9277 opcode(0x0B); 9278 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9279 ins_pipe(ialu_reg_reg); 9280%} 9281 9282 9283// Or Register with Immediate 9284instruct orL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9285%{ 9286 match(Set dst (OrL dst src)); 9287 effect(KILL cr); 9288 9289 format %{ "orq $dst, $src\t# long" %} 9290 opcode(0x81, 0x01); /* Opcode 81 /1 id */ 9291 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9292 ins_pipe(ialu_reg); 9293%} 9294 9295// Or Register with Memory 9296instruct orL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9297%{ 9298 match(Set dst (OrL dst (LoadL src))); 9299 effect(KILL cr); 9300 9301 ins_cost(125); 9302 format %{ "orq $dst, $src\t# long" %} 9303 opcode(0x0B); 9304 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9305 ins_pipe(ialu_reg_mem); 9306%} 9307 9308// Or Memory with Register 9309instruct orL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9310%{ 9311 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9312 effect(KILL cr); 9313 9314 ins_cost(150); 9315 format %{ "orq $dst, $src\t# long" %} 9316 opcode(0x09); /* Opcode 09 /r */ 9317 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9318 ins_pipe(ialu_mem_reg); 9319%} 9320 9321// Or Memory with Immediate 9322instruct orL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9323%{ 9324 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9325 effect(KILL cr); 9326 9327 ins_cost(125); 9328 format %{ "orq $dst, $src\t# long" %} 9329 opcode(0x81, 0x1); /* Opcode 81 /1 id */ 9330 ins_encode(REX_mem_wide(dst), OpcSE(src), 9331 RM_opc_mem(secondary, dst), Con8or32(src)); 9332 ins_pipe(ialu_mem_imm); 9333%} 9334 9335// Xor Instructions 9336// Xor Register with Register 9337instruct xorL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9338%{ 9339 match(Set dst (XorL dst src)); 9340 effect(KILL cr); 9341 9342 format %{ "xorq $dst, $src\t# long" %} 9343 opcode(0x33); 9344 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9345 ins_pipe(ialu_reg_reg); 9346%} 9347 9348// Xor Register with Immediate -1 9349instruct xorL_rReg_im1(rRegL dst, immL_M1 imm) %{ 9350 match(Set dst (XorL dst imm)); 9351 9352 format %{ "notq $dst" %} 9353 ins_encode %{ 9354 __ notq($dst$$Register); 9355 %} 9356 ins_pipe(ialu_reg); 9357%} 9358 9359// Xor Register with Immediate 9360instruct xorL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9361%{ 9362 match(Set dst (XorL dst src)); 9363 effect(KILL cr); 9364 9365 format %{ "xorq $dst, $src\t# long" %} 9366 opcode(0x81, 0x06); /* Opcode 81 /6 id */ 9367 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9368 ins_pipe(ialu_reg); 9369%} 9370 9371// Xor Register with Memory 9372instruct xorL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9373%{ 9374 match(Set dst (XorL dst (LoadL src))); 9375 effect(KILL cr); 9376 9377 ins_cost(125); 9378 format %{ "xorq $dst, $src\t# long" %} 9379 opcode(0x33); 9380 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9381 ins_pipe(ialu_reg_mem); 9382%} 9383 9384// Xor Memory with Register 9385instruct xorL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9386%{ 9387 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 9388 effect(KILL cr); 9389 9390 ins_cost(150); 9391 format %{ "xorq $dst, $src\t# long" %} 9392 opcode(0x31); /* Opcode 31 /r */ 9393 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9394 ins_pipe(ialu_mem_reg); 9395%} 9396 9397// Xor Memory with Immediate 9398instruct xorL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9399%{ 9400 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 9401 effect(KILL cr); 9402 9403 ins_cost(125); 9404 format %{ "xorq $dst, $src\t# long" %} 9405 opcode(0x81, 0x6); /* Opcode 81 /6 id */ 9406 ins_encode(REX_mem_wide(dst), OpcSE(src), 9407 RM_opc_mem(secondary, dst), Con8or32(src)); 9408 ins_pipe(ialu_mem_imm); 9409%} 9410 9411// Convert Int to Boolean 9412instruct convI2B(rRegI dst, rRegI src, rFlagsReg cr) 9413%{ 9414 match(Set dst (Conv2B src)); 9415 effect(KILL cr); 9416 9417 format %{ "testl $src, $src\t# ci2b\n\t" 9418 "setnz $dst\n\t" 9419 "movzbl $dst, $dst" %} 9420 ins_encode(REX_reg_reg(src, src), opc_reg_reg(0x85, src, src), // testl 9421 setNZ_reg(dst), 9422 REX_reg_breg(dst, dst), // movzbl 9423 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst)); 9424 ins_pipe(pipe_slow); // XXX 9425%} 9426 9427// Convert Pointer to Boolean 9428instruct convP2B(rRegI dst, rRegP src, rFlagsReg cr) 9429%{ 9430 match(Set dst (Conv2B src)); 9431 effect(KILL cr); 9432 9433 format %{ "testq $src, $src\t# cp2b\n\t" 9434 "setnz $dst\n\t" 9435 "movzbl $dst, $dst" %} 9436 ins_encode(REX_reg_reg_wide(src, src), opc_reg_reg(0x85, src, src), // testq 9437 setNZ_reg(dst), 9438 REX_reg_breg(dst, dst), // movzbl 9439 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst)); 9440 ins_pipe(pipe_slow); // XXX 9441%} 9442 9443instruct cmpLTMask(rRegI dst, rRegI p, rRegI q, rFlagsReg cr) 9444%{ 9445 match(Set dst (CmpLTMask p q)); 9446 effect(KILL cr); 9447 9448 ins_cost(400); // XXX 9449 format %{ "cmpl $p, $q\t# cmpLTMask\n\t" 9450 "setlt $dst\n\t" 9451 "movzbl $dst, $dst\n\t" 9452 "negl $dst" %} 9453 ins_encode(REX_reg_reg(p, q), opc_reg_reg(0x3B, p, q), // cmpl 9454 setLT_reg(dst), 9455 REX_reg_breg(dst, dst), // movzbl 9456 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst), 9457 neg_reg(dst)); 9458 ins_pipe(pipe_slow); 9459%} 9460 9461instruct cmpLTMask0(rRegI dst, immI0 zero, rFlagsReg cr) 9462%{ 9463 match(Set dst (CmpLTMask dst zero)); 9464 effect(KILL cr); 9465 9466 ins_cost(100); // XXX 9467 format %{ "sarl $dst, #31\t# cmpLTMask0" %} 9468 opcode(0xC1, 0x7); /* C1 /7 ib */ 9469 ins_encode(reg_opc_imm(dst, 0x1F)); 9470 ins_pipe(ialu_reg); 9471%} 9472 9473 9474instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y, rRegI tmp, rFlagsReg cr) 9475%{ 9476 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q))); 9477 effect(TEMP tmp, KILL cr); 9478 9479 ins_cost(400); // XXX 9480 format %{ "subl $p, $q\t# cadd_cmpLTMask1\n\t" 9481 "sbbl $tmp, $tmp\n\t" 9482 "andl $tmp, $y\n\t" 9483 "addl $p, $tmp" %} 9484 ins_encode %{ 9485 Register Rp = $p$$Register; 9486 Register Rq = $q$$Register; 9487 Register Ry = $y$$Register; 9488 Register Rt = $tmp$$Register; 9489 __ subl(Rp, Rq); 9490 __ sbbl(Rt, Rt); 9491 __ andl(Rt, Ry); 9492 __ addl(Rp, Rt); 9493 %} 9494 ins_pipe(pipe_cmplt); 9495%} 9496 9497//---------- FP Instructions------------------------------------------------ 9498 9499instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2) 9500%{ 9501 match(Set cr (CmpF src1 src2)); 9502 9503 ins_cost(145); 9504 format %{ "ucomiss $src1, $src2\n\t" 9505 "jnp,s exit\n\t" 9506 "pushfq\t# saw NaN, set CF\n\t" 9507 "andq [rsp], #0xffffff2b\n\t" 9508 "popfq\n" 9509 "exit:" %} 9510 ins_encode %{ 9511 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9512 emit_cmpfp_fixup(_masm); 9513 %} 9514 ins_pipe(pipe_slow); 9515%} 9516 9517instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{ 9518 match(Set cr (CmpF src1 src2)); 9519 9520 ins_cost(100); 9521 format %{ "ucomiss $src1, $src2" %} 9522 ins_encode %{ 9523 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9524 %} 9525 ins_pipe(pipe_slow); 9526%} 9527 9528instruct cmpF_cc_mem(rFlagsRegU cr, regF src1, memory src2) 9529%{ 9530 match(Set cr (CmpF src1 (LoadF src2))); 9531 9532 ins_cost(145); 9533 format %{ "ucomiss $src1, $src2\n\t" 9534 "jnp,s exit\n\t" 9535 "pushfq\t# saw NaN, set CF\n\t" 9536 "andq [rsp], #0xffffff2b\n\t" 9537 "popfq\n" 9538 "exit:" %} 9539 ins_encode %{ 9540 __ ucomiss($src1$$XMMRegister, $src2$$Address); 9541 emit_cmpfp_fixup(_masm); 9542 %} 9543 ins_pipe(pipe_slow); 9544%} 9545 9546instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{ 9547 match(Set cr (CmpF src1 (LoadF src2))); 9548 9549 ins_cost(100); 9550 format %{ "ucomiss $src1, $src2" %} 9551 ins_encode %{ 9552 __ ucomiss($src1$$XMMRegister, $src2$$Address); 9553 %} 9554 ins_pipe(pipe_slow); 9555%} 9556 9557instruct cmpF_cc_imm(rFlagsRegU cr, regF src, immF con) %{ 9558 match(Set cr (CmpF src con)); 9559 9560 ins_cost(145); 9561 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 9562 "jnp,s exit\n\t" 9563 "pushfq\t# saw NaN, set CF\n\t" 9564 "andq [rsp], #0xffffff2b\n\t" 9565 "popfq\n" 9566 "exit:" %} 9567 ins_encode %{ 9568 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 9569 emit_cmpfp_fixup(_masm); 9570 %} 9571 ins_pipe(pipe_slow); 9572%} 9573 9574instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src, immF con) %{ 9575 match(Set cr (CmpF src con)); 9576 ins_cost(100); 9577 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con" %} 9578 ins_encode %{ 9579 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 9580 %} 9581 ins_pipe(pipe_slow); 9582%} 9583 9584instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2) 9585%{ 9586 match(Set cr (CmpD src1 src2)); 9587 9588 ins_cost(145); 9589 format %{ "ucomisd $src1, $src2\n\t" 9590 "jnp,s exit\n\t" 9591 "pushfq\t# saw NaN, set CF\n\t" 9592 "andq [rsp], #0xffffff2b\n\t" 9593 "popfq\n" 9594 "exit:" %} 9595 ins_encode %{ 9596 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9597 emit_cmpfp_fixup(_masm); 9598 %} 9599 ins_pipe(pipe_slow); 9600%} 9601 9602instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{ 9603 match(Set cr (CmpD src1 src2)); 9604 9605 ins_cost(100); 9606 format %{ "ucomisd $src1, $src2 test" %} 9607 ins_encode %{ 9608 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9609 %} 9610 ins_pipe(pipe_slow); 9611%} 9612 9613instruct cmpD_cc_mem(rFlagsRegU cr, regD src1, memory src2) 9614%{ 9615 match(Set cr (CmpD src1 (LoadD src2))); 9616 9617 ins_cost(145); 9618 format %{ "ucomisd $src1, $src2\n\t" 9619 "jnp,s exit\n\t" 9620 "pushfq\t# saw NaN, set CF\n\t" 9621 "andq [rsp], #0xffffff2b\n\t" 9622 "popfq\n" 9623 "exit:" %} 9624 ins_encode %{ 9625 __ ucomisd($src1$$XMMRegister, $src2$$Address); 9626 emit_cmpfp_fixup(_masm); 9627 %} 9628 ins_pipe(pipe_slow); 9629%} 9630 9631instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{ 9632 match(Set cr (CmpD src1 (LoadD src2))); 9633 9634 ins_cost(100); 9635 format %{ "ucomisd $src1, $src2" %} 9636 ins_encode %{ 9637 __ ucomisd($src1$$XMMRegister, $src2$$Address); 9638 %} 9639 ins_pipe(pipe_slow); 9640%} 9641 9642instruct cmpD_cc_imm(rFlagsRegU cr, regD src, immD con) %{ 9643 match(Set cr (CmpD src con)); 9644 9645 ins_cost(145); 9646 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 9647 "jnp,s exit\n\t" 9648 "pushfq\t# saw NaN, set CF\n\t" 9649 "andq [rsp], #0xffffff2b\n\t" 9650 "popfq\n" 9651 "exit:" %} 9652 ins_encode %{ 9653 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 9654 emit_cmpfp_fixup(_masm); 9655 %} 9656 ins_pipe(pipe_slow); 9657%} 9658 9659instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src, immD con) %{ 9660 match(Set cr (CmpD src con)); 9661 ins_cost(100); 9662 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con" %} 9663 ins_encode %{ 9664 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 9665 %} 9666 ins_pipe(pipe_slow); 9667%} 9668 9669// Compare into -1,0,1 9670instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr) 9671%{ 9672 match(Set dst (CmpF3 src1 src2)); 9673 effect(KILL cr); 9674 9675 ins_cost(275); 9676 format %{ "ucomiss $src1, $src2\n\t" 9677 "movl $dst, #-1\n\t" 9678 "jp,s done\n\t" 9679 "jb,s done\n\t" 9680 "setne $dst\n\t" 9681 "movzbl $dst, $dst\n" 9682 "done:" %} 9683 ins_encode %{ 9684 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9685 emit_cmpfp3(_masm, $dst$$Register); 9686 %} 9687 ins_pipe(pipe_slow); 9688%} 9689 9690// Compare into -1,0,1 9691instruct cmpF_mem(rRegI dst, regF src1, memory src2, rFlagsReg cr) 9692%{ 9693 match(Set dst (CmpF3 src1 (LoadF src2))); 9694 effect(KILL cr); 9695 9696 ins_cost(275); 9697 format %{ "ucomiss $src1, $src2\n\t" 9698 "movl $dst, #-1\n\t" 9699 "jp,s done\n\t" 9700 "jb,s done\n\t" 9701 "setne $dst\n\t" 9702 "movzbl $dst, $dst\n" 9703 "done:" %} 9704 ins_encode %{ 9705 __ ucomiss($src1$$XMMRegister, $src2$$Address); 9706 emit_cmpfp3(_masm, $dst$$Register); 9707 %} 9708 ins_pipe(pipe_slow); 9709%} 9710 9711// Compare into -1,0,1 9712instruct cmpF_imm(rRegI dst, regF src, immF con, rFlagsReg cr) %{ 9713 match(Set dst (CmpF3 src con)); 9714 effect(KILL cr); 9715 9716 ins_cost(275); 9717 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 9718 "movl $dst, #-1\n\t" 9719 "jp,s done\n\t" 9720 "jb,s done\n\t" 9721 "setne $dst\n\t" 9722 "movzbl $dst, $dst\n" 9723 "done:" %} 9724 ins_encode %{ 9725 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 9726 emit_cmpfp3(_masm, $dst$$Register); 9727 %} 9728 ins_pipe(pipe_slow); 9729%} 9730 9731// Compare into -1,0,1 9732instruct cmpD_reg(rRegI dst, regD src1, regD src2, rFlagsReg cr) 9733%{ 9734 match(Set dst (CmpD3 src1 src2)); 9735 effect(KILL cr); 9736 9737 ins_cost(275); 9738 format %{ "ucomisd $src1, $src2\n\t" 9739 "movl $dst, #-1\n\t" 9740 "jp,s done\n\t" 9741 "jb,s done\n\t" 9742 "setne $dst\n\t" 9743 "movzbl $dst, $dst\n" 9744 "done:" %} 9745 ins_encode %{ 9746 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9747 emit_cmpfp3(_masm, $dst$$Register); 9748 %} 9749 ins_pipe(pipe_slow); 9750%} 9751 9752// Compare into -1,0,1 9753instruct cmpD_mem(rRegI dst, regD src1, memory src2, rFlagsReg cr) 9754%{ 9755 match(Set dst (CmpD3 src1 (LoadD src2))); 9756 effect(KILL cr); 9757 9758 ins_cost(275); 9759 format %{ "ucomisd $src1, $src2\n\t" 9760 "movl $dst, #-1\n\t" 9761 "jp,s done\n\t" 9762 "jb,s done\n\t" 9763 "setne $dst\n\t" 9764 "movzbl $dst, $dst\n" 9765 "done:" %} 9766 ins_encode %{ 9767 __ ucomisd($src1$$XMMRegister, $src2$$Address); 9768 emit_cmpfp3(_masm, $dst$$Register); 9769 %} 9770 ins_pipe(pipe_slow); 9771%} 9772 9773// Compare into -1,0,1 9774instruct cmpD_imm(rRegI dst, regD src, immD con, rFlagsReg cr) %{ 9775 match(Set dst (CmpD3 src con)); 9776 effect(KILL cr); 9777 9778 ins_cost(275); 9779 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 9780 "movl $dst, #-1\n\t" 9781 "jp,s done\n\t" 9782 "jb,s done\n\t" 9783 "setne $dst\n\t" 9784 "movzbl $dst, $dst\n" 9785 "done:" %} 9786 ins_encode %{ 9787 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 9788 emit_cmpfp3(_masm, $dst$$Register); 9789 %} 9790 ins_pipe(pipe_slow); 9791%} 9792 9793// -----------Trig and Trancendental Instructions------------------------------ 9794instruct cosD_reg(regD dst) %{ 9795 match(Set dst (CosD dst)); 9796 9797 format %{ "dcos $dst\n\t" %} 9798 opcode(0xD9, 0xFF); 9799 ins_encode( Push_SrcXD(dst), OpcP, OpcS, Push_ResultXD(dst) ); 9800 ins_pipe( pipe_slow ); 9801%} 9802 9803instruct sinD_reg(regD dst) %{ 9804 match(Set dst (SinD dst)); 9805 9806 format %{ "dsin $dst\n\t" %} 9807 opcode(0xD9, 0xFE); 9808 ins_encode( Push_SrcXD(dst), OpcP, OpcS, Push_ResultXD(dst) ); 9809 ins_pipe( pipe_slow ); 9810%} 9811 9812instruct tanD_reg(regD dst) %{ 9813 match(Set dst (TanD dst)); 9814 9815 format %{ "dtan $dst\n\t" %} 9816 ins_encode( Push_SrcXD(dst), 9817 Opcode(0xD9), Opcode(0xF2), //fptan 9818 Opcode(0xDD), Opcode(0xD8), //fstp st 9819 Push_ResultXD(dst) ); 9820 ins_pipe( pipe_slow ); 9821%} 9822 9823instruct log10D_reg(regD dst) %{ 9824 // The source and result Double operands in XMM registers 9825 match(Set dst (Log10D dst)); 9826 // fldlg2 ; push log_10(2) on the FPU stack; full 80-bit number 9827 // fyl2x ; compute log_10(2) * log_2(x) 9828 format %{ "fldlg2\t\t\t#Log10\n\t" 9829 "fyl2x\t\t\t# Q=Log10*Log_2(x)\n\t" 9830 %} 9831 ins_encode(Opcode(0xD9), Opcode(0xEC), // fldlg2 9832 Push_SrcXD(dst), 9833 Opcode(0xD9), Opcode(0xF1), // fyl2x 9834 Push_ResultXD(dst)); 9835 9836 ins_pipe( pipe_slow ); 9837%} 9838 9839instruct logD_reg(regD dst) %{ 9840 // The source and result Double operands in XMM registers 9841 match(Set dst (LogD dst)); 9842 // fldln2 ; push log_e(2) on the FPU stack; full 80-bit number 9843 // fyl2x ; compute log_e(2) * log_2(x) 9844 format %{ "fldln2\t\t\t#Log_e\n\t" 9845 "fyl2x\t\t\t# Q=Log_e*Log_2(x)\n\t" 9846 %} 9847 ins_encode( Opcode(0xD9), Opcode(0xED), // fldln2 9848 Push_SrcXD(dst), 9849 Opcode(0xD9), Opcode(0xF1), // fyl2x 9850 Push_ResultXD(dst)); 9851 ins_pipe( pipe_slow ); 9852%} 9853 9854instruct powD_reg(regD dst, regD src0, regD src1, rax_RegI rax, rdx_RegI rdx, rcx_RegI rcx, rFlagsReg cr) %{ 9855 match(Set dst (PowD src0 src1)); // Raise src0 to the src1'th power 9856 effect(KILL rax, KILL rdx, KILL rcx, KILL cr); 9857 format %{ "fast_pow $src0 $src1 -> $dst // KILL $rax, $rcx, $rdx" %} 9858 ins_encode %{ 9859 __ subptr(rsp, 8); 9860 __ movdbl(Address(rsp, 0), $src1$$XMMRegister); 9861 __ fld_d(Address(rsp, 0)); 9862 __ movdbl(Address(rsp, 0), $src0$$XMMRegister); 9863 __ fld_d(Address(rsp, 0)); 9864 __ fast_pow(); 9865 __ fstp_d(Address(rsp, 0)); 9866 __ movdbl($dst$$XMMRegister, Address(rsp, 0)); 9867 __ addptr(rsp, 8); 9868 %} 9869 ins_pipe( pipe_slow ); 9870%} 9871 9872instruct expD_reg(regD dst, regD src, rax_RegI rax, rdx_RegI rdx, rcx_RegI rcx, rFlagsReg cr) %{ 9873 match(Set dst (ExpD src)); 9874 effect(KILL rax, KILL rcx, KILL rdx, KILL cr); 9875 format %{ "fast_exp $dst -> $src // KILL $rax, $rcx, $rdx" %} 9876 ins_encode %{ 9877 __ subptr(rsp, 8); 9878 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 9879 __ fld_d(Address(rsp, 0)); 9880 __ fast_exp(); 9881 __ fstp_d(Address(rsp, 0)); 9882 __ movdbl($dst$$XMMRegister, Address(rsp, 0)); 9883 __ addptr(rsp, 8); 9884 %} 9885 ins_pipe( pipe_slow ); 9886%} 9887 9888//----------Arithmetic Conversion Instructions--------------------------------- 9889 9890instruct roundFloat_nop(regF dst) 9891%{ 9892 match(Set dst (RoundFloat dst)); 9893 9894 ins_cost(0); 9895 ins_encode(); 9896 ins_pipe(empty); 9897%} 9898 9899instruct roundDouble_nop(regD dst) 9900%{ 9901 match(Set dst (RoundDouble dst)); 9902 9903 ins_cost(0); 9904 ins_encode(); 9905 ins_pipe(empty); 9906%} 9907 9908instruct convF2D_reg_reg(regD dst, regF src) 9909%{ 9910 match(Set dst (ConvF2D src)); 9911 9912 format %{ "cvtss2sd $dst, $src" %} 9913 ins_encode %{ 9914 __ cvtss2sd ($dst$$XMMRegister, $src$$XMMRegister); 9915 %} 9916 ins_pipe(pipe_slow); // XXX 9917%} 9918 9919instruct convF2D_reg_mem(regD dst, memory src) 9920%{ 9921 match(Set dst (ConvF2D (LoadF src))); 9922 9923 format %{ "cvtss2sd $dst, $src" %} 9924 ins_encode %{ 9925 __ cvtss2sd ($dst$$XMMRegister, $src$$Address); 9926 %} 9927 ins_pipe(pipe_slow); // XXX 9928%} 9929 9930instruct convD2F_reg_reg(regF dst, regD src) 9931%{ 9932 match(Set dst (ConvD2F src)); 9933 9934 format %{ "cvtsd2ss $dst, $src" %} 9935 ins_encode %{ 9936 __ cvtsd2ss ($dst$$XMMRegister, $src$$XMMRegister); 9937 %} 9938 ins_pipe(pipe_slow); // XXX 9939%} 9940 9941instruct convD2F_reg_mem(regF dst, memory src) 9942%{ 9943 match(Set dst (ConvD2F (LoadD src))); 9944 9945 format %{ "cvtsd2ss $dst, $src" %} 9946 ins_encode %{ 9947 __ cvtsd2ss ($dst$$XMMRegister, $src$$Address); 9948 %} 9949 ins_pipe(pipe_slow); // XXX 9950%} 9951 9952// XXX do mem variants 9953instruct convF2I_reg_reg(rRegI dst, regF src, rFlagsReg cr) 9954%{ 9955 match(Set dst (ConvF2I src)); 9956 effect(KILL cr); 9957 9958 format %{ "cvttss2sil $dst, $src\t# f2i\n\t" 9959 "cmpl $dst, #0x80000000\n\t" 9960 "jne,s done\n\t" 9961 "subq rsp, #8\n\t" 9962 "movss [rsp], $src\n\t" 9963 "call f2i_fixup\n\t" 9964 "popq $dst\n" 9965 "done: "%} 9966 ins_encode %{ 9967 Label done; 9968 __ cvttss2sil($dst$$Register, $src$$XMMRegister); 9969 __ cmpl($dst$$Register, 0x80000000); 9970 __ jccb(Assembler::notEqual, done); 9971 __ subptr(rsp, 8); 9972 __ movflt(Address(rsp, 0), $src$$XMMRegister); 9973 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::f2i_fixup()))); 9974 __ pop($dst$$Register); 9975 __ bind(done); 9976 %} 9977 ins_pipe(pipe_slow); 9978%} 9979 9980instruct convF2L_reg_reg(rRegL dst, regF src, rFlagsReg cr) 9981%{ 9982 match(Set dst (ConvF2L src)); 9983 effect(KILL cr); 9984 9985 format %{ "cvttss2siq $dst, $src\t# f2l\n\t" 9986 "cmpq $dst, [0x8000000000000000]\n\t" 9987 "jne,s done\n\t" 9988 "subq rsp, #8\n\t" 9989 "movss [rsp], $src\n\t" 9990 "call f2l_fixup\n\t" 9991 "popq $dst\n" 9992 "done: "%} 9993 ins_encode %{ 9994 Label done; 9995 __ cvttss2siq($dst$$Register, $src$$XMMRegister); 9996 __ cmp64($dst$$Register, 9997 ExternalAddress((address) StubRoutines::x86::double_sign_flip())); 9998 __ jccb(Assembler::notEqual, done); 9999 __ subptr(rsp, 8); 10000 __ movflt(Address(rsp, 0), $src$$XMMRegister); 10001 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::f2l_fixup()))); 10002 __ pop($dst$$Register); 10003 __ bind(done); 10004 %} 10005 ins_pipe(pipe_slow); 10006%} 10007 10008instruct convD2I_reg_reg(rRegI dst, regD src, rFlagsReg cr) 10009%{ 10010 match(Set dst (ConvD2I src)); 10011 effect(KILL cr); 10012 10013 format %{ "cvttsd2sil $dst, $src\t# d2i\n\t" 10014 "cmpl $dst, #0x80000000\n\t" 10015 "jne,s done\n\t" 10016 "subq rsp, #8\n\t" 10017 "movsd [rsp], $src\n\t" 10018 "call d2i_fixup\n\t" 10019 "popq $dst\n" 10020 "done: "%} 10021 ins_encode %{ 10022 Label done; 10023 __ cvttsd2sil($dst$$Register, $src$$XMMRegister); 10024 __ cmpl($dst$$Register, 0x80000000); 10025 __ jccb(Assembler::notEqual, done); 10026 __ subptr(rsp, 8); 10027 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 10028 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::d2i_fixup()))); 10029 __ pop($dst$$Register); 10030 __ bind(done); 10031 %} 10032 ins_pipe(pipe_slow); 10033%} 10034 10035instruct convD2L_reg_reg(rRegL dst, regD src, rFlagsReg cr) 10036%{ 10037 match(Set dst (ConvD2L src)); 10038 effect(KILL cr); 10039 10040 format %{ "cvttsd2siq $dst, $src\t# d2l\n\t" 10041 "cmpq $dst, [0x8000000000000000]\n\t" 10042 "jne,s done\n\t" 10043 "subq rsp, #8\n\t" 10044 "movsd [rsp], $src\n\t" 10045 "call d2l_fixup\n\t" 10046 "popq $dst\n" 10047 "done: "%} 10048 ins_encode %{ 10049 Label done; 10050 __ cvttsd2siq($dst$$Register, $src$$XMMRegister); 10051 __ cmp64($dst$$Register, 10052 ExternalAddress((address) StubRoutines::x86::double_sign_flip())); 10053 __ jccb(Assembler::notEqual, done); 10054 __ subptr(rsp, 8); 10055 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 10056 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::d2l_fixup()))); 10057 __ pop($dst$$Register); 10058 __ bind(done); 10059 %} 10060 ins_pipe(pipe_slow); 10061%} 10062 10063instruct convI2F_reg_reg(regF dst, rRegI src) 10064%{ 10065 predicate(!UseXmmI2F); 10066 match(Set dst (ConvI2F src)); 10067 10068 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10069 ins_encode %{ 10070 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Register); 10071 %} 10072 ins_pipe(pipe_slow); // XXX 10073%} 10074 10075instruct convI2F_reg_mem(regF dst, memory src) 10076%{ 10077 match(Set dst (ConvI2F (LoadI src))); 10078 10079 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10080 ins_encode %{ 10081 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Address); 10082 %} 10083 ins_pipe(pipe_slow); // XXX 10084%} 10085 10086instruct convI2D_reg_reg(regD dst, rRegI src) 10087%{ 10088 predicate(!UseXmmI2D); 10089 match(Set dst (ConvI2D src)); 10090 10091 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10092 ins_encode %{ 10093 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Register); 10094 %} 10095 ins_pipe(pipe_slow); // XXX 10096%} 10097 10098instruct convI2D_reg_mem(regD dst, memory src) 10099%{ 10100 match(Set dst (ConvI2D (LoadI src))); 10101 10102 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10103 ins_encode %{ 10104 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Address); 10105 %} 10106 ins_pipe(pipe_slow); // XXX 10107%} 10108 10109instruct convXI2F_reg(regF dst, rRegI src) 10110%{ 10111 predicate(UseXmmI2F); 10112 match(Set dst (ConvI2F src)); 10113 10114 format %{ "movdl $dst, $src\n\t" 10115 "cvtdq2psl $dst, $dst\t# i2f" %} 10116 ins_encode %{ 10117 __ movdl($dst$$XMMRegister, $src$$Register); 10118 __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister); 10119 %} 10120 ins_pipe(pipe_slow); // XXX 10121%} 10122 10123instruct convXI2D_reg(regD dst, rRegI src) 10124%{ 10125 predicate(UseXmmI2D); 10126 match(Set dst (ConvI2D src)); 10127 10128 format %{ "movdl $dst, $src\n\t" 10129 "cvtdq2pdl $dst, $dst\t# i2d" %} 10130 ins_encode %{ 10131 __ movdl($dst$$XMMRegister, $src$$Register); 10132 __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister); 10133 %} 10134 ins_pipe(pipe_slow); // XXX 10135%} 10136 10137instruct convL2F_reg_reg(regF dst, rRegL src) 10138%{ 10139 match(Set dst (ConvL2F src)); 10140 10141 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10142 ins_encode %{ 10143 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Register); 10144 %} 10145 ins_pipe(pipe_slow); // XXX 10146%} 10147 10148instruct convL2F_reg_mem(regF dst, memory src) 10149%{ 10150 match(Set dst (ConvL2F (LoadL src))); 10151 10152 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10153 ins_encode %{ 10154 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Address); 10155 %} 10156 ins_pipe(pipe_slow); // XXX 10157%} 10158 10159instruct convL2D_reg_reg(regD dst, rRegL src) 10160%{ 10161 match(Set dst (ConvL2D src)); 10162 10163 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10164 ins_encode %{ 10165 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Register); 10166 %} 10167 ins_pipe(pipe_slow); // XXX 10168%} 10169 10170instruct convL2D_reg_mem(regD dst, memory src) 10171%{ 10172 match(Set dst (ConvL2D (LoadL src))); 10173 10174 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10175 ins_encode %{ 10176 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Address); 10177 %} 10178 ins_pipe(pipe_slow); // XXX 10179%} 10180 10181instruct convI2L_reg_reg(rRegL dst, rRegI src) 10182%{ 10183 match(Set dst (ConvI2L src)); 10184 10185 ins_cost(125); 10186 format %{ "movslq $dst, $src\t# i2l" %} 10187 ins_encode %{ 10188 __ movslq($dst$$Register, $src$$Register); 10189 %} 10190 ins_pipe(ialu_reg_reg); 10191%} 10192 10193// instruct convI2L_reg_reg_foo(rRegL dst, rRegI src) 10194// %{ 10195// match(Set dst (ConvI2L src)); 10196// // predicate(_kids[0]->_leaf->as_Type()->type()->is_int()->_lo >= 0 && 10197// // _kids[0]->_leaf->as_Type()->type()->is_int()->_hi >= 0); 10198// predicate(((const TypeNode*) n)->type()->is_long()->_hi == 10199// (unsigned int) ((const TypeNode*) n)->type()->is_long()->_hi && 10200// ((const TypeNode*) n)->type()->is_long()->_lo == 10201// (unsigned int) ((const TypeNode*) n)->type()->is_long()->_lo); 10202 10203// format %{ "movl $dst, $src\t# unsigned i2l" %} 10204// ins_encode(enc_copy(dst, src)); 10205// // opcode(0x63); // needs REX.W 10206// // ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst,src)); 10207// ins_pipe(ialu_reg_reg); 10208// %} 10209 10210// Zero-extend convert int to long 10211instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask) 10212%{ 10213 match(Set dst (AndL (ConvI2L src) mask)); 10214 10215 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10216 ins_encode %{ 10217 if ($dst$$reg != $src$$reg) { 10218 __ movl($dst$$Register, $src$$Register); 10219 } 10220 %} 10221 ins_pipe(ialu_reg_reg); 10222%} 10223 10224// Zero-extend convert int to long 10225instruct convI2L_reg_mem_zex(rRegL dst, memory src, immL_32bits mask) 10226%{ 10227 match(Set dst (AndL (ConvI2L (LoadI src)) mask)); 10228 10229 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10230 ins_encode %{ 10231 __ movl($dst$$Register, $src$$Address); 10232 %} 10233 ins_pipe(ialu_reg_mem); 10234%} 10235 10236instruct zerox_long_reg_reg(rRegL dst, rRegL src, immL_32bits mask) 10237%{ 10238 match(Set dst (AndL src mask)); 10239 10240 format %{ "movl $dst, $src\t# zero-extend long" %} 10241 ins_encode %{ 10242 __ movl($dst$$Register, $src$$Register); 10243 %} 10244 ins_pipe(ialu_reg_reg); 10245%} 10246 10247instruct convL2I_reg_reg(rRegI dst, rRegL src) 10248%{ 10249 match(Set dst (ConvL2I src)); 10250 10251 format %{ "movl $dst, $src\t# l2i" %} 10252 ins_encode %{ 10253 __ movl($dst$$Register, $src$$Register); 10254 %} 10255 ins_pipe(ialu_reg_reg); 10256%} 10257 10258 10259instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{ 10260 match(Set dst (MoveF2I src)); 10261 effect(DEF dst, USE src); 10262 10263 ins_cost(125); 10264 format %{ "movl $dst, $src\t# MoveF2I_stack_reg" %} 10265 ins_encode %{ 10266 __ movl($dst$$Register, Address(rsp, $src$$disp)); 10267 %} 10268 ins_pipe(ialu_reg_mem); 10269%} 10270 10271instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{ 10272 match(Set dst (MoveI2F src)); 10273 effect(DEF dst, USE src); 10274 10275 ins_cost(125); 10276 format %{ "movss $dst, $src\t# MoveI2F_stack_reg" %} 10277 ins_encode %{ 10278 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 10279 %} 10280 ins_pipe(pipe_slow); 10281%} 10282 10283instruct MoveD2L_stack_reg(rRegL dst, stackSlotD src) %{ 10284 match(Set dst (MoveD2L src)); 10285 effect(DEF dst, USE src); 10286 10287 ins_cost(125); 10288 format %{ "movq $dst, $src\t# MoveD2L_stack_reg" %} 10289 ins_encode %{ 10290 __ movq($dst$$Register, Address(rsp, $src$$disp)); 10291 %} 10292 ins_pipe(ialu_reg_mem); 10293%} 10294 10295instruct MoveL2D_stack_reg_partial(regD dst, stackSlotL src) %{ 10296 predicate(!UseXmmLoadAndClearUpper); 10297 match(Set dst (MoveL2D src)); 10298 effect(DEF dst, USE src); 10299 10300 ins_cost(125); 10301 format %{ "movlpd $dst, $src\t# MoveL2D_stack_reg" %} 10302 ins_encode %{ 10303 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10304 %} 10305 ins_pipe(pipe_slow); 10306%} 10307 10308instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{ 10309 predicate(UseXmmLoadAndClearUpper); 10310 match(Set dst (MoveL2D src)); 10311 effect(DEF dst, USE src); 10312 10313 ins_cost(125); 10314 format %{ "movsd $dst, $src\t# MoveL2D_stack_reg" %} 10315 ins_encode %{ 10316 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10317 %} 10318 ins_pipe(pipe_slow); 10319%} 10320 10321 10322instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{ 10323 match(Set dst (MoveF2I src)); 10324 effect(DEF dst, USE src); 10325 10326 ins_cost(95); // XXX 10327 format %{ "movss $dst, $src\t# MoveF2I_reg_stack" %} 10328 ins_encode %{ 10329 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 10330 %} 10331 ins_pipe(pipe_slow); 10332%} 10333 10334instruct MoveI2F_reg_stack(stackSlotF dst, rRegI src) %{ 10335 match(Set dst (MoveI2F src)); 10336 effect(DEF dst, USE src); 10337 10338 ins_cost(100); 10339 format %{ "movl $dst, $src\t# MoveI2F_reg_stack" %} 10340 ins_encode %{ 10341 __ movl(Address(rsp, $dst$$disp), $src$$Register); 10342 %} 10343 ins_pipe( ialu_mem_reg ); 10344%} 10345 10346instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{ 10347 match(Set dst (MoveD2L src)); 10348 effect(DEF dst, USE src); 10349 10350 ins_cost(95); // XXX 10351 format %{ "movsd $dst, $src\t# MoveL2D_reg_stack" %} 10352 ins_encode %{ 10353 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 10354 %} 10355 ins_pipe(pipe_slow); 10356%} 10357 10358instruct MoveL2D_reg_stack(stackSlotD dst, rRegL src) %{ 10359 match(Set dst (MoveL2D src)); 10360 effect(DEF dst, USE src); 10361 10362 ins_cost(100); 10363 format %{ "movq $dst, $src\t# MoveL2D_reg_stack" %} 10364 ins_encode %{ 10365 __ movq(Address(rsp, $dst$$disp), $src$$Register); 10366 %} 10367 ins_pipe(ialu_mem_reg); 10368%} 10369 10370instruct MoveF2I_reg_reg(rRegI dst, regF src) %{ 10371 match(Set dst (MoveF2I src)); 10372 effect(DEF dst, USE src); 10373 ins_cost(85); 10374 format %{ "movd $dst,$src\t# MoveF2I" %} 10375 ins_encode %{ 10376 __ movdl($dst$$Register, $src$$XMMRegister); 10377 %} 10378 ins_pipe( pipe_slow ); 10379%} 10380 10381instruct MoveD2L_reg_reg(rRegL dst, regD src) %{ 10382 match(Set dst (MoveD2L src)); 10383 effect(DEF dst, USE src); 10384 ins_cost(85); 10385 format %{ "movd $dst,$src\t# MoveD2L" %} 10386 ins_encode %{ 10387 __ movdq($dst$$Register, $src$$XMMRegister); 10388 %} 10389 ins_pipe( pipe_slow ); 10390%} 10391 10392instruct MoveI2F_reg_reg(regF dst, rRegI src) %{ 10393 match(Set dst (MoveI2F src)); 10394 effect(DEF dst, USE src); 10395 ins_cost(100); 10396 format %{ "movd $dst,$src\t# MoveI2F" %} 10397 ins_encode %{ 10398 __ movdl($dst$$XMMRegister, $src$$Register); 10399 %} 10400 ins_pipe( pipe_slow ); 10401%} 10402 10403instruct MoveL2D_reg_reg(regD dst, rRegL src) %{ 10404 match(Set dst (MoveL2D src)); 10405 effect(DEF dst, USE src); 10406 ins_cost(100); 10407 format %{ "movd $dst,$src\t# MoveL2D" %} 10408 ins_encode %{ 10409 __ movdq($dst$$XMMRegister, $src$$Register); 10410 %} 10411 ins_pipe( pipe_slow ); 10412%} 10413 10414 10415// ======================================================================= 10416// fast clearing of an array 10417instruct rep_stos(rcx_RegL cnt, rdi_RegP base, rax_RegI zero, Universe dummy, 10418 rFlagsReg cr) 10419%{ 10420 predicate(!UseFastStosb); 10421 match(Set dummy (ClearArray cnt base)); 10422 effect(USE_KILL cnt, USE_KILL base, KILL zero, KILL cr); 10423 10424 format %{ "xorq rax, rax\t# ClearArray:\n\t" 10425 "rep stosq\t# Store rax to *rdi++ while rcx--" %} 10426 ins_encode %{ 10427 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register); 10428 %} 10429 ins_pipe(pipe_slow); 10430%} 10431 10432instruct rep_fast_stosb(rcx_RegL cnt, rdi_RegP base, rax_RegI zero, Universe dummy, 10433 rFlagsReg cr) 10434%{ 10435 predicate(UseFastStosb); 10436 match(Set dummy (ClearArray cnt base)); 10437 effect(USE_KILL cnt, USE_KILL base, KILL zero, KILL cr); 10438 format %{ "xorq rax, rax\t# ClearArray:\n\t" 10439 "shlq rcx,3\t# Convert doublewords to bytes\n\t" 10440 "rep stosb\t# Store rax to *rdi++ while rcx--" %} 10441 ins_encode %{ 10442 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register); 10443 %} 10444 ins_pipe( pipe_slow ); 10445%} 10446 10447instruct string_compare(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10448 rax_RegI result, regD tmp1, rFlagsReg cr) 10449%{ 10450 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10451 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10452 10453 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10454 ins_encode %{ 10455 __ string_compare($str1$$Register, $str2$$Register, 10456 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10457 $tmp1$$XMMRegister); 10458 %} 10459 ins_pipe( pipe_slow ); 10460%} 10461 10462// fast search of substring with known size. 10463instruct string_indexof_con(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 10464 rbx_RegI result, regD vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 10465%{ 10466 predicate(UseSSE42Intrinsics); 10467 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 10468 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 10469 10470 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 10471 ins_encode %{ 10472 int icnt2 = (int)$int_cnt2$$constant; 10473 if (icnt2 >= 8) { 10474 // IndexOf for constant substrings with size >= 8 elements 10475 // which don't need to be loaded through stack. 10476 __ string_indexofC8($str1$$Register, $str2$$Register, 10477 $cnt1$$Register, $cnt2$$Register, 10478 icnt2, $result$$Register, 10479 $vec$$XMMRegister, $tmp$$Register); 10480 } else { 10481 // Small strings are loaded through stack if they cross page boundary. 10482 __ string_indexof($str1$$Register, $str2$$Register, 10483 $cnt1$$Register, $cnt2$$Register, 10484 icnt2, $result$$Register, 10485 $vec$$XMMRegister, $tmp$$Register); 10486 } 10487 %} 10488 ins_pipe( pipe_slow ); 10489%} 10490 10491instruct string_indexof(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 10492 rbx_RegI result, regD vec, rcx_RegI tmp, rFlagsReg cr) 10493%{ 10494 predicate(UseSSE42Intrinsics); 10495 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 10496 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 10497 10498 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 10499 ins_encode %{ 10500 __ string_indexof($str1$$Register, $str2$$Register, 10501 $cnt1$$Register, $cnt2$$Register, 10502 (-1), $result$$Register, 10503 $vec$$XMMRegister, $tmp$$Register); 10504 %} 10505 ins_pipe( pipe_slow ); 10506%} 10507 10508// fast string equals 10509instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 10510 regD tmp1, regD tmp2, rbx_RegI tmp3, rFlagsReg cr) 10511%{ 10512 match(Set result (StrEquals (Binary str1 str2) cnt)); 10513 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 10514 10515 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 10516 ins_encode %{ 10517 __ char_arrays_equals(false, $str1$$Register, $str2$$Register, 10518 $cnt$$Register, $result$$Register, $tmp3$$Register, 10519 $tmp1$$XMMRegister, $tmp2$$XMMRegister); 10520 %} 10521 ins_pipe( pipe_slow ); 10522%} 10523 10524// fast array equals 10525instruct array_equals(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 10526 regD tmp1, regD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 10527%{ 10528 match(Set result (AryEq ary1 ary2)); 10529 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 10530 //ins_cost(300); 10531 10532 format %{ "Array Equals $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 10533 ins_encode %{ 10534 __ char_arrays_equals(true, $ary1$$Register, $ary2$$Register, 10535 $tmp3$$Register, $result$$Register, $tmp4$$Register, 10536 $tmp1$$XMMRegister, $tmp2$$XMMRegister); 10537 %} 10538 ins_pipe( pipe_slow ); 10539%} 10540 10541// encode char[] to byte[] in ISO_8859_1 10542instruct encode_iso_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len, 10543 regD tmp1, regD tmp2, regD tmp3, regD tmp4, 10544 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 10545 match(Set result (EncodeISOArray src (Binary dst len))); 10546 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 10547 10548 format %{ "Encode array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %} 10549 ins_encode %{ 10550 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 10551 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 10552 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register); 10553 %} 10554 ins_pipe( pipe_slow ); 10555%} 10556 10557 10558//----------Control Flow Instructions------------------------------------------ 10559// Signed compare Instructions 10560 10561// XXX more variants!! 10562instruct compI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 10563%{ 10564 match(Set cr (CmpI op1 op2)); 10565 effect(DEF cr, USE op1, USE op2); 10566 10567 format %{ "cmpl $op1, $op2" %} 10568 opcode(0x3B); /* Opcode 3B /r */ 10569 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2)); 10570 ins_pipe(ialu_cr_reg_reg); 10571%} 10572 10573instruct compI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 10574%{ 10575 match(Set cr (CmpI op1 op2)); 10576 10577 format %{ "cmpl $op1, $op2" %} 10578 opcode(0x81, 0x07); /* Opcode 81 /7 */ 10579 ins_encode(OpcSErm(op1, op2), Con8or32(op2)); 10580 ins_pipe(ialu_cr_reg_imm); 10581%} 10582 10583instruct compI_rReg_mem(rFlagsReg cr, rRegI op1, memory op2) 10584%{ 10585 match(Set cr (CmpI op1 (LoadI op2))); 10586 10587 ins_cost(500); // XXX 10588 format %{ "cmpl $op1, $op2" %} 10589 opcode(0x3B); /* Opcode 3B /r */ 10590 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2)); 10591 ins_pipe(ialu_cr_reg_mem); 10592%} 10593 10594instruct testI_reg(rFlagsReg cr, rRegI src, immI0 zero) 10595%{ 10596 match(Set cr (CmpI src zero)); 10597 10598 format %{ "testl $src, $src" %} 10599 opcode(0x85); 10600 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src)); 10601 ins_pipe(ialu_cr_reg_imm); 10602%} 10603 10604instruct testI_reg_imm(rFlagsReg cr, rRegI src, immI con, immI0 zero) 10605%{ 10606 match(Set cr (CmpI (AndI src con) zero)); 10607 10608 format %{ "testl $src, $con" %} 10609 opcode(0xF7, 0x00); 10610 ins_encode(REX_reg(src), OpcP, reg_opc(src), Con32(con)); 10611 ins_pipe(ialu_cr_reg_imm); 10612%} 10613 10614instruct testI_reg_mem(rFlagsReg cr, rRegI src, memory mem, immI0 zero) 10615%{ 10616 match(Set cr (CmpI (AndI src (LoadI mem)) zero)); 10617 10618 format %{ "testl $src, $mem" %} 10619 opcode(0x85); 10620 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 10621 ins_pipe(ialu_cr_reg_mem); 10622%} 10623 10624// Unsigned compare Instructions; really, same as signed except they 10625// produce an rFlagsRegU instead of rFlagsReg. 10626instruct compU_rReg(rFlagsRegU cr, rRegI op1, rRegI op2) 10627%{ 10628 match(Set cr (CmpU op1 op2)); 10629 10630 format %{ "cmpl $op1, $op2\t# unsigned" %} 10631 opcode(0x3B); /* Opcode 3B /r */ 10632 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2)); 10633 ins_pipe(ialu_cr_reg_reg); 10634%} 10635 10636instruct compU_rReg_imm(rFlagsRegU cr, rRegI op1, immI op2) 10637%{ 10638 match(Set cr (CmpU op1 op2)); 10639 10640 format %{ "cmpl $op1, $op2\t# unsigned" %} 10641 opcode(0x81,0x07); /* Opcode 81 /7 */ 10642 ins_encode(OpcSErm(op1, op2), Con8or32(op2)); 10643 ins_pipe(ialu_cr_reg_imm); 10644%} 10645 10646instruct compU_rReg_mem(rFlagsRegU cr, rRegI op1, memory op2) 10647%{ 10648 match(Set cr (CmpU op1 (LoadI op2))); 10649 10650 ins_cost(500); // XXX 10651 format %{ "cmpl $op1, $op2\t# unsigned" %} 10652 opcode(0x3B); /* Opcode 3B /r */ 10653 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2)); 10654 ins_pipe(ialu_cr_reg_mem); 10655%} 10656 10657// // // Cisc-spilled version of cmpU_rReg 10658// //instruct compU_mem_rReg(rFlagsRegU cr, memory op1, rRegI op2) 10659// //%{ 10660// // match(Set cr (CmpU (LoadI op1) op2)); 10661// // 10662// // format %{ "CMPu $op1,$op2" %} 10663// // ins_cost(500); 10664// // opcode(0x39); /* Opcode 39 /r */ 10665// // ins_encode( OpcP, reg_mem( op1, op2) ); 10666// //%} 10667 10668instruct testU_reg(rFlagsRegU cr, rRegI src, immI0 zero) 10669%{ 10670 match(Set cr (CmpU src zero)); 10671 10672 format %{ "testl $src, $src\t# unsigned" %} 10673 opcode(0x85); 10674 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src)); 10675 ins_pipe(ialu_cr_reg_imm); 10676%} 10677 10678instruct compP_rReg(rFlagsRegU cr, rRegP op1, rRegP op2) 10679%{ 10680 match(Set cr (CmpP op1 op2)); 10681 10682 format %{ "cmpq $op1, $op2\t# ptr" %} 10683 opcode(0x3B); /* Opcode 3B /r */ 10684 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 10685 ins_pipe(ialu_cr_reg_reg); 10686%} 10687 10688instruct compP_rReg_mem(rFlagsRegU cr, rRegP op1, memory op2) 10689%{ 10690 match(Set cr (CmpP op1 (LoadP op2))); 10691 10692 ins_cost(500); // XXX 10693 format %{ "cmpq $op1, $op2\t# ptr" %} 10694 opcode(0x3B); /* Opcode 3B /r */ 10695 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 10696 ins_pipe(ialu_cr_reg_mem); 10697%} 10698 10699// // // Cisc-spilled version of cmpP_rReg 10700// //instruct compP_mem_rReg(rFlagsRegU cr, memory op1, rRegP op2) 10701// //%{ 10702// // match(Set cr (CmpP (LoadP op1) op2)); 10703// // 10704// // format %{ "CMPu $op1,$op2" %} 10705// // ins_cost(500); 10706// // opcode(0x39); /* Opcode 39 /r */ 10707// // ins_encode( OpcP, reg_mem( op1, op2) ); 10708// //%} 10709 10710// XXX this is generalized by compP_rReg_mem??? 10711// Compare raw pointer (used in out-of-heap check). 10712// Only works because non-oop pointers must be raw pointers 10713// and raw pointers have no anti-dependencies. 10714instruct compP_mem_rReg(rFlagsRegU cr, rRegP op1, memory op2) 10715%{ 10716 predicate(n->in(2)->in(2)->bottom_type()->reloc() == relocInfo::none); 10717 match(Set cr (CmpP op1 (LoadP op2))); 10718 10719 format %{ "cmpq $op1, $op2\t# raw ptr" %} 10720 opcode(0x3B); /* Opcode 3B /r */ 10721 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 10722 ins_pipe(ialu_cr_reg_mem); 10723%} 10724 10725// This will generate a signed flags result. This should be OK since 10726// any compare to a zero should be eq/neq. 10727instruct testP_reg(rFlagsReg cr, rRegP src, immP0 zero) 10728%{ 10729 match(Set cr (CmpP src zero)); 10730 10731 format %{ "testq $src, $src\t# ptr" %} 10732 opcode(0x85); 10733 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 10734 ins_pipe(ialu_cr_reg_imm); 10735%} 10736 10737// This will generate a signed flags result. This should be OK since 10738// any compare to a zero should be eq/neq. 10739instruct testP_mem(rFlagsReg cr, memory op, immP0 zero) 10740%{ 10741 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL)); 10742 match(Set cr (CmpP (LoadP op) zero)); 10743 10744 ins_cost(500); // XXX 10745 format %{ "testq $op, 0xffffffffffffffff\t# ptr" %} 10746 opcode(0xF7); /* Opcode F7 /0 */ 10747 ins_encode(REX_mem_wide(op), 10748 OpcP, RM_opc_mem(0x00, op), Con_d32(0xFFFFFFFF)); 10749 ins_pipe(ialu_cr_reg_imm); 10750%} 10751 10752instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero) 10753%{ 10754 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 10755 match(Set cr (CmpP (LoadP mem) zero)); 10756 10757 format %{ "cmpq R12, $mem\t# ptr (R12_heapbase==0)" %} 10758 ins_encode %{ 10759 __ cmpq(r12, $mem$$Address); 10760 %} 10761 ins_pipe(ialu_cr_reg_mem); 10762%} 10763 10764instruct compN_rReg(rFlagsRegU cr, rRegN op1, rRegN op2) 10765%{ 10766 match(Set cr (CmpN op1 op2)); 10767 10768 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 10769 ins_encode %{ __ cmpl($op1$$Register, $op2$$Register); %} 10770 ins_pipe(ialu_cr_reg_reg); 10771%} 10772 10773instruct compN_rReg_mem(rFlagsRegU cr, rRegN src, memory mem) 10774%{ 10775 match(Set cr (CmpN src (LoadN mem))); 10776 10777 format %{ "cmpl $src, $mem\t# compressed ptr" %} 10778 ins_encode %{ 10779 __ cmpl($src$$Register, $mem$$Address); 10780 %} 10781 ins_pipe(ialu_cr_reg_mem); 10782%} 10783 10784instruct compN_rReg_imm(rFlagsRegU cr, rRegN op1, immN op2) %{ 10785 match(Set cr (CmpN op1 op2)); 10786 10787 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 10788 ins_encode %{ 10789 __ cmp_narrow_oop($op1$$Register, (jobject)$op2$$constant); 10790 %} 10791 ins_pipe(ialu_cr_reg_imm); 10792%} 10793 10794instruct compN_mem_imm(rFlagsRegU cr, memory mem, immN src) 10795%{ 10796 match(Set cr (CmpN src (LoadN mem))); 10797 10798 format %{ "cmpl $mem, $src\t# compressed ptr" %} 10799 ins_encode %{ 10800 __ cmp_narrow_oop($mem$$Address, (jobject)$src$$constant); 10801 %} 10802 ins_pipe(ialu_cr_reg_mem); 10803%} 10804 10805instruct compN_rReg_imm_klass(rFlagsRegU cr, rRegN op1, immNKlass op2) %{ 10806 match(Set cr (CmpN op1 op2)); 10807 10808 format %{ "cmpl $op1, $op2\t# compressed klass ptr" %} 10809 ins_encode %{ 10810 __ cmp_narrow_klass($op1$$Register, (Klass*)$op2$$constant); 10811 %} 10812 ins_pipe(ialu_cr_reg_imm); 10813%} 10814 10815instruct compN_mem_imm_klass(rFlagsRegU cr, memory mem, immNKlass src) 10816%{ 10817 match(Set cr (CmpN src (LoadNKlass mem))); 10818 10819 format %{ "cmpl $mem, $src\t# compressed klass ptr" %} 10820 ins_encode %{ 10821 __ cmp_narrow_klass($mem$$Address, (Klass*)$src$$constant); 10822 %} 10823 ins_pipe(ialu_cr_reg_mem); 10824%} 10825 10826instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{ 10827 match(Set cr (CmpN src zero)); 10828 10829 format %{ "testl $src, $src\t# compressed ptr" %} 10830 ins_encode %{ __ testl($src$$Register, $src$$Register); %} 10831 ins_pipe(ialu_cr_reg_imm); 10832%} 10833 10834instruct testN_mem(rFlagsReg cr, memory mem, immN0 zero) 10835%{ 10836 predicate(Universe::narrow_oop_base() != NULL); 10837 match(Set cr (CmpN (LoadN mem) zero)); 10838 10839 ins_cost(500); // XXX 10840 format %{ "testl $mem, 0xffffffff\t# compressed ptr" %} 10841 ins_encode %{ 10842 __ cmpl($mem$$Address, (int)0xFFFFFFFF); 10843 %} 10844 ins_pipe(ialu_cr_reg_mem); 10845%} 10846 10847instruct testN_mem_reg0(rFlagsReg cr, memory mem, immN0 zero) 10848%{ 10849 predicate(Universe::narrow_oop_base() == NULL && (Universe::narrow_klass_base() == NULL)); 10850 match(Set cr (CmpN (LoadN mem) zero)); 10851 10852 format %{ "cmpl R12, $mem\t# compressed ptr (R12_heapbase==0)" %} 10853 ins_encode %{ 10854 __ cmpl(r12, $mem$$Address); 10855 %} 10856 ins_pipe(ialu_cr_reg_mem); 10857%} 10858 10859// Yanked all unsigned pointer compare operations. 10860// Pointer compares are done with CmpP which is already unsigned. 10861 10862instruct compL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 10863%{ 10864 match(Set cr (CmpL op1 op2)); 10865 10866 format %{ "cmpq $op1, $op2" %} 10867 opcode(0x3B); /* Opcode 3B /r */ 10868 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 10869 ins_pipe(ialu_cr_reg_reg); 10870%} 10871 10872instruct compL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 10873%{ 10874 match(Set cr (CmpL op1 op2)); 10875 10876 format %{ "cmpq $op1, $op2" %} 10877 opcode(0x81, 0x07); /* Opcode 81 /7 */ 10878 ins_encode(OpcSErm_wide(op1, op2), Con8or32(op2)); 10879 ins_pipe(ialu_cr_reg_imm); 10880%} 10881 10882instruct compL_rReg_mem(rFlagsReg cr, rRegL op1, memory op2) 10883%{ 10884 match(Set cr (CmpL op1 (LoadL op2))); 10885 10886 format %{ "cmpq $op1, $op2" %} 10887 opcode(0x3B); /* Opcode 3B /r */ 10888 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 10889 ins_pipe(ialu_cr_reg_mem); 10890%} 10891 10892instruct testL_reg(rFlagsReg cr, rRegL src, immL0 zero) 10893%{ 10894 match(Set cr (CmpL src zero)); 10895 10896 format %{ "testq $src, $src" %} 10897 opcode(0x85); 10898 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 10899 ins_pipe(ialu_cr_reg_imm); 10900%} 10901 10902instruct testL_reg_imm(rFlagsReg cr, rRegL src, immL32 con, immL0 zero) 10903%{ 10904 match(Set cr (CmpL (AndL src con) zero)); 10905 10906 format %{ "testq $src, $con\t# long" %} 10907 opcode(0xF7, 0x00); 10908 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src), Con32(con)); 10909 ins_pipe(ialu_cr_reg_imm); 10910%} 10911 10912instruct testL_reg_mem(rFlagsReg cr, rRegL src, memory mem, immL0 zero) 10913%{ 10914 match(Set cr (CmpL (AndL src (LoadL mem)) zero)); 10915 10916 format %{ "testq $src, $mem" %} 10917 opcode(0x85); 10918 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 10919 ins_pipe(ialu_cr_reg_mem); 10920%} 10921 10922// Manifest a CmpL result in an integer register. Very painful. 10923// This is the test to avoid. 10924instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 10925%{ 10926 match(Set dst (CmpL3 src1 src2)); 10927 effect(KILL flags); 10928 10929 ins_cost(275); // XXX 10930 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 10931 "movl $dst, -1\n\t" 10932 "jl,s done\n\t" 10933 "setne $dst\n\t" 10934 "movzbl $dst, $dst\n\t" 10935 "done:" %} 10936 ins_encode(cmpl3_flag(src1, src2, dst)); 10937 ins_pipe(pipe_slow); 10938%} 10939 10940//----------Max and Min-------------------------------------------------------- 10941// Min Instructions 10942 10943instruct cmovI_reg_g(rRegI dst, rRegI src, rFlagsReg cr) 10944%{ 10945 effect(USE_DEF dst, USE src, USE cr); 10946 10947 format %{ "cmovlgt $dst, $src\t# min" %} 10948 opcode(0x0F, 0x4F); 10949 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 10950 ins_pipe(pipe_cmov_reg); 10951%} 10952 10953 10954instruct minI_rReg(rRegI dst, rRegI src) 10955%{ 10956 match(Set dst (MinI dst src)); 10957 10958 ins_cost(200); 10959 expand %{ 10960 rFlagsReg cr; 10961 compI_rReg(cr, dst, src); 10962 cmovI_reg_g(dst, src, cr); 10963 %} 10964%} 10965 10966instruct cmovI_reg_l(rRegI dst, rRegI src, rFlagsReg cr) 10967%{ 10968 effect(USE_DEF dst, USE src, USE cr); 10969 10970 format %{ "cmovllt $dst, $src\t# max" %} 10971 opcode(0x0F, 0x4C); 10972 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 10973 ins_pipe(pipe_cmov_reg); 10974%} 10975 10976 10977instruct maxI_rReg(rRegI dst, rRegI src) 10978%{ 10979 match(Set dst (MaxI dst src)); 10980 10981 ins_cost(200); 10982 expand %{ 10983 rFlagsReg cr; 10984 compI_rReg(cr, dst, src); 10985 cmovI_reg_l(dst, src, cr); 10986 %} 10987%} 10988 10989// ============================================================================ 10990// Branch Instructions 10991 10992// Jump Direct - Label defines a relative address from JMP+1 10993instruct jmpDir(label labl) 10994%{ 10995 match(Goto); 10996 effect(USE labl); 10997 10998 ins_cost(300); 10999 format %{ "jmp $labl" %} 11000 size(5); 11001 ins_encode %{ 11002 Label* L = $labl$$label; 11003 __ jmp(*L, false); // Always long jump 11004 %} 11005 ins_pipe(pipe_jmp); 11006%} 11007 11008// Jump Direct Conditional - Label defines a relative address from Jcc+1 11009instruct jmpCon(cmpOp cop, rFlagsReg cr, label labl) 11010%{ 11011 match(If cop cr); 11012 effect(USE labl); 11013 11014 ins_cost(300); 11015 format %{ "j$cop $labl" %} 11016 size(6); 11017 ins_encode %{ 11018 Label* L = $labl$$label; 11019 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11020 %} 11021 ins_pipe(pipe_jcc); 11022%} 11023 11024// Jump Direct Conditional - Label defines a relative address from Jcc+1 11025instruct jmpLoopEnd(cmpOp cop, rFlagsReg cr, label labl) 11026%{ 11027 match(CountedLoopEnd cop cr); 11028 effect(USE labl); 11029 11030 ins_cost(300); 11031 format %{ "j$cop $labl\t# loop end" %} 11032 size(6); 11033 ins_encode %{ 11034 Label* L = $labl$$label; 11035 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11036 %} 11037 ins_pipe(pipe_jcc); 11038%} 11039 11040// Jump Direct Conditional - Label defines a relative address from Jcc+1 11041instruct jmpLoopEndU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 11042 match(CountedLoopEnd cop cmp); 11043 effect(USE labl); 11044 11045 ins_cost(300); 11046 format %{ "j$cop,u $labl\t# loop end" %} 11047 size(6); 11048 ins_encode %{ 11049 Label* L = $labl$$label; 11050 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11051 %} 11052 ins_pipe(pipe_jcc); 11053%} 11054 11055instruct jmpLoopEndUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 11056 match(CountedLoopEnd cop cmp); 11057 effect(USE labl); 11058 11059 ins_cost(200); 11060 format %{ "j$cop,u $labl\t# loop end" %} 11061 size(6); 11062 ins_encode %{ 11063 Label* L = $labl$$label; 11064 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11065 %} 11066 ins_pipe(pipe_jcc); 11067%} 11068 11069// Jump Direct Conditional - using unsigned comparison 11070instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 11071 match(If cop cmp); 11072 effect(USE labl); 11073 11074 ins_cost(300); 11075 format %{ "j$cop,u $labl" %} 11076 size(6); 11077 ins_encode %{ 11078 Label* L = $labl$$label; 11079 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11080 %} 11081 ins_pipe(pipe_jcc); 11082%} 11083 11084instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 11085 match(If cop cmp); 11086 effect(USE labl); 11087 11088 ins_cost(200); 11089 format %{ "j$cop,u $labl" %} 11090 size(6); 11091 ins_encode %{ 11092 Label* L = $labl$$label; 11093 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11094 %} 11095 ins_pipe(pipe_jcc); 11096%} 11097 11098instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 11099 match(If cop cmp); 11100 effect(USE labl); 11101 11102 ins_cost(200); 11103 format %{ $$template 11104 if ($cop$$cmpcode == Assembler::notEqual) { 11105 $$emit$$"jp,u $labl\n\t" 11106 $$emit$$"j$cop,u $labl" 11107 } else { 11108 $$emit$$"jp,u done\n\t" 11109 $$emit$$"j$cop,u $labl\n\t" 11110 $$emit$$"done:" 11111 } 11112 %} 11113 ins_encode %{ 11114 Label* l = $labl$$label; 11115 if ($cop$$cmpcode == Assembler::notEqual) { 11116 __ jcc(Assembler::parity, *l, false); 11117 __ jcc(Assembler::notEqual, *l, false); 11118 } else if ($cop$$cmpcode == Assembler::equal) { 11119 Label done; 11120 __ jccb(Assembler::parity, done); 11121 __ jcc(Assembler::equal, *l, false); 11122 __ bind(done); 11123 } else { 11124 ShouldNotReachHere(); 11125 } 11126 %} 11127 ins_pipe(pipe_jcc); 11128%} 11129 11130// ============================================================================ 11131// The 2nd slow-half of a subtype check. Scan the subklass's 2ndary 11132// superklass array for an instance of the superklass. Set a hidden 11133// internal cache on a hit (cache is checked with exposed code in 11134// gen_subtype_check()). Return NZ for a miss or zero for a hit. The 11135// encoding ALSO sets flags. 11136 11137instruct partialSubtypeCheck(rdi_RegP result, 11138 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 11139 rFlagsReg cr) 11140%{ 11141 match(Set result (PartialSubtypeCheck sub super)); 11142 effect(KILL rcx, KILL cr); 11143 11144 ins_cost(1100); // slightly larger than the next version 11145 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 11146 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 11147 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 11148 "repne scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t" 11149 "jne,s miss\t\t# Missed: rdi not-zero\n\t" 11150 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 11151 "xorq $result, $result\t\t Hit: rdi zero\n\t" 11152 "miss:\t" %} 11153 11154 opcode(0x1); // Force a XOR of RDI 11155 ins_encode(enc_PartialSubtypeCheck()); 11156 ins_pipe(pipe_slow); 11157%} 11158 11159instruct partialSubtypeCheck_vs_Zero(rFlagsReg cr, 11160 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 11161 immP0 zero, 11162 rdi_RegP result) 11163%{ 11164 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 11165 effect(KILL rcx, KILL result); 11166 11167 ins_cost(1000); 11168 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 11169 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 11170 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 11171 "repne scasq\t# Scan *rdi++ for a match with rax while cx-- != 0\n\t" 11172 "jne,s miss\t\t# Missed: flags nz\n\t" 11173 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 11174 "miss:\t" %} 11175 11176 opcode(0x0); // No need to XOR RDI 11177 ins_encode(enc_PartialSubtypeCheck()); 11178 ins_pipe(pipe_slow); 11179%} 11180 11181// ============================================================================ 11182// Branch Instructions -- short offset versions 11183// 11184// These instructions are used to replace jumps of a long offset (the default 11185// match) with jumps of a shorter offset. These instructions are all tagged 11186// with the ins_short_branch attribute, which causes the ADLC to suppress the 11187// match rules in general matching. Instead, the ADLC generates a conversion 11188// method in the MachNode which can be used to do in-place replacement of the 11189// long variant with the shorter variant. The compiler will determine if a 11190// branch can be taken by the is_short_branch_offset() predicate in the machine 11191// specific code section of the file. 11192 11193// Jump Direct - Label defines a relative address from JMP+1 11194instruct jmpDir_short(label labl) %{ 11195 match(Goto); 11196 effect(USE labl); 11197 11198 ins_cost(300); 11199 format %{ "jmp,s $labl" %} 11200 size(2); 11201 ins_encode %{ 11202 Label* L = $labl$$label; 11203 __ jmpb(*L); 11204 %} 11205 ins_pipe(pipe_jmp); 11206 ins_short_branch(1); 11207%} 11208 11209// Jump Direct Conditional - Label defines a relative address from Jcc+1 11210instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{ 11211 match(If cop cr); 11212 effect(USE labl); 11213 11214 ins_cost(300); 11215 format %{ "j$cop,s $labl" %} 11216 size(2); 11217 ins_encode %{ 11218 Label* L = $labl$$label; 11219 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 11220 %} 11221 ins_pipe(pipe_jcc); 11222 ins_short_branch(1); 11223%} 11224 11225// Jump Direct Conditional - Label defines a relative address from Jcc+1 11226instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{ 11227 match(CountedLoopEnd cop cr); 11228 effect(USE labl); 11229 11230 ins_cost(300); 11231 format %{ "j$cop,s $labl\t# loop end" %} 11232 size(2); 11233 ins_encode %{ 11234 Label* L = $labl$$label; 11235 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 11236 %} 11237 ins_pipe(pipe_jcc); 11238 ins_short_branch(1); 11239%} 11240 11241// Jump Direct Conditional - Label defines a relative address from Jcc+1 11242instruct jmpLoopEndU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 11243 match(CountedLoopEnd cop cmp); 11244 effect(USE labl); 11245 11246 ins_cost(300); 11247 format %{ "j$cop,us $labl\t# loop end" %} 11248 size(2); 11249 ins_encode %{ 11250 Label* L = $labl$$label; 11251 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 11252 %} 11253 ins_pipe(pipe_jcc); 11254 ins_short_branch(1); 11255%} 11256 11257instruct jmpLoopEndUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 11258 match(CountedLoopEnd cop cmp); 11259 effect(USE labl); 11260 11261 ins_cost(300); 11262 format %{ "j$cop,us $labl\t# loop end" %} 11263 size(2); 11264 ins_encode %{ 11265 Label* L = $labl$$label; 11266 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 11267 %} 11268 ins_pipe(pipe_jcc); 11269 ins_short_branch(1); 11270%} 11271 11272// Jump Direct Conditional - using unsigned comparison 11273instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 11274 match(If cop cmp); 11275 effect(USE labl); 11276 11277 ins_cost(300); 11278 format %{ "j$cop,us $labl" %} 11279 size(2); 11280 ins_encode %{ 11281 Label* L = $labl$$label; 11282 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 11283 %} 11284 ins_pipe(pipe_jcc); 11285 ins_short_branch(1); 11286%} 11287 11288instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 11289 match(If cop cmp); 11290 effect(USE labl); 11291 11292 ins_cost(300); 11293 format %{ "j$cop,us $labl" %} 11294 size(2); 11295 ins_encode %{ 11296 Label* L = $labl$$label; 11297 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 11298 %} 11299 ins_pipe(pipe_jcc); 11300 ins_short_branch(1); 11301%} 11302 11303instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 11304 match(If cop cmp); 11305 effect(USE labl); 11306 11307 ins_cost(300); 11308 format %{ $$template 11309 if ($cop$$cmpcode == Assembler::notEqual) { 11310 $$emit$$"jp,u,s $labl\n\t" 11311 $$emit$$"j$cop,u,s $labl" 11312 } else { 11313 $$emit$$"jp,u,s done\n\t" 11314 $$emit$$"j$cop,u,s $labl\n\t" 11315 $$emit$$"done:" 11316 } 11317 %} 11318 size(4); 11319 ins_encode %{ 11320 Label* l = $labl$$label; 11321 if ($cop$$cmpcode == Assembler::notEqual) { 11322 __ jccb(Assembler::parity, *l); 11323 __ jccb(Assembler::notEqual, *l); 11324 } else if ($cop$$cmpcode == Assembler::equal) { 11325 Label done; 11326 __ jccb(Assembler::parity, done); 11327 __ jccb(Assembler::equal, *l); 11328 __ bind(done); 11329 } else { 11330 ShouldNotReachHere(); 11331 } 11332 %} 11333 ins_pipe(pipe_jcc); 11334 ins_short_branch(1); 11335%} 11336 11337// ============================================================================ 11338// inlined locking and unlocking 11339 11340instruct cmpFastLock(rFlagsReg cr, 11341 rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr) 11342%{ 11343 match(Set cr (FastLock object box)); 11344 effect(TEMP tmp, TEMP scr, USE_KILL box); 11345 11346 ins_cost(300); 11347 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr" %} 11348 ins_encode(Fast_Lock(object, box, tmp, scr)); 11349 ins_pipe(pipe_slow); 11350%} 11351 11352instruct cmpFastUnlock(rFlagsReg cr, 11353 rRegP object, rax_RegP box, rRegP tmp) 11354%{ 11355 match(Set cr (FastUnlock object box)); 11356 effect(TEMP tmp, USE_KILL box); 11357 11358 ins_cost(300); 11359 format %{ "fastunlock $object,$box\t! kills $box,$tmp" %} 11360 ins_encode(Fast_Unlock(object, box, tmp)); 11361 ins_pipe(pipe_slow); 11362%} 11363 11364 11365// ============================================================================ 11366// Safepoint Instructions 11367instruct safePoint_poll(rFlagsReg cr) 11368%{ 11369 predicate(!Assembler::is_polling_page_far()); 11370 match(SafePoint); 11371 effect(KILL cr); 11372 11373 format %{ "testl rax, [rip + #offset_to_poll_page]\t" 11374 "# Safepoint: poll for GC" %} 11375 ins_cost(125); 11376 ins_encode %{ 11377 AddressLiteral addr(os::get_polling_page(), relocInfo::poll_type); 11378 __ testl(rax, addr); 11379 %} 11380 ins_pipe(ialu_reg_mem); 11381%} 11382 11383instruct safePoint_poll_far(rFlagsReg cr, rRegP poll) 11384%{ 11385 predicate(Assembler::is_polling_page_far()); 11386 match(SafePoint poll); 11387 effect(KILL cr, USE poll); 11388 11389 format %{ "testl rax, [$poll]\t" 11390 "# Safepoint: poll for GC" %} 11391 ins_cost(125); 11392 ins_encode %{ 11393 __ relocate(relocInfo::poll_type); 11394 __ testl(rax, Address($poll$$Register, 0)); 11395 %} 11396 ins_pipe(ialu_reg_mem); 11397%} 11398 11399// ============================================================================ 11400// Procedure Call/Return Instructions 11401// Call Java Static Instruction 11402// Note: If this code changes, the corresponding ret_addr_offset() and 11403// compute_padding() functions will have to be adjusted. 11404instruct CallStaticJavaDirect(method meth) %{ 11405 match(CallStaticJava); 11406 predicate(!((CallStaticJavaNode*) n)->is_method_handle_invoke()); 11407 effect(USE meth); 11408 11409 ins_cost(300); 11410 format %{ "call,static " %} 11411 opcode(0xE8); /* E8 cd */ 11412 ins_encode(clear_avx, Java_Static_Call(meth), call_epilog); 11413 ins_pipe(pipe_slow); 11414 ins_alignment(4); 11415%} 11416 11417// Call Java Static Instruction (method handle version) 11418// Note: If this code changes, the corresponding ret_addr_offset() and 11419// compute_padding() functions will have to be adjusted. 11420instruct CallStaticJavaHandle(method meth, rbp_RegP rbp_mh_SP_save) %{ 11421 match(CallStaticJava); 11422 predicate(((CallStaticJavaNode*) n)->is_method_handle_invoke()); 11423 effect(USE meth); 11424 // RBP is saved by all callees (for interpreter stack correction). 11425 // We use it here for a similar purpose, in {preserve,restore}_SP. 11426 11427 ins_cost(300); 11428 format %{ "call,static/MethodHandle " %} 11429 opcode(0xE8); /* E8 cd */ 11430 ins_encode(clear_avx, preserve_SP, 11431 Java_Static_Call(meth), 11432 restore_SP, 11433 call_epilog); 11434 ins_pipe(pipe_slow); 11435 ins_alignment(4); 11436%} 11437 11438// Call Java Dynamic Instruction 11439// Note: If this code changes, the corresponding ret_addr_offset() and 11440// compute_padding() functions will have to be adjusted. 11441instruct CallDynamicJavaDirect(method meth) 11442%{ 11443 match(CallDynamicJava); 11444 effect(USE meth); 11445 11446 ins_cost(300); 11447 format %{ "movq rax, #Universe::non_oop_word()\n\t" 11448 "call,dynamic " %} 11449 ins_encode(clear_avx, Java_Dynamic_Call(meth), call_epilog); 11450 ins_pipe(pipe_slow); 11451 ins_alignment(4); 11452%} 11453 11454// Call Runtime Instruction 11455instruct CallRuntimeDirect(method meth) 11456%{ 11457 match(CallRuntime); 11458 effect(USE meth); 11459 11460 ins_cost(300); 11461 format %{ "call,runtime " %} 11462 ins_encode(clear_avx, Java_To_Runtime(meth)); 11463 ins_pipe(pipe_slow); 11464%} 11465 11466// Call runtime without safepoint 11467instruct CallLeafDirect(method meth) 11468%{ 11469 match(CallLeaf); 11470 effect(USE meth); 11471 11472 ins_cost(300); 11473 format %{ "call_leaf,runtime " %} 11474 ins_encode(clear_avx, Java_To_Runtime(meth)); 11475 ins_pipe(pipe_slow); 11476%} 11477 11478// Call runtime without safepoint 11479instruct CallLeafNoFPDirect(method meth) 11480%{ 11481 match(CallLeafNoFP); 11482 effect(USE meth); 11483 11484 ins_cost(300); 11485 format %{ "call_leaf_nofp,runtime " %} 11486 ins_encode(Java_To_Runtime(meth)); 11487 ins_pipe(pipe_slow); 11488%} 11489 11490// Return Instruction 11491// Remove the return address & jump to it. 11492// Notice: We always emit a nop after a ret to make sure there is room 11493// for safepoint patching 11494instruct Ret() 11495%{ 11496 match(Return); 11497 11498 format %{ "ret" %} 11499 opcode(0xC3); 11500 ins_encode(OpcP); 11501 ins_pipe(pipe_jmp); 11502%} 11503 11504// Tail Call; Jump from runtime stub to Java code. 11505// Also known as an 'interprocedural jump'. 11506// Target of jump will eventually return to caller. 11507// TailJump below removes the return address. 11508instruct TailCalljmpInd(no_rbp_RegP jump_target, rbx_RegP method_oop) 11509%{ 11510 match(TailCall jump_target method_oop); 11511 11512 ins_cost(300); 11513 format %{ "jmp $jump_target\t# rbx holds method oop" %} 11514 opcode(0xFF, 0x4); /* Opcode FF /4 */ 11515 ins_encode(REX_reg(jump_target), OpcP, reg_opc(jump_target)); 11516 ins_pipe(pipe_jmp); 11517%} 11518 11519// Tail Jump; remove the return address; jump to target. 11520// TailCall above leaves the return address around. 11521instruct tailjmpInd(no_rbp_RegP jump_target, rax_RegP ex_oop) 11522%{ 11523 match(TailJump jump_target ex_oop); 11524 11525 ins_cost(300); 11526 format %{ "popq rdx\t# pop return address\n\t" 11527 "jmp $jump_target" %} 11528 opcode(0xFF, 0x4); /* Opcode FF /4 */ 11529 ins_encode(Opcode(0x5a), // popq rdx 11530 REX_reg(jump_target), OpcP, reg_opc(jump_target)); 11531 ins_pipe(pipe_jmp); 11532%} 11533 11534// Create exception oop: created by stack-crawling runtime code. 11535// Created exception is now available to this handler, and is setup 11536// just prior to jumping to this handler. No code emitted. 11537instruct CreateException(rax_RegP ex_oop) 11538%{ 11539 match(Set ex_oop (CreateEx)); 11540 11541 size(0); 11542 // use the following format syntax 11543 format %{ "# exception oop is in rax; no code emitted" %} 11544 ins_encode(); 11545 ins_pipe(empty); 11546%} 11547 11548// Rethrow exception: 11549// The exception oop will come in the first argument position. 11550// Then JUMP (not call) to the rethrow stub code. 11551instruct RethrowException() 11552%{ 11553 match(Rethrow); 11554 11555 // use the following format syntax 11556 format %{ "jmp rethrow_stub" %} 11557 ins_encode(enc_rethrow); 11558 ins_pipe(pipe_jmp); 11559%} 11560 11561 11562// ============================================================================ 11563// This name is KNOWN by the ADLC and cannot be changed. 11564// The ADLC forces a 'TypeRawPtr::BOTTOM' output type 11565// for this guy. 11566instruct tlsLoadP(r15_RegP dst) %{ 11567 match(Set dst (ThreadLocal)); 11568 effect(DEF dst); 11569 11570 size(0); 11571 format %{ "# TLS is in R15" %} 11572 ins_encode( /*empty encoding*/ ); 11573 ins_pipe(ialu_reg_reg); 11574%} 11575 11576 11577//----------PEEPHOLE RULES----------------------------------------------------- 11578// These must follow all instruction definitions as they use the names 11579// defined in the instructions definitions. 11580// 11581// peepmatch ( root_instr_name [preceding_instruction]* ); 11582// 11583// peepconstraint %{ 11584// (instruction_number.operand_name relational_op instruction_number.operand_name 11585// [, ...] ); 11586// // instruction numbers are zero-based using left to right order in peepmatch 11587// 11588// peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 11589// // provide an instruction_number.operand_name for each operand that appears 11590// // in the replacement instruction's match rule 11591// 11592// ---------VM FLAGS--------------------------------------------------------- 11593// 11594// All peephole optimizations can be turned off using -XX:-OptoPeephole 11595// 11596// Each peephole rule is given an identifying number starting with zero and 11597// increasing by one in the order seen by the parser. An individual peephole 11598// can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 11599// on the command-line. 11600// 11601// ---------CURRENT LIMITATIONS---------------------------------------------- 11602// 11603// Only match adjacent instructions in same basic block 11604// Only equality constraints 11605// Only constraints between operands, not (0.dest_reg == RAX_enc) 11606// Only one replacement instruction 11607// 11608// ---------EXAMPLE---------------------------------------------------------- 11609// 11610// // pertinent parts of existing instructions in architecture description 11611// instruct movI(rRegI dst, rRegI src) 11612// %{ 11613// match(Set dst (CopyI src)); 11614// %} 11615// 11616// instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr) 11617// %{ 11618// match(Set dst (AddI dst src)); 11619// effect(KILL cr); 11620// %} 11621// 11622// // Change (inc mov) to lea 11623// peephole %{ 11624// // increment preceeded by register-register move 11625// peepmatch ( incI_rReg movI ); 11626// // require that the destination register of the increment 11627// // match the destination register of the move 11628// peepconstraint ( 0.dst == 1.dst ); 11629// // construct a replacement instruction that sets 11630// // the destination to ( move's source register + one ) 11631// peepreplace ( leaI_rReg_immI( 0.dst 1.src 0.src ) ); 11632// %} 11633// 11634 11635// Implementation no longer uses movX instructions since 11636// machine-independent system no longer uses CopyX nodes. 11637// 11638// peephole 11639// %{ 11640// peepmatch (incI_rReg movI); 11641// peepconstraint (0.dst == 1.dst); 11642// peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 11643// %} 11644 11645// peephole 11646// %{ 11647// peepmatch (decI_rReg movI); 11648// peepconstraint (0.dst == 1.dst); 11649// peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 11650// %} 11651 11652// peephole 11653// %{ 11654// peepmatch (addI_rReg_imm movI); 11655// peepconstraint (0.dst == 1.dst); 11656// peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 11657// %} 11658 11659// peephole 11660// %{ 11661// peepmatch (incL_rReg movL); 11662// peepconstraint (0.dst == 1.dst); 11663// peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 11664// %} 11665 11666// peephole 11667// %{ 11668// peepmatch (decL_rReg movL); 11669// peepconstraint (0.dst == 1.dst); 11670// peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 11671// %} 11672 11673// peephole 11674// %{ 11675// peepmatch (addL_rReg_imm movL); 11676// peepconstraint (0.dst == 1.dst); 11677// peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 11678// %} 11679 11680// peephole 11681// %{ 11682// peepmatch (addP_rReg_imm movP); 11683// peepconstraint (0.dst == 1.dst); 11684// peepreplace (leaP_rReg_imm(0.dst 1.src 0.src)); 11685// %} 11686 11687// // Change load of spilled value to only a spill 11688// instruct storeI(memory mem, rRegI src) 11689// %{ 11690// match(Set mem (StoreI mem src)); 11691// %} 11692// 11693// instruct loadI(rRegI dst, memory mem) 11694// %{ 11695// match(Set dst (LoadI mem)); 11696// %} 11697// 11698 11699peephole 11700%{ 11701 peepmatch (loadI storeI); 11702 peepconstraint (1.src == 0.dst, 1.mem == 0.mem); 11703 peepreplace (storeI(1.mem 1.mem 1.src)); 11704%} 11705 11706peephole 11707%{ 11708 peepmatch (loadL storeL); 11709 peepconstraint (1.src == 0.dst, 1.mem == 0.mem); 11710 peepreplace (storeL(1.mem 1.mem 1.src)); 11711%} 11712 11713//----------SMARTSPILL RULES--------------------------------------------------- 11714// These must follow all instruction definitions as they use the names 11715// defined in the instructions definitions. 11716