All that just to lower div and rem
authorAndrew Lenharth <andrewl@lenharth.org>
Sun, 25 Dec 2005 01:34:27 +0000 (01:34 +0000)
committerAndrew Lenharth <andrewl@lenharth.org>
Sun, 25 Dec 2005 01:34:27 +0000 (01:34 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@25008 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/AlphaInstrInfo.td

index 5eddf5dde9fd674a56e931172283513e17e558da..5fadc81ce84720421ef0d0741695d7f1f2e5427a 100644 (file)
@@ -206,16 +206,20 @@ SDOperand AlphaDAGToDAGISel::Select(SDOperand Op) {
   case AlphaISD::GlobalBaseReg: 
     return getGlobalBaseReg();
   
-  case ISD::TargetConstantPool: {
-    Constant *C = cast<ConstantPoolSDNode>(N)->get();
-    SDOperand Tmp, CPI = CurDAG->getTargetConstantPool(C, MVT::i64);
-    Tmp = CurDAG->getTargetNode(Alpha::LDAHr, MVT::i64, CPI, getGlobalBaseReg());
-    return CurDAG->SelectNodeTo(N, Alpha::LDAr, MVT::i64, CPI, Tmp);
+  case AlphaISD::DivCall: {
+    SDOperand Chain = CurDAG->getEntryNode();
+    Chain = CurDAG->getCopyToReg(Chain, Alpha::R24, Select(Op.getOperand(1)), 
+                                SDOperand(0,0));
+    Chain = CurDAG->getCopyToReg(Chain, Alpha::R25, Select(Op.getOperand(2)), 
+                                Chain.getValue(1));
+    Chain = CurDAG->getCopyToReg(Chain, Alpha::R27, Select(Op.getOperand(0)), 
+                                Chain.getValue(1));
+    Chain = CurDAG->getTargetNode(Alpha::JSRsDAG, MVT::Other, MVT::Flag, 
+                                 Chain, Chain.getValue(1));
+    Chain = CurDAG->getCopyFromReg(Chain, Alpha::R27, MVT::i64, 
+                                 Chain.getValue(1));
+    return CurDAG->SelectNodeTo(N, Alpha::BIS, MVT::i64, Chain, Chain);
   }
-  case ISD::ExternalSymbol:
-    return CurDAG->SelectNodeTo(N, Alpha::LDQl, MVT::i64, 
-                                CurDAG->getTargetExternalSymbol(cast<ExternalSymbolSDNode>(N)->getSymbol(), MVT::i64),
-                                getGlobalBaseReg());
 
   case ISD::RET: {
     SDOperand Chain = Select(N->getOperand(0));     // Token chain.
@@ -268,33 +272,6 @@ SDOperand AlphaDAGToDAGISel::Select(SDOperand Op) {
       }
       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 = Select(CurDAG->getExternalSymbol(opstr, 
-                                               AlphaLowering.getPointerTy()));
-      SDOperand Chain;
-      Chain = CurDAG->getCopyToReg(CurDAG->getEntryNode(), Alpha::R24, Tmp1,
-                                  SDOperand(0,0));
-      Chain = CurDAG->getCopyToReg(Chain, Alpha::R25, Tmp2, Chain.getValue(1));
-      Chain = CurDAG->getCopyToReg(Chain, Alpha::R27, Addr, Chain.getValue(1));
-      Chain = CurDAG->getTargetNode(Alpha::JSRsDAG, MVT::Other, MVT::Flag, 
-                                   Chain, Chain.getValue(1));
-      return CurDAG->getCopyFromReg(Chain, Alpha::R27, MVT::i64, 
-                                   Chain.getValue(1));
-    }
-    break;
 
   case ISD::SETCC:
     if (MVT::isFloatingPoint(N->getOperand(0).Val->getValueType(0))) {
index 472265939c2178346adba13cc9dfe7dc02c2c6bd..cc4144c0b2d00d9317c07ef43f382db9c0e4a5c4 100644 (file)
@@ -82,9 +82,10 @@ AlphaTargetLowering::AlphaTargetLowering(TargetMachine &TM) : TargetLowering(TM)
     setOperationAction(ISD::CTLZ     , MVT::i64  , Expand);
   }
   
-  //If this didn't legalize into a div....
-  //      setOperationAction(ISD::SREM     , MVT::i64, Expand);
-  //      setOperationAction(ISD::UREM     , MVT::i64, Expand);
+  setOperationAction(ISD::SREM     , MVT::i64, Custom);
+  setOperationAction(ISD::UREM     , MVT::i64, Custom);
+  setOperationAction(ISD::SDIV     , MVT::i64, Custom);
+  setOperationAction(ISD::UDIV     , MVT::i64, Custom);
   
   setOperationAction(ISD::MEMMOVE  , MVT::Other, Expand);
   setOperationAction(ISD::MEMSET   , MVT::Other, Expand);
@@ -104,10 +105,12 @@ AlphaTargetLowering::AlphaTargetLowering(TargetMachine &TM) : TargetLowering(TM)
   setOperationAction(ISD::LOCATION, MVT::Other, Expand);
   setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand);
   
-  // We want to legalize GlobalAddress and ConstantPool nodes into the 
-  // appropriate instructions to materialize the address.
-  setOperationAction(ISD::GlobalAddress, MVT::i64, Custom);
-  setOperationAction(ISD::ConstantPool,  MVT::i64, Custom);
+  // We want to legalize GlobalAddress and ConstantPool and
+  // ExternalSymbols nodes into the appropriate instructions to
+  // materialize the address.
+  setOperationAction(ISD::GlobalAddress,  MVT::i64, Custom);
+  setOperationAction(ISD::ConstantPool,   MVT::i64, Custom);
+  setOperationAction(ISD::ExternalSymbol, MVT::i64, Custom);
 
   addLegalFPImmediate(+0.0); //F31
   addLegalFPImmediate(-0.0); //-F31
@@ -461,6 +464,30 @@ SDOperand AlphaTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
     } else
       return DAG.getNode(AlphaISD::RelLit, MVT::i64, GA, DAG.getNode(AlphaISD::GlobalBaseReg, MVT::i64));
   }
