comparison src/cpu/x86/vm/x86_64.ad @ 113:ba764ed4b6f2

6420645: Create a vm that uses compressed oops for up to 32gb heapsizes Summary: Compressed oops in instances, arrays, and headers. Code contributors are coleenp, phh, never, swamyv Reviewed-by: jmasa, kamg, acorn, tbell, kvn, rasbold
author coleenp
date Sun, 13 Apr 2008 17:43:42 -0400
parents 3d62cb85208d
children b130b98db9cf
comparison
equal deleted inserted replaced
110:a49a647afe9a 113:ba764ed4b6f2
310 RBX, RBX_H, 310 RBX, RBX_H,
311 R8, R8_H, 311 R8, R8_H,
312 R9, R9_H, 312 R9, R9_H,
313 R10, R10_H, 313 R10, R10_H,
314 R11, R11_H, 314 R11, R11_H,
315 R12, R12_H,
316 R13, R13_H, 315 R13, R13_H,
317 R14, R14_H); 316 R14, R14_H);
318 317
319 // Class for all pointer registers except RAX and RSP 318 // Class for all pointer registers except RAX and RSP
320 reg_class ptr_no_rax_reg(RDX, RDX_H, 319 reg_class ptr_no_rax_reg(RDX, RDX_H,
390 RBX, RBX_H, 389 RBX, RBX_H,
391 R8, R8_H, 390 R8, R8_H,
392 R9, R9_H, 391 R9, R9_H,
393 R10, R10_H, 392 R10, R10_H,
394 R11, R11_H, 393 R11, R11_H,
395 R12, R12_H,
396 R13, R13_H, 394 R13, R13_H,
397 R14, R14_H); 395 R14, R14_H);
398 396
399 // Class for all long registers except RAX, RDX (and RSP) 397 // Class for all long registers except RAX, RDX (and RSP)
400 reg_class long_no_rax_rdx_reg(RBP, RBP_H, 398 reg_class long_no_rax_rdx_reg(RBP, RBP_H,
404 RBX, RBX_H, 402 RBX, RBX_H,
405 R8, R8_H, 403 R8, R8_H,
406 R9, R9_H, 404 R9, R9_H,
407 R10, R10_H, 405 R10, R10_H,
408 R11, R11_H, 406 R11, R11_H,
409 R12, R12_H,
410 R13, R13_H, 407 R13, R13_H,
411 R14, R14_H); 408 R14, R14_H);
412 409
413 // Class for all long registers except RCX (and RSP) 410 // Class for all long registers except RCX (and RSP)
414 reg_class long_no_rcx_reg(RBP, RBP_H, 411 reg_class long_no_rcx_reg(RBP, RBP_H,
419 RBX, RBX_H, 416 RBX, RBX_H,
420 R8, R8_H, 417 R8, R8_H,
421 R9, R9_H, 418 R9, R9_H,
422 R10, R10_H, 419 R10, R10_H,
423 R11, R11_H, 420 R11, R11_H,
424 R12, R12_H,
425 R13, R13_H, 421 R13, R13_H,
426 R14, R14_H); 422 R14, R14_H);
427 423
428 // Class for all long registers except RAX (and RSP) 424 // Class for all long registers except RAX (and RSP)
429 reg_class long_no_rax_reg(RBP, RBP_H, 425 reg_class long_no_rax_reg(RBP, RBP_H,
434 RBX, RBX_H, 430 RBX, RBX_H,
435 R8, R8_H, 431 R8, R8_H,
436 R9, R9_H, 432 R9, R9_H,
437 R10, R10_H, 433 R10, R10_H,
438 R11, R11_H, 434 R11, R11_H,
439 R12, R12_H,
440 R13, R13_H, 435 R13, R13_H,
441 R14, R14_H); 436 R14, R14_H);
442 437
443 // Singleton class for RAX long register 438 // Singleton class for RAX long register
444 reg_class long_rax_reg(RAX, RAX_H); 439 reg_class long_rax_reg(RAX, RAX_H);
446 // Singleton class for RCX long register 441 // Singleton class for RCX long register
447 reg_class long_rcx_reg(RCX, RCX_H); 442 reg_class long_rcx_reg(RCX, RCX_H);
448 443
449 // Singleton class for RDX long register 444 // Singleton class for RDX long register
450 reg_class long_rdx_reg(RDX, RDX_H); 445 reg_class long_rdx_reg(RDX, RDX_H);
446
447 // Singleton class for R12 long register
448 reg_class long_r12_reg(R12, R12_H);
451 449
452 // Class for all int registers (except RSP) 450 // Class for all int registers (except RSP)
453 reg_class int_reg(RAX, 451 reg_class int_reg(RAX,
454 RDX, 452 RDX,
455 RBP, 453 RBP,
459 RBX, 457 RBX,
460 R8, 458 R8,
461 R9, 459 R9,
462 R10, 460 R10,
463 R11, 461 R11,
464 R12,
465 R13, 462 R13,
466 R14); 463 R14);
467 464
468 // Class for all int registers except RCX (and RSP) 465 // Class for all int registers except RCX (and RSP)
469 reg_class int_no_rcx_reg(RAX, 466 reg_class int_no_rcx_reg(RAX,
474 RBX, 471 RBX,
475 R8, 472 R8,
476 R9, 473 R9,
477 R10, 474 R10,
478 R11, 475 R11,
479 R12,
480 R13, 476 R13,
481 R14); 477 R14);
482 478
483 // Class for all int registers except RAX, RDX (and RSP) 479 // Class for all int registers except RAX, RDX (and RSP)
484 reg_class int_no_rax_rdx_reg(RBP, 480 reg_class int_no_rax_rdx_reg(RBP,
488 RBX, 484 RBX,
489 R8, 485 R8,
490 R9, 486 R9,
491 R10, 487 R10,
492 R11, 488 R11,
493 R12,
494 R13, 489 R13,
495 R14); 490 R14);
496 491
497 // Singleton class for RAX int register 492 // Singleton class for RAX int register
498 reg_class int_rax_reg(RAX); 493 reg_class int_rax_reg(RAX);
1842 1837
1843 //============================================================================= 1838 //=============================================================================
1844 #ifndef PRODUCT 1839 #ifndef PRODUCT
1845 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1840 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const
1846 { 1841 {
1847 st->print_cr("cmpq rax, [j_rarg0 + oopDesc::klass_offset_in_bytes() #%d]\t" 1842 if (UseCompressedOops) {
1848 "# Inline cache check", oopDesc::klass_offset_in_bytes()); 1843 st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes() #%d]\t", oopDesc::klass_offset_in_bytes());
1844 st->print_cr("leaq rscratch1, [r12_heapbase, r, Address::times_8, 0]");
1845 st->print_cr("cmpq rax, rscratch1\t # Inline cache check");
1846 } else {
1847 st->print_cr("cmpq rax, [j_rarg0 + oopDesc::klass_offset_in_bytes() #%d]\t"
1848 "# Inline cache check", oopDesc::klass_offset_in_bytes());
1849 }
1849 st->print_cr("\tjne SharedRuntime::_ic_miss_stub"); 1850 st->print_cr("\tjne SharedRuntime::_ic_miss_stub");
1850 st->print_cr("\tnop"); 1851 st->print_cr("\tnop");
1851 if (!OptoBreakpoint) { 1852 if (!OptoBreakpoint) {
1852 st->print_cr("\tnop"); 1853 st->print_cr("\tnop");
1853 } 1854 }
1858 { 1859 {
1859 MacroAssembler masm(&cbuf); 1860 MacroAssembler masm(&cbuf);
1860 #ifdef ASSERT 1861 #ifdef ASSERT
1861 uint code_size = cbuf.code_size(); 1862 uint code_size = cbuf.code_size();
1862 #endif 1863 #endif
1863 masm.cmpq(rax, Address(j_rarg0, oopDesc::klass_offset_in_bytes())); 1864 if (UseCompressedOops) {
1865 masm.load_klass(rscratch1, j_rarg0);
1866 masm.cmpq(rax, rscratch1);
1867 } else {
1868 masm.cmpq(rax, Address(j_rarg0, oopDesc::klass_offset_in_bytes()));
1869 }
1864 1870
1865 masm.jump_cc(Assembler::notEqual, RuntimeAddress(SharedRuntime::get_ic_miss_stub())); 1871 masm.jump_cc(Assembler::notEqual, RuntimeAddress(SharedRuntime::get_ic_miss_stub()));
1866 1872
1867 /* WARNING these NOPs are critical so that verified entry point is properly 1873 /* WARNING these NOPs are critical so that verified entry point is properly
1868 aligned for patching by NativeJump::patch_verified_entry() */ 1874 aligned for patching by NativeJump::patch_verified_entry() */
1869 int nops_cnt = 1; 1875 int nops_cnt = 1;
1870 if (!OptoBreakpoint) { 1876 if (!OptoBreakpoint) {
1871 // Leave space for int3 1877 // Leave space for int3
1872 nops_cnt += 1; 1878 nops_cnt += 1;
1873 } 1879 }
1880 if (UseCompressedOops) {
1881 // ??? divisible by 4 is aligned?
1882 nops_cnt += 1;
1883 }
1874 masm.nop(nops_cnt); 1884 masm.nop(nops_cnt);
1875 1885
1876 assert(cbuf.code_size() - code_size == size(ra_), 1886 assert(cbuf.code_size() - code_size == size(ra_),
1877 "checking code size of inline cache node"); 1887 "checking code size of inline cache node");
1878 } 1888 }
1879 1889
1880 uint MachUEPNode::size(PhaseRegAlloc* ra_) const 1890 uint MachUEPNode::size(PhaseRegAlloc* ra_) const
1881 { 1891 {
1882 return OptoBreakpoint ? 11 : 12; 1892 if (UseCompressedOops) {
1893 return OptoBreakpoint ? 19 : 20;
1894 } else {
1895 return OptoBreakpoint ? 11 : 12;
1896 }
1883 } 1897 }
1884 1898
1885 1899
1886 //============================================================================= 1900 //=============================================================================
1887 uint size_exception_handler() 1901 uint size_exception_handler()
2050 reg == RSI_num || reg == RSI_H_num || 2064 reg == RSI_num || reg == RSI_H_num ||
2051 reg == RDX_num || reg == RDX_H_num || 2065 reg == RDX_num || reg == RDX_H_num ||
2052 reg == RCX_num || reg == RCX_H_num || 2066 reg == RCX_num || reg == RCX_H_num ||
2053 reg == R8_num || reg == R8_H_num || 2067 reg == R8_num || reg == R8_H_num ||
2054 reg == R9_num || reg == R9_H_num || 2068 reg == R9_num || reg == R9_H_num ||
2069 reg == R12_num || reg == R12_H_num ||
2055 reg == XMM0_num || reg == XMM0_H_num || 2070 reg == XMM0_num || reg == XMM0_H_num ||
2056 reg == XMM1_num || reg == XMM1_H_num || 2071 reg == XMM1_num || reg == XMM1_H_num ||
2057 reg == XMM2_num || reg == XMM2_H_num || 2072 reg == XMM2_num || reg == XMM2_H_num ||
2058 reg == XMM3_num || reg == XMM3_H_num || 2073 reg == XMM3_num || reg == XMM3_H_num ||
2059 reg == XMM4_num || reg == XMM4_H_num || 2074 reg == XMM4_num || reg == XMM4_H_num ||
2083 } 2098 }
2084 2099
2085 // Register for MODL projection of divmodL 2100 // Register for MODL projection of divmodL
2086 RegMask Matcher::modL_proj_mask() { 2101 RegMask Matcher::modL_proj_mask() {
2087 return LONG_RDX_REG_mask; 2102 return LONG_RDX_REG_mask;
2103 }
2104
2105 static Address build_address(int b, int i, int s, int d) {
2106 Register index = as_Register(i);
2107 Address::ScaleFactor scale = (Address::ScaleFactor)s;
2108 if (index == rsp) {
2109 index = noreg;
2110 scale = Address::no_scale;
2111 }
2112 Address addr(as_Register(b), index, scale, d);
2113 return addr;
2088 } 2114 }
2089 2115
2090 %} 2116 %}
2091 2117
2092 //----------ENCODING BLOCK----------------------------------------------------- 2118 //----------ENCODING BLOCK-----------------------------------------------------
2543 %{ 2569 %{
2544 Register Rrdi = as_Register(RDI_enc); // result register 2570 Register Rrdi = as_Register(RDI_enc); // result register
2545 Register Rrax = as_Register(RAX_enc); // super class 2571 Register Rrax = as_Register(RAX_enc); // super class
2546 Register Rrcx = as_Register(RCX_enc); // killed 2572 Register Rrcx = as_Register(RCX_enc); // killed
2547 Register Rrsi = as_Register(RSI_enc); // sub class 2573 Register Rrsi = as_Register(RSI_enc); // sub class
2548 Label hit, miss; 2574 Label hit, miss, cmiss;
2549 2575
2550 MacroAssembler _masm(&cbuf); 2576 MacroAssembler _masm(&cbuf);
2551 // Compare super with sub directly, since super is not in its own SSA. 2577 // Compare super with sub directly, since super is not in its own SSA.
2552 // The compiler used to emit this test, but we fold it in here, 2578 // The compiler used to emit this test, but we fold it in here,
2553 // to allow platform-specific tweaking on sparc. 2579 // to allow platform-specific tweaking on sparc.
2560 __ movq(Rrdi, Address(Rrsi, 2586 __ movq(Rrdi, Address(Rrsi,
2561 sizeof(oopDesc) + 2587 sizeof(oopDesc) +
2562 Klass::secondary_supers_offset_in_bytes())); 2588 Klass::secondary_supers_offset_in_bytes()));
2563 __ movl(Rrcx, Address(Rrdi, arrayOopDesc::length_offset_in_bytes())); 2589 __ movl(Rrcx, Address(Rrdi, arrayOopDesc::length_offset_in_bytes()));
2564 __ addq(Rrdi, arrayOopDesc::base_offset_in_bytes(T_OBJECT)); 2590 __ addq(Rrdi, arrayOopDesc::base_offset_in_bytes(T_OBJECT));
2565 __ repne_scan(); 2591 if (UseCompressedOops) {
2566 __ jcc(Assembler::notEqual, miss); 2592 __ encode_heap_oop(Rrax);
2567 __ movq(Address(Rrsi, 2593 __ repne_scanl();
2568 sizeof(oopDesc) + 2594 __ jcc(Assembler::notEqual, cmiss);
2569 Klass::secondary_super_cache_offset_in_bytes()), 2595 __ decode_heap_oop(Rrax);
2570 Rrax); 2596 __ movq(Address(Rrsi,
2597 sizeof(oopDesc) +
2598 Klass::secondary_super_cache_offset_in_bytes()),
2599 Rrax);
2600 __ jmp(hit);
2601 __ bind(cmiss);
2602 __ decode_heap_oop(Rrax);
2603 __ jmp(miss);
2604 } else {
2605 __ repne_scanq();
2606 __ jcc(Assembler::notEqual, miss);
2607 __ movq(Address(Rrsi,
2608 sizeof(oopDesc) +
2609 Klass::secondary_super_cache_offset_in_bytes()),
2610 Rrax);
2611 }
2571 __ bind(hit); 2612 __ bind(hit);
2572 if ($primary) { 2613 if ($primary) {
2573 __ xorq(Rrdi, Rrdi); 2614 __ xorq(Rrdi, Rrdi);
2574 } 2615 }
2575 __ bind(miss); 2616 __ bind(miss);
3691 int value_offset = java_lang_String::value_offset_in_bytes(); 3732 int value_offset = java_lang_String::value_offset_in_bytes();
3692 int offset_offset = java_lang_String::offset_offset_in_bytes(); 3733 int offset_offset = java_lang_String::offset_offset_in_bytes();
3693 int count_offset = java_lang_String::count_offset_in_bytes(); 3734 int count_offset = java_lang_String::count_offset_in_bytes();
3694 int base_offset = arrayOopDesc::base_offset_in_bytes(T_CHAR); 3735 int base_offset = arrayOopDesc::base_offset_in_bytes(T_CHAR);
3695 3736
3696 masm.movq(rax, Address(rsi, value_offset)); 3737 masm.load_heap_oop(rax, Address(rsi, value_offset));
3697 masm.movl(rcx, Address(rsi, offset_offset)); 3738 masm.movl(rcx, Address(rsi, offset_offset));
3698 masm.leaq(rax, Address(rax, rcx, Address::times_2, base_offset)); 3739 masm.leaq(rax, Address(rax, rcx, Address::times_2, base_offset));
3699 masm.movq(rbx, Address(rdi, value_offset)); 3740 masm.load_heap_oop(rbx, Address(rdi, value_offset));
3700 masm.movl(rcx, Address(rdi, offset_offset)); 3741 masm.movl(rcx, Address(rdi, offset_offset));
3701 masm.leaq(rbx, Address(rbx, rcx, Address::times_2, base_offset)); 3742 masm.leaq(rbx, Address(rbx, rcx, Address::times_2, base_offset));
3702 3743
3703 // Compute the minimum of the string lengths(rsi) and the 3744 // Compute the minimum of the string lengths(rsi) and the
3704 // difference of the string lengths (stack) 3745 // difference of the string lengths (stack)
4116 // cbuf.inst_mark() is beginning of instruction 4157 // cbuf.inst_mark() is beginning of instruction
4117 emit_d32_reloc(cbuf, os::get_polling_page()); 4158 emit_d32_reloc(cbuf, os::get_polling_page());
4118 // relocInfo::poll_type, 4159 // relocInfo::poll_type,
4119 %} 4160 %}
4120 %} 4161 %}
4162
4121 4163
4122 4164
4123 //----------FRAME-------------------------------------------------------------- 4165 //----------FRAME--------------------------------------------------------------
4124 // Definition of frame structure and management information. 4166 // Definition of frame structure and management information.
4125 // 4167 //
4253 "only return normal values"); 4295 "only return normal values");
4254 4296
4255 static const int lo[Op_RegL + 1] = { 4297 static const int lo[Op_RegL + 1] = {
4256 0, 4298 0,
4257 0, 4299 0,
4300 RAX_num, // Op_RegN
4258 RAX_num, // Op_RegI 4301 RAX_num, // Op_RegI
4259 RAX_num, // Op_RegP 4302 RAX_num, // Op_RegP
4260 XMM0_num, // Op_RegF 4303 XMM0_num, // Op_RegF
4261 XMM0_num, // Op_RegD 4304 XMM0_num, // Op_RegD
4262 RAX_num // Op_RegL 4305 RAX_num // Op_RegL
4263 }; 4306 };
4264 static const int hi[Op_RegL + 1] = { 4307 static const int hi[Op_RegL + 1] = {
4265 0, 4308 0,
4266 0, 4309 0,
4310 OptoReg::Bad, // Op_RegN
4267 OptoReg::Bad, // Op_RegI 4311 OptoReg::Bad, // Op_RegI
4268 RAX_H_num, // Op_RegP 4312 RAX_H_num, // Op_RegP
4269 OptoReg::Bad, // Op_RegF 4313 OptoReg::Bad, // Op_RegF
4270 XMM0_H_num, // Op_RegD 4314 XMM0_H_num, // Op_RegD
4271 RAX_H_num // Op_RegL 4315 RAX_H_num // Op_RegL
4272 }; 4316 };
4273 4317 assert(ARRAY_SIZE(hi) == _last_machine_leaf - 1, "missing type");
4274 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 4318 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]);
4275 %} 4319 %}
4276 %} 4320 %}
4277 4321
4278 //----------ATTRIBUTES--------------------------------------------------------- 4322 //----------ATTRIBUTES---------------------------------------------------------
4415 op_cost(5); 4459 op_cost(5);
4416 format %{ %} 4460 format %{ %}
4417 interface(CONST_INTER); 4461 interface(CONST_INTER);
4418 %} 4462 %}
4419 4463
4420 // Unsigned 31-bit Pointer Immediate 4464 // Pointer Immediate
4421 // Can be used in both 32-bit signed and 32-bit unsigned insns. 4465 operand immN() %{
4422 // Works for nulls and markOops; not for relocatable (oop) pointers. 4466 match(ConN);
4467
4468 op_cost(10);
4469 format %{ %}
4470 interface(CONST_INTER);
4471 %}
4472
4473 // NULL Pointer Immediate
4474 operand immN0() %{
4475 predicate(n->get_narrowcon() == 0);
4476 match(ConN);
4477
4478 op_cost(5);
4479 format %{ %}
4480 interface(CONST_INTER);
4481 %}
4482
4423 operand immP31() 4483 operand immP31()
4424 %{ 4484 %{
4425 predicate(!n->as_Type()->type()->isa_oopptr() 4485 predicate(!n->as_Type()->type()->isa_oopptr()
4426 && (n->get_ptr() >> 31) == 0); 4486 && (n->get_ptr() >> 31) == 0);
4427 match(ConP); 4487 match(ConP);
4428 4488
4429 op_cost(5); 4489 op_cost(5);
4430 format %{ %} 4490 format %{ %}
4431 interface(CONST_INTER); 4491 interface(CONST_INTER);
4432 %} 4492 %}
4493
4433 4494
4434 // Long Immediate 4495 // Long Immediate
4435 operand immL() 4496 operand immL()
4436 %{ 4497 %{
4437 match(ConL); 4498 match(ConL);
4765 4826
4766 format %{ %} 4827 format %{ %}
4767 interface(REG_INTER); 4828 interface(REG_INTER);
4768 %} 4829 %}
4769 4830
4831
4832 operand r12RegL() %{
4833 constraint(ALLOC_IN_RC(long_r12_reg));
4834 match(RegL);
4835
4836 format %{ %}
4837 interface(REG_INTER);
4838 %}
4839
4840 operand rRegN() %{
4841 constraint(ALLOC_IN_RC(int_reg));
4842 match(RegN);
4843
4844 format %{ %}
4845 interface(REG_INTER);
4846 %}
4847
4770 // Question: Why is r15_RegP (the read-only TLS register) a match for rRegP? 4848 // Question: Why is r15_RegP (the read-only TLS register) a match for rRegP?
4771 // Answer: Operand match rules govern the DFA as it processes instruction inputs. 4849 // Answer: Operand match rules govern the DFA as it processes instruction inputs.
4772 // It's fine for an instruction input which expects rRegP to match a r15_RegP. 4850 // It's fine for an instruction input which expects rRegP to match a r15_RegP.
4773 // The output of an instruction is controlled by the allocator, which respects 4851 // The output of an instruction is controlled by the allocator, which respects
4774 // register class masks, not match rules. Unless an instruction mentions 4852 // register class masks, not match rules. Unless an instruction mentions
4815 operand rax_RegP() 4893 operand rax_RegP()
4816 %{ 4894 %{
4817 constraint(ALLOC_IN_RC(ptr_rax_reg)); 4895 constraint(ALLOC_IN_RC(ptr_rax_reg));
4818 match(RegP); 4896 match(RegP);
4819 match(rRegP); 4897 match(rRegP);
4898
4899 format %{ %}
4900 interface(REG_INTER);
4901 %}
4902
4903 // Special Registers
4904 // Return a compressed pointer value
4905 operand rax_RegN()
4906 %{
4907 constraint(ALLOC_IN_RC(int_rax_reg));
4908 match(RegN);
4909 match(rRegN);
4820 4910
4821 format %{ %} 4911 format %{ %}
4822 interface(REG_INTER); 4912 interface(REG_INTER);
4823 %} 4913 %}
4824 4914
5106 format %{"[$reg + $off + $lreg << $scale]" %} 5196 format %{"[$reg + $off + $lreg << $scale]" %}
5107 interface(MEMORY_INTER) %{ 5197 interface(MEMORY_INTER) %{
5108 base($reg); 5198 base($reg);
5109 index($lreg); 5199 index($lreg);
5110 scale($scale); 5200 scale($scale);
5201 disp($off);
5202 %}
5203 %}
5204
5205 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand
5206 operand indIndexScaleOffsetComp(rRegN src, immL32 off, r12RegL base) %{
5207 constraint(ALLOC_IN_RC(ptr_reg));
5208 match(AddP (DecodeN src base) off);
5209
5210 op_cost(10);
5211 format %{"[$base + $src << 3 + $off] (compressed)" %}
5212 interface(MEMORY_INTER) %{
5213 base($base);
5214 index($src);
5215 scale(0x3);
5111 disp($off); 5216 disp($off);
5112 %} 5217 %}
5113 %} 5218 %}
5114 5219
5115 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 5220 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand
5257 // instructions for every form of operand when the instruction accepts 5362 // instructions for every form of operand when the instruction accepts
5258 // multiple operand types with the same basic encoding and format. The classic 5363 // multiple operand types with the same basic encoding and format. The classic
5259 // case of this is memory operands. 5364 // case of this is memory operands.
5260 5365
5261 opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex, 5366 opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex,
5262 indIndexScale, indIndexScaleOffset, indPosIndexScaleOffset); 5367 indIndexScale, indIndexScaleOffset, indPosIndexScaleOffset,
5368 indIndexScaleOffsetComp);
5263 5369
5264 //----------PIPELINE----------------------------------------------------------- 5370 //----------PIPELINE-----------------------------------------------------------
5265 // Rules which define the behavior of the target architectures pipeline. 5371 // Rules which define the behavior of the target architectures pipeline.
5266 pipeline %{ 5372 pipeline %{
5267 5373
5935 opcode(0x8B); 6041 opcode(0x8B);
5936 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 6042 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5937 ins_pipe(ialu_reg_mem); // XXX 6043 ins_pipe(ialu_reg_mem); // XXX
5938 %} 6044 %}
5939 6045
6046 // Load Compressed Pointer
6047 instruct loadN(rRegN dst, memory mem, rFlagsReg cr)
6048 %{
6049 match(Set dst (LoadN mem));
6050 effect(KILL cr);
6051
6052 ins_cost(125); // XXX
6053 format %{ "movl $dst, $mem\t# compressed ptr" %}
6054 ins_encode %{
6055 Address addr = build_address($mem$$base, $mem$$index, $mem$$scale, $mem$$disp);
6056 Register dst = as_Register($dst$$reg);
6057 __ movl(dst, addr);
6058 %}
6059 ins_pipe(ialu_reg_mem); // XXX
6060 %}
6061
6062
5940 // Load Klass Pointer 6063 // Load Klass Pointer
5941 instruct loadKlass(rRegP dst, memory mem) 6064 instruct loadKlass(rRegP dst, memory mem)
5942 %{ 6065 %{
5943 match(Set dst (LoadKlass mem)); 6066 match(Set dst (LoadKlass mem));
6067 predicate(!n->in(MemNode::Address)->bottom_type()->is_narrow());
5944 6068
5945 ins_cost(125); // XXX 6069 ins_cost(125); // XXX
5946 format %{ "movq $dst, $mem\t# class" %} 6070 format %{ "movq $dst, $mem\t# class" %}
5947 opcode(0x8B); 6071 opcode(0x8B);
5948 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 6072 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
6073 ins_pipe(ialu_reg_mem); // XXX
6074 %}
6075
6076 // Load Klass Pointer
6077 instruct loadKlassComp(rRegP dst, memory mem)
6078 %{
6079 match(Set dst (LoadKlass mem));
6080 predicate(n->in(MemNode::Address)->bottom_type()->is_narrow());
6081
6082 ins_cost(125); // XXX
6083 format %{ "movl $dst, $mem\t# compressed class" %}
6084 ins_encode %{
6085 Address addr = build_address($mem$$base, $mem$$index, $mem$$scale, $mem$$disp);
6086 Register dst = as_Register($dst$$reg);
6087 __ movl(dst, addr);
6088 // klass is never null in the header but this is generated for all
6089 // klass loads not just the _klass field in the header.
6090 __ decode_heap_oop(dst);
6091 %}
5949 ins_pipe(ialu_reg_mem); // XXX 6092 ins_pipe(ialu_reg_mem); // XXX
5950 %} 6093 %}
5951 6094
5952 // Load Float 6095 // Load Float
5953 instruct loadF(regF dst, memory mem) 6096 instruct loadF(regF dst, memory mem)
6201 format %{ "movss $dst, [$src]" %} 6344 format %{ "movss $dst, [$src]" %}
6202 ins_encode(load_conF(dst, src)); 6345 ins_encode(load_conF(dst, src));
6203 ins_pipe(pipe_slow); 6346 ins_pipe(pipe_slow);
6204 %} 6347 %}
6205 6348
6349 instruct loadConN0(rRegN dst, immN0 src, rFlagsReg cr) %{
6350 match(Set dst src);
6351 effect(KILL cr);
6352 format %{ "xorq $dst, $src\t# compressed ptr" %}
6353 ins_encode %{
6354 Register dst = $dst$$Register;
6355 __ xorq(dst, dst);
6356 %}
6357 ins_pipe(ialu_reg);
6358 %}
6359
6360 instruct loadConN(rRegN dst, immN src) %{
6361 match(Set dst src);
6362
6363 ins_cost(125);
6364 format %{ "movl $dst, $src\t# compressed ptr" %}
6365 ins_encode %{
6366 address con = (address)$src$$constant;
6367 Register dst = $dst$$Register;
6368 if (con == NULL) {
6369 ShouldNotReachHere();
6370 } else {
6371 __ movoop(dst, (jobject)$src$$constant);
6372 __ encode_heap_oop_not_null(dst);
6373 }
6374 %}
6375 ins_pipe(ialu_reg_fat); // XXX
6376 %}
6377
6206 instruct loadConF0(regF dst, immF0 src) 6378 instruct loadConF0(regF dst, immF0 src)
6207 %{ 6379 %{
6208 match(Set dst src); 6380 match(Set dst src);
6209 ins_cost(100); 6381 ins_cost(100);
6210 6382
6454 ins_cost(125); // XXX 6626 ins_cost(125); // XXX
6455 format %{ "movq $mem, $src\t# ptr" %} 6627 format %{ "movq $mem, $src\t# ptr" %}
6456 opcode(0xC7); /* C7 /0 */ 6628 opcode(0xC7); /* C7 /0 */
6457 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 6629 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src));
6458 ins_pipe(ialu_mem_imm); 6630 ins_pipe(ialu_mem_imm);
6631 %}
6632
6633 // Store Compressed Pointer
6634 instruct storeN(memory mem, rRegN src, rFlagsReg cr)
6635 %{
6636 match(Set mem (StoreN mem src));
6637 effect(KILL cr);
6638
6639 ins_cost(125); // XXX
6640 format %{ "movl $mem, $src\t# ptr" %}
6641 ins_encode %{
6642 Address addr = build_address($mem$$base, $mem$$index, $mem$$scale, $mem$$disp);
6643 Register src = as_Register($src$$reg);
6644 __ movl(addr, src);
6645 %}
6646 ins_pipe(ialu_mem_reg);
6459 %} 6647 %}
6460 6648
6461 // Store Integer Immediate 6649 // Store Integer Immediate
6462 instruct storeImmI(memory mem, immI src) 6650 instruct storeImmI(memory mem, immI src)
6463 %{ 6651 %{
6802 6990
6803 format %{ "movq $dst, $src\t# ptr -> long" %} 6991 format %{ "movq $dst, $src\t# ptr -> long" %}
6804 ins_encode(enc_copy_wide(dst, src)); 6992 ins_encode(enc_copy_wide(dst, src));
6805 ins_pipe(ialu_reg_reg); // XXX 6993 ins_pipe(ialu_reg_reg); // XXX
6806 %} 6994 %}
6995
6996
6997 // Convert oop pointer into compressed form
6998 instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{
6999 match(Set dst (EncodeP src));
7000 effect(KILL cr);
7001 format %{ "encode_heap_oop $dst,$src" %}
7002 ins_encode %{
7003 Register s = $src$$Register;
7004 Register d = $dst$$Register;
7005 if (s != d) {
7006 __ movq(d, s);
7007 }
7008 __ encode_heap_oop(d);
7009 %}
7010 ins_pipe(ialu_reg_long);
7011 %}
7012
7013 instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{
7014 match(Set dst (DecodeN src));
7015 effect(KILL cr);
7016 format %{ "decode_heap_oop $dst,$src" %}
7017 ins_encode %{
7018 Register s = $src$$Register;
7019 Register d = $dst$$Register;
7020 if (s != d) {
7021 __ movq(d, s);
7022 }
7023 __ decode_heap_oop(d);
7024 %}
7025 ins_pipe(ialu_reg_long);
7026 %}
7027
6807 7028
6808 //----------Conditional Move--------------------------------------------------- 7029 //----------Conditional Move---------------------------------------------------
6809 // Jump 7030 // Jump
6810 // dummy instruction for generating temp registers 7031 // dummy instruction for generating temp registers
6811 instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{ 7032 instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{
7519 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7740 Opcode(0xF), Opcode(0xB6), reg_reg(res, res));
7520 ins_pipe( pipe_cmpxchg ); 7741 ins_pipe( pipe_cmpxchg );
7521 %} 7742 %}
7522 7743
7523 7744
7745 instruct compareAndSwapN(rRegI res,
7746 memory mem_ptr,
7747 rax_RegN oldval, rRegN newval,
7748 rFlagsReg cr) %{
7749 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval)));
7750 effect(KILL cr, KILL oldval);
7751
7752 format %{ "cmpxchgl $mem_ptr,$newval\t# "
7753 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t"
7754 "sete $res\n\t"
7755 "movzbl $res, $res" %}
7756 opcode(0x0F, 0xB1);
7757 ins_encode(lock_prefix,
7758 REX_reg_mem(newval, mem_ptr),
7759 OpcP, OpcS,
7760 reg_mem(newval, mem_ptr),
7761 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete
7762 REX_reg_breg(res, res), // movzbl
7763 Opcode(0xF), Opcode(0xB6), reg_reg(res, res));
7764 ins_pipe( pipe_cmpxchg );
7765 %}
7766
7524 //----------Subtraction Instructions------------------------------------------- 7767 //----------Subtraction Instructions-------------------------------------------
7525 7768
7526 // Integer Subtraction Instructions 7769 // Integer Subtraction Instructions
7527 instruct subI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7770 instruct subI_rReg(rRegI dst, rRegI src, rFlagsReg cr)
7528 %{ 7771 %{
10769 ins_encode(REX_mem_wide(op), 11012 ins_encode(REX_mem_wide(op),
10770 OpcP, RM_opc_mem(0x00, op), Con_d32(0xFFFFFFFF)); 11013 OpcP, RM_opc_mem(0x00, op), Con_d32(0xFFFFFFFF));
10771 ins_pipe(ialu_cr_reg_imm); 11014 ins_pipe(ialu_cr_reg_imm);
10772 %} 11015 %}
10773 11016
11017 instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{
11018 match(Set cr (CmpN src zero));
11019
11020 format %{ "testl $src, $src" %}
11021 ins_encode %{ __ testl($src$$Register, $src$$Register); %}
11022 ins_pipe(ialu_cr_reg_imm);
11023 %}
11024
10774 // Yanked all unsigned pointer compare operations. 11025 // Yanked all unsigned pointer compare operations.
10775 // Pointer compares are done with CmpP which is already unsigned. 11026 // Pointer compares are done with CmpP which is already unsigned.
10776 11027
10777 instruct compL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 11028 instruct compL_rReg(rFlagsReg cr, rRegL op1, rRegL op2)
10778 %{ 11029 %{
11016 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 11267 rsi_RegP sub, rax_RegP super, rcx_RegI rcx,
11017 immP0 zero, 11268 immP0 zero,
11018 rdi_RegP result) 11269 rdi_RegP result)
11019 %{ 11270 %{
11020 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 11271 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero));
11272 predicate(!UseCompressedOops); // decoding oop kills condition codes
11021 effect(KILL rcx, KILL result); 11273 effect(KILL rcx, KILL result);
11022 11274
11023 ins_cost(1000); 11275 ins_cost(1000);
11024 format %{ "cmpq rax, rsi\n\t" 11276 format %{ "cmpq rax, rsi\n\t"
11025 "jeq,s miss\t# Actually a hit; we are done.\n\t" 11277 "jeq,s miss\t# Actually a hit; we are done.\n\t"