< prev index next >

src/hotspot/cpu/aarch64/aarch64.ad

Print this page




1736   if (C->need_stack_bang(framesize))
1737     st->print("# stack bang size=%d\n\t", framesize);
1738 
1739   if (framesize < ((1 << 9) + 2 * wordSize)) {
1740     st->print("sub  sp, sp, #%d\n\t", framesize);
1741     st->print("stp  rfp, lr, [sp, #%d]", framesize - 2 * wordSize);
1742     if (PreserveFramePointer) st->print("\n\tadd  rfp, sp, #%d", framesize - 2 * wordSize);
1743   } else {
1744     st->print("stp  lr, rfp, [sp, #%d]!\n\t", -(2 * wordSize));
1745     if (PreserveFramePointer) st->print("mov  rfp, sp\n\t");
1746     st->print("mov  rscratch1, #%d\n\t", framesize - 2 * wordSize);
1747     st->print("sub  sp, sp, rscratch1");
1748   }
1749 }
1750 #endif
1751 
1752 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1753   Compile* C = ra_->C;
1754   MacroAssembler _masm(&cbuf);
1755 
1756   // n.b. frame size includes space for return pc and rfp
1757   const long framesize = C->frame_size_in_bytes();
1758   assert(framesize%(2*wordSize) == 0, "must preserve 2*wordSize alignment");
1759 
1760   // insert a nop at the start of the prolog so we can patch in a
1761   // branch if we need to invalidate the method later
1762   __ nop();
1763 
1764   int bangsize = C->bang_size_in_bytes();
1765   if (C->need_stack_bang(bangsize) && UseStackBanging)
1766     __ generate_stack_overflow_check(bangsize);
1767 
1768   __ build_frame(framesize);
1769 
1770   if (NotifySimulator) {
1771     __ notify(Assembler::method_entry);
1772   }
1773 
1774   if (VerifyStackAtCalls) {
1775     Unimplemented();
1776   }
1777 
1778   C->set_frame_complete(cbuf.insts_size());
1779 
1780   if (C->has_mach_constant_base_node()) {
1781     // NOTE: We set the table base offset here because users might be
1782     // emitted before MachConstantBaseNode.
1783     Compile::ConstantTable& constant_table = C->constant_table();
1784     constant_table.set_table_base_offset(constant_table.calculate_table_base_offset());
1785   }
1786 }
1787 
1788 uint MachPrologNode::size(PhaseRegAlloc* ra_) const
1789 {
1790   return MachNode::size(ra_); // too many variables; just compute it
1791                               // the hard way
1792 }
1793 
1794 int MachPrologNode::reloc() const
1795 {
1796   return 0;


2077 #endif
2078 
2079 void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
2080   MacroAssembler _masm(&cbuf);
2081 
2082   int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
2083   int reg    = ra_->get_encode(this);
2084 
2085   if (Assembler::operand_valid_for_add_sub_immediate(offset)) {
2086     __ add(as_Register(reg), sp, offset);
2087   } else {
2088     ShouldNotReachHere();
2089   }
2090 }
2091 
2092 uint BoxLockNode::size(PhaseRegAlloc *ra_) const {
2093   // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_).
2094   return 4;
2095 }
2096 
2097 //=============================================================================











2098 



























