aboutsummaryrefslogtreecommitdiff
path: root/include/llvm/MC
diff options
context:
space:
mode:
authorDerek Schuff <dschuff@chromium.org>2013-01-30 11:34:40 -0800
committerDerek Schuff <dschuff@chromium.org>2013-01-30 11:34:40 -0800
commit1843e19bce9b11fc840858e136c6c52cf8b42e0b (patch)
treee8bfc928152e2d3b3dd120d141d13dc08a9b49e4 /include/llvm/MC
parentaa0fa8a8df25807f784ec9ca9deeb40328636595 (diff)
parenta662a9862501fc86904e90054f7c1519101d9126 (diff)
Merge commit 'a662a9862501fc86904e90054f7c1519101d9126'
Conflicts: include/llvm/CodeGen/IntrinsicLowering.h include/llvm/MC/MCAssembler.h include/llvm/MC/MCObjectStreamer.h lib/LLVMBuild.txt lib/Linker/LinkArchives.cpp lib/MC/MCAssembler.cpp lib/MC/MCELFStreamer.cpp lib/MC/MCParser/AsmParser.cpp lib/MC/MCPureStreamer.cpp lib/MC/WinCOFFStreamer.cpp lib/Makefile lib/Support/Unix/Memory.inc lib/Support/Unix/Process.inc lib/Support/Unix/Program.inc lib/Target/ARM/ARM.h lib/Target/ARM/ARMFastISel.cpp lib/Target/ARM/ARMISelLowering.cpp lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp lib/Target/Mips/MipsInstrFPU.td lib/Target/X86/CMakeLists.txt lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86TargetMachine.cpp lib/Target/X86/X86TargetObjectFile.cpp lib/Transforms/InstCombine/InstCombineCalls.cpp test/CodeGen/X86/fast-isel-x86-64.ll tools/llc/llc.cpp tools/lto/LTOModule.cpp utils/TableGen/EDEmitter.cpp
Diffstat (limited to 'include/llvm/MC')
-rw-r--r--include/llvm/MC/EDInstInfo.h29
-rw-r--r--include/llvm/MC/MCAsmBackend.h14
-rw-r--r--include/llvm/MC/MCAsmInfo.h12
-rw-r--r--include/llvm/MC/MCAsmInfoCOFF.h6
-rw-r--r--include/llvm/MC/MCAsmInfoDarwin.h6
-rw-r--r--include/llvm/MC/MCAsmLayout.h31
-rw-r--r--include/llvm/MC/MCAssembler.h326
-rw-r--r--include/llvm/MC/MCCodeEmitter.h3
-rw-r--r--include/llvm/MC/MCContext.h39
-rw-r--r--include/llvm/MC/MCDisassembler.h14
-rw-r--r--include/llvm/MC/MCELF.h35
-rw-r--r--include/llvm/MC/MCELFStreamer.h11
-rw-r--r--include/llvm/MC/MCExpr.h13
-rw-r--r--include/llvm/MC/MCFixedLenDisassembler.h4
-rw-r--r--include/llvm/MC/MCInstrDesc.h100
-rw-r--r--include/llvm/MC/MCMachObjectWriter.h16
-rw-r--r--include/llvm/MC/MCObjectFileInfo.h4
-rw-r--r--include/llvm/MC/MCObjectStreamer.h26
-rw-r--r--include/llvm/MC/MCObjectWriter.h3
-rw-r--r--include/llvm/MC/MCParser/AsmCond.h4
-rw-r--r--include/llvm/MC/MCParser/AsmLexer.h4
-rw-r--r--include/llvm/MC/MCParser/MCAsmLexer.h14
-rw-r--r--include/llvm/MC/MCParser/MCAsmParser.h27
-rw-r--r--include/llvm/MC/MCParser/MCAsmParserExtension.h4
-rw-r--r--include/llvm/MC/MCParser/MCParsedAsmOperand.h8
-rw-r--r--include/llvm/MC/MCRegisterInfo.h79
-rw-r--r--include/llvm/MC/MCSchedule.h23
-rw-r--r--include/llvm/MC/MCSection.h6
-rw-r--r--include/llvm/MC/MCSectionCOFF.h6
-rw-r--r--include/llvm/MC/MCSectionELF.h7
-rw-r--r--include/llvm/MC/MCSectionMachO.h8
-rw-r--r--include/llvm/MC/MCStreamer.h55
-rw-r--r--include/llvm/MC/MCTargetAsmLexer.h89
33 files changed, 559 insertions, 467 deletions
diff --git a/include/llvm/MC/EDInstInfo.h b/include/llvm/MC/EDInstInfo.h
deleted file mode 100644
index 5b024675cd..0000000000
--- 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 f5ca3d5471..685f2cb89f 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 MCStreamer;
@@ -42,6 +42,9 @@ protected: // Can only create subclasses.
public:
virtual ~MCAsmBackend();
+ /// lifetime management
+ virtual void reset() { }
+
/// createObjectWriter - Create a new MCObjectWriter instance for use by the
/// assembler backend to emit the final object file.
virtual MCObjectWriter *createObjectWriter(raw_ostream &OS) const = 0;
@@ -128,7 +131,7 @@ public:
/// fixup requires the associated instruction to be relaxed.
virtual bool fixupNeedsRelaxation(const MCFixup &Fixup,
uint64_t Value,
- const MCInstFragment *DF,
+ const MCRelaxableFragment *DF,
const MCAsmLayout &Layout) const = 0;
/// RelaxInstruction - Relax the instruction in the given fragment to the next
@@ -160,13 +163,6 @@ public:
virtual void handleAssemblerFlag(MCAssemblerFlag Flag) {}
// @LOCALMOD-BEGIN
- /// getBundleSize - Return the size (in bytes) of code bundling units
- /// for this target. If 0, bundling is disabled. This is used exclusively
- /// for Native Client.
- virtual unsigned getBundleSize() const {
- return 0;
- }
-
/// CustomExpandInst -
/// If the MCInst instruction has a custom expansion, write it to the
/// MCStreamer 'Out'. This can be used to perform "last minute" rewrites of
diff --git a/include/llvm/MC/MCAsmInfo.h b/include/llvm/MC/MCAsmInfo.h
index 44087650c2..e8f7f116fe 100644
--- a/include/llvm/MC/MCAsmInfo.h
+++ b/include/llvm/MC/MCAsmInfo.h
@@ -13,8 +13,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_TARGET_ASM_INFO_H
-#define LLVM_TARGET_ASM_INFO_H
+#ifndef LLVM_MC_MCASMINFO_H
+#define LLVM_MC_MCASMINFO_H
#include "llvm/MC/MCDirectives.h"
#include "llvm/MC/MachineLocation.h"
@@ -110,6 +110,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 ""
@@ -441,6 +444,11 @@ namespace llvm {
const char *getLabelSuffix() const {
return LabelSuffix;
}
+
+ const char *getDebugLabelSuffix() const {
+ return DebugLabelSuffix;
+ }
+
const char *getGlobalPrefix() const {
return GlobalPrefix;
}
diff --git a/include/llvm/MC/MCAsmInfoCOFF.h b/include/llvm/MC/MCAsmInfoCOFF.h
index 0ff3e127ed..7286151760 100644
--- a/include/llvm/MC/MCAsmInfoCOFF.h
+++ b/include/llvm/MC/MCAsmInfoCOFF.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_COFF_TARGET_ASM_INFO_H
-#define LLVM_COFF_TARGET_ASM_INFO_H
+#ifndef LLVM_MC_MCASMINFOCOFF_H
+#define LLVM_MC_MCASMINFOCOFF_H
#include "llvm/MC/MCAsmInfo.h"
@@ -33,4 +33,4 @@ namespace llvm {
}
-#endif // LLVM_COFF_TARGET_ASM_INFO_H
+#endif // LLVM_MC_MCASMINFOCOFF_H
diff --git a/include/llvm/MC/MCAsmInfoDarwin.h b/include/llvm/MC/MCAsmInfoDarwin.h
index af552de6e6..3d249f9306 100644
--- a/include/llvm/MC/MCAsmInfoDarwin.h
+++ b/include/llvm/MC/MCAsmInfoDarwin.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_DARWIN_TARGET_ASM_INFO_H
-#define LLVM_DARWIN_TARGET_ASM_INFO_H
+#ifndef LLVM_MC_MCASMINFODARWIN_H
+#define LLVM_MC_MCASMINFODARWIN_H
#include "llvm/MC/MCAsmInfo.h"
@@ -26,4 +26,4 @@ namespace llvm {
}
-#endif // LLVM_DARWIN_TARGET_ASM_INFO_H
+#endif // LLVM_MC_MCASMINFODARWIN_H
diff --git a/include/llvm/MC/MCAsmLayout.h b/include/llvm/MC/MCAsmLayout.h
index fdded4ffa7..8cb4601283 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)
/// @{
@@ -80,11 +86,6 @@ public:
/// \brief Get the offset of the given fragment inside its containing section.
uint64_t getFragmentOffset(const MCFragment *F) const;
- // @LOCALMOD-BEGIN
- /// \brief Get the bundle padding of the given fragment.
- uint8_t getFragmentPadding(const MCFragment *F) const;
- // @LOCALMOD-END
-
/// @}
/// @name Utility Functions
/// @{
diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h
index 949e99b50b..57aa08a2d0 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.
@@ -48,43 +48,15 @@ public:
FT_Align,
FT_Data,
FT_Fill,
- FT_Inst,
+ FT_Relaxable,
FT_Org,
FT_Dwarf,
FT_DwarfFrame,
- FT_LEB,
- FT_Tiny // @LOCALMOD
- };
-
- // @LOCALMOD-BEGIN
- enum BundleAlignType {
- BundleAlignNone = 0,
- BundleAlignStart = 1,
- BundleAlignEnd = 2
+ FT_LEB
};
- // @LOCALMOD-END
private:
- // @LOCALMOD-BEGIN
- // Try to compress the layout of MCFragment by:
- // 1) Making Kind, the bundling flags, and BundlePadding fit in 32 bits.
- // 2) Move LayoutOrder to fit in the hole left by aligning for 64 bits.
-
- FragmentType Kind : 4;
-
- BundleAlignType BundleAlign : 2;
- bool BundleGroupStart : 1;
- bool BundleGroupEnd : 1;
-
- /// BundlePadding - The computed padding for this fragment. This is ~0
- /// until initialized.
- uint8_t BundlePadding;
-
- /// LayoutOrder - The layout order of this fragment.
- unsigned LayoutOrder;
-
- // @LOCALMOD-END
-
+ FragmentType Kind;
/// Parent - The data for the section this fragment is in.
MCSectionData *Parent;
@@ -103,6 +75,9 @@ private:
/// initialized.
uint64_t Offset;
+ /// LayoutOrder - The layout order of this fragment.
+ unsigned LayoutOrder;
+
/// @}
protected:
@@ -124,74 +99,107 @@ public:
unsigned getLayoutOrder() const { return LayoutOrder; }
void setLayoutOrder(unsigned Value) { LayoutOrder = Value; }
- // @LOCALMOD-BEGIN
- bool isBundleGroupStart() const { return BundleGroupStart; }
- void setBundleGroupStart(bool Value) { BundleGroupStart = Value; }
+ /// \brief Does this fragment have instructions emitted into it? By default
+ /// this is false, but specific fragment types may set it to true.
+ virtual bool hasInstructions() const { return false; }
- bool isBundleGroupEnd() const { return BundleGroupEnd; }
- void setBundleGroupEnd(bool Value) { BundleGroupEnd = Value; }
+ /// \brief Should this fragment be placed at the end of an aligned bundle?
+ virtual bool alignToBundleEnd() const { return false; }
- BundleAlignType getBundleAlign() const { return BundleAlign; }
- void setBundleAlign(BundleAlignType Value) { BundleAlign = Value; }
- // @LOCALMOD-END
+ /// \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();
};
-// @LOCALMOD-BEGIN
-// This is just a tiny data fragment with no fixups.
-// (To help with memory usage)
-class MCTinyFragment : public MCFragment {
- private:
- SmallString<6> Contents;
+class MCEncodedFragment : public MCFragment {
+ virtual void anchor();
+
+ uint8_t BundlePadding;
+public:
+ MCEncodedFragment(MCFragment::FragmentType FType, MCSectionData *SD = 0)
+ : MCFragment(FType, SD), BundlePadding(0)
+ {
+ }
+ virtual ~MCEncodedFragment();
+
+ typedef SmallVectorImpl<MCFixup>::const_iterator const_fixup_iterator;
+ typedef SmallVectorImpl<MCFixup>::iterator fixup_iterator;
+
+ virtual SmallVectorImpl<char> &getContents() = 0;
+ virtual const SmallVectorImpl<char> &getContents() const = 0;
- public:
+ virtual SmallVectorImpl<MCFixup> &getFixups() = 0;
+ virtual const SmallVectorImpl<MCFixup> &getFixups() const = 0;
- MCTinyFragment(MCSectionData *SD = 0) : MCFragment(FT_Tiny, SD) {}
+ 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;
- SmallString<6> &getContents() { return Contents; }
- const SmallString<6> &getContents() const { return Contents; }
+ virtual uint8_t getBundlePadding() const {
+ return BundlePadding;
+ }
+
+ virtual void setBundlePadding(uint8_t N) {
+ BundlePadding = N;
+ }
static bool classof(const MCFragment *F) {
- return F->getKind() == MCFragment::FT_Tiny;
+ MCFragment::FragmentType Kind = F->getKind();
+ return Kind == MCFragment::FT_Relaxable || Kind == MCFragment::FT_Data;
}
- static bool classof(const MCTinyFragment *) { return true; }
};
-// @LOCALMOD-END
-class MCDataFragment : public MCFragment {
+/// Fragment for data and encoded instructions.
+///
+class MCDataFragment : public MCEncodedFragment {
virtual void anchor();
- SmallString<6> Contents; // @LOCALMOD: Memory efficiency
- /// Fixups - The list of fixups in this fragment.
- std::vector<MCFixup> Fixups;
+ /// \brief Does this fragment contain encoded instructions anywhere in it?
+ bool HasInstructions;
-public:
- typedef std::vector<MCFixup>::const_iterator const_fixup_iterator;
- typedef std::vector<MCFixup>::iterator fixup_iterator;
+ /// \brief Should this fragment be aligned to the end of a bundle?
+ bool AlignToBundleEnd;
-public:
- MCDataFragment(MCSectionData *SD = 0) : MCFragment(FT_Data, SD) {}
+ SmallVector<char, 32> Contents;
- /// @name Accessors
- /// @{
+ /// 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)
+ {
+ }
- SmallString<6> &getContents() { return Contents; } // @LOCALMOD
- const SmallString<6> &getContents() const { return Contents; } // @LOCALMOD
+ virtual SmallVectorImpl<char> &getContents() { return Contents; }
+ virtual const SmallVectorImpl<char> &getContents() const { return Contents; }
- /// @}
- /// @name Fixup Access
- /// @{
+ SmallVectorImpl<MCFixup> &getFixups() {
+ return Fixups;
+ }
- 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);
+ const SmallVectorImpl<MCFixup> &getFixups() const {
+ return Fixups;
}
- std::vector<MCFixup> &getFixups() { return Fixups; }
- const std::vector<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(); }
@@ -199,60 +207,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;
}
};
-// 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(); }
@@ -260,12 +254,8 @@ public:
fixup_iterator fixup_end() {return Fixups.end();}
const_fixup_iterator fixup_end() const {return Fixups.end();}
- size_t fixup_size() const { return Fixups.size(); }
-
- /// @}
-
static bool classof(const MCFragment *F) {
- return F->getKind() == MCFragment::FT_Inst;
+ return F->getKind() == MCFragment::FT_Relaxable;
}
};
@@ -499,6 +489,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;
@@ -512,6 +508,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
/// @{
//
@@ -521,29 +524,6 @@ private:
/// it.
unsigned HasInstructions : 1;
- // @LOCALMOD-BEGIN
- bool BundlingEnabled : 1;
- bool BundleLocked : 1;
-
- // Because ".bundle_lock" occurs before the fragment it applies to exists,
- // we need to keep this flag around so we know to mark the next fragment
- // as the start of a bundle group. A similar flag is not necessary for the
- // last fragment, because when a .bundle_unlock occurs, the last fragment
- // in the group already exists and can be marked directly.
- bool BundleGroupFirstFrag : 1;
-
- typedef MCFragment::BundleAlignType BundleAlignType;
- BundleAlignType BundleAlignNext : 2;
-
- // Optimization to reduce the number of fragments generated (for memory
- // savings). Keep track of when we know the offset of the next point to
- // emit an instruction. If we know the offset from a known alignment point,
- // we can just append to the previous fragment.
- bool BundleOffsetKnown : 1;
- unsigned BundleSize;
- unsigned BundleOffset;
- // @LOCALMOD-END
-
/// @}
public:
@@ -565,25 +545,6 @@ public:
unsigned getLayoutOrder() const { return LayoutOrder; }
void setLayoutOrder(unsigned Value) { LayoutOrder = Value; }
- // @LOCALMOD-BEGIN
- bool isBundlingEnabled() const { return BundlingEnabled; }
-
- bool isBundleLocked() const { return BundleLocked; }
- void setBundleLocked(bool Value) { BundleLocked = Value; }
-
- bool isBundleGroupFirstFrag() const { return BundleGroupFirstFrag; }
- void setBundleGroupFirstFrag(bool Value) { BundleGroupFirstFrag = Value; }
-
-
- BundleAlignType getBundleAlignNext() const { return BundleAlignNext; }
- void setBundleAlignNext(BundleAlignType Value) { BundleAlignNext = Value; }
-
- void MarkBundleOffsetUnknown();
- bool ShouldCreateNewFragment(size_t Size);
- void UpdateBundleOffset(size_t Size);
- void AlignBundleOffsetTo(size_t AlignBase);
- // @LOCALMOD-END
-
/// @name Fragment Access
/// @{
@@ -606,6 +567,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();
/// @}
@@ -811,6 +792,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;
@@ -835,20 +821,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);
@@ -904,6 +892,10 @@ public:
raw_ostream &OS);
~MCAssembler();
+ /// Reuse an assembler instance
+ ///
+ void reset();
+
MCContext &getContext() const { return Context; }
MCAsmBackend &getBackend() const { return Backend; }
@@ -931,6 +923,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 0574890902..9bfa08eb5d 100644
--- a/