GenTree* node;
};
- ArrayStack<NonStandardArg> nonStandardArgs(this, 2);
+ ArrayStack<NonStandardArg> nonStandardArgs(this, 3); // We will have at most 3 non-standard arguments
#endif // !LEGACY_BACKEND
// Process the late arguments (which were determined by a previous caller).
// TODO-X86-CQ: Currently RyuJIT/x86 passes args on the stack, so this is not needed.
// If/when we change that, the following code needs to be changed to correctly support the (TBD) managed calling
// convention for x86/SSE.
+
+ // If we have a Fixed Return Buffer argument register then we setup a non-standard argument for it
+ //
+ if (hasFixedRetBuffReg() && call->HasRetBufArg())
+ {
+ args = call->gtCallArgs;
+ assert(args != nullptr);
+ assert(args->IsList());
+
+ argx = call->gtCallArgs->Current();
+
+ // We don't increment numArgs here, since we already counted this argument above.
+
+ NonStandardArg nsa = {theFixedRetBuffReg(), argx};
+ nonStandardArgs.Push(nsa);
+ }
+
+ // We are allowed to have a Fixed Return Buffer argument combined
+ // with any of the remaining non-standard arguments
+ //
if (call->IsUnmanaged() && !opts.ShouldUsePInvokeHelpers())
{
assert(!call->gtCallCookie);
SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR structDesc;
#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
- bool expectRetBuffArg = call->HasRetBufArg();
bool hasStructArgument = false; // @TODO-ARM64-UNIX: Remove this bool during a future refactoring
bool hasMultiregStructArgs = false;
for (args = call->gtCallArgs; args; args = args->gtOp.gtOp2, argIndex++)
fgArgTabEntryPtr newArgEntry;
if (lateArgsComputed)
{
- // If 'expectRetBuffArg' is true then the next argument is the RetBufArg
- // and we may need to change nextRegNum to the theFixedRetBuffReg
- if (!argEntry->isNonStandard && expectRetBuffArg)
- {
- assert(passUsingFloatRegs == false);
-
- if (hasFixedRetBuffReg())
- {
- // Change the register used to pass the next argument to the fixed return buffer register
- nextRegNum = theFixedRetBuffReg();
- // Note that later in this method we don't increment intArgRegNum when we
- // have setup nextRegRun to be the fixed return buffer register
- }
-
- // We no longer are expecting the RetBufArg
- expectRetBuffArg = false;
- }
-
// This is a register argument - possibly update it in the table
newArgEntry = call->fgArgInfo->RemorphRegArg(argIndex, argx, args, nextRegNum, size, argAlign);
}
}
#endif // !LEGACY_BACKEND
- // If 'expectRetBuffArg' is true then the next argument is the RetBufArg
- // and we may need to change nextRegNum to the theFixedRetBuffReg
- if (!isNonStandard && expectRetBuffArg)
- {
- assert(passUsingFloatRegs == false);
-
- if (hasFixedRetBuffReg())
- {
- // Change the register used to pass the next argument to the fixed return buffer register
- nextRegNum = theFixedRetBuffReg();
- // Note that later in this method we don't increment intArgRegNum when we
- // have setup nextRegRun to be the fixed return buffer register
- }
-
- // We no longer are expecting the RetBufArg
- expectRetBuffArg = false;
- }
-
// This is a register argument - put it in the table
newArgEntry = call->fgArgInfo->AddRegArg(argIndex, argx, args, nextRegNum, size, argAlign
#if defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)