MachineCodeEmitter.cpp revision 53a7ba851d445ada2fa9e293542912b9ccf6f7c0
1//===-- MachineCodeEmitter.cpp - Implement the MachineCodeEmitter itf -----===// 2// 3// This file implements the MachineCodeEmitter interface. 4// 5//===----------------------------------------------------------------------===// 6 7#include "llvm/CodeGen/MachineCodeEmitter.h" 8#include "llvm/CodeGen/MachineFunction.h" 9#include "llvm/Function.h" 10#include <fstream> 11 12namespace { 13 struct DebugMachineCodeEmitter : public MachineCodeEmitter { 14 void startFunction(MachineFunction &F) { 15 std::cout << "\n**** Writing machine code for function: " 16 << F.getFunction()->getName() << "\n"; 17 } 18 void finishFunction(MachineFunction &F) { 19 std::cout << "\n"; 20 } 21 void startFunctionStub(const Function &F, unsigned StubSize) { 22 std::cout << "\n--- Function stub for function: " << F.getName() << "\n"; 23 } 24 void *finishFunctionStub(const Function &F) { 25 std::cout << "\n"; 26 return 0; 27 } 28 29 void emitByte(unsigned char B) { 30 std::cout << "0x" << std::hex << (unsigned int)B << std::dec << " "; 31 } 32 void emitWord(unsigned W) { 33 std::cout << "0x" << std::hex << W << std::dec << " "; 34 } 35 36 uint64_t getGlobalValueAddress(GlobalValue *V) { return 0; } 37 uint64_t getGlobalValueAddress(const std::string &Name) { return 0; } 38 uint64_t getConstantPoolEntryAddress(unsigned Num) { return 0; } 39 uint64_t getCurrentPCValue() { return 0; } 40 41 // forceCompilationOf - Force the compilation of the specified function, and 42 // return its address, because we REALLY need the address now. 43 // 44 // FIXME: This is JIT specific! 45 // 46 virtual uint64_t forceCompilationOf(Function *F) { 47 return 0; 48 } 49 }; 50} 51 52 53/// createDebugMachineCodeEmitter - Return a dynamically allocated machine 54/// code emitter, which just prints the opcodes and fields out the cout. This 55/// can be used for debugging users of the MachineCodeEmitter interface. 56/// 57MachineCodeEmitter *MachineCodeEmitter::createDebugEmitter() { 58 return new DebugMachineCodeEmitter(); 59} 60 61namespace { 62 class FilePrinterEmitter : public MachineCodeEmitter { 63 std::ofstream f, actual; 64 std::ostream &o; 65 MachineCodeEmitter &MCE; 66 unsigned counter; 67 bool mustClose; 68 unsigned values[4]; 69 70 public: 71 FilePrinterEmitter(MachineCodeEmitter &M, std::ostream &os) 72 : f("lli.out"), o(os), MCE(M), counter(0), mustClose(false) { 73 if (!f.good()) { 74 std::cerr << "Cannot open 'lli.out' for writing\n"; 75 abort(); 76 } 77 openActual(); 78 } 79 80 ~FilePrinterEmitter() { 81 o << "\n"; 82 actual.close(); 83 if (mustClose) f.close(); 84 } 85 86 void openActual() { 87 actual.open("lli.actual.obj"); 88 if (!actual.good()) { 89 std::cerr << "Cannot open 'lli.actual.obj' for writing\n"; 90 abort(); 91 } 92 } 93 94 void startFunction(MachineFunction &F) { 95 // resolve any outstanding calls 96 MCE.startFunction(F); 97 } 98 void finishFunction(MachineFunction &F) { 99 MCE.finishFunction(F); 100 } 101 102 void startFunctionStub(const Function &F, unsigned StubSize) { 103 MCE.startFunctionStub(F, StubSize); 104 } 105 106 void *finishFunctionStub(const Function &F) { 107 return MCE.finishFunctionStub(F); 108 } 109 110 void emitByte(unsigned char B) { 111 MCE.emitByte(B); 112 actual << B; actual.flush(); 113 114 values[counter] = (unsigned int) B; 115 if (++counter % 4 == 0 && counter != 0) { 116 o << std::hex; 117 for (unsigned i=0; i<4; ++i) { 118 if (values[i] < 16) o << "0"; 119 o << values[i] << " "; 120 } 121 122 o << std::dec << "\t"; 123 for (unsigned i=0; i<4; ++i) { 124 for (int j=7; j>=0; --j) { 125 o << ((values[i] >> j) & 1); 126 } 127 o << " "; 128 } 129 130 o << "\n"; 131 132 unsigned instr = 0; 133 for (unsigned i=0; i<4; ++i) 134 instr |= values[i] << (i*8); 135 136 o << "--- * --- * --- * --- * ---\n"; 137 counter %= 4; 138 } 139 } 140 141 void emitWord(unsigned W) { 142 MCE.emitWord(W); 143 } 144 uint64_t getGlobalValueAddress(GlobalValue *V) { 145 return MCE.getGlobalValueAddress(V); 146 } 147 uint64_t getGlobalValueAddress(const std::string &Name) { 148 return MCE.getGlobalValueAddress(Name); 149 } 150 uint64_t getConstantPoolEntryAddress(unsigned Num) { 151 return MCE.getConstantPoolEntryAddress(Num); 152 } 153 uint64_t getCurrentPCValue() { 154 return MCE.getCurrentPCValue(); 155 } 156 // forceCompilationOf - Force the compilation of the specified function, and 157 // return its address, because we REALLY need the address now. 158 // 159 // FIXME: This is JIT specific! 160 // 161 virtual uint64_t forceCompilationOf(Function *F) { 162 return MCE.forceCompilationOf(F); 163 } 164 }; 165} 166 167MachineCodeEmitter * 168MachineCodeEmitter::createFilePrinterEmitter(MachineCodeEmitter &MCE) { 169 return new FilePrinterEmitter(MCE, std::cerr); 170} 171