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, |
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 |
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" |