[mips] Fix MipsTargetLowering::LowerCall to pass fp128 arguments in floating
authorAkira Hatanaka <ahatanaka@mips.com>
Tue, 5 Mar 2013 22:20:28 +0000 (22:20 +0000)
committerAkira Hatanaka <ahatanaka@mips.com>
Tue, 5 Mar 2013 22:20:28 +0000 (22:20 +0000)
point registers.

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

lib/Target/Mips/MipsISelLowering.cpp
lib/Target/Mips/MipsISelLowering.h
test/CodeGen/Mips/mips64-call.ll

index b52bf71655c3df29183ea83c54da7c517a161301..e48336986554bbf4bcf2d8c6b00725c3532235d5 100644 (file)
@@ -3362,7 +3362,9 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
                  getTargetMachine(), ArgLocs, *DAG.getContext());
   MipsCC MipsCCInfo(CallConv, IsO32, CCInfo);
 
-  MipsCCInfo.analyzeCallOperands(Outs, isVarArg);
+  MipsCCInfo.analyzeCallOperands(Outs, isVarArg,
+                                 getTargetMachine().Options.UseSoftFloat,
+                                 Callee.getNode(), CLI.Args);
 
   // Get a count of how many bytes are to be pushed on the stack.
   unsigned NextStackOffset = CCInfo.getNextStackOffset();
@@ -3421,7 +3423,8 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
     case CCValAssign::Full:
       if (VA.isRegLoc()) {
         if ((ValVT == MVT::f32 && LocVT == MVT::i32) ||
-            (ValVT == MVT::f64 && LocVT == MVT::i64))
+            (ValVT == MVT::f64 && LocVT == MVT::i64) ||
+            (ValVT == MVT::i64 && LocVT == MVT::f64))
           Arg = DAG.getNode(ISD::BITCAST, dl, LocVT, Arg);
         else if (ValVT == MVT::f64 && LocVT == MVT::i32) {
           SDValue Lo = DAG.getNode(MipsISD::ExtractElementF64, dl, MVT::i32,
@@ -4144,7 +4147,8 @@ MipsTargetLowering::MipsCC::MipsCC(CallingConv::ID CC, bool IsO32_,
 
 void MipsTargetLowering::MipsCC::
 analyzeCallOperands(const SmallVectorImpl<ISD::OutputArg> &Args,
-                    bool IsVarArg) {
+                    bool IsVarArg, bool IsSoftFloat, const SDNode *CallNode,
+                    std::vector<ArgListEntry> &FuncArgs) {
   assert((CallConv != CallingConv::Fast || !IsVarArg) &&
          "CallingConv::Fast shouldn't be used for vararg functions.");
 
@@ -4163,8 +4167,11 @@ analyzeCallOperands(const SmallVectorImpl<ISD::OutputArg> &Args,
 
     if (IsVarArg && !Args[I].IsFixed)
       R = VarFn(I, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, CCInfo);
-    else
-      R = FixedFn(I, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, CCInfo);
+    else {
+      MVT RegVT = getRegVT(ArgVT, FuncArgs[Args[I].OrigArgIndex].Ty, CallNode,
+                           IsSoftFloat);
+      R = FixedFn(I, ArgVT, RegVT, CCValAssign::Full, ArgFlags, CCInfo);
+    }
 
     if (R) {
 #ifndef NDEBUG
index 22751694bb3fca52968ecb82725c7183f41dec76..ee40232ca6678ca25d1bfc8ec4a84a690f816ddd 100644 (file)
@@ -205,7 +205,9 @@ namespace llvm {
       MipsCC(CallingConv::ID CallConv, bool IsO32, CCState &Info);
 
       void analyzeCallOperands(const SmallVectorImpl<ISD::OutputArg> &Outs,
-                               bool IsVarArg);
+                               bool IsVarArg, bool IsSoftFloat,
+                               const SDNode *CallNode,
+                               std::vector<ArgListEntry> &FuncArgs);
       void analyzeFormalArguments(const SmallVectorImpl<ISD::InputArg> &Ins,
                                   bool IsSoftFloat,
                                   Function::const_arg_iterator FuncArg);
index 7808ac3cc063f056b42e0c7be5f96bf88e7c643c..ea64ec24579fc9b6d3d4a1dc49bacfaa200faedd 100644 (file)
@@ -11,3 +11,16 @@ entry:
   store fp128 %a0, fp128* @gld0, align 16
   ret void
 }
+
+; CHECK: foo1
+; CHECK: ldc1  $f13, 8(${{[0-9]+}})
+; CHECK: ldc1  $f12, 0(${{[0-9]+}})
+
+define void @foo1() {
+entry:
+  %0 = load fp128* @gld0, align 16
+  tail call void @foo2(fp128 %0)
+  ret void
+}
+
+declare void @foo2(fp128)