Răsfoiți Sursa

Fully fix the movw/movt addend.

The issue is not if the value is pcrel. It is whether we have a
relocation or not.

If we have a relocation, the static linker will select the upper
bits. If we don't have a relocation, we have to do it.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@307730 91177308-0d34-0410-b5e6-96231b3b80d8
Rafael Espindola 8 ani în urmă
părinte
comite
4aebf83110

+ 1 - 1
include/llvm/MC/MCAsmBackend.h

@@ -73,7 +73,7 @@ public:
   /// reported via \p Ctx.
   /// reported via \p Ctx.
   virtual void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
   virtual void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
                           const MCValue &Target, MutableArrayRef<char> Data,
                           const MCValue &Target, MutableArrayRef<char> Data,
-                          uint64_t Value, bool IsPCRel) const = 0;
+                          uint64_t Value, bool IsResolved) const = 0;
 
 
   /// @}
   /// @}
 
 

+ 6 - 5
lib/MC/MCAssembler.cpp

@@ -655,14 +655,15 @@ MCAssembler::handleFixup(const MCAsmLayout &Layout, MCFragment &F,
   uint64_t FixedValue;
   uint64_t FixedValue;
   bool IsPCRel = Backend.getFixupKindInfo(Fixup.getKind()).Flags &
   bool IsPCRel = Backend.getFixupKindInfo(Fixup.getKind()).Flags &
                  MCFixupKindInfo::FKF_IsPCRel;
                  MCFixupKindInfo::FKF_IsPCRel;
-  if (!evaluateFixup(Layout, Fixup, &F, Target, FixedValue)) {
+  bool IsResolved = evaluateFixup(Layout, Fixup, &F, Target, FixedValue);
+  if (!IsResolved) {
     // The fixup was unresolved, we need a relocation. Inform the object
     // The fixup was unresolved, we need a relocation. Inform the object
     // writer of the relocation, and give it an opportunity to adjust the
     // writer of the relocation, and give it an opportunity to adjust the
     // fixup value if need be.
     // fixup value if need be.
     getWriter().recordRelocation(*this, Layout, &F, Fixup, Target, IsPCRel,
     getWriter().recordRelocation(*this, Layout, &F, Fixup, Target, IsPCRel,
                                  FixedValue);
                                  FixedValue);
   }
   }
-  return std::make_tuple(Target, FixedValue, IsPCRel);
+  return std::make_tuple(Target, FixedValue, IsResolved);
 }
 }
 
 
 void MCAssembler::layout(MCAsmLayout &Layout) {
 void MCAssembler::layout(MCAsmLayout &Layout) {
@@ -738,12 +739,12 @@ void MCAssembler::layout(MCAsmLayout &Layout) {
         llvm_unreachable("Unknown fragment with fixups!");
         llvm_unreachable("Unknown fragment with fixups!");
       for (const MCFixup &Fixup : Fixups) {
       for (const MCFixup &Fixup : Fixups) {
         uint64_t FixedValue;
         uint64_t FixedValue;
-        bool IsPCRel;
+        bool IsResolved;
         MCValue Target;
         MCValue Target;
-        std::tie(Target, FixedValue, IsPCRel) =
+        std::tie(Target, FixedValue, IsResolved) =
             handleFixup(Layout, Frag, Fixup);
             handleFixup(Layout, Frag, Fixup);
         getBackend().applyFixup(*this, Fixup, Target, Contents, FixedValue,
         getBackend().applyFixup(*this, Fixup, Target, Contents, FixedValue,
-                                IsPCRel);
+                                IsResolved);
       }
       }
     }
     }
   }
   }

+ 2 - 2
lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp

@@ -73,7 +73,7 @@ public:
 
 
   void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
   void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
                   const MCValue &Target, MutableArrayRef<char> Data,
                   const MCValue &Target, MutableArrayRef<char> Data,
