blob: 224c8c37ccf6777e4dce1c285d22ae833b55f55c [file] [log] [blame]
Chris Lattnerf815aeb2002-12-03 20:56:42 +00001//===-- MachineCodeEmitter.cpp - Implement the MachineCodeEmitter itf -----===//
John Criswellb576c942003-10-20 19:43:21 +00002//
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//===----------------------------------------------------------------------===//
Chris Lattnerf815aeb2002-12-03 20:56:42 +00009//
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"
Misha Brukman3432d1d2003-05-27 22:43:19 +000017#include <fstream>
Reid Spencer954da372004-07-04 12:19:56 +000018#include <iostream>
19
Chris Lattner0742b592004-02-23 18:38:20 +000020using namespace llvm;
Brian Gaeked0fde302003-11-11 22:41:34 +000021
Chris Lattnerf815aeb2002-12-03 20:56:42 +000022namespace {
23 struct DebugMachineCodeEmitter : public MachineCodeEmitter {
24 void startFunction(MachineFunction &F) {
25 std::cout << "\n**** Writing machine code for function: "
26 << F.getFunction()->getName() << "\n";
27 }
28 void finishFunction(MachineFunction &F) {
29 std::cout << "\n";
30 }
Chris Lattnere0e72172003-05-09 03:27:41 +000031 void startFunctionStub(const Function &F, unsigned StubSize) {
Chris Lattnerfd33fb82003-05-08 21:54:18 +000032 std::cout << "\n--- Function stub for function: " << F.getName() << "\n";
33 }
Chris Lattnere0e72172003-05-09 03:27:41 +000034 void *finishFunctionStub(const Function &F) {
Chris Lattnerfd33fb82003-05-08 21:54:18 +000035 std::cout << "\n";
Chris Lattnere0e72172003-05-09 03:27:41 +000036 return 0;
Chris Lattnerfd33fb82003-05-08 21:54:18 +000037 }
Chris Lattnerf815aeb2002-12-03 20:56:42 +000038
39 void emitByte(unsigned char B) {
40 std::cout << "0x" << std::hex << (unsigned int)B << std::dec << " ";
41 }
Chris Lattnerefc84a42003-06-01 23:22:11 +000042 void emitWord(unsigned W) {
43 std::cout << "0x" << std::hex << W << std::dec << " ";
Chris Lattner7775df12003-01-13 00:22:37 +000044 }
Brian Gaekeda8246b2004-04-23 17:11:13 +000045 void emitWordAt(unsigned W, unsigned *Ptr) {
46 std::cout << "0x" << std::hex << W << std::dec << " (at "
47 << (void*) Ptr << ") ";
48 }
Chris Lattner7775df12003-01-13 00:22:37 +000049
Chris Lattnerefc84a42003-06-01 23:22:11 +000050 uint64_t getGlobalValueAddress(GlobalValue *V) { return 0; }
51 uint64_t getGlobalValueAddress(const std::string &Name) { return 0; }
52 uint64_t getConstantPoolEntryAddress(unsigned Num) { return 0; }
53 uint64_t getCurrentPCValue() { return 0; }
54
55 // forceCompilationOf - Force the compilation of the specified function, and
56 // return its address, because we REALLY need the address now.
57 //
58 // FIXME: This is JIT specific!
59 //
60 virtual uint64_t forceCompilationOf(Function *F) {
61 return 0;
Chris Lattner7775df12003-01-13 00:22:37 +000062 }
Chris Lattnerf815aeb2002-12-03 20:56:42 +000063 };
Chris Lattnerf815aeb2002-12-03 20:56:42 +000064
Chris Lattnerefc84a42003-06-01 23:22:11 +000065 class FilePrinterEmitter : public MachineCodeEmitter {
Misha Brukmane6aa9e32003-06-02 20:49:09 +000066 std::ofstream actual;
Misha Brukman3432d1d2003-05-27 22:43:19 +000067 std::ostream &o;
Chris Lattnerefc84a42003-06-01 23:22:11 +000068 MachineCodeEmitter &MCE;
Misha Brukman3432d1d2003-05-27 22:43:19 +000069 unsigned counter;
Misha Brukman3432d1d2003-05-27 22:43:19 +000070 unsigned values[4];
71
72 public:
Chris Lattnerefc84a42003-06-01 23:22:11 +000073 FilePrinterEmitter(MachineCodeEmitter &M, std::ostream &os)
Misha Brukmane6aa9e32003-06-02 20:49:09 +000074 : o(os), MCE(M), counter(0) {
Misha Brukman3432d1d2003-05-27 22:43:19 +000075 openActual();
76 }
Chris Lattnerefc84a42003-06-01 23:22:11 +000077
78 ~FilePrinterEmitter() {
Misha Brukman3432d1d2003-05-27 22:43:19 +000079 o << "\n";
80 actual.close();
Misha Brukman3432d1d2003-05-27 22:43:19 +000081 }
82
83 void openActual() {
84 actual.open("lli.actual.obj");
Chris Lattnerefc84a42003-06-01 23:22:11 +000085 if (!actual.good()) {
Misha Brukman3432d1d2003-05-27 22:43:19 +000086 std::cerr << "Cannot open 'lli.actual.obj' for writing\n";
87 abort();
88 }
89 }
90
91 void startFunction(MachineFunction &F) {
92 // resolve any outstanding calls
Chris Lattnerefc84a42003-06-01 23:22:11 +000093 MCE.startFunction(F);
Misha Brukman3432d1d2003-05-27 22:43:19 +000094 }
95 void finishFunction(MachineFunction &F) {
Chris Lattnerefc84a42003-06-01 23:22:11 +000096 MCE.finishFunction(F);
Misha Brukman3432d1d2003-05-27 22:43:19 +000097 }
98
Misha Brukmand720da22003-06-03 20:00:49 +000099 void emitConstantPool(MachineConstantPool *MCP) {
100 MCE.emitConstantPool(MCP);
101 }
102
Misha Brukman3432d1d2003-05-27 22:43:19 +0000103 void startFunctionStub(const Function &F, unsigned StubSize) {
Chris Lattnerefc84a42003-06-01 23:22:11 +0000104 MCE.startFunctionStub(F, StubSize);
Misha Brukman3432d1d2003-05-27 22:43:19 +0000105 }
106
107 void *finishFunctionStub(const Function &F) {
Chris Lattnerefc84a42003-06-01 23:22:11 +0000108 return MCE.finishFunctionStub(F);
Misha Brukman3432d1d2003-05-27 22:43:19 +0000109 }
110
111 void emitByte(unsigned char B) {
Chris Lattnerefc84a42003-06-01 23:22:11 +0000112 MCE.emitByte(B);
Misha Brukmaneae77de2003-05-28 18:27:19 +0000113 actual << B; actual.flush();
Misha Brukman3432d1d2003-05-27 22:43:19 +0000114
115 values[counter] = (unsigned int) B;
116 if (++counter % 4 == 0 && counter != 0) {
117 o << std::hex;
118 for (unsigned i=0; i<4; ++i) {
119 if (values[i] < 16) o << "0";
120 o << values[i] << " ";
Misha Brukman3432d1d2003-05-27 22:43:19 +0000121 }
Misha Brukman3432d1d2003-05-27 22:43:19 +0000122
123 o << std::dec << "\t";
124 for (unsigned i=0; i<4; ++i) {
125 for (int j=7; j>=0; --j) {
126 o << ((values[i] >> j) & 1);
127 }
128 o << " ";
129 }
130
131 o << "\n";
132
133 unsigned instr = 0;
134 for (unsigned i=0; i<4; ++i)
135 instr |= values[i] << (i*8);
136
137 o << "--- * --- * --- * --- * ---\n";
138 counter %= 4;
139 }
140 }
Misha Brukman3432d1d2003-05-27 22:43:19 +0000141
Chris Lattnerefc84a42003-06-01 23:22:11 +0000142 void emitWord(unsigned W) {
143 MCE.emitWord(W);
Misha Brukman3432d1d2003-05-27 22:43:19 +0000144 }
Brian Gaekeda8246b2004-04-23 17:11:13 +0000145 void emitWordAt(unsigned W, unsigned *Ptr) {
146 MCE.emitWordAt(W, Ptr);
147 }
Chris Lattnerefc84a42003-06-01 23:22:11 +0000148 uint64_t getGlobalValueAddress(GlobalValue *V) {
149 return MCE.getGlobalValueAddress(V);
Misha Brukman3432d1d2003-05-27 22:43:19 +0000150 }
Chris Lattnerefc84a42003-06-01 23:22:11 +0000151 uint64_t getGlobalValueAddress(const std::string &Name) {
152 return MCE.getGlobalValueAddress(Name);
Misha Brukman3432d1d2003-05-27 22:43:19 +0000153 }
Chris Lattnerefc84a42003-06-01 23:22:11 +0000154 uint64_t getConstantPoolEntryAddress(unsigned Num) {
155 return MCE.getConstantPoolEntryAddress(Num);
Misha Brukmanda3a8b12003-05-30 20:32:45 +0000156 }
Chris Lattnerefc84a42003-06-01 23:22:11 +0000157 uint64_t getCurrentPCValue() {
158 return MCE.getCurrentPCValue();
159 }
160 // forceCompilationOf - Force the compilation of the specified function, and
161 // return its address, because we REALLY need the address now.
162 //
163 // FIXME: This is JIT specific!
164 //
165 virtual uint64_t forceCompilationOf(Function *F) {
166 return MCE.forceCompilationOf(F);
167 }
Misha Brukman3432d1d2003-05-27 22:43:19 +0000168 };
169}
170
Brian Gaeked0fde302003-11-11 22:41:34 +0000171/// createDebugMachineCodeEmitter - Return a dynamically allocated machine
172/// code emitter, which just prints the opcodes and fields out the cout. This
173/// can be used for debugging users of the MachineCodeEmitter interface.
174///
175MachineCodeEmitter *
176MachineCodeEmitter::createDebugEmitter() {
177 return new DebugMachineCodeEmitter();
178}
179
Chris Lattnerefc84a42003-06-01 23:22:11 +0000180MachineCodeEmitter *
181MachineCodeEmitter::createFilePrinterEmitter(MachineCodeEmitter &MCE) {
182 return new FilePrinterEmitter(MCE, std::cerr);
Misha Brukman3432d1d2003-05-27 22:43:19 +0000183}