[mips] Move F128 argument handling into MipsCCState as we did for returns. NFC.
authorDaniel Sanders <daniel.sanders@imgtec.com>
Sat, 1 Nov 2014 18:38:03 +0000 (18:38 +0000)
committerDaniel Sanders <daniel.sanders@imgtec.com>
Sat, 1 Nov 2014 18:38:03 +0000 (18:38 +0000)
Summary:
There are a couple more changes to make before analyzeFormalArguments can
be merged into the standard AnalyzeFormalArguments. I've had to temporarily
poke a couple holes in MipsCCState's encapsulation to save having to make
all the required changes for this merge all at once*. These will be removed
shortly.

* We must merge our ByVal argument handling with the implementation in CCState.
  This will be done over the next three patches, then the fourth will merge
  analyzeFormalArguments with AnalyzeFormalArguments.

Depends on D5967

Reviewers: vmedic

Reviewed By: vmedic

Subscribers: llvm-commits

Differential Revision: http://reviews.llvm.org/D5969

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

lib/Target/Mips/MipsCallingConv.td
lib/Target/Mips/MipsISelLowering.cpp
lib/Target/Mips/MipsISelLowering.h

index a2130bb..ae1b01b 100644 (file)
@@ -298,6 +298,21 @@ def RetCC_Mips : CallingConv<[
 ]>;
 
 def CC_Mips_FixedArg : CallingConv<[
+  // f128 needs to be handled similarly to f32 and f64 on hard-float. However,
+  // f128 is not legal and is lowered to i128 which is further lowered to a pair
+  // of i64's.
+  // This presents us with a problem for the calling convention since hard-float
+  // still needs to pass them in FPU registers. We therefore resort to a
+  // pre-analyze (see PreAnalyzeFormalArgsForF128()) step to pass information on
+  // whether the argument was originally an f128 into the tablegen-erated code.
+  //
+  // f128 should only occur for the N64 ABI where long double is 128-bit. On
+  // N32, long double is equivalent to double.
+  CCIfType<[i64],
+      CCIfSubtargetNot<"abiUsesSoftFloat()",
+          CCIf<"static_cast<MipsCCState *>(&State)->WasOriginalArgF128(ValNo)",
+              CCBitConvertToType<f64>>>>,
+
   CCIfCC<"CallingConv::Fast", CCDelegateTo<CC_Mips_FastCC>>,
 
   // FIXME: There wasn't an EABI case in the original code and it seems unlikely
index 8bc2160..5b87111 100644 (file)
@@ -95,10 +95,52 @@ private:
           originalTypeIsF128(MF.getFunction()->getReturnType(), nullptr));
   }
 
+  /// Identify lowered values that originated from f128 arguments and record
+  /// this.
+  void PreAnalyzeCallOperandsForF128(
+      const SmallVectorImpl<ISD::OutputArg> &Outs,
+      std::vector<TargetLowering::ArgListEntry> &FuncArgs, SDNode *CallNode) {
+    const MachineFunction &MF = getMachineFunction();
+    for (unsigned i = 0; i < Outs.size(); ++i)
+      OriginalArgWasF128.push_back(
+          originalTypeIsF128(FuncArgs[Outs[i].OrigArgIndex].Ty, CallNode));
+  }
+
+  /// Identify lowered values that originated from f128 arguments and record
+  /// this.
+  void
+  PreAnalyzeFormalArgumentsForF128(const SmallVectorImpl<ISD::InputArg> &Ins) {
+    const MachineFunction &MF = getMachineFunction();
+    for (unsigned i = 0; i < Ins.size(); ++i) {
+      Function::const_arg_iterator FuncArg = MF.getFunction()->arg_begin();
+      std::advance(FuncArg, Ins[i].OrigArgIndex);
+
+      OriginalArgWasF128.push_back(
+          originalTypeIsF128(FuncArg->getType(), nullptr));
+    }
+  }
+
   /// Records whether the value has been lowered from an f128.
   SmallVector<bool, 4> OriginalArgWasF128;
 
 public:
