LLVM API Documentation
00001 //===-- MachineCodeEmitter.cpp - Implement the MachineCodeEmitter itf -----===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file was developed by the LLVM research group and is distributed under 00006 // the University of Illinois Open Source License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file implements the MachineCodeEmitter interface. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "llvm/CodeGen/MachineCodeEmitter.h" 00015 #include "llvm/CodeGen/MachineFunction.h" 00016 #include "llvm/Function.h" 00017 #include <fstream> 00018 #include <iostream> 00019 #include <ios> 00020 00021 using namespace llvm; 00022 00023 namespace { 00024 struct DebugMachineCodeEmitter : public MachineCodeEmitter { 00025 void startFunction(MachineFunction &F) { 00026 std::cout << "\n**** Writing machine code for function: " 00027 << F.getFunction()->getName() << "\n"; 00028 } 00029 void finishFunction(MachineFunction &F) { 00030 std::cout << "\n"; 00031 } 00032 void startFunctionStub(unsigned StubSize) { 00033 std::cout << "\n--- Function stub:\n"; 00034 } 00035 void *finishFunctionStub(const Function *F) { 00036 std::cout << "\n--- End of stub for Function\n"; 00037 return 0; 00038 } 00039 00040 void emitByte(unsigned char B) { 00041 std::cout << "0x" << std::hex << (unsigned int)B << std::dec << " "; 00042 } 00043 void emitWord(unsigned W) { 00044 std::cout << "0x" << std::hex << W << std::dec << " "; 00045 } 00046 void emitWordAt(unsigned W, unsigned *Ptr) { 00047 std::cout << "0x" << std::hex << W << std::dec << " (at " 00048 << (void*) Ptr << ") "; 00049 } 00050 00051 void addRelocation(const MachineRelocation &MR) { 00052 std::cout << "<relocation> "; 00053 } 00054 00055 virtual unsigned char* allocateGlobal(unsigned size, unsigned alignment) 00056 { return 0; } 00057 00058 uint64_t getConstantPoolEntryAddress(unsigned Num) { return 0; } 00059 uint64_t getCurrentPCValue() { return 0; } 00060 uint64_t getCurrentPCOffset() { return 0; } 00061 }; 00062 00063 class FilePrinterEmitter : public MachineCodeEmitter { 00064 std::ofstream actual; 00065 std::ostream &o; 00066 MachineCodeEmitter &MCE; 00067 unsigned counter; 00068 unsigned values[4]; 00069 00070 public: 00071 FilePrinterEmitter(MachineCodeEmitter &M, std::ostream &os) 00072 : o(os), MCE(M), counter(0) { 00073 openActual(); 00074 } 00075 00076 ~FilePrinterEmitter() { 00077 o << "\n"; 00078 actual.close(); 00079 } 00080 00081 void openActual() { 00082 actual.open("lli.actual.obj"); 00083 if (!actual.good()) { 00084 std::cerr << "Cannot open 'lli.actual.obj' for writing\n"; 00085 abort(); 00086 } 00087 } 00088 00089 void startFunction(MachineFunction &F) { 00090 // resolve any outstanding calls 00091 MCE.startFunction(F); 00092 } 00093 void finishFunction(MachineFunction &F) { 00094 MCE.finishFunction(F); 00095 } 00096 00097 void emitConstantPool(MachineConstantPool *MCP) { 00098 MCE.emitConstantPool(MCP); 00099 } 00100 00101 void startFunctionStub(unsigned StubSize) { 00102 MCE.startFunctionStub(StubSize); 00103 } 00104 00105 void *finishFunctionStub(const Function *F) { 00106 return MCE.finishFunctionStub(F); 00107 } 00108 00109 void emitByte(unsigned char B) { 00110 MCE.emitByte(B); 00111 actual << B; actual.flush(); 00112 00113 values[counter] = (unsigned int) B; 00114 if (++counter % 4 == 0 && counter != 0) { 00115 o << std::hex; 00116 for (unsigned i=0; i<4; ++i) { 00117 if (values[i] < 16) o << "0"; 00118 o << values[i] << " "; 00119 } 00120 00121 o << std::dec << "\t"; 00122 for (unsigned i=0; i<4; ++i) { 00123 for (int j=7; j>=0; --j) { 00124 o << ((values[i] >> j) & 1); 00125 } 00126 o << " "; 00127 } 00128 00129 o << "\n"; 00130 00131 unsigned instr = 0; 00132 for (unsigned i=0; i<4; ++i) 00133 instr |= values[i] << (i*8); 00134 00135 o << "--- * --- * --- * --- * ---\n"; 00136 counter %= 4; 00137 } 00138 } 00139 00140 void emitWord(unsigned W) { 00141 MCE.emitWord(W); 00142 } 00143 void emitWordAt(unsigned W, unsigned *Ptr) { 00144 MCE.emitWordAt(W, Ptr); 00145 } 00146 uint64_t getConstantPoolEntryAddress(unsigned Num) { 00147 return MCE.getConstantPoolEntryAddress(Num); 00148 } 00149 00150 virtual unsigned char* allocateGlobal(unsigned size, unsigned alignment) 00151 { return MCE.allocateGlobal(size, alignment); } 00152 00153 uint64_t getCurrentPCValue() { 00154 return MCE.getCurrentPCValue(); 00155 } 00156 uint64_t getCurrentPCOffset() { 00157 return MCE.getCurrentPCOffset(); 00158 } 00159 void addRelocation(const MachineRelocation &MR) { 00160 return MCE.addRelocation(MR); 00161 } 00162 }; 00163 } 00164 00165 /// createDebugMachineCodeEmitter - Return a dynamically allocated machine 00166 /// code emitter, which just prints the opcodes and fields out the cout. This 00167 /// can be used for debugging users of the MachineCodeEmitter interface. 00168 /// 00169 MachineCodeEmitter * 00170 MachineCodeEmitter::createDebugEmitter() { 00171 return new DebugMachineCodeEmitter(); 00172 } 00173 00174 MachineCodeEmitter * 00175 MachineCodeEmitter::createFilePrinterEmitter(MachineCodeEmitter &MCE) { 00176 return new FilePrinterEmitter(MCE, std::cerr); 00177 }