diff --git a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp index d694b010ffc..d62431b1b91 100644 --- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp @@ -302,22 +302,21 @@ public: Instruction_aarch64::patch(insn_addr, 30, 29, offset_lo); return 1; } - virtual int adrp(address insn_addr, address &target, reloc_insn inner) { + virtual int adrp(address insn_addr, address &target0, reloc_insn inner) { int instructions = 1; #ifdef ASSERT assert(Instruction_aarch64::extract(_insn, 28, 24) == 0b10000, "must be"); #endif - ptrdiff_t offset = target - insn_addr; - instructions = 2; precond(inner != nullptr); + address target = target0; + instructions = (*inner)(insn_addr, target); + ptrdiff_t offset = target - insn_addr; uintptr_t dest = (uintptr_t)target; uintptr_t pc_page = (uintptr_t)insn_addr >> 12; uintptr_t adr_page = (uintptr_t)target >> 12; offset = adr_page - pc_page; - instructions = (*inner)(insn_addr, target); // Now we extract the lower 21 bits of the signed offset field for // the ADRP. - offset = offset << (64-21) >> (64-21); int offset_lo = offset & 3; offset >>= 2; Instruction_aarch64::spatch(insn_addr, 23, 5, offset); @@ -342,6 +341,9 @@ public: static int adrpMovk_impl(address insn_addr, address &target) { uintptr_t dest = (uintptr_t)target; Instruction_aarch64::patch(insn_addr + sizeof (uint32_t), 20, 5, (uintptr_t)target >> 32); + uint64_t adrp_target = (uint64_t)target; + adrp_target = (adrp_target & 0xffffffffULL) | ((uint64_t)insn_addr & 0xffff00000000ULL); + target = (address)adrp_target; return 2; } virtual int immediate(address insn_addr, address &target) {