Add frameindex support
authorChris Lattner <sabre@nondot.org>
Sun, 18 Dec 2005 06:59:57 +0000 (06:59 +0000)
committerChris Lattner <sabre@nondot.org>
Sun, 18 Dec 2005 06:59:57 +0000 (06:59 +0000)
Add support for copying (e.g. returning) doubles
Add support for F<->I instructions

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@24818 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/Sparc/SparcISelDAGToDAG.cpp
lib/Target/Sparc/SparcInstrInfo.td
lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp
lib/Target/SparcV8/SparcV8InstrInfo.td

index 860c76fdb14b801c649d93a5c472f5d2beb46f78..751a8e2b1aca1e699acaf9bb768629ee961ec70a 100644 (file)
@@ -14,6 +14,7 @@
 #include "SparcV8.h"
 #include "SparcV8TargetMachine.h"
 #include "llvm/Function.h"
+#include "llvm/CodeGen/MachineFrameInfo.h"
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/SelectionDAG.h"
 #include "llvm/CodeGen/SelectionDAGISel.h"
@@ -36,6 +37,9 @@ namespace V8ISD {
     BRFCC,    // Branch to dest on fcc condition
     
     Hi, Lo,   // Hi/Lo operations, typically on a global address.
+    
+    FTOI,     // FP to Int within a FP register.
+    ITOF,     // Int to FP within a FP register.
   };
 }
 
@@ -85,6 +89,14 @@ SparcV8TargetLowering::SparcV8TargetLowering(TargetMachine &TM)
   // Sparc has no REM operation.
   setOperationAction(ISD::UREM, MVT::i32, Expand);
   setOperationAction(ISD::SREM, MVT::i32, Expand);
+
+  // Custom expand fp<->sint
+  setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom);
+  setOperationAction(ISD::SINT_TO_FP, MVT::i32, Custom);
+
+  // Expand fp<->uint
+  setOperationAction(ISD::FP_TO_UINT, MVT::i32, Expand);
+  setOperationAction(ISD::UINT_TO_FP, MVT::i32, Expand);
   
   // Sparc has no select or setcc: expand to SELECT_CC.
   setOperationAction(ISD::SELECT, MVT::i32, Expand);
@@ -259,6 +271,31 @@ LowerOperation(SDOperand Op, SelectionDAG &DAG) {
     SDOperand Lo = DAG.getNode(V8ISD::Lo, MVT::i32, CP);
     return DAG.getNode(ISD::ADD, MVT::i32, Lo, Hi);
   }
+  case ISD::FP_TO_SINT: {
+    // Convert the fp value to integer in an FP register.
+    Op = DAG.getNode(V8ISD::FTOI, Op.getOperand(0).getValueType(),
+                     Op.getOperand(0));
+    int Size = Op.getOperand(0).getValueType() == MVT::f32 ? 4 : 8;
+    int FrameIdx =
+      DAG.getMachineFunction().getFrameInfo()->CreateStackObject(Size, Size);
+    SDOperand FI = DAG.getFrameIndex(FrameIdx, MVT::i32);
+    SDOperand ST = DAG.getNode(ISD::STORE, MVT::Other, DAG.getEntryNode(),
+                               Op, FI, DAG.getSrcValue(0));
+    return DAG.getLoad(MVT::i32, ST, FI, DAG.getSrcValue(0));
+  }
+  case ISD::SINT_TO_FP: {
+    int Size = Op.getOperand(0).getValueType() == MVT::f32 ? 4 : 8;
+    int FrameIdx =
+      DAG.getMachineFunction().getFrameInfo()->CreateStackObject(Size, Size);
+    SDOperand FI = DAG.getFrameIndex(FrameIdx, MVT::i32);
+    SDOperand ST = DAG.getNode(ISD::STORE, MVT::Other, DAG.getEntryNode(),
+                               Op.getOperand(0), FI, DAG.getSrcValue(0));
+    
+    Op = DAG.getLoad(Op.getValueType(), ST, FI, DAG.getSrcValue(0));
+    
+    // Convert the int value to FP in an FP register.
+    return DAG.getNode(V8ISD::ITOF, Op.getValueType(), Op);
+  }
   }  
 }
 
