MachineCodeEmitter.cpp revision 37efe6764568a3829fee26aba532283131d1a104
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#include <ios> 20 21using namespace llvm; 22 23namespace { 24 struct DebugMachineCodeEmitter : public MachineCodeEmitter { 25 void startFunction(MachineFunction &F) { 26 std::cout << "\n**** Writing machine code for function: " 27 << F.getFunction()->getName() << "\n"; 28 } 29 void finishFunction(MachineFunction &F) { 30 std::cout << "\n"; 31 } 32 void startFunctionStub(unsigned StubSize) { 33 std::cout << "\n--- Function stub:\n"; 34 } 35 void *finishFunctionStub(const Function *F) { 36 std::cout << "\n--- End of stub for Function\n"; 37 return 0; 38 } 39 40 void emitByte(unsigned char B) { 41 std::cout << "0x" << std::hex << (unsigned int)B << std::dec << " "; 42 } 43 void emitWord(unsigned W) { 44 std::cout << "0x" << std::hex << W << std::dec << " "; 45 } 46 void emitWordAt(unsigned W, unsigned *Ptr) { 47 std::cout << "0x" << std::hex << W << std::dec << " (at " 48 << (void*) Ptr << ") "; 49 } 50 51 void addRelocation(const MachineRelocation &MR) { 52 std::cout << "<relocation> "; 53 } 54 55 virtual unsigned char* allocateGlobal(unsigned size, unsigned alignment) 56 { return 0; } 57 58 uint64_t getConstantPoolEntryAddress(unsigned Num) { return 0; } 59 uint64_t getJumpTableEntryAddress(unsigned Num) { return 0; } 60 uint64_t getCurrentPCValue() { return 0; } 61 uint64_t getCurrentPCOffset() { return 0; } 62 }; 63 64 class FilePrinterEmitter : public MachineCodeEmitter { 65 std::ofstream actual; 66 std::ostream &o; 67 MachineCodeEmitter &MCE; 68 unsigned counter; 69 unsigned values[4]; 70 71 public: 72 FilePrinterEmitter(MachineCodeEmitter &M, std::ostream &os) 73 : o(os), MCE(M), counter(0) { 74 openActual(); 75 } 76 77 ~FilePrinterEmitter() { 78 o << "\n"; 79 actual.close(); 80 } 81 82 void openActual() { 83 actual.open("lli.actual.obj"); 84 if (!actual.good()) { 85 std::cerr << "Cannot open 'lli.actual.obj' for writing\n"; 86 abort(); 87 } 88 } 89 90 void startFunction(MachineFunction &F) { 91 // resolve any outstanding calls 92 MCE.startFunction(F); 93 } 94 void finishFunction(MachineFunction &F) { 95 MCE.finishFunction(F); 96 } 97 98 void emitConstantPool(MachineConstantPool *MCP) { 99 MCE.emitConstantPool(MCP); 100 } 101 void initJumpTableInfo(MachineJumpTableInfo *MJTI) { 102 MCE.initJumpTableInfo(MJTI); 103 } 104 void emitJumpTableInfo(MachineJumpTableInfo *MJTI, 105 std::map<MachineBasicBlock*,uint64_t> &MBBM) { 106 MCE.emitJumpTableInfo(MJTI, MBBM); 107 } 108 109 void startFunctionStub(unsigned StubSize) { 110 MCE.startFunctionStub(StubSize); 111 } 112 113 void *finishFunctionStub(const Function *F) { 114 return MCE.finishFunctionStub(F); 115 } 116 117 void emitByte(unsigned char B) { 118 MCE.emitByte(B); 119 actual << B; actual.flush(); 120 121 values[counter] = (unsigned int) B; 122 if (++counter % 4 == 0 && counter != 0) { 123 o << std::hex; 124 for (unsigned i=0; i<4; ++i) { 125 if (values[i] < 16) o << "0"; 126 o << values[i] << " "; 127 } 128 129 o << std::dec << "\t"; 130 for (unsigned i=0; i<4; ++i) { 131 for (int j=7; j>=0; --j) { 132 o << ((values[i] >> j) & 1); 133 } 134 o << " "; 135 } 136 137 o << "\n"; 138 139 unsigned instr = 0; 140 for (unsigned i=0; i<4; ++i) 141 instr |= values[i] << (i*8); 142 143 o << "--- * --- * --- * --- * ---\n"; 144 counter %= 4; 145 } 146 } 147 148 void emitWord(unsigned W) { 149 MCE.emitWord(W); 150 } 151 void emitWordAt(unsigned W, unsigned *Ptr) { 152 MCE.emitWordAt(W, Ptr); 153 } 154 uint64_t getConstantPoolEntryAddress(unsigned Num) { 155 return MCE.getConstantPoolEntryAddress(Num); 156 } 157 uint64_t getJumpTableEntryAddress(unsigned Num) { 158 return MCE.getJumpTableEntryAddress(Num); 159 } 160 virtual unsigned char* allocateGlobal(unsigned size, unsigned alignment) 161 { return MCE.allocateGlobal(size, alignment); } 162 163 uint64_t getCurrentPCValue() { 164 return MCE.getCurrentPCValue(); 165 } 166 uint64_t getCurrentPCOffset() { 167 return MCE.getCurrentPCOffset(); 168 } 169 void addRelocation(const MachineRelocation &MR) { 170 return MCE.addRelocation(MR); 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