All sorts of stuff.
authorAndrew Lenharth <andrewl@lenharth.org>
Wed, 30 Nov 2005 07:19:56 +0000 (07:19 +0000)
committerAndrew Lenharth <andrewl@lenharth.org>
Wed, 30 Nov 2005 07:19:56 +0000 (07:19 +0000)
Getting in on the custom lowering thing, yay
evilness with fp setcc, yuck
trivial int select, hmmm
in memory args for functions, yay
DIV and REM, always handy.  They should be custom lowered though.

Lots more stuff compiles now (go go single source!).  Of course, none of it
probably works, but that is what the nightly tester can find out :)

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

lib/Target/Alpha/AlphaISelDAGToDAG.cpp
lib/Target/Alpha/AlphaISelLowering.cpp
lib/Target/Alpha/AlphaISelLowering.h
lib/Target/Alpha/AlphaISelPattern.cpp
lib/Target/Alpha/AlphaInstrFormats.td
lib/Target/Alpha/AlphaInstrInfo.td
lib/Target/Alpha/AlphaRegisterInfo.td

index b920bc4d8cc69d65646b4cd028b417335b2dc5dc..50ff1b09d01b4968a3717fd9c0cdbcd99ad8cd6c 100644 (file)
@@ -16,6 +16,7 @@
 #include "AlphaTargetMachine.h"
 #include "AlphaISelLowering.h"
 #include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineFrameInfo.h"
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/SSARegMap.h"
 #include "llvm/CodeGen/SelectionDAG.h"
@@ -278,6 +279,7 @@ SDOperand AlphaDAGToDAGISel::Select(SDOperand Op) {
       CurDAG->SelectNodeTo(N, Alpha::LDAr, MVT::i64, CPI, Tmp);
       return SDOperand(N, 0);
     }
+    break;
   }
   case ISD::ConstantFP:
     if (ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(N)) {
@@ -296,7 +298,76 @@ SDOperand AlphaDAGToDAGISel::Select(SDOperand Op) {
       } else {
         abort();
       }
+      break;
     }
+  case ISD::SDIV:
+  case ISD::UDIV:
+  case ISD::UREM:
+  case ISD::SREM:
+    if (MVT::isInteger(N->getValueType(0))) {
+      const char* opstr = 0;
+      switch(N->getOpcode()) {
+      case ISD::UREM: opstr = "__remqu"; break;
+      case ISD::SREM: opstr = "__remq";  break;
+      case ISD::UDIV: opstr = "__divqu"; break;
+      case ISD::SDIV: opstr = "__divq";  break;
+      }
+      SDOperand Tmp1 = Select(N->getOperand(0)),
+        Tmp2 = Select(N->getOperand(1)),
+        Addr = CurDAG->getExternalSymbol(opstr, AlphaLowering.getPointerTy());
+      SDOperand Tmp3 = Select(Addr);
+      SDOperand Chain = CurDAG->getCopyToReg(CurDAG->getRoot(), Alpha::R24, 
+                                             Tmp1, SDOperand());
+      Chain = CurDAG->getCopyToReg(CurDAG->getRoot(), Alpha::R25, 
+                                   Tmp2, Chain.getValue(1));
+      Chain = CurDAG->getCopyToReg(CurDAG->getRoot(), Alpha::R27, 
+                                   Tmp3, Chain.getValue(1));
+      Chain = CurDAG->getTargetNode(Alpha::JSRs, MVT::i64, MVT::Flag,
+                                    CurDAG->getRegister(Alpha::R27, MVT::i64),
+                                    getI64Imm(0));
+      return CurDAG->getCopyFromReg(Chain.getValue(1), Alpha::R27, MVT::i64, 
+                                    Chain.getValue(1));
+    }
+    break;
+
+  case ISD::SETCC:
+    if (MVT::isFloatingPoint(N->getOperand(0).Val->getValueType(0))) {
+      unsigned Opc = Alpha::WTF;
+      ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(2))->get();
+      bool rev = false;
+      switch(CC) {
+      default: N->dump(); assert(0 && "Unknown FP comparison!");
+      case ISD::SETEQ: Opc = Alpha::CMPTEQ; break;
+      case ISD::SETLT: Opc = Alpha::CMPTLT; break;
+      case ISD::SETLE: Opc = Alpha::CMPTLE; break;
+      case ISD::SETGT: Opc = Alpha::CMPTLT; rev = true; break;
+      case ISD::SETGE: Opc = Alpha::CMPTLE; rev = true; break;
+        //case ISD::SETNE: Opc = Alpha::CMPTEQ; inv = true; break;
+      };
+      SDOperand tmp1 = Select(N->getOperand(0)),
+        tmp2 = Select(N->getOperand(1));
+      SDOperand cmp = CurDAG->getTargetNode(Opc, MVT::f64, 
+                                            rev?tmp2:tmp1,
+                                            rev?tmp1:tmp2);
+      SDOperand LD;
+      if (AlphaLowering.hasITOF()) {
+        LD = CurDAG->getNode(AlphaISD::FTOIT_, MVT::i64, cmp);
+      } else {
+        int FrameIdx =
+          CurDAG->getMachineFunction().getFrameInfo()->CreateStackObject(8, 8);
+        SDOperand FI = CurDAG->getFrameIndex(FrameIdx, MVT::i64);
+        SDOperand ST = CurDAG->getTargetNode(Alpha::STT, MVT::Other, 
+                                             cmp, FI, CurDAG->getRegister(Alpha::R31, MVT::i64));
+        LD = CurDAG->getTargetNode(Alpha::LDQ, MVT::i64, FI, 
+                                   CurDAG->getRegister(Alpha::R31, MVT::i64),
+                                   ST);
+      }
+      SDOperand FP = CurDAG->getTargetNode(Alpha::CMPULT, MVT::i64, 
+                                           CurDAG->getRegister(Alpha::R31, MVT::i64),
+                                           LD);
+      return FP;
+    }
+    break;
   }
   
   return SelectCode(Op);
