1234353Sdim//===-- 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" 17249423Sdim#include "MCTargetDesc/MipsBaseInfo.h" 18226584Sdim#include "MipsInstrInfo.h" 19226584Sdim#include "MipsRelocations.h" 20226584Sdim#include "MipsSubtarget.h" 21226584Sdim#include "MipsTargetMachine.h" 22234353Sdim#include "llvm/ADT/Statistic.h" 23226584Sdim#include "llvm/CodeGen/JITCodeEmitter.h" 24226584Sdim#include "llvm/CodeGen/MachineConstantPool.h" 25226584Sdim#include "llvm/CodeGen/MachineFunctionPass.h" 26226584Sdim#include "llvm/CodeGen/MachineInstr.h" 27226584Sdim#include "llvm/CodeGen/MachineJumpTableInfo.h" 28249423Sdim#include "llvm/CodeGen/MachineInstrBuilder.h" 29226584Sdim#include "llvm/CodeGen/MachineModuleInfo.h" 30234353Sdim#include "llvm/CodeGen/MachineOperand.h" 31226584Sdim#include "llvm/CodeGen/Passes.h" 32249423Sdim#include "llvm/IR/Constants.h" 33249423Sdim#include "llvm/IR/DerivedTypes.h" 34234353Sdim#include "llvm/PassManager.h" 35226584Sdim#include "llvm/Support/Debug.h" 36226584Sdim#include "llvm/Support/ErrorHandling.h" 37226584Sdim#include "llvm/Support/raw_ostream.h" 38226584Sdim#ifndef NDEBUG 39226584Sdim#include <iomanip> 40226584Sdim#endif 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; 51243830Sdim const DataLayout *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 66249423Sdimpublic: 67249423Sdim MipsCodeEmitter(TargetMachine &tm, JITCodeEmitter &mce) 68249423Sdim : MachineFunctionPass(ID), JTI(0), 69249423Sdim II((const MipsInstrInfo *) tm.getInstrInfo()), TD(tm.getDataLayout()), 70249423Sdim TM(tm), MCE(mce), MCPEs(0), MJTEs(0), 71249423Sdim IsPIC(TM.getRelocationModel() == Reloc::PIC_) {} 72226584Sdim 73249423Sdim bool runOnMachineFunction(MachineFunction &MF); 74226584Sdim 75249423Sdim virtual const char *getPassName() const { 76249423Sdim return "Mips Machine Code Emitter"; 77249423Sdim } 78226584Sdim 79249423Sdim /// getBinaryCodeForInstr - This function, generated by the 80249423Sdim /// CodeEmitterGenerator using TableGen, produces the binary encoding for 81249423Sdim /// machine instructions. 82249423Sdim uint64_t getBinaryCodeForInstr(const MachineInstr &MI) const; 83226584Sdim 84249423Sdim void emitInstruction(MachineBasicBlock::instr_iterator MI, 85249423Sdim MachineBasicBlock &MBB); 86226584Sdim 87249423Sdimprivate: 88226584Sdim 89249423Sdim void emitWord(unsigned Word); 90226584Sdim 91249423Sdim /// Routines that handle operands which add machine relocations which are 92249423Sdim /// fixed up by the relocation stage. 93249423Sdim void emitGlobalAddress(const GlobalValue *GV, unsigned Reloc, 94249423Sdim bool MayNeedFarStub) const; 95249423Sdim void emitExternalSymbolAddress(const char *ES, unsigned Reloc) const; 96249423Sdim void emitConstPoolAddress(unsigned CPI, unsigned Reloc) const; 97249423Sdim void emitJumpTableAddress(unsigned JTIndex, unsigned Reloc) const; 98249423Sdim void emitMachineBasicBlock(MachineBasicBlock *BB, unsigned Reloc) const; 99226584Sdim 100249423Sdim /// getMachineOpValue - Return binary encoding of operand. If the machine 101249423Sdim /// operand requires relocation, record the relocation and return zero. 102249423Sdim unsigned getMachineOpValue(const MachineInstr &MI, 103249423Sdim const MachineOperand &MO) const; 104226584Sdim 105249423Sdim unsigned getRelocation(const MachineInstr &MI, 106249423Sdim const MachineOperand &MO) const; 107226584Sdim 108249423Sdim unsigned getJumpTargetOpValue(const MachineInstr &MI, unsigned OpNo) const; 109234353Sdim 110249423Sdim unsigned getBranchTargetOpValue(const MachineInstr &MI, unsigned OpNo) const; 111249423Sdim unsigned getMemEncoding(const MachineInstr &MI, unsigned OpNo) const; 112249423Sdim unsigned getSizeExtEncoding(const MachineInstr &MI, unsigned OpNo) const; 113249423Sdim unsigned getSizeInsEncoding(const MachineInstr &MI, unsigned OpNo) const; 114234353Sdim 115249423Sdim void emitGlobalAddressUnaligned(const GlobalValue *GV, unsigned Reloc, 116249423Sdim int Offset) const; 117249423Sdim 118249423Sdim /// Expand pseudo instructions with accumulator register operands. 119251662Sdim void expandACCInstr(MachineBasicBlock::instr_iterator MI, 120249423Sdim MachineBasicBlock &MBB, unsigned Opc) const; 121249423Sdim 122249423Sdim /// \brief Expand pseudo instruction. Return true if MI was expanded. 123249423Sdim bool expandPseudos(MachineBasicBlock::instr_iterator &MI, 124249423Sdim MachineBasicBlock &MBB) const; 125249423Sdim}; 126226584Sdim} 127226584Sdim 128226584Sdimchar MipsCodeEmitter::ID = 0; 129226584Sdim 130226584Sdimbool MipsCodeEmitter::runOnMachineFunction(MachineFunction &MF) { 131249423Sdim MipsTargetMachine &Target = static_cast<MipsTargetMachine &>( 132249423Sdim const_cast<TargetMachine &>(MF.getTarget())); 133249423Sdim 134249423Sdim JTI = Target.getJITInfo(); 135249423Sdim II = Target.getInstrInfo(); 136249423Sdim TD = Target.getDataLayout(); 137226584Sdim Subtarget = &TM.getSubtarget<MipsSubtarget> (); 138226584Sdim MCPEs = &MF.getConstantPool()->getConstants(); 139226584Sdim MJTEs = 0; 140226584Sdim if (MF.getJumpTableInfo()) MJTEs = &MF.getJumpTableInfo()->getJumpTables(); 141244628Sdim JTI->Initialize(MF, IsPIC, Subtarget->isLittle()); 142226584Sdim MCE.setModuleInfo(&getAnalysis<MachineModuleInfo> ()); 143226584Sdim 144226584Sdim do { 145226584Sdim DEBUG(errs() << "JITTing function '" 146243830Sdim << MF.getName() << "'\n"); 147226584Sdim MCE.startFunction(MF); 148226584Sdim 149226584Sdim for (MachineFunction::iterator MBB = MF.begin(), E = MF.end(); 150226584Sdim MBB != E; ++MBB){ 151226584Sdim MCE.StartMachineBasicBlock(MBB); 152239462Sdim for (MachineBasicBlock::instr_iterator I = MBB->instr_begin(), 153249423Sdim E = MBB->instr_end(); I != E;) 154249423Sdim emitInstruction(*I++, *MBB); 155226584Sdim } 156226584Sdim } while (MCE.finishFunction(MF)); 157226584Sdim 158226584Sdim return false; 159226584Sdim} 160226584Sdim 161226584Sdimunsigned MipsCodeEmitter::getRelocation(const MachineInstr &MI, 162226584Sdim const MachineOperand &MO) const { 163226584Sdim // NOTE: This relocations are for static. 164226584Sdim uint64_t TSFlags = MI.getDesc().TSFlags; 165226584Sdim uint64_t Form = TSFlags & MipsII::FormMask; 166226584Sdim if (Form == MipsII::FrmJ) 167226584Sdim return Mips::reloc_mips_26; 168226584Sdim if ((Form == MipsII::FrmI || Form == MipsII::FrmFI) 169234353Sdim && MI.isBranch()) 170234353Sdim return Mips::reloc_mips_pc16; 171226584Sdim if (Form == MipsII::FrmI && MI.getOpcode() == Mips::LUi) 172226584Sdim return Mips::reloc_mips_hi; 173226584Sdim return Mips::reloc_mips_lo; 174226584Sdim} 175226584Sdim 176234353Sdimunsigned MipsCodeEmitter::getJumpTargetOpValue(const MachineInstr &MI, 177234353Sdim unsigned OpNo) const { 178234353Sdim MachineOperand MO = MI.getOperand(OpNo); 179234353Sdim if (MO.isGlobal()) 180234353Sdim emitGlobalAddress(MO.getGlobal(), getRelocation(MI, MO), true); 181234353Sdim else if (MO.isSymbol()) 182234353Sdim emitExternalSymbolAddress(MO.getSymbolName(), getRelocation(MI, MO)); 183234353Sdim else if (MO.isMBB()) 184234353Sdim emitMachineBasicBlock(MO.getMBB(), getRelocation(MI, MO)); 185234353Sdim else 186234353Sdim llvm_unreachable("Unexpected jump target operand kind."); 187234353Sdim return 0; 188234353Sdim} 189234353Sdim 190234353Sdimunsigned MipsCodeEmitter::getBranchTargetOpValue(const MachineInstr &MI, 191234353Sdim unsigned OpNo) const { 192234353Sdim MachineOperand MO = MI.getOperand(OpNo); 193234353Sdim emitMachineBasicBlock(MO.getMBB(), getRelocation(MI, MO)); 194234353Sdim return 0; 195234353Sdim} 196234353Sdim 197228379Sdimunsigned MipsCodeEmitter::getMemEncoding(const MachineInstr &MI, 198234353Sdim unsigned OpNo) const { 199228379Sdim // Base register is encoded in bits 20-16, offset is encoded in bits 15-0. 200228379Sdim assert(MI.getOperand(OpNo).isReg()); 201228379Sdim unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo)) << 16; 202234353Sdim return (getMachineOpValue(MI, MI.getOperand(OpNo+1)) & 0xFFFF) | RegBits; 203228379Sdim} 204228379Sdim 205228379Sdimunsigned MipsCodeEmitter::getSizeExtEncoding(const MachineInstr &MI, 206234353Sdim unsigned OpNo) const { 207228379Sdim // size is encoded as size-1. 208228379Sdim return getMachineOpValue(MI, MI.getOperand(OpNo)) - 1; 209228379Sdim} 210228379Sdim 211228379Sdimunsigned MipsCodeEmitter::getSizeInsEncoding(const MachineInstr &MI, 212234353Sdim unsigned OpNo) const { 213228379Sdim // size is encoded as pos+size-1. 214228379Sdim return getMachineOpValue(MI, MI.getOperand(OpNo-1)) + 215228379Sdim getMachineOpValue(MI, MI.getOperand(OpNo)) - 1; 216228379Sdim} 217228379Sdim 218226584Sdim/// getMachineOpValue - Return binary encoding of operand. If the machine 219226584Sdim/// operand requires relocation, record the relocation and return zero. 220226584Sdimunsigned MipsCodeEmitter::getMachineOpValue(const MachineInstr &MI, 221234353Sdim const MachineOperand &MO) const { 222226584Sdim if (MO.isReg()) 223249423Sdim return TM.getRegisterInfo()->getEncodingValue(MO.getReg()); 224226584Sdim else if (MO.isImm()) 225226584Sdim return static_cast<unsigned>(MO.getImm()); 226243830Sdim else if (MO.isGlobal()) 227243830Sdim emitGlobalAddress(MO.getGlobal(), getRelocation(MI, MO), true); 228243830Sdim else if (MO.isSymbol()) 229226584Sdim emitExternalSymbolAddress(MO.getSymbolName(), getRelocation(MI, MO)); 230226584Sdim else if (MO.isCPI()) 231226584Sdim emitConstPoolAddress(MO.getIndex(), getRelocation(MI, MO)); 232226584Sdim else if (MO.isJTI()) 233226584Sdim emitJumpTableAddress(MO.getIndex(), getRelocation(MI, MO)); 234226584Sdim else if (MO.isMBB()) 235226584Sdim emitMachineBasicBlock(MO.getMBB(), getRelocation(MI, MO)); 236226584Sdim else 237226584Sdim llvm_unreachable("Unable to encode MachineOperand!"); 238226584Sdim return 0; 239226584Sdim} 240226584Sdim 241226584Sdimvoid MipsCodeEmitter::emitGlobalAddress(const GlobalValue *GV, unsigned Reloc, 242234353Sdim bool MayNeedFarStub) const { 243226584Sdim MCE.addRelocation(MachineRelocation::getGV(MCE.getCurrentPCOffset(), Reloc, 244234353Sdim const_cast<GlobalValue *>(GV), 0, 245234353Sdim MayNeedFarStub)); 246226584Sdim} 247226584Sdim 248234353Sdimvoid MipsCodeEmitter::emitGlobalAddressUnaligned(const GlobalValue *GV, 249234353Sdim unsigned Reloc, int Offset) const { 250234353Sdim MCE.addRelocation(MachineRelocation::getGV(MCE.getCurrentPCOffset(), Reloc, 251234353Sdim const_cast<GlobalValue *>(GV), 0, false)); 252234353Sdim MCE.addRelocation(MachineRelocation::getGV(MCE.getCurrentPCOffset() + Offset, 253234353Sdim Reloc, const_cast<GlobalValue *>(GV), 0, false)); 254234353Sdim} 255234353Sdim 256226584Sdimvoid MipsCodeEmitter:: 257226584SdimemitExternalSymbolAddress(const char *ES, unsigned Reloc) const { 258226584Sdim MCE.addRelocation(MachineRelocation::getExtSym(MCE.getCurrentPCOffset(), 259239462Sdim Reloc, ES, 0, 0)); 260226584Sdim} 261226584Sdim 262226584Sdimvoid MipsCodeEmitter::emitConstPoolAddress(unsigned CPI, unsigned Reloc) const { 263226584Sdim MCE.addRelocation(MachineRelocation::getConstPool(MCE.getCurrentPCOffset(), 264226584Sdim Reloc, CPI, 0, false)); 265226584Sdim} 266226584Sdim 267226584Sdimvoid MipsCodeEmitter:: 268226584SdimemitJumpTableAddress(unsigned JTIndex, unsigned Reloc) const { 269226584Sdim MCE.addRelocation(MachineRelocation::getJumpTable(MCE.getCurrentPCOffset(), 270226584Sdim Reloc, JTIndex, 0, false)); 271226584Sdim} 272226584Sdim 273226584Sdimvoid MipsCodeEmitter::emitMachineBasicBlock(MachineBasicBlock *BB, 274234353Sdim unsigned Reloc) const { 275226584Sdim MCE.addRelocation(MachineRelocation::getBB(MCE.getCurrentPCOffset(), 276226584Sdim Reloc, BB)); 277226584Sdim} 278226584Sdim 279249423Sdimvoid MipsCodeEmitter::emitInstruction(MachineBasicBlock::instr_iterator MI, 280249423Sdim MachineBasicBlock &MBB) { 281249423Sdim DEBUG(errs() << "JIT: " << (void*)MCE.getCurrentPCValue() << ":\t" << *MI); 282226584Sdim 283249423Sdim // Expand pseudo instruction. Skip if MI was not expanded. 284249423Sdim if (((MI->getDesc().TSFlags & MipsII::FormMask) == MipsII::Pseudo) && 285249423Sdim !expandPseudos(MI, MBB)) 286226584Sdim return; 287226584Sdim 288249423Sdim MCE.processDebugLoc(MI->getDebugLoc(), true); 289249423Sdim 290249423Sdim emitWord(getBinaryCodeForInstr(*MI)); 291243830Sdim ++NumEmitted; // Keep track of the # of mi's emitted 292226584Sdim 293249423Sdim MCE.processDebugLoc(MI->getDebugLoc(), false); 294226584Sdim} 295226584Sdim 296244628Sdimvoid MipsCodeEmitter::emitWord(unsigned Word) { 297226584Sdim DEBUG(errs() << " 0x"; 298226584Sdim errs().write_hex(Word) << "\n"); 299244628Sdim if (Subtarget->isLittle()) 300244628Sdim MCE.emitWordLE(Word); 301244628Sdim else 302244628Sdim MCE.emitWordBE(Word); 303226584Sdim} 304226584Sdim 305251662Sdimvoid MipsCodeEmitter::expandACCInstr(MachineBasicBlock::instr_iterator MI, 306249423Sdim MachineBasicBlock &MBB, 307249423Sdim unsigned Opc) const { 308249423Sdim // Expand "pseudomult $ac0, $t0, $t1" to "mult $t0, $t1". 309249423Sdim BuildMI(MBB, &*MI, MI->getDebugLoc(), II->get(Opc)) 310249423Sdim .addReg(MI->getOperand(1).getReg()).addReg(MI->getOperand(2).getReg()); 311249423Sdim} 312249423Sdim 313249423Sdimbool MipsCodeEmitter::expandPseudos(MachineBasicBlock::instr_iterator &MI, 314249423Sdim MachineBasicBlock &MBB) const { 315249423Sdim switch (MI->getOpcode()) { 316249423Sdim case Mips::NOP: 317249423Sdim BuildMI(MBB, &*MI, MI->getDebugLoc(), II->get(Mips::SLL), Mips::ZERO) 318249423Sdim .addReg(Mips::ZERO).addImm(0); 319249423Sdim break; 320249423Sdim case Mips::JALRPseudo: 321249423Sdim BuildMI(MBB, &*MI, MI->getDebugLoc(), II->get(Mips::JALR), Mips::RA) 322249423Sdim .addReg(MI->getOperand(0).getReg()); 323249423Sdim break; 324249423Sdim case Mips::PseudoMULT: 325249423Sdim expandACCInstr(MI, MBB, Mips::MULT); 326249423Sdim break; 327249423Sdim case Mips::PseudoMULTu: 328249423Sdim expandACCInstr(MI, MBB, Mips::MULTu); 329249423Sdim break; 330249423Sdim case Mips::PseudoSDIV: 331249423Sdim expandACCInstr(MI, MBB, Mips::SDIV); 332249423Sdim break; 333249423Sdim case Mips::PseudoUDIV: 334249423Sdim expandACCInstr(MI, MBB, Mips::UDIV); 335249423Sdim break; 336249423Sdim case Mips::PseudoMADD: 337249423Sdim expandACCInstr(MI, MBB, Mips::MADD); 338249423Sdim break; 339249423Sdim case Mips::PseudoMADDU: 340249423Sdim expandACCInstr(MI, MBB, Mips::MADDU); 341249423Sdim break; 342249423Sdim case Mips::PseudoMSUB: 343249423Sdim expandACCInstr(MI, MBB, Mips::MSUB); 344249423Sdim break; 345249423Sdim case Mips::PseudoMSUBU: 346249423Sdim expandACCInstr(MI, MBB, Mips::MSUBU); 347249423Sdim break; 348249423Sdim default: 349249423Sdim return false; 350249423Sdim } 351249423Sdim 352249423Sdim (MI--)->eraseFromBundle(); 353249423Sdim return true; 354249423Sdim} 355249423Sdim 356226584Sdim/// createMipsJITCodeEmitterPass - Return a pass that emits the collected Mips 357226584Sdim/// code to the specified MCE object. 358226584SdimFunctionPass *llvm::createMipsJITCodeEmitterPass(MipsTargetMachine &TM, 359234353Sdim JITCodeEmitter &JCE) { 360226584Sdim return new MipsCodeEmitter(TM, JCE); 361226584Sdim} 362226584Sdim 363228379Sdim#include "MipsGenCodeEmitter.inc" 364