JITCodeEmitter.h revision 255f89faee13dc491cb64fbeae3c763e7e2ea4e6
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===-- llvm/CodeGen/JITCodeEmitter.h - Code emission ----------*- C++ -*-===// 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The LLVM Compiler Infrastructure 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This file is distributed under the University of Illinois Open Source 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// License. See LICENSE.TXT for details. 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===----------------------------------------------------------------------===// 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This file defines an abstract interface that is used by the machine code 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// emission framework to output the code. This allows machine code emission to 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// be separated from concerns such as resolution of call targets, and where the 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// machine code will be written (memory or disk, f.e.). 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===----------------------------------------------------------------------===// 16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef LLVM_CODEGEN_JITCODEEMITTER_H 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define LLVM_CODEGEN_JITCODEEMITTER_H 19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/ADT/DenseMap.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/CodeGen/MachineCodeEmitter.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/Support/DataTypes.h" 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "llvm/Support/MathExtras.h" 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <string> 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace llvm { 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MachineBasicBlock; 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MachineConstantPool; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MachineJumpTableInfo; 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MachineFunction; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MachineModuleInfo; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MachineRelocation; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Value; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class GlobalValue; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Function; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// JITCodeEmitter - This class defines two sorts of methods: those for 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// emitting the actual bytes of machine code, and those for emitting auxiliary 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// structures, such as jump tables, relocations, etc. 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// Emission of machine code is complicated by the fact that we don't (in 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// general) know the size of the machine code that we're about to emit before 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// we emit it. As such, we preallocate a certain amount of memory, and set the 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// BufferBegin/BufferEnd pointers to the start and end of the buffer. As we 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// emit machine instructions, we advance the CurBufferPtr to indicate the 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// location of the next byte to emit. In the case of a buffer overflow (we 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// need to emit more machine code than we have allocated space for), the 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// CurBufferPtr will saturate to BufferEnd and ignore stores. Once the entire 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// function has been emitted, the overflow condition is checked, and if it has 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// occurred, more memory is allocated, and we reemit the code into it. 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class JITCodeEmitter : public MachineCodeEmitter { 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void anchor(); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)public: 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~JITCodeEmitter() {} 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// startFunction - This callback is invoked when the specified function is 59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// about to be code generated. This initializes the BufferBegin/End/Ptr 60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// fields. 61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// 62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void startFunction(MachineFunction &F) = 0; 63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// finishFunction - This callback is invoked when the specified function has 65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// finished code generation. If a buffer overflow has occurred, this method 66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// returns true (the callee is required to try again), otherwise it returns 67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// false. 68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// 69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual bool finishFunction(MachineFunction &F) = 0; 70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// allocIndirectGV - Allocates and fills storage for an indirect 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// GlobalValue, and returns the address. 73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void *allocIndirectGV(const GlobalValue *GV, 74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const uint8_t *Buffer, size_t Size, 75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) unsigned Alignment) = 0; 76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// emitByte - This callback is invoked when a byte needs to be written to the 78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// output stream. 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void emitByte(uint8_t B) { 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CurBufferPtr != BufferEnd) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *CurBufferPtr++ = B; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// emitWordLE - This callback is invoked when a 32-bit word needs to be 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// written to the output stream in little-endian format. 87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// 88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void emitWordLE(uint32_t W) { 89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (4 <= BufferEnd-CurBufferPtr) { 90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *CurBufferPtr++ = (uint8_t)(W >> 0); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *CurBufferPtr++ = (uint8_t)(W >> 8); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *CurBufferPtr++ = (uint8_t)(W >> 16); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *CurBufferPtr++ = (uint8_t)(W >> 24); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurBufferPtr = BufferEnd; 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// emitWordBE - This callback is invoked when a 32-bit word needs to be 100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// written to the output stream in big-endian format. 101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// 102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void emitWordBE(uint32_t W) { 103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (4 <= BufferEnd-CurBufferPtr) { 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *CurBufferPtr++ = (uint8_t)(W >> 24); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *CurBufferPtr++ = (uint8_t)(W >> 16); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *CurBufferPtr++ = (uint8_t)(W >> 8); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *CurBufferPtr++ = (uint8_t)(W >> 0); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurBufferPtr = BufferEnd; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// emitDWordLE - This callback is invoked when a 64-bit word needs to be 114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// written to the output stream in little-endian format. 115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void emitDWordLE(uint64_t W) { 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (8 <= BufferEnd-CurBufferPtr) { 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *CurBufferPtr++ = (uint8_t)(W >> 0); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *CurBufferPtr++ = (uint8_t)(W >> 8); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *CurBufferPtr++ = (uint8_t)(W >> 16); 121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *CurBufferPtr++ = (uint8_t)(W >> 24); 122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *CurBufferPtr++ = (uint8_t)(W >> 32); 123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *CurBufferPtr++ = (uint8_t)(W >> 40); 124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *CurBufferPtr++ = (uint8_t)(W >> 48); 125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *CurBufferPtr++ = (uint8_t)(W >> 56); 126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else { 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurBufferPtr = BufferEnd; 128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// emitDWordBE - This callback is invoked when a 64-bit word needs to be 132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// written to the output stream in big-endian format. 133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// 134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void emitDWordBE(uint64_t W) { 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (8 <= BufferEnd-CurBufferPtr) { 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *CurBufferPtr++ = (uint8_t)(W >> 56); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *CurBufferPtr++ = (uint8_t)(W >> 48); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *CurBufferPtr++ = (uint8_t)(W >> 40); 139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *CurBufferPtr++ = (uint8_t)(W >> 32); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *CurBufferPtr++ = (uint8_t)(W >> 24); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *CurBufferPtr++ = (uint8_t)(W >> 16); 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *CurBufferPtr++ = (uint8_t)(W >> 8); 143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *CurBufferPtr++ = (uint8_t)(W >> 0); 144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else { 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurBufferPtr = BufferEnd; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// emitAlignment - Move the CurBufferPtr pointer up to the specified 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// alignment (saturated to BufferEnd of course). 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void emitAlignment(unsigned Alignment) { 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (Alignment == 0) Alignment = 1; 153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) uint8_t *NewPtr = (uint8_t*)RoundUpToAlignment((uintptr_t)CurBufferPtr, 154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Alignment); 155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CurBufferPtr = std::min(NewPtr, BufferEnd); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// emitAlignmentWithFill - Similar to emitAlignment, except that the 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// extra bytes are filled with the provided byte. 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void emitAlignmentWithFill(unsigned Alignment, uint8_t Fill) { 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (Alignment == 0) Alignment = 1; 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint8_t *NewPtr = (uint8_t*)RoundUpToAlignment((uintptr_t)CurBufferPtr, 163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Alignment); 164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Fail if we don't have room. 165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (NewPtr > BufferEnd) { 166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CurBufferPtr = BufferEnd; 167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) while (CurBufferPtr < NewPtr) { 170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *CurBufferPtr++ = Fill; 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// emitULEB128Bytes - This callback is invoked when a ULEB128 needs to be 175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// written to the output stream. 176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void emitULEB128Bytes(uint64_t Value, unsigned PadTo = 0) { 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint8_t Byte = Value & 0x7f; 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Value >>= 7; 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (Value || PadTo != 0) Byte |= 0x80; 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) emitByte(Byte); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (Value); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (PadTo) { 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint8_t Byte = (PadTo > 1) ? 0x80 : 0x0; 187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) emitByte(Byte); 188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } while (--PadTo); 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// emitSLEB128Bytes - This callback is invoked when a SLEB128 needs to be 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// written to the output stream. 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void emitSLEB128Bytes(int64_t Value) { 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32_t Sign = Value >> (8 * sizeof(Value) - 1); 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool IsMore; 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) do { 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) uint8_t Byte = Value & 0x7f; 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Value >>= 7; 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IsMore = Value != Sign || ((Byte ^ Sign) & 0x40) != 0; 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (IsMore) Byte |= 0x80; 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) emitByte(Byte); 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (IsMore); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// emitString - This callback is invoked when a String needs to be 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// written to the output stream. 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void emitString(const std::string &String) { 210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (unsigned i = 0, N = static_cast<unsigned>(String.size()); 211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) i < N; ++i) { 212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) uint8_t C = String[i]; 213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) emitByte(C); 214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) emitByte(0); 216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// emitInt32 - Emit a int32 directive. 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void emitInt32(uint32_t Value) { 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (4 <= BufferEnd-CurBufferPtr) { 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *((uint32_t*)CurBufferPtr) = Value; 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurBufferPtr += 4; 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurBufferPtr = BufferEnd; 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// emitInt64 - Emit a int64 directive. 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void emitInt64(uint64_t Value) { 230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (8 <= BufferEnd-CurBufferPtr) { 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *((uint64_t*)CurBufferPtr) = Value; 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurBufferPtr += 8; 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CurBufferPtr = BufferEnd; 235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// emitInt32At - Emit the Int32 Value in Addr. 239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void emitInt32At(uintptr_t *Addr, uintptr_t Value) { 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (Addr >= (uintptr_t*)BufferBegin && Addr < (uintptr_t*)BufferEnd) 241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) (*(uint32_t*)Addr) = (uint32_t)Value; 242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// emitInt64At - Emit the Int64 Value in Addr. 245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void emitInt64At(uintptr_t *Addr, uintptr_t Value) { 246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (Addr >= (uintptr_t*)BufferBegin && Addr < (uintptr_t*)BufferEnd) 247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) (*(uint64_t*)Addr) = (uint64_t)Value; 248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// emitLabel - Emits a label 252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void emitLabel(MCSymbol *Label) = 0; 253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// allocateSpace - Allocate a block of space in the current output buffer, 255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// returning null (and setting conditions to indicate buffer overflow) on 256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// failure. Alignment is the alignment in bytes of the buffer desired. 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void *allocateSpace(uintptr_t Size, unsigned Alignment) { 258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) emitAlignment(Alignment); 259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void *Result; 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check for buffer overflow. 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (Size >= (uintptr_t)(BufferEnd-CurBufferPtr)) { 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurBufferPtr = BufferEnd; 264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Result = 0; 265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else { 266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Allocate the space. 267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Result = CurBufferPtr; 268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CurBufferPtr += Size; 269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Result; 272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// allocateGlobal - Allocate memory for a global. Unlike allocateSpace, 275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// this method does not allocate memory in the current output buffer, 276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// because a global may live longer than the current function. 277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void *allocateGlobal(uintptr_t Size, unsigned Alignment) = 0; 278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// StartMachineBasicBlock - This should be called by the target when a new 280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// basic block is about to be emitted. This way the MCE knows where the 281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// start of the block is, and can implement getMachineBasicBlockAddress. 282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void StartMachineBasicBlock(MachineBasicBlock *MBB) = 0; 283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// getCurrentPCValue - This returns the address that the next emitted byte 285c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// will be output to. 286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// 287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual uintptr_t getCurrentPCValue() const { 288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return (uintptr_t)CurBufferPtr; 289c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// getCurrentPCOffset - Return the offset from the start of the emitted 292c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// buffer that we are currently writing to. 293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) uintptr_t getCurrentPCOffset() const { 294c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return CurBufferPtr-BufferBegin; 295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 297c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// earlyResolveAddresses - True if the code emitter can use symbol addresses 298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// during code emission time. The JIT is capable of doing this because it 299c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// creates jump tables or constant pools in memory on the fly while the 300c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// object code emitters rely on a linker to have real addresses and should 301c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// use relocations instead. 302c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool earlyResolveAddresses() const { return true; } 303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// addRelocation - Whenever a relocatable address is needed, it should be 305c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// noted with this interface. 306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void addRelocation(const MachineRelocation &MR) = 0; 307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// FIXME: These should all be handled with relocations! 309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// getConstantPoolEntryAddress - Return the address of the 'Index' entry in 311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// the constant pool that was last emitted with the emitConstantPool method. 312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// 313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual uintptr_t getConstantPoolEntryAddress(unsigned Index) const = 0; 314c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// getJumpTableEntryAddress - Return the address of the jump table with index 316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// 'Index' in the function that last called initJumpTableInfo. 317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// 318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual uintptr_t getJumpTableEntryAddress(unsigned Index) const = 0; 319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// getMachineBasicBlockAddress - Return the address of the specified 321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// MachineBasicBlock, only usable after the label for the MBB has been 322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// emitted. 323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// 324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual uintptr_t getMachineBasicBlockAddress(MachineBasicBlock *MBB) const= 0; 325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// getLabelAddress - Return the address of the specified Label, only usable 327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// after the Label has been emitted. 328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) /// 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual uintptr_t getLabelAddress(MCSymbol *Label) const = 0; 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// Specifies the MachineModuleInfo object. This is used for exception handling 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// purposes. 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void setModuleInfo(MachineModuleInfo* Info) = 0; 3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// getLabelLocations - Return the label locations map of the label IDs to 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// their address. 337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual DenseMap<MCSymbol*, uintptr_t> *getLabelLocations() { return 0; } 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // End llvm namespace 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)