1 //===-- Mips/MipsCodeEmitter.cpp - Convert Mips code to machine code -----===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===---------------------------------------------------------------------===//
10 // This file contains the pass that transforms the Mips machine instructions
11 // into relocatable machine code.
13 //===---------------------------------------------------------------------===//
15 #define DEBUG_TYPE "jit"
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"
40 #include "llvm/CodeGen/MachineOperand.h"
46 class MipsCodeEmitter : public MachineFunctionPass {
48 const MipsInstrInfo *II;
50 const MipsSubtarget *Subtarget;
53 const std::vector<MachineConstantPoolEntry> *MCPEs;
54 const std::vector<MachineJumpTableEntry> *MJTEs;
57 void getAnalysisUsage(AnalysisUsage &AU) const {
58 AU.addRequired<MachineModuleInfo> ();
59 MachineFunctionPass::getAnalysisUsage(AU);
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_) {
72 bool runOnMachineFunction(MachineFunction &MF);
74 virtual const char *getPassName() const {
75 return "Mips Machine Code Emitter";
78 void emitInstruction(const MachineInstr &MI);
80 unsigned getOperandValue(const MachineOperand &MO,
81 unsigned relocType = -1);
83 void emitGlobalAddress(const GlobalValue *GV, unsigned Reloc,
84 bool MayNeedFarStub = true);
86 void emitMachineBasicBlock(MachineBasicBlock *BB, unsigned Reloc,
89 void emitExternalSymbolAddress(const char *ES, unsigned Reloc);
90 void emitJumpTableAddress(unsigned JTIndex, unsigned Reloc) const;
91 void emitConstPoolAddress(unsigned CPI, unsigned Reloc);
95 void 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);
102 /// emitMachineBasicBlock - Emit the specified address basic block.
103 void MipsCodeEmitter::emitMachineBasicBlock(MachineBasicBlock *BB,
104 unsigned Reloc, intptr_t JTBase) {
106 MachineRelocation::getBB(MCE.getCurrentPCOffset(), Reloc, BB, JTBase));
109 void MipsCodeEmitter::emitExternalSymbolAddress(const char *ES,
112 MachineRelocation::getExtSym(MCE.getCurrentPCOffset(), Reloc, ES, 0, 0,
116 void MipsCodeEmitter::emitJumpTableAddress(unsigned JTIndex, unsigned Reloc)
119 MachineRelocation::getJumpTable(MCE.getCurrentPCOffset(), Reloc, JTIndex,
123 void MipsCodeEmitter::emitConstPoolAddress(unsigned CPI, unsigned Reloc) {
125 MachineRelocation::getConstPool
126 (MCE.getCurrentPCOffset(), Reloc, CPI, 0));
129 /// createMipsJITCodeEmitterPass - Return a pass that emits the collected Mips
130 /// code to the specified MCE object.
131 FunctionPass *llvm::createMipsJITCodeEmitterPass(MipsTargetMachine &TM,
132 JITCodeEmitter &JCE) {
133 return new MipsCodeEmitter(TM, JCE);
136 char MipsCodeEmitter::ID = 10;
138 bool 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();
145 if (MF.getJumpTableInfo()) MJTEs = &MF.getJumpTableInfo()->getJumpTables();
146 JTI->Initialize(MF, IsPIC);
147 MCE.setModuleInfo(&getAnalysis<MachineModuleInfo> ());
150 DEBUG(errs() << "JITTing function '"
151 << MF.getFunction()->getName() << "'\n");
152 MCE.startFunction(MF);
154 for (MachineFunction::iterator MBB = MF.begin(), E = MF.end();
156 MCE.StartMachineBasicBlock(MBB);
157 for (MachineBasicBlock::const_iterator I = MBB->begin(), E = MBB->end();
161 } while (MCE.finishFunction(MF));
166 void MipsCodeEmitter::emitInstruction(const MachineInstr &MI) {}
168 unsigned MipsCodeEmitter::getOperandValue(const MachineOperand &MO,
169 unsigned relocType) {
170 switch (MO.getType()) {
171 case MachineOperand::MO_Immediate:
173 case MachineOperand::MO_GlobalAddress:
174 emitGlobalAddress(MO.getGlobal(), relocType, false);
176 case MachineOperand::MO_ExternalSymbol:
177 emitExternalSymbolAddress(MO.getSymbolName(), relocType);
179 case MachineOperand::MO_MachineBasicBlock:
180 emitMachineBasicBlock(MO.getMBB(), relocType, MCE.getCurrentPCValue());
182 case MachineOperand::MO_Register:
183 return MipsRegisterInfo::getRegisterNumbering(MO.getReg());
184 case MachineOperand::MO_JumpTableIndex:
185 emitJumpTableAddress(MO.getIndex(), relocType);
187 case MachineOperand::MO_ConstantPoolIndex:
188 emitConstPoolAddress(MO.getIndex(), relocType);