From 4e815f8a8cae6c846cdca52420046cab902865de Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Mon, 15 Mar 2010 23:51:06 +0000 Subject: [PATCH] MC: Allow modifiers in MCSymbolRefExpr, and eliminate X86MCTargetExpr. - Although it would be nice to allow this decoupling, the assembler needs to be able to reason about MCSymbolRefExprs in too many places to make this viable. We can use a target specific encoding of the variant if this becomes an issue. - This patch also extends llvm-mc to support parsing of the modifiers, as opposed to lumping them in with the symbol. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@98592 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/MC/MCExpr.h | 48 +++++++++++++++-- lib/MC/MCExpr.cpp | 56 ++++++++++++++++++-- lib/MC/MCParser/AsmParser.cpp | 14 ++++- lib/Target/X86/AsmPrinter/X86MCInstLower.cpp | 29 +++++----- lib/Target/X86/CMakeLists.txt | 1 - lib/Target/X86/X86ISelLowering.cpp | 6 +-- lib/Target/X86/X86MCTargetExpr.cpp | 49 ----------------- lib/Target/X86/X86MCTargetExpr.h | 49 ----------------- lib/Target/X86/X86TargetObjectFile.cpp | 4 +- test/CodeGen/X86/personality.ll | 2 +- 10 files changed, 124 insertions(+), 134 deletions(-) delete mode 100644 lib/Target/X86/X86MCTargetExpr.cpp delete mode 100644 lib/Target/X86/X86MCTargetExpr.h diff --git a/include/llvm/MC/MCExpr.h b/include/llvm/MC/MCExpr.h index 5f8163f19e4..6efec52751c 100644 --- a/include/llvm/MC/MCExpr.h +++ b/include/llvm/MC/MCExpr.h @@ -121,21 +121,49 @@ public: /// assembler variable (defined constant), or constitute an implicit definition /// of the symbol as external. class MCSymbolRefExpr : public MCExpr { +public: + enum VariantKind { + VK_None, + VK_Invalid, + + VK_GOT, + VK_GOTOFF, + VK_GOTPCREL, + VK_GOTTPOFF, + VK_INDNTPOFF, + VK_NTPOFF, + VK_PLT, + VK_TLSGD, + VK_TPOFF + }; + +private: + /// The symbol being referenced. const MCSymbol *Symbol; - explicit MCSymbolRefExpr(const MCSymbol *_Symbol) - : MCExpr(MCExpr::SymbolRef), Symbol(_Symbol) {} + /// The symbol reference modifier. + const VariantKind Kind; + + explicit MCSymbolRefExpr(const MCSymbol *_Symbol, VariantKind _Kind) + : MCExpr(MCExpr::SymbolRef), Symbol(_Symbol), Kind(_Kind) {} public: /// @name Construction /// @{ - static const MCSymbolRefExpr *Create(const MCSymbol *Symbol, MCContext &Ctx); - static const MCSymbolRefExpr *Create(StringRef Name, MCContext &Ctx); + static const MCSymbolRefExpr *Create(const MCSymbol *Symbol, MCContext &Ctx) { + return MCSymbolRefExpr::Create(Symbol, VK_None, Ctx); + } + + static const MCSymbolRefExpr *Create(const MCSymbol *Symbol, VariantKind Kind, + MCContext &Ctx); + static const MCSymbolRefExpr *Create(StringRef Name, VariantKind Kind, + MCContext &Ctx); /// CreateTemp - Create a reference to an assembler temporary label with the /// specified name. - static const MCSymbolRefExpr *CreateTemp(StringRef Name, MCContext &Ctx); + static const MCSymbolRefExpr *CreateTemp(StringRef Name, VariantKind Kind, + MCContext &Ctx); /// @} /// @name Accessors @@ -143,6 +171,16 @@ public: const MCSymbol &getSymbol() const { return *Symbol; } + VariantKind getKind() const { return Kind; } + + /// @} + /// @name Static Utility Functions + /// @{ + + static StringRef getVariantKindName(VariantKind Kind); + + static VariantKind getVariantKindForName(StringRef Name); + /// @} static bool classof(const MCExpr *E) { diff --git a/lib/MC/MCExpr.cpp b/lib/MC/MCExpr.cpp index 3bd6b1b6950..a2ed20bb28c 100644 --- a/lib/MC/MCExpr.cpp +++ b/lib/MC/MCExpr.cpp @@ -8,6 +8,7 @@ //===----------------------------------------------------------------------===// #include "llvm/MC/MCExpr.h" +#include "llvm/ADT/StringSwitch.h" #include "llvm/MC/MCAsmLayout.h" #include "llvm/MC/MCAssembler.h" #include "llvm/MC/MCContext.h" @@ -27,7 +28,8 @@ void MCExpr::print(raw_ostream &OS) const { return; case MCExpr::SymbolRef: { - const MCSymbol &Sym = cast(*this).getSymbol(); + const MCSymbolRefExpr &SRE = cast(*this); + const MCSymbol &Sym = SRE.getSymbol(); // Parenthesize names that start with $ so that they don't look like // absolute names. @@ -35,6 +37,10 @@ void MCExpr::print(raw_ostream &OS) const { OS << '(' << Sym << ')'; else OS << Sym; + + if (SRE.getKind() != MCSymbolRefExpr::VK_None) + OS << '@' << MCSymbolRefExpr::getVariantKindName(SRE.getKind()); + return; } @@ -127,20 +133,60 @@ const MCConstantExpr *MCConstantExpr::Create(int64_t Value, MCContext &Ctx) { return new (Ctx) MCConstantExpr(Value); } +/* *** */ + const MCSymbolRefExpr *MCSymbolRefExpr::Create(const MCSymbol *Sym, + VariantKind Kind, MCContext &Ctx) { - return new (Ctx) MCSymbolRefExpr(Sym); + return new (Ctx) MCSymbolRefExpr(Sym, Kind); } -const MCSymbolRefExpr *MCSymbolRefExpr::Create(StringRef Name, MCContext &Ctx) { - return Create(Ctx.GetOrCreateSymbol(Name), Ctx); +const MCSymbolRefExpr *MCSymbolRefExpr::Create(StringRef Name, VariantKind Kind, + MCContext &Ctx) { + return Create(Ctx.GetOrCreateSymbol(Name), Kind, Ctx); } const MCSymbolRefExpr *MCSymbolRefExpr::CreateTemp(StringRef Name, + VariantKind Kind, MCContext &Ctx) { - return Create(Ctx.GetOrCreateTemporarySymbol(Name), Ctx); + return Create(Ctx.GetOrCreateTemporarySymbol(Name), Kind, Ctx); +} + +StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) { + switch (Kind) { + default: + case VK_Invalid: return "<>"; + case VK_None: return "<>"; + + case VK_GOT: return "GOT"; + case VK_GOTOFF: return "GOTOFF"; + case VK_GOTPCREL: return "GOTPCREL"; + case VK_GOTTPOFF: return "GOTTPOFF"; + case VK_INDNTPOFF: return "INDNTPOFF"; + case VK_NTPOFF: return "NTPOFF"; + case VK_PLT: return "PLT"; + case VK_TLSGD: return "TLSGD"; + case VK_TPOFF: return "TPOFF"; + } +} + +MCSymbolRefExpr::VariantKind +MCSymbolRefExpr::getVariantKindForName(StringRef Name) { + return StringSwitch(Name) + .Case("GOT", VK_GOT) + .Case("GOTOFF", VK_GOTOFF) + .Case("GOTPCREL", VK_GOTPCREL) + .Case("GOTTPOFF", VK_GOTTPOFF) + .Case("INDNTPOFF", VK_INDNTPOFF) + .Case("NTPOFF", VK_NTPOFF) + .Case("PLT", VK_PLT) + .Case("TLSGD", VK_TLSGD) + .Case("TPOFF", VK_TPOFF) + .Default(VK_Invalid); } +/* *** */ + void MCTargetExpr::Anchor() {} /* *** */ diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp index a241106465a..4ec5247d62e 100644 --- a/lib/MC/MCParser/AsmParser.cpp +++ b/lib/MC/MCParser/AsmParser.cpp @@ -262,19 +262,29 @@ bool AsmParser::ParsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) { case AsmToken::String: case AsmToken::Identifier: { // This is a symbol reference. - MCSymbol *Sym = CreateSymbol(getTok().getIdentifier()); + std::pair Split = getTok().getIdentifier().split('@'); + MCSymbol *Sym = CreateSymbol(Split.first); + + // Lookup the symbol variant if used. + MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None; + if (Split.first.size() != getTok().getIdentifier().size()) + Variant = MCSymbolRefExpr::getVariantKindForName(Split.second); + EndLoc = Lexer.getLoc(); Lex(); // Eat identifier. // If this is an absolute variable reference, substitute it now to preserve // semantics in the face of reassignment. if (Sym->getValue() && isa(Sym->getValue())) { + if (Variant) + return Error(EndLoc, "unexpected modified on variable reference"); + Res = Sym->getValue(); return false; } // Otherwise create a symbol ref. - Res = MCSymbolRefExpr::Create(Sym, getContext()); + Res = MCSymbolRefExpr::Create(Sym, Variant, getContext()); return false; } case AsmToken::Integer: diff --git a/lib/Target/X86/AsmPrinter/X86MCInstLower.cpp b/lib/Target/X86/AsmPrinter/X86MCInstLower.cpp index a90dfa3cda9..cbfc57a0ab7 100644 --- a/lib/Target/X86/AsmPrinter/X86MCInstLower.cpp +++ b/lib/Target/X86/AsmPrinter/X86MCInstLower.cpp @@ -16,7 +16,6 @@ #include "X86AsmPrinter.h" #include "X86COFFMachineModuleInfo.h" #include "X86MCAsmInfo.h" -#include "X86MCTargetExpr.h" #include "llvm/Analysis/DebugInfo.h" #include "llvm/CodeGen/MachineModuleInfoImpls.h" #include "llvm/MC/MCContext.h" @@ -142,7 +141,7 @@ MCOperand X86MCInstLower::LowerSymbolOperand(const MachineOperand &MO, // FIXME: We would like an efficient form for this, so we don't have to do a // lot of extra uniquing. const MCExpr *Expr = 0; - X86MCTargetExpr::VariantKind RefKind = X86MCTargetExpr::Invalid; + MCSymbolRefExpr::VariantKind RefKind = MCSymbolRefExpr::VK_None; switch (MO.getTargetFlags()) { default: llvm_unreachable("Unknown target flag on GV operand"); @@ -153,15 +152,15 @@ MCOperand X86MCInstLower::LowerSymbolOperand(const MachineOperand &MO, case X86II::MO_DARWIN_STUB: break; - case X86II::MO_TLSGD: RefKind = X86MCTargetExpr::TLSGD; break; - case X86II::MO_GOTTPOFF: RefKind = X86MCTargetExpr::GOTTPOFF; break; - case X86II::MO_INDNTPOFF: RefKind = X86MCTargetExpr::INDNTPOFF; break; - case X86II::MO_TPOFF: RefKind = X86MCTargetExpr::TPOFF; break; - case X86II::MO_NTPOFF: RefKind = X86MCTargetExpr::NTPOFF; break; - case X86II::MO_GOTPCREL: RefKind = X86MCTargetExpr::GOTPCREL; break; - case X86II::MO_GOT: RefKind = X86MCTargetExpr::GOT; break; - case X86II::MO_GOTOFF: RefKind = X86MCTargetExpr::GOTOFF; break; - case X86II::MO_PLT: RefKind = X86MCTargetExpr::PLT; break; + case X86II::MO_TLSGD: RefKind = MCSymbolRefExpr::VK_TLSGD; break; + case X86II::MO_GOTTPOFF: RefKind = MCSymbolRefExpr::VK_GOTTPOFF; break; + case X86II::MO_INDNTPOFF: RefKind = MCSymbolRefExpr::VK_INDNTPOFF; break; + case X86II::MO_TPOFF: RefKind = MCSymbolRefExpr::VK_TPOFF; break; + case X86II::MO_NTPOFF: RefKind = MCSymbolRefExpr::VK_NTPOFF; break; + case X86II::MO_GOTPCREL: RefKind = MCSymbolRefExpr::VK_GOTPCREL; break; + case X86II::MO_GOT: RefKind = MCSymbolRefExpr::VK_GOT; break; + case X86II::MO_GOTOFF: RefKind = MCSymbolRefExpr::VK_GOTOFF; break; + case X86II::MO_PLT: RefKind = MCSymbolRefExpr::VK_PLT; break; case X86II::MO_PIC_BASE_OFFSET: case X86II::MO_DARWIN_NONLAZY_PIC_BASE: case X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE: @@ -173,12 +172,8 @@ MCOperand X86MCInstLower::LowerSymbolOperand(const MachineOperand &MO, break; } - if (Expr == 0) { - if (RefKind == X86MCTargetExpr::Invalid) - Expr = MCSymbolRefExpr::Create(Sym, Ctx); - else - Expr = X86MCTargetExpr::Create(Sym, RefKind, Ctx); - } + if (Expr == 0) + Expr = MCSymbolRefExpr::Create(Sym, RefKind, Ctx); if (!MO.isJTI() && MO.getOffset()) Expr = MCBinaryExpr::CreateAdd(Expr, diff --git a/lib/Target/X86/CMakeLists.txt b/lib/Target/X86/CMakeLists.txt index eed3b45d743..4d3dedf0e5f 100644 --- a/lib/Target/X86/CMakeLists.txt +++ b/lib/Target/X86/CMakeLists.txt @@ -27,7 +27,6 @@ set(sources X86JITInfo.cpp X86MCAsmInfo.cpp X86MCCodeEmitter.cpp - X86MCTargetExpr.cpp X86RegisterInfo.cpp X86Subtarget.cpp X86TargetMachine.cpp diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 2cf6dea0a38..7d2140bf4d9 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -16,7 +16,6 @@ #include "X86.h" #include "X86InstrBuilder.h" #include "X86ISelLowering.h" -#include "X86MCTargetExpr.h" #include "X86TargetMachine.h" #include "X86TargetObjectFile.h" #include "llvm/CallingConv.h" @@ -37,6 +36,7 @@ #include "llvm/CodeGen/PseudoSourceValue.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCExpr.h" #include "llvm/MC/MCSymbol.h" #include "llvm/ADT/BitVector.h" #include "llvm/ADT/SmallSet.h" @@ -1121,8 +1121,8 @@ X86TargetLowering::LowerCustomJumpTableEntry(const MachineJumpTableInfo *MJTI, Subtarget->isPICStyleGOT()); // In 32-bit ELF systems, our jump table entries are formed with @GOTOFF // entries. - return X86MCTargetExpr::Create(MBB->getSymbol(), - X86MCTargetExpr::GOTOFF, Ctx); + return MCSymbolRefExpr::Create(MBB->getSymbol(), + MCSymbolRefExpr::VK_GOTOFF, Ctx); } /// getPICJumpTableRelocaBase - Returns relocation base for the given PIC diff --git a/lib/Target/X86/X86MCTargetExpr.cpp b/lib/Target/X86/X86MCTargetExpr.cpp deleted file mode 100644 index cfcf70221d1..00000000000 --- a/lib/Target/X86/X86MCTargetExpr.cpp +++ /dev/null @@ -1,49 +0,0 @@ -//===- X86MCTargetExpr.cpp - X86 Target Specific MCExpr Implementation ----===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "X86MCTargetExpr.h" -#include "llvm/MC/MCContext.h" -#include "llvm/MC/MCSymbol.h" -#include "llvm/MC/MCValue.h" -#include "llvm/Support/raw_ostream.h" -using namespace llvm; - -X86MCTargetExpr *X86MCTargetExpr::Create(const MCSymbol *Sym, VariantKind K, - MCContext &Ctx) { - return new (Ctx) X86MCTargetExpr(Sym, K); -} - -void X86MCTargetExpr::PrintImpl(raw_ostream &OS) const { - OS << *Sym; - - switch (Kind) { - case Invalid: OS << "@"; break; - case GOT: OS << "@GOT"; break; - case GOTOFF: OS << "@GOTOFF"; break; - case GOTPCREL: OS << "@GOTPCREL"; break; - case GOTTPOFF: OS << "@GOTTPOFF"; break; - case INDNTPOFF: OS << "@INDNTPOFF"; break; - case NTPOFF: OS << "@NTPOFF"; break; - case PLT: OS << "@PLT"; break; - case TLSGD: OS << "@TLSGD"; break; - case TPOFF: OS << "@TPOFF"; break; - } -} - -bool X86MCTargetExpr::EvaluateAsRelocatableImpl(MCValue &Res, - const MCAsmLayout *Layout) const { - // FIXME: I don't know if this is right, it followed MCSymbolRefExpr. - - // Evaluate recursively if this is a variable. - if (Sym->isVariable()) - return Sym->getValue()->EvaluateAsRelocatable(Res, Layout); - - Res = MCValue::get(Sym, 0, 0); - return true; -} diff --git a/lib/Target/X86/X86MCTargetExpr.h b/lib/Target/X86/X86MCTargetExpr.h deleted file mode 100644 index a82e142a07f..00000000000 --- a/lib/Target/X86/X86MCTargetExpr.h +++ /dev/null @@ -1,49 +0,0 @@ -//===- X86MCTargetExpr.h - X86 Target Specific MCExpr -----------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef X86_MCTARGETEXPR_H -#define X86_MCTARGETEXPR_H - -#include "llvm/MC/MCExpr.h" - -namespace llvm { - -/// X86MCTargetExpr - This class represents symbol variants, like foo@GOT. -class X86MCTargetExpr : public MCTargetExpr { -public: - enum VariantKind { - Invalid, - GOT, - GOTOFF, - GOTPCREL, - GOTTPOFF, - INDNTPOFF, - NTPOFF, - PLT, - TLSGD, - TPOFF - }; -private: - /// Sym - The symbol being referenced. - const MCSymbol * const Sym; - /// Kind - The modifier. - const VariantKind Kind; - - X86MCTargetExpr(const MCSymbol *S, VariantKind K) : Sym(S), Kind(K) {} -public: - static X86MCTargetExpr *Create(const MCSymbol *Sym, VariantKind K, - MCContext &Ctx); - - void PrintImpl(raw_ostream &OS) const; - bool EvaluateAsRelocatableImpl(MCValue &Res, const MCAsmLayout *Layout) const; -}; - -} // end namespace llvm - -#endif diff --git a/lib/Target/X86/X86TargetObjectFile.cpp b/lib/Target/X86/X86TargetObjectFile.cpp index f75d41a0716..c15dfbb1c8e 100644 --- a/lib/Target/X86/X86TargetObjectFile.cpp +++ b/lib/Target/X86/X86TargetObjectFile.cpp @@ -7,11 +7,11 @@ // //===----------------------------------------------------------------------===// -#include "X86MCTargetExpr.h" #include "X86TargetObjectFile.h" #include "X86TargetMachine.h" #include "llvm/CodeGen/MachineModuleInfoImpls.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCExpr.h" #include "llvm/MC/MCSectionMachO.h" #include "llvm/Target/Mangler.h" #include "llvm/ADT/SmallString.h" @@ -29,7 +29,7 @@ getExprForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang, if (Encoding & (DW_EH_PE_indirect | DW_EH_PE_pcrel)) { const MCSymbol *Sym = Mang->getSymbol(GV); const MCExpr *Res = - X86MCTargetExpr::Create(Sym, X86MCTargetExpr::GOTPCREL, getContext()); + MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_GOTPCREL, getContext()); const MCExpr *Four = MCConstantExpr::Create(4, getContext()); return MCBinaryExpr::CreateAdd(Res, Four, getContext()); } diff --git a/test/CodeGen/X86/personality.ll b/test/CodeGen/X86/personality.ll index ce57e8fce6f..5acf04cc06c 100644 --- a/test/CodeGen/X86/personality.ll +++ b/test/CodeGen/X86/personality.ll @@ -39,7 +39,7 @@ declare void @__gxx_personality_v0() declare void @__cxa_end_catch() ; X64: Leh_frame_common_begin: -; X64: .long (___gxx_personality_v0@GOTPCREL)+4 +; X64: .long ___gxx_personality_v0@GOTPCREL+4 ; X32: Leh_frame_common_begin: ; X32: .long L___gxx_personality_v0$non_lazy_ptr- -- 2.34.1