Store default libgcc routine names and allow them to be redefined by target.
authorEvan Cheng <evan.cheng@apple.com>
Fri, 12 Jan 2007 02:11:51 +0000 (02:11 +0000)
committerEvan Cheng <evan.cheng@apple.com>
Fri, 12 Jan 2007 02:11:51 +0000 (02:11 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33105 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Target/TargetLowering.h
lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
lib/CodeGen/SelectionDAG/TargetLowering.cpp

index 6880cddf23732e693b6d45c471a94f562cdedad2..5749d520d83619657aa1c4c0c7ee7b8e2b0378ae 100644 (file)
@@ -38,6 +38,93 @@ namespace llvm {
   class MachineBasicBlock;
   class MachineInstr;
 
+namespace RTLIB {
+  /// RTLIB::Libcall enum - This enum defines all of the runtime library calls
+  /// the backend can emit.
+  ///
+  enum Libcall {
+    // Integer
+    SHL_I32,
+    SHL_I64,
+    SRL_I32,
+    SRL_I64,
+    SRA_I32,
+    SRA_I64,
+    MUL_I32,
+    MUL_I64,
+    SDIV_I32,
+    SDIV_I64,
+    UDIV_I32,
+    UDIV_I64,
+    SREM_I32,
+    SREM_I64,
+    UREM_I32,
+    UREM_I64,
+    NEG_I32,
+    NEG_I64,
+
+    // FLOATING POINT
+    ADD_F32,
+    ADD_F64,
+    SUB_F32,
+    SUB_F64,
+    MUL_F32,
+    MUL_F64,
+    DIV_F32,
+    DIV_F64,
+    REM_F32,
+    REM_F64,
+    NEG_F32,
+    NEG_F64,
+    POWI_F32,
+    POWI_F64,
+    SQRT_F32,
+    SQRT_F64,
+    SIN_F32,
+    SIN_F64,
+    COS_F32,
+    COS_F64,
+
+    // CONVERSION
+    FPEXT_F32_F64,
+    FPROUND_F64_F32,
+    FPTOSINT_F32_I32,
+    FPTOSINT_F32_I64,
+    FPTOSINT_F64_I32,
+    FPTOSINT_F64_I64,
+    FPTOUINT_F32_I32,
+    FPTOUINT_F32_I64,
+    FPTOUINT_F64_I32,
+    FPTOUINT_F64_I64,
+    SINTTOFP_I32_F32,
+    SINTTOFP_I32_F64,
+    SINTTOFP_I64_F32,
+    SINTTOFP_I64_F64,
+    UINTTOFP_I32_F32,
+    UINTTOFP_I32_F64,
+    UINTTOFP_I64_F32,
+    UINTTOFP_I64_F64,
+
+    // COMPARISON
+    OEQ_F32,
+    OEQ_F64,
+    UNE_F32,
+    UNE_F64,
+    OGE_F32,
+    OGE_F64,
+    OLT_F32,
+    OLT_F64,
+    OLE_F32,
+    OLE_F64,
+    OGT_F32,
+    OGT_F64,
+    UO_F32,
+    UO_F64,
+
+    UNKNOWN_LIBCALL
+  };
+  }
+
 //===----------------------------------------------------------------------===//
 /// TargetLowering - This class defines information used to lower LLVM code to
 /// legal SelectionDAG operators that the target instruction selector can accept
@@ -857,6 +944,22 @@ public:
                      std::vector<SDNode*>* Created) const;
 
 
+  //===--------------------------------------------------------------------===//
+  // Runtime Library hooks
+  //
+
+  /// setLibcallName - Rename the default libcall routine name for the specified
+  /// libcall.
+  void setLibcallName(RTLIB::Libcall Call, std::string Name) {
+    LibcallRoutineNames[Call] = Name;
+  }
+
+  /// getLibcallName - Get the libcall routine name for the specified libcall.
+  ///
+  const char *getLibcallName(RTLIB::Libcall Call) const {
+    return LibcallRoutineNames[Call].c_str();
+  }
+
 protected:
   /// addLegalAddressScale - Add a integer (> 1) value which can be used as
   /// scale in the target addressing mode. Note: the ordering matters so the
@@ -989,7 +1092,11 @@ private:
   /// Targets add entries to this map with AddPromotedToType(..), clients access
   /// this with getTypeToPromoteTo(..).
   std::map<std::pair<unsigned, MVT::ValueType>, MVT::ValueType> PromoteToType;
-  
+
+  /// LibcallRoutineNames - Stores the name each libcall.
+  ///
+  std::string LibcallRoutineNames[RTLIB::UNKNOWN_LIBCALL];
+
 protected:
   /// When lowering %llvm.memset this field specifies the maximum number of
   /// store operations that may be substituted for the call to memset. Targets
index aad61477eff006a4353413960f47a1bc40ec8310..fee85a13c68e1bfe7bc153659912e615c59667f2 100644 (file)
@@ -2284,11 +2284,11 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
         default:  assert(0 && "Do not know how to expand this integer BinOp!");
         case ISD::UDIV:
         case ISD::SDIV:
-          const char *FnName = Node->getOpcode() == ISD::UDIV
-            ? "__udivsi3" : "__divsi3";
+          RTLIB::Libcall LC = Node->getOpcode() == ISD::UDIV
+            ? RTLIB::UDIV_I32 : RTLIB::SDIV_I32;
           SDOperand Dummy;
           bool isSigned = Node->getOpcode() == ISD::SDIV;
-          Result = ExpandLibCall(FnName, Node, isSigned, Dummy);
+          Result = ExpandLibCall(TLI.getLibcallName(LC), Node, isSigned, Dummy);
         };
         break;
       }