+  case ISD::ExternalSymbol: {
+    return DAG.getNode(AlphaISD::RelLit, MVT::i64, 
+                      DAG.getTargetExternalSymbol(cast<ExternalSymbolSDNode>(Op)->getSymbol(), MVT::i64),
+                      DAG.getNode(AlphaISD::GlobalBaseReg, MVT::i64));
+  }
+
+  case ISD::SDIV:
+  case ISD::UDIV:
+  case ISD::UREM:
+  case ISD::SREM:
+    if (MVT::isInteger(Op.getValueType())) {
+      const char* opstr = 0;
+      switch(Op.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 = Op.getOperand(0),
+        Tmp2 = Op.getOperand(1),
+        Addr = DAG.getExternalSymbol(opstr, MVT::i64);
+      return DAG.getNode(AlphaISD::DivCall, MVT::i64, Addr, Tmp1, Tmp2);
+    }
+    break;
 
   }
 
index 038184d745a8ea30b8fd47cf905ddd2e0000548c..c9245ad26c04c17c0321288712783fc8ea5d2eb9 100644 (file)
@@ -35,9 +35,12 @@ namespace llvm {
       /// RetLit - Literal Relocation of a Global
       RelLit,
 
-      /// GlobalBaseReg, used to restore the GOT ptr
+      /// GlobalBaseReg - used to restore the GOT ptr
       GlobalBaseReg,
 
+      /// DIVCALL - used for special library calls for div and rem
+      DivCall,
+
     };
   }
 
