diff options
| author | David Peixotto <dpeixott@codeaurora.org> | 2013-12-04 22:43:20 +0000 |
|---|---|---|
| committer | David Peixotto <dpeixott@codeaurora.org> | 2013-12-04 22:43:20 +0000 |
| commit | 8ad70b3542ec7ac478d668724d1f9767170740c5 (patch) | |
| tree | 869bf60d950c61e4180d505583c88cd043002777 /llvm/lib/MC | |
| parent | bb9071ea8068557929f0b4c96678c725de38b3b6 (diff) | |
| download | bcm5719-llvm-8ad70b3542ec7ac478d668724d1f9767170740c5.tar.gz bcm5719-llvm-8ad70b3542ec7ac478d668724d1f9767170740c5.zip | |
Add support for parsing ARM symbol variants on ELF targets
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
llvm-svn: 196424
Diffstat (limited to 'llvm/lib/MC')
| -rw-r--r-- | llvm/lib/MC/MCAsmInfo.cpp | 1 | ||||
| -rw-r--r-- | llvm/lib/MC/MCELFStreamer.cpp | 3 | ||||
| -rw-r--r-- | llvm/lib/MC/MCExpr.cpp | 44 | ||||
| -rw-r--r-- | llvm/lib/MC/MCParser/AsmParser.cpp | 20 |
4 files changed, 38 insertions, 30 deletions
diff --git a/llvm/lib/MC/MCAsmInfo.cpp b/llvm/lib/MC/MCAsmInfo.cpp index 16506fe89e6..4eaf6c2054c 100644 --- a/llvm/lib/MC/MCAsmInfo.cpp +++ b/llvm/lib/MC/MCAsmInfo.cpp @@ -88,6 +88,7 @@ MCAsmInfo::MCAsmInfo() { DwarfRegNumForCFI = false; HasMicrosoftFastStdCallMangling = false; NeedsDwarfSectionOffsetDirective = false; + UseParensForSymbolVariant = false; } MCAsmInfo::~MCAsmInfo() { diff --git a/llvm/lib/MC/MCELFStreamer.cpp b/llvm/lib/MC/MCELFStreamer.cpp index e806cb9f1c9..b6017859480 100644 --- a/llvm/lib/MC/MCELFStreamer.cpp +++ b/llvm/lib/MC/MCELFStreamer.cpp @@ -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: diff --git a/llvm/lib/MC/MCExpr.cpp b/llvm/lib/MC/MCExpr.cpp index c777e648bdc..69cdfa35440 100644 --- a/llvm/lib/MC/MCExpr.cpp +++ b/llvm/lib/MC/MCExpr.cpp @@ -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); } diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp index a91bd93105b..01fe87e0d66 100644 --- a/llvm/lib/MC/MCParser/AsmParser.cpp +++ b/llvm/lib/MC/MCParser/AsmParser.cpp @@ -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; |