+  // FIXME: Remove this from a public inteface ASAP. It's a temporary trap door
+  //        to allow analyzeCallOperands to be removed incrementally.
+  void PreAnalyzeCallOperandsForF128_(
+      const SmallVectorImpl<ISD::OutputArg> &Outs,
+      std::vector<TargetLowering::ArgListEntry> &FuncArgs, SDNode *CallNode) {
+    PreAnalyzeCallOperandsForF128(Outs, FuncArgs, CallNode);
+  }
+  // FIXME: Remove this from a public inteface ASAP. It's a temporary trap door
+  //        to allow analyzeFormalArguments to be removed incrementally.
+  void
+  PreAnalyzeFormalArgumentsForF128_(const SmallVectorImpl<ISD::InputArg> &Ins) {
+    PreAnalyzeFormalArgumentsForF128(Ins);
+  }
+  // FIXME: Remove this from a public inteface ASAP. It's a temporary trap door
+  //        to clean up after the above functions.
+  void ClearOriginalArgWasF128() { OriginalArgWasF128.clear(); }
+
   MipsCCState(CallingConv::ID CC, bool isVarArg, MachineFunction &MF,
               SmallVectorImpl<CCValAssign> &locs, LLVMContext &C)
       : CCState(CC, isVarArg, MF, locs, C) {}
@@ -2546,12 +2588,14 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
 
   // Analyze operands of the call, assigning locations to each operand.
   SmallVector<CCValAssign, 16> ArgLocs;
-  CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), ArgLocs,
-                 *DAG.getContext());
+  MipsCCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), ArgLocs,
+                     *DAG.getContext());
   MipsCC MipsCCInfo(CallConv, Subtarget, CCInfo);
 
+  CCInfo.PreAnalyzeCallOperandsForF128_(Outs, CLI.getArgs(), Callee.getNode());
   MipsCCInfo.analyzeCallOperands(Outs, IsVarArg, Subtarget.abiUsesSoftFloat(),
                                  Callee.getNode(), CLI.getArgs(), CCInfo);
+  CCInfo.ClearOriginalArgWasF128();
 
   // Get a count of how many bytes are to be pushed on the stack.
   unsigned NextStackOffset = CCInfo.getNextStackOffset();
@@ -2632,6 +2676,9 @@ MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
         }
       }
       break;
+    case CCValAssign::BCvt:
+      Arg = DAG.getNode(ISD::BITCAST, DL, LocVT, Arg);
+      break;
     case CCValAssign::SExt:
       Arg = DAG.getNode(ISD::SIGN_EXTEND, DL, LocVT, Arg);
       break;
@@ -2829,14 +2876,16 @@ MipsTargetLowering::LowerFormalArguments(SDValue Chain,
 
   // Assign locations to all of the incoming arguments.
   SmallVector<CCValAssign, 16> ArgLocs;
-  CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), ArgLocs,
-                 *DAG.getContext());
+  MipsCCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), ArgLocs,
+                     *DAG.getContext());
   MipsCC MipsCCInfo(CallConv, Subtarget, CCInfo);
   Function::const_arg_iterator FuncArg =
     DAG.getMachineFunction().getFunction()->arg_begin();
   bool UseSoftFloat = Subtarget.abiUsesSoftFloat();
 
-  MipsCCInfo.analyzeFormalArguments(Ins, UseSoftFloat, FuncArg, CCInfo);
+  CCInfo.PreAnalyzeFormalArgumentsForF128_(Ins);
+  MipsCCInfo.analyzeFormalArguments(Ins, UseSoftFloat, CCInfo);
+  CCInfo.ClearOriginalArgWasF128();
   MipsFI->setFormalArgInfo(CCInfo.getNextStackOffset(),
                            MipsCCInfo.hasByValArg());
 