2099 #ifndef PRODUCT
2100 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const
2101 {
2102   st->print_cr("# MachUEPNode");
2103   if (UseCompressedClassPointers) {
2104     st->print_cr("\tldrw rscratch1, j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass");
2105     if (CompressedKlassPointers::shift() != 0) {
2106       st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1");
2107     }
2108   } else {
2109    st->print_cr("\tldr rscratch1, j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass");
2110   }
2111   st->print_cr("\tcmp r0, rscratch1\t # Inline cache check");
2112   st->print_cr("\tbne, SharedRuntime::_ic_miss_stub");
2113 }
2114 #endif
2115 
2116 void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const
2117 {
2118   // This is the unverified entry point.
2119   MacroAssembler _masm(&cbuf);

2120 

2121   __ cmp_klass(j_rarg0, rscratch2, rscratch1);
2122   Label skip;
2123   // TODO
2124   // can we avoid this skip and still use a reloc?
2125   __ br(Assembler::EQ, skip);
2126   __ far_jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub()));
2127   __ bind(skip);
2128 }
2129 
2130 uint MachUEPNode::size(PhaseRegAlloc* ra_) const
2131 {
2132   return MachNode::size(ra_);
2133 }
2134 
2135 // REQUIRED EMIT CODE
2136 
2137 //=============================================================================
2138 
2139 // Emit exception handler code.
2140 int HandlerImpl::emit_exception_handler(CodeBuffer& cbuf)
2141 {
2142   // mov rscratch1 #exception_blob_entry_point


2490     mstack.push(m->in(AddPNode::Base), Pre_Visit);
2491     return true;
2492   }
2493   return false;
2494 }
2495 
2496 void Compile::reshape_address(AddPNode* addp) {
2497 }
2498 
2499 // helper for encoding java_to_runtime calls on sim
2500 //
2501 // this is needed to compute the extra arguments required when
2502 // planting a call to the simulator blrt instruction. the TypeFunc
2503 // can be queried to identify the counts for integral, and floating
2504 // arguments and the return type
2505 
2506 static void getCallInfo(const TypeFunc *tf, int &gpcnt, int &fpcnt, int &rtype)
2507 {
2508   int gps = 0;
2509   int fps = 0;
2510   const TypeTuple *domain = tf->domain();
2511   int max = domain->cnt();
2512   for (int i = TypeFunc::Parms; i < max; i++) {
2513     const Type *t = domain->field_at(i);
2514     switch(t->basic_type()) {
2515     case T_FLOAT:
2516     case T_DOUBLE:
2517       fps++;
2518     default:
2519       gps++;
2520     }
2521   }
2522   gpcnt = gps;
2523   fpcnt = fps;
2524   BasicType rt = tf->return_type();
2525   switch (rt) {
2526   case T_VOID:
2527     rtype = MacroAssembler::ret_type_void;
2528     break;
2529   default:
2530     rtype = MacroAssembler::ret_type_integral;


8165 %}
8166 
8167 // ============================================================================
8168 // Cast/Convert Instructions
8169 
8170 instruct castX2P(iRegPNoSp dst, iRegL src) %{
8171   match(Set dst (CastX2P src));
8172 
8173   ins_cost(INSN_COST);
8174   format %{ "mov $dst, $src\t# long -> ptr" %}
8175 
8176   ins_encode %{
8177     if ($dst$$reg != $src$$reg) {
8178       __ mov(as_Register($dst$$reg), as_Register($src$$reg));
8179     }
8180   %}
8181 
8182   ins_pipe(ialu_reg);
8183 %}
8184 















8185 instruct castP2X(iRegLNoSp dst, iRegP src) %{
8186   match(Set dst (CastP2X src));
8187 
8188   ins_cost(INSN_COST);
8189   format %{ "mov $dst, $src\t# ptr -> long" %}
8190 
8191   ins_encode %{
8192     if ($dst$$reg != $src$$reg) {
8193       __ mov(as_Register($dst$$reg), as_Register($src$$reg));
8194     }
8195   %}
8196 
8197   ins_pipe(ialu_reg);
8198 %}
8199 































8200 // Convert oop into int for vectors alignment masking
8201 instruct convP2I(iRegINoSp dst, iRegP src) %{
8202   match(Set dst (ConvL2I (CastP2X src)));
8203 
8204   ins_cost(INSN_COST);
8205   format %{ "movw $dst, $src\t# ptr -> int" %}
8206   ins_encode %{
8207     __ movw($dst$$Register, $src$$Register);
8208   %}
8209 
8210   ins_pipe(ialu_reg);
8211 %}
8212 
8213 // Convert compressed oop into int for vectors alignment masking
8214 // in case of 32bit oops (heap < 4Gb).
8215 instruct convN2I(iRegINoSp dst, iRegN src)
8216 %{
8217   predicate(CompressedOops::shift() == 0);
8218   match(Set dst (ConvL2I (CastP2X (DecodeN src))));
8219 


13669 
13670   match(Set dst (MoveL2D src));
13671 
13672   effect(DEF dst, USE src);
13673 
13674   ins_cost(INSN_COST);
13675 
13676   format %{ "fmovd $dst, $src\t# MoveL2D_reg_reg" %}
13677 
13678   ins_encode %{
13679     __ fmovd(as_FloatRegister($dst$$reg), $src$$Register);
13680   %}
13681 
13682   ins_pipe(fp_l2d);
13683 
13684 %}
13685 
13686 // ============================================================================
13687 // clearing of an array
13688 
13689 instruct clearArray_reg_reg(iRegL_R11 cnt, iRegP_R10 base, Universe dummy, rFlagsReg cr)
13690 %{
13691   match(Set dummy (ClearArray cnt base));
13692   effect(USE_KILL cnt, USE_KILL base);
13693 
13694   ins_cost(4 * INSN_COST);
13695   format %{ "ClearArray $cnt, $base" %}
13696 
13697   ins_encode %{
13698     __ zero_words($base$$Register, $cnt$$Register);
13699   %}
13700 
13701   ins_pipe(pipe_class_memory);
13702 %}
13703 
13704 instruct clearArray_imm_reg(immL cnt, iRegP_R10 base, Universe dummy, rFlagsReg cr)
13705 %{
13706   predicate((u_int64_t)n->in(2)->get_long()
13707             < (u_int64_t)(BlockZeroingLowLimit >> LogBytesPerWord));
13708   match(Set dummy (ClearArray cnt base));
13709   effect(USE_KILL base);
13710 
13711   ins_cost(4 * INSN_COST);
13712   format %{ "ClearArray $cnt, $base" %}
13713 
13714   ins_encode %{
13715     __ zero_words($base$$Register, (u_int64_t)$cnt$$constant);
13716   %}
13717 
13718   ins_pipe(pipe_class_memory);
13719 %}
13720 
13721 // ============================================================================
13722 // Overflow Math Instructions
13723 
13724 instruct overflowAddI_reg_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2)
13725 %{
13726   match(Set cr (OverflowAddI op1 op2));
13727 
13728   format %{ "cmnw  $op1, $op2\t# overflow check int" %}
13729   ins_cost(INSN_COST);
13730   ins_encode %{
13731     __ cmnw($op1$$Register, $op2$$Register);
13732   %}
13733 
13734   ins_pipe(icmp_reg_reg);
13735 %}




