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