[llvm] 2c14798 - [ARM][llvm-objdump] Annotate PC-relative memory operands of VLDR instructions

Igor Kudrin via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 5 00:12:32 PDT 2021


Author: Igor Kudrin
Date: 2021-08-05T14:11:11+07:00
New Revision: 2c14798ead0dbffca58eb64f5672d40fe59bb040

URL: https://github.com/llvm/llvm-project/commit/2c14798ead0dbffca58eb64f5672d40fe59bb040
DIFF: https://github.com/llvm/llvm-project/commit/2c14798ead0dbffca58eb64f5672d40fe59bb040.diff

LOG: [ARM][llvm-objdump] Annotate PC-relative memory operands of VLDR instructions

This extends D105979 and adds support for VLDR instructions.

Differential Revision: https://reviews.llvm.org/D105980

Added: 
    llvm/test/tools/llvm-objdump/ELF/ARM/literal-vldr-arm.s
    llvm/test/tools/llvm-objdump/ELF/ARM/literal-vldr-thumb2.s

Modified: 
    llvm/include/llvm/MC/MCInstrAnalysis.h
    llvm/lib/MC/MCInstrAnalysis.cpp
    llvm/lib/Target/ARM/ARMInstrInfo.td
    llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp
    llvm/lib/Target/X86/MCTargetDesc/X86ATTInstPrinter.cpp
    llvm/lib/Target/X86/MCTargetDesc/X86IntelInstPrinter.cpp
    llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp
    llvm/tools/llvm-objdump/llvm-objdump.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/MC/MCInstrAnalysis.h b/llvm/include/llvm/MC/MCInstrAnalysis.h