@@ -2470,16 +2470,18 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
         } else {
           assert(Node->getValueType(0) == MVT::i32 &&
                  "Cannot expand this binary operator!");
-          const char *FnName = Node->getOpcode() == ISD::UREM
-            ? "__umodsi3" : "__modsi3";
+          RTLIB::Libcall LC = Node->getOpcode() == ISD::UREM
+            ? RTLIB::UREM_I32 : RTLIB::SREM_I32;
           SDOperand Dummy;
-          Result = ExpandLibCall(FnName, Node, isSigned, Dummy);
+          Result = ExpandLibCall(TLI.getLibcallName(LC), Node, isSigned, Dummy);
         }
       } else {
         // Floating point mod -> fmod libcall.
-        const char *FnName = Node->getValueType(0) == MVT::f32 ? "fmodf":"fmod";
+        RTLIB::Libcall LC = Node->getValueType(0) == MVT::f32
+          ? RTLIB::REM_F32 : RTLIB::REM_F64;
         SDOperand Dummy;
-        Result = ExpandLibCall(FnName, Node, false/*sign irrelevant*/, Dummy);
+        Result = ExpandLibCall(TLI.getLibcallName(LC), Node,
+                               false/*sign irrelevant*/, Dummy);
       }
       break;
     }
@@ -2720,15 +2722,22 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
       case ISD::FSIN:
       case ISD::FCOS: {
         MVT::ValueType VT = Node->getValueType(0);
-        const char *FnName = 0;
+        RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
         switch(Node->getOpcode()) {
-        case ISD::FSQRT: FnName = VT == MVT::f32 ? "sqrtf" : "sqrt"; break;
-        case ISD::FSIN:  FnName = VT == MVT::f32 ? "sinf"  : "sin"; break;
-        case ISD::FCOS:  FnName = VT == MVT::f32 ? "cosf"  : "cos"; break;
+        case ISD::FSQRT:
+          LC = VT == MVT::f32 ? RTLIB::SQRT_F32 : RTLIB::SQRT_F64;
+          break;
+        case ISD::FSIN:
+          LC = VT == MVT::f32 ? RTLIB::SIN_F32 : RTLIB::SIN_F64;
+          break;
+        case ISD::FCOS:
+          LC = VT == MVT::f32 ? RTLIB::COS_F32 : RTLIB::COS_F64;
+          break;
         default: assert(0 && "Unreachable!");
         }
         SDOperand Dummy;
-        Result = ExpandLibCall(FnName, Node, false/*sign irrelevant*/, Dummy);
+        Result = ExpandLibCall(TLI.getLibcallName(LC), Node,
+                               false/*sign irrelevant*/, Dummy);
         break;
       }
       }
