[Arm64] Fix stack struct arg packing
authorSteve MacLean <sdmaclea.qdt@qualcommdatacenter.com>
Mon, 14 May 2018 22:47:23 +0000 (18:47 -0400)
committerSteve MacLean <sdmaclea.qdt@qualcommdatacenter.com>
Tue, 15 May 2018 17:48:20 +0000 (13:48 -0400)
src/jit/codegenarmarch.cpp
src/jit/morph.cpp

index 90b802d..c383f09 100644 (file)
@@ -655,6 +655,12 @@ void CodeGen::genPutArgStk(GenTreePutArgStk* treeNode)
             // Deal with the multi register passed struct args.
             GenTreeFieldList* fieldListPtr = source->AsFieldList();
 
+#ifdef _TARGET_ARM64_
+            // Arm64 ABI does not include argument splitting between registers and stack
+            assert(fieldListPtr);
+            assert(fieldListPtr->gtFieldOffset == 0);
+#endif // _TARGET_ARM64_
+
             // Evaluate each of the GT_FIELD_LIST items into their register
             // and store their register into the outgoing argument area
             for (; fieldListPtr != nullptr; fieldListPtr = fieldListPtr->Rest())
@@ -666,11 +672,21 @@ void CodeGen::genPutArgStk(GenTreePutArgStk* treeNode)
                 var_types type = nextArgNode->TypeGet();
                 emitAttr  attr = emitTypeSize(type);
 
+#ifdef _TARGET_ARM64_
+                // Emit store instructions to store the registers produced by the GT_FIELD_LIST into the outgoing
+                // argument area
+                emit->emitIns_S_R(ins_Store(type), attr, reg, varNumOut, argOffsetOut + fieldListPtr->gtFieldOffset);
+
+                // We can't write beyound the outgoing area area
+                assert((argOffsetOut + fieldListPtr->gtFieldOffset + EA_SIZE_IN_BYTES(attr)) <= argOffsetMax);
+#else
+                // TODO-ARM-Bug?  The following code will pack copied structs
                 // Emit store instructions to store the registers produced by the GT_FIELD_LIST into the outgoing
                 // argument area
                 emit->emitIns_S_R(ins_Store(type), attr, reg, varNumOut, argOffsetOut);
                 argOffsetOut += EA_SIZE_IN_BYTES(attr);
                 assert(argOffsetOut <= argOffsetMax); // We can't write beyound the outgoing area area
+#endif // _TARGET_ARM64_
             }
         }
         else // We must have a GT_OBJ or a GT_LCL_VAR
index 1011256..6293259 100644 (file)
@@ -5497,7 +5497,6 @@ GenTreeFieldList* Compiler::fgMorphLclArgToFieldlist(GenTreeLclVarCommon* lcl)
     LclVarDsc* varDsc = &(lvaTable[lcl->gtLclNum]);
     assert(varDsc->lvPromoted == true);
 
-    unsigned          offset      = 0;
     unsigned          fieldCount  = varDsc->lvFieldCnt;
     GenTreeFieldList* listEntry   = nullptr;
     GenTreeFieldList* newArg      = nullptr;
@@ -5508,12 +5507,12 @@ GenTreeFieldList* Compiler::fgMorphLclArgToFieldlist(GenTreeLclVarCommon* lcl)
     {
         LclVarDsc* fieldVarDsc = &lvaTable[fieldLclNum];
         GenTree*   lclVar      = gtNewLclvNode(fieldLclNum, fieldVarDsc->lvType);
-        listEntry = new (this, GT_FIELD_LIST) GenTreeFieldList(lclVar, offset, fieldVarDsc->lvType, listEntry);
+        listEntry              = new (this, GT_FIELD_LIST)
+            GenTreeFieldList(lclVar, fieldVarDsc->lvFldOffset, fieldVarDsc->lvType, listEntry);
         if (newArg == nullptr)
         {
             newArg = listEntry;
         }
-        offset += TARGET_POINTER_SIZE;
         fieldLclNum++;
     }
     return newArg;