Add support for parsing ARM symbol variants on ELF targets
authorDavid Peixotto <dpeixott@codeaurora.org>
Wed, 4 Dec 2013 22:43:20 +0000 (22:43 +0000)
committerDavid Peixotto <dpeixott@codeaurora.org>
Wed, 4 Dec 2013 22:43:20 +0000 (22:43 +0000)
ARM symbol variants are written with parens instead of @ like this:

  .word __GLOBAL_I_a(target1)

This commit adds support for parsing these symbol variants in
expressions. We introduce a new flag to MCAsmInfo that indicates the
parser should use parens to parse the symbol variant. The expression
parser is modified to look for symbol variants using parens instead
of @ when the corresponding MCAsmInfo flag is true.

The MCAsmInfo parens flag is enabled only for ARM on ELF.

By adding this flag to MCAsmInfo, we are able to get rid of
redundant ARM-specific symbol variants and use the generic variants
instead (e.g. VK_GOT instead of VK_ARM_GOT). We use the new
UseParensForSymbolVariant attribute in MCAsmInfo to correctly print
the symbol variants for arm.

To achive this we need to keep a handle to the MCAsmInfo in the
MCSymbolRefExpr class that we can check when printing the symbol
variant.

Updated Tests:
  Changed case of symbol variant to match the generic kind.
  test/CodeGen/ARM/tls-models.ll
  test/CodeGen/ARM/tls1.ll
  test/CodeGen/ARM/tls2.ll
  test/CodeGen/Thumb2/tls1.ll
  test/CodeGen/Thumb2/tls2.ll

PR18080

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@196424 91177308-0d34-0410-b5e6-96231b3b80d8

17 files changed:
include/llvm/MC/MCAsmInfo.h
include/llvm/MC/MCExpr.h
lib/MC/MCAsmInfo.cpp
lib/MC/MCELFStreamer.cpp
lib/MC/MCExpr.cpp
lib/MC/MCParser/AsmParser.cpp
lib/Target/ARM/ARMAsmPrinter.cpp
lib/Target/ARM/ARMMCInstLower.cpp
lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp
lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp
test/CodeGen/ARM/tls-models.ll
test/CodeGen/ARM/tls1.ll
test/CodeGen/ARM/tls2.ll
test/CodeGen/Thumb2/tls1.ll
test/CodeGen/Thumb2/tls2.ll
test/MC/ARM/symbol-variants-errors.s [new file with mode: 0644]
test/MC/ARM/symbol-variants.s [new file with mode: 0644]