@@ -328,13 +399,26 @@ SDOperand AlphaDAGToDAGISel::SelectCALL(SDOperand Op) {
    for (int i = 0; i < std::min(6, count); ++i) {
      if (MVT::isInteger(TypeOperands[i])) {
        Chain = CurDAG->getCopyToReg(Chain, args_int[i], CallOperands[i]);
-     } else if (TypeOperands[i] == MVT::f64 || TypeOperands[i] == MVT::f64) {
+     } else if (TypeOperands[i] == MVT::f32 || TypeOperands[i] == MVT::f64) {
        Chain = CurDAG->getCopyToReg(Chain, args_float[i], CallOperands[i]);
      } else
        assert(0 && "Unknown operand"); 
    }
-
-   assert(CallOperands.size() <= 6 && "Too big a call");
+   for (int i = 6; i < count; ++i) {
+     unsigned Opc = Alpha::WTF;
+     if (MVT::isInteger(TypeOperands[i])) {
+       Opc = Alpha::STQ;
+     } else if (TypeOperands[i] == MVT::f32) {
+       Opc = Alpha::STS;
+     } else if (TypeOperands[i] == MVT::f64) {
+       Opc = Alpha::STT;
+     } else
+       assert(0 && "Unknown operand"); 
+     Chain = CurDAG->getTargetNode(Opc, MVT::Other, CallOperands[i], 
+                                   getI64Imm((i - 6) * 8), 
+                                   CurDAG->getRegister(Alpha::R30, MVT::i64),
+                                   Chain);
+   }
 
    Chain = CurDAG->getCopyToReg(Chain, Alpha::R27, Addr);
    // Finally, once everything is in registers to pass to the call, emit the
index 021c92db3c9a1a382d0f26752080fc705b961792..92ba16e21bf9d20c404195fc09fb5feba74ad922 100644 (file)
@@ -72,6 +72,7 @@ AlphaTargetLowering::AlphaTargetLowering(TargetMachine &TM) : TargetLowering(TM)
   setOperationAction(ISD::FREM, MVT::f64, Expand);
   
   setOperationAction(ISD::UINT_TO_FP, MVT::i64, Expand);
+  setOperationAction(ISD::SINT_TO_FP, MVT::i64, Custom);
   
   if (!TM.getSubtarget<AlphaSubtarget>().hasCT()) {
     setOperationAction(ISD::CTPOP    , MVT::i64  , Expand);
@@ -101,10 +102,12 @@ AlphaTargetLowering::AlphaTargetLowering(TargetMachine &TM) : TargetLowering(TM)
   // We don't have line number support yet.
   setOperationAction(ISD::LOCATION, MVT::Other, Expand);
   
-  computeRegisterProperties();
-  
   addLegalFPImmediate(+0.0); //F31
   addLegalFPImmediate(-0.0); //-F31
+
+  computeRegisterProperties();
+
+  useITOF = TM.getSubtarget<AlphaSubtarget>().hasF2I();
 }
 
 
@@ -385,3 +388,31 @@ void AlphaTargetLowering::restoreRA(MachineBasicBlock* BB)
 }
 
 
