From: Richard Henderson <[email protected]> This includes handling the ADRP instruction.
Signed-off-by: Richard Henderson <[email protected]> --- disas/arm-a64.cc | 1 + disas/libvixl/a64/disasm-a64.cc | 32 ++++++++++++-------------------- disas/libvixl/a64/disasm-a64.h | 2 ++ 3 files changed, 15 insertions(+), 20 deletions(-) diff --git a/disas/arm-a64.cc b/disas/arm-a64.cc index 162be0c..2f5ba33 100644 --- a/disas/arm-a64.cc +++ b/disas/arm-a64.cc @@ -81,6 +81,7 @@ int print_insn_arm_a64(uint64_t addr, disassemble_info *info) } instr = bytes[0] | bytes[1] << 8 | bytes[2] << 16 | bytes[3] << 24; + vixl_disasm->SetPC(addr); vixl_decoder->Decode(reinterpret_cast<Instruction*>(&instr)); return INSN_SIZE; diff --git a/disas/libvixl/a64/disasm-a64.cc b/disas/libvixl/a64/disasm-a64.cc index aa133a9..76560b0 100644 --- a/disas/libvixl/a64/disasm-a64.cc +++ b/disas/libvixl/a64/disasm-a64.cc @@ -529,8 +529,8 @@ void Disassembler::VisitExtract(Instruction* instr) { void Disassembler::VisitPCRelAddressing(Instruction* instr) { switch (instr->Mask(PCRelAddressingMask)) { case ADR: Format(instr, "adr", "'Xd, 'AddrPCRelByte"); break; - // ADRP is not implemented. - default: Format(instr, "unimplemented", "(PCRelAddressing)"); + case ADRP: Format(instr, "adrp", "'Xd, 'AddrPCRelPage"); break; + default: VIXL_UNREACHABLE(); } } @@ -1406,8 +1406,7 @@ int Disassembler::SubstituteImmediateField(Instruction* instr, } case 'C': { // ICondB - Immediate Conditional Branch. int64_t offset = instr->ImmCondBranch() << 2; - char sign = (offset >= 0) ? '+' : '-'; - AppendToOutput("#%c0x%" PRIx64, sign, offset); + AppendToOutput("#0x%" PRIx64, pc_ + offset); return 6; } case 'A': { // IAddSub. @@ -1568,17 +1567,16 @@ int Disassembler::SubstitutePCRelAddressField(Instruction* instr, VIXL_ASSERT(strncmp(format, "AddrPCRel", 9) == 0); int offset = instr->ImmPCRel(); + uint64_t addr; - // Only ADR (AddrPCRelByte) is supported. - VIXL_ASSERT(strcmp(format, "AddrPCRelByte") == 0); - - char sign = '+'; - if (offset < 0) { - offset = -offset; - sign = '-'; + if (strcmp(format, "AddrPCRelByte") == 0) { + addr = pc_ + offset; + } else { + VIXL_ASSERT(strcmp(format, "AddrPCRelPage") == 0); + addr = (pc_ & -4096) + ((int64_t)offset << 12); } - VIXL_STATIC_ASSERT(sizeof(*instr) == 1); - AppendToOutput("#%c0x%x (addr %p)", sign, offset, instr + offset); + + AppendToOutput("#0x%" PRIx64, addr); return 13; } @@ -1600,13 +1598,7 @@ int Disassembler::SubstituteBranchTargetField(Instruction* instr, default: VIXL_UNIMPLEMENTED(); } offset <<= kInstructionSizeLog2; - char sign = '+'; - if (offset < 0) { - offset = -offset; - sign = '-'; - } - VIXL_STATIC_ASSERT(sizeof(*instr) == 1); - AppendToOutput("#%c0x%" PRIx64 " (addr %p)", sign, offset, instr + offset); + AppendToOutput("#0x%" PRIx64, pc_ + offset); return 8; } diff --git a/disas/libvixl/a64/disasm-a64.h b/disas/libvixl/a64/disasm-a64.h index 3a56e15..7f59fba 100644 --- a/disas/libvixl/a64/disasm-a64.h +++ b/disas/libvixl/a64/disasm-a64.h @@ -40,6 +40,7 @@ class Disassembler: public DecoderVisitor { Disassembler(char* text_buffer, int buffer_size); virtual ~Disassembler(); char* GetOutput(); + void SetPC(uint64_t pc) { pc_ = pc; } // Declare all Visitor functions. #define DECLARE(A) void Visit##A(Instruction* instr); @@ -88,6 +89,7 @@ class Disassembler: public DecoderVisitor { void AppendToOutput(const char* string, ...); char* buffer_; + uint64_t pc_; uint32_t buffer_pos_; uint32_t buffer_size_; bool own_buffer_; -- 1.9.3
