qemu-devel
[Top][All Lists]
Advanced

[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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]