-                  uint64_t Value, bool IsPCRel) const override;
+                  uint64_t Value, bool IsResolved) const override;
 
 
   bool mayNeedRelaxation(const MCInst &Inst) const override;
   bool mayNeedRelaxation(const MCInst &Inst) const override;
   bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value,
   bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value,
@@ -264,7 +264,7 @@ unsigned AArch64AsmBackend::getFixupKindContainereSizeInBytes(unsigned Kind) con
 void AArch64AsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
 void AArch64AsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
                                    const MCValue &Target,
                                    const MCValue &Target,
                                    MutableArrayRef<char> Data, uint64_t Value,
                                    MutableArrayRef<char> Data, uint64_t Value,
-                                   bool IsPCRel) const {
+                                   bool IsResolved) const {
   unsigned NumBytes = getFixupKindNumBytes(Fixup.getKind());
   unsigned NumBytes = getFixupKindNumBytes(Fixup.getKind());
   if (!Value)
   if (!Value)
     return; // Doesn't change encoding.
     return; // Doesn't change encoding.

+ 2 - 2
lib/Target/AMDGPU/MCTargetDesc/AMDGPUAsmBackend.cpp

@@ -32,7 +32,7 @@ public:
 
 
   void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
   void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
                   const MCValue &Target, MutableArrayRef<char> Data,
                   const MCValue &Target, MutableArrayRef<char> Data,
-                  uint64_t Value, bool IsPCRel) const override;
+                  uint64_t Value, bool IsResolved) const override;
   bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value,
   bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value,
                             const MCRelaxableFragment *DF,
                             const MCRelaxableFragment *DF,
                             const MCAsmLayout &Layout) const override {
                             const MCAsmLayout &Layout) const override {
@@ -100,7 +100,7 @@ static uint64_t adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
 void AMDGPUAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
 void AMDGPUAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
                                   const MCValue &Target,
                                   const MCValue &Target,
                                   MutableArrayRef<char> Data, uint64_t Value,
                                   MutableArrayRef<char> Data, uint64_t Value,
-                                  bool IsPCRel) const {
+                                  bool IsResolved) const {
   Value = adjustFixupValue(Fixup, Value, &Asm.getContext());
   Value = adjustFixupValue(Fixup, Value, &Asm.getContext());
   if (!Value)
   if (!Value)
     return; // Doesn't change encoding.
     return; // Doesn't change encoding.

+ 7 - 8
lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp

@@ -361,9 +361,8 @@ static uint32_t joinHalfWords(uint32_t FirstHalf, uint32_t SecondHalf,
 unsigned ARMAsmBackend::adjustFixupValue(const MCAssembler &Asm,
 unsigned ARMAsmBackend::adjustFixupValue(const MCAssembler &Asm,
                                          const MCFixup &Fixup,
                                          const MCFixup &Fixup,
                                          const MCValue &Target, uint64_t Value,
                                          const MCValue &Target, uint64_t Value,
-                                         bool IsPCRel, MCContext &Ctx,
-                                         bool IsLittleEndian,
-                                         bool IsResolved) const {
+                                         bool IsResolved, MCContext &Ctx,
+                                         bool IsLittleEndian) const {
   unsigned Kind = Fixup.getKind();
   unsigned Kind = Fixup.getKind();
 
 
   // MachO tries to make .o files that look vaguely pre-linked, so for MOVW/MOVT
   // MachO tries to make .o files that look vaguely pre-linked, so for MOVW/MOVT
@@ -392,7 +391,7 @@ unsigned ARMAsmBackend::adjustFixupValue(const MCAssembler &Asm,
   case FK_SecRel_4:
   case FK_SecRel_4:
     return Value;
     return Value;
   case ARM::fixup_arm_movt_hi16:
   case ARM::fixup_arm_movt_hi16:
-    if (!IsPCRel && !STI->getTargetTriple().isOSBinFormatELF())
+    if (IsResolved || !STI->getTargetTriple().isOSBinFormatELF())
       Value >>= 16;
       Value >>= 16;
     LLVM_FALLTHROUGH;
     LLVM_FALLTHROUGH;
   case ARM::fixup_arm_movw_lo16: {
   case ARM::fixup_arm_movw_lo16: {
@@ -404,7 +403,7 @@ unsigned ARMAsmBackend::adjustFixupValue(const MCAssembler &Asm,
     return Value;
     return Value;
   }
   }
   case ARM::fixup_t2_movt_hi16:
   case ARM::fixup_t2_movt_hi16:
-    if (!IsPCRel && !STI->getTargetTriple().isOSBinFormatELF())
+    if (IsResolved || !STI->getTargetTriple().isOSBinFormatELF())
       Value >>= 16;
       Value >>= 16;
     LLVM_FALLTHROUGH;
     LLVM_FALLTHROUGH;
   case ARM::fixup_t2_movw_lo16: {
   case ARM::fixup_t2_movw_lo16: {
@@ -885,11 +884,11 @@ static unsigned getFixupKindContainerSizeBytes(unsigned Kind) {
 void ARMAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
 void ARMAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
                                const MCValue &Target,
                                const MCValue &Target,
                                MutableArrayRef<char> Data, uint64_t Value,
                                MutableArrayRef<char> Data, uint64_t Value,
-                               bool IsPCRel) const {
+                               bool IsResolved) const {
   unsigned NumBytes = getFixupKindNumBytes(Fixup.getKind());
   unsigned NumBytes = getFixupKindNumBytes(Fixup.getKind());
   MCContext &Ctx = Asm.getContext();
   MCContext &Ctx = Asm.getContext();
-  Value = adjustFixupValue(Asm, Fixup, Target, Value, IsPCRel, Ctx,
-                           IsLittleEndian, true);
+  Value = adjustFixupValue(Asm, Fixup, Target, Value, IsResolved, Ctx,
+                           IsLittleEndian);
   if (!Value)
   if (!Value)
     return; // Doesn't change encoding.
     return; // Doesn't change encoding.
 
 

+ 4 - 4
lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h

@@ -42,13 +42,13 @@ public:
                              const MCValue &Target) override;
                              const MCValue &Target) override;
 
 
   unsigned adjustFixupValue(const MCAssembler &Asm, const MCFixup &Fixup,
   unsigned adjustFixupValue(const MCAssembler &Asm, const MCFixup &Fixup,
-                            const MCValue &Target, uint64_t Value, bool IsPCRel,
-                            MCContext &Ctx, bool IsLittleEndian,
-                            bool IsResolved) const;
+                            const MCValue &Target, uint64_t Value,
+                            bool IsResolved, MCContext &Ctx,
+                            bool IsLittleEndian) const;
 
 
   void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
   void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
                   const MCValue &Target, MutableArrayRef<char> Data,
                   const MCValue &Target, MutableArrayRef<char> Data,
-                  uint64_t Value, bool IsPCRel) const override;
+                  uint64_t Value, bool IsResolved) const override;
 
 
   unsigned getRelaxedOpcode(unsigned Op) const;
   unsigned getRelaxedOpcode(unsigned Op) const;
 
 

+ 2 - 2
lib/Target/BPF/MCTargetDesc/BPFAsmBackend.cpp

@@ -29,7 +29,7 @@ public:
 
 
   void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
   void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
                   const MCValue &Target, MutableArrayRef<char> Data,
                   const MCValue &Target, MutableArrayRef<char> Data,
-                  uint64_t Value, bool IsPCRel) const override;
+                  uint64_t Value, bool IsResolved) const override;
 
 
   MCObjectWriter *createObjectWriter(raw_pwrite_stream &OS) const override;
   MCObjectWriter *createObjectWriter(raw_pwrite_stream &OS) const override;
 
 
@@ -65,7 +65,7 @@ bool BPFAsmBackend::writeNopData(uint64_t Count, MCObjectWriter *OW) const {
 void BPFAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
 void BPFAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
                                const MCValue &Target,
                                const MCValue &Target,
                                MutableArrayRef<char> Data, uint64_t Value,
                                MutableArrayRef<char> Data, uint64_t Value,
-                               bool IsPCRel) const {
+                               bool IsResolved) const {
   if (Fixup.getKind() == FK_SecRel_4 || Fixup.getKind() == FK_SecRel_8) {
   if (Fixup.getKind() == FK_SecRel_4 || Fixup.getKind() == FK_SecRel_8) {
     assert(Value == 0);
     assert(Value == 0);
   } else if (Fixup.getKind() == FK_Data_4 || Fixup.getKind() == FK_Data_8) {
   } else if (Fixup.getKind() == FK_Data_4 || Fixup.getKind() == FK_Data_8) {

+ 1 - 1
lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp

@@ -412,7 +412,7 @@ public:
   /// fixup kind as appropriate.
   /// fixup kind as appropriate.
   void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
   void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
                   const MCValue &Target, MutableArrayRef<char> Data,
                   const MCValue &Target, MutableArrayRef<char> Data,
-                  uint64_t FixupValue, bool IsPCRel) const override {
+                  uint64_t FixupValue, bool IsResolved) const override {
 
 
     // When FixupValue is 0 the relocation is external and there
     // When FixupValue is 0 the relocation is external and there
     // is nothing for us to do.
     // is nothing for us to do.

+ 2 - 2
lib/Target/Lanai/MCTargetDesc/LanaiAsmBackend.cpp

@@ -51,7 +51,7 @@ public:
 
 
   void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
   void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
                   const MCValue &Target, MutableArrayRef<char> Data,
                   const MCValue &Target, MutableArrayRef<char> Data,
-                  uint64_t Value, bool IsPCRel) const override;
+                  uint64_t Value, bool IsResolved) const override;
 
 
   MCObjectWriter *createObjectWriter(raw_pwrite_stream &OS) const override;
   MCObjectWriter *createObjectWriter(raw_pwrite_stream &OS) const override;
 
 
@@ -92,7 +92,7 @@ bool LanaiAsmBackend::writeNopData(uint64_t Count, MCObjectWriter *OW) const {
 void LanaiAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
 void LanaiAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
                                  const MCValue &Target,
                                  const MCValue &Target,
                                  MutableArrayRef<char> Data, uint64_t Value,
                                  MutableArrayRef<char> Data, uint64_t Value,
-                                 bool /*IsPCRel*/) const {
+                                 bool /*IsResolved*/) const {
   MCFixupKind Kind = Fixup.getKind();
   MCFixupKind Kind = Fixup.getKind();
   Value = adjustFixupValue(static_cast<unsigned>(Kind), Value);
   Value = adjustFixupValue(static_cast<unsigned>(Kind), Value);
 
 

+ 1 - 1
lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp

@@ -238,7 +238,7 @@ static unsigned calculateMMLEIndex(unsigned i) {
 void MipsAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
 void MipsAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
                                 const MCValue &Target,
                                 const MCValue &Target,
                                 MutableArrayRef<char> Data, uint64_t Value,
                                 MutableArrayRef<char> Data, uint64_t Value,
-                                bool IsPCRel) const {
+                                bool IsResolved) const {
   MCFixupKind Kind = Fixup.getKind();
   MCFixupKind Kind = Fixup.getKind();
   MCContext &Ctx = Asm.getContext();
   MCContext &Ctx = Asm.getContext();
   Value = adjustFixupValue(Fixup, Value, Ctx);
   Value = adjustFixupValue(Fixup, Value, Ctx);

+ 1 - 1
lib/Target/Mips/MCTargetDesc/MipsAsmBackend.h

@@ -40,7 +40,7 @@ public:
 
 
   void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
   void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
                   const MCValue &Target, MutableArrayRef<char> Data,
                   const MCValue &Target, MutableArrayRef<char> Data,
-                  uint64_t Value, bool IsPCRel) const override;
+                  uint64_t Value, bool IsResolved) const override;
 
 
   Optional<MCFixupKind> getFixupKind(StringRef Name) const override;
   Optional<MCFixupKind> getFixupKind(StringRef Name) const override;
   const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override;
   const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override;

+ 1 - 1
lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp

@@ -115,7 +115,7 @@ public:
 
 
   void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
   void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
                   const MCValue &Target, MutableArrayRef<char> Data,
                   const MCValue &Target, MutableArrayRef<char> Data,
-                  uint64_t Value, bool IsPCRel) const override {
+                  uint64_t Value, bool IsResolved) const override {
     Value = adjustFixupValue(Fixup.getKind(), Value);
     Value = adjustFixupValue(Fixup.getKind(), Value);
     if (!Value) return;           // Doesn't change encoding.
     if (!Value) return;           // Doesn't change encoding.
 
 

+ 2 - 2
lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp

@@ -34,7 +34,7 @@ public:
 
 
   void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
   void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
                   const MCValue &Target, MutableArrayRef<char> Data,
                   const MCValue &Target, MutableArrayRef<char> Data,
-                  uint64_t Value, bool IsPCRel) const override;
+                  uint64_t Value, bool IsResolved) const override;
 
 
   MCObjectWriter *createObjectWriter(raw_pwrite_stream &OS) const override;
   MCObjectWriter *createObjectWriter(raw_pwrite_stream &OS) const override;
 
 
@@ -73,7 +73,7 @@ bool RISCVAsmBackend::writeNopData(uint64_t Count, MCObjectWriter *OW) const {
 void RISCVAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
 void RISCVAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
                                  const MCValue &Target,
                                  const MCValue &Target,
                                  MutableArrayRef<char> Data, uint64_t Value,
                                  MutableArrayRef<char> Data, uint64_t Value,
-                                 bool IsPCRel) const {
+                                 bool IsResolved) const {
   return;
   return;
 }
 }
 
 

+ 1 - 1
lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp

@@ -276,7 +276,7 @@ namespace {
 
 
     void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
     void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
                     const MCValue &Target, MutableArrayRef<char> Data,
                     const MCValue &Target, MutableArrayRef<char> Data,
-                    uint64_t Value, bool IsPCRel) const override {
+                    uint64_t Value, bool IsResolved) const override {
 
 
       Value = adjustFixupValue(Fixup.getKind(), Value);
       Value = adjustFixupValue(Fixup.getKind(), Value);
       if (!Value) return;           // Doesn't change encoding.
       if (!Value) return;           // Doesn't change encoding.

+ 2 - 2
lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmBackend.cpp

@@ -52,7 +52,7 @@ public:
   const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override;
   const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override;
   void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
   void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
                   const MCValue &Target, MutableArrayRef<char> Data,
                   const MCValue &Target, MutableArrayRef<char> Data,
-                  uint64_t Value, bool IsPCRel) const override;
+                  uint64_t Value, bool IsResolved) const override;
   bool mayNeedRelaxation(const MCInst &Inst) const override {
   bool mayNeedRelaxation(const MCInst &Inst) const override {
     return false;
     return false;
   }
   }
