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) 68263508Sdim : MachineFunctionPass(ID), JTI(0), II(0), TD(0), 69249423Sdim TM(tm), MCE(mce), MCPEs(0), MJTEs(0), 70249423Sdim IsPIC(TM.getRelocationModel() == Reloc::PIC_) {} 71226584Sdim 72249423Sdim bool runOnMachineFunction(MachineFunction &MF); 73226584Sdim 74249423Sdim virtual const char *getPassName() const { 75249423Sdim return "Mips Machine Code Emitter"; 76249423Sdim } 77226584Sdim 78249423Sdim /// getBinaryCodeForInstr - This function, generated by the 79249423Sdim /// CodeEmitterGenerator using TableGen, produces the binary encoding for 80249423Sdim /// machine instructions. 81249423Sdim uint64_t getBinaryCodeForInstr(const MachineInstr &MI) const; 82226584Sdim 83249423Sdim void emitInstruction(MachineBasicBlock::instr_iterator MI, 84249423Sdim MachineBasicBlock &MBB); 85226584Sdim 86249423Sdimprivate: 87226584Sdim 88249423Sdim void emitWord(unsigned Word); 89226584Sdim 90249423Sdim /// Routines that handle operands which add machine relocations which are 91249423Sdim /// fixed up by the relocation stage. 92249423Sdim void emitGlobalAddress(const GlobalValue *GV, unsigned Reloc, 93249423Sdim bool MayNeedFarStub) const; 94249423Sdim void emitExternalSymbolAddress(const char *ES, unsigned Reloc) const; 95249423Sdim void emitConstPoolAddress(unsigned CPI, unsigned Reloc) const; 96249423Sdim void emitJumpTableAddress(unsigned JTIndex, unsigned Reloc) const; 97249423Sdim void emitMachineBasicBlock(MachineBasicBlock *BB, unsigned Reloc) const; 98226584Sdim 99249423Sdim /// getMachineOpValue - Return binary encoding of operand. If the machine 100249423Sdim /// operand requires relocation, record the relocation and return zero. 101249423Sdim unsigned getMachineOpValue(const MachineInstr &MI, 102249423Sdim const MachineOperand &MO) const; 103226584Sdim 104249423Sdim unsigned getRelocation(const MachineInstr &MI, 105249423Sdim const MachineOperand &MO) const; 106226584Sdim 107249423Sdim unsigned getJumpTargetOpValue(const MachineInstr &MI, unsigned OpNo) const; 108263508Sdim unsigned getJumpTargetOpValueMM(const MachineInstr &MI, unsigned OpNo) const; 109263508Sdim unsigned getBranchTargetOpValueMM(const MachineInstr &MI, 110263508Sdim unsigned OpNo) const; 111234353Sdim 112249423Sdim unsigned getBranchTargetOpValue(const MachineInstr &MI, unsigned OpNo) const; 113249423Sdim unsigned getMemEncoding(const MachineInstr &MI, unsigned OpNo) const; 114263508Sdim unsigned getMemEncodingMMImm12(const MachineInstr &MI, unsigned OpNo) const; 115249423Sdim unsigned getSizeExtEncoding(const MachineInstr &MI, unsigned OpNo) const; 116249423Sdim unsigned getSizeInsEncoding(const MachineInstr &MI, unsigned OpNo) const; 117263508Sdim unsigned getLSAImmEncoding(const MachineInstr &MI, unsigned OpNo) const; 118234353Sdim 119249423Sdim void emitGlobalAddressUnaligned(const GlobalValue *GV, unsigned Reloc, 120249423Sdim int Offset) const; 121249423Sdim 122249423Sdim /// Expand pseudo instructions with accumulator register operands. 123251662Sdim void expandACCInstr(MachineBasicBlock::instr_iterator MI, 124249423Sdim MachineBasicBlock &MBB, unsigned Opc) const; 125249423Sdim 126249423Sdim /// \brief Expand pseudo instruction. Return true if MI was expanded. 127249423Sdim bool expandPseudos(MachineBasicBlock::instr_iterator &MI, 128249423Sdim MachineBasicBlock &MBB) const; 129249423Sdim}; 130226584Sdim} 131226584Sdim 132226584Sdimchar MipsCodeEmitter::ID = 0; 133226584Sdim 134226584Sdimbool MipsCodeEmitter::runOnMachineFunction(MachineFunction &MF) { 135249423Sdim MipsTargetMachine &Target = static_cast<MipsTargetMachine &>( 136249423Sdim const_cast<TargetMachine &>(MF.getTarget())); 137249423Sdim 138249423Sdim JTI = Target.getJITInfo(); 139249423Sdim II = Target.getInstrInfo(); 140249423Sdim TD = Target.getDataLayout(); 141226584Sdim Subtarget = &TM.getSubtarget<MipsSubtarget> (); 142226584Sdim MCPEs = &MF.getConstantPool()->getConstants(); 143226584Sdim MJTEs = 0; 144226584Sdim if (MF.getJumpTableInfo()) MJTEs = &MF.getJumpTableInfo()->getJumpTables(); 145244628Sdim JTI->Initialize(MF, IsPIC, Subtarget->isLittle()); 146226584Sdim MCE.setModuleInfo(&getAnalysis<MachineModuleInfo> ()); 147226584Sdim 148226584Sdim do { 149226584Sdim DEBUG(errs() << "JITTing function '" 150243830Sdim << MF.getName() << "'\n"); 151226584Sdim MCE.startFunction(MF); 152226584Sdim 153226584Sdim for (MachineFunction::iterator MBB = MF.begin(), E = MF.end(); 154226584Sdim MBB != E; ++MBB){ 155226584Sdim MCE.StartMachineBasicBlock(MBB); 156239462Sdim for (MachineBasicBlock::instr_iterator I = MBB->instr_begin(), 157249423Sdim E = MBB->instr_end(); I != E;) 158249423Sdim emitInstruction(*I++, *MBB); 159226584Sdim } 160226584Sdim } while (MCE.finishFunction(MF)); 161226584Sdim 162226584Sdim return false; 163226584Sdim} 164226584Sdim 165226584Sdimunsigned MipsCodeEmitter::getRelocation(const MachineInstr &MI, 166226584Sdim const MachineOperand &MO) const { 167226584Sdim // NOTE: This relocations are for static. 168226584Sdim uint64_t TSFlags = MI.getDesc().TSFlags; 169226584Sdim uint64_t Form = TSFlags & MipsII::FormMask; 170226584Sdim if (Form == MipsII::FrmJ) 171226584Sdim return Mips::reloc_mips_26; 172226584Sdim if ((Form == MipsII::FrmI || Form == MipsII::FrmFI) 173234353Sdim && MI.isBranch()) 174234353Sdim return Mips::reloc_mips_pc16; 175226584Sdim if (Form == MipsII::FrmI && MI.getOpcode() == Mips::LUi) 176226584Sdim return Mips::reloc_mips_hi; 177226584Sdim return Mips::reloc_mips_lo; 178226584Sdim} 179226584Sdim 180234353Sdimunsigned MipsCodeEmitter::getJumpTargetOpValue(const MachineInstr &MI, 181234353Sdim unsigned OpNo) const { 182234353Sdim MachineOperand MO = MI.getOperand(OpNo); 183234353Sdim if (MO.isGlobal()) 184234353Sdim emitGlobalAddress(MO.getGlobal(), getRelocation(MI, MO), true); 185234353Sdim else if (MO.isSymbol()) 186234353Sdim emitExternalSymbolAddress(MO.getSymbolName(), getRelocation(MI, MO)); 187234353Sdim else if (MO.isMBB()) 188234353Sdim emitMachineBasicBlock(MO.getMBB(), getRelocation(MI, MO)); 189234353Sdim else 190234353Sdim llvm_unreachable("Unexpected jump target operand kind."); 191234353Sdim return 0; 192234353Sdim} 193234353Sdim 194263508Sdimunsigned MipsCodeEmitter::getJumpTargetOpValueMM(const MachineInstr &MI, 195263508Sdim unsigned OpNo) const { 196263508Sdim llvm_unreachable("Unimplemented function."); 197263508Sdim return 0; 198263508Sdim} 199263508Sdim 200263508Sdimunsigned MipsCodeEmitter::getBranchTargetOpValueMM(const MachineInstr &MI, 201263508Sdim unsigned OpNo) const { 202263508Sdim llvm_unreachable("Unimplemented function."); 203263508Sdim return 0; 204263508Sdim} 205263508Sdim 206234353Sdimunsigned MipsCodeEmitter::getBranchTargetOpValue(const MachineInstr &MI, 207234353Sdim unsigned OpNo) const { 208234353Sdim MachineOperand MO = MI.getOperand(OpNo); 209234353Sdim emitMachineBasicBlock(MO.getMBB(), getRelocation(MI, MO)); 210234353Sdim return 0; 211234353Sdim} 212234353Sdim 213228379Sdimunsigned MipsCodeEmitter::getMemEncoding(const MachineInstr &MI, 214234353Sdim unsigned OpNo) const { 215228379Sdim // Base register is encoded in bits 20-16, offset is encoded in bits 15-0. 216228379Sdim assert(MI.getOperand(OpNo).isReg()); 217228379Sdim unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo)) << 16; 218234353Sdim return (getMachineOpValue(MI, MI.getOperand(OpNo+1)) & 0xFFFF) | RegBits; 219228379Sdim} 220228379Sdim 221263508Sdimunsigned MipsCodeEmitter::getMemEncodingMMImm12(const MachineInstr &MI, 222263508Sdim unsigned OpNo) const { 223263508Sdim llvm_unreachable("Unimplemented function."); 224263508Sdim return 0; 225263508Sdim} 226263508Sdim 227228379Sdimunsigned MipsCodeEmitter::getSizeExtEncoding(const MachineInstr &MI, 228234353Sdim unsigned OpNo) const { 229228379Sdim // size is encoded as size-1. 230228379Sdim return getMachineOpValue(MI, MI.getOperand(OpNo)) - 1; 231228379Sdim} 232228379Sdim 233228379Sdimunsigned MipsCodeEmitter::getSizeInsEncoding(const MachineInstr &MI, 234234353Sdim unsigned OpNo) const { 235228379Sdim // size is encoded as pos+size-1. 236228379Sdim return getMachineOpValue(MI, MI.getOperand(OpNo-1)) + 237228379Sdim getMachineOpValue(MI, MI.getOperand(OpNo)) - 1; 238228379Sdim} 239228379Sdim 240263508Sdimunsigned MipsCodeEmitter::getLSAImmEncoding(const MachineInstr &MI, 241263508Sdim unsigned OpNo) const { 242263508Sdim llvm_unreachable("Unimplemented function."); 243263508Sdim return 0; 244263508Sdim} 245263508Sdim 246226584Sdim/// getMachineOpValue - Return binary encoding of operand. If the machine 247226584Sdim/// operand requires relocation, record the relocation and return zero. 248226584Sdimunsigned MipsCodeEmitter::getMachineOpValue(const MachineInstr &MI, 249234353Sdim const MachineOperand &MO) const { 250226584Sdim if (MO.isReg()) 251249423Sdim return TM.getRegisterInfo()->getEncodingValue(MO.getReg()); 252226584Sdim else if (MO.isImm()) 253226584Sdim return static_cast<unsigned>(MO.getImm()); 254243830Sdim else if (MO.isGlobal()) 255243830Sdim emitGlobalAddress(MO.getGlobal(), getRelocation(MI, MO), true); 256243830Sdim else if (MO.isSymbol()) 257226584Sdim emitExternalSymbolAddress(MO.getSymbolName(), getRelocation(MI, MO)); 258226584Sdim else if (MO.isCPI()) 259226584Sdim emitConstPoolAddress(MO.getIndex(), getRelocation(MI, MO)); 260226584Sdim else if (MO.isJTI()) 261226584Sdim emitJumpTableAddress(MO.getIndex(), getRelocation(MI, MO)); 262226584Sdim else if (MO.isMBB()) 263226584Sdim emitMachineBasicBlock(MO.getMBB(), getRelocation(MI, MO)); 264226584Sdim else 265226584Sdim llvm_unreachable("Unable to encode MachineOperand!"); 266226584Sdim return 0; 267226584Sdim} 268226584Sdim 269226584Sdimvoid MipsCodeEmitter::emitGlobalAddress(const GlobalValue *GV, unsigned Reloc, 270234353Sdim bool MayNeedFarStub) const { 271226584Sdim MCE.addRelocation(MachineRelocation::getGV(MCE.getCurrentPCOffset(), Reloc, 272234353Sdim const_cast<GlobalValue *>(GV), 0, 273234353Sdim MayNeedFarStub)); 274226584Sdim} 275226584Sdim 276234353Sdimvoid MipsCodeEmitter::emitGlobalAddressUnaligned(const GlobalValue *GV, 277234353Sdim unsigned Reloc, int Offset) const { 278234353Sdim MCE.addRelocation(MachineRelocation::getGV(MCE.getCurrentPCOffset(), Reloc, 279234353Sdim const_cast<GlobalValue *>(GV), 0, false)); 280234353Sdim MCE.addRelocation(MachineRelocation::getGV(MCE.getCurrentPCOffset() + Offset, 281234353Sdim Reloc, const_cast<GlobalValue *>(GV), 0, false)); 282234353Sdim} 283234353Sdim 284226584Sdimvoid MipsCodeEmitter:: 285226584SdimemitExternalSymbolAddress(const char *ES, unsigned Reloc) const { 286226584Sdim MCE.addRelocation(MachineRelocation::getExtSym(MCE.getCurrentPCOffset(), 287239462Sdim Reloc, ES, 0, 0)); 288226584Sdim} 289226584Sdim 290226584Sdimvoid MipsCodeEmitter::emitConstPoolAddress(unsigned CPI, unsigned Reloc) const { 291226584Sdim MCE.addRelocation(MachineRelocation::getConstPool(MCE.getCurrentPCOffset(), 292226584Sdim Reloc, CPI, 0, false)); 293226584Sdim} 294226584Sdim 295226584Sdimvoid MipsCodeEmitter:: 296226584SdimemitJumpTableAddress(unsigned JTIndex, unsigned Reloc) const { 297226584Sdim MCE.addRelocation(MachineRelocation::getJumpTable(MCE.getCurrentPCOffset(), 298226584Sdim Reloc, JTIndex, 0, false)); 299226584Sdim} 300226584Sdim 301226584Sdimvoid MipsCodeEmitter::emitMachineBasicBlock(MachineBasicBlock *BB, 302234353Sdim unsigned Reloc) const { 303226584Sdim MCE.addRelocation(MachineRelocation::getBB(MCE.getCurrentPCOffset(), 304226584Sdim Reloc, BB)); 305226584Sdim} 306226584Sdim 307249423Sdimvoid MipsCodeEmitter::emitInstruction(MachineBasicBlock::instr_iterator MI, 308249423Sdim MachineBasicBlock &MBB) { 309249423Sdim DEBUG(errs() << "JIT: " << (void*)MCE.getCurrentPCValue() << ":\t" << *MI); 310226584Sdim 311249423Sdim // Expand pseudo instruction. Skip if MI was not expanded. 312249423Sdim if (((MI->getDesc().TSFlags & MipsII::FormMask) == MipsII::Pseudo) && 313249423Sdim !expandPseudos(MI, MBB)) 314226584Sdim return; 315226584Sdim 316249423Sdim MCE.processDebugLoc(MI->getDebugLoc(), true); 317249423Sdim 318249423Sdim emitWord(getBinaryCodeForInstr(*MI)); 319243830Sdim ++NumEmitted; // Keep track of the # of mi's emitted 320226584Sdim 321249423Sdim MCE.processDebugLoc(MI->getDebugLoc(), false); 322226584Sdim} 323226584Sdim 324244628Sdimvoid MipsCodeEmitter::emitWord(unsigned Word) { 325226584Sdim DEBUG(errs() << " 0x"; 326226584Sdim errs().write_hex(Word) << "\n"); 327244628Sdim if (Subtarget->isLittle()) 328244628Sdim MCE.emitWordLE(Word); 329244628Sdim else 330244628Sdim MCE.emitWordBE(Word); 331226584Sdim} 332226584Sdim 333251662Sdimvoid MipsCodeEmitter::expandACCInstr(MachineBasicBlock::instr_iterator MI, 334249423Sdim MachineBasicBlock &MBB, 335249423Sdim unsigned Opc) const { 336249423Sdim // Expand "pseudomult $ac0, $t0, $t1" to "mult $t0, $t1". 337249423Sdim BuildMI(MBB, &*MI, MI->getDebugLoc(), II->get(Opc)) 338249423Sdim .addReg(MI->getOperand(1).getReg()).addReg(MI->getOperand(2).getReg()); 339249423Sdim} 340249423Sdim 341249423Sdimbool MipsCodeEmitter::expandPseudos(MachineBasicBlock::instr_iterator &MI, 342249423Sdim MachineBasicBlock &MBB) const { 343249423Sdim switch (MI->getOpcode()) { 344249423Sdim case Mips::NOP: 345249423Sdim BuildMI(MBB, &*MI, MI->getDebugLoc(), II->get(Mips::SLL), Mips::ZERO) 346249423Sdim .addReg(Mips::ZERO).addImm(0); 347249423Sdim break; 348263508Sdim case Mips::B: 349263508Sdim BuildMI(MBB, &*MI, MI->getDebugLoc(), II->get(Mips::BEQ)).addReg(Mips::ZERO) 350263508Sdim .addReg(Mips::ZERO).addOperand(MI->getOperand(0)); 351263508Sdim break; 352263508Sdim case Mips::TRAP: 353263508Sdim BuildMI(MBB, &*MI, MI->getDebugLoc(), II->get(Mips::BREAK)).addImm(0) 354263508Sdim .addImm(0); 355263508Sdim break; 356249423Sdim case Mips::JALRPseudo: 357249423Sdim BuildMI(MBB, &*MI, MI->getDebugLoc(), II->get(Mips::JALR), Mips::RA) 358249423Sdim .addReg(MI->getOperand(0).getReg()); 359249423Sdim break; 360249423Sdim case Mips::PseudoMULT: 361249423Sdim expandACCInstr(MI, MBB, Mips::MULT); 362249423Sdim break; 363249423Sdim case Mips::PseudoMULTu: 364249423Sdim expandACCInstr(MI, MBB, Mips::MULTu); 365249423Sdim break; 366249423Sdim case Mips::PseudoSDIV: 367249423Sdim expandACCInstr(MI, MBB, Mips::SDIV); 368249423Sdim break; 369249423Sdim case Mips::PseudoUDIV: 370249423Sdim expandACCInstr(MI, MBB, Mips::UDIV); 371249423Sdim break; 372249423Sdim case Mips::PseudoMADD: 373249423Sdim expandACCInstr(MI, MBB, Mips::MADD); 374249423Sdim break; 375249423Sdim case Mips::PseudoMADDU: 376249423Sdim expandACCInstr(MI, MBB, Mips::MADDU); 377249423Sdim break; 378249423Sdim case Mips::PseudoMSUB: 379249423Sdim expandACCInstr(MI, MBB, Mips::MSUB); 380249423Sdim break; 381249423Sdim case Mips::PseudoMSUBU: 382249423Sdim expandACCInstr(MI, MBB, Mips::MSUBU); 383249423Sdim break; 384249423Sdim default: 385249423Sdim return false; 386249423Sdim } 387249423Sdim 388249423Sdim (MI--)->eraseFromBundle(); 389249423Sdim return true; 390249423Sdim} 391249423Sdim 392226584Sdim/// createMipsJITCodeEmitterPass - Return a pass that emits the collected Mips 393226584Sdim/// code to the specified MCE object. 394226584SdimFunctionPass *llvm::createMipsJITCodeEmitterPass(MipsTargetMachine &TM, 395234353Sdim JITCodeEmitter &JCE) { 396226584Sdim return new MipsCodeEmitter(TM, JCE); 397226584Sdim} 398226584Sdim 399228379Sdim#include "MipsGenCodeEmitter.inc" 400