Home | History | Annotate | Download | only in Mips
      1 //===-- 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 "MCTargetDesc/MipsBaseInfo.h"
     18 #include "MipsInstrInfo.h"
     19 #include "MipsRelocations.h"
     20 #include "MipsSubtarget.h"
     21 #include "MipsTargetMachine.h"
     22 #include "llvm/ADT/Statistic.h"
     23 #include "llvm/CodeGen/JITCodeEmitter.h"
     24 #include "llvm/CodeGen/MachineConstantPool.h"
     25 #include "llvm/CodeGen/MachineFunctionPass.h"
     26 #include "llvm/CodeGen/MachineInstr.h"
     27 #include "llvm/CodeGen/MachineJumpTableInfo.h"
     28 #include "llvm/CodeGen/MachineInstrBuilder.h"
     29 #include "llvm/CodeGen/MachineModuleInfo.h"
     30 #include "llvm/CodeGen/MachineOperand.h"
     31 #include "llvm/CodeGen/Passes.h"
     32 #include "llvm/IR/Constants.h"
     33 #include "llvm/IR/DerivedTypes.h"
     34 #include "llvm/PassManager.h"
     35 #include "llvm/Support/Debug.h"
     36 #include "llvm/Support/ErrorHandling.h"
     37 #include "llvm/Support/raw_ostream.h"
     38 #ifndef NDEBUG
     39 #include <iomanip>
     40 #endif
     41 
     42 using namespace llvm;
     43 
     44 STATISTIC(NumEmitted, "Number of machine instructions emitted");
     45 
     46 namespace {
     47 
     48 class MipsCodeEmitter : public MachineFunctionPass {
     49   MipsJITInfo *JTI;
     50   const MipsInstrInfo *II;
     51   const DataLayout *TD;
     52   const MipsSubtarget *Subtarget;
     53   TargetMachine &TM;
     54   JITCodeEmitter &MCE;
     55   const std::vector<MachineConstantPoolEntry> *MCPEs;
     56   const std::vector<MachineJumpTableEntry> *MJTEs;
     57   bool IsPIC;
     58 
     59   void getAnalysisUsage(AnalysisUsage &AU) const {
     60     AU.addRequired<MachineModuleInfo> ();
     61     MachineFunctionPass::getAnalysisUsage(AU);
     62   }
     63 
     64   static char ID;
     65 
     66 public:
     67   MipsCodeEmitter(TargetMachine &tm, JITCodeEmitter &mce)
     68     : MachineFunctionPass(ID), JTI(0), II(0), TD(0),
     69       TM(tm), MCE(mce), MCPEs(0), MJTEs(0),
     70       IsPIC(TM.getRelocationModel() == Reloc::PIC_) {}
     71 
     72   bool runOnMachineFunction(MachineFunction &MF);
     73 
     74   virtual const char *getPassName() const {
     75     return "Mips Machine Code Emitter";
     76   }
     77 
     78   /// getBinaryCodeForInstr - This function, generated by the
     79   /// CodeEmitterGenerator using TableGen, produces the binary encoding for
     80   /// machine instructions.
     81   uint64_t getBinaryCodeForInstr(const MachineInstr &MI) const;
     82 
     83   void emitInstruction(MachineBasicBlock::instr_iterator MI,
     84                        MachineBasicBlock &MBB);
     85 
     86 private:
     87 
     88   void emitWord(unsigned Word);
     89 
     90   /// Routines that handle operands which add machine relocations which are
     91   /// fixed up by the relocation stage.
     92   void emitGlobalAddress(const GlobalValue *GV, unsigned Reloc,
     93                          bool MayNeedFarStub) const;
     94   void emitExternalSymbolAddress(const char *ES, unsigned Reloc) const;
     95   void emitConstPoolAddress(unsigned CPI, unsigned Reloc) const;
     96   void emitJumpTableAddress(unsigned JTIndex, unsigned Reloc) const;
     97   void emitMachineBasicBlock(MachineBasicBlock *BB, unsigned Reloc) const;
     98 
     99   /// getMachineOpValue - Return binary encoding of operand. If the machine
    100   /// operand requires relocation, record the relocation and return zero.
    101   unsigned getMachineOpValue(const MachineInstr &MI,
    102                              const MachineOperand &MO) const;
    103 
    104   unsigned getRelocation(const MachineInstr &MI,
    105                          const MachineOperand &MO) const;
    106 
    107   unsigned getJumpTargetOpValue(const MachineInstr &MI, unsigned OpNo) const;
    108 
    109   unsigned getBranchTargetOpValue(const MachineInstr &MI, unsigned OpNo) const;
    110   unsigned getMemEncoding(const MachineInstr &MI, unsigned OpNo) const;
    111   unsigned getSizeExtEncoding(const MachineInstr &MI, unsigned OpNo) const;
    112   unsigned getSizeInsEncoding(const MachineInstr &MI, unsigned OpNo) const;
    113 
    114   void emitGlobalAddressUnaligned(const GlobalValue *GV, unsigned Reloc,
    115                                   int Offset) const;
    116 
    117   /// Expand pseudo instructions with accumulator register operands.
    118   void expandACCInstr(MachineBasicBlock::instr_iterator MI,
    119                       MachineBasicBlock &MBB, unsigned Opc) const;
    120 
    121   /// \brief Expand pseudo instruction. Return true if MI was expanded.
    122   bool expandPseudos(MachineBasicBlock::instr_iterator &MI,
    123                      MachineBasicBlock &MBB) const;
    124 };
    125 }
    126 
    127 char MipsCodeEmitter::ID = 0;
    128 
    129 bool MipsCodeEmitter::runOnMachineFunction(MachineFunction &MF) {
    130   MipsTargetMachine &Target = static_cast<MipsTargetMachine &>(
    131                                 const_cast<TargetMachine &>(MF.getTarget()));
    132 
    133   JTI = Target.getJITInfo();
    134   II = Target.getInstrInfo();
    135   TD = Target.getDataLayout();
    136   Subtarget = &TM.getSubtarget<MipsSubtarget> ();
    137   MCPEs = &MF.getConstantPool()->getConstants();
    138   MJTEs = 0;
    139   if (MF.getJumpTableInfo()) MJTEs = &MF.getJumpTableInfo()->getJumpTables();
    140   JTI->Initialize(MF, IsPIC, Subtarget->isLittle());
    141   MCE.setModuleInfo(&getAnalysis<MachineModuleInfo> ());
    142 
    143   do {
    144     DEBUG(errs() << "JITTing function '"
    145         << MF.getName() << "'\n");
    146     MCE.startFunction(MF);
    147 
    148     for (MachineFunction::iterator MBB = MF.begin(), E = MF.end();
    149         MBB != E; ++MBB){
    150       MCE.StartMachineBasicBlock(MBB);
    151       for (MachineBasicBlock::instr_iterator I = MBB->instr_begin(),
    152            E = MBB->instr_end(); I != E;)
    153         emitInstruction(*I++, *MBB);
    154     }
    155   } while (MCE.finishFunction(MF));
    156 
    157   return false;
    158 }
    159 
    160 unsigned MipsCodeEmitter::getRelocation(const MachineInstr &MI,
    161                                         const MachineOperand &MO) const {
    162   // NOTE: This relocations are for static.
    163   uint64_t TSFlags = MI.getDesc().TSFlags;
    164   uint64_t Form = TSFlags & MipsII::FormMask;
    165   if (Form == MipsII::FrmJ)
    166     return Mips::reloc_mips_26;
    167   if ((Form == MipsII::FrmI || Form == MipsII::FrmFI)
    168        && MI.isBranch())
    169     return Mips::reloc_mips_pc16;
    170   if (Form == MipsII::FrmI && MI.getOpcode() == Mips::LUi)
    171     return Mips::reloc_mips_hi;
    172   return Mips::reloc_mips_lo;
    173 }
    174 
    175 unsigned MipsCodeEmitter::getJumpTargetOpValue(const MachineInstr &MI,
    176                                                unsigned OpNo) const {
    177   MachineOperand MO = MI.getOperand(OpNo);
    178   if (MO.isGlobal())
    179     emitGlobalAddress(MO.getGlobal(), getRelocation(MI, MO), true);
    180   else if (MO.isSymbol())
    181     emitExternalSymbolAddress(MO.getSymbolName(), getRelocation(MI, MO));
    182   else if (MO.isMBB())
    183     emitMachineBasicBlock(MO.getMBB(), getRelocation(MI, MO));
    184   else
    185     llvm_unreachable("Unexpected jump target operand kind.");
    186   return 0;
    187 }
    188 
    189 unsigned MipsCodeEmitter::getBranchTargetOpValue(const MachineInstr &MI,
    190                                                  unsigned OpNo) const {
    191   MachineOperand MO = MI.getOperand(OpNo);
    192   emitMachineBasicBlock(MO.getMBB(), getRelocation(MI, MO));
    193   return 0;
    194 }
    195 
    196 unsigned MipsCodeEmitter::getMemEncoding(const MachineInstr &MI,
    197                                          unsigned OpNo) const {
    198   // Base register is encoded in bits 20-16, offset is encoded in bits 15-0.
    199   assert(MI.getOperand(OpNo).isReg());
    200   unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo)) << 16;
    201   return (getMachineOpValue(MI, MI.getOperand(OpNo+1)) & 0xFFFF) | RegBits;
    202 }
    203 
    204 unsigned MipsCodeEmitter::getSizeExtEncoding(const MachineInstr &MI,
    205                                              unsigned OpNo) const {
    206   // size is encoded as size-1.
    207   return getMachineOpValue(MI, MI.getOperand(OpNo)) - 1;
    208 }
    209 
    210 unsigned MipsCodeEmitter::getSizeInsEncoding(const MachineInstr &MI,
    211                                              unsigned OpNo) const {
    212   // size is encoded as pos+size-1.
    213   return getMachineOpValue(MI, MI.getOperand(OpNo-1)) +
    214          getMachineOpValue(MI, MI.getOperand(OpNo)) - 1;
    215 }
    216 
    217 /// getMachineOpValue - Return binary encoding of operand. If the machine
    218 /// operand requires relocation, record the relocation and return zero.
    219 unsigned MipsCodeEmitter::getMachineOpValue(const MachineInstr &MI,
    220                                             const MachineOperand &MO) const {
    221   if (MO.isReg())
    222     return TM.getRegisterInfo()->getEncodingValue(MO.getReg());
    223   else if (MO.isImm())
    224     return static_cast<unsigned>(MO.getImm());
    225   else if (MO.isGlobal())
    226     emitGlobalAddress(MO.getGlobal(), getRelocation(MI, MO), true);
    227   else if (MO.isSymbol())
    228     emitExternalSymbolAddress(MO.getSymbolName(), getRelocation(MI, MO));
    229   else if (MO.isCPI())
    230     emitConstPoolAddress(MO.getIndex(), getRelocation(MI, MO));
    231   else if (MO.isJTI())
    232     emitJumpTableAddress(MO.getIndex(), getRelocation(MI, MO));
    233   else if (MO.isMBB())
    234     emitMachineBasicBlock(MO.getMBB(), getRelocation(MI, MO));
    235   else
    236     llvm_unreachable("Unable to encode MachineOperand!");
    237   return 0;
    238 }
    239 
    240 void MipsCodeEmitter::emitGlobalAddress(const GlobalValue *GV, unsigned Reloc,
    241                                         bool MayNeedFarStub) const {
    242   MCE.addRelocation(MachineRelocation::getGV(MCE.getCurrentPCOffset(), Reloc,
    243                                              const_cast<GlobalValue *>(GV), 0,
    244                                              MayNeedFarStub));
    245 }
    246 
    247 void MipsCodeEmitter::emitGlobalAddressUnaligned(const GlobalValue *GV,
    248                                            unsigned Reloc, int Offset) const {
    249   MCE.addRelocation(MachineRelocation::getGV(MCE.getCurrentPCOffset(), Reloc,
    250                              const_cast<GlobalValue *>(GV), 0, false));
    251   MCE.addRelocation(MachineRelocation::getGV(MCE.getCurrentPCOffset() + Offset,
    252                       Reloc, const_cast<GlobalValue *>(GV), 0, false));
    253 }
    254 
    255 void MipsCodeEmitter::
    256 emitExternalSymbolAddress(const char *ES, unsigned Reloc) const {
    257   MCE.addRelocation(MachineRelocation::getExtSym(MCE.getCurrentPCOffset(),
    258                                                  Reloc, ES, 0, 0));
    259 }
    260 
    261 void MipsCodeEmitter::emitConstPoolAddress(unsigned CPI, unsigned Reloc) const {
    262   MCE.addRelocation(MachineRelocation::getConstPool(MCE.getCurrentPCOffset(),
    263                                                     Reloc, CPI, 0, false));
    264 }
    265 
    266 void MipsCodeEmitter::
    267 emitJumpTableAddress(unsigned JTIndex, unsigned Reloc) const {
    268   MCE.addRelocation(MachineRelocation::getJumpTable(MCE.getCurrentPCOffset(),
    269                                                     Reloc, JTIndex, 0, false));
    270 }
    271 
    272 void MipsCodeEmitter::emitMachineBasicBlock(MachineBasicBlock *BB,
    273                                             unsigned Reloc) const {
    274   MCE.addRelocation(MachineRelocation::getBB(MCE.getCurrentPCOffset(),
    275                                              Reloc, BB));
    276 }
    277 
    278 void MipsCodeEmitter::emitInstruction(MachineBasicBlock::instr_iterator MI,
    279                                       MachineBasicBlock &MBB) {
    280   DEBUG(errs() << "JIT: " << (void*)MCE.getCurrentPCValue() << ":\t" << *MI);
    281 
    282   // Expand pseudo instruction. Skip if MI was not expanded.
    283   if (((MI->getDesc().TSFlags & MipsII::FormMask) == MipsII::Pseudo) &&
    284       !expandPseudos(MI, MBB))
    285     return;
    286 
    287   MCE.processDebugLoc(MI->getDebugLoc(), true);
    288 
    289   emitWord(getBinaryCodeForInstr(*MI));
    290   ++NumEmitted;  // Keep track of the # of mi's emitted
    291 
    292   MCE.processDebugLoc(MI->getDebugLoc(), false);
    293 }
    294 
    295 void MipsCodeEmitter::emitWord(unsigned Word) {
    296   DEBUG(errs() << "  0x";
    297         errs().write_hex(Word) << "\n");
    298   if (Subtarget->isLittle())
    299     MCE.emitWordLE(Word);
    300   else
    301     MCE.emitWordBE(Word);
    302 }
    303 
    304 void MipsCodeEmitter::expandACCInstr(MachineBasicBlock::instr_iterator MI,
    305                                      MachineBasicBlock &MBB,
    306                                      unsigned Opc) const {
    307   // Expand "pseudomult $ac0, $t0, $t1" to "mult $t0, $t1".
    308   BuildMI(MBB, &*MI, MI->getDebugLoc(), II->get(Opc))
    309     .addReg(MI->getOperand(1).getReg()).addReg(MI->getOperand(2).getReg());
    310 }
    311 
    312 bool MipsCodeEmitter::expandPseudos(MachineBasicBlock::instr_iterator &MI,
    313                                     MachineBasicBlock &MBB) const {
    314   switch (MI->getOpcode()) {
    315   case Mips::NOP:
    316     BuildMI(MBB, &*MI, MI->getDebugLoc(), II->get(Mips::SLL), Mips::ZERO)
    317       .addReg(Mips::ZERO).addImm(0);
    318     break;
    319   case Mips::JALRPseudo:
    320     BuildMI(MBB, &*MI, MI->getDebugLoc(), II->get(Mips::JALR), Mips::RA)
    321       .addReg(MI->getOperand(0).getReg());
    322     break;
    323   case Mips::PseudoMULT:
    324     expandACCInstr(MI, MBB, Mips::MULT);
    325     break;
    326   case Mips::PseudoMULTu:
    327     expandACCInstr(MI, MBB, Mips::MULTu);
    328     break;
    329   case Mips::PseudoSDIV:
    330     expandACCInstr(MI, MBB, Mips::SDIV);
    331     break;
    332   case Mips::PseudoUDIV:
    333     expandACCInstr(MI, MBB, Mips::UDIV);
    334     break;
    335   case Mips::PseudoMADD:
    336     expandACCInstr(MI, MBB, Mips::MADD);
    337     break;
    338   case Mips::PseudoMADDU:
    339     expandACCInstr(MI, MBB, Mips::MADDU);
    340     break;
    341   case Mips::PseudoMSUB:
    342     expandACCInstr(MI, MBB, Mips::MSUB);
    343     break;
    344   case Mips::PseudoMSUBU:
    345     expandACCInstr(MI, MBB, Mips::MSUBU);
    346     break;
    347   default:
    348     return false;
    349   }
    350 
    351   (MI--)->eraseFromBundle();
    352   return true;
    353 }
    354 
    355 /// createMipsJITCodeEmitterPass - Return a pass that emits the collected Mips
    356 /// code to the specified MCE object.
    357 FunctionPass *llvm::createMipsJITCodeEmitterPass(MipsTargetMachine &TM,
    358                                                  JITCodeEmitter &JCE) {
    359   return new MipsCodeEmitter(TM, JCE);
    360 }
    361 
    362 #include "MipsGenCodeEmitter.inc"
    363