119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===-- Mips/MipsCodeEmitter.cpp - Convert Mips code to machine code -----===//
219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//
319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//                     The LLVM Compiler Infrastructure
419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//
519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// This file is distributed under the University of Illinois Open Source
619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// License. See LICENSE.TXT for details.
719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//
819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===---------------------------------------------------------------------===//
919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//
1019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// This file contains the pass that transforms the Mips machine instructions
1119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// into relocatable machine code.
1219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//
1319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===---------------------------------------------------------------------===//
1419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
1519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#define DEBUG_TYPE "jit"
1619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "Mips.h"
1719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "MipsInstrInfo.h"
1819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "MipsRelocations.h"
1919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "MipsSubtarget.h"
2019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "MipsTargetMachine.h"
2119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Constants.h"
2219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/DerivedTypes.h"
2319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Function.h"
2419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/PassManager.h"
2519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/CodeGen/JITCodeEmitter.h"
2619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/CodeGen/MachineConstantPool.h"
2719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/CodeGen/MachineFunctionPass.h"
2819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/CodeGen/MachineInstr.h"
2919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/CodeGen/MachineJumpTableInfo.h"
3019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/CodeGen/MachineModuleInfo.h"
3119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/CodeGen/Passes.h"
3219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/ADT/Statistic.h"
3319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Support/Debug.h"
3419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Support/ErrorHandling.h"
3519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Support/raw_ostream.h"
3619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#ifndef NDEBUG
3719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include <iomanip>
3819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#endif
3919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
4019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/CodeGen/MachineOperand.h"
4119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
4219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanusing namespace llvm;
4319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
4419bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanSTATISTIC(NumEmitted, "Number of machine instructions emitted");
4519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
4619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumannamespace {
4719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
4819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanclass MipsCodeEmitter : public MachineFunctionPass {
4919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MipsJITInfo *JTI;
5019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const MipsInstrInfo *II;
5119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const TargetData *TD;
5219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const MipsSubtarget *Subtarget;
5319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  TargetMachine &TM;
5419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  JITCodeEmitter &MCE;
5519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const std::vector<MachineConstantPoolEntry> *MCPEs;
5619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const std::vector<MachineJumpTableEntry> *MJTEs;
5719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool IsPIC;
5819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
5919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  void getAnalysisUsage(AnalysisUsage &AU) const {
6019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    AU.addRequired<MachineModuleInfo> ();
6119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MachineFunctionPass::getAnalysisUsage(AU);
6219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
6319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
6419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  static char ID;
6519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
6619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  public:
6719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MipsCodeEmitter(TargetMachine &tm, JITCodeEmitter &mce) :
6819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      MachineFunctionPass(ID), JTI(0),
6919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        II((const MipsInstrInfo *) tm.getInstrInfo()),
7019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        TD(tm.getTargetData()), TM(tm), MCE(mce), MCPEs(0), MJTEs(0),
7119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        IsPIC(TM.getRelocationModel() == Reloc::PIC_) {
7219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
7319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
7419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    bool runOnMachineFunction(MachineFunction &MF);
7519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
7619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    virtual const char *getPassName() const {
7719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return "Mips Machine Code Emitter";
7819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
7919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
8019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// getBinaryCodeForInstr - This function, generated by the
8119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// CodeEmitterGenerator using TableGen, produces the binary encoding for
8219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// machine instructions.
8319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    unsigned getBinaryCodeForInstr(const MachineInstr &MI) const;
8419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
8519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    void emitInstruction(const MachineInstr &MI);
8619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
8719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  private:
8819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
8919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    void emitWordLE(unsigned Word);
9019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
9119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// Routines that handle operands which add machine relocations which are
9219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// fixed up by the relocation stage.
9319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    void emitGlobalAddress(const GlobalValue *GV, unsigned Reloc,
9419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                bool MayNeedFarStub) const;
9519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    void emitExternalSymbolAddress(const char *ES, unsigned Reloc) const;
9619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    void emitConstPoolAddress(unsigned CPI, unsigned Reloc) const;
9719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    void emitJumpTableAddress(unsigned JTIndex, unsigned Reloc) const;
9819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    void emitMachineBasicBlock(MachineBasicBlock *BB, unsigned Reloc) const;
9919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
10019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// getMachineOpValue - Return binary encoding of operand. If the machine
10119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// operand requires relocation, record the relocation and return zero.
10219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    unsigned getMachineOpValue(const MachineInstr &MI,
10319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                               const MachineOperand &MO) const;
10419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
10519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    unsigned getRelocation(const MachineInstr &MI,
10619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                           const MachineOperand &MO) const;
10719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
10819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    unsigned getMemEncoding(const MachineInstr &MI, unsigned OpNo) const;
10919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    unsigned getSizeExtEncoding(const MachineInstr &MI, unsigned OpNo) const;
11019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    unsigned getSizeInsEncoding(const MachineInstr &MI, unsigned OpNo) const;
11119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  };
11219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
11319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
11419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanchar MipsCodeEmitter::ID = 0;
11519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
11619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool MipsCodeEmitter::runOnMachineFunction(MachineFunction &MF) {
11719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  JTI = ((MipsTargetMachine&) MF.getTarget()).getJITInfo();
11819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  II = ((const MipsTargetMachine&) MF.getTarget()).getInstrInfo();
11919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  TD = ((const MipsTargetMachine&) MF.getTarget()).getTargetData();
12019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Subtarget = &TM.getSubtarget<MipsSubtarget> ();
12119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MCPEs = &MF.getConstantPool()->getConstants();
12219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MJTEs = 0;
12319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (MF.getJumpTableInfo()) MJTEs = &MF.getJumpTableInfo()->getJumpTables();
12419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  JTI->Initialize(MF, IsPIC);
12519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MCE.setModuleInfo(&getAnalysis<MachineModuleInfo> ());
12619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
12719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  do {
12819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    DEBUG(errs() << "JITTing function '"
12919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        << MF.getFunction()->getName() << "'\n");
13019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MCE.startFunction(MF);
13119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
13219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    for (MachineFunction::iterator MBB = MF.begin(), E = MF.end();
13319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        MBB != E; ++MBB){
13419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      MCE.StartMachineBasicBlock(MBB);
13519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      for (MachineBasicBlock::const_iterator I = MBB->begin(), E = MBB->end();
13619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          I != E; ++I)
13719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        emitInstruction(*I);
13819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
13919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  } while (MCE.finishFunction(MF));
14019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
14119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return false;
14219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
14319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
14419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanunsigned MipsCodeEmitter::getRelocation(const MachineInstr &MI,
14519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                        const MachineOperand &MO) const {
14619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // NOTE: This relocations are for static.
14719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  uint64_t TSFlags = MI.getDesc().TSFlags;
14819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  uint64_t Form = TSFlags & MipsII::FormMask;
14919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (Form == MipsII::FrmJ)
15019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return Mips::reloc_mips_26;
15119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if ((Form == MipsII::FrmI || Form == MipsII::FrmFI)
15219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman       && MI.getDesc().isBranch())
15319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return Mips::reloc_mips_branch;
15419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (Form == MipsII::FrmI && MI.getOpcode() == Mips::LUi)
15519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return Mips::reloc_mips_hi;
15619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return Mips::reloc_mips_lo;
15719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
15819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
15919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanunsigned MipsCodeEmitter::getMemEncoding(const MachineInstr &MI,
16019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                          unsigned OpNo) const {
16119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Base register is encoded in bits 20-16, offset is encoded in bits 15-0.
16219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  assert(MI.getOperand(OpNo).isReg());
16319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo)) << 16;
16419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return
16519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    (getMachineOpValue(MI, MI.getOperand(OpNo+1)) & 0xFFFF) | RegBits;
16619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
16719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
16819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanunsigned MipsCodeEmitter::getSizeExtEncoding(const MachineInstr &MI,
16919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                          unsigned OpNo) const {
17019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // size is encoded as size-1.
17119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return getMachineOpValue(MI, MI.getOperand(OpNo)) - 1;
17219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
17319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
17419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanunsigned MipsCodeEmitter::getSizeInsEncoding(const MachineInstr &MI,
17519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                          unsigned OpNo) const {
17619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // size is encoded as pos+size-1.
17719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return getMachineOpValue(MI, MI.getOperand(OpNo-1)) +
17819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman         getMachineOpValue(MI, MI.getOperand(OpNo)) - 1;
17919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
18019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
18119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// getMachineOpValue - Return binary encoding of operand. If the machine
18219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// operand requires relocation, record the relocation and return zero.
18319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanunsigned MipsCodeEmitter::getMachineOpValue(const MachineInstr &MI,
18419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                           const MachineOperand &MO) const {
18519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (MO.isReg())
18619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return MipsRegisterInfo::getRegisterNumbering(MO.getReg());
18719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  else if (MO.isImm())
18819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return static_cast<unsigned>(MO.getImm());
18919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  else if (MO.isGlobal())
19019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    emitGlobalAddress(MO.getGlobal(), getRelocation(MI, MO), true);
19119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  else if (MO.isSymbol())
19219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    emitExternalSymbolAddress(MO.getSymbolName(), getRelocation(MI, MO));
19319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  else if (MO.isCPI())
19419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    emitConstPoolAddress(MO.getIndex(), getRelocation(MI, MO));
19519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  else if (MO.isJTI())
19619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    emitJumpTableAddress(MO.getIndex(), getRelocation(MI, MO));
19719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  else if (MO.isMBB())
19819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    emitMachineBasicBlock(MO.getMBB(), getRelocation(MI, MO));
19919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  else
20019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    llvm_unreachable("Unable to encode MachineOperand!");
20119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return 0;
20219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
20319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
20419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid MipsCodeEmitter::emitGlobalAddress(const GlobalValue *GV, unsigned Reloc,
20519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                                bool MayNeedFarStub) const {
20619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MCE.addRelocation(MachineRelocation::getGV(MCE.getCurrentPCOffset(), Reloc,
20719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                             const_cast<GlobalValue *>(GV), 0, MayNeedFarStub));
20819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
20919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
21019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid MipsCodeEmitter::
21119bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanemitExternalSymbolAddress(const char *ES, unsigned Reloc) const {
21219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MCE.addRelocation(MachineRelocation::getExtSym(MCE.getCurrentPCOffset(),
21319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                                 Reloc, ES, 0, 0, false));
21419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
21519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
21619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid MipsCodeEmitter::emitConstPoolAddress(unsigned CPI, unsigned Reloc) const {
21719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MCE.addRelocation(MachineRelocation::getConstPool(MCE.getCurrentPCOffset(),
21819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                                    Reloc, CPI, 0, false));
21919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
22019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
22119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid MipsCodeEmitter::
22219bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanemitJumpTableAddress(unsigned JTIndex, unsigned Reloc) const {
22319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MCE.addRelocation(MachineRelocation::getJumpTable(MCE.getCurrentPCOffset(),
22419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                                    Reloc, JTIndex, 0, false));
22519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
22619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
22719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid MipsCodeEmitter::emitMachineBasicBlock(MachineBasicBlock *BB,
22819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                           unsigned Reloc) const {
22919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MCE.addRelocation(MachineRelocation::getBB(MCE.getCurrentPCOffset(),
23019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                             Reloc, BB));
23119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
23219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
23319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid MipsCodeEmitter::emitInstruction(const MachineInstr &MI) {
23419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  DEBUG(errs() << "JIT: " << (void*)MCE.getCurrentPCValue() << ":\t" << MI);
23519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
23619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MCE.processDebugLoc(MI.getDebugLoc(), true);
23719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
23819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Skip pseudo instructions.
23919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if ((MI.getDesc().TSFlags & MipsII::FormMask) == MipsII::Pseudo)
24019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return;
24119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
24219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  ++NumEmitted;  // Keep track of the # of mi's emitted
24319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
24419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  switch (MI.getOpcode()) {
24519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  default:
24619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    emitWordLE(getBinaryCodeForInstr(MI));
24719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    break;
24819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
24919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
25019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MCE.processDebugLoc(MI.getDebugLoc(), false);
25119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
25219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
25319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid MipsCodeEmitter::emitWordLE(unsigned Word) {
25419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  DEBUG(errs() << "  0x";
25519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        errs().write_hex(Word) << "\n");
25619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MCE.emitWordLE(Word);
25719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
25819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
25919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// createMipsJITCodeEmitterPass - Return a pass that emits the collected Mips
26019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// code to the specified MCE object.
26119bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanFunctionPass *llvm::createMipsJITCodeEmitterPass(MipsTargetMachine &TM,
26219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    JITCodeEmitter &JCE) {
26319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return new MipsCodeEmitter(TM, JCE);
26419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
26519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
26619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "MipsGenCodeEmitter.inc"
267