aboutsummaryrefslogtreecommitdiffstats
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.h20
-rw-r--r--include/llvm/MC/MCAsmInfo.h10
-rw-r--r--include/llvm/MC/MCAsmLayout.h26
-rw-r--r--include/llvm/MC/MCAssembler.h267
-rw-r--r--include/llvm/MC/MCCodeEmitter.h7
-rw-r--r--include/llvm/MC/MCContext.h44
-rw-r--r--include/llvm/MC/MCDisassembler.h12
-rw-r--r--include/llvm/MC/MCDwarf.h130
-rw-r--r--include/llvm/MC/MCELF.h35
-rw-r--r--include/llvm/MC/MCELFObjectWriter.h9
-rw-r--r--include/llvm/MC/MCELFStreamer.h113
-rw-r--r--include/llvm/MC/MCExpr.h33
-rw-r--r--include/llvm/MC/MCInst.h2
-rw-r--r--include/llvm/MC/MCInstBuilder.h68
-rw-r--r--include/llvm/MC/MCInstPrinter.h25
-rw-r--r--include/llvm/MC/MCInstrDesc.h102
-rw-r--r--include/llvm/MC/MCLabel.h2
-rw-r--r--include/llvm/MC/MCMachObjectWriter.h22
-rw-r--r--include/llvm/MC/MCObjectFileInfo.h71
-rw-r--r--include/llvm/MC/MCObjectStreamer.h23
-rw-r--r--include/llvm/MC/MCObjectWriter.h11
-rw-r--r--include/llvm/MC/MCParser/MCAsmLexer.h19
-rw-r--r--include/llvm/MC/MCParser/MCAsmParser.h36
-rw-r--r--include/llvm/MC/MCParser/MCAsmParserExtension.h6
-rw-r--r--include/llvm/MC/MCParser/MCParsedAsmOperand.h54
-rw-r--r--include/llvm/MC/MCRegisterInfo.h104
-rw-r--r--include/llvm/MC/MCSchedule.h141
-rw-r--r--include/llvm/MC/MCSection.h8
-rw-r--r--include/llvm/MC/MCSectionCOFF.h9
-rw-r--r--include/llvm/MC/MCSectionELF.h10
-rw-r--r--include/llvm/MC/MCSectionMachO.h11
-rw-r--r--include/llvm/MC/MCStreamer.h60
-rw-r--r--include/llvm/MC/MCSubtargetInfo.h65
-rw-r--r--include/llvm/MC/MCSymbol.h6
-rw-r--r--include/llvm/MC/MCTargetAsmLexer.h89
-rw-r--r--include/llvm/MC/MCTargetAsmParser.h79
-rw-r--r--include/llvm/MC/MCValue.h4
-rw-r--r--include/llvm/MC/MCWinCOFFObjectWriter.h3
-rw-r--r--include/llvm/MC/SubtargetFeature.h6
40 files changed, 1314 insertions, 457 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 1c45090..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;
@@ -36,10 +36,14 @@ protected: // Can only create subclasses.
MCAsmBackend();
unsigned HasReliableSymbolDifference : 1;
+ unsigned HasDataInCodeSupport : 1;
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;
@@ -65,6 +69,12 @@ public:
return HasReliableSymbolDifference;
}
+ /// hasDataInCodeSupport - Check whether this target implements data-in-code
+ /// markers. If not, data region directives will be ignored.
+ bool hasDataInCodeSupport() const {
+ return HasDataInCodeSupport;
+ }
+
/// doesSectionRequireSymbols - Check whether the given section requires that
/// all symbols (even temporaries) have symbol table entries.
virtual bool doesSectionRequireSymbols(const MCSection &Section) const {
@@ -99,7 +109,7 @@ public:
/// @}
- /// applyFixup - Apply the \arg Value for given \arg Fixup into the provided
+ /// applyFixup - Apply the \p Value for given \p Fixup into the provided
/// data fragment, at the offset specified by the fixup and following the
/// fixup kind as appropriate.
virtual void applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize,
@@ -120,15 +130,15 @@ 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
/// wider instruction.
///
- /// \param Inst - The instruction to relax, which may be the same as the
+ /// \param Inst The instruction to relax, which may be the same as the
/// output.
- /// \parm Res [output] - On return, the relaxed instruction.
+ /// \param [out] Res On return, the relaxed instruction.
virtual void relaxInstruction(const MCInst &Inst, MCInst &Res) const = 0;
/// @}
diff --git a/include/llvm/MC/MCAsmInfo.h b/include/llvm/MC/MCAsmInfo.h
index 97aad71..38cf060 100644
--- a/include/llvm/MC/MCAsmInfo.h
+++ b/include/llvm/MC/MCAsmInfo.h
@@ -16,8 +16,8 @@
#ifndef LLVM_TARGET_ASM_INFO_H
#define LLVM_TARGET_ASM_INFO_H
-#include "llvm/MC/MachineLocation.h"
#include "llvm/MC/MCDirectives.h"
+#include "llvm/MC/MachineLocation.h"
#include <cassert>
#include <vector>
@@ -102,6 +102,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 ""
@@ -426,6 +429,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/MCAsmLayout.h b/include/llvm/MC/MCAsmLayout.h
index cf79216..8cb4601 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,14 @@ 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 after F because it has been resized.
+ /// The fragment's size should have already been updated.
+ void invalidateFragmentsAfter(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 1858349..40766b4 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.
@@ -53,7 +53,7 @@ public:
FT_Align,
FT_Data,
FT_Fill,
- FT_Inst,
+ FT_Relaxable,
FT_Org,
FT_Dwarf,
FT_DwarfFrame,
@@ -107,44 +107,107 @@ public:
unsigned getLayoutOrder() const { return LayoutOrder; }
void setLayoutOrder(unsigned Value) { LayoutOrder = Value; }
- static bool classof(const MCFragment *O) { return true; }
+ /// \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; }
+
+ /// \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 {
+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();
-public:
- MCDataFragment(MCSectionData *SD = 0) : MCFragment(FT_Data, SD) {}
+ typedef SmallVectorImpl<MCFixup>::const_iterator const_fixup_iterator;
+ typedef SmallVectorImpl<MCFixup>::iterator fixup_iterator;
- /// @name Accessors
- /// @{
+ virtual SmallVectorImpl<char> &getContents() = 0;
+ virtual const SmallVectorImpl<char> &getContents() const = 0;
- SmallString<32> &getContents() { return Contents; }
- const SmallString<32> &getContents() const { return Contents; }
+ virtual SmallVectorImpl<MCFixup> &getFixups() = 0;
+ virtual const SmallVectorImpl<MCFixup> &getFixups() const = 0;
- /// @}
- /// @name Fixup Access
- /// @{
+ 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;
+
+ virtual uint8_t getBundlePadding() const {
+ return BundlePadding;
+ }
- 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);
+ virtual void setBundlePadding(uint8_t N) {
+ BundlePadding = N;
}
- std::vector<MCFixup> &getFixups() { return Fixups; }
- const std::vector<MCFixup> &getFixups() const { return Fixups; }
+ 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 MCEncodedFragment {
+ 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;
+
+ /// Fixups - The list of fixups in this fragment.
+ SmallVector<MCFixup, 4> Fixups;
+public:
+ MCDataFragment(MCSectionData *SD = 0)
+ : MCEncodedFragment(FT_Data, SD),
+ HasInstructions(false), AlignToBundleEnd(false)
+ {
+ }
+
+ 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(); }
@@ -152,61 +215,46 @@ 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;
}
- static bool classof(const MCDataFragment *) { return true; }
};
-// 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 MCEncodedFragment {
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)
+ : MCEncodedFragment(FT_Relaxable, SD), Inst(_Inst) {
}
- /// @name Accessors
- /// @{
-
- SmallVectorImpl<char> &getCode() { return Code; }
- const SmallVectorImpl<char> &getCode() const { return Code; }
-
- unsigned getInstSize() const { return Code.size(); }
+ virtual SmallVectorImpl<char> &getContents() { return Contents; }
+ virtual const SmallVectorImpl<char> &getContents() const { return Contents; }
- 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;
+ }
- SmallVectorImpl<MCFixup> &getFixups() { return Fixups; }
- const SmallVectorImpl<MCFixup> &getFixups() const { 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(); }
@@ -214,14 +262,9 @@ 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;
}
- static bool classof(const MCInstFragment *) { return true; }
};
class MCAlignFragment : public MCFragment {
@@ -233,7 +276,7 @@ class MCAlignFragment : public MCFragment {
/// Value - Value to use for filling padding bytes.
int64_t Value;
- /// ValueSize - The size of the integer (in bytes) of \arg Value.
+ /// ValueSize - The size of the integer (in bytes) of \p Value.
unsigned ValueSize;
/// MaxBytesToEmit - The maximum number of bytes to emit; if the alignment
@@ -271,7 +314,6 @@ public:
static bool classof(const MCFragment *F) {
return F->getKind() == MCFragment::FT_Align;
}
- static bool classof(const MCAlignFragment *) { return true; }
};
class MCFillFragment : public MCFragment {
@@ -280,7 +322,7 @@ class MCFillFragment : public MCFragment {
/// Value - Value to use for filling bytes.
int64_t Value;
- /// ValueSize - The size (in bytes) of \arg Value to use when filling, or 0 if
+ /// ValueSize - The size (in bytes) of \p Value to use when filling, or 0 if
/// this is a virtual fill fragment.
unsigned ValueSize;
@@ -310,7 +352,6 @@ public:
static bool classof(const MCFragment *F) {
return F->getKind() == MCFragment::FT_Fill;
}
- static bool classof(const MCFillFragment *) { return true; }
};
class MCOrgFragment : public MCFragment {
@@ -339,7 +380,6 @@ public:
static bool classof(const MCFragment *F) {
return F->getKind() == MCFragment::FT_Org;
}
- static bool classof(const MCOrgFragment *) { return true; }
};
class MCLEBFragment : public MCFragment {
@@ -372,7 +412,6 @@ public:
static bool classof(const MCFragment *F) {
return F->getKind() == MCFragment::FT_LEB;
}
- static bool classof(const MCLEBFragment *) { return true; }
};
class MCDwarfLineAddrFragment : public MCFragment {
@@ -409,7 +448,6 @@ public:
static bool classof(const MCFragment *F) {
return F->getKind() == MCFragment::FT_Dwarf;
}
- static bool classof(const MCDwarfLineAddrFragment *) { return true; }
};
class MCDwarfCallFrameFragment : public MCFragment {
@@ -439,7 +477,6 @@ public:
static bool classof(const MCFragment *F) {
return F->getKind() == MCFragment::FT_DwarfFrame;
}
- static bool classof(const MCDwarfCallFrameFragment *) { return true; }
};
// FIXME: Should this be a separate class, or just merged into MCSection? Since
@@ -448,8 +485,8 @@ public:
class MCSectionData : public ilist_node<MCSectionData> {
friend class MCAsmLayout;
- MCSectionData(const MCSectionData&); // DO NOT IMPLEMENT
- void operator=(const MCSectionData&); // DO NOT IMPLEMENT
+ MCSectionData(const MCSectionData&) LLVM_DELETED_FUNCTION;
+ void operator=(const MCSectionData&) LLVM_DELETED_FUNCTION;
public:
typedef iplist<MCFragment> FragmentListType;
@@ -460,6 +497,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;
@@ -473,6 +516,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
/// @{
//
@@ -525,6 +575,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();
/// @}
@@ -691,8 +761,8 @@ public:
typedef std::vector<DataRegionData>::iterator data_region_iterator;
private:
- MCAssembler(const MCAssembler&); // DO NOT IMPLEMENT
- void operator=(const MCAssembler&); // DO NOT IMPLEMENT
+ MCAssembler(const MCAssembler&) LLVM_DELETED_FUNCTION;
+ void operator=(const MCAssembler&) LLVM_DELETED_FUNCTION;
MCContext &Context;
@@ -730,6 +800,11 @@ 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;
@@ -746,7 +821,7 @@ private:
/// \param Value [out] On return, the value of the fixup as currently laid
/// out.
/// \return Whether the fixup value was fully resolved. This is true if the
- /// \arg Value result is fixed, otherwise the value may change due to
+ /// \p Value result is fixed, otherwise the value may change due to
/// relocation.
bool evaluateFixup(const MCAsmLayout &Layout,
const MCFixup &Fixup, const MCFragment *DF,
@@ -754,20 +829,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);
@@ -783,7 +860,7 @@ private:
public:
/// Compute the effective fragment size assuming it is laid out at the given
- /// \arg SectionAddress and \arg FragmentOffset.
+ /// \p SectionAddress and \p FragmentOffset.
uint64_t computeFragmentSize(const MCAsmLayout &Layout,
const MCFragment &F) const;
@@ -812,7 +889,7 @@ public:
public:
/// Construct a new assembler instance.
///
- /// \arg OS - The stream to output to.
+ /// \param OS The stream to output to.
//
// FIXME: How are we going to parameterize this? Two obvious options are stay
// concrete and require clients to pass in a target like object. The other
@@ -823,6 +900,10 @@ public:
raw_ostream &OS);
~MCAssembler();
+ /// Reuse an assembler instance
+ ///
+ void reset();
+
MCContext &getContext() const { return Context; }
MCAsmBackend &getBackend() const { return Backend; }
@@ -834,7 +915,7 @@ public:
void setWriter(MCObjectWriter &ObjectWriter);
/// Finish - Do final processing and write the object to the output stream.
- /// \arg Writer is used for custom object writer (as the MCJIT does),
+ /// \p Writer is used for custom object writer (as the MCJIT does),
/// if not specified it is automatically created from backend.
void Finish();
@@ -852,6 +933,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
/// @{
diff --git a/include/llvm/MC/MCCodeEmitter.h b/include/llvm/MC/MCCodeEmitter.h
index 4f7d103..9bfa08e 100644
--- a/include/llvm/MC/MCCodeEmitter.h
+++ b/include/llvm/MC/MCCodeEmitter.h
@@ -29,8 +29,11 @@ protected: // Can only create subclasses.
public:
virtual ~MCCodeEmitter();
- /// EncodeInstruction - Encode the given \arg Inst to bytes on the output
- /// stream \arg OS.
+ /// 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,
SmallVectorImpl<MCFixup> &Fixups) const = 0;
};
diff --git a/include/llvm/MC/MCContext.h b/include/llvm/MC/MCContext.h
index 23652f0..e92d3b9 100644
--- a/include/llvm/MC/MCContext.h
+++ b/include/llvm/MC/MCContext.h
@@ -10,10 +10,10 @@
#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/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"
@@ -94,6 +94,12 @@ 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;
@@ -137,11 +143,15 @@ namespace llvm {
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 +164,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
/// @{
@@ -183,6 +202,7 @@ namespace llvm {
/// LookupSymbol - Get the symbol for \p Name, or null.
MCSymbol *LookupSymbol(StringRef Name) const;
+ MCSymbol *LookupSymbol(const Twine &Name) const;
/// getSymbols - Get a reference for the symbol table for clients that
/// want to, for example, iterate over all symbols. 'const' because we
@@ -234,6 +254,24 @@ 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);
diff --git a/include/llvm/MC/MCDisassembler.h b/include/llvm/MC/MCDisassembler.h
index 53a9ce0..1b6beb2 100644
--- a/include/llvm/MC/MCDisassembler.h
+++ b/include/llvm/MC/MCDisassembler.h
@@ -9,8 +9,8 @@
#ifndef MCDISASSEMBLER_H
#define 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 9e09ddf..3160b61 100644
--- a/include/llvm/MC/MCDwarf.h
+++ b/include/llvm/MC/MCDwarf.h
@@ -16,10 +16,9 @@
#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 <vector>
namespace llvm {
@@ -59,7 +58,7 @@ namespace llvm {
unsigned getDirIndex() const { return DirIndex; }
- /// print - Print the value to the stream \arg OS.
+ /// print - Print the value to the stream \p OS.
void print(raw_ostream &OS) const;
/// dump - Print the value to stderr.
@@ -178,8 +177,8 @@ namespace llvm {
class MCLineSection {
private:
- MCLineSection(const MCLineSection&); // DO NOT IMPLEMENT
- void operator=(const MCLineSection&); // DO NOT IMPLEMENT
+ MCLineSection(const MCLineSection&) LLVM_DELETED_FUNCTION;
+ void operator=(const MCLineSection&) LLVM_DELETED_FUNCTION;
public:
// Constructor to create an MCLineSection with an empty MCLineEntries
@@ -266,42 +265,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, "");
}
- MCCFIInstruction(OpType Op, MCSymbol *L, unsigned Register)
- : Operation(Op), Label(L), Destination(Register) {
- assert(Op == SameValue || Op == Restore);
+
+ static MCCFIInstruction
+ createDefCfaRegister(MCSymbol *L, unsigned Register) {
+ return MCCFIInstruction(OpDefCfaRegister, L, Register, 0, "");
}
- MCCFIInstruction(MCSymbol *L, const MachineLocation &D,
- const MachineLocation &S)
- : Operation(Move), Label(L), Destination(D), Source(S) {
+
+ static MCCFIInstruction createDefCfaOffset(MCSymbol *L, int Offset) {
+ return MCCFIInstruction(OpDefCfaOffset, L, 0, -Offset, "");
}
- MCCFIInstruction(OpType Op, MCSymbol *L, const MachineLocation &D,
- const MachineLocation &S)
- : Operation(Op), Label(L), Destination(D), Source(S) {
- assert(Op == RelMove);
+
+ static MCCFIInstruction
+ createDefCfa(MCSymbol *L, unsigned Register, int Offset) {
+ return MCCFIInstruction(OpDefCfa, L, Register, -Offset, "");
}
- MCCFIInstruction(OpType Op, MCSymbol *L, StringRef Vals)
- : Operation(Op), Label(L), Values(Vals.begin(), Vals.end()) {
- assert(Op == Escape);
+
+ static MCCFIInstruction createUndefined(MCSymbol *L, unsigned Register) {
+ return MCCFIInstruction(OpUndefined, L, Register, 0, "");
+ }
+
+ 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, "");
}
+
+ 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, "");
+ }
+
+ static MCCFIInstruction createEscape(MCSymbol *L, StringRef Vals) {
+ return MCCFIInstruction(OpEscape, L, 0, 0, Vals);
+ }
+
+ 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..e08f1e6
--- /dev/null
+++ b/include/llvm/MC/MCELF.h
@@ -0,0 +1,35 @@
+//===- 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);
+};
+
+}
+
+#endif
diff --git a/include/llvm/MC/MCELFObjectWriter.h b/include/llvm/MC/MCELFObjectWriter.h
index abbe188..38cdc72 100644
--- a/include/llvm/MC/MCELFObjectWriter.h
+++ b/include/llvm/MC/MCELFObjectWriter.h
@@ -85,6 +85,9 @@ public:
const MCFragment &F,
const MCFixup &Fixup,
bool IsPCRel) const;
+ virtual const MCSymbol *undefinedExplicitRelSym(const MCValue &Target,
+ const MCFixup &Fixup,
+ bool IsPCRel) const;
virtual void adjustFixupOffset(const MCFixup &Fixup,
uint64_t &RelocOffset);
@@ -93,9 +96,9 @@ public:
/// @name Accessors
/// @{
- uint8_t getOSABI() { return OSABI; }
- uint16_t getEMachine() { return EMachine; }
- bool hasRelocationAddend() { return HasRelocationAddend; }
+ uint8_t getOSABI() const { return OSABI; }
+ uint16_t getEMachine() const { return EMachine; }
+ bool hasRelocationAddend() const { return HasRelocationAddend; }
bool is64Bit() const { return Is64Bit; }
bool isN64() const { return IsN64; }
/// @}
diff --git a/include/llvm/MC/MCELFStreamer.h b/include/llvm/MC/MCELFStreamer.h
new file mode 100644
index 0000000..ab20ee8
--- /dev/null
+++ b/include/llvm/MC/MCELFStreamer.h
@@ -0,0 +1,113 @@
+//===- 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 {
+public:
+ MCELFStreamer(MCContext &Context, MCAsmBackend &TAB,
+ raw_ostream &OS, MCCodeEmitter *Emitter)
+ : MCObjectStreamer(Context, TAB, OS, Emitter) {}
+
+ MCELFStreamer(MCContext &Context, MCAsmBackend &TAB,
+ raw_ostream &OS, MCCodeEmitter *Emitter,
+ MCAssembler *Assembler)
+ : MCObjectStreamer(Context, TAB, OS, Emitter, Assembler) {}
+
+ virtual ~MCELFStreamer();
+
+ /// @name MCStreamer Interface
+ /// @{
+
+ virtual void InitSections();
+ 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 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();
+ /// @}
+
+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 f36db3c..475981f 100644
--- a/include/llvm/MC/MCExpr.h
+++ b/include/llvm/MC/MCExpr.h
@@ -99,8 +99,6 @@ public:
const MCSection *FindAssociatedSection() const;
/// @}
-
- static bool classof(const MCExpr *) { return true; }
};
inline raw_ostream &operator<<(raw_ostream &OS, const MCExpr &E) {
@@ -132,7 +130,6 @@ public:
static bool classof(const MCExpr *E) {
return E->getKind() == MCExpr::Constant;
}
- static bool classof(const MCConstantExpr *) { return true; }
};
/// MCSymbolRefExpr - Represent a reference to a symbol from inside an
@@ -163,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,
@@ -170,15 +168,30 @@ public:
VK_ARM_TPOFF,
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,
@@ -199,7 +212,11 @@ public:
VK_Mips_GOT_PAGE,
VK_Mips_GOT_OFST,
VK_Mips_HIGHER,
- VK_Mips_HIGHEST
+ VK_Mips_HIGHEST,
+ VK_Mips_GOT_HI16,
+ VK_Mips_GOT_LO16,
+ VK_Mips_CALL_HI16,
+ VK_Mips_CALL_LO16
};
private:
@@ -248,7 +265,6 @@ public:
static bool classof(const MCExpr *E) {
return E->getKind() == MCExpr::SymbolRef;
}
- static bool classof(const MCSymbolRefExpr *) { return true; }
};
/// MCUnaryExpr - Unary assembler expressions.
@@ -302,7 +318,6 @@ public:
static bool classof(const MCExpr *E) {
return E->getKind() == MCExpr::Unary;
}
- static bool classof(const MCUnaryExpr *) { return true; }
};
/// MCBinaryExpr - Binary assembler expressions.
@@ -437,7 +452,6 @@ public:
static bool classof(const MCExpr *E) {
return E->getKind() == MCExpr::Binary;
}
- static bool classof(const MCBinaryExpr *) { return true; }
};
/// MCTargetExpr - This is an extension point for target-specific MCExpr
@@ -446,7 +460,7 @@ public:
/// NOTE: All subclasses are required to have trivial destructors because
/// MCExprs are bump pointer allocated and not destructed.
class MCTargetExpr : public MCExpr {
- virtual void Anchor();
+ virtual void anchor();
protected:
MCTargetExpr() : MCExpr(Target) {}
virtual ~MCTargetExpr() {}
@@ -461,7 +475,6 @@ public:
static bool classof(const MCExpr *E) {
return E->getKind() == MCExpr::Target;
}
- static bool classof(const MCTargetExpr *) { return true; }
};
} // end namespace llvm
diff --git a/include/llvm/MC/MCInst.h b/include/llvm/MC/MCInst.h
index 397a37d..e91c6a2 100644
--- a/include/llvm/MC/MCInst.h
+++ b/include/llvm/MC/MCInst.h
@@ -182,7 +182,7 @@ public:
void dump() const;
/// \brief Dump the MCInst as prettily as possible using the additional MC
- /// structures, if given. Operators are separated by the \arg Separator
+ /// structures, if given. Operators are separated by the \p Separator
/// string.
void dump_pretty(raw_ostream &OS, const MCAsmInfo *MAI = 0,
const MCInstPrinter *Printer = 0,
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 3c4f28b..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;
@@ -33,12 +36,19 @@ protected:
/// The current set of available features.
unsigned AvailableFeatures;
+ /// 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) {}
+ : CommentStream(0), MAI(mai), MII(mii), MRI(mri), AvailableFeatures(0),
+ UseMarkup(0), PrintImmHex(0) {}
virtual ~MCInstPrinter();
@@ -59,6 +69,19 @@ public:
unsigned getAvailableFeatures() const { return AvailableFeatures; }
void setAvailableFeatures(unsigned Value) { AvailableFeatures = Value; }
+
+ bool getUseMarkup() const { return UseMarkup; }
+ void setUseMarkup(bool Value) { UseMarkup = Value; }
+
+ /// 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 dbf16d8..9b5415a 100644
--- a/include/llvm/MC/MCInstrDesc.h
+++ b/include/llvm/MC/MCInstrDesc.h
@@ -1,4 +1,4 @@
-//===-- llvm/Mc/McInstrDesc.h - Instruction Descriptors -*- C++ -*-===//
+//===-- llvm/MC/MCInstrDesc.h - Instruction Descriptors -*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -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/MCLabel.h b/include/llvm/MC/MCLabel.h
index c72aabd..f531de8 100644
--- a/include/llvm/MC/MCLabel.h
+++ b/include/llvm/MC/MCLabel.h
@@ -42,7 +42,7 @@ namespace llvm {
/// Label.
unsigned incInstance() { return ++Instance; }
- /// print - Print the value to the stream \arg OS.
+ /// print - Print the value to the stream \p OS.
void print(raw_ostream &OS) const;
/// dump - Print the value to stderr.
diff --git a/include/llvm/MC/MCMachObjectWriter.h b/include/llvm/MC/MCMachObjectWriter.h
index 949d907..3cd278e 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
/// @{
@@ -153,8 +167,8 @@ public:
/// WriteSegmentLoadCommand - Write a segment load command.
///
- /// \arg NumSections - The number of sections in this segment.
- /// \arg SectionDataSize - The total size of the sections.
+ /// \param NumSections The number of sections in this segment.
+ /// \param SectionDataSize The total size of the sections.
void WriteSegmentLoadCommand(unsigned NumSections,
uint64_t VMSize,
uint64_t SectionDataStartOffset,
@@ -223,8 +237,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,
@@ -233,6 +245,8 @@ public:
void computeSectionAddresses(const MCAssembler &Asm,
const MCAsmLayout &Layout);
+ void markAbsoluteVariableSymbols(MCAssembler &Asm,
+ const MCAsmLayout &Layout);
void ExecutePostLayoutBinding(MCAssembler &Asm, const MCAsmLayout &Layout);
virtual bool IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
diff --git a/include/llvm/MC/MCObjectFileInfo.h b/include/llvm/MC/MCObjectFileInfo.h
index 74e2263..c8444fd 100644
--- a/include/llvm/MC/MCObjectFileInfo.h
+++ b/include/llvm/MC/MCObjectFileInfo.h
@@ -84,14 +84,6 @@ protected:
/// this is the section to emit them into.
const MCSection *CompactUnwindSection;
- /// DwarfAccelNamesSection, DwarfAccelObjCSection
- /// 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 +98,24 @@ protected:
const MCSection *DwarfRangesSection;
const MCSection *DwarfMacroInfoSection;
+ // 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;
+
// Extra TLS Variable Data section. If the target needs to put additional
// information for a TLS variable, it'll go here.
const MCSection *TLSExtraDataSection;
@@ -194,18 +204,6 @@ 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; }
@@ -221,6 +219,39 @@ 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 *getTLSExtraDataSection() const {
return TLSExtraDataSection;
}
diff --git a/include/llvm/MC/MCObjectStreamer.h b/include/llvm/MC/MCObjectStreamer.h
index b59b76c..0ece092 100644
--- a/include/llvm/MC/MCObjectStreamer.h
+++ b/include/llvm/MC/MCObjectStreamer.h
@@ -45,6 +45,11 @@ protected:
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,7 +78,21 @@ 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 EmitBundleAlignMode(unsigned AlignPow2);
+ virtual void EmitBundleLock(bool AlignToEnd);
+ virtual void EmitBundleUnlock();
+ virtual void EmitBytes(StringRef Data, unsigned AddrSpace);
+ virtual void EmitValueToAlignment(unsigned ByteAlignment,
+ int64_t Value = 0,
+ unsigned ValueSize = 1,
+ unsigned MaxBytesToEmit = 0);
+ virtual void EmitCodeAlignment(unsigned ByteAlignment,
+ unsigned MaxBytesToEmit = 0);
virtual bool EmitValueToOffset(const MCExpr *Offset, unsigned char Value);
virtual void EmitDwarfAdvanceLineAddr(int64_t LineDelta,
const MCSymbol *LastLabel,
@@ -81,6 +102,8 @@ public:
const MCSymbol *Label);
virtual void EmitGPRel32Value(const MCExpr *Value);
virtual void EmitGPRel64Value(const MCExpr *Value);
+ virtual void EmitFill(uint64_t NumBytes, uint8_t FillValue,
+ unsigned AddrSpace);
virtual void FinishImpl();
/// @}
diff --git a/include/llvm/MC/MCObjectWriter.h b/include/llvm/MC/MCObjectWriter.h
index 14fe75f..9d5c1a7 100644
--- a/include/llvm/MC/MCObjectWriter.h
+++ b/include/llvm/MC/MCObjectWriter.h
@@ -10,9 +10,9 @@
#ifndef LLVM_MC_MCOBJECTWRITER_H
#define LLVM_MC_MCOBJECTWRITER_H
-#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/raw_ostream.h"
#include <cassert>
namespace llvm {
@@ -51,6 +51,9 @@ protected: // Can only create subclasses.
public:
virtual ~MCObjectWriter();
+ /// lifetime management
+ virtual void reset() { }
+
bool isLittleEndian() const { return IsLittleEndian; }
raw_ostream &getStream() { return OS; }
@@ -173,7 +176,13 @@ public:
OS << StringRef(Zeros, N % 16);
}
+ void WriteBytes(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/MCAsmLexer.h b/include/llvm/MC/MCParser/MCAsmLexer.h
index ca163c5..37a69e2 100644
--- a/include/llvm/MC/MCParser/MCAsmLexer.h
+++ b/include/llvm/MC/MCParser/MCAsmLexer.h
@@ -34,12 +34,10 @@ public:
// Real values.
Real,
- // Register values (stored in IntVal). Only used by MCTargetAsmLexer.
- Register,
-
// No-value.
EndOfStatement,
Colon,
+ Space,
Plus, Minus, Tilde,
Slash, // '/'
BackSlash, // '\'
@@ -103,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
@@ -126,6 +117,7 @@ class MCAsmLexer {
void operator=(const MCAsmLexer &) LLVM_DELETED_FUNCTION;
protected: // Can only create subclasses.
const char *TokStart;
+ bool SkipSpace;
MCAsmLexer();
@@ -170,11 +162,14 @@ public:
/// getKind - Get the kind of current token.
AsmToken::TokenKind getKind() const { return CurTok.getKind(); }
- /// is - Check if the current token has kind \arg K.
+ /// 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 \arg K.
+ /// isNot - Check if the current token has kind \p K.
bool isNot(AsmToken::TokenKind K) const { return CurTok.isNot(K); }
+
+ /// setSkipSpace - Set whether spaces should be ignored by the lexer
+ void setSkipSpace(bool val) { SkipSpace = val; }
};
} // End llvm namespace
diff --git a/include/llvm/MC/MCParser/MCAsmParser.h b/include/llvm/MC/MCParser/MCAsmParser.h
index c673a79..b9490fa 100644
--- a/include/llvm/MC/MCParser/MCAsmParser.h
+++ b/include/llvm/MC/MCParser/MCAsmParser.h
@@ -10,8 +10,8 @@
#ifndef LLVM_MC_MCASMPARSER_H
#define LLVM_MC_MCASMPARSER_H
-#include "llvm/Support/DataTypes.h"
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/Support/DataTypes.h"
namespace llvm {
class AsmToken;
@@ -20,6 +20,9 @@ class MCAsmLexer;
class MCAsmParserExtension;
class MCContext;
class MCExpr;
+class MCInstPrinter;
+class MCInstrInfo;
+class MCParsedAsmOperand;
class MCStreamer;
class MCTargetAsmParser;
class SMLoc;
@@ -28,6 +31,16 @@ class SourceMgr;
class StringRef;
class Twine;
+/// MCAsmParserSemaCallback - Generic Sema callback for assembly parser.
+class MCAsmParserSemaCallback {
+public:
+ virtual ~MCAsmParserSemaCallback();
+ virtual void *LookupInlineAsmIdentifier(StringRef Name, void *Loc,
+ unsigned &Size) = 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 {
@@ -73,15 +86,26 @@ public:
/// Run - Run the parser on the input source buffer.
virtual bool Run(bool NoInitialTextSection, bool NoFinalize = false) = 0;
- /// Warning - Emit a warning at the location \arg L, with the message \arg
- /// Msg.
+ virtual void setParsingInlineAsm(bool V) = 0;
+ virtual bool isParsingInlineAsm() = 0;
+
+ /// 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,
+ SmallVectorImpl<std::string> &Clobbers,
+ const MCInstrInfo *MII,
+ const MCInstPrinter *IP,
+ MCAsmParserSemaCallback &SI) = 0;
+
+ /// Warning - Emit a warning at the location \p L, with the message \p Msg.
///
/// \return The return value is true, if warnings are fatal.
virtual bool Warning(SMLoc L, const Twine &Msg,
ArrayRef<SMRange> Ranges = ArrayRef<SMRange>()) = 0;
- /// Error - Emit an error at the location \arg L, with the message \arg
- /// Msg.
+ /// Error - Emit an error at the location \p L, with the message \p Msg.
///
/// \return The return value is always true, as an idiomatic convenience to
/// clients.
@@ -100,7 +124,7 @@ public:
ArrayRef<SMRange> Ranges = ArrayRef<SMRange>());
/// ParseIdentifier - Parse an identifier or string (as a quoted identifier)
- /// and set \arg Res to the identifier contents.
+ /// and set \p Res to the identifier contents.
virtual bool ParseIdentifier(StringRef &Res) = 0;
/// \brief Parse up to the end of statement and return the contents from the
diff --git a/include/llvm/MC/MCParser/MCAsmParserExtension.h b/include/llvm/MC/MCParser/MCAsmParserExtension.h
index 59593a8..84b33b5 100644
--- a/include/llvm/MC/MCParser/MCAsmParserExtension.h
+++ b/include/llvm/MC/MCParser/MCAsmParserExtension.h
@@ -10,8 +10,8 @@
#ifndef LLVM_MC_MCASMPARSEREXTENSION_H
#define LLVM_MC_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 {
@@ -43,8 +43,8 @@ protected:
public:
virtual ~MCAsmParserExtension();
- /// \brief Initialize the extension for parsing using the given \arg
- /// Parser. The extension should use the AsmParser interfaces to register its
+ /// \brief Initialize the extension for parsing using the given \p Parser.
+ /// The extension should use the AsmParser interfaces to register its
/// parsing routines.
virtual void Initialize(MCAsmParser &Parser);
diff --git a/include/llvm/MC/MCParser/MCParsedAsmOperand.h b/include/llvm/MC/MCParser/MCParsedAsmOperand.h
index 2556e5f..60e7887 100644
--- a/include/llvm/MC/MCParser/MCParsedAsmOperand.h
+++ b/include/llvm/MC/MCParser/MCParsedAsmOperand.h
@@ -19,15 +19,69 @@ class raw_ostream;
/// base class is used by target-independent clients and is the interface
/// between parsing an asm instruction and recognizing it.
class MCParsedAsmOperand {
+ /// MCOperandNum - The corresponding MCInst operand number. Only valid when
+ /// parsing MS-style inline assembly.
+ unsigned MCOperandNum;
+
+ /// Constraint - The constraint on this operand. Only valid when parsing
+ /// MS-style inline assembly.
+ std::string Constraint;
+
public:
MCParsedAsmOperand() {}
virtual ~MCParsedAsmOperand() {}
+ void setConstraint(StringRef C) { Constraint = C.str(); }
+ StringRef getConstraint() { return Constraint; }
+
+ void setMCOperandNum (unsigned OpNum) { MCOperandNum = OpNum; }
+ unsigned getMCOperandNum() { return MCOperandNum; }
+
+ unsigned getNameLen() {
+ assert (getStartLoc().isValid() && "Invalid StartLoc!");
+ assert (getEndLoc().isValid() && "Invalid EndLoc!");
+ return getEndLoc().getPointer() - getStartLoc().getPointer();
+ }
+
+ StringRef getName() {
+ return StringRef(getStartLoc().getPointer(), getNameLen());
+ }
+
+ /// isToken - Is this a token operand?
+ virtual bool isToken() const = 0;
+ /// isImm - Is this an immediate operand?
+ virtual bool isImm() const = 0;
+ /// isReg - Is this a register operand?
+ virtual bool isReg() const = 0;
+ virtual unsigned getReg() const = 0;
+
+ /// 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; }
+
+ /// 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
+ /// inline assembly.
+ virtual bool isOffsetOf() const { return false; }
+
+ /// 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 46a9d71..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,70 +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;
}
- /// getNumRegUnits - Return the number of (native) register units in the
+ /// \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;
+ }
+
+ /// \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;
@@ -361,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 {
+ 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);
+ }
+
};
//===----------------------------------------------------------------------===//
@@ -415,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
//===----------------------------------------------------------------------===//
@@ -434,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;
@@ -473,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 3b1cdf1..0c71ee5 100644
--- a/include/llvm/MC/MCSchedule.h
+++ b/include/llvm/MC/MCSchedule.h
@@ -16,17 +16,111 @@
#define LLVM_MC_MCSCHEDMODEL_H
#include "llvm/Support/DataTypes.h"
+#include <cassert>
namespace llvm {
struct InstrItinerary;
+/// Define a kind of processor resource that will be modeled by the scheduler.
+struct MCProcResourceDesc {
+#ifndef NDEBUG
+ const char *Name;
+#endif
+ unsigned NumUnits; // Number of resource of this kind
+ unsigned SuperIdx; // Index of the resources kind that contains this kind.
+
+ // Buffered resources may be consumed at some indeterminate cycle after
+ // dispatch (e.g. for instructions that may issue out-of-order). Unbuffered
+ // resources always consume their resource some fixed number of cycles after
+ // dispatch (e.g. for instruction interlocking that may stall the pipeline).
+ bool IsBuffered;
+
+ bool operator==(const MCProcResourceDesc &Other) const {
+ return NumUnits == Other.NumUnits && SuperIdx == Other.SuperIdx
+ && IsBuffered == Other.IsBuffered;
+ }
+};
+
+/// Identify one of the processor resource kinds consumed by a particular
+/// scheduling class for the specified number of cycles.
+struct MCWriteProcResEntry {
+ unsigned ProcResourceIdx;
+ unsigned Cycles;
+
+ bool operator==(const MCWriteProcResEntry &Other) const {
+ return ProcResourceIdx == Other.ProcResourceIdx && Cycles == Other.Cycles;
+ }
+};
+
+/// Specify the latency in cpu cycles for a particular scheduling class and def
+/// index. -1 indicates an invalid latency. Heuristics would typically consider
+/// an instruction with invalid latency to have infinite latency. Also identify
+/// the WriteResources of this def. When the operand expands to a sequence of
+/// writes, this ID is the last write in the sequence.
+struct MCWriteLatencyEntry {
+ int Cycles;
+ unsigned WriteResourceID;
+
+ bool operator==(const MCWriteLatencyEntry &Other) const {
+ return Cycles == Other.Cycles && WriteResourceID == Other.WriteResourceID;
+ }
+};
+
+/// Specify the number of cycles allowed after instruction issue before a
+/// particular use operand reads its registers. This effectively reduces the
+/// write's latency. Here we allow negative cycles for corner cases where
+/// latency increases. This rule only applies when the entry's WriteResource
+/// matches the write's WriteResource.
+///
+/// MCReadAdvanceEntries are sorted first by operand index (UseIdx), then by
+/// WriteResourceIdx.
+struct MCReadAdvanceEntry {
+ unsigned UseIdx;
+ unsigned WriteResourceID;
+ int Cycles;
+
+ bool operator==(const MCReadAdvanceEntry &Other) const {
+ return UseIdx == Other.UseIdx && WriteResourceID == Other.WriteResourceID
+ && Cycles == Other.Cycles;
+ }
+};
+
+/// Summarize the scheduling resources required for an instruction of a
+/// particular scheduling class.
+///
+/// Defined as an aggregate struct for creating tables with initializer lists.
+struct MCSchedClassDesc {
+ static const unsigned short InvalidNumMicroOps = UINT16_MAX;
+ static const unsigned short VariantNumMicroOps = UINT16_MAX - 1;
+
+#ifndef NDEBUG
+ const char* Name;
+#endif
+ unsigned short NumMicroOps;
+ bool BeginGroup;
+ bool EndGroup;
+ unsigned WriteProcResIdx; // First index into WriteProcResTable.
+ unsigned NumWriteProcResEntries;
+ unsigned WriteLatencyIdx; // First index into WriteLatencyTable.
+ unsigned NumWriteLatencyEntries;
+ unsigned ReadAdvanceIdx; // First index into ReadAdvanceTable.
+ unsigned NumReadAdvanceEntries;
+
+ bool isValid() const {
+ return NumMicroOps != InvalidNumMicroOps;
+ }
+ bool isVariant() const {
+ return NumMicroOps == VariantNumMicroOps;
+ }
+};
+
/// Machine model for scheduling, bundling, and heuristics.
///
/// The machine model directly provides basic information about the
/// microarchitecture to the scheduler in the form of properties. It also
-/// optionally refers to scheduler resources tables and itinerary
-/// tables. Scheduler resources tables model the latency and cost for each
+/// optionally refers to scheduler resource tables and itinerary
+/// tables. Scheduler resource tables model the latency and cost for each
/// instruction type. Itinerary tables are an independant mechanism that
/// provides a detailed reservation table describing each cycle of instruction
/// execution. Subtargets may define any or all of the above categories of data
@@ -84,8 +178,11 @@ public:
static const unsigned DefaultMispredictPenalty = 10;
private:
- // TODO: Add a reference to proc resource types and sched resource tables.
-
+ unsigned ProcID;
+ const MCProcResourceDesc *ProcResourceTable;
+ const MCSchedClassDesc *SchedClassTable;
+ unsigned NumProcResourceKinds;
+ unsigned NumSchedClasses;
// Instruction itinerary tables used by InstrItineraryData.
friend class InstrItineraryData;
const InstrItinerary *InstrItineraries;
@@ -100,13 +197,45 @@ public:
LoadLatency(DefaultLoadLatency),
HighLatency(DefaultHighLatency),
MispredictPenalty(DefaultMispredictPenalty),
- InstrItineraries(0) {}
+ ProcID(0), ProcResourceTable(0), SchedClassTable(0),
+ NumProcResourceKinds(0), NumSchedClasses(0),
+ InstrItineraries(0) {
+ (void)NumProcResourceKinds;
+ (void)NumSchedClasses;
+ }
// Table-gen driven ctor.
MCSchedModel(unsigned iw, int ml, unsigned ll, unsigned hl, 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), InstrItineraries(ii){}
+ MispredictPenalty(mp), ProcID(pi), ProcResourceTable(pr),
+ SchedClassTable(sc), NumProcResourceKinds(npr), NumSchedClasses(nsc),
+ InstrItineraries(ii) {}
+
+ unsigned getProcessorID() const { return ProcID; }
+
+ /// Does this machine model include instruction-level scheduling.
+ bool hasInstrSchedModel() const { return SchedClassTable; }
+
+ unsigned getNumProcResourceKinds() const {
+ return NumProcResourceKinds;
+ }
+
+ const MCProcResourceDesc *getProcResource(unsigned ProcResourceIdx) const {
+ assert(hasInstrSchedModel() && "No scheduling machine model");
+
+ assert(ProcResourceIdx < NumProcResourceKinds && "bad proc resource idx");
+ return &ProcResourceTable[ProcResourceIdx];
+ }
+
+ const MCSchedClassDesc *getSchedClassDesc(unsigned SchedClassIdx) const {
+ assert(hasInstrSchedModel() && "No scheduling machine model");
+
+ assert(SchedClassIdx < NumSchedClasses && "bad scheduling class idx");
+ return &SchedClassTable[SchedClassIdx];
+ }
};
} // End llvm namespace
diff --git a/include/llvm/MC/MCSection.h b/include/llvm/MC/MCSection.h
index f90ad6a..5d6cac2 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"
@@ -50,6 +51,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
@@ -65,8 +71,6 @@ namespace llvm {
/// isVirtualSection - Check whether this section is "virtual", that is
/// has no actual object file contents.
virtual bool isVirtualSection() const = 0;
-
- static bool classof(const MCSection *) { return true; }
};
} // end namespace llvm
diff --git a/include/llvm/MC/MCSectionCOFF.h b/include/llvm/MC/MCSectionCOFF.h
index 7eacde5..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; }
@@ -61,7 +67,6 @@ namespace llvm {
static bool classof(const MCSection *S) {
return S->getVariant() == SV_COFF;
}
- static bool classof(const MCSectionCOFF *) { return true; }
};
} // end namespace llvm
diff --git a/include/llvm/MC/MCSectionELF.h b/include/llvm/MC/MCSectionELF.h
index 7321ca8..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; }
@@ -76,7 +83,6 @@ public:
static bool classof(const MCSection *S) {
return S->getVariant() == SV_ELF;
}
- static bool classof(const MCSectionELF *) { return true; }
// Return the entry size for sections with fixed-width data.
static unsigned DetermineEntrySize(SectionKind Kind);
diff --git a/include/llvm/MC/MCSectionMachO.h b/include/llvm/MC/MCSectionMachO.h
index 15eb4f4..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; }
@@ -174,7 +182,6 @@ public:
static bool classof(const MCSection *S) {
return S->getVariant() == SV_MachO;
}
- static bool classof(const MCSectionMachO *) { return true; }
};
} // end namespace llvm
diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h
index 91593b9..05a33c5 100644
--- a/include/llvm/MC/MCStreamer.h
+++ b/include/llvm/MC/MCStreamer.h
@@ -14,12 +14,12 @@
#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/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"
namespace llvm {
class MCAsmBackend;
@@ -55,6 +55,7 @@ namespace llvm {
std::vector<MCDwarfFrameInfo> FrameInfos;
MCDwarfFrameInfo *getCurrentFrameInfo();
+ MCSymbol *EmitCFICommon();
void EnsureValidFrame();
std::vector<MCWin64EHUnwindInfo *> W64UnwindInfos;
@@ -69,6 +70,8 @@ namespace llvm {
SmallVector<std::pair<const MCSection *,
const MCSection *>, 4> SectionStack;
+ bool AutoInitSections;
+
protected:
MCStreamer(MCContext &Ctx);
@@ -89,6 +92,10 @@ namespace llvm {
public:
virtual ~MCStreamer();
+ /// State management
+ ///
+ virtual void reset();
+
MCContext &getContext() const { return Context; }
unsigned getNumFrameInfos() {
@@ -213,6 +220,17 @@ 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;
@@ -226,6 +244,8 @@ namespace llvm {
/// used in an assignment.
virtual void EmitLabel(MCSymbol *Symbol);
+ virtual void EmitDebugLabel(MCSymbol *Symbol);
+
virtual void EmitEHSymAttributes(const MCSymbol *Symbol,
MCSymbol *EHSymbol);
@@ -342,7 +362,7 @@ namespace llvm {
/// @name Generating Data
/// @{
- /// EmitBytes - Emit the bytes in \arg Data into the output.
+ /// EmitBytes - Emit the bytes in \p Data into the output.
///
/// This is used to implement assembler directives such as .byte, .ascii,
/// etc.
@@ -417,7 +437,6 @@ namespace llvm {
EmitFill(NumBytes, 0, AddrSpace);
}
-
/// EmitValueToAlignment - Emit some number of copies of @p Value until
/// the byte alignment @p ByteAlignment is reached.
///
@@ -515,6 +534,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 +556,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.
@@ -554,6 +589,11 @@ namespace llvm {
virtual void EmitRegSave(const SmallVectorImpl<unsigned> &RegList,
bool isVector);
+ /// PPC-related methods.
+ /// FIXME: Eventually replace it with some "target MC streamer" and move
+ /// these methods there.
+ virtual void EmitTCEntry(const MCSymbol &S);
+
/// FinishImpl - Streamer specific finalization.
virtual void FinishImpl() = 0;
/// Finish - Finish emission of machine code.
@@ -573,11 +613,11 @@ namespace llvm {
/// InstPrint.
///
/// \param CE - If given, a code emitter to use to show the instruction
- /// encoding inline with the assembly. This method takes ownership of \arg CE.
+ /// encoding inline with the assembly. This method takes ownership of \p CE.
///
/// \param TAB - If given, a target asm backend to use to show the fixup
/// information in conjunction with encoding information. This method takes
- /// ownership of \arg TAB.
+ /// ownership of \p TAB.
///
/// \param ShowInst - Whether to show the MCInst representation inline with
/// the assembly.
@@ -594,7 +634,7 @@ namespace llvm {
/// createMachOStreamer - Create a machine code streamer which will generate
/// Mach-O format object files.
///
- /// Takes ownership of \arg TAB and \arg CE.
+ /// Takes ownership of \p TAB and \p CE.
MCStreamer *createMachOStreamer(MCContext &Ctx, MCAsmBackend &TAB,
raw_ostream &OS, MCCodeEmitter *CE,
bool RelaxAll = false);
@@ -602,7 +642,7 @@ namespace llvm {
/// createWinCOFFStreamer - Create a machine code streamer which will
/// generate Microsoft COFF format object files.
///
- /// Takes ownership of \arg TAB and \arg CE.
+ /// Takes ownership of \p TAB and \p CE.
MCStreamer *createWinCOFFStreamer(MCContext &Ctx,
MCAsmBackend &TAB,
MCCodeEmitter &CE, raw_ostream &OS,
@@ -617,7 +657,7 @@ namespace llvm {
/// createPureStreamer - Create a machine code streamer which will generate
/// "pure" MC object files, for use with MC-JIT and testing tools.
///
- /// Takes ownership of \arg TAB and \arg CE.
+ /// Takes ownership of \p TAB and \p CE.
MCStreamer *createPureStreamer(MCContext &Ctx, MCAsmBackend &TAB,
raw_ostream &OS, MCCodeEmitter *CE);
diff --git a/include/llvm/MC/MCSubtargetInfo.h b/include/llvm/MC/MCSubtargetInfo.h
index 6c96f49..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 {
@@ -30,7 +30,14 @@ class MCSubtargetInfo {
std::string TargetTriple; // Target triple
const SubtargetFeatureKV *ProcFeatures; // Processor feature list
const SubtargetFeatureKV *ProcDesc; // Processor descriptions
- const SubtargetInfoKV *ProcSchedModel; // Scheduler machine model
+
+ // Scheduler machine model
+ const SubtargetInfoKV *ProcSchedModels;
+ const MCWriteProcResEntry *WriteProcResTable;
+ const MCWriteLatencyEntry *WriteLatencyTable;
+ const MCReadAdvanceEntry *ReadAdvanceTable;
+ const MCSchedModel *CPUSchedModel;
+
const InstrStage *Stages; // Instruction itinerary stages
const unsigned *OperandCycles; // Itinerary operand cycles
const unsigned *ForwardingPaths; // Forwarding paths
@@ -43,6 +50,9 @@ public:
const SubtargetFeatureKV *PF,
const SubtargetFeatureKV *PD,
const SubtargetInfoKV *ProcSched,
+ const MCWriteProcResEntry *WPR,
+ const MCWriteLatencyEntry *WL,
+ const MCReadAdvanceEntry *RA,
const InstrStage *IS,
const unsigned *OC, const unsigned *FP,
unsigned NF, unsigned NP);
@@ -58,9 +68,9 @@ public:
return FeatureBits;
}
- /// ReInitMCSubtargetInfo - Change CPU (and optionally supplemented with
- /// feature string), recompute and return feature bits.
- uint64_t ReInitMCSubtargetInfo(StringRef CPU, StringRef FS);
+ /// InitMCProcessorInfo - Set or change the CPU (optionally supplemented with
+ /// feature string). Recompute feature bits and scheduling model.
+ void InitMCProcessorInfo(StringRef CPU, StringRef FS);
/// ToggleFeature - Toggle a feature and returns the re-computed feature
/// bits. This version does not change the implied bits.
@@ -74,9 +84,54 @@ public:
///
const MCSchedModel *getSchedModelForCPU(StringRef CPU) const;
+ /// getSchedModel - Get the machine model for this subtarget's CPU.
+ ///
+ const MCSchedModel *getSchedModel() const { return CPUSchedModel; }
+
+ /// Return an iterator at the first process resource consumed by the given
+ /// scheduling class.
+ const MCWriteProcResEntry *getWriteProcResBegin(
+ const MCSchedClassDesc *SC) const {
+ return &WriteProcResTable[SC->WriteProcResIdx];
+ }
+ const MCWriteProcResEntry *getWriteProcResEnd(
+ const MCSchedClassDesc *SC) const {
+ return getWriteProcResBegin(SC) + SC->NumWriteProcResEntries;
+ }
+
+ const MCWriteLatencyEntry *getWriteLatencyEntry(const MCSchedClassDesc *SC,
+ unsigned DefIdx) const {
+ assert(DefIdx < SC->NumWriteLatencyEntries &&
+ "MachineModel does not specify a WriteResource for DefIdx");
+
+ return &WriteLatencyTable[SC->WriteLatencyIdx + DefIdx];
+ }
+
+ int getReadAdvanceCycles(const MCSchedClassDesc *SC, unsigned UseIdx,
+ unsigned WriteResID) const {
+ // TODO: The number of read advance entries in a class can be significant
+ // (~50). Consider compressing the WriteID into a dense ID of those that are
+ // used by ReadAdvance and representing them as a bitset.
+ for (const MCReadAdvanceEntry *I = &ReadAdvanceTable[SC->ReadAdvanceIdx],
+ *E = I + SC->NumReadAdvanceEntries; I != E; ++I) {
+ if (I->UseIdx < UseIdx)
+ continue;
+ if (I->UseIdx > UseIdx)
+ break;
+ // Find the first WriteResIdx match, which has the highest cycle count.
+ if (!I->WriteResourceID || I->WriteResourceID == WriteResID) {
+ return I->Cycles;
+ }
+ }
+ return 0;
+ }
+
/// getInstrItineraryForCPU - Get scheduling itinerary of a CPU.
///
InstrItineraryData getInstrItineraryForCPU(StringRef CPU) const;
+
+ /// Initialize an InstrItineraryData instance.
+ void initInstrItins(InstrItineraryData &InstrItins) const;
};
} // End llvm namespace
diff --git a/include/llvm/MC/MCSymbol.h b/include/llvm/MC/MCSymbol.h
index 4c9e7f5..fe92755 100644
--- a/include/llvm/MC/MCSymbol.h
+++ b/include/llvm/MC/MCSymbol.h
@@ -113,7 +113,7 @@ namespace llvm {
return *Section;
}
- /// setSection - Mark the symbol as defined in the section \arg S.
+ /// setSection - Mark the symbol as defined in the section \p S.
void setSection(const MCSection &S) { Section = &S; }
/// setUndefined - Mark the symbol as undefined.
@@ -133,7 +133,7 @@ namespace llvm {
return Value != 0;
}
- /// getValue() - Get the value for variable symbols.
+ /// getVariableValue() - Get the value for variable symbols.
const MCExpr *getVariableValue() const {
assert(isVariable() && "Invalid accessor!");
IsUsed = true;
@@ -149,7 +149,7 @@ namespace llvm {
/// @}
- /// print - Print the value to the stream \arg OS.
+ /// print - Print the value to the stream \p OS.
void print(raw_ostream &OS) const;
/// dump - Print the value to stderr.
diff --git a/include/llvm/MC/MCTargetAsmLexer.h b/include/llvm/MC/MCTargetAsmLexer.h
deleted file mode 100644
index d09fe04..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 \arg 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 \arg K.
- bool is(AsmToken::TokenKind K) const { return CurTok.is(K); }
-
- /// isNot - Check if the current token has kind \arg 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 709c2d2..483a80b 100644
--- a/include/llvm/MC/MCTargetAsmParser.h
+++ b/include/llvm/MC/MCTargetAsmParser.h
@@ -21,6 +21,39 @@ class MCParsedAsmOperand;
class MCInst;
template <typename T> class SmallVectorImpl;
+enum AsmRewriteKind {
+ AOK_DotOperator, // Rewrite a dot operator expression as an immediate.
+ // E.g., [eax].foo.bar -> [eax].8
+ AOK_Emit, // Rewrite _emit as .byte.
+ AOK_Imm, // Rewrite as $$N.
+ AOK_ImmPrefix, // Add $$ before a parsed Imm.
+ AOK_Input, // Rewrite in terms of $N.
+ AOK_Output, // Rewrite in terms of $N.
+ AOK_SizeDirective, // Add a sizing directive (e.g., dword ptr).
+ AOK_Skip // Skip emission (e.g., offset/type operators).
+};
+
+struct AsmRewrite {
+ AsmRewriteKind Kind;
+ SMLoc Loc;
+ unsigned Len;
+ unsigned Val;
+public:
+ AsmRewrite(AsmRewriteKind kind, SMLoc loc, unsigned len = 0, unsigned val = 0)
+ : Kind(kind), Loc(loc), Len(len), Val(val) {}
+};
+
+struct ParseInstructionInfo {
+
+ SmallVectorImpl<AsmRewrite> *AsmRewrites;
+
+ ParseInstructionInfo() : AsmRewrites(0) {}
+ ParseInstructionInfo(SmallVectorImpl<AsmRewrite> *rewrites)
+ : AsmRewrites(rewrites) {}
+
+ ~ParseInstructionInfo() {}
+};
+
/// MCTargetAsmParser - Generic interface to target specific assembly parsers.
class MCTargetAsmParser : public MCAsmParserExtension {
public:
@@ -41,12 +74,26 @@ protected: // Can only create subclasses.
/// AvailableFeatures - The current set of available features.
unsigned AvailableFeatures;
+ /// ParsingInlineAsm - Are we parsing ms-style inline assembly?
+ bool ParsingInlineAsm;
+
+ /// SemaCallback - The Sema callback implementation. Must be set when parsing
+ /// ms-style inline assembly.
+ MCAsmParserSemaCallback *SemaCallback;
+
public:
virtual ~MCTargetAsmParser();
unsigned getAvailableFeatures() const { return AvailableFeatures; }
void setAvailableFeatures(unsigned Value) { AvailableFeatures = Value; }
+ bool isParsingInlineAsm () { return ParsingInlineAsm; }
+ void setParsingInlineAsm (bool Value) { ParsingInlineAsm = Value; }
+
+ void setSemaCallback(MCAsmParserSemaCallback *Callback) {
+ SemaCallback = Callback;
+ }
+
virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
SMLoc &EndLoc) = 0;
@@ -63,7 +110,8 @@ public:
/// \param Operands [out] - The list of parsed operands, this returns
/// ownership of them to the caller.
/// \return True on failure.
- virtual bool ParseInstruction(StringRef Name, SMLoc NameLoc,
+ virtual bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
+ SMLoc NameLoc,
SmallVectorImpl<MCParsedAsmOperand*> &Operands) = 0;
/// ParseDirective - Parse a target specific assembler directive
@@ -78,21 +126,9 @@ public:
/// \param DirectiveID - the identifier token of the directive.
virtual bool ParseDirective(AsmToken DirectiveID) = 0;
- /// MatchInstruction - Recognize a series of operands of a parsed instruction
- /// as an actual MCInst. This returns false on success and returns true on
- /// failure to match.
- ///
- /// On failure, the target parser is responsible for emitting a diagnostic
- /// explaining the match failure.
- virtual bool
- MatchInstruction(SMLoc IDLoc, unsigned &Kind,
- SmallVectorImpl<MCParsedAsmOperand*> &Operands,
- SmallVectorImpl<MCInst> &MCInsts,
- unsigned &OrigErrorInfo,
- bool matchingInlineAsm = false) {
- OrigErrorInfo = ~0x0;
- return true;
- }
+ /// mnemonicIsValid - This returns true if this is a valid mnemonic and false
+ /// otherwise.
+ virtual bool mnemonicIsValid(StringRef Mnemonic) = 0;
/// MatchAndEmitInstruction - Recognize a series of operands of a parsed
/// instruction as an actual MCInst and emit it to the specified MCStreamer.
@@ -101,9 +137,10 @@ public:
/// On failure, the target parser is responsible for emitting a diagnostic
/// explaining the match failure.
virtual bool
- MatchAndEmitInstruction(SMLoc IDLoc,
+ MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
SmallVectorImpl<MCParsedAsmOperand*> &Operands,
- MCStreamer &Out) = 0;
+ MCStreamer &Out, unsigned &ErrorInfo,
+ bool MatchingInlineAsm) = 0;
/// checkTargetMatchPredicate - Validate the instruction match against
/// any complex target predicates not expressible via match classes.
@@ -111,10 +148,8 @@ public:
return Match_Success;
}
- virtual unsigned getMCInstOperandNum(unsigned Kind, MCInst &Inst,
- const SmallVectorImpl<MCParsedAsmOperand*> &Operands,
- unsigned OperandNum,
- unsigned &NumMCOperands) = 0;
+ virtual void convertToMapAndConstraints(unsigned Kind,
+ const SmallVectorImpl<MCParsedAsmOperand*> &Operands) = 0;
};
} // End llvm namespace
diff --git a/include/llvm/MC/MCValue.h b/include/llvm/MC/MCValue.h
index 8352ed1..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 {
@@ -46,7 +46,7 @@ public:
/// isAbsolute - Is this an absolute (as opposed to relocatable) value.
bool isAbsolute() const { return !SymA && !SymB; }
- /// print - Print the value to the stream \arg OS.
+ /// print - Print the value to the stream \p OS.
void print(raw_ostream &OS, const MCAsmInfo *MAI) const;
/// dump - Print the value to stderr.
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 87c5fd3..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;
@@ -95,10 +95,6 @@ public:
const SubtargetFeatureKV *FeatureTable,
size_t FeatureTableSize);
- /// Get scheduling itinerary of a CPU.
- const void *getItinerary(const StringRef CPU,
- const SubtargetInfoKV *Table, size_t TableSize);
-
/// Print feature string.
void print(raw_ostream &OS) const;