[llvm-commits] [llvm] r53146 - in /llvm/trunk/lib/Target/Mips: Mips.td MipsAsmPrinter.cpp MipsCallingConv.td MipsISelDAGToDAG.cpp MipsISelLowering.cpp MipsISelLowering.h MipsInstrFPU.td MipsInstrFormats.td MipsInstrInfo.cpp MipsInstrInfo.h MipsInstrInfo.td MipsMachineFunction.h MipsRegisterInfo.cpp MipsRegisterInfo.td MipsSubtarget.cpp MipsSubtarget.h MipsTargetMachine.cpp

Bruno Cardoso Lopes bruno.cardoso at gmail.com
Sat Jul 5 12:05:22 PDT 2008


Author: bruno
Date: Sat Jul  5 14:05:21 2008
New Revision: 53146

URL: http://llvm.org/viewvc/llvm-project?rev=53146&view=rev
Log:
Several changes to Mips backend, experimental fp support being the most
important.
- Cleanup in the Subtarget info with addition of new features, not all support
  yet, but they allow the future inclusion of features easier. Among new features,
  we have : Arch family info (mips1, mips2, ...), ABI info (o32, eabi), 64-bit
  integer
  and float registers, allegrex vector FPU (VFPU), single float only support.
- TargetMachine now detects allegrex core.
- Added allegrex (Mips32r2) sext_inreg instructions.
- *Added Float Point Instructions*, handling single float only, and
  aliased accesses for 32-bit FPUs.
- Some cleanup in FP instruction formats and FP register classes.
- Calling conventions improved to support mips 32-bit EABI.
- Added Asm Printer support for fp cond codes.
- Added support for sret copy to a return register.
- EABI support added into LowerCALL and FORMAL_ARGS.
- MipsFunctionInfo now keeps a virtual register per function to track the
  sret on function entry until function ret.
- MipsInstrInfo FP support into methods (isMoveInstr, isLoadFromStackSlot, ...),
  FP cond codes mapping and initial FP Branch Analysis.
- Two new Mips SDNode to handle fp branch and compare instructions : FPBrcond,
  FPCmp
- MipsTargetLowering : handling different FP classes, Allegrex support, sret
  return copy, no homing location within EABI, non 32-bit stack objects
  arguments, and asm constraint for float.


Added:
    llvm/trunk/lib/Target/Mips/MipsInstrFPU.td
Modified:
    llvm/trunk/lib/Target/Mips/Mips.td
    llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp
    llvm/trunk/lib/Target/Mips/MipsCallingConv.td
    llvm/trunk/lib/Target/Mips/MipsISelDAGToDAG.cpp
    llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp
    llvm/trunk/lib/Target/Mips/MipsISelLowering.h
    llvm/trunk/lib/Target/Mips/MipsInstrFormats.td
    llvm/trunk/lib/Target/Mips/MipsInstrInfo.cpp
    llvm/trunk/lib/Target/Mips/MipsInstrInfo.h
    llvm/trunk/lib/Target/Mips/MipsInstrInfo.td
    llvm/trunk/lib/Target/Mips/MipsMachineFunction.h
    llvm/trunk/lib/Target/Mips/MipsRegisterInfo.cpp
    llvm/trunk/lib/Target/Mips/MipsRegisterInfo.td
    llvm/trunk/lib/Target/Mips/MipsSubtarget.cpp
    llvm/trunk/lib/Target/Mips/MipsSubtarget.h
    llvm/trunk/lib/Target/Mips/MipsTargetMachine.cpp

Modified: llvm/trunk/lib/Target/Mips/Mips.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/Mips.td?rev=53146&r1=53145&r2=53146&view=diff

==============================================================================
--- llvm/trunk/lib/Target/Mips/Mips.td (original)
+++ llvm/trunk/lib/Target/Mips/Mips.td Sat Jul  5 14:05:21 2008
@@ -16,7 +16,7 @@
 include "../Target.td"
 
 //===----------------------------------------------------------------------===//
-// Descriptions
+// Register File, Calling Conv, Instruction Descriptions
 //===----------------------------------------------------------------------===//
 
 include "MipsRegisterInfo.td"
@@ -30,22 +30,43 @@
 }
 
 //===----------------------------------------------------------------------===//
-// CPU Directives                                                             //
+// Mips Subtarget features                                                    //
 //===----------------------------------------------------------------------===//
 
-// Not currently supported, but work as SubtargetFeature placeholder.
-def FeatureMipsIII : SubtargetFeature<"mips3", "IsMipsIII", "true",
-                                      "MipsIII ISA Support">;
+def FeatureGP64Bit      : SubtargetFeature<"gp64", "IsGP64bit", "true",
+                                "General Purpose Registers are 64-bit wide.">;
+def FeatureFP64Bit      : SubtargetFeature<"fp64", "IsFP64bit", "true",
+                                "Support 64-bit FP registers.">;
+def FeatureSingleFloat  : SubtargetFeature<"single-float", "IsSingleFloat",
+                                "true", "Only supports single precision float">;
+def FeatureAllegrexVFPU : SubtargetFeature<"allegrex-vfpu", "HasAllegrexVFPU", 
+                                "true", "Enable Allegrex VFPU instructions.">;
+def FeatureMips2        : SubtargetFeature<"mips2", "MipsArchVersion", "Mips2",
+                                "Mips2 ISA Support">;
+def FeatureO32          : SubtargetFeature<"o32", "MipsABI", "O32",
+                                "Enable o32 ABI">;
+def FeatureEABI         : SubtargetFeature<"eabi", "MipsABI", "EABI",
+                                "Enable eabi ABI">;
 
 //===----------------------------------------------------------------------===//
 // Mips processors supported.
 //===----------------------------------------------------------------------===//
 
-def : Processor<"mips1", MipsGenericItineraries, []>;
-def : Processor<"r2000", MipsGenericItineraries, []>;
-def : Processor<"r3000", MipsGenericItineraries, []>;
+class Proc<string Name, list<SubtargetFeature> Features>
+ : Processor<Name, MipsGenericItineraries, Features>;
+
+def : Proc<"mips1", []>;
+def : Proc<"r2000", []>;
+def : Proc<"r3000", []>;
+
+def : Proc<"mips2", [FeatureMips2]>;
+def : Proc<"r6000", [FeatureMips2]>;
+
+// Allegrex is a 32bit subset of r4000, both for interger and fp registers, 
+// but much more similar to Mips2 than Mips3. 
+def : Proc<"allegrex", [FeatureMips2, FeatureSingleFloat, FeatureAllegrexVFPU,
+                        FeatureEABI]>;
 
 def Mips : Target {
   let InstructionSet = MipsInstrInfo;
 }
-

Modified: llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp?rev=53146&r1=53145&r2=53146&view=diff

==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp (original)
+++ llvm/trunk/lib/Target/Mips/MipsAsmPrinter.cpp Sat Jul  5 14:05:21 2008
@@ -62,6 +62,8 @@
     void printOperand(const MachineInstr *MI, int opNum);
     void printMemOperand(const MachineInstr *MI, int opNum, 
                          const char *Modifier = 0);
+    void printFCCOperand(const MachineInstr *MI, int opNum, 
+                         const char *Modifier = 0);
 
     unsigned int getSavedRegsBitmask(bool isFloat, MachineFunction &MF);
     void printHex32(unsigned int Value);
@@ -428,6 +430,13 @@
   O << ")";
 }
 
+void MipsAsmPrinter::
+printFCCOperand(const MachineInstr *MI, int opNum, const char *Modifier) 
+{
+  const MachineOperand& MO = MI->getOperand(opNum);
+  O << Mips::MipsFCCToString((Mips::CondCode)MO.getImm()); 
+}
+
 bool MipsAsmPrinter::
 doInitialization(Module &M) 
 {

Modified: llvm/trunk/lib/Target/Mips/MipsCallingConv.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsCallingConv.td?rev=53146&r1=53145&r2=53146&view=diff

==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsCallingConv.td (original)
+++ llvm/trunk/lib/Target/Mips/MipsCallingConv.td Sat Jul  5 14:05:21 2008
@@ -14,26 +14,76 @@
   CCIf<!strconcat("State.getTarget().getSubtarget<MipsSubtarget>().", F), A>;
 
 //===----------------------------------------------------------------------===//
-// Mips Return Value Calling Convention
+// Mips O32 Calling Convention
 //===----------------------------------------------------------------------===//
-def RetCC_Mips : CallingConv<[
+def CC_MipsO32 : 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>>
+]>;
+
+def RetCC_MipsO32 : CallingConv<[
   // i32 are returned in registers V0, V1
   CCIfType<[i32], CCAssignToReg<[V0, V1]>>
 ]>;
 
-
 //===----------------------------------------------------------------------===//
-// Mips Argument Calling Conventions
+// Mips EABI Calling Convention
 //===----------------------------------------------------------------------===//
-def CC_Mips : CallingConv<[
+def CC_MipsEABI : 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 arguments are passed in integer registers.
+  CCIfType<[i32], CCAssignToReg<[A0, A1, A2, A3, T0, T1, T2, T3]>>,
+
+  // Single fp arguments are passed in pairs within 32-bit mode 
+  CCIfType<[f32], CCIfSubtarget<"isSingleFloat()", 
+                  CCAssignToReg<[F12, F13, F14, F15, F16, F17, F18, F19]>>>,
+
+  CCIfType<[f32], CCIfSubtarget<"isNotSingleFloat()", 
+                  CCAssignToReg<[F12, F14, F16, F18]>>>,
+
+  // The first 4 doubl fp arguments are passed in single fp registers.
+  CCIfType<[f64], CCIfSubtarget<"isNotSingleFloat()", 
+                  CCAssignToReg<[D6, D7, D8, D9]>>>,
 
   // Integer values get stored in stack slots that are 4 bytes in
   // size and 4-byte aligned.
-  CCIfType<[i32], CCAssignToStack<4, 4>>
+  CCIfType<[i32, f32], CCAssignToStack<4, 4>>,
+
+  // Integer values get stored in stack slots that are 8 bytes in
+  // size and 8-byte aligned.
+  CCIfType<[f64], CCIfSubtarget<"isNotSingleFloat()", CCAssignToStack<8, 8>>>
+]>;
+
+def RetCC_MipsEABI : CallingConv<[
+  // i32 are returned in registers V0, V1
+  CCIfType<[i32], CCAssignToReg<[V0, V1]>>,
+
+  // f32 are returned in registers F0, F1
+  CCIfType<[f32], CCAssignToReg<[F0, F1]>>,
+
+  // f64 are returned in register D0
+  CCIfType<[f64], CCIfSubtarget<"isNotSingleFloat()", CCAssignToReg<[D0]>>>
 ]>;
 
+//===----------------------------------------------------------------------===//
+// Mips Calling Convention Dispatch
+//===----------------------------------------------------------------------===//
+
+def CC_Mips : CallingConv<[
+  CCIfSubtarget<"isABI_EABI()", CCDelegateTo<CC_MipsEABI>>,
+  CCDelegateTo<CC_MipsO32>
+]>;
+
+def RetCC_Mips : CallingConv<[
+  CCIfSubtarget<"isABI_EABI()", CCDelegateTo<RetCC_MipsEABI>>,
+  CCDelegateTo<RetCC_MipsO32>
+]>;

Modified: llvm/trunk/lib/Target/Mips/MipsISelDAGToDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsISelDAGToDAG.cpp?rev=53146&r1=53145&r2=53146&view=diff

==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsISelDAGToDAG.cpp (original)
+++ llvm/trunk/lib/Target/Mips/MipsISelDAGToDAG.cpp Sat Jul  5 14:05:21 2008
@@ -58,13 +58,12 @@
 
   /// 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;
+  const MipsSubtarget &Subtarget;
  
 public:
-  MipsDAGToDAGISel(MipsTargetMachine &tm) : 
-        SelectionDAGISel(MipsLowering),
-        TM(tm), MipsLowering(*TM.getTargetLowering()) {}
+  MipsDAGToDAGISel(MipsTargetMachine &tm) : SelectionDAGISel(MipsLowering),
+  TM(tm), MipsLowering(*TM.getTargetLowering()), 
+  Subtarget(tm.getSubtarget<MipsSubtarget>()) {}
   
   virtual void InstructionSelect(SelectionDAG &SD);
 

Modified: llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp?rev=53146&r1=53145&r2=53146&view=diff

==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp Sat Jul  5 14:05:21 2008
@@ -17,6 +17,7 @@
 #include "MipsISelLowering.h"
 #include "MipsMachineFunction.h"
 #include "MipsTargetMachine.h"
+#include "MipsSubtarget.h"
 #include "llvm/DerivedTypes.h"
 #include "llvm/Function.h"
 #include "llvm/Intrinsics.h"
@@ -44,6 +45,8 @@
     case MipsISD::Lo        : return "MipsISD::Lo";
     case MipsISD::Ret       : return "MipsISD::Ret";
     case MipsISD::SelectCC  : return "MipsISD::SelectCC";
+    case MipsISD::FPBrcond  : return "MipsISD::FPBrcond";
+    case MipsISD::FPCmp     : return "MipsISD::FPCmp";
     default                 : return NULL;
   }
 }
@@ -51,6 +54,8 @@
 MipsTargetLowering::
 MipsTargetLowering(MipsTargetMachine &TM): TargetLowering(TM) 
 {
+  Subtarget = &TM.getSubtarget<MipsSubtarget>();
+
   // Mips does not have i1 type, so use i32 for
   // setcc operations results (slt, sgt, ...). 
   setSetCCResultContents(ZeroOrOneSetCCResult);
@@ -61,12 +66,24 @@
   // Set up the register classes
   addRegisterClass(MVT::i32, Mips::CPURegsRegisterClass);
 
+  // When dealing with single precision only, use libcalls
+  if (!Subtarget->isSingleFloat()) {
+    addRegisterClass(MVT::f32, Mips::AFGR32RegisterClass);
+    if (!Subtarget->isFP64bit())
+      addRegisterClass(MVT::f64, Mips::AFGR64RegisterClass);
+  } else 
+    addRegisterClass(MVT::f32, Mips::FGR32RegisterClass);
+
   // Custom
   setOperationAction(ISD::GlobalAddress, MVT::i32, Custom);
   setOperationAction(ISD::GlobalTLSAddress, MVT::i32, Custom);
   setOperationAction(ISD::RET, MVT::Other, Custom);
   setOperationAction(ISD::JumpTable, MVT::i32, Custom);
   setOperationAction(ISD::SELECT_CC, MVT::i32, Custom);
+  setOperationAction(ISD::SELECT_CC, MVT::f32, Custom);
+
+  if (Subtarget->isSingleFloat()) 
+    setOperationAction(ISD::SELECT_CC, MVT::f64, Expand);
 
   // Load extented operations for i1 types must be promoted 
   setLoadXAction(ISD::EXTLOAD,  MVT::i1,  Promote);
@@ -80,6 +97,11 @@
   setOperationAction(ISD::SELECT,    MVT::i32,   Expand);
   setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
 
+  if (!Subtarget->isAllegrex()) {
+    setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i8, Expand);
+    setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16, Expand);
+  }
+
   // Mips not supported intrinsics.
   setOperationAction(ISD::MEMBARRIER, MVT::Other, Expand);
 
