aboutsummaryrefslogtreecommitdiff
path: root/include/llvm/MC
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/MC')
-rw-r--r--include/llvm/MC/MCAsmBackend.h18
-rw-r--r--include/llvm/MC/MCAsmInfo.h15
-rw-r--r--include/llvm/MC/MCAsmLayout.h5
-rw-r--r--include/llvm/MC/MCAssembler.h128
-rw-r--r--include/llvm/MC/MCELFObjectWriter.h6
-rw-r--r--include/llvm/MC/MCObjectStreamer.h8
-rw-r--r--include/llvm/MC/MCStreamer.h21
7 files changed, 193 insertions, 8 deletions
diff --git a/include/llvm/MC/MCAsmBackend.h b/include/llvm/MC/MCAsmBackend.h
index 348a5f52d2..ebe5542555 100644
--- a/include/llvm/MC/MCAsmBackend.h
+++ b/include/llvm/MC/MCAsmBackend.h
@@ -25,6 +25,7 @@ class MCInst;
class MCInstFragment;
class MCObjectWriter;
class MCSection;
+class MCStreamer;
class MCValue;
class raw_ostream;
@@ -150,6 +151,23 @@ public:
/// handleAssemblerFlag - Handle any target-specific assembler flags.
/// By default, do nothing.
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
+ /// MCInst instructions for emission.
+ virtual bool CustomExpandInst(const MCInst &Inst, MCStreamer &Out) const {
+ return false;
+ }
+ // @LOCALMOD-END
};
} // End llvm namespace
diff --git a/include/llvm/MC/MCAsmInfo.h b/include/llvm/MC/MCAsmInfo.h
index 97aad71fd9..29ec1020c3 100644
--- a/include/llvm/MC/MCAsmInfo.h
+++ b/include/llvm/MC/MCAsmInfo.h
@@ -48,6 +48,14 @@ namespace llvm {
/// Default is 4.
unsigned PointerSize;
+ /// @LOCALMOD-BEGIN
+ /// TODO(pdox): Before upstreaming this, make sure every target backend
+ /// sets it correctly.
+ /// StackSlotSize - Stack slot size in bytes.
+ /// Default is 4.
+ unsigned StackSlotSize;
+ /// @LOCALMOD-END
+
/// IsLittleEndian - True if target is little endian.
/// Default is true.
bool IsLittleEndian;
@@ -340,6 +348,13 @@ namespace llvm {
return PointerSize;
}
+ /// @LOCALMOD-BEGIN
+ /// getStackSlotSize - Get the stack slot size in bytes.
+ unsigned getStackSlotSize() const {
+ return StackSlotSize;
+ }
+ /// @LOCALMOD-END
+
/// islittleendian - True if the target is little endian.
bool isLittleEndian() const {
return IsLittleEndian;
diff --git a/include/llvm/MC/MCAsmLayout.h b/include/llvm/MC/MCAsmLayout.h
index cf79216d07..fdded4ffa7 100644
--- a/include/llvm/MC/MCAsmLayout.h
+++ b/include/llvm/MC/MCAsmLayout.h
@@ -80,6 +80,11 @@ 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 83c01ec5b9..6fc685cb33 100644
--- a/include/llvm/MC/MCAssembler.h
+++ b/include/llvm/MC/MCAssembler.h
@@ -52,11 +52,39 @@ public:
FT_Org,
FT_Dwarf,
FT_DwarfFrame,
- FT_LEB
+ FT_LEB,
+ FT_Tiny // @LOCALMOD
};
+ // @LOCALMOD-BEGIN
+ enum BundleAlignType {
+ BundleAlignNone = 0,
+ BundleAlignStart = 1,
+ BundleAlignEnd = 2
+ };
+ // @LOCALMOD-END
+
private:
- FragmentType Kind;
+ // @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
+
/// Parent - The data for the section this fragment is in.
MCSectionData *Parent;
@@ -75,9 +103,6 @@ private:
/// initialized.
uint64_t Offset;
- /// LayoutOrder - The layout order of this fragment.
- unsigned LayoutOrder;
-
/// @}
protected:
@@ -99,14 +124,46 @@ 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; }
+
+ bool isBundleGroupEnd() const { return BundleGroupEnd; }
+ void setBundleGroupEnd(bool Value) { BundleGroupEnd = Value; }
+
+ BundleAlignType getBundleAlign() const { return BundleAlign; }
+ void setBundleAlign(BundleAlignType Value) { BundleAlign = Value; }
+ // @LOCALMOD-END
+
static bool classof(const MCFragment *O) { return true; }
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;
+
+ public:
+
+ MCTinyFragment(MCSectionData *SD = 0) : MCFragment(FT_Tiny, SD) {}
+
+ SmallString<6> &getContents() { return Contents; }
+ const SmallString<6> &getContents() const { return Contents; }
+
+ static bool classof(const MCFragment *F) {
+ return F->getKind() == MCFragment::FT_Tiny;
+ }
+ static bool classof(const MCTinyFragment *) { return true; }
+};
+// @LOCALMOD-END
+
class MCDataFragment : public MCFragment {
virtual void anchor();
- SmallString<32> Contents;
+ SmallString<6> Contents; // @LOCALMOD: Memory efficiency
/// Fixups - The list of fixups in this fragment.
std::vector<MCFixup> Fixups;
@@ -121,8 +178,8 @@ public:
/// @name Accessors
/// @{
- SmallString<32> &getContents() { return Contents; }
- const SmallString<32> &getContents() const { return Contents; }
+ SmallString<6> &getContents() { return Contents; } // @LOCALMOD
+ const SmallString<6> &getContents() const { return Contents; } // @LOCALMOD
/// @}
/// @name Fixup Access
@@ -474,6 +531,29 @@ 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:
@@ -495,6 +575,25 @@ 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
/// @{
@@ -753,6 +852,13 @@ private:
bool fragmentNeedsRelaxation(const MCInstFragment *IF,
const MCAsmLayout &Layout) const;
+ // @LOCALMOD-BEGIN
+ uint8_t ComputeBundlePadding(const MCAsmLayout &Layout,
+ MCFragment *F,
+ uint64_t FragmentOffset) const;
+ // @LOCALMOD-END
+
+
/// layoutOnce - Perform one layout iteration and return true if any offsets
/// were adjusted.
bool layoutOnce(MCAsmLayout &Layout);
@@ -819,6 +925,12 @@ public:
MCAsmBackend &getBackend() const { return Backend; }
+ // @LOCALMOD-BEGIN
+ uint64_t getBundleSize() const;
+ uint64_t getBundleMask() const;
+ // @LOCALMOD-END
+
+
MCCodeEmitter &getEmitter() const { return Emitter; }
MCObjectWriter &getWriter() const { return Writer; }
diff --git a/include/llvm/MC/MCELFObjectWriter.h b/include/llvm/MC/MCELFObjectWriter.h
index abbe188fe8..688c8a9575 100644
--- a/include/llvm/MC/MCELFObjectWriter.h
+++ b/include/llvm/MC/MCELFObjectWriter.h
@@ -69,6 +69,12 @@ public:
return ELF::ELFOSABI_FREEBSD;
case Triple::Linux:
return ELF::ELFOSABI_LINUX;
+ // @LOCALMOD-BEGIN
+ // This shouldn't be needed anymore (sel_ldr doesn't check for it),
+ // but removing it may require some changes in binutils also.
+ case Triple::NativeClient:
+ return ELF::ELFOSABI_NACL;
+ // @LOCALMOD-END
default:
return ELF::ELFOSABI_NONE;
}
diff --git a/include/llvm/MC/MCObjectStreamer.h b/include/llvm/MC/MCObjectStreamer.h
index b59b76c2be..466773bc0a 100644
--- a/include/llvm/MC/MCObjectStreamer.h
+++ b/include/llvm/MC/MCObjectStreamer.h
@@ -68,6 +68,14 @@ public:
unsigned AddrSpace);
virtual void EmitULEB128Value(const MCExpr *Value);
virtual void EmitSLEB128Value(const MCExpr *Value);
+
+ // @LOCALMOD-BEGIN
+ void EmitBundleLock();
+ void EmitBundleUnlock();
+ void EmitBundleAlignStart();
+ void EmitBundleAlignEnd();
+ // @LOCALMOD-END
+
virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol);
virtual void ChangeSection(const MCSection *Section);
virtual void EmitInstruction(const MCInst &Inst);
diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h
index 44698989c1..ad30b9ca60 100644
--- a/include/llvm/MC/MCStreamer.h
+++ b/include/llvm/MC/MCStreamer.h
@@ -467,6 +467,27 @@ namespace llvm {
/// @}
+ // @LOCALMOD-BEGIN
+ /// @name Bundling Directives
+ /// @{
+
+ /// EmitBundleLock - Begin a group of instructions which cannot
+ /// cross a bundle boundary.
+ virtual void EmitBundleLock() = 0;
+
+ /// EmitBundleUnlock - End a bundle-locked group of instructions.
+ virtual void EmitBundleUnlock() = 0;
+
+ /// EmitBundleAlignStart - Guarantee that the next instruction or
+ /// bundle-locked group starts at the beginning of a bundle.
+ virtual void EmitBundleAlignStart() = 0;
+
+ /// EmitBundleAlignEnd - Guarantee that the next instruction or
+ /// bundle-locked group finishes at the end of a bundle.
+ virtual void EmitBundleAlignEnd() = 0;
+ /// @}
+ // @LOCALMOD-END
+
/// EmitFileDirective - Switch to a new logical file. This is used to
/// implement the '.file "foo.c"' assembler directive.
virtual void EmitFileDirective(StringRef Filename) = 0;