@@ -2737,10 +2746,11 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
     break;
   case ISD::FPOWI: {
     // We always lower FPOWI into a libcall.  No target support it yet.
-    const char *FnName = Node->getValueType(0) == MVT::f32
-                            ? "__powisf2" : "__powidf2";
+    RTLIB::Libcall LC = Node->getValueType(0) == MVT::f32
+      ? RTLIB::POWI_F32 : RTLIB::POWI_F64;
     SDOperand Dummy;
-    Result = ExpandLibCall(FnName, Node, false/*sign irrelevant*/, Dummy);
+    Result = ExpandLibCall(TLI.getLibcallName(LC), Node,
+                           false/*sign irrelevant*/, Dummy);
     break;
   }
   case ISD::BIT_CONVERT:
@@ -2909,24 +2919,29 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
     case Expand: {
       // Convert f32 / f64 to i32 / i64.
       MVT::ValueType VT = Op.getValueType();
-      const char *FnName = 0;
+      RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
       switch (Node->getOpcode()) {
       case ISD::FP_TO_SINT:
         if (Node->getOperand(0).getValueType() == MVT::f32)
-          FnName = (VT == MVT::i32) ? "__fixsfsi" : "__fixsfdi";
+          LC = (VT == MVT::i32)
+            ? RTLIB::FPTOSINT_F32_I32 : RTLIB::FPTOSINT_F32_I64;
         else
-          FnName = (VT == MVT::i32) ? "__fixdfsi" : "__fixdfdi";
+          LC = (VT == MVT::i32)
+            ? RTLIB::FPTOSINT_F64_I32 : RTLIB::FPTOSINT_F64_I64;
         break;
       case ISD::FP_TO_UINT:
         if (Node->getOperand(0).getValueType() == MVT::f32)
-          FnName = (VT == MVT::i32) ? "__fixunssfsi" : "__fixunssfdi";
+          LC = (VT == MVT::i32)
+            ? RTLIB::FPTOUINT_F32_I32 : RTLIB::FPTOSINT_F32_I64;
         else
-          FnName = (VT == MVT::i32) ? "__fixunsdfsi" : "__fixunsdfdi";
+          LC = (VT == MVT::i32)
+            ? RTLIB::FPTOUINT_F64_I32 : RTLIB::FPTOSINT_F64_I64;
         break;
       default: assert(0 && "Unreachable!");
       }
       SDOperand Dummy;
-      Result = ExpandLibCall(FnName, Node, false/*sign irrelevant*/, Dummy);
+      Result = ExpandLibCall(TLI.getLibcallName(LC), Node,
+                             false/*sign irrelevant*/, Dummy);
       break;
     }
     case Promote:
