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