summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTom Stellard <[email protected]>2012-05-25 12:18:14 -0400
committerTom Stellard <[email protected]>2012-05-25 15:40:59 -0400
commit4863477e22e02af046915ca2a33dbecfd0ed34b4 (patch)
treeae3c334f03ae8d5103622888ddb54fa73ad8ce63 /src
parent667cdba2118cf82e0027bf44314c9d1334d00840 (diff)
radeon/llvm: Use tablegen pattern to lower bitconvert
Diffstat (limited to 'src')
-rw-r--r--src/gallium/drivers/radeon/AMDGPUInstructions.td6
-rw-r--r--src/gallium/drivers/radeon/AMDILISelLowering.cpp285
-rw-r--r--src/gallium/drivers/radeon/R600Instructions.td5
-rw-r--r--src/gallium/drivers/radeon/R600LowerInstructions.cpp9
4 files changed, 11 insertions, 294 deletions
diff --git a/src/gallium/drivers/radeon/AMDGPUInstructions.td b/src/gallium/drivers/radeon/AMDGPUInstructions.td
index a004b9c5aba..f4abbae6397 100644
--- a/src/gallium/drivers/radeon/AMDGPUInstructions.td
+++ b/src/gallium/drivers/radeon/AMDGPUInstructions.td
@@ -115,6 +115,12 @@ class Insert_Element <ValueType elem_type, ValueType vec_type,
(INSERT_SUBREG vec_class:$vec, elem_class:$elem, sub_reg)
>;
+// bitconvert pattern
+class BitConvert <ValueType dt, ValueType st, RegisterClass rc> : Pat <
+ (dt (bitconvert (st rc:$src0))),
+ (dt rc:$src0)
+>;
+
include "R600Instructions.td"
include "SIInstrInfo.td"
diff --git a/src/gallium/drivers/radeon/AMDILISelLowering.cpp b/src/gallium/drivers/radeon/AMDILISelLowering.cpp
index 96d7e518ba4..92cf9d60b64 100644
--- a/src/gallium/drivers/radeon/AMDILISelLowering.cpp
+++ b/src/gallium/drivers/radeon/AMDILISelLowering.cpp
@@ -640,7 +640,6 @@ AMDILTargetLowering::convertToReg(MachineOperand op) const
setOperationAction(ISD::SREM, VT, Expand);
setOperationAction(ISD::UINT_TO_FP, VT, Custom);
setOperationAction(ISD::FP_TO_UINT, VT, Custom);
- setOperationAction(ISDBITCAST, VT, Custom);
setOperationAction(ISD::GlobalAddress, VT, Custom);
setOperationAction(ISD::JumpTable, VT, Custom);
setOperationAction(ISD::ConstantPool, VT, Custom);
@@ -1513,7 +1512,6 @@ AMDILTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const
LOWER(SELECT);
LOWER(SETCC);
LOWER(SIGN_EXTEND_INREG);
- LOWER(BITCAST);
LOWER(DYNAMIC_STACKALLOC);
LOWER(BRCOND);
LOWER(BR_CC);
@@ -3232,289 +3230,6 @@ AMDILTargetLowering::genIntType(uint32_t size, uint32_t numEle) const
}
SDValue
-AMDILTargetLowering::LowerBITCAST(SDValue Op, SelectionDAG &DAG) const
-{
- SDValue Src = Op.getOperand(0);
- SDValue Dst = Op;
- SDValue Res;
- DebugLoc DL = Op.getDebugLoc();
- EVT SrcVT = Src.getValueType();
- EVT DstVT = Dst.getValueType();
- // Lets bitcast the floating point types to an
- // equivalent integer type before converting to vectors.
- if (SrcVT.getScalarType().isFloatingPoint()) {
- Src = DAG.getNode(AMDILISD::BITCONV, DL, genIntType(
- SrcVT.getScalarType().getSimpleVT().getSizeInBits(),
- SrcVT.isVector() ? SrcVT.getVectorNumElements() : 1),
- Src);
- SrcVT = Src.getValueType();
- }
- uint32_t ScalarSrcSize = SrcVT.getScalarType()
- .getSimpleVT().getSizeInBits();
- uint32_t ScalarDstSize = DstVT.getScalarType()
- .getSimpleVT().getSizeInBits();
- uint32_t SrcNumEle = SrcVT.isVector() ? SrcVT.getVectorNumElements() : 1;
- uint32_t DstNumEle = DstVT.isVector() ? DstVT.getVectorNumElements() : 1;
- bool isVec = SrcVT.isVector();
- if (DstVT.getScalarType().isInteger() &&
- (SrcVT.getScalarType().isInteger()
- || SrcVT.getScalarType().isFloatingPoint())) {
- if ((ScalarDstSize == 64 && SrcNumEle == 4 && ScalarSrcSize == 16)
- || (ScalarSrcSize == 64
- && DstNumEle == 4
- && ScalarDstSize == 16)) {
- // This is the problematic case when bitcasting i64 <-> <4 x i16>
- // This approach is a little different as we cannot generate a
- // <4 x i64> vector
- // as that is illegal in our backend and we are already past
- // the DAG legalizer.
- // So, in this case, we will do the following conversion.
- // Case 1:
- // %dst = <4 x i16> %src bitconvert i64 ==>
- // %tmp = <4 x i16> %src convert <4 x i32>
- // %tmp = <4 x i32> %tmp and 0xFFFF
- // %tmp = <4 x i32> %tmp shift_left <0, 16, 0, 16>
- // %tmp = <4 x i32> %tmp or %tmp.xz %tmp.yw
- // %dst = <2 x i32> %tmp bitcast i64
- // case 2:
- // %dst = i64 %src bitconvert <4 x i16> ==>
- // %tmp = i64 %src bitcast <2 x i32>
- // %tmp = <4 x i32> %tmp vinsert %tmp.xxyy
- // %tmp = <4 x i32> %tmp shift_right <0, 16, 0, 16>
- // %tmp = <4 x i32> %tmp and 0xFFFF
- // %dst = <4 x i16> %tmp bitcast <4 x i32>
- SDValue mask = DAG.getNode(AMDILISD::VBUILD, DL, MVT::v4i32,
- DAG.getConstant(0xFFFF, MVT::i32));
- SDValue const16 = DAG.getConstant(16, MVT::i32);
- if (ScalarDstSize == 64) {
- // case 1
- Op = DAG.getSExtOrTrunc(Src, DL, MVT::v4i32);
- Op = DAG.getNode(ISD::AND, DL, Op.getValueType(), Op, mask);
- SDValue x = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::i32,
- Op, DAG.getConstant(0, MVT::i32));
- SDValue y = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::i32,
- Op, DAG.getConstant(1, MVT::i32));
- y = DAG.getNode(ISD::SHL, DL, MVT::i32, y, const16);
- SDValue z = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::i32,
- Op, DAG.getConstant(2, MVT::i32));
- SDValue w = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL, MVT::i32,
- Op, DAG.getConstant(3, MVT::i32));
- w = DAG.getNode(ISD::SHL, DL, MVT::i32, w, const16);
- x = DAG.getNode(ISD::OR, DL, MVT::i32, x, y);
- y = DAG.getNode(ISD::OR, DL, MVT::i32, z, w);
- Res = DAG.getNode((isVec) ? AMDILISD::LCREATE2 : AMDILISD::LCREATE, DL, MVT::i64, x, y);
- return Res;
- } else {
- // case 2
- SDValue lo = DAG.getNode((isVec) ? AMDILISD::LCOMPLO2 : AMDILISD::LCOMPLO, DL, MVT::i32, Src);
- SDValue lor16
- = DAG.getNode(ISD::SRL, DL, MVT::i32, lo, const16);
- SDValue hi = DAG.getNode((isVec) ? AMDILISD::LCOMPHI2 : AMDILISD::LCOMPHI, DL, MVT::i32, Src);
- SDValue hir16
- = DAG.getNode(ISD::SRL, DL, MVT::i32, hi, const16);
- SDValue resVec = DAG.getNode(AMDILISD::VBUILD, DL,
- MVT::v4i32, lo);
- SDValue idxVal = DAG.getNode(ISD::ZERO_EXTEND, DL,
- getPointerTy(), DAG.getConstant(1, MVT::i32));
- resVec = DAG.getNode(ISD::INSERT_VECTOR_ELT, DL, MVT::v4i32,
- resVec, lor16, idxVal);
- idxVal = DAG.getNode(ISD::ZERO_EXTEND, DL,
- getPointerTy(), DAG.getConstant(2, MVT::i32));
- resVec = DAG.getNode(ISD::INSERT_VECTOR_ELT, DL, MVT::v4i32,
- resVec, hi, idxVal);
- idxVal = DAG.getNode(ISD::ZERO_EXTEND, DL,
- getPointerTy(), DAG.getConstant(3, MVT::i32));
- resVec = DAG.getNode(ISD::INSERT_VECTOR_ELT, DL, MVT::v4i32,
- resVec, hir16, idxVal);
- resVec = DAG.getNode(ISD::AND, DL, MVT::v4i32, resVec, mask);
- Res = DAG.getSExtOrTrunc(resVec, DL, MVT::v4i16);
- return Res;
- }
- } else {
- // There are four cases we need to worry about for bitcasts
- // where the size of all
- // source, intermediates and result is <= 128 bits, unlike
- // the above case
- // 1) Sub32bit bitcast 32bitAlign
- // %dst = <4 x i8> bitcast i32
- // (also <[2|4] x i16> to <[2|4] x i32>)
- // 2) 32bitAlign bitcast Sub32bit
- // %dst = i32 bitcast <4 x i8>
- // 3) Sub32bit bitcast LargerSub32bit
- // %dst = <2 x i8> bitcast i16
- // (also <4 x i8> to <2 x i16>)
- // 4) Sub32bit bitcast SmallerSub32bit
- // %dst = i16 bitcast <2 x i8>
- // (also <2 x i16> to <4 x i8>)
- // This also only handles types that are powers of two
- if ((ScalarDstSize & (ScalarDstSize - 1))
- || (ScalarSrcSize & (ScalarSrcSize - 1))) {
- } else if (ScalarDstSize >= 32 && ScalarSrcSize < 32) {
- // case 1:
- EVT IntTy = genIntType(ScalarDstSize, SrcNumEle);
-#if 0 // TODO: LLVM does not like this for some reason, cannot SignExt vectors
- SDValue res = DAG.getSExtOrTrunc(Src, DL, IntTy);
-#else
- SDValue res = DAG.getNode(AMDILISD::VBUILD, DL, IntTy,
- DAG.getUNDEF(IntTy.getScalarType()));
- for (uint32_t x = 0; x < SrcNumEle; ++x) {
- SDValue idx = DAG.getNode(ISD::ZERO_EXTEND, DL,
- getPointerTy(), DAG.getConstant(x, MVT::i32));
- SDValue temp = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL,
- SrcVT.getScalarType(), Src,
- DAG.getConstant(x, MVT::i32));
- temp = DAG.getSExtOrTrunc(temp, DL, IntTy.getScalarType());
- res = DAG.getNode(ISD::INSERT_VECTOR_ELT, DL, IntTy,
- res, temp, idx);
- }
-#endif
- SDValue mask = DAG.getNode(AMDILISD::VBUILD, DL, IntTy,
- DAG.getConstant((1 << ScalarSrcSize) - 1, MVT::i32));
- SDValue *newEle = new SDValue[SrcNumEle];
- res = DAG.getNode(ISD::AND, DL, IntTy, res, mask);
- for (uint32_t x = 0; x < SrcNumEle; ++x) {
- newEle[x] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL,
- IntTy.getScalarType(), res,
- DAG.getConstant(x, MVT::i32));
- }
- uint32_t Ratio = SrcNumEle / DstNumEle;
- for (uint32_t x = 0; x < SrcNumEle; ++x) {
- if (x % Ratio) {
- newEle[x] = DAG.getNode(ISD::SHL, DL,
- IntTy.getScalarType(), newEle[x],
- DAG.getConstant(ScalarSrcSize * (x % Ratio),
- MVT::i32));
- }
- }
- for (uint32_t x = 0; x < SrcNumEle; x += 2) {
- newEle[x] = DAG.getNode(ISD::OR, DL,
- IntTy.getScalarType(), newEle[x], newEle[x + 1]);
- }
- if (ScalarSrcSize == 8) {
- for (uint32_t x = 0; x < SrcNumEle; x += 4) {
- newEle[x] = DAG.getNode(ISD::OR, DL,
- IntTy.getScalarType(), newEle[x], newEle[x + 2]);
- }
- if (DstNumEle == 1) {
- Dst = newEle[0];
- } else {
- Dst = DAG.getNode(AMDILISD::VBUILD, DL, DstVT,
- newEle[0]);
- for (uint32_t x = 1; x < DstNumEle; ++x) {
- SDValue idx = DAG.getNode(ISD::ZERO_EXTEND, DL,
- getPointerTy(), DAG.getConstant(x, MVT::i32));
- Dst = DAG.getNode(ISD::INSERT_VECTOR_ELT, DL,
- DstVT, Dst, newEle[x * 4], idx);
- }
- }
- } else {
- if (DstNumEle == 1) {
- Dst = newEle[0];
- } else {
- Dst = DAG.getNode(AMDILISD::VBUILD, DL, DstVT,
- newEle[0]);
- for (uint32_t x = 1; x < DstNumEle; ++x) {
- SDValue idx = DAG.getNode(ISD::ZERO_EXTEND, DL,
- getPointerTy(), DAG.getConstant(x, MVT::i32));
- Dst = DAG.getNode(ISD::INSERT_VECTOR_ELT, DL,
- DstVT, Dst, newEle[x * 2], idx);
- }
- }
- }
- delete [] newEle;
- return Dst;
- } else if (ScalarDstSize < 32 && ScalarSrcSize >= 32) {
- // case 2:
- EVT IntTy = genIntType(ScalarSrcSize, DstNumEle);
- SDValue vec = DAG.getNode(AMDILISD::VBUILD, DL, IntTy,
- DAG.getUNDEF(IntTy.getScalarType()));
- uint32_t mult = (ScalarDstSize == 8) ? 4 : 2;
- for (uint32_t x = 0; x < SrcNumEle; ++x) {
- for (uint32_t y = 0; y < mult; ++y) {
- SDValue idx = DAG.getNode(ISD::ZERO_EXTEND, DL,
- getPointerTy(),
- DAG.getConstant(x * mult + y, MVT::i32));
- SDValue t;
- if (SrcNumEle > 1) {
- t = DAG.getNode(ISD::EXTRACT_VECTOR_ELT,
- DL, SrcVT.getScalarType(), Src,
- DAG.getConstant(x, MVT::i32));
- } else {
- t = Src;
- }
- if (y != 0) {
- t = DAG.getNode(ISD::SRL, DL, t.getValueType(),
- t, DAG.getConstant(y * ScalarDstSize,
- MVT::i32));
- }
- vec = DAG.getNode(ISD::INSERT_VECTOR_ELT,
- DL, IntTy, vec, t, idx);
- }
- }
- Dst = DAG.getSExtOrTrunc(vec, DL, DstVT);
- return Dst;
- } else if (ScalarDstSize == 16 && ScalarSrcSize == 8) {
- // case 3:
- SDValue *numEle = new SDValue[SrcNumEle];
- for (uint32_t x = 0; x < SrcNumEle; ++x) {
- numEle[x] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL,
- MVT::i8, Src, DAG.getConstant(x, MVT::i32));
- numEle[x] = DAG.getSExtOrTrunc(numEle[x], DL, MVT::i16);
- numEle[x] = DAG.getNode(ISD::AND, DL, MVT::i16, numEle[x],
- DAG.getConstant(0xFF, MVT::i16));
- }
- for (uint32_t x = 1; x < SrcNumEle; x += 2) {
- numEle[x] = DAG.getNode(ISD::SHL, DL, MVT::i16, numEle[x],
- DAG.getConstant(8, MVT::i16));
- numEle[x - 1] = DAG.getNode(ISD::OR, DL, MVT::i16,
- numEle[x-1], numEle[x]);
- }
- if (DstNumEle > 1) {
- // If we are not a scalar i16, the only other case is a
- // v2i16 since we can't have v8i8 at this point, v4i16
- // cannot be generated
- Dst = DAG.getNode(AMDILISD::VBUILD, DL, MVT::v2i16,
- numEle[0]);
- SDValue idx = DAG.getNode(ISD::ZERO_EXTEND, DL,
- getPointerTy(), DAG.getConstant(1, MVT::i32));
- Dst = DAG.getNode(ISD::INSERT_VECTOR_ELT, DL, MVT::v2i16,
- Dst, numEle[2], idx);
- } else {
- Dst = numEle[0];
- }
- delete [] numEle;
- return Dst;
- } else if (ScalarDstSize == 8 && ScalarSrcSize == 16) {
- // case 4:
- SDValue *numEle = new SDValue[DstNumEle];
- for (uint32_t x = 0; x < SrcNumEle; ++x) {
- numEle[x * 2] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DL,
- MVT::i16, Src, DAG.getConstant(x, MVT::i32));
- numEle[x * 2 + 1] = DAG.getNode(ISD::SRL, DL, MVT::i16,
- numEle[x * 2], DAG.getConstant(8, MVT::i16));
- }
- MVT ty = (SrcNumEle == 1) ? MVT::v2i16 : MVT::v4i16;
- Dst = DAG.getNode(AMDILISD::VBUILD, DL, ty, numEle[0]);
- for (uint32_t x = 1; x < DstNumEle; ++x) {
- SDValue idx = DAG.getNode(ISD::ZERO_EXTEND, DL,
- getPointerTy(), DAG.getConstant(x, MVT::i32));
- Dst = DAG.getNode(ISD::INSERT_VECTOR_ELT, DL, ty,
- Dst, numEle[x], idx);
- }
- delete [] numEle;
- ty = (SrcNumEle == 1) ? MVT::v2i8 : MVT::v4i8;
- Res = DAG.getSExtOrTrunc(Dst, DL, ty);
- return Res;
- }
- }
- }
- Res = DAG.getNode(AMDILISD::BITCONV,
- Dst.getDebugLoc(),
- Dst.getValueType(), Src);
- return Res;
-}
-
-SDValue
AMDILTargetLowering::LowerDYNAMIC_STACKALLOC(SDValue Op,
SelectionDAG &DAG) const
{
diff --git a/src/gallium/drivers/radeon/R600Instructions.td b/src/gallium/drivers/radeon/R600Instructions.td
index a2a509ea8ba..f038736267b 100644
--- a/src/gallium/drivers/radeon/R600Instructions.td
+++ b/src/gallium/drivers/radeon/R600Instructions.td
@@ -1164,4 +1164,9 @@ def : Insert_Element <i32, v4i32, R600_Reg32, R600_Reg128, 5, sel_y>;
def : Insert_Element <i32, v4i32, R600_Reg32, R600_Reg128, 6, sel_z>;
def : Insert_Element <i32, v4i32, R600_Reg32, R600_Reg128, 7, sel_w>;
+// bitconvert patterns
+
+def : BitConvert <i32, f32, R600_Reg32>;
+def : BitConvert <f32, i32, R600_Reg32>;
+
} // End isR600toCayman Predicate
diff --git a/src/gallium/drivers/radeon/R600LowerInstructions.cpp b/src/gallium/drivers/radeon/R600LowerInstructions.cpp
index 3b96b195fe6..70c9b8b9f67 100644
--- a/src/gallium/drivers/radeon/R600LowerInstructions.cpp
+++ b/src/gallium/drivers/radeon/R600LowerInstructions.cpp
@@ -164,15 +164,6 @@ bool R600LowerInstructionsPass::runOnMachineFunction(MachineFunction &MF)
break;
}
- case AMDIL::IL_ASINT_f32:
- case AMDIL::IL_ASINT_i32:
- case AMDIL::IL_ASFLOAT_f32:
- case AMDIL::IL_ASFLOAT_i32:
- BuildMI(MBB, I, MBB.findDebugLoc(I), TII->get(AMDIL::COPY))
- .addOperand(MI.getOperand(0))
- .addOperand(MI.getOperand(1));
- break;
-
case AMDIL::ILT:
BuildMI(MBB, I, MBB.findDebugLoc(I), TII->get(AMDIL::SETGT_INT))
.addOperand(MI.getOperand(0))