@@ -3575,87 +3590,87 @@ void SelectionDAGLegalize::LegalizeSetCCOperands(SDOperand &LHS,
     MVT::ValueType VT = LHS.getValueType();
     if (VT == MVT::f32 || VT == MVT::f64) {
       // Expand into one or more soft-fp libcall(s).
-      const char *FnName1 = NULL, *FnName2 = NULL;
+      RTLIB::Libcall LC1, LC2 = RTLIB::UNKNOWN_LIBCALL;
       ISD::CondCode CC1, CC2 = ISD::SETCC_INVALID;
       switch (cast<CondCodeSDNode>(CC)->get()) {
       case ISD::SETEQ:
       case ISD::SETOEQ:
-        FnName1 = (VT == MVT::f32) ? "__eqsf2" : "__eqdf2";
+        LC1 = (VT == MVT::f32) ? RTLIB::OEQ_F32 : RTLIB::OEQ_F64;
         CC1 = ISD::SETEQ;
         break;
       case ISD::SETNE:
       case ISD::SETUNE:
-        FnName1 = (VT == MVT::f32) ? "__nesf2" : "__nedf2";
+        LC1 = (VT == MVT::f32) ? RTLIB::UNE_F32 : RTLIB::UNE_F64;
         CC1 = ISD::SETNE;
         break;
       case ISD::SETGE:
       case ISD::SETOGE:
-        FnName1 = (VT == MVT::f32) ? "__gesf2" : "__gedf2";
+        LC1 = (VT == MVT::f32) ? RTLIB::OGE_F32 : RTLIB::OGE_F64;
         CC1 = ISD::SETGE;
         break;
       case ISD::SETLT:
       case ISD::SETOLT:
-        FnName1 = (VT == MVT::f32) ? "__ltsf2" : "__ltdf2";
+        LC1 = (VT == MVT::f32) ? RTLIB::OLT_F32 : RTLIB::OLT_F64;
         CC1 = ISD::SETLT;
         break;
       case ISD::SETLE:
       case ISD::SETOLE:
-        FnName1 = (VT == MVT::f32) ? "__lesf2" : "__ledf2";
+        LC1 = (VT == MVT::f32) ? RTLIB::OLE_F32 : RTLIB::OLE_F64;
         CC1 = ISD::SETLE;
         break;
       case ISD::SETGT:
       case ISD::SETOGT:
-        FnName1 = (VT == MVT::f32) ? "__gtsf2" : "__gtdf2";
+        LC1 = (VT == MVT::f32) ? RTLIB::OGT_F32 : RTLIB::OGT_F64;
         CC1 = ISD::SETGT;
         break;
       case ISD::SETUO:
       case ISD::SETO:
-        FnName1 = (VT == MVT::f32) ? "__unordsf2" : "__unorddf2";
+        LC1 = (VT == MVT::f32) ? RTLIB::UO_F32 : RTLIB::UO_F64;
         CC1 = cast<CondCodeSDNode>(CC)->get() == ISD::SETO
           ? ISD::SETEQ : ISD::SETNE;
         break;
       default:
-        FnName1 = (VT == MVT::f32) ? "__unordsf2" : "__unorddf2";
+        LC1 = (VT == MVT::f32) ? RTLIB::UO_F32 : RTLIB::UO_F64;
         CC1 = ISD::SETNE;
         switch (cast<CondCodeSDNode>(CC)->get()) {
         case ISD::SETONE:
           // SETONE = SETOLT | SETOGT
-          FnName1 = (VT == MVT::f32) ? "__ltsf2" : "__ltdf2";
+          LC1 = (VT == MVT::f32) ? RTLIB::OLT_F32 : RTLIB::OLT_F64;
           CC1 = ISD::SETLT;
           // Fallthrough
         case ISD::SETUGT:
-          FnName2 = (VT == MVT::f32) ? "__gtsf2" : "__gtdf2";
+          LC2 = (VT == MVT::f32) ? RTLIB::OGT_F32 : RTLIB::OGT_F64;
           CC2 = ISD::SETGT;
           break;
         case ISD::SETUGE:
-          FnName2 = (VT == MVT::f32) ? "__gesf2" : "__gedf2";
+          LC2 = (VT == MVT::f32) ? RTLIB::OGE_F32 : RTLIB::OGE_F64;
           CC2 = ISD::SETGE;
           break;
         case ISD::SETULT:
-          FnName2 = (VT == MVT::f32) ? "__ltsf2" : "__ltdf2";
+          LC2 = (VT == MVT::f32) ? RTLIB::OLT_F32 : RTLIB::OLT_F64;
           CC2 = ISD::SETLT;
           break;
         case ISD::SETULE:
-          FnName2 = (VT == MVT::f32) ? "__lesf2" : "__ledf2";
+          LC2 = (VT == MVT::f32) ? RTLIB::OLE_F32 : RTLIB::OLE_F64;
           CC2 = ISD::SETLE;
           break;
-          case ISD::SETUEQ:
-            FnName2 = (VT == MVT::f32) ? "__eqsf2" : "__eqdf2";
-            CC2 = ISD::SETEQ;
-            break;
+        case ISD::SETUEQ:
+          LC2 = (VT == MVT::f32) ? RTLIB::OEQ_F32 : RTLIB::OEQ_F64;
+          CC2 = ISD::SETEQ;
+          break;
         default: assert(0 && "Unsupported FP setcc!");
         }
       }
       
       SDOperand Dummy;
-      Tmp1 = ExpandLibCall(FnName1,
+      Tmp1 = ExpandLibCall(TLI.getLibcallName(LC1),
                            DAG.getNode(ISD::MERGE_VALUES, VT, LHS, RHS).Val, 
                            false /*sign irrelevant*/, Dummy);
       Tmp2 = DAG.getConstant(0, MVT::i32);
       CC = DAG.getCondCode(CC1);
-      if (FnName2) {
+      if (LC2 != RTLIB::UNKNOWN_LIBCALL) {
         Tmp1 = DAG.getNode(ISD::SETCC, TLI.getSetCCResultTy(), Tmp1, Tmp2, CC);
-        LHS = ExpandLibCall(FnName2,
+        LHS = ExpandLibCall(TLI.getLibcallName(LC2),
                             DAG.getNode(ISD::MERGE_VALUES, VT, LHS, RHS).Val, 
                             false /*sign irrelevant*/, Dummy);
         Tmp2 = DAG.getNode(ISD::SETCC, TLI.getSetCCResultTy(), LHS, Tmp2,
@@ -4202,17 +4217,18 @@ ExpandIntToFP(bool isSigned, MVT::ValueType DestTy, SDOperand Source) {
   ExpandOp(Source, SrcLo, SrcHi);
   Source = DAG.getNode(ISD::BUILD_PAIR, Source.getValueType(), SrcLo, SrcHi);
 
-  const char *FnName = 0;
+  RTLIB::Libcall LC;
   if (DestTy == MVT::f32)
-    FnName = "__floatdisf";
+    LC = RTLIB::SINTTOFP_I64_F32;
   else {
     assert(DestTy == MVT::f64 && "Unknown fp value type!");
-    FnName = "__floatdidf";
+    LC = RTLIB::SINTTOFP_I64_F64;
   }
   
   Source = DAG.getNode(ISD::SINT_TO_FP, DestTy, Source);
   SDOperand UnusedHiPart;
-  return ExpandLibCall(FnName, Source.Val, isSigned, UnusedHiPart);
+  return ExpandLibCall(TLI.getLibcallName(LC), Source.Val, isSigned,
+                       UnusedHiPart);
 }
 
 /// ExpandLegalINT_TO_FP - This function is responsible for legalizing a
@@ -4845,7 +4861,7 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){
 
     // These operators cannot be expanded directly, emit them as calls to
     // library functions.
-  case ISD::FP_TO_SINT:
+  case ISD::FP_TO_SINT: {
     if (TLI.getOperationAction(ISD::FP_TO_SINT, VT) == TargetLowering::Custom) {
       SDOperand Op;
       switch (getTypeAction(Node->getOperand(0).getValueType())) {
@@ -4864,13 +4880,17 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){
       }
     }
 
+    RTLIB::Libcall LC;
     if (Node->getOperand(0).getValueType() == MVT::f32)
-      Lo = ExpandLibCall("__fixsfdi", Node, false/*sign irrelevant*/, Hi);
+      LC = RTLIB::FPTOSINT_F32_I64;
     else
-      Lo = ExpandLibCall("__fixdfdi", Node, false/*sign irrelevant*/, Hi);
+      LC = RTLIB::FPTOSINT_F64_I64;
+    Lo = ExpandLibCall(TLI.getLibcallName(LC), Node,
+                       false/*sign irrelevant*/, Hi);
     break;
+  }
 
-  case ISD::FP_TO_UINT:
+  case ISD::FP_TO_UINT: {
     if (TLI.getOperationAction(ISD::FP_TO_UINT, VT) == TargetLowering::Custom) {
       SDOperand Op;
       switch (getTypeAction(Node->getOperand(0).getValueType())) {
@@ -4888,11 +4908,15 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){
       }
     }
 
+    RTLIB::Libcall LC;
     if (Node->getOperand(0).getValueType() == MVT::f32)
-      Lo = ExpandLibCall("__fixunssfdi", Node, false/*sign irrelevant*/, Hi);
+      LC = RTLIB::FPTOUINT_F32_I64;
     else
-      Lo = ExpandLibCall("__fixunsdfdi", Node, false/*sign irrelevant*/, Hi);
+      LC = RTLIB::FPTOUINT_F64_I64;
+    Lo = ExpandLibCall(TLI.getLibcallName(LC), Node,
+                       false/*sign irrelevant*/, Hi);
     break;
+  }
 
   case ISD::SHL: {
     // If the target wants custom lowering, do so.
@@ -4940,7 +4964,8 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){
     }
 
     // Otherwise, emit a libcall.
-    Lo = ExpandLibCall("__ashldi3", Node, false/*left shift=unsigned*/, Hi);
+    Lo = ExpandLibCall(TLI.getLibcallName(RTLIB::SHL_I64), Node,
+                       false/*left shift=unsigned*/, Hi);
     break;
   }
 
@@ -4972,7 +4997,8 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){
     }
 
     // Otherwise, emit a libcall.
-    Lo = ExpandLibCall("__ashrdi3", Node, true/*ashr is signed*/, Hi);
+    Lo = ExpandLibCall(TLI.getLibcallName(RTLIB::SRA_I64), Node,
+                       true/*ashr is signed*/, Hi);
     break;
   }
 
@@ -5004,7 +5030,8 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){
     }
 
     // Otherwise, emit a libcall.
-    Lo = ExpandLibCall("__lshrdi3", Node, false/*lshr is unsigned*/, Hi);
+    Lo = ExpandLibCall(TLI.getLibcallName(RTLIB::SRL_I64), Node,
+                       false/*lshr is unsigned*/, Hi);
     break;
   }
 
@@ -5091,47 +5118,66 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){
       }
     }
 
