[llvm-commits] CVS: llvm/lib/Target/Mips/Makefile Mips.h Mips.td MipsAsmPrinter.cpp MipsCallingConv.td MipsISelDAGToDAG.cpp MipsISelLowering.cpp MipsISelLowering.h MipsInstrFormats.td MipsInstrInfo.cpp MipsInstrInfo.h MipsInstrInfo.td MipsRegisterInfo.cpp MipsRegisterInfo.h MipsRegisterInfo.td MipsSubtarget.cpp MipsSubtarget.h MipsTargetAsmInfo.cpp MipsTargetAsmInfo.h MipsTargetMachine.cpp MipsTargetMachine.h

Bruno Cardoso Lopes bruno.cardoso at gmail.com
Wed Jun 6 00:43:12 PDT 2007



Changes in directory llvm/lib/Target/Mips:

Makefile added (r1.1)
Mips.h added (r1.1)
Mips.td added (r1.1)
MipsAsmPrinter.cpp added (r1.1)
MipsCallingConv.td added (r1.1)
MipsISelDAGToDAG.cpp added (r1.1)
MipsISelLowering.cpp added (r1.1)
MipsISelLowering.h added (r1.1)
MipsInstrFormats.td added (r1.1)
MipsInstrInfo.cpp added (r1.1)
MipsInstrInfo.h added (r1.1)
MipsInstrInfo.td added (r1.1)
MipsRegisterInfo.cpp added (r1.1)
MipsRegisterInfo.h added (r1.1)
MipsRegisterInfo.td added (r1.1)
MipsSubtarget.cpp added (r1.1)
MipsSubtarget.h added (r1.1)
MipsTargetAsmInfo.cpp added (r1.1)
MipsTargetAsmInfo.h added (r1.1)
MipsTargetMachine.cpp added (r1.1)
MipsTargetMachine.h added (r1.1)
---
Log message:

Initial Mips support, here we go! =)
- Modifications from the last patch included 
  (issues pointed by Evan Cheng are now fixed). 
- Added more MipsI instructions.
- Added more patterns to match branch instructions.


---
Diffs of the changes:  (+2788 -0)

 Makefile              |   21 ++
 Mips.h                |   38 +++
 Mips.td               |   63 ++++++
 MipsAsmPrinter.cpp    |  294 ++++++++++++++++++++++++++++
 MipsCallingConv.td    |   39 +++
 MipsISelDAGToDAG.cpp  |  272 ++++++++++++++++++++++++++
 MipsISelLowering.cpp  |  519 ++++++++++++++++++++++++++++++++++++++++++++++++++
 MipsISelLowering.h    |   83 +++++++
 MipsInstrFormats.td   |   96 +++++++++
 MipsInstrInfo.cpp     |  114 ++++++++++
 MipsInstrInfo.h       |   63 ++++++
 MipsInstrInfo.td      |  468 +++++++++++++++++++++++++++++++++++++++++++++
 MipsRegisterInfo.cpp  |  288 +++++++++++++++++++++++++++
 MipsRegisterInfo.h    |   83 +++++++
 MipsRegisterInfo.td   |   80 +++++++
 MipsSubtarget.cpp     |   26 ++
 MipsSubtarget.h       |   43 ++++
 MipsTargetAsmInfo.cpp |   22 ++
 MipsTargetAsmInfo.h   |   30 ++
 MipsTargetMachine.cpp |   81 +++++++
 MipsTargetMachine.h   |   65 ++++++
 21 files changed, 2788 insertions(+)


Index: llvm/lib/Target/Mips/Makefile
diff -c /dev/null llvm/lib/Target/Mips/Makefile:1.1
*** /dev/null	Wed Jun  6 02:42:17 2007
--- llvm/lib/Target/Mips/Makefile	Wed Jun  6 02:42:05 2007
***************
*** 0 ****
--- 1,21 ----
+ ##===- lib/Target/Mips/Makefile ----------------------------*- Makefile -*-===##
+ # 
+ #                     The LLVM Compiler Infrastructure
+ #
+ # This file was developed by Bruno Cardoso Lopes and is distributed under the 
+ # University of Illinois Open Source License. See LICENSE.TXT for details.
+ # 
+ ##===----------------------------------------------------------------------===##
+ LEVEL = ../../..
+ LIBRARYNAME = LLVMMips
+ TARGET = Mips
+ 
+ # Make sure that tblgen is run, first thing.
+ BUILT_SOURCES = MipsGenRegisterInfo.h.inc MipsGenRegisterNames.inc \
+ 								MipsGenRegisterInfo.inc MipsGenInstrNames.inc \
+ 								MipsGenInstrInfo.inc MipsGenAsmWriter.inc \
+ 								MipsGenDAGISel.inc MipsGenCallingConv.inc \
+ 								MipsGenSubtarget.inc
+ 
+ include $(LEVEL)/Makefile.common
+ 


Index: llvm/lib/Target/Mips/Mips.h
diff -c /dev/null llvm/lib/Target/Mips/Mips.h:1.1
*** /dev/null	Wed Jun  6 02:43:11 2007
--- llvm/lib/Target/Mips/Mips.h	Wed Jun  6 02:42:06 2007
***************
*** 0 ****
--- 1,38 ----
+ //===-- Mips.h - Top-level interface for Mips representation ----*- C++ -*-===//
+ //
+ //                     The LLVM Compiler Infrastructure
+ //
+ // This file was developed by Bruno Cardoso Lopes and is distributed under the 
+ // University of Illinois Open Source License. See LICENSE.TXT for details.
+ //
+ //===----------------------------------------------------------------------===//
+ //
+ // This file contains the entry points for global functions defined in 
+ // the LLVM Mips back-end.
+ //
+ //===----------------------------------------------------------------------===//
+ 
+ #ifndef TARGET_MIPS_H
+ #define TARGET_MIPS_H
+ 
+ #include <iosfwd>
+ 
+ namespace llvm {
+   class MipsTargetMachine;
+   class FunctionPassManager;
+   class FunctionPass;
+   class MachineCodeEmitter;
+ 
+   FunctionPass *createMipsCodePrinterPass(std::ostream &OS, 
+                                           MipsTargetMachine &TM);
+   FunctionPass *createMipsISelDag(MipsTargetMachine &TM);
+ } // end namespace llvm;
+ 
+ // Defines symbolic names for Mips registers.  This defines a mapping from
+ // register name to register number.
+ #include "MipsGenRegisterNames.inc"
+ 
+ // Defines symbolic names for the Mips instructions.
+ #include "MipsGenInstrNames.inc"
+ 
+ #endif


Index: llvm/lib/Target/Mips/Mips.td
diff -c /dev/null llvm/lib/Target/Mips/Mips.td:1.1
*** /dev/null	Wed Jun  6 02:43:11 2007
--- llvm/lib/Target/Mips/Mips.td	Wed Jun  6 02:42:06 2007
***************
*** 0 ****
--- 1,63 ----
+ //===- Mips.td - Describe the Mips Target Machine ---------------*- C++ -*-===//
+ //
+ //                     The LLVM Compiler Infrastructure
+ //
+ // This file was developed by Bruno Cardoso Lopes and is distributed under the 
+ // University of Illinois Open Source License. See LICENSE.TXT for details.
+ //
+ //===----------------------------------------------------------------------===//
+ 
+ //===----------------------------------------------------------------------===//
+ // Target-independent interfaces which we are implementing
+ //===----------------------------------------------------------------------===//
+ 
+ include "../Target.td"
+ 
+ //===----------------------------------------------------------------------===//
+ // Register File Description
+ //===----------------------------------------------------------------------===//
+ 
+ include "MipsRegisterInfo.td"
+ 
+ //===----------------------------------------------------------------------===//
+ // Subtarget features
+ //===----------------------------------------------------------------------===//
+ 
+ // TODO: dummy, needed to compile
+ def FeatureCIX : SubtargetFeature<"r3000", "isR3000", "true",
+                                   "Enable r3000 extentions">;
+ 
+ //===----------------------------------------------------------------------===//
+ // Instruction Description
+ //===----------------------------------------------------------------------===//
+ 
+ include "MipsInstrInfo.td"
+ 
+ def MipsInstrInfo : InstrInfo {
+   // Define how we want to layout our target-specific information field.
+   let TSFlagsFields = [];
+   let TSFlagsShifts = [];
+ }
+ //===----------------------------------------------------------------------===//
+ // Calling Conventions
+ //===----------------------------------------------------------------------===//
+ 
+ include "MipsCallingConv.td"
+ 
+ //===----------------------------------------------------------------------===//
+ // Mips processors supported.
+ //===----------------------------------------------------------------------===//
+ 
+ class Proc<string Name, list<SubtargetFeature> Features>
+  : Processor<Name, NoItineraries, Features>;
+ 
+ def : Proc<"generic", []>;
+ 
+ //===----------------------------------------------------------------------===//
+ // Declare the target which we are implementing
+ //===----------------------------------------------------------------------===//
+ 
+ def Mips : Target {
+   // Pull in Instruction Info:
+   let InstructionSet = MipsInstrInfo;
+ }


Index: llvm/lib/Target/Mips/MipsAsmPrinter.cpp
diff -c /dev/null llvm/lib/Target/Mips/MipsAsmPrinter.cpp:1.1
*** /dev/null	Wed Jun  6 02:43:11 2007
--- llvm/lib/Target/Mips/MipsAsmPrinter.cpp	Wed Jun  6 02:42:06 2007
***************
*** 0 ****
--- 1,294 ----
+ //===-- MipsAsmPrinter.cpp - Mips LLVM assembly writer --------------------===//
+ //
+ //                     The LLVM Compiler Infrastructure
+ //
+ // This file was developed by Bruno Cardoso Lopes and is distributed under the 
+ // University of Illinois Open Source License. See LICENSE.TXT for details.
+ //
+ //===----------------------------------------------------------------------===//
+ //
+ // This file contains a printer that converts from our internal representation
+ // of machine-dependent LLVM code to GAS-format MIPS assembly language.
+ //
+ //===----------------------------------------------------------------------===//
+ 
+ #define DEBUG_TYPE "mips-asm-printer"
+ 
+ #include "Mips.h"
+ #include "MipsInstrInfo.h"
+ #include "MipsTargetMachine.h"
+ #include "llvm/Constants.h"
+ #include "llvm/DerivedTypes.h"
+ #include "llvm/Module.h"
+ #include "llvm/CodeGen/AsmPrinter.h"
+ #include "llvm/CodeGen/MachineFunctionPass.h"
+ #include "llvm/CodeGen/MachineConstantPool.h"
+ #include "llvm/CodeGen/MachineInstr.h"
+ #include "llvm/Target/TargetAsmInfo.h"
+ #include "llvm/Target/TargetData.h"
+ #include "llvm/Target/TargetMachine.h"
+ #include "llvm/Support/Mangler.h"
+ #include "llvm/ADT/Statistic.h"
+ #include "llvm/ADT/StringExtras.h"
+ #include "llvm/Support/CommandLine.h"
+ #include "llvm/Support/MathExtras.h"
+ #include <cctype>
+ 
+ using namespace llvm;
+ 
+ STATISTIC(EmittedInsts, "Number of machine instrs printed");
+ 
+ namespace {
+   struct VISIBILITY_HIDDEN MipsAsmPrinter : public AsmPrinter {
+     MipsAsmPrinter(std::ostream &O, MipsTargetMachine &TM, 
+                    const TargetAsmInfo *T): 
+                    AsmPrinter(O, TM, T) {}
+ 
+     virtual const char *getPassName() const {
+       return "Mips Assembly Printer";
+     }
+ 
+     void printOperand(const MachineInstr *MI, int opNum);
+     void printMemOperand(const MachineInstr *MI, int opNum, 
+                          const char *Modifier = 0);
+ 
+     bool printInstruction(const MachineInstr *MI);  // autogenerated.
+     bool runOnMachineFunction(MachineFunction &F);
+     bool doInitialization(Module &M);
+     bool doFinalization(Module &M);
+   };
+ } // end of anonymous namespace
+ 
+ #include "MipsGenAsmWriter.inc"
+ 
+ /// createMipsCodePrinterPass - Returns a pass that prints the MIPS
+ /// assembly code for a MachineFunction to the given output stream,
+ /// using the given target machine description.  This should work
+ /// regardless of whether the function is in SSA form.
+ FunctionPass *llvm::createMipsCodePrinterPass(std::ostream &o,
+                                               MipsTargetMachine &tm) 
+ {
+   return new MipsAsmPrinter(o, tm, tm.getTargetAsmInfo());
+ }
+ 
+ /// runOnMachineFunction - This uses the printMachineInstruction()
+ /// method to print assembly for each instruction.
+ bool MipsAsmPrinter::
+ runOnMachineFunction(MachineFunction &MF) 
+ {
+   SetupMachineFunction(MF);
+ 
+   // Print out constants referenced by the function
+   EmitConstantPool(MF.getConstantPool());
+ 
+   O << "\n\n";
+ 
+   // What's my mangled name?
+   CurrentFnName = Mang->getValueName(MF.getFunction());
+ 
+   // Print out the label for the function.
+   const Function *F = MF.getFunction();
+   SwitchToTextSection(getSectionForFunction(*F).c_str(), F);
+ 
+   // On Mips GAS if .align #n is present, #n means the number of bits 
+   // to be cleared to align. So, if we want 4 byte alignment, we must 
+   // have .align 2
+   // TODO:
+   //  add gas ".mask" and ".fmask"
+   EmitAlignment(1, F);
+   O << "\t.globl\t" << CurrentFnName << "\n";
+   O << "\t.ent\t" << CurrentFnName << "\n";
+   O << "\t.type\t"  << CurrentFnName << ", @function\n";
+   O << CurrentFnName << ":\n";
+ 
+   // Print out code for the function.
+   for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
+        I != E; ++I) {
+ 
+     // Print a label for the basic block.
+     if (I != MF.begin()) {
+       printBasicBlockLabel(I, true);
+       O << '\n';
+     }
+ 
+     for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
+          II != E; ++II) {
+       // Print the assembly for the instruction.
+       O << "\t";
+       printInstruction(II);
+       ++EmittedInsts;
+     }
+   }
+ 
+   // close function with asm directive
+   O << "\t.end\t" << CurrentFnName << "\n";
+ 
+   // We didn't modify anything.
+   return false;
+ }
+ 
+ void MipsAsmPrinter::
+ printOperand(const MachineInstr *MI, int opNum) 
+ {
+   const MachineOperand &MO = MI->getOperand(opNum);
+   const MRegisterInfo  &RI = *TM.getRegisterInfo();
+   bool  closeP=false;
+ 
+   // %hi and %lo used on mips gas to break large constants
+   if (MI->getOpcode() == Mips::LUi && !MO.isRegister() 
+       && !MO.isImmediate()) {
+     O << "%hi(";
+     closeP = true;
+   } else if ((MI->getOpcode() == Mips::ADDiu) && !MO.isRegister() 
+              && !MO.isImmediate()) {
+     O << "%lo(";
+     closeP = true;
+   }
+  
+   switch (MO.getType()) 
+   {
+     case MachineOperand::MO_Register:
+       if (MRegisterInfo::isPhysicalRegister(MO.getReg()))
+         O << "$" << LowercaseString (RI.get(MO.getReg()).Name);
+       else
+         O << "$" << MO.getReg();
+       break;
+ 
+     case MachineOperand::MO_Immediate:
+       if ((MI->getOpcode() == Mips::SLTiu) || (MI->getOpcode() == Mips::ORi) || 
+           (MI->getOpcode() == Mips::LUi) || (MI->getOpcode() == Mips::ANDi))
+         O << (unsigned int)MO.getImmedValue();
+       else
+         O << (int)MO.getImmedValue();
+       break;
+ 
+     case MachineOperand::MO_MachineBasicBlock:
+       printBasicBlockLabel(MO.getMachineBasicBlock());
+       return;
+ 
+     case MachineOperand::MO_GlobalAddress:
+       O << Mang->getValueName(MO.getGlobal());
+       break;
+ 
+     case MachineOperand::MO_ExternalSymbol:
+       O << MO.getSymbolName();
+       break;
+ 
+     case MachineOperand::MO_ConstantPoolIndex:
+       O << TAI->getPrivateGlobalPrefix() << "CPI"
+         << getFunctionNumber() << "_" << MO.getConstantPoolIndex();
+       break;
+   
+     default:
+       O << "<unknown operand type>"; abort (); break;
+   }
+ 
+   if (closeP) O << ")";
+ }
+ 
+ void MipsAsmPrinter::
+ printMemOperand(const MachineInstr *MI, int opNum, const char *Modifier) 
+ {
+   // lw/sw $reg, MemOperand
+   // will turn into :
+   // lw/sw $reg, imm($reg)
+   printOperand(MI, opNum);
+   O << "(";
+   printOperand(MI, opNum+1);
+   O << ")";
+ }
+ 
+ bool MipsAsmPrinter::
+ doInitialization(Module &M) 
+ {
+   Mang = new Mangler(M);
+   return false; // success
+ }
+ 
+ bool MipsAsmPrinter::
+ doFinalization(Module &M) 
+ {
+   const TargetData *TD = TM.getTargetData();
+ 
+   // Print out module-level global variables here.
+   for (Module::const_global_iterator I = M.global_begin(),
+          E = M.global_end(); I != E; ++I)
+ 
+     // External global require no code
+     if (I->hasInitializer()) {
+ 
+       // Check to see if this is a special global 
+       // used by LLVM, if so, emit it.
+       if (EmitSpecialLLVMGlobal(I))
+         continue;
+       
+       O << "\n\n";
+       std::string name = Mang->getValueName(I);
+       Constant *C      = I->getInitializer();
+       unsigned Size    = TD->getTypeSize(C->getType());
+       unsigned Align   = TD->getPrefTypeAlignment(C->getType());
+ 
+       if (C->isNullValue() && (I->hasLinkOnceLinkage() || 
+         I->hasInternalLinkage() || I->hasWeakLinkage() 
+         /* FIXME: Verify correct */)) {
+ 
+         SwitchToDataSection(".data", I);
+         if (I->hasInternalLinkage())
+           O << "\t.local " << name << "\n";
+ 
+         O << "\t.comm " << name << "," 
+           << TD->getTypeSize(C->getType()) 
+           << "," << Align << "\n";
+ 
+       } else {
+ 
+         switch (I->getLinkage()) 
+         {
+           case GlobalValue::LinkOnceLinkage:
+           case GlobalValue::WeakLinkage:   
+             // FIXME: Verify correct for weak.
+             // Nonnull linkonce -> weak
+             O << "\t.weak " << name << "\n";
+             SwitchToDataSection("", I);
+             O << "\t.section\t\".llvm.linkonce.d." << name
+                           << "\",\"aw\", at progbits\n";
+             break;
+           case GlobalValue::AppendingLinkage:
+             // FIXME: appending linkage variables 
+             // should go into a section of  their name or 
+             // something.  For now, just emit them as external.
+           case GlobalValue::ExternalLinkage:
+             // If external or appending, declare as a global symbol
+             O << "\t.globl " << name << "\n";
+           case GlobalValue::InternalLinkage:
+             if (C->isNullValue())
+               SwitchToDataSection(".bss", I);
+             else
+               SwitchToDataSection(".data", I);
+             break;
+           case GlobalValue::GhostLinkage:
+             cerr << "Should not have any" 
+                  << "unmaterialized functions!\n";
+             abort();
+           case GlobalValue::DLLImportLinkage:
+             cerr << "DLLImport linkage is" 
+                  << "not supported by this target!\n";
+             abort();
+           case GlobalValue::DLLExportLinkage:
+             cerr << "DLLExport linkage is" 
+                  << "not supported by this target!\n";
+             abort();
+           default:
+             assert(0 && "Unknown linkage type!");          
+         }
+         O << "\t.align " << Align << "\n";
+         O << "\t.type " << name << ", at object\n";
+         O << "\t.size " << name << "," << Size << "\n";
+         O << name << ":\n";
+         EmitGlobalConstant(C);
+     }
+   }
+ 
+   AsmPrinter::doFinalization(M);
+   return false; // success
+ }


