From 8fad9b58c71721ab4ae4f22b743b432aea377712 Mon Sep 17 00:00:00 2001 From: Mikhail Skvortcov Date: Thu, 16 Mar 2017 16:23:05 +0300 Subject: [PATCH] RyuJIT/ARM32: Enable GT_COPY and GT_MEMORYBARRIER Commit migrated from https://github.com/dotnet/coreclr/commit/e2a91a6d6cd7ca980ba37e906f41fb433bbe6093 --- src/coreclr/src/jit/codegenarm.cpp | 83 +++++++++++++++++++++++++++++--------- src/coreclr/src/jit/lsraarm.cpp | 1 + 2 files changed, 65 insertions(+), 19 deletions(-) diff --git a/src/coreclr/src/jit/codegenarm.cpp b/src/coreclr/src/jit/codegenarm.cpp index e276b71..9a931b5 100644 --- a/src/coreclr/src/jit/codegenarm.cpp +++ b/src/coreclr/src/jit/codegenarm.cpp @@ -1082,24 +1082,7 @@ void CodeGen::genCodeForTreeNode(GenTreePtr treeNode) break; case GT_COPY: - { - assert(treeNode->gtOp.gtOp1->IsLocal()); - GenTreeLclVarCommon* lcl = treeNode->gtOp.gtOp1->AsLclVarCommon(); - LclVarDsc* varDsc = &compiler->lvaTable[lcl->gtLclNum]; - inst_RV_RV(ins_Move_Extend(targetType, true), targetReg, genConsumeReg(treeNode->gtOp.gtOp1), targetType, - emitTypeSize(targetType)); - - // The old location is dying - genUpdateRegLife(varDsc, /*isBorn*/ false, /*isDying*/ true DEBUGARG(treeNode->gtOp.gtOp1)); - - gcInfo.gcMarkRegSetNpt(genRegMask(treeNode->gtOp.gtOp1->gtRegNum)); - - genUpdateVarReg(varDsc, treeNode); - - // The new location is going live - genUpdateRegLife(varDsc, /*isBorn*/ true, /*isDying*/ false DEBUGARG(treeNode)); - } - genProduceReg(treeNode); + // This is handled at the time we call genConsumeReg() on the GT_COPY break; case GT_LIST: @@ -1138,6 +1121,10 @@ void CodeGen::genCodeForTreeNode(GenTreePtr treeNode) genLockedInstructions(treeNode->AsOp()); break; + case GT_MEMORYBARRIER: + instGen_MemoryBarrier(); + break; + case GT_CMPXCHG: { NYI("GT_CMPXCHG"); @@ -1879,7 +1866,65 @@ void CodeGen::genCodeForShiftLong(GenTreePtr tree) // void CodeGen::genRegCopy(GenTree* treeNode) { - NYI("genRegCopy"); + assert(treeNode->OperGet() == GT_COPY); + + var_types targetType = treeNode->TypeGet(); + regNumber targetReg = treeNode->gtRegNum; + assert(targetReg != REG_NA); + + GenTree* op1 = treeNode->gtOp.gtOp1; + + // Check whether this node and the node from which we're copying the value have the same + // register type. + // This can happen if (currently iff) we have a SIMD vector type that fits in an integer + // register, in which case it is passed as an argument, or returned from a call, + // in an integer register and must be copied if it's in an xmm register. + + if (varTypeIsFloating(treeNode) != varTypeIsFloating(op1)) + { + NYI("genRegCopy floating point"); + } + else + { + inst_RV_RV(ins_Copy(targetType), targetReg, genConsumeReg(op1), targetType); + } + + if (op1->IsLocal()) + { + // The lclVar will never be a def. + // If it is a last use, the lclVar will be killed by genConsumeReg(), as usual, and genProduceReg will + // appropriately set the gcInfo for the copied value. + // If not, there are two cases we need to handle: + // - If this is a TEMPORARY copy (indicated by the GTF_VAR_DEATH flag) the variable + // will remain live in its original register. + // genProduceReg() will appropriately set the gcInfo for the copied value, + // and genConsumeReg will reset it. + // - Otherwise, we need to update register info for the lclVar. + + GenTreeLclVarCommon* lcl = op1->AsLclVarCommon(); + assert((lcl->gtFlags & GTF_VAR_DEF) == 0); + + if ((lcl->gtFlags & GTF_VAR_DEATH) == 0 && (treeNode->gtFlags & GTF_VAR_DEATH) == 0) + { + LclVarDsc* varDsc = &compiler->lvaTable[lcl->gtLclNum]; + + // If we didn't just spill it (in genConsumeReg, above), then update the register info + if (varDsc->lvRegNum != REG_STK) + { + // The old location is dying + genUpdateRegLife(varDsc, /*isBorn*/ false, /*isDying*/ true DEBUGARG(op1)); + + gcInfo.gcMarkRegSetNpt(genRegMask(op1->gtRegNum)); + + genUpdateVarReg(varDsc, treeNode); + + // The new location is going live + genUpdateRegLife(varDsc, /*isBorn*/ true, /*isDying*/ false DEBUGARG(treeNode)); + } + } + } + + genProduceReg(treeNode); } //------------------------------------------------------------------------ diff --git a/src/coreclr/src/jit/lsraarm.cpp b/src/coreclr/src/jit/lsraarm.cpp index 3a2206b..9ecde34 100644 --- a/src/coreclr/src/jit/lsraarm.cpp +++ b/src/coreclr/src/jit/lsraarm.cpp @@ -1354,6 +1354,7 @@ void Lowering::TreeNodeInfoInit(GenTree* tree) case GT_LABEL: case GT_PINVOKE_PROLOG: case GT_JCC: + case GT_MEMORYBARRIER: info->dstCount = tree->IsValue() ? 1 : 0; if (kind & (GTK_CONST | GTK_LEAF)) { -- 2.7.4