mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-28 19:31:58 +00:00
R600: Move division custom lowering out of AMDILISelLowering
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@210997 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
47d34abdb0
commit
57177e3361
@ -464,8 +464,6 @@ SDValue AMDGPUTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG)
|
||||
"instruction is not implemented yet!");
|
||||
break;
|
||||
// AMDIL DAG lowering
|
||||
case ISD::SDIV: return LowerSDIV(Op, DAG);
|
||||
case ISD::SREM: return LowerSREM(Op, DAG);
|
||||
case ISD::SIGN_EXTEND_INREG: return LowerSIGN_EXTEND_INREG(Op, DAG);
|
||||
case ISD::BRCOND: return LowerBRCOND(Op, DAG);
|
||||
// AMDGPU DAG lowering
|
||||
@ -473,6 +471,8 @@ SDValue AMDGPUTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG)
|
||||
case ISD::EXTRACT_SUBVECTOR: return LowerEXTRACT_SUBVECTOR(Op, DAG);
|
||||
case ISD::FrameIndex: return LowerFrameIndex(Op, DAG);
|
||||
case ISD::INTRINSIC_WO_CHAIN: return LowerINTRINSIC_WO_CHAIN(Op, DAG);
|
||||
case ISD::SDIV: return LowerSDIV(Op, DAG);
|
||||
case ISD::SREM: return LowerSREM(Op, DAG);
|
||||
case ISD::UDIVREM: return LowerUDIVREM(Op, DAG);
|
||||
case ISD::UINT_TO_FP: return LowerUINT_TO_FP(Op, DAG);
|
||||
}
|
||||
@ -1199,6 +1199,250 @@ SDValue AMDGPUTargetLowering::LowerSTORE(SDValue Op, SelectionDAG &DAG) const {
|
||||
return SDValue();
|
||||
}
|
||||
|
||||
SDValue AMDGPUTargetLowering::LowerSDIV24(SDValue Op, SelectionDAG &DAG) const {
|
||||
SDLoc DL(Op);
|
||||
EVT OVT = Op.getValueType();
|
||||
SDValue LHS = Op.getOperand(0);
|
||||
SDValue RHS = Op.getOperand(1);
|
||||
MVT INTTY;
|
||||
MVT FLTTY;
|
||||
if (!OVT.isVector()) {
|
||||
INTTY = MVT::i32;
|
||||
FLTTY = MVT::f32;
|
||||
} else if (OVT.getVectorNumElements() == 2) {
|
||||
INTTY = MVT::v2i32;
|
||||
FLTTY = MVT::v2f32;
|
||||
} else if (OVT.getVectorNumElements() == 4) {
|
||||
INTTY = MVT::v4i32;
|
||||
FLTTY = MVT::v4f32;
|
||||
}
|
||||
unsigned bitsize = OVT.getScalarType().getSizeInBits();
|
||||
// char|short jq = ia ^ ib;
|
||||
SDValue jq = DAG.getNode(ISD::XOR, DL, OVT, LHS, RHS);
|
||||
|
||||
// jq = jq >> (bitsize - 2)
|
||||
jq = DAG.getNode(ISD::SRA, DL, OVT, jq, DAG.getConstant(bitsize - 2, OVT));
|
||||
|
||||
// jq = jq | 0x1
|
||||
jq = DAG.getNode(ISD::OR, DL, OVT, jq, DAG.getConstant(1, OVT));
|
||||
|
||||
// jq = (int)jq
|
||||
jq = DAG.getSExtOrTrunc(jq, DL, INTTY);
|
||||
|
||||
// int ia = (int)LHS;
|
||||
SDValue ia = DAG.getSExtOrTrunc(LHS, DL, INTTY);
|
||||
|
||||
// int ib, (int)RHS;
|
||||
SDValue ib = DAG.getSExtOrTrunc(RHS, DL, INTTY);
|
||||
|
||||
// float fa = (float)ia;
|
||||
SDValue fa = DAG.getNode(ISD::SINT_TO_FP, DL, FLTTY, ia);
|
||||
|
||||
// float fb = (float)ib;
|
||||
SDValue fb = DAG.getNode(ISD::SINT_TO_FP, DL, FLTTY, ib);
|
||||
|
||||
// float fq = native_divide(fa, fb);
|
||||
SDValue fq = DAG.getNode(AMDGPUISD::DIV_INF, DL, FLTTY, fa, fb);
|
||||
|
||||
// fq = trunc(fq);
|
||||
fq = DAG.getNode(ISD::FTRUNC, DL, FLTTY, fq);
|
||||
|
||||
// float fqneg = -fq;
|
||||
SDValue fqneg = DAG.getNode(ISD::FNEG, DL, FLTTY, fq);
|
||||
|
||||
// float fr = mad(fqneg, fb, fa);
|
||||
SDValue fr = DAG.getNode(ISD::FADD, DL, FLTTY,
|
||||
DAG.getNode(ISD::MUL, DL, FLTTY, fqneg, fb), fa);
|
||||
|
||||
// int iq = (int)fq;
|
||||
SDValue iq = DAG.getNode(ISD::FP_TO_SINT, DL, INTTY, fq);
|
||||
|
||||
// fr = fabs(fr);
|
||||
fr = DAG.getNode(ISD::FABS, DL, FLTTY, fr);
|
||||
|
||||
// fb = fabs(fb);
|
||||
fb = DAG.getNode(ISD::FABS, DL, FLTTY, fb);
|
||||
|
||||
// int cv = fr >= fb;
|
||||
SDValue cv;
|
||||
if (INTTY == MVT::i32) {
|
||||
cv = DAG.getSetCC(DL, INTTY, fr, fb, ISD::SETOGE);
|
||||
} else {
|
||||
cv = DAG.getSetCC(DL, INTTY, fr, fb, ISD::SETOGE);
|
||||
}
|
||||
// jq = (cv ? jq : 0);
|
||||
jq = DAG.getNode(ISD::SELECT, DL, OVT, cv, jq,
|
||||
DAG.getConstant(0, OVT));
|
||||
// dst = iq + jq;
|
||||
iq = DAG.getSExtOrTrunc(iq, DL, OVT);
|
||||
iq = DAG.getNode(ISD::ADD, DL, OVT, iq, jq);
|
||||
return iq;
|
||||
}
|
||||
|
||||
SDValue AMDGPUTargetLowering::LowerSDIV32(SDValue Op, SelectionDAG &DAG) const {
|
||||
SDLoc DL(Op);
|
||||
EVT OVT = Op.getValueType();
|
||||
SDValue LHS = Op.getOperand(0);
|
||||
SDValue RHS = Op.getOperand(1);
|
||||
// The LowerSDIV32 function generates equivalent to the following IL.
|
||||
// mov r0, LHS
|
||||
// mov r1, RHS
|
||||
// ilt r10, r0, 0
|
||||
// ilt r11, r1, 0
|
||||
// iadd r0, r0, r10
|
||||
// iadd r1, r1, r11
|
||||
// ixor r0, r0, r10
|
||||
// ixor r1, r1, r11
|
||||
// udiv r0, r0, r1
|
||||
// ixor r10, r10, r11
|
||||
// iadd r0, r0, r10
|
||||
// ixor DST, r0, r10
|
||||
|
||||
// mov r0, LHS
|
||||
SDValue r0 = LHS;
|
||||
|
||||
// mov r1, RHS
|
||||
SDValue r1 = RHS;
|
||||
|
||||
// ilt r10, r0, 0
|
||||
SDValue r10 = DAG.getSelectCC(DL,
|
||||
r0, DAG.getConstant(0, OVT),
|
||||
DAG.getConstant(-1, MVT::i32),
|
||||
DAG.getConstant(0, MVT::i32),
|
||||
ISD::SETLT);
|
||||
|
||||
// ilt r11, r1, 0
|
||||
SDValue r11 = DAG.getSelectCC(DL,
|
||||
r1, DAG.getConstant(0, OVT),
|
||||
DAG.getConstant(-1, MVT::i32),
|
||||
DAG.getConstant(0, MVT::i32),
|
||||
ISD::SETLT);
|
||||
|
||||
// iadd r0, r0, r10
|
||||
r0 = DAG.getNode(ISD::ADD, DL, OVT, r0, r10);
|
||||
|
||||
// iadd r1, r1, r11
|
||||
r1 = DAG.getNode(ISD::ADD, DL, OVT, r1, r11);
|
||||
|
||||
// ixor r0, r0, r10
|
||||
r0 = DAG.getNode(ISD::XOR, DL, OVT, r0, r10);
|
||||
|
||||
// ixor r1, r1, r11
|
||||
r1 = DAG.getNode(ISD::XOR, DL, OVT, r1, r11);
|
||||
|
||||
// udiv r0, r0, r1
|
||||
r0 = DAG.getNode(ISD::UDIV, DL, OVT, r0, r1);
|
||||
|
||||
// ixor r10, r10, r11
|
||||
r10 = DAG.getNode(ISD::XOR, DL, OVT, r10, r11);
|
||||
|
||||
// iadd r0, r0, r10
|
||||
r0 = DAG.getNode(ISD::ADD, DL, OVT, r0, r10);
|
||||
|
||||
// ixor DST, r0, r10
|
||||
SDValue DST = DAG.getNode(ISD::XOR, DL, OVT, r0, r10);
|
||||
return DST;
|
||||
}
|
||||
|
||||
SDValue AMDGPUTargetLowering::LowerSDIV64(SDValue Op, SelectionDAG &DAG) const {
|
||||
return SDValue(Op.getNode(), 0);
|
||||
}
|
||||
|
||||
SDValue AMDGPUTargetLowering::LowerSDIV(SDValue Op, SelectionDAG &DAG) const {
|
||||
EVT OVT = Op.getValueType().getScalarType();
|
||||
|
||||
if (OVT == MVT::i64)
|
||||
return LowerSDIV64(Op, DAG);
|
||||
|
||||
if (OVT.getScalarType() == MVT::i32)
|
||||
return LowerSDIV32(Op, DAG);
|
||||
|
||||
if (OVT == MVT::i16 || OVT == MVT::i8) {
|
||||
// FIXME: We should be checking for the masked bits. This isn't reached
|
||||
// because i8 and i16 are not legal types.
|
||||
return LowerSDIV24(Op, DAG);
|
||||
}
|
||||
|
||||
return SDValue(Op.getNode(), 0);
|
||||
}
|
||||
|
||||
SDValue AMDGPUTargetLowering::LowerSREM32(SDValue Op, SelectionDAG &DAG) const {
|
||||
SDLoc DL(Op);
|
||||
EVT OVT = Op.getValueType();
|
||||
SDValue LHS = Op.getOperand(0);
|
||||
SDValue RHS = Op.getOperand(1);
|
||||
// The LowerSREM32 function generates equivalent to the following IL.
|
||||
// mov r0, LHS
|
||||
// mov r1, RHS
|
||||
// ilt r10, r0, 0
|
||||
// ilt r11, r1, 0
|
||||
// iadd r0, r0, r10
|
||||
// iadd r1, r1, r11
|
||||
// ixor r0, r0, r10
|
||||
// ixor r1, r1, r11
|
||||
// udiv r20, r0, r1
|
||||
// umul r20, r20, r1
|
||||
// sub r0, r0, r20
|
||||
// iadd r0, r0, r10
|
||||
// ixor DST, r0, r10
|
||||
|
||||
// mov r0, LHS
|
||||
SDValue r0 = LHS;
|
||||
|
||||
// mov r1, RHS
|
||||
SDValue r1 = RHS;
|
||||
|
||||
// ilt r10, r0, 0
|
||||
SDValue r10 = DAG.getSetCC(DL, OVT, r0, DAG.getConstant(0, OVT), ISD::SETLT);
|
||||
|
||||
// ilt r11, r1, 0
|
||||
SDValue r11 = DAG.getSetCC(DL, OVT, r1, DAG.getConstant(0, OVT), ISD::SETLT);
|
||||
|
||||
// iadd r0, r0, r10
|
||||
r0 = DAG.getNode(ISD::ADD, DL, OVT, r0, r10);
|
||||
|
||||
// iadd r1, r1, r11
|
||||
r1 = DAG.getNode(ISD::ADD, DL, OVT, r1, r11);
|
||||
|
||||
// ixor r0, r0, r10
|
||||
r0 = DAG.getNode(ISD::XOR, DL, OVT, r0, r10);
|
||||
|
||||
// ixor r1, r1, r11
|
||||
r1 = DAG.getNode(ISD::XOR, DL, OVT, r1, r11);
|
||||
|
||||
// udiv r20, r0, r1
|
||||
SDValue r20 = DAG.getNode(ISD::UREM, DL, OVT, r0, r1);
|
||||
|
||||
// umul r20, r20, r1
|
||||
r20 = DAG.getNode(AMDGPUISD::UMUL, DL, OVT, r20, r1);
|
||||
|
||||
// sub r0, r0, r20
|
||||
r0 = DAG.getNode(ISD::SUB, DL, OVT, r0, r20);
|
||||
|
||||
// iadd r0, r0, r10
|
||||
r0 = DAG.getNode(ISD::ADD, DL, OVT, r0, r10);
|
||||
|
||||
// ixor DST, r0, r10
|
||||
SDValue DST = DAG.getNode(ISD::XOR, DL, OVT, r0, r10);
|
||||
return DST;
|
||||
}
|
||||
|
||||
SDValue AMDGPUTargetLowering::LowerSREM64(SDValue Op, SelectionDAG &DAG) const {
|
||||
return SDValue(Op.getNode(), 0);
|
||||
}
|
||||
|
||||
SDValue AMDGPUTargetLowering::LowerSREM(SDValue Op, SelectionDAG &DAG) const {
|
||||
EVT OVT = Op.getValueType();
|
||||
|
||||
if (OVT.getScalarType() == MVT::i64)
|
||||
return LowerSREM64(Op, DAG);
|
||||
|
||||
if (OVT.getScalarType() == MVT::i32)
|
||||
return LowerSREM32(Op, DAG);
|
||||
|
||||
return SDValue(Op.getNode(), 0);
|
||||
}
|
||||
|
||||
SDValue AMDGPUTargetLowering::LowerUDIVREM(SDValue Op,
|
||||
SelectionDAG &DAG) const {
|
||||
SDLoc DL(Op);
|
||||
|
@ -42,6 +42,14 @@ private:
|
||||
SDValue MergeVectorStore(const SDValue &Op, SelectionDAG &DAG) const;
|
||||
/// \brief Split a vector store into multiple scalar stores.
|
||||
/// \returns The resulting chain.
|
||||
|
||||
SDValue LowerSDIV(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue LowerSDIV24(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue LowerSDIV32(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue LowerSDIV64(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue LowerSREM(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue LowerSREM32(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue LowerSREM64(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue LowerUDIVREM(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue LowerUINT_TO_FP(SDValue Op, SelectionDAG &DAG) const;
|
||||
|
||||
@ -146,13 +154,6 @@ public:
|
||||
|
||||
private:
|
||||
void InitAMDILLowering();
|
||||
SDValue LowerSREM(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue LowerSREM32(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue LowerSREM64(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue LowerSDIV(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue LowerSDIV24(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue LowerSDIV32(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue LowerSDIV64(SDValue Op, SelectionDAG &DAG) const;
|
||||
|
||||
SDValue ExpandSIGN_EXTEND_INREG(SDValue Op,
|
||||
unsigned BitsDiff,
|
||||
|
@ -138,274 +138,15 @@ AMDGPUTargetLowering::ShouldShrinkFPConstant(EVT VT) const {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// isMaskedValueZeroForTargetNode - Return true if 'Op & Mask' is known to
|
||||
// be zero. Op is expected to be a target specific node. Used by DAG
|
||||
// combiner.
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Other Lowering Hooks
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
SDValue
|
||||
AMDGPUTargetLowering::LowerSDIV(SDValue Op, SelectionDAG &DAG) const {
|
||||
EVT OVT = Op.getValueType();
|
||||
SDValue DST;
|
||||
if (OVT.getScalarType() == MVT::i64) {
|
||||
DST = LowerSDIV64(Op, DAG);
|
||||
} else if (OVT.getScalarType() == MVT::i32) {
|
||||
DST = LowerSDIV32(Op, DAG);
|
||||
} else if (OVT.getScalarType() == MVT::i16
|
||||
|| OVT.getScalarType() == MVT::i8) {
|
||||
DST = LowerSDIV24(Op, DAG);
|
||||
} else {
|
||||
DST = SDValue(Op.getNode(), 0);
|
||||
}
|
||||
return DST;
|
||||
}
|
||||
|
||||
SDValue
|
||||
AMDGPUTargetLowering::LowerSREM(SDValue Op, SelectionDAG &DAG) const {
|
||||
EVT OVT = Op.getValueType();
|
||||
|
||||
if (OVT.getScalarType() == MVT::i64)
|
||||
return LowerSREM64(Op, DAG);
|
||||
|
||||
if (OVT.getScalarType() == MVT::i32)
|
||||
return LowerSREM32(Op, DAG);
|
||||
|
||||
return SDValue(Op.getNode(), 0);
|
||||
}
|
||||
|
||||
SDValue
|
||||
AMDGPUTargetLowering::LowerBRCOND(SDValue Op, SelectionDAG &DAG) const {
|
||||
SDValue AMDGPUTargetLowering::LowerBRCOND(SDValue Op, SelectionDAG &DAG) const {
|
||||
SDValue Chain = Op.getOperand(0);
|
||||
SDValue Cond = Op.getOperand(1);
|
||||
SDValue Jump = Op.getOperand(2);
|
||||
SDValue Result;
|
||||
Result = DAG.getNode(
|
||||
AMDGPUISD::BRANCH_COND,
|
||||
SDLoc(Op),
|
||||
Op.getValueType(),
|
||||
Chain, Jump, Cond);
|
||||
return Result;
|
||||
}
|
||||
|
||||
SDValue
|
||||
AMDGPUTargetLowering::LowerSDIV24(SDValue Op, SelectionDAG &DAG) const {
|
||||
SDLoc DL(Op);
|
||||
EVT OVT = Op.getValueType();
|
||||
SDValue LHS = Op.getOperand(0);
|
||||
SDValue RHS = Op.getOperand(1);
|
||||
MVT INTTY;
|
||||
MVT FLTTY;
|
||||
if (!OVT.isVector()) {
|
||||
INTTY = MVT::i32;
|
||||
FLTTY = MVT::f32;
|
||||
} else if (OVT.getVectorNumElements() == 2) {
|
||||
INTTY = MVT::v2i32;
|
||||
FLTTY = MVT::v2f32;
|
||||
} else if (OVT.getVectorNumElements() == 4) {
|
||||
INTTY = MVT::v4i32;
|
||||
FLTTY = MVT::v4f32;
|
||||
}
|
||||
unsigned bitsize = OVT.getScalarType().getSizeInBits();
|
||||
// char|short jq = ia ^ ib;
|
||||
SDValue jq = DAG.getNode(ISD::XOR, DL, OVT, LHS, RHS);
|
||||
|
||||
// jq = jq >> (bitsize - 2)
|
||||
jq = DAG.getNode(ISD::SRA, DL, OVT, jq, DAG.getConstant(bitsize - 2, OVT));
|
||||
|
||||
// jq = jq | 0x1
|
||||
jq = DAG.getNode(ISD::OR, DL, OVT, jq, DAG.getConstant(1, OVT));
|
||||
|
||||
// jq = (int)jq
|
||||
jq = DAG.getSExtOrTrunc(jq, DL, INTTY);
|
||||
|
||||
// int ia = (int)LHS;
|
||||
SDValue ia = DAG.getSExtOrTrunc(LHS, DL, INTTY);
|
||||
|
||||
// int ib, (int)RHS;
|
||||
SDValue ib = DAG.getSExtOrTrunc(RHS, DL, INTTY);
|
||||
|
||||
// float fa = (float)ia;
|
||||
SDValue fa = DAG.getNode(ISD::SINT_TO_FP, DL, FLTTY, ia);
|
||||
|
||||
// float fb = (float)ib;
|
||||
SDValue fb = DAG.getNode(ISD::SINT_TO_FP, DL, FLTTY, ib);
|
||||
|
||||
// float fq = native_divide(fa, fb);
|
||||
SDValue fq = DAG.getNode(AMDGPUISD::DIV_INF, DL, FLTTY, fa, fb);
|
||||
|
||||
// fq = trunc(fq);
|
||||
fq = DAG.getNode(ISD::FTRUNC, DL, FLTTY, fq);
|
||||
|
||||
// float fqneg = -fq;
|
||||
SDValue fqneg = DAG.getNode(ISD::FNEG, DL, FLTTY, fq);
|
||||
|
||||
// float fr = mad(fqneg, fb, fa);
|
||||
SDValue fr = DAG.getNode(ISD::FADD, DL, FLTTY,
|
||||
DAG.getNode(ISD::MUL, DL, FLTTY, fqneg, fb), fa);
|
||||
|
||||
// int iq = (int)fq;
|
||||
SDValue iq = DAG.getNode(ISD::FP_TO_SINT, DL, INTTY, fq);
|
||||
|
||||
// fr = fabs(fr);
|
||||
fr = DAG.getNode(ISD::FABS, DL, FLTTY, fr);
|
||||
|
||||
// fb = fabs(fb);
|
||||
fb = DAG.getNode(ISD::FABS, DL, FLTTY, fb);
|
||||
|
||||
// int cv = fr >= fb;
|
||||
SDValue cv;
|
||||
if (INTTY == MVT::i32) {
|
||||
cv = DAG.getSetCC(DL, INTTY, fr, fb, ISD::SETOGE);
|
||||
} else {
|
||||
cv = DAG.getSetCC(DL, INTTY, fr, fb, ISD::SETOGE);
|
||||
}
|
||||
// jq = (cv ? jq : 0);
|
||||
jq = DAG.getNode(ISD::SELECT, DL, OVT, cv, jq,
|
||||
DAG.getConstant(0, OVT));
|
||||
// dst = iq + jq;
|
||||
iq = DAG.getSExtOrTrunc(iq, DL, OVT);
|
||||
iq = DAG.getNode(ISD::ADD, DL, OVT, iq, jq);
|
||||
return iq;
|
||||
}
|
||||
|
||||
SDValue
|
||||
AMDGPUTargetLowering::LowerSDIV32(SDValue Op, SelectionDAG &DAG) const {
|
||||
SDLoc DL(Op);
|
||||
EVT OVT = Op.getValueType();
|
||||
SDValue LHS = Op.getOperand(0);
|
||||
SDValue RHS = Op.getOperand(1);
|
||||
// The LowerSDIV32 function generates equivalent to the following IL.
|
||||
// mov r0, LHS
|
||||
// mov r1, RHS
|
||||
// ilt r10, r0, 0
|
||||
// ilt r11, r1, 0
|
||||
// iadd r0, r0, r10
|
||||
// iadd r1, r1, r11
|
||||
// ixor r0, r0, r10
|
||||
// ixor r1, r1, r11
|
||||
// udiv r0, r0, r1
|
||||
// ixor r10, r10, r11
|
||||
// iadd r0, r0, r10
|
||||
// ixor DST, r0, r10
|
||||
|
||||
// mov r0, LHS
|
||||
SDValue r0 = LHS;
|
||||
|
||||
// mov r1, RHS
|
||||
SDValue r1 = RHS;
|
||||
|
||||
// ilt r10, r0, 0
|
||||
SDValue r10 = DAG.getSelectCC(DL,
|
||||
r0, DAG.getConstant(0, OVT),
|
||||
DAG.getConstant(-1, MVT::i32),
|
||||
DAG.getConstant(0, MVT::i32),
|
||||
ISD::SETLT);
|
||||
|
||||
// ilt r11, r1, 0
|
||||
SDValue r11 = DAG.getSelectCC(DL,
|
||||
r1, DAG.getConstant(0, OVT),
|
||||
DAG.getConstant(-1, MVT::i32),
|
||||
DAG.getConstant(0, MVT::i32),
|
||||
ISD::SETLT);
|
||||
|
||||
// iadd r0, r0, r10
|
||||
r0 = DAG.getNode(ISD::ADD, DL, OVT, r0, r10);
|
||||
|
||||
// iadd r1, r1, r11
|
||||
r1 = DAG.getNode(ISD::ADD, DL, OVT, r1, r11);
|
||||
|
||||
// ixor r0, r0, r10
|
||||
r0 = DAG.getNode(ISD::XOR, DL, OVT, r0, r10);
|
||||
|
||||
// ixor r1, r1, r11
|
||||
r1 = DAG.getNode(ISD::XOR, DL, OVT, r1, r11);
|
||||
|
||||
// udiv r0, r0, r1
|
||||
r0 = DAG.getNode(ISD::UDIV, DL, OVT, r0, r1);
|
||||
|
||||
// ixor r10, r10, r11
|
||||
r10 = DAG.getNode(ISD::XOR, DL, OVT, r10, r11);
|
||||
|
||||
// iadd r0, r0, r10
|
||||
r0 = DAG.getNode(ISD::ADD, DL, OVT, r0, r10);
|
||||
|
||||
// ixor DST, r0, r10
|
||||
SDValue DST = DAG.getNode(ISD::XOR, DL, OVT, r0, r10);
|
||||
return DST;
|
||||
}
|
||||
|
||||
SDValue
|
||||
AMDGPUTargetLowering::LowerSDIV64(SDValue Op, SelectionDAG &DAG) const {
|
||||
return SDValue(Op.getNode(), 0);
|
||||
}
|
||||
|
||||
SDValue
|
||||
AMDGPUTargetLowering::LowerSREM32(SDValue Op, SelectionDAG &DAG) const {
|
||||
SDLoc DL(Op);
|
||||
EVT OVT = Op.getValueType();
|
||||
SDValue LHS = Op.getOperand(0);
|
||||
SDValue RHS = Op.getOperand(1);
|
||||
// The LowerSREM32 function generates equivalent to the following IL.
|
||||
// mov r0, LHS
|
||||
// mov r1, RHS
|
||||
// ilt r10, r0, 0
|
||||
// ilt r11, r1, 0
|
||||
// iadd r0, r0, r10
|
||||
// iadd r1, r1, r11
|
||||
// ixor r0, r0, r10
|
||||
// ixor r1, r1, r11
|
||||
// udiv r20, r0, r1
|
||||
// umul r20, r20, r1
|
||||
// sub r0, r0, r20
|
||||
// iadd r0, r0, r10
|
||||
// ixor DST, r0, r10
|
||||
|
||||
// mov r0, LHS
|
||||
SDValue r0 = LHS;
|
||||
|
||||
// mov r1, RHS
|
||||
SDValue r1 = RHS;
|
||||
|
||||
// ilt r10, r0, 0
|
||||
SDValue r10 = DAG.getSetCC(DL, OVT, r0, DAG.getConstant(0, OVT), ISD::SETLT);
|
||||
|
||||
// ilt r11, r1, 0
|
||||
SDValue r11 = DAG.getSetCC(DL, OVT, r1, DAG.getConstant(0, OVT), ISD::SETLT);
|
||||
|
||||
// iadd r0, r0, r10
|
||||
r0 = DAG.getNode(ISD::ADD, DL, OVT, r0, r10);
|
||||
|
||||
// iadd r1, r1, r11
|
||||
r1 = DAG.getNode(ISD::ADD, DL, OVT, r1, r11);
|
||||
|
||||
// ixor r0, r0, r10
|
||||
r0 = DAG.getNode(ISD::XOR, DL, OVT, r0, r10);
|
||||
|
||||
// ixor r1, r1, r11
|
||||
r1 = DAG.getNode(ISD::XOR, DL, OVT, r1, r11);
|
||||
|
||||
// udiv r20, r0, r1
|
||||
SDValue r20 = DAG.getNode(ISD::UREM, DL, OVT, r0, r1);
|
||||
|
||||
// umul r20, r20, r1
|
||||
r20 = DAG.getNode(AMDGPUISD::UMUL, DL, OVT, r20, r1);
|
||||
|
||||
// sub r0, r0, r20
|
||||
r0 = DAG.getNode(ISD::SUB, DL, OVT, r0, r20);
|
||||
|
||||
// iadd r0, r0, r10
|
||||
r0 = DAG.getNode(ISD::ADD, DL, OVT, r0, r10);
|
||||
|
||||
// ixor DST, r0, r10
|
||||
SDValue DST = DAG.getNode(ISD::XOR, DL, OVT, r0, r10);
|
||||
return DST;
|
||||
}
|
||||
|
||||
SDValue
|
||||
AMDGPUTargetLowering::LowerSREM64(SDValue Op, SelectionDAG &DAG) const {
|
||||
return SDValue(Op.getNode(), 0);
|
||||
|
||||
return DAG.getNode(AMDGPUISD::BRANCH_COND, SDLoc(Op), Op.getValueType(),
|
||||
Chain, Jump, Cond);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user