summaryrefslogtreecommitdiffstats
path: root/include/llvm/MC
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/MC')
-rw-r--r--include/llvm/MC/MCAsmInfo.h9
-rw-r--r--include/llvm/MC/MCAsmLayout.h36
-rw-r--r--include/llvm/MC/MCAssembler.h100
-rw-r--r--include/llvm/MC/MCContext.h20
-rw-r--r--include/llvm/MC/MCExpr.h66
-rw-r--r--include/llvm/MC/MCParser/AsmParser.h3
-rw-r--r--include/llvm/MC/MCParser/MCAsmParser.h1
-rw-r--r--include/llvm/MC/MCSection.h2
-rw-r--r--include/llvm/MC/MCSectionELF.h11
-rw-r--r--include/llvm/MC/MCSectionMachO.h8
-rw-r--r--include/llvm/MC/MCStreamer.h16
-rw-r--r--include/llvm/MC/MCSymbol.h13
12 files changed, 238 insertions, 47 deletions
diff --git a/include/llvm/MC/MCAsmInfo.h b/include/llvm/MC/MCAsmInfo.h
index 7e0c8a5..4dfe9f0 100644
--- a/include/llvm/MC/MCAsmInfo.h
+++ b/include/llvm/MC/MCAsmInfo.h
@@ -145,6 +145,11 @@ namespace llvm {
/// which doesn't support the '.bss' directive only.
bool UsesELFSectionDirectiveForBSS; // Defaults to false.
+ /// HasMicrosoftFastStdCallMangling - True if this target uses microsoft
+ /// style mangling for functions with X86_StdCall/X86_FastCall calling
+ /// convention.
+ bool HasMicrosoftFastStdCallMangling; // Defaults to false.
+
//===--- Alignment Information ----------------------------------------===//
/// AlignDirective - The directive used to emit round up to an alignment
@@ -295,6 +300,10 @@ namespace llvm {
return UsesELFSectionDirectiveForBSS;
}
+ bool hasMicrosoftFastStdCallMangling() const {
+ return HasMicrosoftFastStdCallMangling;
+ }
+
// Accessors.
//
bool hasMachoZeroFillDirective() const { return HasMachoZeroFillDirective; }
diff --git a/include/llvm/MC/MCAsmLayout.h b/include/llvm/MC/MCAsmLayout.h
new file mode 100644
index 0000000..27bdbe9
--- /dev/null
+++ b/include/llvm/MC/MCAsmLayout.h
@@ -0,0 +1,36 @@
+//===- MCAsmLayout.h - Assembly Layout Object -------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCASMLAYOUT_H
+#define LLVM_MC_MCASMLAYOUT_H
+
+namespace llvm {
+class MCAssembler;
+
+/// Encapsulates the layout of an assembly file at a particular point in time.
+///
+/// Assembly may requiring compute multiple layouts for a particular assembly
+/// file as part of the relaxation process. This class encapsulates the layout
+/// at a single point in time in such a way that it is always possible to
+/// efficiently compute the exact addresses of any symbol in the assembly file,
+/// even during the relaxation process.
+class MCAsmLayout {
+private:
+ MCAssembler &Assembler;
+
+public:
+ MCAsmLayout(MCAssembler &_Assembler) : Assembler(_Assembler) {}
+
+ /// Get the assembler object this is a layout for.
+ MCAssembler &getAssembler() const { return Assembler; }
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h
index 882929f..1d8051f 100644
--- a/include/llvm/MC/MCAssembler.h
+++ b/include/llvm/MC/MCAssembler.h
@@ -10,6 +10,7 @@
#ifndef LLVM_MC_MCASSEMBLER_H
#define LLVM_MC_MCASSEMBLER_H
+#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/ilist.h"
#include "llvm/ADT/ilist_node.h"
@@ -20,6 +21,7 @@
namespace llvm {
class raw_ostream;
+class MCAsmLayout;
class MCAssembler;
class MCContext;
class MCExpr;
@@ -27,6 +29,8 @@ class MCFragment;
class MCSection;
class MCSectionData;
class MCSymbol;
+class MCValue;
+class TargetAsmBackend;
/// MCAsmFixup - Represent a fixed size region of bytes inside some fragment
/// which needs to be rewritten. This region will either be rewritten by the
@@ -160,6 +164,13 @@ public:
/// @name Fixup Access
/// @{
+ void addFixup(MCAsmFixup Fixup) {
+ // Enforce invariant that fixups are in offset order.
+ assert((Fixups.empty() || Fixup.Offset > Fixups.back().Offset) &&
+ "Fixups must be added in order!");
+ Fixups.push_back(Fixup);
+ }
+
std::vector<MCAsmFixup> &getFixups() { return Fixups; }
const std::vector<MCAsmFixup> &getFixups() const { return Fixups; }
@@ -195,7 +206,8 @@ class MCAlignFragment : public MCFragment {
/// cannot be satisfied in this width then this fragment is ignored.
unsigned MaxBytesToEmit;
- /// EmitNops - true when aligning code and optimal nops to be used for filling
+ /// EmitNops - true when aligning code and optimal nops to be used for
+ /// filling.
bool EmitNops;
public:
@@ -505,6 +517,11 @@ public:
uint64_t getOffset() const { return Offset; }
void setOffset(uint64_t Value) { Offset = Value; }
+ uint64_t getAddress() const {
+ assert(getFragment() && "Invalid getAddress() on undefined symbol!");
+ return getFragment()->getAddress() + getOffset();
+ }
+
/// @}
/// @name Symbol Attributes
/// @{
@@ -581,22 +598,61 @@ private:
MCContext &Context;
+ TargetAsmBackend &Backend;
+
raw_ostream &OS;
iplist<MCSectionData> Sections;
iplist<MCSymbolData> Symbols;
+ /// The map of sections to their associated assembler backend data.
+ //
+ // FIXME: Avoid this indirection?
+ DenseMap<const MCSection*, MCSectionData*> SectionMap;
+
+ /// The map of symbols to their associated assembler backend data.
+ //
+ // FIXME: Avoid this indirection?
+ DenseMap<const MCSymbol*, MCSymbolData*> SymbolMap;
+
std::vector<IndirectSymbolData> IndirectSymbols;
unsigned SubsectionsViaSymbols : 1;
private:
+ /// Check whether a fixup can be satisfied, or whether it needs to be relaxed
+ /// (increased in size, in order to hold its value correctly).
+ bool FixupNeedsRelaxation(MCAsmFixup &Fixup, MCDataFragment *DF);
+
/// LayoutSection - Assign offsets and sizes to the fragments in the section
/// \arg SD, and update the section size. The section file offset should
/// already have been computed.
void LayoutSection(MCSectionData &SD);
+ /// LayoutOnce - Perform one layout iteration and return true if any offsets
+ /// were adjusted.
+ bool LayoutOnce();
+
+ // FIXME: Make protected once we factor out object writer classes.
+public:
+ /// Evaluate a fixup to a relocatable expression and the value which should be
+ /// placed into the fixup.
+ ///
+ /// \param Layout The layout to use for evaluation.
+ /// \param Fixup The fixup to evaluate.
+ /// \param DF The fragment the fixup is inside.
+ /// \param Target [out] On return, the relocatable expression the fixup
+ /// evaluates to.
+ /// \param Value [out] On return, the value of the fixup as currently layed
+ /// out.
+ /// \return Whether the fixup value was fully resolved. This is true if the
+ /// \arg Value result is fixed, otherwise the value may change due to
+ /// relocation.
+ bool EvaluateFixup(const MCAsmLayout &Layout,
+ MCAsmFixup &Fixup, MCDataFragment *DF,
+ MCValue &Target, uint64_t &Value) const;
+
public:
/// Construct a new assembler instance.
///
@@ -606,11 +662,13 @@ public:
// concrete and require clients to pass in a target like object. The other
// option is to make this abstract, and have targets provide concrete
// implementations as we do with AsmParser.
- MCAssembler(MCContext &_Context, raw_ostream &OS);
+ MCAssembler(MCContext &_Context, TargetAsmBackend &_Backend, raw_ostream &OS);
~MCAssembler();
MCContext &getContext() const { return Context; }
+ TargetAsmBackend &getBackend() const { return Backend; }
+
/// Finish - Do final processing and write the object to the output stream.
void Finish();
@@ -673,6 +731,44 @@ public:
size_t indirect_symbol_size() const { return IndirectSymbols.size(); }
/// @}
+ /// @name Backend Data Access
+ /// @{
+
+ MCSectionData &getSectionData(const MCSection &Section) const {
+ MCSectionData *Entry = SectionMap.lookup(&Section);
+ assert(Entry && "Missing section data!");
+ return *Entry;
+ }
+
+ MCSectionData &getOrCreateSectionData(const MCSection &Section,
+ bool *Created = 0) {
+ MCSectionData *&Entry = SectionMap[&Section];
+
+ if (Created) *Created = !Entry;
+ if (!Entry)
+ Entry = new MCSectionData(Section, this);
+
+ return *Entry;
+ }
+
+ MCSymbolData &getSymbolData(const MCSymbol &Symbol) const {
+ MCSymbolData *Entry = SymbolMap.lookup(&Symbol);
+ assert(Entry && "Missing symbol data!");
+ return *Entry;
+ }
+
+ MCSymbolData &getOrCreateSymbolData(const MCSymbol &Symbol,
+ bool *Created = 0) {
+ MCSymbolData *&Entry = SymbolMap[&Symbol];
+
+ if (Created) *Created = !Entry;
+ if (!Entry)
+ Entry = new MCSymbolData(Symbol, 0, 0, this);
+
+ return *Entry;
+ }
+
+ /// @}
void dump();
};
diff --git a/include/llvm/MC/MCContext.h b/include/llvm/MC/MCContext.h
index f2f1456..85114e3 100644
--- a/include/llvm/MC/MCContext.h
+++ b/include/llvm/MC/MCContext.h
@@ -15,6 +15,7 @@
#include "llvm/Support/Allocator.h"
namespace llvm {
+ class MCAsmInfo;
class MCExpr;
class MCSection;
class MCSymbol;
@@ -28,31 +29,44 @@ namespace llvm {
MCContext(const MCContext&); // DO NOT IMPLEMENT
MCContext &operator=(const MCContext&); // DO NOT IMPLEMENT
+ /// The MCAsmInfo for this target.
+ const MCAsmInfo &MAI;
+
/// Sections - Bindings of names to allocated sections.
StringMap<MCSection*> Sections;
/// Symbols - Bindings of names to symbols.
StringMap<MCSymbol*> Symbols;
+ /// NextUniqueID - The next ID to dole out to an unnamed assembler temporary
+ /// symbol.
+ unsigned NextUniqueID;
+
/// Allocator - Allocator object used for creating machine code objects.
///
/// We use a bump pointer allocator to avoid the need to track all allocated
/// objects.
BumpPtrAllocator Allocator;
public:
- MCContext();
+ explicit MCContext(const MCAsmInfo &MAI);
~MCContext();
+
+ const MCAsmInfo &getAsmInfo() const { return MAI; }
/// @name Symbol Managment
/// @{
+
+ /// CreateTempSymbol - Create and return a new assembler temporary symbol
+ /// with a unique but unspecified name.
+ MCSymbol *CreateTempSymbol();
/// GetOrCreateSymbol - Lookup the symbol inside with the specified
/// @p Name. If it exists, return it. If not, create a forward
/// reference and return it.
///
/// @param Name - The symbol name, which must be unique across all symbols.
- MCSymbol *GetOrCreateSymbol(StringRef Name);
- MCSymbol *GetOrCreateSymbol(const Twine &Name);
+ MCSymbol *GetOrCreateSymbol(StringRef Name, bool isTemporary = false);
+ MCSymbol *GetOrCreateSymbol(const Twine &Name, bool isTemporary = false);
/// GetOrCreateTemporarySymbol - Create a new assembler temporary symbol
/// with the specified @p Name if it doesn't exist or return the existing
diff --git a/include/llvm/MC/MCExpr.h b/include/llvm/MC/MCExpr.h
index 3f17492..6efec52 100644
--- a/include/llvm/MC/MCExpr.h
+++ b/include/llvm/MC/MCExpr.h
@@ -15,6 +15,7 @@
namespace llvm {
class MCAsmInfo;
+class MCAsmLayout;
class MCContext;
class MCSymbol;
class MCValue;
@@ -62,21 +63,25 @@ public:
/// EvaluateAsAbsolute - Try to evaluate the expression to an absolute value.
///
/// @param Res - The absolute value, if evaluation succeeds.
+ /// @param Layout - The assembler layout object to use for evaluating symbol
+ /// values. If not given, then only non-symbolic expressions will be
+ /// evaluated.
/// @result - True on success.
- bool EvaluateAsAbsolute(int64_t &Res) const;
+ bool EvaluateAsAbsolute(int64_t &Res, const MCAsmLayout *Layout = 0) const;
/// EvaluateAsRelocatable - Try to evaluate the expression to a relocatable
/// value, i.e. an expression of the fixed form (a - b + constant).
///
/// @param Res - The relocatable value, if evaluation succeeds.
+ /// @param Layout - The assembler layout object to use for evaluating values.
/// @result - True on success.
- bool EvaluateAsRelocatable(MCValue &Res) const;
+ bool EvaluateAsRelocatable(MCValue &Res, const MCAsmLayout *Layout = 0) const;
/// @}
static bool classof(const MCExpr *) { return true; }
};
-
+
inline raw_ostream &operator<<(raw_ostream &OS, const MCExpr &E) {
E.print(OS);
return OS;
@@ -116,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
@@ -138,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) {
@@ -346,11 +389,12 @@ protected:
MCTargetExpr() : MCExpr(Target) {}
virtual ~MCTargetExpr() {}
public:
-
+
virtual void PrintImpl(raw_ostream &OS) const = 0;
- virtual bool EvaluateAsRelocatableImpl(MCValue &Res) const = 0;
+ virtual bool EvaluateAsRelocatableImpl(MCValue &Res,
+ const MCAsmLayout *Layout) const = 0;
+
-
static bool classof(const MCExpr *E) {
return E->getKind() == MCExpr::Target;
}
diff --git a/include/llvm/MC/MCParser/AsmParser.h b/include/llvm/MC/MCParser/AsmParser.h
index 829604c..06e0920 100644
--- a/include/llvm/MC/MCParser/AsmParser.h
+++ b/include/llvm/MC/MCParser/AsmParser.h
@@ -31,7 +31,6 @@ class MCExpr;
class MCInst;
class MCStreamer;
class MCAsmInfo;
-class MCValue;
class SourceMgr;
class TargetAsmParser;
class Twine;
@@ -65,7 +64,7 @@ public:
const MCAsmInfo &MAI);
~AsmParser();
- bool Run();
+ bool Run(bool NoInitialTextSection);
void AddDirectiveHandler(StringRef Directive,
diff --git a/include/llvm/MC/MCParser/MCAsmParser.h b/include/llvm/MC/MCParser/MCAsmParser.h
index 843c692..7f7f1b6 100644
--- a/include/llvm/MC/MCParser/MCAsmParser.h
+++ b/include/llvm/MC/MCParser/MCAsmParser.h
@@ -18,7 +18,6 @@ class MCAsmLexer;
class MCContext;
class MCExpr;
class MCStreamer;
-class MCValue;
class SMLoc;
class Twine;
diff --git a/include/llvm/MC/MCSection.h b/include/llvm/MC/MCSection.h
index ceb6d27..3d8815a 100644
--- a/include/llvm/MC/MCSection.h
+++ b/include/llvm/MC/MCSection.h
@@ -42,6 +42,8 @@ namespace llvm {
};
class MCSectionCOFF : public MCSection {
+ // FIXME: This memory is leaked because MCSectionCOFF is bump pointer
+ // allocated and this never gets freed.
std::string Name;
/// IsDirective - This is true if the section name is a directive, not
diff --git a/include/llvm/MC/MCSectionELF.h b/include/llvm/MC/MCSectionELF.h
index 2dccf5c..cdd2f73 100644
--- a/include/llvm/MC/MCSectionELF.h
+++ b/include/llvm/MC/MCSectionELF.h
@@ -21,7 +21,9 @@ namespace llvm {
/// MCSectionELF - This represents a section on linux, lots of unix variants
/// and some bare metal systems.
class MCSectionELF : public MCSection {
- std::string SectionName;
+ /// SectionName - This is the name of the section. The referenced memory is
+ /// owned by TargetLoweringObjectFileELF's ELFUniqueMap.
+ StringRef SectionName;
/// Type - This is the sh_type field of a section, drawn from the enums below.
unsigned Type;
@@ -37,7 +39,7 @@ class MCSectionELF : public MCSection {
protected:
MCSectionELF(StringRef Section, unsigned type, unsigned flags,
SectionKind K, bool isExplicit)
- : MCSection(K), SectionName(Section.str()), Type(type), Flags(flags),
+ : MCSection(K), SectionName(Section), Type(type), Flags(flags),
IsExplicit(isExplicit) {}
public:
@@ -163,10 +165,7 @@ public:
TARGET_INDEP_SHF = FIRST_TARGET_DEP_FLAG-1U
};
- StringRef getSectionName() const {
- return StringRef(SectionName);
- }
-
+ StringRef getSectionName() const { return SectionName; }
unsigned getType() const { return Type; }
unsigned getFlags() const { return Flags; }
diff --git a/include/llvm/MC/MCSectionMachO.h b/include/llvm/MC/MCSectionMachO.h
index 6156819..5839c28 100644
--- a/include/llvm/MC/MCSectionMachO.h
+++ b/include/llvm/MC/MCSectionMachO.h
@@ -151,10 +151,12 @@ public:
return StringRef(SectionName, 16);
return StringRef(SectionName);
}
-
+
unsigned getTypeAndAttributes() const { return TypeAndAttributes; }
unsigned getStubSize() const { return Reserved2; }
-
+
+ unsigned getType() const { return TypeAndAttributes & SECTION_TYPE; }
+
/// ParseSectionSpecifier - Parse the section specifier indicated by "Spec".
/// This is a string that can appear after a .section directive in a mach-o
/// flavored .s file. If successful, this fills in the specified Out
@@ -165,7 +167,7 @@ public:
StringRef &Section, // Out.
unsigned &TAA, // Out.
unsigned &StubSize); // Out.
-
+
virtual void PrintSwitchToSection(const MCAsmInfo &MAI,
raw_ostream &OS) const;
};
diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h
index 6359cce..47befca 100644
--- a/include/llvm/MC/MCStreamer.h
+++ b/include/llvm/MC/MCStreamer.h
@@ -27,6 +27,7 @@ namespace llvm {
class MCSection;
class MCSymbol;
class StringRef;
+class TargetAsmBackend;
class Twine;
class raw_ostream;
class formatted_raw_ostream;
@@ -298,24 +299,15 @@ namespace llvm {
/// \param ShowInst - Whether to show the MCInst representation inline with
/// the assembly.
MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS,
- const MCAsmInfo &MAI, bool isLittleEndian,
- bool isVerboseAsm,
+ bool isLittleEndian, bool isVerboseAsm,
MCInstPrinter *InstPrint = 0,
MCCodeEmitter *CE = 0,
bool ShowInst = false);
- // FIXME: These two may end up getting rolled into a single
- // createObjectStreamer interface, which implements the assembler backend, and
- // is parameterized on an output object file writer.
-
/// createMachOStream - Create a machine code streamer which will generative
/// Mach-O format object files.
- MCStreamer *createMachOStreamer(MCContext &Ctx, raw_ostream &OS,
- MCCodeEmitter *CE);
-
- /// createELFStreamer - Create a machine code streamer which will generative
- /// ELF format object files.
- MCStreamer *createELFStreamer(MCContext &Ctx, raw_ostream &OS);
+ MCStreamer *createMachOStreamer(MCContext &Ctx, TargetAsmBackend &TAB,
+ raw_ostream &OS, MCCodeEmitter *CE);
} // end namespace llvm
diff --git a/include/llvm/MC/MCSymbol.h b/include/llvm/MC/MCSymbol.h
index d5c4d95..e41eb2a 100644
--- a/include/llvm/MC/MCSymbol.h
+++ b/include/llvm/MC/MCSymbol.h
@@ -14,9 +14,7 @@
#ifndef LLVM_MC_MCSYMBOL_H
#define LLVM_MC_MCSYMBOL_H
-#include <string>
#include "llvm/ADT/StringRef.h"
-#include "llvm/System/DataTypes.h"
namespace llvm {
class MCExpr;
@@ -38,8 +36,9 @@ namespace llvm {
// FIXME: Use a PointerInt wrapper for this?
static const MCSection *AbsolutePseudoSection;
- /// Name - The name of the symbol.
- std::string Name;
+ /// Name - The name of the symbol. The referred-to string data is actually
+ /// held by the StringMap that lives in MCContext.
+ StringRef Name;
/// Section - The section the symbol is defined in. This is null for
/// undefined symbols, and the special AbsolutePseudoSection value for
@@ -56,14 +55,14 @@ namespace llvm {
private: // MCContext creates and uniques these.
friend class MCContext;
- MCSymbol(StringRef _Name, bool _IsTemporary)
- : Name(_Name), Section(0), Value(0), IsTemporary(_IsTemporary) {}
+ MCSymbol(StringRef name, bool isTemporary)
+ : Name(name), Section(0), Value(0), IsTemporary(isTemporary) {}
MCSymbol(const MCSymbol&); // DO NOT IMPLEMENT
void operator=(const MCSymbol&); // DO NOT IMPLEMENT
public:
/// getName - Get the symbol name.
- const std::string &getName() const { return Name; }
+ StringRef getName() const { return Name; }
/// @name Symbol Type
/// @{
OpenPOWER on IntegriCloud