@@ -2875,16 +2924,24 @@ MipsTargetLowering::LowerFormalArguments(SDValue Chain,
       // If this is an 8 or 16-bit value, it has been passed promoted
       // to 32 bits.  Insert an assert[sz]ext to capture this, then
       // truncate to the right size.
-      if (VA.getLocInfo() != CCValAssign::Full) {
-        unsigned Opcode = 0;
-        if (VA.getLocInfo() == CCValAssign::SExt)
-          Opcode = ISD::AssertSext;
-        else if (VA.getLocInfo() == CCValAssign::ZExt)
-          Opcode = ISD::AssertZext;
-        if (Opcode)
-          ArgValue = DAG.getNode(Opcode, DL, RegVT, ArgValue,
-                                 DAG.getValueType(ValVT));
+      switch (VA.getLocInfo()) {
+      default:
+        llvm_unreachable("Unknown loc info!");
+      case CCValAssign::Full:
+        break;
+      case CCValAssign::SExt:
+        ArgValue = DAG.getNode(ISD::AssertSext, DL, RegVT, ArgValue,
+                               DAG.getValueType(ValVT));
+        ArgValue = DAG.getNode(ISD::TRUNCATE, DL, ValVT, ArgValue);
+        break;
+      case CCValAssign::ZExt:
+        ArgValue = DAG.getNode(ISD::AssertZext, DL, RegVT, ArgValue,
+                               DAG.getValueType(ValVT));
         ArgValue = DAG.getNode(ISD::TRUNCATE, DL, ValVT, ArgValue);
+        break;
+      case CCValAssign::BCvt:
+        ArgValue = DAG.getNode(ISD::BITCAST, DL, ValVT, ArgValue);
+        break;
       }
 
       // Handle floating point arguments passed in integer registers and
@@ -3563,11 +3620,8 @@ void MipsTargetLowering::MipsCC::analyzeCallOperands(
 
     if (IsVarArg && !Args[I].IsFixed)
       R = CC_Mips_VarArg(I, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, State);
-    else {
-      MVT RegVT = getRegVT(ArgVT, FuncArgs[Args[I].OrigArgIndex].Ty, CallNode,
-                           IsSoftFloat);
-      R = FixedFn(I, ArgVT, RegVT, CCValAssign::Full, ArgFlags, State);
-    }
+    else
+      R = FixedFn(I, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, State);
 
     if (R) {
 #ifndef NDEBUG
@@ -3581,24 +3635,19 @@ void MipsTargetLowering::MipsCC::analyzeCallOperands(
 
 void MipsTargetLowering::MipsCC::analyzeFormalArguments(
     const SmallVectorImpl<ISD::InputArg> &Args, bool IsSoftFloat,
-    Function::const_arg_iterator FuncArg, CCState &State) {
+    CCState &State) {
   unsigned NumArgs = Args.size();
-  unsigned CurArgIdx = 0;
 
   for (unsigned I = 0; I != NumArgs; ++I) {
     MVT ArgVT = Args[I].VT;
     ISD::ArgFlagsTy ArgFlags = Args[I].Flags;
-    std::advance(FuncArg, Args[I].OrigArgIndex - CurArgIdx);
-    CurArgIdx = Args[I].OrigArgIndex;
 
     if (ArgFlags.isByVal()) {
       handleByValArg(I, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, State);
       continue;
     }
 
-    MVT RegVT = getRegVT(ArgVT, FuncArg->getType(), nullptr, IsSoftFloat);
-
-    if (!CC_Mips_FixedArg(I, ArgVT, RegVT, CCValAssign::Full, ArgFlags, State))
+    if (!CC_Mips_FixedArg(I, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, State))
       continue;
 
 #ifndef NDEBUG
index 1b48725..3c7d683 100644 (file)
@@ -366,7 +366,6 @@ namespace llvm {
                                CCState &State);
       void analyzeFormalArguments(const SmallVectorImpl<ISD::InputArg> &Ins,
                                   bool IsSoftFloat,
-                                  Function::const_arg_iterator FuncArg,
                                   CCState &State);
 
       /// hasByValArg - Returns true if function has byval arguments.