LLVM API Documentation

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 #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 }