Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

341 lines
12 KiB

  1. //===-- llvm/CodeGen/JITCodeEmitter.h - Code emission ----------*- 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 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. #ifndef LLVM_CODEGEN_JITCODEEMITTER_H
  17. #define LLVM_CODEGEN_JITCODEEMITTER_H
  18. #include "llvm/ADT/DenseMap.h"
  19. #include "llvm/CodeGen/MachineCodeEmitter.h"
  20. #include "llvm/Support/DataTypes.h"
  21. #include "llvm/Support/MathExtras.h"
  22. #include <string>
  23. namespace llvm {
  24. class MachineBasicBlock;
  25. class MachineConstantPool;
  26. class MachineJumpTableInfo;
  27. class MachineFunction;
  28. class MachineModuleInfo;
  29. class MachineRelocation;
  30. class Value;
  31. class GlobalValue;
  32. class Function;
  33. /// JITCodeEmitter - This class defines two sorts of methods: those for
  34. /// emitting the actual bytes of machine code, and those for emitting auxiliary
  35. /// structures, such as jump tables, relocations, etc.
  36. ///
  37. /// Emission of machine code is complicated by the fact that we don't (in
  38. /// general) know the size of the machine code that we're about to emit before
  39. /// we emit it. As such, we preallocate a certain amount of memory, and set the
  40. /// BufferBegin/BufferEnd pointers to the start and end of the buffer. As we
  41. /// emit machine instructions, we advance the CurBufferPtr to indicate the
  42. /// location of the next byte to emit. In the case of a buffer overflow (we
  43. /// need to emit more machine code than we have allocated space for), the
  44. /// CurBufferPtr will saturate to BufferEnd and ignore stores. Once the entire
  45. /// function has been emitted, the overflow condition is checked, and if it has
  46. /// occurred, more memory is allocated, and we reemit the code into it.
  47. ///
  48. class JITCodeEmitter : public MachineCodeEmitter {
  49. virtual void anchor();
  50. public:
  51. virtual ~JITCodeEmitter() {}
  52. /// startFunction - This callback is invoked when the specified function is
  53. /// about to be code generated. This initializes the BufferBegin/End/Ptr
  54. /// fields.
  55. ///
  56. virtual void startFunction(MachineFunction &F) = 0;
  57. /// finishFunction - This callback is invoked when the specified function has
  58. /// finished code generation. If a buffer overflow has occurred, this method
  59. /// returns true (the callee is required to try again), otherwise it returns
  60. /// false.
  61. ///
  62. virtual bool finishFunction(MachineFunction &F) = 0;
  63. /// allocIndirectGV - Allocates and fills storage for an indirect
  64. /// GlobalValue, and returns the address.
  65. virtual void *allocIndirectGV(const GlobalValue *GV,
  66. const uint8_t *Buffer, size_t Size,
  67. unsigned Alignment) = 0;
  68. /// emitByte - This callback is invoked when a byte needs to be written to the
  69. /// output stream.
  70. ///
  71. void emitByte(uint8_t B) {
  72. if (CurBufferPtr != BufferEnd)
  73. *CurBufferPtr++ = B;
  74. }
  75. /// emitWordLE - This callback is invoked when a 32-bit word needs to be
  76. /// written to the output stream in little-endian format.
  77. ///
  78. void emitWordLE(uint32_t W) {
  79. if (4 <= BufferEnd-CurBufferPtr) {
  80. *CurBufferPtr++ = (uint8_t)(W >> 0);
  81. *CurBufferPtr++ = (uint8_t)(W >> 8);
  82. *CurBufferPtr++ = (uint8_t)(W >> 16);
  83. *CurBufferPtr++ = (uint8_t)(W >> 24);
  84. } else {
  85. CurBufferPtr = BufferEnd;
  86. }
  87. }
  88. /// emitWordBE - This callback is invoked when a 32-bit word needs to be
  89. /// written to the output stream in big-endian format.
  90. ///
  91. void emitWordBE(uint32_t W) {
  92. if (4 <= BufferEnd-CurBufferPtr) {
  93. *CurBufferPtr++ = (uint8_t)(W >> 24);
  94. *CurBufferPtr++ = (uint8_t)(W >> 16);
  95. *CurBufferPtr++ = (uint8_t)(W >> 8);
  96. *CurBufferPtr++ = (uint8_t)(W >> 0);
  97. } else {
  98. CurBufferPtr = BufferEnd;
  99. }
  100. }
  101. /// emitDWordLE - This callback is invoked when a 64-bit word needs to be
  102. /// written to the output stream in little-endian format.
  103. ///
  104. void emitDWordLE(uint64_t W) {
  105. if (8 <= BufferEnd-CurBufferPtr) {
  106. *CurBufferPtr++ = (uint8_t)(W >> 0);
  107. *CurBufferPtr++ = (uint8_t)(W >> 8);
  108. *CurBufferPtr++ = (uint8_t)(W >> 16);
  109. *CurBufferPtr++ = (uint8_t)(W >> 24);
  110. *CurBufferPtr++ = (uint8_t)(W >> 32);
  111. *CurBufferPtr++ = (uint8_t)(W >> 40);
  112. *CurBufferPtr++ = (uint8_t)(W >> 48);
  113. *CurBufferPtr++ = (uint8_t)(W >> 56);
  114. } else {
  115. CurBufferPtr = BufferEnd;
  116. }
  117. }
  118. /// emitDWordBE - This callback is invoked when a 64-bit word needs to be
  119. /// written to the output stream in big-endian format.
  120. ///
  121. void emitDWordBE(uint64_t W) {
  122. if (8 <= BufferEnd-CurBufferPtr) {
  123. *CurBufferPtr++ = (uint8_t)(W >> 56);
  124. *CurBufferPtr++ = (uint8_t)(W >> 48);
  125. *CurBufferPtr++ = (uint8_t)(W >> 40);
  126. *CurBufferPtr++ = (uint8_t)(W >> 32);
  127. *CurBufferPtr++ = (uint8_t)(W >> 24);
  128. *CurBufferPtr++ = (uint8_t)(W >> 16);
  129. *CurBufferPtr++ = (uint8_t)(W >> 8);
  130. *CurBufferPtr++ = (uint8_t)(W >> 0);
  131. } else {
  132. CurBufferPtr = BufferEnd;
  133. }
  134. }
  135. /// emitAlignment - Move the CurBufferPtr pointer up to the specified
  136. /// alignment (saturated to BufferEnd of course).
  137. void emitAlignment(unsigned Alignment) {
  138. if (Alignment == 0) Alignment = 1;
  139. uint8_t *NewPtr = (uint8_t*)RoundUpToAlignment((uintptr_t)CurBufferPtr,
  140. Alignment);
  141. CurBufferPtr = std::min(NewPtr, BufferEnd);
  142. }
  143. /// emitAlignmentWithFill - Similar to emitAlignment, except that the
  144. /// extra bytes are filled with the provided byte.
  145. void emitAlignmentWithFill(unsigned Alignment, uint8_t Fill) {
  146. if (Alignment == 0) Alignment = 1;
  147. uint8_t *NewPtr = (uint8_t*)RoundUpToAlignment((uintptr_t)CurBufferPtr,
  148. Alignment);
  149. // Fail if we don't have room.
  150. if (NewPtr > BufferEnd) {
  151. CurBufferPtr = BufferEnd;
  152. return;
  153. }
  154. while (CurBufferPtr < NewPtr) {
  155. *CurBufferPtr++ = Fill;
  156. }
  157. }
  158. /// emitULEB128Bytes - This callback is invoked when a ULEB128 needs to be
  159. /// written to the output stream.
  160. void emitULEB128Bytes(uint64_t Value, unsigned PadTo = 0) {
  161. do {
  162. uint8_t Byte = Value & 0x7f;
  163. Value >>= 7;
  164. if (Value || PadTo != 0) Byte |= 0x80;
  165. emitByte(Byte);
  166. } while (Value);
  167. if (PadTo) {
  168. do {
  169. uint8_t Byte = (PadTo > 1) ? 0x80 : 0x0;
  170. emitByte(Byte);
  171. } while (--PadTo);
  172. }
  173. }
  174. /// emitSLEB128Bytes - This callback is invoked when a SLEB128 needs to be
  175. /// written to the output stream.
  176. void emitSLEB128Bytes(int64_t Value) {
  177. int32_t Sign = Value >> (8 * sizeof(Value) - 1);
  178. bool IsMore;
  179. do {
  180. uint8_t Byte = Value & 0x7f;
  181. Value >>= 7;
  182. IsMore = Value != Sign || ((Byte ^ Sign) & 0x40) != 0;
  183. if (IsMore) Byte |= 0x80;
  184. emitByte(Byte);
  185. } while (IsMore);
  186. }
  187. /// emitString - This callback is invoked when a String needs to be
  188. /// written to the output stream.
  189. void emitString(const std::string &String) {
  190. for (size_t i = 0, N = String.size(); i < N; ++i) {
  191. uint8_t C = String[i];
  192. emitByte(C);
  193. }
  194. emitByte(0);
  195. }
  196. /// emitInt32 - Emit a int32 directive.
  197. void emitInt32(uint32_t Value) {
  198. if (4 <= BufferEnd-CurBufferPtr) {
  199. *((uint32_t*)CurBufferPtr) = Value;
  200. CurBufferPtr += 4;
  201. } else {
  202. CurBufferPtr = BufferEnd;
  203. }
  204. }
  205. /// emitInt64 - Emit a int64 directive.
  206. void emitInt64(uint64_t Value) {
  207. if (8 <= BufferEnd-CurBufferPtr) {
  208. *((uint64_t*)CurBufferPtr) = Value;
  209. CurBufferPtr += 8;
  210. } else {
  211. CurBufferPtr = BufferEnd;
  212. }
  213. }
  214. /// emitInt32At - Emit the Int32 Value in Addr.
  215. void emitInt32At(uintptr_t *Addr, uintptr_t Value) {
  216. if (Addr >= (uintptr_t*)BufferBegin && Addr < (uintptr_t*)BufferEnd)
  217. (*(uint32_t*)Addr) = (uint32_t)Value;
  218. }
  219. /// emitInt64At - Emit the Int64 Value in Addr.
  220. void emitInt64At(uintptr_t *Addr, uintptr_t Value) {
  221. if (Addr >= (uintptr_t*)BufferBegin && Addr < (uintptr_t*)BufferEnd)
  222. (*(uint64_t*)Addr) = (uint64_t)Value;
  223. }
  224. /// emitLabel - Emits a label
  225. virtual void emitLabel(MCSymbol *Label) = 0;
  226. /// allocateSpace - Allocate a block of space in the current output buffer,
  227. /// returning null (and setting conditions to indicate buffer overflow) on
  228. /// failure. Alignment is the alignment in bytes of the buffer desired.
  229. virtual void *allocateSpace(uintptr_t Size, unsigned Alignment) {
  230. emitAlignment(Alignment);
  231. void *Result;
  232. // Check for buffer overflow.
  233. if (Size >= (uintptr_t)(BufferEnd-CurBufferPtr)) {
  234. CurBufferPtr = BufferEnd;
  235. Result = 0;
  236. } else {
  237. // Allocate the space.
  238. Result = CurBufferPtr;
  239. CurBufferPtr += Size;
  240. }
  241. return Result;
  242. }
  243. /// allocateGlobal - Allocate memory for a global. Unlike allocateSpace,
  244. /// this method does not allocate memory in the current output buffer,
  245. /// because a global may live longer than the current function.
  246. virtual void *allocateGlobal(uintptr_t Size, unsigned Alignment) = 0;
  247. /// StartMachineBasicBlock - This should be called by the target when a new
  248. /// basic block is about to be emitted. This way the MCE knows where the
  249. /// start of the block is, and can implement getMachineBasicBlockAddress.
  250. virtual void StartMachineBasicBlock(MachineBasicBlock *MBB) = 0;
  251. /// getCurrentPCValue - This returns the address that the next emitted byte
  252. /// will be output to.
  253. ///
  254. virtual uintptr_t getCurrentPCValue() const {
  255. return (uintptr_t)CurBufferPtr;
  256. }
  257. /// getCurrentPCOffset - Return the offset from the start of the emitted
  258. /// buffer that we are currently writing to.
  259. uintptr_t getCurrentPCOffset() const {
  260. return CurBufferPtr-BufferBegin;
  261. }
  262. /// earlyResolveAddresses - True if the code emitter can use symbol addresses
  263. /// during code emission time. The JIT is capable of doing this because it
  264. /// creates jump tables or constant pools in memory on the fly while the
  265. /// object code emitters rely on a linker to have real addresses and should
  266. /// use relocations instead.
  267. bool earlyResolveAddresses() const { return true; }
  268. /// addRelocation - Whenever a relocatable address is needed, it should be
  269. /// noted with this interface.
  270. virtual void addRelocation(const MachineRelocation &MR) = 0;
  271. /// FIXME: These should all be handled with relocations!
  272. /// getConstantPoolEntryAddress - Return the address of the 'Index' entry in
  273. /// the constant pool that was last emitted with the emitConstantPool method.
  274. ///
  275. virtual uintptr_t getConstantPoolEntryAddress(unsigned Index) const = 0;
  276. /// getJumpTableEntryAddress - Return the address of the jump table with index
  277. /// 'Index' in the function that last called initJumpTableInfo.
  278. ///
  279. virtual uintptr_t getJumpTableEntryAddress(unsigned Index) const = 0;
  280. /// getMachineBasicBlockAddress - Return the address of the specified
  281. /// MachineBasicBlock, only usable after the label for the MBB has been
  282. /// emitted.
  283. ///
  284. virtual uintptr_t getMachineBasicBlockAddress(MachineBasicBlock *MBB) const= 0;
  285. /// getLabelAddress - Return the address of the specified Label, only usable
  286. /// after the Label has been emitted.
  287. ///
  288. virtual uintptr_t getLabelAddress(MCSymbol *Label) const = 0;
  289. /// Specifies the MachineModuleInfo object. This is used for exception handling
  290. /// purposes.
  291. virtual void setModuleInfo(MachineModuleInfo* Info) = 0;
  292. /// getLabelLocations - Return the label locations map of the label IDs to
  293. /// their address.
  294. virtual DenseMap<MCSymbol*, uintptr_t> *getLabelLocations() { return 0; }
  295. };
  296. } // End llvm namespace
  297. #endif