-    Lo = ExpandLibCall("__muldi3" , Node, false/*sign irrelevant*/, Hi);
+    Lo = ExpandLibCall(TLI.getLibcallName(RTLIB::MUL_I64), Node,
+                       false/*sign irrelevant*/, Hi);
     break;
   }
-  case ISD::SDIV: Lo = ExpandLibCall("__divdi3" , Node, true, Hi); break;
-  case ISD::UDIV: Lo = ExpandLibCall("__udivdi3", Node, false, Hi); break;
-  case ISD::SREM: Lo = ExpandLibCall("__moddi3" , Node, true, Hi); break;
-  case ISD::UREM: Lo = ExpandLibCall("__umoddi3", Node, false, Hi); break;
+  case ISD::SDIV:
+    Lo = ExpandLibCall(TLI.getLibcallName(RTLIB::SDIV_I64), Node, true, Hi);
+    break;
+  case ISD::UDIV:
+    Lo = ExpandLibCall(TLI.getLibcallName(RTLIB::UDIV_I64), Node, true, Hi);
+    break;
+  case ISD::SREM:
+    Lo = ExpandLibCall(TLI.getLibcallName(RTLIB::SREM_I64), Node, true, Hi);
+    break;
+  case ISD::UREM:
+    Lo = ExpandLibCall(TLI.getLibcallName(RTLIB::UREM_I64), Node, true, Hi);
+    break;
 
   case ISD::FADD:
