summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/jit/codegenarm.cpp47
-rw-r--r--src/jit/codegenarmarch.cpp8
-rw-r--r--src/jit/lsraarm.cpp6
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;