index 898ca47b13b8c..68506d1fced45 100644
--- a/llvm/include/llvm/MC/MCInstrAnalysis.h
+++ b/llvm/include/llvm/MC/MCInstrAnalysis.h
@@ -154,9 +154,9 @@ class MCInstrAnalysis {
 
   /// Given an instruction tries to get the address of a memory operand. Returns
   /// the address on success.
-  virtual Optional<uint64_t> evaluateMemoryOperandAddress(const MCInst &Inst,
-                                                          uint64_t Addr,
-                                                          uint64_t Size) const;
+  virtual Optional<uint64_t>
+  evaluateMemoryOperandAddress(const MCInst &Inst, const MCSubtargetInfo *STI,
+                               uint64_t Addr, uint64_t Size) const;
 
   /// Returns (PLT virtual address, GOT virtual address) pairs for PLT entries.
   virtual std::vector<std::pair<uint64_t, uint64_t>>

diff  --git a/llvm/lib/MC/MCInstrAnalysis.cpp b/llvm/lib/MC/MCInstrAnalysis.cpp
index a7dc0626d0ab7..ef5516c1afb2b 100644
--- a/llvm/lib/MC/MCInstrAnalysis.cpp
+++ b/llvm/lib/MC/MCInstrAnalysis.cpp
@@ -29,8 +29,8 @@ bool MCInstrAnalysis::evaluateBranch(const MCInst & /*Inst*/, uint64_t /*Addr*/,
   return false;
 }
 
-Optional<uint64_t>
-MCInstrAnalysis::evaluateMemoryOperandAddress(const MCInst &Inst, uint64_t Addr,
-                                              uint64_t Size) const {
+Optional<uint64_t> MCInstrAnalysis::evaluateMemoryOperandAddress(
+    const MCInst &Inst, const MCSubtargetInfo *STI, uint64_t Addr,
+    uint64_t Size) const {
   return None;
 }

diff  --git a/llvm/lib/Target/ARM/ARMInstrInfo.td b/llvm/lib/Target/ARM/ARMInstrInfo.td
index eeab4ce6d3ebd..f690f11aacde3 100644
--- a/llvm/lib/Target/ARM/ARMInstrInfo.td
+++ b/llvm/lib/Target/ARM/ARMInstrInfo.td
@@ -1252,7 +1252,7 @@ def addrmode5_pre : AddrMode5 {
 // addrmode5fp16 := reg +/- imm8*2
 //
 def AddrMode5FP16AsmOperand : AsmOperandClass { let Name = "AddrMode5FP16"; }
-class AddrMode5FP16 : Operand<i32>,
+class AddrMode5FP16 : MemOperand,
                       ComplexPattern<i32, 2, "SelectAddrMode5FP16", []> {
   let EncoderMethod = "getAddrMode5FP16OpValue";
   let DecoderMethod = "DecodeAddrMode5FP16Operand";

diff  --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp
index 3522639676096..cafa4de963349 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp
@@ -443,6 +443,7 @@ class ARMMCInstrAnalysis : public MCInstrAnalysis {
   }
 
   Optional<uint64_t> evaluateMemoryOperandAddress(const MCInst &Inst,
+                                                  const MCSubtargetInfo *STI,
                                                   uint64_t Addr,
                                                   uint64_t Size) const override;
 };
@@ -509,6 +510,25 @@ static Optional<uint64_t> evaluateMemOpAddrForAddrMode5(const MCInst &Inst,
   return Addr + ImmOffs * 4;
 }
 
+static Optional<uint64_t>
+evaluateMemOpAddrForAddrMode5FP16(const MCInst &Inst, const MCInstrDesc &Desc,
+                                  unsigned MemOpIndex, uint64_t Addr) {
+  if (MemOpIndex + 1 >= Desc.getNumOperands())
+    return None;
+
+  const MCOperand &MO1 = Inst.getOperand(MemOpIndex);
+  const MCOperand &MO2 = Inst.getOperand(MemOpIndex + 1);
+  if (!MO1.isReg() || MO1.getReg() != ARM::PC || !MO2.isImm())
+    return None;
+
+  unsigned ImmOffs = ARM_AM::getAM5FP16Offset(MO2.getImm());
+  ARM_AM::AddrOpc Op = ARM_AM::getAM5FP16Op(MO2.getImm());
+
+  if (Op == ARM_AM::sub)
+    return Addr - ImmOffs * 2;
+  return Addr + ImmOffs * 2;
+}
+
 static Optional<uint64_t>
 // NOLINTNEXTLINE(readability-identifier-naming)
 evaluateMemOpAddrForAddrModeT2_i8s4(const MCInst &Inst, const MCInstrDesc &Desc,
@@ -554,7 +574,8 @@ evaluateMemOpAddrForAddrModeT1_s(const MCInst &Inst, const MCInstrDesc &Desc,
 }
 
 Optional<uint64_t> ARMMCInstrAnalysis::evaluateMemoryOperandAddress(
-    const MCInst &Inst, uint64_t Addr, uint64_t Size) const {
+    const MCInst &Inst, const MCSubtargetInfo *STI, uint64_t Addr,
+    uint64_t Size) const {
   const MCInstrDesc &Desc = Info->get(Inst.getOpcode());
 
   // Only load instructions can have PC-relative memory addressing.
@@ -588,6 +609,11 @@ Optional<uint64_t> ARMMCInstrAnalysis::evaluateMemoryOperandAddress(
   case ARMII::ThumbFrm:
     Addr += 4;
     break;
+  // VLDR* instructions share the same opcode (and thus the same form) for Arm
+  // and Thumb. Use a bit longer route through STI in that case.
+  case ARMII::VFPLdStFrm:
+    Addr += STI->getFeatureBits()[ARM::ModeThumb] ? 4 : 8;
+    break;
   }
 
   // Eveluate the address depending on the addressing mode
@@ -601,6 +627,8 @@ Optional<uint64_t> ARMMCInstrAnalysis::evaluateMemoryOperandAddress(
     return evaluateMemOpAddrForAddrMode3(Inst, Desc, OpIndex, Addr);
   case ARMII::AddrMode5:
     return evaluateMemOpAddrForAddrMode5(Inst, Desc, OpIndex, Addr);
+  case ARMII::AddrMode5FP16:
+    return evaluateMemOpAddrForAddrMode5FP16(Inst, Desc, OpIndex, Addr);
   case ARMII::AddrModeT2_i8s4:
     return evaluateMemOpAddrForAddrModeT2_i8s4(Inst, Desc, OpIndex, Addr);
   case ARMII::AddrModeT2_pc:

diff  --git a/llvm/lib/Target/X86/MCTargetDesc/X86ATTInstPrinter.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86ATTInstPrinter.cpp
index c685d7e0db81c..30f279cc94a51 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86ATTInstPrinter.cpp
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86ATTInstPrinter.cpp
@@ -391,7 +391,7 @@ void X86ATTInstPrinter::printMemReference(const MCInst *MI, unsigned Op,
     uint64_t Target;
     if (MIA->evaluateBranch(*MI, 0, 0, Target))
       return;
-    if (MIA->evaluateMemoryOperandAddress(*MI, 0, 0))
+    if (MIA->evaluateMemoryOperandAddress(*MI, /*STI=*/nullptr, 0, 0))
       return;
   }
 

diff  --git a/llvm/lib/Target/X86/MCTargetDesc/X86IntelInstPrinter.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86IntelInstPrinter.cpp
index d5b205ad9a63c..e88d3d06eddff 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86IntelInstPrinter.cpp
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86IntelInstPrinter.cpp
@@ -349,7 +349,7 @@ void X86IntelInstPrinter::printMemReference(const MCInst *MI, unsigned Op,
     uint64_t Target;
     if (MIA->evaluateBranch(*MI, 0, 0, Target))
       return;
-    if (MIA->evaluateMemoryOperandAddress(*MI, 0, 0))
+    if (MIA->evaluateMemoryOperandAddress(*MI, /*STI=*/nullptr, 0, 0))
       return;
   }
   const MCOperand &BaseReg  = MI->getOperand(Op+X86::AddrBaseReg);

diff  --git a/llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp
index 12dc053cd9705..7bd1f3678d51a 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp
@@ -405,6 +405,7 @@ class X86MCInstrAnalysis : public MCInstrAnalysis {
   bool evaluateBranch(const MCInst &Inst, uint64_t Addr, uint64_t Size,
                       uint64_t &Target) const override;
   Optional<uint64_t> evaluateMemoryOperandAddress(const MCInst &Inst,
+                                                  const MCSubtargetInfo *STI,
                                                   uint64_t Addr,
                                                   uint64_t Size) const override;
 };
@@ -532,7 +533,8 @@ bool X86MCInstrAnalysis::evaluateBranch(const MCInst &Inst, uint64_t Addr,
 }
 
 Optional<uint64_t> X86MCInstrAnalysis::evaluateMemoryOperandAddress(
-    const MCInst &Inst, uint64_t Addr, uint64_t Size) const {
+    const MCInst &Inst, const MCSubtargetInfo *STI, uint64_t Addr,
+    uint64_t Size) const {
   const MCInstrDesc &MCID = Info->get(Inst.getOpcode());
   int MemOpStart = X86II::getMemoryOperandNo(MCID.TSFlags);
   if (MemOpStart == -1)

diff  --git a/llvm/test/tools/llvm-objdump/ELF/ARM/literal-vldr-arm.s b/llvm/test/tools/llvm-objdump/ELF/ARM/literal-vldr-arm.s
new file mode 100644
index 0000000000000..cbc779ab451b1
--- /dev/null
+++ b/llvm/test/tools/llvm-objdump/ELF/ARM/literal-vldr-arm.s
@@ -0,0 +1,48 @@
+@@ Check that PC-relative memory addressing is annotated
+
+@ RUN: llvm-mc %s -triple=armv8a --mattr=+fullfp16 -filetype=obj | \
+@ RUN:   llvm-objdump -d --no-show-raw-insn --triple=armv8a --mattr=+fullfp16 - | \
+@ RUN:   FileCheck %s
+
+.text
+foo:
+@ CHECK:      00000000 <foo>:
+  .short 0x0102
+foo2:
+@ CHECK:      00000002 <foo2>:
+  .short 0x0304
+
+_start:
+@ CHECK:      00000004 <_start>:
+@@ Check AddrMode5 instructions, with positive and negative immediates
+  vldr d0, foo
+  vldr s0, bar
+@ CHECK-NEXT:    4: vldr    d0, [pc, #-12]          @ 0x0 <foo>
+@ CHECK-NEXT:    8: vldr    s0, [pc, #20]           @ 0x24 <bar>
+
+@@ Check that AddrMode5 instructions which do not use PC-relative addressing are
+@@ not annotated
+  vldr d0, [r1, #8]
+@ CHECK-NEXT:    c: vldr    d0, [r1, #8]{{$}}
+
+@@ Check AddrMode5FP16 instructions, with positive and negative immediates
+  vldr.16 s0, foo
+  vldr.16 s0, foo2
+  vldr.16 s1, bar
+  vldr.16 s1, bar2
+@ CHECK-NEXT:   10: vldr.16 s0, [pc, #-24]          @ 0x0 <foo>
+@ CHECK-NEXT:   14: vldr.16 s0, [pc, #-26]          @ 0x2 <foo2>
+@ CHECK-NEXT:   18: vldr.16 s1, [pc, #4]            @ 0x24 <bar>
+@ CHECK-NEXT:   1c: vldr.16 s1, [pc, #2]            @ 0x26 <bar2>
+
+@@ Check that AddrMode5FP16 instructions which do not use PC-relative addressing
+@@ are not annotated
+  vldr.16 s0, [r1, #8]
+@ CHECK-NEXT:   20: vldr.16 s0, [r1, #8]{{$}}
+
+bar:
+@ CHECK:      00000024 <bar>:
+  .short 0x0102
+bar2:
+@ CHECK:      00000026 <bar2>:
+  .short 0x0304

diff  --git a/llvm/test/tools/llvm-objdump/ELF/ARM/literal-vldr-thumb2.s b/llvm/test/tools/llvm-objdump/ELF/ARM/literal-vldr-thumb2.s
new file mode 100644
index 0000000000000..fe699170f76d8
--- /dev/null
+++ b/llvm/test/tools/llvm-objdump/ELF/ARM/literal-vldr-thumb2.s
@@ -0,0 +1,66 @@
+@@ Check that PC-relative memory addressing is annotated
+
+@ RUN: llvm-mc %s -triple=thumbv8a --mattr=+fullfp16 -filetype=obj | \
+@ RUN:   llvm-objdump -d --no-show-raw-insn --triple=thumbv8a --mattr=+fullfp16 - | \
+@ RUN:   FileCheck %s
+
+.text
+foo:
+@ CHECK:      00000000 <foo>:
+  .short 0x0102
+foo2:
+@ CHECK:      00000002 <foo2>:
+  .short 0x0304
+
+_start:
+@@ Check AddrMode5 instructions, with positive and negative immediates
+  .balign 4
+  vldr d0, foo
+  vldr s0, bar
+@ CHECK:         4: vldr      d0, [pc, #-8]           @ 0x0 <foo>
+@ CHECK-NEXT:    8: vldr      s0, [pc, #56]           @ 0x44 <bar>
+
+@@ Same instructions, but the addresses are not 4-byte aligned
+  nop
+  vldr d0, foo
+  vldr s0, bar
+@ CHECK:          e: vldr     d0, [pc, #-16]          @ 0x0 <foo>
+@ CHECK-NEXT:    12: vldr     s0, [pc, #48]           @ 0x44 <bar>
+
+@@ Check that AddrMode5 instructions which do not use PC-relative addressing are not annotated
+  vldr d0, [r1, #8]
+@ CHECK:         16: vldr     d0, [r1, #8]{{$}}
+
+@@ Check AddrMode5FP16 instructions, with positive and negative immediates
+  .balign 4
+  vldr.16 s0, foo
+  vldr.16 s0, foo2
+  vldr.16 s1, bar
+  vldr.16 s1, bar2
+@ CHECK:         1c: vldr.16  s0, [pc, #-32]          @ 0x0 <foo>
+@ CHECK-NEXT:    20: vldr.16  s0, [pc, #-34]          @ 0x2 <foo2>
+@ CHECK-NEXT:    24: vldr.16  s1, [pc, #28]           @ 0x44 <bar>
+@ CHECK-NEXT:    28: vldr.16  s1, [pc, #26]           @ 0x46 <bar2>
+
+@@ Same instructions, but the addresses are not 4-byte aligned
+  nop
+  vldr.16 s0, foo
+  vldr.16 s0, foo2
+  vldr.16 s1, bar
+  vldr.16 s1, bar2
+@ CHECK:         2e: vldr.16  s0, [pc, #-48]          @ 0x0 <foo>
+@ CHECK-NEXT:    32: vldr.16  s0, [pc, #-50]          @ 0x2 <foo2>
+@ CHECK-NEXT:    36: vldr.16  s1, [pc, #12]           @ 0x44 <bar>
+@ CHECK-NEXT:    3a: vldr.16  s1, [pc, #10]           @ 0x46 <bar2>
+
+@@ Check that AddrMode5FP16 instructions which do not use PC-relative addressing are not annotated
+  vldr.16 s0, [r1, #8]
+@ CHECK:         3e: vldr.16  s0, [r1, #8]{{$}}
+
+  .balign 4
+bar:
+@ CHECK:      00000044 <bar>:
+  .short 0x0102
+bar2:
+@ CHECK:      00000046 <bar2>:
+  .short 0x0304

diff  --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp
index 0e4f4024ca40d..a062957cc7430 100644
--- a/llvm/tools/llvm-objdump/llvm-objdump.cpp
+++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp
@@ -1480,7 +1480,7 @@ static void disassembleObject(const Target *TheTarget, const ObjectFile *Obj,
             if (!PrintTarget)
               if (Optional<uint64_t> MaybeTarget =
                       MIA->evaluateMemoryOperandAddress(
-                          Inst, SectionAddr + Index, Size)) {
+                          Inst, STI, SectionAddr + Index, Size)) {
                 Target = *MaybeTarget;
                 PrintTarget = true;
                 // Do not print real address when symbolizing.


        


More information about the llvm-commits mailing list