blob: eb8f7e0870eba044fd2a9d03e929dd342ed6d008 [file] [log] [blame]
Bruno Cardoso Lopesdca6cdd2011-07-21 16:28:51 +00001//===-- Mips/MipsCodeEmitter.cpp - Convert Mips code to machine code -----===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===---------------------------------------------------------------------===//
9//
10// This file contains the pass that transforms the Mips machine instructions
11// into relocatable machine code.
12//
13//===---------------------------------------------------------------------===//
14
15#define DEBUG_TYPE "jit"
16#include "Mips.h"
17#include "MipsInstrInfo.h"
18#include "MipsRelocations.h"
19#include "MipsSubtarget.h"
20#include "MipsTargetMachine.h"
21#include "llvm/Constants.h"
22#include "llvm/DerivedTypes.h"
23#include "llvm/Function.h"
24#include "llvm/PassManager.h"
25#include "llvm/CodeGen/JITCodeEmitter.h"
26#include "llvm/CodeGen/MachineConstantPool.h"
27#include "llvm/CodeGen/MachineFunctionPass.h"
28#include "llvm/CodeGen/MachineInstr.h"
29#include "llvm/CodeGen/MachineJumpTableInfo.h"
30#include "llvm/CodeGen/MachineModuleInfo.h"
31#include "llvm/CodeGen/Passes.h"
32#include "llvm/ADT/Statistic.h"
33#include "llvm/Support/Debug.h"
34#include "llvm/Support/ErrorHandling.h"
35#include "llvm/Support/raw_ostream.h"
36#ifndef NDEBUG
37#include <iomanip>
38#endif
39
40#include "llvm/CodeGen/MachineOperand.h"
41
42using namespace llvm;
43
44namespace {
45
46class MipsCodeEmitter : public MachineFunctionPass {
47 MipsJITInfo *JTI;
48 const MipsInstrInfo *II;
49 const TargetData *TD;
50 const MipsSubtarget *Subtarget;
51 TargetMachine &TM;
52 JITCodeEmitter &MCE;
53 const std::vector<MachineConstantPoolEntry> *MCPEs;
54 const std::vector<MachineJumpTableEntry> *MJTEs;
55 bool IsPIC;
56
57 void getAnalysisUsage(AnalysisUsage &AU) const {
58 AU.addRequired<MachineModuleInfo> ();
59 MachineFunctionPass::getAnalysisUsage(AU);
60 }
61
62 static char ID;
63
64 public:
65 MipsCodeEmitter(TargetMachine &tm, JITCodeEmitter &mce) :
66 MachineFunctionPass(ID), JTI(0),
67 II((const MipsInstrInfo *) tm.getInstrInfo()),
68 TD(tm.getTargetData()), TM(tm), MCE(mce), MCPEs(0), MJTEs(0),
69 IsPIC(TM.getRelocationModel() == Reloc::PIC_) {
70 }
71
72 bool runOnMachineFunction(MachineFunction &MF);
73
74 virtual const char *getPassName() const {
75 return "Mips Machine Code Emitter";
76 }
77
78 void emitInstruction(const MachineInstr &MI);
79
80 unsigned getOperandValue(const MachineOperand &MO,
81 unsigned relocType = -1);
82
83 void emitGlobalAddress(const GlobalValue *GV, unsigned Reloc,
84 bool MayNeedFarStub = true);
85
86 void emitMachineBasicBlock(MachineBasicBlock *BB, unsigned Reloc,
87 intptr_t JTBase = 0);
88
89 void emitExternalSymbolAddress(const char *ES, unsigned Reloc);
90 void emitJumpTableAddress(unsigned JTIndex, unsigned Reloc) const;
91 void emitConstPoolAddress(unsigned CPI, unsigned Reloc);
92};
93}
94
95void MipsCodeEmitter::emitGlobalAddress(const GlobalValue *GV, unsigned Reloc,
96 bool mayNeedFarStub) {
97 MachineRelocation MR = MachineRelocation::getGV(MCE.getCurrentPCOffset(),
98 Reloc, const_cast<GlobalValue *> (GV), 0, mayNeedFarStub);
99 MCE.addRelocation(MR);
100}
101
102/// emitMachineBasicBlock - Emit the specified address basic block.
103void MipsCodeEmitter::emitMachineBasicBlock(MachineBasicBlock *BB,
104 unsigned Reloc, intptr_t JTBase) {
105 MCE.addRelocation(
106 MachineRelocation::getBB(MCE.getCurrentPCOffset(), Reloc, BB, JTBase));
107}
108
109void MipsCodeEmitter::emitExternalSymbolAddress(const char *ES,
110 unsigned Reloc) {
111 MCE.addRelocation(
112 MachineRelocation::getExtSym(MCE.getCurrentPCOffset(), Reloc, ES, 0, 0,
113 false));
114}
115
116void MipsCodeEmitter::emitJumpTableAddress(unsigned JTIndex, unsigned Reloc)
117 const {
118 MCE.addRelocation(
119 MachineRelocation::getJumpTable(MCE.getCurrentPCOffset(), Reloc, JTIndex,
120 0, false));
121}
122
123void MipsCodeEmitter::emitConstPoolAddress(unsigned CPI, unsigned Reloc) {
124 MCE.addRelocation(
125 MachineRelocation::getConstPool
126 (MCE.getCurrentPCOffset(), Reloc, CPI, 0));
127}
128
129/// createMipsJITCodeEmitterPass - Return a pass that emits the collected Mips
130/// code to the specified MCE object.
131FunctionPass *llvm::createMipsJITCodeEmitterPass(MipsTargetMachine &TM,
132 JITCodeEmitter &JCE) {
133 return new MipsCodeEmitter(TM, JCE);
134}
135
136char MipsCodeEmitter::ID = 10;
137
138bool MipsCodeEmitter::runOnMachineFunction(MachineFunction &MF) {
139 JTI = ((MipsTargetMachine&) MF.getTarget()).getJITInfo();
140 II = ((const MipsTargetMachine&) MF.getTarget()).getInstrInfo();
141 TD = ((const MipsTargetMachine&) MF.getTarget()).getTargetData();
142 Subtarget = &TM.getSubtarget<MipsSubtarget> ();
143 MCPEs = &MF.getConstantPool()->getConstants();
144 MJTEs = 0;
145 if (MF.getJumpTableInfo()) MJTEs = &MF.getJumpTableInfo()->getJumpTables();
146 JTI->Initialize(MF, IsPIC);
147 MCE.setModuleInfo(&getAnalysis<MachineModuleInfo> ());
148
149 do {
150 DEBUG(errs() << "JITTing function '"
151 << MF.getFunction()->getName() << "'\n");
152 MCE.startFunction(MF);
153
154 for (MachineFunction::iterator MBB = MF.begin(), E = MF.end();
155 MBB != E; ++MBB){
156 MCE.StartMachineBasicBlock(MBB);
157 for (MachineBasicBlock::const_iterator I = MBB->begin(), E = MBB->end();
158 I != E; ++I)
159 emitInstruction(*I);
160 }
161 } while (MCE.finishFunction(MF));
162
163 return false;
164}
165
166void MipsCodeEmitter::emitInstruction(const MachineInstr &MI) {}
167
168unsigned MipsCodeEmitter::getOperandValue(const MachineOperand &MO,
169 unsigned relocType) {
170 switch (MO.getType()) {
171 case MachineOperand::MO_Immediate:
172 return MO.getImm();
173 case MachineOperand::MO_GlobalAddress:
174 emitGlobalAddress(MO.getGlobal(), relocType, false);
175 return 0;
176 case MachineOperand::MO_ExternalSymbol:
177 emitExternalSymbolAddress(MO.getSymbolName(), relocType);
178 return 0;
179 case MachineOperand::MO_MachineBasicBlock:
180 emitMachineBasicBlock(MO.getMBB(), relocType, MCE.getCurrentPCValue());
181 return 0;
182 case MachineOperand::MO_Register:
183 return MipsRegisterInfo::getRegisterNumbering(MO.getReg());
184 case MachineOperand::MO_JumpTableIndex:
185 emitJumpTableAddress(MO.getIndex(), relocType);
186 return 0;
187 case MachineOperand::MO_ConstantPoolIndex:
188 emitConstPoolAddress(MO.getIndex(), relocType);
189 return 0;
190 default: return 0;
191 }
192}
193