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