[llvm] r176527 - [mips] Fix MipsCC::analyzeReturn so that, in soft-float mode, fp128 gets

Akira Hatanaka ahatanaka at mips.com
Tue Mar 5 14:54:59 PST 2013


Author: ahatanak
Date: Tue Mar  5 16:54:59 2013
New Revision: 176527

URL: http://llvm.org/viewvc/llvm-project?rev=176527&view=rev
Log:
[mips] Fix MipsCC::analyzeReturn so that, in soft-float mode, fp128 gets
returned in registers $2 and $4.


Modified:
    llvm/trunk/lib/Target/Mips/MipsCallingConv.td
    llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp
    llvm/trunk/test/CodeGen/Mips/mips64-f128.ll

Modified: llvm/trunk/lib/Target/Mips/MipsCallingConv.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsCallingConv.td?rev=176527&r1=176526&r2=176527&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsCallingConv.td (original)
+++ llvm/trunk/lib/Target/Mips/MipsCallingConv.td Tue Mar  5 16:54:59 2013
@@ -96,6 +96,12 @@ def RetCC_MipsN : CallingConv<[
   CCIfType<[f64], CCAssignToReg<[D0_64, D2_64]>>
 ]>;
 
+// In soft-mode, register A0_64, instead of V1_64, is used to return a long
+// double value.
+def RetCC_F128Soft : CallingConv<[
+  CCIfType<[i64], CCAssignToReg<[V0_64, A0_64]>>
+]>;
+
 //===----------------------------------------------------------------------===//
 // Mips EABI Calling Convention
 //===----------------------------------------------------------------------===//

Modified: llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp?rev=176527&r1=176526&r2=176527&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp Tue Mar  5 16:54:59 2013
@@ -4152,6 +4152,46 @@ unsigned MipsTargetLowering::getJumpTabl
   return TargetLowering::getJumpTableEncoding();
 }
 