-    Lo = ExpandLibCall(((VT == MVT::f32) ? "__addsf3" : "__adddf3"), Node, 
-                       false, Hi);
+    Lo = ExpandLibCall(TLI.getLibcallName((VT == MVT::f32)
+                                          ? RTLIB::ADD_F32 : RTLIB::ADD_F64),
+                       Node, false, Hi);
     break;
   case ISD::FSUB:
-    Lo = ExpandLibCall(((VT == MVT::f32) ? "__subsf3" : "__subdf3"), Node, 
-                       false, Hi);
+    Lo = ExpandLibCall(TLI.getLibcallName((VT == MVT::f32)
+                                          ? RTLIB::SUB_F32 : RTLIB::SUB_F64),
+                       Node, false, Hi);
     break;
   case ISD::FMUL:
-    Lo = ExpandLibCall(((VT == MVT::f32) ? "__mulsf3" : "__muldf3"), Node, 
-                       false, Hi);
+    Lo = ExpandLibCall(TLI.getLibcallName((VT == MVT::f32)
+                                          ? RTLIB::MUL_F32 : RTLIB::MUL_F64),
+                       Node, false, Hi);
     break;
   case ISD::FDIV:
-    Lo = ExpandLibCall(((VT == MVT::f32) ? "__divsf3" : "__divdf3"), Node, 
-                       false, Hi);
+    Lo = ExpandLibCall(TLI.getLibcallName((VT == MVT::f32)
+                                          ? RTLIB::DIV_F32 : RTLIB::DIV_F64),
+                       Node, false, Hi);
     break;
   case ISD::FP_EXTEND:
-    Lo = ExpandLibCall("__extendsfdf2", Node, false, Hi);
+    Lo = ExpandLibCall(TLI.getLibcallName(RTLIB::FPEXT_F32_F64), Node, true,Hi);
     break;
   case ISD::FP_ROUND:
