]> granicus.if.org Git - llvm/commitdiff
Merged from r221056:
authorDaniel Sanders <daniel.sanders@imgtec.com>
Mon, 1 Dec 2014 15:24:14 +0000 (15:24 +0000)
committerDaniel Sanders <daniel.sanders@imgtec.com>
Mon, 1 Dec 2014 15:24:14 +0000 (15:24 +0000)
[mips] Move F128 argument handling into MipsCCState as we did for returns. NFC.

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.

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/branches/release_35@223034 91177308-0d34-0410-b5e6-96231b3b80d8

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

index 37f861949af80e55c8c6ba3357ecafbd4b0a21a9..0790163b13bff27b073f93c6f1d1a089116a7de6 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 fae7d391491b2dfc8accc954c76ebd39b7cc4e79..6ca199465967d9f00224690d170fae84a0c68a46 100644 (file)
@@ -94,10 +94,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,
               const TargetMachine &TM, SmallVectorImpl<CCValAssign> &locs, LLVMContext &C)
       : CCState(CC, isVarArg, MF, TM, locs, C) {}
@@ -2531,12 +2573,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(),
-                 getTargetMachine(), ArgLocs, *DAG.getContext());
+  MipsCCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(),
+                     getTargetMachine(), 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();
@@ -2617,6 +2661,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;
@@ -2808,14 +2855,16 @@ MipsTargetLowering::LowerFormalArguments(SDValue Chain,
 
   // Assign locations to all of the incoming arguments.
   SmallVector<CCValAssign, 16> ArgLocs;
-  CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(),
-                 getTargetMachine(), ArgLocs, *DAG.getContext());
+  MipsCCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(),
+                     getTargetMachine(), 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());
 
@@ -2854,16 +2903,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
@@ -3543,11 +3600,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
@@ -3561,24 +3615,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 a98a69932bb38a97a8fea02f509b1b07423720af..81113bc7be50b913aa1b434c53c7ce5e7d2549b3 100644 (file)
@@ -365,7 +365,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.