+/// LowerOperation - Provide custom lowering hooks for some operations.
+///
+SDOperand AlphaTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
+  switch (Op.getOpcode()) {
+  default: assert(0 && "Wasn't expecting to be able to lower this!"); 
+  case ISD::SINT_TO_FP: {
+    assert(MVT::i64 == Op.getOperand(0).getValueType() && 
+           "Unhandled SINT_TO_FP type in custom expander!");
+    SDOperand LD;
+    bool isDouble = MVT::f64 == Op.getValueType();
+    if (useITOF) {
+      LD = DAG.getNode(AlphaISD::ITOFT_, MVT::f64, Op.getOperand(0));
+    } else {
+      int FrameIdx =
+        DAG.getMachineFunction().getFrameInfo()->CreateStackObject(8, 8);
+      SDOperand FI = DAG.getFrameIndex(FrameIdx, MVT::i64);
+      SDOperand ST = DAG.getNode(ISD::STORE, MVT::Other, DAG.getEntryNode(),
+                                 Op.getOperand(0), FI, DAG.getSrcValue(0));
+      LD = DAG.getLoad(MVT::f64, ST, FI, DAG.getSrcValue(0));
+      }
+    SDOperand FP = DAG.getNode(isDouble?AlphaISD::CVTQT_:AlphaISD::CVTQS_,
+                               isDouble?MVT::f64:MVT::f32, LD);
+    return FP;
+  }
+  }
+  return SDOperand();
+}
+
index 2bcd526d8fde0edb12241a378bd48776af99752f..378ec0f92479029a2d38e302d4f4686165c9093a 100644 (file)
@@ -25,6 +25,8 @@ namespace llvm {
     enum NodeType {
       // Start the numbering where the builting ops and target ops leave off.
       FIRST_NUMBER = ISD::BUILTIN_OP_END+Alpha::INSTRUCTION_LIST_END,
+      //These corrospond to the identical Instruction
+      ITOFT_, FTOIT_, CVTQT_, CVTQS_,
     };
   }
 
@@ -33,9 +35,14 @@ namespace llvm {
     int VarArgsBase;    // What is the base FrameIndex
     unsigned GP; //GOT vreg
     unsigned RA; //Return Address
+    bool useITOF;
   public:
     AlphaTargetLowering(TargetMachine &TM);
-
+    
+    /// LowerOperation - Provide custom lowering hooks for some operations.
+    ///
+    virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG);
+    
     /// LowerArguments - This hook must be implemented to indicate how we should
     /// lower the arguments for the specified function, into the specified DAG.
     virtual std::vector<SDOperand>
@@ -61,6 +68,7 @@ namespace llvm {
     void restoreRA(MachineBasicBlock* BB);
     unsigned getVRegGP() { return GP; }
     unsigned getVRegRA() { return RA; }
+    bool hasITOF() { return useITOF; }
   };
 }
 
index 6c2e3a6f53d4ac63a4b4371cb9d49114bc6c7da2..05ed61f8cf5e803556a03cddc1938ee0c4c1f184 100644 (file)
@@ -1559,17 +1559,17 @@ unsigned AlphaISel::SelectExpr(SDOperand N) {
     }
     return Result;
 
