summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/patches/patch-r262261-llvm-r198281-sparc.diff
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/patches/patch-r262261-llvm-r198281-sparc.diff')
-rw-r--r--contrib/llvm/patches/patch-r262261-llvm-r198281-sparc.diff99
1 files changed, 99 insertions, 0 deletions
diff --git a/contrib/llvm/patches/patch-r262261-llvm-r198281-sparc.diff b/contrib/llvm/patches/patch-r262261-llvm-r198281-sparc.diff
new file mode 100644
index 0000000..0af21f4
--- /dev/null
+++ b/contrib/llvm/patches/patch-r262261-llvm-r198281-sparc.diff
@@ -0,0 +1,99 @@
+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://svn.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
OpenPOWER on IntegriCloud