4b66fe85678cb85395cb84a76903d544075cfd70
[oota-llvm.git] / include / llvm / CodeGen / BinaryObject.h
1 //===-- llvm/CodeGen/BinaryObject.h - Binary Object. -----------*- 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 // This file defines a Binary Object Aka. "blob" for holding data from code
11 // generators, ready for data to the object module code writters.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #ifndef LLVM_CODEGEN_BINARYOBJECT_H
16 #define LLVM_CODEGEN_BINARYOBJECT_H
17
18 #include <string>
19 #include <vector>
20
21 namespace llvm {
22
23 class MachineRelocation;
24 typedef std::vector<uint8_t> BinaryData;
25
26 class BinaryObject {
27 protected:
28   std::string Name;
29   bool IsLittleEndian;
30   bool Is64Bit;
31   BinaryData Data;
32   std::vector<MachineRelocation> Relocations;
33
34 public:
35   /// Constructors and destructor
36   BinaryObject() {}
37
38   BinaryObject(bool isLittleEndian, bool is64Bit)
39     : IsLittleEndian(isLittleEndian), Is64Bit(is64Bit) {}
40
41   BinaryObject(const std::string &name, bool isLittleEndian, bool is64Bit)
42     : Name(name), IsLittleEndian(isLittleEndian), Is64Bit(is64Bit) {}
43
44   ~BinaryObject() {}
45
46   /// getName - get name of BinaryObject
47   inline std::string getName() const { return Name; }
48
49   /// get size of binary data
50   size_t size() const {
51     return Data.size();
52   }
53
54   /// get binary data
55   BinaryData& getData() {
56     return Data;
57   }
58
59   /// get machine relocations
60   const std::vector<MachineRelocation>& getRelocations() const {
61     return Relocations;
62   }
63
64   /// hasRelocations - Return true if 'Relocations' is not empty
65   bool hasRelocations() const {
66     return !Relocations.empty();
67   }
68
69   /// emitByte - This callback is invoked when a byte needs to be
70   /// written to the data stream.
71   inline void emitByte(uint8_t B) {
72     Data.push_back(B);
73   }
74
75   /// emitWord16 - This callback is invoked when a 16-bit word needs to be
76   /// written to the data stream in correct endian format and correct size.
77   inline void emitWord16(uint16_t W) {
78     if (IsLittleEndian)
79       emitWord16LE(W);
80     else
81       emitWord16BE(W);
82   }
83
84   /// emitWord16LE - This callback is invoked when a 16-bit word needs to be
85   /// written to the data stream in correct endian format and correct size.
86   inline void emitWord16LE(uint16_t W) {
87     Data.push_back((W >> 0) & 255);
88     Data.push_back((W >> 8) & 255);
89   }
90
91   /// emitWord16BE - This callback is invoked when a 16-bit word needs to be
92   /// written to the data stream in correct endian format and correct size.
93   inline void emitWord16BE(uint16_t W) {
94     Data.push_back((W >> 8) & 255);
95     Data.push_back((W >> 0) & 255);
96   }
97
98   /// emitWord - This callback is invoked when a word needs to be
99   /// written to the data stream in correct endian format and correct size.
100   inline void emitWord(uint64_t W) {
101     if (!Is64Bit)
102       emitWord32(W);
103     else
104       emitWord64(W);
105   }
106
107   /// emitWord32 - This callback is invoked when a 32-bit word needs to be
108   /// written to the data stream in correct endian format.
109   inline void emitWord32(uint32_t W) {
110     if (IsLittleEndian)
111       emitWordLE(W);
112     else
113       emitWordBE(W);
114   }
115
116   /// emitWord64 - This callback is invoked when a 32-bit word needs to be
117   /// written to the data stream in correct endian format.
118   inline void emitWord64(uint64_t W) {
119     if (IsLittleEndian)
120       emitDWordLE(W);
121     else
122       emitDWordBE(W);
123   }
124
125   /// emitWordLE - This callback is invoked when a 32-bit word needs to be
126   /// written to the data stream in little-endian format.
127   inline void emitWordLE(uint32_t W) {
128     Data.push_back((W >>  0) & 255);
129     Data.push_back((W >>  8) & 255);
130     Data.push_back((W >> 16) & 255);
131     Data.push_back((W >> 24) & 255);
132   }
133
134   /// emitWordBE - This callback is invoked when a 32-bit word needs to be
135   /// written to the data stream in big-endian format.
136   ///
137   inline void emitWordBE(uint32_t W) {
138     Data.push_back((W >> 24) & 255);
139     Data.push_back((W >> 16) & 255);
140     Data.push_back((W >>  8) & 255);
141     Data.push_back((W >>  0) & 255);
142   }
143
144   /// emitDWordLE - This callback is invoked when a 64-bit word needs to be
145   /// written to the data stream in little-endian format.
146   inline void emitDWordLE(uint64_t W) {
147     Data.push_back(unsigned(W >>  0) & 255);
148     Data.push_back(unsigned(W >>  8) & 255);
149     Data.push_back(unsigned(W >> 16) & 255);
150     Data.push_back(unsigned(W >> 24) & 255);
151     Data.push_back(unsigned(W >> 32) & 255);
152     Data.push_back(unsigned(W >> 40) & 255);
153     Data.push_back(unsigned(W >> 48) & 255);
154     Data.push_back(unsigned(W >> 56) & 255);
155   }
156
157   /// emitDWordBE - This callback is invoked when a 64-bit word needs to be
158   /// written to the data stream in big-endian format.
159   inline void emitDWordBE(uint64_t W) {
160     Data.push_back(unsigned(W >> 56) & 255);
161     Data.push_back(unsigned(W >> 48) & 255);
162     Data.push_back(unsigned(W >> 40) & 255);
163     Data.push_back(unsigned(W >> 32) & 255);
164     Data.push_back(unsigned(W >> 24) & 255);
165     Data.push_back(unsigned(W >> 16) & 255);
166     Data.push_back(unsigned(W >>  8) & 255);
167     Data.push_back(unsigned(W >>  0) & 255);
168   }
169
170   /// fixByte - This callback is invoked when a byte needs to be
171   /// fixup the buffer.
172   inline void fixByte(uint8_t B, uint32_t offset) {
173     Data[offset] = B;
174   }
175
176   /// fixWord16 - This callback is invoked when a 16-bit word needs to
177   /// fixup the data stream in correct endian format.
178   inline void fixWord16(uint16_t W, uint32_t offset) {
179     if (IsLittleEndian)
180       fixWord16LE(W, offset);
181     else
182       fixWord16BE(W, offset);
183   }
184
185   /// emitWord16LE - This callback is invoked when a 16-bit word needs to
186   /// fixup the data stream in little endian format.
187   inline void fixWord16LE(uint16_t W, uint32_t offset) {
188     Data[offset++] = W & 255;
189     Data[offset] = (W >> 8) & 255;
190   }
191
192   /// fixWord16BE - This callback is invoked when a 16-bit word needs to
193   /// fixup data stream in big endian format.
194   inline void fixWord16BE(uint16_t W, uint32_t offset) {
195     Data[offset++] = (W >> 8) & 255;
196     Data[offset] = W & 255;
197   }
198
199   /// emitWord - This callback is invoked when a word needs to
200   /// fixup the data in correct endian format and correct size.
201   inline void fixWord(uint64_t W, uint32_t offset) {
202     if (!Is64Bit)
203       fixWord32(W, offset);
204     else
205       fixWord64(W, offset);
206   }
207
208   /// fixWord32 - This callback is invoked when a 32-bit word needs to
209   /// fixup the data in correct endian format.
210   inline void fixWord32(uint32_t W, uint32_t offset) {
211     if (IsLittleEndian)
212       fixWord32LE(W, offset);
213     else
214       fixWord32BE(W, offset);
215   }
216
217   /// fixWord32LE - This callback is invoked when a 32-bit word needs to
218   /// fixup the data in little endian format.
219   inline void fixWord32LE(uint32_t W, uint32_t offset) {
220     Data[offset++] = W & 255;
221     Data[offset++] = (W >> 8) & 255;
222     Data[offset++] = (W >> 16) & 255;
223     Data[offset] = (W >> 24) & 255;
224   }
225
226   /// fixWord32BE - This callback is invoked when a 32-bit word needs to
227   /// fixup the data in big endian format.
228   inline void fixWord32BE(uint32_t W, uint32_t offset) {
229     Data[offset++] = (W >> 24) & 255;
230     Data[offset++] = (W >> 16) & 255;
231     Data[offset++] = (W >> 8) & 255;
232     Data[offset] = W & 255;
233   }
234
235   /// fixWord64 - This callback is invoked when a 64-bit word needs to
236   /// fixup the data in correct endian format.
237   inline void fixWord64(uint64_t W, uint32_t offset) {
238     if (IsLittleEndian)
239       fixWord64LE(W, offset);
240     else
241       fixWord64BE(W, offset);
242   }
243
244   /// fixWord64BE - This callback is invoked when a 64-bit word needs to
245   /// fixup the data in little endian format.
246   inline void fixWord64LE(uint64_t W, uint32_t offset) {
247     Data[offset++] = W & 255;
248     Data[offset++] = (W >> 8) & 255;
249     Data[offset++] = (W >> 16) & 255;
250     Data[offset++] = (W >> 24) & 255;
251     Data[offset++] = (W >> 32) & 255;
252     Data[offset++] = (W >> 40) & 255;
253     Data[offset++] = (W >> 48) & 255;
254     Data[offset] = (W >> 56) & 255;
255   }
256
257   /// fixWord64BE - This callback is invoked when a 64-bit word needs to
258   /// fixup the data in big endian format.
259   inline void fixWord64BE(uint64_t W, uint32_t offset) {
260     Data[offset++] = (W >> 56) & 255;
261     Data[offset++] = (W >> 48) & 255;
262     Data[offset++] = (W >> 40) & 255;
263     Data[offset++] = (W >> 32) & 255;
264     Data[offset++] = (W >> 24) & 255;
265     Data[offset++] = (W >> 16) & 255;
266     Data[offset++] = (W >> 8) & 255;
267     Data[offset] = W & 255;
268   }
269
270   /// emitAlignment - Pad the data to the specified alignment.
271   void emitAlignment(unsigned Alignment) {
272     if (Alignment <= 1) return;
273     unsigned PadSize = -Data.size() & (Alignment-1);
274     for (unsigned i = 0; i<PadSize; ++i)
275       Data.push_back(0);
276   }
277
278   /// emitULEB128Bytes - This callback is invoked when a ULEB128 needs to be
279   /// written to the data stream.
280   void emitULEB128Bytes(uint64_t Value) {
281     do {
282       unsigned char Byte = Value & 0x7f;
283       Value >>= 7;
284       if (Value) Byte |= 0x80;
285       emitByte(Byte);
286     } while (Value);
287   }
288
289   /// emitSLEB128Bytes - This callback is invoked when a SLEB128 needs to be
290   /// written to the data stream.
291   void emitSLEB128Bytes(int64_t Value) {
292     int Sign = Value >> (8 * sizeof(Value) - 1);
293     bool IsMore;
294
295     do {
296       unsigned char Byte = Value & 0x7f;
297       Value >>= 7;
298       IsMore = Value != Sign || ((Byte ^ Sign) & 0x40) != 0;
299       if (IsMore) Byte |= 0x80;
300       emitByte(Byte);
301     } while (IsMore);
302   }
303
304   /// emitString - This callback is invoked when a String needs to be
305   /// written to the data stream.
306   void emitString(const std::string &String) {
307     for (unsigned i = 0, N = static_cast<unsigned>(String.size()); i<N; ++i) {
308       unsigned char C = String[i];
309       emitByte(C);
310     }
311     emitByte(0);
312   }
313
314   /// getCurrentPCOffset - Return the offset from the start of the emitted
315   /// buffer that we are currently writing to.
316   uintptr_t getCurrentPCOffset() const {
317     return Data.size();
318   }
319
320   /// addRelocation - Whenever a relocatable address is needed, it should be
321   /// noted with this interface.
322   void addRelocation(const MachineRelocation& relocation) {
323     Relocations.push_back(relocation);
324   }
325
326 };
327
328 } // end namespace llvm
329
330 #endif
331