From 0fc8c68b11a05aa276a066922d3c076034f1e37a Mon Sep 17 00:00:00 2001 From: David Peixotto Date: Wed, 4 Dec 2013 22:43:20 +0000 Subject: 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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@196424 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/MC/MCAsmInfo.cpp | 1 + lib/MC/MCELFStreamer.cpp | 3 -- lib/MC/MCExpr.cpp | 44 ++++++++++------------ lib/MC/MCParser/AsmParser.cpp | 20 ++++++++-- lib/Target/ARM/ARMAsmPrinter.cpp | 10 ++--- lib/Target/ARM/ARMMCInstLower.cpp | 2 +- lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp | 16 ++++---- lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp | 3 ++ 8 files changed, 55 insertions(+), 44 deletions(-) (limited to 'lib') diff --git a/lib/MC/MCAsmInfo.cpp b/lib/MC/MCAsmInfo.cpp index 16506fe89e..4eaf6c2054 100644 --- a/lib/MC/MCAsmInfo.cpp +++ b/lib/MC/MCAsmInfo.cpp @@ -88,6 +88,7 @@ MCAsmInfo::MCAsmInfo() { DwarfRegNumForCFI = false; HasMicrosoftFastStdCallMangling = false; NeedsDwarfSectionOffsetDirective = false; + UseParensForSymbolVariant = false; } MCAsmInfo::~MCAsmInfo() { diff --git a/lib/MC/MCELFStreamer.cpp b/lib/MC/MCELFStreamer.cpp index e806cb9f1c..b601785948 100644 --- a/lib/MC/MCELFStreamer.cpp +++ b/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/lib/MC/MCExpr.cpp b/lib/MC/MCExpr.cpp index c777e648bd..69cdfa3544 100644 --- a/lib/MC/MCExpr.cpp +++ b/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/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp index a91bd93105..01fe87e0d6 100644 --- a/lib/MC/MCParser/AsmParser.cpp +++ b/lib/MC/MCParser/AsmParser.cpp @@ -789,20 +789,34 @@ bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) { return true; } } + // Parse symbol variant + std::pair 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 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; diff --git a/lib/Target/ARM/ARMAsmPrinter.cpp b/lib/Target/ARM/ARMAsmPrinter.cpp index 720c9b0111..8e28a98277 100644 --- a/lib/Target/ARM/ARMAsmPrinter.cpp +++ b/lib/Target/ARM/ARMAsmPrinter.cpp @@ -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!"); } diff --git a/lib/Target/ARM/ARMMCInstLower.cpp b/lib/Target/ARM/ARMMCInstLower.cpp index 1cc987ce99..c830627759 100644 --- a/lib/Target/ARM/ARMMCInstLower.cpp +++ b/lib/Target/ARM/ARMMCInstLower.cpp @@ -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; } diff --git a/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp b/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp index f98bbd204c..72ac6e22e8 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp @@ -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: diff --git a/lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp b/lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp index 714142123d..b2a71a8706 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp @@ -54,4 +54,7 @@ ARMELFMCAsmInfo::ARMELFMCAsmInfo() { // Exceptions handling if (EnableARMEHABI) ExceptionsType = ExceptionHandling::ARM; + + // foo(plt) instead of foo@plt + UseParensForSymbolVariant = true; } -- cgit v1.2.3