+/// This function returns true if CallSym is a long double emulation routine.
+static bool isF128SoftLibCall(const char *CallSym) {
+  const char *const LibCalls[] =
+    {"__addtf3", "__divtf3", "__eqtf2", "__extenddftf2", "__extendsftf2",
+     "__fixtfdi", "__fixtfsi", "__fixtfti", "__fixunstfdi", "__fixunstfsi",
+     "__fixunstfti", "__floatditf", "__floatsitf", "__floattitf",
+     "__floatunditf", "__floatunsitf", "__floatuntitf", "__getf2", "__gttf2",
+     "__letf2", "__lttf2", "__multf3", "__netf2", "__powitf2", "__subtf3",
+     "__trunctfdf2", "__trunctfsf2", "__unordtf2",
+     "ceill", "copysignl", "cosl", "exp2l", "expl", "floorl", "fmal", "fmodl",
+     "log10l", "log2l", "logl", "nearbyintl", "powl", "rintl", "sinl", "sqrtl",
+     "truncl"};
+
+  const char * const *End = LibCalls + array_lengthof(LibCalls);
+
+  // Check that LibCalls is sorted alphabetically.
+#ifndef NDEBUG
+  ltstr Comp;
+
+  for (const char * const *I = LibCalls; I < End - 1; ++I)
+    assert(Comp(*I, *(I + 1)));
+#endif
+
+  return std::binary_search(LibCalls, End, CallSym, ltstr());
+}
+
+/// This function returns true if Ty is fp128 or i128 which was originally a
+/// fp128.
+static bool originalTypeIsF128(const Type *Ty, const SDNode *CallNode) {
+  if (Ty->isFP128Ty())
+    return true;
+
+  const ExternalSymbolSDNode *ES =
+    dyn_cast_or_null<const ExternalSymbolSDNode>(CallNode);
+
+  // If the Ty is i128 and the function being called is a long double emulation
+  // routine, then the original type is f128.
+  return (ES && Ty->isIntegerTy(128) && isF128SoftLibCall(ES->getSymbol()));
+}
+
 MipsTargetLowering::MipsCC::MipsCC(CallingConv::ID CC, bool IsO32_,
                                    CCState &Info)
   : CCInfo(Info), CallConv(CC), IsO32(IsO32_) {
@@ -4232,13 +4272,19 @@ template<typename Ty>
 void MipsTargetLowering::MipsCC::
 analyzeReturn(const SmallVectorImpl<Ty> &RetVals, bool IsSoftFloat,
               const SDNode *CallNode, const Type *RetTy) const {
+  CCAssignFn *Fn;
+
+  if (IsSoftFloat && originalTypeIsF128(RetTy, CallNode))
+    Fn = RetCC_F128Soft;
+  else
+    Fn = RetCC_Mips;
+
   for (unsigned I = 0, E = RetVals.size(); I < E; ++I) {
     MVT VT = RetVals[I].VT;
     ISD::ArgFlagsTy Flags = RetVals[I].Flags;
     MVT RegVT = this->getRegVT(VT, RetTy, CallNode, IsSoftFloat);
 
-    if (RetCC_Mips(I, VT, RegVT, CCValAssign::Full, Flags,
-                   this->CCInfo)) {
+    if (Fn(I, VT, RegVT, CCValAssign::Full, Flags, this->CCInfo)) {
 #ifndef NDEBUG
       dbgs() << "Call result #" << I << " has unhandled type "
              << EVT(VT).getEVTString() << '\n';
@@ -4334,33 +4380,6 @@ void MipsTargetLowering::MipsCC::allocat
     CCInfo.AllocateReg(IntArgRegs[I], ShadowRegs[I]);
 }
 
-/// This function returns true if CallSym is a long double emulation routine.
-static bool isF128SoftLibCall(const char *CallSym) {
-  const char *const LibCalls[] =
-    {"__addtf3", "__divtf3", "__eqtf2", "__extenddftf2", "__extendsftf2",
-     "__fixtfdi", "__fixtfsi", "__fixtfti", "__fixunstfdi", "__fixunstfsi",
-     "__fixunstfti", "__floatditf", "__floatsitf", "__floattitf",
-     "__floatunditf", "__floatunsitf", "__floatuntitf", "__getf2", "__gttf2",
-     "__letf2", "__lttf2", "__multf3", "__netf2", "__powitf2", "__subtf3",
-     "__trunctfdf2", "__trunctfsf2", "__unordtf2",
-     "ceill", "copysignl", "cosl", "exp2l", "expl", "floorl", "fmal", "fmodl",
-     "log10l", "log2l", "logl", "nearbyintl", "powl", "rintl", "sinl", "sqrtl",
-     "truncl"};
-
-  const char * const *End = LibCalls + array_lengthof(LibCalls);
-
-  // Check that LibCalls is sorted alphabetically.
-#ifndef NDEBUG
-  ltstr Comp;
-
-  for (const char * const *I = LibCalls; I < End - 1; ++I)
-    assert(Comp(*I, *(I + 1)));
-#endif
-
-  return std::binary_search(LibCalls, End, CallSym, ltstr());
-}
-
-
 MVT MipsTargetLowering::MipsCC::getRegVT(MVT VT, const Type *OrigTy,
                                          const SDNode *CallNode,
                                          bool IsSoftFloat) const {
@@ -4368,17 +4387,7 @@ MVT MipsTargetLowering::MipsCC::getRegVT
     return VT;
 
   // Check if the original type was fp128.
-  if (OrigTy->isFP128Ty()) {
-    assert(VT == MVT::i64);
-    return MVT::f64;
-  }
-
-  const ExternalSymbolSDNode *ES =
-    dyn_cast_or_null<const ExternalSymbolSDNode>(CallNode);
-
-  // If the original type was i128 and the function being called is a long
-  // double emulation routine, the argument must be passed in an f64 register.
-  if (ES && OrigTy->isIntegerTy(128) && isF128SoftLibCall(ES->getSymbol())) {
+  if (originalTypeIsF128(OrigTy, CallNode)) {
     assert(VT == MVT::i64);
     return MVT::f64;
   }

Modified: llvm/trunk/test/CodeGen/Mips/mips64-f128.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Mips/mips64-f128.ll?rev=176527&r1=176526&r2=176527&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/Mips/mips64-f128.ll (original)
+++ llvm/trunk/test/CodeGen/Mips/mips64-f128.ll Tue Mar  5 16:54:59 2013
@@ -236,7 +236,7 @@ entry:
 ; CHECK: daddiu  $[[R1:[0-9]+]], $zero, 1
 ; CHECK: dsll    $[[R2:[0-9]+]], $[[R1]], 63
 ; CHECK: daddiu  $[[R3:[0-9]+]], $[[R2]], -1
-; CHECK: and     $3, $[[R0]], $[[R3]]
+; CHECK: and     $4, $[[R0]], $[[R3]]
 ; CHECK: ld      $2, 0($[[R4]])
 
 define fp128 @libcall1_fabsl() {
@@ -413,7 +413,7 @@ declare fp128 @llvm.powi.f128(fp128, i32
 ; CHECK: ld     $[[R6:[0-9]+]], 8($[[R5]])
 ; CHECK: daddiu $[[R7:[0-9]+]], $[[R3]], -1
 ; CHECK: and    $[[R8:[0-9]+]], $[[R6]], $[[R7]]
-; CHECK: or     $3, $[[R8]], $[[R4]]
+; CHECK: or     $4, $[[R8]], $[[R4]]
 ; CHECK: ld     $2, 0($[[R5]])
 
 define fp128 @libcall2_copysignl() {
@@ -529,7 +529,7 @@ entry:
 ; CHECK: load_LD_LD:
 ; CHECK: ld $[[R0:[0-9]+]], %got_disp(gld1)
 ; CHECK: ld $2, 0($[[R0]])
-; CHECK: ld $3, 8($[[R0]])
+; CHECK: ld $4, 8($[[R0]])
 
 define fp128 @load_LD_LD() {
 entry:
@@ -616,7 +616,7 @@ entry:
 ; CHECK: movn $8, $6, $4
 ; CHECK: movn $9, $7, $4
 ; CHECK: move $2, $8
-; CHECK: move $3, $9
+; CHECK: move $4, $9
 
 define fp128 @select_LD(i32 %a, i64, fp128 %b, fp128 %c) {
 entry:
@@ -636,7 +636,7 @@ entry:
 ; CHECK: movz $[[R1]], $[[R3]], $1
 ; CHECK: movz $[[R0]], $[[R2]], $1
 ; CHECK: move $2, $[[R1]]
-; CHECK: move $3, $[[R0]]
+; CHECK: move $4, $[[R0]]
 
 define fp128 @selectCC_LD(fp128 %a, fp128 %b, fp128 %c, fp128 %d) {
 entry:





More information about the llvm-commits mailing list