diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/jit/codegenarm.cpp | 47 | ||||
-rw-r--r-- | src/jit/codegenarmarch.cpp | 8 | ||||
-rw-r--r-- | src/jit/lsraarm.cpp | 6 |
3 files changed, 57 insertions, 4 deletions
diff --git a/src/jit/codegenarm.cpp b/src/jit/codegenarm.cpp index 7102279c83..380cf2694d 100644 --- a/src/jit/codegenarm.cpp +++ b/src/jit/codegenarm.cpp @@ -1230,6 +1230,53 @@ void CodeGen::genCodeForDivMod(GenTreeOp* 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. // // Arguments: diff --git a/src/jit/codegenarmarch.cpp b/src/jit/codegenarmarch.cpp index e85ea6a1ca..590c67e8c9 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; |