Index: llvm/lib/Target/Mips/MipsCallingConv.td
diff -c /dev/null llvm/lib/Target/Mips/MipsCallingConv.td:1.1
*** /dev/null	Wed Jun  6 02:43:11 2007
--- llvm/lib/Target/Mips/MipsCallingConv.td	Wed Jun  6 02:42:06 2007
***************
*** 0 ****
--- 1,39 ----
+ //===- MipsCallingConv.td - Calling Conventions for Mips --------*- C++ -*-===//
+ // 
+ //                     The LLVM Compiler Infrastructure
+ //
+ // This file was developed by Bruno Cardoso Lopes and is distributed under the 
+ // University of Illinois Open Source License. See LICENSE.TXT for details.
+ // 
+ //===----------------------------------------------------------------------===//
+ // This describes the calling conventions for Mips architecture.
+ //===----------------------------------------------------------------------===//
+ 
+ /// CCIfSubtarget - Match if the current subtarget has a feature F.
+ class CCIfSubtarget<string F, CCAction A>: 
+   CCIf<!strconcat("State.getTarget().getSubtarget<MipsSubtarget>().", F), A>;
+ 
+ //===----------------------------------------------------------------------===//
+ // Mips Return Value Calling Convention
+ //===----------------------------------------------------------------------===//
+ def RetCC_Mips : CallingConv<[
+   // i32 are returned in registers V0, V1
+   CCIfType<[i32], CCAssignToReg<[V0, V1]>>
+ ]>;
+ 
+ 
+ //===----------------------------------------------------------------------===//
+ // Mips Argument Calling Conventions
+ //===----------------------------------------------------------------------===//
+ def CC_Mips : CallingConv<[
+   // Promote i8/i16 arguments to i32.
+   CCIfType<[i8, i16], CCPromoteToType<i32>>,
+ 
+   // The first 4 integer arguments are passed in integer registers.
+   CCIfType<[i32], CCAssignToReg<[A0, A1, A2, A3]>>,
+ 
+   // Integer values get stored in stack slots that are 4 bytes in
+   // size and 4-byte aligned.
+   CCIfType<[i32], CCAssignToStack<4, 4>>
+ ]>;
+ 


Index: llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp
diff -c /dev/null llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp:1.1
*** /dev/null	Wed Jun  6 02:43:11 2007
--- llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp	Wed Jun  6 02:42:06 2007
***************
*** 0 ****
--- 1,272 ----
+ //===-- MipsISelDAGToDAG.cpp - A dag to dag inst selector for Mips --------===//
+ //
+ //                     The LLVM Compiler Infrastructure
+ //
+ // This file was developed by Bruno Cardoso Lopes is distributed under the 
+ // University of Illinois Open Source License. See LICENSE.TXT for details.
+ //
+ //===----------------------------------------------------------------------===//
+ //
+ // This file defines an instruction selector for the MIPS target.
+ //
+ //===----------------------------------------------------------------------===//
+ 
+ #define DEBUG_TYPE "mips-isel"
+ 
+ #include "Mips.h"
+ #include "MipsISelLowering.h"
+ #include "MipsRegisterInfo.h"
+ #include "MipsSubtarget.h"
+ #include "MipsTargetMachine.h"
+ #include "llvm/GlobalValue.h"
+ #include "llvm/Instructions.h"
+ #include "llvm/Intrinsics.h"
+ #include "llvm/Support/CFG.h"
+ #include "llvm/Type.h"
+ #include "llvm/CodeGen/MachineConstantPool.h"
+ #include "llvm/CodeGen/MachineFunction.h"
+ #include "llvm/CodeGen/MachineFrameInfo.h"
+ #include "llvm/CodeGen/MachineInstrBuilder.h"
+ #include "llvm/CodeGen/SelectionDAGISel.h"
+ #include "llvm/Target/TargetMachine.h"
+ #include "llvm/Support/Compiler.h"
+ #include "llvm/Support/Debug.h"
+ #include <queue>
+ #include <set>
+ 
+ using namespace llvm;
+ 
+ //===----------------------------------------------------------------------===//
+ // Instruction Selector Implementation
+ //===----------------------------------------------------------------------===//
+ 
+ //===----------------------------------------------------------------------===//
+ // MipsDAGToDAGISel - MIPS specific code to select MIPS machine
+ // instructions for SelectionDAG operations.
+ //===----------------------------------------------------------------------===//
+ namespace {
+ 
+ class VISIBILITY_HIDDEN MipsDAGToDAGISel : public SelectionDAGISel {
+ 
+   /// TM - Keep a reference to MipsTargetMachine.
+   MipsTargetMachine &TM;
+ 
+   /// MipsLowering - This object fully describes how to lower LLVM code to an
+   /// Mips-specific SelectionDAG.
+   MipsTargetLowering MipsLowering;
+ 
+   /// Subtarget - Keep a pointer to the MipsSubtarget around so that we can
+   /// make the right decision when generating code for different targets.
+   //TODO: add initialization on constructor
+   //const MipsSubtarget *Subtarget;
+  
+ public:
+   MipsDAGToDAGISel(MipsTargetMachine &tm) : 
+         SelectionDAGISel(MipsLowering),
+         TM(tm), MipsLowering(*TM.getTargetLowering()) {}
+   
+   virtual void InstructionSelectBasicBlock(SelectionDAG &SD);
+ 
+   // Pass Name
+   virtual const char *getPassName() const {
+     return "MIPS DAG->DAG Pattern Instruction Selection";
+   } 
+   
+ 
+ private:  
+   // Include the pieces autogenerated from the target description.
+   #include "MipsGenDAGISel.inc"
+ 
+   SDNode *Select(SDOperand N);
+ 
+   // Complex Pattern.
+   bool SelectAddr(SDOperand Op, SDOperand N, 
+                   SDOperand &Base, SDOperand &Offset);
+ 
+ 
+   // getI32Imm - Return a target constant with the specified
+   // value, of type i32.
+   inline SDOperand getI32Imm(unsigned Imm) {
+     return CurDAG->getTargetConstant(Imm, MVT::i32);
+   }
+ 
+ 
+   #ifndef NDEBUG
+   unsigned Indent;
+   #endif
+ };
+ 
+ }
+ 
+ /// InstructionSelectBasicBlock - This callback is invoked by
+ /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
+ void MipsDAGToDAGISel::
+ InstructionSelectBasicBlock(SelectionDAG &SD) 
+ {
+   DEBUG(BB->dump());
+   // Codegen the basic block.
+   #ifndef NDEBUG
+   DOUT << "===== Instruction selection begins:\n";
+   Indent = 0;
+   #endif
+ 
+   // Select target instructions for the DAG.
+   SD.setRoot(SelectRoot(SD.getRoot()));
+ 
+   #ifndef NDEBUG
+   DOUT << "===== Instruction selection ends:\n";
+   #endif
+ 
+   SD.RemoveDeadNodes();
+   
+   // Emit machine code to BB. 
+   ScheduleAndEmitDAG(SD);
+ }
+ 
+ /// ComplexPattern used on MipsInstrInfo
+ /// Used on Mips Load/Store instructions
+ bool MipsDAGToDAGISel::
+ SelectAddr(SDOperand Op, SDOperand Addr, SDOperand &Offset, SDOperand &Base)
+ {
+   // if Address is FI, get the TargetFrameIndex.
+   if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
+     Base   = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
+     Offset = CurDAG->getTargetConstant(0, MVT::i32);
+     return true;
+   }
+     
+   // TargetExternalSymbol and TargetGlobalAddress are
+   // lowered and their addresses go into registers, so
+   // they should not be touched here.
+   if ((Addr.getOpcode() == ISD::TargetExternalSymbol ||
+        Addr.getOpcode() == ISD::TargetGlobalAddress))
+     return false;
+   
+   // Operand is an result from an ADD.
+   if (Addr.getOpcode() == ISD::ADD) 
+   {
+     if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) 
+     {
+       if (Predicate_immSExt16(CN)) 
+       {
+         // If the first operand is a FI, get the TargetFI Node
+         if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>
+                                     (Addr.getOperand(0))) {
+           Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
+         } else {
+           Base = Addr.getOperand(0);
+         }
+ 
+         Offset = CurDAG->getTargetConstant(CN->getValue(), MVT::i32);
+         return true;
+       }
+     }
+   }
+ 
+   Base = Addr;
+   Offset = CurDAG->getTargetConstant(0, MVT::i32);
+   return true;
+ }
+ 
+ /// Select instructions not customized! Used for
+ /// expanded, promoted and normal instructions
+ SDNode* MipsDAGToDAGISel::
+ Select(SDOperand N) 
+ {
+   SDNode *Node = N.Val;
+   unsigned Opcode = Node->getOpcode();
+ 
+   // Dump information about the Node being selected
+   #ifndef NDEBUG
+   DOUT << std::string(Indent, ' ') << "Selecting: ";
+   DEBUG(Node->dump(CurDAG));
+   DOUT << "\n";
+   Indent += 2;
+   #endif
+ 
+   // If we have a custom node, we already have selected!
+   if (Opcode >= ISD::BUILTIN_OP_END && Opcode < MipsISD::FIRST_NUMBER) {
+     #ifndef NDEBUG
+     DOUT << std::string(Indent-2, ' ') << "== ";
+     DEBUG(Node->dump(CurDAG));
+     DOUT << "\n";
+     Indent -= 2;
+     #endif
+     return NULL;
+   }
+ 
+   ///
+   // Instruction Selection not handled by custom or by the 
+   // auto-generated tablegen selection should be handled here
+   /// 
+   switch(Opcode) {
+ 
+     default: break;
+ 
+     /// Special Mul operations
+     case ISD::MULHS:
+     case ISD::MULHU: {
+       SDOperand MulOp1 = Node->getOperand(0);
+       SDOperand MulOp2 = Node->getOperand(1);
+       AddToISelQueue(MulOp1);
+       AddToISelQueue(MulOp2);
+ 
+       unsigned MulOp  = (Opcode == ISD::MULHU ? Mips::MULTu : Mips::MULT);
+       SDNode *MulNode = CurDAG->getTargetNode(MulOp, MVT::Flag, MulOp1, MulOp2);
+ 
+       SDOperand MFInFlag = SDOperand(MulNode, 0);
+       return CurDAG->getTargetNode(Mips::MFHI, MVT::i32, MFInFlag);
+     }
+ 
+     /// Div operations
+     case ISD::SDIV: 
+     case ISD::UDIV: {
+       SDOperand DivOp1 = Node->getOperand(0);
+       SDOperand DivOp2 = Node->getOperand(1);
+       AddToISelQueue(DivOp1);
+       AddToISelQueue(DivOp2);
+ 
+       unsigned DivOp  = (Opcode == ISD::SDIV ? Mips::DIV : Mips::DIVu);
+       SDNode *DivNode = CurDAG->getTargetNode(DivOp, MVT::Flag, DivOp1, DivOp2);
+ 
+       SDOperand MFInFlag = SDOperand(DivNode, 0);
+       return CurDAG->getTargetNode(Mips::MFLO, MVT::i32, MFInFlag);
+     }
+ 
+     /// Rem operations
+     case ISD::SREM: 
+     case ISD::UREM: {
+       SDOperand RemOp1 = Node->getOperand(0);
+       SDOperand RemOp2 = Node->getOperand(1);
+       AddToISelQueue(RemOp1);
+       AddToISelQueue(RemOp2);
+       
+       unsigned RemOp  = (Opcode == ISD::SREM ? Mips::DIV : Mips::DIVu);
+       SDNode *RemNode = CurDAG->getTargetNode(RemOp, MVT::Flag, RemOp1, RemOp2);
+ 
+       SDOperand MFInFlag = SDOperand(RemNode, 0);
+       return CurDAG->getTargetNode(Mips::MFHI, MVT::i32, MFInFlag);
+     }
+   }
+ 
+   // Select the default instruction
+   SDNode *ResNode = SelectCode(N);
+ 
+   #ifndef NDEBUG
+   DOUT << std::string(Indent-2, ' ') << "=> ";
+   if (ResNode == NULL || ResNode == N.Val)
+     DEBUG(N.Val->dump(CurDAG));
+   else
+     DEBUG(ResNode->dump(CurDAG));
+   DOUT << "\n";
+   Indent -= 2;
+   #endif
+ 
+   return ResNode;
+ }
+ 
+ /// createMipsISelDag - This pass converts a legalized DAG into a 
+ /// MIPS-specific DAG, ready for instruction scheduling.
+ FunctionPass *llvm::createMipsISelDag(MipsTargetMachine &TM) {
+   return new MipsDAGToDAGISel(TM);
+ }


