diff options
author | Matt Arsenault <Matthew.Arsenault@amd.com> | 2013-11-18 20:09:47 +0000 |
---|---|---|
committer | Matt Arsenault <Matthew.Arsenault@amd.com> | 2013-11-18 20:09:47 +0000 |
commit | e64a2896094be370f5ca3d755f62c762fb94b37a (patch) | |
tree | 380c065a1d26e1dd8a02a6d1a49df1651626752a /lib/Target/R600 | |
parent | 15703e0a71e7583b107499045374c364976452e2 (diff) | |
download | external_llvm-e64a2896094be370f5ca3d755f62c762fb94b37a.zip external_llvm-e64a2896094be370f5ca3d755f62c762fb94b37a.tar.gz external_llvm-e64a2896094be370f5ca3d755f62c762fb94b37a.tar.bz2 |
R600/SI: Implement add i64, but do not yet enable.
Test doesn't actually check the output. I need
to fix add i64 being matched for the addressing
calculations.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@195040 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/R600')
-rw-r--r-- | lib/Target/R600/SIISelLowering.cpp | 28 | ||||
-rw-r--r-- | lib/Target/R600/SIISelLowering.h | 1 |
2 files changed, 29 insertions, 0 deletions
diff --git a/lib/Target/R600/SIISelLowering.cpp b/lib/Target/R600/SIISelLowering.cpp index 95b3be7..9435e9b 100644 --- a/lib/Target/R600/SIISelLowering.cpp +++ b/lib/Target/R600/SIISelLowering.cpp @@ -424,6 +424,7 @@ SDValue SITargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const { SIMachineFunctionInfo *MFI = MF.getInfo<SIMachineFunctionInfo>(); switch (Op.getOpcode()) { default: return AMDGPUTargetLowering::LowerOperation(Op, DAG); + case ISD::ADD: return LowerADD(Op, DAG); case ISD::BRCOND: return LowerBRCOND(Op, DAG); case ISD::LOAD: { LoadSDNode *Load = dyn_cast<LoadSDNode>(Op); @@ -560,6 +561,33 @@ SDValue SITargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const { return SDValue(); } +SDValue SITargetLowering::LowerADD(SDValue Op, + SelectionDAG &DAG) const { + if (Op.getValueType() != MVT::i64) + return SDValue(); + + SDLoc DL(Op); + SDValue LHS = Op.getOperand(0); + SDValue RHS = Op.getOperand(1); + + SDValue Zero = DAG.getConstant(0, MVT::i32); + SDValue One = DAG.getConstant(1, MVT::i32); + + SDValue Lo0 = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, LHS, Zero); + SDValue Hi0 = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, LHS, One); + + SDValue Lo1 = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, RHS, Zero); + SDValue Hi1 = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, RHS, One); + + SDVTList VTList = DAG.getVTList(MVT::i32, MVT::Glue); + + SDValue AddLo = DAG.getNode(ISD::ADDC, DL, VTList, Lo0, Lo1); + SDValue Carry = AddLo.getValue(1); + SDValue AddHi = DAG.getNode(ISD::ADDE, DL, VTList, Hi0, Hi1, Carry); + + return DAG.getNode(ISD::BUILD_PAIR, DL, MVT::i64, AddLo, AddHi.getValue(0)); +} + /// \brief Helper function for LowerBRCOND static SDNode *findUser(SDValue Value, unsigned Opcode) { diff --git a/lib/Target/R600/SIISelLowering.h b/lib/Target/R600/SIISelLowering.h index 384caf4..9933ece 100644 --- a/lib/Target/R600/SIISelLowering.h +++ b/lib/Target/R600/SIISelLowering.h @@ -30,6 +30,7 @@ class SITargetLowering : public AMDGPUTargetLowering { SDValue LowerSIGN_EXTEND(SDValue Op, SelectionDAG &DAG) const; SDValue LowerSTORE(SDValue Op, SelectionDAG &DAG) const; SDValue LowerZERO_EXTEND(SDValue Op, SelectionDAG &DAG) const; + SDValue LowerADD(SDValue Op, SelectionDAG &DAG) const; SDValue LowerBRCOND(SDValue Op, SelectionDAG &DAG) const; SDValue ResourceDescriptorToi128(SDValue Op, SelectionDAG &DAG) const; |