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