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.

334 lines
12 KiB

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