mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-14 11:32:34 +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:
parent
b58d211dbb
commit
11ac797f5e
@ -332,7 +332,11 @@ bool DAGTypeLegalizer::SoftenFloatOperand(SDNode *N, unsigned OpNo) {
|
||||
assert(0 && "Do not know how to convert this operator's operand!");
|
||||
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;
|
||||
}
|
||||
|
||||
/// 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) {
|
||||
return DAG.getNode(ISD::BIT_CONVERT, N->getValueType(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
|
||||
@ -477,6 +618,10 @@ bool DAGTypeLegalizer::ExpandFloatOperand(SDNode *N, unsigned OpNo) {
|
||||
case ISD::BUILD_VECTOR: Res = ExpandOp_BUILD_VECTOR(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:
|
||||
Res = ExpandFloatOp_STORE(cast<StoreSDNode>(N), OpNo);
|
||||
break;
|
||||
@ -502,6 +647,87 @@ bool DAGTypeLegalizer::ExpandFloatOperand(SDNode *N, unsigned OpNo) {
|
||||
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) {
|
||||
if (ISD::isNormalStore(N))
|
||||
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::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::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::STORE: Res = PromoteIntOp_STORE(cast<StoreSDNode>(N),
|
||||
@ -601,10 +601,6 @@ void DAGTypeLegalizer::PromoteSetCCOperands(SDOperand &NewLHS,SDOperand &NewRHS,
|
||||
NewLHS = GetPromotedInteger(NewLHS);
|
||||
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
|
||||
// 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
|
||||
@ -622,7 +618,7 @@ void DAGTypeLegalizer::PromoteSetCCOperands(SDOperand &NewLHS,SDOperand &NewRHS,
|
||||
// usually a simpler/cheaper operation, so prefer it.
|
||||
NewLHS = DAG.getZeroExtendInReg(NewLHS, VT);
|
||||
NewRHS = DAG.getZeroExtendInReg(NewRHS, VT);
|
||||
return;
|
||||
break;
|
||||
case ISD::SETGE:
|
||||
case ISD::SETGT:
|
||||
case ISD::SETLT:
|
||||
@ -631,7 +627,7 @@ void DAGTypeLegalizer::PromoteSetCCOperands(SDOperand &NewLHS,SDOperand &NewRHS,
|
||||
DAG.getValueType(VT));
|
||||
NewRHS = DAG.getNode(ISD::SIGN_EXTEND_INREG, NewRHS.getValueType(), NewRHS,
|
||||
DAG.getValueType(VT));
|
||||
return;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1610,8 +1606,9 @@ bool DAGTypeLegalizer::ExpandIntegerOperand(SDNode *N, unsigned OpNo) {
|
||||
Res = ExpandIntOp_UINT_TO_FP(N->getOperand(0), N->getValueType(0));
|
||||
break;
|
||||
|
||||
case ISD::BR_CC: Res = ExpandIntOp_BR_CC(N); break;
|
||||
case ISD::SETCC: Res = ExpandIntOp_SETCC(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::STORE:
|
||||
Res = ExpandIntOp_STORE(cast<StoreSDNode>(N), OpNo);
|
||||
@ -1735,7 +1732,7 @@ SDOperand DAGTypeLegalizer::ExpandIntOp_UINT_TO_FP(SDOperand Source,
|
||||
SDOperand DAGTypeLegalizer::ExpandIntOp_BR_CC(SDNode *N) {
|
||||
SDOperand NewLHS = N->getOperand(2), NewRHS = N->getOperand(3);
|
||||
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
|
||||
// against zero to select between true and false values.
|
||||
@ -1750,55 +1747,63 @@ SDOperand DAGTypeLegalizer::ExpandIntOp_BR_CC(SDNode *N) {
|
||||
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 NewLHS = N->getOperand(0), NewRHS = N->getOperand(1);
|
||||
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 (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.
|
||||
return DAG.UpdateNodeOperands(SDOperand(N, 0), NewLHS, NewRHS,
|
||||
DAG.getCondCode(CCCode));
|
||||
}
|
||||
|
||||
/// ExpandSetCCOperands - Expand the operands of a comparison. This code is
|
||||
/// shared among BR_CC, SELECT_CC, and SETCC handlers.
|
||||
void DAGTypeLegalizer::ExpandSetCCOperands(SDOperand &NewLHS, SDOperand &NewRHS,
|
||||
ISD::CondCode &CCCode) {
|
||||
/// IntegerExpandSetCCOperands - Expand the operands of a comparison. This code
|
||||
/// is shared among BR_CC, SELECT_CC, and SETCC handlers.
|
||||
void DAGTypeLegalizer::IntegerExpandSetCCOperands(SDOperand &NewLHS,
|
||||
SDOperand &NewRHS,
|
||||
ISD::CondCode &CCCode) {
|
||||
SDOperand LHSLo, LHSHi, RHSLo, RHSHi;
|
||||
GetExpandedInteger(NewLHS, LHSLo, LHSHi);
|
||||
GetExpandedInteger(NewRHS, RHSLo, RHSHi);
|
||||
|
||||
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 (RHSLo == RHSHi)
|
||||
if (ConstantSDNode *RHSCST = dyn_cast<ConstantSDNode>(RHSLo))
|
||||
if (RHSLo == RHSHi) {
|
||||
if (ConstantSDNode *RHSCST = dyn_cast<ConstantSDNode>(RHSLo)) {
|
||||
if (RHSCST->isAllOnesValue()) {
|
||||
// Equality comparison to -1.
|
||||
NewLHS = DAG.getNode(ISD::AND, LHSLo.getValueType(), LHSLo, LHSHi);
|
||||
NewRHS = RHSLo;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NewLHS = DAG.getNode(ISD::XOR, LHSLo.getValueType(), LHSLo, RHSLo);
|
||||
NewRHS = DAG.getNode(ISD::XOR, LHSLo.getValueType(), LHSHi, RHSHi);
|
||||
|
@ -301,14 +301,15 @@ private:
|
||||
SDOperand ExpandIntOp_BR_CC(SDNode *N);
|
||||
SDOperand ExpandIntOp_BUILD_VECTOR(SDNode *N);
|
||||
SDOperand ExpandIntOp_EXTRACT_ELEMENT(SDNode *N);
|
||||
SDOperand ExpandIntOp_SELECT_CC(SDNode *N);
|
||||
SDOperand ExpandIntOp_SETCC(SDNode *N);
|
||||
SDOperand ExpandIntOp_SINT_TO_FP(SDOperand Source, MVT DestTy);
|
||||
SDOperand ExpandIntOp_STORE(StoreSDNode *N, unsigned OpNo);
|
||||
SDOperand ExpandIntOp_TRUNCATE(SDNode *N);
|
||||
SDOperand ExpandIntOp_UINT_TO_FP(SDOperand Source, MVT DestTy);
|
||||
|
||||
void ExpandSetCCOperands(SDOperand &NewLHS, SDOperand &NewRHS,
|
||||
ISD::CondCode &CCCode);
|
||||
void IntegerExpandSetCCOperands(SDOperand &NewLHS, SDOperand &NewRHS,
|
||||
ISD::CondCode &CCCode);
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Float to Integer Conversion Support: LegalizeFloatTypes.cpp
|
||||
@ -337,6 +338,12 @@ private:
|
||||
// Operand Float to Integer Conversion.
|
||||
bool SoftenFloatOperand(SDNode *N, unsigned OpNo);
|
||||
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
|
||||
@ -351,8 +358,14 @@ private:
|
||||
|
||||
// Float Operand Expansion.
|
||||
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);
|
||||
|
||||
void FloatExpandSetCCOperands(SDOperand &NewLHS, SDOperand &NewRHS,
|
||||
ISD::CondCode &CCCode);
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Scalarization Support: LegalizeVectorTypes.cpp
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
Loading…
Reference in New Issue
Block a user