< 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;

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

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

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

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

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

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

5720   assert(dest.getMode() == Address::literal, "ADRP must be applied to a literal address");
5721 
5722   InstructionMark im(this);
5723   code_section()->relocate(inst_mark(), dest.rspec());
5724   // 8143067: Ensure that the adrp can reach the dest from anywhere within
5725   // the code cache so that if it is relocated we know it will still reach
5726   if (offset_high >= -(1<<20) && offset_low < (1<<20)) {
5727     _adrp(reg1, dest.target());
5728   } else {
5729     uint64_t target = (uint64_t)dest.target();
5730     uint64_t adrp_target
5731       = (target & 0xffffffffULL) | ((uint64_t)pc() & 0xffff00000000ULL);
5732 
5733     _adrp(reg1, (address)adrp_target);
5734     movk(reg1, target >> 32, 32);
5735   }
5736   byte_offset = (uint64_t)dest.target() & 0xfff;
5737 }
5738 
5739 void MacroAssembler::load_byte_map_base(Register reg) {








5740   CardTable::CardValue* byte_map_base =
5741     ((CardTableBarrierSet*)(BarrierSet::barrier_set()))->card_table()->byte_map_base();
5742 
5743   // Strictly speaking the byte_map_base isn't an address at all, and it might
5744   // even be negative. It is thus materialised as a constant.
5745   mov(reg, (uint64_t)byte_map_base);
5746 }
5747 














5748 void MacroAssembler::build_frame(int framesize) {
5749   assert(framesize >= 2 * wordSize, "framesize must include space for FP/LR");
5750   assert(framesize % (2*wordSize) == 0, "must preserve 2*wordSize alignment");
5751   protect_return_address();
5752   if (framesize < ((1 << 9) + 2 * wordSize)) {
5753     sub(sp, sp, framesize);
5754     stp(rfp, lr, Address(sp, framesize - 2 * wordSize));
5755     if (PreserveFramePointer) add(rfp, sp, framesize - 2 * wordSize);
5756   } else {
5757     stp(rfp, lr, Address(pre(sp, -2 * wordSize)));
5758     if (PreserveFramePointer) mov(rfp, sp);
5759     if (framesize < ((1 << 12) + 2 * wordSize))
5760       sub(sp, sp, framesize - 2 * wordSize);
5761     else {
5762       mov(rscratch1, framesize - 2 * wordSize);
5763       sub(sp, sp, rscratch1);
5764     }
5765   }
5766   verify_cross_modify_fence_not_required();
5767 }

   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;

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




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

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

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

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

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

5738   assert(dest.getMode() == Address::literal, "ADRP must be applied to a literal address");
5739 
5740   InstructionMark im(this);
5741   code_section()->relocate(inst_mark(), dest.rspec());
5742   // 8143067: Ensure that the adrp can reach the dest from anywhere within
5743   // the code cache so that if it is relocated we know it will still reach
5744   if (offset_high >= -(1<<20) && offset_low < (1<<20)) {
5745     _adrp(reg1, dest.target());
5746   } else {
5747     uint64_t target = (uint64_t)dest.target();
5748     uint64_t adrp_target
5749       = (target & 0xffffffffULL) | ((uint64_t)pc() & 0xffff00000000ULL);
5750 
5751     _adrp(reg1, (address)adrp_target);
5752     movk(reg1, target >> 32, 32);
5753   }
5754   byte_offset = (uint64_t)dest.target() & 0xfff;
5755 }
5756 
5757 void MacroAssembler::load_byte_map_base(Register reg) {
5758 #if INCLUDE_CDS
5759   if (AOTCodeCache::is_on_for_dump()) {
5760     address byte_map_base_adr = AOTRuntimeConstants::card_table_address();
5761     lea(reg, ExternalAddress(byte_map_base_adr));
5762     ldr(reg, Address(reg));
5763     return;
5764   }
5765 #endif
5766   CardTable::CardValue* byte_map_base =
5767     ((CardTableBarrierSet*)(BarrierSet::barrier_set()))->card_table()->byte_map_base();
5768 
5769   // Strictly speaking the byte_map_base isn't an address at all, and it might
5770   // even be negative. It is thus materialised as a constant.
5771   mov(reg, (uint64_t)byte_map_base);
5772 }
5773 
5774 void MacroAssembler::load_aotrc_address(Register reg, address a) {
5775 #if INCLUDE_CDS
5776   assert(AOTRuntimeConstants::contains(a), "address out of range for data area");
5777   if (AOTCodeCache::is_on_for_dump()) {
5778     // all aotrc field addresses should be registered in the AOTCodeCache address table
5779     lea(reg, ExternalAddress(a));
5780   } else {
5781     mov(reg, (uint64_t)a);
5782   }
5783 #else
5784   ShouldNotReachHere();
5785 #endif
5786 }
5787 
5788 void MacroAssembler::build_frame(int framesize) {
5789   assert(framesize >= 2 * wordSize, "framesize must include space for FP/LR");
5790   assert(framesize % (2*wordSize) == 0, "must preserve 2*wordSize alignment");
5791   protect_return_address();
5792   if (framesize < ((1 << 9) + 2 * wordSize)) {
5793     sub(sp, sp, framesize);
5794     stp(rfp, lr, Address(sp, framesize - 2 * wordSize));
5795     if (PreserveFramePointer) add(rfp, sp, framesize - 2 * wordSize);
5796   } else {
5797     stp(rfp, lr, Address(pre(sp, -2 * wordSize)));
5798     if (PreserveFramePointer) mov(rfp, sp);
5799     if (framesize < ((1 << 12) + 2 * wordSize))
5800       sub(sp, sp, framesize - 2 * wordSize);
5801     else {
5802       mov(rscratch1, framesize - 2 * wordSize);
5803       sub(sp, sp, rscratch1);
5804     }
5805   }
5806   verify_cross_modify_fence_not_required();
5807 }
< prev index next >