mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-29 10:32:47 +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!");
|
"instruction is not implemented yet!");
|
||||||
break;
|
break;
|
||||||
// AMDIL DAG lowering
|
// 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::SIGN_EXTEND_INREG: return LowerSIGN_EXTEND_INREG(Op, DAG);
|
||||||
case ISD::BRCOND: return LowerBRCOND(Op, DAG);
|
case ISD::BRCOND: return LowerBRCOND(Op, DAG);
|
||||||
// AMDGPU DAG lowering
|
// 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::EXTRACT_SUBVECTOR: return LowerEXTRACT_SUBVECTOR(Op, DAG);
|
||||||
case ISD::FrameIndex: return LowerFrameIndex(Op, DAG);
|
case ISD::FrameIndex: return LowerFrameIndex(Op, DAG);
|
||||||
case ISD::INTRINSIC_WO_CHAIN: return LowerINTRINSIC_WO_CHAIN(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::UDIVREM: return LowerUDIVREM(Op, DAG);
|
||||||
case ISD::UINT_TO_FP: return LowerUINT_TO_FP(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();
|
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,
|
SDValue AMDGPUTargetLowering::LowerUDIVREM(SDValue Op,
|
||||||
SelectionDAG &DAG) const {
|
SelectionDAG &DAG) const {
|
||||||
SDLoc DL(Op);
|
SDLoc DL(Op);
|
||||||
|
@ -42,6 +42,14 @@ private:
|
|||||||
SDValue MergeVectorStore(const SDValue &Op, SelectionDAG &DAG) const;
|
SDValue MergeVectorStore(const SDValue &Op, SelectionDAG &DAG) const;
|
||||||
/// \brief Split a vector store into multiple scalar stores.
|
/// \brief Split a vector store into multiple scalar stores.
|
||||||
/// \returns The resulting chain.
|
/// \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 LowerUDIVREM(SDValue Op, SelectionDAG &DAG) const;
|
||||||
SDValue LowerUINT_TO_FP(SDValue Op, SelectionDAG &DAG) const;
|
SDValue LowerUINT_TO_FP(SDValue Op, SelectionDAG &DAG) const;
|
||||||
|
|
||||||
@ -146,13 +154,6 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void InitAMDILLowering();
|
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,
|
SDValue ExpandSIGN_EXTEND_INREG(SDValue Op,
|
||||||
unsigned BitsDiff,
|
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
|
// Other Lowering Hooks
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
SDValue
|
SDValue AMDGPUTargetLowering::LowerBRCOND(SDValue Op, SelectionDAG &DAG) const {
|
||||||
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 Chain = Op.getOperand(0);
|
SDValue Chain = Op.getOperand(0);
|
||||||
SDValue Cond = Op.getOperand(1);
|
SDValue Cond = Op.getOperand(1);
|
||||||
SDValue Jump = Op.getOperand(2);
|
SDValue Jump = Op.getOperand(2);
|
||||||
SDValue Result;
|
|
||||||
Result = DAG.getNode(
|
return DAG.getNode(AMDGPUISD::BRANCH_COND, SDLoc(Op), Op.getValueType(),
|
||||||
AMDGPUISD::BRANCH_COND,
|
Chain, Jump, 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);
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user