index e6a06645975bc0238987a3952eaa75966dc035d6..afacf726cb3041efac3d041d5020e0cd40cbf03e 100644 (file)
@@ -74,7 +74,6 @@ class AlphaISel : public SelectionDAGISel {
 
   int count_ins;
   int count_outs;
-  bool has_sym;
   int max_depth;
 
 public:
@@ -93,15 +92,12 @@ public:
     count_ins = 0;
     count_outs = 0;
     max_depth = 0;
-    has_sym = false;
 
     // Codegen the basic block.
     ISelDAG = &DAG;
     max_depth = DAG.getRoot().getNodeDepth();
     Select(DAG.getRoot());
 
-    if(has_sym)
-      ++count_ins;
     if(EnableAlphaCount)
       std::cerr << "COUNT: "
                 << BB->getParent()->getFunction ()->getName() << " "
@@ -689,12 +685,11 @@ unsigned AlphaISel::SelectExpr(SDOperand N) {
                   dyn_cast<ConstantPoolSDNode>(Address)) {
          unsigned CPIdx = BB->getParent()->getConstantPool()->
            getConstantPoolIndex(CP->get());
-         has_sym = true;
          if (EnableAlphaLSMark)
            BuildMI(BB, Alpha::MEMLABEL, 4).addImm(i).addImm(j).addImm(k)
              .addImm(getUID());
          BuildMI(BB, GetRelVersion(Opc), 2, Result)
-           .addConstantPoolIndex(CPIdx).addReg(Tmp1);
+           .addConstantPoolIndex(CPIdx).addReg(Hi);
        } else assert(0 && "Unknown Lo part");
       } else if(Address.getOpcode() == ISD::FrameIndex) {
         if (EnableAlphaLSMark)
@@ -717,56 +712,43 @@ unsigned AlphaISel::SelectExpr(SDOperand N) {
     AlphaLowering.restoreGP(BB);
     BuildMI(BB, Alpha::BIS, 2, Result).addReg(Alpha::R29).addReg(Alpha::R29);
     return Result;
-  case AlphaISD::GPRelHi:
+  case AlphaISD::GPRelHi: {
+    unsigned hi = SelectExpr(N.getOperand(1));
     if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(N.getOperand(0)))
       BuildMI(BB, Alpha::LDAHr, 2, Result)
        .addConstantPoolIndex(BB->getParent()->getConstantPool()->
-                             getConstantPoolIndex(CP->get()))
-       .addReg(SelectExpr(N.getOperand(1)));
+                             getConstantPoolIndex(CP->get())).addReg(hi);
     else if (GlobalAddressSDNode *GASD = 
             dyn_cast<GlobalAddressSDNode>(N.getOperand(0)))
       BuildMI(BB, Alpha::LDAHr, 2, Result)
-       .addGlobalAddress(GASD->getGlobal())
-       .addReg(SelectExpr(N.getOperand(1)));
+       .addGlobalAddress(GASD->getGlobal()).addReg(hi);
     else assert(0 && "unknown Hi part");
     return Result;
-  case AlphaISD::GPRelLo:
+  }
+  case AlphaISD::GPRelLo: {
+    unsigned hi = SelectExpr(N.getOperand(1));
     if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(N.getOperand(0)))
       BuildMI(BB, Alpha::LDAr, 2, Result)
        .addConstantPoolIndex(BB->getParent()->getConstantPool()->
-                             getConstantPoolIndex(CP->get()))
-       .addReg(SelectExpr(N.getOperand(1)));
+                             getConstantPoolIndex(CP->get())).addReg(hi);
     else if (GlobalAddressSDNode *GASD = 
             dyn_cast<GlobalAddressSDNode>(N.getOperand(0)))
       BuildMI(BB, Alpha::LDAr, 2, Result)
-       .addGlobalAddress(GASD->getGlobal())
-       .addReg(SelectExpr(N.getOperand(1)));
+       .addGlobalAddress(GASD->getGlobal()).addReg(hi);
     else assert(0 && "unknown Lo part");
     return Result;