@@ -311,34 +348,29 @@ void SparcV8DAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) {
   ScheduleAndEmitDAG(DAG);
 }
 
-bool SparcV8DAGToDAGISel::SelectADDRrr(SDOperand Addr, SDOperand &R1, 
-                                       SDOperand &R2) {
-  if (Addr.getOpcode() == ISD::ADD) {
-    if (isa<ConstantSDNode>(Addr.getOperand(1)) &&
-        Predicate_simm13(Addr.getOperand(1).Val))
-      return false;  // Let the reg+imm pattern catch this!
-    if (Addr.getOperand(0).getOpcode() == V8ISD::Lo ||
-        Addr.getOperand(1).getOpcode() == V8ISD::Lo)
-      return false;  // Let the reg+imm pattern catch this!
-    R1 = Select(Addr.getOperand(0));
-    R2 = Select(Addr.getOperand(1));
-    return true;
-  }
-
-  R1 = Select(Addr);
-  R2 = CurDAG->getRegister(V8::G0, MVT::i32);
-  return true;
-}
-
 bool SparcV8DAGToDAGISel::SelectADDRri(SDOperand Addr, SDOperand &Base,
                                        SDOperand &Offset) {
+  if (Addr.getOpcode() == ISD::FrameIndex) {
+    int FI = cast<FrameIndexSDNode>(Addr)->getIndex();
+    Base = CurDAG->getTargetFrameIndex(FI, MVT::i32);
+    Offset = CurDAG->getTargetConstant(0, MVT::i32);
+    return true;
+  }
+  
   if (Addr.getOpcode() == ISD::ADD) {
-    if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1)))
+    if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) {
       if (Predicate_simm13(CN)) {
-        Base = Select(Addr.getOperand(0));
+        if (Addr.getOperand(0).getOpcode() == ISD::FrameIndex) {
+          // Constant offset from frame ref.
+          int FI = cast<FrameIndexSDNode>(Addr)->getIndex();
+          Base = CurDAG->getTargetFrameIndex(FI, MVT::i32);
+        } else {
+          Base = Select(Addr.getOperand(0));
+        }
         Offset = CurDAG->getTargetConstant(CN->getValue(), MVT::i32);
         return true;
       }
+    }
     if (Addr.getOperand(0).getOpcode() == V8ISD::Lo) {
       Base = Select(Addr.getOperand(1));
       Offset = Addr.getOperand(0).getOperand(0);
@@ -355,6 +387,25 @@ bool SparcV8DAGToDAGISel::SelectADDRri(SDOperand Addr, SDOperand &Base,
   return true;
 }
 
+bool SparcV8DAGToDAGISel::SelectADDRrr(SDOperand Addr, SDOperand &R1, 
+                                       SDOperand &R2) {
+  if (Addr.getOpcode() == ISD::FrameIndex) return false; 
+  if (Addr.getOpcode() == ISD::ADD) {
+    if (isa<ConstantSDNode>(Addr.getOperand(1)) &&
+        Predicate_simm13(Addr.getOperand(1).Val))
+      return false;  // Let the reg+imm pattern catch this!
+    if (Addr.getOperand(0).getOpcode() == V8ISD::Lo ||
+        Addr.getOperand(1).getOpcode() == V8ISD::Lo)
+      return false;  // Let the reg+imm pattern catch this!
+    R1 = Select(Addr.getOperand(0));
+    R2 = Select(Addr.getOperand(1));
+    return true;
+  }
+
+  R1 = Select(Addr);
+  R2 = CurDAG->getRegister(V8::G0, MVT::i32);
+  return true;
+}
 
 SDOperand SparcV8DAGToDAGISel::Select(SDOperand Op) {
   SDNode *N = Op.Val;
@@ -368,6 +419,17 @@ SDOperand SparcV8DAGToDAGISel::Select(SDOperand Op) {
   switch (N->getOpcode()) {
   default: break;
   case ISD::BasicBlock:         return CodeGenMap[Op] = Op;
+  case ISD::FrameIndex: {
+    int FI = cast<FrameIndexSDNode>(N)->getIndex();
+    if (N->hasOneUse())
+      return CurDAG->SelectNodeTo(N, V8::ADDri, MVT::i32,
+                                  CurDAG->getTargetFrameIndex(FI, MVT::i32),
+                                  CurDAG->getTargetConstant(0, MVT::i32));
+    return CodeGenMap[Op] = 
+      CurDAG->getTargetNode(V8::ADDri, MVT::i32,
+                            CurDAG->getTargetFrameIndex(FI, MVT::i32),
+                            CurDAG->getTargetConstant(0, MVT::i32));
+  }
   case V8ISD::CMPICC: {
     // FIXME: Handle compare with immediate.
     SDOperand LHS = Select(N->getOperand(0));
index 22ed2417df59e8e2ffea65cf0deeed7f041ee911..fabd23555c7480df5b000c9b898743c99710a8d0 100644 (file)
@@ -87,6 +87,9 @@ def V8brfcc : SDNode<"V8ISD::BRFCC", SDTV8brcc, [SDNPHasChain]>;
 def V8hi    : SDNode<"V8ISD::Hi", SDTIntUnaryOp>;
 def V8lo    : SDNode<"V8ISD::Lo", SDTIntUnaryOp>;
 
+def V8ftoi  : SDNode<"V8ISD::FTOI", SDTFPUnaryOp>;
+def V8itof  : SDNode<"V8ISD::ITOF", SDTFPUnaryOp>;
+
 //===----------------------------------------------------------------------===//
 // Instructions
 //===----------------------------------------------------------------------===//
@@ -104,7 +107,8 @@ def ADJCALLSTACKUP : PseudoInstV8<"!ADJCALLSTACKUP $amt",
 //def IMPLICIT_USE : PseudoInstV8<"!IMPLICIT_USE",(ops variable_ops)>;
 def IMPLICIT_DEF : PseudoInstV8<"!IMPLICIT_DEF $dst", 
                                 (ops IntRegs:$dst)>;
-def FpMOVD : PseudoInstV8<"!FpMOVD", (ops)>; // pseudo 64-bit double move
+def FpMOVD : PseudoInstV8<"!FpMOVD",       // pseudo 64-bit double move
+                          (ops DFPRegs:$dst, DFPRegs:$src)>;
 
 // Section A.3 - Synthetic Instructions, p. 85
 // special cases of JMPL:
@@ -544,18 +548,22 @@ def WRYri : F3_2<2, 0b110000,
 // Convert Integer to Floating-point Instructions, p. 141
 def FITOS : F3_3<2, 0b110100, 0b011000100,
                  (ops FPRegs:$dst, FPRegs:$src),
-                 "fitos $src, $dst", []>;
+                 "fitos $src, $dst",
+                 [(set FPRegs:$dst, (V8itof FPRegs:$src))]>;
 def FITOD : F3_3<2, 0b110100, 0b011001000, 
                  (ops DFPRegs:$dst, DFPRegs:$src),
-                 "fitod $src, $dst", []>;
+                 "fitod $src, $dst",
+                 [(set DFPRegs:$dst, (V8itof DFPRegs:$src))]>;
 
 // Convert Floating-point to Integer Instructions, p. 142
 def FSTOI : F3_3<2, 0b110100, 0b011010001,
                  (ops FPRegs:$dst, FPRegs:$src),
-                 "fstoi $src, $dst", []>;
+                 "fstoi $src, $dst",
+                 [(set FPRegs:$dst, (V8ftoi FPRegs:$src))]>;
 def FDTOI : F3_3<2, 0b110100, 0b011010010,
                  (ops DFPRegs:$dst, DFPRegs:$src),
-                 "fdtoi $src, $dst", []>;
+                 "fdtoi $src, $dst",
+                 [(set DFPRegs:$dst, (V8ftoi DFPRegs:$src))]>;
 
 // Convert between Floating-point Formats Instructions, p. 143
 def FSTOD : F3_3<2, 0b110100, 0b011001001, 
index 860c76fdb14b801c649d93a5c472f5d2beb46f78..751a8e2b1aca1e699acaf9bb768629ee961ec70a 100644 (file)
@@ -14,6 +14,7 @@
 #include "SparcV8.h"
 #include "SparcV8TargetMachine.h"
 #include "llvm/Function.h"
+#include "llvm/CodeGen/MachineFrameInfo.h"
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/SelectionDAG.h"
 #include "llvm/CodeGen/SelectionDAGISel.h"
@@ -36,6 +37,9 @@ namespace V8ISD {
     BRFCC,    // Branch to dest on fcc condition
     
     Hi, Lo,   // Hi/Lo operations, typically on a global address.
+    
+    FTOI,     // FP to Int within a FP register.
+    ITOF,     // Int to FP within a FP register.
   };
 }
 
@@ -85,6 +89,14 @@ SparcV8TargetLowering::SparcV8TargetLowering(TargetMachine &TM)
   // Sparc has no REM operation.
   setOperationAction(ISD::UREM, MVT::i32, Expand);
   setOperationAction(ISD::SREM, MVT::i32, Expand);
+
+  // Custom expand fp<->sint
+  setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom);
+  setOperationAction(ISD::SINT_TO_FP, MVT::i32, Custom);
+
+  // Expand fp<->uint
+  setOperationAction(ISD::FP_TO_UINT, MVT::i32, Expand);
+  setOperationAction(ISD::UINT_TO_FP, MVT::i32, Expand);
   
   // Sparc has no select or setcc: expand to SELECT_CC.
   setOperationAction(ISD::SELECT, MVT::i32, Expand);
@@ -259,6 +271,31 @@ LowerOperation(SDOperand Op, SelectionDAG &DAG) {
     SDOperand Lo = DAG.getNode(V8ISD::Lo, MVT::i32, CP);
     return DAG.getNode(ISD::ADD, MVT::i32, Lo, Hi);
   }
+  case ISD::FP_TO_SINT: {
+    // Convert the fp value to integer in an FP register.
+    Op = DAG.getNode(V8ISD::FTOI, Op.getOperand(0).getValueType(),
+                     Op.getOperand(0));
+    int Size = Op.getOperand(0).getValueType() == MVT::f32 ? 4 : 8;
+    int FrameIdx =
+      DAG.getMachineFunction().getFrameInfo()->CreateStackObject(Size, Size);
+    SDOperand FI = DAG.getFrameIndex(FrameIdx, MVT::i32);
+    SDOperand ST = DAG.getNode(ISD::STORE, MVT::Other, DAG.getEntryNode(),
+                               Op, FI, DAG.getSrcValue(0));
+    return DAG.getLoad(MVT::i32, ST, FI, DAG.getSrcValue(0));
+  }
+  case ISD::SINT_TO_FP: {
+    int Size = Op.getOperand(0).getValueType() == MVT::f32 ? 4 : 8;
+    int FrameIdx =
+      DAG.getMachineFunction().getFrameInfo()->CreateStackObject(Size, Size);
+    SDOperand FI = DAG.getFrameIndex(FrameIdx, MVT::i32);
+    SDOperand ST = DAG.getNode(ISD::STORE, MVT::Other, DAG.getEntryNode(),
+                               Op.getOperand(0), FI, DAG.getSrcValue(0));
+    
+    Op = DAG.getLoad(Op.getValueType(), ST, FI, DAG.getSrcValue(0));
+    
+    // Convert the int value to FP in an FP register.
+    return DAG.getNode(V8ISD::ITOF, Op.getValueType(), Op);
+  }
   }  
 }
 
@@ -311,34 +348,29 @@ void SparcV8DAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) {
   ScheduleAndEmitDAG(DAG);
 }
 
