summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoseph Tremoulet <JCTremoulet@gmail.com>2017-09-13 09:03:13 -0400
committerGitHub <noreply@github.com>2017-09-13 09:03:13 -0400
commit819b655feadbd939721bc7de2e4e1e6ddf9fbb89 (patch)
treeff6fcd8497d1ccfd796ba6bd05780daa6b15d382
parentd956c18bbf48f29be498431a52463c4ebbabbbbe (diff)
parent15d90c6be7058f7488f16918a4f23c400109c7d8 (diff)
downloadcoreclr-819b655feadbd939721bc7de2e4e1e6ddf9fbb89.tar.gz
coreclr-819b655feadbd939721bc7de2e4e1e6ddf9fbb89.tar.bz2
coreclr-819b655feadbd939721bc7de2e4e1e6ddf9fbb89.zip
Merge pull request #13835 from sdmaclea/PR-ARM64-GT_MULHI
[Arm64] Add GT_MULHI
-rw-r--r--src/jit/codegenarm64.cpp63
-rw-r--r--src/jit/lower.cpp8
2 files changed, 31 insertions, 40 deletions
diff --git a/src/jit/codegenarm64.cpp b/src/jit/codegenarm64.cpp
index a61be7cd45..640478b4e7 100644
--- a/src/jit/codegenarm64.cpp
+++ b/src/jit/codegenarm64.cpp
@@ -1502,53 +1502,44 @@ void CodeGen::genSetRegToConst(regNumber targetReg, var_types targetType, GenTre
// Generate code to get the high N bits of a N*N=2N bit multiplication result
void CodeGen::genCodeForMulHi(GenTreeOp* treeNode)
{
- assert(!(treeNode->gtFlags & GTF_UNSIGNED));
assert(!treeNode->gtOverflowEx());
-#if 0
+ genConsumeOperands(treeNode);
+
regNumber targetReg = treeNode->gtRegNum;
var_types targetType = treeNode->TypeGet();
- emitter *emit = getEmitter();
- emitAttr size = emitTypeSize(treeNode);
- GenTree *op1 = treeNode->gtOp1;
- GenTree *op2 = treeNode->gtOp2;
+ emitter* emit = getEmitter();
+ emitAttr attr = emitTypeSize(treeNode);
+ unsigned isUnsigned = (treeNode->gtFlags & GTF_UNSIGNED);
- // to get the high bits of the multiply, we are constrained to using the
- // 1-op form: RDX:RAX = RAX * rm
- // The 3-op form (Rx=Ry*Rz) does not support it.
+ GenTreePtr op1 = treeNode->gtGetOp1();
+ GenTreePtr op2 = treeNode->gtGetOp2();
- genConsumeOperands(treeNode);
+ assert(!varTypeIsFloating(targetType));
- GenTree* regOp = op1;
- GenTree* rmOp = op2;
-
- // Set rmOp to the contained memory operand (if any)
- //
- if (op1->isContained() || (!op2->isContained() && (op2->gtRegNum == targetReg)))
- {
- regOp = op2;
- rmOp = op1;
- }
- assert(!regOp->isContained());
-
- // Setup targetReg when neither of the source operands was a matching register
- if (regOp->gtRegNum != targetReg)
+ // The arithmetic node must be sitting in a register (since it's not contained)
+ assert(targetReg != REG_NA);
+
+ if (EA_SIZE(attr) == EA_8BYTE)
{
- inst_RV_RV(ins_Copy(targetType), targetReg, regOp->gtRegNum, targetType);
+ instruction ins = isUnsigned ? INS_umulh : INS_smulh;
+
+ regNumber r = emit->emitInsTernary(ins, attr, treeNode, op1, op2);
+
+ assert(r == targetReg);
}
-
- emit->emitInsBinary(INS_imulEAX, size, treeNode, rmOp);
-
- // Move the result to the desired register, if necessary
- if (targetReg != REG_RDX)
+ else
{
- inst_RV_RV(INS_mov, targetReg, REG_RDX, targetType);
+ assert(EA_SIZE(attr) == EA_4BYTE);
+
+ instruction ins = isUnsigned ? INS_umull : INS_smull;
+
+ regNumber r = emit->emitInsTernary(ins, EA_4BYTE, treeNode, op1, op2);
+
+ emit->emitIns_R_R_I(isUnsigned ? INS_lsr : INS_asr, EA_8BYTE, targetReg, targetReg, 32);
}
genProduceReg(treeNode);
-#else // !0
- NYI("genCodeForMulHi");
-#endif // !0
}
// Generate code for ADD, SUB, MUL, DIV, UDIV, AND, OR and XOR
@@ -1568,10 +1559,10 @@ void CodeGen::genCodeForBinary(GenTree* treeNode)
instruction ins = genGetInsForOper(treeNode->OperGet(), targetType);
// The arithmetic node must be sitting in a register (since it's not contained)
- noway_assert(targetReg != REG_NA);
+ assert(targetReg != REG_NA);
regNumber r = emit->emitInsTernary(ins, emitTypeSize(treeNode), treeNode, op1, op2);
- noway_assert(r == targetReg);
+ assert(r == targetReg);
genProduceReg(treeNode);
}
diff --git a/src/jit/lower.cpp b/src/jit/lower.cpp
index 78ef11769f..86c1c5a348 100644
--- a/src/jit/lower.cpp
+++ b/src/jit/lower.cpp
@@ -4122,8 +4122,8 @@ bool Lowering::LowerUnsignedDivOrMod(GenTreeOp* divMod)
}
}
-// TODO-ARM-CQ: Currently there's no GT_MULHI for ARM32/64
-#ifdef _TARGET_XARCH_
+// TODO-ARM-CQ: Currently there's no GT_MULHI for ARM32
+#if defined(_TARGET_XARCH_) || defined(_TARGET_ARM64_)
if (!comp->opts.MinOpts() && (divisorValue >= 3))
{
size_t magic;
@@ -4300,7 +4300,7 @@ GenTree* Lowering::LowerConstIntDivOrMod(GenTree* node)
return next;
}
-#ifdef _TARGET_XARCH_
+#if defined(_TARGET_XARCH_) || defined(_TARGET_ARM64_)
ssize_t magic;
int shift;
@@ -4407,7 +4407,7 @@ GenTree* Lowering::LowerConstIntDivOrMod(GenTree* node)
return mulhi;
#else
- // Currently there's no GT_MULHI for ARM32/64
+ // Currently there's no GT_MULHI for ARM32
return next;
#endif
}