@@ -323,7 +345,7 @@
 /// LowerCCCCallTo - functions arguments are copied from virtual
 /// regs to (physical regs)/(stack frame), CALLSEQ_START and
 /// CALLSEQ_END are emitted.
-/// TODO: isVarArg, isTailCall, sret.
+/// TODO: isVarArg, isTailCall.
 SDOperand MipsTargetLowering::
 LowerCCCCallTo(SDOperand Op, SelectionDAG &DAG, unsigned CC) 
 {
@@ -351,10 +373,14 @@
   Chain = DAG.getCALLSEQ_START(Chain,DAG.getConstant(NumBytes, 
                                  getPointerTy()));
 
-  SmallVector<std::pair<unsigned, SDOperand>, 8> RegsToPass;
+  // With EABI is it possible to have 16 args on registers.
+  SmallVector<std::pair<unsigned, SDOperand>, 16> RegsToPass;
   SmallVector<SDOperand, 8> MemOpChains;
 
-  int LastStackLoc = 0;
+  // First/LastArgStackLoc contains the first/last 
+  // "at stack" argument location.
+  int LastArgStackLoc = 0;
+  unsigned FirstStackArgLoc = (Subtarget->isABI_EABI() ? 0 : 16);
 
   // Walk the register/memloc assignments, inserting copies/loads.
   for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
@@ -385,14 +411,16 @@
       continue;
     }
     
+    // Register cant get to this point...
     assert(VA.isMemLoc());
     
     // Create the frame index object for this incoming parameter
     // This guarantees that when allocating Local Area the firsts
-    // 16 bytes which are alwayes reserved won't be overwritten.
-    LastStackLoc = (16 + VA.getLocMemOffset());
+    // 16 bytes which are alwayes reserved won't be overwritten
+    // if O32 ABI is used. For EABI the first address is zero.
+    LastArgStackLoc = (FirstStackArgLoc + VA.getLocMemOffset());
     int FI = MFI->CreateFixedObject(VA.getValVT().getSizeInBits()/8,
-                                    LastStackLoc);
+                                    LastArgStackLoc);
 
     SDOperand PtrOff = DAG.getFrameIndex(FI,getPointerTy());
 
@@ -401,8 +429,8 @@
     MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
   }
 
-  // Transform all store nodes into one single node because
-  // all store nodes are independent of each other.
+  // Transform all store nodes into one single node because all store
+  // nodes are independent of each other.
   if (!MemOpChains.empty())     
     Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, 
                         &MemOpChains[0], MemOpChains.size());
@@ -460,18 +488,18 @@
   // emited CALL's to restore GP. 
   if (getTargetMachine().getRelocationModel() == Reloc::PIC_) {
       // Function can have an arbitrary number of calls, so 
-      // hold the LastStackLoc with the biggest offset.
+      // hold the LastArgStackLoc with the biggest offset.
       int FI;
       MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
-      if (LastStackLoc >= MipsFI->getGPStackOffset()) {
-        LastStackLoc = (!LastStackLoc) ? (16) : (LastStackLoc+4);
+      if (LastArgStackLoc >= MipsFI->getGPStackOffset()) {
+        LastArgStackLoc = (!LastArgStackLoc) ? (16) : (LastArgStackLoc+4);
         // Create the frame index only once. SPOffset here can be anything 
         // (this will be fixed on processFunctionBeforeFrameFinalized)
         if (MipsFI->getGPStackOffset() == -1) {
           FI = MFI->CreateFixedObject(4, 0);
           MipsFI->setGPFI(FI);
         }
-        MipsFI->setGPStackOffset(LastStackLoc);
+        MipsFI->setGPStackOffset(LastArgStackLoc);
       }
 
       // Reload GP value.
@@ -543,7 +571,7 @@
 /// LowerCCCArguments - transform physical registers into
 /// virtual registers and generate load operations for
 /// arguments places on the stack.
-/// TODO: isVarArg, sret
+/// TODO: isVarArg
 SDOperand MipsTargetLowering::
 LowerCCCArguments(SDOperand Op, SelectionDAG &DAG) 
 {
@@ -566,9 +594,11 @@
   CCState CCInfo(CC, isVarArg, getTargetMachine(), ArgLocs);
 
   CCInfo.AnalyzeFormalArguments(Op.Val, CC_Mips);
-  SmallVector<SDOperand, 8> ArgValues;
+  SmallVector<SDOperand, 16> ArgValues;
   SDOperand StackPtr;
 
+  unsigned FirstStackArgLoc = (Subtarget->isABI_EABI() ? 0 : 16);
+
   for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
 
     CCValAssign &VA = ArgLocs[i];
@@ -579,9 +609,17 @@
       TargetRegisterClass *RC;
             
       if (RegVT == MVT::i32)
-        RC = Mips::CPURegsRegisterClass;
-      else
-        assert(0 && "support only Mips::CPURegsRegisterClass");
+        RC = Mips::CPURegsRegisterClass; 
+      else if (RegVT == MVT::f32) {
+        if (Subtarget->isSingleFloat())
+          RC = Mips::FGR32RegisterClass;
+        else
+          RC = Mips::AFGR32RegisterClass;
+      } else if (RegVT == MVT::f64) {
+        if (!Subtarget->isSingleFloat()) 
+          RC = Mips::AFGR64RegisterClass;
+      } else  
+        assert(0 && "RegVT not supported by FORMAL_ARGUMENTS Lowering");
 
       // Transform the arguments stored on 
       // physical registers into virtual ones
@@ -605,8 +643,7 @@
 
       // To meet ABI, when VARARGS are passed on registers, the registers
       // must have their values written to the caller stack frame. 
-      if (isVarArg) {
-
+      if ((isVarArg) && (Subtarget->isABI_O32())) {
         if (StackPtr.Val == 0)
           StackPtr = DAG.getRegister(StackReg, getPointerTy());
      
@@ -627,7 +664,8 @@
         ArgValues.push_back(DAG.getStore(Root, ArgValue, PtrOff, NULL, 0));
       }
 
-    } else {
+    } else { // VA.isRegLoc()
+
       // sanity check
       assert(VA.isMemLoc());
       
@@ -639,14 +677,30 @@
       // be used on emitPrologue) to avoid mis-calc of the first stack 
       // offset on PEI::calculateFrameObjectOffsets.
       // Arguments are always 32-bit.
-      int FI = MFI->CreateFixedObject(4, 0);
-      MipsFI->recordLoadArgsFI(FI, -(4+(16+VA.getLocMemOffset())));
+      unsigned ArgSize = VA.getLocVT().getSizeInBits()/8;
+      int FI = MFI->CreateFixedObject(ArgSize, 0);
+      MipsFI->recordLoadArgsFI(FI, -(ArgSize+
+        (FirstStackArgLoc + 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));
     }
   }
+
+  // The mips ABIs for returning structs by value requires that we copy
+  // the sret argument into $v0 for the return. Save the argument into
+  // a virtual register so that we can access it from the return points.
+  if (DAG.getMachineFunction().getFunction()->hasStructRetAttr()) {
+    unsigned Reg = MipsFI->getSRetReturnReg();
+    if (!Reg) {
+      Reg = MF.getRegInfo().createVirtualRegister(getRegClassFor(MVT::i32));
+      MipsFI->setSRetReturnReg(Reg);
+    }
+    SDOperand Copy = DAG.getCopyToReg(DAG.getEntryNode(), Reg, ArgValues[0]);
+    Root = DAG.getNode(ISD::TokenFactor, MVT::Other, Copy, Root);
+  }
+
   ArgValues.push_back(Root);
 
   // Return the new list of results.
@@ -699,6 +753,23 @@
     Flag = Chain.getValue(1);
   }
 
+  // The mips ABIs for returning structs by value requires that we copy
+  // the sret argument into $v0 for the return. We saved the argument into
+  // a virtual register in the entry block, so now we copy the value out
+  // and into $v0.
+  if (DAG.getMachineFunction().getFunction()->hasStructRetAttr()) {
+    MachineFunction &MF      = DAG.getMachineFunction();
+    MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();
+    unsigned Reg = MipsFI->getSRetReturnReg();
+
+    if (!Reg) 
+      assert(0 && "sret virtual register not created in the entry block");
+    SDOperand Val = DAG.getCopyFromReg(Chain, Reg, getPointerTy());
+
+    Chain = DAG.getCopyToReg(Chain, Mips::V0, Val, Flag);
+    Flag = Chain.getValue(1);
+  }
+
   // Return on Mips is always a "jr $ra"
   if (Flag.Val)
     return DAG.getNode(MipsISD::Ret, MVT::Other, 
@@ -717,19 +788,20 @@
 MipsTargetLowering::ConstraintType MipsTargetLowering::
 getConstraintType(const std::string &Constraint) const 
 {
+  // Mips specific constrainy 
+  // GCC config/mips/constraints.md
+  //
+  // 'd' : An address register. Equivalent to r 
+  //       unless generating MIPS16 code. 
+  // 'y' : Equivalent to r; retained for 
+  //       backwards compatibility. 
+  // 'f' : Float Point registers.      
   if (Constraint.size() == 1) {
-    // Mips specific constrainy 
-    // GCC config/mips/constraints.md
-    //
-    // 'd' : An address register. Equivalent to r 
-    //       unless generating MIPS16 code. 
-    // 'y' : Equivalent to r; retained for 
-    //       backwards compatibility. 
-    //
     switch (Constraint[0]) {
       default : break;
       case 'd':     
       case 'y': 
+      case 'f':
         return C_RegisterClass;
         break;
     }
@@ -737,6 +809,9 @@
   return TargetLowering::getConstraintType(Constraint);
 }
 
+/// getRegClassForInlineAsmConstraint - Given a constraint letter (e.g. "r"),
+/// return a list of registers that can be used to satisfy the constraint.
+/// This should only be used for C_RegisterClass constraints.
 std::pair<unsigned, const TargetRegisterClass*> MipsTargetLowering::
 getRegForInlineAsmConstraint(const std::string &Constraint, MVT VT) const
 {
@@ -744,12 +819,23 @@
     switch (Constraint[0]) {
     case 'r':
       return std::make_pair(0U, Mips::CPURegsRegisterClass);
-      break;
+    case 'f':
+      if (VT == MVT::f32)
+        if (Subtarget->isSingleFloat())
+          return std::make_pair(0U, Mips::FGR32RegisterClass);
+        else
+          return std::make_pair(0U, Mips::AFGR32RegisterClass);
+      if (VT == MVT::f64)    
+        if ((!Subtarget->isSingleFloat()) && (!Subtarget->isFP64bit()))
+          return std::make_pair(0U, Mips::AFGR64RegisterClass);
     }
   }
   return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT);
 }
 
+/// Given a register class constraint, like 'r', if this corresponds directly
+/// to an LLVM register class, return a register of 0 and the register class
+/// pointer.
 std::vector<unsigned> MipsTargetLowering::
 getRegClassForInlineAsmConstraint(const std::string &Constraint,
                                   MVT VT) const
@@ -763,15 +849,29 @@
     // GCC Mips Constraint Letters
     case 'd':     
     case 'y': 
-      return make_vector<unsigned>(Mips::V0, Mips::V1, Mips::A0, 
-                                   Mips::A1, Mips::A2, Mips::A3, 
-                                   Mips::T0, Mips::T1, Mips::T2, 
-                                   Mips::T3, Mips::T4, Mips::T5, 
-                                   Mips::T6, Mips::T7, Mips::S0, 
-                                   Mips::S1, Mips::S2, Mips::S3, 
-                                   Mips::S4, Mips::S5, Mips::S6, 
-                                   Mips::S7, Mips::T8, Mips::T9, 0);
-      break;
+      return make_vector<unsigned>(Mips::T0, Mips::T1, Mips::T2, Mips::T3, 
+             Mips::T4, Mips::T5, Mips::T6, Mips::T7, Mips::S0, Mips::S1, 
+             Mips::S2, Mips::S3, Mips::S4, Mips::S5, Mips::S6, Mips::S7, 
+             Mips::T8, 0);
+
+    case 'f':
+      if (VT == MVT::f32)
+        if (Subtarget->isSingleFloat())
+          return make_vector<unsigned>(Mips::F2, Mips::F3, Mips::F4, Mips::F5,
+                 Mips::F6, Mips::F7, Mips::F8, Mips::F9, Mips::F10, Mips::F11,
+                 Mips::F20, Mips::F21, Mips::F22, Mips::F23, Mips::F24,
+                 Mips::F25, Mips::F26, Mips::F27, Mips::F28, Mips::F29,
+                 Mips::F30, Mips::F31, 0);
+        else
+          return make_vector<unsigned>(Mips::F2, Mips::F4, Mips::F6, Mips::F8, 
+                 Mips::F10, Mips::F20, Mips::F22, Mips::F24, Mips::F26, 
+                 Mips::F28, Mips::F30, 0);
+
+      if (VT == MVT::f64)    
+        if ((!Subtarget->isSingleFloat()) && (!Subtarget->isFP64bit()))
+          return make_vector<unsigned>(Mips::D1, Mips::D2, Mips::D3, Mips::D4, 
+                 Mips::D5, Mips::D10, Mips::D11, Mips::D12, Mips::D13, 
+                 Mips::D14, Mips::D15, 0);
   }
   return std::vector<unsigned>();
 }

