+static bool originalTypeIsF128(const Type *Ty, const SDNode *CallNode);
+
+namespace {
+class MipsCCState : public CCState {
+private:
+ /// Identify lowered values that originated from f128 arguments and record
+ /// this for use by RetCC_MipsN.
+ void
+ PreAnalyzeCallResultForF128(const SmallVectorImpl<ISD::InputArg> &Ins,
+ const TargetLowering::CallLoweringInfo &CLI) {
+ for (unsigned i = 0; i < Ins.size(); ++i)
+ OriginalArgWasF128.push_back(
+ originalTypeIsF128(CLI.RetTy, CLI.Callee.getNode()));
+ }
+
+ /// Identify lowered values that originated from f128 arguments and record
+ /// this for use by RetCC_MipsN.
+ void PreAnalyzeReturnForF128(const SmallVectorImpl<ISD::OutputArg> &Outs) {
+ const MachineFunction &MF = getMachineFunction();
+ for (unsigned i = 0; i < Outs.size(); ++i)
+ OriginalArgWasF128.push_back(
+ 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) {
+ 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) {}
+
+ void AnalyzeCallResult(const SmallVectorImpl<ISD::InputArg> &Ins,
+ CCAssignFn Fn,
+ const TargetLowering::CallLoweringInfo &CLI) {
+ PreAnalyzeCallResultForF128(Ins, CLI);
+ CCState::AnalyzeCallResult(Ins, Fn);
+ OriginalArgWasF128.clear();
+ }
+
+ void AnalyzeReturn(const SmallVectorImpl<ISD::OutputArg> &Outs,
+ CCAssignFn Fn) {
+ PreAnalyzeReturnForF128(Outs);
+ CCState::AnalyzeReturn(Outs, Fn);
+ OriginalArgWasF128.clear();
+ }
+
+ bool CheckReturn(const SmallVectorImpl<ISD::OutputArg> &ArgsFlags,
+ CCAssignFn Fn) {
+ PreAnalyzeReturnForF128(ArgsFlags);
+ bool Return = CCState::CheckReturn(ArgsFlags, Fn);
+ OriginalArgWasF128.clear();
+ return Return;
+ }
+
+ bool WasOriginalArgF128(unsigned ValNo) { return OriginalArgWasF128[ValNo]; }
+};
+}
+