-    Lo = ExpandLibCall("__truncdfsf2", Node, false, Hi);
+    Lo = ExpandLibCall(TLI.getLibcallName(RTLIB::FPROUND_F64_F32),Node,true,Hi);
     break;
   case ISD::FSQRT:
   case ISD::FSIN:
   case ISD::FCOS: {
-    const char *FnName = 0;
+    RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
     switch(Node->getOpcode()) {
-    case ISD::FSQRT: FnName = (VT == MVT::f32) ? "sqrtf" : "sqrt"; break;
-    case ISD::FSIN:  FnName = (VT == MVT::f32) ? "sinf"  : "sin";  break;
-    case ISD::FCOS:  FnName = (VT == MVT::f32) ? "cosf"  : "cos";  break;
+    case ISD::FSQRT:
+      LC = (VT == MVT::f32) ? RTLIB::SQRT_F32 : RTLIB::SQRT_F64;
+      break;
+    case ISD::FSIN:
+      LC = (VT == MVT::f32) ? RTLIB::SIN_F32 : RTLIB::SIN_F64;
+      break;
+    case ISD::FCOS:
+      LC = (VT == MVT::f32) ? RTLIB::COS_F32 : RTLIB::COS_F64;
+      break;
     default: assert(0 && "Unreachable!");
     }
-    Lo = ExpandLibCall(FnName, Node, false, Hi);
+    Lo = ExpandLibCall(TLI.getLibcallName(LC), Node, false, Hi);
     break;
   }
   case ISD::FABS: {
@@ -5166,17 +5212,17 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){
   case ISD::UINT_TO_FP: {
     bool isSigned = Node->getOpcode() == ISD::SINT_TO_FP;
     MVT::ValueType SrcVT = Node->getOperand(0).getValueType();
-    const char *FnName = 0;
+    RTLIB::Libcall LC;
     if (Node->getOperand(0).getValueType() == MVT::i64) {
       if (VT == MVT::f32)
-        FnName = isSigned ? "__floatdisf" : "__floatundisf";
+        LC = isSigned ? RTLIB::SINTTOFP_I64_F32 : RTLIB::UINTTOFP_I64_F32;
       else
-        FnName = isSigned ? "__floatdidf" : "__floatundidf";
+        LC = isSigned ? RTLIB::SINTTOFP_I64_F64 : RTLIB::UINTTOFP_I64_F64;
     } else {
       if (VT == MVT::f32)
-        FnName = isSigned ? "__floatsisf" : "__floatunsisf";
+        LC = isSigned ? RTLIB::SINTTOFP_I32_F32 : RTLIB::UINTTOFP_I32_F32;
       else
-        FnName = isSigned ? "__floatsidf" : "__floatunsidf";
+        LC = isSigned ? RTLIB::SINTTOFP_I32_F64 : RTLIB::UINTTOFP_I32_F64;
     }
 
     // Promote the operand if needed.
@@ -5188,7 +5234,7 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){
         : DAG.getZeroExtendInReg(Tmp, SrcVT);
       Node = DAG.UpdateNodeOperands(Op, Tmp).Val;
     }
-    Lo = ExpandLibCall(FnName, Node, isSigned, Hi);
+    Lo = ExpandLibCall(TLI.getLibcallName(LC), Node, isSigned, Hi);
     break;
   }
   }
index 79e8013e4f585e3fc1c349f6e788a3b07e2a6abc..7b4a67845803f6e367c3a76b39faf758cf87629f 100644 (file)
 #include "llvm/Support/MathExtras.h"
 using namespace llvm;
 
