summaryrefslogtreecommitdiffstats
path: root/include/llvm/MC
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/MC')
-rw-r--r--include/llvm/MC/EDInstInfo.h29
-rw-r--r--include/llvm/MC/MCAsmBackend.h7
-rw-r--r--include/llvm/MC/MCAsmInfo.h27
-rw-r--r--include/llvm/MC/MCAsmInfoCOFF.h6
-rw-r--r--include/llvm/MC/MCAsmInfoDarwin.h6
-rw-r--r--include/llvm/MC/MCAsmLayout.h27
-rw-r--r--include/llvm/MC/MCAssembler.h323
-rw-r--r--include/llvm/MC/MCAtom.h4
-rw-r--r--include/llvm/MC/MCCodeEmitter.h3
-rw-r--r--include/llvm/MC/MCContext.h103
-rw-r--r--include/llvm/MC/MCDisassembler.h16
-rw-r--r--include/llvm/MC/MCDwarf.h151
-rw-r--r--include/llvm/MC/MCELF.h37
-rw-r--r--include/llvm/MC/MCELFObjectWriter.h1
-rw-r--r--include/llvm/MC/MCELFStreamer.h125
-rw-r--r--include/llvm/MC/MCExpr.h19
-rw-r--r--include/llvm/MC/MCFixedLenDisassembler.h4
-rw-r--r--include/llvm/MC/MCInstBuilder.h68
-rw-r--r--include/llvm/MC/MCInstPrinter.h14
-rw-r--r--include/llvm/MC/MCInstrDesc.h100
-rw-r--r--include/llvm/MC/MCMachObjectWriter.h18
-rw-r--r--include/llvm/MC/MCObjectFileInfo.h80
-rw-r--r--include/llvm/MC/MCObjectStreamer.h26
-rw-r--r--include/llvm/MC/MCObjectWriter.h21
-rw-r--r--include/llvm/MC/MCParser/AsmCond.h4
-rw-r--r--include/llvm/MC/MCParser/AsmLexer.h4
-rw-r--r--include/llvm/MC/MCParser/MCAsmLexer.h14
-rw-r--r--include/llvm/MC/MCParser/MCAsmParser.h59
-rw-r--r--include/llvm/MC/MCParser/MCAsmParserExtension.h6
-rw-r--r--include/llvm/MC/MCParser/MCParsedAsmOperand.h17
-rw-r--r--include/llvm/MC/MCRegisterInfo.h97
-rw-r--r--include/llvm/MC/MCSchedule.h23
-rw-r--r--include/llvm/MC/MCSection.h6
-rw-r--r--include/llvm/MC/MCSectionCOFF.h8
-rw-r--r--include/llvm/MC/MCSectionELF.h9
-rw-r--r--include/llvm/MC/MCSectionMachO.h10
-rw-r--r--include/llvm/MC/MCStreamer.h88
-rw-r--r--include/llvm/MC/MCSubtargetInfo.h2
-rw-r--r--include/llvm/MC/MCTargetAsmLexer.h89
-rw-r--r--include/llvm/MC/MCTargetAsmParser.h10
-rw-r--r--include/llvm/MC/MCValue.h2
-rw-r--r--include/llvm/MC/MCWinCOFFObjectWriter.h3
-rw-r--r--include/llvm/MC/SubtargetFeature.h2
43 files changed, 1220 insertions, 448 deletions
diff --git a/include/llvm/MC/EDInstInfo.h b/include/llvm/MC/EDInstInfo.h
deleted file mode 100644
index 5b02467..0000000
--- a/include/llvm/MC/EDInstInfo.h
+++ /dev/null
@@ -1,29 +0,0 @@
-//===-- llvm/MC/EDInstInfo.h - EDis instruction info ------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef EDINSTINFO_H
-#define EDINSTINFO_H
-
-#include "llvm/Support/DataTypes.h"
-
-namespace llvm {
-
-#define EDIS_MAX_OPERANDS 13
-#define EDIS_MAX_SYNTAXES 2
-
-struct EDInstInfo {
- uint8_t instructionType;
- uint8_t numOperands;
- uint8_t operandTypes[EDIS_MAX_OPERANDS];
- uint8_t operandFlags[EDIS_MAX_OPERANDS];
- const signed char operandOrders[EDIS_MAX_SYNTAXES][EDIS_MAX_OPERANDS];
-};
-
-} // namespace llvm
-
-#endif
diff --git a/include/llvm/MC/MCAsmBackend.h b/include/llvm/MC/MCAsmBackend.h
index 72ed1a3..9a6b703 100644
--- a/include/llvm/MC/MCAsmBackend.h
+++ b/include/llvm/MC/MCAsmBackend.h
@@ -22,7 +22,7 @@ class MCELFObjectTargetWriter;
struct MCFixupKindInfo;
class MCFragment;
class MCInst;
-class MCInstFragment;
+class MCRelaxableFragment;
class MCObjectWriter;
class MCSection;
class MCValue;
@@ -41,6 +41,9 @@ protected: // Can only create subclasses.
public:
virtual ~MCAsmBackend();
+ /// lifetime management
+ virtual void reset() { }
+
/// createObjectWriter - Create a new MCObjectWriter instance for use by the
/// assembler backend to emit the final object file.
virtual MCObjectWriter *createObjectWriter(raw_ostream &OS) const = 0;
@@ -127,7 +130,7 @@ public:
/// fixup requires the associated instruction to be relaxed.
virtual bool fixupNeedsRelaxation(const MCFixup &Fixup,
uint64_t Value,
- const MCInstFragment *DF,
+ const MCRelaxableFragment *DF,
const MCAsmLayout &Layout) const = 0;
/// RelaxInstruction - Relax the instruction in the given fragment to the next
diff --git a/include/llvm/MC/MCAsmInfo.h b/include/llvm/MC/MCAsmInfo.h
index 97aad71..28256b3 100644
--- a/include/llvm/MC/MCAsmInfo.h
+++ b/include/llvm/MC/MCAsmInfo.h
@@ -13,11 +13,11 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_TARGET_ASM_INFO_H
-#define LLVM_TARGET_ASM_INFO_H
+#ifndef LLVM_MC_MCASMINFO_H
+#define LLVM_MC_MCASMINFO_H
-#include "llvm/MC/MachineLocation.h"
#include "llvm/MC/MCDirectives.h"
+#include "llvm/MC/MachineLocation.h"
#include <cassert>
#include <vector>
@@ -48,6 +48,11 @@ namespace llvm {
/// Default is 4.
unsigned PointerSize;
+ /// CalleeSaveStackSlotSize - Size of the stack slot reserved for
+ /// callee-saved registers, in bytes.
+ /// Default is same as pointer size.
+ unsigned CalleeSaveStackSlotSize;
+
/// IsLittleEndian - True if target is little endian.
/// Default is true.
bool IsLittleEndian;
@@ -102,6 +107,9 @@ namespace llvm {
/// LabelSuffix - This is appended to emitted labels.
const char *LabelSuffix; // Defaults to ":"
+ /// LabelSuffix - This is appended to emitted labels.
+ const char *DebugLabelSuffix; // Defaults to ":"
+
/// GlobalPrefix - If this is set to a non-empty string, it is prepended
/// onto all global symbols. This is often used for "_" or ".".
const char *GlobalPrefix; // Defaults to ""
@@ -340,7 +348,13 @@ namespace llvm {
return PointerSize;
}
- /// islittleendian - True if the target is little endian.
+ /// getCalleeSaveStackSlotSize - Get the callee-saved register stack slot
+ /// size in bytes.
+ unsigned getCalleeSaveStackSlotSize() const {
+ return CalleeSaveStackSlotSize;
+ }
+
+ /// isLittleEndian - True if the target is little endian.
bool isLittleEndian() const {
return IsLittleEndian;
}
@@ -426,6 +440,11 @@ namespace llvm {
const char *getLabelSuffix() const {
return LabelSuffix;
}
+
+ const char *getDebugLabelSuffix() const {
+ return DebugLabelSuffix;
+ }
+
const char *getGlobalPrefix() const {
return GlobalPrefix;
}
diff --git a/include/llvm/MC/MCAsmInfoCOFF.h b/include/llvm/MC/MCAsmInfoCOFF.h
index 0ff3e12..7286151 100644
--- a/include/llvm/MC/MCAsmInfoCOFF.h
+++ b/include/llvm/MC/MCAsmInfoCOFF.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_COFF_TARGET_ASM_INFO_H
-#define LLVM_COFF_TARGET_ASM_INFO_H
+#ifndef LLVM_MC_MCASMINFOCOFF_H
+#define LLVM_MC_MCASMINFOCOFF_H
#include "llvm/MC/MCAsmInfo.h"
@@ -33,4 +33,4 @@ namespace llvm {
}
-#endif // LLVM_COFF_TARGET_ASM_INFO_H
+#endif // LLVM_MC_MCASMINFOCOFF_H
diff --git a/include/llvm/MC/MCAsmInfoDarwin.h b/include/llvm/MC/MCAsmInfoDarwin.h
index af552de..3d249f9 100644
--- a/include/llvm/MC/MCAsmInfoDarwin.h
+++ b/include/llvm/MC/MCAsmInfoDarwin.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_DARWIN_TARGET_ASM_INFO_H
-#define LLVM_DARWIN_TARGET_ASM_INFO_H
+#ifndef LLVM_MC_MCASMINFODARWIN_H
+#define LLVM_MC_MCASMINFODARWIN_H
#include "llvm/MC/MCAsmInfo.h"
@@ -26,4 +26,4 @@ namespace llvm {
}
-#endif // LLVM_DARWIN_TARGET_ASM_INFO_H
+#endif // LLVM_MC_MCASMINFODARWIN_H
diff --git a/include/llvm/MC/MCAsmLayout.h b/include/llvm/MC/MCAsmLayout.h
index cf79216..3058b7b 100644
--- a/include/llvm/MC/MCAsmLayout.h
+++ b/include/llvm/MC/MCAsmLayout.h
@@ -21,10 +21,10 @@ class MCSymbolData;
/// Encapsulates the layout of an assembly file at a particular point in time.
///
-/// Assembly may requiring compute multiple layouts for a particular assembly
+/// Assembly may require computing 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,
+/// efficiently compute the exact address of any symbol in the assembly file,
/// even during the relaxation process.
class MCAsmLayout {
public:
@@ -39,14 +39,20 @@ private:
/// The last fragment which was laid out, or 0 if nothing has been laid
/// out. Fragments are always laid out in order, so all fragments with a
- /// lower ordinal will be up to date.
- mutable DenseMap<const MCSectionData*, MCFragment *> LastValidFragment;
+ /// lower ordinal will be valid.
+ mutable DenseMap<const MCSectionData*, MCFragment*> LastValidFragment;
/// \brief Make sure that the layout for the given fragment is valid, lazily
/// computing it if necessary.
- void EnsureValid(const MCFragment *F) const;
+ void ensureValid(const MCFragment *F) const;
- bool isFragmentUpToDate(const MCFragment *F) const;
+ /// \brief Is the layout for this fragment valid?
+ bool isFragmentValid(const MCFragment *F) const;
+
+ /// \brief Compute the amount of padding required before this fragment to
+ /// obey bundling restrictions.
+ uint64_t computeBundlePadding(const MCFragment *F,
+ uint64_t FOffset, uint64_t FSize);
public:
MCAsmLayout(MCAssembler &_Assembler);
@@ -54,14 +60,15 @@ public:
/// Get the assembler object this is a layout for.
MCAssembler &getAssembler() const { return Assembler; }
- /// \brief Invalidate all following fragments because a fragment has been
- /// resized. The fragments size should have already been updated.
- void Invalidate(MCFragment *F);
+ /// \brief Invalidate the fragments starting with F because it has been
+ /// resized. The fragment's size should have already been updated, but
+ /// its bundle padding will be recomputed.
+ void invalidateFragmentsFrom(MCFragment *F);
/// \brief Perform layout for a single fragment, assuming that the previous
/// fragment has already been laid out correctly, and the parent section has
/// been initialized.
- void LayoutFragment(MCFragment *Fragment);
+ void layoutFragment(MCFragment *Fragment);
/// @name Section Access (in layout order)
/// @{
diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h
index 5771415..43fbdc9 100644
--- a/include/llvm/MC/MCAssembler.h
+++ b/include/llvm/MC/MCAssembler.h
@@ -10,13 +10,13 @@
#ifndef LLVM_MC_MCASSEMBLER_H
#define LLVM_MC_MCASSEMBLER_H
-#include "llvm/MC/MCFixup.h"
-#include "llvm/MC/MCInst.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/ilist.h"
#include "llvm/ADT/ilist_node.h"
+#include "llvm/MC/MCFixup.h"
+#include "llvm/MC/MCInst.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/DataTypes.h"
#include <vector> // FIXME: Shouldn't be needed.
@@ -47,8 +47,9 @@ public:
enum FragmentType {
FT_Align,
FT_Data,
+ FT_CompactEncodedInst,
FT_Fill,
- FT_Inst,
+ FT_Relaxable,
FT_Org,
FT_Dwarf,
FT_DwarfFrame,
@@ -99,42 +100,139 @@ public:
unsigned getLayoutOrder() const { return LayoutOrder; }
void setLayoutOrder(unsigned Value) { LayoutOrder = Value; }
+ /// \brief Does this fragment have instructions emitted into it? By default
+ /// this is false, but specific fragment types may set it to true.
+ virtual bool hasInstructions() const { return false; }
+
+ /// \brief Should this fragment be placed at the end of an aligned bundle?
+ virtual bool alignToBundleEnd() const { return false; }
+ virtual void setAlignToBundleEnd(bool V) { }
+
+ /// \brief Get the padding size that must be inserted before this fragment.
+ /// Used for bundling. By default, no padding is inserted.
+ /// Note that padding size is restricted to 8 bits. This is an optimization
+ /// to reduce the amount of space used for each fragment. In practice, larger
+ /// padding should never be required.
+ virtual uint8_t getBundlePadding() const {
+ return 0;
+ }
+
+ /// \brief Set the padding size for this fragment. By default it's a no-op,
+ /// and only some fragments have a meaningful implementation.
+ virtual void setBundlePadding(uint8_t N) {
+ }
+
void dump();
};
-class MCDataFragment : public MCFragment {
+/// Interface implemented by fragments that contain encoded instructions and/or
+/// data.
+///
+class MCEncodedFragment : public MCFragment {
virtual void anchor();
- SmallString<32> Contents;
-
- /// Fixups - The list of fixups in this fragment.
- std::vector<MCFixup> Fixups;
+ uint8_t BundlePadding;
public:
- typedef std::vector<MCFixup>::const_iterator const_fixup_iterator;
- typedef std::vector<MCFixup>::iterator fixup_iterator;
+ MCEncodedFragment(MCFragment::FragmentType FType, MCSectionData *SD = 0)
+ : MCFragment(FType, SD), BundlePadding(0)
+ {
+ }
+ virtual ~MCEncodedFragment();
+
+ virtual SmallVectorImpl<char> &getContents() = 0;
+ virtual const SmallVectorImpl<char> &getContents() const = 0;
+
+ virtual uint8_t getBundlePadding() const {
+ return BundlePadding;
+ }
+
+ virtual void setBundlePadding(uint8_t N) {
+ BundlePadding = N;
+ }
+
+ static bool classof(const MCFragment *F) {
+ MCFragment::FragmentType Kind = F->getKind();
+ switch (Kind) {
+ default:
+ return false;
+ case MCFragment::FT_Relaxable:
+ case MCFragment::FT_CompactEncodedInst:
+ case MCFragment::FT_Data:
+ return true;
+ }
+ }
+};
+
+/// Interface implemented by fragments that contain encoded instructions and/or
+/// data and also have fixups registered.
+///
+class MCEncodedFragmentWithFixups : public MCEncodedFragment {
+ virtual void anchor();
public:
- MCDataFragment(MCSectionData *SD = 0) : MCFragment(FT_Data, SD) {}
+ MCEncodedFragmentWithFixups(MCFragment::FragmentType FType,
+ MCSectionData *SD = 0)
+ : MCEncodedFragment(FType, SD)
+ {
+ }
- /// @name Accessors
- /// @{
+ virtual ~MCEncodedFragmentWithFixups();
- SmallString<32> &getContents() { return Contents; }
- const SmallString<32> &getContents() const { return Contents; }
+ typedef SmallVectorImpl<MCFixup>::const_iterator const_fixup_iterator;
+ typedef SmallVectorImpl<MCFixup>::iterator fixup_iterator;
- /// @}
- /// @name Fixup Access
- /// @{
+ virtual SmallVectorImpl<MCFixup> &getFixups() = 0;
+ virtual const SmallVectorImpl<MCFixup> &getFixups() const = 0;
+
+ virtual fixup_iterator fixup_begin() = 0;
+ virtual const_fixup_iterator fixup_begin() const = 0;
+ virtual fixup_iterator fixup_end() = 0;
+ virtual const_fixup_iterator fixup_end() const = 0;
+
+ static bool classof(const MCFragment *F) {
+ MCFragment::FragmentType Kind = F->getKind();
+ return Kind == MCFragment::FT_Relaxable || Kind == MCFragment::FT_Data;
+ }
+};
+
+/// Fragment for data and encoded instructions.
+///
+class MCDataFragment : public MCEncodedFragmentWithFixups {
+ virtual void anchor();
+
+ /// \brief Does this fragment contain encoded instructions anywhere in it?
+ bool HasInstructions;
+
+ /// \brief Should this fragment be aligned to the end of a bundle?
+ bool AlignToBundleEnd;
+
+ SmallVector<char, 32> Contents;
- void addFixup(MCFixup Fixup) {
- // Enforce invariant that fixups are in offset order.
- assert((Fixups.empty() || Fixup.getOffset() >= Fixups.back().getOffset()) &&
- "Fixups must be added in order!");
- Fixups.push_back(Fixup);
+ /// Fixups - The list of fixups in this fragment.
+ SmallVector<MCFixup, 4> Fixups;
+public:
+ MCDataFragment(MCSectionData *SD = 0)
+ : MCEncodedFragmentWithFixups(FT_Data, SD),
+ HasInstructions(false), AlignToBundleEnd(false)
+ {
}
- std::vector<MCFixup> &getFixups() { return Fixups; }
- const std::vector<MCFixup> &getFixups() const { return Fixups; }
+ virtual SmallVectorImpl<char> &getContents() { return Contents; }
+ virtual const SmallVectorImpl<char> &getContents() const { return Contents; }
+
+ SmallVectorImpl<MCFixup> &getFixups() {
+ return Fixups;
+ }
+
+ const SmallVectorImpl<MCFixup> &getFixups() const {
+ return Fixups;
+ }
+
+ virtual bool hasInstructions() const { return HasInstructions; }
+ virtual void setHasInstructions(bool V) { HasInstructions = V; }
+
+ virtual bool alignToBundleEnd() const { return AlignToBundleEnd; }
+ virtual void setAlignToBundleEnd(bool V) { AlignToBundleEnd = V; }
fixup_iterator fixup_begin() { return Fixups.begin(); }
const_fixup_iterator fixup_begin() const { return Fixups.begin(); }
@@ -142,60 +240,79 @@ public:
fixup_iterator fixup_end() {return Fixups.end();}
const_fixup_iterator fixup_end() const {return Fixups.end();}
- size_t fixup_size() const { return Fixups.size(); }
+ static bool classof(const MCFragment *F) {
+ return F->getKind() == MCFragment::FT_Data;
+ }
+};
- /// @}
+/// This is a compact (memory-size-wise) fragment for holding an encoded
+/// instruction (non-relaxable) that has no fixups registered. When applicable,
+/// it can be used instead of MCDataFragment and lead to lower memory
+/// consumption.
+///
+class MCCompactEncodedInstFragment : public MCEncodedFragment {
+ virtual void anchor();
+
+ /// \brief Should this fragment be aligned to the end of a bundle?
+ bool AlignToBundleEnd;
+
+ SmallVector<char, 4> Contents;
+public:
+ MCCompactEncodedInstFragment(MCSectionData *SD = 0)
+ : MCEncodedFragment(FT_CompactEncodedInst, SD), AlignToBundleEnd(false)
+ {
+ }
+
+ virtual bool hasInstructions() const {
+ return true;
+ }
+
+ virtual SmallVectorImpl<char> &getContents() { return Contents; }
+ virtual const SmallVectorImpl<char> &getContents() const { return Contents; }
+
+ virtual bool alignToBundleEnd() const { return AlignToBundleEnd; }
+ virtual void setAlignToBundleEnd(bool V) { AlignToBundleEnd = V; }
static bool classof(const MCFragment *F) {
- return F->getKind() == MCFragment::FT_Data;
+ return F->getKind() == MCFragment::FT_CompactEncodedInst;
}
};
-// FIXME: This current incarnation of MCInstFragment doesn't make much sense, as
-// it is almost entirely a duplicate of MCDataFragment. If we decide to stick
-// with this approach (as opposed to making MCInstFragment a very light weight
-// object with just the MCInst and a code size, then we should just change
-// MCDataFragment to have an optional MCInst at its end.
-class MCInstFragment : public MCFragment {
+/// A relaxable fragment holds on to its MCInst, since it may need to be
+/// relaxed during the assembler layout and relaxation stage.
+///
+class MCRelaxableFragment : public MCEncodedFragmentWithFixups {
virtual void anchor();
/// Inst - The instruction this is a fragment for.
MCInst Inst;
- /// Code - Binary data for the currently encoded instruction.
- SmallString<8> Code;
+ /// Contents - Binary data for the currently encoded instruction.
+ SmallVector<char, 8> Contents;
/// Fixups - The list of fixups in this fragment.
SmallVector<MCFixup, 1> Fixups;
public:
- typedef SmallVectorImpl<MCFixup>::const_iterator const_fixup_iterator;
- typedef SmallVectorImpl<MCFixup>::iterator fixup_iterator;
-
-public:
- MCInstFragment(const MCInst &_Inst, MCSectionData *SD = 0)
- : MCFragment(FT_Inst, SD), Inst(_Inst) {
+ MCRelaxableFragment(const MCInst &_Inst, MCSectionData *SD = 0)
+ : MCEncodedFragmentWithFixups(FT_Relaxable, SD), Inst(_Inst) {
}
- /// @name Accessors
- /// @{
-
- SmallVectorImpl<char> &getCode() { return Code; }
- const SmallVectorImpl<char> &getCode() const { return Code; }
+ virtual SmallVectorImpl<char> &getContents() { return Contents; }
+ virtual const SmallVectorImpl<char> &getContents() const { return Contents; }
- unsigned getInstSize() const { return Code.size(); }
-
- MCInst &getInst() { return Inst; }
const MCInst &getInst() const { return Inst; }
-
void setInst(const MCInst& Value) { Inst = Value; }
- /// @}
- /// @name Fixup Access
- /// @{
+ SmallVectorImpl<MCFixup> &getFixups() {
+ return Fixups;
+ }
+
+ const SmallVectorImpl<MCFixup> &getFixups() const {
+ return Fixups;
+ }
- SmallVectorImpl<MCFixup> &getFixups() { return Fixups; }
- const SmallVectorImpl<MCFixup> &getFixups() const { return Fixups; }
+ virtual bool hasInstructions() const { return true; }
fixup_iterator fixup_begin() { return Fixups.begin(); }
const_fixup_iterator fixup_begin() const { return Fixups.begin(); }
@@ -203,12 +320,8 @@ public:
fixup_iterator fixup_end() {return Fixups.end();}
const_fixup_iterator fixup_end() const {return Fixups.end();}
- size_t fixup_size() const { return Fixups.size(); }
-
- /// @}
-
static bool classof(const MCFragment *F) {
- return F->getKind() == MCFragment::FT_Inst;
+ return F->getKind() == MCFragment::FT_Relaxable;
}
};
@@ -442,6 +555,12 @@ public:
typedef FragmentListType::const_reverse_iterator const_reverse_iterator;
typedef FragmentListType::reverse_iterator reverse_iterator;
+ /// \brief Express the state of bundle locked groups while emitting code.
+ enum BundleLockStateType {
+ NotBundleLocked,
+ BundleLocked,
+ BundleLockedAlignToEnd
+ };
private:
FragmentListType Fragments;
const MCSection *Section;
@@ -455,6 +574,13 @@ private:
/// Alignment - The maximum alignment seen in this section.
unsigned Alignment;
+ /// \brief Keeping track of bundle-locked state.
+ BundleLockStateType BundleLockState;
+
+ /// \brief We've seen a bundle_lock directive but not its first instruction
+ /// yet.
+ bool BundleGroupBeforeFirstInst;
+
/// @name Assembler Backend Data
/// @{
//
@@ -507,6 +633,26 @@ public:
bool empty() const { return Fragments.empty(); }
+ bool isBundleLocked() const {
+ return BundleLockState != NotBundleLocked;
+ }
+
+ BundleLockStateType getBundleLockState() const {
+ return BundleLockState;
+ }
+
+ void setBundleLockState(BundleLockStateType NewState) {
+ BundleLockState = NewState;
+ }
+
+ bool isBundleGroupBeforeFirstInst() const {
+ return BundleGroupBeforeFirstInst;
+ }
+
+ void setBundleGroupBeforeFirstInst(bool IsFirst) {
+ BundleGroupBeforeFirstInst = IsFirst;
+ }
+
void dump();
/// @}
@@ -703,6 +849,10 @@ private:
std::vector<IndirectSymbolData> IndirectSymbols;
std::vector<DataRegionData> DataRegions;
+
+ /// The list of linker options to propagate into the object file.
+ std::vector<std::vector<std::string> > LinkerOptions;
+
/// The set of function symbols for which a .thumb_func directive has
/// been seen.
//
@@ -712,10 +862,21 @@ private:
// refactoring too.
SmallPtrSet<const MCSymbol*, 64> ThumbFuncs;
+ /// \brief The bundle alignment size currently set in the assembler.
+ ///
+ /// By default it's 0, which means bundling is disabled.
+ unsigned BundleAlignSize;
+
unsigned RelaxAll : 1;
unsigned NoExecStack : 1;
unsigned SubsectionsViaSymbols : 1;
+ /// ELF specific e_header flags
+ // It would be good if there were an MCELFAssembler class to hold this.
+ // ELF header flags are used both by the integrated and standalone assemblers.
+ // Access to the flags is necessary in cases where assembler directives affect
+ // which flags to be set.
+ unsigned ELFHeaderEFlags;
private:
/// Evaluate a fixup to a relocatable expression and the value which should be
/// placed into the fixup.
@@ -736,20 +897,22 @@ 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(const MCFixup &Fixup, const MCInstFragment *DF,
+ bool fixupNeedsRelaxation(const MCFixup &Fixup, const MCRelaxableFragment *DF,
const MCAsmLayout &Layout) const;
/// Check whether the given fragment needs relaxation.
- bool fragmentNeedsRelaxation(const MCInstFragment *IF,
+ bool fragmentNeedsRelaxation(const MCRelaxableFragment *IF,
const MCAsmLayout &Layout) const;
- /// layoutOnce - Perform one layout iteration and return true if any offsets
+ /// \brief Perform one layout iteration and return true if any offsets
/// were adjusted.
bool layoutOnce(MCAsmLayout &Layout);
+ /// \brief Perform one layout iteration of the given section and return true
+ /// if any offsets were adjusted.
bool layoutSectionOnce(MCAsmLayout &Layout, MCSectionData &SD);
- bool relaxInstruction(MCAsmLayout &Layout, MCInstFragment &IF);
+ bool relaxInstruction(MCAsmLayout &Layout, MCRelaxableFragment &IF);
bool relaxLEB(MCAsmLayout &Layout, MCLEBFragment &IF);
@@ -791,6 +954,10 @@ public:
/// Flag a function symbol as the target of a .thumb_func directive.
void setIsThumbFunc(const MCSymbol *Func) { ThumbFuncs.insert(Func); }
+ /// ELF e_header flags
+ unsigned getELFHeaderEFlags() const {return ELFHeaderEFlags;}
+ void setELFHeaderEFlags(unsigned Flags) { ELFHeaderEFlags = Flags;}
+
public:
/// Construct a new assembler instance.
///
@@ -805,6 +972,10 @@ public:
raw_ostream &OS);
~MCAssembler();
+ /// Reuse an assembler instance
+ ///
+ void reset();
+
MCContext &getContext() const { return Context; }
MCAsmBackend &getBackend() const { return Backend; }
@@ -832,6 +1003,20 @@ public:
bool getNoExecStack() const { return NoExecStack; }
void setNoExecStack(bool Value) { NoExecStack = Value; }
+ bool isBundlingEnabled() const {
+ return BundleAlignSize != 0;
+ }
+
+ unsigned getBundleAlignSize() const {
+ return BundleAlignSize;
+ }
+
+ void setBundleAlignSize(unsigned Size) {
+ assert((Size == 0 || !(Size & (Size - 1))) &&
+ "Expect a power-of-two bundle align size");
+ BundleAlignSize = Size;
+ }
+
/// @name Section List Access
/// @{
@@ -889,6 +1074,14 @@ public:
size_t indirect_symbol_size() const { return IndirectSymbols.size(); }
/// @}
+ /// @name Linker Option List Access
+ /// @{
+
+ std::vector<std::vector<std::string> > &getLinkerOptions() {
+ return LinkerOptions;
+ }
+
+ /// @}
/// @name Data Region List Access
/// @{
diff --git a/include/llvm/MC/MCAtom.h b/include/llvm/MC/MCAtom.h
index 682cf7c..ae5bf0b 100644
--- a/include/llvm/MC/MCAtom.h
+++ b/include/llvm/MC/MCAtom.h
@@ -46,8 +46,8 @@ class MCAtom {
: Type(T), Parent(P), Begin(B), End(E) { }
public:
- bool isTextAtom() { return Type == TextAtom; }
- bool isDataAtom() { return Type == DataAtom; }
+ bool isTextAtom() const { return Type == TextAtom; }
+ bool isDataAtom() const { return Type == DataAtom; }
void addInst(const MCInst &I, uint64_t Address, unsigned Size);
void addData(const MCData &D);
diff --git a/include/llvm/MC/MCCodeEmitter.h b/include/llvm/MC/MCCodeEmitter.h
index 0574890..9bfa08e 100644
--- a/include/llvm/MC/MCCodeEmitter.h
+++ b/include/llvm/MC/MCCodeEmitter.h
@@ -29,6 +29,9 @@ protected: // Can only create subclasses.
public:
virtual ~MCCodeEmitter();
+ /// Lifetime management
+ virtual void reset() { }
+
/// EncodeInstruction - Encode the given \p Inst to bytes on the output
/// stream \p OS.
virtual void EncodeInstruction(const MCInst &Inst, raw_ostream &OS,
diff --git a/include/llvm/MC/MCContext.h b/include/llvm/MC/MCContext.h
index 5a8830c..0db3dee 100644
--- a/include/llvm/MC/MCContext.h
+++ b/include/llvm/MC/MCContext.h
@@ -10,13 +10,15 @@
#ifndef LLVM_MC_MCCONTEXT_H
#define LLVM_MC_MCCONTEXT_H
-#include "llvm/MC/SectionKind.h"
-#include "llvm/MC/MCDwarf.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
+#include "llvm/MC/MCDwarf.h"
+#include "llvm/MC/SectionKind.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/raw_ostream.h"
+#include <map>
#include <vector> // FIXME: Shouldn't be needed.
namespace llvm {
@@ -94,9 +96,19 @@ namespace llvm {
/// .secure_log_reset appearing between them.
bool SecureLogUsed;
+ /// The compilation directory to use for DW_AT_comp_dir.
+ std::string CompilationDir;
+
+ /// The main file name if passed in explicitly.
+ std::string MainFileName;
+
/// The dwarf file and directory tables from the dwarf .file directive.
- std::vector<MCDwarfFile *> MCDwarfFiles;
- std::vector<StringRef> MCDwarfDirs;
+ /// We now emit a line table for each compile unit. To reduce the prologue
+ /// size of each line table, the files and directories used by each compile
+ /// unit are separated.
+ typedef std::map<unsigned, SmallVector<MCDwarfFile *, 4> > MCDwarfFilesMap;
+ MCDwarfFilesMap MCDwarfFilesCUMap;
+ std::map<unsigned, SmallVector<StringRef, 4> > MCDwarfDirsCUMap;
/// The current dwarf line information from the last dwarf .loc directive.
MCDwarfLoc CurrentDwarfLoc;
@@ -123,6 +135,10 @@ namespace llvm {
/// non-empty.
StringRef DwarfDebugFlags;
+ /// The string to embed in as the dwarf AT_producer for the compile unit, if
+ /// non-empty.
+ StringRef DwarfDebugProducer;
+
/// Honor temporary labels, this is useful for debugging semantic
/// differences between temporary and non-temporary labels (primarily on
/// Darwin).
@@ -134,14 +150,22 @@ namespace llvm {
/// We need a deterministic iteration order, so we remember the order
/// the elements were added.
std::vector<const MCSection *> MCLineSectionOrder;
+ /// The Compile Unit ID that we are currently processing.
+ unsigned DwarfCompileUnitID;
+ /// The line table start symbol for each Compile Unit.
+ DenseMap<unsigned, MCSymbol *> MCLineTableSymbols;
void *MachOUniquingMap, *ELFUniquingMap, *COFFUniquingMap;
+ /// Do automatic reset in destructor
+ bool AutoReset;
+
MCSymbol *CreateSymbol(StringRef Name);
public:
explicit MCContext(const MCAsmInfo &MAI, const MCRegisterInfo &MRI,
- const MCObjectFileInfo *MOFI, const SourceMgr *Mgr = 0);
+ const MCObjectFileInfo *MOFI, const SourceMgr *Mgr = 0,
+ bool DoAutoReset = true);
~MCContext();
const SourceMgr *getSourceManager() const { return SrcMgr; }
@@ -154,6 +178,15 @@ namespace llvm {
void setAllowTemporaryLabels(bool Value) { AllowTemporaryLabels = Value; }
+ /// @name Module Lifetime Management
+ /// @{
+
+ /// reset - return object to right after construction state to prepare
+ /// to process a new module
+ void reset();
+
+ /// @}
+
/// @name Symbol Management
/// @{
@@ -235,21 +268,45 @@ namespace llvm {
/// @name Dwarf Management
/// @{
+ /// \brief Get the compilation directory for DW_AT_comp_dir
+ /// This can be overridden by clients which want to control the reported
+ /// compilation directory and have it be something other than the current
+ /// working directory.
+ const std::string &getCompilationDir() const { return CompilationDir; }
+
+ /// \brief Set the compilation directory for DW_AT_comp_dir
+ /// Override the default (CWD) compilation directory.
+ void setCompilationDir(StringRef S) { CompilationDir = S.str(); }
+
+ /// \brief Get the main file name for use in error messages and debug
+ /// info. This can be set to ensure we've got the correct file name
+ /// after preprocessing or for -save-temps.
+ const std::string &getMainFileName() const { return MainFileName; }
+
+ /// \brief Set the main file name and override the default.
+ void setMainFileName(StringRef S) { MainFileName = S.str(); }
+
/// GetDwarfFile - creates an entry in the dwarf file and directory tables.
unsigned GetDwarfFile(StringRef Directory, StringRef FileName,
- unsigned FileNumber);
+ unsigned FileNumber, unsigned CUID);
- bool isValidDwarfFileNumber(unsigned FileNumber);
+ bool isValidDwarfFileNumber(unsigned FileNumber, unsigned CUID = 0);
bool hasDwarfFiles() const {
- return !MCDwarfFiles.empty();
+ // Traverse MCDwarfFilesCUMap and check whether each entry is empty.
+ MCDwarfFilesMap::const_iterator MapB, MapE;
+ for (MapB = MCDwarfFilesCUMap.begin(), MapE = MCDwarfFilesCUMap.end();
+ MapB != MapE; MapB++)
+ if (!MapB->second.empty())
+ return true;
+ return false;
}
- const std::vector<MCDwarfFile *> &getMCDwarfFiles() {
- return MCDwarfFiles;
+ const SmallVectorImpl<MCDwarfFile *> &getMCDwarfFiles(unsigned CUID = 0) {
+ return MCDwarfFilesCUMap[CUID];
}
- const std::vector<StringRef> &getMCDwarfDirs() {
- return MCDwarfDirs;
+ const SmallVectorImpl<StringRef> &getMCDwarfDirs(unsigned CUID = 0) {
+ return MCDwarfDirsCUMap[CUID];
}
const DenseMap<const MCSection *, MCLineSection *>
@@ -263,6 +320,25 @@ namespace llvm {
MCLineSections[Sec] = Line;
MCLineSectionOrder.push_back(Sec);
}
+ unsigned getDwarfCompileUnitID() {
+ return DwarfCompileUnitID;
+ }
+ void setDwarfCompileUnitID(unsigned CUIndex) {
+ DwarfCompileUnitID = CUIndex;
+ }
+ const DenseMap<unsigned, MCSymbol *> &getMCLineTableSymbols() const {
+ return MCLineTableSymbols;
+ }
+ MCSymbol *getMCLineTableSymbol(unsigned ID) const {
+ DenseMap<unsigned, MCSymbol *>::const_iterator CIter =
+ MCLineTableSymbols.find(ID);
+ if (CIter == MCLineTableSymbols.end())
+ return NULL;
+ return CIter->second;
+ }
+ void setMCLineTableSymbol(MCSymbol *Sym, unsigned ID) {
+ MCLineTableSymbols[ID] = Sym;
+ }
/// setCurrentDwarfLoc - saves the information from the currently parsed
/// dwarf .loc directive and sets DwarfLocSeen. When the next instruction
@@ -309,6 +385,9 @@ namespace llvm {
void setDwarfDebugFlags(StringRef S) { DwarfDebugFlags = S; }
StringRef getDwarfDebugFlags() { return DwarfDebugFlags; }
+ void setDwarfDebugProducer(StringRef S) { DwarfDebugProducer = S; }
+ StringRef getDwarfDebugProducer() { return DwarfDebugProducer; }
+
/// @}
char *getSecureLogFile() { return SecureLogFile; }
diff --git a/include/llvm/MC/MCDisassembler.h b/include/llvm/MC/MCDisassembler.h
index 53a9ce0..36fbcb0 100644
--- a/include/llvm/MC/MCDisassembler.h
+++ b/include/llvm/MC/MCDisassembler.h
@@ -6,11 +6,11 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-#ifndef MCDISASSEMBLER_H
-#define MCDISASSEMBLER_H
+#ifndef LLVM_MC_MCDISASSEMBLER_H
+#define LLVM_MC_MCDISASSEMBLER_H
-#include "llvm/Support/DataTypes.h"
#include "llvm-c/Disassembler.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
@@ -20,8 +20,6 @@ class MemoryObject;
class raw_ostream;
class MCContext;
-struct EDInstInfo;
-
/// MCDisassembler - Superclass for all disassemblers. Consumes a memory region
/// and provides an array of assembly instructions.
class MCDisassembler {
@@ -84,14 +82,6 @@ public:
raw_ostream &vStream,
raw_ostream &cStream) const = 0;
- /// getEDInfo - Returns the enhanced instruction information corresponding to
- /// the disassembler.
- ///
- /// @return - An array of instruction information, with one entry for
- /// each MCInst opcode this disassembler returns.
- /// NULL if there is no info for this target.
- virtual const EDInstInfo *getEDInfo() const { return (EDInstInfo*)0; }
-
private:
//
// Hooks for symbolic disassembly via the public 'C' interface.
diff --git a/include/llvm/MC/MCDwarf.h b/include/llvm/MC/MCDwarf.h
index 8fc437f..1a392e8 100644
--- a/include/llvm/MC/MCDwarf.h
+++ b/include/llvm/MC/MCDwarf.h
@@ -16,10 +16,10 @@
#define LLVM_MC_MCDWARF_H
#include "llvm/ADT/StringRef.h"
-#include "llvm/MC/MachineLocation.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/Support/Dwarf.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/Support/Dwarf.h"
+#include "llvm/Support/raw_ostream.h"
+#include <map>
#include <vector>
namespace llvm {
@@ -187,29 +187,43 @@ namespace llvm {
MCLineSection() {}
// addLineEntry - adds an entry to this MCLineSection's line entries
- void addLineEntry(const MCLineEntry &LineEntry) {
- MCLineEntries.push_back(LineEntry);
+ void addLineEntry(const MCLineEntry &LineEntry, unsigned CUID) {
+ MCLineDivisions[CUID].push_back(LineEntry);
}
typedef std::vector<MCLineEntry> MCLineEntryCollection;
typedef MCLineEntryCollection::iterator iterator;
typedef MCLineEntryCollection::const_iterator const_iterator;
+ typedef std::map<unsigned, MCLineEntryCollection> MCLineDivisionMap;
private:
- MCLineEntryCollection MCLineEntries;
+ // A collection of MCLineEntry for each Compile Unit ID.
+ MCLineDivisionMap MCLineDivisions;
public:
- const MCLineEntryCollection *getMCLineEntries() const {
- return &MCLineEntries;
+ // Returns whether MCLineSection contains entries for a given Compile
+ // Unit ID.
+ bool containEntriesForID(unsigned CUID) const {
+ return MCLineDivisions.count(CUID);
+ }
+ // Returns the collection of MCLineEntry for a given Compile Unit ID.
+ const MCLineEntryCollection &getMCLineEntries(unsigned CUID) const {
+ MCLineDivisionMap::const_iterator CIter = MCLineDivisions.find(CUID);
+ assert(CIter != MCLineDivisions.end());
+ return CIter->second;
}
};
class MCDwarfFileTable {
public:
//
- // This emits the Dwarf file and the line tables.
+ // This emits the Dwarf file and the line tables for all Compile Units.
//
static const MCSymbol *Emit(MCStreamer *MCOS);
+ //
+ // This emits the Dwarf file and the line tables for a given Compile Unit.
+ //
+ static const MCSymbol *EmitCU(MCStreamer *MCOS, unsigned ID);
};
class MCDwarfLineAddr {
@@ -266,42 +280,115 @@ namespace llvm {
class MCCFIInstruction {
public:
- enum OpType { SameValue, RememberState, RestoreState, Move, RelMove, Escape,
- Restore};
+ enum OpType { OpSameValue, OpRememberState, OpRestoreState, OpOffset,
+ OpDefCfaRegister, OpDefCfaOffset, OpDefCfa, OpRelOffset,
+ OpAdjustCfaOffset, OpEscape, OpRestore, OpUndefined,
+ OpRegister };
private:
OpType Operation;
MCSymbol *Label;
- // Move to & from location.
- MachineLocation Destination;
- MachineLocation Source;
+ unsigned Register;
+ union {
+ int Offset;
+ unsigned Register2;
+ };
std::vector<char> Values;
+
+ MCCFIInstruction(OpType Op, MCSymbol *L, unsigned R, int O, StringRef V) :
+ Operation(Op), Label(L), Register(R), Offset(O),
+ Values(V.begin(), V.end()) {
+ assert(Op != OpRegister);
+ }
+
+ MCCFIInstruction(OpType Op, MCSymbol *L, unsigned R1, unsigned R2) :
+ Operation(Op), Label(L), Register(R1), Register2(R2) {
+ assert(Op == OpRegister);
+ }
+
public:
- MCCFIInstruction(OpType Op, MCSymbol *L)
- : Operation(Op), Label(L) {
- assert(Op == RememberState || Op == RestoreState);
+ static MCCFIInstruction
+ createOffset(MCSymbol *L, unsigned Register, int Offset) {
+ return MCCFIInstruction(OpOffset, L, Register, Offset, "");
+ }
+
+ static MCCFIInstruction
+ createDefCfaRegister(MCSymbol *L, unsigned Register) {
+ return MCCFIInstruction(OpDefCfaRegister, L, Register, 0, "");
+ }
+
+ static MCCFIInstruction createDefCfaOffset(MCSymbol *L, int Offset) {
+ return MCCFIInstruction(OpDefCfaOffset, L, 0, -Offset, "");
+ }
+
+ static MCCFIInstruction
+ createDefCfa(MCSymbol *L, unsigned Register, int Offset) {
+ return MCCFIInstruction(OpDefCfa, L, Register, -Offset, "");
+ }
+
+ static MCCFIInstruction createUndefined(MCSymbol *L, unsigned Register) {
+ return MCCFIInstruction(OpUndefined, L, Register, 0, "");
}
- MCCFIInstruction(OpType Op, MCSymbol *L, unsigned Register)
- : Operation(Op), Label(L), Destination(Register) {
- assert(Op == SameValue || Op == Restore);
+
+ static MCCFIInstruction createRestore(MCSymbol *L, unsigned Register) {
+ return MCCFIInstruction(OpRestore, L, Register, 0, "");
+ }
+
+ static MCCFIInstruction createSameValue(MCSymbol *L, unsigned Register) {
+ return MCCFIInstruction(OpSameValue, L, Register, 0, "");
+ }
+
+ static MCCFIInstruction createRestoreState(MCSymbol *L) {
+ return MCCFIInstruction(OpRestoreState, L, 0, 0, "");
}
- MCCFIInstruction(MCSymbol *L, const MachineLocation &D,
- const MachineLocation &S)
- : Operation(Move), Label(L), Destination(D), Source(S) {
+
+ static MCCFIInstruction createRememberState(MCSymbol *L) {
+ return MCCFIInstruction(OpRememberState, L, 0, 0, "");
+ }
+
+ static MCCFIInstruction
+ createRelOffset(MCSymbol *L, unsigned Register, int Offset) {
+ return MCCFIInstruction(OpRelOffset, L, Register, Offset, "");
+ }
+
+ static MCCFIInstruction
+ createAdjustCfaOffset(MCSymbol *L, int Adjustment) {
+ return MCCFIInstruction(OpAdjustCfaOffset, L, 0, Adjustment, "");
}
- MCCFIInstruction(OpType Op, MCSymbol *L, const MachineLocation &D,
- const MachineLocation &S)
- : Operation(Op), Label(L), Destination(D), Source(S) {
- assert(Op == RelMove);
+
+ static MCCFIInstruction createEscape(MCSymbol *L, StringRef Vals) {
+ return MCCFIInstruction(OpEscape, L, 0, 0, Vals);
}
- MCCFIInstruction(OpType Op, MCSymbol *L, StringRef Vals)
- : Operation(Op), Label(L), Values(Vals.begin(), Vals.end()) {
- assert(Op == Escape);
+
+ static MCCFIInstruction
+ createRegister(MCSymbol *L, unsigned Register1, unsigned Register2) {
+ return MCCFIInstruction(OpRegister, L, Register1, Register2);
}
+
OpType getOperation() const { return Operation; }
MCSymbol *getLabel() const { return Label; }
- const MachineLocation &getDestination() const { return Destination; }
- const MachineLocation &getSource() const { return Source; }
+
+ unsigned getRegister() const {
+ assert(Operation == OpDefCfa || Operation == OpOffset ||
+ Operation == OpRestore || Operation == OpUndefined ||
+ Operation == OpSameValue || Operation == OpDefCfaRegister ||
+ Operation == OpRelOffset || Operation == OpRegister);
+ return Register;
+ }
+
+ unsigned getRegister2() const {
+ assert(Operation == OpRegister);
+ return Register2;
+ }
+
+ int getOffset() const {
+ assert(Operation == OpDefCfa || Operation == OpOffset ||
+ Operation == OpRelOffset || Operation == OpDefCfaOffset ||
+ Operation == OpAdjustCfaOffset);
+ return Offset;
+ }
+
const StringRef getValues() const {
+ assert(Operation == OpEscape);
return StringRef(&Values[0], Values.size());
}
};
diff --git a/include/llvm/MC/MCELF.h b/include/llvm/MC/MCELF.h
new file mode 100644
index 0000000..7e59911
--- /dev/null
+++ b/include/llvm/MC/MCELF.h
@@ -0,0 +1,37 @@
+//===- lib/MC/MCELF.h - ELF MC --------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains some support functions used by the ELF Streamer and
+// ObjectWriter.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCELF_H
+#define LLVM_MC_MCELF_H
+
+#include "llvm/MC/MCExpr.h"
+
+namespace llvm {
+class MCSymbolData;
+
+class MCELF {
+ public:
+ static void SetBinding(MCSymbolData &SD, unsigned Binding);
+ static unsigned GetBinding(const MCSymbolData &SD);
+ static void SetType(MCSymbolData &SD, unsigned Type);
+ static unsigned GetType(const MCSymbolData &SD);
+ static void SetVisibility(MCSymbolData &SD, unsigned Visibility);
+ static unsigned GetVisibility(MCSymbolData &SD);
+ static void setOther(MCSymbolData &SD, unsigned Other);
+ static unsigned getOther(MCSymbolData &SD);
+};
+
+}
+
+#endif
diff --git a/include/llvm/MC/MCELFObjectWriter.h b/include/llvm/MC/MCELFObjectWriter.h
index 38cdc72..a59776d 100644
--- a/include/llvm/MC/MCELFObjectWriter.h
+++ b/include/llvm/MC/MCELFObjectWriter.h
@@ -79,7 +79,6 @@ public:
virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
bool IsPCRel, bool IsRelocWithSymbol,
int64_t Addend) const = 0;
- virtual unsigned getEFlags() const;
virtual const MCSymbol *ExplicitRelSym(const MCAssembler &Asm,
const MCValue &Target,
const MCFragment &F,
diff --git a/include/llvm/MC/MCELFStreamer.h b/include/llvm/MC/MCELFStreamer.h
new file mode 100644
index 0000000..6fb2d22
--- /dev/null
+++ b/include/llvm/MC/MCELFStreamer.h
@@ -0,0 +1,125 @@
+//===- MCELFStreamer.h - MCStreamer ELF Object File Interface ---*- 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_MCELFSTREAMER_H
+#define LLVM_MC_MCELFSTREAMER_H
+
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/MC/MCDirectives.h"
+#include "llvm/MC/MCObjectStreamer.h"
+#include "llvm/MC/SectionKind.h"
+#include "llvm/Support/DataTypes.h"
+#include <vector>
+
+namespace llvm {
+class MCAsmBackend;
+class MCAssembler;
+class MCCodeEmitter;
+class MCExpr;
+class MCInst;
+class MCSymbol;
+class MCSymbolData;
+class raw_ostream;
+
+class MCELFStreamer : public MCObjectStreamer {
+protected:
+ MCELFStreamer(StreamerKind Kind, MCContext &Context, MCAsmBackend &TAB,
+ raw_ostream &OS, MCCodeEmitter *Emitter)
+ : MCObjectStreamer(Kind, Context, TAB, OS, Emitter) {}
+
+public:
+ MCELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS,
+ MCCodeEmitter *Emitter)
+ : MCObjectStreamer(SK_ELFStreamer, Context, TAB, OS, Emitter) {}
+
+ MCELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS,
+ MCCodeEmitter *Emitter, MCAssembler *Assembler)
+ : MCObjectStreamer(SK_ELFStreamer, Context, TAB, OS, Emitter,
+ Assembler) {}
+
+ virtual ~MCELFStreamer();
+
+ /// @name MCStreamer Interface
+ /// @{
+
+ virtual void InitSections();
+ virtual void InitToTextSection();
+ virtual void ChangeSection(const MCSection *Section);
+ virtual void EmitLabel(MCSymbol *Symbol);
+ virtual void EmitDebugLabel(MCSymbol *Symbol);
+ virtual void EmitAssemblerFlag(MCAssemblerFlag Flag);
+ virtual void EmitThumbFunc(MCSymbol *Func);
+ virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol);
+ virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute);
+ virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue);
+ virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+ unsigned ByteAlignment);
+ virtual void BeginCOFFSymbolDef(const MCSymbol *Symbol);
+ virtual void EmitCOFFSymbolStorageClass(int StorageClass);
+ virtual void EmitCOFFSymbolType(int Type);
+ virtual void EndCOFFSymbolDef();
+
+ virtual MCSymbolData &getOrCreateSymbolData(MCSymbol *Symbol);
+
+ virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value);
+
+ virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+ unsigned ByteAlignment);
+
+ virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0,
+ uint64_t Size = 0, unsigned ByteAlignment = 0);
+ virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
+ uint64_t Size, unsigned ByteAlignment = 0);
+ virtual void EmitValueImpl(const MCExpr *Value, unsigned Size,
+ unsigned AddrSpace);
+
+ virtual void EmitFileDirective(StringRef Filename);
+
+ virtual void EmitTCEntry(const MCSymbol &S);
+
+ virtual void EmitValueToAlignment(unsigned, int64_t, unsigned, unsigned);
+
+ virtual void FinishImpl();
+ /// @}
+
+ static bool classof(const MCStreamer *S) {
+ return S->getKind() == SK_ELFStreamer || S->getKind() == SK_ARMELFStreamer;
+ }
+
+private:
+ virtual void EmitInstToFragment(const MCInst &Inst);
+ virtual void EmitInstToData(const MCInst &Inst);
+
+ virtual void EmitBundleAlignMode(unsigned AlignPow2);
+ virtual void EmitBundleLock(bool AlignToEnd);
+ virtual void EmitBundleUnlock();
+
+ void fixSymbolsInTLSFixups(const MCExpr *expr);
+
+ struct LocalCommon {
+ MCSymbolData *SD;
+ uint64_t Size;
+ unsigned ByteAlignment;
+ };
+
+ std::vector<LocalCommon> LocalCommons;
+
+ SmallPtrSet<MCSymbol *, 16> BindingExplicitlySet;
+
+
+ void SetSection(StringRef Section, unsigned Type, unsigned Flags,
+ SectionKind Kind);
+ void SetSectionData();
+ void SetSectionText();
+ void SetSectionBss();
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/MC/MCExpr.h b/include/llvm/MC/MCExpr.h
index 1007aa5..b5bfed1 100644
--- a/include/llvm/MC/MCExpr.h
+++ b/include/llvm/MC/MCExpr.h
@@ -160,6 +160,7 @@ public:
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,
@@ -168,15 +169,29 @@ public:
VK_ARM_GOTTPOFF,
VK_ARM_TARGET1,
VK_ARM_TARGET2,
+ VK_ARM_PREL31,
VK_PPC_TOC, // TOC base
VK_PPC_TOC_ENTRY, // TOC entry
VK_PPC_DARWIN_HA16, // ha16(symbol)
VK_PPC_DARWIN_LO16, // lo16(symbol)
VK_PPC_GAS_HA16, // symbol@ha
- VK_PPC_GAS_LO16, // symbol@l
+ VK_PPC_GAS_LO16, // symbol@l
VK_PPC_TPREL16_HA, // symbol@tprel@ha
VK_PPC_TPREL16_LO, // symbol@tprel@l
+ VK_PPC_DTPREL16_HA, // symbol@dtprel@ha
+ VK_PPC_DTPREL16_LO, // symbol@dtprel@l
+ VK_PPC_TOC16_HA, // symbol@toc@ha
+ VK_PPC_TOC16_LO, // symbol@toc@l
+ VK_PPC_GOT_TPREL16_HA, // symbol@got@tprel@ha
+ VK_PPC_GOT_TPREL16_LO, // symbol@got@tprel@l
+ VK_PPC_TLS, // symbol@tls
+ VK_PPC_GOT_TLSGD16_HA, // symbol@got@tlsgd@ha
+ VK_PPC_GOT_TLSGD16_LO, // symbol@got@tlsgd@l
+ VK_PPC_TLSGD, // symbol@tlsgd
+ VK_PPC_GOT_TLSLD16_HA, // symbol@got@tlsld@ha
+ VK_PPC_GOT_TLSLD16_LO, // symbol@got@tlsld@l
+ VK_PPC_TLSLD, // symbol@tlsld
VK_Mips_GPREL,
VK_Mips_GOT_CALL,
@@ -457,6 +472,8 @@ public:
virtual void AddValueSymbols(MCAssembler *) const = 0;
virtual const MCSection *FindAssociatedSection() const = 0;
+ virtual void fixELFSymbolsInTLSFixups(MCAssembler &) const = 0;
+
static bool classof(const MCExpr *E) {
return E->getKind() == MCExpr::Target;
}
diff --git a/include/llvm/MC/MCFixedLenDisassembler.h b/include/llvm/MC/MCFixedLenDisassembler.h
index 22b3c32..ad99943 100644
--- a/include/llvm/MC/MCFixedLenDisassembler.h
+++ b/include/llvm/MC/MCFixedLenDisassembler.h
@@ -8,8 +8,8 @@
//===----------------------------------------------------------------------===//
// Fixed length disassembler decoder state machine driver.
//===----------------------------------------------------------------------===//
-#ifndef MCFIXEDLENDISASSEMBLER_H
-#define MCFIXEDLENDISASSEMBLER_H
+#ifndef LLVM_MC_MCFIXEDLENDISASSEMBLER_H
+#define LLVM_MC_MCFIXEDLENDISASSEMBLER_H
namespace llvm {
diff --git a/include/llvm/MC/MCInstBuilder.h b/include/llvm/MC/MCInstBuilder.h
new file mode 100644
index 0000000..c5acb26
--- /dev/null
+++ b/include/llvm/MC/MCInstBuilder.h
@@ -0,0 +1,68 @@
+//===-- llvm/MC/MCInstBuilder.h - Simplify creation of MCInsts --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the MCInstBuilder class for convenient creation of
+// MCInsts.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCINSTBUILDER_H
+#define LLVM_MC_MCINSTBUILDER_H
+
+#include "llvm/MC/MCInst.h"
+
+namespace llvm {
+
+class MCInstBuilder {
+ MCInst Inst;
+
+public:
+ /// \brief Create a new MCInstBuilder for an MCInst with a specific opcode.
+ MCInstBuilder(unsigned Opcode) {
+ Inst.setOpcode(Opcode);
+ }
+
+ /// \brief Add a new register operand.
+ MCInstBuilder &addReg(unsigned Reg) {
+ Inst.addOperand(MCOperand::CreateReg(Reg));
+ return *this;
+ }
+
+ /// \brief Add a new integer immediate operand.
+ MCInstBuilder &addImm(int64_t Val) {
+ Inst.addOperand(MCOperand::CreateImm(Val));
+ return *this;
+ }
+
+ /// \brief Add a new floating point immediate operand.
+ MCInstBuilder &addFPImm(double Val) {
+ Inst.addOperand(MCOperand::CreateFPImm(Val));
+ return *this;
+ }
+
+ /// \brief Add a new MCExpr operand.
+ MCInstBuilder &addExpr(const MCExpr *Val) {
+ Inst.addOperand(MCOperand::CreateExpr(Val));
+ return *this;
+ }
+
+ /// \brief Add a new MCInst operand.
+ MCInstBuilder &addInst(const MCInst *Val) {
+ Inst.addOperand(MCOperand::CreateInst(Val));
+ return *this;
+ }
+
+ operator MCInst&() {
+ return Inst;
+ }
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/MC/MCInstPrinter.h b/include/llvm/MC/MCInstPrinter.h
index 3b9420a..a18cbd9 100644
--- a/include/llvm/MC/MCInstPrinter.h
+++ b/include/llvm/MC/MCInstPrinter.h
@@ -10,6 +10,9 @@
#ifndef LLVM_MC_MCINSTPRINTER_H
#define LLVM_MC_MCINSTPRINTER_H
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/Format.h"
+
namespace llvm {
class MCInst;
class raw_ostream;
@@ -36,13 +39,16 @@ protected:
/// True if we are printing marked up assembly.
bool UseMarkup;
+ /// True if we are printing immediates as hex.
+ bool PrintImmHex;
+
/// Utility function for printing annotations.
void printAnnotation(raw_ostream &OS, StringRef Annot);
public:
MCInstPrinter(const MCAsmInfo &mai, const MCInstrInfo &mii,
const MCRegisterInfo &mri)
: CommentStream(0), MAI(mai), MII(mii), MRI(mri), AvailableFeatures(0),
- UseMarkup(0) {}
+ UseMarkup(0), PrintImmHex(0) {}
virtual ~MCInstPrinter();
@@ -70,6 +76,12 @@ public:
/// Utility functions to make adding mark ups simpler.
StringRef markup(StringRef s) const;
StringRef markup(StringRef a, StringRef b) const;
+
+ bool getPrintImmHex() const { return PrintImmHex; }
+ void setPrintImmHex(bool Value) { PrintImmHex = Value; }
+
+ /// Utility function to print immediates in decimal or hex.
+ format_object1<int64_t> formatImm(const int64_t Value) const;
};
} // namespace llvm
diff --git a/include/llvm/MC/MCInstrDesc.h b/include/llvm/MC/MCInstrDesc.h
index 02383f8..9b5415a 100644
--- a/include/llvm/MC/MCInstrDesc.h
+++ b/include/llvm/MC/MCInstrDesc.h
@@ -15,6 +15,8 @@
#ifndef LLVM_MC_MCINSTRDESC_H
#define LLVM_MC_MCINSTRDESC_H
+#include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/Support/DataTypes.h"
namespace llvm {
@@ -144,7 +146,7 @@ public:
const uint16_t *ImplicitDefs; // Registers implicitly defined by this instr
const MCOperandInfo *OpInfo; // 'NumOperands' entries about operands
- /// getOperandConstraint - Returns the value of the specific constraint if
+ /// \brief Returns the value of the specific constraint if
/// it is set. Returns -1 if it is not set.
int getOperandConstraint(unsigned OpNum,
MCOI::OperandConstraint Constraint) const {
@@ -156,12 +158,12 @@ public:
return -1;
}
- /// getOpcode - Return the opcode number for this descriptor.
+ /// \brief Return the opcode number for this descriptor.
unsigned getOpcode() const {
return Opcode;
}
- /// getNumOperands - Return the number of declared MachineOperands for this
+ /// \brief Return the number of declared MachineOperands for this
/// MachineInstruction. Note that variadic (isVariadic() returns true)
/// instructions may have additional operands at the end of the list, and note
/// that the machine instruction may include implicit register def/uses as
@@ -170,7 +172,7 @@ public:
return NumOperands;
}
- /// getNumDefs - Return the number of MachineOperands that are register
+ /// \brief Return the number of MachineOperands that are register
/// definitions. Register definitions always occur at the start of the
/// machine operand list. This is the number of "outs" in the .td file,
/// and does not include implicit defs.
@@ -178,11 +180,10 @@ public:
return NumDefs;
}
- /// getFlags - Return flags of this instruction.
- ///
+ /// \brief Return flags of this instruction.
unsigned getFlags() const { return Flags; }
- /// isVariadic - Return true if this instruction can have a variable number of
+ /// \brief Return true if this instruction can have a variable number of
/// operands. In this case, the variable operands will be after the normal
/// operands but before the implicit definitions and uses (if any are
/// present).
@@ -190,35 +191,37 @@ public:
return Flags & (1 << MCID::Variadic);
}
- /// hasOptionalDef - Set if this instruction has an optional definition, e.g.
+ /// \brief Set if this instruction has an optional definition, e.g.
/// ARM instructions which can set condition code if 's' bit is set.
bool hasOptionalDef() const {
return Flags & (1 << MCID::HasOptionalDef);
}
- /// isPseudo - Return true if this is a pseudo instruction that doesn't
+ /// \brief Return true if this is a pseudo instruction that doesn't
/// correspond to a real machine instruction.
///
bool isPseudo() const {
return Flags & (1 << MCID::Pseudo);
}
+ /// \brief Return true if the instruction is a return.
bool isReturn() const {
return Flags & (1 << MCID::Return);
}
+ /// \brief Return true if the instruction is a call.
bool isCall() const {
return Flags & (1 << MCID::Call);
}
- /// isBarrier - Returns true if the specified instruction stops control flow
+ /// \brief Returns true if the specified instruction stops control flow
/// from executing the instruction immediately following it. Examples include
/// unconditional branches and return instructions.
bool isBarrier() const {
return Flags & (1 << MCID::Barrier);
}
- /// isTerminator - Returns true if this instruction part of the terminator for
+ /// \brief Returns true if this instruction part of the terminator for
/// a basic block. Typically this is things like return and branch
/// instructions.
///
@@ -228,7 +231,7 @@ public:
return Flags & (1 << MCID::Terminator);
}
- /// isBranch - Returns true if this is a conditional, unconditional, or
+ /// \brief Returns true if this is a conditional, unconditional, or
/// indirect branch. Predicates below can be used to discriminate between
/// these cases, and the TargetInstrInfo::AnalyzeBranch method can be used to
/// get more information.
@@ -236,13 +239,13 @@ public:
return Flags & (1 << MCID::Branch);
}
- /// isIndirectBranch - Return true if this is an indirect branch, such as a
+ /// \brief Return true if this is an indirect branch, such as a
/// branch through a register.
bool isIndirectBranch() const {
return Flags & (1 << MCID::IndirectBranch);
}
- /// isConditionalBranch - Return true if this is a branch which may fall
+ /// \brief Return true if this is a branch which may fall
/// through to the next instruction or may transfer control flow to some other
/// block. The TargetInstrInfo::AnalyzeBranch method can be used to get more
/// information about this branch.
@@ -250,7 +253,7 @@ public:
return isBranch() & !isBarrier() & !isIndirectBranch();
}
- /// isUnconditionalBranch - Return true if this is a branch which always
+ /// \brief Return true if this is a branch which always
/// transfers control flow to some other block. The
/// TargetInstrInfo::AnalyzeBranch method can be used to get more information
/// about this branch.
@@ -258,38 +261,47 @@ public:
return isBranch() & isBarrier() & !isIndirectBranch();
}
- // isPredicable - Return true if this instruction has a predicate operand that
- // controls execution. It may be set to 'always', or may be set to other
- /// values. There are various methods in TargetInstrInfo that can be used to
+ /// \brief Return true if this is a branch or an instruction which directly
+ /// writes to the program counter. Considered 'may' affect rather than
+ /// 'does' affect as things like predication are not taken into account.
+ bool mayAffectControlFlow(const MCInst &MI, const MCRegisterInfo &RI) const {
+ if (isBranch() || isCall() || isReturn() || isIndirectBranch())
+ return true;
+ unsigned PC = RI.getProgramCounter();
+ if (PC == 0) return false;
+ return hasDefOfPhysReg(MI, PC, RI);
+ }
+
+ /// \brief Return true if this instruction has a predicate operand
+ /// that controls execution. It may be set to 'always', or may be set to other
+ /// values. There are various methods in TargetInstrInfo that can be used to
/// control and modify the predicate in this instruction.
bool isPredicable() const {
return Flags & (1 << MCID::Predicable);
}
- /// isCompare - Return true if this instruction is a comparison.
+ /// \brief Return true if this instruction is a comparison.
bool isCompare() const {
return Flags & (1 << MCID::Compare);
}
- /// isMoveImmediate - Return true if this instruction is a move immediate
+ /// \brief Return true if this instruction is a move immediate
/// (including conditional moves) instruction.
bool isMoveImmediate() const {
return Flags & (1 << MCID::MoveImm);
}
- /// isBitcast - Return true if this instruction is a bitcast instruction.
- ///
+ /// \brief Return true if this instruction is a bitcast instruction.
bool isBitcast() const {
return Flags & (1 << MCID::Bitcast);
}
- /// isSelect - Return true if this is a select instruction.
- ///
+ /// \brief Return true if this is a select instruction.
bool isSelect() const {
return Flags & (1 << MCID::Select);
}
- /// isNotDuplicable - Return true if this instruction cannot be safely
+ /// \brief Return true if this instruction cannot be safely
/// duplicated. For example, if the instruction has a unique labels attached
/// to it, duplicating it would cause multiple definition errors.
bool isNotDuplicable() const {
@@ -318,7 +330,7 @@ public:
// Side Effect Analysis
//===--------------------------------------------------------------------===//
- /// mayLoad - Return true if this instruction could possibly read memory.
+ /// \brief Return true if this instruction could possibly read memory.
/// Instructions with this flag set are not necessarily simple load
/// instructions, they may load a value and modify it, for example.
bool mayLoad() const {
@@ -326,7 +338,7 @@ public:
}
- /// mayStore - Return true if this instruction could possibly modify memory.
+ /// \brief Return true if this instruction could possibly modify memory.
/// Instructions with this flag set are not necessarily simple store
/// instructions, they may store a modified value based on their operands, or
/// may not actually modify anything, for example.
@@ -459,8 +471,7 @@ public:
return ImplicitUses;
}
- /// getNumImplicitUses - Return the number of implicit uses this instruction
- /// has.
+ /// \brief Return the number of implicit uses this instruction has.
unsigned getNumImplicitUses() const {
if (ImplicitUses == 0) return 0;
unsigned i = 0;
@@ -482,8 +493,7 @@ public:
return ImplicitDefs;
}
- /// getNumImplicitDefs - Return the number of implicit defs this instruction
- /// has.
+ /// \brief Return the number of implicit defs this instruct has.
unsigned getNumImplicitDefs() const {
if (ImplicitDefs == 0) return 0;
unsigned i = 0;
@@ -491,7 +501,7 @@ public:
return i;
}
- /// hasImplicitUseOfPhysReg - Return true if this instruction implicitly
+ /// \brief Return true if this instruction implicitly
/// uses the specified physical register.
bool hasImplicitUseOfPhysReg(unsigned Reg) const {
if (const uint16_t *ImpUses = ImplicitUses)
@@ -500,31 +510,43 @@ public:
return false;
}
- /// hasImplicitDefOfPhysReg - Return true if this instruction implicitly
+ /// \brief Return true if this instruction implicitly
/// defines the specified physical register.
- bool hasImplicitDefOfPhysReg(unsigned Reg) const {
+ bool hasImplicitDefOfPhysReg(unsigned Reg,
+ const MCRegisterInfo *MRI = 0) const {
if (const uint16_t *ImpDefs = ImplicitDefs)
for (; *ImpDefs; ++ImpDefs)
- if (*ImpDefs == Reg) return true;
+ if (*ImpDefs == Reg || (MRI && MRI->isSubRegister(Reg, *ImpDefs)))
+ return true;
return false;
}
- /// getSchedClass - Return the scheduling class for this instruction. The
+ /// \brief Return true if this instruction defines the specified physical
+ /// register, either explicitly or implicitly.
+ bool hasDefOfPhysReg(const MCInst &MI, unsigned Reg,
+ const MCRegisterInfo &RI) const {
+ for (int i = 0, e = NumDefs; i != e; ++i)
+ if (MI.getOperand(i).isReg() &&
+ RI.isSubRegisterEq(Reg, MI.getOperand(i).getReg()))
+ return true;
+ return hasImplicitDefOfPhysReg(Reg, &RI);
+ }
+
+ /// \brief Return the scheduling class for this instruction. The
/// scheduling class is an index into the InstrItineraryData table. This
/// returns zero if there is no known scheduling information for the
/// instruction.
- ///
unsigned getSchedClass() const {
return SchedClass;
}
- /// getSize - Return the number of bytes in the encoding of this instruction,
+ /// \brief Return the number of bytes in the encoding of this instruction,
/// or zero if the encoding size cannot be known from the opcode.
unsigned getSize() const {
return Size;
}
- /// findFirstPredOperandIdx() - Find the index of the first operand in the
+ /// \brief Find the index of the first operand in the
/// operand list that is used to represent the predicate. It returns -1 if
/// none is found.
int findFirstPredOperandIdx() const {
diff --git a/include/llvm/MC/MCMachObjectWriter.h b/include/llvm/MC/MCMachObjectWriter.h
index efaabfb..3c9a588 100644
--- a/include/llvm/MC/MCMachObjectWriter.h
+++ b/include/llvm/MC/MCMachObjectWriter.h
@@ -45,6 +45,13 @@ protected:
public:
virtual ~MCMachObjectTargetWriter();
+ /// @name Lifetime Management
+ /// @{
+
+ virtual void reset() {};
+
+ /// @}
+
/// @name Accessors
/// @{
@@ -111,6 +118,13 @@ public:
: MCObjectWriter(_OS, _IsLittleEndian), TargetObjectWriter(MOTW) {
}
+ /// @name Lifetime management Methods
+ /// @{
+
+ virtual void reset();
+
+ /// @}
+
/// @name Utility Methods
/// @{
@@ -182,6 +196,8 @@ public:
void WriteLinkeditLoadCommand(uint32_t Type, uint32_t DataOffset,
uint32_t DataSize);
+ void WriteLinkerOptionsLoadCommand(const std::vector<std::string> &Options);
+
// FIXME: We really need to improve the relocation validation. Basically, we
// want to implement a separate computation which evaluates the relocation
// entry as the linker would, and verifies that the resultant fixup value is
@@ -223,8 +239,6 @@ public:
/// ComputeSymbolTable - Compute the symbol table data
///
/// \param StringTable [out] - The string table data.
- /// \param StringIndexMap [out] - Map from symbol names to offsets in the
- /// string table.
void ComputeSymbolTable(MCAssembler &Asm, SmallString<256> &StringTable,
std::vector<MachSymbolData> &LocalSymbolData,
std::vector<MachSymbolData> &ExternalSymbolData,
diff --git a/include/llvm/MC/MCObjectFileInfo.h b/include/llvm/MC/MCObjectFileInfo.h
index 23e5513..c8d7484 100644
--- a/include/llvm/MC/MCObjectFileInfo.h
+++ b/include/llvm/MC/MCObjectFileInfo.h
@@ -84,15 +84,6 @@ protected:
/// this is the section to emit them into.
const MCSection *CompactUnwindSection;
- /// DwarfAccelNamesSection, DwarfAccelObjCSection,
- /// DwarfAccelNamespaceSection, DwarfAccelTypesSection -
- /// If we use the DWARF accelerated hash tables then we want toe emit these
- /// sections.
- const MCSection *DwarfAccelNamesSection;
- const MCSection *DwarfAccelObjCSection;
- const MCSection *DwarfAccelNamespaceSection;
- const MCSection *DwarfAccelTypesSection;
-
// Dwarf sections for debug info. If a target supports debug info, these must
// be set.
const MCSection *DwarfAbbrevSection;
@@ -106,6 +97,28 @@ protected:
const MCSection *DwarfARangesSection;
const MCSection *DwarfRangesSection;
const MCSection *DwarfMacroInfoSection;
+ // The pubnames section is no longer generated by default. The generation
+ // can be enabled by a compiler flag.
+ const MCSection *DwarfPubNamesSection;
+
+ // DWARF5 Experimental Debug Info Sections
+ /// DwarfAccelNamesSection, DwarfAccelObjCSection,
+ /// DwarfAccelNamespaceSection, DwarfAccelTypesSection -
+ /// If we use the DWARF accelerated hash tables then we want to emit these
+ /// sections.
+ const MCSection *DwarfAccelNamesSection;
+ const MCSection *DwarfAccelObjCSection;
+ const MCSection *DwarfAccelNamespaceSection;
+ const MCSection *DwarfAccelTypesSection;
+
+ /// These are used for the Fission separate debug information files.
+ const MCSection *DwarfInfoDWOSection;
+ const MCSection *DwarfAbbrevDWOSection;
+ const MCSection *DwarfStrDWOSection;
+ const MCSection *DwarfLineDWOSection;
+ const MCSection *DwarfLocDWOSection;
+ const MCSection *DwarfStrOffDWOSection;
+ const MCSection *DwarfAddrSection;
// Extra TLS Variable Data section. If the target needs to put additional
// information for a TLS variable, it'll go here.
@@ -195,22 +208,11 @@ public:
const MCSection *getCompactUnwindSection() const{
return CompactUnwindSection;
}
- const MCSection *getDwarfAccelNamesSection() const {
- return DwarfAccelNamesSection;
- }
- const MCSection *getDwarfAccelObjCSection() const {
- return DwarfAccelObjCSection;
- }
- const MCSection *getDwarfAccelNamespaceSection() const {
- return DwarfAccelNamespaceSection;
- }
- const MCSection *getDwarfAccelTypesSection() const {
- return DwarfAccelTypesSection;
- }
const MCSection *getDwarfAbbrevSection() const { return DwarfAbbrevSection; }
const MCSection *getDwarfInfoSection() const { return DwarfInfoSection; }
const MCSection *getDwarfLineSection() const { return DwarfLineSection; }
const MCSection *getDwarfFrameSection() const { return DwarfFrameSection; }
+ const MCSection *getDwarfPubNamesSection() const{return DwarfPubNamesSection;}
const MCSection *getDwarfPubTypesSection() const{return DwarfPubTypesSection;}
const MCSection *getDwarfDebugInlineSection() const {
return DwarfDebugInlineSection;
@@ -222,6 +224,42 @@ public:
const MCSection *getDwarfMacroInfoSection() const {
return DwarfMacroInfoSection;
}
+
+ // DWARF5 Experimental Debug Info Sections
+ const MCSection *getDwarfAccelNamesSection() const {
+ return DwarfAccelNamesSection;
+ }
+ const MCSection *getDwarfAccelObjCSection() const {
+ return DwarfAccelObjCSection;
+ }
+ const MCSection *getDwarfAccelNamespaceSection() const {
+ return DwarfAccelNamespaceSection;
+ }
+ const MCSection *getDwarfAccelTypesSection() const {
+ return DwarfAccelTypesSection;
+ }
+ const MCSection *getDwarfInfoDWOSection() const {
+ return DwarfInfoDWOSection;
+ }
+ const MCSection *getDwarfAbbrevDWOSection() const {
+ return DwarfAbbrevDWOSection;
+ }
+ const MCSection *getDwarfStrDWOSection() const {
+ return DwarfStrDWOSection;
+ }
+ const MCSection *getDwarfLineDWOSection() const {
+ return DwarfLineDWOSection;
+ }
+ const MCSection *getDwarfLocDWOSection() const {
+ return DwarfLocDWOSection;
+ }
+ const MCSection *getDwarfStrOffDWOSection() const {
+ return DwarfStrOffDWOSection;
+ }
+ const MCSection *getDwarfAddrSection() const {
+ return DwarfAddrSection;
+ }
+
const MCSection *getTLSExtraDataSection() const {
return TLSExtraDataSection;
}
diff --git a/include/llvm/MC/MCObjectStreamer.h b/include/llvm/MC/MCObjectStreamer.h
index 08b00f1..f06c49f 100644
--- a/include/llvm/MC/MCObjectStreamer.h
+++ b/include/llvm/MC/MCObjectStreamer.h
@@ -38,13 +38,18 @@ class MCObjectStreamer : public MCStreamer {
virtual void EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame);
protected:
- MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB,
+ MCObjectStreamer(StreamerKind Kind, MCContext &Context, MCAsmBackend &TAB,
raw_ostream &_OS, MCCodeEmitter *_Emitter);
- MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB,
+ MCObjectStreamer(StreamerKind Kind, MCContext &Context, MCAsmBackend &TAB,
raw_ostream &_OS, MCCodeEmitter *_Emitter,
MCAssembler *_Assembler);
~MCObjectStreamer();
+public:
+ /// state management
+ virtual void reset();
+
+protected:
MCSectionData *getCurrentSectionData() const {
return CurSectionData;
}
@@ -64,6 +69,8 @@ public:
/// @{
virtual void EmitLabel(MCSymbol *Symbol);
+ virtual void EmitDebugLabel(MCSymbol *Symbol);
+ virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value);
virtual void EmitValueImpl(const MCExpr *Value, unsigned Size,
unsigned AddrSpace);
virtual void EmitULEB128Value(const MCExpr *Value);
@@ -71,8 +78,15 @@ public:
virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol);
virtual void ChangeSection(const MCSection *Section);
virtual void EmitInstruction(const MCInst &Inst);
+
+ /// \brief Emit an instruction to a special fragment, because this instruction
+ /// can change its size during relaxation.
virtual void EmitInstToFragment(const MCInst &Inst);
- virtual void EmitBytes(StringRef Data, unsigned AddrSpace);
+
+ virtual void EmitBundleAlignMode(unsigned AlignPow2);
+ virtual void EmitBundleLock(bool AlignToEnd);
+ virtual void EmitBundleUnlock();
+ virtual void EmitBytes(StringRef Data, unsigned AddrSpace = 0);
virtual void EmitValueToAlignment(unsigned ByteAlignment,
int64_t Value = 0,
unsigned ValueSize = 1,
@@ -89,10 +103,14 @@ public:
virtual void EmitGPRel32Value(const MCExpr *Value);
virtual void EmitGPRel64Value(const MCExpr *Value);
virtual void EmitFill(uint64_t NumBytes, uint8_t FillValue,
- unsigned AddrSpace);
+ unsigned AddrSpace = 0);
virtual void FinishImpl();
/// @}
+
+ static bool classof(const MCStreamer *S) {
+ return S->getKind() >= SK_ELFStreamer && S->getKind() <= SK_WinCOFFStreamer;
+ }
};
} // end namespace llvm
diff --git a/include/llvm/MC/MCObjectWriter.h b/include/llvm/MC/MCObjectWriter.h
index 14fe75f..4939a3f 100644
--- a/include/llvm/MC/MCObjectWriter.h
+++ b/include/llvm/MC/MCObjectWriter.h
@@ -10,9 +10,10 @@
#ifndef LLVM_MC_MCOBJECTWRITER_H
#define LLVM_MC_MCOBJECTWRITER_H
-#include "llvm/Support/raw_ostream.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/raw_ostream.h"
#include <cassert>
namespace llvm {
@@ -51,6 +52,9 @@ protected: // Can only create subclasses.
public:
virtual ~MCObjectWriter();
+ /// lifetime management
+ virtual void reset() { }
+
bool isLittleEndian() const { return IsLittleEndian; }
raw_ostream &getStream() { return OS; }
@@ -58,15 +62,15 @@ public:
/// @name High-Level API
/// @{
- /// Perform any late binding of symbols (for example, to assign symbol indices
- /// for use when generating relocations).
+ /// \brief Perform any late binding of symbols (for example, to assign symbol
+ /// indices for use when generating relocations).
///
/// This routine is called by the assembler after layout and relaxation is
/// complete.
virtual void ExecutePostLayoutBinding(MCAssembler &Asm,
const MCAsmLayout &Layout) = 0;
- /// Record a relocation entry.
+ /// \brief Record a relocation entry.
///
/// This routine is called by the assembler after layout and relaxation, and
/// post layout binding. The implementation is responsible for storing
@@ -96,8 +100,7 @@ public:
bool InSet,
bool IsPCRel) const;
-
- /// Write the object file.
+ /// \brief Write the object file.
///
/// This routine is called by the assembler after layout and relaxation is
/// complete, fixups have been evaluated and applied, and relocations
@@ -173,7 +176,13 @@ public:
OS << StringRef(Zeros, N % 16);
}
+ void WriteBytes(const SmallVectorImpl<char> &ByteVec, unsigned ZeroFillSize = 0) {
+ WriteBytes(StringRef(ByteVec.data(), ByteVec.size()), ZeroFillSize);
+ }
+
void WriteBytes(StringRef Str, unsigned ZeroFillSize = 0) {
+ // TODO: this version may need to go away once all fragment contents are
+ // converted to SmallVector<char, N>
assert((ZeroFillSize == 0 || Str.size () <= ZeroFillSize) &&
"data size greater than fill size, unexpected large write will occur");
OS << Str;
diff --git a/include/llvm/MC/MCParser/AsmCond.h b/include/llvm/MC/MCParser/AsmCond.h
index 92a115e..a918b56 100644
--- a/include/llvm/MC/MCParser/AsmCond.h
+++ b/include/llvm/MC/MCParser/AsmCond.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef ASMCOND_H
-#define ASMCOND_H
+#ifndef LLVM_MC_MCPARSER_ASMCOND_H
+#define LLVM_MC_MCPARSER_ASMCOND_H
namespace llvm {
diff --git a/include/llvm/MC/MCParser/AsmLexer.h b/include/llvm/MC/MCParser/AsmLexer.h
index e102dfb..0dab314 100644
--- a/include/llvm/MC/MCParser/AsmLexer.h
+++ b/include/llvm/MC/MCParser/AsmLexer.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef ASMLEXER_H
-#define ASMLEXER_H
+#ifndef LLVM_MC_MCPARSER_ASMLEXER_H
+#define LLVM_MC_MCPARSER_ASMLEXER_H
#include "llvm/ADT/StringRef.h"
#include "llvm/MC/MCParser/MCAsmLexer.h"
diff --git a/include/llvm/MC/MCParser/MCAsmLexer.h b/include/llvm/MC/MCParser/MCAsmLexer.h
index 0a961d6..53b380f 100644
--- a/include/llvm/MC/MCParser/MCAsmLexer.h
+++ b/include/llvm/MC/MCParser/MCAsmLexer.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_MC_MCASMLEXER_H
-#define LLVM_MC_MCASMLEXER_H
+#ifndef LLVM_MC_MCPARSER_MCASMLEXER_H
+#define LLVM_MC_MCPARSER_MCASMLEXER_H
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Compiler.h"
@@ -34,9 +34,6 @@ public:
// Real values.
Real,
- // Register values (stored in IntVal). Only used by MCTargetAsmLexer.
- Register,
-
// No-value.
EndOfStatement,
Colon,
@@ -104,13 +101,6 @@ public:
assert(Kind == Integer && "This token isn't an integer!");
return IntVal;
}
-
- /// getRegVal - Get the register number for the current token, which should
- /// be a register.
- unsigned getRegVal() const {
- assert(Kind == Register && "This token isn't a register!");
- return static_cast<unsigned>(IntVal);
- }
};
/// MCAsmLexer - Generic assembler lexer interface, for use by target specific
diff --git a/include/llvm/MC/MCParser/MCAsmParser.h b/include/llvm/MC/MCParser/MCAsmParser.h
index a71d3c3..d7e3902 100644
--- a/include/llvm/MC/MCParser/MCAsmParser.h
+++ b/include/llvm/MC/MCParser/MCAsmParser.h
@@ -7,14 +7,15 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_MC_MCASMPARSER_H
-#define LLVM_MC_MCASMPARSER_H
+#ifndef LLVM_MC_MCPARSER_MCASMPARSER_H
+#define LLVM_MC_MCPARSER_MCASMPARSER_H
-#include "llvm/Support/DataTypes.h"
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/MC/MCParser/AsmLexer.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
-class AsmToken;
class MCAsmInfo;
class MCAsmLexer;
class MCAsmParserExtension;
@@ -22,13 +23,11 @@ class MCContext;
class MCExpr;
class MCInstPrinter;
class MCInstrInfo;
-class MCParsedAsmOperand;
class MCStreamer;
class MCTargetAsmParser;
class SMLoc;
class SMRange;
class SourceMgr;
-class StringRef;
class Twine;
/// MCAsmParserSemaCallback - Generic Sema callback for assembly parser.
@@ -36,16 +35,21 @@ class MCAsmParserSemaCallback {
public:
virtual ~MCAsmParserSemaCallback();
virtual void *LookupInlineAsmIdentifier(StringRef Name, void *Loc,
- unsigned &Size) = 0;
+ unsigned &Length, unsigned &Size,
+ unsigned &Type, bool &IsVarDecl) = 0;
+
virtual bool LookupInlineAsmField(StringRef Base, StringRef Member,
unsigned &Offset) = 0;
};
+
/// MCAsmParser - Generic assembler parser interface, for use by target specific
/// assembly parsers.
class MCAsmParser {
public:
typedef bool (*DirectiveHandler)(MCAsmParserExtension*, StringRef, SMLoc);
+ typedef std::pair<MCAsmParserExtension*, DirectiveHandler>
+ ExtensionDirectiveHandler;
private:
MCAsmParser(const MCAsmParser &) LLVM_DELETED_FUNCTION;
@@ -61,9 +65,8 @@ protected: // Can only create subclasses.
public:
virtual ~MCAsmParser();
- virtual void AddDirectiveHandler(MCAsmParserExtension *Object,
- StringRef Directive,
- DirectiveHandler Handler) = 0;
+ virtual void addDirectiveHandler(StringRef Directive,
+ ExtensionDirectiveHandler Handler) = 0;
virtual SourceMgr &getSourceManager() = 0;
@@ -89,8 +92,8 @@ public:
virtual void setParsingInlineAsm(bool V) = 0;
virtual bool isParsingInlineAsm() = 0;
- /// ParseMSInlineAsm - Parse ms-style inline assembly.
- virtual bool ParseMSInlineAsm(void *AsmLoc, std::string &AsmString,
+ /// parseMSInlineAsm - Parse ms-style inline assembly.
+ virtual bool parseMSInlineAsm(void *AsmLoc, std::string &AsmString,
unsigned &NumOutputs, unsigned &NumInputs,
SmallVectorImpl<std::pair<void *, bool> > &OpDecls,
SmallVectorImpl<std::string> &Constraints,
@@ -123,42 +126,50 @@ public:
bool TokError(const Twine &Msg,
ArrayRef<SMRange> Ranges = ArrayRef<SMRange>());
- /// ParseIdentifier - Parse an identifier or string (as a quoted identifier)
+ /// parseIdentifier - Parse an identifier or string (as a quoted identifier)
/// and set \p Res to the identifier contents.
- virtual bool ParseIdentifier(StringRef &Res) = 0;
+ virtual bool parseIdentifier(StringRef &Res) = 0;
/// \brief Parse up to the end of statement and return the contents from the
/// current token until the end of the statement; the current token on exit
/// will be either the EndOfStatement or EOF.
- virtual StringRef ParseStringToEndOfStatement() = 0;
+ virtual StringRef parseStringToEndOfStatement() = 0;
+
+ /// parseEscapedString - Parse the current token as a string which may include
+ /// escaped characters and return the string contents.
+ virtual bool parseEscapedString(std::string &Data) = 0;
- /// EatToEndOfStatement - Skip to the end of the current statement, for error
+ /// eatToEndOfStatement - Skip to the end of the current statement, for error
/// recovery.
- virtual void EatToEndOfStatement() = 0;
+ virtual void eatToEndOfStatement() = 0;
- /// ParseExpression - Parse an arbitrary expression.
+ /// parseExpression - Parse an arbitrary expression.
///
/// @param Res - The value of the expression. The result is undefined
/// on error.
/// @result - False on success.
- virtual bool ParseExpression(const MCExpr *&Res, SMLoc &EndLoc) = 0;
- bool ParseExpression(const MCExpr *&Res);
+ virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc) = 0;
+ bool parseExpression(const MCExpr *&Res);
- /// ParseParenExpression - Parse an arbitrary expression, assuming that an
+ /// parseParenExpression - Parse an arbitrary expression, assuming that an
/// initial '(' has already been consumed.
///
/// @param Res - The value of the expression. The result is undefined
/// on error.
/// @result - False on success.
- virtual bool ParseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) = 0;
+ virtual bool parseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) = 0;
- /// ParseAbsoluteExpression - Parse an expression which must evaluate to an
+ /// parseAbsoluteExpression - Parse an expression which must evaluate to an
/// absolute value.
///
/// @param Res - The value of the absolute expression. The result is undefined
/// on error.
/// @result - False on success.
- virtual bool ParseAbsoluteExpression(int64_t &Res) = 0;
+ virtual bool parseAbsoluteExpression(int64_t &Res) = 0;
+
+ /// checkForValidSection - Ensure that we have a valid section set in the
+ /// streamer. Otherwise, report an error and switch to .text.
+ virtual void checkForValidSection() = 0;
};
/// \brief Create an MCAsmParser instance.
diff --git a/include/llvm/MC/MCParser/MCAsmParserExtension.h b/include/llvm/MC/MCParser/MCAsmParserExtension.h
index 0918c93..2eda3a9 100644
--- a/include/llvm/MC/MCParser/MCAsmParserExtension.h
+++ b/include/llvm/MC/MCParser/MCAsmParserExtension.h
@@ -7,11 +7,11 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_MC_MCASMPARSEREXTENSION_H
-#define LLVM_MC_MCASMPARSEREXTENSION_H
+#ifndef LLVM_MC_MCPARSER_MCASMPARSEREXTENSION_H
+#define LLVM_MC_MCPARSER_MCASMPARSEREXTENSION_H
-#include "llvm/MC/MCParser/MCAsmParser.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/MC/MCParser/MCAsmParser.h"
#include "llvm/Support/SMLoc.h"
namespace llvm {
diff --git a/include/llvm/MC/MCParser/MCParsedAsmOperand.h b/include/llvm/MC/MCParser/MCParsedAsmOperand.h
index 60e7887..4650bf2 100644
--- a/include/llvm/MC/MCParser/MCParsedAsmOperand.h
+++ b/include/llvm/MC/MCParser/MCParsedAsmOperand.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_MC_MCASMOPERAND_H
-#define LLVM_MC_MCASMOPERAND_H
+#ifndef LLVM_MC_MCPARSER_MCPARSEDASMOPERAND_H
+#define LLVM_MC_MCPARSER_MCPARSEDASMOPERAND_H
namespace llvm {
class SMLoc;
@@ -57,18 +57,15 @@ public:
/// isMem - Is this a memory operand?
virtual bool isMem() const = 0;
- virtual unsigned getMemSize() const { return 0; }
/// getStartLoc - Get the location of the first token of this operand.
virtual SMLoc getStartLoc() const = 0;
/// getEndLoc - Get the location of the last token of this operand.
virtual SMLoc getEndLoc() const = 0;
- /// needAsmRewrite - AsmRewrites happen in both the target-independent and
- /// target-dependent parsers. The target-independent parser calls this
- /// function to determine if the target-dependent parser has already taken
- /// care of the rewrites. Only valid when parsing MS-style inline assembly.
- virtual bool needAsmRewrite() const { return true; }
+ /// needAddressOf - Do we need to emit code to get the address of the
+ /// variable/label? Only valid when parsing MS-style inline assembly.
+ virtual bool needAddressOf() const { return false; }
/// isOffsetOf - Do we need to emit code to get the offset of the variable,
/// rather then the value of the variable? Only valid when parsing MS-style
@@ -78,10 +75,6 @@ public:
/// getOffsetOfLoc - Get the location of the offset operator.
virtual SMLoc getOffsetOfLoc() const { return SMLoc(); }
- /// needSizeDirective - Do we need to emit a sizing directive for this
- /// operand? Only valid when parsing MS-style inline assembly.
- virtual bool needSizeDirective() const { return false; }
-
/// print - Print a debug representation of the operand to the given stream.
virtual void print(raw_ostream &OS) const = 0;
/// dump - Print to the debug stream.
diff --git a/include/llvm/MC/MCRegisterInfo.h b/include/llvm/MC/MCRegisterInfo.h
index f05baea..f5b4ddd 100644
--- a/include/llvm/MC/MCRegisterInfo.h
+++ b/include/llvm/MC/MCRegisterInfo.h
@@ -22,11 +22,15 @@
namespace llvm {
+/// An unsigned integer type large enough to represent all physical registers,
+/// but not necessarily virtual registers.
+typedef uint16_t MCPhysReg;
+
/// MCRegisterClass - Base class of TargetRegisterClass.
class MCRegisterClass {
public:
- typedef const uint16_t* iterator;
- typedef const uint16_t* const_iterator;
+ typedef const MCPhysReg* iterator;
+ typedef const MCPhysReg* const_iterator;
const char *Name;
const iterator RegsBegin;
@@ -148,11 +152,12 @@ private:
const MCRegisterDesc *Desc; // Pointer to the descriptor array
unsigned NumRegs; // Number of entries in the array
unsigned RAReg; // Return address register
+ unsigned PCReg; // Program counter register
const MCRegisterClass *Classes; // Pointer to the regclass array
unsigned NumClasses; // Number of entries in the array
unsigned NumRegUnits; // Number of regunits.
const uint16_t (*RegUnitRoots)[2]; // Pointer to regunit root table.
- const uint16_t *DiffLists; // Pointer to the difflists array
+ const MCPhysReg *DiffLists; // Pointer to the difflists array
const char *RegStrings; // Pointer to the string table.
const uint16_t *SubRegIndices; // Pointer to the subreg lookup
// array.
@@ -177,7 +182,7 @@ public:
/// defined below.
class DiffListIterator {
uint16_t Val;
- const uint16_t *List;
+ const MCPhysReg *List;
protected:
/// Create an invalid iterator. Call init() to point to something useful.
@@ -186,7 +191,7 @@ public:
/// init - Point the iterator to InitVal, decoding subsequent values from
/// DiffList. The iterator will initially point to InitVal, sub-classes are
/// responsible for skipping the seed value if it is not part of the list.
- void init(uint16_t InitVal, const uint16_t *DiffList) {
+ void init(MCPhysReg InitVal, const MCPhysReg *DiffList) {
Val = InitVal;
List = DiffList;
}
@@ -196,7 +201,7 @@ public:
/// is the caller's responsibility (by checking for a 0 return value).
unsigned advance() {
assert(isValid() && "Cannot move off the end of the list.");
- uint16_t D = *List++;
+ MCPhysReg D = *List++;
Val += D;
return D;
}
@@ -225,13 +230,14 @@ public:
friend class MCRegUnitIterator;
friend class MCRegUnitRootIterator;
- /// InitMCRegisterInfo - Initialize MCRegisterInfo, called by TableGen
+ /// \brief Initialize MCRegisterInfo, called by TableGen
/// auto-generated routines. *DO NOT USE*.
void InitMCRegisterInfo(const MCRegisterDesc *D, unsigned NR, unsigned RA,
+ unsigned PC,
const MCRegisterClass *C, unsigned NC,
const uint16_t (*RURoots)[2],
unsigned NRU,
- const uint16_t *DL,
+ const MCPhysReg *DL,
const char *Strings,
const uint16_t *SubIndices,
unsigned NumIndices,
@@ -239,6 +245,7 @@ public:
Desc = D;
NumRegs = NR;
RAReg = RA;
+ PCReg = PC;
Classes = C;
DiffLists = DL;
RegStrings = Strings;
@@ -250,7 +257,7 @@ public:
RegEncodingTable = RET;
}
- /// mapLLVMRegsToDwarfRegs - Used to initialize LLVM register to Dwarf
+ /// \brief Used to initialize LLVM register to Dwarf
/// register number mapping. Called by TableGen auto-generated routines.
/// *DO NOT USE*.
void mapLLVMRegsToDwarfRegs(const DwarfLLVMRegPair *Map, unsigned Size,
@@ -264,7 +271,7 @@ public:
}
}
- /// mapDwarfRegsToLLVMRegs - Used to initialize Dwarf register to LLVM
+ /// \brief Used to initialize Dwarf register to LLVM
/// register number mapping. Called by TableGen auto-generated routines.
/// *DO NOT USE*.
void mapDwarfRegsToLLVMRegs(const DwarfLLVMRegPair *Map, unsigned Size,
@@ -287,77 +294,80 @@ public:
L2SEHRegs[LLVMReg] = SEHReg;
}
- /// getRARegister - This method should return the register where the return
+ /// \brief This method should return the register where the return
/// address can be found.
unsigned getRARegister() const {
return RAReg;
}
+ /// Return the register which is the program counter.
+ unsigned getProgramCounter() const {
+ return PCReg;
+ }
+
const MCRegisterDesc &operator[](unsigned RegNo) const {
assert(RegNo < NumRegs &&
"Attempting to access record for invalid register number!");
return Desc[RegNo];
}
- /// Provide a get method, equivalent to [], but more useful if we have a
+ /// \brief Provide a get method, equivalent to [], but more useful with a
/// pointer to this object.
- ///
const MCRegisterDesc &get(unsigned RegNo) const {
return operator[](RegNo);
}
- /// getSubReg - Returns the physical register number of sub-register "Index"
+ /// \brief Returns the physical register number of sub-register "Index"
/// for physical register RegNo. Return zero if the sub-register does not
/// exist.
unsigned getSubReg(unsigned Reg, unsigned Idx) const;
- /// getMatchingSuperReg - Return a super-register of the specified register
+ /// \brief Return a super-register of the specified register
/// Reg so its sub-register of index SubIdx is Reg.
unsigned getMatchingSuperReg(unsigned Reg, unsigned SubIdx,
const MCRegisterClass *RC) const;
- /// getSubRegIndex - For a given register pair, return the sub-register index
+ /// \brief For a given register pair, return the sub-register index
/// if the second register is a sub-register of the first. Return zero
/// otherwise.
unsigned getSubRegIndex(unsigned RegNo, unsigned SubRegNo) const;
- /// getName - Return the human-readable symbolic target-specific name for the
+ /// \brief Return the human-readable symbolic target-specific name for the
/// specified physical register.
const char *getName(unsigned RegNo) const {
return RegStrings + get(RegNo).Name;
}
- /// getNumRegs - Return the number of registers this target has (useful for
+ /// \brief Return the number of registers this target has (useful for
/// sizing arrays holding per register information)
unsigned getNumRegs() const {
return NumRegs;
}
- /// getNumSubRegIndices - Return the number of sub-register indices
+ /// \brief Return the number of sub-register indices
/// understood by the target. Index 0 is reserved for the no-op sub-register,
/// while 1 to getNumSubRegIndices() - 1 represent real sub-registers.
unsigned getNumSubRegIndices() const {
return NumSubRegIndices;
}
- /// getNumRegUnits - Return the number of (native) register units in the
+ /// \brief Return the number of (native) register units in the
/// target. Register units are numbered from 0 to getNumRegUnits() - 1. They
/// can be accessed through MCRegUnitIterator defined below.
unsigned getNumRegUnits() const {
return NumRegUnits;
}
- /// getDwarfRegNum - Map a target register to an equivalent dwarf register
+ /// \brief Map a target register to an equivalent dwarf register
/// number. Returns -1 if there is no equivalent value. The second
/// parameter allows targets to use different numberings for EH info and
/// debugging info.
int getDwarfRegNum(unsigned RegNum, bool isEH) const;
- /// getLLVMRegNum - Map a dwarf register back to a target register.
- ///
+ /// \brief Map a dwarf register back to a target register.
int getLLVMRegNum(unsigned RegNum, bool isEH) const;
- /// getSEHRegNum - Map a target register to an equivalent SEH register
+ /// \brief Map a target register to an equivalent SEH register
/// number. Returns LLVM register number if there is no equivalent value.
int getSEHRegNum(unsigned RegNum) const;
@@ -368,20 +378,39 @@ public:
return (unsigned)(regclass_end()-regclass_begin());
}
- /// getRegClass - Returns the register class associated with the enumeration
+ /// \brief Returns the register class associated with the enumeration
/// value. See class MCOperandInfo.
const MCRegisterClass& getRegClass(unsigned i) const {
assert(i < getNumRegClasses() && "Register Class ID out of range");
return Classes[i];
}
- /// getEncodingValue - Returns the encoding for RegNo
+ /// \brief Returns the encoding for RegNo
uint16_t getEncodingValue(unsigned RegNo) const {
assert(RegNo < NumRegs &&
"Attempting to get encoding for invalid register number!");
return RegEncodingTable[RegNo];
}
+ /// \brief Returns true if RegB is a sub-register of RegA.
+ bool isSubRegister(unsigned RegA, unsigned RegB) const {
+ return isSuperRegister(RegB, RegA);
+ }
+
+ /// \brief Returns true if RegB is a super-register of RegA.
+ bool isSuperRegister(unsigned RegA, unsigned RegB) const;
+
+ /// \brief Returns true if RegB is a sub-register of RegA or if RegB == RegA.
+ bool isSubRegisterEq(unsigned RegA, unsigned RegB) const {
+ return isSuperRegisterEq(RegB, RegA);
+ }
+
+ /// \brief Returns true if RegB is a super-register of RegA or if
+ /// RegB == RegA.
+ bool isSuperRegisterEq(unsigned RegA, unsigned RegB) const {
+ return RegA == RegB || isSuperRegister(RegA, RegB);
+ }
+
};
//===----------------------------------------------------------------------===//
@@ -422,6 +451,15 @@ public:
}
};
+// Definition for isSuperRegister. Put it down here since it needs the
+// iterator defined above in addition to the MCRegisterInfo class itself.
+inline bool MCRegisterInfo::isSuperRegister(unsigned RegA, unsigned RegB) const{
+ for (MCSuperRegIterator I(RegA, this); I.isValid(); ++I)
+ if (*I == RegB)
+ return true;
+ return false;
+}
+
//===----------------------------------------------------------------------===//
// Register Units
//===----------------------------------------------------------------------===//
@@ -441,6 +479,7 @@ public:
/// MCRegUnitIterator - Create an iterator that traverses the register units
/// in Reg.
MCRegUnitIterator(unsigned Reg, const MCRegisterInfo *MCRI) {
+ assert(Reg && "Null register has no regunits");
// Decode the RegUnits MCRegisterDesc field.
unsigned RU = MCRI->get(Reg).RegUnits;
unsigned Scale = RU & 15;
@@ -480,17 +519,17 @@ public:
Reg1 = MCRI->RegUnitRoots[RegUnit][1];
}
- /// Dereference to get the current root register.
+ /// \brief Dereference to get the current root register.
unsigned operator*() const {
return Reg0;
}
- /// isValid - Check if the iterator is at the end of the list.
+ /// \brief Check if the iterator is at the end of the list.
bool isValid() const {
return Reg0;
}
- /// Preincrement to move to the next root register.
+ /// \brief Preincrement to move to the next root register.
void operator++() {
assert(isValid() && "Cannot move off the end of the list.");
Reg0 = Reg1;
diff --git a/include/llvm/MC/MCSchedule.h b/include/llvm/MC/MCSchedule.h
index 0c71ee5..defa299 100644
--- a/include/llvm/MC/MCSchedule.h
+++ b/include/llvm/MC/MCSchedule.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_MC_MCSCHEDMODEL_H
-#define LLVM_MC_MCSCHEDMODEL_H
+#ifndef LLVM_MC_MCSCHEDULE_H
+#define LLVM_MC_MCSCHEDULE_H
#include "llvm/Support/DataTypes.h"
#include <cassert>
@@ -155,7 +155,7 @@ public:
// Optional InstrItinerary OperandCycles provides expected latency.
// TODO: can't yet specify both min and expected latency per operand.
int MinLatency;
- static const unsigned DefaultMinLatency = -1;
+ static const int DefaultMinLatency = -1;
// LoadLatency is the expected latency of load instructions.
//
@@ -172,6 +172,16 @@ public:
unsigned HighLatency;
static const unsigned DefaultHighLatency = 10;
+ // ILPWindow is the number of cycles that the scheduler effectively ignores
+ // before attempting to hide latency. This should be zero for in-order cpus to
+ // always hide expected latency. For out-of-order cpus, it may be tweaked as
+ // desired to roughly approximate instruction buffers. The actual threshold is
+ // not very important for an OOO processor, as long as it isn't too high. A
+ // nonzero value helps avoid rescheduling to hide latency when its is fairly
+ // obviously useless and makes register pressure heuristics more effective.
+ unsigned ILPWindow;
+ static const unsigned DefaultILPWindow = 0;
+
// MispredictPenalty is the typical number of extra cycles the processor
// takes to recover from a branch misprediction.
unsigned MispredictPenalty;
@@ -196,6 +206,7 @@ public:
MinLatency(DefaultMinLatency),
LoadLatency(DefaultLoadLatency),
HighLatency(DefaultHighLatency),
+ ILPWindow(DefaultILPWindow),
MispredictPenalty(DefaultMispredictPenalty),
ProcID(0), ProcResourceTable(0), SchedClassTable(0),
NumProcResourceKinds(0), NumSchedClasses(0),
@@ -205,12 +216,12 @@ public:
}
// Table-gen driven ctor.
- MCSchedModel(unsigned iw, int ml, unsigned ll, unsigned hl, unsigned mp,
- unsigned pi, const MCProcResourceDesc *pr,
+ MCSchedModel(unsigned iw, int ml, unsigned ll, unsigned hl, unsigned ilp,
+ unsigned mp, unsigned pi, const MCProcResourceDesc *pr,
const MCSchedClassDesc *sc, unsigned npr, unsigned nsc,
const InstrItinerary *ii):
IssueWidth(iw), MinLatency(ml), LoadLatency(ll), HighLatency(hl),
- MispredictPenalty(mp), ProcID(pi), ProcResourceTable(pr),
+ ILPWindow(ilp), MispredictPenalty(mp), ProcID(pi), ProcResourceTable(pr),
SchedClassTable(sc), NumProcResourceKinds(npr), NumSchedClasses(nsc),
InstrItineraries(ii) {}
diff --git a/include/llvm/MC/MCSection.h b/include/llvm/MC/MCSection.h
index 21fdb6b..e575424 100644
--- a/include/llvm/MC/MCSection.h
+++ b/include/llvm/MC/MCSection.h
@@ -14,6 +14,7 @@
#ifndef LLVM_MC_MCSECTION_H
#define LLVM_MC_MCSECTION_H
+#include "llvm/ADT/StringRef.h"
#include "llvm/MC/SectionKind.h"
#include "llvm/Support/Compiler.h"
@@ -49,6 +50,11 @@ namespace llvm {
virtual void PrintSwitchToSection(const MCAsmInfo &MAI,
raw_ostream &OS) const = 0;
+ // Convenience routines to get label names for the beginning/end of a
+ // section.
+ virtual std::string getLabelBeginName() const = 0;
+ virtual std::string getLabelEndName() const = 0;
+
/// isBaseAddressKnownZero - Return true if we know that this section will
/// get a base address of zero. In cases where we know that this is true we
/// can emit section offsets as direct references to avoid a subtraction
diff --git a/include/llvm/MC/MCSectionCOFF.h b/include/llvm/MC/MCSectionCOFF.h
index b050c0f..07c4714 100644
--- a/include/llvm/MC/MCSectionCOFF.h
+++ b/include/llvm/MC/MCSectionCOFF.h
@@ -14,9 +14,9 @@
#ifndef LLVM_MC_MCSECTIONCOFF_H
#define LLVM_MC_MCSECTIONCOFF_H
+#include "llvm/ADT/StringRef.h"
#include "llvm/MC/MCSection.h"
#include "llvm/Support/COFF.h"
-#include "llvm/ADT/StringRef.h"
namespace llvm {
@@ -50,6 +50,12 @@ namespace llvm {
bool ShouldOmitSectionDirective(StringRef Name, const MCAsmInfo &MAI) const;
StringRef getSectionName() const { return SectionName; }
+ virtual std::string getLabelBeginName() const {
+ return SectionName.str() + "_begin";
+ }
+ virtual std::string getLabelEndName() const {
+ return SectionName.str() + "_end";
+ }
unsigned getCharacteristics() const { return Characteristics; }
int getSelection () const { return Selection; }
diff --git a/include/llvm/MC/MCSectionELF.h b/include/llvm/MC/MCSectionELF.h
index 4d54465..4b8b849 100644
--- a/include/llvm/MC/MCSectionELF.h
+++ b/include/llvm/MC/MCSectionELF.h
@@ -14,9 +14,11 @@
#ifndef LLVM_MC_MCSECTIONELF_H
#define LLVM_MC_MCSECTIONELF_H
+#include "llvm/ADT/StringRef.h"
#include "llvm/MC/MCSection.h"
+#include "llvm/Support/Debug.h"
#include "llvm/Support/ELF.h"
-#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/raw_ostream.h"
namespace llvm {
@@ -57,6 +59,11 @@ public:
bool ShouldOmitSectionDirective(StringRef Name, const MCAsmInfo &MAI) const;
StringRef getSectionName() const { return SectionName; }
+ virtual std::string getLabelBeginName() const {
+ return SectionName.str() + "_begin"; }
+ virtual std::string getLabelEndName() const {
+ return SectionName.str() + "_end";
+ }
unsigned getType() const { return Type; }
unsigned getFlags() const { return Flags; }
unsigned getEntrySize() const { return EntrySize; }
diff --git a/include/llvm/MC/MCSectionMachO.h b/include/llvm/MC/MCSectionMachO.h
index 71ea8f3..898f571 100644
--- a/include/llvm/MC/MCSectionMachO.h
+++ b/include/llvm/MC/MCSectionMachO.h
@@ -14,8 +14,8 @@
#ifndef LLVM_MC_MCSECTIONMACHO_H
#define LLVM_MC_MCSECTIONMACHO_H
-#include "llvm/MC/MCSection.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/MC/MCSection.h"
namespace llvm {
@@ -145,6 +145,14 @@ public:
return StringRef(SectionName);
}
+ virtual std::string getLabelBeginName() const {
+ return StringRef(getSegmentName().str() + getSectionName().str() + "_begin");
+ }
+
+ virtual std::string getLabelEndName() const {
+ return StringRef(getSegmentName().str() + getSectionName().str() + "_end");
+ }
+
unsigned getTypeAndAttributes() const { return TypeAndAttributes; }
unsigned getStubSize() const { return Reserved2; }
diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h
index 230d27e..a069a2b 100644
--- a/include/llvm/MC/MCStreamer.h
+++ b/include/llvm/MC/MCStreamer.h
@@ -14,12 +14,14 @@
#ifndef LLVM_MC_MCSTREAMER_H
#define LLVM_MC_MCSTREAMER_H
-#include "llvm/Support/DataTypes.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCDirectives.h"
#include "llvm/MC/MCDwarf.h"
#include "llvm/MC/MCWin64EH.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/DataTypes.h"
+#include <string>
namespace llvm {
class MCAsmBackend;
@@ -45,6 +47,23 @@ namespace llvm {
/// a .s file, and implementations that write out .o files of various formats.
///
class MCStreamer {
+ public:
+ enum StreamerKind {
+ SK_AsmStreamer,
+ SK_NullStreamer,
+ SK_RecordStreamer,
+
+ // MCObjectStreamer subclasses.
+ SK_ELFStreamer,
+ SK_ARMELFStreamer,
+ SK_MachOStreamer,
+ SK_PureStreamer,
+ SK_MipsELFStreamer,
+ SK_WinCOFFStreamer
+ };
+
+ private:
+ const StreamerKind Kind;
MCContext &Context;
MCStreamer(const MCStreamer&) LLVM_DELETED_FUNCTION;
@@ -55,6 +74,7 @@ namespace llvm {
std::vector<MCDwarfFrameInfo> FrameInfos;
MCDwarfFrameInfo *getCurrentFrameInfo();
+ MCSymbol *EmitCFICommon();
void EnsureValidFrame();
std::vector<MCWin64EHUnwindInfo *> W64UnwindInfos;
@@ -69,8 +89,10 @@ namespace llvm {
SmallVector<std::pair<const MCSection *,
const MCSection *>, 4> SectionStack;
+ bool AutoInitSections;
+
protected:
- MCStreamer(MCContext &Ctx);
+ MCStreamer(StreamerKind Kind, MCContext &Ctx);
const MCExpr *BuildSymbolDiff(MCContext &Context, const MCSymbol *A,
const MCSymbol *B);
@@ -89,6 +111,12 @@ namespace llvm {
public:
virtual ~MCStreamer();
+ StreamerKind getKind() const { return Kind; }
+
+ /// State management
+ ///
+ virtual void reset();
+
MCContext &getContext() const { return Context; }
unsigned getNumFrameInfos() {
@@ -213,9 +241,23 @@ namespace llvm {
SectionStack.back().first = Section;
}
+ /// Initialize the streamer.
+ void InitStreamer() {
+ if (AutoInitSections)
+ InitSections();
+ }
+
+ /// Tell this MCStreamer to call InitSections upon initialization.
+ void setAutoInitSections(bool AutoInitSections) {
+ this->AutoInitSections = AutoInitSections;
+ }
+
/// InitSections - Create the default sections and set the initial one.
virtual void InitSections() = 0;
+ /// InitToTextSection - Create a text section and switch the streamer to it.
+ virtual void InitToTextSection() = 0;
+
/// EmitLabel - Emit a label for @p Symbol into the current section.
///
/// This corresponds to an assembler statement such as:
@@ -226,12 +268,18 @@ namespace llvm {
/// used in an assignment.
virtual void EmitLabel(MCSymbol *Symbol);
+ virtual void EmitDebugLabel(MCSymbol *Symbol);
+
virtual void EmitEHSymAttributes(const MCSymbol *Symbol,
MCSymbol *EHSymbol);
/// EmitAssemblerFlag - Note in the output the specified @p Flag.
virtual void EmitAssemblerFlag(MCAssemblerFlag Flag) = 0;
+ /// EmitLinkerOptions - Emit the given list @p Options of strings as linker
+ /// options into the output.
+ virtual void EmitLinkerOptions(ArrayRef<std::string> Kind) {}
+
/// EmitDataRegion - Note in the output the specified region @p Kind.
virtual void EmitDataRegion(MCDataRegionType Kind) {}
@@ -239,6 +287,9 @@ namespace llvm {
/// a Thumb mode function (ARM target only).
virtual void EmitThumbFunc(MCSymbol *Func) = 0;
+ /// getOrCreateSymbolData - Get symbol data for given symbol.
+ virtual MCSymbolData &getOrCreateSymbolData(MCSymbol *Symbol);
+
/// EmitAssignment - Emit an assignment of @p Value to @p Symbol.
///
/// This corresponds to an assembler statement such as:
@@ -346,7 +397,7 @@ namespace llvm {
///
/// This is used to implement assembler directives such as .byte, .ascii,
/// etc.
- virtual void EmitBytes(StringRef Data, unsigned AddrSpace) = 0;
+ virtual void EmitBytes(StringRef Data, unsigned AddrSpace = 0) = 0;
/// EmitValue - Emit the expression @p Value into the output as a native
/// integer of the given @p Size bytes.
@@ -380,8 +431,8 @@ namespace llvm {
/// EmitULEB128Value - Special case of EmitULEB128Value that avoids the
/// client having to pass in a MCExpr for constant integers.
- void EmitULEB128IntValue(uint64_t Value, unsigned AddrSpace = 0,
- unsigned Padding = 0);
+ void EmitULEB128IntValue(uint64_t Value, unsigned Padding = 0,
+ unsigned AddrSpace = 0);
/// EmitSLEB128Value - Special case of EmitSLEB128Value that avoids the
/// client having to pass in a MCExpr for constant integers.
@@ -409,15 +460,14 @@ namespace llvm {
/// EmitFill - Emit NumBytes bytes worth of the value specified by
/// FillValue. This implements directives such as '.space'.
virtual void EmitFill(uint64_t NumBytes, uint8_t FillValue,
- unsigned AddrSpace);
+ unsigned AddrSpace = 0);
/// EmitZeros - Emit NumBytes worth of zeros. This is a convenience
/// function that just wraps EmitFill.
- void EmitZeros(uint64_t NumBytes, unsigned AddrSpace) {
+ void EmitZeros(uint64_t NumBytes, unsigned AddrSpace = 0) {
EmitFill(NumBytes, 0, AddrSpace);
}
-
/// EmitValueToAlignment - Emit some number of copies of @p Value until
/// the byte alignment @p ByteAlignment is reached.
///
@@ -475,7 +525,7 @@ namespace llvm {
/// file number. This implements the DWARF2 '.file 4 "foo.c"' assembler
/// directive.
virtual bool EmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
- StringRef Filename);
+ StringRef Filename, unsigned CUID = 0);
/// EmitDwarfLocDirective - This implements the DWARF2
// '.loc fileno lineno ...' assembler directive.
@@ -515,6 +565,8 @@ namespace llvm {
virtual void EmitCFIAdjustCfaOffset(int64_t Adjustment);
virtual void EmitCFIEscape(StringRef Values);
virtual void EmitCFISignalFrame();
+ virtual void EmitCFIUndefined(int64_t Register);
+ virtual void EmitCFIRegister(int64_t Register1, int64_t Register2);
virtual void EmitWin64EHStartProc(const MCSymbol *Symbol);
virtual void EmitWin64EHEndProc();
@@ -535,6 +587,20 @@ namespace llvm {
/// section.
virtual void EmitInstruction(const MCInst &Inst) = 0;
+ /// \brief Set the bundle alignment mode from now on in the section.
+ /// The argument is the power of 2 to which the alignment is set. The
+ /// value 0 means turn the bundle alignment off.
+ virtual void EmitBundleAlignMode(unsigned AlignPow2) = 0;
+
+ /// \brief The following instructions are a bundle-locked group.
+ ///
+ /// \param AlignToEnd - If true, the bundle-locked group will be aligned to
+ /// the end of a bundle.
+ virtual void EmitBundleLock(bool AlignToEnd) = 0;
+
+ /// \brief Ends a bundle-locked group.
+ virtual void EmitBundleUnlock() = 0;
+
/// EmitRawText - If this file is backed by a assembly streamer, this dumps
/// the specified string in the output .s file. This capability is
/// indicated by the hasRawTextSupport() predicate. By default this aborts.
diff --git a/include/llvm/MC/MCSubtargetInfo.h b/include/llvm/MC/MCSubtargetInfo.h
index 69213cd..346fb2d 100644
--- a/include/llvm/MC/MCSubtargetInfo.h
+++ b/include/llvm/MC/MCSubtargetInfo.h
@@ -14,8 +14,8 @@
#ifndef LLVM_MC_MCSUBTARGET_H
#define LLVM_MC_MCSUBTARGET_H
-#include "llvm/MC/SubtargetFeature.h"
#include "llvm/MC/MCInstrItineraries.h"
+#include "llvm/MC/SubtargetFeature.h"
#include <string>
namespace llvm {
diff --git a/include/llvm/MC/MCTargetAsmLexer.h b/include/llvm/MC/MCTargetAsmLexer.h
deleted file mode 100644
index b1cc546..0000000
--- a/include/llvm/MC/MCTargetAsmLexer.h
+++ /dev/null
@@ -1,89 +0,0 @@
-//===-- llvm/MC/MCTargetAsmLexer.h - Target Assembly Lexer ------*- 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_MCTARGETASMLEXER_H
-#define LLVM_MC_MCTARGETASMLEXER_H
-
-#include "llvm/MC/MCParser/MCAsmLexer.h"
-
-namespace llvm {
-class Target;
-
-/// MCTargetAsmLexer - Generic interface to target specific assembly lexers.
-class MCTargetAsmLexer {
- /// The current token
- AsmToken CurTok;
-
- /// The location and description of the current error
- SMLoc ErrLoc;
- std::string Err;
-
- MCTargetAsmLexer(const MCTargetAsmLexer &) LLVM_DELETED_FUNCTION;
- void operator=(const MCTargetAsmLexer &) LLVM_DELETED_FUNCTION;
-protected: // Can only create subclasses.
- MCTargetAsmLexer(const Target &);
-
- virtual AsmToken LexToken() = 0;
-
- void SetError(const SMLoc &errLoc, const std::string &err) {
- ErrLoc = errLoc;
- Err = err;
- }
-
- /// TheTarget - The Target that this machine was created for.
- const Target &TheTarget;
- MCAsmLexer *Lexer;
-
-public:
- virtual ~MCTargetAsmLexer();
-
- const Target &getTarget() const { return TheTarget; }
-
- /// InstallLexer - Set the lexer to get tokens from lower-level lexer \p L.
- void InstallLexer(MCAsmLexer &L) {
- Lexer = &L;
- }
-
- MCAsmLexer *getLexer() {
- return Lexer;
- }
-
- /// Lex - Consume the next token from the input stream and return it.
- const AsmToken &Lex() {
- return CurTok = LexToken();
- }
-
- /// getTok - Get the current (last) lexed token.
- const AsmToken &getTok() {
- return CurTok;
- }
-
- /// getErrLoc - Get the current error location
- const SMLoc &getErrLoc() {
- return ErrLoc;
- }
-
- /// getErr - Get the current error string
- const std::string &getErr() {
- return Err;
- }
-
- /// getKind - Get the kind of current token.
- AsmToken::TokenKind getKind() const { return CurTok.getKind(); }
-
- /// is - Check if the current token has kind \p K.
- bool is(AsmToken::TokenKind K) const { return CurTok.is(K); }
-
- /// isNot - Check if the current token has kind \p K.
- bool isNot(AsmToken::TokenKind K) const { return CurTok.isNot(K); }
-};
-
-} // End llvm namespace
-
-#endif
diff --git a/include/llvm/MC/MCTargetAsmParser.h b/include/llvm/MC/MCTargetAsmParser.h
index 483a80b..4c5b176 100644
--- a/include/llvm/MC/MCTargetAsmParser.h
+++ b/include/llvm/MC/MCTargetAsmParser.h
@@ -22,6 +22,7 @@ class MCInst;
template <typename T> class SmallVectorImpl;
enum AsmRewriteKind {
+ AOK_Align, // Rewrite align as .align.
AOK_DotOperator, // Rewrite a dot operator expression as an immediate.
// E.g., [eax].foo.bar -> [eax].8
AOK_Emit, // Rewrite _emit as .byte.
@@ -142,6 +143,15 @@ public:
MCStreamer &Out, unsigned &ErrorInfo,
bool MatchingInlineAsm) = 0;
+ /// Allow a target to add special case operand matching for things that
+ /// tblgen doesn't/can't handle effectively. For example, literal
+ /// immediates on ARM. TableGen expects a token operand, but the parser
+ /// will recognize them as immediates.
+ virtual unsigned validateTargetOperandClass(MCParsedAsmOperand *Op,
+ unsigned Kind) {
+ return Match_InvalidOperand;
+ }
+
/// checkTargetMatchPredicate - Validate the instruction match against
/// any complex target predicates not expressible via match classes.
virtual unsigned checkTargetMatchPredicate(MCInst &Inst) {
diff --git a/include/llvm/MC/MCValue.h b/include/llvm/MC/MCValue.h
index f9af8bc..a4e7301 100644
--- a/include/llvm/MC/MCValue.h
+++ b/include/llvm/MC/MCValue.h
@@ -14,8 +14,8 @@
#ifndef LLVM_MC_MCVALUE_H
#define LLVM_MC_MCVALUE_H
-#include "llvm/Support/DataTypes.h"
#include "llvm/MC/MCSymbol.h"
+#include "llvm/Support/DataTypes.h"
#include <cassert>
namespace llvm {
diff --git a/include/llvm/MC/MCWinCOFFObjectWriter.h b/include/llvm/MC/MCWinCOFFObjectWriter.h
index 7a0b1ff..11df574 100644
--- a/include/llvm/MC/MCWinCOFFObjectWriter.h
+++ b/include/llvm/MC/MCWinCOFFObjectWriter.h
@@ -11,6 +11,9 @@
#define LLVM_MC_MCWINCOFFOBJECTWRITER_H
namespace llvm {
+ class MCObjectWriter;
+ class raw_ostream;
+
class MCWinCOFFObjectTargetWriter {
const unsigned Machine;
diff --git a/include/llvm/MC/SubtargetFeature.h b/include/llvm/MC/SubtargetFeature.h
index 57f0518..37ae03b 100644
--- a/include/llvm/MC/SubtargetFeature.h
+++ b/include/llvm/MC/SubtargetFeature.h
@@ -18,9 +18,9 @@
#ifndef LLVM_MC_SUBTARGETFEATURE_H
#define LLVM_MC_SUBTARGETFEATURE_H
-#include <vector>
#include "llvm/ADT/Triple.h"
#include "llvm/Support/DataTypes.h"
+#include <vector>
namespace llvm {
class raw_ostream;
OpenPOWER on IntegriCloud