diff options
author | Joseph Tremoulet <JCTremoulet@gmail.com> | 2017-09-13 09:03:13 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-09-13 09:03:13 -0400 |
commit | 819b655feadbd939721bc7de2e4e1e6ddf9fbb89 (patch) | |
tree | ff6fcd8497d1ccfd796ba6bd05780daa6b15d382 | |
parent | d956c18bbf48f29be498431a52463c4ebbabbbbe (diff) | |
parent | 15d90c6be7058f7488f16918a4f23c400109c7d8 (diff) | |
download | coreclr-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.cpp | 63 | ||||
-rw-r--r-- | src/jit/lower.cpp | 8 |
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 } |