1736   if (C->need_stack_bang(framesize))
1737     st->print("# stack bang size=%d\n\t", framesize);
1738 
1739   if (framesize < ((1 << 9) + 2 * wordSize)) {
1740     st->print("sub  sp, sp, #%d\n\t", framesize);
1741     st->print("stp  rfp, lr, [sp, #%d]", framesize - 2 * wordSize);
1742     if (PreserveFramePointer) st->print("\n\tadd  rfp, sp, #%d", framesize - 2 * wordSize);
1743   } else {
1744     st->print("stp  lr, rfp, [sp, #%d]!\n\t", -(2 * wordSize));
1745     if (PreserveFramePointer) st->print("mov  rfp, sp\n\t");
1746     st->print("mov  rscratch1, #%d\n\t", framesize - 2 * wordSize);
1747     st->print("sub  sp, sp, rscratch1");
1748   }
1749 }
1750 #endif
1751 
1752 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1753   Compile* C = ra_->C;
1754   MacroAssembler _masm(&cbuf);
1755 
1756   __ verified_entry(C, 0);
1757   __ bind(*_verified_entry);



















1758 
1759   C->set_frame_complete(cbuf.insts_size());
1760 
1761   if (C->has_mach_constant_base_node()) {
1762     // NOTE: We set the table base offset here because users might be
1763     // emitted before MachConstantBaseNode.
1764     Compile::ConstantTable& constant_table = C->constant_table();
1765     constant_table.set_table_base_offset(constant_table.calculate_table_base_offset());
1766   }
1767 }
1768 
1769 uint MachPrologNode::size(PhaseRegAlloc* ra_) const
1770 {
1771   return MachNode::size(ra_); // too many variables; just compute it
1772                               // the hard way
1773 }
1774 
1775 int MachPrologNode::reloc() const
1776 {
1777   return 0;


2058 #endif
2059 
2060 void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
2061   MacroAssembler _masm(&cbuf);
2062 
2063   int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
2064   int reg    = ra_->get_encode(this);
2065 
2066   if (Assembler::operand_valid_for_add_sub_immediate(offset)) {
2067     __ add(as_Register(reg), sp, offset);
2068   } else {
2069     ShouldNotReachHere();
2070   }
2071 }
2072 
2073 uint BoxLockNode::size(PhaseRegAlloc *ra_) const {
2074   // BoxLockNode is not a MachNode, so we can't just call MachNode::size(ra_).
2075   return 4;
2076 }
2077 
2078 ///=============================================================================
2079 #ifndef PRODUCT
2080 void MachVEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const
2081 {
2082   st->print_cr("# MachVEPNode");
2083   if (!_verified) {
2084     st->print_cr("\t load_class");
2085   } else {
2086     st->print_cr("\t unpack_value_arg");
2087   }
2088 }
2089 #endif
2090 
2091 void MachVEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const
2092 {
2093   MacroAssembler _masm(&cbuf);
2094 
2095   if (!_verified) {
2096     Label skip;
2097     __ cmp_klass(j_rarg0, rscratch2, rscratch1);
2098     __ br(Assembler::EQ, skip);
2099       __ far_jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub()));
2100     __ bind(skip);
2101 
2102   } else {
2103     // Unpack value type args passed as oop and then jump to
2104     // the verified entry point (skipping the unverified entry).
2105     __ unpack_value_args(ra_->C, _receiver_only);
2106     __ b(*_verified_entry);
2107   }
2108 }
2109 
2110 
2111 uint MachVEPNode::size(PhaseRegAlloc* ra_) const
2112 {
2113   return MachNode::size(ra_); // too many variables; just compute it the hard way
2114 }
2115 
2116 
2117 //=============================================================================
2118 #ifndef PRODUCT
2119 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const
2120 {
2121   st->print_cr("# MachUEPNode");
2122   if (UseCompressedClassPointers) {
2123     st->print_cr("\tldrw rscratch1, j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass");
2124     if (CompressedKlassPointers::shift() != 0) {
2125       st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1");
2126     }
2127   } else {
2128    st->print_cr("\tldr rscratch1, j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass");
2129   }
2130   st->print_cr("\tcmp r0, rscratch1\t # Inline cache check");
2131   st->print_cr("\tbne, SharedRuntime::_ic_miss_stub");
2132 }
2133 #endif
2134 
2135 void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const
2136 {
2137   // This is the unverified entry point.
2138   MacroAssembler _masm(&cbuf);
2139   Label skip;
2140 
2141   // UseCompressedClassPointers logic are inside cmp_klass
2142   __ cmp_klass(j_rarg0, rscratch2, rscratch1);
2143 
2144   // TODO
2145   // can we avoid this skip and still use a reloc?
2146   __ br(Assembler::EQ, skip);
2147   __ far_jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub()));
2148   __ bind(skip);
2149 }
2150 
2151 uint MachUEPNode::size(PhaseRegAlloc* ra_) const
2152 {
2153   return MachNode::size(ra_);
2154 }
2155 
2156 // REQUIRED EMIT CODE
2157 
2158 //=============================================================================
2159 
2160 // Emit exception handler code.
2161 int HandlerImpl::emit_exception_handler(CodeBuffer& cbuf)
2162 {
2163   // mov rscratch1 #exception_blob_entry_point


2511     mstack.push(m->in(AddPNode::Base), Pre_Visit);
2512     return true;
2513   }
2514   return false;
2515 }
2516 
2517 void Compile::reshape_address(AddPNode* addp) {
2518 }
2519 
2520 // helper for encoding java_to_runtime calls on sim
2521 //
2522 // this is needed to compute the extra arguments required when
2523 // planting a call to the simulator blrt instruction. the TypeFunc
2524 // can be queried to identify the counts for integral, and floating
2525 // arguments and the return type
2526 
2527 static void getCallInfo(const TypeFunc *tf, int &gpcnt, int &fpcnt, int &rtype)
2528 {
2529   int gps = 0;
2530   int fps = 0;
2531   const TypeTuple *domain = tf->domain_cc();
2532   int max = domain->cnt();
2533   for (int i = TypeFunc::Parms; i < max; i++) {
2534     const Type *t = domain->field_at(i);
2535     switch(t->basic_type()) {
2536     case T_FLOAT:
2537     case T_DOUBLE:
2538       fps++;
2539     default:
2540       gps++;
2541     }
2542   }
2543   gpcnt = gps;
2544   fpcnt = fps;
2545   BasicType rt = tf->return_type();
2546   switch (rt) {
2547   case T_VOID:
2548     rtype = MacroAssembler::ret_type_void;
2549     break;
2550   default:
2551     rtype = MacroAssembler::ret_type_integral;


8186 %}
8187 
8188 // ============================================================================
8189 // Cast/Convert Instructions
8190 
8191 instruct castX2P(iRegPNoSp dst, iRegL src) %{
8192   match(Set dst (CastX2P src));
8193 
8194   ins_cost(INSN_COST);
8195   format %{ "mov $dst, $src\t# long -> ptr" %}
8196 
8197   ins_encode %{
8198     if ($dst$$reg != $src$$reg) {
8199       __ mov(as_Register($dst$$reg), as_Register($src$$reg));
8200     }
8201   %}
8202 
8203   ins_pipe(ialu_reg);
8204 %}
8205 
8206 instruct castN2X(iRegLNoSp dst, iRegN src) %{
8207   match(Set dst (CastP2X src));
8208 
8209   ins_cost(INSN_COST);
8210   format %{ "mov $dst, $src\t# ptr -> long" %}
8211 
8212   ins_encode %{
8213     if ($dst$$reg != $src$$reg) {
8214       __ mov(as_Register($dst$$reg), as_Register($src$$reg));
8215     }
8216   %}
8217 
8218   ins_pipe(ialu_reg);
8219 %}
8220 
8221 instruct castP2X(iRegLNoSp dst, iRegP src) %{
8222   match(Set dst (CastP2X src));
8223 
8224   ins_cost(INSN_COST);
8225   format %{ "mov $dst, $src\t# ptr -> long" %}
8226 
8227   ins_encode %{
8228     if ($dst$$reg != $src$$reg) {
8229       __ mov(as_Register($dst$$reg), as_Register($src$$reg));
8230     }
8231   %}
8232 
8233   ins_pipe(ialu_reg);
8234 %}
8235 
8236 instruct castN2I(iRegINoSp dst, iRegN src) %{
8237   match(Set dst (CastN2I src));
8238 
8239   ins_cost(INSN_COST);
8240   format %{ "movw $dst, $src\t# compressed ptr -> int" %}
8241 
8242   ins_encode %{
8243     if ($dst$$reg != $src$$reg) {
8244       __ movw(as_Register($dst$$reg), as_Register($src$$reg));
8245     }
8246   %}
8247 
8248   ins_pipe(ialu_reg);
8249 %}
8250 
8251 instruct castI2N(iRegNNoSp dst, iRegI src) %{
8252   match(Set dst (CastI2N src));
8253 
8254   ins_cost(INSN_COST);
8255   format %{ "movw $dst, $src\t# int -> compressed ptr" %}
8256 
8257   ins_encode %{
8258     if ($dst$$reg != $src$$reg) {
8259       __ movw(as_Register($dst$$reg), as_Register($src$$reg));
8260     }
8261   %}
8262 
8263   ins_pipe(ialu_reg);
8264 %}
8265 
8266 
8267 // Convert oop into int for vectors alignment masking
8268 instruct convP2I(iRegINoSp dst, iRegP src) %{
8269   match(Set dst (ConvL2I (CastP2X src)));
8270 
8271   ins_cost(INSN_COST);
8272   format %{ "movw $dst, $src\t# ptr -> int" %}
8273   ins_encode %{
8274     __ movw($dst$$Register, $src$$Register);
8275   %}
8276 
8277   ins_pipe(ialu_reg);
8278 %}
8279 
8280 // Convert compressed oop into int for vectors alignment masking
8281 // in case of 32bit oops (heap < 4Gb).
8282 instruct convN2I(iRegINoSp dst, iRegN src)
8283 %{
8284   predicate(CompressedOops::shift() == 0);
8285   match(Set dst (ConvL2I (CastP2X (DecodeN src))));
8286 


13736 
13737   match(Set dst (MoveL2D src));
13738 
13739   effect(DEF dst, USE src);
13740 
13741   ins_cost(INSN_COST);
13742 
13743   format %{ "fmovd $dst, $src\t# MoveL2D_reg_reg" %}
13744 
13745   ins_encode %{
13746     __ fmovd(as_FloatRegister($dst$$reg), $src$$Register);
13747   %}
13748 
13749   ins_pipe(fp_l2d);
13750 
13751 %}
13752 
13753 // ============================================================================
13754 // clearing of an array
13755 
13756 instruct clearArray_reg_reg(iRegL_R11 cnt, iRegP_R10 base, iRegL val, Universe dummy, rFlagsReg cr)
13757 %{
13758   match(Set dummy (ClearArray (Binary cnt base) val));
13759   effect(USE_KILL cnt, USE_KILL base);
13760 
13761   ins_cost(4 * INSN_COST);
13762   format %{ "ClearArray $cnt, $base, $val" %}

















13763 
13764   ins_encode %{
13765     __ fill_words($base$$Register, $cnt$$Register, $val$$Register);
13766   %}
13767 
13768   ins_pipe(pipe_class_memory);
13769 %}
13770 
13771 // ============================================================================
13772 // Overflow Math Instructions
13773 
13774 instruct overflowAddI_reg_reg(rFlagsReg cr, iRegIorL2I op1, iRegIorL2I op2)
13775 %{
13776   match(Set cr (OverflowAddI op1 op2));
13777 
13778   format %{ "cmnw  $op1, $op2\t# overflow check int" %}
13779   ins_cost(INSN_COST);
13780   ins_encode %{
13781     __ cmnw($op1$$Register, $op2$$Register);
13782   %}
13783 
13784   ins_pipe(icmp_reg_reg);
13785 %}


< prev index next >