+/// InitLibcallNames - Set default libcall names.
+///
+static void InitLibcallNames(std::string *Names) {
+  Names[RTLIB::SHL_I32] = "__ashlsi3";
+  Names[RTLIB::SHL_I64] = "__ashldi3";
+  Names[RTLIB::SRL_I32] = "__lshrsi3";
+  Names[RTLIB::SRL_I64] = "__lshrdi3";
+  Names[RTLIB::SRA_I32] = "__ashrsi3";
+  Names[RTLIB::SRA_I64] = "__ashrdi3";
+  Names[RTLIB::MUL_I32] = "__mulsi3";
+  Names[RTLIB::MUL_I64] = "__muldi3";
+  Names[RTLIB::SDIV_I32] = "__divsi3";
+  Names[RTLIB::SDIV_I64] = "__divdi3";
+  Names[RTLIB::UDIV_I32] = "__udivsi3";
+  Names[RTLIB::UDIV_I64] = "__udivdi3";
+  Names[RTLIB::SREM_I32] = "__modsi3";
+  Names[RTLIB::SREM_I64] = "__moddi3";
+  Names[RTLIB::UREM_I32] = "__umodsi3";
+  Names[RTLIB::UREM_I64] = "__umoddi3";
+  Names[RTLIB::NEG_I32] = "__negsi2";
+  Names[RTLIB::NEG_I64] = "__negdi2";
+  Names[RTLIB::ADD_F32] = "__addsf3";
+  Names[RTLIB::ADD_F64] = "__adddf3";
+  Names[RTLIB::SUB_F32] = "__subsf3";
+  Names[RTLIB::SUB_F64] = "__subdf3";
+  Names[RTLIB::MUL_F32] = "__mulsf3";
+  Names[RTLIB::MUL_F64] = "__muldf3";
+  Names[RTLIB::DIV_F32] = "__divsf3";
+  Names[RTLIB::DIV_F64] = "__divdf3";
+  Names[RTLIB::REM_F32] = "fmodf";
+  Names[RTLIB::REM_F64] = "fmod";
+  Names[RTLIB::NEG_F32] = "__negsf2";
+  Names[RTLIB::NEG_F64] = "__negdf2";
+  Names[RTLIB::POWI_F32] = "__powisf2";
+  Names[RTLIB::POWI_F64] = "__powidf2";
+  Names[RTLIB::SQRT_F32] = "sqrtf";
+  Names[RTLIB::SQRT_F64] = "sqrt";
+  Names[RTLIB::SIN_F32] = "sinf";
+  Names[RTLIB::SIN_F64] = "sin";
+  Names[RTLIB::COS_F32] = "cosf";
+  Names[RTLIB::COS_F64] = "cos";
+  Names[RTLIB::FPEXT_F32_F64] = "__extendsfdf2";
+  Names[RTLIB::FPROUND_F64_F32] = "__truncdfsf2";
+  Names[RTLIB::FPTOSINT_F32_I32] = "__fixsfsi";
+  Names[RTLIB::FPTOSINT_F32_I64] = "__fixsfdi";
+  Names[RTLIB::FPTOSINT_F64_I32] = "__fixdfsi";
+  Names[RTLIB::FPTOSINT_F64_I64] = "__fixdfdi";
+  Names[RTLIB::FPTOUINT_F32_I32] = "__fixunssfsi";
+  Names[RTLIB::FPTOUINT_F32_I64] = "__fixunssfdi";
+  Names[RTLIB::FPTOUINT_F64_I32] = "__fixunsdfsi";
+  Names[RTLIB::FPTOUINT_F64_I64] = "__fixunsdfdi";
+  Names[RTLIB::SINTTOFP_I32_F32] = "__floatsisf";
+  Names[RTLIB::SINTTOFP_I32_F64] = "__floatsidf";
+  Names[RTLIB::SINTTOFP_I64_F32] = "__floatdisf";
+  Names[RTLIB::SINTTOFP_I64_F64] = "__floatdidf";
+  Names[RTLIB::UINTTOFP_I32_F32] = "__floatunsisf";
+  Names[RTLIB::UINTTOFP_I32_F64] = "__floatunsidf";
+  Names[RTLIB::UINTTOFP_I64_F32] = "__floatundisf";
+  Names[RTLIB::UINTTOFP_I64_F64] = "__floatundidf";
+  Names[RTLIB::OEQ_F32] = "__eqsf2";
+  Names[RTLIB::OEQ_F64] = "__eqdf2";
+  Names[RTLIB::UNE_F32] = "__nesf2";
+  Names[RTLIB::UNE_F64] = "__nedf2";
+  Names[RTLIB::OGE_F32] = "__gesf2";
+  Names[RTLIB::OGE_F64] = "__gedf2";
+  Names[RTLIB::OLT_F32] = "__ltsf2";
+  Names[RTLIB::OLT_F64] = "__ltdf2";
+  Names[RTLIB::OLE_F32] = "__lesf2";
+  Names[RTLIB::OLE_F64] = "__ledf2";
+  Names[RTLIB::OGT_F32] = "__gtsf2";
+  Names[RTLIB::OGT_F64] = "__gtdf2";
+  Names[RTLIB::UO_F32] = "__unordsf2";
+  Names[RTLIB::UO_F64] = "__unorddf2";
+}
+
 TargetLowering::TargetLowering(TargetMachine &tm)
   : TM(tm), TD(TM.getTargetData()) {
   assert(ISD::BUILTIN_OP_END <= 156 &&
@@ -55,6 +130,8 @@ TargetLowering::TargetLowering(TargetMachine &tm)
   SchedPreferenceInfo = SchedulingForLatency;
   JumpBufSize = 0;
   JumpBufAlignment = 0;
+
+  InitLibcallNames(LibcallRoutineNames);
 }
 
 TargetLowering::~TargetLowering() {}