Index: llvm/lib/Target/Mips/MipsISelLowering.cpp
diff -c /dev/null llvm/lib/Target/Mips/MipsISelLowering.cpp:1.1
*** /dev/null	Wed Jun  6 02:43:11 2007
--- llvm/lib/Target/Mips/MipsISelLowering.cpp	Wed Jun  6 02:42:06 2007
***************
*** 0 ****
--- 1,519 ----
+ //===-- MipsISelLowering.cpp - Mips DAG Lowering Implementation -----------===//
+ //
+ //                     The LLVM Compiler Infrastructure
+ //
+ // This file was developed by Bruno Cardoso Lopes and is distributed under the 
+ // University of Illinois Open Source License. See LICENSE.TXT for details.
+ //
+ //===----------------------------------------------------------------------===//
+ //
+ // This file defines the interfaces that Mips uses to lower LLVM code into a
+ // selection DAG.
+ //
+ //===----------------------------------------------------------------------===//
+ 
+ #define DEBUG_TYPE "mips-lower"
+ 
+ #include "MipsISelLowering.h"
+ #include "MipsTargetMachine.h"
+ #include "llvm/DerivedTypes.h"
+ #include "llvm/Function.h"
+ #include "llvm/Intrinsics.h"
+ #include "llvm/CallingConv.h"
+ #include "llvm/CodeGen/CallingConvLower.h"
+ #include "llvm/CodeGen/MachineFrameInfo.h"
+ #include "llvm/CodeGen/MachineFunction.h"
+ #include "llvm/CodeGen/MachineInstrBuilder.h"
+ #include "llvm/CodeGen/SelectionDAGISel.h"
+ #include "llvm/CodeGen/SSARegMap.h"
+ #include "llvm/CodeGen/ValueTypes.h"
+ #include "llvm/Support/Debug.h"
+ #include <queue>
+ #include <set>
+ 
+ using namespace llvm;
+ 
+ const char *MipsTargetLowering::
+ getTargetNodeName(unsigned Opcode) const 
+ {
+   switch (Opcode) 
+   {
+     case MipsISD::JmpLink   : return "MipsISD::JmpLink";
+     case MipsISD::Hi        : return "MipsISD::Hi";
+     case MipsISD::Lo        : return "MipsISD::Lo";
+     case MipsISD::Ret       : return "MipsISD::Ret";
+     default                 : return NULL;
+   }
+ }
+ 
+ MipsTargetLowering::
+ MipsTargetLowering(MipsTargetMachine &TM): TargetLowering(TM) 
+ {
+   // Mips does not have i1 type, so use i32 for
+   // setcc operations results (slt, sgt, ...). 
+   setSetCCResultType(MVT::i32);
+   setSetCCResultContents(ZeroOrOneSetCCResult);
+ 
+   // Set up the register classes
+   addRegisterClass(MVT::i32, Mips::CPURegsRegisterClass);
+ 
+   // Custom
+   setOperationAction(ISD::GlobalAddress, MVT::i32, Custom);
+   setOperationAction(ISD::RET, MVT::Other, Custom);
+ 
+   // Load extented operations for i1 types must be promoted 
+   setLoadXAction(ISD::EXTLOAD,  MVT::i1,  Promote);
+   setLoadXAction(ISD::ZEXTLOAD, MVT::i1,  Promote);
+   setLoadXAction(ISD::SEXTLOAD, MVT::i1,  Promote);
+ 
+   // Store operations for i1 types must be promoted
+   setStoreXAction(MVT::i1, Promote);
+ 
+   // Mips does not have these NodeTypes below.
+   setOperationAction(ISD::BR_JT,     MVT::Other, Expand);
+   setOperationAction(ISD::BR_CC,     MVT::Other, Expand);
+   setOperationAction(ISD::SELECT_CC, MVT::Other, Expand);
+   setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
+   setOperationAction(ISD::SELECT, MVT::i32, Expand);
+ 
+   // Mips not supported intrinsics.
+   setOperationAction(ISD::MEMMOVE, MVT::Other, Expand);
+   setOperationAction(ISD::MEMSET, MVT::Other, Expand);
+   setOperationAction(ISD::MEMCPY, MVT::Other, Expand);
+ 
+   setOperationAction(ISD::CTPOP, MVT::i32, Expand);
+   setOperationAction(ISD::CTTZ , MVT::i32, Expand);
+   setOperationAction(ISD::CTLZ , MVT::i32, Expand);
+   setOperationAction(ISD::ROTL , MVT::i32, Expand);
+   setOperationAction(ISD::ROTR , MVT::i32, Expand);
+   setOperationAction(ISD::BSWAP, MVT::i32, Expand);
+ 
+   setOperationAction(ISD::SHL_PARTS, MVT::i32, Expand);
+   setOperationAction(ISD::SRA_PARTS, MVT::i32, Expand);
+   setOperationAction(ISD::SRL_PARTS, MVT::i32, Expand);
+ 
+   // We don't have line number support yet.
+   setOperationAction(ISD::LOCATION, MVT::Other, Expand);
+   setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand);
+   setOperationAction(ISD::LABEL, MVT::Other, Expand);
+ 
+   // Use the default for now
+   setOperationAction(ISD::STACKSAVE, MVT::Other, Expand);
+   setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand);
+ 
+   setStackPointerRegisterToSaveRestore(Mips::SP);
+   computeRegisterProperties();
+ }
+ 
+ 
+ SDOperand MipsTargetLowering::
+ LowerOperation(SDOperand Op, SelectionDAG &DAG) 
+ {
+   switch (Op.getOpcode()) 
+   {
+     case ISD::CALL:             return LowerCALL(Op, DAG);
+     case ISD::FORMAL_ARGUMENTS: return LowerFORMAL_ARGUMENTS(Op, DAG);
+     case ISD::RET:              return LowerRET(Op, DAG);
+     case ISD::GlobalAddress:    return LowerGlobalAddress(Op, DAG);
+     case ISD::RETURNADDR:       return LowerRETURNADDR(Op, DAG);
+   }
+   return SDOperand();
+ }
+ 
+ //===----------------------------------------------------------------------===//
+ //  Lower helper functions
+ //===----------------------------------------------------------------------===//
+ 
+ // AddLiveIn - This helper function adds the specified physical register to the
+ // MachineFunction as a live in value.  It also creates a corresponding
+ // virtual register for it.
+ static unsigned
+ AddLiveIn(MachineFunction &MF, unsigned PReg, TargetRegisterClass *RC) 
+ {
+   assert(RC->contains(PReg) && "Not the correct regclass!");
+   unsigned VReg = MF.getSSARegMap()->createVirtualRegister(RC);
+   MF.addLiveIn(PReg, VReg);
+   return VReg;
+ }
+ 
+ // Set up a frame object for the return address.
+ SDOperand MipsTargetLowering::getReturnAddressFrameIndex(SelectionDAG &DAG) {
+   if (ReturnAddrIndex == 0) {
+     MachineFunction &MF = DAG.getMachineFunction();
+     ReturnAddrIndex = MF.getFrameInfo()->CreateFixedObject(4, 0);
+   }
+ 
+   return DAG.getFrameIndex(ReturnAddrIndex, getPointerTy());
+ }
+ 
+ 
+ //===----------------------------------------------------------------------===//
+ //  Misc Lower Operation implementation
+ //===----------------------------------------------------------------------===//
+ SDOperand MipsTargetLowering::
+ LowerGlobalAddress(SDOperand Op, SelectionDAG &DAG) 
+ {
+   GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
+ 
+   SDOperand GA = DAG.getTargetGlobalAddress(GV, MVT::i32);
+   SDOperand Hi = DAG.getNode(MipsISD::Hi, MVT::i32, GA);
+   SDOperand Lo = DAG.getNode(MipsISD::Lo, MVT::i32, GA);
+ 
+   return DAG.getNode(ISD::ADD, MVT::i32, Lo, Hi);
+ }
+ 
+ SDOperand MipsTargetLowering::
+ LowerRETURNADDR(SDOperand Op, SelectionDAG &DAG) {
+   // Depths > 0 not supported yet!
+   if (cast<ConstantSDNode>(Op.getOperand(0))->getValue() > 0)
+     return SDOperand();
+   
+   // Just load the return address
+   SDOperand RetAddrFI = getReturnAddressFrameIndex(DAG);
+   return DAG.getLoad(getPointerTy(), DAG.getEntryNode(), RetAddrFI, NULL, 0);
+ }
+ 
+ //===----------------------------------------------------------------------===//
+ //                      Calling Convention Implementation
+ //
+ //  The lower operations present on calling convention works on this order:
+ //      LowerCALL (virt regs --> phys regs, virt regs --> stack) 
+ //      LowerFORMAL_ARGUMENTS (phys --> virt regs, stack --> virt regs)
+ //      LowerRET (virt regs --> phys regs)
+ //      LowerCALL (phys regs --> virt regs)
+ //
+ //===----------------------------------------------------------------------===//
+ 
+ #include "MipsGenCallingConv.inc"
+ 
+ //===----------------------------------------------------------------------===//
+ //                  CALL Calling Convention Implementation
+ //===----------------------------------------------------------------------===//
+ 
+ /// Mips custom CALL implementation
+ SDOperand MipsTargetLowering::
+ LowerCALL(SDOperand Op, SelectionDAG &DAG)
+ {
+   unsigned CallingConv= cast<ConstantSDNode>(Op.getOperand(1))->getValue();
+ 
+   // By now, only CallingConv::C implemented
+   switch (CallingConv) 
+   {
+     default:
+       assert(0 && "Unsupported calling convention");
+     case CallingConv::Fast:
+     case CallingConv::C:
+       return LowerCCCCallTo(Op, DAG, CallingConv);
+   }
+ }
+ 
+ /// LowerCCCCallTo - functions arguments are copied from virtual
+ /// regs to (physical regs)/(stack frame), CALLSEQ_START and
+ /// CALLSEQ_END are emitted.
+ /// TODO: isVarArg, isTailCall, sret, GOT, linkage types.
+ SDOperand MipsTargetLowering::
+ LowerCCCCallTo(SDOperand Op, SelectionDAG &DAG, unsigned CC) 
+ {
+   SDOperand Chain  = Op.getOperand(0);
+   SDOperand Callee = Op.getOperand(4);
+ 
+   // Analyze operands of the call, assigning locations to each operand.
+   SmallVector<CCValAssign, 16> ArgLocs;
+   CCState CCInfo(CC, getTargetMachine(), ArgLocs);
+   CCInfo.AnalyzeCallOperands(Op.Val, CC_Mips);
+   
+   // Get a count of how many bytes are to be pushed on the stack.
+   unsigned NumBytes = CCInfo.getNextStackOffset();
+ 
+   Chain = DAG.getCALLSEQ_START(Chain,DAG.getConstant(NumBytes, 
+                                  getPointerTy()));
+ 
+   SmallVector<std::pair<unsigned, SDOperand>, 8> RegsToPass;
+   SmallVector<SDOperand, 8> MemOpChains;
+ 
+   SDOperand StackPtr;
+ 
+   // Walk the register/memloc assignments, inserting copies/loads.
+   for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
+     CCValAssign &VA = ArgLocs[i];
+ 
+     // Arguments start after the 5 first operands of ISD::CALL
+     SDOperand Arg = Op.getOperand(5+2*VA.getValNo());
+     
+     // Promote the value if needed.
+     switch (VA.getLocInfo()) {
+       default: assert(0 && "Unknown loc info!");
+       case CCValAssign::Full: break;
+       case CCValAssign::SExt:
+         Arg = DAG.getNode(ISD::SIGN_EXTEND, VA.getLocVT(), Arg);
+         break;
+       case CCValAssign::ZExt:
+         Arg = DAG.getNode(ISD::ZERO_EXTEND, VA.getLocVT(), Arg);
+         break;
+       case CCValAssign::AExt:
+         Arg = DAG.getNode(ISD::ANY_EXTEND, VA.getLocVT(), Arg);
+         break;
+     }
+     
+     // Arguments that can be passed on register, 
+     // must be kept at RegsToPass vector
+     if (VA.isRegLoc()) {
+       RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
+     } else {
+       assert(VA.isMemLoc());
+       // Mips::SP holds our stack pointer
+       if (StackPtr.Val == 0)
+         StackPtr = DAG.getRegister(Mips::SP, getPointerTy());
+      
+       SDOperand PtrOff = DAG.getConstant(VA.getLocMemOffset(), 
+                                          getPointerTy());
+       
+       // emit a ISD::ADD which emits the final 
+       // stack location to place the parameter
+       PtrOff = DAG.getNode(ISD::ADD, getPointerTy(), StackPtr, PtrOff);
+ 
+       // emit ISD::STORE whichs stores the 
+       // parameter value to a stack Location
+       MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
+     }
+   }
+ 
+   // Transform all store nodes into one single node because
+   // all store nodes ar independent of each other.
+   if (!MemOpChains.empty())     
+     Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, 
+                         &MemOpChains[0], MemOpChains.size());
+ 
+   // Build a sequence of copy-to-reg nodes chained together with token 
+   // chain and flag operands which copy the outgoing args into registers.
+   // The InFlag in necessary since all emited instructions must be
+   // stuck together.
+   SDOperand InFlag;
+   for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
+     Chain = DAG.getCopyToReg(Chain, RegsToPass[i].first, 
+                              RegsToPass[i].second, InFlag);
+     InFlag = Chain.getValue(1);
+   }
+ 
+   // If the callee is a GlobalAddress node (quite common, every direct 
+   // call is) turn it into a TargetGlobalAddress node so that legalize 
+   // doesn't hack it.
+   if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
+     Callee = DAG.getTargetGlobalAddress(G->getGlobal(), getPointerTy());
+   } else 
+   if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee))
+     Callee = DAG.getTargetExternalSymbol(S->getSymbol(), getPointerTy());
+ 
+   // MipsJmpLink = #chain, #target_address, #opt_in_flags...
+   //             = Chain, Callee, Reg#1, Reg#2, ...  
+   //
+   // Returns a chain & a flag for retval copy to use.
+   SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Flag);
+   SmallVector<SDOperand, 8> Ops;
+   Ops.push_back(Chain);
+   Ops.push_back(Callee);
+ 
+   // Add argument registers to the end of the list so that they are 
+   // known live into the call.
+   for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i)
+     Ops.push_back(DAG.getRegister(RegsToPass[i].first,
+                                   RegsToPass[i].second.getValueType()));
+ 
+   if (InFlag.Val)
+     Ops.push_back(InFlag);
+ 
+   Chain  = DAG.getNode(MipsISD::JmpLink, NodeTys, &Ops[0], Ops.size());
+   InFlag = Chain.getValue(1);
+ 
+   // Create the CALLSEQ_END node.
+   NodeTys = DAG.getVTList(MVT::Other, MVT::Flag);
+   Ops.clear();
+   Ops.push_back(Chain);
+   Ops.push_back(DAG.getConstant(NumBytes, getPointerTy()));
+   Ops.push_back(InFlag);
+   Chain  = DAG.getNode(ISD::CALLSEQ_END, NodeTys, &Ops[0], Ops.size());
+   InFlag = Chain.getValue(1);
+ 
+   // Handle result values, copying them out of physregs into vregs that we
+   // return.
+   return SDOperand(LowerCallResult(Chain, InFlag, Op.Val, CC, DAG), Op.ResNo);
+ }
+ 
+ /// LowerCallResult - Lower the result values of an ISD::CALL into the
+ /// appropriate copies out of appropriate physical registers.  This assumes that
+ /// Chain/InFlag are the input chain/flag to use, and that TheCall is the call
+ /// being lowered. Returns a SDNode with the same number of values as the 
+ /// ISD::CALL.
+ SDNode *MipsTargetLowering::
+ LowerCallResult(SDOperand Chain, SDOperand InFlag, SDNode *TheCall, 
+         unsigned CallingConv, SelectionDAG &DAG) {
+   
+   // Assign locations to each value returned by this call.
+   SmallVector<CCValAssign, 16> RVLocs;
+   CCState CCInfo(CallingConv, getTargetMachine(), RVLocs);
+   CCInfo.AnalyzeCallResult(TheCall, RetCC_Mips);
+   SmallVector<SDOperand, 8> ResultVals;
+ 
+   // returns void
+   if (!RVLocs.size())
+     return Chain.Val;
+ 
+   // Copy all of the result registers out of their specified physreg.
+   for (unsigned i = 0; i != RVLocs.size(); ++i) {
+     Chain = DAG.getCopyFromReg(Chain, RVLocs[i].getLocReg(),
+                                  RVLocs[i].getValVT(), InFlag).getValue(1);
+     InFlag = Chain.getValue(2);
+     ResultVals.push_back(Chain.getValue(0));
+   }
+   
+   // Merge everything together with a MERGE_VALUES node.
+   ResultVals.push_back(Chain);
+   return DAG.getNode(ISD::MERGE_VALUES, TheCall->getVTList(),
+                        &ResultVals[0], ResultVals.size()).Val;
+ }
+ 
+ //===----------------------------------------------------------------------===//
+ //             FORMAL_ARGUMENTS Calling Convention Implementation
+ //===----------------------------------------------------------------------===//
+ 
+ /// Mips custom FORMAL_ARGUMENTS implementation
+ SDOperand MipsTargetLowering::
+ LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG) 
+ {
+   unsigned CC = cast<ConstantSDNode>(Op.getOperand(1))->getValue();
+   switch(CC) 
+   {
+     default:
+       assert(0 && "Unsupported calling convention");
+     case CallingConv::C:
+       return LowerCCCArguments(Op, DAG);
+   }
+ }
+ 
+ /// LowerCCCArguments - transform physical registers into
+ /// virtual registers and generate load operations for
+ /// arguments places on the stack.
+ /// TODO: isVarArg, sret
+ SDOperand MipsTargetLowering::
+ LowerCCCArguments(SDOperand Op, SelectionDAG &DAG) 
+ {
+   MachineFunction &MF   = DAG.getMachineFunction();
+   MachineFrameInfo *MFI = MF.getFrameInfo();
+   SDOperand Root        = Op.getOperand(0);
+ 
+   // Assign locations to all of the incoming arguments.
+   SmallVector<CCValAssign, 16> ArgLocs;
+   CCState CCInfo(MF.getFunction()->getCallingConv(), 
+                  getTargetMachine(), ArgLocs);
+   CCInfo.AnalyzeFormalArguments(Op.Val, CC_Mips);
+   SmallVector<SDOperand, 8> ArgValues;
+ 
+   for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
+ 
+     CCValAssign &VA = ArgLocs[i];
+ 
+     // Arguments stored on registers
+     if (VA.isRegLoc()) {
+       MVT::ValueType RegVT = VA.getLocVT();
+       TargetRegisterClass *RC;
+             
+       if (RegVT == MVT::i32)
+         RC = Mips::CPURegsRegisterClass;
+       else
+         assert(0 && "support only Mips::CPURegsRegisterClass");
+       
+       unsigned Reg = AddLiveIn(DAG.getMachineFunction(), VA.getLocReg(), RC);
+ 
+       // Transform the arguments stored on 
+       // physical registers into virtual ones
+       SDOperand ArgValue = DAG.getCopyFromReg(Root, Reg, RegVT);
+       
+       // If this is an 8 or 16-bit value, it is really passed promoted 
+       // to 32 bits.  Insert an assert[sz]ext to capture this, then 
+       // truncate to the right size.
+       if (VA.getLocInfo() == CCValAssign::SExt)
+         ArgValue = DAG.getNode(ISD::AssertSext, RegVT, ArgValue,
+                                DAG.getValueType(VA.getValVT()));
+       else if (VA.getLocInfo() == CCValAssign::ZExt)
+         ArgValue = DAG.getNode(ISD::AssertZext, RegVT, ArgValue,
+                                DAG.getValueType(VA.getValVT()));
+       
+       if (VA.getLocInfo() != CCValAssign::Full)
+         ArgValue = DAG.getNode(ISD::TRUNCATE, VA.getValVT(), ArgValue);
+ 
+       ArgValues.push_back(ArgValue);
+ 
+     } else {
+       // sanity check
+       assert(VA.isMemLoc());
+       
+       // Create the frame index object for this incoming parameter...
+       int FI = MFI->CreateFixedObject(MVT::getSizeInBits(VA.getValVT())/8,
+                                       VA.getLocMemOffset());
+ 
+       // Create load nodes to retrieve arguments from the stack
+       SDOperand FIN = DAG.getFrameIndex(FI, getPointerTy());
+       ArgValues.push_back(DAG.getLoad(VA.getValVT(), Root, FIN, NULL, 0));
+     }
+   }
+   ArgValues.push_back(Root);
+ 
+   ReturnAddrIndex = 0;
+ 
+   // Return the new list of results.
+   return DAG.getNode(ISD::MERGE_VALUES, Op.Val->getVTList(),
+                      &ArgValues[0], ArgValues.size()).getValue(Op.ResNo);
+ }
+ 
+ //===----------------------------------------------------------------------===//
+ //               Return Value Calling Convention Implementation
+ //===----------------------------------------------------------------------===//
+ 
+ SDOperand MipsTargetLowering::
+ LowerRET(SDOperand Op, SelectionDAG &DAG)
+ {
+   // CCValAssign - represent the assignment of
+   // the return value to a location
+   SmallVector<CCValAssign, 16> RVLocs;
+   unsigned CC = DAG.getMachineFunction().getFunction()->getCallingConv();
+ 
+   // CCState - Info about the registers and stack slot.
+   CCState CCInfo(CC, getTargetMachine(), RVLocs);
+ 
+   // Analize return values of ISD::RET
+   CCInfo.AnalyzeReturn(Op.Val, RetCC_Mips);
+ 
+   // If this is the first return lowered for this function, add 
+   // the regs to the liveout set for the function.
+   if (DAG.getMachineFunction().liveout_empty()) {
+     for (unsigned i = 0; i != RVLocs.size(); ++i)
+       DAG.getMachineFunction().addLiveOut(RVLocs[i].getLocReg());
+   }
+ 
+   // The chain is always operand #0
+   SDOperand Chain = Op.getOperand(0);
+   SDOperand Flag;
+ 
+   // Copy the result values into the output registers.
+   for (unsigned i = 0; i != RVLocs.size(); ++i) {
+     CCValAssign &VA = RVLocs[i];
+     assert(VA.isRegLoc() && "Can only return in registers!");
+ 
+     // ISD::RET => ret chain, (regnum1,val1), ...
+     // So i*2+1 index only the regnums
+     Chain = DAG.getCopyToReg(Chain, VA.getLocReg(), 
+                                  Op.getOperand(i*2+1), Flag);
+ 
+     // guarantee that all emitted copies are
+     // stuck together, avoiding something bad
+     Flag = Chain.getValue(1);
+   }
+ 
+   // Return on Mips is always a "jr $ra"
+   if (Flag.Val)
+     return DAG.getNode(MipsISD::Ret, MVT::Other, 
+                            Chain, DAG.getRegister(Mips::RA, MVT::i32), Flag);
+   else // Return Void
+     return DAG.getNode(MipsISD::Ret, MVT::Other, 
+                            Chain, DAG.getRegister(Mips::RA, MVT::i32));
+ }