Modified: llvm/trunk/lib/Target/Mips/MipsISelLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsISelLowering.h?rev=53146&r1=53145&r2=53146&view=diff

==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsISelLowering.h (original)
+++ llvm/trunk/lib/Target/Mips/MipsISelLowering.h Sat Jul  5 14:05:21 2008
@@ -40,6 +40,12 @@
       // Select CC Pseudo Instruction
       SelectCC,
 
+      // Float Point Branch Conditional
+      FPBrcond,
+
+      // Float Point Compare
+      FPCmp,
+
       // Return 
       Ret
     };
@@ -69,6 +75,9 @@
     MVT getSetCCResultType(const SDOperand &) const;
 
   private:
+    // Subtarget Info
+    const MipsSubtarget *Subtarget;
+
     // Lower Operand helpers
     SDOperand LowerCCCArguments(SDOperand Op, SelectionDAG &DAG);
     SDOperand LowerCCCCallTo(SDOperand Op, SelectionDAG &DAG, unsigned CC);

Added: llvm/trunk/lib/Target/Mips/MipsInstrFPU.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsInstrFPU.td?rev=53146&view=auto

==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsInstrFPU.td (added)
+++ llvm/trunk/lib/Target/Mips/MipsInstrFPU.td Sat Jul  5 14:05:21 2008
@@ -0,0 +1,296 @@
+//===- MipsInstrFPU.td - Mips FPU Instruction Information -------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the Mips implementation of the TargetInstrInfo class.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Float Point Instructions
+// ------------------------
+// * 64bit fp:
+//    - 32 64-bit registers (default mode)
+//    - 16 even 32-bit registers (32-bit compatible mode) for
+//      single and double access.
+// * 32bit fp:
+//    - 16 even 32-bit registers - single and double (aliased)
+//    - 32 32-bit registers (within single-only mode)
+//===----------------------------------------------------------------------===//
+
+// Float Point Compare and Branch
+def SDT_MipsFPBrcond : SDTypeProfile<0, 3, [SDTCisSameAs<0, 2>, SDTCisInt<0>,
+                                     SDTCisVT<1, OtherVT>]>;
+def SDT_MipsFPCmp : SDTypeProfile<0, 3, [SDTCisSameAs<0, 1>, SDTCisFP<0>, 
+                                  SDTCisInt<2>]>;
+def MipsFPBrcond : SDNode<"MipsISD::FPBrcond", SDT_MipsFPBrcond, 
+                          [SDNPHasChain]>; 
+def MipsFPCmp    : SDNode<"MipsISD::FPCmp", SDT_MipsFPCmp>;
+
+// Operand for printing out a condition code.
+let PrintMethod = "printFCCOperand" in
+  def condcode : Operand<i32>;
+
+//===----------------------------------------------------------------------===//
+// Feature predicates.
+//===----------------------------------------------------------------------===//
+
+def In32BitMode      : Predicate<"!Subtarget.isFP64bit()">;
+def In64BitMode      : Predicate<"Subtarget.isFP64bit()">;
+def IsSingleFloat    : Predicate<"Subtarget.isSingleFloat()">;
+def IsNotSingleFloat : Predicate<"!Subtarget.isSingleFloat()">;
+
+//===----------------------------------------------------------------------===//
+// Instruction Class Templates
+//
+// A set of multiclasses is used to address this in one shot. 
+// SO32 - single precision only, uses all 32 32-bit fp registers
+//        require FGR32 Register Class and IsSingleFloat
+// AS32 - 16 even fp registers are used for single precision
+//        require AFGR32 Register Class and In32BitMode
+// S64  - 32 64 bit registers are used to hold 32-bit single precision values.
+//        require FGR64 Register Class and In64BitMode
+// D32  - 16 even fp registers are used for double precision
+//        require AFGR64 Register Class and In32BitMode
+// D64  - 32 64 bit registers are used to hold 64-bit double precision values.
+//        require FGR64 Register Class and In64BitMode
+//
+// Only SO32, AS32 and D32 are supported right now.
+//
+//===----------------------------------------------------------------------===//
+
+multiclass FFR1_1<bits<6> funct, string asmstr> 
+{
+  def _SO32 : FFR<0x11, funct, 0x0, (outs FGR32:$fd), (ins FGR32:$fs),
+      !strconcat(asmstr, ".s $fd, $fs"), []>, Requires<[IsSingleFloat]>;
+
+  def _AS32 : FFR<0x11, funct, 0x0, (outs AFGR32:$fd), (ins AFGR32:$fs),
+      !strconcat(asmstr, ".s $fd, $fs"), []>, Requires<[In32BitMode]>;
+
+  def _D32  : FFR<0x11, funct, 0x1, (outs AFGR64:$fd), (ins AFGR64:$fs),
+      !strconcat(asmstr, ".d $fd, $fs"), []>, Requires<[In32BitMode]>;
+}
+
+multiclass FFR1_2<bits<6> funct, string asmstr, SDNode FOp> 
+{
+  def _SO32 : FFR<0x11, funct, 0x0, (outs FGR32:$fd), (ins FGR32:$fs),
+                 !strconcat(asmstr, ".s $fd, $fs"), 
+                 [(set FGR32:$fd, (FOp FGR32:$fs))]>, Requires<[IsSingleFloat]>;
+
+  def _AS32 : FFR<0x11, funct, 0x0, (outs AFGR32:$fd), (ins AFGR32:$fs),
+                 !strconcat(asmstr, ".s $fd, $fs"), 
+                 [(set AFGR32:$fd, (FOp AFGR32:$fs))]>, Requires<[In32BitMode]>;
+
+  def _D32  : FFR<0x11, funct, 0x1, (outs AFGR64:$fd), (ins AFGR64:$fs),
+                 !strconcat(asmstr, ".d $fd, $fs"), 
+                 [(set AFGR64:$fd, (FOp AFGR64:$fs))]>, Requires<[In32BitMode]>;
+}
+
+class FFR1_3<bits<6> funct, bits<5> fmt, RegisterClass RcSrc, 
+              RegisterClass RcDst, string asmstr>: 
+  FFR<0x11, funct, fmt, (outs RcSrc:$fd), (ins RcDst:$fs), 
+      !strconcat(asmstr, " $fd, $fs"), []>; 
+
+
+multiclass FFR1_4<bits<6> funct, string asmstr, SDNode FOp> {
+  def _SO32 : FFR<0x11, funct, 0x0, (outs FGR32:$fd), (ins FGR32:$fs, FGR32:$ft), 
+                 !strconcat(asmstr, ".s $fd, $fs, $ft"),
+                 [(set FGR32:$fd, (FOp FGR32:$fs, FGR32:$ft))]>,
+                 Requires<[IsSingleFloat]>;
+
+  def _AS32 : FFR<0x11, funct, 0x0, (outs AFGR32:$fd), 
+                 (ins AFGR32:$fs, AFGR32:$ft), 
+                 !strconcat(asmstr, ".s $fd, $fs, $ft"),
+                 [(set AFGR32:$fd, (FOp AFGR32:$fs, AFGR32:$ft))]>,
+                 Requires<[In32BitMode]>;
+
+  def _D32  : FFR<0x11, funct, 0x1, (outs AFGR64:$fd), 
+                 (ins AFGR64:$fs, AFGR64:$ft), 
+                 !strconcat(asmstr, ".d $fd, $fs, $ft"),
+                 [(set AFGR64:$fd, (FOp AFGR64:$fs, AFGR64:$ft))]>,
+                 Requires<[In32BitMode]>;
+}
+
+//===----------------------------------------------------------------------===//
+// Float Point Instructions
+//===----------------------------------------------------------------------===//
+
+let ft = 0 in {
+  defm FLOOR_W : FFR1_1<0b001111, "floor.w">;
+  defm CEIL_W  : FFR1_1<0b001110, "ceil.w">;
+  defm ROUND_W : FFR1_1<0b001100, "round.w">;
+  defm TRUNC_W : FFR1_1<0b001101, "trunc.w">;
+  defm CVTW    : FFR1_1<0b100100, "cvt.w">;
+  defm FMOV    : FFR1_1<0b000110, "mov">;
+
+  defm FABS    : FFR1_2<0b000101, "abs",  fabs>; 
+  defm FNEG    : FFR1_2<0b000111, "neg",  fneg>; 
+  defm FSQRT   : FFR1_2<0b000100, "sqrt", fsqrt>;
+
+  let Predicates = [IsNotSingleFloat] in {
+    /// Ceil to long signed integer
+    def CEIL_LS   : FFR1_3<0b001010, 0x0, AFGR32, AFGR32, "ceil.l">;
+    def CEIL_LD   : FFR1_3<0b001010, 0x1, AFGR64, AFGR64, "ceil.l">;
+
+    /// Round to long signed integer
+    def ROUND_LS  : FFR1_3<0b001000, 0x0, AFGR32, AFGR32, "round.l">;
+    def ROUND_LD  : FFR1_3<0b001000, 0x1, AFGR64, AFGR64, "round.l">;
+
+    /// Floor to long signed integer
+    def FLOOR_LS  : FFR1_3<0b001011, 0x0, AFGR32, AFGR32, "floor.l">;
+    def FLOOR_LD  : FFR1_3<0b001011, 0x1, AFGR64, AFGR64, "floor.l">;
+
+    /// Trunc to long signed integer
+    def TRUNC_LS  : FFR1_3<0b001001, 0x0, AFGR32, AFGR32, "trunc.l">;
+    def TRUNC_LD  : FFR1_3<0b001001, 0x1, AFGR64, AFGR64, "trunc.l">;
+
+    /// Convert to long signed integer
+    def CVTL_S    : FFR1_3<0b100101, 0x0, AFGR32, AFGR32, "cvt.l">; 
+    def CVTL_D    : FFR1_3<0b100101, 0x1, AFGR64, AFGR64, "cvt.l">; 
+
+    /// Convert to Double Precison 
+    def CVTD_S32 : FFR1_3<0b100001, 0x0, AFGR64, FGR32, "cvt.d.s">; 
+    def CVTD_W32 : FFR1_3<0b100001, 0x2, AFGR64, FGR32, "cvt.d.w">; 
+    def CVTD_L32 : FFR1_3<0b100001, 0x3, AFGR64, AFGR64, "cvt.d.l">; 
+                   
+    /// Convert to Single Precison
+    def CVTS_D32 : FFR1_3<0b100000, 0x1, FGR32, AFGR64, "cvt.s.d">;
+    def CVTS_L32 : FFR1_3<0b100000, 0x3, FGR32, AFGR64, "cvt.s.l">; 
+  }
+
+  /// Convert to Single Precison
+  def CVTS_W32 : FFR1_3<0b100000, 0x2, FGR32,  FGR32,  "cvt.s.w">, 
+                 Requires<[IsSingleFloat]>;
+}
+
+// The odd-numbered registers are only referenced when doing loads,
+// stores, and moves between floating-point and integer registers.
+// When defining instructions, we reference all 32-bit registers, 
+// regardless of register aliasing.
+let fd = 0 in {
+  /// Move Control Registers From/To CPU Registers
+  ///def CFC1  : FFR<0x11, 0x0, 0x2, (outs CPURegs:$rt), (ins FGR32:$fs),
+  ///                "cfc1 $rt, $fs", []>;
+
+  ///def CTC1  : FFR<0x11, 0x0, 0x6, (outs CPURegs:$rt), (ins FGR32:$fs),
+  ///                "ctc1 $rt, $fs", []>;
+  ///                
+  ///def CFC1A : FFR<0x11, 0x0, 0x2, (outs CPURegs:$rt), (ins AFGR32:$fs),
+  ///                "cfc1 $rt, $fs", []>;
+
+  ///def CTC1A : FFR<0x11, 0x0, 0x6, (outs CPURegs:$rt), (ins AFGR32:$fs),
+  ///                "ctc1 $rt, $fs", []>;
+
+  def MFC1  : FFR<0x11, 0x00, 0x00, (outs CPURegs:$rt), (ins FGR32:$fs),
+                  "mfc1 $rt, $fs", []>;
+
+  def MTC1  : FFR<0x11, 0x00, 0x04, (outs FGR32:$fs), (ins CPURegs:$rt),
+                  "mtc1 $fs, $rt", []>;
+
+  def MFC1A : FFR<0x11, 0x00, 0x00, (outs CPURegs:$rt), (ins AFGR32:$fs),
+                  "mfc1 $rt, $fs", []>;
+
+  def MTC1A : FFR<0x11, 0x00, 0x04, (outs AFGR32:$fs), (ins CPURegs:$rt),
+                  "mtc1 $fs, $rt", []>;
+}
+
+/// Float Point Memory Instructions
+let Predicates = [IsNotSingleFloat] in {
+  def LDC1 : FFI<0b110101, (outs AFGR64:$ft), (ins mem:$addr), 
+                 "ldc1 $ft, $addr", [(set AFGR64:$ft, (load addr:$addr))]>;
+
+  def SDC1 : FFI<0b111101, (outs), (ins AFGR64:$ft, mem:$addr), 
+                 "sdc1 $ft, $addr", [(store AFGR64:$ft, addr:$addr)]>;
+}
+
+// LWC1 and SWC1 can always be emited with odd registers.
+def LWC1  : FFI<0b110001, (outs FGR32:$ft), (ins mem:$addr), "lwc1 $ft, $addr",
+               [(set FGR32:$ft, (load addr:$addr))]>; 
+def SWC1  : FFI<0b111001, (outs), (ins FGR32:$ft, mem:$addr), "swc1 $ft, $addr",
+               [(store FGR32:$ft, addr:$addr)]>; 
+
+def LWC1A : FFI<0b110001, (outs AFGR32:$ft), (ins mem:$addr), "lwc1 $ft, $addr",
+               [(set AFGR32:$ft, (load addr:$addr))]>; 
+def SWC1A : FFI<0b111001, (outs), (ins AFGR32:$ft, mem:$addr), "swc1 $ft, $addr",
+               [(store AFGR32:$ft, addr:$addr)]>; 
+
+/// Floating-point Aritmetic
+defm FADD : FFR1_4<0x10, "add", fadd>;
+defm FDIV : FFR1_4<0x03, "div", fdiv>;
+defm FMUL : FFR1_4<0x02, "mul", fmul>;
+defm FSUB : FFR1_4<0x01, "sub", fsub>;
+
+//===----------------------------------------------------------------------===//
+// Float Point Branch Codes
+//===----------------------------------------------------------------------===//
+// Mips branch codes. These correspond to condcode in MipsInstrInfo.h. 
+// They must be kept in synch.
+def MIPS_BRANCH_F  : PatLeaf<(i32 0)>;
+def MIPS_BRANCH_T  : PatLeaf<(i32 1)>;
+def MIPS_BRANCH_FL : PatLeaf<(i32 2)>;
+def MIPS_BRANCH_TL : PatLeaf<(i32 3)>;
+
+/// Float Point Branch of False/True (Likely)
+let isBranch=1, isTerminator=1, hasDelaySlot=1, base=0x8, Uses=[FCR31] in {
+  class FBRANCH<PatLeaf op, string asmstr> : FFI<0x11, (ops), 
+        (ins brtarget:$dst), !strconcat(asmstr, " $dst"),
+        [(MipsFPBrcond op, bb:$dst, FCR31)]>;
+}
+def BC1F  : FBRANCH<MIPS_BRANCH_F, "bc1f">;
+def BC1T  : FBRANCH<MIPS_BRANCH_T, "bc1t">;
+def BC1FL : FBRANCH<MIPS_BRANCH_FL, "bc1fl">;
+def BC1TL : FBRANCH<MIPS_BRANCH_TL, "bc1tl">;
+
+//===----------------------------------------------------------------------===//
+// Float Point Flag Conditions
+//===----------------------------------------------------------------------===//
+// Mips condition codes. They must correspond to condcode in MipsInstrInfo.h. 
+// They must be kept in synch.
+def MIPS_FCOND_F    : PatLeaf<(i32 0)>;
+def MIPS_FCOND_UN   : PatLeaf<(i32 1)>;
+def MIPS_FCOND_EQ   : PatLeaf<(i32 2)>;
+def MIPS_FCOND_UEQ  : PatLeaf<(i32 3)>;
+def MIPS_FCOND_OLT  : PatLeaf<(i32 4)>;
+def MIPS_FCOND_ULT  : PatLeaf<(i32 5)>;
+def MIPS_FCOND_OLE  : PatLeaf<(i32 6)>;
+def MIPS_FCOND_ULE  : PatLeaf<(i32 7)>;
+def MIPS_FCOND_SF   : PatLeaf<(i32 8)>;
+def MIPS_FCOND_NGLE : PatLeaf<(i32 9)>;
+def MIPS_FCOND_SEQ  : PatLeaf<(i32 10)>;
+def MIPS_FCOND_NGL  : PatLeaf<(i32 11)>;
+def MIPS_FCOND_LT   : PatLeaf<(i32 12)>;
+def MIPS_FCOND_NGE  : PatLeaf<(i32 13)>;
+def MIPS_FCOND_LE   : PatLeaf<(i32 14)>;
+def MIPS_FCOND_NGT  : PatLeaf<(i32 15)>;
+
+/// Floating Point Compare
+let hasDelaySlot = 1, Defs=[FCR31] in {
+
+//multiclass FCC1_1<RegisterClass RC>
+
+  def FCMP_SO32 : FCC<0x0, (outs), (ins FGR32:$fs, FGR32:$ft, condcode:$cc),
+      "c.$cc.s $fs $ft", [(MipsFPCmp FGR32:$fs, FGR32:$ft, imm:$cc), 
+      (implicit FCR31)]>, Requires<[IsSingleFloat]>;
+  
+  def FCMP_AS32 : FCC<0x0, (outs), (ins AFGR32:$fs, AFGR32:$ft, condcode:$cc),
+      "c.$cc.s $fs $ft", [(MipsFPCmp AFGR32:$fs, AFGR32:$ft, imm:$cc), 
+      (implicit FCR31)]>, Requires<[In32BitMode]>;
+
+  def FCMP_D32 : FCC<0x1, (outs), (ins AFGR64:$fs, AFGR64:$ft, condcode:$cc),
+      "c.$cc.d $fs $ft", [(MipsFPCmp AFGR64:$fs, AFGR64:$ft, imm:$cc),
+      (implicit FCR31)]>, Requires<[In32BitMode]>;
+}
+
+//===----------------------------------------------------------------------===//
+// Float Point Patterns
+//===----------------------------------------------------------------------===//
+def : Pat<(f32 (sint_to_fp CPURegs:$src)), (CVTS_W32 (MTC1 CPURegs:$src))>;
+def : Pat<(f64 (sint_to_fp CPURegs:$src)), (CVTD_W32 (MTC1 CPURegs:$src))>;
+def : Pat<(i32 (fp_to_sint FGR32:$src)), (MFC1 (CVTW_SO32 FGR32:$src))>;
+def : Pat<(i32 (fp_to_sint AFGR32:$src)), (MFC1 (CVTW_AS32 AFGR32:$src))>;
+

