MachineCodeEmitter.cpp revision 0742b59913a7760eb26f08121cd244a37e83e3b3
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 44 uint64_t getGlobalValueAddress(GlobalValue *V) { return 0; } 45 uint64_t getGlobalValueAddress(const std::string &Name) { return 0; } 46 uint64_t getConstantPoolEntryAddress(unsigned Num) { return 0; } 47 uint64_t getCurrentPCValue() { return 0; } 48 49 // forceCompilationOf - Force the compilation of the specified function, and 50 // return its address, because we REALLY need the address now. 51 // 52 // FIXME: This is JIT specific! 53 // 54 virtual uint64_t forceCompilationOf(Function *F) { 55 return 0; 56 } 57 }; 58 59 class FilePrinterEmitter : public MachineCodeEmitter { 60 std::ofstream actual; 61 std::ostream &o; 62 MachineCodeEmitter &MCE; 63 unsigned counter; 64 unsigned values[4]; 65 66 public: 67 FilePrinterEmitter(MachineCodeEmitter &M, std::ostream &os) 68 : o(os), MCE(M), counter(0) { 69 openActual(); 70 } 71 72 ~FilePrinterEmitter() { 73 o << "\n"; 74 actual.close(); 75 } 76 77 void openActual() { 78 actual.open("lli.actual.obj"); 79 if (!actual.good()) { 80 std::cerr << "Cannot open 'lli.actual.obj' for writing\n"; 81 abort(); 82 } 83 } 84 85 void startFunction(MachineFunction &F) { 86 // resolve any outstanding calls 87 MCE.startFunction(F); 88 } 89 void finishFunction(MachineFunction &F) { 90 MCE.finishFunction(F); 91 } 92 93 void emitConstantPool(MachineConstantPool *MCP) { 94 MCE.emitConstantPool(MCP); 95 } 96 97 void startFunctionStub(const Function &F, unsigned StubSize) { 98 MCE.startFunctionStub(F, StubSize); 99 } 100 101 void *finishFunctionStub(const Function &F) { 102 return MCE.finishFunctionStub(F); 103 } 104 105 void emitByte(unsigned char B) { 106 MCE.emitByte(B); 107 actual << B; actual.flush(); 108 109 values[counter] = (unsigned int) B; 110 if (++counter % 4 == 0 && counter != 0) { 111 o << std::hex; 112 for (unsigned i=0; i<4; ++i) { 113 if (values[i] < 16) o << "0"; 114 o << values[i] << " "; 115 } 116 117 o << std::dec << "\t"; 118 for (unsigned i=0; i<4; ++i) { 119 for (int j=7; j>=0; --j) { 120 o << ((values[i] >> j) & 1); 121 } 122 o << " "; 123 } 124 125 o << "\n"; 126 127 unsigned instr = 0; 128 for (unsigned i=0; i<4; ++i) 129 instr |= values[i] << (i*8); 130 131 o << "--- * --- * --- * --- * ---\n"; 132 counter %= 4; 133 } 134 } 135 136 void emitWord(unsigned W) { 137 MCE.emitWord(W); 138 } 139 uint64_t getGlobalValueAddress(GlobalValue *V) { 140 return MCE.getGlobalValueAddress(V); 141 } 142 uint64_t getGlobalValueAddress(const std::string &Name) { 143 return MCE.getGlobalValueAddress(Name); 144 } 145 uint64_t getConstantPoolEntryAddress(unsigned Num) { 146 return MCE.getConstantPoolEntryAddress(Num); 147 } 148 uint64_t getCurrentPCValue() { 149 return MCE.getCurrentPCValue(); 150 } 151 // forceCompilationOf - Force the compilation of the specified function, and 152 // return its address, because we REALLY need the address now. 153 // 154 // FIXME: This is JIT specific! 155 // 156 virtual uint64_t forceCompilationOf(Function *F) { 157 return MCE.forceCompilationOf(F); 158 } 159 }; 160} 161 162/// createDebugMachineCodeEmitter - Return a dynamically allocated machine 163/// code emitter, which just prints the opcodes and fields out the cout. This 164/// can be used for debugging users of the MachineCodeEmitter interface. 165/// 166MachineCodeEmitter * 167MachineCodeEmitter::createDebugEmitter() { 168 return new DebugMachineCodeEmitter(); 169} 170 171MachineCodeEmitter * 172MachineCodeEmitter::createFilePrinterEmitter(MachineCodeEmitter &MCE) { 173 return new FilePrinterEmitter(MCE, std::cerr); 174} 175