From 969b7c59fc60fbbda680aa1d911166a4f291d5f8 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Wed, 6 Sep 2017 18:41:06 -0400 Subject: [Arm64] Add GT_MULHI Enable related lowerings --- src/jit/codegenarm64.cpp | 63 +++++++++++++++++++++--------------------------- 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 2e98e21c4d..f36528ec6d 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 - regNumber targetReg = treeNode->gtRegNum; - var_types targetType = treeNode->TypeGet(); - emitter *emit = getEmitter(); - emitAttr size = emitTypeSize(treeNode); - GenTree *op1 = treeNode->gtOp1; - GenTree *op2 = treeNode->gtOp2; + genConsumeOperands(treeNode); - // 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. + regNumber targetReg = treeNode->gtRegNum; + var_types targetType = treeNode->TypeGet(); + emitter* emit = getEmitter(); + emitAttr attr = emitTypeSize(treeNode); + bool isUnsigned = (treeNode->gtFlags & GTF_UNSIGNED); - genConsumeOperands(treeNode); + GenTreePtr op1 = treeNode->gtGetOp1(); + GenTreePtr op2 = treeNode->gtGetOp2(); - 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) + assert(!varTypeIsFloating(targetType)); + + // The arithmetic node must be sitting in a register (since it's not contained) + noway_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); + + noway_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 diff --git a/src/jit/lower.cpp b/src/jit/lower.cpp index 7c604053ec..7ca2252f82 100644 --- a/src/jit/lower.cpp +++ b/src/jit/lower.cpp @@ -4115,8 +4115,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; @@ -4293,7 +4293,7 @@ GenTree* Lowering::LowerConstIntDivOrMod(GenTree* node) return next; } -#ifdef _TARGET_XARCH_ +#if defined(_TARGET_XARCH_) || defined(_TARGET_ARM64_) ssize_t magic; int shift; @@ -4400,7 +4400,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 } -- cgit v1.2.3 From 47a92f5bdafb830467cede2b2ffc1c66212cc33b Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Thu, 7 Sep 2017 19:21:27 -0400 Subject: Fix formatting --- src/jit/codegenarm64.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/jit/codegenarm64.cpp b/src/jit/codegenarm64.cpp index f36528ec6d..7b4a3156c1 100644 --- a/src/jit/codegenarm64.cpp +++ b/src/jit/codegenarm64.cpp @@ -1506,14 +1506,14 @@ void CodeGen::genCodeForMulHi(GenTreeOp* treeNode) genConsumeOperands(treeNode); - regNumber targetReg = treeNode->gtRegNum; - var_types targetType = treeNode->TypeGet(); - emitter* emit = getEmitter(); - emitAttr attr = emitTypeSize(treeNode); - bool isUnsigned = (treeNode->gtFlags & GTF_UNSIGNED); + regNumber targetReg = treeNode->gtRegNum; + var_types targetType = treeNode->TypeGet(); + emitter* emit = getEmitter(); + emitAttr attr = emitTypeSize(treeNode); + bool isUnsigned = (treeNode->gtFlags & GTF_UNSIGNED); - GenTreePtr op1 = treeNode->gtGetOp1(); - GenTreePtr op2 = treeNode->gtGetOp2(); + GenTreePtr op1 = treeNode->gtGetOp1(); + GenTreePtr op2 = treeNode->gtGetOp2(); assert(!varTypeIsFloating(targetType)); -- cgit v1.2.3 From db976783397a1f815c9b3e4f3831d02abfa879ce Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Thu, 7 Sep 2017 20:05:49 -0400 Subject: Fix warning->error --- src/jit/codegenarm64.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/jit/codegenarm64.cpp b/src/jit/codegenarm64.cpp index 7b4a3156c1..d7eca41cd4 100644 --- a/src/jit/codegenarm64.cpp +++ b/src/jit/codegenarm64.cpp @@ -1510,7 +1510,7 @@ void CodeGen::genCodeForMulHi(GenTreeOp* treeNode) var_types targetType = treeNode->TypeGet(); emitter* emit = getEmitter(); emitAttr attr = emitTypeSize(treeNode); - bool isUnsigned = (treeNode->gtFlags & GTF_UNSIGNED); + unsigned isUnsigned = (treeNode->gtFlags & GTF_UNSIGNED); GenTreePtr op1 = treeNode->gtGetOp1(); GenTreePtr op2 = treeNode->gtGetOp2(); -- cgit v1.2.3 From 15d90c6be7058f7488f16918a4f23c400109c7d8 Mon Sep 17 00:00:00 2001 From: Steve MacLean Date: Tue, 12 Sep 2017 11:44:47 -0400 Subject: noway_assert to assert per review --- src/jit/codegenarm64.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/jit/codegenarm64.cpp b/src/jit/codegenarm64.cpp index d7eca41cd4..a9f2fc2f30 100644 --- a/src/jit/codegenarm64.cpp +++ b/src/jit/codegenarm64.cpp @@ -1518,7 +1518,7 @@ void CodeGen::genCodeForMulHi(GenTreeOp* treeNode) assert(!varTypeIsFloating(targetType)); // The arithmetic node must be sitting in a register (since it's not contained) - noway_assert(targetReg != REG_NA); + assert(targetReg != REG_NA); if (EA_SIZE(attr) == EA_8BYTE) { @@ -1526,7 +1526,7 @@ void CodeGen::genCodeForMulHi(GenTreeOp* treeNode) regNumber r = emit->emitInsTernary(ins, attr, treeNode, op1, op2); - noway_assert(r == targetReg); + assert(r == targetReg); } else { @@ -1559,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); } -- cgit v1.2.3