Modified: llvm/trunk/lib/Target/Mips/MipsInstrFormats.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsInstrFormats.td?rev=53146&r1=53145&r2=53146&view=diff

==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsInstrFormats.td (original)
+++ llvm/trunk/lib/Target/Mips/MipsInstrFormats.td Sat Jul  5 14:05:21 2008
@@ -120,8 +120,8 @@
 //===----------------------------------------------------------------------===//
 
 class FFR<bits<6> op, bits<6> _funct, bits<5> _fmt, dag outs, dag ins, 
-          string asmstr, list<dag> pattern, InstrItinClass itin> : 
-          MipsInst<outs, ins, asmstr, pattern, itin> 
+          string asmstr, list<dag> pattern> : 
+          MipsInst<outs, ins, asmstr, pattern, NoItinerary> 
 {
   bits<5>  fd;
   bits<5>  fs;
@@ -141,21 +141,42 @@
 }
 
 //===----------------------------------------------------------------------===//
-// Format FI instruction class in Mips : <|opcode|fmt|ft|immediate|>
+// Format FI instruction class in Mips : <|opcode|base|ft|immediate|>
 //===----------------------------------------------------------------------===//
 
-class FFI<bits<6> op, bits<5> _fmt, dag outs, dag ins, string asmstr, 
-          list<dag> pattern, InstrItinClass itin>: 
-          MipsInst<outs, ins, asmstr, pattern, itin> 
+class FFI<bits<6> op, dag outs, dag ins, string asmstr, list<dag> pattern>: 
+          MipsInst<outs, ins, asmstr, pattern, NoItinerary> 
 {
   bits<5>  ft;
-  bits<5>  fmt;
+  bits<5>  base;
   bits<16> imm16;
 
   let opcode = op;
+
+  let Inst{25-21} = base;
+  let Inst{20-16} = ft; 
+  let Inst{15-0}  = imm16;
+}
+
+//===----------------------------------------------------------------------===//
+// Compare instruction class in Mips : <|010001|fmt|ft|fs|0000011|condcode|>
+//===----------------------------------------------------------------------===//
+
+class FCC<bits<5> _fmt, dag outs, dag ins, string asmstr, list<dag> pattern> : 
+          MipsInst<outs, ins, asmstr, pattern, NoItinerary> 
+{
+  bits<5>  fs;
+  bits<5>  ft;
+  bits<4>  cc;
+  bits<5>  fmt;
+
+  let opcode = 0x11;
   let fmt    = _fmt;
 
   let Inst{25-21} = fmt;
   let Inst{20-16} = ft; 
-  let Inst{15-0}  = imm16;
+  let Inst{15-11} = fs;
+  let Inst{10-6}  = 0;
+  let Inst{5-4}   = 0b11;
+  let Inst{3-0}   = cc;
 }

Modified: llvm/trunk/lib/Target/Mips/MipsInstrInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsInstrInfo.cpp?rev=53146&r1=53145&r2=53146&view=diff

==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsInstrInfo.cpp (original)
+++ llvm/trunk/lib/Target/Mips/MipsInstrInfo.cpp Sat Jul  5 14:05:21 2008
@@ -19,7 +19,6 @@
 
 using namespace llvm;
 
-// TODO: Add the subtarget support on this constructor
 MipsInstrInfo::MipsInstrInfo(MipsTargetMachine &tm)
   : TargetInstrInfoImpl(MipsInsts, array_lengthof(MipsInsts)),
     TM(tm), RI(*this) {}
@@ -35,8 +34,7 @@
 {
   //  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.getOpcode() == Mips::ADDu) || (MI.getOpcode() == Mips::OR)) {
     if (MI.getOperand(1).getReg() == Mips::ZERO) {
       DstReg = MI.getOperand(0).getReg();
       SrcReg = MI.getOperand(2).getReg();
@@ -48,9 +46,20 @@
     }
   }
 
+  // mov $fpDst, $fpSrc
+  // mfc $gpDst, $fpSrc
+  // mtc $fpDst, $gpSrc
+  if (MI.getOpcode() == Mips::FMOV_SO32 || MI.getOpcode() == Mips::FMOV_AS32 ||
+      MI.getOpcode() == Mips::FMOV_D32 || MI.getOpcode() == Mips::MFC1A ||
+      MI.getOpcode() == Mips::MFC1 || MI.getOpcode() == Mips::MTC1A ||
+      MI.getOpcode() == Mips::MTC1 ) {
+    DstReg = MI.getOperand(0).getReg();
+    SrcReg = MI.getOperand(1).getReg();
+    return true;
+  }
+
   //  addiu $dst, $src, 0
