}
else
#endif // defined(_TARGET_X86_)
- if (call->gtCallType == CT_INDIRECT && call->gtCallCookie)
+ if (call->gtCallType == CT_INDIRECT && (call->gtCallCookie != nullptr))
{
assert(!call->IsUnmanaged());
noway_assert(arg != nullptr);
call->gtCallCookie = nullptr;
+#if defined(_TARGET_X86_)
+ // x86 passes the cookie on the stack as the final argument to the call.
+ GenTreeArgList** insertionPoint = &call->gtCallArgs;
+ for (; *insertionPoint != nullptr; insertionPoint = &(*insertionPoint)->Rest())
+ {
+ }
+ *insertionPoint = gtNewListNode(arg, nullptr);
+#else // !defined(_TARGET_X86_)
+ // All other architectures pass the cookie in a register.
call->gtCallArgs = gtNewListNode(arg, call->gtCallArgs);
- numArgs++;
-
- // x86 passes the cookie on the stack.
- CLANG_FORMAT_COMMENT_ANCHOR;
+#endif // defined(_TARGET_X86_)
-#if !defined(_TARGET_X86_)
- // put cookie into R11
nonStandardArgs.Add(arg, REG_PINVOKE_COOKIE_PARAM);
-#endif // !defined(_TARGET_X86_)
+ numArgs++;
// put destination into R10/EAX
arg = gtClone(call->gtCallAddr, true);
compFloatingPointUsed = true;
}
- unsigned size = 0;
- CORINFO_CLASS_HANDLE copyBlkClass = nullptr;
- bool isRegArg = false;
+ unsigned size = 0;
+ CORINFO_CLASS_HANDLE copyBlkClass = nullptr;
+ bool isRegArg = false;
+ bool isNonStandard = false;
+ regNumber nonStdRegNum = REG_NA;
fgArgTabEntryPtr argEntry = nullptr;
}
}
#else // !FEATURE_UNIX_AMD64_STRUCT_PASSING
- size = 1; // On AMD64, all primitives fit in a single (64-bit) 'slot'
+ size = 1; // On AMD64, all primitives fit in a single (64-bit) 'slot'
#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
#elif defined(_TARGET_ARM64_)
if (isStructArg)
isRegArg = false;
}
-#if defined(_TARGET_X86_) && !defined(LEGACY_BACKEND)
- if (call->IsTailCallViaHelper())
+#ifndef LEGACY_BACKEND
+ // If there are nonstandard args (outside the calling convention) they were inserted above
+ // and noted them in a table so we can recognize them here and build their argInfo.
+ //
+ // They should not affect the placement of any other args or stack space required.
+ // Example: on AMD64 R10 and R11 are used for indirect VSD (generic interface) and cookie calls.
+ isNonStandard = nonStandardArgs.FindReg(argx, &nonStdRegNum);
+ if (isNonStandard && (nonStdRegNum == REG_STK))
+ {
+ isRegArg = false;
+ }
+#if defined(_TARGET_X86_)
+ else if (call->IsTailCallViaHelper())
{
// We have already (before calling fgMorphArgs()) appended the 4 special args
// required by the x86 tailcall helper. These args are required to go on the
isRegArg = false;
}
}
-#endif // defined(_TARGET_X86_) && !defined(LEGACY_BACKEND)
-
+#endif // defined(_TARGET_X86_)
+#endif // !LEGACY_BACKEND
} // end !reMorphing
//
}
else
{
- bool isNonStandard = false;
-
-#ifndef LEGACY_BACKEND
- // If there are nonstandard args (outside the calling convention) they were inserted above
- // and noted them in a table so we can recognize them here and build their argInfo.
- //
- // They should not affect the placement of any other args or stack space required.
- // Example: on AMD64 R10 and R11 are used for indirect VSD (generic interface) and cookie calls.
- isNonStandard = nonStandardArgs.FindReg(argx, &nextRegNum);
-#endif // !LEGACY_BACKEND
+ if (isNonStandard)
+ {
+ nextRegNum = nonStdRegNum;
+ }
// This is a register argument - put it in the table
newArgEntry = call->fgArgInfo->AddRegArg(argIndex, argx, args, nextRegNum, size, argAlign