Added the infrastructute necessary for MIPS JIT support. Patch by Vladimir
Stefanovic. I removed the part that actually emits the instructions cause
I want that to get in better shape first and in incremental steps. This
also makes it easier to review the upcoming parts.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@135678 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Target/Mips/MipsCodeEmitter.cpp b/lib/Target/Mips/MipsCodeEmitter.cpp
new file mode 100644
index 0000000..eb8f7e0
--- /dev/null
+++ b/lib/Target/Mips/MipsCodeEmitter.cpp
@@ -0,0 +1,193 @@
+//===-- Mips/MipsCodeEmitter.cpp - Convert Mips code to machine code -----===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===---------------------------------------------------------------------===//
+//
+// This file contains the pass that transforms the Mips machine instructions
+// into relocatable machine code.
+//
+//===---------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "jit"
+#include "Mips.h"
+#include "MipsInstrInfo.h"
+#include "MipsRelocations.h"
+#include "MipsSubtarget.h"
+#include "MipsTargetMachine.h"
+#include "llvm/Constants.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/Function.h"
+#include "llvm/PassManager.h"
+#include "llvm/CodeGen/JITCodeEmitter.h"
+#include "llvm/CodeGen/MachineConstantPool.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/CodeGen/MachineJumpTableInfo.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/raw_ostream.h"
+#ifndef NDEBUG
+#include <iomanip>
+#endif
+
+#include "llvm/CodeGen/MachineOperand.h"
+
+using namespace llvm;
+
+namespace {
+
+class MipsCodeEmitter : public MachineFunctionPass {
+  MipsJITInfo *JTI;
+  const MipsInstrInfo *II;
+  const TargetData *TD;
+  const MipsSubtarget *Subtarget;
+  TargetMachine &TM;
+  JITCodeEmitter &MCE;
+  const std::vector<MachineConstantPoolEntry> *MCPEs;
+  const std::vector<MachineJumpTableEntry> *MJTEs;
+  bool IsPIC;
+
+  void getAnalysisUsage(AnalysisUsage &AU) const {
+    AU.addRequired<MachineModuleInfo> ();
+    MachineFunctionPass::getAnalysisUsage(AU);
+  }
+
+  static char ID;
+
+  public:
+    MipsCodeEmitter(TargetMachine &tm, JITCodeEmitter &mce) :
+      MachineFunctionPass(ID), JTI(0),
+        II((const MipsInstrInfo *) tm.getInstrInfo()),
+        TD(tm.getTargetData()), TM(tm), MCE(mce), MCPEs(0), MJTEs(0),
+        IsPIC(TM.getRelocationModel() == Reloc::PIC_) {
+    }
+
+    bool runOnMachineFunction(MachineFunction &MF);
+
+    virtual const char *getPassName() const {
+      return "Mips Machine Code Emitter";
+    }
+
+    void emitInstruction(const MachineInstr &MI);
+
+    unsigned getOperandValue(const MachineOperand &MO,
+        unsigned relocType = -1);
+
+    void emitGlobalAddress(const GlobalValue *GV, unsigned Reloc,
+        bool MayNeedFarStub = true);
+
+    void emitMachineBasicBlock(MachineBasicBlock *BB, unsigned Reloc,
+        intptr_t JTBase = 0);
+
+    void emitExternalSymbolAddress(const char *ES, unsigned Reloc);
+    void emitJumpTableAddress(unsigned JTIndex, unsigned Reloc) const;
+    void emitConstPoolAddress(unsigned CPI, unsigned Reloc);
+};
+}
+
+void MipsCodeEmitter::emitGlobalAddress(const GlobalValue *GV, unsigned Reloc,
+    bool mayNeedFarStub) {
+  MachineRelocation MR = MachineRelocation::getGV(MCE.getCurrentPCOffset(),
+                  Reloc, const_cast<GlobalValue *> (GV), 0, mayNeedFarStub);
+  MCE.addRelocation(MR);
+}
+
+/// emitMachineBasicBlock - Emit the specified address basic block.
+void MipsCodeEmitter::emitMachineBasicBlock(MachineBasicBlock *BB,
+    unsigned Reloc, intptr_t JTBase) {
+  MCE.addRelocation(
+      MachineRelocation::getBB(MCE.getCurrentPCOffset(), Reloc, BB, JTBase));
+}
+
+void MipsCodeEmitter::emitExternalSymbolAddress(const char *ES,
+    unsigned Reloc) {
+  MCE.addRelocation(
+      MachineRelocation::getExtSym(MCE.getCurrentPCOffset(), Reloc, ES, 0, 0,
+          false));
+}
+
+void MipsCodeEmitter::emitJumpTableAddress(unsigned JTIndex, unsigned Reloc)
+    const {
+  MCE.addRelocation(
+      MachineRelocation::getJumpTable(MCE.getCurrentPCOffset(), Reloc, JTIndex,
+          0, false));
+}
+
+void MipsCodeEmitter::emitConstPoolAddress(unsigned CPI, unsigned Reloc) {
+  MCE.addRelocation(
+      MachineRelocation::getConstPool
+        (MCE.getCurrentPCOffset(), Reloc, CPI, 0));
+}
+
+/// createMipsJITCodeEmitterPass - Return a pass that emits the collected Mips
+/// code to the specified MCE object.
+FunctionPass *llvm::createMipsJITCodeEmitterPass(MipsTargetMachine &TM,
+    JITCodeEmitter &JCE) {
+  return new MipsCodeEmitter(TM, JCE);
+}
+
+char MipsCodeEmitter::ID = 10;
+
+bool MipsCodeEmitter::runOnMachineFunction(MachineFunction &MF) {
+  JTI = ((MipsTargetMachine&) MF.getTarget()).getJITInfo();
+  II = ((const MipsTargetMachine&) MF.getTarget()).getInstrInfo();
+  TD = ((const MipsTargetMachine&) MF.getTarget()).getTargetData();
+  Subtarget = &TM.getSubtarget<MipsSubtarget> ();
+  MCPEs = &MF.getConstantPool()->getConstants();
+  MJTEs = 0;
+  if (MF.getJumpTableInfo()) MJTEs = &MF.getJumpTableInfo()->getJumpTables();
+  JTI->Initialize(MF, IsPIC);
+  MCE.setModuleInfo(&getAnalysis<MachineModuleInfo> ());
+
+  do {
+    DEBUG(errs() << "JITTing function '"
+        << MF.getFunction()->getName() << "'\n");
+    MCE.startFunction(MF);
+
+    for (MachineFunction::iterator MBB = MF.begin(), E = MF.end();
+        MBB != E; ++MBB){
+      MCE.StartMachineBasicBlock(MBB);
+      for (MachineBasicBlock::const_iterator I = MBB->begin(), E = MBB->end();
+          I != E; ++I)
+        emitInstruction(*I);
+    }
+  } while (MCE.finishFunction(MF));
+
+  return false;
+}
+
+void MipsCodeEmitter::emitInstruction(const MachineInstr &MI) {}
+
+unsigned MipsCodeEmitter::getOperandValue(const MachineOperand &MO,
+    unsigned relocType) {
+  switch (MO.getType()) {
+  case MachineOperand::MO_Immediate:
+    return MO.getImm();
+  case MachineOperand::MO_GlobalAddress:
+    emitGlobalAddress(MO.getGlobal(), relocType, false);
+    return 0;
+  case MachineOperand::MO_ExternalSymbol:
+    emitExternalSymbolAddress(MO.getSymbolName(), relocType);
+    return 0;
+  case MachineOperand::MO_MachineBasicBlock:
+    emitMachineBasicBlock(MO.getMBB(), relocType, MCE.getCurrentPCValue());
+    return 0;
+  case MachineOperand::MO_Register:
+    return MipsRegisterInfo::getRegisterNumbering(MO.getReg());
+  case MachineOperand::MO_JumpTableIndex:
+    emitJumpTableAddress(MO.getIndex(), relocType);
+    return 0;
+  case MachineOperand::MO_ConstantPoolIndex:
+    emitConstPoolAddress(MO.getIndex(), relocType);
+    return 0;
+  default: return 0;
+  }
+}
+