[ms-inline asm] Remove the MatchInstruction() function. Previously, this was
[oota-llvm.git] / include / llvm / MC / MCObjectWriter.h
1 //===-- llvm/MC/MCObjectWriter.h - Object File Writer Interface -*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #ifndef LLVM_MC_MCOBJECTWRITER_H
11 #define LLVM_MC_MCOBJECTWRITER_H
12
13 #include "llvm/Support/raw_ostream.h"
14 #include "llvm/Support/Compiler.h"
15 #include "llvm/Support/DataTypes.h"
16 #include <cassert>
17
18 namespace llvm {
19 class MCAsmLayout;
20 class MCAssembler;
21 class MCFixup;
22 class MCFragment;
23 class MCSymbolData;
24 class MCSymbolRefExpr;
25 class MCValue;
26
27 /// MCObjectWriter - Defines the object file and target independent interfaces
28 /// used by the assembler backend to write native file format object files.
29 ///
30 /// The object writer contains a few callbacks used by the assembler to allow
31 /// the object writer to modify the assembler data structures at appropriate
32 /// points. Once assembly is complete, the object writer is given the
33 /// MCAssembler instance, which contains all the symbol and section data which
34 /// should be emitted as part of WriteObject().
35 ///
36 /// The object writer also contains a number of helper methods for writing
37 /// binary data to the output stream.
38 class MCObjectWriter {
39   MCObjectWriter(const MCObjectWriter &) LLVM_DELETED_FUNCTION;
40   void operator=(const MCObjectWriter &) LLVM_DELETED_FUNCTION;
41
42 protected:
43   raw_ostream &OS;
44
45   unsigned IsLittleEndian : 1;
46
47 protected: // Can only create subclasses.
48   MCObjectWriter(raw_ostream &_OS, bool _IsLittleEndian)
49     : OS(_OS), IsLittleEndian(_IsLittleEndian) {}
50
51 public:
52   virtual ~MCObjectWriter();
53
54   bool isLittleEndian() const { return IsLittleEndian; }
55
56   raw_ostream &getStream() { return OS; }
57
58   /// @name High-Level API
59   /// @{
60
61   /// Perform any late binding of symbols (for example, to assign symbol indices
62   /// for use when generating relocations).
63   ///
64   /// This routine is called by the assembler after layout and relaxation is
65   /// complete.
66   virtual void ExecutePostLayoutBinding(MCAssembler &Asm,
67                                         const MCAsmLayout &Layout) = 0;
68
69   /// Record a relocation entry.
70   ///
71   /// This routine is called by the assembler after layout and relaxation, and
72   /// post layout binding. The implementation is responsible for storing
73   /// information about the relocation so that it can be emitted during
74   /// WriteObject().
75   virtual void RecordRelocation(const MCAssembler &Asm,
76                                 const MCAsmLayout &Layout,
77                                 const MCFragment *Fragment,
78                                 const MCFixup &Fixup, MCValue Target,
79                                 uint64_t &FixedValue) = 0;
80
81   /// \brief Check whether the difference (A - B) between two symbol
82   /// references is fully resolved.
83   ///
84   /// Clients are not required to answer precisely and may conservatively return
85   /// false, even when a difference is fully resolved.
86   bool
87   IsSymbolRefDifferenceFullyResolved(const MCAssembler &Asm,
88                                      const MCSymbolRefExpr *A,
89                                      const MCSymbolRefExpr *B,
90                                      bool InSet) const;
91
92   virtual bool
93   IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
94                                          const MCSymbolData &DataA,
95                                          const MCFragment &FB,
96                                          bool InSet,
97                                          bool IsPCRel) const;
98
99
100   /// Write the object file.
101   ///
102   /// This routine is called by the assembler after layout and relaxation is
103   /// complete, fixups have been evaluated and applied, and relocations
104   /// generated.
105   virtual void WriteObject(MCAssembler &Asm,
106                            const MCAsmLayout &Layout) = 0;
107
108   /// @}
109   /// @name Binary Output
110   /// @{
111
112   void Write8(uint8_t Value) {
113     OS << char(Value);
114   }
115
116   void WriteLE16(uint16_t Value) {
117     Write8(uint8_t(Value >> 0));
118     Write8(uint8_t(Value >> 8));
119   }
120
121   void WriteLE32(uint32_t Value) {
122     WriteLE16(uint16_t(Value >> 0));
123     WriteLE16(uint16_t(Value >> 16));
124   }
125
126   void WriteLE64(uint64_t Value) {
127     WriteLE32(uint32_t(Value >> 0));
128     WriteLE32(uint32_t(Value >> 32));
129   }
130
131   void WriteBE16(uint16_t Value) {
132     Write8(uint8_t(Value >> 8));
133     Write8(uint8_t(Value >> 0));
134   }
135
136   void WriteBE32(uint32_t Value) {
137     WriteBE16(uint16_t(Value >> 16));
138     WriteBE16(uint16_t(Value >> 0));
139   }
140
141   void WriteBE64(uint64_t Value) {
142     WriteBE32(uint32_t(Value >> 32));
143     WriteBE32(uint32_t(Value >> 0));
144   }
145
146   void Write16(uint16_t Value) {
147     if (IsLittleEndian)
148       WriteLE16(Value);
149     else
150       WriteBE16(Value);
151   }
152
153   void Write32(uint32_t Value) {
154     if (IsLittleEndian)
155       WriteLE32(Value);
156     else
157       WriteBE32(Value);
158   }
159
160   void Write64(uint64_t Value) {
161     if (IsLittleEndian)
162       WriteLE64(Value);
163     else
164       WriteBE64(Value);
165   }
166
167   void WriteZeros(unsigned N) {
168     const char Zeros[16] = { 0 };
169
170     for (unsigned i = 0, e = N / 16; i != e; ++i)
171       OS << StringRef(Zeros, 16);
172
173     OS << StringRef(Zeros, N % 16);
174   }
175
176   void WriteBytes(StringRef Str, unsigned ZeroFillSize = 0) {
177     assert((ZeroFillSize == 0 || Str.size () <= ZeroFillSize) &&
178       "data size greater than fill size, unexpected large write will occur");
179     OS << Str;
180     if (ZeroFillSize)
181       WriteZeros(ZeroFillSize - Str.size());
182   }
183
184   /// @}
185
186 };
187
188 } // End llvm namespace
189
190 #endif