a426b286c8
patch for r263619, and unify all the URLs to point to svnweb.
100 lines
3.8 KiB
Diff
100 lines
3.8 KiB
Diff
Pull in r198281 from upstream llvm trunk (by Venkatraman Govindaraju):
|
|
|
|
[SparcV9]: Custom lower UMULO/SMULO so that the arguments are send to __multi3() in correct order.
|
|
|
|
Introduced here: http://svnweb.freebsd.org/changeset/base/262261
|
|
|
|
Index: lib/Target/Sparc/SparcISelLowering.cpp
|
|
===================================================================
|
|
--- lib/Target/Sparc/SparcISelLowering.cpp
|
|
+++ lib/Target/Sparc/SparcISelLowering.cpp
|
|
@@ -1525,6 +1525,9 @@ SparcTargetLowering::SparcTargetLowering(TargetMac
|
|
setOperationAction(ISD::SMUL_LOHI, MVT::i64, Expand);
|
|
setOperationAction(ISD::MULHU, MVT::i64, Expand);
|
|
setOperationAction(ISD::MULHS, MVT::i64, Expand);
|
|
+
|
|
+ setOperationAction(ISD::UMULO, MVT::i64, Custom);
|
|
+ setOperationAction(ISD::SMULO, MVT::i64, Custom);
|
|
}
|
|
|
|
// VASTART needs to be custom lowered to use the VarArgsFrameIndex.
|
|
@@ -2673,6 +2676,53 @@ static SDValue LowerADDC_ADDE_SUBC_SUBE(SDValue Op
|
|
return DAG.getMergeValues(Ops, 2, dl);
|
|
}
|
|
|
|
+// Custom lower UMULO/SMULO for SPARC. This code is similar to ExpandNode()
|
|
+// in LegalizeDAG.cpp except the order of arguments to the library function.
|
|
+static SDValue LowerUMULO_SMULO(SDValue Op, SelectionDAG &DAG,
|
|
+ const SparcTargetLowering &TLI)
|
|
+{
|
|
+ unsigned opcode = Op.getOpcode();
|
|
+ assert((opcode == ISD::UMULO || opcode == ISD::SMULO) && "Invalid Opcode.");
|
|
+
|
|
+ bool isSigned = (opcode == ISD::SMULO);
|
|
+ EVT VT = MVT::i64;
|
|
+ EVT WideVT = MVT::i128;
|
|
+ SDLoc dl(Op);
|
|
+ SDValue LHS = Op.getOperand(0);
|
|
+
|
|
+ if (LHS.getValueType() != VT)
|
|
+ return Op;
|
|
+
|
|
+ SDValue ShiftAmt = DAG.getConstant(63, VT);
|
|
+
|
|
+ SDValue RHS = Op.getOperand(1);
|
|
+ SDValue HiLHS = DAG.getNode(ISD::SRA, dl, VT, LHS, ShiftAmt);
|
|
+ SDValue HiRHS = DAG.getNode(ISD::SRA, dl, MVT::i64, RHS, ShiftAmt);
|
|
+ SDValue Args[] = { HiLHS, LHS, HiRHS, RHS };
|
|
+
|
|
+ SDValue MulResult = TLI.makeLibCall(DAG,
|
|
+ RTLIB::MUL_I128, WideVT,
|
|
+ Args, 4, isSigned, dl).first;
|
|
+ SDValue BottomHalf = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, VT,
|
|
+ MulResult, DAG.getIntPtrConstant(0));
|
|
+ SDValue TopHalf = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, VT,
|
|
+ MulResult, DAG.getIntPtrConstant(1));
|
|
+ if (isSigned) {
|
|
+ SDValue Tmp1 = DAG.getNode(ISD::SRA, dl, VT, BottomHalf, ShiftAmt);
|
|
+ TopHalf = DAG.getSetCC(dl, MVT::i32, TopHalf, Tmp1, ISD::SETNE);
|
|
+ } else {
|
|
+ TopHalf = DAG.getSetCC(dl, MVT::i32, TopHalf, DAG.getConstant(0, VT),
|
|
+ ISD::SETNE);
|
|
+ }
|
|
+ // MulResult is a node with an illegal type. Because such things are not
|
|
+ // generally permitted during this phase of legalization, delete the
|
|
+ // node. The above EXTRACT_ELEMENT nodes should have been folded.
|
|
+ DAG.DeleteNode(MulResult.getNode());
|
|
+
|
|
+ SDValue Ops[2] = { BottomHalf, TopHalf } ;
|
|
+ return DAG.getMergeValues(Ops, 2, dl);
|
|
+}
|
|
+
|
|
SDValue SparcTargetLowering::
|
|
LowerOperation(SDValue Op, SelectionDAG &DAG) const {
|
|
|
|
@@ -2726,6 +2776,8 @@ LowerOperation(SDValue Op, SelectionDAG &DAG) cons
|
|
case ISD::ADDE:
|
|
case ISD::SUBC:
|
|
case ISD::SUBE: return LowerADDC_ADDE_SUBC_SUBE(Op, DAG);
|
|
+ case ISD::UMULO:
|
|
+ case ISD::SMULO: return LowerUMULO_SMULO(Op, DAG, *this);
|
|
}
|
|
}
|
|
|
|
Index: test/CodeGen/SPARC/64cond.ll
|
|
===================================================================
|
|
--- test/CodeGen/SPARC/64cond.ll
|
|
+++ test/CodeGen/SPARC/64cond.ll
|
|
@@ -111,6 +111,11 @@ entry:
|
|
}
|
|
|
|
; CHECK-LABEL: setcc_resultty
|
|
+; CHECK-DAG: srax %i0, 63, %o0
|
|
+; CHECK-DAG: or %g0, %i0, %o1
|
|
+; CHECK-DAG: or %g0, 0, %o2
|
|
+; CHECK-DAG: or %g0, 32, %o3
|
|
+; CHECK-DAG: call __multi3
|
|
; CHECK: cmp
|
|
; CHECK: movne %xcc, 1, [[R:%[gilo][0-7]]]
|
|
; CHECK: or [[R]], %i1, %i0
|