mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-09-27 16:17:17 +00:00
Add/complete support for integer and float
select_cc and friends. This code could be factorized a bit but I'm not sure that it's worth it. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@52724 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -333,6 +333,10 @@ bool DAGTypeLegalizer::SoftenFloatOperand(SDNode *N, unsigned OpNo) {
|
|||||||
abort();
|
abort();
|
||||||
|
|
||||||
case ISD::BIT_CONVERT: Res = SoftenFloatOp_BIT_CONVERT(N); break;
|
case ISD::BIT_CONVERT: Res = SoftenFloatOp_BIT_CONVERT(N); break;
|
||||||
|
|
||||||
|
case ISD::BR_CC: Res = SoftenFloatOp_BR_CC(N); break;
|
||||||
|
case ISD::SELECT_CC: Res = SoftenFloatOp_BR_CC(N); break;
|
||||||
|
case ISD::SETCC: Res = SoftenFloatOp_BR_CC(N); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -356,11 +360,148 @@ bool DAGTypeLegalizer::SoftenFloatOperand(SDNode *N, unsigned OpNo) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// SoftenSetCCOperands - Soften the operands of a comparison. This code is
|
||||||
|
/// shared among BR_CC, SELECT_CC, and SETCC handlers.
|
||||||
|
void DAGTypeLegalizer::SoftenSetCCOperands(SDOperand &NewLHS, SDOperand &NewRHS,
|
||||||
|
ISD::CondCode &CCCode) {
|
||||||
|
SDOperand LHSInt = GetSoftenedFloat(NewLHS);
|
||||||
|
SDOperand RHSInt = GetSoftenedFloat(NewRHS);
|
||||||
|
MVT VT = NewLHS.getValueType();
|
||||||
|
MVT NVT = LHSInt.getValueType();
|
||||||
|
|
||||||
|
assert((VT == MVT::f32 || VT == MVT::f64) && "Unsupported setcc type!");
|
||||||
|
|
||||||
|
// Expand into one or more soft-fp libcall(s).
|
||||||
|
RTLIB::Libcall LC1, LC2 = RTLIB::UNKNOWN_LIBCALL;
|
||||||
|
switch (CCCode) {
|
||||||
|
case ISD::SETEQ:
|
||||||
|
case ISD::SETOEQ:
|
||||||
|
LC1 = (VT == MVT::f32) ? RTLIB::OEQ_F32 : RTLIB::OEQ_F64;
|
||||||
|
break;
|
||||||
|
case ISD::SETNE:
|
||||||
|
case ISD::SETUNE:
|
||||||
|
LC1 = (VT == MVT::f32) ? RTLIB::UNE_F32 : RTLIB::UNE_F64;
|
||||||
|
break;
|
||||||
|
case ISD::SETGE:
|
||||||
|
case ISD::SETOGE:
|
||||||
|
LC1 = (VT == MVT::f32) ? RTLIB::OGE_F32 : RTLIB::OGE_F64;
|
||||||
|
break;
|
||||||
|
case ISD::SETLT:
|
||||||
|
case ISD::SETOLT:
|
||||||
|
LC1 = (VT == MVT::f32) ? RTLIB::OLT_F32 : RTLIB::OLT_F64;
|
||||||
|
break;
|
||||||
|
case ISD::SETLE:
|
||||||
|
case ISD::SETOLE:
|
||||||
|
LC1 = (VT == MVT::f32) ? RTLIB::OLE_F32 : RTLIB::OLE_F64;
|
||||||
|
break;
|
||||||
|
case ISD::SETGT:
|
||||||
|
case ISD::SETOGT:
|
||||||
|
LC1 = (VT == MVT::f32) ? RTLIB::OGT_F32 : RTLIB::OGT_F64;
|
||||||
|
break;
|
||||||
|
case ISD::SETUO:
|
||||||
|
LC1 = (VT == MVT::f32) ? RTLIB::UO_F32 : RTLIB::UO_F64;
|
||||||
|
break;
|
||||||
|
case ISD::SETO:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LC1 = (VT == MVT::f32) ? RTLIB::UO_F32 : RTLIB::UO_F64;
|
||||||
|
switch (CCCode) {
|
||||||
|
case ISD::SETONE:
|
||||||
|
// SETONE = SETOLT | SETOGT
|
||||||
|
LC1 = (VT == MVT::f32) ? RTLIB::OLT_F32 : RTLIB::OLT_F64;
|
||||||
|
// Fallthrough
|
||||||
|
case ISD::SETUGT:
|
||||||
|
LC2 = (VT == MVT::f32) ? RTLIB::OGT_F32 : RTLIB::OGT_F64;
|
||||||
|
break;
|
||||||
|
case ISD::SETUGE:
|
||||||
|
LC2 = (VT == MVT::f32) ? RTLIB::OGE_F32 : RTLIB::OGE_F64;
|
||||||
|
break;
|
||||||
|
case ISD::SETULT:
|
||||||
|
LC2 = (VT == MVT::f32) ? RTLIB::OLT_F32 : RTLIB::OLT_F64;
|
||||||
|
break;
|
||||||
|
case ISD::SETULE:
|
||||||
|
LC2 = (VT == MVT::f32) ? RTLIB::OLE_F32 : RTLIB::OLE_F64;
|
||||||
|
break;
|
||||||
|
case ISD::SETUEQ:
|
||||||
|
LC2 = (VT == MVT::f32) ? RTLIB::OEQ_F32 : RTLIB::OEQ_F64;
|
||||||
|
break;
|
||||||
|
default: assert(false && "Do not know how to soften this setcc!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SDOperand Ops[2] = { LHSInt, RHSInt };
|
||||||
|
NewLHS = MakeLibCall(LC1, NVT, Ops, 2, false/*sign irrelevant*/);
|
||||||
|
NewRHS = DAG.getConstant(0, NVT);
|
||||||
|
if (LC2 != RTLIB::UNKNOWN_LIBCALL) {
|
||||||
|
SDOperand Tmp = DAG.getNode(ISD::SETCC, TLI.getSetCCResultType(NewLHS),
|
||||||
|
NewLHS, NewRHS,
|
||||||
|
DAG.getCondCode(TLI.getCmpLibcallCC(LC1)));
|
||||||
|
NewLHS = MakeLibCall(LC2, NVT, Ops, 2, false/*sign irrelevant*/);
|
||||||
|
NewLHS = DAG.getNode(ISD::SETCC, TLI.getSetCCResultType(NewLHS), NewLHS,
|
||||||
|
NewRHS, DAG.getCondCode(TLI.getCmpLibcallCC(LC2)));
|
||||||
|
NewLHS = DAG.getNode(ISD::OR, Tmp.getValueType(), Tmp, NewLHS);
|
||||||
|
NewRHS = SDOperand();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SDOperand DAGTypeLegalizer::SoftenFloatOp_BIT_CONVERT(SDNode *N) {
|
SDOperand DAGTypeLegalizer::SoftenFloatOp_BIT_CONVERT(SDNode *N) {
|
||||||
return DAG.getNode(ISD::BIT_CONVERT, N->getValueType(0),
|
return DAG.getNode(ISD::BIT_CONVERT, N->getValueType(0),
|
||||||
GetSoftenedFloat(N->getOperand(0)));
|
GetSoftenedFloat(N->getOperand(0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SDOperand DAGTypeLegalizer::SoftenFloatOp_BR_CC(SDNode *N) {
|
||||||
|
SDOperand NewLHS = N->getOperand(2), NewRHS = N->getOperand(3);
|
||||||
|
ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(1))->get();
|
||||||
|
SoftenSetCCOperands(NewLHS, NewRHS, CCCode);
|
||||||
|
|
||||||
|
// If SoftenSetCCOperands returned a scalar, we need to compare the result
|
||||||
|
// against zero to select between true and false values.
|
||||||
|
if (NewRHS.Val == 0) {
|
||||||
|
NewRHS = DAG.getConstant(0, NewLHS.getValueType());
|
||||||
|
CCCode = ISD::SETNE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update N to have the operands specified.
|
||||||
|
return DAG.UpdateNodeOperands(SDOperand(N, 0), N->getOperand(0),
|
||||||
|
DAG.getCondCode(CCCode), NewLHS, NewRHS,
|
||||||
|
N->getOperand(4));
|
||||||
|
}
|
||||||
|
|
||||||
|
SDOperand DAGTypeLegalizer::SoftenFloatOp_SELECT_CC(SDNode *N) {
|
||||||
|
SDOperand NewLHS = N->getOperand(0), NewRHS = N->getOperand(1);
|
||||||
|
ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(4))->get();
|
||||||
|
SoftenSetCCOperands(NewLHS, NewRHS, CCCode);
|
||||||
|
|
||||||
|
// If SoftenSetCCOperands returned a scalar, we need to compare the result
|
||||||
|
// against zero to select between true and false values.
|
||||||
|
if (NewRHS.Val == 0) {
|
||||||
|
NewRHS = DAG.getConstant(0, NewLHS.getValueType());
|
||||||
|
CCCode = ISD::SETNE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update N to have the operands specified.
|
||||||
|
return DAG.UpdateNodeOperands(SDOperand(N, 0), NewLHS, NewRHS,
|
||||||
|
N->getOperand(2), N->getOperand(3),
|
||||||
|
DAG.getCondCode(CCCode));
|
||||||
|
}
|
||||||
|
|
||||||
|
SDOperand DAGTypeLegalizer::SoftenFloatOp_SETCC(SDNode *N) {
|
||||||
|
SDOperand NewLHS = N->getOperand(0), NewRHS = N->getOperand(1);
|
||||||
|
ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(2))->get();
|
||||||
|
SoftenSetCCOperands(NewLHS, NewRHS, CCCode);
|
||||||
|
|
||||||
|
// If SoftenSetCCOperands returned a scalar, use it.
|
||||||
|
if (NewRHS.Val == 0) {
|
||||||
|
assert(NewLHS.getValueType() == N->getValueType(0) &&
|
||||||
|
"Unexpected setcc expansion!");
|
||||||
|
return NewLHS;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, update N to have the operands specified.
|
||||||
|
return DAG.UpdateNodeOperands(SDOperand(N, 0), NewLHS, NewRHS,
|
||||||
|
DAG.getCondCode(CCCode));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Float Result Expansion
|
// Float Result Expansion
|
||||||
@@ -477,6 +618,10 @@ bool DAGTypeLegalizer::ExpandFloatOperand(SDNode *N, unsigned OpNo) {
|
|||||||
case ISD::BUILD_VECTOR: Res = ExpandOp_BUILD_VECTOR(N); break;
|
case ISD::BUILD_VECTOR: Res = ExpandOp_BUILD_VECTOR(N); break;
|
||||||
case ISD::EXTRACT_ELEMENT: Res = ExpandOp_EXTRACT_ELEMENT(N); break;
|
case ISD::EXTRACT_ELEMENT: Res = ExpandOp_EXTRACT_ELEMENT(N); break;
|
||||||
|
|
||||||
|
case ISD::BR_CC: Res = ExpandFloatOp_BR_CC(N); break;
|
||||||
|
case ISD::SELECT_CC: Res = ExpandFloatOp_BR_CC(N); break;
|
||||||
|
case ISD::SETCC: Res = ExpandFloatOp_BR_CC(N); break;
|
||||||
|
|
||||||
case ISD::STORE:
|
case ISD::STORE:
|
||||||
Res = ExpandFloatOp_STORE(cast<StoreSDNode>(N), OpNo);
|
Res = ExpandFloatOp_STORE(cast<StoreSDNode>(N), OpNo);
|
||||||
break;
|
break;
|
||||||
@@ -502,6 +647,87 @@ bool DAGTypeLegalizer::ExpandFloatOperand(SDNode *N, unsigned OpNo) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// FloatExpandSetCCOperands - Expand the operands of a comparison. This code
|
||||||
|
/// is shared among BR_CC, SELECT_CC, and SETCC handlers.
|
||||||
|
void DAGTypeLegalizer::FloatExpandSetCCOperands(SDOperand &NewLHS,
|
||||||
|
SDOperand &NewRHS,
|
||||||
|
ISD::CondCode &CCCode) {
|
||||||
|
SDOperand LHSLo, LHSHi, RHSLo, RHSHi;
|
||||||
|
GetExpandedFloat(NewLHS, LHSLo, LHSHi);
|
||||||
|
GetExpandedFloat(NewRHS, RHSLo, RHSHi);
|
||||||
|
|
||||||
|
MVT VT = NewLHS.getValueType();
|
||||||
|
assert(VT == MVT::ppcf128 && "Unsupported setcc type!");
|
||||||
|
|
||||||
|
// FIXME: This generated code sucks. We want to generate
|
||||||
|
// FCMP crN, hi1, hi2
|
||||||
|
// BNE crN, L:
|
||||||
|
// FCMP crN, lo1, lo2
|
||||||
|
// The following can be improved, but not that much.
|
||||||
|
SDOperand Tmp1, Tmp2, Tmp3;
|
||||||
|
Tmp1 = DAG.getSetCC(TLI.getSetCCResultType(LHSHi), LHSHi, RHSHi, ISD::SETEQ);
|
||||||
|
Tmp2 = DAG.getSetCC(TLI.getSetCCResultType(LHSLo), LHSLo, RHSLo, CCCode);
|
||||||
|
Tmp3 = DAG.getNode(ISD::AND, Tmp1.getValueType(), Tmp1, Tmp2);
|
||||||
|
Tmp1 = DAG.getSetCC(TLI.getSetCCResultType(LHSHi), LHSHi, RHSHi, ISD::SETNE);
|
||||||
|
Tmp2 = DAG.getSetCC(TLI.getSetCCResultType(LHSHi), LHSHi, RHSHi, CCCode);
|
||||||
|
Tmp1 = DAG.getNode(ISD::AND, Tmp1.getValueType(), Tmp1, Tmp2);
|
||||||
|
NewLHS = DAG.getNode(ISD::OR, Tmp1.getValueType(), Tmp1, Tmp3);
|
||||||
|
NewRHS = SDOperand(); // LHS is the result, not a compare.
|
||||||
|
}
|
||||||
|
|
||||||
|
SDOperand DAGTypeLegalizer::ExpandFloatOp_BR_CC(SDNode *N) {
|
||||||
|
SDOperand NewLHS = N->getOperand(2), NewRHS = N->getOperand(3);
|
||||||
|
ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(1))->get();
|
||||||
|
FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode);
|
||||||
|
|
||||||
|
// If ExpandSetCCOperands returned a scalar, we need to compare the result
|
||||||
|
// against zero to select between true and false values.
|
||||||
|
if (NewRHS.Val == 0) {
|
||||||
|
NewRHS = DAG.getConstant(0, NewLHS.getValueType());
|
||||||
|
CCCode = ISD::SETNE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update N to have the operands specified.
|
||||||
|
return DAG.UpdateNodeOperands(SDOperand(N, 0), N->getOperand(0),
|
||||||
|
DAG.getCondCode(CCCode), NewLHS, NewRHS,
|
||||||
|
N->getOperand(4));
|
||||||
|
}
|
||||||
|
|
||||||
|
SDOperand DAGTypeLegalizer::ExpandFloatOp_SELECT_CC(SDNode *N) {
|
||||||
|
SDOperand NewLHS = N->getOperand(0), NewRHS = N->getOperand(1);
|
||||||
|
ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(4))->get();
|
||||||
|
FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode);
|
||||||
|
|
||||||
|
// If ExpandSetCCOperands returned a scalar, we need to compare the result
|
||||||
|
// against zero to select between true and false values.
|
||||||
|
if (NewRHS.Val == 0) {
|
||||||
|
NewRHS = DAG.getConstant(0, NewLHS.getValueType());
|
||||||
|
CCCode = ISD::SETNE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update N to have the operands specified.
|
||||||
|
return DAG.UpdateNodeOperands(SDOperand(N, 0), NewLHS, NewRHS,
|
||||||
|
N->getOperand(2), N->getOperand(3),
|
||||||
|
DAG.getCondCode(CCCode));
|
||||||
|
}
|
||||||
|
|
||||||
|
SDOperand DAGTypeLegalizer::ExpandFloatOp_SETCC(SDNode *N) {
|
||||||
|
SDOperand NewLHS = N->getOperand(0), NewRHS = N->getOperand(1);
|
||||||
|
ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(2))->get();
|
||||||
|
FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode);
|
||||||
|
|
||||||
|
// If ExpandSetCCOperands returned a scalar, use it.
|
||||||
|
if (NewRHS.Val == 0) {
|
||||||
|
assert(NewLHS.getValueType() == N->getValueType(0) &&
|
||||||
|
"Unexpected setcc expansion!");
|
||||||
|
return NewLHS;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, update N to have the operands specified.
|
||||||
|
return DAG.UpdateNodeOperands(SDOperand(N, 0), NewLHS, NewRHS,
|
||||||
|
DAG.getCondCode(CCCode));
|
||||||
|
}
|
||||||
|
|
||||||
SDOperand DAGTypeLegalizer::ExpandFloatOp_STORE(SDNode *N, unsigned OpNo) {
|
SDOperand DAGTypeLegalizer::ExpandFloatOp_STORE(SDNode *N, unsigned OpNo) {
|
||||||
if (ISD::isNormalStore(N))
|
if (ISD::isNormalStore(N))
|
||||||
return ExpandOp_NormalStore(N, OpNo);
|
return ExpandOp_NormalStore(N, OpNo);
|
||||||
|
@@ -441,9 +441,9 @@ bool DAGTypeLegalizer::PromoteIntegerOperand(SDNode *N, unsigned OpNo) {
|
|||||||
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::BUILD_PAIR: Res = PromoteIntOp_BUILD_PAIR(N); break;
|
case ISD::BUILD_PAIR: Res = PromoteIntOp_BUILD_PAIR(N); break;
|
||||||
|
|
||||||
case ISD::SELECT: Res = PromoteIntOp_SELECT(N, OpNo); break;
|
|
||||||
case ISD::BRCOND: Res = PromoteIntOp_BRCOND(N, OpNo); break;
|
case ISD::BRCOND: Res = PromoteIntOp_BRCOND(N, OpNo); break;
|
||||||
case ISD::BR_CC: Res = PromoteIntOp_BR_CC(N, OpNo); break;
|
case ISD::BR_CC: Res = PromoteIntOp_BR_CC(N, OpNo); break;
|
||||||
|
case ISD::SELECT: Res = PromoteIntOp_SELECT(N, OpNo); break;
|
||||||
case ISD::SETCC: Res = PromoteIntOp_SETCC(N, OpNo); break;
|
case ISD::SETCC: Res = PromoteIntOp_SETCC(N, OpNo); break;
|
||||||
|
|
||||||
case ISD::STORE: Res = PromoteIntOp_STORE(cast<StoreSDNode>(N),
|
case ISD::STORE: Res = PromoteIntOp_STORE(cast<StoreSDNode>(N),
|
||||||
@@ -601,10 +601,6 @@ void DAGTypeLegalizer::PromoteSetCCOperands(SDOperand &NewLHS,SDOperand &NewRHS,
|
|||||||
NewLHS = GetPromotedInteger(NewLHS);
|
NewLHS = GetPromotedInteger(NewLHS);
|
||||||
NewRHS = GetPromotedInteger(NewRHS);
|
NewRHS = GetPromotedInteger(NewRHS);
|
||||||
|
|
||||||
// If this is an FP compare, the operands have already been extended.
|
|
||||||
if (!NewLHS.getValueType().isInteger())
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Otherwise, we have to insert explicit sign or zero extends. Note
|
// Otherwise, we have to insert explicit sign or zero extends. Note
|
||||||
// that we could insert sign extends for ALL conditions, but zero extend
|
// that we could insert sign extends for ALL conditions, but zero extend
|
||||||
// is cheaper on many machines (an AND instead of two shifts), so prefer
|
// is cheaper on many machines (an AND instead of two shifts), so prefer
|
||||||
@@ -622,7 +618,7 @@ void DAGTypeLegalizer::PromoteSetCCOperands(SDOperand &NewLHS,SDOperand &NewRHS,
|
|||||||
// usually a simpler/cheaper operation, so prefer it.
|
// usually a simpler/cheaper operation, so prefer it.
|
||||||
NewLHS = DAG.getZeroExtendInReg(NewLHS, VT);
|
NewLHS = DAG.getZeroExtendInReg(NewLHS, VT);
|
||||||
NewRHS = DAG.getZeroExtendInReg(NewRHS, VT);
|
NewRHS = DAG.getZeroExtendInReg(NewRHS, VT);
|
||||||
return;
|
break;
|
||||||
case ISD::SETGE:
|
case ISD::SETGE:
|
||||||
case ISD::SETGT:
|
case ISD::SETGT:
|
||||||
case ISD::SETLT:
|
case ISD::SETLT:
|
||||||
@@ -631,7 +627,7 @@ void DAGTypeLegalizer::PromoteSetCCOperands(SDOperand &NewLHS,SDOperand &NewRHS,
|
|||||||
DAG.getValueType(VT));
|
DAG.getValueType(VT));
|
||||||
NewRHS = DAG.getNode(ISD::SIGN_EXTEND_INREG, NewRHS.getValueType(), NewRHS,
|
NewRHS = DAG.getNode(ISD::SIGN_EXTEND_INREG, NewRHS.getValueType(), NewRHS,
|
||||||
DAG.getValueType(VT));
|
DAG.getValueType(VT));
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1611,6 +1607,7 @@ bool DAGTypeLegalizer::ExpandIntegerOperand(SDNode *N, unsigned OpNo) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case ISD::BR_CC: Res = ExpandIntOp_BR_CC(N); break;
|
case ISD::BR_CC: Res = ExpandIntOp_BR_CC(N); break;
|
||||||
|
case ISD::SELECT_CC: Res = ExpandIntOp_SELECT_CC(N); break;
|
||||||
case ISD::SETCC: Res = ExpandIntOp_SETCC(N); break;
|
case ISD::SETCC: Res = ExpandIntOp_SETCC(N); break;
|
||||||
|
|
||||||
case ISD::STORE:
|
case ISD::STORE:
|
||||||
@@ -1735,7 +1732,7 @@ SDOperand DAGTypeLegalizer::ExpandIntOp_UINT_TO_FP(SDOperand Source,
|
|||||||
SDOperand DAGTypeLegalizer::ExpandIntOp_BR_CC(SDNode *N) {
|
SDOperand DAGTypeLegalizer::ExpandIntOp_BR_CC(SDNode *N) {
|
||||||
SDOperand NewLHS = N->getOperand(2), NewRHS = N->getOperand(3);
|
SDOperand NewLHS = N->getOperand(2), NewRHS = N->getOperand(3);
|
||||||
ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(1))->get();
|
ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(1))->get();
|
||||||
ExpandSetCCOperands(NewLHS, NewRHS, CCCode);
|
IntegerExpandSetCCOperands(NewLHS, NewRHS, CCCode);
|
||||||
|
|
||||||
// If ExpandSetCCOperands returned a scalar, we need to compare the result
|
// If ExpandSetCCOperands returned a scalar, we need to compare the result
|
||||||
// against zero to select between true and false values.
|
// against zero to select between true and false values.
|
||||||
@@ -1750,55 +1747,63 @@ SDOperand DAGTypeLegalizer::ExpandIntOp_BR_CC(SDNode *N) {
|
|||||||
N->getOperand(4));
|
N->getOperand(4));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SDOperand DAGTypeLegalizer::ExpandIntOp_SELECT_CC(SDNode *N) {
|
||||||
|
SDOperand NewLHS = N->getOperand(0), NewRHS = N->getOperand(1);
|
||||||
|
ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(4))->get();
|
||||||
|
IntegerExpandSetCCOperands(NewLHS, NewRHS, CCCode);
|
||||||
|
|
||||||
|
// If ExpandSetCCOperands returned a scalar, we need to compare the result
|
||||||
|
// against zero to select between true and false values.
|
||||||
|
if (NewRHS.Val == 0) {
|
||||||
|
NewRHS = DAG.getConstant(0, NewLHS.getValueType());
|
||||||
|
CCCode = ISD::SETNE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update N to have the operands specified.
|
||||||
|
return DAG.UpdateNodeOperands(SDOperand(N, 0), NewLHS, NewRHS,
|
||||||
|
N->getOperand(2), N->getOperand(3),
|
||||||
|
DAG.getCondCode(CCCode));
|
||||||
|
}
|
||||||
|
|
||||||
SDOperand DAGTypeLegalizer::ExpandIntOp_SETCC(SDNode *N) {
|
SDOperand DAGTypeLegalizer::ExpandIntOp_SETCC(SDNode *N) {
|
||||||
SDOperand NewLHS = N->getOperand(0), NewRHS = N->getOperand(1);
|
SDOperand NewLHS = N->getOperand(0), NewRHS = N->getOperand(1);
|
||||||
ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(2))->get();
|
ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(2))->get();
|
||||||
ExpandSetCCOperands(NewLHS, NewRHS, CCCode);
|
IntegerExpandSetCCOperands(NewLHS, NewRHS, CCCode);
|
||||||
|
|
||||||
// If ExpandSetCCOperands returned a scalar, use it.
|
// If ExpandSetCCOperands returned a scalar, use it.
|
||||||
if (NewRHS.Val == 0) return NewLHS;
|
if (NewRHS.Val == 0) {
|
||||||
|
assert(NewLHS.getValueType() == N->getValueType(0) &&
|
||||||
|
"Unexpected setcc expansion!");
|
||||||
|
return NewLHS;
|
||||||
|
}
|
||||||
|
|
||||||
// Otherwise, update N to have the operands specified.
|
// Otherwise, update N to have the operands specified.
|
||||||
return DAG.UpdateNodeOperands(SDOperand(N, 0), NewLHS, NewRHS,
|
return DAG.UpdateNodeOperands(SDOperand(N, 0), NewLHS, NewRHS,
|
||||||
DAG.getCondCode(CCCode));
|
DAG.getCondCode(CCCode));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ExpandSetCCOperands - Expand the operands of a comparison. This code is
|
/// IntegerExpandSetCCOperands - Expand the operands of a comparison. This code
|
||||||
/// shared among BR_CC, SELECT_CC, and SETCC handlers.
|
/// is shared among BR_CC, SELECT_CC, and SETCC handlers.
|
||||||
void DAGTypeLegalizer::ExpandSetCCOperands(SDOperand &NewLHS, SDOperand &NewRHS,
|
void DAGTypeLegalizer::IntegerExpandSetCCOperands(SDOperand &NewLHS,
|
||||||
|
SDOperand &NewRHS,
|
||||||
ISD::CondCode &CCCode) {
|
ISD::CondCode &CCCode) {
|
||||||
SDOperand LHSLo, LHSHi, RHSLo, RHSHi;
|
SDOperand LHSLo, LHSHi, RHSLo, RHSHi;
|
||||||
GetExpandedInteger(NewLHS, LHSLo, LHSHi);
|
GetExpandedInteger(NewLHS, LHSLo, LHSHi);
|
||||||
GetExpandedInteger(NewRHS, RHSLo, RHSHi);
|
GetExpandedInteger(NewRHS, RHSLo, RHSHi);
|
||||||
|
|
||||||
MVT VT = NewLHS.getValueType();
|
MVT VT = NewLHS.getValueType();
|
||||||
if (VT == MVT::ppcf128) {
|
|
||||||
// FIXME: This generated code sucks. We want to generate
|
|
||||||
// FCMP crN, hi1, hi2
|
|
||||||
// BNE crN, L:
|
|
||||||
// FCMP crN, lo1, lo2
|
|
||||||
// The following can be improved, but not that much.
|
|
||||||
SDOperand Tmp1, Tmp2, Tmp3;
|
|
||||||
Tmp1 = DAG.getSetCC(TLI.getSetCCResultType(LHSHi), LHSHi, RHSHi, ISD::SETEQ);
|
|
||||||
Tmp2 = DAG.getSetCC(TLI.getSetCCResultType(LHSLo), LHSLo, RHSLo, CCCode);
|
|
||||||
Tmp3 = DAG.getNode(ISD::AND, Tmp1.getValueType(), Tmp1, Tmp2);
|
|
||||||
Tmp1 = DAG.getSetCC(TLI.getSetCCResultType(LHSHi), LHSHi, RHSHi, ISD::SETNE);
|
|
||||||
Tmp2 = DAG.getSetCC(TLI.getSetCCResultType(LHSHi), LHSHi, RHSHi, CCCode);
|
|
||||||
Tmp1 = DAG.getNode(ISD::AND, Tmp1.getValueType(), Tmp1, Tmp2);
|
|
||||||
NewLHS = DAG.getNode(ISD::OR, Tmp1.getValueType(), Tmp1, Tmp3);
|
|
||||||
NewRHS = SDOperand(); // LHS is the result, not a compare.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CCCode == ISD::SETEQ || CCCode == ISD::SETNE) {
|
if (CCCode == ISD::SETEQ || CCCode == ISD::SETNE) {
|
||||||
if (RHSLo == RHSHi)
|
if (RHSLo == RHSHi) {
|
||||||
if (ConstantSDNode *RHSCST = dyn_cast<ConstantSDNode>(RHSLo))
|
if (ConstantSDNode *RHSCST = dyn_cast<ConstantSDNode>(RHSLo)) {
|
||||||
if (RHSCST->isAllOnesValue()) {
|
if (RHSCST->isAllOnesValue()) {
|
||||||
// Equality comparison to -1.
|
// Equality comparison to -1.
|
||||||
NewLHS = DAG.getNode(ISD::AND, LHSLo.getValueType(), LHSLo, LHSHi);
|
NewLHS = DAG.getNode(ISD::AND, LHSLo.getValueType(), LHSLo, LHSHi);
|
||||||
NewRHS = RHSLo;
|
NewRHS = RHSLo;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
NewLHS = DAG.getNode(ISD::XOR, LHSLo.getValueType(), LHSLo, RHSLo);
|
NewLHS = DAG.getNode(ISD::XOR, LHSLo.getValueType(), LHSLo, RHSLo);
|
||||||
NewRHS = DAG.getNode(ISD::XOR, LHSLo.getValueType(), LHSHi, RHSHi);
|
NewRHS = DAG.getNode(ISD::XOR, LHSLo.getValueType(), LHSHi, RHSHi);
|
||||||
|
@@ -301,13 +301,14 @@ private:
|
|||||||
SDOperand ExpandIntOp_BR_CC(SDNode *N);
|
SDOperand ExpandIntOp_BR_CC(SDNode *N);
|
||||||
SDOperand ExpandIntOp_BUILD_VECTOR(SDNode *N);
|
SDOperand ExpandIntOp_BUILD_VECTOR(SDNode *N);
|
||||||
SDOperand ExpandIntOp_EXTRACT_ELEMENT(SDNode *N);
|
SDOperand ExpandIntOp_EXTRACT_ELEMENT(SDNode *N);
|
||||||
|
SDOperand ExpandIntOp_SELECT_CC(SDNode *N);
|
||||||
SDOperand ExpandIntOp_SETCC(SDNode *N);
|
SDOperand ExpandIntOp_SETCC(SDNode *N);
|
||||||
SDOperand ExpandIntOp_SINT_TO_FP(SDOperand Source, MVT DestTy);
|
SDOperand ExpandIntOp_SINT_TO_FP(SDOperand Source, MVT DestTy);
|
||||||
SDOperand ExpandIntOp_STORE(StoreSDNode *N, unsigned OpNo);
|
SDOperand ExpandIntOp_STORE(StoreSDNode *N, unsigned OpNo);
|
||||||
SDOperand ExpandIntOp_TRUNCATE(SDNode *N);
|
SDOperand ExpandIntOp_TRUNCATE(SDNode *N);
|
||||||
SDOperand ExpandIntOp_UINT_TO_FP(SDOperand Source, MVT DestTy);
|
SDOperand ExpandIntOp_UINT_TO_FP(SDOperand Source, MVT DestTy);
|
||||||
|
|
||||||
void ExpandSetCCOperands(SDOperand &NewLHS, SDOperand &NewRHS,
|
void IntegerExpandSetCCOperands(SDOperand &NewLHS, SDOperand &NewRHS,
|
||||||
ISD::CondCode &CCCode);
|
ISD::CondCode &CCCode);
|
||||||
|
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
@@ -337,6 +338,12 @@ private:
|
|||||||
// Operand Float to Integer Conversion.
|
// Operand Float to Integer Conversion.
|
||||||
bool SoftenFloatOperand(SDNode *N, unsigned OpNo);
|
bool SoftenFloatOperand(SDNode *N, unsigned OpNo);
|
||||||
SDOperand SoftenFloatOp_BIT_CONVERT(SDNode *N);
|
SDOperand SoftenFloatOp_BIT_CONVERT(SDNode *N);
|
||||||
|
SDOperand SoftenFloatOp_BR_CC(SDNode *N);
|
||||||
|
SDOperand SoftenFloatOp_SELECT_CC(SDNode *N);
|
||||||
|
SDOperand SoftenFloatOp_SETCC(SDNode *N);
|
||||||
|
|
||||||
|
void SoftenSetCCOperands(SDOperand &NewLHS, SDOperand &NewRHS,
|
||||||
|
ISD::CondCode &CCCode);
|
||||||
|
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
// Float Expansion Support: LegalizeFloatTypes.cpp
|
// Float Expansion Support: LegalizeFloatTypes.cpp
|
||||||
@@ -351,8 +358,14 @@ private:
|
|||||||
|
|
||||||
// Float Operand Expansion.
|
// Float Operand Expansion.
|
||||||
bool ExpandFloatOperand(SDNode *N, unsigned OperandNo);
|
bool ExpandFloatOperand(SDNode *N, unsigned OperandNo);
|
||||||
|
SDOperand ExpandFloatOp_BR_CC(SDNode *N);
|
||||||
|
SDOperand ExpandFloatOp_SELECT_CC(SDNode *N);
|
||||||
|
SDOperand ExpandFloatOp_SETCC(SDNode *N);
|
||||||
SDOperand ExpandFloatOp_STORE(SDNode *N, unsigned OpNo);
|
SDOperand ExpandFloatOp_STORE(SDNode *N, unsigned OpNo);
|
||||||
|
|
||||||
|
void FloatExpandSetCCOperands(SDOperand &NewLHS, SDOperand &NewRHS,
|
||||||
|
ISD::CondCode &CCCode);
|
||||||
|
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
// Scalarization Support: LegalizeVectorTypes.cpp
|
// Scalarization Support: LegalizeVectorTypes.cpp
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
|
Reference in New Issue
Block a user