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