mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-10-31 08:16:47 +00:00 
			
		
		
		
	I have some uncommitted changes to the cast code that catch this sort of thing at compile-time but I still need to do some other cleanup before I can enable it. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@174853 91177308-0d34-0410-b5e6-96231b3b80d8
		
			
				
	
	
		
			200 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			200 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| //===-- llvm/MC/MCObjectWriter.h - Object File Writer Interface -*- 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_MCOBJECTWRITER_H
 | |
| #define LLVM_MC_MCOBJECTWRITER_H
 | |
| 
 | |
| #include "llvm/ADT/SmallVector.h"
 | |
| #include "llvm/Support/Compiler.h"
 | |
| #include "llvm/Support/DataTypes.h"
 | |
| #include "llvm/Support/raw_ostream.h"
 | |
| #include <cassert>
 | |
| 
 | |
| namespace llvm {
 | |
| class MCAsmLayout;
 | |
| class MCAssembler;
 | |
| class MCFixup;
 | |
| class MCFragment;
 | |
| class MCSymbolData;
 | |
| class MCSymbolRefExpr;
 | |
| class MCValue;
 | |
| 
 | |
| /// MCObjectWriter - Defines the object file and target independent interfaces
 | |
| /// used by the assembler backend to write native file format object files.
 | |
| ///
 | |
| /// The object writer contains a few callbacks used by the assembler to allow
 | |
| /// the object writer to modify the assembler data structures at appropriate
 | |
| /// points. Once assembly is complete, the object writer is given the
 | |
| /// MCAssembler instance, which contains all the symbol and section data which
 | |
| /// should be emitted as part of WriteObject().
 | |
| ///
 | |
| /// The object writer also contains a number of helper methods for writing
 | |
| /// binary data to the output stream.
 | |
| class MCObjectWriter {
 | |
|   MCObjectWriter(const MCObjectWriter &) LLVM_DELETED_FUNCTION;
 | |
|   void operator=(const MCObjectWriter &) LLVM_DELETED_FUNCTION;
 | |
| 
 | |
| protected:
 | |
|   raw_ostream &OS;
 | |
| 
 | |
|   unsigned IsLittleEndian : 1;
 | |
| 
 | |
| protected: // Can only create subclasses.
 | |
|   MCObjectWriter(raw_ostream &_OS, bool _IsLittleEndian)
 | |
|     : OS(_OS), IsLittleEndian(_IsLittleEndian) {}
 | |
| 
 | |
| public:
 | |
|   virtual ~MCObjectWriter();
 | |
| 
 | |
|   /// lifetime management
 | |
|   virtual void reset() { }
 | |
| 
 | |
|   bool isLittleEndian() const { return IsLittleEndian; }
 | |
| 
 | |
|   raw_ostream &getStream() { return OS; }
 | |
| 
 | |
|   /// @name High-Level API
 | |
|   /// @{
 | |
| 
 | |
|   /// \brief Perform any late binding of symbols (for example, to assign symbol
 | |
|   /// indices for use when generating relocations).
 | |
|   ///
 | |
|   /// This routine is called by the assembler after layout and relaxation is
 | |
|   /// complete.
 | |
|   virtual void ExecutePostLayoutBinding(MCAssembler &Asm,
 | |
|                                         const MCAsmLayout &Layout) = 0;
 | |
| 
 | |
|   /// \brief Record a relocation entry.
 | |
|   ///
 | |
|   /// This routine is called by the assembler after layout and relaxation, and
 | |
|   /// post layout binding. The implementation is responsible for storing
 | |
|   /// information about the relocation so that it can be emitted during
 | |
|   /// WriteObject().
 | |
|   virtual void RecordRelocation(const MCAssembler &Asm,
 | |
|                                 const MCAsmLayout &Layout,
 | |
|                                 const MCFragment *Fragment,
 | |
|                                 const MCFixup &Fixup, MCValue Target,
 | |
|                                 uint64_t &FixedValue) = 0;
 | |
| 
 | |
|   /// \brief Check whether the difference (A - B) between two symbol
 | |
|   /// references is fully resolved.
 | |
|   ///
 | |
|   /// Clients are not required to answer precisely and may conservatively return
 | |
|   /// false, even when a difference is fully resolved.
 | |
|   bool
 | |
|   IsSymbolRefDifferenceFullyResolved(const MCAssembler &Asm,
 | |
|                                      const MCSymbolRefExpr *A,
 | |
|                                      const MCSymbolRefExpr *B,
 | |
|                                      bool InSet) const;
 | |
| 
 | |
|   virtual bool
 | |
|   IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
 | |
|                                          const MCSymbolData &DataA,
 | |
|                                          const MCFragment &FB,
 | |
|                                          bool InSet,
 | |
|                                          bool IsPCRel) const;
 | |
| 
 | |
|   /// \brief Write the object file.
 | |
|   ///
 | |
|   /// This routine is called by the assembler after layout and relaxation is
 | |
|   /// complete, fixups have been evaluated and applied, and relocations
 | |
|   /// generated.
 | |
|   virtual void WriteObject(MCAssembler &Asm,
 | |
|                            const MCAsmLayout &Layout) = 0;
 | |
| 
 | |
|   /// @}
 | |
|   /// @name Binary Output
 | |
|   /// @{
 | |
| 
 | |
|   void Write8(uint8_t Value) {
 | |
|     OS << char(Value);
 | |
|   }
 | |
| 
 | |
|   void WriteLE16(uint16_t Value) {
 | |
|     Write8(uint8_t(Value >> 0));
 | |
|     Write8(uint8_t(Value >> 8));
 | |
|   }
 | |
| 
 | |
|   void WriteLE32(uint32_t Value) {
 | |
|     WriteLE16(uint16_t(Value >> 0));
 | |
|     WriteLE16(uint16_t(Value >> 16));
 | |
|   }
 | |
| 
 | |
|   void WriteLE64(uint64_t Value) {
 | |
|     WriteLE32(uint32_t(Value >> 0));
 | |
|     WriteLE32(uint32_t(Value >> 32));
 | |
|   }
 | |
| 
 | |
|   void WriteBE16(uint16_t Value) {
 | |
|     Write8(uint8_t(Value >> 8));
 | |
|     Write8(uint8_t(Value >> 0));
 | |
|   }
 | |
| 
 | |
|   void WriteBE32(uint32_t Value) {
 | |
|     WriteBE16(uint16_t(Value >> 16));
 | |
|     WriteBE16(uint16_t(Value >> 0));
 | |
|   }
 | |
| 
 | |
|   void WriteBE64(uint64_t Value) {
 | |
|     WriteBE32(uint32_t(Value >> 32));
 | |
|     WriteBE32(uint32_t(Value >> 0));
 | |
|   }
 | |
| 
 | |
|   void Write16(uint16_t Value) {
 | |
|     if (IsLittleEndian)
 | |
|       WriteLE16(Value);
 | |
|     else
 | |
|       WriteBE16(Value);
 | |
|   }
 | |
| 
 | |
|   void Write32(uint32_t Value) {
 | |
|     if (IsLittleEndian)
 | |
|       WriteLE32(Value);
 | |
|     else
 | |
|       WriteBE32(Value);
 | |
|   }
 | |
| 
 | |
|   void Write64(uint64_t Value) {
 | |
|     if (IsLittleEndian)
 | |
|       WriteLE64(Value);
 | |
|     else
 | |
|       WriteBE64(Value);
 | |
|   }
 | |
| 
 | |
|   void WriteZeros(unsigned N) {
 | |
|     const char Zeros[16] = { 0 };
 | |
| 
 | |
|     for (unsigned i = 0, e = N / 16; i != e; ++i)
 | |
|       OS << StringRef(Zeros, 16);
 | |
| 
 | |
|     OS << StringRef(Zeros, N % 16);
 | |
|   }
 | |
| 
 | |
|   void WriteBytes(const SmallVectorImpl<char> &ByteVec, unsigned ZeroFillSize = 0) {
 | |
|     WriteBytes(StringRef(ByteVec.data(), ByteVec.size()), ZeroFillSize);
 | |
|   }
 | |
| 
 | |
|   void WriteBytes(StringRef Str, unsigned ZeroFillSize = 0) {
 | |
|     // TODO: this version may need to go away once all fragment contents are
 | |
|     // converted to SmallVector<char, N>
 | |
|     assert((ZeroFillSize == 0 || Str.size () <= ZeroFillSize) &&
 | |
|       "data size greater than fill size, unexpected large write will occur");
 | |
|     OS << Str;
 | |
|     if (ZeroFillSize)
 | |
|       WriteZeros(ZeroFillSize - Str.size());
 | |
|   }
 | |
| 
 | |
|   /// @}
 | |
| 
 | |
| };
 | |
| 
 | |
| } // End llvm namespace
 | |
| 
 | |
| #endif
 |