-  if (MI.getOpcode() == Mips::ADDiu) 
-  {
+  if (MI.getOpcode() == Mips::ADDiu) {
     if ((MI.getOperand(1).isRegister()) && (isZeroImm(MI.getOperand(2)))) {
       DstReg = MI.getOperand(0).getReg();
       SrcReg = MI.getOperand(1).getReg();
@@ -68,12 +77,11 @@
 unsigned MipsInstrInfo::
 isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const 
 {
-  if (MI->getOpcode() == Mips::LW) 
-  {
+  if ((MI->getOpcode() == Mips::LW) || (MI->getOpcode() == Mips::LWC1) ||
+      (MI->getOpcode() == Mips::LWC1A) || (MI->getOpcode() == Mips::LDC1)) {
     if ((MI->getOperand(2).isFrameIndex()) && // is a stack slot
         (MI->getOperand(1).isImmediate()) &&  // the imm is zero
-        (isZeroImm(MI->getOperand(1)))) 
-    {
+        (isZeroImm(MI->getOperand(1)))) {
       FrameIndex = MI->getOperand(2).getIndex();
       return MI->getOperand(0).getReg();
     }
@@ -90,11 +98,11 @@
 unsigned MipsInstrInfo::
 isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) const 
 {
-  if (MI->getOpcode() == Mips::SW) {
+  if ((MI->getOpcode() == Mips::SW) || (MI->getOpcode() == Mips::SWC1) ||
+      (MI->getOpcode() == Mips::SWC1A) || (MI->getOpcode() == Mips::SDC1)) {
     if ((MI->getOperand(0).isFrameIndex()) && // is a stack slot
         (MI->getOperand(1).isImmediate()) &&  // the imm is zero
-        (isZeroImm(MI->getOperand(1)))) 
-    {
+        (isZeroImm(MI->getOperand(1)))) {
       FrameIndex = MI->getOperand(0).getIndex();
       return MI->getOperand(2).getReg();
     }
@@ -110,6 +118,208 @@
   BuildMI(MBB, MI, get(Mips::NOP));
 }
 
+void MipsInstrInfo::
+copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
+             unsigned DestReg, unsigned SrcReg,
+             const TargetRegisterClass *DestRC,
+             const TargetRegisterClass *SrcRC) const {
+  if (DestRC != SrcRC) {
+    if ((DestRC == Mips::CPURegsRegisterClass) && 
+        (SrcRC == Mips::FGR32RegisterClass))
+      BuildMI(MBB, I, get(Mips::MFC1), DestReg).addReg(SrcReg);
+    else if ((DestRC == Mips::CPURegsRegisterClass) && 
+             (SrcRC == Mips::AFGR32RegisterClass))
+      BuildMI(MBB, I, get(Mips::MFC1A), DestReg).addReg(SrcReg);
+    else if ((DestRC == Mips::FGR32RegisterClass) &&
+             (SrcRC == Mips::CPURegsRegisterClass))
+      BuildMI(MBB, I, get(Mips::MTC1), DestReg).addReg(SrcReg);
+    else if ((DestRC == Mips::AFGR32RegisterClass) &&
+             (SrcRC == Mips::CPURegsRegisterClass))
+      BuildMI(MBB, I, get(Mips::MTC1A), DestReg).addReg(SrcReg);
+    else 
+      assert (0 && "DestRC != SrcRC, Can't copy this register");
+  }
+
+  if (DestRC == Mips::CPURegsRegisterClass)
+    BuildMI(MBB, I, get(Mips::ADDu), DestReg).addReg(Mips::ZERO)
+      .addReg(SrcReg);
+  else if (DestRC == Mips::FGR32RegisterClass) 
+    BuildMI(MBB, I, get(Mips::FMOV_SO32), DestReg).addReg(SrcReg);
+  else if (DestRC == Mips::AFGR32RegisterClass)
+    BuildMI(MBB, I, get(Mips::FMOV_AS32), DestReg).addReg(SrcReg);
+  else if (DestRC == Mips::AFGR64RegisterClass)
+    BuildMI(MBB, I, get(Mips::FMOV_D32), DestReg).addReg(SrcReg);
+  else
+    assert (0 && "Can't copy this register");
+}
+
+void MipsInstrInfo::
+storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
+          unsigned SrcReg, bool isKill, int FI, 
+          const TargetRegisterClass *RC) const 
+{
+  unsigned Opc;
+  if (RC == Mips::CPURegsRegisterClass) 
+    Opc = Mips::SW;
+  else if (RC == Mips::FGR32RegisterClass)
+    Opc = Mips::SWC1;
+  else if (RC == Mips::AFGR32RegisterClass)
+    Opc = Mips::SWC1A;
+  else if (RC == Mips::AFGR64RegisterClass)
+    Opc = Mips::SDC1;
+  else 
+    assert(0 && "Can't store this register to stack slot");
+
+  BuildMI(MBB, I, get(Opc)).addReg(SrcReg, false, false, isKill)
+          .addImm(0).addFrameIndex(FI);
+}
+
+void MipsInstrInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg,
+  bool isKill, SmallVectorImpl<MachineOperand> &Addr, 
+  const TargetRegisterClass *RC, SmallVectorImpl<MachineInstr*> &NewMIs) const 
+{
+  unsigned Opc;
+  if (RC == Mips::CPURegsRegisterClass) 
+    Opc = Mips::SW;
+  else if (RC == Mips::FGR32RegisterClass)
+    Opc = Mips::SWC1;
+  else if (RC == Mips::AFGR32RegisterClass)
+    Opc = Mips::SWC1A;
+  else if (RC == Mips::AFGR64RegisterClass)
+    Opc = Mips::SDC1;
+  else 
+    assert(0 && "Can't store this register");
+
+  MachineInstrBuilder MIB = BuildMI(get(Opc))
+    .addReg(SrcReg, false, false, isKill);
+  for (unsigned i = 0, e = Addr.size(); i != e; ++i) {
+    MachineOperand &MO = Addr[i];
+    if (MO.isRegister())
+      MIB.addReg(MO.getReg());
+    else if (MO.isImmediate())
+      MIB.addImm(MO.getImm());
+    else
+      MIB.addFrameIndex(MO.getIndex());
+  }
+  NewMIs.push_back(MIB);
+  return;
+}
+
+void MipsInstrInfo::
+loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
+                     unsigned DestReg, int FI,
+                     const TargetRegisterClass *RC) const 
+{
+  unsigned Opc;
+  if (RC == Mips::CPURegsRegisterClass) 
+    Opc = Mips::LW;
+  else if (RC == Mips::FGR32RegisterClass)
+    Opc = Mips::LWC1;
+  else if (RC == Mips::AFGR32RegisterClass)
+    Opc = Mips::LWC1A;
+  else if (RC == Mips::AFGR64RegisterClass)
+    Opc = Mips::LDC1;
+  else 
+    assert(0 && "Can't load this register from stack slot");
+    
+  BuildMI(MBB, I, get(Opc), DestReg).addImm(0).addFrameIndex(FI);
+}
+
+void MipsInstrInfo::loadRegFromAddr(MachineFunction &MF, unsigned DestReg,
+                                       SmallVectorImpl<MachineOperand> &Addr,
+                                       const TargetRegisterClass *RC,
+                                 SmallVectorImpl<MachineInstr*> &NewMIs) const {
+  unsigned Opc;
+  if (RC == Mips::CPURegsRegisterClass) 
+    Opc = Mips::LW;
+  else if (RC == Mips::FGR32RegisterClass)
+    Opc = Mips::LWC1;
+  else if (RC == Mips::AFGR32RegisterClass)
+    Opc = Mips::LWC1A;
+  else if (RC == Mips::AFGR64RegisterClass)
+    Opc = Mips::LDC1;
+  else 
+    assert(0 && "Can't load this register");
+
+  MachineInstrBuilder MIB = BuildMI(get(Opc), DestReg);
+  for (unsigned i = 0, e = Addr.size(); i != e; ++i) {
+    MachineOperand &MO = Addr[i];
+    if (MO.isRegister())
+      MIB.addReg(MO.getReg());
+    else if (MO.isImmediate())
+      MIB.addImm(MO.getImm());
+    else
+      MIB.addFrameIndex(MO.getIndex());
+  }
+  NewMIs.push_back(MIB);
+  return;
+}
+
+MachineInstr *MipsInstrInfo::
+foldMemoryOperand(MachineFunction &MF,
+                  MachineInstr* MI,
+                  SmallVectorImpl<unsigned> &Ops, int FI) const 
+{
+  if (Ops.size() != 1) return NULL;
+
+  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 (Ops[0] == 0) {    // COPY -> STORE
+        unsigned SrcReg = MI->getOperand(2).getReg();
+        bool isKill = MI->getOperand(2).isKill();
+        NewMI = BuildMI(get(Mips::SW)).addFrameIndex(FI)
+          .addImm(0).addReg(SrcReg, false, false, isKill);
+      } else {              // COPY -> LOAD
+        unsigned DstReg = MI->getOperand(0).getReg();
+        bool isDead = MI->getOperand(0).isDead();
+        NewMI = BuildMI(get(Mips::LW))
+          .addReg(DstReg, true, false, false, isDead)
+          .addImm(0).addFrameIndex(FI);
+      }
+    }
+    break;
+  case Mips::FMOV_SO32:
+  case Mips::FMOV_AS32:
+  case Mips::FMOV_D32:
+    if ((MI->getOperand(0).isRegister()) &&
+        (MI->getOperand(1).isRegister())) {
+      const TargetRegisterClass *RC = RI.getRegClass(MI->getOperand(0).getReg());
+      unsigned StoreOpc, LoadOpc;
+
+      if (RC == Mips::FGR32RegisterClass) {
+        LoadOpc = Mips::LWC1; StoreOpc = Mips::SWC1;
+      } else if (RC == Mips::AFGR32RegisterClass) {
+        LoadOpc = Mips::LWC1A; StoreOpc = Mips::SWC1A;
+      } else if (RC == Mips::AFGR64RegisterClass) {
+        LoadOpc = Mips::LDC1; StoreOpc = Mips::SDC1;
+      } else
+        assert(0 && "foldMemoryOperand register unknown");
+
+      if (Ops[0] == 0) {    // COPY -> STORE
+        unsigned SrcReg = MI->getOperand(1).getReg();
+        bool isKill = MI->getOperand(1).isKill();
+        NewMI = BuildMI(get(StoreOpc)).addFrameIndex(FI)
+          .addImm(0).addReg(SrcReg, false, false, isKill);
+      } else {              // COPY -> LOAD
+        unsigned DstReg = MI->getOperand(0).getReg();
+        bool isDead = MI->getOperand(0).isDead();
+        NewMI = BuildMI(get(LoadOpc))
+          .addReg(DstReg, true, false, false, isDead)
+          .addImm(0).addFrameIndex(FI);
+      }
+    }
+    break;
+  }
+
+  return NewMI;
+}
+
 //===----------------------------------------------------------------------===//
 // Branch Analysis
 //===----------------------------------------------------------------------===//
@@ -120,12 +330,12 @@
 {
   switch (BrOpc) {
   default: return Mips::COND_INVALID;
-  case Mips::BEQ  : return Mips::COND_E;
-  case Mips::BNE  : return Mips::COND_NE;
-  case Mips::BGTZ : return Mips::COND_GZ;
-  case Mips::BGEZ : return Mips::COND_GEZ;
-  case Mips::BLTZ : return Mips::COND_LZ;
-  case Mips::BLEZ : return Mips::COND_LEZ;
+  case Mips::BEQ   : return Mips::COND_E;
+  case Mips::BNE   : return Mips::COND_NE;
+  case Mips::BGTZ  : return Mips::COND_GZ;
+  case Mips::BGEZ  : return Mips::COND_GEZ;
+  case Mips::BLTZ  : return Mips::COND_LZ;
+  case Mips::BLEZ  : return Mips::COND_LEZ;
   }
 }
 
@@ -156,6 +366,22 @@
   case Mips::COND_GEZ : return Mips::COND_LZ;
   case Mips::COND_LZ  : return Mips::COND_GEZ;
   case Mips::COND_LEZ : return Mips::COND_GZ;
+  case Mips::FCOND_F  : return Mips::FCOND_T;
+  case Mips::FCOND_UN : return Mips::FCOND_OR;
+  case Mips::FCOND_EQ : return Mips::FCOND_NEQ;
+  case Mips::FCOND_UEQ: return Mips::FCOND_OGL;
+  case Mips::FCOND_OLT: return Mips::FCOND_UGE;
+  case Mips::FCOND_ULT: return Mips::FCOND_OGE;
+  case Mips::FCOND_OLE: return Mips::FCOND_UGT;
+  case Mips::FCOND_ULE: return Mips::FCOND_OGT;
+  case Mips::FCOND_SF:  return Mips::FCOND_ST;
+  case Mips::FCOND_NGLE:return Mips::FCOND_GLE;
+  case Mips::FCOND_SEQ: return Mips::FCOND_SNE;
+  case Mips::FCOND_NGL: return Mips::FCOND_GL;
+  case Mips::FCOND_LT:  return Mips::FCOND_NLT;
+  case Mips::FCOND_NGE: return Mips::FCOND_GE;
+  case Mips::FCOND_LE:  return Mips::FCOND_NLE;
+  case Mips::FCOND_NGT: return Mips::FCOND_GT;
   }
 }
 
@@ -287,124 +513,6 @@
   return 2;
 }
 
-void MipsInstrInfo::
-copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
-             unsigned DestReg, unsigned SrcReg,
-             const TargetRegisterClass *DestRC,
-             const TargetRegisterClass *SrcRC) const {
-  if (DestRC != SrcRC) {
-    cerr << "Not yet supported!";
-    abort();
-  }
-
-  if (DestRC == Mips::CPURegsRegisterClass)
-    BuildMI(MBB, I, get(Mips::ADDu), DestReg).addReg(Mips::ZERO)
-      .addReg(SrcReg);
-  else
-    assert (0 && "Can't copy this register");
-}
-
-void MipsInstrInfo::
-storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
-          unsigned SrcReg, bool isKill, int FI, 
-          const TargetRegisterClass *RC) const 
-{
-  if (RC == Mips::CPURegsRegisterClass)
-    BuildMI(MBB, I, get(Mips::SW)).addReg(SrcReg, false, false, isKill)
-          .addImm(0).addFrameIndex(FI);
-  else
-    assert(0 && "Can't store this register to stack slot");
-}
-
-void MipsInstrInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg,
-                                      bool isKill,
-                                      SmallVectorImpl<MachineOperand> &Addr,
-                                      const TargetRegisterClass *RC,
-                                 SmallVectorImpl<MachineInstr*> &NewMIs) const {
-  if (RC != Mips::CPURegsRegisterClass)
-    assert(0 && "Can't store this register");
-  MachineInstrBuilder MIB = BuildMI(get(Mips::SW))
-    .addReg(SrcReg, false, false, isKill);
-  for (unsigned i = 0, e = Addr.size(); i != e; ++i) {
-    MachineOperand &MO = Addr[i];
-    if (MO.isRegister())
-      MIB.addReg(MO.getReg());
-    else if (MO.isImmediate())
-      MIB.addImm(MO.getImm());
-    else
-      MIB.addFrameIndex(MO.getIndex());
-  }
-  NewMIs.push_back(MIB);
-  return;
-}
-
-void MipsInstrInfo::
-loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
-                     unsigned DestReg, int FI,
-                     const TargetRegisterClass *RC) const 
-{
-  if (RC == Mips::CPURegsRegisterClass)
-    BuildMI(MBB, I, get(Mips::LW), DestReg).addImm(0).addFrameIndex(FI);
-  else
-    assert(0 && "Can't load this register from stack slot");
-}
-
-void MipsInstrInfo::loadRegFromAddr(MachineFunction &MF, unsigned DestReg,
-                                       SmallVectorImpl<MachineOperand> &Addr,
-                                       const TargetRegisterClass *RC,
-                                 SmallVectorImpl<MachineInstr*> &NewMIs) const {
-  if (RC != Mips::CPURegsRegisterClass)
-    assert(0 && "Can't load this register");
-  MachineInstrBuilder MIB = BuildMI(get(Mips::LW), DestReg);
-  for (unsigned i = 0, e = Addr.size(); i != e; ++i) {
-    MachineOperand &MO = Addr[i];
-    if (MO.isRegister())
-      MIB.addReg(MO.getReg());
-    else if (MO.isImmediate())
-      MIB.addImm(MO.getImm());
-    else
-      MIB.addFrameIndex(MO.getIndex());
-  }
-  NewMIs.push_back(MIB);
-  return;
-}
-
-MachineInstr *MipsInstrInfo::
-foldMemoryOperand(MachineFunction &MF,
-                  MachineInstr* MI,
-                  SmallVectorImpl<unsigned> &Ops, int FI) const 
-{
-  if (Ops.size() != 1) return NULL;
-
-  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 (Ops[0] == 0) {    // COPY -> STORE
-          unsigned SrcReg = MI->getOperand(2).getReg();
-          bool isKill = MI->getOperand(2).isKill();
-          NewMI = BuildMI(get(Mips::SW)).addFrameIndex(FI)
-            .addImm(0).addReg(SrcReg, false, false, isKill);
-        } else {              // COPY -> LOAD
-          unsigned DstReg = MI->getOperand(0).getReg();
-          bool isDead = MI->getOperand(0).isDead();
-          NewMI = BuildMI(get(Mips::LW))
-            .addReg(DstReg, true, false, false, isDead)
-            .addImm(0).addFrameIndex(FI);
-        }
-      }
-      break;
-  }
-
-  return NewMI;
-}
-
 unsigned MipsInstrInfo::
 RemoveBranch(MachineBasicBlock &MBB) const 
 {
@@ -456,5 +564,3 @@
   Cond[0].setImm(GetOppositeBranchCondition((Mips::CondCode)Cond[0].getImm()));
   return false;
 }
-
-

Modified: llvm/trunk/lib/Target/Mips/MipsInstrInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsInstrInfo.h?rev=53146&r1=53145&r2=53146&view=diff

