JITCodeEmitter.h revision 186c670e15828327960d05a652ec43ae768c9b8e
1a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes//===-- llvm/CodeGen/JITCodeEmitter.h - Code emission ----------*- C++ -*-===// 2a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes// 3a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes// The LLVM Compiler Infrastructure 4a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes// 5a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes// This file is distributed under the University of Illinois Open Source 6a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes// License. See LICENSE.TXT for details. 7a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes// 8a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes//===----------------------------------------------------------------------===// 9a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes// 10a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes// This file defines an abstract interface that is used by the machine code 11a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes// emission framework to output the code. This allows machine code emission to 12a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes// be separated from concerns such as resolution of call targets, and where the 13a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes// machine code will be written (memory or disk, f.e.). 14a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes// 15a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes//===----------------------------------------------------------------------===// 16a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes 17a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes#ifndef LLVM_CODEGEN_JITCODEEMITTER_H 18a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes#define LLVM_CODEGEN_JITCODEEMITTER_H 19a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes 20a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes#include <string> 21a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes#include "llvm/Support/DataTypes.h" 22a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes#include "llvm/Support/Streams.h" 23a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes#include "llvm/CodeGen/MachineCodeEmitter.h" 24a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes 25a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopesusing namespace std; 26a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes 27a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopesnamespace llvm { 28a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes 29a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopesclass MachineBasicBlock; 30a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopesclass MachineConstantPool; 31a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopesclass MachineJumpTableInfo; 32a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopesclass MachineFunction; 33a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopesclass MachineModuleInfo; 34a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopesclass MachineRelocation; 35a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopesclass Value; 36a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopesclass GlobalValue; 37a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopesclass Function; 38a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes 39a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes/// JITCodeEmitter - This class defines two sorts of methods: those for 40a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes/// emitting the actual bytes of machine code, and those for emitting auxillary 41a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes/// structures, such as jump tables, relocations, etc. 42a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes/// 43a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes/// Emission of machine code is complicated by the fact that we don't (in 44a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes/// general) know the size of the machine code that we're about to emit before 45a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes/// we emit it. As such, we preallocate a certain amount of memory, and set the 46a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes/// BufferBegin/BufferEnd pointers to the start and end of the buffer. As we 47a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes/// emit machine instructions, we advance the CurBufferPtr to indicate the 48a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes/// location of the next byte to emit. In the case of a buffer overflow (we 49a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes/// need to emit more machine code than we have allocated space for), the 50a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes/// CurBufferPtr will saturate to BufferEnd and ignore stores. Once the entire 51a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes/// function has been emitted, the overflow condition is checked, and if it has 52a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes/// occurred, more memory is allocated, and we reemit the code into it. 53a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes/// 54a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopesclass JITCodeEmitter : public MachineCodeEmitter { 55a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopespublic: 56a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes virtual ~JITCodeEmitter() {} 57a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes 58a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// startFunction - This callback is invoked when the specified function is 59a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// about to be code generated. This initializes the BufferBegin/End/Ptr 60a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// fields. 61a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// 62a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes virtual void startFunction(MachineFunction &F) = 0; 63a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes 64a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// finishFunction - This callback is invoked when the specified function has 65a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// finished code generation. If a buffer overflow has occurred, this method 66a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// returns true (the callee is required to try again), otherwise it returns 67a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// false. 68a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// 69a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes virtual bool finishFunction(MachineFunction &F) = 0; 70a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes 71a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// startGVStub - This callback is invoked when the JIT needs the 72a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// address of a GV (e.g. function) that has not been code generated yet. 73a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// The StubSize specifies the total size required by the stub. 74a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// 75a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes virtual void startGVStub(const GlobalValue* GV, unsigned StubSize, 76a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes unsigned Alignment = 1) = 0; 77a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes 78a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// startGVStub - This callback is invoked when the JIT needs the address of a 79a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// GV (e.g. function) that has not been code generated yet. Buffer points to 80a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// memory already allocated for this stub. 81a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// 82a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes virtual void startGVStub(const GlobalValue* GV, void *Buffer, 83a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes unsigned StubSize) = 0; 84a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes 85a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// finishGVStub - This callback is invoked to terminate a GV stub. 86a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// 87a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes virtual void *finishGVStub(const GlobalValue* F) = 0; 88a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes 89a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// emitByte - This callback is invoked when a byte needs to be written to the 90a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// output stream. 91a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// 92186c670e15828327960d05a652ec43ae768c9b8eBruno Cardoso Lopes void emitByte(uint8_t B) { 93a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes if (CurBufferPtr != BufferEnd) 94a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes *CurBufferPtr++ = B; 95a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes } 96a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes 97a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// emitWordLE - This callback is invoked when a 32-bit word needs to be 98a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// written to the output stream in little-endian format. 99a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// 100a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes void emitWordLE(unsigned W) { 101a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes if (4 <= BufferEnd-CurBufferPtr) { 102186c670e15828327960d05a652ec43ae768c9b8eBruno Cardoso Lopes *CurBufferPtr++ = (uint8_t)(W >> 0); 103186c670e15828327960d05a652ec43ae768c9b8eBruno Cardoso Lopes *CurBufferPtr++ = (uint8_t)(W >> 8); 104186c670e15828327960d05a652ec43ae768c9b8eBruno Cardoso Lopes *CurBufferPtr++ = (uint8_t)(W >> 16); 105186c670e15828327960d05a652ec43ae768c9b8eBruno Cardoso Lopes *CurBufferPtr++ = (uint8_t)(W >> 24); 106a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes } else { 107a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes CurBufferPtr = BufferEnd; 108a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes } 109a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes } 110a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes 111a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// emitWordBE - This callback is invoked when a 32-bit word needs to be 112a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// written to the output stream in big-endian format. 113a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// 114a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes void emitWordBE(unsigned W) { 115a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes if (4 <= BufferEnd-CurBufferPtr) { 116186c670e15828327960d05a652ec43ae768c9b8eBruno Cardoso Lopes *CurBufferPtr++ = (uint8_t)(W >> 24); 117186c670e15828327960d05a652ec43ae768c9b8eBruno Cardoso Lopes *CurBufferPtr++ = (uint8_t)(W >> 16); 118186c670e15828327960d05a652ec43ae768c9b8eBruno Cardoso Lopes *CurBufferPtr++ = (uint8_t)(W >> 8); 119186c670e15828327960d05a652ec43ae768c9b8eBruno Cardoso Lopes *CurBufferPtr++ = (uint8_t)(W >> 0); 120a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes } else { 121a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes CurBufferPtr = BufferEnd; 122a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes } 123a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes } 124a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes 125a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// emitDWordLE - This callback is invoked when a 64-bit word needs to be 126a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// written to the output stream in little-endian format. 127a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// 128a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes void emitDWordLE(uint64_t W) { 129a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes if (8 <= BufferEnd-CurBufferPtr) { 130186c670e15828327960d05a652ec43ae768c9b8eBruno Cardoso Lopes *CurBufferPtr++ = (uint8_t)(W >> 0); 131186c670e15828327960d05a652ec43ae768c9b8eBruno Cardoso Lopes *CurBufferPtr++ = (uint8_t)(W >> 8); 132186c670e15828327960d05a652ec43ae768c9b8eBruno Cardoso Lopes *CurBufferPtr++ = (uint8_t)(W >> 16); 133186c670e15828327960d05a652ec43ae768c9b8eBruno Cardoso Lopes *CurBufferPtr++ = (uint8_t)(W >> 24); 134186c670e15828327960d05a652ec43ae768c9b8eBruno Cardoso Lopes *CurBufferPtr++ = (uint8_t)(W >> 32); 135186c670e15828327960d05a652ec43ae768c9b8eBruno Cardoso Lopes *CurBufferPtr++ = (uint8_t)(W >> 40); 136186c670e15828327960d05a652ec43ae768c9b8eBruno Cardoso Lopes *CurBufferPtr++ = (uint8_t)(W >> 48); 137186c670e15828327960d05a652ec43ae768c9b8eBruno Cardoso Lopes *CurBufferPtr++ = (uint8_t)(W >> 56); 138a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes } else { 139a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes CurBufferPtr = BufferEnd; 140a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes } 141a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes } 142a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes 143a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// emitDWordBE - This callback is invoked when a 64-bit word needs to be 144a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// written to the output stream in big-endian format. 145a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// 146a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes void emitDWordBE(uint64_t W) { 147a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes if (8 <= BufferEnd-CurBufferPtr) { 148186c670e15828327960d05a652ec43ae768c9b8eBruno Cardoso Lopes *CurBufferPtr++ = (uint8_t)(W >> 56); 149186c670e15828327960d05a652ec43ae768c9b8eBruno Cardoso Lopes *CurBufferPtr++ = (uint8_t)(W >> 48); 150186c670e15828327960d05a652ec43ae768c9b8eBruno Cardoso Lopes *CurBufferPtr++ = (uint8_t)(W >> 40); 151186c670e15828327960d05a652ec43ae768c9b8eBruno Cardoso Lopes *CurBufferPtr++ = (uint8_t)(W >> 32); 152186c670e15828327960d05a652ec43ae768c9b8eBruno Cardoso Lopes *CurBufferPtr++ = (uint8_t)(W >> 24); 153186c670e15828327960d05a652ec43ae768c9b8eBruno Cardoso Lopes *CurBufferPtr++ = (uint8_t)(W >> 16); 154186c670e15828327960d05a652ec43ae768c9b8eBruno Cardoso Lopes *CurBufferPtr++ = (uint8_t)(W >> 8); 155186c670e15828327960d05a652ec43ae768c9b8eBruno Cardoso Lopes *CurBufferPtr++ = (uint8_t)(W >> 0); 156a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes } else { 157a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes CurBufferPtr = BufferEnd; 158a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes } 159a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes } 160a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes 161a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// emitAlignment - Move the CurBufferPtr pointer up the the specified 162a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// alignment (saturated to BufferEnd of course). 163a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes void emitAlignment(unsigned Alignment) { 164a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes if (Alignment == 0) Alignment = 1; 165a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes 166a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes if(Alignment <= (uintptr_t)(BufferEnd-CurBufferPtr)) { 167a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes // Move the current buffer ptr up to the specified alignment. 168a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes CurBufferPtr = 169186c670e15828327960d05a652ec43ae768c9b8eBruno Cardoso Lopes (uint8_t*)(((uintptr_t)CurBufferPtr+Alignment-1) & 170186c670e15828327960d05a652ec43ae768c9b8eBruno Cardoso Lopes ~(uintptr_t)(Alignment-1)); 171a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes } else { 172a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes CurBufferPtr = BufferEnd; 173a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes } 174a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes } 175a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes 176a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes 177a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// emitULEB128Bytes - This callback is invoked when a ULEB128 needs to be 178a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// written to the output stream. 179a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes void emitULEB128Bytes(unsigned Value) { 180a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes do { 181186c670e15828327960d05a652ec43ae768c9b8eBruno Cardoso Lopes uint8_t Byte = Value & 0x7f; 182a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes Value >>= 7; 183a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes if (Value) Byte |= 0x80; 184a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes emitByte(Byte); 185a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes } while (Value); 186a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes } 187a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes 188a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// emitSLEB128Bytes - This callback is invoked when a SLEB128 needs to be 189a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// written to the output stream. 190186c670e15828327960d05a652ec43ae768c9b8eBruno Cardoso Lopes void emitSLEB128Bytes(int32_t Value) { 191186c670e15828327960d05a652ec43ae768c9b8eBruno Cardoso Lopes int32_t Sign = Value >> (8 * sizeof(Value) - 1); 192a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes bool IsMore; 193a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes 194a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes do { 195186c670e15828327960d05a652ec43ae768c9b8eBruno Cardoso Lopes uint8_t Byte = Value & 0x7f; 196a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes Value >>= 7; 197a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes IsMore = Value != Sign || ((Byte ^ Sign) & 0x40) != 0; 198a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes if (IsMore) Byte |= 0x80; 199a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes emitByte(Byte); 200a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes } while (IsMore); 201a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes } 202a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes 203a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// emitString - This callback is invoked when a String needs to be 204a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// written to the output stream. 205a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes void emitString(const std::string &String) { 206a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes for (unsigned i = 0, N = static_cast<unsigned>(String.size()); 207a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes i < N; ++i) { 208186c670e15828327960d05a652ec43ae768c9b8eBruno Cardoso Lopes uint8_t C = String[i]; 209a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes emitByte(C); 210a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes } 211a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes emitByte(0); 212a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes } 213a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes 214a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// emitInt32 - Emit a int32 directive. 215186c670e15828327960d05a652ec43ae768c9b8eBruno Cardoso Lopes void emitInt32(int32_t Value) { 216a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes if (4 <= BufferEnd-CurBufferPtr) { 217a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes *((uint32_t*)CurBufferPtr) = Value; 218a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes CurBufferPtr += 4; 219a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes } else { 220a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes CurBufferPtr = BufferEnd; 221a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes } 222a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes } 223a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes 224a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// emitInt64 - Emit a int64 directive. 225a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes void emitInt64(uint64_t Value) { 226a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes if (8 <= BufferEnd-CurBufferPtr) { 227a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes *((uint64_t*)CurBufferPtr) = Value; 228a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes CurBufferPtr += 8; 229a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes } else { 230a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes CurBufferPtr = BufferEnd; 231a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes } 232a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes } 233a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes 234a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// emitInt32At - Emit the Int32 Value in Addr. 235a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes void emitInt32At(uintptr_t *Addr, uintptr_t Value) { 236a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes if (Addr >= (uintptr_t*)BufferBegin && Addr < (uintptr_t*)BufferEnd) 237a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes (*(uint32_t*)Addr) = (uint32_t)Value; 238a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes } 239a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes 240a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// emitInt64At - Emit the Int64 Value in Addr. 241a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes void emitInt64At(uintptr_t *Addr, uintptr_t Value) { 242a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes if (Addr >= (uintptr_t*)BufferBegin && Addr < (uintptr_t*)BufferEnd) 243a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes (*(uint64_t*)Addr) = (uint64_t)Value; 244a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes } 245a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes 246a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes 247a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// emitLabel - Emits a label 248a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes virtual void emitLabel(uint64_t LabelID) = 0; 249a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes 250a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// allocateSpace - Allocate a block of space in the current output buffer, 251a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// returning null (and setting conditions to indicate buffer overflow) on 252a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// failure. Alignment is the alignment in bytes of the buffer desired. 253a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes virtual void *allocateSpace(uintptr_t Size, unsigned Alignment) { 254a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes emitAlignment(Alignment); 255a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes void *Result; 256a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes 257a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes // Check for buffer overflow. 258a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes if (Size >= (uintptr_t)(BufferEnd-CurBufferPtr)) { 259a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes CurBufferPtr = BufferEnd; 260a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes Result = 0; 261a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes } else { 262a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes // Allocate the space. 263a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes Result = CurBufferPtr; 264a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes CurBufferPtr += Size; 265a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes } 266a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes 267a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes return Result; 268a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes } 269a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes 270a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// StartMachineBasicBlock - This should be called by the target when a new 271a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// basic block is about to be emitted. This way the MCE knows where the 272a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// start of the block is, and can implement getMachineBasicBlockAddress. 273a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes virtual void StartMachineBasicBlock(MachineBasicBlock *MBB) = 0; 274a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes 275a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// getCurrentPCValue - This returns the address that the next emitted byte 276a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// will be output to. 277a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// 278a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes virtual uintptr_t getCurrentPCValue() const { 279a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes return (uintptr_t)CurBufferPtr; 280a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes } 281a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes 282a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// getCurrentPCOffset - Return the offset from the start of the emitted 283a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// buffer that we are currently writing to. 284a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes uintptr_t getCurrentPCOffset() const { 285a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes return CurBufferPtr-BufferBegin; 286a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes } 287a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes 288a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// addRelocation - Whenever a relocatable address is needed, it should be 289a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// noted with this interface. 290a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes virtual void addRelocation(const MachineRelocation &MR) = 0; 291a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes 292a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// FIXME: These should all be handled with relocations! 293a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes 294a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// getConstantPoolEntryAddress - Return the address of the 'Index' entry in 295a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// the constant pool that was last emitted with the emitConstantPool method. 296a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// 297a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes virtual uintptr_t getConstantPoolEntryAddress(unsigned Index) const = 0; 298a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes 299a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// getJumpTableEntryAddress - Return the address of the jump table with index 300a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// 'Index' in the function that last called initJumpTableInfo. 301a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// 302a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes virtual uintptr_t getJumpTableEntryAddress(unsigned Index) const = 0; 303a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes 304a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// getMachineBasicBlockAddress - Return the address of the specified 305a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// MachineBasicBlock, only usable after the label for the MBB has been 306a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// emitted. 307a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// 308a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes virtual uintptr_t getMachineBasicBlockAddress(MachineBasicBlock *MBB) const= 0; 309a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes 310a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// getLabelAddress - Return the address of the specified LabelID, only usable 311a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// after the LabelID has been emitted. 312a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// 313a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes virtual uintptr_t getLabelAddress(uint64_t LabelID) const = 0; 314a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes 315a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// Specifies the MachineModuleInfo object. This is used for exception handling 316a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// purposes. 317a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes virtual void setModuleInfo(MachineModuleInfo* Info) = 0; 318a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes}; 319a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes 320a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes} // End llvm namespace 321a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes 322a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes#endif 323