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