==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsInstrInfo.h (original)
+++ llvm/trunk/lib/Target/Mips/MipsInstrInfo.h Sat Jul  5 14:05:21 2008
@@ -24,6 +24,45 @@
 
   // Mips Condition Codes
   enum CondCode {
+    // To be used with float branch True
+    FCOND_F,
+    FCOND_UN,
+    FCOND_EQ,
+    FCOND_UEQ,
+    FCOND_OLT,
+    FCOND_ULT,
+    FCOND_OLE,
+    FCOND_ULE,
+    FCOND_SF,
+    FCOND_NGLE,
+    FCOND_SEQ,
+    FCOND_NGL,
+    FCOND_LT,
+    FCOND_NGE,
+    FCOND_LE,
+    FCOND_NGT,
+
+    // To be used with float branch False
+    // This conditions have the same mnemonic as the
+    // above ones, but are used with a branch False;
+    FCOND_T,
+    FCOND_OR,
+    FCOND_NEQ,
+    FCOND_OGL,
+    FCOND_UGE,
+    FCOND_OGE,
+    FCOND_UGT,
+    FCOND_OGT,
+    FCOND_ST,
+    FCOND_GLE,
+    FCOND_SNE,
+    FCOND_GL,
+    FCOND_NLT,
+    FCOND_GE,
+    FCOND_NLE,
+    FCOND_GT,
+
+    // Only integer conditions
     COND_E,
     COND_GZ,
     COND_GEZ,
@@ -40,6 +79,45 @@
   /// e.g. turning COND_E to COND_NE.
   CondCode GetOppositeBranchCondition(Mips::CondCode CC);
 
+  /// MipsCCToString - Map each FP condition code to its string
+  inline static const char *MipsFCCToString(Mips::CondCode CC) 
+  {
+    switch (CC) {
+      default: assert(0 && "Unknown condition code");
+      case FCOND_F:
+      case FCOND_T:   return "f";
+      case FCOND_UN:
+      case FCOND_OR:  return "un";
+      case FCOND_EQ: 
+      case FCOND_NEQ: return "eq";
+      case FCOND_UEQ:
+      case FCOND_OGL: return "ueq";
+      case FCOND_OLT:
+      case FCOND_UGE: return "olt";
+      case FCOND_ULT:
+      case FCOND_OGE: return "ult";
+      case FCOND_OLE:
+      case FCOND_UGT: return "ole";
+      case FCOND_ULE:
+      case FCOND_OGT: return "ule";
+      case FCOND_SF:
+      case FCOND_ST:  return "sf";
+      case FCOND_NGLE:
+      case FCOND_GLE: return "ngle";
+      case FCOND_SEQ:
+      case FCOND_SNE: return "seq";
+      case FCOND_NGL:
+      case FCOND_GL:  return "ngl";
+      case FCOND_LT:
+      case FCOND_NLT: return "lt";
+      case FCOND_NGE:
+      case FCOND_GE:  return "ge";
+      case FCOND_LE:
+      case FCOND_NLE: return "nle";
+      case FCOND_NGT:
+      case FCOND_GT:  return "gt";
+    }
+  }
 }
 
 class MipsInstrInfo : public TargetInstrInfoImpl {

Modified: llvm/trunk/lib/Target/Mips/MipsInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsInstrInfo.td?rev=53146&r1=53145&r2=53146&view=diff

==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsInstrInfo.td (original)
+++ llvm/trunk/lib/Target/Mips/MipsInstrInfo.td Sat Jul  5 14:05:21 2008
@@ -17,10 +17,16 @@
 // Mips profiles and nodes
 //===----------------------------------------------------------------------===//
 
+def SDT_MipsRet          : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
+def SDT_MipsJmpLink      : SDTypeProfile<0, 1, [SDTCisVT<0, iPTR>]>;
+def SDT_MipsSelectCC     : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, 
+                                         SDTCisSameAs<1, 2>, SDTCisInt<3>]>;
+def SDT_MipsCallSeqStart : SDCallSeqStart<[SDTCisVT<0, i32>]>;
+def SDT_MipsCallSeqEnd   : SDCallSeqEnd<[SDTCisVT<0, i32>, SDTCisVT<1, i32>]>;
+
 // Call
-def SDT_MipsJmpLink : SDTypeProfile<0, 1, [SDTCisVT<0, iPTR>]>;
-def MipsJmpLink     : SDNode<"MipsISD::JmpLink",SDT_MipsJmpLink, [SDNPHasChain,
-                             SDNPOutFlag]>;
+def MipsJmpLink : SDNode<"MipsISD::JmpLink",SDT_MipsJmpLink, [SDNPHasChain,
+                         SDNPOutFlag]>;
 
 // Hi and Lo nodes are used to handle global addresses. Used on 
 // MipsISelLowering to lower stuff like GlobalAddress, ExternalSymbol 
@@ -29,29 +35,22 @@
 def MipsLo  : SDNode<"MipsISD::Lo", SDTIntUnaryOp>;
 
 // Return
-def SDT_MipsRet : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
-def MipsRet     : SDNode<"MipsISD::Ret", SDT_MipsRet, [SDNPHasChain,
-                             SDNPOptInFlag]>;
+def MipsRet : SDNode<"MipsISD::Ret", SDT_MipsRet, [SDNPHasChain, 
+                     SDNPOptInFlag]>;
 
 // These are target-independent nodes, but have target-specific formats.
-def SDT_MipsCallSeqStart : SDCallSeqStart<[SDTCisVT<0, i32>]>;
-def SDT_MipsCallSeqEnd   : SDCallSeqEnd<[SDTCisVT<0, i32>,
-                                         SDTCisVT<1, i32>]>;
+def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_MipsCallSeqStart,
+                           [SDNPHasChain, SDNPOutFlag]>;
+def callseq_end   : SDNode<"ISD::CALLSEQ_END", SDT_MipsCallSeqEnd,
+                           [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
 
-def callseq_start   : SDNode<"ISD::CALLSEQ_START", SDT_MipsCallSeqStart,
-                             [SDNPHasChain, SDNPOutFlag]>;
-def callseq_end     : SDNode<"ISD::CALLSEQ_END", SDT_MipsCallSeqEnd,
-                             [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
-
-// Select CC
-def SDT_MipsSelectCC : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, 
-                                            SDTCisSameAs<1, 2>, SDTCisInt<3>]>;
-def MipsSelectCC : SDNode<"MipsISD::SelectCC", SDT_MipsSelectCC>;
+// Select Condition Code
+def MipsSelectCC  : SDNode<"MipsISD::SelectCC", SDT_MipsSelectCC>;
 
 //===----------------------------------------------------------------------===//
 // Mips Instruction Predicate Definitions.
 //===----------------------------------------------------------------------===//
-def IsStatic : Predicate<"TM.getRelocationModel() == Reloc::Static">;
+def IsAllegrex : Predicate<"Subtarget.isAllegrex()">;
 
 //===----------------------------------------------------------------------===//
 // Mips Operand, Complex Patterns and Transformations Definitions.
@@ -63,7 +62,6 @@
 def uimm16      : Operand<i32>;
 def simm16      : Operand<i32>;
 def shamt       : Operand<i32>;
-def addrlabel   : Operand<i32>;
 
 // Address operand
 def mem : Operand<i32> {
@@ -345,6 +343,12 @@
      instr_asm,
      [(set CPURegs:$dst, addr:$addr)], IIAlu>;
 
+class SignExtInReg<bits<6> func, string instr_asm, ValueType vt>:
+  FR< 0x3f, func, (outs CPURegs:$dst), (ins CPURegs:$src),
+      !strconcat(instr_asm, " $dst, $src"),
+      [(set CPURegs:$dst, (sext_inreg CPURegs:$src, vt))], NoItinerary>;
+
+
 //===----------------------------------------------------------------------===//
 // Pseudo instructions
 //===----------------------------------------------------------------------===//
@@ -352,11 +356,11 @@
 // As stack alignment is always done with addiu, we need a 16-bit immediate
 let Defs = [SP], Uses = [SP] in {
 def ADJCALLSTACKDOWN : MipsPseudo<(outs), (ins uimm16:$amt),
-                                      "!ADJCALLSTACKDOWN $amt",
-                                      [(callseq_start imm:$amt)]>;
+                                  "!ADJCALLSTACKDOWN $amt",
+                                  [(callseq_start imm:$amt)]>;
 def ADJCALLSTACKUP   : MipsPseudo<(outs), (ins uimm16:$amt1, uimm16:$amt2),
-                                      "!ADJCALLSTACKUP $amt1",
-                                      [(callseq_end imm:$amt1, imm:$amt2)]>;
+                                  "!ADJCALLSTACKUP $amt1",
+                                  [(callseq_end imm:$amt1, imm:$amt2)]>;
 }
 
 // When handling PIC code the assembler needs .cpload and .cprestore
@@ -364,10 +368,10 @@
 // are used, we have the same behavior, but get also a bunch of warnings
 // from the assembler.
 def CPLOAD : MipsPseudo<(outs), (ins CPURegs:$reg),
-                            ".set noreorder\n\t.cpload $reg\n\t.set reorder\n", 
-                            []>;
+                        ".set noreorder\n\t.cpload $reg\n\t.set reorder\n", 
+                        []>;
 def CPRESTORE : MipsPseudo<(outs), (ins uimm16:$loc),
-                               ".cprestore $loc\n", []>;
+                           ".cprestore $loc\n", []>;
 
 // The supported Mips ISAs dont have any instruction close to the SELECT_CC 
 // operation. The solution is to create a Mips pseudo SELECT_CC instruction
@@ -474,19 +478,6 @@
 def MTHI    : MoveFromTo<0x11, "mthi">;
 def MTLO    : MoveFromTo<0x13, "mtlo">;
 
-// Count Leading
-// CLO/CLZ are part of the newer MIPS32(tm) instruction
-// set and not older Mips I keep this for future use
-// though. 
-//def CLO     : CountLeading<0x21, "clo">;
-//def CLZ     : CountLeading<0x20, "clz">;
-
-// MADD*/MSUB* are not part of MipsI either.
-//def MADD    : MArithR<0x00, "madd">;
-//def MADDU   : MArithR<0x01, "maddu">;
-//def MSUB    : MArithR<0x04, "msub">;
-//def MSUBU   : MArithR<0x05, "msubu">;
-
 // No operation
 let addr=0 in
 def NOP     : FJ<0, (outs), (ins), "nop", [], IIAlu>;
@@ -506,6 +497,27 @@
 // can be matched. It's similar to Sparc LEA_ADDRi
 def LEA_ADDiu : EffectiveAddress<"addiu $dst, ${addr:stackloc}">;
 
+// Count Leading
+// CLO/CLZ are part of the newer MIPS32(tm) instruction
+// set and not older Mips I keep this for future use
+// though. 
+//def CLO     : CountLeading<0x21, "clo">;
+//def CLZ     : CountLeading<0x20, "clz">;
+
+// MADD*/MSUB* are not part of MipsI either.
+//def MADD    : MArithR<0x00, "madd">;
+//def MADDU   : MArithR<0x01, "maddu">;
+//def MSUB    : MArithR<0x04, "msub">;
+//def MSUBU   : MArithR<0x05, "msubu">;
+
+let Predicates = [IsAllegrex] in {
+  let shamt = 0x10, rs = 0 in 
+    def SEB : SignExtInReg<0x21, "seb", i8>;
+
+  let shamt = 0x18, rs = 0 in 
+    def SEH : SignExtInReg<0x20, "seh", i16>;
+}
+
 //===----------------------------------------------------------------------===//
 //  Arbitrary patterns that map to one or more instructions
 //===----------------------------------------------------------------------===//
@@ -546,7 +558,7 @@
 def : Pat<(add CPURegs:$hi, (MipsLo tjumptable:$lo)),
           (ADDiu CPURegs:$hi, tjumptable:$lo)>;
 
-// Mips does not have not, so we increase the operation
+// Mips does not have "not", so we expand our way
 def : Pat<(not CPURegs:$in),
           (NOR CPURegs:$in, ZERO)>;
 
@@ -558,10 +570,7 @@
 // peepholes
 def : Pat<(store (i32 0), addr:$dst), (SW ZERO, addr:$dst)>;
 
-///
-/// brcond patterns
-///
-
+// brcond patterns
 // direct match equal/notequal zero branches
 def : Pat<(brcond (setne CPURegs:$lhs, 0), bb:$dst),
           (BNE CPURegs:$lhs, ZERO, bb:$dst)>;
@@ -601,12 +610,8 @@
 def : Pat<(brcond CPURegs:$cond, bb:$dst),
           (BNE CPURegs:$cond, ZERO, bb:$dst)>;
 
-///
 /// setcc patterns, only matched when there
 /// is no brcond following a setcc operation
-///
-
-// setcc 2 register operands
 def : Pat<(setle CPURegs:$lhs, CPURegs:$rhs),
           (XORi (SLT CPURegs:$rhs, CPURegs:$lhs), 1)>;
 def : Pat<(setule CPURegs:$lhs, CPURegs:$rhs),
@@ -630,8 +635,14 @@
           (XORi (OR (SLT CPURegs:$lhs, CPURegs:$rhs),
                     (SLT CPURegs:$rhs, CPURegs:$lhs)), 1)>;
 
-// setcc reg/imm operands
 def : Pat<(setge CPURegs:$lhs, immSExt16:$rhs),
           (XORi (SLTi CPURegs:$lhs, immSExt16:$rhs), 1)>;
 def : Pat<(setuge CPURegs:$lhs, immZExt16:$rhs),
           (XORi (SLTiu CPURegs:$lhs, immZExt16:$rhs), 1)>;
+
+//===----------------------------------------------------------------------===//
+// Floating Point Support
+//===----------------------------------------------------------------------===//
+
+include "MipsInstrFPU.td"
+

Modified: llvm/trunk/lib/Target/Mips/MipsMachineFunction.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsMachineFunction.h?rev=53146&r1=53145&r2=53146&view=diff

==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsMachineFunction.h (original)
+++ llvm/trunk/lib/Target/Mips/MipsMachineFunction.h Sat Jul  5 14:05:21 2008
@@ -25,12 +25,12 @@
 class MipsFunctionInfo : public MachineFunctionInfo {
 
 private:
-  /// Holds for each function where on the stack 
-  /// the Frame Pointer must be saved
+  /// Holds for each function where on the stack the Frame Pointer must be 
+  /// saved.
   int FPStackOffset;
 
-  /// Holds for each function where on the stack 
-  /// the Return Address must be saved
+  /// Holds for each function where on the stack the Return Address must be 
+  /// saved.
   int RAStackOffset;
 
   /// MipsFIHolder - Holds a FrameIndex and it's Stack Pointer Offset
@@ -43,31 +43,34 @@
       : FI(FrameIndex), SPOffset(StackPointerOffset) {}
   };
 
-  /// When PIC is used the GP must be saved on the stack
-  /// on the function prologue and must be reloaded from this
-  /// stack location after every call. A reference to its stack
-  /// location and frame index must be kept to be used on
-  /// emitPrologue and processFunctionBeforeFrameFinalized.
+  /// When PIC is used the GP must be saved on the stack on the function 
+  /// prologue and must be reloaded from this stack location after every 
+  /// call. A reference to its stack location and frame index must be kept 
+  /// to be used on emitPrologue and processFunctionBeforeFrameFinalized.
   MipsFIHolder GPHolder;
 
-  // On LowerFORMAL_ARGUMENTS the stack size is unknown,
-  // so the Stack Pointer Offset calculation of "not in 
-  // register arguments" must be postponed to emitPrologue. 
+  // On LowerFORMAL_ARGUMENTS the stack size is unknown, so the Stack 
+  // Pointer Offset calculation of "not in register arguments" must be 
+  // postponed to emitPrologue. 
   SmallVector<MipsFIHolder, 16> FnLoadArgs;
   bool HasLoadArgs;
 
-  // When VarArgs, we must write registers back to caller
-  // stack, preserving on register arguments. Since the 
-  // stack size is unknown on LowerFORMAL_ARGUMENTS,
-  // the Stack Pointer Offset calculation must be
+  // When VarArgs, we must write registers back to caller stack, preserving 
+  // on register arguments. Since the stack size is unknown on 
+  // LowerFORMAL_ARGUMENTS, the Stack Pointer Offset calculation must be
   // postponed to emitPrologue. 
   SmallVector<MipsFIHolder, 4> FnStoreVarArgs;
   bool HasStoreVarArgs;
 
+  /// SRetReturnReg - Some subtargets require that sret lowering includes
+  /// returning the value of the returned struct in a register. This field
+  /// holds the virtual register into which the sret argument is passed.
+  unsigned SRetReturnReg;
+
 public:
   MipsFunctionInfo(MachineFunction& MF) 
-  : FPStackOffset(0), RAStackOffset(0), GPHolder(-1,-1),
-    HasLoadArgs(false), HasStoreVarArgs(false)
+  : FPStackOffset(0), RAStackOffset(0), GPHolder(-1,-1), HasLoadArgs(false),
+    HasStoreVarArgs(false), SRetReturnReg(0)
   {}
 
   int getFPStackOffset() const { return FPStackOffset; }
@@ -109,6 +112,8 @@
       MFI->setObjectOffset( FnStoreVarArgs[i].FI, FnStoreVarArgs[i].SPOffset );
   }
 
+  unsigned getSRetReturnReg() const { return SRetReturnReg; }
+  void setSRetReturnReg(unsigned Reg) { SRetReturnReg = Reg; }
 };
 
 } // end of namespace llvm

