MipsCodeEmitter.cpp revision 228379
1226584Sdim//===-- Mips/MipsCodeEmitter.cpp - Convert Mips code to machine code -----===// 2226584Sdim// 3226584Sdim// The LLVM Compiler Infrastructure 4226584Sdim// 5226584Sdim// This file is distributed under the University of Illinois Open Source 6226584Sdim// License. See LICENSE.TXT for details. 7226584Sdim// 8226584Sdim//===---------------------------------------------------------------------===// 9226584Sdim// 10226584Sdim// This file contains the pass that transforms the Mips machine instructions 11226584Sdim// into relocatable machine code. 12226584Sdim// 13226584Sdim//===---------------------------------------------------------------------===// 14226584Sdim 15226584Sdim#define DEBUG_TYPE "jit" 16226584Sdim#include "Mips.h" 17226584Sdim#include "MipsInstrInfo.h" 18226584Sdim#include "MipsRelocations.h" 19226584Sdim#include "MipsSubtarget.h" 20226584Sdim#include "MipsTargetMachine.h" 21226584Sdim#include "llvm/Constants.h" 22226584Sdim#include "llvm/DerivedTypes.h" 23226584Sdim#include "llvm/Function.h" 24226584Sdim#include "llvm/PassManager.h" 25226584Sdim#include "llvm/CodeGen/JITCodeEmitter.h" 26226584Sdim#include "llvm/CodeGen/MachineConstantPool.h" 27226584Sdim#include "llvm/CodeGen/MachineFunctionPass.h" 28226584Sdim#include "llvm/CodeGen/MachineInstr.h" 29226584Sdim#include "llvm/CodeGen/MachineJumpTableInfo.h" 30226584Sdim#include "llvm/CodeGen/MachineModuleInfo.h" 31226584Sdim#include "llvm/CodeGen/Passes.h" 32226584Sdim#include "llvm/ADT/Statistic.h" 33226584Sdim#include "llvm/Support/Debug.h" 34226584Sdim#include "llvm/Support/ErrorHandling.h" 35226584Sdim#include "llvm/Support/raw_ostream.h" 36226584Sdim#ifndef NDEBUG 37226584Sdim#include <iomanip> 38226584Sdim#endif 39226584Sdim 40226584Sdim#include "llvm/CodeGen/MachineOperand.h" 41226584Sdim 42226584Sdimusing namespace llvm; 43226584Sdim 44226584SdimSTATISTIC(NumEmitted, "Number of machine instructions emitted"); 45226584Sdim 46226584Sdimnamespace { 47226584Sdim 48226584Sdimclass MipsCodeEmitter : public MachineFunctionPass { 49226584Sdim MipsJITInfo *JTI; 50226584Sdim const MipsInstrInfo *II; 51226584Sdim const TargetData *TD; 52226584Sdim const MipsSubtarget *Subtarget; 53226584Sdim TargetMachine &TM; 54226584Sdim JITCodeEmitter &MCE; 55226584Sdim const std::vector<MachineConstantPoolEntry> *MCPEs; 56226584Sdim const std::vector<MachineJumpTableEntry> *MJTEs; 57226584Sdim bool IsPIC; 58226584Sdim 59226584Sdim void getAnalysisUsage(AnalysisUsage &AU) const { 60226584Sdim AU.addRequired<MachineModuleInfo> (); 61226584Sdim MachineFunctionPass::getAnalysisUsage(AU); 62226584Sdim } 63226584Sdim 64226584Sdim static char ID; 65226584Sdim 66226584Sdim public: 67226584Sdim MipsCodeEmitter(TargetMachine &tm, JITCodeEmitter &mce) : 68226584Sdim MachineFunctionPass(ID), JTI(0), 69226584Sdim II((const MipsInstrInfo *) tm.getInstrInfo()), 70226584Sdim TD(tm.getTargetData()), TM(tm), MCE(mce), MCPEs(0), MJTEs(0), 71226584Sdim IsPIC(TM.getRelocationModel() == Reloc::PIC_) { 72226584Sdim } 73226584Sdim 74226584Sdim bool runOnMachineFunction(MachineFunction &MF); 75226584Sdim 76226584Sdim virtual const char *getPassName() const { 77226584Sdim return "Mips Machine Code Emitter"; 78226584Sdim } 79226584Sdim 80226584Sdim /// getBinaryCodeForInstr - This function, generated by the 81226584Sdim /// CodeEmitterGenerator using TableGen, produces the binary encoding for 82226584Sdim /// machine instructions. 83226584Sdim unsigned getBinaryCodeForInstr(const MachineInstr &MI) const; 84226584Sdim 85226584Sdim void emitInstruction(const MachineInstr &MI); 86226584Sdim 87226584Sdim private: 88226584Sdim 89226584Sdim void emitWordLE(unsigned Word); 90226584Sdim 91226584Sdim /// Routines that handle operands which add machine relocations which are 92226584Sdim /// fixed up by the relocation stage. 93226584Sdim void emitGlobalAddress(const GlobalValue *GV, unsigned Reloc, 94226584Sdim bool MayNeedFarStub) const; 95226584Sdim void emitExternalSymbolAddress(const char *ES, unsigned Reloc) const; 96226584Sdim void emitConstPoolAddress(unsigned CPI, unsigned Reloc) const; 97226584Sdim void emitJumpTableAddress(unsigned JTIndex, unsigned Reloc) const; 98226584Sdim void emitMachineBasicBlock(MachineBasicBlock *BB, unsigned Reloc) const; 99226584Sdim 100226584Sdim /// getMachineOpValue - Return binary encoding of operand. If the machine 101226584Sdim /// operand requires relocation, record the relocation and return zero. 102226584Sdim unsigned getMachineOpValue(const MachineInstr &MI, 103226584Sdim const MachineOperand &MO) const; 104226584Sdim 105226584Sdim unsigned getRelocation(const MachineInstr &MI, 106226584Sdim const MachineOperand &MO) const; 107226584Sdim 108228379Sdim unsigned getMemEncoding(const MachineInstr &MI, unsigned OpNo) const; 109228379Sdim unsigned getSizeExtEncoding(const MachineInstr &MI, unsigned OpNo) const; 110228379Sdim unsigned getSizeInsEncoding(const MachineInstr &MI, unsigned OpNo) const; 111226584Sdim }; 112226584Sdim} 113226584Sdim 114226584Sdimchar MipsCodeEmitter::ID = 0; 115226584Sdim 116226584Sdimbool MipsCodeEmitter::runOnMachineFunction(MachineFunction &MF) { 117226584Sdim JTI = ((MipsTargetMachine&) MF.getTarget()).getJITInfo(); 118226584Sdim II = ((const MipsTargetMachine&) MF.getTarget()).getInstrInfo(); 119226584Sdim TD = ((const MipsTargetMachine&) MF.getTarget()).getTargetData(); 120226584Sdim Subtarget = &TM.getSubtarget<MipsSubtarget> (); 121226584Sdim MCPEs = &MF.getConstantPool()->getConstants(); 122226584Sdim MJTEs = 0; 123226584Sdim if (MF.getJumpTableInfo()) MJTEs = &MF.getJumpTableInfo()->getJumpTables(); 124226584Sdim JTI->Initialize(MF, IsPIC); 125226584Sdim MCE.setModuleInfo(&getAnalysis<MachineModuleInfo> ()); 126226584Sdim 127226584Sdim do { 128226584Sdim DEBUG(errs() << "JITTing function '" 129226584Sdim << MF.getFunction()->getName() << "'\n"); 130226584Sdim MCE.startFunction(MF); 131226584Sdim 132226584Sdim for (MachineFunction::iterator MBB = MF.begin(), E = MF.end(); 133226584Sdim MBB != E; ++MBB){ 134226584Sdim MCE.StartMachineBasicBlock(MBB); 135226584Sdim for (MachineBasicBlock::const_iterator I = MBB->begin(), E = MBB->end(); 136226584Sdim I != E; ++I) 137226584Sdim emitInstruction(*I); 138226584Sdim } 139226584Sdim } while (MCE.finishFunction(MF)); 140226584Sdim 141226584Sdim return false; 142226584Sdim} 143226584Sdim 144226584Sdimunsigned MipsCodeEmitter::getRelocation(const MachineInstr &MI, 145226584Sdim const MachineOperand &MO) const { 146226584Sdim // NOTE: This relocations are for static. 147226584Sdim uint64_t TSFlags = MI.getDesc().TSFlags; 148226584Sdim uint64_t Form = TSFlags & MipsII::FormMask; 149226584Sdim if (Form == MipsII::FrmJ) 150226584Sdim return Mips::reloc_mips_26; 151226584Sdim if ((Form == MipsII::FrmI || Form == MipsII::FrmFI) 152226584Sdim && MI.getDesc().isBranch()) 153226584Sdim return Mips::reloc_mips_branch; 154226584Sdim if (Form == MipsII::FrmI && MI.getOpcode() == Mips::LUi) 155226584Sdim return Mips::reloc_mips_hi; 156226584Sdim return Mips::reloc_mips_lo; 157226584Sdim} 158226584Sdim 159228379Sdimunsigned MipsCodeEmitter::getMemEncoding(const MachineInstr &MI, 160228379Sdim unsigned OpNo) const { 161228379Sdim // Base register is encoded in bits 20-16, offset is encoded in bits 15-0. 162228379Sdim assert(MI.getOperand(OpNo).isReg()); 163228379Sdim unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo)) << 16; 164228379Sdim return 165228379Sdim (getMachineOpValue(MI, MI.getOperand(OpNo+1)) & 0xFFFF) | RegBits; 166228379Sdim} 167228379Sdim 168228379Sdimunsigned MipsCodeEmitter::getSizeExtEncoding(const MachineInstr &MI, 169228379Sdim unsigned OpNo) const { 170228379Sdim // size is encoded as size-1. 171228379Sdim return getMachineOpValue(MI, MI.getOperand(OpNo)) - 1; 172228379Sdim} 173228379Sdim 174228379Sdimunsigned MipsCodeEmitter::getSizeInsEncoding(const MachineInstr &MI, 175228379Sdim unsigned OpNo) const { 176228379Sdim // size is encoded as pos+size-1. 177228379Sdim return getMachineOpValue(MI, MI.getOperand(OpNo-1)) + 178228379Sdim getMachineOpValue(MI, MI.getOperand(OpNo)) - 1; 179228379Sdim} 180228379Sdim 181226584Sdim/// getMachineOpValue - Return binary encoding of operand. If the machine 182226584Sdim/// operand requires relocation, record the relocation and return zero. 183226584Sdimunsigned MipsCodeEmitter::getMachineOpValue(const MachineInstr &MI, 184226584Sdim const MachineOperand &MO) const { 185226584Sdim if (MO.isReg()) 186226584Sdim return MipsRegisterInfo::getRegisterNumbering(MO.getReg()); 187226584Sdim else if (MO.isImm()) 188226584Sdim return static_cast<unsigned>(MO.getImm()); 189226584Sdim else if (MO.isGlobal()) 190226584Sdim emitGlobalAddress(MO.getGlobal(), getRelocation(MI, MO), true); 191226584Sdim else if (MO.isSymbol()) 192226584Sdim emitExternalSymbolAddress(MO.getSymbolName(), getRelocation(MI, MO)); 193226584Sdim else if (MO.isCPI()) 194226584Sdim emitConstPoolAddress(MO.getIndex(), getRelocation(MI, MO)); 195226584Sdim else if (MO.isJTI()) 196226584Sdim emitJumpTableAddress(MO.getIndex(), getRelocation(MI, MO)); 197226584Sdim else if (MO.isMBB()) 198226584Sdim emitMachineBasicBlock(MO.getMBB(), getRelocation(MI, MO)); 199226584Sdim else 200226584Sdim llvm_unreachable("Unable to encode MachineOperand!"); 201226584Sdim return 0; 202226584Sdim} 203226584Sdim 204226584Sdimvoid MipsCodeEmitter::emitGlobalAddress(const GlobalValue *GV, unsigned Reloc, 205226584Sdim bool MayNeedFarStub) const { 206226584Sdim MCE.addRelocation(MachineRelocation::getGV(MCE.getCurrentPCOffset(), Reloc, 207226584Sdim const_cast<GlobalValue *>(GV), 0, MayNeedFarStub)); 208226584Sdim} 209226584Sdim 210226584Sdimvoid MipsCodeEmitter:: 211226584SdimemitExternalSymbolAddress(const char *ES, unsigned Reloc) const { 212226584Sdim MCE.addRelocation(MachineRelocation::getExtSym(MCE.getCurrentPCOffset(), 213226584Sdim Reloc, ES, 0, 0, false)); 214226584Sdim} 215226584Sdim 216226584Sdimvoid MipsCodeEmitter::emitConstPoolAddress(unsigned CPI, unsigned Reloc) const { 217226584Sdim MCE.addRelocation(MachineRelocation::getConstPool(MCE.getCurrentPCOffset(), 218226584Sdim Reloc, CPI, 0, false)); 219226584Sdim} 220226584Sdim 221226584Sdimvoid MipsCodeEmitter:: 222226584SdimemitJumpTableAddress(unsigned JTIndex, unsigned Reloc) const { 223226584Sdim MCE.addRelocation(MachineRelocation::getJumpTable(MCE.getCurrentPCOffset(), 224226584Sdim Reloc, JTIndex, 0, false)); 225226584Sdim} 226226584Sdim 227226584Sdimvoid MipsCodeEmitter::emitMachineBasicBlock(MachineBasicBlock *BB, 228226584Sdim unsigned Reloc) const { 229226584Sdim MCE.addRelocation(MachineRelocation::getBB(MCE.getCurrentPCOffset(), 230226584Sdim Reloc, BB)); 231226584Sdim} 232226584Sdim 233226584Sdimvoid MipsCodeEmitter::emitInstruction(const MachineInstr &MI) { 234226584Sdim DEBUG(errs() << "JIT: " << (void*)MCE.getCurrentPCValue() << ":\t" << MI); 235226584Sdim 236226584Sdim MCE.processDebugLoc(MI.getDebugLoc(), true); 237226584Sdim 238226584Sdim // Skip pseudo instructions. 239226584Sdim if ((MI.getDesc().TSFlags & MipsII::FormMask) == MipsII::Pseudo) 240226584Sdim return; 241226584Sdim 242226584Sdim ++NumEmitted; // Keep track of the # of mi's emitted 243226584Sdim 244226584Sdim switch (MI.getOpcode()) { 245226584Sdim default: 246226584Sdim emitWordLE(getBinaryCodeForInstr(MI)); 247226584Sdim break; 248226584Sdim } 249226584Sdim 250226584Sdim MCE.processDebugLoc(MI.getDebugLoc(), false); 251226584Sdim} 252226584Sdim 253226584Sdimvoid MipsCodeEmitter::emitWordLE(unsigned Word) { 254226584Sdim DEBUG(errs() << " 0x"; 255226584Sdim errs().write_hex(Word) << "\n"); 256226584Sdim MCE.emitWordLE(Word); 257226584Sdim} 258226584Sdim 259226584Sdim/// createMipsJITCodeEmitterPass - Return a pass that emits the collected Mips 260226584Sdim/// code to the specified MCE object. 261226584SdimFunctionPass *llvm::createMipsJITCodeEmitterPass(MipsTargetMachine &TM, 262226584Sdim JITCodeEmitter &JCE) { 263226584Sdim return new MipsCodeEmitter(TM, JCE); 264226584Sdim} 265226584Sdim 266228379Sdim#include "MipsGenCodeEmitter.inc" 267