Change the Arm64 fixed return buffer argument to be handled as a non-standard argument
authorBrian Sullivan <briansul@microsoft.com>
Thu, 23 Jun 2016 00:40:39 +0000 (17:40 -0700)
committerBrian Sullivan <briansul@microsoft.com>
Thu, 23 Jun 2016 00:40:39 +0000 (17:40 -0700)
We already have support for the handling of non-standard arguments and
it is simpler and better to handle the fixed return buffer argument as a non-standard argument.

src/jit/morph.cpp

index 295bf7f..dc577b0 100644 (file)
@@ -2595,7 +2595,7 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* callNode)
         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).
@@ -2643,6 +2643,26 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* callNode)
         // 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);
@@ -2870,7 +2890,6 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* callNode)
     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++)
@@ -3621,24 +3640,6 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* callNode)
             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);
             }
@@ -3663,24 +3664,6 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* callNode)
                 }
 #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)