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