Index: llvm/lib/Target/Mips/MipsISelLowering.h
diff -c /dev/null llvm/lib/Target/Mips/MipsISelLowering.h:1.1
*** /dev/null	Wed Jun  6 02:43:11 2007
--- llvm/lib/Target/Mips/MipsISelLowering.h	Wed Jun  6 02:42:06 2007
***************
*** 0 ****
--- 1,83 ----
+ //===-- MipsISelLowering.h - Mips DAG Lowering Interface --------*- C++ -*-===//
+ //
+ //                     The LLVM Compiler Infrastructure
+ //
+ // This file was developed by Bruno Cardoso Lopes and is distributed under the 
+ // University of Illinois Open Source License. See LICENSE.TXT for details.
+ //
+ //===----------------------------------------------------------------------===//
+ //
+ // This file defines the interfaces that Mips uses to lower LLVM code into a
+ // selection DAG.
+ //
+ //===----------------------------------------------------------------------===//
+ 
+ #ifndef MipsISELLOWERING_H
+ #define MipsISELLOWERING_H
+ 
+ #include "llvm/CodeGen/SelectionDAG.h"
+ #include "llvm/Target/TargetLowering.h"
+ #include "Mips.h"
+ #include "MipsSubtarget.h"
+ 
+ namespace llvm {
+   namespace MipsISD {
+     enum NodeType {
+       // Start the numbering from where ISD NodeType finishes.
+       FIRST_NUMBER = ISD::BUILTIN_OP_END+Mips::INSTRUCTION_LIST_END,
+ 
+       // Jump and link (call)
+       JmpLink,
+ 
+       // Get the Higher 16 bits from a 32-bit immediate
+       // No relation with Mips Hi register
+       Hi, 
+ 
+       // Get the Lower 16 bits from a 32-bit immediate
+       // No relation with Mips Lo register
+       Lo, 
+ 
+       // Return 
+       Ret
+     };
+   }
+ 
+   //===--------------------------------------------------------------------===//
+   // TargetLowering Implementation
+   //===--------------------------------------------------------------------===//
+   class MipsTargetLowering : public TargetLowering 
+   {
+     // FrameIndex for return slot.
+     int ReturnAddrIndex;
+ 
+     // const MipsSubtarget &MipsSubTarget;
+   public:
+ 
+     MipsTargetLowering(MipsTargetMachine &TM);
+ 
+     /// LowerOperation - Provide custom lowering hooks for some operations.
+     virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG);
+ 
+     /// getTargetNodeName - This method returns the name of a target specific 
+     //  DAG node.
+     virtual const char *getTargetNodeName(unsigned Opcode) const;
+ 
+   private:
+     // Lower Operand helpers
+     SDOperand LowerCCCArguments(SDOperand Op, SelectionDAG &DAG);
+     SDOperand LowerCCCCallTo(SDOperand Op, SelectionDAG &DAG, unsigned CC);
+     SDNode *LowerCallResult(SDOperand Chain, SDOperand InFlag, SDNode*TheCall,
+                             unsigned CallingConv, SelectionDAG &DAG);
+     SDOperand getReturnAddressFrameIndex(SelectionDAG &DAG);
+ 
+     // Lower Operand specifics
+     SDOperand LowerRET(SDOperand Op, SelectionDAG &DAG);
+     SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG);
+     SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG);
+     SDOperand LowerGlobalAddress(SDOperand Op, SelectionDAG &DAG);
+     SDOperand LowerRETURNADDR(SDOperand Op, SelectionDAG &DAG);
+ 
+   };
+ }
+ 
+ #endif // MipsISELLOWERING_H


Index: llvm/lib/Target/Mips/MipsInstrFormats.td
diff -c /dev/null llvm/lib/Target/Mips/MipsInstrFormats.td:1.1
*** /dev/null	Wed Jun  6 02:43:11 2007
--- llvm/lib/Target/Mips/MipsInstrFormats.td	Wed Jun  6 02:42:06 2007
***************
*** 0 ****
--- 1,96 ----
+ //===- MipsRegisterInfo.td - Mips Register defs -----------------*- C++ -*-===//
+ //
+ //                     The LLVM Compiler Infrastructure
+ //
+ // This file was developed by Bruno Cardoso Lopes and is distributed under the 
+ // University of Illinois Open Source License. See LICENSE.TXT for details.
+ //
+ //===----------------------------------------------------------------------===//
+ 
+ //===----------------------------------------------------------------------===//
+ //  Describe MIPS instructions format
+ //
+ //  All the possible Mips fields are:
+ //
+ //  opcode  - operation code.
+ //  rs      - src reg.
+ //  rt      - dst reg (on a 2 regs instr) or src reg (on a 3 reg instr).
+ //  rd      - dst reg, only used on 3 regs instr.
+ //  shamt   - only used on shift instructions, contains the shift amount.
+ //  funct   - combined with opcode field give us an operation code.
+ //
+ //===----------------------------------------------------------------------===//
+ 
+ // Generic Mips Format
+ class MipsInst<dag ops, string asmstr, list<dag> pattern>: 
+       Instruction 
+ {
+   field bits<32> Inst;
+ 
+   let Namespace = "Mips";
+ 
+   bits<6> opcode;
+ 
+   // Top 5 bits are the 'opcode' field
+   let Inst{31-26} = opcode;   
+   
+   dag OperandList = ops;
+   let AsmString   = asmstr;
+   let Pattern     = pattern;
+ }
+ 
+ 
+ //===----------------------------------------------------------------------===//
+ // Format R instruction class in Mips : <|opcode|rs|rt|rd|shamt|funct|>
+ //===----------------------------------------------------------------------===//
+ 
+ class FR<bits<6> op, bits<6> _funct, dag ops, string asmstr, list<dag> pattern>:
+       MipsInst<ops, asmstr, pattern> 
+ {
+   bits<5>  rd;
+   bits<5>  rs;
+   bits<5>  rt;
+   bits<5>  shamt;
+   bits<6>  funct;
+ 
+   let opcode = op;
+   let funct  = _funct;
+ 
+   let Inst{25-21} = rs;
+   let Inst{20-16} = rt; 
+   let Inst{15-11} = rd;
+   let Inst{10-6}  = shamt;
+   let Inst{5-0}   = funct;
+ }
+ 
+ //===----------------------------------------------------------------------===//
+ // Format I instruction class in Mips : <|opcode|rs|rt|immediate|>
+ //===----------------------------------------------------------------------===//
+ 
+ class FI<bits<6> op, dag ops, string asmstr, list<dag> pattern>: 
+       MipsInst<ops, asmstr, pattern> 
+ {
+   bits<5>  rt;
+   bits<5>  rs;
+   bits<16> imm16;
+ 
+   let opcode = op;
+ 
+   let Inst{25-21} = rs;
+   let Inst{20-16} = rt; 
+   let Inst{15-0}  = imm16;
+ }
+ 
+ //===----------------------------------------------------------------------===//
+ // Format J instruction class in Mips : <|opcode|address|>
+ //===----------------------------------------------------------------------===//
+ 
+ class FJ<bits<6> op, dag ops, string asmstr, list<dag> pattern>: 
+       MipsInst<ops, asmstr, pattern> 
+ {
+   bits<26> addr;
+ 
+   let opcode = op;
+   
+   let Inst{25-0} = addr;
+ }


