From ba04e23c8df4653e423630788aca1bda08f63fce Mon Sep 17 00:00:00 2001 From: Mikhail Skvortcov Date: Thu, 18 May 2017 16:21:55 +0300 Subject: RyuJIT/ARM32: enable ckfinite codegen. --- src/jit/codegenarm.cpp | 47 ++++++++++++++++++++++++++++++++++++++++++++++ src/jit/codegenarmarch.cpp | 8 ++++---- src/jit/lsraarm.cpp | 6 ++++++ 3 files changed, 57 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/jit/codegenarm.cpp b/src/jit/codegenarm.cpp index 40371e358c..58f3644f89 100644 --- a/src/jit/codegenarm.cpp +++ b/src/jit/codegenarm.cpp @@ -1229,6 +1229,53 @@ void CodeGen::genCodeForDivMod(GenTreeOp* tree) genProduceReg(tree); } +//------------------------------------------------------------------------ +// genCkfinite: Generate code for ckfinite opcode. +// +// Arguments: +// treeNode - The GT_CKFINITE node +// +// Return Value: +// None. +// +// Assumptions: +// GT_CKFINITE node has reserved an internal register. +// +void CodeGen::genCkfinite(GenTreePtr treeNode) +{ + assert(treeNode->OperGet() == GT_CKFINITE); + + emitter* emit = getEmitter(); + var_types targetType = treeNode->TypeGet(); + regNumber intReg = treeNode->GetSingleTempReg(); + regNumber fpReg = genConsumeReg(treeNode->gtOp.gtOp1); + regNumber targetReg = treeNode->gtRegNum; + + // Extract and sign-extend the exponent into an integer register + if (targetType == TYP_FLOAT) + { + emit->emitIns_R_R(INS_vmov_f2i, EA_4BYTE, intReg, fpReg); + emit->emitIns_R_R_I_I(INS_sbfx, EA_4BYTE, intReg, intReg, 23, 8); + } + else + { + assert(targetType == TYP_DOUBLE); + emit->emitIns_R_R(INS_vmov_f2i, EA_4BYTE, intReg, REG_NEXT(fpReg)); + emit->emitIns_R_R_I_I(INS_sbfx, EA_4BYTE, intReg, intReg, 20, 11); + } + + // If exponent is all 1's, throw ArithmeticException + emit->emitIns_R_I(INS_add, EA_4BYTE, intReg, 1, INS_FLAGS_SET); + genJumpToThrowHlpBlk(EJ_eq, SCK_ARITH_EXCPN); + + // If it's a finite value, copy it to targetReg + if (targetReg != fpReg) + { + emit->emitIns_R_R(ins_Copy(targetType), emitTypeSize(treeNode), targetReg, fpReg); + } + genProduceReg(treeNode); +} + //------------------------------------------------------------------------ // genCodeForCompare: Produce code for a GT_EQ/GT_NE/GT_LT/GT_LE/GT_GE/GT_GT node. // diff --git a/src/jit/codegenarmarch.cpp b/src/jit/codegenarmarch.cpp index 103ce47625..60a9a56bf4 100644 --- a/src/jit/codegenarmarch.cpp +++ b/src/jit/codegenarmarch.cpp @@ -195,10 +195,6 @@ void CodeGen::genCodeForTreeNode(GenTreePtr treeNode) genCodeForMulHi(treeNode->AsOp()); break; - case GT_CKFINITE: - genCkfinite(treeNode); - break; - case GT_SWAP: genCodeForSwap(treeNode->AsOp()); break; @@ -209,6 +205,10 @@ void CodeGen::genCodeForTreeNode(GenTreePtr treeNode) #endif // _TARGET_ARM64_ + case GT_CKFINITE: + genCkfinite(treeNode); + break; + case GT_INTRINSIC: genIntrinsic(treeNode); break; diff --git a/src/jit/lsraarm.cpp b/src/jit/lsraarm.cpp index 0d1cfe6bfa..2c139540cb 100644 --- a/src/jit/lsraarm.cpp +++ b/src/jit/lsraarm.cpp @@ -629,6 +629,12 @@ void Lowering::TreeNodeInfoInit(GenTree* tree) TreeNodeInfoInitCmp(tree); break; + case GT_CKFINITE: + info->srcCount = 1; + info->dstCount = 1; + info->internalIntCount = 1; + break; + case GT_CALL: TreeNodeInfoInitCall(tree->AsCall()); break; -- cgit v1.2.3