From 3070e211eaa2e8dfdb0059de01a7c1693e589579 Mon Sep 17 00:00:00 2001 From: Bruce Forstall Date: Tue, 3 Apr 2018 14:32:19 -0700 Subject: Remove most ARM NYI (#17365) * Remove most ARM NYI Convert most existing ARM NYI either to asserts or remove the code entirely. A few NYI are left, including: 1. GT_BITCAST from 'int' to 'float' 2. initblk unrolling is unimplemented: https://github.com/dotnet/coreclr/issues/16349 3. SIMD-related NYI (SIMD is currently unimplemented) --- src/jit/codegenarm.cpp | 47 +++++++--------------------------------------- src/jit/codegenarmarch.cpp | 30 ++++++++++++++++------------- src/jit/codegenxarch.cpp | 6 ++---- src/jit/compiler.h | 16 +++++++--------- src/jit/lowerarmarch.cpp | 9 ++------- src/jit/lsraarm.cpp | 20 ++++++++++---------- 6 files changed, 45 insertions(+), 83 deletions(-) (limited to 'src') diff --git a/src/jit/codegenarm.cpp b/src/jit/codegenarm.cpp index 639d259558..c405e33110 100644 --- a/src/jit/codegenarm.cpp +++ b/src/jit/codegenarm.cpp @@ -239,17 +239,6 @@ void CodeGen::genCodeForBinary(GenTree* treeNode) genProduceReg(treeNode); } -//------------------------------------------------------------------------ -// genLockedInstructions: Generate code for the locked operations. -// -// Notes: -// Handles GT_LOCKADD, GT_XCHG, GT_XADD nodes. -// -void CodeGen::genLockedInstructions(GenTreeOp* treeNode) -{ - NYI("genLockedInstructions"); -} - //-------------------------------------------------------------------------------------- // genLclHeap: Generate code for localloc // @@ -988,17 +977,10 @@ void CodeGen::genCodeForStoreLclFld(GenTreeLclFld* tree) GenTree* data = tree->gtOp1; instruction ins = ins_Store(targetType); emitAttr attr = emitTypeSize(targetType); - if (data->isContainedIntOrIImmed()) - { - assert(data->IsIntegralConst(0)); - NYI_ARM("st.lclFld contained operand"); - } - else - { - assert(!data->isContained()); - genConsumeReg(data); - emit->emitIns_S_R(ins, attr, data->gtRegNum, varNum, offset); - } + + assert(!data->isContained()); + genConsumeReg(data); + emit->emitIns_S_R(ins, attr, data->gtRegNum, varNum, offset); genUpdateLife(tree); varDsc->lvRegNum = REG_STK; @@ -1039,17 +1021,8 @@ void CodeGen::genCodeForStoreLclVar(GenTreeLclVar* tree) { genConsumeRegs(data); - regNumber dataReg = REG_NA; - if (data->isContainedIntOrIImmed()) - { - assert(data->IsIntegralConst(0)); - NYI_ARM("st.lclVar contained operand"); - } - else - { - assert(!data->isContained()); - dataReg = data->gtRegNum; - } + assert(!data->isContained()); + regNumber dataReg = data->gtRegNum; assert(dataReg != REG_NA); if (targetReg == REG_NA) // store into stack based LclVar @@ -1282,9 +1255,6 @@ void CodeGen::genCodeForStoreInd(GenTreeStoreInd* tree) // registers are taken care of. genConsumeOperands(tree); -#if NOGC_WRITE_BARRIERS - NYI_ARM("NOGC_WRITE_BARRIERS"); -#else // At this point, we should not have any interference. // That is, 'data' must not be in REG_ARG_0, // as that is where 'addr' must go. @@ -1301,7 +1271,6 @@ void CodeGen::genCodeForStoreInd(GenTreeStoreInd* tree) { inst_RV_RV(INS_mov, REG_ARG_1, data->gtRegNum, data->TypeGet()); } -#endif // NOGC_WRITE_BARRIERS genGCWriteBarrier(tree, writeBarrierForm); } @@ -1694,9 +1663,7 @@ void CodeGen::genStoreLongLclVar(GenTree* treeNode) GenTree* loVal = op1->gtGetOp1(); GenTree* hiVal = op1->gtGetOp2(); - // NYI: Contained immediates. - NYI_IF((loVal->gtRegNum == REG_NA) || (hiVal->gtRegNum == REG_NA), - "Store of long lclVar with contained immediate"); + noway_assert((loVal->gtRegNum != REG_NA) && (hiVal->gtRegNum != REG_NA)); emit->emitIns_S_R(ins_Store(TYP_INT), EA_4BYTE, loVal->gtRegNum, lclNum, 0); emit->emitIns_S_R(ins_Store(TYP_INT), EA_4BYTE, hiVal->gtRegNum, lclNum, genTypeSize(TYP_INT)); diff --git a/src/jit/codegenarmarch.cpp b/src/jit/codegenarmarch.cpp index d4f6343515..79cea8d5e7 100644 --- a/src/jit/codegenarmarch.cpp +++ b/src/jit/codegenarmarch.cpp @@ -160,7 +160,9 @@ void CodeGen::genCodeForTreeNode(GenTree* treeNode) #else // !_TARGET_ARM64_ if (varTypeIsFloating(treeNode)) { - NYI_ARM("genRegCopy from 'int' to 'float'"); + // GT_BITCAST on ARM is only used to cast floating-point arguments to integer + // registers. Nobody generates GT_BITCAST from int to float currently. + NYI_ARM("GT_BITCAST from 'int' to 'float'"); } else { @@ -172,7 +174,8 @@ void CodeGen::genCodeForTreeNode(GenTree* treeNode) } else { - regNumber otherReg = (regNumber)treeNode->AsMultiRegOp()->gtOtherReg; + assert(op1->TypeGet() == TYP_DOUBLE); + regNumber otherReg = treeNode->AsMultiRegOp()->gtOtherReg; assert(otherReg != REG_NA); inst_RV_RV_RV(INS_vmov_d2i, targetReg, otherReg, genConsumeReg(op1), EA_8BYTE); } @@ -328,28 +331,27 @@ void CodeGen::genCodeForTreeNode(GenTree* treeNode) case GT_PUTARG_SPLIT: genPutArgSplit(treeNode->AsPutArgSplit()); break; -#endif +#endif // _TARGET_ARM_ case GT_CALL: genCallInstruction(treeNode->AsCall()); break; + case GT_MEMORYBARRIER: + instGen_MemoryBarrier(); + break; + +#ifdef _TARGET_ARM64_ case GT_LOCKADD: case GT_XCHG: case GT_XADD: genLockedInstructions(treeNode->AsOp()); break; - case GT_MEMORYBARRIER: - instGen_MemoryBarrier(); - break; - case GT_CMPXCHG: - NYI_ARM("GT_CMPXCHG"); -#ifdef _TARGET_ARM64_ genCodeForCmpXchg(treeNode->AsCmpXchg()); -#endif break; +#endif // _TARGET_ARM64_ case GT_RELOAD: // do nothing - reload is just a marker. @@ -511,12 +513,12 @@ void CodeGen::genIntrinsic(GenTree* treeNode) genConsumeOperands(treeNode->AsOp()); getEmitter()->emitInsBinary(INS_frintm, emitActualTypeSize(treeNode), treeNode, srcNode); break; -#endif + case CORINFO_INTRINSIC_Round: - NYI_ARM("genIntrinsic for round - not implemented yet"); genConsumeOperands(treeNode->AsOp()); - getEmitter()->emitInsBinary(INS_ROUND, emitActualTypeSize(treeNode), treeNode, srcNode); + getEmitter()->emitInsBinary(INS_frintn, emitActualTypeSize(treeNode), treeNode, srcNode); break; +#endif // _TARGET_ARM64_ case CORINFO_INTRINSIC_Sqrt: genConsumeOperands(treeNode->AsOp()); @@ -2116,6 +2118,8 @@ void CodeGen::genRegCopy(GenTree* treeNode) #else // !_TARGET_ARM64_ if (varTypeIsFloating(treeNode)) { + // GT_COPY from 'int' to 'float' currently can't happen. Maybe if ARM SIMD is implemented + // it will happen, according to the comment above? NYI_ARM("genRegCopy from 'int' to 'float'"); } else diff --git a/src/jit/codegenxarch.cpp b/src/jit/codegenxarch.cpp index 9f7f38d3e3..a6dc3b57f5 100644 --- a/src/jit/codegenxarch.cpp +++ b/src/jit/codegenxarch.cpp @@ -3576,7 +3576,7 @@ void CodeGen::genLockedInstructions(GenTreeOp* treeNode) } //------------------------------------------------------------------------ -// genCodeForSwap: Produce code for a GT_CMPXCHG node. +// genCodeForCmpXchg: Produce code for a GT_CMPXCHG node. // // Arguments: // tree - the GT_CMPXCHG node @@ -8640,9 +8640,7 @@ void CodeGen::genStoreLongLclVar(GenTree* treeNode) GenTree* loVal = op1->gtGetOp1(); GenTree* hiVal = op1->gtGetOp2(); - // NYI: Contained immediates. - NYI_IF((loVal->gtRegNum == REG_NA) || (hiVal->gtRegNum == REG_NA), - "Store of long lclVar with contained immediate"); + noway_assert((loVal->gtRegNum != REG_NA) && (hiVal->gtRegNum != REG_NA)); emit->emitIns_S_R(ins_Store(TYP_INT), EA_4BYTE, loVal->gtRegNum, lclNum, 0); emit->emitIns_S_R(ins_Store(TYP_INT), EA_4BYTE, hiVal->gtRegNum, lclNum, genTypeSize(TYP_INT)); diff --git a/src/jit/compiler.h b/src/jit/compiler.h index 80c90e8f62..a39f714d9e 100644 --- a/src/jit/compiler.h +++ b/src/jit/compiler.h @@ -10528,7 +10528,7 @@ const instruction INS_ADDC = INS_adc; const instruction INS_SUBC = INS_sbb; const instruction INS_NOT = INS_not; -#endif +#endif // _TARGET_XARCH_ #ifdef _TARGET_ARM_ @@ -10550,22 +10550,20 @@ const instruction INS_ADDC = INS_adc; const instruction INS_SUBC = INS_sbc; const instruction INS_NOT = INS_mvn; -const instruction INS_ABS = INS_vabs; -const instruction INS_ROUND = INS_invalid; -const instruction INS_SQRT = INS_vsqrt; +const instruction INS_ABS = INS_vabs; +const instruction INS_SQRT = INS_vsqrt; -#endif +#endif // _TARGET_ARM_ #ifdef _TARGET_ARM64_ const instruction INS_MULADD = INS_madd; const instruction INS_BREAKPOINT = INS_bkpt; -const instruction INS_ABS = INS_fabs; -const instruction INS_ROUND = INS_frintn; -const instruction INS_SQRT = INS_fsqrt; +const instruction INS_ABS = INS_fabs; +const instruction INS_SQRT = INS_fsqrt; -#endif +#endif // _TARGET_ARM64_ /*****************************************************************************/ diff --git a/src/jit/lowerarmarch.cpp b/src/jit/lowerarmarch.cpp index 0d755fe4c2..f18793d06c 100644 --- a/src/jit/lowerarmarch.cpp +++ b/src/jit/lowerarmarch.cpp @@ -409,17 +409,12 @@ void Lowering::LowerCast(GenTree* tree) if (varTypeIsFloating(srcType)) { noway_assert(!tree->gtOverflow()); + assert(!varTypeIsSmall(dstType)); // fgMorphCast creates intermediate casts when converting from float to small + // int. } assert(!varTypeIsSmall(srcType)); - // case of src is a floating point type and dst is a small type. - if (varTypeIsFloating(srcType) && varTypeIsSmall(dstType)) - { - NYI_ARM("Lowering for cast from float to small type"); // Not tested yet. - tmpType = TYP_INT; - } - if (tmpType != TYP_UNDEF) { GenTree* tmp = comp->gtNewCastNode(tmpType, op1, tree->IsUnsigned(), tmpType); diff --git a/src/jit/lsraarm.cpp b/src/jit/lsraarm.cpp index 63e93fa8ea..05a02381cf 100644 --- a/src/jit/lsraarm.cpp +++ b/src/jit/lsraarm.cpp @@ -237,7 +237,7 @@ void LinearScan::BuildNode(GenTree* tree) assert(info->dstCount == 1); break; default: - NYI_ARM("LinearScan::Build for GT_INTRINSIC"); + unreached(); break; } } @@ -756,15 +756,6 @@ void LinearScan::BuildNode(GenTree* tree) } break; - default: -#ifdef DEBUG - char message[256]; - _snprintf_s(message, _countof(message), _TRUNCATE, "NYI: Unimplemented node type %s", - GenTree::OpName(tree->OperGet())); - NYIRAW(message); -#else - NYI_ARM("BuildNode default case"); -#endif case GT_LCL_FLD: case GT_LCL_FLD_ADDR: case GT_LCL_VAR: @@ -788,6 +779,15 @@ void LinearScan::BuildNode(GenTree* tree) info->srcCount = appendBinaryLocationInfoToList(tree->AsOp()); assert(info->srcCount == 2); break; + + default: +#ifdef DEBUG + char message[256]; + _snprintf_s(message, _countof(message), _TRUNCATE, "NYI: Unimplemented node type %s", + GenTree::OpName(tree->OperGet())); + NYIRAW(message); +#endif + unreached(); } // end switch (tree->OperGet()) if (tree->IsUnusedValue() && (info->dstCount != 0)) -- cgit v1.2.3