Modified: llvm/trunk/lib/Target/Mips/MipsRegisterInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsRegisterInfo.cpp?rev=53146&r1=53145&r2=53146&view=diff

==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsRegisterInfo.cpp (original)
+++ llvm/trunk/lib/Target/Mips/MipsRegisterInfo.cpp Sat Jul  5 14:05:21 2008
@@ -32,14 +32,12 @@
 #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) {}
+    TII(tii) {}
 
 /// getRegisterNumbering - Given the enum value for some register, e.g.
 /// Mips::RA, return the number that it corresponds to (e.g. 31).
@@ -47,38 +45,38 @@
 getRegisterNumbering(unsigned RegEnum) 
 {
   switch (RegEnum) {
-    case Mips::ZERO : return 0;
-    case Mips::AT   : return 1;
-    case Mips::V0   : return 2;
-    case Mips::V1   : return 3;
-    case Mips::A0   : return 4;
-    case Mips::A1   : return 5;
-    case Mips::A2   : return 6;
-    case Mips::A3   : return 7;
-    case Mips::T0   : return 8;
-    case Mips::T1   : return 9;
-    case Mips::T2   : return 10;
-    case Mips::T3   : return 11;
-    case Mips::T4   : return 12;
-    case Mips::T5   : return 13;
-    case Mips::T6   : return 14;
-    case Mips::T7   : return 15;
-    case Mips::T8   : return 16;
-    case Mips::T9   : return 17;
-    case Mips::S0   : return 18;
-    case Mips::S1   : return 19;
-    case Mips::S2   : return 20;
-    case Mips::S3   : return 21;
-    case Mips::S4   : return 22;
-    case Mips::S5   : return 23;
-    case Mips::S6   : return 24;
-    case Mips::S7   : return 25;
-    case Mips::K0   : return 26;
-    case Mips::K1   : return 27;
-    case Mips::GP   : return 28;
-    case Mips::SP   : return 29;
-    case Mips::FP   : return 30;
-    case Mips::RA   : return 31;
+    case Mips::ZERO : case Mips::F0 : return 0;
+    case Mips::AT   : case Mips::F1 : return 1;
+    case Mips::V0   : case Mips::F2 : return 2;
+    case Mips::V1   : case Mips::F3 : return 3;
+    case Mips::A0   : case Mips::F4 : return 4;
+    case Mips::A1   : case Mips::F5 : return 5;
+    case Mips::A2   : case Mips::F6 : return 6;
+    case Mips::A3   : case Mips::F7 : return 7;
+    case Mips::T0   : case Mips::F8 : return 8;
+    case Mips::T1   : case Mips::F9 : return 9;
+    case Mips::T2   : case Mips::F10: return 10;
+    case Mips::T3   : case Mips::F11: return 11;
+    case Mips::T4   : case Mips::F12: return 12;
+    case Mips::T5   : case Mips::F13: return 13;
+    case Mips::T6   : case Mips::F14: return 14;
+    case Mips::T7   : case Mips::F15: return 15;
+    case Mips::T8   : case Mips::F16: return 16;
+    case Mips::T9   : case Mips::F17: return 17;
+    case Mips::S0   : case Mips::F18: return 18;
+    case Mips::S1   : case Mips::F19: return 19;
+    case Mips::S2   : case Mips::F20: return 20;
+    case Mips::S3   : case Mips::F21: return 21;
+    case Mips::S4   : case Mips::F22: return 22;
+    case Mips::S5   : case Mips::F23: return 23;
+    case Mips::S6   : case Mips::F24: return 24;
+    case Mips::S7   : case Mips::F25: return 25;
+    case Mips::K0   : case Mips::F26: return 26;
+    case Mips::K1   : case Mips::F27: return 27;
+    case Mips::GP   : case Mips::F28: return 28;
+    case Mips::SP   : case Mips::F29: return 29;
+    case Mips::FP   : case Mips::F30: return 30;
+    case Mips::RA   : case Mips::F31: return 31;
     default: assert(0 && "Unknown register number!");
   }    
   return 0; // Not reached
@@ -94,11 +92,12 @@
 const unsigned* MipsRegisterInfo::
 getCalleeSavedRegs(const MachineFunction *MF) const 
 {
-  // Mips calle-save register range is $16-$26(s0-s7)
+  // Mips callee-save register range is $16-$23(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;
 }
 
@@ -271,6 +270,8 @@
   int FPOffset, RAOffset;
   
   // Allocate space for saved RA and FP when needed 
+  // FIXME: within 64-bit registers, change hardcoded
+  // sizes for RA and FP offsets.
   if ((hasFP(MF)) && (MFI->hasCalls())) {
     FPOffset = NumBytes;
     RAOffset = (NumBytes+4);
@@ -283,8 +284,7 @@
     FPOffset = NumBytes;
     RAOffset = 0;
     NumBytes += 4;
-  } else {
-    // No calls and no fp.
+  } else { // No calls and no fp.
     RAOffset = FPOffset = 0;
   }
 

Modified: llvm/trunk/lib/Target/Mips/MipsRegisterInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsRegisterInfo.td?rev=53146&r1=53145&r2=53146&view=diff

==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsRegisterInfo.td (original)
+++ llvm/trunk/lib/Target/Mips/MipsRegisterInfo.td Sat Jul  5 14:05:21 2008
@@ -17,50 +17,123 @@
   let Namespace = "Mips";
 }
 
-//===----------------------------------------------------------------------===//
-//  General Purpose Registers
-//===----------------------------------------------------------------------===//
-
 // 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]>;
+// Mips 32-bit FPU Registers
+class FPR<bits<5> num, string n> : MipsReg<n> {
+  let Num = num;
+}
+
+// Mips 64-bit (aliased) FPU Registers
+class AFPR<bits<5> num, string n, list<Register> aliases> : MipsReg<n> {
+  let Num = num;
+  let Aliases = aliases;
+}
+
+//===----------------------------------------------------------------------===//
+//  Registers
+//===----------------------------------------------------------------------===//
+
+let Namespace = "Mips" in {
+
+  // General Purpose 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]>;
+  
+  /// Mips Single point precision FPU Registers
+  def F0  : FPR< 0,  "F0">, DwarfRegNum<[32]>;
+  def F1  : FPR< 1,  "F1">, DwarfRegNum<[33]>;
+  def F2  : FPR< 2,  "F2">, DwarfRegNum<[34]>;
+  def F3  : FPR< 3,  "F3">, DwarfRegNum<[35]>;
+  def F4  : FPR< 4,  "F4">, DwarfRegNum<[36]>;
+  def F5  : FPR< 5,  "F5">, DwarfRegNum<[37]>;
+  def F6  : FPR< 6,  "F6">, DwarfRegNum<[38]>;
+  def F7  : FPR< 7,  "F7">, DwarfRegNum<[39]>;
+  def F8  : FPR< 8,  "F8">, DwarfRegNum<[40]>;
+  def F9  : FPR< 9,  "F9">, DwarfRegNum<[41]>;
+  def F10 : FPR<10, "F10">, DwarfRegNum<[42]>;
+  def F11 : FPR<11, "F11">, DwarfRegNum<[43]>;
+  def F12 : FPR<12, "F12">, DwarfRegNum<[44]>;
+  def F13 : FPR<13, "F13">, DwarfRegNum<[45]>;
+  def F14 : FPR<14, "F14">, DwarfRegNum<[46]>;
+  def F15 : FPR<15, "F15">, DwarfRegNum<[47]>;
+  def F16 : FPR<16, "F16">, DwarfRegNum<[48]>;
+  def F17 : FPR<17, "F17">, DwarfRegNum<[49]>;
+  def F18 : FPR<18, "F18">, DwarfRegNum<[50]>;
+  def F19 : FPR<19, "F19">, DwarfRegNum<[51]>;
+  def F20 : FPR<20, "F20">, DwarfRegNum<[52]>;
+  def F21 : FPR<21, "F21">, DwarfRegNum<[53]>;
+  def F22 : FPR<22, "F22">, DwarfRegNum<[54]>;
+  def F23 : FPR<23, "F23">, DwarfRegNum<[55]>;
+  def F24 : FPR<24, "F24">, DwarfRegNum<[56]>;
+  def F25 : FPR<25, "F25">, DwarfRegNum<[57]>;
+  def F26 : FPR<26, "F26">, DwarfRegNum<[58]>;
+  def F27 : FPR<27, "F27">, DwarfRegNum<[59]>;
+  def F28 : FPR<28, "F28">, DwarfRegNum<[60]>;
+  def F29 : FPR<29, "F29">, DwarfRegNum<[61]>;
+  def F30 : FPR<30, "F30">, DwarfRegNum<[62]>;
+  def F31 : FPR<31, "F31">, DwarfRegNum<[63]>;
+  
+  /// Mips Double point precision FPU Registers (aliased
+  /// with the single precision to hold 64 bit values)
+  def D0  : AFPR< 0,  "F0", [F0,   F1]>, DwarfRegNum<[32]>;
+  def D1  : AFPR< 2,  "F2", [F2,   F3]>, DwarfRegNum<[34]>;
+  def D2  : AFPR< 4,  "F4", [F4,   F5]>, DwarfRegNum<[36]>;
+  def D3  : AFPR< 6,  "F6", [F6,   F7]>, DwarfRegNum<[38]>;
+  def D4  : AFPR< 8,  "F8", [F8,   F9]>, DwarfRegNum<[40]>;
+  def D5  : AFPR<10, "F10", [F10, F11]>, DwarfRegNum<[42]>;
+  def D6  : AFPR<12, "F12", [F12, F13]>, DwarfRegNum<[44]>;
+  def D7  : AFPR<14, "F14", [F14, F15]>, DwarfRegNum<[46]>;
+  def D8  : AFPR<16, "F16", [F16, F17]>, DwarfRegNum<[48]>;
+  def D9  : AFPR<18, "F18", [F18, F19]>, DwarfRegNum<[50]>;
+  def D10 : AFPR<20, "F20", [F20, F21]>, DwarfRegNum<[52]>;
+  def D11 : AFPR<22, "F22", [F22, F23]>, DwarfRegNum<[54]>;
+  def D12 : AFPR<24, "F24", [F24, F25]>, DwarfRegNum<[56]>;
+  def D13 : AFPR<26, "F26", [F26, F27]>, DwarfRegNum<[58]>;
+  def D14 : AFPR<28, "F28", [F28, F29]>, DwarfRegNum<[60]>;
+  def D15 : AFPR<30, "F30", [F30, F31]>, DwarfRegNum<[62]>;
+
+  // Status flags register
+  def FCR31 : Register<"FCR31">;
+}
+
+//===----------------------------------------------------------------------===//
+// Register Classes
+//===----------------------------------------------------------------------===//
 
-// CPU Registers Class
 def CPURegs : RegisterClass<"Mips", [i32], 32, 
   // Return Values and Arguments
   [V0, V1, A0, A1, A2, A3,
@@ -83,51 +156,14 @@
   }];
 }
 
