case ISD::ANY_EXTEND: ExpandResult_ANY_EXTEND(N, Lo, Hi); break;
case ISD::ZERO_EXTEND: ExpandResult_ZERO_EXTEND(N, Lo, Hi); break;
case ISD::SIGN_EXTEND: ExpandResult_SIGN_EXTEND(N, Lo, Hi); break;
+ case ISD::AssertZext: ExpandResult_AssertZext(N, Lo, Hi); break;
+ case ISD::TRUNCATE: ExpandResult_TRUNCATE(N, Lo, Hi); break;
case ISD::BIT_CONVERT: ExpandResult_BIT_CONVERT(N, Lo, Hi); break;
case ISD::SIGN_EXTEND_INREG: ExpandResult_SIGN_EXTEND_INREG(N, Lo, Hi); break;
case ISD::LOAD: ExpandResult_LOAD(cast<LoadSDNode>(N), Lo, Hi); break;
case ISD::SHL:
case ISD::SRA:
case ISD::SRL: ExpandResult_Shift(N, Lo, Hi); break;
+
+ case ISD::CTLZ: ExpandResult_CTLZ(N, Lo, Hi); break;
+ case ISD::CTPOP: ExpandResult_CTPOP(N, Lo, Hi); break;
+ case ISD::CTTZ: ExpandResult_CTTZ(N, Lo, Hi); break;
}
-
+
// If Lo/Hi is null, the sub-method took care of registering results etc.
if (Lo.Val)
SetExpandedOp(SDOperand(N, ResNo), Lo, Hi);
}
}
+void DAGTypeLegalizer::ExpandResult_AssertZext(SDNode *N,
+ SDOperand &Lo, SDOperand &Hi) {
+ GetExpandedOp(N->getOperand(0), Lo, Hi);
+ MVT::ValueType NVT = Lo.getValueType();
+ MVT::ValueType EVT = cast<VTSDNode>(N->getOperand(1))->getVT();
+ unsigned NVTBits = MVT::getSizeInBits(NVT);
+ unsigned EVTBits = MVT::getSizeInBits(EVT);
+
+ if (NVTBits < EVTBits) {
+ Hi = DAG.getNode(ISD::AssertZext, NVT, Hi,
+ DAG.getValueType(MVT::getIntegerType(EVTBits - NVTBits)));
+ } else {
+ Lo = DAG.getNode(ISD::AssertZext, NVT, Lo, DAG.getValueType(EVT));
+ // The high part must be zero, make it explicit.
+ Hi = DAG.getConstant(0, NVT);
+ }
+}
+
+void DAGTypeLegalizer::ExpandResult_TRUNCATE(SDNode *N,
+ SDOperand &Lo, SDOperand &Hi) {
+ MVT::ValueType NVT = TLI.getTypeToTransformTo(N->getValueType(0));
+ Lo = DAG.getNode(ISD::TRUNCATE, NVT, N->getOperand(0));
+ Hi = DAG.getNode(ISD::SRL, N->getOperand(0).getValueType(), N->getOperand(0),
+ DAG.getConstant(MVT::getSizeInBits(NVT),
+ TLI.getShiftAmountTy()));
+ Hi = DAG.getNode(ISD::TRUNCATE, NVT, Hi);
+}
+
void DAGTypeLegalizer::ExpandResult_BIT_CONVERT(SDNode *N,
SDOperand &Lo, SDOperand &Hi) {
// Lower the bit-convert to a store/load from the stack, then expand the load.
Hi.getValue(1));
// Handle endianness of the load.
- if (!TLI.isLittleEndian())
+ if (TLI.isBigEndian())
std::swap(Lo, Hi);
- } else if (MVT::getSizeInBits(N->getLoadedVT()) <= MVT::getSizeInBits(NVT)) {
- MVT::ValueType EVT = N->getLoadedVT();
+ } else if (MVT::getSizeInBits(N->getMemoryVT()) <= MVT::getSizeInBits(NVT)) {
+ MVT::ValueType EVT = N->getMemoryVT();
Lo = DAG.getExtLoad(ExtType, NVT, Ch, Ptr, N->getSrcValue(), SVOffset, EVT,
isVolatile, Alignment);
isVolatile, Alignment);
unsigned ExcessBits =
- MVT::getSizeInBits(N->getLoadedVT()) - MVT::getSizeInBits(NVT);
+ MVT::getSizeInBits(N->getMemoryVT()) - MVT::getSizeInBits(NVT);
MVT::ValueType NEVT = MVT::getIntegerType(ExcessBits);
// Increment the pointer to the other half.
} else {
// Big-endian - high bits are at low addresses. Favor aligned loads at
// the cost of some bit-fiddling.
- MVT::ValueType EVT = N->getLoadedVT();
+ MVT::ValueType EVT = N->getMemoryVT();
unsigned EBytes = MVT::getStoreSizeInBits(EVT)/8;
unsigned IncrementSize = MVT::getSizeInBits(NVT)/8;
unsigned ExcessBits = (EBytes - IncrementSize)*8;
#endif
}
+void DAGTypeLegalizer::ExpandResult_CTLZ(SDNode *N,
+ SDOperand &Lo, SDOperand &Hi) {
+ // ctlz (HiLo) -> Hi != 0 ? ctlz(Hi) : (ctlz(Lo)+32)
+ GetExpandedOp(N->getOperand(0), Lo, Hi);
+ MVT::ValueType NVT = Lo.getValueType();
+
+ SDOperand HiNotZero = DAG.getSetCC(TLI.getSetCCResultTy(), Hi,
+ DAG.getConstant(0, NVT), ISD::SETNE);
+
+ SDOperand LoLZ = DAG.getNode(ISD::CTLZ, NVT, Lo);
+ SDOperand HiLZ = DAG.getNode(ISD::CTLZ, NVT, Hi);
+
+ Lo = DAG.getNode(ISD::SELECT, NVT, HiNotZero, HiLZ,
+ DAG.getNode(ISD::ADD, NVT, LoLZ,
+ DAG.getConstant(MVT::getSizeInBits(NVT), NVT)));
+ Hi = DAG.getConstant(0, NVT);
+}
+
+void DAGTypeLegalizer::ExpandResult_CTPOP(SDNode *N,
+ SDOperand &Lo, SDOperand &Hi) {
+ // ctpop(HiLo) -> ctpop(Hi)+ctpop(Lo)
+ GetExpandedOp(N->getOperand(0), Lo, Hi);
+ MVT::ValueType NVT = Lo.getValueType();
+ Lo = DAG.getNode(ISD::ADD, NVT, DAG.getNode(ISD::CTPOP, NVT, Lo),
+ DAG.getNode(ISD::CTPOP, NVT, Hi));
+ Hi = DAG.getConstant(0, NVT);
+}
+
+void DAGTypeLegalizer::ExpandResult_CTTZ(SDNode *N,
+ SDOperand &Lo, SDOperand &Hi) {
+ // cttz (HiLo) -> Lo != 0 ? cttz(Lo) : (cttz(Hi)+32)
+ GetExpandedOp(N->getOperand(0), Lo, Hi);
+ MVT::ValueType NVT = Lo.getValueType();
+
+ SDOperand LoNotZero = DAG.getSetCC(TLI.getSetCCResultTy(), Lo,
+ DAG.getConstant(0, NVT), ISD::SETNE);
+
+ SDOperand LoLZ = DAG.getNode(ISD::CTTZ, NVT, Lo);
+ SDOperand HiLZ = DAG.getNode(ISD::CTTZ, NVT, Hi);
+
+ Lo = DAG.getNode(ISD::SELECT, NVT, LoNotZero, LoLZ,
+ DAG.getNode(ISD::ADD, NVT, HiLZ,
+ DAG.getConstant(MVT::getSizeInBits(NVT), NVT)));
+ Hi = DAG.getConstant(0, NVT);
+}
/// ExpandShiftByConstant - N is a shift by a value that needs to be expanded,
/// and the shift amount is a constant 'Amt'. Expand the operation.
DEBUG(cerr << "Expand node operand: "; N->dump(&DAG); cerr << "\n");
SDOperand Res(0, 0);
- if (TLI.getOperationAction(N->getOpcode(), N->getValueType(0)) ==
- TargetLowering::Custom)
+ if (TLI.getOperationAction(N->getOpcode(), N->getOperand(OpNo).getValueType())
+ == TargetLowering::Custom)
Res = TLI.LowerOperation(SDOperand(N, 0), DAG);
if (Res.Val == 0) {
Res = ExpandOperand_UINT_TO_FP(N->getOperand(0), N->getValueType(0));
break;
case ISD::EXTRACT_ELEMENT: Res = ExpandOperand_EXTRACT_ELEMENT(N); break;
+
+ case ISD::BR_CC: Res = ExpandOperand_BR_CC(N); break;
case ISD::SETCC: Res = ExpandOperand_SETCC(N); break;
case ISD::STORE:
return cast<ConstantSDNode>(N->getOperand(1))->getValue() ? Hi : Lo;
}
+SDOperand DAGTypeLegalizer::ExpandOperand_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);
+
+ // 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::ExpandOperand_SETCC(SDNode *N) {
SDOperand NewLHS = N->getOperand(0), NewRHS = N->getOperand(1);
ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(2))->get();
GetExpandedOp(N->getValue(), Lo, Hi);
IncrementSize = MVT::getSizeInBits(Hi.getValueType())/8;
- if (!TLI.isLittleEndian())
+ if (TLI.isBigEndian())
std::swap(Lo, Hi);
Lo = DAG.getStore(Ch, Lo, Ptr, N->getSrcValue(),
Hi = DAG.getStore(Ch, Hi, Ptr, N->getSrcValue(), SVOffset+IncrementSize,
isVolatile, MinAlign(Alignment, IncrementSize));
return DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi);
- } else if (MVT::getSizeInBits(N->getStoredVT()) <= MVT::getSizeInBits(NVT)) {
+ } else if (MVT::getSizeInBits(N->getMemoryVT()) <= MVT::getSizeInBits(NVT)) {
GetExpandedOp(N->getValue(), Lo, Hi);
return DAG.getTruncStore(Ch, Lo, Ptr, N->getSrcValue(), SVOffset,
- N->getStoredVT(), isVolatile, Alignment);
+ N->getMemoryVT(), isVolatile, Alignment);
} else if (TLI.isLittleEndian()) {
// Little-endian - low bits are at low addresses.
GetExpandedOp(N->getValue(), Lo, Hi);
isVolatile, Alignment);
unsigned ExcessBits =
- MVT::getSizeInBits(N->getStoredVT()) - MVT::getSizeInBits(NVT);
+ MVT::getSizeInBits(N->getMemoryVT()) - MVT::getSizeInBits(NVT);
MVT::ValueType NEVT = MVT::getIntegerType(ExcessBits);
// Increment the pointer to the other half.
// the cost of some bit-fiddling.
GetExpandedOp(N->getValue(), Lo, Hi);
- MVT::ValueType EVT = N->getStoredVT();
+ MVT::ValueType EVT = N->getMemoryVT();
unsigned EBytes = MVT::getStoreSizeInBits(EVT)/8;
unsigned IncrementSize = MVT::getSizeInBits(NVT)/8;
unsigned ExcessBits = (EBytes - IncrementSize)*8;