[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 2/2] disas/libvixl: Properly display pc-relative add
From: |
Richard Henderson |
Subject: |
[Qemu-devel] [PATCH 2/2] disas/libvixl: Properly display pc-relative addresses |
Date: |
Tue, 27 May 2014 13:43:49 -0700 |
From: Richard Henderson <address@hidden>
This includes handling the ADRP instruction.
Signed-off-by: Richard Henderson <address@hidden>
---
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