< prev index next >

src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp

Print this page

   9  *
  10  * This code is distributed in the hope that it will be useful, but WITHOUT
  11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  13  * version 2 for more details (a copy is included in the LICENSE file that
  14  * accompanied this code).
  15  *
  16  * You should have received a copy of the GNU General Public License version
  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  *
  24  */
  25 
  26 #include "asm/assembler.hpp"
  27 #include "asm/assembler.inline.hpp"
  28 #include "ci/ciEnv.hpp"

  29 #include "code/compiledIC.hpp"
  30 #include "compiler/compileTask.hpp"
  31 #include "compiler/disassembler.hpp"
  32 #include "compiler/oopMap.hpp"
  33 #include "gc/shared/barrierSet.hpp"
  34 #include "gc/shared/barrierSetAssembler.hpp"
  35 #include "gc/shared/cardTableBarrierSet.hpp"
  36 #include "gc/shared/cardTable.hpp"
  37 #include "gc/shared/collectedHeap.hpp"
  38 #include "gc/shared/tlab_globals.hpp"
  39 #include "interpreter/bytecodeHistogram.hpp"
  40 #include "interpreter/interpreter.hpp"
  41 #include "interpreter/interpreterRuntime.hpp"
  42 #include "jvm.h"
  43 #include "memory/resourceArea.hpp"
  44 #include "memory/universe.hpp"
  45 #include "nativeInst_aarch64.hpp"
  46 #include "oops/accessDecorators.hpp"
  47 #include "oops/compressedKlass.inline.hpp"
  48 #include "oops/compressedOops.inline.hpp"

 331     uint32_t insn2 = insn_at(insn_addr, 1);
 332     uint32_t size = Instruction_aarch64::extract(insn2, 31, 30);
 333     Instruction_aarch64::patch(insn_addr + sizeof (uint32_t), 21, 10, offset_lo >> size);
 334     guarantee(((dest >> size) << size) == dest, "misaligned target");
 335     return 2;
 336   }
 337   static int adrpAdd_impl(address insn_addr, address &target) {
 338     uintptr_t dest = (uintptr_t)target;
 339     int offset_lo = dest & 0xfff;
 340     Instruction_aarch64::patch(insn_addr + sizeof (uint32_t), 21, 10, offset_lo);
 341     return 2;
 342   }
 343   static int adrpMovk_impl(address insn_addr, address &target) {
 344     uintptr_t dest = uintptr_t(target);
 345     Instruction_aarch64::patch(insn_addr + sizeof (uint32_t), 20, 5, (uintptr_t)target >> 32);
 346     dest = (dest & 0xffffffffULL) | (uintptr_t(insn_addr) & 0xffff00000000ULL);
 347     target = address(dest);
 348     return 2;
 349   }
 350   virtual int immediate(address insn_addr, address &target) {










 351     assert(Instruction_aarch64::extract(_insn, 31, 21) == 0b11010010100, "must be");
 352     uint64_t dest = (uint64_t)target;
 353     // Move wide constant
 354     assert(nativeInstruction_at(insn_addr+4)->is_movk(), "wrong insns in patch");
 355     assert(nativeInstruction_at(insn_addr+8)->is_movk(), "wrong insns in patch");
 356     Instruction_aarch64::patch(insn_addr, 20, 5, dest & 0xffff);
 357     Instruction_aarch64::patch(insn_addr+4, 20, 5, (dest >>= 16) & 0xffff);
 358     Instruction_aarch64::patch(insn_addr+8, 20, 5, (dest >>= 16) & 0xffff);
 359     return 3;
 360   }
 361   virtual void verify(address insn_addr, address &target) {
 362 #ifdef ASSERT
 363     address address_is = MacroAssembler::target_addr_for_insn(insn_addr);
 364     if (!(address_is == target)) {
 365       tty->print_cr("%p at %p should be %p", address_is, insn_addr, target);
 366       disnm((intptr_t)insn_addr);
 367       assert(address_is == target, "should be");
 368     }
 369 #endif
 370   }

 461     uint32_t insn2 = insn_at(insn_addr, 1);
 462     uint64_t dest = uint64_t(target);
 463     dest = (dest & 0xffff0000ffffffff) |
 464       ((uint64_t)Instruction_aarch64::extract(insn2, 20, 5) << 32);
 465     target = address(dest);
 466 
 467     // We know the destination 4k page. Maybe we have a third
 468     // instruction.
 469     uint32_t insn = insn_at(insn_addr, 0);
 470     uint32_t insn3 = insn_at(insn_addr, 2);
 471     ptrdiff_t byte_offset;
 472     if (offset_for(insn, insn3, byte_offset)) {
 473       target += byte_offset;
 474       return 3;
 475     } else {
 476       return 2;
 477     }
 478   }
 479   virtual int immediate(address insn_addr, address &target) {
 480     uint32_t *insns = (uint32_t *)insn_addr;










 481     assert(Instruction_aarch64::extract(_insn, 31, 21) == 0b11010010100, "must be");
 482     // Move wide constant: movz, movk, movk.  See movptr().
 483     assert(nativeInstruction_at(insns+1)->is_movk(), "wrong insns in patch");
 484     assert(nativeInstruction_at(insns+2)->is_movk(), "wrong insns in patch");
 485     target = address(uint64_t(Instruction_aarch64::extract(_insn, 20, 5))
 486                  + (uint64_t(Instruction_aarch64::extract(insns[1], 20, 5)) << 16)
 487                  + (uint64_t(Instruction_aarch64::extract(insns[2], 20, 5)) << 32));
 488     assert(nativeInstruction_at(insn_addr+4)->is_movk(), "wrong insns in patch");
 489     assert(nativeInstruction_at(insn_addr+8)->is_movk(), "wrong insns in patch");
 490     return 3;
 491   }
 492   virtual void verify(address insn_addr, address &target) {
 493   }
 494 };
 495 
 496 address MacroAssembler::target_addr_for_insn(address insn_addr, uint32_t insn) {
 497   AArch64Decoder decoder(insn_addr, insn);
 498   address target;
 499   decoder.run(insn_addr, target);
 500   return target;

 975   // Max stub size: alignment nop, TrampolineStub.
 976   return NativeInstruction::instruction_size + NativeCallTrampolineStub::instruction_size;
 977 }
 978 
 979 void MacroAssembler::emit_static_call_stub() {
 980   // CompiledDirectCall::set_to_interpreted knows the
 981   // exact layout of this stub.
 982 
 983   isb();
 984   mov_metadata(rmethod, nullptr);
 985 
 986   // Jump to the entry point of the c2i stub.
 987   if (codestub_branch_needs_far_jump()) {
 988     movptr(rscratch1, 0);
 989     br(rscratch1);
 990   } else {
 991     b(pc());
 992   }
 993 }
 994 
 995 int MacroAssembler::static_call_stub_size() {
 996   if (!codestub_branch_needs_far_jump()) {
 997     // isb; movk; movz; movz; b
 998     return 5 * NativeInstruction::instruction_size;
 999   }
1000   // isb; movk; movz; movz; movk; movz; movz; br
1001   return 8 * NativeInstruction::instruction_size;
1002 }
1003 
1004 void MacroAssembler::c2bool(Register x) {
1005   // implements x == 0 ? 0 : 1
1006   // note: must only look at least-significant byte of x
1007   //       since C-style booleans are stored in one byte
1008   //       only! (was bug)
1009   tst(x, 0xff);
1010   cset(x, Assembler::NE);
1011 }
1012 
1013 address MacroAssembler::ic_call(address entry, jint method_index) {
1014   RelocationHolder rh = virtual_call_Relocation::spec(pc(), method_index);
1015   movptr(rscratch2, (intptr_t)Universe::non_oop_word());
1016   return trampoline_call(Address(entry, rh));
1017 }
1018 
1019 int MacroAssembler::ic_check_size() {

3327 
3328 void MacroAssembler::sub(Register Rd, Register Rn, RegisterOrConstant decrement) {
3329   if (decrement.is_register()) {
3330     sub(Rd, Rn, decrement.as_register());
3331   } else {
3332     sub(Rd, Rn, decrement.as_constant());
3333   }
3334 }
3335 
3336 void MacroAssembler::subw(Register Rd, Register Rn, RegisterOrConstant decrement) {
3337   if (decrement.is_register()) {
3338     subw(Rd, Rn, decrement.as_register());
3339   } else {
3340     subw(Rd, Rn, decrement.as_constant());
3341   }
3342 }
3343 
3344 void MacroAssembler::reinit_heapbase()
3345 {
3346   if (UseCompressedOops) {
3347     if (Universe::is_fully_initialized()) {
3348       mov(rheapbase, CompressedOops::base());
3349     } else {
3350       lea(rheapbase, ExternalAddress(CompressedOops::base_addr()));
3351       ldr(rheapbase, Address(rheapbase));
3352     }
3353   }
3354 }
3355 
3356 // this simulates the behaviour of the x86 cmpxchg instruction using a
3357 // load linked/store conditional pair. we use the acquire/release
3358 // versions of these instructions so that we flush pending writes as
3359 // per Java semantics.
3360 
3361 // n.b the x86 version assumes the old value to be compared against is
3362 // in rax and updates rax with the value located in memory if the
3363 // cmpxchg fails. we supply a register for the old value explicitly
3364 
3365 // the aarch64 load linked/store conditional instructions do not
3366 // accept an offset. so, unlike x86, we must provide a plain register
3367 // to identify the memory word to be compared/exchanged rather than a

5097 void MacroAssembler::load_mirror(Register dst, Register method, Register tmp1, Register tmp2) {
5098   const int mirror_offset = in_bytes(Klass::java_mirror_offset());
5099   ldr(dst, Address(rmethod, Method::const_offset()));
5100   ldr(dst, Address(dst, ConstMethod::constants_offset()));
5101   ldr(dst, Address(dst, ConstantPool::pool_holder_offset()));
5102   ldr(dst, Address(dst, mirror_offset));
5103   resolve_oop_handle(dst, tmp1, tmp2);
5104 }
5105 
5106 void MacroAssembler::cmp_klass(Register obj, Register klass, Register tmp) {
5107   assert_different_registers(obj, klass, tmp);
5108   if (UseCompressedClassPointers) {
5109     if (UseCompactObjectHeaders) {
5110       load_narrow_klass_compact(tmp, obj);
5111     } else {
5112       ldrw(tmp, Address(obj, oopDesc::klass_offset_in_bytes()));
5113     }
5114     if (CompressedKlassPointers::base() == nullptr) {
5115       cmp(klass, tmp, LSL, CompressedKlassPointers::shift());
5116       return;
5117     } else if (((uint64_t)CompressedKlassPointers::base() & 0xffffffff) == 0

5118                && CompressedKlassPointers::shift() == 0) {
5119       // Only the bottom 32 bits matter
5120       cmpw(klass, tmp);
5121       return;
5122     }
5123     decode_klass_not_null(tmp);
5124   } else {
5125     ldr(tmp, Address(obj, oopDesc::klass_offset_in_bytes()));
5126   }
5127   cmp(klass, tmp);
5128 }
5129 
5130 void MacroAssembler::cmp_klasses_from_objects(Register obj1, Register obj2, Register tmp1, Register tmp2) {
5131   if (UseCompactObjectHeaders) {
5132     load_narrow_klass_compact(tmp1, obj1);
5133     load_narrow_klass_compact(tmp2,  obj2);
5134     cmpw(tmp1, tmp2);
5135   } else if (UseCompressedClassPointers) {
5136     ldrw(tmp1, Address(obj1, oopDesc::klass_offset_in_bytes()));
5137     ldrw(tmp2, Address(obj2, oopDesc::klass_offset_in_bytes()));

5356   if (dst != src) {
5357     // we can load the base into dst, subtract it formthe src and shift down
5358     lea(dst, ExternalAddress(CompressedKlassPointers::base_addr()));
5359     ldr(dst, dst);
5360     sub(dst, src, dst);
5361     lsr(dst, dst, shift);
5362   } else {
5363     // we need an extra register in order to load the coop base
5364     Register tmp = pick_different_tmp(dst, src);
5365     RegSet regs = RegSet::of(tmp);
5366     push(regs, sp);
5367     lea(tmp, ExternalAddress(CompressedKlassPointers::base_addr()));
5368     ldr(tmp, tmp);
5369     sub(dst, src, tmp);
5370     lsr(dst, dst, shift);
5371     pop(regs, sp);
5372   }
5373 }
5374 
5375 void MacroAssembler::encode_klass_not_null(Register dst, Register src) {
5376   if (AOTCodeCache::is_on_for_dump()) {
5377     encode_klass_not_null_for_aot(dst, src);
5378     return;
5379   }
5380 
5381   switch (klass_decode_mode()) {
5382   case KlassDecodeZero:
5383     if (CompressedKlassPointers::shift() != 0) {
5384       lsr(dst, src, CompressedKlassPointers::shift());
5385     } else {
5386       if (dst != src) mov(dst, src);
5387     }
5388     break;
5389 
5390   case KlassDecodeXor:
5391     if (CompressedKlassPointers::shift() != 0) {
5392       eor(dst, src, (uint64_t)CompressedKlassPointers::base());
5393       lsr(dst, dst, CompressedKlassPointers::shift());
5394     } else {
5395       eor(dst, src, (uint64_t)CompressedKlassPointers::base());
5396     }

5422   if (dst != src) {
5423     // we can load the base into dst then add the offset with a suitable shift
5424     lea(dst, ExternalAddress(CompressedKlassPointers::base_addr()));
5425     ldr(dst, dst);
5426     add(dst, dst, src, LSL,  shift);
5427   } else {
5428     // we need an extra register in order to load the coop base
5429     Register tmp = pick_different_tmp(dst, src);
5430     RegSet regs = RegSet::of(tmp);
5431     push(regs, sp);
5432     lea(tmp, ExternalAddress(CompressedKlassPointers::base_addr()));
5433     ldr(tmp, tmp);
5434     add(dst, tmp,  src, LSL,  shift);
5435     pop(regs, sp);
5436   }
5437 }
5438 
5439 void  MacroAssembler::decode_klass_not_null(Register dst, Register src) {
5440   assert (UseCompressedClassPointers, "should only be used for compressed headers");
5441 
5442   if (AOTCodeCache::is_on_for_dump()) {
5443     decode_klass_not_null_for_aot(dst, src);
5444     return;
5445   }
5446 
5447   switch (klass_decode_mode()) {
5448   case KlassDecodeZero:
5449     if (CompressedKlassPointers::shift() != 0) {
5450       lsl(dst, src, CompressedKlassPointers::shift());
5451     } else {
5452       if (dst != src) mov(dst, src);
5453     }
5454     break;
5455 
5456   case KlassDecodeXor:
5457     if (CompressedKlassPointers::shift() != 0) {
5458       lsl(dst, src, CompressedKlassPointers::shift());
5459       eor(dst, dst, (uint64_t)CompressedKlassPointers::base());
5460     } else {
5461       eor(dst, src, (uint64_t)CompressedKlassPointers::base());
5462     }

5756   // the code cache so that if it is relocated we know it will still reach
5757   if (offset_high >= -(1<<20) && offset_low < (1<<20)) {
5758     _adrp(reg1, dest.target());
5759   } else {
5760     uint64_t target = (uint64_t)dest.target();
5761     uint64_t adrp_target
5762       = (target & 0xffffffffULL) | ((uint64_t)pc() & 0xffff00000000ULL);
5763 
5764     _adrp(reg1, (address)adrp_target);
5765     movk(reg1, target >> 32, 32);
5766   }
5767   byte_offset = (uint64_t)dest.target() & 0xfff;
5768 }
5769 
5770 void MacroAssembler::load_byte_map_base(Register reg) {
5771   CardTable::CardValue* byte_map_base =
5772     ((CardTableBarrierSet*)(BarrierSet::barrier_set()))->card_table()->byte_map_base();
5773 
5774   // Strictly speaking the byte_map_base isn't an address at all, and it might
5775   // even be negative. It is thus materialised as a constant.
5776   mov(reg, (uint64_t)byte_map_base);























5777 }
5778 
5779 void MacroAssembler::build_frame(int framesize) {
5780   assert(framesize >= 2 * wordSize, "framesize must include space for FP/LR");
5781   assert(framesize % (2*wordSize) == 0, "must preserve 2*wordSize alignment");
5782   protect_return_address();
5783   if (framesize < ((1 << 9) + 2 * wordSize)) {
5784     sub(sp, sp, framesize);
5785     stp(rfp, lr, Address(sp, framesize - 2 * wordSize));
5786     if (PreserveFramePointer) add(rfp, sp, framesize - 2 * wordSize);
5787   } else {
5788     stp(rfp, lr, Address(pre(sp, -2 * wordSize)));
5789     if (PreserveFramePointer) mov(rfp, sp);
5790     if (framesize < ((1 << 12) + 2 * wordSize))
5791       sub(sp, sp, framesize - 2 * wordSize);
5792     else {
5793       mov(rscratch1, framesize - 2 * wordSize);
5794       sub(sp, sp, rscratch1);
5795     }
5796   }

   9  *
  10  * This code is distributed in the hope that it will be useful, but WITHOUT
  11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  13  * version 2 for more details (a copy is included in the LICENSE file that
  14  * accompanied this code).
  15  *
  16  * You should have received a copy of the GNU General Public License version
  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  *
  24  */
  25 
  26 #include "asm/assembler.hpp"
  27 #include "asm/assembler.inline.hpp"
  28 #include "ci/ciEnv.hpp"
  29 #include "ci/ciUtilities.hpp"
  30 #include "code/compiledIC.hpp"
  31 #include "compiler/compileTask.hpp"
  32 #include "compiler/disassembler.hpp"
  33 #include "compiler/oopMap.hpp"
  34 #include "gc/shared/barrierSet.hpp"
  35 #include "gc/shared/barrierSetAssembler.hpp"
  36 #include "gc/shared/cardTableBarrierSet.hpp"
  37 #include "gc/shared/cardTable.hpp"
  38 #include "gc/shared/collectedHeap.hpp"
  39 #include "gc/shared/tlab_globals.hpp"
  40 #include "interpreter/bytecodeHistogram.hpp"
  41 #include "interpreter/interpreter.hpp"
  42 #include "interpreter/interpreterRuntime.hpp"
  43 #include "jvm.h"
  44 #include "memory/resourceArea.hpp"
  45 #include "memory/universe.hpp"
  46 #include "nativeInst_aarch64.hpp"
  47 #include "oops/accessDecorators.hpp"
  48 #include "oops/compressedKlass.inline.hpp"
  49 #include "oops/compressedOops.inline.hpp"

 332     uint32_t insn2 = insn_at(insn_addr, 1);
 333     uint32_t size = Instruction_aarch64::extract(insn2, 31, 30);
 334     Instruction_aarch64::patch(insn_addr + sizeof (uint32_t), 21, 10, offset_lo >> size);
 335     guarantee(((dest >> size) << size) == dest, "misaligned target");
 336     return 2;
 337   }
 338   static int adrpAdd_impl(address insn_addr, address &target) {
 339     uintptr_t dest = (uintptr_t)target;
 340     int offset_lo = dest & 0xfff;
 341     Instruction_aarch64::patch(insn_addr + sizeof (uint32_t), 21, 10, offset_lo);
 342     return 2;
 343   }
 344   static int adrpMovk_impl(address insn_addr, address &target) {
 345     uintptr_t dest = uintptr_t(target);
 346     Instruction_aarch64::patch(insn_addr + sizeof (uint32_t), 20, 5, (uintptr_t)target >> 32);
 347     dest = (dest & 0xffffffffULL) | (uintptr_t(insn_addr) & 0xffff00000000ULL);
 348     target = address(dest);
 349     return 2;
 350   }
 351   virtual int immediate(address insn_addr, address &target) {
 352     // Metadata pointers are either narrow (32 bits) or wide (48 bits).
 353     // We encode narrow ones by setting the upper 16 bits in the first
 354     // instruction.
 355     if (Instruction_aarch64::extract(_insn, 31, 21) == 0b11010010101) {
 356       assert(nativeInstruction_at(insn_addr+4)->is_movk(), "wrong insns in patch");
 357       narrowKlass nk = CompressedKlassPointers::encode((Klass*)target);
 358       Instruction_aarch64::patch(insn_addr, 20, 5, nk >> 16);
 359       Instruction_aarch64::patch(insn_addr+4, 20, 5, nk & 0xffff);
 360       return 2;
 361     }
 362     assert(Instruction_aarch64::extract(_insn, 31, 21) == 0b11010010100, "must be");
 363     uint64_t dest = (uint64_t)target;
 364     // Move wide constant
 365     assert(nativeInstruction_at(insn_addr+4)->is_movk(), "wrong insns in patch");
 366     assert(nativeInstruction_at(insn_addr+8)->is_movk(), "wrong insns in patch");
 367     Instruction_aarch64::patch(insn_addr, 20, 5, dest & 0xffff);
 368     Instruction_aarch64::patch(insn_addr+4, 20, 5, (dest >>= 16) & 0xffff);
 369     Instruction_aarch64::patch(insn_addr+8, 20, 5, (dest >>= 16) & 0xffff);
 370     return 3;
 371   }
 372   virtual void verify(address insn_addr, address &target) {
 373 #ifdef ASSERT
 374     address address_is = MacroAssembler::target_addr_for_insn(insn_addr);
 375     if (!(address_is == target)) {
 376       tty->print_cr("%p at %p should be %p", address_is, insn_addr, target);
 377       disnm((intptr_t)insn_addr);
 378       assert(address_is == target, "should be");
 379     }
 380 #endif
 381   }

 472     uint32_t insn2 = insn_at(insn_addr, 1);
 473     uint64_t dest = uint64_t(target);
 474     dest = (dest & 0xffff0000ffffffff) |
 475       ((uint64_t)Instruction_aarch64::extract(insn2, 20, 5) << 32);
 476     target = address(dest);
 477 
 478     // We know the destination 4k page. Maybe we have a third
 479     // instruction.
 480     uint32_t insn = insn_at(insn_addr, 0);
 481     uint32_t insn3 = insn_at(insn_addr, 2);
 482     ptrdiff_t byte_offset;
 483     if (offset_for(insn, insn3, byte_offset)) {
 484       target += byte_offset;
 485       return 3;
 486     } else {
 487       return 2;
 488     }
 489   }
 490   virtual int immediate(address insn_addr, address &target) {
 491     uint32_t *insns = (uint32_t *)insn_addr;
 492     // Metadata pointers are either narrow (32 bits) or wide (48 bits).
 493     // We encode narrow ones by setting the upper 16 bits in the first
 494     // instruction.
 495     if (Instruction_aarch64::extract(_insn, 31, 21) == 0b11010010101) {
 496       assert(nativeInstruction_at(insn_addr+4)->is_movk(), "wrong insns in patch");
 497       narrowKlass nk = (narrowKlass)((uint32_t(Instruction_aarch64::extract(_insn, 20, 5)) << 16)
 498                                    +  uint32_t(Instruction_aarch64::extract(insns[1], 20, 5)));
 499       target = (address)CompressedKlassPointers::decode(nk);
 500       return 2;
 501     }
 502     assert(Instruction_aarch64::extract(_insn, 31, 21) == 0b11010010100, "must be");
 503     // Move wide constant: movz, movk, movk.  See movptr().
 504     assert(nativeInstruction_at(insns+1)->is_movk(), "wrong insns in patch");
 505     assert(nativeInstruction_at(insns+2)->is_movk(), "wrong insns in patch");
 506     target = address(uint64_t(Instruction_aarch64::extract(_insn, 20, 5))
 507                  + (uint64_t(Instruction_aarch64::extract(insns[1], 20, 5)) << 16)
 508                  + (uint64_t(Instruction_aarch64::extract(insns[2], 20, 5)) << 32));
 509     assert(nativeInstruction_at(insn_addr+4)->is_movk(), "wrong insns in patch");
 510     assert(nativeInstruction_at(insn_addr+8)->is_movk(), "wrong insns in patch");
 511     return 3;
 512   }
 513   virtual void verify(address insn_addr, address &target) {
 514   }
 515 };
 516 
 517 address MacroAssembler::target_addr_for_insn(address insn_addr, uint32_t insn) {
 518   AArch64Decoder decoder(insn_addr, insn);
 519   address target;
 520   decoder.run(insn_addr, target);
 521   return target;

 996   // Max stub size: alignment nop, TrampolineStub.
 997   return NativeInstruction::instruction_size + NativeCallTrampolineStub::instruction_size;
 998 }
 999 
1000 void MacroAssembler::emit_static_call_stub() {
1001   // CompiledDirectCall::set_to_interpreted knows the
1002   // exact layout of this stub.
1003 
1004   isb();
1005   mov_metadata(rmethod, nullptr);
1006 
1007   // Jump to the entry point of the c2i stub.
1008   if (codestub_branch_needs_far_jump()) {
1009     movptr(rscratch1, 0);
1010     br(rscratch1);
1011   } else {
1012     b(pc());
1013   }
1014 }
1015 
1016 int MacroAssembler::max_static_call_stub_size() {




1017   // isb; movk; movz; movz; movk; movz; movz; br
1018   return 8 * NativeInstruction::instruction_size;
1019 }
1020 
1021 void MacroAssembler::c2bool(Register x) {
1022   // implements x == 0 ? 0 : 1
1023   // note: must only look at least-significant byte of x
1024   //       since C-style booleans are stored in one byte
1025   //       only! (was bug)
1026   tst(x, 0xff);
1027   cset(x, Assembler::NE);
1028 }
1029 
1030 address MacroAssembler::ic_call(address entry, jint method_index) {
1031   RelocationHolder rh = virtual_call_Relocation::spec(pc(), method_index);
1032   movptr(rscratch2, (intptr_t)Universe::non_oop_word());
1033   return trampoline_call(Address(entry, rh));
1034 }
1035 
1036 int MacroAssembler::ic_check_size() {

3344 
3345 void MacroAssembler::sub(Register Rd, Register Rn, RegisterOrConstant decrement) {
3346   if (decrement.is_register()) {
3347     sub(Rd, Rn, decrement.as_register());
3348   } else {
3349     sub(Rd, Rn, decrement.as_constant());
3350   }
3351 }
3352 
3353 void MacroAssembler::subw(Register Rd, Register Rn, RegisterOrConstant decrement) {
3354   if (decrement.is_register()) {
3355     subw(Rd, Rn, decrement.as_register());
3356   } else {
3357     subw(Rd, Rn, decrement.as_constant());
3358   }
3359 }
3360 
3361 void MacroAssembler::reinit_heapbase()
3362 {
3363   if (UseCompressedOops) {
3364     if (Universe::is_fully_initialized() && !AOTCodeCache::is_on_for_dump()) {
3365       mov(rheapbase, CompressedOops::base());
3366     } else {
3367       lea(rheapbase, ExternalAddress(CompressedOops::base_addr()));
3368       ldr(rheapbase, Address(rheapbase));
3369     }
3370   }
3371 }
3372 
3373 // this simulates the behaviour of the x86 cmpxchg instruction using a
3374 // load linked/store conditional pair. we use the acquire/release
3375 // versions of these instructions so that we flush pending writes as
3376 // per Java semantics.
3377 
3378 // n.b the x86 version assumes the old value to be compared against is
3379 // in rax and updates rax with the value located in memory if the
3380 // cmpxchg fails. we supply a register for the old value explicitly
3381 
3382 // the aarch64 load linked/store conditional instructions do not
3383 // accept an offset. so, unlike x86, we must provide a plain register
3384 // to identify the memory word to be compared/exchanged rather than a

5114 void MacroAssembler::load_mirror(Register dst, Register method, Register tmp1, Register tmp2) {
5115   const int mirror_offset = in_bytes(Klass::java_mirror_offset());
5116   ldr(dst, Address(rmethod, Method::const_offset()));
5117   ldr(dst, Address(dst, ConstMethod::constants_offset()));
5118   ldr(dst, Address(dst, ConstantPool::pool_holder_offset()));
5119   ldr(dst, Address(dst, mirror_offset));
5120   resolve_oop_handle(dst, tmp1, tmp2);
5121 }
5122 
5123 void MacroAssembler::cmp_klass(Register obj, Register klass, Register tmp) {
5124   assert_different_registers(obj, klass, tmp);
5125   if (UseCompressedClassPointers) {
5126     if (UseCompactObjectHeaders) {
5127       load_narrow_klass_compact(tmp, obj);
5128     } else {
5129       ldrw(tmp, Address(obj, oopDesc::klass_offset_in_bytes()));
5130     }
5131     if (CompressedKlassPointers::base() == nullptr) {
5132       cmp(klass, tmp, LSL, CompressedKlassPointers::shift());
5133       return;
5134     } else if (!AOTCodeCache::is_on_for_dump() &&
5135                ((uint64_t)CompressedKlassPointers::base() & 0xffffffff) == 0
5136                && CompressedKlassPointers::shift() == 0) {
5137       // Only the bottom 32 bits matter
5138       cmpw(klass, tmp);
5139       return;
5140     }
5141     decode_klass_not_null(tmp);
5142   } else {
5143     ldr(tmp, Address(obj, oopDesc::klass_offset_in_bytes()));
5144   }
5145   cmp(klass, tmp);
5146 }
5147 
5148 void MacroAssembler::cmp_klasses_from_objects(Register obj1, Register obj2, Register tmp1, Register tmp2) {
5149   if (UseCompactObjectHeaders) {
5150     load_narrow_klass_compact(tmp1, obj1);
5151     load_narrow_klass_compact(tmp2,  obj2);
5152     cmpw(tmp1, tmp2);
5153   } else if (UseCompressedClassPointers) {
5154     ldrw(tmp1, Address(obj1, oopDesc::klass_offset_in_bytes()));
5155     ldrw(tmp2, Address(obj2, oopDesc::klass_offset_in_bytes()));

5374   if (dst != src) {
5375     // we can load the base into dst, subtract it formthe src and shift down
5376     lea(dst, ExternalAddress(CompressedKlassPointers::base_addr()));
5377     ldr(dst, dst);
5378     sub(dst, src, dst);
5379     lsr(dst, dst, shift);
5380   } else {
5381     // we need an extra register in order to load the coop base
5382     Register tmp = pick_different_tmp(dst, src);
5383     RegSet regs = RegSet::of(tmp);
5384     push(regs, sp);
5385     lea(tmp, ExternalAddress(CompressedKlassPointers::base_addr()));
5386     ldr(tmp, tmp);
5387     sub(dst, src, tmp);
5388     lsr(dst, dst, shift);
5389     pop(regs, sp);
5390   }
5391 }
5392 
5393 void MacroAssembler::encode_klass_not_null(Register dst, Register src) {
5394   if (CompressedKlassPointers::base() != nullptr && AOTCodeCache::is_on_for_dump()) {
5395     encode_klass_not_null_for_aot(dst, src);
5396     return;
5397   }
5398 
5399   switch (klass_decode_mode()) {
5400   case KlassDecodeZero:
5401     if (CompressedKlassPointers::shift() != 0) {
5402       lsr(dst, src, CompressedKlassPointers::shift());
5403     } else {
5404       if (dst != src) mov(dst, src);
5405     }
5406     break;
5407 
5408   case KlassDecodeXor:
5409     if (CompressedKlassPointers::shift() != 0) {
5410       eor(dst, src, (uint64_t)CompressedKlassPointers::base());
5411       lsr(dst, dst, CompressedKlassPointers::shift());
5412     } else {
5413       eor(dst, src, (uint64_t)CompressedKlassPointers::base());
5414     }

5440   if (dst != src) {
5441     // we can load the base into dst then add the offset with a suitable shift
5442     lea(dst, ExternalAddress(CompressedKlassPointers::base_addr()));
5443     ldr(dst, dst);
5444     add(dst, dst, src, LSL,  shift);
5445   } else {
5446     // we need an extra register in order to load the coop base
5447     Register tmp = pick_different_tmp(dst, src);
5448     RegSet regs = RegSet::of(tmp);
5449     push(regs, sp);
5450     lea(tmp, ExternalAddress(CompressedKlassPointers::base_addr()));
5451     ldr(tmp, tmp);
5452     add(dst, tmp,  src, LSL,  shift);
5453     pop(regs, sp);
5454   }
5455 }
5456 
5457 void  MacroAssembler::decode_klass_not_null(Register dst, Register src) {
5458   assert (UseCompressedClassPointers, "should only be used for compressed headers");
5459 
5460   if (CompressedKlassPointers::base() != nullptr && AOTCodeCache::is_on_for_dump()) {
5461     decode_klass_not_null_for_aot(dst, src);
5462     return;
5463   }
5464 
5465   switch (klass_decode_mode()) {
5466   case KlassDecodeZero:
5467     if (CompressedKlassPointers::shift() != 0) {
5468       lsl(dst, src, CompressedKlassPointers::shift());
5469     } else {
5470       if (dst != src) mov(dst, src);
5471     }
5472     break;
5473 
5474   case KlassDecodeXor:
5475     if (CompressedKlassPointers::shift() != 0) {
5476       lsl(dst, src, CompressedKlassPointers::shift());
5477       eor(dst, dst, (uint64_t)CompressedKlassPointers::base());
5478     } else {
5479       eor(dst, src, (uint64_t)CompressedKlassPointers::base());
5480     }

5774   // the code cache so that if it is relocated we know it will still reach
5775   if (offset_high >= -(1<<20) && offset_low < (1<<20)) {
5776     _adrp(reg1, dest.target());
5777   } else {
5778     uint64_t target = (uint64_t)dest.target();
5779     uint64_t adrp_target
5780       = (target & 0xffffffffULL) | ((uint64_t)pc() & 0xffff00000000ULL);
5781 
5782     _adrp(reg1, (address)adrp_target);
5783     movk(reg1, target >> 32, 32);
5784   }
5785   byte_offset = (uint64_t)dest.target() & 0xfff;
5786 }
5787 
5788 void MacroAssembler::load_byte_map_base(Register reg) {
5789   CardTable::CardValue* byte_map_base =
5790     ((CardTableBarrierSet*)(BarrierSet::barrier_set()))->card_table()->byte_map_base();
5791 
5792   // Strictly speaking the byte_map_base isn't an address at all, and it might
5793   // even be negative. It is thus materialised as a constant.
5794 #if INCLUDE_CDS
5795   if (AOTCodeCache::is_on_for_dump()) {
5796     // AOT code needs relocation info for card table base
5797     lea(reg, ExternalAddress(reinterpret_cast<address>(byte_map_base)));
5798   } else {
5799 #endif
5800     mov(reg, (uint64_t)byte_map_base);
5801 #if INCLUDE_CDS
5802   }
5803 #endif
5804 }
5805 
5806 void MacroAssembler::load_aotrc_address(Register reg, address a) {
5807 #if INCLUDE_CDS
5808   assert(AOTRuntimeConstants::contains(a), "address out of range for data area");
5809   if (AOTCodeCache::is_on_for_dump()) {
5810     // all aotrc field addresses should be registered in the AOTCodeCache address table
5811     lea(reg, ExternalAddress(a));
5812   } else {
5813     mov(reg, (uint64_t)a);
5814   }
5815 #else
5816   ShouldNotReachHere();
5817 #endif
5818 }
5819 
5820 void MacroAssembler::build_frame(int framesize) {
5821   assert(framesize >= 2 * wordSize, "framesize must include space for FP/LR");
5822   assert(framesize % (2*wordSize) == 0, "must preserve 2*wordSize alignment");
5823   protect_return_address();
5824   if (framesize < ((1 << 9) + 2 * wordSize)) {
5825     sub(sp, sp, framesize);
5826     stp(rfp, lr, Address(sp, framesize - 2 * wordSize));
5827     if (PreserveFramePointer) add(rfp, sp, framesize - 2 * wordSize);
5828   } else {
5829     stp(rfp, lr, Address(pre(sp, -2 * wordSize)));
5830     if (PreserveFramePointer) mov(rfp, sp);
5831     if (framesize < ((1 << 12) + 2 * wordSize))
5832       sub(sp, sp, framesize - 2 * wordSize);
5833     else {
5834       mov(rscratch1, framesize - 2 * wordSize);
5835       sub(sp, sp, rscratch1);
5836     }
5837   }
< prev index next >