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