diff options
author | Richard Osborne <richard@xmos.com> | 2010-03-10 13:20:07 +0000 |
---|---|---|
committer | Richard Osborne <richard@xmos.com> | 2010-03-10 13:20:07 +0000 |
commit | a7e78402b8b3d3583e7b63fcca99a4034a2f4db4 (patch) | |
tree | 8ecd3ec316861d81c9a1c552883a49b385d72567 | |
parent | 34f9d88221319054085934018a711fac5a65a6b1 (diff) | |
download | llvm-a7e78402b8b3d3583e7b63fcca99a4034a2f4db4.tar.gz llvm-a7e78402b8b3d3583e7b63fcca99a4034a2f4db4.tar.bz2 llvm-a7e78402b8b3d3583e7b63fcca99a4034a2f4db4.tar.xz |
Custom lower (S|U)MUL_LOHI -> MACC(S|U)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@98152 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Target/XCore/XCoreISelLowering.cpp | 38 | ||||
-rw-r--r-- | lib/Target/XCore/XCoreISelLowering.h | 2 | ||||
-rw-r--r-- | test/CodeGen/XCore/mul64.ll | 30 |
3 files changed, 70 insertions, 0 deletions
diff --git a/lib/Target/XCore/XCoreISelLowering.cpp b/lib/Target/XCore/XCoreISelLowering.cpp index 596abb3506..70ceadd4df 100644 --- a/lib/Target/XCore/XCoreISelLowering.cpp +++ b/lib/Target/XCore/XCoreISelLowering.cpp @@ -98,6 +98,8 @@ XCoreTargetLowering::XCoreTargetLowering(XCoreTargetMachine &XTM) // 64bit setOperationAction(ISD::ADD, MVT::i64, Custom); setOperationAction(ISD::SUB, MVT::i64, Custom); + setOperationAction(ISD::SMUL_LOHI, MVT::i32, Custom); + setOperationAction(ISD::UMUL_LOHI, MVT::i32, Custom); setOperationAction(ISD::MULHS, MVT::i32, Expand); setOperationAction(ISD::MULHU, MVT::i32, Expand); setOperationAction(ISD::SHL_PARTS, MVT::i32, Expand); @@ -167,6 +169,8 @@ LowerOperation(SDValue Op, SelectionDAG &DAG) { case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG); case ISD::VAARG: return LowerVAARG(Op, DAG); case ISD::VASTART: return LowerVASTART(Op, DAG); + case ISD::SMUL_LOHI: return LowerSMUL_LOHI(Op, DAG); + case ISD::UMUL_LOHI: return LowerUMUL_LOHI(Op, DAG); // FIXME: Remove these when LegalizeDAGTypes lands. case ISD::ADD: case ISD::SUB: return ExpandADDSUB(Op.getNode(), DAG); @@ -544,6 +548,40 @@ LowerSTORE(SDValue Op, SelectionDAG &DAG) } SDValue XCoreTargetLowering:: +LowerSMUL_LOHI(SDValue Op, SelectionDAG &DAG) +{ + assert(Op.getValueType() == MVT::i32 && Op.getOpcode() == ISD::SMUL_LOHI && + "Unexpected operand to lower!"); + DebugLoc dl = Op.getDebugLoc(); + SDValue LHS = Op.getOperand(0); + SDValue RHS = Op.getOperand(1); + SDValue Zero = DAG.getConstant(0, MVT::i32); + SDValue Hi = DAG.getNode(XCoreISD::MACCS, dl, + DAG.getVTList(MVT::i32, MVT::i32), Zero, Zero, + LHS, RHS); + SDValue Lo(Hi.getNode(), 1); + SDValue Ops[] = { Lo, Hi }; + return DAG.getMergeValues(Ops, 2, dl); +} + +SDValue XCoreTargetLowering:: +LowerUMUL_LOHI(SDValue Op, SelectionDAG &DAG) +{ + assert(Op.getValueType() == MVT::i32 && Op.getOpcode() == ISD::UMUL_LOHI && + "Unexpected operand to lower!"); + DebugLoc dl = Op.getDebugLoc(); + SDValue LHS = Op.getOperand(0); + SDValue RHS = Op.getOperand(1); + SDValue Zero = DAG.getConstant(0, MVT::i32); + SDValue Hi = DAG.getNode(XCoreISD::MACCU, dl, + DAG.getVTList(MVT::i32, MVT::i32), Zero, Zero, + LHS, RHS); + SDValue Lo(Hi.getNode(), 1); + SDValue Ops[] = { Lo, Hi }; + return DAG.getMergeValues(Ops, 2, dl); +} + +SDValue XCoreTargetLowering:: TryExpandADDSUBWithMul(SDNode *N, SelectionDAG &DAG) { SDValue Mul; diff --git a/lib/Target/XCore/XCoreISelLowering.h b/lib/Target/XCore/XCoreISelLowering.h index 4013723111..6b467c3f9c 100644 --- a/lib/Target/XCore/XCoreISelLowering.h +++ b/lib/Target/XCore/XCoreISelLowering.h @@ -138,6 +138,8 @@ namespace llvm { SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG); SDValue LowerVAARG(SDValue Op, SelectionDAG &DAG); SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG); + SDValue LowerUMUL_LOHI(SDValue Op, SelectionDAG &DAG); + SDValue LowerSMUL_LOHI(SDValue Op, SelectionDAG &DAG); SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG); // Inline asm support diff --git a/test/CodeGen/XCore/mul64.ll b/test/CodeGen/XCore/mul64.ll new file mode 100644 index 0000000000..c42c2f59cd --- /dev/null +++ b/test/CodeGen/XCore/mul64.ll @@ -0,0 +1,30 @@ +; RUN: llc < %s -march=xcore | FileCheck %s +define i64 @umul_lohi(i32 %a, i32 %b) { +entry: + %0 = zext i32 %a to i64 + %1 = zext i32 %b to i64 + %2 = mul i64 %1, %0 + ret i64 %2 +} +; CHECK: umul_lohi: +; CHECK: ldc r2, 0 +; CHECK-NEXT: mov r3, r2 +; CHECK-NEXT: maccu r2, r3, r1, r0 +; CHECK-NEXT: mov r0, r3 +; CHECK-NEXT: mov r1, r2 +; CHECK-NEXT: retsp 0 + +define i64 @smul_lohi(i32 %a, i32 %b) { +entry: + %0 = sext i32 %a to i64 + %1 = sext i32 %b to i64 + %2 = mul i64 %1, %0 + ret i64 %2 +} +; CHECK: smul_lohi: +; CHECK: ldc r2, 0 +; CHECK-NEXT: mov r3, r2 +; CHECK-NEXT: maccs r2, r3, r1, r0 +; CHECK-NEXT: mov r0, r3 +; CHECK-NEXT: mov r1, r2 +; CHECK-NEXT: retsp 0 |