-bool SparcV8DAGToDAGISel::SelectADDRrr(SDOperand Addr, SDOperand &R1, 
-                                       SDOperand &R2) {
-  if (Addr.getOpcode() == ISD::ADD) {
-    if (isa<ConstantSDNode>(Addr.getOperand(1)) &&
-        Predicate_simm13(Addr.getOperand(1).Val))
-      return false;  // Let the reg+imm pattern catch this!
-    if (Addr.getOperand(0).getOpcode() == V8ISD::Lo ||
-        Addr.getOperand(1).getOpcode() == V8ISD::Lo)
-      return false;  // Let the reg+imm pattern catch this!
-    R1 = Select(Addr.getOperand(0));
-    R2 = Select(Addr.getOperand(1));
-    return true;
-  }
-
-  R1 = Select(Addr);
-  R2 = CurDAG->getRegister(V8::G0, MVT::i32);
-  return true;
-}
-
 bool SparcV8DAGToDAGISel::SelectADDRri(SDOperand Addr, SDOperand &Base,
                                        SDOperand &Offset) {
+  if (Addr.getOpcode() == ISD::FrameIndex) {
+    int FI = cast<FrameIndexSDNode>(Addr)->getIndex();
+    Base = CurDAG->getTargetFrameIndex(FI, MVT::i32);
+    Offset = CurDAG->getTargetConstant(0, MVT::i32);
+    return true;
+  }
+  
   if (Addr.getOpcode() == ISD::ADD) {
-    if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1)))
+    if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) {
       if (Predicate_simm13(CN)) {
-        Base = Select(Addr.getOperand(0));
+        if (Addr.getOperand(0).getOpcode() == ISD::FrameIndex) {
+          // Constant offset from frame ref.
+          int FI = cast<FrameIndexSDNode>(Addr)->getIndex();
+          Base = CurDAG->getTargetFrameIndex(FI, MVT::i32);
+        } else {
+          Base = Select(Addr.getOperand(0));
+        }
         Offset = CurDAG->getTargetConstant(CN->getValue(), MVT::i32);
         return true;
       }
+    }
     if (Addr.getOperand(0).getOpcode() == V8ISD::Lo) {
       Base = Select(Addr.getOperand(1));
       Offset = Addr.getOperand(0).getOperand(0);
@@ -355,6 +387,25 @@ bool SparcV8DAGToDAGISel::SelectADDRri(SDOperand Addr, SDOperand &Base,
   return true;
 }
 
+bool SparcV8DAGToDAGISel::SelectADDRrr(SDOperand Addr, SDOperand &R1, 
+                                       SDOperand &R2) {
+  if (Addr.getOpcode() == ISD::FrameIndex) return false; 
+  if (Addr.getOpcode() == ISD::ADD) {
+    if (isa<ConstantSDNode>(Addr.getOperand(1)) &&
+        Predicate_simm13(Addr.getOperand(1).Val))
+      return false;  // Let the reg+imm pattern catch this!
+    if (Addr.getOperand(0).getOpcode() == V8ISD::Lo ||
+        Addr.getOperand(1).getOpcode() == V8ISD::Lo)
+      return false;  // Let the reg+imm pattern catch this!
+    R1 = Select(Addr.getOperand(0));
+    R2 = Select(Addr.getOperand(1));
+    return true;
+  }
+
+  R1 = Select(Addr);
+  R2 = CurDAG->getRegister(V8::G0, MVT::i32);
+  return true;
+}
 
 SDOperand SparcV8DAGToDAGISel::Select(SDOperand Op) {
   SDNode *N = Op.Val;
@@ -368,6 +419,17 @@ SDOperand SparcV8DAGToDAGISel::Select(SDOperand Op) {
   switch (N->getOpcode()) {
   default: break;
   case ISD::BasicBlock:         return CodeGenMap[Op] = Op;
+  case ISD::FrameIndex: {
+    int FI = cast<FrameIndexSDNode>(N)->getIndex();
+    if (N->hasOneUse())
+      return CurDAG->SelectNodeTo(N, V8::ADDri, MVT::i32,
+                                  CurDAG->getTargetFrameIndex(FI, MVT::i32),
+                                  CurDAG->getTargetConstant(0, MVT::i32));
+    return CodeGenMap[Op] = 
+      CurDAG->getTargetNode(V8::ADDri, MVT::i32,
+                            CurDAG->getTargetFrameIndex(FI, MVT::i32),
+                            CurDAG->getTargetConstant(0, MVT::i32));
+  }
   case V8ISD::CMPICC: {
     // FIXME: Handle compare with immediate.
     SDOperand LHS = Select(N->getOperand(0));
index 22ed2417df59e8e2ffea65cf0deeed7f041ee911..fabd23555c7480df5b000c9b898743c99710a8d0 100644 (file)
@@ -87,6 +87,9 @@ def V8brfcc : SDNode<"V8ISD::BRFCC", SDTV8brcc, [SDNPHasChain]>;
 def V8hi    : SDNode<"V8ISD::Hi", SDTIntUnaryOp>;
 def V8lo    : SDNode<"V8ISD::Lo", SDTIntUnaryOp>;
 
+def V8ftoi  : SDNode<"V8ISD::FTOI", SDTFPUnaryOp>;
+def V8itof  : SDNode<"V8ISD::ITOF", SDTFPUnaryOp>;
+
 //===----------------------------------------------------------------------===//
 // Instructions
 //===----------------------------------------------------------------------===//
@@ -104,7 +107,8 @@ def ADJCALLSTACKUP : PseudoInstV8<"!ADJCALLSTACKUP $amt",
 //def IMPLICIT_USE : PseudoInstV8<"!IMPLICIT_USE",(ops variable_ops)>;
 def IMPLICIT_DEF : PseudoInstV8<"!IMPLICIT_DEF $dst", 
                                 (ops IntRegs:$dst)>;
-def FpMOVD : PseudoInstV8<"!FpMOVD", (ops)>; // pseudo 64-bit double move
+def FpMOVD : PseudoInstV8<"!FpMOVD",       // pseudo 64-bit double move
+                          (ops DFPRegs:$dst, DFPRegs:$src)>;
 
 // Section A.3 - Synthetic Instructions, p. 85
 // special cases of JMPL:
@@ -544,18 +548,22 @@ def WRYri : F3_2<2, 0b110000,
 // Convert Integer to Floating-point Instructions, p. 141
 def FITOS : F3_3<2, 0b110100, 0b011000100,
                  (ops FPRegs:$dst, FPRegs:$src),
-                 "fitos $src, $dst", []>;
+                 "fitos $src, $dst",
+                 [(set FPRegs:$dst, (V8itof FPRegs:$src))]>;
 def FITOD : F3_3<2, 0b110100, 0b011001000, 
                  (ops DFPRegs:$dst, DFPRegs:$src),
-                 "fitod $src, $dst", []>;
+                 "fitod $src, $dst",
+                 [(set DFPRegs:$dst, (V8itof DFPRegs:$src))]>;
 
 // Convert Floating-point to Integer Instructions, p. 142
 def FSTOI : F3_3<2, 0b110100, 0b011010001,
                  (ops FPRegs:$dst, FPRegs:$src),
-                 "fstoi $src, $dst", []>;
+                 "fstoi $src, $dst",
+                 [(set FPRegs:$dst, (V8ftoi FPRegs:$src))]>;
 def FDTOI : F3_3<2, 0b110100, 0b011010010,
                  (ops DFPRegs:$dst, DFPRegs:$src),
-                 "fdtoi $src, $dst", []>;
+                 "fdtoi $src, $dst",
+                 [(set DFPRegs:$dst, (V8ftoi DFPRegs:$src))]>;
 
 // Convert between Floating-point Formats Instructions, p. 143
 def FSTOD : F3_3<2, 0b110100, 0b011001001,