[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 a2130bb67a0befb5076e9c119c260360b013efe7..ae1b01b4019dab6dfece8bc6cf239db00a153416 100644 (file)
@@ -298,6 +298,21 @@ def RetCC_Mips : CallingConv<[
 ]>;
 
 def CC_Mips_FixedArg : 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
   CCIfCC<"CallingConv::Fast", CCDelegateTo<CC_Mips_FastCC>>,
 
   // FIXME: There wasn't an EABI case in the original code and it seems unlikely
index 8bc216021ad334ad01a03331fbc22f303f2e266d..5b87111d5add9495122fe40c2ae2e65207b4a60c 100644 (file)
@@ -95,10 +95,52 @@ private:
           originalTypeIsF128(MF.getFunction()->getReturnType(), nullptr));
   }
 
           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:
   /// 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) {}
   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;
 
   // 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);
 
   MipsCC MipsCCInfo(CallConv, Subtarget, CCInfo);
 
+  CCInfo.PreAnalyzeCallOperandsForF128_(Outs, CLI.getArgs(), Callee.getNode());
   MipsCCInfo.analyzeCallOperands(Outs, IsVarArg, Subtarget.abiUsesSoftFloat(),
                                  Callee.getNode(), CLI.getArgs(), CCInfo);
   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();
 
   // 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;
         }
       }
       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;
     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;
 
   // 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();
 
   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());
 
   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 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);
         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
       }
 
       // 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);
 
     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
 
     if (R) {
 #ifndef NDEBUG
@@ -3581,24 +3635,19 @@ void MipsTargetLowering::MipsCC::analyzeCallOperands(
 
 void MipsTargetLowering::MipsCC::analyzeFormalArguments(
     const SmallVectorImpl<ISD::InputArg> &Args, bool IsSoftFloat,
 
 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 NumArgs = Args.size();
-  unsigned CurArgIdx = 0;
 
   for (unsigned I = 0; I != NumArgs; ++I) {
     MVT ArgVT = Args[I].VT;
     ISD::ArgFlagsTy ArgFlags = Args[I].Flags;
 
   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;
     }
 
 
     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
       continue;
 
 #ifndef NDEBUG
index 1b4872528d4a69f8a327570df28fb8cd4dbfd941..3c7d683c7714adf864ca11cd07817bffbe688a25 100644 (file)
@@ -366,7 +366,6 @@ namespace llvm {
                                CCState &State);
       void analyzeFormalArguments(const SmallVectorImpl<ISD::InputArg> &Ins,
                                   bool IsSoftFloat,
                                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.
                                   CCState &State);
 
       /// hasByValArg - Returns true if function has byval arguments.