diff options
Diffstat (limited to 'include/llvm/MC')
-rw-r--r-- | include/llvm/MC/MCAsmBackend.h | 18 | ||||
-rw-r--r-- | include/llvm/MC/MCAsmInfo.h | 15 | ||||
-rw-r--r-- | include/llvm/MC/MCAsmLayout.h | 5 | ||||
-rw-r--r-- | include/llvm/MC/MCAssembler.h | 128 | ||||
-rw-r--r-- | include/llvm/MC/MCELFObjectWriter.h | 6 | ||||
-rw-r--r-- | include/llvm/MC/MCObjectStreamer.h | 8 | ||||
-rw-r--r-- | include/llvm/MC/MCStreamer.h | 21 |
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; |