-//===----------------------------------------------------------------------===//
-//  Floating Point Unit Registers (Single Precision)
-//===----------------------------------------------------------------------===//
-
-/// Mips Single point precision FPU Register Format
-class MipsFPUReg<bits<5> num, string n> : MipsReg<n> {
-  let Num = num;
-}
-
-/// Mips Single point precision FPU Registers
-def F0  : MipsFPUReg< 0,  "F0">, DwarfRegNum<[32]>;
-def F1  : MipsFPUReg< 1,  "F1">, DwarfRegNum<[33]>;
-def F2  : MipsFPUReg< 2,  "F2">, DwarfRegNum<[34]>;
-def F3  : MipsFPUReg< 3,  "F3">, DwarfRegNum<[35]>;
-def F4  : MipsFPUReg< 4,  "F4">, DwarfRegNum<[36]>;
-def F5  : MipsFPUReg< 5,  "F5">, DwarfRegNum<[37]>;
-def F6  : MipsFPUReg< 6,  "F6">, DwarfRegNum<[38]>;
-def F7  : MipsFPUReg< 7,  "F7">, DwarfRegNum<[39]>;
-def F8  : MipsFPUReg< 8,  "F8">, DwarfRegNum<[40]>;
-def F9  : MipsFPUReg< 9,  "F9">, DwarfRegNum<[41]>;
-def F10 : MipsFPUReg<10, "F10">, DwarfRegNum<[42]>;
-def F11 : MipsFPUReg<11, "F11">, DwarfRegNum<[43]>;
-def F12 : MipsFPUReg<12, "F12">, DwarfRegNum<[44]>;
-def F13 : MipsFPUReg<13, "F13">, DwarfRegNum<[45]>;
-def F14 : MipsFPUReg<14, "F14">, DwarfRegNum<[46]>;
-def F15 : MipsFPUReg<15, "F15">, DwarfRegNum<[47]>;
-def F16 : MipsFPUReg<16, "F16">, DwarfRegNum<[48]>;
-def F17 : MipsFPUReg<17, "F17">, DwarfRegNum<[49]>;
-def F18 : MipsFPUReg<18, "F18">, DwarfRegNum<[50]>;
-def F19 : MipsFPUReg<19, "F19">, DwarfRegNum<[51]>;
-def F20 : MipsFPUReg<20, "F20">, DwarfRegNum<[52]>;
-def F21 : MipsFPUReg<21, "F21">, DwarfRegNum<[53]>;
-def F22 : MipsFPUReg<22, "F22">, DwarfRegNum<[54]>;
-def F23 : MipsFPUReg<23, "F23">, DwarfRegNum<[55]>;
-def F24 : MipsFPUReg<24, "F24">, DwarfRegNum<[56]>;
-def F25 : MipsFPUReg<25, "F25">, DwarfRegNum<[57]>;
-def F26 : MipsFPUReg<26, "F26">, DwarfRegNum<[58]>;
-def F27 : MipsFPUReg<27, "F27">, DwarfRegNum<[59]>;
-def F28 : MipsFPUReg<28, "F28">, DwarfRegNum<[60]>;
-def F29 : MipsFPUReg<29, "F29">, DwarfRegNum<[61]>;
-def F30 : MipsFPUReg<30, "F30">, DwarfRegNum<[62]>;
-def F31 : MipsFPUReg<31, "F31">, DwarfRegNum<[63]>;
-
-/// FPU Single Point Precision Registers Class
-def FPUDRegs : RegisterClass<"Mips", [f32], 32, 
+// * 64bit fp:
+//    - FGR64 = 32 64-bit registers (default mode)
+//    - AFGR32/AFGR64 = 16 even 32-bit registers (32-bit compatible mode) for
+//      single and double access.
+// * 32bit fp:
+//    - AFGR32/AFGR64 = 16 even 32-bit registers - single and double
+//    - FGR32 = 32 32-bit registers (within single-only mode)
+def FGR32 : RegisterClass<"Mips", [f32], 32, 
   // Return Values and Arguments
   [F0, F1, F2, F3, F12, F13, F14, F15,
   // Not preserved across procedure calls
@@ -141,45 +177,37 @@
     iterator allocation_order_end(const MachineFunction &MF) const;
   }];
   let MethodBodies = [{
-    FPUDRegsClass::iterator
-    FPUDRegsClass::allocation_order_end(const MachineFunction &MF) const {
+    FGR32Class::iterator
+    FGR32Class::allocation_order_end(const MachineFunction &MF) const {
       // The last register on the list above is reserved
       return end()-1;
     }
   }];
 }
 
-//===----------------------------------------------------------------------===//
-//  Floating Point Unit Registers (Double Precision)
-//===----------------------------------------------------------------------===//
-
-/// Mips Double point precision FPU Register Format
-class MipsFPUDReg<bits<5> num, string n, list<Register> aliases> : MipsReg<n> {
-  let Num = num;
-  let Aliases = aliases;
+def AFGR32 : RegisterClass<"Mips", [f32], 32, 
+  // Return Values and Arguments
+  [F0, F2, F12, F14, 
+  // Not preserved across procedure calls
+  F4, F6, F8, F10, F16, F18, 
+  // Callee save
+  F20, F22, F24, F26, F28, F30,
+  // Reserved
+  F31]>
+{
+  let MethodProtos = [{
+    iterator allocation_order_end(const MachineFunction &MF) const;
+  }];
+  let MethodBodies = [{
+    AFGR32Class::iterator
+    AFGR32Class::allocation_order_end(const MachineFunction &MF) const {
+      // The last register on the list above is reserved
+      return end()-1;
+    }
+  }];
 }
 
-/// Mips Double point precision FPU Registers (aliased
-/// with the single precision to hold 64 bit values)
-def D0  : MipsFPUDReg< 0,  "F0", [F0,   F1]>, DwarfRegNum<[32]>;
-def D1  : MipsFPUDReg< 2,  "F2", [F2,   F3]>, DwarfRegNum<[34]>;
-def D2  : MipsFPUDReg< 4,  "F4", [F4,   F5]>, DwarfRegNum<[36]>;
-def D3  : MipsFPUDReg< 6,  "F6", [F6,   F7]>, DwarfRegNum<[38]>;
-def D4  : MipsFPUDReg< 8,  "F8", [F8,   F9]>, DwarfRegNum<[40]>;
-def D5  : MipsFPUDReg<10, "F10", [F10, F11]>, DwarfRegNum<[42]>;
-def D6  : MipsFPUDReg<12, "F12", [F12, F13]>, DwarfRegNum<[44]>;
-def D7  : MipsFPUDReg<14, "F14", [F14, F15]>, DwarfRegNum<[46]>;
-def D8  : MipsFPUDReg<16, "F16", [F16, F17]>, DwarfRegNum<[48]>;
-def D9  : MipsFPUDReg<18, "F18", [F18, F19]>, DwarfRegNum<[50]>;
-def D10 : MipsFPUDReg<20, "F20", [F20, F21]>, DwarfRegNum<[52]>;
-def D11 : MipsFPUDReg<22, "F22", [F22, F23]>, DwarfRegNum<[54]>;
-def D12 : MipsFPUDReg<24, "F24", [F24, F25]>, DwarfRegNum<[56]>;
-def D13 : MipsFPUDReg<26, "F26", [F26, F27]>, DwarfRegNum<[58]>;
-def D14 : MipsFPUDReg<28, "F28", [F28, F29]>, DwarfRegNum<[60]>;
-def D15 : MipsFPUDReg<30, "F30", [F30, F31]>, DwarfRegNum<[62]>;
-
-/// FPU Single Point Precision Registers Class
-def FPURegs : RegisterClass<"Mips", [f32], 32, 
+def AFGR64 : RegisterClass<"Mips", [f64], 64, 
   // Return Values and Arguments
   [D0, D1, D6, D7,
   // Not preserved across procedure calls
@@ -193,10 +221,15 @@
     iterator allocation_order_end(const MachineFunction &MF) const;
   }];
   let MethodBodies = [{
-    FPURegsClass::iterator
-    FPURegsClass::allocation_order_end(const MachineFunction &MF) const {
+    AFGR64Class::iterator
+    AFGR64Class::allocation_order_end(const MachineFunction &MF) const {
       // The last register on the list above is reserved
       return end()-1;
     }
   }];
 }
+
+def CCR : RegisterClass<"Mips", [i32], 32, [FCR31]> {
+  let CopyCost = -1;  // Don't allow copying of status registers.
+}
+

Modified: llvm/trunk/lib/Target/Mips/MipsSubtarget.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsSubtarget.cpp?rev=53146&r1=53145&r2=53146&view=diff

==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsSubtarget.cpp (original)
+++ llvm/trunk/lib/Target/Mips/MipsSubtarget.cpp Sat Jul  5 14:05:21 2008
@@ -14,15 +14,29 @@
 #include "MipsSubtarget.h"
 #include "Mips.h"
 #include "MipsGenSubtarget.inc"
+#include "llvm/Module.h"
 using namespace llvm;
 
 MipsSubtarget::MipsSubtarget(const TargetMachine &TM, const Module &M, 
                              const std::string &FS, bool little) : 
-  IsMipsIII(false),
-  IsLittle(little)
+  MipsArchVersion(Mips1), MipsABI(O32), IsLittle(little), IsSingleFloat(false),
+  IsFP64bit(false), IsGP64bit(false), HasAllegrexVFPU(false), IsAllegrex(false)
 {
   std::string CPU = "mips1";
 
   // Parse features string.
   ParseSubtargetFeatures(FS, CPU);
+
+  // When only the target triple is specified and is 
+  // a allegrex target, set the features. We also match
+  // big and little endian allegrex cores (dont really
+  // know if a big one exists)
+  const std::string& TT = M.getTargetTriple();
+  if (TT.find("mipsallegrex") != std::string::npos) {
+    MipsABI = EABI;
+    IsSingleFloat = true;
+    MipsArchVersion = Mips2;
+    HasAllegrexVFPU = true; // Enables Allegrex Vector FPU (not supported yet)
+    IsAllegrex = true;
+  }
 }

Modified: llvm/trunk/lib/Target/Mips/MipsSubtarget.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsSubtarget.h?rev=53146&r1=53145&r2=53146&view=diff

==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsSubtarget.h (original)
+++ llvm/trunk/lib/Target/Mips/MipsSubtarget.h Sat Jul  5 14:05:21 2008
@@ -26,11 +26,48 @@
 
 protected:
 
-  bool IsMipsIII;
+  enum MipsArchEnum {
+    Mips1, Mips2, Mips3, Mips4, Mips32, Mips32r2
+  };
+
+  enum MipsABIEnum {
+    O32, EABI
+  }; 
+  
+  // Mips architecture version 
+  MipsArchEnum MipsArchVersion;
+
+  // Mips supported ABIs 
+  MipsABIEnum MipsABI;
+
+  // IsLittle - The target is Little Endian
   bool IsLittle;
+
+  // IsSingleFloat - The target only supports single precision float
+  // point operations. This enable the target to use all 32 32-bit
+  // float point registers instead of only using even ones.
+  bool IsSingleFloat;
+
+  // IsFP64bit - The target processor has 64-bit float point registers.
+  bool IsFP64bit;
+
+  // IsFP64bit - General-purpose registers are 64 bits wide
+  bool IsGP64bit;
+
+  // HasAllegrexVFPU - Allegrex processor has a vector float point unit.
+  bool HasAllegrexVFPU;
+
+  // IsAllegrex - The target processor is a Allegrex core.
+  bool IsAllegrex;
+
   InstrItineraryData InstrItins;
 
 public:
+
+  /// Only O32 and EABI supported right now.
+  bool isABI_EABI() const { return MipsABI == EABI; }
+  bool isABI_O32() const { return MipsABI == O32; }
+
   /// This constructor initializes the data members to match that
   /// of the specified module.
   MipsSubtarget(const TargetMachine &TM, const Module &M, 
@@ -40,12 +77,17 @@
   /// subtarget options.  Definition of function is auto generated by tblgen.
   void ParseSubtargetFeatures(const std::string &FS, const std::string &CPU);
 
-  /// isMipsIII - Return true if the selected CPU supports MipsIII ISA
-  /// support. 
-  bool isMipsIII() const { return IsMipsIII; }
+  bool hasMips2Ops() const { return MipsArchVersion >= Mips2; }
 
-  /// isMipsIII - Return true if the target is little endian. 
   bool isLittle() const { return IsLittle; }
+  bool isFP64bit() const { return IsFP64bit; };
+  bool isGP64bit() const { return IsGP64bit; };
+  bool isGP32bit() const { return !IsGP64bit; };
+  bool isSingleFloat() const { return IsSingleFloat; };
+  bool isNotSingleFloat() const { return !IsSingleFloat; };
+  bool hasAllegrexVFPU() const { return HasAllegrexVFPU; };
+  bool isAllegrex() const { return IsAllegrex; };
+
 };
 } // End llvm namespace
 

Modified: llvm/trunk/lib/Target/Mips/MipsTargetMachine.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsTargetMachine.cpp?rev=53146&r1=53145&r2=53146&view=diff

==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsTargetMachine.cpp (original)
+++ llvm/trunk/lib/Target/Mips/MipsTargetMachine.cpp Sat Jul  5 14:05:21 2008
@@ -34,8 +34,7 @@
 // On function prologue, the stack is created by decrementing
 // its pointer. Once decremented, all references are done with positive
 // offset from the stack/frame pointer, so StackGrowsUp is used.
-// When using CodeModel::Large the behaviour 
-//
+// Using CodeModel::Large enables different CALL behavior.
 MipsTargetMachine::
 MipsTargetMachine(const Module &M, const std::string &FS, bool isLittle=false):
   Subtarget(*this, M, FS, isLittle), 
@@ -59,22 +58,33 @@
 unsigned MipsTargetMachine::
 getModuleMatchQuality(const Module &M) 
 {
-  // We strongly match "mips-*".
+  // We strongly match "mips*-*".
   std::string TT = M.getTargetTriple();
   if (TT.size() >= 5 && std::string(TT.begin(), TT.begin()+5) == "mips-")
     return 20;
   
+  if (TT.size() >= 13 && std::string(TT.begin(), 
+      TT.begin()+13) == "mipsallegrex-")
+    return 20;
+
   return 0;
 }
 
-// return 0 and must specify -march to gen MIPSel code.
+// return 0 and must specify -march to gen MIPSEL code.
 unsigned MipselTargetMachine::
 getModuleMatchQuality(const Module &M) 
 {
-  // We strongly match "mipsel-*".
+  // We strongly match "mips*el-*".
   std::string TT = M.getTargetTriple();
   if (TT.size() >= 7 && std::string(TT.begin(), TT.begin()+7) == "mipsel-")
     return 20;
+
+  if (TT.size() >= 15 && std::string(TT.begin(), 
+      TT.begin()+15) == "mipsallegrexel-")
+    return 20;
+
+  if (TT.size() == 3 && std::string(TT.begin(), TT.begin()+3) == "psp")
+    return 20;
   
   return 0;
 }





More information about the llvm-commits mailing list