-  case ISD::SINT_TO_FP:
-    {
-      assert (N.getOperand(0).getValueType() == MVT::i64
-              && "only quads can be loaded from");
-      Tmp1 = SelectExpr(N.getOperand(0));  // Get the operand register
-      Tmp2 = MakeReg(MVT::f64);
-      MoveInt2FP(Tmp1, Tmp2, true);
-      Opc = DestType == MVT::f64 ? Alpha::CVTQT : Alpha::CVTQS;
-      BuildMI(BB, Opc, 1, Result).addReg(Tmp2);
-      return Result;
-    }
+  case AlphaISD::CVTQT_:
+    BuildMI(BB, Alpha::CVTQT, 1, Result).addReg(SelectExpr(N.getOperand(0)));
+    return Result;
+
+  case AlphaISD::CVTQS_:
+    BuildMI(BB, Alpha::CVTQS, 1, Result).addReg(SelectExpr(N.getOperand(0)));
+    return Result;
+
+  case AlphaISD::ITOFT_:
+    BuildMI(BB, Alpha::ITOFT, 1, Result).addReg(SelectExpr(N.getOperand(0)));
+    return Result;
 
   case ISD::AssertSext:
   case ISD::AssertZext:
index 1f446072758619bd62a961b538802fb9e0973a3a..1d4c11d1d8226203baac3fc9436e51e95ca51b77 100644 (file)
@@ -40,6 +40,16 @@ class InstAlpha<bits<6> op, dag OL, string asmstr>
 }
 
 //3.3.1