Index: llvm/lib/Target/Mips/MipsInstrInfo.cpp
diff -c /dev/null llvm/lib/Target/Mips/MipsInstrInfo.cpp:1.1
*** /dev/null	Wed Jun  6 02:43:11 2007
--- llvm/lib/Target/Mips/MipsInstrInfo.cpp	Wed Jun  6 02:42:06 2007
***************
*** 0 ****
--- 1,114 ----
+ //===- MipsInstrInfo.cpp - Mips Instruction Information ---------*- C++ -*-===//
+ //
+ //                     The LLVM Compiler Infrastructure
+ //
+ // This file was developed by Bruno Cardoso Lopes and is distributed under the 
+ // University of Illinois Open Source License. See LICENSE.TXT for details.
+ //
+ //===----------------------------------------------------------------------===//
+ //
+ // This file contains the Mips implementation of the TargetInstrInfo class.
+ //
+ //===----------------------------------------------------------------------===//
+ 
+ #include "Mips.h"
+ #include "MipsInstrInfo.h"
+ #include "llvm/CodeGen/MachineInstrBuilder.h"
+ #include "MipsGenInstrInfo.inc"
+ 
+ using namespace llvm;
+ 
+ // TODO: Add the subtarget support on this constructor
+ MipsInstrInfo::MipsInstrInfo(MipsTargetMachine &tm)
+   : TargetInstrInfo(MipsInsts, sizeof(MipsInsts)/sizeof(MipsInsts[0])),
+     TM(tm), RI(*this) {}
+ 
+ static bool isZeroImm(const MachineOperand &op) {
+   return op.isImmediate() && op.getImmedValue() == 0;
+ }
+ 
+ /// Return true if the instruction is a register to register move and
+ /// leave the source and dest operands in the passed parameters.
+ bool MipsInstrInfo::
+ isMoveInstr(const MachineInstr &MI, unsigned &SrcReg, unsigned &DstReg) const 
+ {
+   //  addu  $dst, $src, $zero || addu  $dst, $zero, $src
+   //  or    $dst, $src, $zero || or    $dst, $zero, $src
+   if ((MI.getOpcode() == Mips::ADDu) || (MI.getOpcode() == Mips::OR))
+   {
+     if (MI.getOperand(1).getReg() == Mips::ZERO) {
+       DstReg = MI.getOperand(0).getReg();
+       SrcReg = MI.getOperand(2).getReg();
+       return true;
+     } else if (MI.getOperand(2).getReg() == Mips::ZERO) {
+       DstReg = MI.getOperand(0).getReg();
+       SrcReg = MI.getOperand(1).getReg();
+       return true;
+     }
+   }
+ 
+   //  addiu $dst, $src, 0
+   if (MI.getOpcode() == Mips::ADDiu) 
+   {
+     if ((MI.getOperand(1).isRegister()) && (isZeroImm(MI.getOperand(2)))) {
+       DstReg = MI.getOperand(0).getReg();
+       SrcReg = MI.getOperand(1).getReg();
+       return true;
+     }
+   }
+   return false;
+ }
+ 
+ /// isLoadFromStackSlot - If the specified machine instruction is a direct
+ /// load from a stack slot, return the virtual or physical register number of
+ /// the destination along with the FrameIndex of the loaded stack slot.  If
+ /// not, return 0.  This predicate must return 0 if the instruction has
+ /// any side effects other than loading from the stack slot.
+ unsigned MipsInstrInfo::
+ isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const 
+ {
+   // TODO: add lhu, lbu ???
+   if (MI->getOpcode() == Mips::LW) 
+   {
+     if ((MI->getOperand(2).isFrameIndex()) && // is a stack slot
+         (MI->getOperand(1).isImmediate()) &&  // the imm is zero
+         (isZeroImm(MI->getOperand(1)))) 
+     {
+       FrameIndex = MI->getOperand(2).getFrameIndex();
+       return MI->getOperand(0).getReg();
+     }
+   }
+ 
+   return 0;
+ }
+ 
+ /// isStoreToStackSlot - If the specified machine instruction is a direct
+ /// store to a stack slot, return the virtual or physical register number of
+ /// the source reg along with the FrameIndex of the loaded stack slot.  If
+ /// not, return 0.  This predicate must return 0 if the instruction has
+ /// any side effects other than storing to the stack slot.
+ unsigned MipsInstrInfo::
+ isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) const 
+ {
+   // TODO: add sb, sh ???
+   if (MI->getOpcode() == Mips::SW) {
+     if ((MI->getOperand(0).isFrameIndex()) && // is a stack slot
+         (MI->getOperand(1).isImmediate()) &&  // the imm is zero
+         (isZeroImm(MI->getOperand(1)))) 
+     {
+       FrameIndex = MI->getOperand(0).getFrameIndex();
+       return MI->getOperand(2).getReg();
+     }
+   }
+   return 0;
+ }
+ 
+ unsigned MipsInstrInfo::
+ InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, 
+              MachineBasicBlock *FBB, const std::vector<MachineOperand> &Cond)
+              const
+ {
+   // TODO: add Mips::J here.
+   assert(0 && "Cant handle any kind of branches!");
+   return 1;
+ }


Index: llvm/lib/Target/Mips/MipsInstrInfo.h
diff -c /dev/null llvm/lib/Target/Mips/MipsInstrInfo.h:1.1
*** /dev/null	Wed Jun  6 02:43:11 2007
--- llvm/lib/Target/Mips/MipsInstrInfo.h	Wed Jun  6 02:42:06 2007
***************
*** 0 ****
--- 1,63 ----
+ //===- MipsInstrInfo.h - Mips Instruction Information -----------*- C++ -*-===//
+ //
+ //                     The LLVM Compiler Infrastructure
+ //
+ // This file was developed by Bruno Cardoso Lopes and is distributed under the 
+ // University of Illinois Open Source License. See LICENSE.TXT for details.
+ //
+ //===----------------------------------------------------------------------===//
+ //
+ // This file contains the Mips implementation of the TargetInstrInfo class.
+ //
+ //===----------------------------------------------------------------------===//
+ 
+ #ifndef MIPSINSTRUCTIONINFO_H
+ #define MIPSINSTRUCTIONINFO_H
+ 
+ #include "Mips.h"
+ #include "llvm/Target/TargetInstrInfo.h"
+ #include "MipsRegisterInfo.h"
+ 
+ namespace llvm {
+ 
+ class MipsInstrInfo : public TargetInstrInfo 
+ {
+   MipsTargetMachine &TM;
+   const MipsRegisterInfo RI;
+ public:
+   MipsInstrInfo(MipsTargetMachine &TM);
+ 
+   /// getRegisterInfo - TargetInstrInfo is a superset of MRegister info.  As
+   /// such, whenever a client has an instance of instruction info, it should
+   /// always be able to get register info as well (through this method).
+   ///
+   virtual const MRegisterInfo &getRegisterInfo() const { return RI; }
+ 
+   /// Return true if the instruction is a register to register move and
+   /// leave the source and dest operands in the passed parameters.
+   ///
+   virtual bool isMoveInstr(const MachineInstr &MI,
+                            unsigned &SrcReg, unsigned &DstReg) const;
+   
+   /// isLoadFromStackSlot - If the specified machine instruction is a direct
+   /// load from a stack slot, return the virtual or physical register number of
+   /// the destination along with the FrameIndex of the loaded stack slot.  If
+   /// not, return 0.  This predicate must return 0 if the instruction has
+   /// any side effects other than loading from the stack slot.
+   virtual unsigned isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const;
+   
+   /// isStoreToStackSlot - If the specified machine instruction is a direct
+   /// store to a stack slot, return the virtual or physical register number of
+   /// the source reg along with the FrameIndex of the loaded stack slot.  If
+   /// not, return 0.  This predicate must return 0 if the instruction has
+   /// any side effects other than storing to the stack slot.
+   virtual unsigned isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) const;
+   
+   virtual unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
+                                 MachineBasicBlock *FBB, 
+                                 const std::vector<MachineOperand> &Cond) const;
+ };
+ 
+ }
+ 
+ #endif