index 8672b8dacfd9dc18c3797cf5cce60956055b5d01..f58a25d3319aa4b26c60d928353629fdda3be7a7 100644 (file)
@@ -306,6 +306,10 @@ namespace llvm {
     /// instead of symbolic register names in .cfi_* directives.
     bool DwarfRegNumForCFI;  // Defaults to false;
 
+    /// UseParensForSymbolVariant - True if target uses parens to indicate the
+    /// symbol variant instead of @. For example, foo(plt) instead of foo@plt.
+    bool UseParensForSymbolVariant; // Defaults to false;
+
     //===--- Prologue State ----------------------------------------------===//
 
     std::vector<MCCFIInstruction> InitialFrameState;
@@ -530,6 +534,9 @@ namespace llvm {
     bool useDwarfRegNumForCFI() const {
       return DwarfRegNumForCFI;
     }
+    bool useParensForSymbolVariant() const {
+      return UseParensForSymbolVariant;
+    }
 
     void addInitialFrameState(const MCCFIInstruction &Inst) {
       InitialFrameState.push_back(Inst);
index 5d559744da972181957e5c01a537c5543f1fb631..3052de112fac9d61667bce2b4bad1462f82682a5 100644 (file)
@@ -15,6 +15,7 @@
 #include "llvm/Support/DataTypes.h"
 
 namespace llvm {
+class MCAsmInfo;
 class MCAsmLayout;
 class MCAssembler;
 class MCContext;
@@ -159,14 +160,8 @@ public:
     VK_DTPOFF,
     VK_TLVP,      // Mach-O thread local variable relocation
     VK_SECREL,
-    // FIXME: We'd really like to use the generic Kinds listed above for these.
+
     VK_ARM_NONE,
-    VK_ARM_PLT,   // ARM-style PLT references. i.e., (PLT) instead of @PLT
-    VK_ARM_TLSGD, //   ditto for TLSGD, GOT, GOTOFF, TPOFF and GOTTPOFF
-    VK_ARM_GOT,
-    VK_ARM_GOTOFF,
-    VK_ARM_TPOFF,
-    VK_ARM_GOTTPOFF,
     VK_ARM_TARGET1,
     VK_ARM_TARGET2,
     VK_ARM_PREL31,
@@ -258,9 +253,14 @@ private:
   /// The symbol reference modifier.
   const VariantKind Kind;
 
-  explicit MCSymbolRefExpr(const MCSymbol *_Symbol, VariantKind _Kind)
-    : MCExpr(MCExpr::SymbolRef), Symbol(_Symbol), Kind(_Kind) {
+  /// MCAsmInfo that is used to print symbol variants correctly.
+  const MCAsmInfo *MAI;
+
+  explicit MCSymbolRefExpr(const MCSymbol *_Symbol, VariantKind _Kind,
+                           const MCAsmInfo *_MAI)
+    : MCExpr(MCExpr::SymbolRef), Symbol(_Symbol), Kind(_Kind), MAI(_MAI) {
     assert(Symbol);
+    assert(MAI);
   }
 
 public:
@@ -281,6 +281,7 @@ public:
   /// @{
 
   const MCSymbol &getSymbol() const { return *Symbol; }
+  const MCAsmInfo &getMCAsmInfo() const { return *MAI; }
 
   VariantKind getKind() const { return Kind; }
 
index 16506fe89e6bf4c5d9b24e6aa735088c85f3c4ee..4eaf6c2054cb76b8f958cba1244e98632a8051f5 100644 (file)
@@ -88,6 +88,7 @@ MCAsmInfo::MCAsmInfo() {
   DwarfRegNumForCFI = false;
   HasMicrosoftFastStdCallMangling = false;
   NeedsDwarfSectionOffsetDirective = false;
+  UseParensForSymbolVariant = false;
 }
 
 MCAsmInfo::~MCAsmInfo() {
index e806cb9f1c94de9e6fb1541cce6551135843da0e..b6017859480f9c546598ed28671c24854f2964fa 100644 (file)
@@ -371,9 +371,6 @@ void MCELFStreamer::fixSymbolsInTLSFixups(const MCExpr *expr) {
     case MCSymbolRefExpr::VK_TLSLDM:
     case MCSymbolRefExpr::VK_TPOFF:
     case MCSymbolRefExpr::VK_DTPOFF:
-    case MCSymbolRefExpr::VK_ARM_TLSGD:
-    case MCSymbolRefExpr::VK_ARM_TPOFF:
-    case MCSymbolRefExpr::VK_ARM_GOTTPOFF:
     case MCSymbolRefExpr::VK_Mips_TLSGD:
     case MCSymbolRefExpr::VK_Mips_GOTTPREL:
     case MCSymbolRefExpr::VK_Mips_TPREL_HI:
index c777e648bdc6d1ca25024cdb75c31fa23063677f..69cdfa354401b7bd9b1a01426ca662011acd7c2f 100644 (file)
@@ -11,6 +11,7 @@
 #include "llvm/MC/MCExpr.h"
 #include "llvm/ADT/Statistic.h"
 #include "llvm/ADT/StringSwitch.h"
+#include "llvm/MC/MCAsmInfo.h"
 #include "llvm/MC/MCAsmLayout.h"
 #include "llvm/MC/MCAssembler.h"
 #include "llvm/MC/MCContext.h"
@@ -47,19 +48,12 @@ void MCExpr::print(raw_ostream &OS) const {
     else
       OS << Sym;
 
-    if (SRE.getKind() == MCSymbolRefExpr::VK_ARM_NONE ||
-        SRE.getKind() == MCSymbolRefExpr::VK_ARM_PLT ||
-        SRE.getKind() == MCSymbolRefExpr::VK_ARM_TLSGD ||
-        SRE.getKind() == MCSymbolRefExpr::VK_ARM_GOT ||
-        SRE.getKind() == MCSymbolRefExpr::VK_ARM_GOTOFF ||
-        SRE.getKind() == MCSymbolRefExpr::VK_ARM_TPOFF ||
-        SRE.getKind() == MCSymbolRefExpr::VK_ARM_GOTTPOFF ||
-        SRE.getKind() == MCSymbolRefExpr::VK_ARM_TARGET1 ||
-        SRE.getKind() == MCSymbolRefExpr::VK_ARM_TARGET2 ||
-        SRE.getKind() == MCSymbolRefExpr::VK_ARM_PREL31)
-      OS << MCSymbolRefExpr::getVariantKindName(SRE.getKind());
-    else if (SRE.getKind() != MCSymbolRefExpr::VK_None)
-      OS << '@' << MCSymbolRefExpr::getVariantKindName(SRE.getKind());
+    if (SRE.getKind() != MCSymbolRefExpr::VK_None) {
+      if (SRE.getMCAsmInfo().useParensForSymbolVariant())
+        OS << '(' << MCSymbolRefExpr::getVariantKindName(SRE.getKind()) << ')';
+      else
+        OS << '@' << MCSymbolRefExpr::getVariantKindName(SRE.getKind());
+    }
 
     return;
   }
@@ -158,7 +152,7 @@ const MCConstantExpr *MCConstantExpr::Create(int64_t Value, MCContext &Ctx) {
 const MCSymbolRefExpr *MCSymbolRefExpr::Create(const MCSymbol *Sym,
                                                VariantKind Kind,
                                                MCContext &Ctx) {
-  return new (Ctx) MCSymbolRefExpr(Sym, Kind);
+  return new (Ctx) MCSymbolRefExpr(Sym, Kind, Ctx.getAsmInfo());
 }
 
 const MCSymbolRefExpr *MCSymbolRefExpr::Create(StringRef Name, VariantKind Kind,
@@ -186,16 +180,10 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) {
   case VK_DTPOFF: return "DTPOFF";
   case VK_TLVP: return "TLVP";
   case VK_SECREL: return "SECREL32";
-  case VK_ARM_NONE: return "(NONE)";
-  case VK_ARM_PLT: return "(PLT)";
-  case VK_ARM_GOT: return "(GOT)";
-  case VK_ARM_GOTOFF: return "(GOTOFF)";
-  case VK_ARM_TPOFF: return "(tpoff)";
-  case VK_ARM_GOTTPOFF: return "(gottpoff)";
-  case VK_ARM_TLSGD: return "(tlsgd)";
-  case VK_ARM_TARGET1: return "(target1)";
-  case VK_ARM_TARGET2: return "(target2)";
-  case VK_ARM_PREL31: return "(prel31)";
+  case VK_ARM_NONE: return "none";
+  case VK_ARM_TARGET1: return "target1";
+  case VK_ARM_TARGET2: return "target2";
+  case VK_ARM_PREL31: return "prel31";
   case VK_PPC_LO: return "l";
   case VK_PPC_HI: return "h";
   case VK_PPC_HA: return "ha";
@@ -409,6 +397,14 @@ MCSymbolRefExpr::getVariantKindForName(StringRef Name) {
     .Case("got@tlsld@h", VK_PPC_GOT_TLSLD_HI)
     .Case("GOT@TLSLD@HA", VK_PPC_GOT_TLSLD_HA)
     .Case("got@tlsld@ha", VK_PPC_GOT_TLSLD_HA)
+    .Case("NONE", VK_ARM_NONE)
+    .Case("none", VK_ARM_NONE)
+    .Case("TARGET1", VK_ARM_TARGET1)
+    .Case("target1", VK_ARM_TARGET1)
+    .Case("TARGET2", VK_ARM_TARGET2)
+    .Case("target2", VK_ARM_TARGET2)
+    .Case("PREL31", VK_ARM_PREL31)
+    .Case("prel31", VK_ARM_PREL31)
     .Default(VK_Invalid);
 }
 
index a91bd93105b653ad603efcb7aa324dbda6ddf46a..01fe87e0d66bbb7fd4ce67650b8ea2679a2d8c96 100644 (file)
@@ -789,20 +789,34 @@ bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
         return true;
       }
     }
+    // Parse symbol variant
+    std::pair<StringRef, StringRef> Split;
+    if (!MAI.useParensForSymbolVariant()) {
+      Split = Identifier.split('@');
+    } else if (Lexer.is(AsmToken::LParen)) {
+      Lexer.Lex(); // eat (
+      StringRef VName;
+      parseIdentifier(VName);
+      if (Lexer.isNot(AsmToken::RParen)) {
+          return Error(Lexer.getTok().getLoc(),
+                       "unexpected token in variant, expected ')'");
+      }
+      Lexer.Lex(); // eat )
+      Split = std::make_pair(Identifier, VName);
+    }
 
     EndLoc = SMLoc::getFromPointer(Identifier.end());
 
     // This is a symbol reference.
     StringRef SymbolName = Identifier;
     MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
-    std::pair<StringRef, StringRef> Split = Identifier.split('@');
 
     // Lookup the symbol variant if used.
-    if (Split.first.size() != Identifier.size()) {
+    if (Split.second.size()) {
       Variant = MCSymbolRefExpr::getVariantKindForName(Split.second);
       if (Variant != MCSymbolRefExpr::VK_Invalid) {
         SymbolName = Split.first;
-      } else if (MAI.doesAllowAtInName()) {
+      } else if (MAI.doesAllowAtInName() && !MAI.useParensForSymbolVariant()) {
         Variant = MCSymbolRefExpr::VK_None;
       } else {
         Variant = MCSymbolRefExpr::VK_None;
index 720c9b0111d915ebc0b665cabcf6cd17971dd0ac..8e28a98277d841976b54cfa7dbe8a1e0212c5afe 100644 (file)
@@ -756,11 +756,11 @@ static MCSymbolRefExpr::VariantKind
 getModifierVariantKind(ARMCP::ARMCPModifier Modifier) {
   switch (Modifier) {
   case ARMCP::no_modifier: return MCSymbolRefExpr::VK_None;
-  case ARMCP::TLSGD:       return MCSymbolRefExpr::VK_ARM_TLSGD;
-  case ARMCP::TPOFF:       return MCSymbolRefExpr::VK_ARM_TPOFF;
-  case ARMCP::GOTTPOFF:    return MCSymbolRefExpr::VK_ARM_GOTTPOFF;
-  case ARMCP::GOT:         return MCSymbolRefExpr::VK_ARM_GOT;
-  case ARMCP::GOTOFF:      return MCSymbolRefExpr::VK_ARM_GOTOFF;
+  case ARMCP::TLSGD:       return MCSymbolRefExpr::VK_TLSGD;
+  case ARMCP::TPOFF:       return MCSymbolRefExpr::VK_TPOFF;
+  case ARMCP::GOTTPOFF:    return MCSymbolRefExpr::VK_GOTTPOFF;
+  case ARMCP::GOT:         return MCSymbolRefExpr::VK_GOT;
+  case ARMCP::GOTOFF:      return MCSymbolRefExpr::VK_GOTOFF;
   }
   llvm_unreachable("Invalid ARMCPModifier!");
 }
index 1cc987ce99d1318a38f23be1495b457fcbe2ee7b..c83062775908737b749284482505b645350b448a 100644 (file)
@@ -50,7 +50,7 @@ MCOperand ARMAsmPrinter::GetSymbolRef(const MachineOperand &MO,
   }
 
   case ARMII::MO_PLT:
-    Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_ARM_PLT,
+    Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_PLT,
                                    OutContext);
     break;
   }
index f98bbd204c7a14aa8caa353d8d83534d0e5c43b1..72ac6e22e8dd149cc706f466563ffff17c8c6b1b 100644 (file)
@@ -166,9 +166,9 @@ unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target,
       case MCSymbolRefExpr::VK_None:
         Type = ELF::R_ARM_REL32;
         break;
-      case MCSymbolRefExpr::VK_ARM_TLSGD:
+      case MCSymbolRefExpr::VK_TLSGD:
         llvm_unreachable("unimplemented");
-      case MCSymbolRefExpr::VK_ARM_GOTTPOFF:
+      case MCSymbolRefExpr::VK_GOTTPOFF:
         Type = ELF::R_ARM_TLS_IE32;
         break;
       }
@@ -176,7 +176,7 @@ unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target,
     case ARM::fixup_arm_blx:
     case ARM::fixup_arm_uncondbl:
       switch (Modifier) {
-      case MCSymbolRefExpr::VK_ARM_PLT:
+      case MCSymbolRefExpr::VK_PLT:
         Type = ELF::R_ARM_PLT32;
         break;
       default:
@@ -223,22 +223,22 @@ unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target,
       case MCSymbolRefExpr::VK_ARM_NONE:
         Type = ELF::R_ARM_NONE;
         break;
-      case MCSymbolRefExpr::VK_ARM_GOT:
+      case MCSymbolRefExpr::VK_GOT:
         Type = ELF::R_ARM_GOT_BREL;
         break;
-      case MCSymbolRefExpr::VK_ARM_TLSGD:
+      case MCSymbolRefExpr::VK_TLSGD:
         Type = ELF::R_ARM_TLS_GD32;
         break;
-      case MCSymbolRefExpr::VK_ARM_TPOFF:
+      case MCSymbolRefExpr::VK_TPOFF:
         Type = ELF::R_ARM_TLS_LE32;
         break;
-      case MCSymbolRefExpr::VK_ARM_GOTTPOFF:
+      case MCSymbolRefExpr::VK_GOTTPOFF:
         Type = ELF::R_ARM_TLS_IE32;
         break;
       case MCSymbolRefExpr::VK_None:
         Type = ELF::R_ARM_ABS32;
         break;
-      case MCSymbolRefExpr::VK_ARM_GOTOFF:
+      case MCSymbolRefExpr::VK_GOTOFF:
         Type = ELF::R_ARM_GOTOFF32;
         break;
       case MCSymbolRefExpr::VK_ARM_TARGET1:
index 714142123d94907c78e300fa20f77d4bf3ff715a..b2a71a87061a92516a119b977dce117f7e43c4e5 100644 (file)
@@ -54,4 +54,7 @@ ARMELFMCAsmInfo::ARMELFMCAsmInfo() {
   // Exceptions handling
   if (EnableARMEHABI)
     ExceptionsType = ExceptionHandling::ARM;
+
+  // foo(plt) instead of foo@plt
+  UseParensForSymbolVariant = true;
 }
index ccc9032313b8b9a0b8110c046b4a465ce39c39b2..42c1ba9110288f06f359307945865a2666e156ad 100644 (file)
@@ -22,9 +22,9 @@ entry:
 
   ; Non-PIC code can use initial-exec, PIC code has to use general dynamic.
   ; CHECK-NONPIC-LABEL:   f1:
-  ; CHECK-NONPIC:   external_gd(gottpoff)
+  ; CHECK-NONPIC:   external_gd(GOTTPOFF)
   ; CHECK-PIC-LABEL:      f1:
-  ; CHECK-PIC:      external_gd(tlsgd)
+  ; CHECK-PIC:      external_gd(TLSGD)
 }
 
 define i32* @f2() {
@@ -34,9 +34,9 @@ entry:
   ; Non-PIC code can use local exec, PIC code can use local dynamic,
   ; but that is not implemented, so falls back to general dynamic.
   ; CHECK-NONPIC-LABEL:   f2:
-  ; CHECK-NONPIC:   internal_gd(tpoff)
+  ; CHECK-NONPIC:   internal_gd(TPOFF)
   ; CHECK-PIC-LABEL:      f2:
-  ; CHECK-PIC:      internal_gd(tlsgd)
+  ; CHECK-PIC:      internal_gd(TLSGD)
 }
 
 
@@ -49,9 +49,9 @@ entry:
   ; Non-PIC code can use initial exec, PIC should use local dynamic,
   ; but that is not implemented, so falls back to general dynamic.
   ; CHECK-NONPIC-LABEL:   f3:
-  ; CHECK-NONPIC:   external_ld(gottpoff)
+  ; CHECK-NONPIC:   external_ld(GOTTPOFF)
   ; CHECK-PIC-LABEL:      f3:
-  ; CHECK-PIC:      external_ld(tlsgd)
+  ; CHECK-PIC:      external_ld(TLSGD)
 }
 
 define i32* @f4() {
@@ -61,9 +61,9 @@ entry:
   ; Non-PIC code can use local exec, PIC code can use local dynamic,
   ; but that is not implemented, so it falls back to general dynamic.
   ; CHECK-NONPIC-LABEL:   f4:
-  ; CHECK-NONPIC:   internal_ld(tpoff)
+  ; CHECK-NONPIC:   internal_ld(TPOFF)
   ; CHECK-PIC-LABEL:      f4:
-  ; CHECK-PIC:      internal_ld(tlsgd)
+  ; CHECK-PIC:      internal_ld(TLSGD)
 }
 
 
@@ -75,9 +75,9 @@ entry:
 
   ; Non-PIC and PIC code will use initial exec as specified.
   ; CHECK-NONPIC-LABEL:   f5:
-  ; CHECK-NONPIC:   external_ie(gottpoff)
+  ; CHECK-NONPIC:   external_ie(GOTTPOFF)
   ; CHECK-PIC-LABEL:      f5:
-  ; CHECK-PIC:      external_ie(gottpoff)
+  ; CHECK-PIC:      external_ie(GOTTPOFF)
 }
 
 define i32* @f6() {
@@ -86,9 +86,9 @@ entry:
 
   ; Non-PIC code can use local exec, PIC code use initial exec as specified.
   ; CHECK-NONPIC-LABEL:   f6:
-  ; CHECK-NONPIC:   internal_ie(tpoff)
+  ; CHECK-NONPIC:   internal_ie(TPOFF)
   ; CHECK-PIC-LABEL:      f6:
-  ; CHECK-PIC:      internal_ie(gottpoff)
+  ; CHECK-PIC:      internal_ie(GOTTPOFF)
 }
 
 
@@ -100,9 +100,9 @@ entry:
 
   ; Non-PIC and PIC code will use local exec as specified.
   ; CHECK-NONPIC-LABEL:   f7:
-  ; CHECK-NONPIC:   external_le(tpoff)
+  ; CHECK-NONPIC:   external_le(TPOFF)
   ; CHECK-PIC-LABEL:      f7:
-  ; CHECK-PIC:      external_le(tpoff)
+  ; CHECK-PIC:      external_le(TPOFF)
 }
 
 define i32* @f8() {
@@ -111,7 +111,7 @@ entry:
 
   ; Non-PIC and PIC code will use local exec as specified.
   ; CHECK-NONPIC-LABEL:   f8:
-  ; CHECK-NONPIC:   internal_le(tpoff)
+  ; CHECK-NONPIC:   internal_le(TPOFF)
   ; CHECK-PIC-LABEL:      f8:
-  ; CHECK-PIC:      internal_le(tpoff)
+  ; CHECK-PIC:      internal_le(TPOFF)
 }
index ec4278ce72f6b9abac69756398c9f449411920be..a1ca0b758b452f0a2358f30ca320a656b1397270 100644 (file)
@@ -1,5 +1,5 @@
 ; RUN: llc < %s -march=arm -mtriple=arm-linux-gnueabi | \
-; RUN:     grep "i(tpoff)"
+; RUN:     grep "i(TPOFF)"
 ; RUN: llc < %s -march=arm -mtriple=arm-linux-gnueabi | \
 ; RUN:     grep "__aeabi_read_tp"
 ; RUN: llc < %s -march=arm -mtriple=arm-linux-gnueabi \
index f048125831143c4802d7d64782db00558bbb2e86..24b4794b061a2622677582a2d8d8931aa974b570 100644 (file)
@@ -8,7 +8,7 @@
 define i32 @f() {
 ; CHECK-NONPIC-LABEL: f:
 ; CHECK-NONPIC: ldr {{r.}}, [pc, {{r.}}]
-; CHECK-NONPIC: i(gottpoff)
+; CHECK-NONPIC: i(GOTTPOFF)
 ; CHECK-PIC-LABEL: f:
 ; CHECK-PIC: __tls_get_addr
 entry:
@@ -19,7 +19,7 @@ entry:
 define i32* @g() {
 ; CHECK-NONPIC-LABEL: g:
 ; CHECK-NONPIC: ldr {{r.}}, [pc, {{r.}}]
-; CHECK-NONPIC: i(gottpoff)
+; CHECK-NONPIC: i(GOTTPOFF)
 ; CHECK-PIC-LABEL: g:
 ; CHECK-PIC: __tls_get_addr
 entry:
index d91e3b32f9b7abb62ffe2f48eafbb37152160ac7..40973562d2b9aa077e60d60f43cc6176ebbba3c6 100644 (file)
@@ -1,5 +1,5 @@
 ; RUN: llc < %s -mtriple=thumbv7-linux-gnueabi | \
-; RUN:     grep "i(tpoff)"
+; RUN:     grep "i(TPOFF)"
 ; RUN: llc < %s -mtriple=thumbv7-linux-gnueabi | \
 ; RUN:     grep "__aeabi_read_tp"
 ; RUN: llc < %s -mtriple=thumbv7-linux-gnueabi \
index 6cb019ff00ec28ec5f012170f2c783fa4ade3f06..e6bed2f65a492074995148321bac971cbe32eb4b 100644 (file)
@@ -8,7 +8,7 @@ entry:
 ; CHECK-NOT-PIC-LABEL: f:
 ; CHECK-NOT-PIC: add r0, pc
 ; CHECK-NOT-PIC: ldr r1, [r0]
-; CHECK-NOT-PIC: i(gottpoff)
+; CHECK-NOT-PIC: i(GOTTPOFF)
 
 ; CHECK-PIC-LABEL: f:
 ; CHECK-PIC: bl __tls_get_addr(PLT)
@@ -21,7 +21,7 @@ entry:
 ; CHECK-NOT-PIC-LABEL: g:
 ; CHECK-NOT-PIC: add r0, pc
 ; CHECK-NOT-PIC: ldr r1, [r0]
-; CHECK-NOT-PIC: i(gottpoff)
+; CHECK-NOT-PIC: i(GOTTPOFF)
 
 ; CHECK-PIC-LABEL: g:
 ; CHECK-PIC: bl __tls_get_addr(PLT)
diff --git a/test/MC/ARM/symbol-variants-errors.s b/test/MC/ARM/symbol-variants-errors.s
new file mode 100644 (file)
index 0000000..03401cd
--- /dev/null
@@ -0,0 +1,23 @@
+@ RUN: not llvm-mc < %s -triple armv7-none-linux-gnueabi 2>&1 | FileCheck %s
+
+@ check for invalid variant
+f1:
+  bl bar(blargh)
+@CHECK: error: invalid variant 'blargh'
+@CHECK:  bl bar(blargh)
+@CHECK:                ^
+
+@ check for missing closed paren
+f2:
+  .word bar(got
+@CHECK: error: unexpected token in variant, expected ')'
+@CHECK:  .word bar(got
+@CHECK:               ^
+
+@ check for invalid symbol before variant end
+f3:
+  .word bar(got+2)
+
+@CHECK: error: unexpected token in variant, expected ')'
+@CHECK:  .word bar(got+2)
+@CHECK:               ^
diff --git a/test/MC/ARM/symbol-variants.s b/test/MC/ARM/symbol-variants.s
new file mode 100644 (file)
index 0000000..d24d5c7
--- /dev/null
@@ -0,0 +1,67 @@
+@ RUN: llvm-mc < %s -triple armv7-none-linux-gnueabi -filetype=obj  | llvm-objdump -triple armv7-none-linux-gnueabi -r - | FileCheck %s --check-prefix=CHECK --check-prefix=ARM
+@ RUN: llvm-mc < %s -triple thumbv7-none-linux-gnueabi -filetype=obj  | llvm-objdump -triple thumbv7-none-linux-gnueabi -r - | FileCheck %s --check-prefix=CHECK --check-prefix=THUMB
+
+@ CHECK-LABEL: RELOCATION RECORDS FOR [.rel.text]
+
+@ empty
+.word f00
+.word f01
+@CHECK: 0 R_ARM_ABS32 f00
+@CHECK: 4 R_ARM_ABS32 f01
+
+@ none
+.word f02(NONE)
+.word f03(none)
+@CHECK: 8 R_ARM_NONE f02
+@CHECK: 12 R_ARM_NONE f03
+
+@ plt
+bl f04(PLT)
+bl f05(plt)
+@ARM: 16 R_ARM_PLT32 f04
+@ARM: 20 R_ARM_PLT32 f05
+@THUMB: 16 R_ARM_THM_CALL f04
+@THUMB: 20 R_ARM_THM_CALL f05
+
+@ got
+.word f06(GOT)
+.word f07(got)
+@CHECK: 24 R_ARM_GOT_BREL f06
+@CHECK: 28 R_ARM_GOT_BREL f07
+
+@ gotoff
+.word f08(GOTOFF)
+.word f09(gotoff)
+@CHECK: 32 R_ARM_GOTOFF32 f08
+@CHECK: 36 R_ARM_GOTOFF32 f09
+
+@ tpoff
+.word f10(TPOFF)
+.word f11(tpoff)
+@CHECK: 40 R_ARM_TLS_LE32 f10
+@CHECK: 44 R_ARM_TLS_LE32 f11
+
+@ tlsgd
+.word f12(TLSGD)
+.word f13(tlsgd)
+@CHECK: 48 R_ARM_TLS_GD32 f12
+@CHECK: 52 R_ARM_TLS_GD32 f13
+
+@ target1
+.word f14(TARGET1)
+.word f15(target1)
+@CHECK: 56 R_ARM_TARGET1 f14
+@CHECK: 60 R_ARM_TARGET1 f15
+
+@ target2
+.word f16(TARGET2)
+.word f17(target2)
+@CHECK: 64 R_ARM_TARGET2 f16
+@CHECK: 68 R_ARM_TARGET2 f17
+
+@ prel31
+.word f18(PREL31)
+.word f19(prel31)
+@CHECK: 72 R_ARM_PREL31 f18
+@CHECK: 76 R_ARM_PREL31 f19
+