-
+  }
   case AlphaISD::RelLit: {
-    GlobalAddressSDNode *GASD = cast<GlobalAddressSDNode>(N.getOperand(0));
-    BuildMI(BB, Alpha::LDQl, 2, Result)
-      .addGlobalAddress(GASD->getGlobal())
-      .addReg(SelectExpr(N.getOperand(1)));
+    unsigned hi = SelectExpr(N.getOperand(1));
+    if (GlobalAddressSDNode *GASD = dyn_cast<GlobalAddressSDNode>(N.getOperand(0)))
+      BuildMI(BB, Alpha::LDQl, 2, Result)
+       .addGlobalAddress(GASD->getGlobal()).addReg(hi);
+    else if (ExternalSymbolSDNode *ESSD = dyn_cast<ExternalSymbolSDNode>(N.getOperand(0)))
+      BuildMI(BB, Alpha::LDQl, 2, Result)
+       .addExternalSymbol(ESSD->getSymbol()).addReg(hi);
     return Result;
   }
 
-  case ISD::ExternalSymbol:
-    AlphaLowering.restoreGP(BB);
-    has_sym = true;
-
-    Reg = Result = MakeReg(MVT::i64);
-
-    if (EnableAlphaLSMark)
-      BuildMI(BB, Alpha::MEMLABEL, 4).addImm(5).addImm(0).addImm(0)
-        .addImm(getUID());
-
-    BuildMI(BB, Alpha::LDQl, 2, Result)
-      .addExternalSymbol(cast<ExternalSymbolSDNode>(N)->getSymbol())
-      .addReg(Alpha::R29);
-    return Result;
-
   case ISD::TAILCALL:
   case ISD::CALL:
     {
@@ -1248,60 +1230,16 @@ unsigned AlphaISel::SelectExpr(SDOperand N) {
     BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
     return Result;
   }
-  case ISD::SDIV:
-    {
-      //check if we can convert into a shift!
-      if (isSIntImmediate(N.getOperand(1), SImm) &&
-          SImm != 0 && isPowerOf2_64(llabs(SImm))) {
-        unsigned k = Log2_64(llabs(SImm));
-        Tmp1 = SelectExpr(N.getOperand(0));
-        if (k == 1)
-          Tmp2 = Tmp1;
-        else
-        {
-          Tmp2 = MakeReg(MVT::i64);
-          BuildMI(BB, Alpha::SRAi, 2, Tmp2).addReg(Tmp1).addImm(k - 1);
-        }
-        Tmp3 = MakeReg(MVT::i64);
-        BuildMI(BB, Alpha::SRLi, 2, Tmp3).addReg(Tmp2).addImm(64-k);
-        unsigned Tmp4 = MakeReg(MVT::i64);
-        BuildMI(BB, Alpha::ADDQ, 2, Tmp4).addReg(Tmp3).addReg(Tmp1);
-        if (SImm > 0)
-          BuildMI(BB, Alpha::SRAi, 2, Result).addReg(Tmp4).addImm(k);
-        else
-        {
-          unsigned Tmp5 = MakeReg(MVT::i64);
-          BuildMI(BB, Alpha::SRAi, 2, Tmp5).addReg(Tmp4).addImm(k);
-          BuildMI(BB, Alpha::SUBQ, 2, Result).addReg(Alpha::R31).addReg(Tmp5);
-        }
-        return Result;
-      }
-    }
-    //Else fall through
-  case ISD::UDIV:
-    //else fall though
-  case ISD::UREM:
-  case ISD::SREM: {
-    const char* opstr = 0;
-    switch(opcode) {
-    case ISD::UREM: opstr = "__remqu"; break;
-    case ISD::SREM: opstr = "__remq";  break;
-    case ISD::UDIV: opstr = "__divqu"; break;
-    case ISD::SDIV: opstr = "__divq";  break;
-    }
+  case AlphaISD::DivCall:
     Tmp1 = SelectExpr(N.getOperand(0));
     Tmp2 = SelectExpr(N.getOperand(1));
-    SDOperand Addr =
-      ISelDAG->getExternalSymbol(opstr, AlphaLowering.getPointerTy());
-    Tmp3 = SelectExpr(Addr);
-    //set up regs explicitly (helps Reg alloc)
-    BuildMI(BB, Alpha::BIS, 2, Alpha::R24).addReg(Tmp1).addReg(Tmp1);
-    BuildMI(BB, Alpha::BIS, 2, Alpha::R25).addReg(Tmp2).addReg(Tmp2);
-    BuildMI(BB, Alpha::BIS, 2, Alpha::R27).addReg(Tmp3).addReg(Tmp3);
+    Tmp3 = SelectExpr(N.getOperand(2));
+    BuildMI(BB, Alpha::BIS, 2, Alpha::R24).addReg(Tmp2).addReg(Tmp2);
+    BuildMI(BB, Alpha::BIS, 2, Alpha::R25).addReg(Tmp3).addReg(Tmp3);
+    BuildMI(BB, Alpha::BIS, 2, Alpha::R27).addReg(Tmp1).addReg(Tmp1);
     BuildMI(BB, Alpha::JSRs, 2, Alpha::R23).addReg(Alpha::R27).addImm(0);
     BuildMI(BB, Alpha::BIS, 2, Result).addReg(Alpha::R27).addReg(Alpha::R27);
     return Result;
-  }
 
   case ISD::SELECT:
     if (isFP) {
@@ -1492,7 +1430,6 @@ unsigned AlphaISel::SelectExpr(SDOperand N) {
           ConstantUInt::get(Type::getPrimitiveType(Type::ULongTyID) , val);
         unsigned CPI = CP->getConstantPoolIndex(C);
         AlphaLowering.restoreGP(BB);
-        has_sym = true;
         Tmp1 = MakeReg(MVT::i64);
         BuildMI(BB, Alpha::LDAHr, 2, Tmp1).addConstantPoolIndex(CPI)
           .addReg(Alpha::R29);
index 31321843e3372680a10c58c9c9ad4a83c4a69a09..d73c3abab8cc23847e74ba63bf08861647ae3c98 100644 (file)
@@ -434,6 +434,7 @@ let isCall = 1, Defs = [R24, R25, R27, R28], Uses = [R24, R25] in
 let isCall = 1, Defs = [R23, R24, R25, R27, R28], Uses = [R24, R25, R27] in
   def JSRsDAG : MbrForm< 0x1A, 0x01, (ops ), "jsr $$23,($$27),0">; //Jump to div or rem
 
+
 def JSR_COROUTINE : MbrForm< 0x1A, 0x03, (ops GPRC:$RD, GPRC:$RS, s14imm:$DISP), "jsr_coroutine $RD,($RS),$DISP">; //Jump to subroutine return
 def BR : BForm<0x30, "br $RA,$DISP">; //Branch
 
@@ -575,9 +576,11 @@ def LDAHg : MFormAlt<0x09, "ldah $RA,0($RB)\t\t!gpdisp!$NUM">;  //Load address
 }
 
 //Load quad, rellocated literal form
-let OperandList = (ops GPRC:$RA, s64imm:$DISP, GPRC:$RB) in
+let OperandList = (ops GPRC:$RA, s64imm:$DISP, GPRC:$RB) in 
 def LDQl : MForm<0x29, 0, 1, "ldq $RA,$DISP($RB)\t\t!literal",
                  [(set GPRC:$RA, (Alpha_rellit tglobaladdr:$DISP, GPRC:$RB))]>;
+def : Pat<(Alpha_rellit texternalsym:$ext, GPRC:$RB),
+          (LDQl texternalsym:$ext, GPRC:$RB)>;
 
 //Branches, int
 def BEQ : BForm<0x39,  "beq $RA,$DISP">; //Branch if = zero