From e8098e514ce43a2c35edec4f5f231c8cc4854074 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Mon, 14 May 2018 18:47:23 -0400 Subject: [PATCH] [Arm64] Fix stack struct arg packing --- src/jit/codegenarmarch.cpp | 16 ++++++++++++++++ src/jit/morph.cpp | 5 ++--- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/jit/codegenarmarch.cpp b/src/jit/codegenarmarch.cpp index 90b802d..c383f09 100644 --- a/src/jit/codegenarmarch.cpp +++ b/src/jit/codegenarmarch.cpp @@ -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 diff --git a/src/jit/morph.cpp b/src/jit/morph.cpp index 1011256..6293259 100644 --- a/src/jit/morph.cpp +++ b/src/jit/morph.cpp @@ -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; -- 2.7.4