+class MFormAlt<bits<6> opcode, string asmstr> 
+        : InstAlphaAlt<opcode, asmstr> {
+  bits<5> Ra;
+  bits<16> disp;
+  bits<5> Rb;
+
+  let Inst{25-21} = Ra;
+  let Inst{20-16} = Rb;
+  let Inst{15-0} = disp;
+}
 class MForm<bits<6> opcode, string asmstr> 
         : InstAlpha<opcode, (ops GPRC:$RA, s16imm:$DISP, GPRC:$RB), asmstr> {
   bits<5> Ra;
index aea28619947074284aee7413b656db09533498a4..6bd9d78d88a01cb77c0b08a082fd3e51de2f6d0d 100644 (file)
 
 include "AlphaInstrFormats.td"
 
+//********************
+//Custom DAG Nodes
+//********************
+
+def SDTFPUnaryOpUnC  : SDTypeProfile<1, 1, [
+  SDTCisFP<1>, SDTCisFP<0>
+]>;
+
+def Alpha_itoft : SDNode<"AlphaISD::ITOFT_", SDTIntToFPOp, []>;
+def Alpha_ftoit : SDNode<"AlphaISD::FTOIT_", SDTFPToIntOp, []>;
+def Alpha_cvtqt : SDNode<"AlphaISD::CVTQT_", SDTFPUnaryOpUnC, []>;
+def Alpha_cvtqs : SDNode<"AlphaISD::CVTQS_", SDTFPUnaryOpUnC, []>;
+
+
 //********************
 //Paterns for matching
 //********************
@@ -143,6 +157,10 @@ def CMOVLTi  : OForm4L< 0x11, 0x44, "cmovlt $RCOND,$L,$RDEST">; //CMOVE if RCOND
 def CMOVNE   : OForm4<  0x11, 0x26, "cmovne $RCOND,$RSRC,$RDEST">; //CMOVE if RCOND != zero
 def CMOVNEi  : OForm4L< 0x11, 0x26, "cmovne $RCOND,$L,$RDEST">; //CMOVE if RCOND != zero
 
+//FIXME: fold setcc with select
+def : Pat<(select GPRC:$which, GPRC:$src1, GPRC:$src2),
+      (CMOVEQ GPRC:$src1, GPRC:$src2, GPRC:$which)>;
+
 //conditional moves, fp
 let OperandList = (ops F8RC:$RDEST, F8RC:$RSRC2, F8RC:$RSRC, F8RC:$RCOND),
     isTwoAddress = 1 in {
@@ -409,12 +427,16 @@ def LDBU : MForm<0x0A, "ldbu $RA,$DISP($RB)">; //Load zero-extended byte
 def LDWU : MForm<0x0C, "ldwu $RA,$DISP($RB)">; //Load zero-extended word
 
 //Stores, float
-def STS : MForm<0x26, "sts $RA,$DISP($RB)">; //Store S_floating
-def STT : MForm<0x27, "stt $RA,$DISP($RB)">; //Store T_floating
+let OperandList = (ops F4RC:$RA, s16imm:$DISP, GPRC:$RB) in
+def STS : MFormAlt<0x26, "sts $RA,$DISP($RB)">; //Store S_floating
+let OperandList = (ops F8RC:$RA, s16imm:$DISP, GPRC:$RB) in
+def STT : MFormAlt<0x27, "stt $RA,$DISP($RB)">; //Store T_floating
 
 //Loads, float
-def LDS : MForm<0x22, "lds $RA,$DISP($RB)">; //Load S_floating
-def LDT : MForm<0x23, "ldt $RA,$DISP($RB)">; //Load T_floating
+let OperandList = (ops F4RC:$RA, s16imm:$DISP, GPRC:$RB) in
+def LDS : MFormAlt<0x22, "lds $RA,$DISP($RB)">; //Load S_floating
+let OperandList = (ops F8RC:$RA, s16imm:$DISP, GPRC:$RB) in
+def LDT : MFormAlt<0x23, "ldt $RA,$DISP($RB)">; //Load T_floating
 
 //Load address
 def LDA : MForm<0x08,  "lda $RA,$DISP($RB)">;  //Load address
@@ -428,8 +450,10 @@ def LDBUr : MForm<0x0A, "ldbu $RA,$DISP($RB)\t\t!gprellow">; //Load zero-extende
 def LDWUr : MForm<0x0C, "ldwu $RA,$DISP($RB)\t\t!gprellow">; //Load zero-extended word
 
 //Loads, float, Rellocated Low form
-def LDSr : MForm<0x22, "lds $RA,$DISP($RB)\t\t!gprellow">; //Load S_floating
-def LDTr : MForm<0x23, "ldt $RA,$DISP($RB)\t\t!gprellow">; //Load T_floating
+let OperandList = (ops F4RC:$RA, s16imm:$DISP, GPRC:$RB) in
+def LDSr : MFormAlt<0x22, "lds $RA,$DISP($RB)\t\t!gprellow">; //Load S_floating
+let OperandList = (ops F8RC:$RA, s16imm:$DISP, GPRC:$RB) in
+def LDTr : MFormAlt<0x23, "ldt $RA,$DISP($RB)\t\t!gprellow">; //Load T_floating
 
 //Load address, rellocated low and high form
 def LDAr : MForm<0x08,  "lda $RA,$DISP($RB)\t\t!gprellow">;  //Load address
@@ -450,8 +474,10 @@ def STLr : MForm<0x2C, "stl $RA,$DISP($RB)\t\t!gprellow">; // Store longword
 def STQr : MForm<0x2D, "stq $RA,$DISP($RB)\t\t!gprellow">; //Store quadword
 
 //Stores, float
-def STSr : MForm<0x26, "sts $RA,$DISP($RB)\t\t!gprellow">; //Store S_floating
-def STTr : MForm<0x27, "stt $RA,$DISP($RB)\t\t!gprellow">; //Store T_floating
+let OperandList = (ops F4RC:$RA, s16imm:$DISP, GPRC:$RB) in
+def STSr : MFormAlt<0x26, "sts $RA,$DISP($RB)\t\t!gprellow">; //Store S_floating
+let OperandList = (ops F8RC:$RA, s16imm:$DISP, GPRC:$RB) in
+def STTr : MFormAlt<0x27, "stt $RA,$DISP($RB)\t\t!gprellow">; //Store T_floating
 
 
 //Branches, int
@@ -533,17 +559,21 @@ def CMPTUN : FPForm<0x16, 0x5A4, "cmptun/su $RA,$RB,$RC", []>;
 let OperandList = (ops GPRC:$RC, F4RC:$RA), Fb = 31 in 
 def FTOIS : FPForm<0x1C, 0x078, "ftois $RA,$RC",[]>; //Floating to integer move, S_floating
 let OperandList = (ops GPRC:$RC, F8RC:$RA), Fb = 31 in 
-def FTOIT : FPForm<0x1C, 0x070, "ftoit $RA,$RC",[]>; //Floating to integer move, T_floating
+def FTOIT : FPForm<0x1C, 0x070, "ftoit $RA,$RC",
+        [(set GPRC:$RC, (Alpha_ftoit F8RC:$RA))]>; //Floating to integer move
 let OperandList = (ops F4RC:$RC, GPRC:$RA), Fb = 31 in 
 def ITOFS : FPForm<0x14, 0x004, "itofs $RA,$RC",[]>; //Integer to floating move, S_floating
 let OperandList = (ops F8RC:$RC, GPRC:$RA), Fb = 31 in 
-def ITOFT : FPForm<0x14, 0x024, "itoft $RA,$RC",[]>; //Integer to floating move, T_floating
+def ITOFT : FPForm<0x14, 0x024, "itoft $RA,$RC",
+        [(set F8RC:$RC, (Alpha_itoft GPRC:$RA))]>; //Integer to floating move
 
 
 let OperandList = (ops F4RC:$RC, F8RC:$RB), Fa = 31 in 
-def CVTQS : FPForm<0x16, 0x7BC, "cvtqs/sui $RB,$RC",[]>; //Convert quadword to S_floating
+def CVTQS : FPForm<0x16, 0x7BC, "cvtqs/sui $RB,$RC",
+        [(set F4RC:$RC, (Alpha_cvtqs F8RC:$RB))]>;
 let OperandList = (ops F8RC:$RC, F8RC:$RB), Fa = 31 in 
-def CVTQT : FPForm<0x16, 0x7BE, "cvtqt/sui $RB,$RC",[]>; //Convert quadword to T_floating
+def CVTQT : FPForm<0x16, 0x7BE, "cvtqt/sui $RB,$RC",
+        [(set F8RC:$RC, (Alpha_cvtqt F8RC:$RB))]>;
 let OperandList = (ops F8RC:$RC, F8RC:$RB), Fa = 31 in 
 def CVTTQ : FPForm<0x16, 0x52F, "cvttq/svc $RB,$RC",[]>; //Convert T_floating to quadword
 let OperandList = (ops F8RC:$RC, F4RC:$RB), Fa = 31 in 
@@ -648,3 +678,11 @@ def : Pat<(sext_inreg GPRC:$RB, i32),
 def : Pat<(select GPRC:$which, GPRC:$src1, GPRC:$src2),
           (CMOVEQ GPRC:$src1, GPRC:$src2, GPRC:$which)>; //may be CMOVNE
 
+def : Pat<(fabs F8RC:$RB),
+          (CPYST F31, F8RC:$RB)>;
+def : Pat<(fabs F4RC:$RB),
+          (CPYSS F31, F4RC:$RB)>;
+def : Pat<(fneg F8RC:$RB),
+          (CPYSNT F8RC:$RB, F8RC:$RB)>;
+def : Pat<(fneg F4RC:$RB),
+          (CPYSNS F4RC:$RB, F4RC:$RB)>;
index b99086553f6531fb17b32cf682bc6b665c78bec6..b0884360861ab198d751582be354d92408748d2a 100644 (file)
@@ -78,7 +78,6 @@ def F30 : FPR<30, "$f30">;  def F31 : FPR<31, "$f31">;
   // $28 is undefined after any and all calls
 
 /// Register classes
-// Don't allocate 15, 28, 30, 31
 def GPRC : RegisterClass<"Alpha", i64, 64,
      // Volatile
      [R0, R1, R2, R3, R4, R5, R6, R7, R8, R16, R17, R18, R19, R20, R21, R22,
@@ -89,7 +88,8 @@ def GPRC : RegisterClass<"Alpha", i64, 64,
      R29, //global offset table address
      // Non-volatile
      R9, R10, R11, R12, R13, R14,
-     R31 ]> //zero
+// Don't allocate 15, 30, 31
+     R15, R30, R31 ]> //zero
 {
   let MethodProtos = [{
     iterator allocation_order_end(MachineFunction &MF) const;
@@ -97,7 +97,7 @@ def GPRC : RegisterClass<"Alpha", i64, 64,
   let MethodBodies = [{
     GPRCClass::iterator
     GPRCClass::allocation_order_end(MachineFunction &MF) const {
-        return end()-1;
+        return end()-3;
     }
   }];
 }