mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-09 13:33:17 +00:00
Added CONVERT_RNDSAT (conversion with rounding and saturation) SDNode to
support targets that support these conversions. Users should avoid using this node as the current targets don't generating code for it. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@59001 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
cf1f23f6e3
commit
77cdf30742
@ -343,6 +343,11 @@ public:
|
||||
|
||||
SDValue getCondCode(ISD::CondCode Cond);
|
||||
|
||||
/// Returns the ConvertRndSat Note: Avoid using this node because it may
|
||||
/// disappear in the future and most targets don't support it.
|
||||
SDValue getConvertRndSat(MVT VT, SDValue Val, SDValue DTy, SDValue STy,
|
||||
SDValue Rnd, SDValue Sat, ISD::CvtCode Code);
|
||||
|
||||
/// getZeroExtendInReg - Return the expression required to zero extend the Op
|
||||
/// value assuming it was the smaller SrcTy value.
|
||||
SDValue getZeroExtendInReg(SDValue Op, MVT SrcTy);
|
||||
|
@ -431,6 +431,18 @@ namespace ISD {
|
||||
// conversions, but that is a noop, deleted by getNode().
|
||||
BIT_CONVERT,
|
||||
|
||||
// CONVERT_RNDSAT - This operator is used to support various conversions
|
||||
// between various types (float, signed, unsigned) with rounding and
|
||||
// saturation. NOTE: Avoid using this operator as most target don't support
|
||||
// it and they might be removed. It takes the following arguments:
|
||||
// 0) value
|
||||
// 1) dest type (type to convert to)
|
||||
// 2) src type (type to convert from)
|
||||
// 3) rounding imm
|
||||
// 4) saturation imm
|
||||
// 5) ISD::CvtCode indicating the type of conversion to do
|
||||
CONVERT_RNDSAT,
|
||||
|
||||
// FNEG, FABS, FSQRT, FSIN, FCOS, FPOWI, FPOW,
|
||||
// FLOG, FLOG2, FLOG10, FEXP, FEXP2,
|
||||
// FCEIL, FTRUNC, FRINT, FNEARBYINT, FFLOOR - Perform various unary floating
|
||||
@ -831,6 +843,22 @@ namespace ISD {
|
||||
/// function returns SETCC_INVALID if it is not possible to represent the
|
||||
/// resultant comparison.
|
||||
CondCode getSetCCAndOperation(CondCode Op1, CondCode Op2, bool isInteger);
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
/// CvtCode enum - This enum defines the various converts CONVERT_RNDSAT
|
||||
/// supports.
|
||||
enum CvtCode {
|
||||
CVT_FF, // Float from Float
|
||||
CVT_FS, // Float from Signed
|
||||
CVT_FU, // Float from Unsigned
|
||||
CVT_SF, // Signed from Float
|
||||
CVT_UF, // Unsigned from Float
|
||||
CVT_SS, // Signed from Signed
|
||||
CVT_SU, // Signed from Unsigned
|
||||
CVT_US, // Unsigned from Signed
|
||||
CVT_UU, // Unsigned from Unsigned
|
||||
CVT_INVALID // Marker - Invalid opcode
|
||||
};
|
||||
} // end llvm::ISD namespace
|
||||
|
||||
|
||||
@ -2125,6 +2153,27 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
/// CvtRndSatSDNode - NOTE: avoid using this node as this may disappear in the
|
||||
/// future and most targets don't support it.
|
||||
class CvtRndSatSDNode : public SDNode {
|
||||
ISD::CvtCode CvtCode;
|
||||
virtual void ANCHOR(); // Out-of-line virtual method to give class a home.
|
||||
protected:
|
||||
friend class SelectionDAG;
|
||||
explicit CvtRndSatSDNode(MVT VT, const SDValue *Ops, unsigned NumOps,
|
||||
ISD::CvtCode Code)
|
||||
: SDNode(ISD::CONVERT_RNDSAT, getSDVTList(VT), Ops, NumOps), CvtCode(Code) {
|
||||
assert(NumOps == 5 && "wrong number of operations");
|
||||
}
|
||||
public:
|
||||
ISD::CvtCode getCvtCode() const { return CvtCode; }
|
||||
|
||||
static bool classof(const CvtRndSatSDNode *) { return true; }
|
||||
static bool classof(const SDNode *N) {
|
||||
return N->getOpcode() == ISD::CONVERT_RNDSAT;
|
||||
}
|
||||
};
|
||||
|
||||
namespace ISD {
|
||||
struct ArgFlagsTy {
|
||||
private:
|
||||
|
@ -362,6 +362,29 @@ def int_flt_rounds : Intrinsic<[llvm_i32_ty]>,
|
||||
def int_trap : Intrinsic<[llvm_void_ty]>,
|
||||
GCCBuiltin<"__builtin_trap">;
|
||||
|
||||
// These convert intrinsics are to support various conversions between
|
||||
// various types with rounding and saturation. NOTE: avoid using these
|
||||
// intrinsics as they might be removed sometime in the future and
|
||||
// most targets don't support them.
|
||||
def int_convertff : Intrinsic<[llvm_anyfloat_ty, llvm_anyfloat_ty,
|
||||
llvm_i32_ty, llvm_i32_ty]>;
|
||||
def int_convertfsi : Intrinsic<[llvm_anyfloat_ty, llvm_anyint_ty,
|
||||
llvm_i32_ty, llvm_i32_ty]>;
|
||||
def int_convertfui : Intrinsic<[llvm_anyfloat_ty, llvm_anyint_ty,
|
||||
llvm_i32_ty, llvm_i32_ty]>;
|
||||
def int_convertsif : Intrinsic<[llvm_anyint_ty, llvm_anyfloat_ty,
|
||||
llvm_i32_ty, llvm_i32_ty]>;
|
||||
def int_convertuif : Intrinsic<[llvm_anyint_ty, llvm_anyfloat_ty,
|
||||
llvm_i32_ty, llvm_i32_ty]>;
|
||||
def int_convertss : Intrinsic<[llvm_anyint_ty, llvm_anyint_ty,
|
||||
llvm_i32_ty, llvm_i32_ty]>;
|
||||
def int_convertsu : Intrinsic<[llvm_anyint_ty, llvm_anyint_ty,
|
||||
llvm_i32_ty, llvm_i32_ty]>;
|
||||
def int_convertus : Intrinsic<[llvm_anyint_ty, llvm_anyint_ty,
|
||||
llvm_i32_ty, llvm_i32_ty]>;
|
||||
def int_convertuu : Intrinsic<[llvm_anyint_ty, llvm_anyint_ty,
|
||||
llvm_i32_ty, llvm_i32_ty]>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Target-specific intrinsics
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -3816,7 +3816,49 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ISD::CONVERT_RNDSAT: {
|
||||
ISD::CvtCode CvtCode = cast<CvtRndSatSDNode>(Node)->getCvtCode();
|
||||
switch (CvtCode) {
|
||||
default: assert(0 && "Unknown cvt code!");
|
||||
case ISD::CVT_SF:
|
||||
case ISD::CVT_UF:
|
||||
break;
|
||||
case ISD::CVT_FF:
|
||||
case ISD::CVT_FS:
|
||||
case ISD::CVT_FU:
|
||||
case ISD::CVT_SS:
|
||||
case ISD::CVT_SU:
|
||||
case ISD::CVT_US:
|
||||
case ISD::CVT_UU: {
|
||||
SDValue DTyOp = Node->getOperand(1);
|
||||
SDValue STyOp = Node->getOperand(2);
|
||||
SDValue RndOp = Node->getOperand(3);
|
||||
SDValue SatOp = Node->getOperand(4);
|
||||
switch (getTypeAction(Node->getOperand(0).getValueType())) {
|
||||
case Expand: assert(0 && "Shouldn't need to expand other operators here!");
|
||||
case Legal:
|
||||
Tmp1 = LegalizeOp(Node->getOperand(0));
|
||||
Result = DAG.UpdateNodeOperands(Result, Tmp1, DTyOp, STyOp,
|
||||
RndOp, SatOp);
|
||||
if (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0)) ==
|
||||
TargetLowering::Custom) {
|
||||
Tmp1 = TLI.LowerOperation(Result, DAG);
|
||||
if (Tmp1.getNode()) Result = Tmp1;
|
||||
}
|
||||
break;
|
||||
case Promote:
|
||||
Result = PromoteOp(Node->getOperand(0));
|
||||
// For FP, make Op1 a i32
|
||||
|
||||
Result = DAG.getConvertRndSat(Result.getValueType(), Result,
|
||||
DTyOp, STyOp, RndOp, SatOp, CvtCode);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} // end switch CvtCode
|
||||
break;
|
||||
}
|
||||
// Conversion operators. The source and destination have different types.
|
||||
case ISD::SINT_TO_FP:
|
||||
case ISD::UINT_TO_FP: {
|
||||
@ -4234,6 +4276,19 @@ SDValue SelectionDAGLegalize::PromoteOp(SDValue Op) {
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ISD::CONVERT_RNDSAT: {
|
||||
ISD::CvtCode CvtCode = cast<CvtRndSatSDNode>(Node)->getCvtCode();
|
||||
assert ((CvtCode == ISD::CVT_SS || CvtCode == ISD::CVT_SU ||
|
||||
CvtCode == ISD::CVT_US || CvtCode == ISD::CVT_UU ||
|
||||
CvtCode == ISD::CVT_SF || CvtCode == ISD::CVT_UF) &&
|
||||
"can only promote integers");
|
||||
Result = DAG.getConvertRndSat(NVT, Node->getOperand(0),
|
||||
Node->getOperand(1), Node->getOperand(2),
|
||||
Node->getOperand(3), Node->getOperand(4),
|
||||
CvtCode);
|
||||
break;
|
||||
|
||||
}
|
||||
case ISD::BIT_CONVERT:
|
||||
Result = EmitStackConvert(Node->getOperand(0), Node->getValueType(0),
|
||||
Node->getValueType(0));
|
||||
@ -7344,6 +7399,24 @@ void SelectionDAGLegalize::SplitVectorOp(SDValue Op, SDValue &Lo,
|
||||
Hi = DAG.getNode(Node->getOpcode(), NewVT_Hi, H);
|
||||
break;
|
||||
}
|
||||
case ISD::CONVERT_RNDSAT: {
|
||||
ISD::CvtCode CvtCode = cast<CvtRndSatSDNode>(Node)->getCvtCode();
|
||||
SDValue L, H;
|
||||
SplitVectorOp(Node->getOperand(0), L, H);
|
||||
SDValue DTyOpL = DAG.getValueType(NewVT_Lo);
|
||||
SDValue DTyOpH = DAG.getValueType(NewVT_Hi);
|
||||
SDValue STyOpL = DAG.getValueType(L.getValueType());
|
||||
SDValue STyOpH = DAG.getValueType(H.getValueType());
|
||||
|
||||
SDValue RndOp = Node->getOperand(3);
|
||||
SDValue SatOp = Node->getOperand(4);
|
||||
|
||||
Lo = DAG.getConvertRndSat(NewVT_Lo, L, DTyOpL, STyOpL,
|
||||
RndOp, SatOp, CvtCode);
|
||||
Hi = DAG.getConvertRndSat(NewVT_Hi, H, DTyOpH, STyOpH,
|
||||
RndOp, SatOp, CvtCode);
|
||||
break;
|
||||
}
|
||||
case ISD::LOAD: {
|
||||
LoadSDNode *LD = cast<LoadSDNode>(Node);
|
||||
SDValue Ch = LD->getChain();
|
||||
@ -7482,6 +7555,16 @@ SDValue SelectionDAGLegalize::ScalarizeVectorOp(SDValue Op) {
|
||||
NewVT,
|
||||
ScalarizeVectorOp(Node->getOperand(0)));
|
||||
break;
|
||||
case ISD::CONVERT_RNDSAT: {
|
||||
SDValue Op0 = ScalarizeVectorOp(Node->getOperand(0));
|
||||
Result = DAG.getConvertRndSat(NewVT, Op0,
|
||||
DAG.getValueType(NewVT),
|
||||
DAG.getValueType(Op0.getValueType()),
|
||||
Node->getOperand(3),
|
||||
Node->getOperand(4),
|
||||
cast<CvtRndSatSDNode>(Node)->getCvtCode());
|
||||
break;
|
||||
}
|
||||
case ISD::FPOWI:
|
||||
case ISD::FP_ROUND:
|
||||
Result = DAG.getNode(Node->getOpcode(),
|
||||
@ -7781,6 +7864,44 @@ SDValue SelectionDAGLegalize::WidenVectorOp(SDValue Op, MVT WidenVT) {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ISD::CONVERT_RNDSAT: {
|
||||
SDValue RndOp = Node->getOperand(3);
|
||||
SDValue SatOp = Node->getOperand(4);
|
||||
|
||||
TargetLowering::LegalizeAction action =
|
||||
TLI.getOperationAction(Node->getOpcode(), WidenVT);
|
||||
|
||||
SDValue SrcOp = Node->getOperand(0);
|
||||
|
||||
// Converts between two different types so we need to determine
|
||||
// the correct widen type for the input operand.
|
||||
MVT SVT = SrcOp.getValueType();
|
||||
assert(SVT.isVector() && "can not widen non vector type");
|
||||
MVT SEVT = SVT.getVectorElementType();
|
||||
MVT SWidenVT = MVT::getVectorVT(SEVT, NewNumElts);
|
||||
|
||||
SrcOp = WidenVectorOp(SrcOp, SWidenVT);
|
||||
assert(SrcOp.getValueType() == WidenVT);
|
||||
SDValue DTyOp = DAG.getValueType(WidenVT);
|
||||
SDValue STyOp = DAG.getValueType(SrcOp.getValueType());
|
||||
ISD::CvtCode CvtCode = cast<CvtRndSatSDNode>(Node)->getCvtCode();
|
||||
|
||||
Result = DAG.getConvertRndSat(WidenVT, SrcOp, DTyOp, STyOp,
|
||||
RndOp, SatOp, CvtCode);
|
||||
switch (action) {
|
||||
default: assert(0 && "action not supported");
|
||||
case TargetLowering::Legal:
|
||||
break;
|
||||
case TargetLowering::Promote:
|
||||
// We defer the promotion to when we legalize the op
|
||||
break;
|
||||
case TargetLowering::Expand:
|
||||
// Expand the operation into a bunch of nasty scalar code.
|
||||
Result = LegalizeOp(UnrollVectorOp(Result));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ISD::FPOW:
|
||||
case ISD::FPOWI:
|
||||
case ISD::ADD:
|
||||
|
@ -610,7 +610,8 @@ bool DAGTypeLegalizer::PromoteIntegerOperand(SDNode *N, unsigned OpNo) {
|
||||
case ISD::ZERO_EXTEND: Res = PromoteIntOp_ZERO_EXTEND(N); break;
|
||||
|
||||
case ISD::SINT_TO_FP:
|
||||
case ISD::UINT_TO_FP: Res = PromoteIntOp_INT_TO_FP(N); break;
|
||||
case ISD::UINT_TO_FP: Res = PromoteIntOp_INT_TO_FP(N); break;
|
||||
case ISD::CONVERT_RNDSAT: Res = PromoteIntOp_CONVERT_RNDSAT(N); break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -813,6 +814,21 @@ SDValue DAGTypeLegalizer::PromoteIntOp_INT_TO_FP(SDNode *N) {
|
||||
return DAG.UpdateNodeOperands(SDValue(N, 0), In);
|
||||
}
|
||||
|
||||
SDValue DAGTypeLegalizer::PromoteIntOp_CONVERT_RNDSAT(SDNode *N) {
|
||||
MVT OutVT = TLI.getTypeToTransformTo(N->getValueType(0));
|
||||
ISD::CvtCode CvtCode = cast<CvtRndSatSDNode>(N)->getCvtCode();
|
||||
assert ((CvtCode == ISD::CVT_SS || CvtCode == ISD::CVT_SU ||
|
||||
CvtCode == ISD::CVT_US || CvtCode == ISD::CVT_UU ||
|
||||
CvtCode == ISD::CVT_SF || CvtCode == ISD::CVT_UF) &&
|
||||
"can only promote integers");
|
||||
SDValue In = DAG.getConvertRndSat(OutVT,N->getOperand(0),
|
||||
N->getOperand(1), N->getOperand(2),
|
||||
N->getOperand(3), N->getOperand(4), CvtCode);
|
||||
return DAG.UpdateNodeOperands(SDValue(N, 0), In);
|
||||
}
|
||||
|
||||
|
||||
|
||||
SDValue DAGTypeLegalizer::PromoteIntOp_MEMBARRIER(SDNode *N) {
|
||||
SDValue NewOps[6];
|
||||
NewOps[0] = N->getOperand(0);
|
||||
|
@ -259,6 +259,7 @@ private:
|
||||
SDValue PromoteIntOp_BR_CC(SDNode *N, unsigned OpNo);
|
||||
SDValue PromoteIntOp_BRCOND(SDNode *N, unsigned OpNo);
|
||||
SDValue PromoteIntOp_BUILD_VECTOR(SDNode *N);
|
||||
SDValue PromoteIntOp_CONVERT_RNDSAT(SDNode *N);
|
||||
SDValue PromoteIntOp_FP_EXTEND(SDNode *N);
|
||||
SDValue PromoteIntOp_FP_ROUND(SDNode *N);
|
||||
SDValue PromoteIntOp_INT_TO_FP(SDNode *N);
|
||||
@ -442,6 +443,7 @@ private:
|
||||
SDValue ScalarizeVecRes_UnaryOp(SDNode *N);
|
||||
|
||||
SDValue ScalarizeVecRes_BIT_CONVERT(SDNode *N);
|
||||
SDValue ScalarizeVecRes_CONVERT_RNDSAT(SDNode *N);
|
||||
SDValue ScalarizeVecRes_EXTRACT_SUBVECTOR(SDNode *N);
|
||||
SDValue ScalarizeVecRes_FPOWI(SDNode *N);
|
||||
SDValue ScalarizeVecRes_INSERT_VECTOR_ELT(SDNode *N);
|
||||
@ -475,6 +477,7 @@ private:
|
||||
void SplitVecRes_BUILD_PAIR(SDNode *N, SDValue &Lo, SDValue &Hi);
|
||||
void SplitVecRes_BUILD_VECTOR(SDNode *N, SDValue &Lo, SDValue &Hi);
|
||||
void SplitVecRes_CONCAT_VECTORS(SDNode *N, SDValue &Lo, SDValue &Hi);
|
||||
void SplitVecRes_CONVERT_RNDSAT(SDNode *N, SDValue &Lo, SDValue &Hi);
|
||||
void SplitVecRes_EXTRACT_SUBVECTOR(SDNode *N, SDValue &Lo, SDValue &Hi);
|
||||
void SplitVecRes_FPOWI(SDNode *N, SDValue &Lo, SDValue &Hi);
|
||||
void SplitVecRes_INSERT_VECTOR_ELT(SDNode *N, SDValue &Lo, SDValue &Hi);
|
||||
|
@ -43,6 +43,7 @@ void DAGTypeLegalizer::ScalarizeVectorResult(SDNode *N, unsigned ResNo) {
|
||||
|
||||
case ISD::BIT_CONVERT: R = ScalarizeVecRes_BIT_CONVERT(N); break;
|
||||
case ISD::BUILD_VECTOR: R = N->getOperand(0); break;
|
||||
case ISD::CONVERT_RNDSAT: R = ScalarizeVecRes_CONVERT_RNDSAT(N); break;
|
||||
case ISD::EXTRACT_SUBVECTOR: R = ScalarizeVecRes_EXTRACT_SUBVECTOR(N); break;
|
||||
case ISD::FPOWI: R = ScalarizeVecRes_FPOWI(N); break;
|
||||
case ISD::INSERT_VECTOR_ELT: R = ScalarizeVecRes_INSERT_VECTOR_ELT(N); break;
|
||||
@ -106,6 +107,16 @@ SDValue DAGTypeLegalizer::ScalarizeVecRes_BIT_CONVERT(SDNode *N) {
|
||||
return DAG.getNode(ISD::BIT_CONVERT, NewVT, N->getOperand(0));
|
||||
}
|
||||
|
||||
SDValue DAGTypeLegalizer::ScalarizeVecRes_CONVERT_RNDSAT(SDNode *N) {
|
||||
MVT NewVT = N->getValueType(0).getVectorElementType();
|
||||
SDValue Op0 = GetScalarizedVector(N->getOperand(0));
|
||||
return DAG.getConvertRndSat(NewVT, Op0, DAG.getValueType(NewVT),
|
||||
DAG.getValueType(Op0.getValueType()),
|
||||
N->getOperand(3),
|
||||
N->getOperand(4),
|
||||
cast<CvtRndSatSDNode>(N)->getCvtCode());
|
||||
}
|
||||
|
||||
SDValue DAGTypeLegalizer::ScalarizeVecRes_EXTRACT_SUBVECTOR(SDNode *N) {
|
||||
return DAG.getNode(ISD::EXTRACT_VECTOR_ELT,
|
||||
N->getValueType(0).getVectorElementType(),
|
||||
@ -339,6 +350,7 @@ void DAGTypeLegalizer::SplitVectorResult(SDNode *N, unsigned ResNo) {
|
||||
case ISD::BIT_CONVERT: SplitVecRes_BIT_CONVERT(N, Lo, Hi); break;
|
||||
case ISD::BUILD_VECTOR: SplitVecRes_BUILD_VECTOR(N, Lo, Hi); break;
|
||||
case ISD::CONCAT_VECTORS: SplitVecRes_CONCAT_VECTORS(N, Lo, Hi); break;
|
||||
case ISD::CONVERT_RNDSAT: SplitVecRes_CONVERT_RNDSAT(N, Lo, Hi); break;
|
||||
case ISD::EXTRACT_SUBVECTOR: SplitVecRes_EXTRACT_SUBVECTOR(N, Lo, Hi); break;
|
||||
case ISD::FPOWI: SplitVecRes_FPOWI(N, Lo, Hi); break;
|
||||
case ISD::INSERT_VECTOR_ELT: SplitVecRes_INSERT_VECTOR_ELT(N, Lo, Hi); break;
|
||||
@ -487,6 +499,25 @@ void DAGTypeLegalizer::SplitVecRes_CONCAT_VECTORS(SDNode *N, SDValue &Lo,
|
||||
Hi = DAG.getNode(ISD::CONCAT_VECTORS, HiVT, &HiOps[0], HiOps.size());
|
||||
}
|
||||
|
||||
void DAGTypeLegalizer::SplitVecRes_CONVERT_RNDSAT(SDNode *N, SDValue &Lo,
|
||||
SDValue &Hi) {
|
||||
MVT LoVT, HiVT;
|
||||
GetSplitDestVTs(N->getValueType(0), LoVT, HiVT);
|
||||
SDValue VLo, VHi;
|
||||
GetSplitVector(N->getOperand(0), VLo, VHi);
|
||||
SDValue DTyOpLo = DAG.getValueType(LoVT);
|
||||
SDValue DTyOpHi = DAG.getValueType(HiVT);
|
||||
SDValue STyOpLo = DAG.getValueType(VLo.getValueType());
|
||||
SDValue STyOpHi = DAG.getValueType(VHi.getValueType());
|
||||
|
||||
SDValue RndOp = N->getOperand(3);
|
||||
SDValue SatOp = N->getOperand(4);
|
||||
ISD::CvtCode CvtCode = cast<CvtRndSatSDNode>(N)->getCvtCode();
|
||||
|
||||
Lo = DAG.getConvertRndSat(LoVT, VLo, DTyOpLo, STyOpLo, RndOp, SatOp, CvtCode);
|
||||
Hi = DAG.getConvertRndSat(HiVT, VHi, DTyOpHi, STyOpHi, RndOp, SatOp, CvtCode);
|
||||
}
|
||||
|
||||
void DAGTypeLegalizer::SplitVecRes_EXTRACT_SUBVECTOR(SDNode *N, SDValue &Lo,
|
||||
SDValue &Hi) {
|
||||
MVT LoVT, HiVT;
|
||||
|
@ -1137,6 +1137,21 @@ SDValue SelectionDAG::getCondCode(ISD::CondCode Cond) {
|
||||
return SDValue(CondCodeNodes[Cond], 0);
|
||||
}
|
||||
|
||||
SDValue SelectionDAG::getConvertRndSat(MVT VT, SDValue Val, SDValue DTy,
|
||||
SDValue STy, SDValue Rnd, SDValue Sat,
|
||||
ISD::CvtCode Code) {
|
||||
FoldingSetNodeID ID;
|
||||
void* IP = 0;
|
||||
if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
|
||||
return SDValue(E, 0);
|
||||
CvtRndSatSDNode *N = NodeAllocator.Allocate<CvtRndSatSDNode>();
|
||||
SDValue Ops[] = { Val, DTy, STy, Rnd, Sat };
|
||||
new (N) CvtRndSatSDNode(VT, Ops, 5, Code);
|
||||
CSEMap.InsertNode(N, IP);
|
||||
AllNodes.push_back(N);
|
||||
return SDValue(N, 0);
|
||||
}
|
||||
|
||||
SDValue SelectionDAG::getRegister(unsigned RegNo, MVT VT) {
|
||||
FoldingSetNodeID ID;
|
||||
AddNodeIDNode(ID, ISD::Register, getVTList(VT), 0, 0);
|
||||
@ -4727,6 +4742,7 @@ void StoreSDNode::ANCHOR() {}
|
||||
void AtomicSDNode::ANCHOR() {}
|
||||
void MemIntrinsicSDNode::ANCHOR() {}
|
||||
void CallSDNode::ANCHOR() {}
|
||||
void CvtRndSatSDNode::ANCHOR() {}
|
||||
|
||||
HandleSDNode::~HandleSDNode() {
|
||||
DropOperands();
|
||||
@ -5160,6 +5176,21 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const {
|
||||
case ISD::FP_TO_SINT: return "fp_to_sint";
|
||||
case ISD::FP_TO_UINT: return "fp_to_uint";
|
||||
case ISD::BIT_CONVERT: return "bit_convert";
|
||||
|
||||
case ISD::CONVERT_RNDSAT: {
|
||||
switch (cast<CvtRndSatSDNode>(this)->getCvtCode()) {
|
||||
default: assert(0 && "Unknown cvt code!");
|
||||
case ISD::CVT_FF: return "cvt_ff";
|
||||
case ISD::CVT_FS: return "cvt_fs";
|
||||
case ISD::CVT_FU: return "cvt_fu";
|
||||
case ISD::CVT_SF: return "cvt_sf";
|
||||
case ISD::CVT_UF: return "cvt_uf";
|
||||
case ISD::CVT_SS: return "cvt_ss";
|
||||
case ISD::CVT_SU: return "cvt_su";
|
||||
case ISD::CVT_US: return "cvt_us";
|
||||
case ISD::CVT_UU: return "cvt_uu";
|
||||
}
|
||||
}
|
||||
|
||||
// Control flow instructions
|
||||
case ISD::BR: return "br";
|
||||
|
@ -3859,6 +3859,38 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
case Intrinsic::convertff:
|
||||
case Intrinsic::convertfsi:
|
||||
case Intrinsic::convertfui:
|
||||
case Intrinsic::convertsif:
|
||||
case Intrinsic::convertuif:
|
||||
case Intrinsic::convertss:
|
||||
case Intrinsic::convertsu:
|
||||
case Intrinsic::convertus:
|
||||
case Intrinsic::convertuu: {
|
||||
ISD::CvtCode Code = ISD::CVT_INVALID;
|
||||
switch (Intrinsic) {
|
||||
case Intrinsic::convertff: Code = ISD::CVT_FF; break;
|
||||
case Intrinsic::convertfsi: Code = ISD::CVT_FS; break;
|
||||
case Intrinsic::convertfui: Code = ISD::CVT_FU; break;
|
||||
case Intrinsic::convertsif: Code = ISD::CVT_SF; break;
|
||||
case Intrinsic::convertuif: Code = ISD::CVT_UF; break;
|
||||
case Intrinsic::convertss: Code = ISD::CVT_SS; break;
|
||||
case Intrinsic::convertsu: Code = ISD::CVT_SU; break;
|
||||
case Intrinsic::convertus: Code = ISD::CVT_US; break;
|
||||
case Intrinsic::convertuu: Code = ISD::CVT_UU; break;
|
||||
}
|
||||
MVT DestVT = TLI.getValueType(I.getType());
|
||||
Value* Op1 = I.getOperand(1);
|
||||
setValue(&I, DAG.getConvertRndSat(DestVT, getValue(Op1),
|
||||
DAG.getValueType(DestVT),
|
||||
DAG.getValueType(getValue(Op1).getValueType()),
|
||||
getValue(I.getOperand(2)),
|
||||
getValue(I.getOperand(3)),
|
||||
Code));
|
||||
return 0;
|
||||
}
|
||||
|
||||
case Intrinsic::sqrt:
|
||||
setValue(&I, DAG.getNode(ISD::FSQRT,
|
||||
getValue(I.getOperand(1)).getValueType(),
|
||||
|
@ -200,6 +200,10 @@ def STDAtomic2 : SDTypeProfile<1, 2, [
|
||||
SDTCisSameAs<0,2>, SDTCisInt<0>, SDTCisPtrTy<1>
|
||||
]>;
|
||||
|
||||
def SDTConvertOp : SDTypeProfile<1, 5, [ //cvtss, su, us, uu, ff, fs, fu, sf, su
|
||||
SDTCisVT<2, OtherVT>, SDTCisVT<3, OtherVT>, SDTCisPtrTy<4>, SDTCisPtrTy<5>
|
||||
]>;
|
||||
|
||||
class SDCallSeqStart<list<SDTypeConstraint> constraints> :
|
||||
SDTypeProfile<0, 1, constraints>;
|
||||
class SDCallSeqEnd<list<SDTypeConstraint> constraints> :
|
||||
@ -490,6 +494,8 @@ def intrinsic_w_chain : SDNode<"ISD::INTRINSIC_W_CHAIN",
|
||||
def intrinsic_wo_chain : SDNode<"ISD::INTRINSIC_WO_CHAIN",
|
||||
SDTypeProfile<1, -1, [SDTCisPtrTy<1>]>, []>;
|
||||
|
||||
// Do not use cvt directly. Use cvt forms below
|
||||
def cvt : SDNode<"ISD::CONVERT_RNDSAT", SDTConvertOp>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Selection DAG Condition Codes
|
||||
@ -788,6 +794,54 @@ def setle : PatFrag<(ops node:$lhs, node:$rhs),
|
||||
def setne : PatFrag<(ops node:$lhs, node:$rhs),
|
||||
(setcc node:$lhs, node:$rhs, SETNE)>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Selection DAG CONVERT_RNDSAT patterns
|
||||
|
||||
def cvtff : PatFrag<(ops node:$val, node:$dty, node:$sty, node:$rd, node:$sat),
|
||||
(cvt node:$val, node:$dty, node:$sty, node:$rd, node:$sat), [{
|
||||
return cast<CvtRndSatSDNode>(N)->getCvtCode() == ISD::CVT_FF;
|
||||
}]>;
|
||||
|
||||
def cvtss : PatFrag<(ops node:$val, node:$dty, node:$sty, node:$rd, node:$sat),
|
||||
(cvt node:$val, node:$dty, node:$sty, node:$rd, node:$sat), [{
|
||||
return cast<CvtRndSatSDNode>(N)->getCvtCode() == ISD::CVT_SS;
|
||||
}]>;
|
||||
|
||||
def cvtsu : PatFrag<(ops node:$val, node:$dty, node:$sty, node:$rd, node:$sat),
|
||||
(cvt node:$val, node:$dty, node:$sty, node:$rd, node:$sat), [{
|
||||
return cast<CvtRndSatSDNode>(N)->getCvtCode() == ISD::CVT_SU;
|
||||
}]>;
|
||||
|
||||
def cvtus : PatFrag<(ops node:$val, node:$dty, node:$sty, node:$rd, node:$sat),
|
||||
(cvt node:$val, node:$dty, node:$sty, node:$rd, node:$sat), [{
|
||||
return cast<CvtRndSatSDNode>(N)->getCvtCode() == ISD::CVT_US;
|
||||
}]>;
|
||||
|
||||
def cvtuu : PatFrag<(ops node:$val, node:$dty, node:$sty, node:$rd, node:$sat),
|
||||
(cvt node:$val, node:$dty, node:$sty, node:$rd, node:$sat), [{
|
||||
return cast<CvtRndSatSDNode>(N)->getCvtCode() == ISD::CVT_UU;
|
||||
}]>;
|
||||
|
||||
def cvtsf : PatFrag<(ops node:$val, node:$dty, node:$sty, node:$rd, node:$sat),
|
||||
(cvt node:$val, node:$dty, node:$sty, node:$rd, node:$sat), [{
|
||||
return cast<CvtRndSatSDNode>(N)->getCvtCode() == ISD::CVT_SF;
|
||||
}]>;
|
||||
|
||||
def cvtuf : PatFrag<(ops node:$val, node:$dty, node:$sty, node:$rd, node:$sat),
|
||||
(cvt node:$val, node:$dty, node:$sty, node:$rd, node:$sat), [{
|
||||
return cast<CvtRndSatSDNode>(N)->getCvtCode() == ISD::CVT_UF;
|
||||
}]>;
|
||||
|
||||
def cvtfs : PatFrag<(ops node:$val, node:$dty, node:$sty, node:$rd, node:$sat),
|
||||
(cvt node:$val, node:$dty, node:$sty, node:$rd, node:$sat), [{
|
||||
return cast<CvtRndSatSDNode>(N)->getCvtCode() == ISD::CVT_FS;
|
||||
}]>;
|
||||
|
||||
def cvtfu : PatFrag<(ops node:$val, node:$dty, node:$sty, node:$rd, node:$sat),
|
||||
(cvt node:$val, node:$dty, node:$sty, node:$rd, node:$sat), [{
|
||||
return cast<CvtRndSatSDNode>(N)->getCvtCode() == ISD::CVT_FU;
|
||||
}]>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Selection DAG Pattern Support.
|
||||
//
|
||||
|
Loading…
x
Reference in New Issue
Block a user