MCStreamer.h revision 410ef2b263e92d3de1b2acff7437059400daed7d
125e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar//===- MCStreamer.h - High-level Streaming Machine Code Output --*- C++ -*-===//
225e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar//
325e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar//                     The LLVM Compiler Infrastructure
425e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar//
525e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar// This file is distributed under the University of Illinois Open Source
625e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar// License. See LICENSE.TXT for details.
725e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar//
825e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar//===----------------------------------------------------------------------===//
9e18e0c58dcd740c64e962fefde44249d685d0568Chris Lattner//
10e18e0c58dcd740c64e962fefde44249d685d0568Chris Lattner// This file declares the MCStreamer class.
11e18e0c58dcd740c64e962fefde44249d685d0568Chris Lattner//
12e18e0c58dcd740c64e962fefde44249d685d0568Chris Lattner//===----------------------------------------------------------------------===//
1325e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar
1425e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar#ifndef LLVM_MC_MCSTREAMER_H
1525e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar#define LLVM_MC_MCSTREAMER_H
1625e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar
177768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola#include "llvm/ADT/SmallVector.h"
181f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer#include "llvm/Support/DataTypes.h"
19a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner#include "llvm/MC/MCDirectives.h"
2089b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola#include "llvm/MC/MCDwarf.h"
210855bc5b973320052c87bdcc2fa17b9711edc3deCharles Davis#include "llvm/MC/MCWin64EH.h"
2284a2926fb7ab388d688a133b0b375a26e669fd55Daniel Dunbar
2325e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbarnamespace llvm {
244a0abd80f18f9c2a10bf5b14cd6731d51972a426Daniel Dunbar  class MCAsmInfo;
254a0abd80f18f9c2a10bf5b14cd6731d51972a426Daniel Dunbar  class MCCodeEmitter;
2625e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar  class MCContext;
27821e3334ed3390d931f497300e6a5f1dc21bcfb3Daniel Dunbar  class MCExpr;
2825e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar  class MCInst;
2990edac0e8b35f766599362b6301863229f0ddcdbChris Lattner  class MCInstPrinter;
3025e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar  class MCSection;
3125e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar  class MCSymbol;
329a7e2ccf574368b60455f8c8975030475a1f3ce0Daniel Dunbar  class StringRef;
33b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner  class TargetAsmBackend;
34195a0ce484cd12a5adae9184188f6d0fb52b84c0Rafael Espindola  class TargetLoweringObjectFile;
3586e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner  class Twine;
3625e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar  class raw_ostream;
3786e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner  class formatted_raw_ostream;
3825e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar
39e18e0c58dcd740c64e962fefde44249d685d0568Chris Lattner  /// MCStreamer - Streaming machine code generation interface.  This interface
40e18e0c58dcd740c64e962fefde44249d685d0568Chris Lattner  /// is intended to provide a programatic interface that is very similar to the
41e18e0c58dcd740c64e962fefde44249d685d0568Chris Lattner  /// level that an assembler .s file provides.  It has callbacks to emit bytes,
427092c7e1dcf9d05741b400dd54bbd7d3419773b2Daniel Dunbar  /// handle directives, etc.  The implementation of this interface retains
43e18e0c58dcd740c64e962fefde44249d685d0568Chris Lattner  /// state to know what the current section is etc.
44e18e0c58dcd740c64e962fefde44249d685d0568Chris Lattner  ///
45e18e0c58dcd740c64e962fefde44249d685d0568Chris Lattner  /// There are multiple implementations of this interface: one for writing out
46e18e0c58dcd740c64e962fefde44249d685d0568Chris Lattner  /// a .s file, and implementations that write out .o files of various formats.
47e18e0c58dcd740c64e962fefde44249d685d0568Chris Lattner  ///
4825e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar  class MCStreamer {
4925e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar    MCContext &Context;
5025e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar
5125e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar    MCStreamer(const MCStreamer&); // DO NOT IMPLEMENT
5225e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar    MCStreamer &operator=(const MCStreamer&); // DO NOT IMPLEMENT
5325e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar
54f9efd83166401bca542c6702ea329f9901c4e04bRafael Espindola    bool EmitEHFrame;
55f9efd83166401bca542c6702ea329f9901c4e04bRafael Espindola    bool EmitDebugFrame;
56f9efd83166401bca542c6702ea329f9901c4e04bRafael Espindola
57d7c8ccae8e48dce3ab7c3e9b4d8a309998c47961Rafael Espindola    std::vector<MCDwarfFrameInfo> FrameInfos;
58d7c8ccae8e48dce3ab7c3e9b4d8a309998c47961Rafael Espindola    MCDwarfFrameInfo *getCurrentFrameInfo();
59d7c8ccae8e48dce3ab7c3e9b4d8a309998c47961Rafael Espindola    void EnsureValidFrame();
60d7c8ccae8e48dce3ab7c3e9b4d8a309998c47961Rafael Espindola
610855bc5b973320052c87bdcc2fa17b9711edc3deCharles Davis    std::vector<MCWin64EHUnwindInfo> W64UnwindInfos;
6291d9a1c0f7c598d51c50f80bc9e8dfc1494f78c1Charles Davis    MCWin64EHUnwindInfo *CurrentW64UnwindInfo;
6391d9a1c0f7c598d51c50f80bc9e8dfc1494f78c1Charles Davis    void setCurrentW64UnwindInfo(MCWin64EHUnwindInfo *Frame);
640855bc5b973320052c87bdcc2fa17b9711edc3deCharles Davis    void EnsureValidW64UnwindInfo();
650855bc5b973320052c87bdcc2fa17b9711edc3deCharles Davis
66ed708f9c1facb9928ef2f79503e7030c8f25b00dRafael Espindola    const MCSymbol* LastNonPrivate;
67ed708f9c1facb9928ef2f79503e7030c8f25b00dRafael Espindola
687d0805dcb82e9ba1d90ce8d702169683b9caded7Joerg Sonnenberger    /// SectionStack - This is stack of current and previous section
697d0805dcb82e9ba1d90ce8d702169683b9caded7Joerg Sonnenberger    /// values saved by PushSection.
707d0805dcb82e9ba1d90ce8d702169683b9caded7Joerg Sonnenberger    SmallVector<std::pair<const MCSection *,
717d0805dcb82e9ba1d90ce8d702169683b9caded7Joerg Sonnenberger                const MCSection *>, 4> SectionStack;
727092c7e1dcf9d05741b400dd54bbd7d3419773b2Daniel Dunbar
737768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola  protected:
747768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola    MCStreamer(MCContext &Ctx);
75a37bd1d02c0e3d93474fdf30352bf4a425cbe25bRafael Espindola
76a37bd1d02c0e3d93474fdf30352bf4a425cbe25bRafael Espindola    const MCExpr *BuildSymbolDiff(MCContext &Context, const MCSymbol *A,
77a37bd1d02c0e3d93474fdf30352bf4a425cbe25bRafael Espindola                                  const MCSymbol *B);
78a37bd1d02c0e3d93474fdf30352bf4a425cbe25bRafael Espindola
79a6f2678f08299f053feb58337fc4322131d99bf4Rafael Espindola    const MCExpr *ForceExpAbs(const MCExpr* Expr);
801674b0b0e4972b844833f253286cbf99a6e99d6eBenjamin Kramer
81c25dad8750083829d9a8935ce40d0734e5488f8eRafael Espindola    void EmitFrames(bool usingCFI);
82c25dad8750083829d9a8935ce40d0734e5488f8eRafael Espindola
833185f5c35322cbd10040ab20f265042d477efe62Charles Davis    MCWin64EHUnwindInfo *getCurrentW64UnwindInfo(){return CurrentW64UnwindInfo;}
8438ea9eecd7c810e11f96c8306b241f9db88fc62fCharles Davis    void EmitW64Tables();
853185f5c35322cbd10040ab20f265042d477efe62Charles Davis
86381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar  public:
8725e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar    virtual ~MCStreamer();
8825e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar
8925e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar    MCContext &getContext() const { return Context; }
9025e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar
9189b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola    unsigned getNumFrameInfos() {
9289b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola      return FrameInfos.size();
9389b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola    }
9489b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola
9589b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola    const MCDwarfFrameInfo &getFrameInfo(unsigned i) {
9689b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola      return FrameInfos[i];
9789b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola    }
9889b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola
9938ea9eecd7c810e11f96c8306b241f9db88fc62fCharles Davis    unsigned getNumW64UnwindInfos() {
10038ea9eecd7c810e11f96c8306b241f9db88fc62fCharles Davis      return W64UnwindInfos.size();
10138ea9eecd7c810e11f96c8306b241f9db88fc62fCharles Davis    }
10238ea9eecd7c810e11f96c8306b241f9db88fc62fCharles Davis
10338ea9eecd7c810e11f96c8306b241f9db88fc62fCharles Davis    MCWin64EHUnwindInfo &getW64UnwindInfo(unsigned i) {
10438ea9eecd7c810e11f96c8306b241f9db88fc62fCharles Davis      return W64UnwindInfos[i];
10538ea9eecd7c810e11f96c8306b241f9db88fc62fCharles Davis    }
10638ea9eecd7c810e11f96c8306b241f9db88fc62fCharles Davis
1070fd90fd8d1c2143a763dee509c66a5b3c74088b1Chris Lattner    /// @name Assembly File Formatting.
1080fd90fd8d1c2143a763dee509c66a5b3c74088b1Chris Lattner    /// @{
1090dd2c9331887b9d0aa06b1e201c5eda4361365fcJim Grosbach
11091bead790518fcf5cb26019fb1ebf2372e8a5b3fChris Lattner    /// isVerboseAsm - Return true if this streamer supports verbose assembly
11191bead790518fcf5cb26019fb1ebf2372e8a5b3fChris Lattner    /// and if it is enabled.
11256591ab218639d8a6e4c756ca37adaf20215c3b6Chris Lattner    virtual bool isVerboseAsm() const { return false; }
1130dd2c9331887b9d0aa06b1e201c5eda4361365fcJim Grosbach
11491bead790518fcf5cb26019fb1ebf2372e8a5b3fChris Lattner    /// hasRawTextSupport - Return true if this asm streamer supports emitting
11591bead790518fcf5cb26019fb1ebf2372e8a5b3fChris Lattner    /// unformatted text to the .s file with EmitRawText.
11691bead790518fcf5cb26019fb1ebf2372e8a5b3fChris Lattner    virtual bool hasRawTextSupport() const { return false; }
1170fd90fd8d1c2143a763dee509c66a5b3c74088b1Chris Lattner
118d32c7cfa248f685e6e3064c0958dc2f0c31a4df6Chris Lattner    /// AddComment - Add a comment that can be emitted to the generated .s
11986e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner    /// file if applicable as a QoI issue to make the output of the compiler
12086e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner    /// more readable.  This only affects the MCAsmStreamer, and only when
12186e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner    /// verbose assembly output is enabled.
12286e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner    ///
12386e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner    /// If the comment includes embedded \n's, they will each get the comment
12486e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner    /// prefix as appropriate.  The added comment should not end with a \n.
125d32c7cfa248f685e6e3064c0958dc2f0c31a4df6Chris Lattner    virtual void AddComment(const Twine &T) {}
1260dd2c9331887b9d0aa06b1e201c5eda4361365fcJim Grosbach
127d79d9dce47d505369662ae5111dba24f9ccdef68Chris Lattner    /// GetCommentOS - Return a raw_ostream that comments can be written to.
128d79d9dce47d505369662ae5111dba24f9ccdef68Chris Lattner    /// Unlike AddComment, you are required to terminate comments with \n if you
129d79d9dce47d505369662ae5111dba24f9ccdef68Chris Lattner    /// use this method.
130d79d9dce47d505369662ae5111dba24f9ccdef68Chris Lattner    virtual raw_ostream &GetCommentOS();
1310dd2c9331887b9d0aa06b1e201c5eda4361365fcJim Grosbach
1320fd90fd8d1c2143a763dee509c66a5b3c74088b1Chris Lattner    /// AddBlankLine - Emit a blank line to a .s file to pretty it up.
1330fd90fd8d1c2143a763dee509c66a5b3c74088b1Chris Lattner    virtual void AddBlankLine() {}
1340dd2c9331887b9d0aa06b1e201c5eda4361365fcJim Grosbach
1350fd90fd8d1c2143a763dee509c66a5b3c74088b1Chris Lattner    /// @}
1360dd2c9331887b9d0aa06b1e201c5eda4361365fcJim Grosbach
13784a2926fb7ab388d688a133b0b375a26e669fd55Daniel Dunbar    /// @name Symbol & Section Management
13884a2926fb7ab388d688a133b0b375a26e669fd55Daniel Dunbar    /// @{
1390dd2c9331887b9d0aa06b1e201c5eda4361365fcJim Grosbach
1406a4824c466bbfbcbe7dc4d95ec1e23a14ec73d87Dan Gohman    /// getCurrentSection - Return the current section that the streamer is
1417092c7e1dcf9d05741b400dd54bbd7d3419773b2Daniel Dunbar    /// emitting code to.
1427768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola    const MCSection *getCurrentSection() const {
1437d0805dcb82e9ba1d90ce8d702169683b9caded7Joerg Sonnenberger      if (!SectionStack.empty())
1447d0805dcb82e9ba1d90ce8d702169683b9caded7Joerg Sonnenberger        return SectionStack.back().first;
1457768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola      return NULL;
1467768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola    }
14784a2926fb7ab388d688a133b0b375a26e669fd55Daniel Dunbar
1481674b0b0e4972b844833f253286cbf99a6e99d6eBenjamin Kramer    /// getPreviousSection - Return the previous section that the streamer is
1491674b0b0e4972b844833f253286cbf99a6e99d6eBenjamin Kramer    /// emitting code to.
1507768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola    const MCSection *getPreviousSection() const {
1517d0805dcb82e9ba1d90ce8d702169683b9caded7Joerg Sonnenberger      if (!SectionStack.empty())
1527d0805dcb82e9ba1d90ce8d702169683b9caded7Joerg Sonnenberger        return SectionStack.back().second;
1537768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola      return NULL;
1547768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola    }
1557768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola
1567768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola    /// ChangeSection - Update streamer for a new active section.
1577768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola    ///
1587768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola    /// This is called by PopSection and SwitchSection, if the current
1597768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola    /// section changes.
1607768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola    virtual void ChangeSection(const MCSection *) = 0;
1617768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola
1627768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola    /// pushSection - Save the current and previous section on the
1637768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola    /// section stack.
1647768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola    void PushSection() {
1657d0805dcb82e9ba1d90ce8d702169683b9caded7Joerg Sonnenberger      SectionStack.push_back(std::make_pair(getCurrentSection(),
1667d0805dcb82e9ba1d90ce8d702169683b9caded7Joerg Sonnenberger                                            getPreviousSection()));
1677768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola    }
1687768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola
1697768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola    /// popSection - Restore the current and previous section from
1707768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola    /// the section stack.  Calls ChangeSection as needed.
1717768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola    ///
1727768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola    /// Returns false if the stack was empty.
1737768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola    bool PopSection() {
1747d0805dcb82e9ba1d90ce8d702169683b9caded7Joerg Sonnenberger      if (SectionStack.size() <= 1)
1757768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola        return false;
1767d0805dcb82e9ba1d90ce8d702169683b9caded7Joerg Sonnenberger      const MCSection *oldSection = SectionStack.pop_back_val().first;
1777d0805dcb82e9ba1d90ce8d702169683b9caded7Joerg Sonnenberger      const MCSection *curSection = SectionStack.back().first;
1787768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola
1797768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola      if (oldSection != curSection)
1807768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola        ChangeSection(curSection);
1817768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola      return true;
1827768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola    }
1831674b0b0e4972b844833f253286cbf99a6e99d6eBenjamin Kramer
184381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar    /// SwitchSection - Set the current section where code is being emitted to
185fb76fe09297ee292129e44d723127f2408602a3dDan Gohman    /// @p Section.  This is required to update CurSection.
186381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar    ///
187381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar    /// This corresponds to assembler directives like .section, .text, etc.
1887768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola    void SwitchSection(const MCSection *Section) {
1897768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola      assert(Section && "Cannot switch to a null section!");
1907d0805dcb82e9ba1d90ce8d702169683b9caded7Joerg Sonnenberger      const MCSection *curSection = SectionStack.back().first;
1917d0805dcb82e9ba1d90ce8d702169683b9caded7Joerg Sonnenberger      SectionStack.back().second = curSection;
1927768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola      if (Section != curSection) {
1937d0805dcb82e9ba1d90ce8d702169683b9caded7Joerg Sonnenberger        SectionStack.back().first = Section;
1947768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola        ChangeSection(Section);
1957768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola      }
1967768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola    }
1970dd2c9331887b9d0aa06b1e201c5eda4361365fcJim Grosbach
198410ef2b263e92d3de1b2acff7437059400daed7dCharles Davis    /// SwitchSectionNoChange - Set the current section where code is being
199410ef2b263e92d3de1b2acff7437059400daed7dCharles Davis    /// emitted to @p Section.  This is required to update CurSection. This
200410ef2b263e92d3de1b2acff7437059400daed7dCharles Davis    /// version does not call ChangeSection.
201410ef2b263e92d3de1b2acff7437059400daed7dCharles Davis    void SwitchSectionNoChange(const MCSection *Section) {
202410ef2b263e92d3de1b2acff7437059400daed7dCharles Davis      assert(Section && "Cannot switch to a null section!");
203410ef2b263e92d3de1b2acff7437059400daed7dCharles Davis      const MCSection *curSection = SectionStack.back().first;
204410ef2b263e92d3de1b2acff7437059400daed7dCharles Davis      SectionStack.back().second = curSection;
205410ef2b263e92d3de1b2acff7437059400daed7dCharles Davis      if (Section != curSection)
206410ef2b263e92d3de1b2acff7437059400daed7dCharles Davis        SectionStack.back().first = Section;
207410ef2b263e92d3de1b2acff7437059400daed7dCharles Davis    }
208410ef2b263e92d3de1b2acff7437059400daed7dCharles Davis
209d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola    /// InitSections - Create the default sections and set the initial one.
210d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola    virtual void InitSections() = 0;
211d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola
212fb76fe09297ee292129e44d723127f2408602a3dDan Gohman    /// EmitLabel - Emit a label for @p Symbol into the current section.
213381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar    ///
214381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar    /// This corresponds to an assembler statement such as:
215381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar    ///   foo:
216381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar    ///
217381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar    /// @param Symbol - The symbol to emit. A given symbol should only be
218381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar    /// emitted as a label once, and symbols emitted as a label should never be
219381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar    /// used in an assignment.
220ed708f9c1facb9928ef2f79503e7030c8f25b00dRafael Espindola    virtual void EmitLabel(MCSymbol *Symbol);
221381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar
2228bca4106dfc2945723251db10e340183f3e372ddRafael Espindola    virtual void EmitEHSymAttributes(const MCSymbol *Symbol,
2238bca4106dfc2945723251db10e340183f3e372ddRafael Espindola                                     MCSymbol *EHSymbol);
2248bca4106dfc2945723251db10e340183f3e372ddRafael Espindola
225fb76fe09297ee292129e44d723127f2408602a3dDan Gohman    /// EmitAssemblerFlag - Note in the output the specified @p Flag
226a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner    virtual void EmitAssemblerFlag(MCAssemblerFlag Flag) = 0;
227a5c783280f83df5c60a8ed9e32c61b05a11048e3Kevin Enderby
228ce79299f78bb04e76e1860ab119b85d69f3a19c7Jim Grosbach    /// EmitThumbFunc - Note in the output that the specified @p Func is
229ce79299f78bb04e76e1860ab119b85d69f3a19c7Jim Grosbach    /// a Thumb mode function (ARM target only).
230ce79299f78bb04e76e1860ab119b85d69f3a19c7Jim Grosbach    virtual void EmitThumbFunc(MCSymbol *Func) = 0;
231ce79299f78bb04e76e1860ab119b85d69f3a19c7Jim Grosbach
232fb76fe09297ee292129e44d723127f2408602a3dDan Gohman    /// EmitAssignment - Emit an assignment of @p Value to @p Symbol.
233381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar    ///
234381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar    /// This corresponds to an assembler statement such as:
235381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar    ///  symbol = value
236381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar    ///
237381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar    /// The assignment generates no code, but has the side effect of binding the
238381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar    /// value in the current context. For the assembly streamer, this prints the
239381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar    /// binding into the .s file.
240381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar    ///
241381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar    /// @param Symbol - The symbol being assigned to.
242381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar    /// @param Value - The value for the symbol.
243821e3334ed3390d931f497300e6a5f1dc21bcfb3Daniel Dunbar    virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) = 0;
24425e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar
245484291c27319668ad99cb87def000254357736fbRafael Espindola    /// EmitWeakReference - Emit an weak reference from @p Alias to @p Symbol.
246484291c27319668ad99cb87def000254357736fbRafael Espindola    ///
247484291c27319668ad99cb87def000254357736fbRafael Espindola    /// This corresponds to an assembler statement such as:
248484291c27319668ad99cb87def000254357736fbRafael Espindola    ///  .weakref alias, symbol
249484291c27319668ad99cb87def000254357736fbRafael Espindola    ///
250484291c27319668ad99cb87def000254357736fbRafael Espindola    /// @param Alias - The alias that is being created.
251484291c27319668ad99cb87def000254357736fbRafael Espindola    /// @param Symbol - The symbol being aliased.
252484291c27319668ad99cb87def000254357736fbRafael Espindola    virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) = 0;
253484291c27319668ad99cb87def000254357736fbRafael Espindola
254fb76fe09297ee292129e44d723127f2408602a3dDan Gohman    /// EmitSymbolAttribute - Add the given @p Attribute to @p Symbol.
255a11af531ec48ad84f790b9511f003ac5c934a999Daniel Dunbar    virtual void EmitSymbolAttribute(MCSymbol *Symbol,
256a5ad93a10a5435f21090b09edb6b3a7e44967648Chris Lattner                                     MCSymbolAttr Attribute) = 0;
25725e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar
258fb76fe09297ee292129e44d723127f2408602a3dDan Gohman    /// EmitSymbolDesc - Set the @p DescValue for the @p Symbol.
25995cf30c444707634bbd950f13405b6c8bcfe496bKevin Enderby    ///
26095cf30c444707634bbd950f13405b6c8bcfe496bKevin Enderby    /// @param Symbol - The symbol to have its n_desc field set.
26195cf30c444707634bbd950f13405b6c8bcfe496bKevin Enderby    /// @param DescValue - The value to set into the n_desc field.
26295cf30c444707634bbd950f13405b6c8bcfe496bKevin Enderby    virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) = 0;
26395cf30c444707634bbd950f13405b6c8bcfe496bKevin Enderby
264b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner    /// BeginCOFFSymbolDef - Start emitting COFF symbol definition
265b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner    ///
266b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner    /// @param Symbol - The symbol to have its External & Type fields set.
267b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner    virtual void BeginCOFFSymbolDef(const MCSymbol *Symbol) = 0;
268b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner
269b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner    /// EmitCOFFSymbolStorageClass - Emit the storage class of the symbol.
270b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner    ///
271b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner    /// @param StorageClass - The storage class the symbol should have.
272b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner    virtual void EmitCOFFSymbolStorageClass(int StorageClass) = 0;
273b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner
274b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner    /// EmitCOFFSymbolType - Emit the type of the symbol.
275b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner    ///
276b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner    /// @param Type - A COFF type identifier (see COFF::SymbolType in X86COFF.h)
277b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner    virtual void EmitCOFFSymbolType(int Type) = 0;
278b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner
279b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner    /// EndCOFFSymbolDef - Marks the end of the symbol definition.
280b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner    virtual void EndCOFFSymbolDef() = 0;
281b54b9ddaaf2d258767d360583642ed1b91075fc9Chris Lattner
28299328add833807f12a4950c7de29fb2a5df04703Chris Lattner    /// EmitELFSize - Emit an ELF .size directive.
28399328add833807f12a4950c7de29fb2a5df04703Chris Lattner    ///
28499328add833807f12a4950c7de29fb2a5df04703Chris Lattner    /// This corresponds to an assembler statement such as:
28599328add833807f12a4950c7de29fb2a5df04703Chris Lattner    ///  .size symbol, expression
28699328add833807f12a4950c7de29fb2a5df04703Chris Lattner    ///
28799328add833807f12a4950c7de29fb2a5df04703Chris Lattner    virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) = 0;
2880dd2c9331887b9d0aa06b1e201c5eda4361365fcJim Grosbach
2899eb158d5b4cd4f6fc80912e2dd77bdf13c3ca0e7Chris Lattner    /// EmitCommonSymbol - Emit a common symbol.
2904e4db7adfc9858a8f77f841c7467bc6fcbb8110eChris Lattner    ///
2914e4db7adfc9858a8f77f841c7467bc6fcbb8110eChris Lattner    /// @param Symbol - The common symbol to emit.
2924e4db7adfc9858a8f77f841c7467bc6fcbb8110eChris Lattner    /// @param Size - The size of the common symbol.
2937092c7e1dcf9d05741b400dd54bbd7d3419773b2Daniel Dunbar    /// @param ByteAlignment - The alignment of the symbol if
2949eb158d5b4cd4f6fc80912e2dd77bdf13c3ca0e7Chris Lattner    /// non-zero. This must be a power of 2.
2959eb158d5b4cd4f6fc80912e2dd77bdf13c3ca0e7Chris Lattner    virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
2967092c7e1dcf9d05741b400dd54bbd7d3419773b2Daniel Dunbar                                  unsigned ByteAlignment) = 0;
2974e4db7adfc9858a8f77f841c7467bc6fcbb8110eChris Lattner
2989eb158d5b4cd4f6fc80912e2dd77bdf13c3ca0e7Chris Lattner    /// EmitLocalCommonSymbol - Emit a local common (.lcomm) symbol.
2999eb158d5b4cd4f6fc80912e2dd77bdf13c3ca0e7Chris Lattner    ///
3009eb158d5b4cd4f6fc80912e2dd77bdf13c3ca0e7Chris Lattner    /// @param Symbol - The common symbol to emit.
3019eb158d5b4cd4f6fc80912e2dd77bdf13c3ca0e7Chris Lattner    /// @param Size - The size of the common symbol.
3029eb158d5b4cd4f6fc80912e2dd77bdf13c3ca0e7Chris Lattner    virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size) = 0;
3030dd2c9331887b9d0aa06b1e201c5eda4361365fcJim Grosbach
3040df4a80e2063424929bbfaa61dd7973062218ad4Eric Christopher    /// EmitZerofill - Emit the zerofill section and an optional symbol.
3059be3fee2bdc3126fb87e4e1b31935905f4bcc4d0Chris Lattner    ///
3069be3fee2bdc3126fb87e4e1b31935905f4bcc4d0Chris Lattner    /// @param Section - The zerofill section to create and or to put the symbol
3079be3fee2bdc3126fb87e4e1b31935905f4bcc4d0Chris Lattner    /// @param Symbol - The zerofill symbol to emit, if non-NULL.
3089be3fee2bdc3126fb87e4e1b31935905f4bcc4d0Chris Lattner    /// @param Size - The size of the zerofill symbol.
3097092c7e1dcf9d05741b400dd54bbd7d3419773b2Daniel Dunbar    /// @param ByteAlignment - The alignment of the zerofill symbol if
3107092c7e1dcf9d05741b400dd54bbd7d3419773b2Daniel Dunbar    /// non-zero. This must be a power of 2 on some targets.
3118751b94ffbd9c49df8949a37f78d6bd0be87b256Daniel Dunbar    virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0,
3127092c7e1dcf9d05741b400dd54bbd7d3419773b2Daniel Dunbar                              unsigned Size = 0,unsigned ByteAlignment = 0) = 0;
3139be3fee2bdc3126fb87e4e1b31935905f4bcc4d0Chris Lattner
314482eba054ab3543ee0e1f453d3d6441092f4b76dEric Christopher    /// EmitTBSSSymbol - Emit a thread local bss (.tbss) symbol.
315482eba054ab3543ee0e1f453d3d6441092f4b76dEric Christopher    ///
3164d01cbe93b0e1a349b5c2881f1b319963f9e0504Eric Christopher    /// @param Section - The thread local common section.
317482eba054ab3543ee0e1f453d3d6441092f4b76dEric Christopher    /// @param Symbol - The thread local common symbol to emit.
318482eba054ab3543ee0e1f453d3d6441092f4b76dEric Christopher    /// @param Size - The size of the symbol.
319482eba054ab3543ee0e1f453d3d6441092f4b76dEric Christopher    /// @param ByteAlignment - The alignment of the thread local common symbol
320482eba054ab3543ee0e1f453d3d6441092f4b76dEric Christopher    /// if non-zero.  This must be a power of 2 on some targets.
3214d01cbe93b0e1a349b5c2881f1b319963f9e0504Eric Christopher    virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
3220dd2c9331887b9d0aa06b1e201c5eda4361365fcJim Grosbach                                uint64_t Size, unsigned ByteAlignment = 0) = 0;
323ff96a12db635daf4f88cfea899e63a885dfaa9edCharles Davis
32484a2926fb7ab388d688a133b0b375a26e669fd55Daniel Dunbar    /// @}
32584a2926fb7ab388d688a133b0b375a26e669fd55Daniel Dunbar    /// @name Generating Data
32684a2926fb7ab388d688a133b0b375a26e669fd55Daniel Dunbar    /// @{
32784a2926fb7ab388d688a133b0b375a26e669fd55Daniel Dunbar
3287092c7e1dcf9d05741b400dd54bbd7d3419773b2Daniel Dunbar    /// EmitBytes - Emit the bytes in \arg Data into the output.
329381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar    ///
330381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar    /// This is used to implement assembler directives such as .byte, .ascii,
331381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar    /// etc.
332aaec205b87637cd0d59d4f11630db603686eb73dChris Lattner    virtual void EmitBytes(StringRef Data, unsigned AddrSpace) = 0;
333381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar
334fb76fe09297ee292129e44d723127f2408602a3dDan Gohman    /// EmitValue - Emit the expression @p Value into the output as a native
335fb76fe09297ee292129e44d723127f2408602a3dDan Gohman    /// integer of the given @p Size bytes.
336381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar    ///
337381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar    /// This is used to implement assembler directives such as .word, .quad,
338381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar    /// etc.
339381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar    ///
340381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar    /// @param Value - The value to emit.
341381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar    /// @param Size - The size of the integer (in bytes) to emit. This must
342381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar    /// match a native machine width.
34389b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola    virtual void EmitValueImpl(const MCExpr *Value, unsigned Size,
344debd7e4e8bc5cfe61bfb71835ce2b1a3fbccc2beRafael Espindola                               unsigned AddrSpace) = 0;
34589b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola
34689b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola    void EmitValue(const MCExpr *Value, unsigned Size, unsigned AddrSpace = 0);
34789b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola
34832ae3fe0ba469240753e2342e36485f7c9acfb5cChris Lattner    /// EmitIntValue - Special case of EmitValue that avoids the client having
34932ae3fe0ba469240753e2342e36485f7c9acfb5cChris Lattner    /// to pass in a MCExpr for constant integers.
3502df042cb32ecb8d2e1d499dfa27d5074c8b40e13Rafael Espindola    virtual void EmitIntValue(uint64_t Value, unsigned Size,
3512df042cb32ecb8d2e1d499dfa27d5074c8b40e13Rafael Espindola                              unsigned AddrSpace = 0);
3520dd2c9331887b9d0aa06b1e201c5eda4361365fcJim Grosbach
3530bbe0b440ee2cef47dcb7b281825eb70341c16ddRafael Espindola    /// EmitAbsValue - Emit the Value, but try to avoid relocations. On MachO
3540bbe0b440ee2cef47dcb7b281825eb70341c16ddRafael Espindola    /// this is done by producing
3550bbe0b440ee2cef47dcb7b281825eb70341c16ddRafael Espindola    /// foo = value
3560bbe0b440ee2cef47dcb7b281825eb70341c16ddRafael Espindola    /// .long foo
3570bbe0b440ee2cef47dcb7b281825eb70341c16ddRafael Espindola    void EmitAbsValue(const MCExpr *Value, unsigned Size,
3580bbe0b440ee2cef47dcb7b281825eb70341c16ddRafael Espindola                      unsigned AddrSpace = 0);
3593bb435301a2b5c901a993b0e151d05b596697038Kevin Enderby
360e8cfbd843d737e1f95c3032c7670c2be3838a6f6Rafael Espindola    virtual void EmitULEB128Value(const MCExpr *Value) = 0;
3613ff57094a7d176a759ddb1e1668489d89064f56cRafael Espindola
362e8cfbd843d737e1f95c3032c7670c2be3838a6f6Rafael Espindola    virtual void EmitSLEB128Value(const MCExpr *Value) = 0;
3633ff57094a7d176a759ddb1e1668489d89064f56cRafael Espindola
3643ff57094a7d176a759ddb1e1668489d89064f56cRafael Espindola    /// EmitULEB128Value - Special case of EmitULEB128Value that avoids the
3653ff57094a7d176a759ddb1e1668489d89064f56cRafael Espindola    /// client having to pass in a MCExpr for constant integers.
36671e7f9210d87fa29202d851c43b5e91bbbd2fa51Rafael Espindola    void EmitULEB128IntValue(uint64_t Value, unsigned AddrSpace = 0);
3673ff57094a7d176a759ddb1e1668489d89064f56cRafael Espindola
3683ff57094a7d176a759ddb1e1668489d89064f56cRafael Espindola    /// EmitSLEB128Value - Special case of EmitSLEB128Value that avoids the
3693ff57094a7d176a759ddb1e1668489d89064f56cRafael Espindola    /// client having to pass in a MCExpr for constant integers.
37071e7f9210d87fa29202d851c43b5e91bbbd2fa51Rafael Espindola    void EmitSLEB128IntValue(int64_t Value, unsigned AddrSpace = 0);
3713bb435301a2b5c901a993b0e151d05b596697038Kevin Enderby
3726cde3e6e993126df756e3be5b9ef43540b904644Chris Lattner    /// EmitSymbolValue - Special case of EmitValue that avoids the client
3736cde3e6e993126df756e3be5b9ef43540b904644Chris Lattner    /// having to pass in a MCExpr for MCSymbols.
374175ccab75f3a355285cf4533c201cbcecfd5928dRafael Espindola    void EmitSymbolValue(const MCSymbol *Sym, unsigned Size,
375175ccab75f3a355285cf4533c201cbcecfd5928dRafael Espindola                         unsigned AddrSpace = 0);
3760dd2c9331887b9d0aa06b1e201c5eda4361365fcJim Grosbach
377fb76fe09297ee292129e44d723127f2408602a3dDan Gohman    /// EmitGPRel32Value - Emit the expression @p Value into the output as a
378718fb59801320b8cb22363d115b5fc5ec40dc1f5Chris Lattner    /// gprel32 (32-bit GP relative) value.
379718fb59801320b8cb22363d115b5fc5ec40dc1f5Chris Lattner    ///
380718fb59801320b8cb22363d115b5fc5ec40dc1f5Chris Lattner    /// This is used to implement assembler directives such as .gprel32 on
381718fb59801320b8cb22363d115b5fc5ec40dc1f5Chris Lattner    /// targets that support them.
3823e03211625bba5bbb70a193c140ebf4dd8388bb7Rafael Espindola    virtual void EmitGPRel32Value(const MCExpr *Value);
3830dd2c9331887b9d0aa06b1e201c5eda4361365fcJim Grosbach
384ddf6bdde44287b5b559bc403a02ff971e15e8303Chris Lattner    /// EmitFill - Emit NumBytes bytes worth of the value specified by
385ddf6bdde44287b5b559bc403a02ff971e15e8303Chris Lattner    /// FillValue.  This implements directives such as '.space'.
386aaec205b87637cd0d59d4f11630db603686eb73dChris Lattner    virtual void EmitFill(uint64_t NumBytes, uint8_t FillValue,
387aaec205b87637cd0d59d4f11630db603686eb73dChris Lattner                          unsigned AddrSpace);
3880dd2c9331887b9d0aa06b1e201c5eda4361365fcJim Grosbach
3896449abfbc86310edbbe0b5ffb3fad5c14301307fChris Lattner    /// EmitZeros - Emit NumBytes worth of zeros.  This is a convenience
3906449abfbc86310edbbe0b5ffb3fad5c14301307fChris Lattner    /// function that just wraps EmitFill.
3916449abfbc86310edbbe0b5ffb3fad5c14301307fChris Lattner    void EmitZeros(uint64_t NumBytes, unsigned AddrSpace) {
3926449abfbc86310edbbe0b5ffb3fad5c14301307fChris Lattner      EmitFill(NumBytes, 0, AddrSpace);
3936449abfbc86310edbbe0b5ffb3fad5c14301307fChris Lattner    }
3946449abfbc86310edbbe0b5ffb3fad5c14301307fChris Lattner
3950dd2c9331887b9d0aa06b1e201c5eda4361365fcJim Grosbach
396fb76fe09297ee292129e44d723127f2408602a3dDan Gohman    /// EmitValueToAlignment - Emit some number of copies of @p Value until
397fb76fe09297ee292129e44d723127f2408602a3dDan Gohman    /// the byte alignment @p ByteAlignment is reached.
39884a2926fb7ab388d688a133b0b375a26e669fd55Daniel Dunbar    ///
39984a2926fb7ab388d688a133b0b375a26e669fd55Daniel Dunbar    /// If the number of bytes need to emit for the alignment is not a multiple
400fb76fe09297ee292129e44d723127f2408602a3dDan Gohman    /// of @p ValueSize, then the contents of the emitted fill bytes is
40184a2926fb7ab388d688a133b0b375a26e669fd55Daniel Dunbar    /// undefined.
40284a2926fb7ab388d688a133b0b375a26e669fd55Daniel Dunbar    ///
40384a2926fb7ab388d688a133b0b375a26e669fd55Daniel Dunbar    /// This used to implement the .align assembler directive.
40484a2926fb7ab388d688a133b0b375a26e669fd55Daniel Dunbar    ///
40584a2926fb7ab388d688a133b0b375a26e669fd55Daniel Dunbar    /// @param ByteAlignment - The alignment to reach. This must be a power of
406c29dfa786a23c9ff0827ce4a56b5b178e4087aaaDaniel Dunbar    /// two on some targets.
40784a2926fb7ab388d688a133b0b375a26e669fd55Daniel Dunbar    /// @param Value - The value to use when filling bytes.
408fb76fe09297ee292129e44d723127f2408602a3dDan Gohman    /// @param ValueSize - The size of the integer (in bytes) to emit for
409fb76fe09297ee292129e44d723127f2408602a3dDan Gohman    /// @p Value. This must match a native machine width.
41084a2926fb7ab388d688a133b0b375a26e669fd55Daniel Dunbar    /// @param MaxBytesToEmit - The maximum numbers of bytes to emit, or 0. If
41184a2926fb7ab388d688a133b0b375a26e669fd55Daniel Dunbar    /// the alignment cannot be reached in this many bytes, no bytes are
41284a2926fb7ab388d688a133b0b375a26e669fd55Daniel Dunbar    /// emitted.
41384a2926fb7ab388d688a133b0b375a26e669fd55Daniel Dunbar    virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
41484a2926fb7ab388d688a133b0b375a26e669fd55Daniel Dunbar                                      unsigned ValueSize = 1,
41584a2926fb7ab388d688a133b0b375a26e669fd55Daniel Dunbar                                      unsigned MaxBytesToEmit = 0) = 0;
4166e72048add2a6464e038121c6c275da37528aa0aKevin Enderby
4176e72048add2a6464e038121c6c275da37528aa0aKevin Enderby    /// EmitCodeAlignment - Emit nops until the byte alignment @p ByteAlignment
4186e72048add2a6464e038121c6c275da37528aa0aKevin Enderby    /// is reached.
4196e72048add2a6464e038121c6c275da37528aa0aKevin Enderby    ///
4206e72048add2a6464e038121c6c275da37528aa0aKevin Enderby    /// This used to align code where the alignment bytes may be executed.  This
4216e72048add2a6464e038121c6c275da37528aa0aKevin Enderby    /// can emit different bytes for different sizes to optimize execution.
4226e72048add2a6464e038121c6c275da37528aa0aKevin Enderby    ///
4236e72048add2a6464e038121c6c275da37528aa0aKevin Enderby    /// @param ByteAlignment - The alignment to reach. This must be a power of
4246e72048add2a6464e038121c6c275da37528aa0aKevin Enderby    /// two on some targets.
4256e72048add2a6464e038121c6c275da37528aa0aKevin Enderby    /// @param MaxBytesToEmit - The maximum numbers of bytes to emit, or 0. If
4266e72048add2a6464e038121c6c275da37528aa0aKevin Enderby    /// the alignment cannot be reached in this many bytes, no bytes are
4276e72048add2a6464e038121c6c275da37528aa0aKevin Enderby    /// emitted.
4286e72048add2a6464e038121c6c275da37528aa0aKevin Enderby    virtual void EmitCodeAlignment(unsigned ByteAlignment,
4296e72048add2a6464e038121c6c275da37528aa0aKevin Enderby                                   unsigned MaxBytesToEmit = 0) = 0;
43084a2926fb7ab388d688a133b0b375a26e669fd55Daniel Dunbar
431fb76fe09297ee292129e44d723127f2408602a3dDan Gohman    /// EmitValueToOffset - Emit some number of copies of @p Value until the
432fb76fe09297ee292129e44d723127f2408602a3dDan Gohman    /// byte offset @p Offset is reached.
43384a2926fb7ab388d688a133b0b375a26e669fd55Daniel Dunbar    ///
43484a2926fb7ab388d688a133b0b375a26e669fd55Daniel Dunbar    /// This is used to implement assembler directives such as .org.
43584a2926fb7ab388d688a133b0b375a26e669fd55Daniel Dunbar    ///
4364a1fadaf5207e46d19c64e5773ff8d9e65e607d7Daniel Dunbar    /// @param Offset - The offset to reach. This may be an expression, but the
43784a2926fb7ab388d688a133b0b375a26e669fd55Daniel Dunbar    /// expression must be associated with the current section.
43884a2926fb7ab388d688a133b0b375a26e669fd55Daniel Dunbar    /// @param Value - The value to use when filling bytes.
439821e3334ed3390d931f497300e6a5f1dc21bcfb3Daniel Dunbar    virtual void EmitValueToOffset(const MCExpr *Offset,
44084a2926fb7ab388d688a133b0b375a26e669fd55Daniel Dunbar                                   unsigned char Value = 0) = 0;
4410dd2c9331887b9d0aa06b1e201c5eda4361365fcJim Grosbach
44284a2926fb7ab388d688a133b0b375a26e669fd55Daniel Dunbar    /// @}
4430dd2c9331887b9d0aa06b1e201c5eda4361365fcJim Grosbach
444a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner    /// EmitFileDirective - Switch to a new logical file.  This is used to
445a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner    /// implement the '.file "foo.c"' assembler directive.
446a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner    virtual void EmitFileDirective(StringRef Filename) = 0;
4470dd2c9331887b9d0aa06b1e201c5eda4361365fcJim Grosbach
448a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner    /// EmitDwarfFileDirective - Associate a filename with a specified logical
449a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner    /// file number.  This implements the DWARF2 '.file 4 "foo.c"' assembler
450a6594fc7156c0afbe6fd5a6aab9b099aaf950c53Chris Lattner    /// directive.
451af6b5808756d6ce335df9eb158efa33894b401c4Rafael Espindola    virtual bool EmitDwarfFileDirective(unsigned FileNo,StringRef Filename);
452af6b5808756d6ce335df9eb158efa33894b401c4Rafael Espindola
453af6b5808756d6ce335df9eb158efa33894b401c4Rafael Espindola    /// EmitDwarfLocDirective - This implements the DWARF2
454af6b5808756d6ce335df9eb158efa33894b401c4Rafael Espindola    // '.loc fileno lineno ...' assembler directive.
455af6b5808756d6ce335df9eb158efa33894b401c4Rafael Espindola    virtual void EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
456af6b5808756d6ce335df9eb158efa33894b401c4Rafael Espindola                                       unsigned Column, unsigned Flags,
457af6b5808756d6ce335df9eb158efa33894b401c4Rafael Espindola                                       unsigned Isa,
4583f3bf9387b75f4c932e4c59bd7af719d26ae4b99Devang Patel                                       unsigned Discriminator,
4593f3bf9387b75f4c932e4c59bd7af719d26ae4b99Devang Patel                                       StringRef FileName);
46084a2926fb7ab388d688a133b0b375a26e669fd55Daniel Dunbar
46132a006e606742b1c5401e49607e33717bb5441f0Rafael Espindola    virtual void EmitDwarfAdvanceLineAddr(int64_t LineDelta,
46232a006e606742b1c5401e49607e33717bb5441f0Rafael Espindola                                          const MCSymbol *LastLabel,
46332a006e606742b1c5401e49607e33717bb5441f0Rafael Espindola                                          const MCSymbol *Label) = 0;
46432a006e606742b1c5401e49607e33717bb5441f0Rafael Espindola
465245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola    virtual void EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
466245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola                                           const MCSymbol *Label) {
467245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola    }
468245a1e20419aa5a3c833d7a8e89168e19d5f4d2cRafael Espindola
46932a006e606742b1c5401e49607e33717bb5441f0Rafael Espindola    void EmitDwarfSetLineAddr(int64_t LineDelta, const MCSymbol *Label,
47032a006e606742b1c5401e49607e33717bb5441f0Rafael Espindola                              int PointerSize);
47132a006e606742b1c5401e49607e33717bb5441f0Rafael Espindola
472f9efd83166401bca542c6702ea329f9901c4e04bRafael Espindola    virtual void EmitCFISections(bool EH, bool Debug);
473066c2f495ae396ce5335e374c45b1e4ace4f2470Rafael Espindola    virtual void EmitCFIStartProc();
474066c2f495ae396ce5335e374c45b1e4ace4f2470Rafael Espindola    virtual void EmitCFIEndProc();
475066c2f495ae396ce5335e374c45b1e4ace4f2470Rafael Espindola    virtual void EmitCFIDefCfa(int64_t Register, int64_t Offset);
476066c2f495ae396ce5335e374c45b1e4ace4f2470Rafael Espindola    virtual void EmitCFIDefCfaOffset(int64_t Offset);
477066c2f495ae396ce5335e374c45b1e4ace4f2470Rafael Espindola    virtual void EmitCFIDefCfaRegister(int64_t Register);
478066c2f495ae396ce5335e374c45b1e4ace4f2470Rafael Espindola    virtual void EmitCFIOffset(int64_t Register, int64_t Offset);
479066c2f495ae396ce5335e374c45b1e4ace4f2470Rafael Espindola    virtual void EmitCFIPersonality(const MCSymbol *Sym, unsigned Encoding);
480066c2f495ae396ce5335e374c45b1e4ace4f2470Rafael Espindola    virtual void EmitCFILsda(const MCSymbol *Sym, unsigned Encoding);
481066c2f495ae396ce5335e374c45b1e4ace4f2470Rafael Espindola    virtual void EmitCFIRememberState();
482066c2f495ae396ce5335e374c45b1e4ace4f2470Rafael Espindola    virtual void EmitCFIRestoreState();
483066c2f495ae396ce5335e374c45b1e4ace4f2470Rafael Espindola    virtual void EmitCFISameValue(int64_t Register);
484066c2f495ae396ce5335e374c45b1e4ace4f2470Rafael Espindola    virtual void EmitCFIRelOffset(int64_t Register, int64_t Offset);
485066c2f495ae396ce5335e374c45b1e4ace4f2470Rafael Espindola    virtual void EmitCFIAdjustCfaOffset(int64_t Adjustment);
486cdfecc8759941c2996214070478d30084b79d463Rafael Espindola
487fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis    virtual void EmitWin64EHStartProc(const MCSymbol *Symbol);
4889c77398d1c89f615735d304cd7eda3c3e9b1504fCharles Davis    virtual void EmitWin64EHEndProc();
489f07090134d06e0cf3508e8b8e87d775f0a7982c1Charles Davis    virtual void EmitWin64EHStartChained();
490f07090134d06e0cf3508e8b8e87d775f0a7982c1Charles Davis    virtual void EmitWin64EHEndChained();
491440596ffe5bb77a202acb36d5eadd158976ff39aCharles Davis    virtual void EmitWin64EHHandler(const MCSymbol *Sym, bool Unwind,
492440596ffe5bb77a202acb36d5eadd158976ff39aCharles Davis                                    bool Except);
493440596ffe5bb77a202acb36d5eadd158976ff39aCharles Davis    virtual void EmitWin64EHHandlerData();
494c3b162857a587c9877e903f038471b882b213232Charles Davis    virtual void EmitWin64EHPushReg(unsigned Register);
495c3b162857a587c9877e903f038471b882b213232Charles Davis    virtual void EmitWin64EHSetFrame(unsigned Register, unsigned Offset);
496c3b162857a587c9877e903f038471b882b213232Charles Davis    virtual void EmitWin64EHAllocStack(unsigned Size);
497c3b162857a587c9877e903f038471b882b213232Charles Davis    virtual void EmitWin64EHSaveReg(unsigned Register, unsigned Offset);
498c3b162857a587c9877e903f038471b882b213232Charles Davis    virtual void EmitWin64EHSaveXMM(unsigned Register, unsigned Offset);
499ff96a12db635daf4f88cfea899e63a885dfaa9edCharles Davis    virtual void EmitWin64EHPushFrame(bool Code);
5009c77398d1c89f615735d304cd7eda3c3e9b1504fCharles Davis    virtual void EmitWin64EHEndProlog();
501ff96a12db635daf4f88cfea899e63a885dfaa9edCharles Davis
502fb76fe09297ee292129e44d723127f2408602a3dDan Gohman    /// EmitInstruction - Emit the given @p Instruction into the current
503381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar    /// section.
50425e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar    virtual void EmitInstruction(const MCInst &Inst) = 0;
505ba1da8a7b10b8a7df04f3ca47ca36ad18adad80eDaniel Dunbar
50691bead790518fcf5cb26019fb1ebf2372e8a5b3fChris Lattner    /// EmitRawText - If this file is backed by a assembly streamer, this dumps
50791bead790518fcf5cb26019fb1ebf2372e8a5b3fChris Lattner    /// the specified string in the output .s file.  This capability is
50891bead790518fcf5cb26019fb1ebf2372e8a5b3fChris Lattner    /// indicated by the hasRawTextSupport() predicate.  By default this aborts.
50991bead790518fcf5cb26019fb1ebf2372e8a5b3fChris Lattner    virtual void EmitRawText(StringRef String);
51058bc4dd4a91443ddd3120b0a2f1801ad4d6aae1cChris Lattner    void EmitRawText(const Twine &String);
5110dd2c9331887b9d0aa06b1e201c5eda4361365fcJim Grosbach
512b5e16af9ea04cc1f94ca631104e5e6be96546aa1Anton Korobeynikov    /// ARM-related methods.
513b5e16af9ea04cc1f94ca631104e5e6be96546aa1Anton Korobeynikov    /// FIXME: Eventually we should have some "target MC streamer" and move
514b5e16af9ea04cc1f94ca631104e5e6be96546aa1Anton Korobeynikov    /// these methods there.
515b5e16af9ea04cc1f94ca631104e5e6be96546aa1Anton Korobeynikov    virtual void EmitFnStart();
516b5e16af9ea04cc1f94ca631104e5e6be96546aa1Anton Korobeynikov    virtual void EmitFnEnd();
517b5e16af9ea04cc1f94ca631104e5e6be96546aa1Anton Korobeynikov    virtual void EmitCantUnwind();
518b5e16af9ea04cc1f94ca631104e5e6be96546aa1Anton Korobeynikov    virtual void EmitPersonality(const MCSymbol *Personality);
519b5e16af9ea04cc1f94ca631104e5e6be96546aa1Anton Korobeynikov    virtual void EmitHandlerData();
52057caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov    virtual void EmitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset = 0);
52157caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov    virtual void EmitPad(int64_t Offset);
52257caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov    virtual void EmitRegSave(const SmallVectorImpl<unsigned> &RegList,
52357caad7a33ff145b71545f10dcfbbf2fd0f595d3Anton Korobeynikov                             bool isVector);
524b5e16af9ea04cc1f94ca631104e5e6be96546aa1Anton Korobeynikov
5254b1000d117f1b7cc5411bc251d141fe182a4ae1cDan Gohman    /// Finish - Finish emission of machine code.
526ba1da8a7b10b8a7df04f3ca47ca36ad18adad80eDaniel Dunbar    virtual void Finish() = 0;
52725e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar  };
52825e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar
529011e4db845b5c4166142338c77adc8ac03e5e041Daniel Dunbar  /// createNullStreamer - Create a dummy machine code streamer, which does
530011e4db845b5c4166142338c77adc8ac03e5e041Daniel Dunbar  /// nothing. This is useful for timing the assembler front end.
531011e4db845b5c4166142338c77adc8ac03e5e041Daniel Dunbar  MCStreamer *createNullStreamer(MCContext &Ctx);
532011e4db845b5c4166142338c77adc8ac03e5e041Daniel Dunbar
533381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar  /// createAsmStreamer - Create a machine code streamer which will print out
534381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar  /// assembly for the native target, suitable for compiling with a native
535381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar  /// assembler.
5369dee8e3009408fd08c656558397a8ac8604139baDaniel Dunbar  ///
5379dee8e3009408fd08c656558397a8ac8604139baDaniel Dunbar  /// \param InstPrint - If given, the instruction printer to use. If not given
5384c42a6de9f5456cc1b28f2d37db589f580f2adc7Chris Lattner  /// the MCInst representation will be printed.  This method takes ownership of
5394c42a6de9f5456cc1b28f2d37db589f580f2adc7Chris Lattner  /// InstPrint.
5409dee8e3009408fd08c656558397a8ac8604139baDaniel Dunbar  ///
5419dee8e3009408fd08c656558397a8ac8604139baDaniel Dunbar  /// \param CE - If given, a code emitter to use to show the instruction
5421abcd06856df324eac98d4bf5ba673fb77ae6a11Benjamin Kramer  /// encoding inline with the assembly. This method takes ownership of \arg CE.
5439dee8e3009408fd08c656558397a8ac8604139baDaniel Dunbar  ///
544745dacc91d7ee9531bfba76b21beb5d4eef93a7dDaniel Dunbar  /// \param TAB - If given, a target asm backend to use to show the fixup
545745dacc91d7ee9531bfba76b21beb5d4eef93a7dDaniel Dunbar  /// information in conjunction with encoding information. This method takes
546745dacc91d7ee9531bfba76b21beb5d4eef93a7dDaniel Dunbar  /// ownership of \arg TAB.
547745dacc91d7ee9531bfba76b21beb5d4eef93a7dDaniel Dunbar  ///
5489dee8e3009408fd08c656558397a8ac8604139baDaniel Dunbar  /// \param ShowInst - Whether to show the MCInst representation inline with
5499dee8e3009408fd08c656558397a8ac8604139baDaniel Dunbar  /// the assembly.
55086e2211d0a496f470ea1d320161c8dc43593c5c6Chris Lattner  MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS,
55189b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola                                bool isVerboseAsm,
55289b9372605db2ce3b0085c84089e389f7bc1fbddRafael Espindola                                bool useLoc,
553f1a5c7ec04002769f1638e64f7439589f0f926e6Rafael Espindola                                bool useCFI,
55490edac0e8b35f766599362b6301863229f0ddcdbChris Lattner                                MCInstPrinter *InstPrint = 0,
5559dee8e3009408fd08c656558397a8ac8604139baDaniel Dunbar                                MCCodeEmitter *CE = 0,
556745dacc91d7ee9531bfba76b21beb5d4eef93a7dDaniel Dunbar                                TargetAsmBackend *TAB = 0,
5575532cf44a012149ce3afce43dbd0651b4d87a505Daniel Dunbar                                bool ShowInst = false);
558381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar
559d86e6ac9892ee61742d85f9f14f1179216d2e47bDan Gohman  /// createMachOStreamer - Create a machine code streamer which will generate
560381e92c66a98ee766ea53039b0cd8ce3bde7be2dDaniel Dunbar  /// Mach-O format object files.
5611abcd06856df324eac98d4bf5ba673fb77ae6a11Benjamin Kramer  ///
5621abcd06856df324eac98d4bf5ba673fb77ae6a11Benjamin Kramer  /// Takes ownership of \arg TAB and \arg CE.
5631f3e445184e5ca2aa4295c2a77f2a4e0b957fea1Daniel Dunbar  MCStreamer *createMachOStreamer(MCContext &Ctx, TargetAsmBackend &TAB,
564ac2884a717daf3ad2aa8425320795d661e8a980bDaniel Dunbar                                  raw_ostream &OS, MCCodeEmitter *CE,
565ac2884a717daf3ad2aa8425320795d661e8a980bDaniel Dunbar                                  bool RelaxAll = false);
56625e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar
567eb72dcaef7423069cf8f9e802fa8de64dc8f8f30Chris Lattner  /// createWinCOFFStreamer - Create a machine code streamer which will
568eb72dcaef7423069cf8f9e802fa8de64dc8f8f30Chris Lattner  /// generate Microsoft COFF format object files.
5691abcd06856df324eac98d4bf5ba673fb77ae6a11Benjamin Kramer  ///
5701abcd06856df324eac98d4bf5ba673fb77ae6a11Benjamin Kramer  /// Takes ownership of \arg TAB and \arg CE.
571eb72dcaef7423069cf8f9e802fa8de64dc8f8f30Chris Lattner  MCStreamer *createWinCOFFStreamer(MCContext &Ctx,
572eb72dcaef7423069cf8f9e802fa8de64dc8f8f30Chris Lattner                                    TargetAsmBackend &TAB,
573e2195d8b357d7081edb5eb09d1d6e9d7b4bfc308Michael J. Spencer                                    MCCodeEmitter &CE, raw_ostream &OS,
574e2195d8b357d7081edb5eb09d1d6e9d7b4bfc308Michael J. Spencer                                    bool RelaxAll = false);
575eb72dcaef7423069cf8f9e802fa8de64dc8f8f30Chris Lattner
5766b2e257e74b2c8e2f93bb244e0c80cb73005b74aMatt Fleming  /// createELFStreamer - Create a machine code streamer which will generate
5776b2e257e74b2c8e2f93bb244e0c80cb73005b74aMatt Fleming  /// ELF format object files.
5786b2e257e74b2c8e2f93bb244e0c80cb73005b74aMatt Fleming  MCStreamer *createELFStreamer(MCContext &Ctx, TargetAsmBackend &TAB,
5796b2e257e74b2c8e2f93bb244e0c80cb73005b74aMatt Fleming				raw_ostream &OS, MCCodeEmitter *CE,
58096aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola				bool RelaxAll, bool NoExecStack);
5816b2e257e74b2c8e2f93bb244e0c80cb73005b74aMatt Fleming
582fdb5a8617996a20370756962e34c2e80176d6e87Daniel Dunbar  /// createLoggingStreamer - Create a machine code streamer which just logs the
583fdb5a8617996a20370756962e34c2e80176d6e87Daniel Dunbar  /// API calls and then dispatches to another streamer.
584fdb5a8617996a20370756962e34c2e80176d6e87Daniel Dunbar  ///
585fdb5a8617996a20370756962e34c2e80176d6e87Daniel Dunbar  /// The new streamer takes ownership of the \arg Child.
586fdb5a8617996a20370756962e34c2e80176d6e87Daniel Dunbar  MCStreamer *createLoggingStreamer(MCStreamer *Child, raw_ostream &OS);
587fdb5a8617996a20370756962e34c2e80176d6e87Daniel Dunbar
588abc756216dbace87826398f8fa1e8e57e401cc86Daniel Dunbar  /// createPureStreamer - Create a machine code streamer which will generate
589abc756216dbace87826398f8fa1e8e57e401cc86Daniel Dunbar  /// "pure" MC object files, for use with MC-JIT and testing tools.
590abc756216dbace87826398f8fa1e8e57e401cc86Daniel Dunbar  ///
591abc756216dbace87826398f8fa1e8e57e401cc86Daniel Dunbar  /// Takes ownership of \arg TAB and \arg CE.
592abc756216dbace87826398f8fa1e8e57e401cc86Daniel Dunbar  MCStreamer *createPureStreamer(MCContext &Ctx, TargetAsmBackend &TAB,
593abc756216dbace87826398f8fa1e8e57e401cc86Daniel Dunbar                                 raw_ostream &OS, MCCodeEmitter *CE);
594abc756216dbace87826398f8fa1e8e57e401cc86Daniel Dunbar
59525e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar} // end namespace llvm
59625e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar
59725e0d8f755736b0a17400adbdd367aee89fbecfcDaniel Dunbar#endif
598