diff options
Diffstat (limited to 'include/llvm/MC')
-rw-r--r-- | include/llvm/MC/MCContext.h | 166 | ||||
-rw-r--r-- | include/llvm/MC/MCInst.h | 6 | ||||
-rw-r--r-- | include/llvm/MC/MCSection.h | 28 | ||||
-rw-r--r-- | include/llvm/MC/MCStreamer.h | 191 | ||||
-rw-r--r-- | include/llvm/MC/MCSymbol.h | 33 | ||||
-rw-r--r-- | include/llvm/MC/MCValue.h (renamed from include/llvm/MC/MCImm.h) | 29 |
6 files changed, 437 insertions, 16 deletions
diff --git a/include/llvm/MC/MCContext.h b/include/llvm/MC/MCContext.h new file mode 100644 index 0000000..13180e8 --- /dev/null +++ b/include/llvm/MC/MCContext.h @@ -0,0 +1,166 @@ +//===- MCContext.h - Machine Code Context -----------------------*- 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_MCCONTEXT_H +#define LLVM_MC_MCCONTEXT_H + +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/Support/Allocator.h" + +namespace llvm { + class MCValue; + class MCSection; + class MCSymbol; + + /// MCContext - Context object for machine code objects. + class MCContext { + MCContext(const MCContext&); // DO NOT IMPLEMENT + MCContext &operator=(const MCContext&); // DO NOT IMPLEMENT + + /// Sections - Bindings of names to allocated sections. + StringMap<MCSection*> Sections; + + /// Symbols - Bindings of names to symbols. + StringMap<MCSymbol*> Symbols; + + /// SymbolValues - Bindings of symbols to values. + DenseMap<MCSymbol*, MCValue> SymbolValues; + + /// Allocator - Allocator object used for creating machine code objects. + /// + /// We use a bump pointer allocator to avoid the need to track all allocated + /// objects. + BumpPtrAllocator Allocator; + + public: + MCContext(); + ~MCContext(); + + /// GetSection - Get or create a new section with the given @param Name. + MCSection *GetSection(const char *Name); + + /// CreateSymbol - Create a new symbol with the specified @param Name. + /// + /// @param Name - The symbol name, which must be unique across all symbols. + MCSymbol *CreateSymbol(const char *Name); + + /// GetOrCreateSymbol - Lookup the symbol inside with the specified + /// @param Name. If it exists, return it. If not, create a forward + /// reference and return it. + /// + /// @param Name - The symbol name, which must be unique across all symbols. + MCSymbol *GetOrCreateSymbol(const char *Name); + + /// CreateTemporarySymbol - Create a new temporary symbol with the specified + /// @param Name. + /// + /// @param Name - The symbol name, for debugging purposes only, temporary + /// symbols do not surive assembly. If non-empty the name must be unique + /// across all symbols. + MCSymbol *CreateTemporarySymbol(const char *Name = ""); + + /// LookupSymbol - Get the symbol for @param Name, or null. + MCSymbol *LookupSymbol(const char *Name) const; + + /// ClearSymbolValue - Erase a value binding for @param Symbol, if one + /// exists. + void ClearSymbolValue(MCSymbol *Symbol); + + /// SetSymbolValue - Set the value binding for @param Symbol to @param + /// Value. + void SetSymbolValue(MCSymbol *Symbol, const MCValue &Value); + + /// GetSymbolValue - Return the current value for @param Symbol, or null if + /// none exists. + const MCValue *GetSymbolValue(MCSymbol *Symbol) const; + + void *Allocate(unsigned Size, unsigned Align = 8) { + return Allocator.Allocate(Size, Align); + } + void Deallocate(void *Ptr) { + } + }; + +} // end namespace llvm + +// operator new and delete aren't allowed inside namespaces. +// The throw specifications are mandated by the standard. +/// @brief Placement new for using the MCContext's allocator. +/// +/// This placement form of operator new uses the MCContext's allocator for +/// obtaining memory. It is a non-throwing new, which means that it returns +/// null on error. (If that is what the allocator does. The current does, so if +/// this ever changes, this operator will have to be changed, too.) +/// Usage looks like this (assuming there's an MCContext 'Context' in scope): +/// @code +/// // Default alignment (16) +/// IntegerLiteral *Ex = new (Context) IntegerLiteral(arguments); +/// // Specific alignment +/// IntegerLiteral *Ex2 = new (Context, 8) IntegerLiteral(arguments); +/// @endcode +/// Please note that you cannot use delete on the pointer; it must be +/// deallocated using an explicit destructor call followed by +/// @c Context.Deallocate(Ptr). +/// +/// @param Bytes The number of bytes to allocate. Calculated by the compiler. +/// @param C The MCContext that provides the allocator. +/// @param Alignment The alignment of the allocated memory (if the underlying +/// allocator supports it). +/// @return The allocated memory. Could be NULL. +inline void *operator new(size_t Bytes, llvm::MCContext &C, + size_t Alignment = 16) throw () { + return C.Allocate(Bytes, Alignment); +} +/// @brief Placement delete companion to the new above. +/// +/// This operator is just a companion to the new above. There is no way of +/// invoking it directly; see the new operator for more details. This operator +/// is called implicitly by the compiler if a placement new expression using +/// the MCContext throws in the object constructor. +inline void operator delete(void *Ptr, llvm::MCContext &C, size_t) + throw () { + C.Deallocate(Ptr); +} + +/// This placement form of operator new[] uses the MCContext's allocator for +/// obtaining memory. It is a non-throwing new[], which means that it returns +/// null on error. +/// Usage looks like this (assuming there's an MCContext 'Context' in scope): +/// @code +/// // Default alignment (16) +/// char *data = new (Context) char[10]; +/// // Specific alignment +/// char *data = new (Context, 8) char[10]; +/// @endcode +/// Please note that you cannot use delete on the pointer; it must be +/// deallocated using an explicit destructor call followed by +/// @c Context.Deallocate(Ptr). +/// +/// @param Bytes The number of bytes to allocate. Calculated by the compiler. +/// @param C The MCContext that provides the allocator. +/// @param Alignment The alignment of the allocated memory (if the underlying +/// allocator supports it). +/// @return The allocated memory. Could be NULL. +inline void *operator new[](size_t Bytes, llvm::MCContext& C, + size_t Alignment = 16) throw () { + return C.Allocate(Bytes, Alignment); +} + +/// @brief Placement delete[] companion to the new[] above. +/// +/// This operator is just a companion to the new[] above. There is no way of +/// invoking it directly; see the new[] operator for more details. This operator +/// is called implicitly by the compiler if a placement new[] expression using +/// the MCContext throws in the object constructor. +inline void operator delete[](void *Ptr, llvm::MCContext &C) throw () { + C.Deallocate(Ptr); +} + +#endif diff --git a/include/llvm/MC/MCInst.h b/include/llvm/MC/MCInst.h index 457c2ae..3108985 100644 --- a/include/llvm/MC/MCInst.h +++ b/include/llvm/MC/MCInst.h @@ -16,7 +16,7 @@ #ifndef LLVM_MC_MCINST_H #define LLVM_MC_MCINST_H -#include "llvm/MC/MCImm.h" +#include "llvm/MC/MCValue.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Support/DataTypes.h" #include "llvm/Support/DebugLoc.h" @@ -31,14 +31,14 @@ class MCOperand { kRegister, ///< Register operand. kImmediate, ///< Immediate operand. kMBBLabel, ///< Basic block label. - kMCImm + kMCValue }; unsigned char Kind; union { unsigned RegVal; int64_t ImmVal; - MCImm MCImmVal; + MCValue MCValueVal; struct { unsigned FunctionNo; unsigned BlockNo; diff --git a/include/llvm/MC/MCSection.h b/include/llvm/MC/MCSection.h new file mode 100644 index 0000000..341f7f0 --- /dev/null +++ b/include/llvm/MC/MCSection.h @@ -0,0 +1,28 @@ +//===- MCSection.h - Machine Code Sections ----------------------*- 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_MCSECTION_H +#define LLVM_MC_MCSECTION_H + +#include <string> + +namespace llvm { + + class MCSection { + std::string Name; + + public: + MCSection(const char *_Name) : Name(_Name) {} + + const std::string &getName() const { return Name; } + }; + +} // end namespace llvm + +#endif diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h new file mode 100644 index 0000000..bb85d2d --- /dev/null +++ b/include/llvm/MC/MCStreamer.h @@ -0,0 +1,191 @@ +//===- MCStreamer.h - High-level Streaming Machine Code Output --*- 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_MCSTREAMER_H +#define LLVM_MC_MCSTREAMER_H + +#include "llvm/Support/DataTypes.h" + +namespace llvm { + class MCContext; + class MCValue; + class MCInst; + class MCSection; + class MCSymbol; + class raw_ostream; + + /// MCStreamer - Streaming machine code generation interface. + class MCStreamer { + public: + enum SymbolAttr { + Global, /// .globl + Hidden, /// .hidden (ELF) + IndirectSymbol, /// .indirect_symbol (Apple) + Internal, /// .internal (ELF) + LazyReference, /// .lazy_reference (Apple) + NoDeadStrip, /// .no_dead_strip (Apple) + PrivateExtern, /// .private_extern (Apple) + Protected, /// .protected (ELF) + Reference, /// .reference (Apple) + Weak, /// .weak + WeakDefinition, /// .weak_definition (Apple) + WeakReference, /// .weak_reference (Apple) + + SymbolAttrFirst = Global, + SymbolAttrLast = WeakReference + }; + + private: + MCContext &Context; + + MCStreamer(const MCStreamer&); // DO NOT IMPLEMENT + MCStreamer &operator=(const MCStreamer&); // DO NOT IMPLEMENT + + protected: + MCStreamer(MCContext &Ctx); + + public: + virtual ~MCStreamer(); + + MCContext &getContext() const { return Context; } + + /// @name Symbol & Section Management + /// @{ + + /// SwitchSection - Set the current section where code is being emitted to + /// @param Section. + /// + /// This corresponds to assembler directives like .section, .text, etc. + virtual void SwitchSection(MCSection *Section) = 0; + + /// EmitLabel - Emit a label for @param Symbol into the current section. + /// + /// This corresponds to an assembler statement such as: + /// foo: + /// + /// @param Symbol - The symbol to emit. A given symbol should only be + /// emitted as a label once, and symbols emitted as a label should never be + /// used in an assignment. + // + // FIXME: What to do about the current section? Should we get rid of the + // symbol section in the constructor and initialize it here? + virtual void EmitLabel(MCSymbol *Symbol) = 0; + + /// EmitAssignment - Emit an assignment of @param Value to @param Symbol. + /// + /// This corresponds to an assembler statement such as: + /// symbol = value + /// + /// The assignment generates no code, but has the side effect of binding the + /// value in the current context. For the assembly streamer, this prints the + /// binding into the .s file. + /// + /// @param Symbol - The symbol being assigned to. + /// @param Value - The value for the symbol. + /// @param MakeAbsolute - If true, then the symbol should be given the + /// absolute value of @param Value, even if @param Value would be + /// relocatable expression. This corresponds to the ".set" directive. + virtual void EmitAssignment(MCSymbol *Symbol, const MCValue &Value, + bool MakeAbsolute = false) = 0; + + /// EmitSymbolAttribute - Add the given @param Attribute to @param Symbol. + // + // FIXME: This doesn't make much sense, could we just have attributes be on + // the symbol and make the printer smart enough to add the right symbols? + // This should work as long as the order of attributes in the file doesn't + // matter. + virtual void EmitSymbolAttribute(MCSymbol *Symbol, + SymbolAttr Attribute) = 0; + + /// @} + /// @name Generating Data + /// @{ + + /// EmitBytes - Emit @param Length bytes starting at @param Data into the + /// output. + /// + /// This is used to implement assembler directives such as .byte, .ascii, + /// etc. + virtual void EmitBytes(const char *Data, unsigned Length) = 0; + + /// EmitValue - Emit the expression @param Value into the output as a native + /// integer of the given @param Size bytes. + /// + /// This is used to implement assembler directives such as .word, .quad, + /// etc. + /// + /// @param Value - The value to emit. + /// @param Size - The size of the integer (in bytes) to emit. This must + /// match a native machine width. + virtual void EmitValue(const MCValue &Value, unsigned Size) = 0; + + /// EmitValueToAlignment - Emit some number of copies of @param Value until + /// the byte alignment @param ByteAlignment is reached. + /// + /// If the number of bytes need to emit for the alignment is not a multiple + /// of @param ValueSize, then the contents of the emitted fill bytes is + /// undefined. + /// + /// This used to implement the .align assembler directive. + /// + /// @param ByteAlignment - The alignment to reach. This must be a power of + /// two. + /// @param Value - The value to use when filling bytes. + /// @param Size - The size of the integer (in bytes) to emit for @param + /// Value. This must match a native machine width. + /// @param MaxBytesToEmit - The maximum numbers of bytes to emit, or 0. If + /// the alignment cannot be reached in this many bytes, no bytes are + /// emitted. + virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0, + unsigned ValueSize = 1, + unsigned MaxBytesToEmit = 0) = 0; + + /// EmitValueToOffset - Emit some number of copies of @param Value until the + /// byte offset @param Offset is reached. + /// + /// This is used to implement assembler directives such as .org. + /// + /// @param Offset - The offset to reach.This may be an expression, but the + /// expression must be associated with the current section. + /// @param Value - The value to use when filling bytes. + // + // FIXME: How are we going to signal failures out of this? + virtual void EmitValueToOffset(const MCValue &Offset, + unsigned char Value = 0) = 0; + + /// @} + + /// EmitInstruction - Emit the given @param Instruction into the current + /// section. + virtual void EmitInstruction(const MCInst &Inst) = 0; + + /// Finish - Finish emission of machine code and flush any output. + virtual void Finish() = 0; + }; + + /// createAsmStreamer - Create a machine code streamer which will print out + /// assembly for the native target, suitable for compiling with a native + /// assembler. + MCStreamer *createAsmStreamer(MCContext &Ctx, raw_ostream &OS); + + // FIXME: These two may end up getting rolled into a single + // createObjectStreamer interface, which implements the assembler backend, and + // is parameterized on an output object file writer. + + /// createMachOStream - Create a machine code streamer which will generative + /// Mach-O format object files. + MCStreamer *createMachOStreamer(MCContext &Ctx, raw_ostream &OS); + + /// createELFStreamer - Create a machine code streamer which will generative + /// ELF format object files. + MCStreamer *createELFStreamer(MCContext &Ctx, raw_ostream &OS); + +} // end namespace llvm + +#endif diff --git a/include/llvm/MC/MCSymbol.h b/include/llvm/MC/MCSymbol.h new file mode 100644 index 0000000..06f50ae --- /dev/null +++ b/include/llvm/MC/MCSymbol.h @@ -0,0 +1,33 @@ +//===- MCSymbol.h - Machine Code Symbols ------------------------*- 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_MCSYMBOL_H +#define LLVM_MC_MCSYMBOL_H + +#include <string> + +namespace llvm { + class MCSymbol { + MCSection *Section; + std::string Name; + unsigned IsTemporary : 1; + + public: + MCSymbol(const char *_Name, bool _IsTemporary) + : Section(0), Name(_Name), IsTemporary(_IsTemporary) {} + + MCSection *getSection() const { return Section; } + void setSection(MCSection *Value) { Section = Value; } + + const std::string &getName() const { return Name; } + }; + +} // end namespace llvm + +#endif diff --git a/include/llvm/MC/MCImm.h b/include/llvm/MC/MCValue.h index 5b1efd8..7df12da 100644 --- a/include/llvm/MC/MCImm.h +++ b/include/llvm/MC/MCValue.h @@ -1,4 +1,4 @@ -//===-- llvm/MC/MCImm.h - MCImm class ---------------------------*- C++ -*-===// +//===-- llvm/MC/MCValue.h - MCValue class -----------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,22 +7,25 @@ // //===----------------------------------------------------------------------===// // -// This file contains the declaration of the MCInst and MCOperand classes, which -// is the basic representation used to represent low-level machine code -// instructions. +// This file contains the declaration of the MCValue class. // //===----------------------------------------------------------------------===// -#ifndef LLVM_MC_MCIMM_H -#define LLVM_MC_MCIMM_H +#ifndef LLVM_MC_MCVALUE_H +#define LLVM_MC_MCVALUE_H + +#include "llvm/Support/DataTypes.h" namespace llvm { class MCSymbol; -/// MCImm - This represents an "assembler immediate". In its most general form, -/// this can hold "SymbolA - SymbolB + imm64". Not all targets supports +/// MCValue - This represents an "assembler immediate". In its most general +/// form, this can hold "SymbolA - SymbolB + imm64". Not all targets supports /// relocations of this general form, but we need to represent this anyway. -class MCImm { +/// +/// Note that this class must remain a simple POD value class, because we need +/// it to live in unions etc. +class MCValue { MCSymbol *SymA, *SymB; int64_t Cst; public: @@ -32,16 +35,16 @@ public: MCSymbol *getSymB() const { return SymB; } - static MCImm get(MCSymbol *SymA, MCSymbol *SymB = 0, int64_t Val = 0) { - MCImm R; + static MCValue get(MCSymbol *SymA, MCSymbol *SymB = 0, int64_t Val = 0) { + MCValue R; R.Cst = Val; R.SymA = SymA; R.SymB = SymB; return R; } - static MCImm get(int64_t Val) { - MCImm R; + static MCValue get(int64_t Val) { + MCValue R; R.Cst = Val; R.SymA = 0; R.SymB = 0; |