blob: d598a9387aee8e70529ffd35298219bea0c6a577 [file] [log] [blame]
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001//===-- llvm/CodeGen/MachineCodeEmitter.h - Code emission -------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner84e66db2007-12-29 19:59:42 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Dan Gohmanf17a25c2007-07-18 16:29:46 +00007//
8//===----------------------------------------------------------------------===//
9//
10// This file defines an abstract interface that is used by the machine code
11// emission framework to output the code. This allows machine code emission to
12// be separated from concerns such as resolution of call targets, and where the
13// machine code will be written (memory or disk, f.e.).
14//
15//===----------------------------------------------------------------------===//
16
17#ifndef LLVM_CODEGEN_MACHINECODEEMITTER_H
18#define LLVM_CODEGEN_MACHINECODEEMITTER_H
19
Chandler Carruth1ec7df12009-10-26 01:35:46 +000020#include "llvm/System/DataTypes.h"
Jeffrey Yasskin8ad296e2009-07-16 21:07:26 +000021#include "llvm/Support/DebugLoc.h"
Dan Gohmanf17a25c2007-07-18 16:29:46 +000022
23namespace llvm {
24
25class MachineBasicBlock;
26class MachineConstantPool;
27class MachineJumpTableInfo;
28class MachineFunction;
Nicolas Geoffray0e757e12008-02-13 18:39:37 +000029class MachineModuleInfo;
Dan Gohmanf17a25c2007-07-18 16:29:46 +000030class MachineRelocation;
31class Value;
32class GlobalValue;
33class Function;
34
35/// MachineCodeEmitter - This class defines two sorts of methods: those for
36/// emitting the actual bytes of machine code, and those for emitting auxillary
37/// structures, such as jump tables, relocations, etc.
38///
39/// Emission of machine code is complicated by the fact that we don't (in
40/// general) know the size of the machine code that we're about to emit before
41/// we emit it. As such, we preallocate a certain amount of memory, and set the
42/// BufferBegin/BufferEnd pointers to the start and end of the buffer. As we
43/// emit machine instructions, we advance the CurBufferPtr to indicate the
44/// location of the next byte to emit. In the case of a buffer overflow (we
45/// need to emit more machine code than we have allocated space for), the
46/// CurBufferPtr will saturate to BufferEnd and ignore stores. Once the entire
47/// function has been emitted, the overflow condition is checked, and if it has
48/// occurred, more memory is allocated, and we reemit the code into it.
49///
50class MachineCodeEmitter {
51protected:
Jeffrey Yasskin43a22282009-12-15 22:42:46 +000052 /// BufferBegin/BufferEnd - Pointers to the start and end of the memory
53 /// allocated for this code buffer.
54 uint8_t *BufferBegin, *BufferEnd;
55 /// CurBufferPtr - Pointer to the next byte of memory to fill when emitting
56 /// code. This is guranteed to be in the range [BufferBegin,BufferEnd]. If
57 /// this pointer is at BufferEnd, it will never move due to code emission, and
58 /// all code emission requests will be ignored (this is the buffer overflow
59 /// condition).
60 uint8_t *CurBufferPtr;
Evan Chengaf743252008-01-05 02:26:58 +000061
Dan Gohmanf17a25c2007-07-18 16:29:46 +000062public:
63 virtual ~MachineCodeEmitter() {}
64
65 /// startFunction - This callback is invoked when the specified function is
66 /// about to be code generated. This initializes the BufferBegin/End/Ptr
67 /// fields.
68 ///
69 virtual void startFunction(MachineFunction &F) = 0;
70
71 /// finishFunction - This callback is invoked when the specified function has
72 /// finished code generation. If a buffer overflow has occurred, this method
73 /// returns true (the callee is required to try again), otherwise it returns
74 /// false.
75 ///
76 virtual bool finishFunction(MachineFunction &F) = 0;
Dan Gohmanf17a25c2007-07-18 16:29:46 +000077
78 /// emitByte - This callback is invoked when a byte needs to be written to the
79 /// output stream.
80 ///
Bruno Cardoso Lopes214ae972009-06-04 00:15:51 +000081 void emitByte(uint8_t B) {
Dan Gohmanf17a25c2007-07-18 16:29:46 +000082 if (CurBufferPtr != BufferEnd)
83 *CurBufferPtr++ = B;
84 }
85
86 /// emitWordLE - This callback is invoked when a 32-bit word needs to be
87 /// written to the output stream in little-endian format.
88 ///
Bruno Cardoso Lopesd6ba5092009-06-12 23:51:56 +000089 void emitWordLE(uint32_t W) {
Evan Cheng6e561c72008-12-10 02:32:19 +000090 if (4 <= BufferEnd-CurBufferPtr) {
Jeffrey Yasskin43a22282009-12-15 22:42:46 +000091 emitWordLEInto(CurBufferPtr, W);
Dan Gohmanf17a25c2007-07-18 16:29:46 +000092 } else {
93 CurBufferPtr = BufferEnd;
94 }
95 }
Jeffrey Yasskin43a22282009-12-15 22:42:46 +000096
97 /// emitWordLEInto - This callback is invoked when a 32-bit word needs to be
98 /// written to an arbitrary buffer in little-endian format. Buf must have at
99 /// least 4 bytes of available space.
100 ///
101 static void emitWordLEInto(uint8_t *&Buf, uint32_t W) {
102 *Buf++ = (uint8_t)(W >> 0);
103 *Buf++ = (uint8_t)(W >> 8);
104 *Buf++ = (uint8_t)(W >> 16);
105 *Buf++ = (uint8_t)(W >> 24);
106 }
107
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000108 /// emitWordBE - This callback is invoked when a 32-bit word needs to be
109 /// written to the output stream in big-endian format.
110 ///
Bruno Cardoso Lopesd6ba5092009-06-12 23:51:56 +0000111 void emitWordBE(uint32_t W) {
Evan Cheng6e561c72008-12-10 02:32:19 +0000112 if (4 <= BufferEnd-CurBufferPtr) {
Bruno Cardoso Lopes214ae972009-06-04 00:15:51 +0000113 *CurBufferPtr++ = (uint8_t)(W >> 24);
114 *CurBufferPtr++ = (uint8_t)(W >> 16);
115 *CurBufferPtr++ = (uint8_t)(W >> 8);
116 *CurBufferPtr++ = (uint8_t)(W >> 0);
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000117 } else {
118 CurBufferPtr = BufferEnd;
119 }
120 }
121
Dan Gohman5ad09472008-10-24 01:57:54 +0000122 /// emitDWordLE - This callback is invoked when a 64-bit word needs to be
123 /// written to the output stream in little-endian format.
124 ///
125 void emitDWordLE(uint64_t W) {
Evan Cheng6e561c72008-12-10 02:32:19 +0000126 if (8 <= BufferEnd-CurBufferPtr) {
Bruno Cardoso Lopes214ae972009-06-04 00:15:51 +0000127 *CurBufferPtr++ = (uint8_t)(W >> 0);
128 *CurBufferPtr++ = (uint8_t)(W >> 8);
129 *CurBufferPtr++ = (uint8_t)(W >> 16);
130 *CurBufferPtr++ = (uint8_t)(W >> 24);
131 *CurBufferPtr++ = (uint8_t)(W >> 32);
132 *CurBufferPtr++ = (uint8_t)(W >> 40);
133 *CurBufferPtr++ = (uint8_t)(W >> 48);
134 *CurBufferPtr++ = (uint8_t)(W >> 56);
Dan Gohman5ad09472008-10-24 01:57:54 +0000135 } else {
136 CurBufferPtr = BufferEnd;
137 }
138 }
139
140 /// emitDWordBE - This callback is invoked when a 64-bit word needs to be
141 /// written to the output stream in big-endian format.
142 ///
143 void emitDWordBE(uint64_t W) {
Evan Cheng6e561c72008-12-10 02:32:19 +0000144 if (8 <= BufferEnd-CurBufferPtr) {
Bruno Cardoso Lopes214ae972009-06-04 00:15:51 +0000145 *CurBufferPtr++ = (uint8_t)(W >> 56);
146 *CurBufferPtr++ = (uint8_t)(W >> 48);
147 *CurBufferPtr++ = (uint8_t)(W >> 40);
148 *CurBufferPtr++ = (uint8_t)(W >> 32);
149 *CurBufferPtr++ = (uint8_t)(W >> 24);
150 *CurBufferPtr++ = (uint8_t)(W >> 16);
151 *CurBufferPtr++ = (uint8_t)(W >> 8);
152 *CurBufferPtr++ = (uint8_t)(W >> 0);
Dan Gohman5ad09472008-10-24 01:57:54 +0000153 } else {
154 CurBufferPtr = BufferEnd;
155 }
156 }
157
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000158 /// emitAlignment - Move the CurBufferPtr pointer up the the specified
159 /// alignment (saturated to BufferEnd of course).
160 void emitAlignment(unsigned Alignment) {
161 if (Alignment == 0) Alignment = 1;
Evan Cheng6e561c72008-12-10 02:32:19 +0000162
163 if(Alignment <= (uintptr_t)(BufferEnd-CurBufferPtr)) {
164 // Move the current buffer ptr up to the specified alignment.
165 CurBufferPtr =
Bruno Cardoso Lopes214ae972009-06-04 00:15:51 +0000166 (uint8_t*)(((uintptr_t)CurBufferPtr+Alignment-1) &
167 ~(uintptr_t)(Alignment-1));
Evan Cheng6e561c72008-12-10 02:32:19 +0000168 } else {
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000169 CurBufferPtr = BufferEnd;
Evan Cheng6e561c72008-12-10 02:32:19 +0000170 }
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000171 }
172
Nicolas Geoffray0e757e12008-02-13 18:39:37 +0000173
174 /// emitULEB128Bytes - This callback is invoked when a ULEB128 needs to be
175 /// written to the output stream.
Bruno Cardoso Lopesd6ba5092009-06-12 23:51:56 +0000176 void emitULEB128Bytes(uint64_t Value) {
Nicolas Geoffray0e757e12008-02-13 18:39:37 +0000177 do {
Bruno Cardoso Lopes214ae972009-06-04 00:15:51 +0000178 uint8_t Byte = Value & 0x7f;
Nicolas Geoffray0e757e12008-02-13 18:39:37 +0000179 Value >>= 7;
180 if (Value) Byte |= 0x80;
181 emitByte(Byte);
182 } while (Value);
183 }
184
185 /// emitSLEB128Bytes - This callback is invoked when a SLEB128 needs to be
186 /// written to the output stream.
Bruno Cardoso Lopesd6ba5092009-06-12 23:51:56 +0000187 void emitSLEB128Bytes(uint64_t Value) {
188 uint64_t Sign = Value >> (8 * sizeof(Value) - 1);
Nicolas Geoffray0e757e12008-02-13 18:39:37 +0000189 bool IsMore;
190
191 do {
Bruno Cardoso Lopes214ae972009-06-04 00:15:51 +0000192 uint8_t Byte = Value & 0x7f;
Nicolas Geoffray0e757e12008-02-13 18:39:37 +0000193 Value >>= 7;
194 IsMore = Value != Sign || ((Byte ^ Sign) & 0x40) != 0;
195 if (IsMore) Byte |= 0x80;
196 emitByte(Byte);
197 } while (IsMore);
198 }
199
200 /// emitString - This callback is invoked when a String needs to be
201 /// written to the output stream.
202 void emitString(const std::string &String) {
Evan Cheng591bfc82008-05-05 18:30:58 +0000203 for (unsigned i = 0, N = static_cast<unsigned>(String.size());
204 i < N; ++i) {
Bruno Cardoso Lopes214ae972009-06-04 00:15:51 +0000205 uint8_t C = String[i];
Nicolas Geoffray0e757e12008-02-13 18:39:37 +0000206 emitByte(C);
207 }
208 emitByte(0);
209 }
210
211 /// emitInt32 - Emit a int32 directive.
Bruno Cardoso Lopes214ae972009-06-04 00:15:51 +0000212 void emitInt32(int32_t Value) {
Evan Cheng6e561c72008-12-10 02:32:19 +0000213 if (4 <= BufferEnd-CurBufferPtr) {
Nicolas Geoffray0e757e12008-02-13 18:39:37 +0000214 *((uint32_t*)CurBufferPtr) = Value;
215 CurBufferPtr += 4;
216 } else {
217 CurBufferPtr = BufferEnd;
218 }
219 }
220
221 /// emitInt64 - Emit a int64 directive.
222 void emitInt64(uint64_t Value) {
Evan Cheng6e561c72008-12-10 02:32:19 +0000223 if (8 <= BufferEnd-CurBufferPtr) {
Nicolas Geoffray0e757e12008-02-13 18:39:37 +0000224 *((uint64_t*)CurBufferPtr) = Value;
225 CurBufferPtr += 8;
226 } else {
227 CurBufferPtr = BufferEnd;
228 }
229 }
230
Nicolas Geoffray30920192008-11-18 10:44:46 +0000231 /// emitInt32At - Emit the Int32 Value in Addr.
232 void emitInt32At(uintptr_t *Addr, uintptr_t Value) {
Nicolas Geoffray0e757e12008-02-13 18:39:37 +0000233 if (Addr >= (uintptr_t*)BufferBegin && Addr < (uintptr_t*)BufferEnd)
Nicolas Geoffray30920192008-11-18 10:44:46 +0000234 (*(uint32_t*)Addr) = (uint32_t)Value;
Nicolas Geoffray0e757e12008-02-13 18:39:37 +0000235 }
236
Nicolas Geoffray30920192008-11-18 10:44:46 +0000237 /// emitInt64At - Emit the Int64 Value in Addr.
238 void emitInt64At(uintptr_t *Addr, uintptr_t Value) {
239 if (Addr >= (uintptr_t*)BufferBegin && Addr < (uintptr_t*)BufferEnd)
240 (*(uint64_t*)Addr) = (uint64_t)Value;
241 }
242
Jeffrey Yasskin8ad296e2009-07-16 21:07:26 +0000243 /// processDebugLoc - Records debug location information about a
244 /// MachineInstruction. This is called before emitting any bytes associated
245 /// with the instruction. Even if successive instructions have the same debug
246 /// location, this method will be called for each one.
Devang Patel5450fc12009-10-06 02:19:11 +0000247 virtual void processDebugLoc(DebugLoc DL, bool BeforePrintintInsn) {}
Jeffrey Yasskin8ad296e2009-07-16 21:07:26 +0000248
Nicolas Geoffray0e757e12008-02-13 18:39:37 +0000249 /// emitLabel - Emits a label
250 virtual void emitLabel(uint64_t LabelID) = 0;
251
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000252 /// allocateSpace - Allocate a block of space in the current output buffer,
253 /// returning null (and setting conditions to indicate buffer overflow) on
254 /// failure. Alignment is the alignment in bytes of the buffer desired.
Evan Cheng6e561c72008-12-10 02:32:19 +0000255 virtual void *allocateSpace(uintptr_t Size, unsigned Alignment) {
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000256 emitAlignment(Alignment);
Evan Cheng6e561c72008-12-10 02:32:19 +0000257 void *Result;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000258
259 // Check for buffer overflow.
Evan Cheng6e561c72008-12-10 02:32:19 +0000260 if (Size >= (uintptr_t)(BufferEnd-CurBufferPtr)) {
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000261 CurBufferPtr = BufferEnd;
262 Result = 0;
Evan Cheng6e561c72008-12-10 02:32:19 +0000263 } else {
264 // Allocate the space.
265 Result = CurBufferPtr;
266 CurBufferPtr += Size;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000267 }
Evan Cheng6e561c72008-12-10 02:32:19 +0000268
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000269 return Result;
270 }
271
272 /// StartMachineBasicBlock - This should be called by the target when a new
273 /// basic block is about to be emitted. This way the MCE knows where the
274 /// start of the block is, and can implement getMachineBasicBlockAddress.
275 virtual void StartMachineBasicBlock(MachineBasicBlock *MBB) = 0;
276
277 /// getCurrentPCValue - This returns the address that the next emitted byte
278 /// will be output to.
279 ///
Evan Cheng6e561c72008-12-10 02:32:19 +0000280 virtual uintptr_t getCurrentPCValue() const {
281 return (uintptr_t)CurBufferPtr;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000282 }
283
284 /// getCurrentPCOffset - Return the offset from the start of the emitted
285 /// buffer that we are currently writing to.
Bruno Cardoso Lopesaabb9a52009-07-06 05:09:34 +0000286 virtual uintptr_t getCurrentPCOffset() const {
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000287 return CurBufferPtr-BufferBegin;
288 }
289
Bruno Cardoso Lopes670400e2009-08-05 00:11:21 +0000290 /// earlyResolveAddresses - True if the code emitter can use symbol addresses
291 /// during code emission time. The JIT is capable of doing this because it
292 /// creates jump tables or constant pools in memory on the fly while the
293 /// object code emitters rely on a linker to have real addresses and should
294 /// use relocations instead.
295 virtual bool earlyResolveAddresses() const = 0;
296
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000297 /// addRelocation - Whenever a relocatable address is needed, it should be
298 /// noted with this interface.
299 virtual void addRelocation(const MachineRelocation &MR) = 0;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000300
301 /// FIXME: These should all be handled with relocations!
302
303 /// getConstantPoolEntryAddress - Return the address of the 'Index' entry in
304 /// the constant pool that was last emitted with the emitConstantPool method.
305 ///
Evan Cheng6e561c72008-12-10 02:32:19 +0000306 virtual uintptr_t getConstantPoolEntryAddress(unsigned Index) const = 0;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000307
308 /// getJumpTableEntryAddress - Return the address of the jump table with index
309 /// 'Index' in the function that last called initJumpTableInfo.
310 ///
Evan Cheng6e561c72008-12-10 02:32:19 +0000311 virtual uintptr_t getJumpTableEntryAddress(unsigned Index) const = 0;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000312
313 /// getMachineBasicBlockAddress - Return the address of the specified
314 /// MachineBasicBlock, only usable after the label for the MBB has been
315 /// emitted.
316 ///
Evan Cheng6e561c72008-12-10 02:32:19 +0000317 virtual uintptr_t getMachineBasicBlockAddress(MachineBasicBlock *MBB) const= 0;
Nicolas Geoffray0e757e12008-02-13 18:39:37 +0000318
319 /// getLabelAddress - Return the address of the specified LabelID, only usable
320 /// after the LabelID has been emitted.
321 ///
Evan Cheng6e561c72008-12-10 02:32:19 +0000322 virtual uintptr_t getLabelAddress(uint64_t LabelID) const = 0;
Nicolas Geoffray0e757e12008-02-13 18:39:37 +0000323
324 /// Specifies the MachineModuleInfo object. This is used for exception handling
325 /// purposes.
326 virtual void setModuleInfo(MachineModuleInfo* Info) = 0;
Dan Gohmanf17a25c2007-07-18 16:29:46 +0000327};
328
329} // End llvm namespace
330
331#endif