Index: src/arm64/instructions-arm64.cc |
diff --git a/src/arm64/instructions-arm64.cc b/src/arm64/instructions-arm64.cc |
index 4d1428a1507bbd7b6049e45ec2240ac3ec8e7afe..6f4e76fa6a17bf862f21f6e5797f8e7c8dd5af95 100644 |
--- a/src/arm64/instructions-arm64.cc |
+++ b/src/arm64/instructions-arm64.cc |
@@ -254,11 +254,18 @@ void Instruction::SetImmPCOffsetTarget(Instruction* target) { |
void Instruction::SetPCRelImmTarget(Instruction* target) { |
// ADRP is not supported, so 'this' must point to an ADR instruction. |
- ASSERT(Mask(PCRelAddressingMask) == ADR); |
+ ASSERT(IsAdr()); |
- Instr imm = Assembler::ImmPCRelAddress(DistanceTo(target)); |
- |
- SetInstructionBits(Mask(~ImmPCRel_mask) | imm); |
+ int target_offset = DistanceTo(target); |
+ Instr imm; |
+ if (Instruction::IsValidPCRelOffset(target_offset)) { |
+ imm = Assembler::ImmPCRelAddress(target_offset); |
+ SetInstructionBits(Mask(~ImmPCRel_mask) | imm); |
+ } else { |
+ PatchingAssembler patcher(this, |
+ PatchingAssembler::kAdrFarPatchableNInstrs); |
+ patcher.PatchAdrFar(target); |
+ } |
} |