Index: llvm/lib/Target/Mips/MipsInstrInfo.td
diff -c /dev/null llvm/lib/Target/Mips/MipsInstrInfo.td:1.1
*** /dev/null	Wed Jun  6 02:43:11 2007
--- llvm/lib/Target/Mips/MipsInstrInfo.td	Wed Jun  6 02:42:06 2007
***************
*** 0 ****
--- 1,468 ----
+ //===- MipsInstrInfo.td - Mips Register defs --------------------*- C++ -*-===//
+ //
+ //                     The LLVM Compiler Infrastructure
+ //
+ // This file was developed by Bruno Cardoso Lopes and is distributed under the 
+ // University of Illinois Open Source License. See LICENSE.TXT for details.
+ //
+ //===----------------------------------------------------------------------===//
+ 
+ //===----------------------------------------------------------------------===//
+ // Instruction format superclass
+ //===----------------------------------------------------------------------===//
+ 
+ include "MipsInstrFormats.td"
+ 
+ //===----------------------------------------------------------------------===//
+ // Mips profiles and nodes
+ //===----------------------------------------------------------------------===//
+ 
+ // Call
+ def SDT_MipsJmpLink : SDTypeProfile<0, 1, [SDTCisVT<0, iPTR>]>;
+ def MipsJmpLink     : SDNode<"MipsISD::JmpLink",SDT_MipsJmpLink, [SDNPHasChain,
+                              SDNPOutFlag]>;
+ 
+ // Hi and Lo nodes are created to let easy manipulation of 16-bit when 
+ // handling 32-bit immediates. They are used on MipsISelLowering to 
+ // lower stuff like GlobalAddress, ExternalSymbol, ...
+ // This two nodes have nothing to do with Mips Registers Hi and Lo.
+ def MipsHi : SDNode<"MipsISD::Hi", SDTIntUnaryOp>;
+ def MipsLo : SDNode<"MipsISD::Lo", SDTIntUnaryOp>; 
+ 
+ // Return 
+ def SDT_MipsRet : SDTypeProfile<0, 1, [SDTCisInt<0>]>; 
+ def MipsRet     : SDNode<"MipsISD::Ret", SDT_MipsRet, [SDNPHasChain, 
+                              SDNPOptInFlag]>;
+ 
+ // These are target-independent nodes, but have target-specific formats.
+ def SDT_MipsCallSeq : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>;
+ def callseq_start   : SDNode<"ISD::CALLSEQ_START", SDT_MipsCallSeq, 
+                              [SDNPHasChain, SDNPOutFlag]>;
+ def callseq_end     : SDNode<"ISD::CALLSEQ_END", SDT_MipsCallSeq, 
+                              [SDNPHasChain, SDNPOutFlag]>;
+ 
+ // Instruction operand types
+ def brtarget    : Operand<OtherVT>;
+ def calltarget  : Operand<i32>;
+ def uimm16      : Operand<i32>;
+ def simm16      : Operand<i32>;
+ def shamt       : Operand<i32>; 
+ 
+ // Address operand
+ def mem : Operand<i32> {
+   let PrintMethod = "printMemOperand";
+   let MIOperandInfo = (ops simm16, CPURegs);
+ }
+ 
+ //===----------------------------------------------------------------------===//
+ // Mips Patterns and Transformations
+ //===----------------------------------------------------------------------===//
+ 
+ // Transformation Function - get the lower 16 bits.
+ def LO16 : SDNodeXForm<imm, [{
+   return getI32Imm((unsigned)N->getValue() & 0xFFFF);
+ }]>;
+ 
+ // Transformation Function - get the higher 16 bits.
+ def HI16 : SDNodeXForm<imm, [{
+   return getI32Imm((unsigned)N->getValue() >> 16);
+ }]>;
+ 
+ // Node immediate fits as 16-bit sign extended on target immediate.
+ // e.g. addi, andi
+ def immSExt16  : PatLeaf<(imm), [{
+   if (N->getValueType(0) == MVT::i32)
+     return (int32_t)N->getValue() == (short)N->getValue();
+   else
+     return (int64_t)N->getValue() == (short)N->getValue();
+ }]>;
+ 
+ // Node immediate fits as 16-bit zero extended on target immediate.
+ // The LO16 param means that only the lower 16 bits of the node
+ // immediate are caught.
+ // e.g. addiu, sltiu
+ def immZExt16  : PatLeaf<(imm), [{
+   return (uint64_t)N->getValue() == (unsigned short)N->getValue();
+ }], LO16>;
+ 
+ // Node immediate must have only it's 16 high bits set.
+ // The HI16 param means that only the higher 16 bits of the node
+ // immediate are caught.
+ // e.g. lui
+ def imm16ShiftedZExt : PatLeaf<(imm), [{
+   return (N->getValue() & ~uint64_t(0xFFFF0000)) == 0;
+ }], HI16>;
+ 
+ // shamt field must fit in 5 bits.
+ def immZExt5 : PatLeaf<(imm), [{
+   return N->getValue() == ((N->getValue()) & 0x1f) ;
+ }]>;
+ 
+ // Mips Address Mode! SDNode frameindex could possibily be a match 
+ // since load and store instructions from stack used it.
+ def addr : ComplexPattern<i32, 2, "SelectAddr", [frameindex], []>;
+ 
+ //===----------------------------------------------------------------------===//
+ // Instructions specific format
+ //===----------------------------------------------------------------------===//
+ 
+ // Arithmetic 3 register operands
+ let isCommutable = 1 in 
+ class ArithR< bits<6> op, bits<6> func, string instr_asm, SDNode OpNode>: 
+   FR< op, 
+       func, 
+       (ops CPURegs:$dst, CPURegs:$b, CPURegs:$c), 
+       !strconcat(instr_asm, " $dst, $b, $c"), 
+       [(set CPURegs:$dst, (OpNode CPURegs:$b, CPURegs:$c))] >;
+ 
+ let isCommutable = 1 in 
+ class ArithOverflowR< bits<6> op, bits<6> func, string instr_asm>: 
+   FR< op, 
+       func, 
+       (ops CPURegs:$dst, CPURegs:$b, CPURegs:$c), 
+       !strconcat(instr_asm, " $dst, $b, $c"), 
+       []>;
+ 
+ // Arithmetic 2 register operands
+ let isCommutable = 1 in
+ class ArithI<bits<6> op, string instr_asm, SDNode OpNode, 
+              Operand Od, PatLeaf imm_type> : 
+   FI< op, 
+       (ops CPURegs:$dst, CPURegs:$b, Od:$c), 
+       !strconcat(instr_asm, " $dst, $b, $c"), 
+       [(set CPURegs:$dst, (OpNode CPURegs:$b, imm_type:$c))] >;
+ 
+ // Arithmetic Multiply ADD/SUB
+ let rd=0 in
+ class MArithR<bits<6> func, string instr_asm> : 
+   FR< 0x1c, 
+       func,
+       (ops CPURegs:$rs, CPURegs:$rt), 
+       !strconcat(instr_asm, " $rs, $rt"), 
+       []>;
+ 
+ //  Logical
+ class LogicR<bits<6> func, string instr_asm, SDNode OpNode>:
+   FR< 0x00, 
+       func, 
+       (ops CPURegs:$dst, CPURegs:$b, CPURegs:$c), 
+       !strconcat(instr_asm, " $dst, $b, $c"), 
+       [(set CPURegs:$dst, (OpNode CPURegs:$b, CPURegs:$c))] >;
+ 
+ class LogicI<bits<6> op, string instr_asm, SDNode OpNode>:
+   FI< op,
+       (ops CPURegs:$dst, CPURegs:$b, uimm16:$c),
+       !strconcat(instr_asm, " $dst, $b, $c"),
+       [(set CPURegs:$dst, (OpNode CPURegs:$b, immSExt16:$c))]>;
+ 
+ class LogicNOR<bits<6> op, bits<6> func, string instr_asm>:
+   FR< op, 
+       func, 
+       (ops CPURegs:$dst, CPURegs:$b, CPURegs:$c), 
+       !strconcat(instr_asm, " $dst, $b, $c"), 
+       [(set CPURegs:$dst, (not (or CPURegs:$b, CPURegs:$c)))] >;
+ 
+ // Shifts
+ let rt = 0 in
+ class LogicR_shift_imm<bits<6> func, string instr_asm, SDNode OpNode>:
+   FR< 0x00, 
+       func, 
+       (ops CPURegs:$dst, CPURegs:$b, shamt:$c),
+       !strconcat(instr_asm, " $dst, $b, $c"), 
+       [(set CPURegs:$dst, (OpNode CPURegs:$b, immZExt5:$c))] >;
+ 
+ class LogicR_shift_reg<bits<6> func, string instr_asm, SDNode OpNode>:
+   FR< 0x00, 
+       func, 
+       (ops CPURegs:$dst, CPURegs:$b, CPURegs:$c),
+       !strconcat(instr_asm, " $dst, $b, $c"), 
+       [(set CPURegs:$dst, (OpNode CPURegs:$b, CPURegs:$c))] >;
+ 
+ // Load Upper Imediate
+ class LoadUpper<bits<6> op, string instr_asm>:
+   FI< op,
+       (ops CPURegs:$dst, uimm16:$imm),
+       !strconcat(instr_asm, " $dst, $imm"),
+       [(set CPURegs:$dst, imm16ShiftedZExt:$imm)]>;
+ 
+ // Memory Load/Store 
+ let isLoad = 1 in
+ class LoadM<bits<6> op, string instr_asm, PatFrag OpNode>:
+   FI< op,
+       (ops CPURegs:$dst, mem:$addr),
+       !strconcat(instr_asm, " $dst, $addr"),
+       [(set CPURegs:$dst, (OpNode addr:$addr))]>;
+ 
+ let isStore = 1 in
+ class StoreM<bits<6> op, string instr_asm, PatFrag OpNode>:
+   FI< op,
+       (ops CPURegs:$dst, mem:$addr),
+       !strconcat(instr_asm, " $dst, $addr"),
+       [(OpNode CPURegs:$dst, addr:$addr)]>;
+ 
+ // Conditional Branch
+ let isBranch = 1, noResults=1, isTerminator=1 in
+ class CBranch<bits<6> op, string instr_asm, PatFrag cond_op>:
+   FI< op,
+       (ops CPURegs:$a, CPURegs:$b, brtarget:$offset),
+       !strconcat(instr_asm, " $a, $b, $offset"),
+       [(brcond (cond_op CPURegs:$a, CPURegs:$b), bb:$offset)]>;
+ 
+ class SetCC_R<bits<6> op, bits<6> func, string instr_asm,
+       PatFrag cond_op>:
+   FR< op,
+       func,
+       (ops CPURegs:$dst, CPURegs:$b, CPURegs:$c),
+       !strconcat(instr_asm, " $dst, $b, $c"),
+       [(set CPURegs:$dst, (cond_op CPURegs:$b, CPURegs:$c))]>;
+ 
+ class SetCC_I<bits<6> op, string instr_asm, PatFrag cond_op,
+       Operand Od, PatLeaf imm_type>:
+   FI< op,
+       (ops CPURegs:$dst, CPURegs:$b, Od:$c),
+       !strconcat(instr_asm, " $dst, $b, $c"),
+       [(set CPURegs:$dst, (cond_op CPURegs:$b, imm_type:$c))]>;
+ 
+ // Unconditional branch
+ let hasCtrlDep=1, noResults=1, isTerminator=1 in
+ class JumpFJ<bits<6> op, string instr_asm>:
+   FJ< op,
+       (ops brtarget:$target),
+       !strconcat(instr_asm, " $target"),
+       [(br bb:$target)]>;
+ 
+ let hasCtrlDep=1, noResults=1, isTerminator=1, rd=0 in
+ class JumpFR<bits<6> op, bits<6> func, string instr_asm>:
+   FR< op,
+       func,
+       (ops CPURegs:$target),
+       !strconcat(instr_asm, " $target"),
+       []>;
+ 
+ // Jump and Link (Call)
+ let isCall=1 in
+ class JumpLink<bits<6> op, string instr_asm>: 
+   FJ< op,
+       (ops calltarget:$target),
+       !strconcat(instr_asm, " $target"),
+       [(MipsJmpLink imm:$target)]>;
+ 
+ let isCall=1 in
+ class JumpLinkReg<bits<6> op, bits<6> func, string instr_asm>:
+   FR< op,
+       func,
+       (ops CPURegs:$rd, CPURegs:$rs),
+       !strconcat(instr_asm, " $rs, $rd"),
+       []>;
+ 
+ // Mul, Div 
+ class MulDiv<bits<6> func, string instr_asm>: 
+   FR< 0x00, 
+       func, 
+       (ops CPURegs:$a, CPURegs:$b), 
+       !strconcat(instr_asm, " $a, $b"), 
+       []>;
+ 
+ // Move from Hi/Lo 
+ class MoveFromTo<bits<6> func, string instr_asm>:
+   FR< 0x00, 
+       func, 
+       (ops CPURegs:$dst), 
+       !strconcat(instr_asm, " $dst"), 
+       []>;
+ 
+ // Count Leading Ones/Zeros in Word
+ class CountLeading<bits<6> func, string instr_asm>:
+   FR< 0x1c, 
+       func, 
+       (ops CPURegs:$dst, CPURegs:$src), 
+       !strconcat(instr_asm, " $dst, $src"), 
+       []>;
+ 
+ 
+ //===----------------------------------------------------------------------===//
+ // Pseudo instructions
+ //===----------------------------------------------------------------------===//
+ 
+ class Pseudo<dag ops, string asmstr, list<dag> pattern>: 
+       MipsInst<ops, asmstr, pattern>;
+ 
+ // As stack alignment is always done with addiu, we need a 16-bit immediate
+ def ADJCALLSTACKDOWN : Pseudo<(ops uimm16:$amt),
+                               "!ADJCALLSTACKDOWN $amt",
+                               [(callseq_start imm:$amt)]>, Imp<[SP],[SP]>;
+ def ADJCALLSTACKUP   : Pseudo<(ops uimm16:$amt),
+                               "!ADJCALLSTACKUP $amt",
+                               [(callseq_end imm:$amt)]>, Imp<[SP],[SP]>;
+ 
+ def IMPLICIT_DEF_CPURegs : Pseudo<(ops CPURegs:$dst),
+                                   "!IMPLICIT_DEF $dst",
+                                   [(set CPURegs:$dst, (undef))]>;
+ 
+ //===----------------------------------------------------------------------===//
+ // Instruction definition
+ //===----------------------------------------------------------------------===//
+ 
+ //===----------------------------------------------------------------------===//
+ // Mips32 I
+ //===----------------------------------------------------------------------===//
+ 
+ // Arithmetic
+ def ADDi    : ArithI<0x08, "addi",  add, simm16, immZExt16>;
+ def ADDiu   : ArithI<0x09, "addiu", add, uimm16, immSExt16>;
+ def MUL     : ArithR<0x1c, 0x02, "mul", mul>;
+ def ADDu    : ArithR<0x00, 0x21, "addu", add>;
+ def SUBu    : ArithR<0x00, 0x23, "subu", sub>;
+ def ADD     : ArithOverflowR<0x00, 0x20, "add">;
+ def SUB     : ArithOverflowR<0x00, 0x22, "sub">;
+ def MADD    : MArithR<0x00, "madd">;
+ def MADDU   : MArithR<0x01, "maddu">;
+ def MSUB    : MArithR<0x04, "msub">;
+ def MSUBU   : MArithR<0x05, "msubu">;
+ 
+ // Logical
+ def AND     : LogicR<0x24, "and", and>;
+ def OR      : LogicR<0x25, "or",  or>;
+ def XOR     : LogicR<0x26, "xor", xor>;
+ def ANDi    : LogicI<0x0c, "andi", and>;
+ def ORi     : LogicI<0x0d, "ori",  or>;
+ def XORi    : LogicI<0x0e, "xori",  xor>;
+ def NOR     : LogicNOR<0x00, 0x27, "nor">;
+ 
+ // Shifts 
+ def SLL     : LogicR_shift_imm<0x00, "sll", shl>;
+ def SRL     : LogicR_shift_imm<0x02, "srl", srl>;
+ def SRA     : LogicR_shift_imm<0x03, "sra", sra>;
+ def SLLV    : LogicR_shift_reg<0x04, "sllv", shl>;
+ def SRLV    : LogicR_shift_reg<0x06, "srlv", srl>;
+ def SRAV    : LogicR_shift_reg<0x07, "srav", sra>;
+ 
+ // Load Upper Immediate
+ def LUi     : LoadUpper<0x0f, "lui">;
+ 
+ // Load/Store
+ def LB      : LoadM<0x20, "lb",  sextloadi8>;
+ def LBu     : LoadM<0x24, "lbu", zextloadi8>;
+ def LH      : LoadM<0x21, "lh",  sextloadi16>;
+ def LHu     : LoadM<0x25, "lhu", zextloadi16>;
+ def LW      : LoadM<0x23, "lw",  load>;
+ def SB      : StoreM<0x28, "sb", truncstorei8>;
+ def SH      : StoreM<0x29, "sh", truncstorei16>;
+ def SW      : StoreM<0x2b, "sw", store>;
+ 
+ // Conditional Branch
+ def BEQ     : CBranch<0x04, "beq", seteq>;
+ def BNE     : CBranch<0x05, "bne", setne>;
+ def SLT     : SetCC_R<0x00, 0x2a, "slt", setlt>;
+ def SLTu    : SetCC_R<0x00, 0x2b, "sltu", setult>;
+ def SLTi    : SetCC_I<0x0a, "slti", setlt, simm16, immSExt16>;
+ def SLTiu   : SetCC_I<0x0b, "sltiu", setult, uimm16, immZExt16>;
+ 
+ // Unconditional jump
+ def J       : JumpFJ<0x02, "j">;
+ def JR      : JumpFR<0x00, 0x08, "jr">;
+ 
+ // Jump and Link (Call)
+ def JAL     : JumpLink<0x03, "jal">;
+ def JALR    : JumpLinkReg<0x00, 0x09, "jalr">;
+ 
+ // MulDiv and Move From Hi/Lo operations, have
+ // their correpondent SDNodes created on ISelDAG.
+ // Special Mul, Div operations
+ def MULT    : MulDiv<0x18, "mult">;
+ def MULTu   : MulDiv<0x19, "multu">;
+ def DIV     : MulDiv<0x1a, "div">;
+ def DIVu    : MulDiv<0x1b, "divu">;
+ 
+ // Move From Hi/Lo 
+ def MFHI    : MoveFromTo<0x10, "mfhi">;
+ def MFLO    : MoveFromTo<0x12, "mflo">;
+ def MTHI    : MoveFromTo<0x11, "mthi">;
+ def MTLO    : MoveFromTo<0x13, "mtlo">;
+ 
+ // Count Leading
+ def CLO     : CountLeading<0x21, "clo">;
+ def CLZ     : CountLeading<0x20, "clz">;
+ 
+ // No operation
+ let addr=0 in
+ def NOOP :  FJ<0, (ops), "nop", []>;
+ 
+ // Ret instruction - as mips does not have "ret" a 
+ // jr $ra must be generated.
+ let isReturn=1, isTerminator=1, hasDelaySlot=1, noResults=1,
+     isBarrier=1, hasCtrlDep=1, rs=0, rt=0, shamt=0 in 
+ {
+   def RET : FR <0x00, 0x02, (ops CPURegs:$target),
+                 "jr $target", [(MipsRet CPURegs:$target)]>;
+ }
+ 
+ //===----------------------------------------------------------------------===//
+ //  Arbitrary patterns that map to one or more instructions
+ //===----------------------------------------------------------------------===//
+ 
+ // Small immediates
+ def : Pat<(i32 immSExt16:$in), 
+           (ORi ZERO, imm:$in)>;
+ 
+ // Arbitrary immediates
+ def : Pat<(i32 imm:$imm),
+           (ORi (LUi (HI16 imm:$imm)), (LO16 imm:$imm))>;
+ 
+ // Call
+ def : Pat<(MipsJmpLink (i32 tglobaladdr:$dst)),
+           (JAL tglobaladdr:$dst)>;
+ def : Pat<(MipsJmpLink (i32 texternalsym:$dst)),
+           (JAL texternalsym:$dst)>;
+ 
+ // GlobalAddress, Constant Pool, ExternalSymbol, and JumpTable
+ def : Pat<(MipsHi tglobaladdr:$in), (LUi tglobaladdr:$in)>;
+ def : Pat<(MipsLo tglobaladdr:$in), (ADDiu ZERO, tglobaladdr:$in)>;
+ 
+ // When extracting the address from GlobalAddress we
+ // need something of the form "addiu $reg, %lo(addr)"
+ def : Pat<(add CPURegs:$a, (MipsLo tglobaladdr:$in)),
+           (ADDiu CPURegs:$a, tglobaladdr:$in)>;
+ 
+ // Mips does not have not, so we increase the operation  
+ def : Pat<(not CPURegs:$in),
+           (NOR CPURegs:$in, CPURegs:$in)>;
+ 
+ // extended load and stores 
+ def : Pat<(i32 (extloadi8  addr:$src)), (LBu addr:$src)>;
+ def : Pat<(i32 (extloadi16 addr:$src)), (LHu addr:$src)>;
+ def : Pat<(truncstorei1 CPURegs:$src, addr:$addr), 
+            (SB CPURegs:$src, addr:$src)>;
+ 
+ // Conditional branch patterns.
+ // cond branches patterns, 2 register operands signed.
+ def : Pat<(brcond (setlt CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
+           (BNE (SLT CPURegs:$lhs, CPURegs:$rhs), ZERO, bb:$dst)>;
+ def : Pat<(brcond (setle CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
+           (BEQ (SLT CPURegs:$rhs, CPURegs:$lhs), ZERO, bb:$dst)>;
+ def : Pat<(brcond (setgt CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
+           (BNE (SLT CPURegs:$rhs, CPURegs:$lhs), ZERO, bb:$dst)>;
+ def : Pat<(brcond (setge CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
+           (BEQ (SLT CPURegs:$lhs, CPURegs:$rhs), ZERO, bb:$dst)>;
+ 
+ // cond branches patterns, 2 register operands unsigned.
+ def : Pat<(brcond (setult CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
+           (BNE (SLTu CPURegs:$lhs, CPURegs:$rhs), ZERO, bb:$dst)>;
+ def : Pat<(brcond (setule CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
+           (BEQ (SLTu CPURegs:$rhs, CPURegs:$lhs), ZERO, bb:$dst)>;
+ def : Pat<(brcond (setugt CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
+           (BNE (SLTu CPURegs:$rhs, CPURegs:$lhs), ZERO, bb:$dst)>;
+ def : Pat<(brcond (setuge CPURegs:$lhs, CPURegs:$rhs), bb:$dst),
+           (BEQ (SLTu CPURegs:$lhs, CPURegs:$rhs), ZERO, bb:$dst)>;
+ 
+ // cond branches patterns, reg/imm operands signed.
+ def : Pat<(brcond (setult CPURegs:$lhs, immSExt16:$rhs), bb:$dst),
+           (BNE (SLTi CPURegs:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>;
+ def : Pat<(brcond (setuge CPURegs:$lhs, immSExt16:$rhs), bb:$dst),
+           (BEQ (SLTi CPURegs:$lhs, immSExt16:$rhs), ZERO, bb:$dst)>;
+ 
+ // cond branches patterns, reg/imm operands unsigned.
+ def : Pat<(brcond (setult CPURegs:$lhs, immZExt16:$rhs), bb:$dst),
+           (BNE (SLTiu CPURegs:$lhs, immZExt16:$rhs), ZERO, bb:$dst)>;
+ def : Pat<(brcond (setuge CPURegs:$lhs, immZExt16:$rhs), bb:$dst),
+           (BEQ (SLTiu CPURegs:$lhs, immZExt16:$rhs), ZERO, bb:$dst)>;


Index: llvm/lib/Target/Mips/MipsRegisterInfo.cpp
diff -c /dev/null llvm/lib/Target/Mips/MipsRegisterInfo.cpp:1.1
*** /dev/null	Wed Jun  6 02:43:11 2007
--- llvm/lib/Target/Mips/MipsRegisterInfo.cpp	Wed Jun  6 02:42:06 2007
***************
*** 0 ****
--- 1,288 ----
+ //===- MipsRegisterInfo.cpp - MIPS Register Information -== -----*- C++ -*-===//
+ //
+ //                     The LLVM Compiler Infrastructure
+ //
+ // This file was developed by Bruno Cardoso Lopes and is distributed under the 
+ // University of Illinois Open Source License. See LICENSE.TXT for details.
+ //
+ //===----------------------------------------------------------------------===//
+ //
+ // This file contains the MIPS implementation of the MRegisterInfo class.
+ //
+ //===----------------------------------------------------------------------===//
+ 
+ #define DEBUG_TYPE "mips-reg-info"
+ 
+ #include "Mips.h"
+ #include "MipsRegisterInfo.h"
+ #include "llvm/Constants.h"
+ #include "llvm/Type.h"
+ #include "llvm/Function.h"
+ #include "llvm/CodeGen/ValueTypes.h"
+ #include "llvm/CodeGen/MachineInstrBuilder.h"
+ #include "llvm/CodeGen/MachineFunction.h"
+ #include "llvm/CodeGen/MachineFrameInfo.h"
+ #include "llvm/CodeGen/MachineLocation.h"
+ #include "llvm/Target/TargetFrameInfo.h"
+ #include "llvm/Target/TargetMachine.h"
+ #include "llvm/Target/TargetOptions.h"
+ #include "llvm/Target/TargetInstrInfo.h"
+ #include "llvm/Support/CommandLine.h"
+ #include "llvm/Support/Debug.h"
+ #include "llvm/ADT/BitVector.h"
+ #include "llvm/ADT/STLExtras.h"
+ //#include "MipsSubtarget.h"
+ 
+ using namespace llvm;
+ 
+ // TODO: add subtarget support
+ MipsRegisterInfo::MipsRegisterInfo(const TargetInstrInfo &tii)
+   : MipsGenRegisterInfo(Mips::ADJCALLSTACKDOWN, Mips::ADJCALLSTACKUP),
+   TII(tii) {}
+ 
+ void MipsRegisterInfo::
+ storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
+           unsigned SrcReg, int FI, 
+           const TargetRegisterClass *RC) const 
+ {
+   if (RC == Mips::CPURegsRegisterClass)
+     BuildMI(MBB, I, TII.get(Mips::SW)).addFrameIndex(FI)
+           .addImm(0).addReg(SrcReg, false, false, true);
+   else
+     assert(0 && "Can't store this register to stack slot");
+ }
+ 
+ void MipsRegisterInfo::
+ loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
+                      unsigned DestReg, int FI,
+                      const TargetRegisterClass *RC) const 
+ {
+   if (RC == Mips::CPURegsRegisterClass)
+     BuildMI(MBB, I, TII.get(Mips::LW), DestReg).addImm(0).addFrameIndex(FI);
+   else
+     assert(0 && "Can't load this register from stack slot");
+ }
+ 
+ void MipsRegisterInfo::
+ copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
+              unsigned DestReg, unsigned SrcReg,
+              const TargetRegisterClass *RC) const 
+ {
+   if (RC == Mips::CPURegsRegisterClass)
+     BuildMI(MBB, I, TII.get(Mips::ADDu), DestReg).addReg(Mips::ZERO)
+       .addReg(SrcReg);
+   else
+     assert (0 && "Can't copy this register");
+ }
+ 
+ void MipsRegisterInfo::reMaterialize(MachineBasicBlock &MBB, 
+                                       MachineBasicBlock::iterator I,
+                                       unsigned DestReg, 
+                                       const MachineInstr *Orig) const 
+ {
+     MachineInstr *MI = Orig->clone();
+     MI->getOperand(0).setReg(DestReg);
+     MBB.insert(I, MI);
+ }
+ 
+ MachineInstr *MipsRegisterInfo::
+ foldMemoryOperand(MachineInstr* MI, unsigned OpNum, int FI) const 
+ {
+   MachineInstr *NewMI = NULL;
+ 
+   switch (MI->getOpcode()) 
+   {
+     case Mips::ADDu:
+       if ((MI->getOperand(0).isRegister()) &&
+         (MI->getOperand(1).isRegister()) && 
+         (MI->getOperand(1).getReg() == Mips::ZERO) &&
+         (MI->getOperand(2).isRegister())) 
+       {
+         if (OpNum == 0)    // COPY -> STORE
+           NewMI = BuildMI(TII.get(Mips::SW)).addFrameIndex(FI)
+                   .addImm(0).addReg(MI->getOperand(2).getReg());
+         else               // COPY -> LOAD
+           NewMI = BuildMI(TII.get(Mips::LW), MI->getOperand(0)
+                   .getReg()).addImm(0).addFrameIndex(FI);
+       }
+       break;
+   }
+ 
+   if (NewMI)
+     NewMI->copyKillDeadInfo(MI);
+   return NewMI;
+ }
+ 
+ /// Mips Callee Saved Registers
+ const unsigned* MipsRegisterInfo::
+ getCalleeSavedRegs() const 
+ {
+   // Mips calle-save register range is $16-$26(s0-s7)
+   static const unsigned CalleeSavedRegs[] = {  
+     Mips::S0, Mips::S1, Mips::S2, Mips::S3, 
+     Mips::S4, Mips::S5, Mips::S6, Mips::S7, 0
+   };
+   return CalleeSavedRegs;
+ }
+ 
+ /// Mips Callee Saved Register Classes
+ const TargetRegisterClass* const* 
+ MipsRegisterInfo::getCalleeSavedRegClasses() const 
+ {
+   static const TargetRegisterClass * const CalleeSavedRegClasses[] = {
+     &Mips::CPURegsRegClass, &Mips::CPURegsRegClass,
+     &Mips::CPURegsRegClass, &Mips::CPURegsRegClass,
+     &Mips::CPURegsRegClass, &Mips::CPURegsRegClass,
+     &Mips::CPURegsRegClass, &Mips::CPURegsRegClass, 0 
+   };
+   return CalleeSavedRegClasses;
+ }
+ 
+ BitVector MipsRegisterInfo::
+ getReservedRegs(const MachineFunction &MF) const
+ {
+   BitVector Reserved(getNumRegs());
+   Reserved.set(Mips::ZERO);
+   Reserved.set(Mips::AT);
+   Reserved.set(Mips::K0);
+   Reserved.set(Mips::K1);
+   Reserved.set(Mips::GP);
+   Reserved.set(Mips::SP);
+   Reserved.set(Mips::FP);
+   Reserved.set(Mips::RA);
+   return Reserved;
+ }
+ 
+ //===----------------------------------------------------------------------===//
+ // Stack Frame Processing methods
+ //===----------------------------------------------------------------------===//
+ 
+ // True if target has frame pointer
+ bool MipsRegisterInfo::
+ hasFP(const MachineFunction &MF) const {
+   return false;
+ }
+ 
+ // This function eliminate ADJCALLSTACKDOWN, 
+ // ADJCALLSTACKUP pseudo instructions
+ void MipsRegisterInfo::
+ eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
+                               MachineBasicBlock::iterator I) const {
+   // Simply discard ADJCALLSTACKDOWN, ADJCALLSTACKUP instructions.
+   MBB.erase(I);
+ }
+ 
+ // FrameIndex represent objects inside a abstract stack.
+ // We must replace FrameIndex with an stack/frame pointer
+ // direct reference.
+ void MipsRegisterInfo::
+ eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj, 
+                     RegScavenger *RS) const 
+ {
+   unsigned i = 0;
+   MachineInstr &MI    = *II;
+   MachineFunction &MF = *MI.getParent()->getParent();
+ 
+   while (!MI.getOperand(i).isFrameIndex()) {
+     ++i;
+     assert(i < MI.getNumOperands() && 
+            "Instr doesn't have FrameIndex operand!");
+   }
+ 
+   // FrameInfo addressable stack objects are accessed 
+   // using neg. offsets, so we must add with the stack
+   // size to obtain $sp relative address.
+   int FrameIndex = MI.getOperand(i).getFrameIndex();
+   int stackSize  = MF.getFrameInfo()->getStackSize();
+   int spOffset   = MF.getFrameInfo()->getObjectOffset(FrameIndex);
+ 
+   #ifndef NDEBUG
+   DOUT << "\n<--------->\n";
+   MI.print(DOUT);
+   DOUT << "FrameIndex : " << FrameIndex << "\n";
+   DOUT << "spOffset   : " << spOffset << "\n";
+   DOUT << "stackSize  : " << stackSize << "\n";
+   #endif
+ 
+   // If the FrameIndex points to a positive SPOffset this
+   // means we are inside the callee and getting the arguments 
+   // from the caller stack
+   int Offset = (-(stackSize)) + spOffset; 
+ 
+   #ifndef NDEBUG
+   DOUT << "Offset     : " << Offset << "\n";
+   DOUT << "<--------->\n";
+   #endif
+ 
+   MI.getOperand(i-1).ChangeToImmediate(Offset);
+   MI.getOperand(i).ChangeToRegister(Mips::SP,false);
+ }
+ 
+ void MipsRegisterInfo::
+ emitPrologue(MachineFunction &MF) const 
+ {
+   MachineBasicBlock &MBB = MF.front();
+   MachineFrameInfo *MFI  = MF.getFrameInfo();
+ 
+   // Get the number of bytes to allocate from the FrameInfo
+   int NumBytes = (int) MFI->getStackSize();
+ 
+   // Do we need to allocate space on the stack?
+   if (NumBytes == 0) return;
+ 
+   // FIXME: is Stack Align needed here ?? (maybe it's done before...)
+   unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment();
+   NumBytes = -((NumBytes+Align-1)/Align*Align);
+ 
+   // Update frame info to pretend that this is part of the stack...
+   MFI->setStackSize(NumBytes);
+ 
+   // adjust stack : addi sp, sp, (-imm)
+   BuildMI(MBB, MBB.begin(), TII.get(Mips::ADDi), Mips::SP)
+       .addReg(Mips::SP).addImm(NumBytes);
+ }
+ 
+ void MipsRegisterInfo::
+ emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const 
+ {
+   MachineBasicBlock::iterator MBBI = prior(MBB.end());
+   MachineFrameInfo *MFI = MF.getFrameInfo();
+ 
+   // Get the number of bytes from FrameInfo
+   int NumBytes = (int) MFI->getStackSize();
+ 
+   // adjust stack  : insert addi sp, sp, (imm)
+   if (NumBytes) {
+     BuildMI(MBB, MBBI, TII.get(Mips::ADDi), Mips::SP)
+       .addReg(Mips::SP).addImm(-NumBytes);
+   }
+ }
+ 
+ void MipsRegisterInfo::
+ processFunctionBeforeFrameFinalized(MachineFunction &MF) const {}
+ 
+ unsigned MipsRegisterInfo::
+ getRARegister() const {
+   return Mips::RA;
+ }
+ 
+ unsigned MipsRegisterInfo::
+ getFrameRegister(MachineFunction &MF) const {
+   assert(0 && "What is the frame register");
+   return Mips::FP;
+ }
+ 
+ unsigned MipsRegisterInfo::
+ getEHExceptionRegister() const {
+   assert(0 && "What is the exception register");
+   return 0;
+ }
+ 
+ unsigned MipsRegisterInfo::
+ getEHHandlerRegister() const {
+   assert(0 && "What is the exception handler register");
+   return 0;
+ }
+ 
+ #include "MipsGenRegisterInfo.inc"
+ 


Index: llvm/lib/Target/Mips/MipsRegisterInfo.h
diff -c /dev/null llvm/lib/Target/Mips/MipsRegisterInfo.h:1.1
*** /dev/null	Wed Jun  6 02:43:11 2007
--- llvm/lib/Target/Mips/MipsRegisterInfo.h	Wed Jun  6 02:42:06 2007
***************
*** 0 ****
--- 1,83 ----
+ //===- MipsRegisterInfo.h - Mips Register Information Impl ------*- C++ -*-===//
+ //
+ //                     The LLVM Compiler Infrastructure
+ //
+ // This file was developed by Bruno Cardoso Lopes and is distributed under the 
+ // University of Illinois Open Source License. See LICENSE.TXT for details.
+ //
+ //===----------------------------------------------------------------------===//
+ //
+ // This file contains the Mips implementation of the MRegisterInfo class.
+ //
+ //===----------------------------------------------------------------------===//
+ 
+ #ifndef MIPSREGISTERINFO_H
+ #define MIPSREGISTERINFO_H
+ 
+ #include "llvm/Target/MRegisterInfo.h"
+ #include "MipsGenRegisterInfo.h.inc"
+ 
+ namespace llvm {
+ 
+ class TargetInstrInfo;
+ class Type;
+ 
+ struct MipsRegisterInfo : public MipsGenRegisterInfo {
+   const TargetInstrInfo &TII;
+   
+   MipsRegisterInfo(const TargetInstrInfo &tii);
+ 
+   /// Code Generation virtual methods...
+   void storeRegToStackSlot(MachineBasicBlock &MBB,
+                            MachineBasicBlock::iterator MBBI,
+                            unsigned SrcReg, int FrameIndex,
+                            const TargetRegisterClass *RC) const;
+ 
+   void loadRegFromStackSlot(MachineBasicBlock &MBB,
+               MachineBasicBlock::iterator MBBI,
+               unsigned DestReg, int FrameIndex,
+               const TargetRegisterClass *RC) const;
+ 
+   void reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
+                      unsigned DestReg, const MachineInstr *Orig) const;
+ 
+   MachineInstr* foldMemoryOperand(MachineInstr* MI, unsigned OpNum,
+                                   int FrameIndex) const;
+ 
+   void copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
+           unsigned DestReg, unsigned SrcReg,
+           const TargetRegisterClass *RC) const;
+   
+ 
+   const unsigned *getCalleeSavedRegs() const;
+ 
+   const TargetRegisterClass* const* getCalleeSavedRegClasses() const;
+ 
+   BitVector getReservedRegs(const MachineFunction &MF) const;
+ 
+   bool hasFP(const MachineFunction &MF) const;
+ 
+   void eliminateCallFramePseudoInstr(MachineFunction &MF,
+                                      MachineBasicBlock &MBB,
+                                      MachineBasicBlock::iterator I) const;
+ 
+   void eliminateFrameIndex(MachineBasicBlock::iterator II,
+                            int SPAdj, RegScavenger *RS = NULL) const;
+ 
+   void processFunctionBeforeFrameFinalized(MachineFunction &MF) const;
+ 
+   void emitPrologue(MachineFunction &MF) const;
+   void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;
+   
+   // Debug information queries.
+   unsigned getRARegister() const;
+   unsigned getFrameRegister(MachineFunction &MF) const;
+ 
+   // Exception handling queries.
+   unsigned getEHExceptionRegister() const;
+   unsigned getEHHandlerRegister() const;
+ };
+ 
+ } // end namespace llvm
+ 
+ #endif


Index: llvm/lib/Target/Mips/MipsRegisterInfo.td
diff -c /dev/null llvm/lib/Target/Mips/MipsRegisterInfo.td:1.1
*** /dev/null	Wed Jun  6 02:43:11 2007
--- llvm/lib/Target/Mips/MipsRegisterInfo.td	Wed Jun  6 02:42:06 2007
***************
*** 0 ****
--- 1,80 ----
+ //===- MipsRegisterInfo.td - Mips Register defs -----------------*- C++ -*-===//
+ //
+ //                     The LLVM Compiler Infrastructure
+ //
+ // This file was developed by Bruno Cardoso Lopes and is distributed under the 
+ // University of Illinois Open Source License. See LICENSE.TXT for details.
+ //
+ //===----------------------------------------------------------------------===//
+ 
+ //===----------------------------------------------------------------------===//
+ //  Declarations that describe the MIPS register file
+ //===----------------------------------------------------------------------===//
+ 
+ // We have banks of 32 registers each.
+ class MipsReg<string n> : Register<n> {
+   field bits<5> Num;
+   let Namespace = "Mips";
+ }
+ 
+ // Mips CPU Registers
+ class MipsGPRReg<bits<5> num, string n> : MipsReg<n> {
+   let Num = num;
+ }
+ 
+ // CPU GPR Registers
+ def ZERO : MipsGPRReg< 0, "ZERO">, DwarfRegNum<0>;
+ def AT : MipsGPRReg< 1, "AT">, DwarfRegNum<1>;
+ def V0 : MipsGPRReg< 2, "2">, DwarfRegNum<2>;
+ def V1 : MipsGPRReg< 3, "3">, DwarfRegNum<3>;
+ def A0 : MipsGPRReg< 4, "4">, DwarfRegNum<5>;
+ def A1 : MipsGPRReg< 5, "5">, DwarfRegNum<5>;
+ def A2 : MipsGPRReg< 6, "6">, DwarfRegNum<6>;
+ def A3 : MipsGPRReg< 7, "7">, DwarfRegNum<7>;
+ def T0 : MipsGPRReg< 8, "8">, DwarfRegNum<8>;
+ def T1 : MipsGPRReg< 9, "9">, DwarfRegNum<9>;
+ def T2 : MipsGPRReg< 10, "10">, DwarfRegNum<10>;
+ def T3 : MipsGPRReg< 11, "11">, DwarfRegNum<11>;
+ def T4 : MipsGPRReg< 12, "12">, DwarfRegNum<12>;
+ def T5 : MipsGPRReg< 13, "13">, DwarfRegNum<13>;
+ def T6 : MipsGPRReg< 14, "14">, DwarfRegNum<14>;
+ def T7 : MipsGPRReg< 15, "15">, DwarfRegNum<15>;
+ def S0 : MipsGPRReg< 16, "16">, DwarfRegNum<16>;
+ def S1 : MipsGPRReg< 17, "17">, DwarfRegNum<17>;
+ def S2 : MipsGPRReg< 18, "18">, DwarfRegNum<18>;
+ def S3 : MipsGPRReg< 19, "19">, DwarfRegNum<19>;
+ def S4 : MipsGPRReg< 20, "20">, DwarfRegNum<20>;
+ def S5 : MipsGPRReg< 21, "21">, DwarfRegNum<21>;
+ def S6 : MipsGPRReg< 22, "22">, DwarfRegNum<22>;
+ def S7 : MipsGPRReg< 23, "23">, DwarfRegNum<23>;
+ def T8 : MipsGPRReg< 24, "24">, DwarfRegNum<24>;
+ def T9 : MipsGPRReg< 25, "25">, DwarfRegNum<25>;
+ def K0 : MipsGPRReg< 26, "26">, DwarfRegNum<26>;
+ def K1 : MipsGPRReg< 27, "27">, DwarfRegNum<27>;
+ def GP : MipsGPRReg< 28, "GP">, DwarfRegNum<28>;
+ def SP : MipsGPRReg< 29, "SP">, DwarfRegNum<29>;
+ def FP : MipsGPRReg< 30, "FP">, DwarfRegNum<30>;
+ def RA : MipsGPRReg< 31, "RA">, DwarfRegNum<31>;
+ 
+ // CPU Registers Class
+ def CPURegs : RegisterClass<"Mips", [i32], 32, 
+   // Return Values and Arguments
+   [V0, V1, A0, A1, A2, A3,
+   // Not preserved across procedure calls
+   T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, 
+   // Callee save
+   S0, S1, S2, S3, S4, S5, S6, S7,
+   // Reserved
+   ZERO, AT, K0, K1, GP, SP, FP, RA]>
+ {
+   let MethodProtos = [{
+     iterator allocation_order_end(const MachineFunction &MF) const;
+   }];
+   let MethodBodies = [{
+     CPURegsClass::iterator
+     CPURegsClass::allocation_order_end(const MachineFunction &MF) const {
+       // The last 8 registers on the list above are reserved
+       return end()-8;
+     }
+   }];
+ }


Index: llvm/lib/Target/Mips/MipsSubtarget.cpp
diff -c /dev/null llvm/lib/Target/Mips/MipsSubtarget.cpp:1.1
*** /dev/null	Wed Jun  6 02:43:11 2007
--- llvm/lib/Target/Mips/MipsSubtarget.cpp	Wed Jun  6 02:42:06 2007
***************
*** 0 ****
--- 1,26 ----
+ //===- MipsSubtarget.cpp - Mips Subtarget Information -----------*- C++ -*-===//
+ //
+ //                     The LLVM Compiler Infrastructure
+ //
+ // This file was developed by Bruno Cardoso Lopes and is distributed under the 
+ // University of Illinois Open Source License. See LICENSE.TXT for details.
+ //
+ //===----------------------------------------------------------------------===//
+ //
+ // This file implements the Mips specific subclass of TargetSubtarget.
+ //
+ //===----------------------------------------------------------------------===//
+ 
+ #include "MipsSubtarget.h"
+ #include "Mips.h"
+ #include "MipsGenSubtarget.inc"
+ using namespace llvm;
+ 
+ MipsSubtarget::MipsSubtarget(const TargetMachine &TM, const Module &M, 
+                              const std::string &FS) : isR3000(false) 
+ {
+   std::string CPU = "generic";
+ 
+   // Parse features string.
+   ParseSubtargetFeatures(FS, CPU);
+ }


Index: llvm/lib/Target/Mips/MipsSubtarget.h
diff -c /dev/null llvm/lib/Target/Mips/MipsSubtarget.h:1.1
*** /dev/null	Wed Jun  6 02:43:11 2007
--- llvm/lib/Target/Mips/MipsSubtarget.h	Wed Jun  6 02:42:06 2007
***************
*** 0 ****
--- 1,43 ----
+ //=====-- MipsSubtarget.h - Define Subtarget for the Mips -----*- C++ -*--====//
+ //
+ //                     The LLVM Compiler Infrastructure
+ //
+ // This file was developed by Bruno Cardoso Lopes and is distributed under the 
+ // University of Illinois Open Source License. See LICENSE.TXT for details.
+ //
+ //===----------------------------------------------------------------------===//
+ //
+ // This file declares the Mips specific subclass of TargetSubtarget.
+ //
+ //===----------------------------------------------------------------------===//
+ 
+ #ifndef MIPSSUBTARGET_H
+ #define MIPSSUBTARGET_H
+ 
+ #include "llvm/Target/TargetSubtarget.h"
+ #include "llvm/Target/TargetMachine.h"
+ 
+ #include <string>
+ 
+ namespace llvm {
+ class Module;
+ 
+ class MipsSubtarget : public TargetSubtarget {
+ protected:
+   bool isR3000;
+ public:
+   /// This constructor initializes the data members to match that
+   /// of the specified module.
+   ///
+   MipsSubtarget(const TargetMachine &TM, const Module &M, 
+                 const std::string &FS);
+   
+   /// ParseSubtargetFeatures - Parses features string setting specified 
+   /// subtarget options.  Definition of function is auto generated by tblgen.
+   void ParseSubtargetFeatures(const std::string &FS, const std::string &CPU);
+ 
+   bool IsR3000() const { return isR3000; }
+ };
+ } // End llvm namespace
+ 
+ #endif


Index: llvm/lib/Target/Mips/MipsTargetAsmInfo.cpp
diff -c /dev/null llvm/lib/Target/Mips/MipsTargetAsmInfo.cpp:1.1
*** /dev/null	Wed Jun  6 02:43:11 2007
--- llvm/lib/Target/Mips/MipsTargetAsmInfo.cpp	Wed Jun  6 02:42:06 2007
***************
*** 0 ****
--- 1,22 ----
+ //===-- MipsTargetAsmInfo.cpp - Mips asm properties -------------*- C++ -*-===//
+ //
+ //                     The LLVM Compiler Infrastructure
+ //
+ // This file was developed by Bruno Cardoso Lopes and is distributed under the
+ // University of Illinois Open Source License. See LICENSE.TXT for details.
+ //
+ //===----------------------------------------------------------------------===//
+ //
+ // This file contains the declarations of the MipsTargetAsmInfo properties.
+ //
+ //===----------------------------------------------------------------------===//
+ 
+ #include "MipsTargetAsmInfo.h"
+ 
+ using namespace llvm;
+ 
+ MipsTargetAsmInfo::MipsTargetAsmInfo(const MipsTargetMachine &TM) {
+   Data16bitsDirective = "\t.half\t";
+   Data32bitsDirective = "\t.word\t";
+   CommentString = "#";
+ }


Index: llvm/lib/Target/Mips/MipsTargetAsmInfo.h
diff -c /dev/null llvm/lib/Target/Mips/MipsTargetAsmInfo.h:1.1
*** /dev/null	Wed Jun  6 02:43:11 2007
--- llvm/lib/Target/Mips/MipsTargetAsmInfo.h	Wed Jun  6 02:42:06 2007
***************
*** 0 ****
--- 1,30 ----
+ //=====-- MipsTargetAsmInfo.h - Mips asm properties -----------*- C++ -*--====//
+ //
+ //                     The LLVM Compiler Infrastructure
+ //
+ // This file was developed by Bruno Cardoso Lopes and is distributed under the
+ // University of Illinois Open Source License. See LICENSE.TXT for details.
+ //
+ //===----------------------------------------------------------------------===//
+ //
+ // This file contains the declaration of the MipsTargetAsmInfo class.
+ //
+ //===----------------------------------------------------------------------===//
+ 
+ #ifndef MIPSTARGETASMINFO_H
+ #define MIPSTARGETASMINFO_H
+ 
+ #include "llvm/Target/TargetAsmInfo.h"
+ 
+ namespace llvm {
+ 
+   // Forward declaration.
+   class MipsTargetMachine;
+ 
+   struct MipsTargetAsmInfo : public TargetAsmInfo {
+     MipsTargetAsmInfo(const MipsTargetMachine &TM);
+   };
+ 
+ } // namespace llvm
+ 
+ #endif


Index: llvm/lib/Target/Mips/MipsTargetMachine.cpp
diff -c /dev/null llvm/lib/Target/Mips/MipsTargetMachine.cpp:1.1
*** /dev/null	Wed Jun  6 02:43:11 2007
--- llvm/lib/Target/Mips/MipsTargetMachine.cpp	Wed Jun  6 02:42:06 2007
***************
*** 0 ****
--- 1,81 ----
+ //===-- MipsTargetMachine.cpp - Define TargetMachine for Mips -------------===//
+ //
+ //                     The LLVM Compiler Infrastructure
+ //
+ // This file was developed by Bruno Cardoso Lopes and is distributed under the
+ // University of Illinois Open Source License. See LICENSE.TXT for details.
+ //
+ //===----------------------------------------------------------------------===//
+ //
+ // Implements the info about Mips target spec.
+ //
+ //===----------------------------------------------------------------------===//
+ 
+ #include "Mips.h"
+ #include "MipsTargetAsmInfo.h"
+ #include "MipsTargetMachine.h"
+ #include "llvm/Module.h"
+ #include "llvm/PassManager.h"
+ #include "llvm/Target/TargetMachineRegistry.h"
+ using namespace llvm;
+ 
+ namespace {
+   // Register the target.
+   RegisterTarget<MipsTargetMachine> X("mips", "  Mips");
+ }
+ 
+ const TargetAsmInfo *MipsTargetMachine::
+ createTargetAsmInfo() const 
+ {
+   return new MipsTargetAsmInfo(*this);
+ }
+ 
+ // DataLayout --> Big-endian, 32-bit pointer/ABI/alignment
+ // FrameInfo  --> StackGrowsDown, 8 bytes aligned, LOA : -4 (Ra : 0)
+ MipsTargetMachine::
+ MipsTargetMachine(const Module &M, const std::string &FS): 
+   Subtarget(*this, M, FS), DataLayout("E-p:32:32:32"), 
+   InstrInfo(*this), FrameInfo(TargetFrameInfo::StackGrowsDown, 8, -4),
+   TLInfo(*this) {}
+ 
+ // return 0 and must specify -march to gen MIPS code.
+ unsigned MipsTargetMachine::
+ getModuleMatchQuality(const Module &M) 
+ {
+   // We strongly match "mips-*".
+   std::string TT = M.getTargetTriple();
+   if (TT.size() >= 5 && std::string(TT.begin(), TT.begin()+5) == "mips-")
+     return 20;
+   
+   return 0;
+ }
+ 
+ // Install an instruction selector pass using 
+ // the ISelDag to gen Mips code.
+ bool MipsTargetMachine::
+ addInstSelector(FunctionPassManager &PM, bool Fast) 
+ {
+   PM.add(createMipsISelDag(*this));
+   return false;
+ }
+ 
+ // Implemented by targets that want to run passes immediately before 
+ // machine code is emitted. return true if -print-machineinstrs should 
+ // print out the code after the passes.
+ // TODO: Delay slot must be implemented here.
+ bool MipsTargetMachine::
+ addPreEmitPass(FunctionPassManager &PM, bool Fast) 
+ {
+   return false;
+ }
+ 
+ // Implements the AssemblyEmitter for the target. Must return
+ // true if AssemblyEmitter is supported
+ bool MipsTargetMachine::
+ addAssemblyEmitter(FunctionPassManager &PM, bool Fast, 
+                    std::ostream &Out) 
+ {
+   // Output assembly language.
+   PM.add(createMipsCodePrinterPass(Out, *this));
+   return false;
+ }


Index: llvm/lib/Target/Mips/MipsTargetMachine.h
diff -c /dev/null llvm/lib/Target/Mips/MipsTargetMachine.h:1.1
*** /dev/null	Wed Jun  6 02:43:11 2007
--- llvm/lib/Target/Mips/MipsTargetMachine.h	Wed Jun  6 02:42:06 2007
***************
*** 0 ****
--- 1,65 ----
+ //===-- MipsTargetMachine.h - Define TargetMachine for Mips -00--*- C++ -*-===//
+ //
+ //                     The LLVM Compiler Infrastructure
+ //
+ // This file was developed by Bruno Cardoso Lopes and is distributed under the 
+ // University of Illinois Open Source License. See LICENSE.TXT for details.
+ //
+ //===----------------------------------------------------------------------===//
+ //
+ // This file declares the Mips specific subclass of TargetMachine.
+ //
+ //===----------------------------------------------------------------------===//
+ 
+ #ifndef MIPSTARGETMACHINE_H
+ #define MIPSTARGETMACHINE_H
+ 
+ #include "MipsSubtarget.h"
+ #include "MipsInstrInfo.h"
+ #include "MipsISelLowering.h"
+ #include "llvm/Target/TargetMachine.h"
+ #include "llvm/Target/TargetData.h"
+ #include "llvm/Target/TargetFrameInfo.h"
+ 
+ namespace llvm {
+   class MipsTargetMachine : public LLVMTargetMachine {
+     MipsSubtarget       Subtarget;
+     const TargetData    DataLayout; // Calculates type size & alignment
+     MipsInstrInfo       InstrInfo;
+     TargetFrameInfo     FrameInfo;
+     MipsTargetLowering  TLInfo;
+   
+   protected:
+     virtual const TargetAsmInfo *createTargetAsmInfo() const;
+   
+   public:
+     MipsTargetMachine(const Module &M, const std::string &FS);
+ 
+     virtual const MipsInstrInfo   *getInstrInfo()     const 
+     { return &InstrInfo; }
+     virtual const TargetFrameInfo *getFrameInfo()     const 
+     { return &FrameInfo; }
+     virtual const TargetSubtarget *getSubtargetImpl() const 
+     { return &Subtarget; }
+     virtual const TargetData      *getTargetData()    const 
+     { return &DataLayout;}
+ 
+     virtual const MRegisterInfo   *getRegisterInfo()  const {
+       return &InstrInfo.getRegisterInfo();
+     }
+ 
+     virtual MipsTargetLowering   *getTargetLowering() const { 
+       return const_cast<MipsTargetLowering*>(&TLInfo); 
+     }
+ 
+     static unsigned getModuleMatchQuality(const Module &M);
+ 
+     // Pass Pipeline Configuration
+     virtual bool addInstSelector(FunctionPassManager &PM, bool Fast);
+     virtual bool addPreEmitPass(FunctionPassManager &PM, bool Fast);
+     virtual bool addAssemblyEmitter(FunctionPassManager &PM, bool Fast, 
+                                     std::ostream &Out);
+   };
+ } // End llvm namespace
+ 
+ #endif






More information about the llvm-commits mailing list