LLVM API Documentation

Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

MachineCodeEmitter.cpp

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