@@ -94,7 +94,7 @@ void SystemZMCAsmBackend::applyFixup(const MCAssembler &Asm,
                                      const MCFixup &Fixup,
                                      const MCFixup &Fixup,
                                      const MCValue &Target,
                                      const MCValue &Target,
                                      MutableArrayRef<char> Data, uint64_t Value,
                                      MutableArrayRef<char> Data, uint64_t Value,
-                                     bool IsPCRel) const {
+                                     bool IsResolved) const {
   MCFixupKind Kind = Fixup.getKind();
   MCFixupKind Kind = Fixup.getKind();
   unsigned Offset = Fixup.getOffset();
   unsigned Offset = Fixup.getOffset();
   unsigned BitSize = getFixupKindInfo(Kind).TargetSize;
   unsigned BitSize = getFixupKindInfo(Kind).TargetSize;

+ 1 - 1
lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp

@@ -110,7 +110,7 @@ public:
 
 
   void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
   void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
                   const MCValue &Target, MutableArrayRef<char> Data,
                   const MCValue &Target, MutableArrayRef<char> Data,
-                  uint64_t Value, bool IsPCRel) const override {
+                  uint64_t Value, bool IsResolved) const override {
     unsigned Size = 1 << getFixupKindLog2Size(Fixup.getKind());
     unsigned Size = 1 << getFixupKindLog2Size(Fixup.getKind());
 
 
     assert(Fixup.getOffset() + Size <= Data.size() && "Invalid fixup offset!");
     assert(Fixup.getOffset() + Size <= Data.size() && "Invalid fixup offset!");

+ 12 - 1
test/MC/ARM/elf-movt.s

@@ -16,10 +16,17 @@ barf:                                   @ @barf
 .LPC0_2:
 .LPC0_2:
 	movw	r0, :lower16:extern_symbol+1234
 	movw	r0, :lower16:extern_symbol+1234
 	movt	r0, :upper16:extern_symbol+1234
 	movt	r0, :upper16:extern_symbol+1234
+
+	movw	r0, :lower16:(foo - bar + 1234)
+	movt	r0, :upper16:(foo - bar + 1234)
+foo:
+bar:
+
 @ ASM:          movw    r0, :lower16:(GOT-(.LPC0_2+8))
 @ ASM:          movw    r0, :lower16:(GOT-(.LPC0_2+8))
 @ ASM-NEXT:     movt    r0, :upper16:(GOT-(.LPC0_2+8))
 @ ASM-NEXT:     movt    r0, :upper16:(GOT-(.LPC0_2+8))
 @ ASM:          movw    r0, :lower16:(extern_symbol+1234)
 @ ASM:          movw    r0, :lower16:(extern_symbol+1234)
-@ ASM-NEXT:     movt    r0, :upper16:(extern_symbol+1234)
+@ ASM:          movw    r0, :lower16:((foo-bar)+1234)
+@ ASM-NEXT:     movt    r0, :upper16:((foo-bar)+1234)
 
 
 @OBJ:      Disassembly of section .text:
 @OBJ:      Disassembly of section .text:
 @OBJ-NEXT: barf:
 @OBJ-NEXT: barf:
@@ -31,6 +38,8 @@ barf:                                   @ @barf
 @OBJ-NEXT: 00000008:         R_ARM_MOVW_ABS_NC    extern_symbol
 @OBJ-NEXT: 00000008:         R_ARM_MOVW_ABS_NC    extern_symbol
 @OBJ-NEXT: c:             d2 04 40 e3     movt    r0, #1234
 @OBJ-NEXT: c:             d2 04 40 e3     movt    r0, #1234
 @OBJ-NEXT: 0000000c:         R_ARM_MOVT_ABS       extern_symbol
 @OBJ-NEXT: 0000000c:         R_ARM_MOVT_ABS       extern_symbol
+@OBJ-NEXT: 10:            d2 04 00 e3     movw    r0, #1234
+@OBJ-NEXT: 14:            00 00 40 e3     movt    r0, #0
 
 
 @THUMB:      Disassembly of section .text:
 @THUMB:      Disassembly of section .text:
 @THUMB-NEXT: barf:
 @THUMB-NEXT: barf:
@@ -42,3 +51,5 @@ barf:                                   @ @barf
 @THUMB-NEXT: 00000008:         R_ARM_THM_MOVW_ABS_NC  extern_symbol
 @THUMB-NEXT: 00000008:         R_ARM_THM_MOVW_ABS_NC  extern_symbol
 @THUMB-NEXT: c:             c0 f2 d2 40     movt    r0, #1234
 @THUMB-NEXT: c:             c0 f2 d2 40     movt    r0, #1234
 @THUMB-NEXT: 0000000c:         R_ARM_THM_MOVT_ABS     extern_symbol
 @THUMB-NEXT: 0000000c:         R_ARM_THM_MOVT_ABS     extern_symbol
+@THUMB-NEXT: 10:            40 f2 d2 40     movw    r0, #1234
+@THUMB-NEXT: 14:            c0 f2 00 00     movt    r0, #0