//===- MCAssembler.h - Object File Generation -------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_MC_MCASSEMBLER_H
#define LLVM_MC_MCASSEMBLER_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.
namespace llvm {
class raw_ostream;
class MCAsmLayout;
class MCAssembler;
class MCContext;
class MCCodeEmitter;
class MCExpr;
class MCFragment;
class MCObjectWriter;
class MCSection;
class MCSectionData;
class MCSymbol;
class MCSymbolData;
class MCValue;
class MCAsmBackend;
class MCFragment : public ilist_node<MCFragment> {
friend class MCAsmLayout;
MCFragment(const MCFragment&) LLVM_DELETED_FUNCTION;
void operator=(const MCFragment&) LLVM_DELETED_FUNCTION;
public:
enum FragmentType {
FT_Align,
FT_Data,
FT_CompactEncodedInst,
FT_Fill,
FT_Relaxable,
FT_Org,
FT_Dwarf,
FT_DwarfFrame,
FT_LEB
};
private:
FragmentType Kind;
/// Parent - The data for the section this fragment is in.
MCSectionData *Parent;
/// Atom - The atom this fragment is in, as represented by it's defining
/// symbol. Atom's are only used by backends which set
/// \see MCAsmBackend::hasReliableSymbolDifference().
MCSymbolData *Atom;
/// @name Assembler Backend Data
/// @{
//
// FIXME: This could all be kept private to the assembler implementation.
/// Offset - The offset of this fragment in its section. This is ~0 until
/// initialized.
uint64_t Offset;
/// LayoutOrder - The layout order of this fragment.
unsigned LayoutOrder;
/// @}
protected:
MCFragment(FragmentType _Kind, MCSectionData *_Parent = 0);
public:
// Only for sentinel.
MCFragment();
virtual ~MCFragment();
FragmentType getKind() const { return Kind; }
MCSectionData *getParent() const { return Parent; }
void setParent(MCSectionData *Value) { Parent = Value; }
MCSymbolData *getAtom() const { return Atom; }
void setAtom(MCSymbolData *Value) { Atom = Value; }
unsigned getLayoutOrder() const { return LayoutOrder; }
void setLayoutOrder(unsigned Value) { LayoutOrder = 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; }
/// \brief Should this fragment be placed at the end of an aligned bundle?
virtual bool alignToBundleEnd() const { return false; }
virtual void setAlignToBundleEnd(bool V) { }
/// \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();
};
/// Interface implemented by fragments that contain encoded instructions and/or
/// data.
///
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();
virtual