SDOperand ExpandIntToFP(bool isSigned, MVT::ValueType DestTy,
SDOperand Source);
- SDOperand ExpandBIT_CONVERT(MVT::ValueType DestVT, SDOperand SrcOp);
+ SDOperand EmitStackConvert(SDOperand SrcOp, MVT::ValueType SlotVT,
+ MVT::ValueType DestVT);
SDOperand ExpandBUILD_VECTOR(SDNode *Node);
SDOperand ExpandSCALAR_TO_VECTOR(SDNode *Node);
SDOperand ExpandLegalINT_TO_FP(bool isSigned,
SDOperand ExpandEXTRACT_SUBVECTOR(SDOperand Op);
SDOperand ExpandEXTRACT_VECTOR_ELT(SDOperand Op);
-
- SDOperand getIntPtrConstant(uint64_t Val) {
- return DAG.getConstant(Val, TLI.getPointerTy());
- }
};
}
return DAG.getNode(ISD::BUILD_VECTOR, VT, &Scalars[0], Scalars.size());
}
+/// GetFPLibCall - Return the right libcall for the given floating point type.
+static RTLIB::Libcall GetFPLibCall(MVT::ValueType VT,
+ RTLIB::Libcall Call_F32,
+ RTLIB::Libcall Call_F64,
+ RTLIB::Libcall Call_F80,
+ RTLIB::Libcall Call_PPCF128) {
+ return
+ VT == MVT::f32 ? Call_F32 :
+ VT == MVT::f64 ? Call_F64 :
+ VT == MVT::f80 ? Call_F80 :
+ VT == MVT::ppcf128 ? Call_PPCF128 :
+ RTLIB::UNKNOWN_LIBCALL;
+}
+
/// LegalizeOp - We know that the specified value has a legal type, and
/// that its operands are legal. Now ensure that the operation itself
/// is legal, recursively ensuring that the operands' operations remain
default: assert(0 && "This action is not supported yet!");
case TargetLowering::Expand: {
unsigned Reg = TLI.getExceptionAddressRegister();
- Result = DAG.getCopyFromReg(Tmp1, Reg, VT).getValue(Op.ResNo);
+ Result = DAG.getCopyFromReg(Tmp1, Reg, VT);
}
break;
case TargetLowering::Custom:
case TargetLowering::Legal: {
SDOperand Ops[] = { DAG.getConstant(0, VT), Tmp1 };
Result = DAG.getNode(ISD::MERGE_VALUES, DAG.getVTList(VT, MVT::Other),
- Ops, 2).getValue(Op.ResNo);
+ Ops, 2);
break;
}
}
}
- break;
+ if (Result.Val->getNumValues() == 1) break;
+
+ assert(Result.Val->getNumValues() == 2 &&
+ "Cannot return more than two values!");
+
+ // Since we produced two values, make sure to remember that we
+ // legalized both of them.
+ Tmp1 = LegalizeOp(Result);
+ Tmp2 = LegalizeOp(Result.getValue(1));
+ AddLegalizedOperand(Op.getValue(0), Tmp1);
+ AddLegalizedOperand(Op.getValue(1), Tmp2);
+ return Op.ResNo ? Tmp2 : Tmp1;
case ISD::EHSELECTION: {
Tmp1 = LegalizeOp(Node->getOperand(0));
Tmp2 = LegalizeOp(Node->getOperand(1));
default: assert(0 && "This action is not supported yet!");
case TargetLowering::Expand: {
unsigned Reg = TLI.getExceptionSelectorRegister();
- Result = DAG.getCopyFromReg(Tmp2, Reg, VT).getValue(Op.ResNo);
+ Result = DAG.getCopyFromReg(Tmp2, Reg, VT);
}
break;
case TargetLowering::Custom:
case TargetLowering::Legal: {
SDOperand Ops[] = { DAG.getConstant(0, VT), Tmp2 };
Result = DAG.getNode(ISD::MERGE_VALUES, DAG.getVTList(VT, MVT::Other),
- Ops, 2).getValue(Op.ResNo);
+ Ops, 2);
break;
}
}
}
- break;
+ if (Result.Val->getNumValues() == 1) break;
+
+ assert(Result.Val->getNumValues() == 2 &&
+ "Cannot return more than two values!");
+
+ // Since we produced two values, make sure to remember that we
+ // legalized both of them.
+ Tmp1 = LegalizeOp(Result);
+ Tmp2 = LegalizeOp(Result.getValue(1));
+ AddLegalizedOperand(Op.getValue(0), Tmp1);
+ AddLegalizedOperand(Op.getValue(1), Tmp2);
+ return Op.ResNo ? Tmp2 : Tmp1;
case ISD::EH_RETURN: {
MVT::ValueType VT = Node->getValueType(0);
// The only "good" option for this node is to custom lower it.
case TargetLowering::Legal:
break;
case TargetLowering::Custom:
- Tmp3 = TLI.LowerOperation(Result, DAG);
- if (Tmp3.Val) {
- Result = Tmp3;
+ Tmp4 = TLI.LowerOperation(Result, DAG);
+ if (Tmp4.Val) {
+ Result = Tmp4;
break;
}
// FALLTHROUGH
return Op.ResNo ? Tmp4 : Tmp3;
} else {
MVT::ValueType SrcVT = LD->getLoadedVT();
- switch (TLI.getLoadXAction(ExtType, SrcVT)) {
- default: assert(0 && "This action is not supported yet!");
- case TargetLowering::Promote:
- assert(SrcVT == MVT::i1 &&
- "Can only promote extending LOAD from i1 -> i8!");
- Result = DAG.getExtLoad(ExtType, Node->getValueType(0), Tmp1, Tmp2,
- LD->getSrcValue(), LD->getSrcValueOffset(),
- MVT::i8, LD->isVolatile(), LD->getAlignment());
- Tmp1 = Result.getValue(0);
- Tmp2 = Result.getValue(1);
- break;
- case TargetLowering::Custom:
- isCustom = true;
- // FALLTHROUGH
- case TargetLowering::Legal:
- Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, LD->getOffset());
- Tmp1 = Result.getValue(0);
- Tmp2 = Result.getValue(1);
-
- if (isCustom) {
- Tmp3 = TLI.LowerOperation(Result, DAG);
- if (Tmp3.Val) {
- Tmp1 = LegalizeOp(Tmp3);
- Tmp2 = LegalizeOp(Tmp3.getValue(1));
- }
+ unsigned SrcWidth = MVT::getSizeInBits(SrcVT);
+ int SVOffset = LD->getSrcValueOffset();
+ unsigned Alignment = LD->getAlignment();
+ bool isVolatile = LD->isVolatile();
+
+ if (SrcWidth != MVT::getStoreSizeInBits(SrcVT) &&
+ // Some targets pretend to have an i1 loading operation, and actually
+ // load an i8. This trick is correct for ZEXTLOAD because the top 7
+ // bits are guaranteed to be zero; it helps the optimizers understand
+ // that these bits are zero. It is also useful for EXTLOAD, since it
+ // tells the optimizers that those bits are undefined. It would be
+ // nice to have an effective generic way of getting these benefits...
+ // Until such a way is found, don't insist on promoting i1 here.
+ (SrcVT != MVT::i1 ||
+ TLI.getLoadXAction(ExtType, MVT::i1) == TargetLowering::Promote)) {
+ // Promote to a byte-sized load if not loading an integral number of
+ // bytes. For example, promote EXTLOAD:i20 -> EXTLOAD:i24.
+ unsigned NewWidth = MVT::getStoreSizeInBits(SrcVT);
+ MVT::ValueType NVT = MVT::getIntegerType(NewWidth);
+ SDOperand Ch;
+
+ // The extra bits are guaranteed to be zero, since we stored them that
+ // way. A zext load from NVT thus automatically gives zext from SrcVT.
+
+ ISD::LoadExtType NewExtType =
+ ExtType == ISD::ZEXTLOAD ? ISD::ZEXTLOAD : ISD::EXTLOAD;
+
+ Result = DAG.getExtLoad(NewExtType, Node->getValueType(0),
+ Tmp1, Tmp2, LD->getSrcValue(), SVOffset,
+ NVT, isVolatile, Alignment);
+
+ Ch = Result.getValue(1); // The chain.
+
+ if (ExtType == ISD::SEXTLOAD)
+ // Having the top bits zero doesn't help when sign extending.
+ Result = DAG.getNode(ISD::SIGN_EXTEND_INREG, Result.getValueType(),
+ Result, DAG.getValueType(SrcVT));
+ else if (ExtType == ISD::ZEXTLOAD || NVT == Result.getValueType())
+ // All the top bits are guaranteed to be zero - inform the optimizers.
+ Result = DAG.getNode(ISD::AssertZext, Result.getValueType(), Result,
+ DAG.getValueType(SrcVT));
+
+ Tmp1 = LegalizeOp(Result);
+ Tmp2 = LegalizeOp(Ch);
+ } else if (SrcWidth & (SrcWidth - 1)) {
+ // If not loading a power-of-2 number of bits, expand as two loads.
+ assert(MVT::isExtendedVT(SrcVT) && !MVT::isVector(SrcVT) &&
+ "Unsupported extload!");
+ unsigned RoundWidth = 1 << Log2_32(SrcWidth);
+ assert(RoundWidth < SrcWidth);
+ unsigned ExtraWidth = SrcWidth - RoundWidth;
+ assert(ExtraWidth < RoundWidth);
+ assert(!(RoundWidth % 8) && !(ExtraWidth % 8) &&
+ "Load size not an integral number of bytes!");
+ MVT::ValueType RoundVT = MVT::getIntegerType(RoundWidth);
+ MVT::ValueType ExtraVT = MVT::getIntegerType(ExtraWidth);
+ SDOperand Lo, Hi, Ch;
+ unsigned IncrementSize;
+
+ if (TLI.isLittleEndian()) {
+ // EXTLOAD:i24 -> ZEXTLOAD:i16 | (shl EXTLOAD@+2:i8, 16)
+ // Load the bottom RoundWidth bits.
+ Lo = DAG.getExtLoad(ISD::ZEXTLOAD, Node->getValueType(0), Tmp1, Tmp2,
+ LD->getSrcValue(), SVOffset, RoundVT, isVolatile,
+ Alignment);
+
+ // Load the remaining ExtraWidth bits.
+ IncrementSize = RoundWidth / 8;
+ Tmp2 = DAG.getNode(ISD::ADD, Tmp2.getValueType(), Tmp2,
+ DAG.getIntPtrConstant(IncrementSize));
+ Hi = DAG.getExtLoad(ExtType, Node->getValueType(0), Tmp1, Tmp2,
+ LD->getSrcValue(), SVOffset + IncrementSize,
+ ExtraVT, isVolatile,
+ MinAlign(Alignment, IncrementSize));
+
+ // Build a factor node to remember that this load is independent of the
+ // other one.
+ Ch = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo.getValue(1),
+ Hi.getValue(1));
+
+ // Move the top bits to the right place.
+ Hi = DAG.getNode(ISD::SHL, Hi.getValueType(), Hi,
+ DAG.getConstant(RoundWidth, TLI.getShiftAmountTy()));
+
+ // Join the hi and lo parts.
+ Result = DAG.getNode(ISD::OR, Node->getValueType(0), Lo, Hi);
} else {
- // If this is an unaligned load and the target doesn't support it,
- // expand it.
- if (!TLI.allowsUnalignedMemoryAccesses()) {
- unsigned ABIAlignment = TLI.getTargetData()->
- getABITypeAlignment(MVT::getTypeForValueType(LD->getLoadedVT()));
- if (LD->getAlignment() < ABIAlignment){
- Result = ExpandUnalignedLoad(cast<LoadSDNode>(Result.Val), DAG,
- TLI);
- Tmp1 = Result.getOperand(0);
- Tmp2 = Result.getOperand(1);
- Tmp1 = LegalizeOp(Tmp1);
- Tmp2 = LegalizeOp(Tmp2);
+ // Big endian - avoid unaligned loads.
+ // EXTLOAD:i24 -> (shl EXTLOAD:i16, 8) | ZEXTLOAD@+2:i8
+ // Load the top RoundWidth bits.
+ Hi = DAG.getExtLoad(ExtType, Node->getValueType(0), Tmp1, Tmp2,
+ LD->getSrcValue(), SVOffset, RoundVT, isVolatile,
+ Alignment);
+
+ // Load the remaining ExtraWidth bits.
+ IncrementSize = RoundWidth / 8;
+ Tmp2 = DAG.getNode(ISD::ADD, Tmp2.getValueType(), Tmp2,
+ DAG.getIntPtrConstant(IncrementSize));
+ Lo = DAG.getExtLoad(ISD::ZEXTLOAD, Node->getValueType(0), Tmp1, Tmp2,
+ LD->getSrcValue(), SVOffset + IncrementSize,
+ ExtraVT, isVolatile,
+ MinAlign(Alignment, IncrementSize));
+
+ // Build a factor node to remember that this load is independent of the
+ // other one.
+ Ch = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo.getValue(1),
+ Hi.getValue(1));
+
+ // Move the top bits to the right place.
+ Hi = DAG.getNode(ISD::SHL, Hi.getValueType(), Hi,
+ DAG.getConstant(ExtraWidth, TLI.getShiftAmountTy()));
+
+ // Join the hi and lo parts.
+ Result = DAG.getNode(ISD::OR, Node->getValueType(0), Lo, Hi);
+ }
+
+ Tmp1 = LegalizeOp(Result);
+ Tmp2 = LegalizeOp(Ch);
+ } else {
+ switch (TLI.getLoadXAction(ExtType, SrcVT)) {
+ default: assert(0 && "This action is not supported yet!");
+ case TargetLowering::Custom:
+ isCustom = true;
+ // FALLTHROUGH
+ case TargetLowering::Legal:
+ Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, LD->getOffset());
+ Tmp1 = Result.getValue(0);
+ Tmp2 = Result.getValue(1);
+
+ if (isCustom) {
+ Tmp3 = TLI.LowerOperation(Result, DAG);
+ if (Tmp3.Val) {
+ Tmp1 = LegalizeOp(Tmp3);
+ Tmp2 = LegalizeOp(Tmp3.getValue(1));
+ }
+ } else {
+ // If this is an unaligned load and the target doesn't support it,
+ // expand it.
+ if (!TLI.allowsUnalignedMemoryAccesses()) {
+ unsigned ABIAlignment = TLI.getTargetData()->
+ getABITypeAlignment(MVT::getTypeForValueType(LD->getLoadedVT()));
+ if (LD->getAlignment() < ABIAlignment){
+ Result = ExpandUnalignedLoad(cast<LoadSDNode>(Result.Val), DAG,
+ TLI);
+ Tmp1 = Result.getOperand(0);
+ Tmp2 = Result.getOperand(1);
+ Tmp1 = LegalizeOp(Tmp1);
+ Tmp2 = LegalizeOp(Tmp2);
+ }
}
}
- }
- break;
- case TargetLowering::Expand:
- // f64 = EXTLOAD f32 should expand to LOAD, FP_EXTEND
- if (SrcVT == MVT::f32 && Node->getValueType(0) == MVT::f64) {
- SDOperand Load = DAG.getLoad(SrcVT, Tmp1, Tmp2, LD->getSrcValue(),
- LD->getSrcValueOffset(),
- LD->isVolatile(), LD->getAlignment());
- Result = DAG.getNode(ISD::FP_EXTEND, Node->getValueType(0), Load);
- Tmp1 = LegalizeOp(Result); // Relegalize new nodes.
- Tmp2 = LegalizeOp(Load.getValue(1));
+ break;
+ case TargetLowering::Expand:
+ // f64 = EXTLOAD f32 should expand to LOAD, FP_EXTEND
+ if (SrcVT == MVT::f32 && Node->getValueType(0) == MVT::f64) {
+ SDOperand Load = DAG.getLoad(SrcVT, Tmp1, Tmp2, LD->getSrcValue(),
+ LD->getSrcValueOffset(),
+ LD->isVolatile(), LD->getAlignment());
+ Result = DAG.getNode(ISD::FP_EXTEND, Node->getValueType(0), Load);
+ Tmp1 = LegalizeOp(Result); // Relegalize new nodes.
+ Tmp2 = LegalizeOp(Load.getValue(1));
+ break;
+ }
+ assert(ExtType != ISD::EXTLOAD &&"EXTLOAD should always be supported!");
+ // Turn the unsupported load into an EXTLOAD followed by an explicit
+ // zero/sign extend inreg.
+ Result = DAG.getExtLoad(ISD::EXTLOAD, Node->getValueType(0),
+ Tmp1, Tmp2, LD->getSrcValue(),
+ LD->getSrcValueOffset(), SrcVT,
+ LD->isVolatile(), LD->getAlignment());
+ SDOperand ValRes;
+ if (ExtType == ISD::SEXTLOAD)
+ ValRes = DAG.getNode(ISD::SIGN_EXTEND_INREG, Result.getValueType(),
+ Result, DAG.getValueType(SrcVT));
+ else
+ ValRes = DAG.getZeroExtendInReg(Result, SrcVT);
+ Tmp1 = LegalizeOp(ValRes); // Relegalize new nodes.
+ Tmp2 = LegalizeOp(Result.getValue(1)); // Relegalize new nodes.
break;
}
- assert(ExtType != ISD::EXTLOAD &&"EXTLOAD should always be supported!");
- // Turn the unsupported load into an EXTLOAD followed by an explicit
- // zero/sign extend inreg.
- Result = DAG.getExtLoad(ISD::EXTLOAD, Node->getValueType(0),
- Tmp1, Tmp2, LD->getSrcValue(),
- LD->getSrcValueOffset(), SrcVT,
- LD->isVolatile(), LD->getAlignment());
- SDOperand ValRes;
- if (ExtType == ISD::SEXTLOAD)
- ValRes = DAG.getNode(ISD::SIGN_EXTEND_INREG, Result.getValueType(),
- Result, DAG.getValueType(SrcVT));
- else
- ValRes = DAG.getZeroExtendInReg(Result, SrcVT);
- Tmp1 = LegalizeOp(ValRes); // Relegalize new nodes.
- Tmp2 = LegalizeOp(Result.getValue(1)); // Relegalize new nodes.
- break;
}
+
// Since loads produce two values, make sure to remember that we legalized
// both of them.
AddLegalizedOperand(SDOperand(Node, 0), Tmp1);
Lo = DAG.getStore(Tmp1, Lo, Tmp2, ST->getSrcValue(),
SVOffset, isVolatile, Alignment);
Tmp2 = DAG.getNode(ISD::ADD, Tmp2.getValueType(), Tmp2,
- getIntPtrConstant(4));
+ DAG.getIntPtrConstant(4));
Hi = DAG.getStore(Tmp1, Hi, Tmp2, ST->getSrcValue(), SVOffset+4,
isVolatile, MinAlign(Alignment, 4U));
if (MVT::isVector(ST->getValue().getValueType())) {
SDNode *InVal = ST->getValue().Val;
int InIx = ST->getValue().ResNo;
- unsigned NumElems = MVT::getVectorNumElements(InVal->getValueType(InIx));
- MVT::ValueType EVT = MVT::getVectorElementType(InVal->getValueType(InIx));
+ MVT::ValueType InVT = InVal->getValueType(InIx);
+ unsigned NumElems = MVT::getVectorNumElements(InVT);
+ MVT::ValueType EVT = MVT::getVectorElementType(InVT);
// Figure out if there is a simple type corresponding to this Vector
// type. If so, convert to the vector type.
}
Tmp2 = DAG.getNode(ISD::ADD, Tmp2.getValueType(), Tmp2,
- getIntPtrConstant(IncrementSize));
+ DAG.getIntPtrConstant(IncrementSize));
assert(isTypeLegal(Tmp2.getValueType()) &&
"Pointers must be legal!");
SVOffset += IncrementSize;
break;
}
} else {
- // Truncating store
- assert(isTypeLegal(ST->getValue().getValueType()) &&
- "Cannot handle illegal TRUNCSTORE yet!");
- Tmp3 = LegalizeOp(ST->getValue());
-
- // The only promote case we handle is TRUNCSTORE:i1 X into
- // -> TRUNCSTORE:i8 (and X, 1)
- if (ST->getStoredVT() == MVT::i1 &&
- TLI.getStoreXAction(MVT::i1) == TargetLowering::Promote) {
- // Promote the bool to a mask then store.
- Tmp3 = DAG.getNode(ISD::AND, Tmp3.getValueType(), Tmp3,
- DAG.getConstant(1, Tmp3.getValueType()));
- Result = DAG.getTruncStore(Tmp1, Tmp3, Tmp2, ST->getSrcValue(),
- SVOffset, MVT::i8,
- isVolatile, Alignment);
- } else if (Tmp1 != ST->getChain() || Tmp3 != ST->getValue() ||
- Tmp2 != ST->getBasePtr()) {
- Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp3, Tmp2,
- ST->getOffset());
+ switch (getTypeAction(ST->getValue().getValueType())) {
+ case Legal:
+ Tmp3 = LegalizeOp(ST->getValue());
+ break;
+ case Promote:
+ // We can promote the value, the truncstore will still take care of it.
+ Tmp3 = PromoteOp(ST->getValue());
+ break;
+ case Expand:
+ // Just store the low part. This may become a non-trunc store, so make
+ // sure to use getTruncStore, not UpdateNodeOperands below.
+ ExpandOp(ST->getValue(), Tmp3, Tmp4);
+ return DAG.getTruncStore(Tmp1, Tmp3, Tmp2, ST->getSrcValue(),
+ SVOffset, MVT::i8, isVolatile, Alignment);
}
- MVT::ValueType StVT = cast<StoreSDNode>(Result.Val)->getStoredVT();
- switch (TLI.getStoreXAction(StVT)) {
- default: assert(0 && "This action is not supported yet!");
- case TargetLowering::Legal:
- // If this is an unaligned store and the target doesn't support it,
- // expand it.
- if (!TLI.allowsUnalignedMemoryAccesses()) {
- unsigned ABIAlignment = TLI.getTargetData()->
- getABITypeAlignment(MVT::getTypeForValueType(ST->getStoredVT()));
- if (ST->getAlignment() < ABIAlignment)
- Result = ExpandUnalignedStore(cast<StoreSDNode>(Result.Val), DAG,
- TLI);
+ MVT::ValueType StVT = ST->getStoredVT();
+ unsigned StWidth = MVT::getSizeInBits(StVT);
+
+ if (StWidth != MVT::getStoreSizeInBits(StVT)) {
+ // Promote to a byte-sized store with upper bits zero if not
+ // storing an integral number of bytes. For example, promote
+ // TRUNCSTORE:i1 X -> TRUNCSTORE:i8 (and X, 1)
+ MVT::ValueType NVT = MVT::getIntegerType(MVT::getStoreSizeInBits(StVT));
+ Tmp3 = DAG.getZeroExtendInReg(Tmp3, StVT);
+ Result = DAG.getTruncStore(Tmp1, Tmp3, Tmp2, ST->getSrcValue(),
+ SVOffset, NVT, isVolatile, Alignment);
+ } else if (StWidth & (StWidth - 1)) {
+ // If not storing a power-of-2 number of bits, expand as two stores.
+ assert(MVT::isExtendedVT(StVT) && !MVT::isVector(StVT) &&
+ "Unsupported truncstore!");
+ unsigned RoundWidth = 1 << Log2_32(StWidth);
+ assert(RoundWidth < StWidth);
+ unsigned ExtraWidth = StWidth - RoundWidth;
+ assert(ExtraWidth < RoundWidth);
+ assert(!(RoundWidth % 8) && !(ExtraWidth % 8) &&
+ "Store size not an integral number of bytes!");
+ MVT::ValueType RoundVT = MVT::getIntegerType(RoundWidth);
+ MVT::ValueType ExtraVT = MVT::getIntegerType(ExtraWidth);
+ SDOperand Lo, Hi;
+ unsigned IncrementSize;
+
+ if (TLI.isLittleEndian()) {
+ // TRUNCSTORE:i24 X -> TRUNCSTORE:i16 X, TRUNCSTORE@+2:i8 (srl X, 16)
+ // Store the bottom RoundWidth bits.
+ Lo = DAG.getTruncStore(Tmp1, Tmp3, Tmp2, ST->getSrcValue(),
+ SVOffset, RoundVT,
+ isVolatile, Alignment);
+
+ // Store the remaining ExtraWidth bits.
+ IncrementSize = RoundWidth / 8;
+ Tmp2 = DAG.getNode(ISD::ADD, Tmp2.getValueType(), Tmp2,
+ DAG.getIntPtrConstant(IncrementSize));
+ Hi = DAG.getNode(ISD::SRL, Tmp3.getValueType(), Tmp3,
+ DAG.getConstant(RoundWidth, TLI.getShiftAmountTy()));
+ Hi = DAG.getTruncStore(Tmp1, Hi, Tmp2, ST->getSrcValue(),
+ SVOffset + IncrementSize, ExtraVT, isVolatile,
+ MinAlign(Alignment, IncrementSize));
+ } else {
+ // Big endian - avoid unaligned stores.
+ // TRUNCSTORE:i24 X -> TRUNCSTORE:i16 (srl X, 8), TRUNCSTORE@+2:i8 X
+ // Store the top RoundWidth bits.
+ Hi = DAG.getNode(ISD::SRL, Tmp3.getValueType(), Tmp3,
+ DAG.getConstant(ExtraWidth, TLI.getShiftAmountTy()));
+ Hi = DAG.getTruncStore(Tmp1, Hi, Tmp2, ST->getSrcValue(), SVOffset,
+ RoundVT, isVolatile, Alignment);
+
+ // Store the remaining ExtraWidth bits.
+ IncrementSize = RoundWidth / 8;
+ Tmp2 = DAG.getNode(ISD::ADD, Tmp2.getValueType(), Tmp2,
+ DAG.getIntPtrConstant(IncrementSize));
+ Lo = DAG.getTruncStore(Tmp1, Tmp3, Tmp2, ST->getSrcValue(),
+ SVOffset + IncrementSize, ExtraVT, isVolatile,
+ MinAlign(Alignment, IncrementSize));
+ }
+
+ // The order of the stores doesn't matter.
+ Result = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi);
+ } else {
+ if (Tmp1 != ST->getChain() || Tmp3 != ST->getValue() ||
+ Tmp2 != ST->getBasePtr())
+ Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp3, Tmp2,
+ ST->getOffset());
+
+ switch (TLI.getTruncStoreAction(ST->getValue().getValueType(), StVT)) {
+ default: assert(0 && "This action is not supported yet!");
+ case TargetLowering::Legal:
+ // If this is an unaligned store and the target doesn't support it,
+ // expand it.
+ if (!TLI.allowsUnalignedMemoryAccesses()) {
+ unsigned ABIAlignment = TLI.getTargetData()->
+ getABITypeAlignment(MVT::getTypeForValueType(ST->getStoredVT()));
+ if (ST->getAlignment() < ABIAlignment)
+ Result = ExpandUnalignedStore(cast<StoreSDNode>(Result.Val), DAG,
+ TLI);
+ }
+ break;
+ case TargetLowering::Custom:
+ Result = TLI.LowerOperation(Result, DAG);
+ break;
+ case Expand:
+ // TRUNCSTORE:i16 i32 -> STORE i16
+ assert(isTypeLegal(StVT) && "Do not know how to expand this store!");
+ Tmp3 = DAG.getNode(ISD::TRUNCATE, StVT, Tmp3);
+ Result = DAG.getStore(Tmp1, Tmp3, Tmp2, ST->getSrcValue(), SVOffset,
+ isVolatile, Alignment);
+ break;
}
- break;
- case TargetLowering::Custom:
- Tmp1 = TLI.LowerOperation(Result, DAG);
- if (Tmp1.Val) Result = Tmp1;
- break;
}
}
break;
Tmp3 = DAG.getNode(ExtOp, NVT, Tmp3);
// Perform the larger operation, then round down.
Result = DAG.getNode(ISD::SELECT, NVT, Tmp1, Tmp2,Tmp3);
- Result = DAG.getNode(TruncOp, Node->getValueType(0), Result);
+ if (TruncOp != ISD::FP_ROUND)
+ Result = DAG.getNode(TruncOp, Node->getValueType(0), Result);
+ else
+ Result = DAG.getNode(TruncOp, Node->getValueType(0), Result,
+ DAG.getIntPtrConstant(0));
break;
}
}
}
break;
case ISD::FPOW:
- LC = VT == MVT::f32 ? RTLIB::POW_F32 :
- VT == MVT::f64 ? RTLIB::POW_F64 :
- VT == MVT::f80 ? RTLIB::POW_F80 :
- VT == MVT::ppcf128 ? RTLIB::POW_PPCF128 :
- RTLIB::UNKNOWN_LIBCALL;
+ LC = GetFPLibCall(VT, RTLIB::POW_F32, RTLIB::POW_F64, RTLIB::POW_F80,
+ RTLIB::POW_PPCF128);
break;
default: break;
}
Result = LegalizeOp(UnrollVectorOp(Op));
} else {
// Floating point mod -> fmod libcall.
- RTLIB::Libcall LC = VT == MVT::f32
- ? RTLIB::REM_F32 : RTLIB::REM_F64;
+ RTLIB::Libcall LC = GetFPLibCall(VT, RTLIB::REM_F32, RTLIB::REM_F64,
+ RTLIB::REM_F80, RTLIB::REM_PPCF128);
SDOperand Dummy;
Result = ExpandLibCall(TLI.getLibcallName(LC), Node,
false/*sign irrelevant*/, Dummy);
RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
switch(Node->getOpcode()) {
case ISD::FSQRT:
- LC = VT == MVT::f32 ? RTLIB::SQRT_F32 :
- VT == MVT::f64 ? RTLIB::SQRT_F64 :
- VT == MVT::f80 ? RTLIB::SQRT_F80 :
- VT == MVT::ppcf128 ? RTLIB::SQRT_PPCF128 :
- RTLIB::UNKNOWN_LIBCALL;
+ LC = GetFPLibCall(VT, RTLIB::SQRT_F32, RTLIB::SQRT_F64,
+ RTLIB::SQRT_F80, RTLIB::SQRT_PPCF128);
break;
case ISD::FSIN:
- LC = VT == MVT::f32 ? RTLIB::SIN_F32 : RTLIB::SIN_F64;
+ LC = GetFPLibCall(VT, RTLIB::SIN_F32, RTLIB::SIN_F64,
+ RTLIB::SIN_F80, RTLIB::SIN_PPCF128);
break;
case ISD::FCOS:
- LC = VT == MVT::f32 ? RTLIB::COS_F32 : RTLIB::COS_F64;
+ LC = GetFPLibCall(VT, RTLIB::COS_F32, RTLIB::COS_F64,
+ RTLIB::COS_F80, RTLIB::COS_PPCF128);
break;
default: assert(0 && "Unreachable!");
}
}
// We always lower FPOWI into a libcall. No target support for it yet.
- RTLIB::Libcall LC =
- VT == MVT::f32 ? RTLIB::POWI_F32 :
- VT == MVT::f64 ? RTLIB::POWI_F64 :
- VT == MVT::f80 ? RTLIB::POWI_F80 :
- VT == MVT::ppcf128 ? RTLIB::POWI_PPCF128 :
- RTLIB::UNKNOWN_LIBCALL;
+ RTLIB::Libcall LC = GetFPLibCall(VT, RTLIB::POWI_F32, RTLIB::POWI_F64,
+ RTLIB::POWI_F80, RTLIB::POWI_PPCF128);
SDOperand Dummy;
Result = ExpandLibCall(TLI.getLibcallName(LC), Node,
false/*sign irrelevant*/, Dummy);
}
case ISD::BIT_CONVERT:
if (!isTypeLegal(Node->getOperand(0).getValueType())) {
- Result = ExpandBIT_CONVERT(Node->getValueType(0), Node->getOperand(0));
+ Result = EmitStackConvert(Node->getOperand(0), Node->getValueType(0),
+ Node->getValueType(0));
} else if (MVT::isVector(Op.getOperand(0).getValueType())) {
// The input has to be a vector type, we have to either scalarize it, pack
// it, or convert it based on whether the input vector type is legal.
Node->getOperand(0).getValueType())) {
default: assert(0 && "Unknown operation action!");
case TargetLowering::Expand:
- Result = ExpandBIT_CONVERT(Node->getValueType(0), Node->getOperand(0));
+ Result = EmitStackConvert(Node->getOperand(0), Node->getValueType(0),
+ Node->getValueType(0));
break;
case TargetLowering::Legal:
Tmp1 = LegalizeOp(Node->getOperand(0));
MVT::ValueType OVT = Node->getOperand(0).getValueType();
// Convert ppcf128 to i32
if (OVT == MVT::ppcf128 && VT == MVT::i32) {
- if (Node->getOpcode()==ISD::FP_TO_SINT)
- Result = DAG.getNode(ISD::FP_TO_SINT, VT,
- DAG.getNode(ISD::FP_ROUND, MVT::f64,
- (DAG.getNode(ISD::FP_ROUND_INREG,
- MVT::ppcf128, Node->getOperand(0),
- DAG.getValueType(MVT::f64)))));
- else {
+ if (Node->getOpcode() == ISD::FP_TO_SINT) {
+ Result = DAG.getNode(ISD::FP_ROUND_INREG, MVT::ppcf128,
+ Node->getOperand(0), DAG.getValueType(MVT::f64));
+ Result = DAG.getNode(ISD::FP_ROUND, MVT::f64, Result,
+ DAG.getIntPtrConstant(1));
+ Result = DAG.getNode(ISD::FP_TO_SINT, VT, Result);
+ } else {
const uint64_t TwoE31[] = {0x41e0000000000000LL, 0};
APFloat apf = APFloat(APInt(128, 2, TwoE31));
Tmp2 = DAG.getConstantFP(apf, OVT);
}
break;
- case ISD::FP_EXTEND:
+ case ISD::FP_EXTEND: {
+ MVT::ValueType DstVT = Op.getValueType();
+ MVT::ValueType SrcVT = Op.getOperand(0).getValueType();
+ if (TLI.getConvertAction(SrcVT, DstVT) == TargetLowering::Expand) {
+ // The only other way we can lower this is to turn it into a STORE,
+ // LOAD pair, targetting a temporary location (a stack slot).
+ Result = EmitStackConvert(Node->getOperand(0), SrcVT, DstVT);
+ break;
+ }
+ 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);
+ break;
+ case Promote:
+ Tmp1 = PromoteOp(Node->getOperand(0));
+ Result = DAG.getNode(ISD::FP_EXTEND, Op.getValueType(), Tmp1);
+ break;
+ }
+ break;
+ }
case ISD::FP_ROUND: {
- MVT::ValueType newVT = Op.getValueType();
- MVT::ValueType oldVT = Op.getOperand(0).getValueType();
- if (TLI.getConvertAction(oldVT, newVT) == TargetLowering::Expand) {
- if (Node->getOpcode() == ISD::FP_ROUND && oldVT == MVT::ppcf128) {
- SDOperand Lo, Hi;
- ExpandOp(Node->getOperand(0), Lo, Hi);
- if (newVT == MVT::f64)
- Result = Hi;
- else
- Result = DAG.getNode(ISD::FP_ROUND, newVT, Hi);
- break;
- } else {
- // The only other way we can lower this is to turn it into a STORE,
- // LOAD pair, targetting a temporary location (a stack slot).
-
- // NOTE: there is a choice here between constantly creating new stack
- // slots and always reusing the same one. We currently always create
- // new ones, as reuse may inhibit scheduling.
- MVT::ValueType slotVT =
- (Node->getOpcode() == ISD::FP_EXTEND) ? oldVT : newVT;
- const Type *Ty = MVT::getTypeForValueType(slotVT);
- uint64_t TySize = TLI.getTargetData()->getABITypeSize(Ty);
- unsigned Align = TLI.getTargetData()->getPrefTypeAlignment(Ty);
- MachineFunction &MF = DAG.getMachineFunction();
- int SSFI =
- MF.getFrameInfo()->CreateStackObject(TySize, Align);
- SDOperand StackSlot = DAG.getFrameIndex(SSFI, TLI.getPointerTy());
- if (Node->getOpcode() == ISD::FP_EXTEND) {
- Result = DAG.getStore(DAG.getEntryNode(), Node->getOperand(0),
- StackSlot, NULL, 0);
- Result = DAG.getExtLoad(ISD::EXTLOAD, newVT,
- Result, StackSlot, NULL, 0, oldVT);
- } else {
- Result = DAG.getTruncStore(DAG.getEntryNode(), Node->getOperand(0),
- StackSlot, NULL, 0, newVT);
- Result = DAG.getLoad(newVT, Result, StackSlot, NULL, 0);
- }
- break;
- }
+ MVT::ValueType DstVT = Op.getValueType();
+ MVT::ValueType SrcVT = Op.getOperand(0).getValueType();
+ if (TLI.getConvertAction(SrcVT, DstVT) == TargetLowering::Expand) {
+ if (SrcVT == MVT::ppcf128) {
+ SDOperand Lo;
+ ExpandOp(Node->getOperand(0), Lo, Result);
+ // Round it the rest of the way (e.g. to f32) if needed.
+ if (DstVT!=MVT::f64)
+ Result = DAG.getNode(ISD::FP_ROUND, DstVT, Result, Op.getOperand(1));
+ break;
}
+ // The only other way we can lower this is to turn it into a STORE,
+ // LOAD pair, targetting a temporary location (a stack slot).
+ Result = EmitStackConvert(Node->getOperand(0), DstVT, DstVT);
+ break;
+ }
+ 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, Node->getOperand(1));
+ break;
+ case Promote:
+ Tmp1 = PromoteOp(Node->getOperand(0));
+ Result = DAG.getNode(ISD::FP_ROUND, Op.getValueType(), Tmp1,
+ Node->getOperand(1));
+ break;
}
- // FALL THROUGH
+ break;
+ }
case ISD::ANY_EXTEND:
case ISD::ZERO_EXTEND:
case ISD::SIGN_EXTEND:
Result,
DAG.getValueType(Node->getOperand(0).getValueType()));
break;
- case ISD::FP_EXTEND:
- Result = PromoteOp(Node->getOperand(0));
- if (Result.getValueType() != Op.getValueType())
- // Dynamically dead while we have only 2 FP types.
- Result = DAG.getNode(ISD::FP_EXTEND, Op.getValueType(), Result);
- break;
- case ISD::FP_ROUND:
- Result = PromoteOp(Node->getOperand(0));
- Result = DAG.getNode(Node->getOpcode(), Op.getValueType(), Result);
- break;
}
}
break;
// NOTE: there is a choice here between constantly creating new stack
// slots and always reusing the same one. We currently always create
// new ones, as reuse may inhibit scheduling.
- const Type *Ty = MVT::getTypeForValueType(ExtraVT);
- uint64_t TySize = TLI.getTargetData()->getABITypeSize(Ty);
- unsigned Align = TLI.getTargetData()->getPrefTypeAlignment(Ty);
- MachineFunction &MF = DAG.getMachineFunction();
- int SSFI =
- MF.getFrameInfo()->CreateStackObject(TySize, Align);
- SDOperand StackSlot = DAG.getFrameIndex(SSFI, TLI.getPointerTy());
- Result = DAG.getTruncStore(DAG.getEntryNode(), Node->getOperand(0),
- StackSlot, NULL, 0, ExtraVT);
- Result = DAG.getExtLoad(ISD::EXTLOAD, Node->getValueType(0),
- Result, StackSlot, NULL, 0, ExtraVT);
+ Result = EmitStackConvert(Node->getOperand(0), ExtraVT,
+ Node->getValueType(0));
} else {
assert(0 && "Unknown op");
}
break;
}
}
+ case ISD::TRAP: {
+ MVT::ValueType VT = Node->getValueType(0);
+ switch (TLI.getOperationAction(Node->getOpcode(), VT)) {
+ default: assert(0 && "This action not supported for this op yet!");
+ case TargetLowering::Legal:
+ Tmp1 = LegalizeOp(Node->getOperand(0));
+ Result = DAG.UpdateNodeOperands(Result, Tmp1);
+ break;
+ case TargetLowering::Custom:
+ Result = TLI.LowerOperation(Op, DAG);
+ if (Result.Val) break;
+ // Fall Thru
+ case TargetLowering::Expand:
+ // If this operation is not supported, lower it to 'abort()' call
+ Tmp1 = LegalizeOp(Node->getOperand(0));
+ TargetLowering::ArgListTy Args;
+ std::pair<SDOperand,SDOperand> CallResult =
+ TLI.LowerCallTo(Tmp1, Type::VoidTy, false, false, CallingConv::C, false,
+ DAG.getExternalSymbol("abort", TLI.getPointerTy()),
+ Args, DAG);
+ Result = CallResult.second;
+ break;
+ }
+ break;
+ }
}
assert(Result.getValueType() == Op.getValueType() &&
}
break;
case ISD::BIT_CONVERT:
- Result = ExpandBIT_CONVERT(Node->getValueType(0), Node->getOperand(0));
+ Result = EmitStackConvert(Node->getOperand(0), Node->getValueType(0),
+ Node->getValueType(0));
Result = PromoteOp(Result);
break;
case Expand: assert(0 && "BUG: Cannot expand FP regs!");
case Promote: assert(0 && "Unreachable with 2 FP types!");
case Legal:
- // Input is legal? Do an FP_ROUND_INREG.
- Result = DAG.getNode(ISD::FP_ROUND_INREG, NVT, Node->getOperand(0),
- DAG.getValueType(VT));
+ if (Node->getConstantOperandVal(1) == 0) {
+ // Input is legal? Do an FP_ROUND_INREG.
+ Result = DAG.getNode(ISD::FP_ROUND_INREG, NVT, Node->getOperand(0),
+ DAG.getValueType(VT));
+ } else {
+ // Just remove the truncate, it isn't affecting the value.
+ Result = DAG.getNode(ISD::FP_ROUND, NVT, Node->getOperand(0),
+ Node->getOperand(1));
+ }
break;
}
break;
-
case ISD::SINT_TO_FP:
case ISD::UINT_TO_FP:
switch (getTypeAction(Node->getOperand(0).getValueType())) {
case ISD::FCOPYSIGN:
// These operators require that their input be fp extended.
switch (getTypeAction(Node->getOperand(0).getValueType())) {
- case Legal:
- Tmp1 = LegalizeOp(Node->getOperand(0));
- break;
- case Promote:
- Tmp1 = PromoteOp(Node->getOperand(0));
- break;
- case Expand:
- assert(0 && "not implemented");
+ case Expand: assert(0 && "not implemented");
+ case Legal: Tmp1 = LegalizeOp(Node->getOperand(0)); break;
+ case Promote: Tmp1 = PromoteOp(Node->getOperand(0)); break;
}
switch (getTypeAction(Node->getOperand(1).getValueType())) {
- case Legal:
- Tmp2 = LegalizeOp(Node->getOperand(1));
- break;
- case Promote:
- Tmp2 = PromoteOp(Node->getOperand(1));
- break;
- case Expand:
- assert(0 && "not implemented");
+ case Expand: assert(0 && "not implemented");
+ case Legal: Tmp2 = LegalizeOp(Node->getOperand(1)); break;
+ case Promote: Tmp2 = PromoteOp(Node->getOperand(1)); break;
}
Result = DAG.getNode(Node->getOpcode(), NVT, Tmp1, Tmp2);
RHS = Tmp2;
}
-/// ExpandBIT_CONVERT - Expand a BIT_CONVERT node into a store/load combination.
-/// The resultant code need not be legal. Note that SrcOp is the input operand
-/// to the BIT_CONVERT, not the BIT_CONVERT node itself.
-SDOperand SelectionDAGLegalize::ExpandBIT_CONVERT(MVT::ValueType DestVT,
- SDOperand SrcOp) {
+/// EmitStackConvert - Emit a store/load combination to the stack. This stores
+/// SrcOp to a stack slot of type SlotVT, truncating it if needed. It then does
+/// a load from the stack slot to DestVT, extending it if needed.
+/// The resultant code need not be legal.
+SDOperand SelectionDAGLegalize::EmitStackConvert(SDOperand SrcOp,
+ MVT::ValueType SlotVT,
+ MVT::ValueType DestVT) {
// Create the stack frame object.
- SDOperand FIPtr = DAG.CreateStackTemporary(DestVT);
+ SDOperand FIPtr = DAG.CreateStackTemporary(SlotVT);
+
+ unsigned SrcSize = MVT::getSizeInBits(SrcOp.getValueType());
+ unsigned SlotSize = MVT::getSizeInBits(SlotVT);
+ unsigned DestSize = MVT::getSizeInBits(DestVT);
+
+ // Emit a store to the stack slot. Use a truncstore if the input value is
+ // later than DestVT.
+ SDOperand Store;
+ if (SrcSize > SlotSize)
+ Store = DAG.getTruncStore(DAG.getEntryNode(), SrcOp, FIPtr, NULL, 0,SlotVT);
+ else {
+ assert(SrcSize == SlotSize && "Invalid store");
+ Store = DAG.getStore(DAG.getEntryNode(), SrcOp, FIPtr, NULL, 0);
+ }
- // Emit a store to the stack slot.
- SDOperand Store = DAG.getStore(DAG.getEntryNode(), SrcOp, FIPtr, NULL, 0);
// Result is a load from the stack slot.
- return DAG.getLoad(DestVT, Store, FIPtr, NULL, 0);
+ if (SlotSize == DestSize)
+ return DAG.getLoad(DestVT, Store, FIPtr, NULL, 0);
+
+ assert(SlotSize < DestSize && "Unknown extension!");
+ return DAG.getExtLoad(ISD::EXTLOAD, DestVT, Store, FIPtr, NULL, 0, SlotVT);
}
SDOperand SelectionDAGLegalize::ExpandSCALAR_TO_VECTOR(SDNode *Node) {
SDOperand SignSet = DAG.getSetCC(TLI.getSetCCResultTy(), Hi,
DAG.getConstant(0, Hi.getValueType()),
ISD::SETLT);
- SDOperand Zero = getIntPtrConstant(0), Four = getIntPtrConstant(4);
+ SDOperand Zero = DAG.getIntPtrConstant(0), Four = DAG.getIntPtrConstant(4);
SDOperand CstOffset = DAG.getNode(ISD::SELECT, Zero.getValueType(),
SignSet, Four, Zero);
uint64_t FF = 0x5f800000ULL;
if (Op0.getValueType() == MVT::i32) {
// simple 32-bit [signed|unsigned] integer to float/double expansion
- // get the stack frame index of a 8 byte buffer, pessimistically aligned
- MachineFunction &MF = DAG.getMachineFunction();
- const Type *F64Type = MVT::getTypeForValueType(MVT::f64);
- unsigned StackAlign =
- (unsigned)TLI.getTargetData()->getPrefTypeAlignment(F64Type);
- int SSFI = MF.getFrameInfo()->CreateStackObject(8, StackAlign);
- // get address of 8 byte buffer
- SDOperand StackSlot = DAG.getFrameIndex(SSFI, TLI.getPointerTy());
+ // Get the stack frame index of a 8 byte buffer.
+ SDOperand StackSlot = DAG.CreateStackTemporary(MVT::f64);
+
// word offset constant for Hi/Lo address computation
SDOperand WordOff = DAG.getConstant(sizeof(int), TLI.getPointerTy());
// set up Hi and Lo (into buffer) address based on endian
// do nothing
Result = Sub;
} else if (MVT::getSizeInBits(DestVT) < MVT::getSizeInBits(MVT::f64)) {
- Result = DAG.getNode(ISD::FP_ROUND, DestVT, Sub);
+ Result = DAG.getNode(ISD::FP_ROUND, DestVT, Sub,
+ DAG.getIntPtrConstant(0));
} else if (MVT::getSizeInBits(DestVT) > MVT::getSizeInBits(MVT::f64)) {
Result = DAG.getNode(ISD::FP_EXTEND, DestVT, Sub);
}
SDOperand SignSet = DAG.getSetCC(TLI.getSetCCResultTy(), Op0,
DAG.getConstant(0, Op0.getValueType()),
ISD::SETLT);
- SDOperand Zero = getIntPtrConstant(0), Four = getIntPtrConstant(4);
+ SDOperand Zero = DAG.getIntPtrConstant(0), Four = DAG.getIntPtrConstant(4);
SDOperand CstOffset = DAG.getNode(ISD::SELECT, Zero.getValueType(),
SignSet, Four, Zero);
// Increment the pointer to the other half.
unsigned IncrementSize = MVT::getSizeInBits(Lo.getValueType())/8;
Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
- getIntPtrConstant(IncrementSize));
+ DAG.getIntPtrConstant(IncrementSize));
SVOffset += IncrementSize;
Alignment = MinAlign(Alignment, IncrementSize);
Hi = DAG.getLoad(NVT, Ch, Ptr, LD->getSrcValue(), SVOffset,
// Turn this into a load/store pair by default.
if (Tmp.Val == 0)
- Tmp = ExpandBIT_CONVERT(VT, Node->getOperand(0));
+ Tmp = EmitStackConvert(Node->getOperand(0), VT, VT);
ExpandOp(Tmp, Lo, Hi);
break;
break;
case ISD::FADD:
- Lo = ExpandLibCall(TLI.getLibcallName(VT == MVT::f32 ? RTLIB::ADD_F32 :
- VT == MVT::f64 ? RTLIB::ADD_F64 :
- VT == MVT::ppcf128 ?
- RTLIB::ADD_PPCF128 :
- RTLIB::UNKNOWN_LIBCALL),
+ Lo = ExpandLibCall(TLI.getLibcallName(GetFPLibCall(VT, RTLIB::ADD_F32,
+ RTLIB::ADD_F64,
+ RTLIB::ADD_F80,
+ RTLIB::ADD_PPCF128)),
Node, false, Hi);
break;
case ISD::FSUB:
- Lo = ExpandLibCall(TLI.getLibcallName(VT == MVT::f32 ? RTLIB::SUB_F32 :
- VT == MVT::f64 ? RTLIB::SUB_F64 :
- VT == MVT::ppcf128 ?
- RTLIB::SUB_PPCF128 :
- RTLIB::UNKNOWN_LIBCALL),
+ Lo = ExpandLibCall(TLI.getLibcallName(GetFPLibCall(VT, RTLIB::SUB_F32,
+ RTLIB::SUB_F64,
+ RTLIB::SUB_F80,
+ RTLIB::SUB_PPCF128)),
Node, false, Hi);
break;
case ISD::FMUL:
- Lo = ExpandLibCall(TLI.getLibcallName(VT == MVT::f32 ? RTLIB::MUL_F32 :
- VT == MVT::f64 ? RTLIB::MUL_F64 :
- VT == MVT::ppcf128 ?
- RTLIB::MUL_PPCF128 :
- RTLIB::UNKNOWN_LIBCALL),
+ Lo = ExpandLibCall(TLI.getLibcallName(GetFPLibCall(VT, RTLIB::MUL_F32,
+ RTLIB::MUL_F64,
+ RTLIB::MUL_F80,
+ RTLIB::MUL_PPCF128)),
Node, false, Hi);
break;
case ISD::FDIV:
- Lo = ExpandLibCall(TLI.getLibcallName(VT == MVT::f32 ? RTLIB::DIV_F32 :
- VT == MVT::f64 ? RTLIB::DIV_F64 :
- VT == MVT::ppcf128 ?
- RTLIB::DIV_PPCF128 :
- RTLIB::UNKNOWN_LIBCALL),
+ Lo = ExpandLibCall(TLI.getLibcallName(GetFPLibCall(VT, RTLIB::DIV_F32,
+ RTLIB::DIV_F64,
+ RTLIB::DIV_F80,
+ RTLIB::DIV_PPCF128)),
Node, false, Hi);
break;
case ISD::FP_EXTEND:
Lo = ExpandLibCall(TLI.getLibcallName(RTLIB::FPROUND_F64_F32),Node,true,Hi);
break;
case ISD::FPOWI:
- Lo = ExpandLibCall(TLI.getLibcallName((VT == MVT::f32) ? RTLIB::POWI_F32 :
- (VT == MVT::f64) ? RTLIB::POWI_F64 :
- (VT == MVT::f80) ? RTLIB::POWI_F80 :
- (VT == MVT::ppcf128) ?
- RTLIB::POWI_PPCF128 :
- RTLIB::UNKNOWN_LIBCALL),
+ Lo = ExpandLibCall(TLI.getLibcallName(GetFPLibCall(VT, RTLIB::POWI_F32,
+ RTLIB::POWI_F64,
+ RTLIB::POWI_F80,
+ RTLIB::POWI_PPCF128)),
Node, false, Hi);
break;
case ISD::FSQRT:
RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
switch(Node->getOpcode()) {
case ISD::FSQRT:
- LC = (VT == MVT::f32) ? RTLIB::SQRT_F32 :
- (VT == MVT::f64) ? RTLIB::SQRT_F64 :
- (VT == MVT::f80) ? RTLIB::SQRT_F80 :
- (VT == MVT::ppcf128) ? RTLIB::SQRT_PPCF128 :
- RTLIB::UNKNOWN_LIBCALL;
+ LC = GetFPLibCall(VT, RTLIB::SQRT_F32, RTLIB::SQRT_F64,
+ RTLIB::SQRT_F80, RTLIB::SQRT_PPCF128);
break;
case ISD::FSIN:
- LC = (VT == MVT::f32) ? RTLIB::SIN_F32 : RTLIB::SIN_F64;
+ LC = GetFPLibCall(VT, RTLIB::SIN_F32, RTLIB::SIN_F64,
+ RTLIB::SIN_F80, RTLIB::SIN_PPCF128);
break;
case ISD::FCOS:
- LC = (VT == MVT::f32) ? RTLIB::COS_F32 : RTLIB::COS_F64;
+ LC = GetFPLibCall(VT, RTLIB::COS_F32, RTLIB::COS_F64,
+ RTLIB::COS_F80, RTLIB::COS_PPCF128);
break;
default: assert(0 && "Unreachable!");
}
Lo = DAG.getLoad(NewVT_Lo, Ch, Ptr, SV, SVOffset, isVolatile, Alignment);
unsigned IncrementSize = NewNumElts_Lo * MVT::getSizeInBits(NewEltVT)/8;
Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
- getIntPtrConstant(IncrementSize));
+ DAG.getIntPtrConstant(IncrementSize));
SVOffset += IncrementSize;
Alignment = MinAlign(Alignment, IncrementSize);
Hi = DAG.getLoad(NewVT_Hi, Ch, Ptr, SV, SVOffset, isVolatile, Alignment);