#include "llvm/CallingConv.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
-#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/Alignment.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/Support/MathExtras.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/SmallPtrSet.h"
void LegalizeSetCCOperands(SDOperand &LHS, SDOperand &RHS, SDOperand &CC);
- SDOperand CreateStackTemporary(MVT::ValueType VT);
-
SDOperand ExpandLibCall(const char *Name, SDNode *Node, bool isSigned,
SDOperand &Hi);
SDOperand ExpandIntToFP(bool isSigned, MVT::ValueType DestTy,
ST->isVolatile(), Alignment);
Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
DAG.getConstant(IncrementSize, TLI.getPointerTy()));
+ Alignment = MinAlign(Alignment, IncrementSize);
Store2 = DAG.getTruncStore(Chain, TLI.isLittleEndian()?Hi:Lo, Ptr,
ST->getSrcValue(), SVOffset + IncrementSize,
NewStoredVT, ST->isVolatile(), Alignment);
DAG.getConstant(IncrementSize, TLI.getPointerTy()));
Hi = DAG.getExtLoad(HiExtType, VT, Chain, Ptr, LD->getSrcValue(),
SVOffset + IncrementSize, NewLoadedVT, LD->isVolatile(),
- Alignment);
+ MinAlign(Alignment, IncrementSize));
} else {
Hi = DAG.getExtLoad(HiExtType, VT, Chain, Ptr, LD->getSrcValue(), SVOffset,
NewLoadedVT,LD->isVolatile(), Alignment);
DAG.getConstant(IncrementSize, TLI.getPointerTy()));
Lo = DAG.getExtLoad(ISD::ZEXTLOAD, VT, Chain, Ptr, LD->getSrcValue(),
SVOffset + IncrementSize, NewLoadedVT, LD->isVolatile(),
- Alignment);
+ MinAlign(Alignment, IncrementSize));
}
// aggregate the two parts
case ISD::STRING:
case ISD::CONDCODE:
// Primitives must all be legal.
- assert(TLI.isOperationLegal(Node->getValueType(0), Node->getValueType(0)) &&
+ assert(TLI.isOperationLegal(Node->getOpcode(), Node->getValueType(0)) &&
"This must be legal!");
break;
default:
MVT::ValueType EltVT = Tmp2.getValueType();
MVT::ValueType IdxVT = Tmp3.getValueType();
MVT::ValueType PtrVT = TLI.getPointerTy();
- SDOperand StackPtr = CreateStackTemporary(VT);
+ SDOperand StackPtr = DAG.CreateStackTemporary(VT);
// Store the vector.
SDOperand Ch = DAG.getStore(DAG.getEntryNode(), Tmp1, StackPtr, NULL, 0);
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);
+ Tmp1 = Result.getValue(0);
+ Tmp2 = Result.getValue(1);
break;
case TargetLowering::Custom:
isCustom = true;
Result = LegalizeOp(Result);
} else {
SDNode *InVal = Tmp2.Val;
- unsigned NumElems = MVT::getVectorNumElements(InVal->getValueType(0));
- MVT::ValueType EVT = MVT::getVectorElementType(InVal->getValueType(0));
+ int InIx = Tmp2.ResNo;
+ unsigned NumElems = MVT::getVectorNumElements(InVal->getValueType(InIx));
+ MVT::ValueType EVT = MVT::getVectorElementType(InVal->getValueType(InIx));
// Figure out if there is a simple type corresponding to this Vector
// type. If so, convert to the vector type.
// probably means that we need to integrate dag combiner and legalizer
// together.
// We generally can't do this one for long doubles.
- if (ConstantFPSDNode *CFP =dyn_cast<ConstantFPSDNode>(ST->getValue())) {
- if (CFP->getValueType(0) == MVT::f32) {
+ if (ConstantFPSDNode *CFP = dyn_cast<ConstantFPSDNode>(ST->getValue())) {
+ if (CFP->getValueType(0) == MVT::f32 &&
+ getTypeAction(MVT::i32) == Legal) {
Tmp3 = DAG.getConstant((uint32_t)CFP->getValueAPF().
convertToAPInt().getZExtValue(),
MVT::i32);
SVOffset, isVolatile, Alignment);
break;
} else if (CFP->getValueType(0) == MVT::f64) {
- Tmp3 = DAG.getConstant(CFP->getValueAPF().convertToAPInt().
- getZExtValue(), MVT::i64);
- Result = DAG.getStore(Tmp1, Tmp3, Tmp2, ST->getSrcValue(),
- SVOffset, isVolatile, Alignment);
- break;
+ // If this target supports 64-bit registers, do a single 64-bit store.
+ if (getTypeAction(MVT::i64) == Legal) {
+ Tmp3 = DAG.getConstant(CFP->getValueAPF().convertToAPInt().
+ getZExtValue(), MVT::i64);
+ Result = DAG.getStore(Tmp1, Tmp3, Tmp2, ST->getSrcValue(),
+ SVOffset, isVolatile, Alignment);
+ break;
+ } else if (getTypeAction(MVT::i32) == Legal) {
+ // Otherwise, if the target supports 32-bit registers, use 2 32-bit
+ // stores. If the target supports neither 32- nor 64-bits, this
+ // xform is certainly not worth it.
+ uint64_t IntVal =CFP->getValueAPF().convertToAPInt().getZExtValue();
+ SDOperand Lo = DAG.getConstant(uint32_t(IntVal), MVT::i32);
+ SDOperand Hi = DAG.getConstant(uint32_t(IntVal >>32), MVT::i32);
+ if (!TLI.isLittleEndian()) std::swap(Lo, Hi);
+
+ Lo = DAG.getStore(Tmp1, Lo, Tmp2, ST->getSrcValue(),
+ SVOffset, isVolatile, Alignment);
+ Tmp2 = DAG.getNode(ISD::ADD, Tmp2.getValueType(), Tmp2,
+ getIntPtrConstant(4));
+ Hi = DAG.getStore(Tmp1, Hi, Tmp2, ST->getSrcValue(), SVOffset+4,
+ isVolatile, MinAlign(Alignment, 4U));
+
+ Result = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi);
+ break;
+ }
}
}
// in the high half of the vector.
if (MVT::isVector(ST->getValue().getValueType())) {
SDNode *InVal = ST->getValue().Val;
- unsigned NumElems = MVT::getVectorNumElements(InVal->getValueType(0));
- MVT::ValueType EVT = MVT::getVectorElementType(InVal->getValueType(0));
+ int InIx = ST->getValue().ResNo;
+ unsigned NumElems = MVT::getVectorNumElements(InVal->getValueType(InIx));
+ MVT::ValueType EVT = MVT::getVectorElementType(InVal->getValueType(InIx));
// Figure out if there is a simple type corresponding to this Vector
// type. If so, convert to the vector type.
assert(isTypeLegal(Tmp2.getValueType()) &&
"Pointers must be legal!");
SVOffset += IncrementSize;
- if (Alignment > IncrementSize)
- Alignment = IncrementSize;
+ Alignment = MinAlign(Alignment, IncrementSize);
Hi = DAG.getStore(Tmp1, Hi, Tmp2, ST->getSrcValue(),
SVOffset, isVolatile, Alignment);
Result = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi);
break;
}
+ SDOperand Tmp6;
+ switch (getTypeAction(Node->getOperand(5).getValueType())) { // bool
+ case Expand: assert(0 && "Cannot expand this yet!");
+ case Legal:
+ Tmp6 = LegalizeOp(Node->getOperand(5));
+ break;
+ case Promote:
+ Tmp6 = PromoteOp(Node->getOperand(5));
+ break;
+ }
+
switch (TLI.getOperationAction(Node->getOpcode(), MVT::Other)) {
default: assert(0 && "This action not implemented for this operation!");
case TargetLowering::Custom:
isCustom = true;
// FALLTHROUGH
- case TargetLowering::Legal:
- Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Tmp3, Tmp4, Tmp5);
+ case TargetLowering::Legal: {
+ SDOperand Ops[] = { Tmp1, Tmp2, Tmp3, Tmp4, Tmp5, Tmp6 };
+ Result = DAG.UpdateNodeOperands(Result, Ops, 6);
if (isCustom) {
Tmp1 = TLI.LowerOperation(Result, DAG);
if (Tmp1.Val) Result = Tmp1;
}
break;
+ }
case TargetLowering::Expand: {
// Otherwise, the target does not support this operation. Lower the
// operation to an explicit libcall as appropriate.
case ISD::UDIVREM:
// These nodes will only be produced by target-specific lowering, so
// they shouldn't be here if they aren't legal.
- assert(TLI.isOperationLegal(Node->getValueType(0), Node->getValueType(0)) &&
+ assert(TLI.isOperationLegal(Node->getOpcode(), Node->getValueType(0)) &&
"This must be legal!");
Tmp1 = LegalizeOp(Node->getOperand(0)); // LHS
// 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.
SDNode *InVal = Node->getOperand(0).Val;
- unsigned NumElems = MVT::getVectorNumElements(InVal->getValueType(0));
- MVT::ValueType EVT = MVT::getVectorElementType(InVal->getValueType(0));
+ int InIx = Node->getOperand(0).ResNo;
+ unsigned NumElems = MVT::getVectorNumElements(InVal->getValueType(InIx));
+ MVT::ValueType EVT = MVT::getVectorElementType(InVal->getValueType(InIx));
// Figure out if there is a simple type corresponding to this Vector
// type. If so, convert to the vector type.
} else {
Result = DAG.getTruncStore(DAG.getEntryNode(), Node->getOperand(0),
StackSlot, NULL, 0, newVT);
- Result = DAG.getLoad(newVT, Result, StackSlot, NULL, 0, newVT);
+ Result = DAG.getLoad(newVT, Result, StackSlot, NULL, 0);
}
break;
}
} else {
// Store the value to a temporary stack slot, then LOAD the scalar
// element back out.
- SDOperand StackPtr = CreateStackTemporary(Vec.getValueType());
+ SDOperand StackPtr = DAG.CreateStackTemporary(Vec.getValueType());
SDOperand Ch = DAG.getStore(DAG.getEntryNode(), Vec, StackPtr, NULL, 0);
// Add the offset to the index.
unsigned EltSize = MVT::getSizeInBits(Op.getValueType())/8;
Idx = DAG.getNode(ISD::MUL, Idx.getValueType(), Idx,
DAG.getConstant(EltSize, Idx.getValueType()));
+
+ if (MVT::getSizeInBits(Idx.getValueType()) >
+ MVT::getSizeInBits(TLI.getPointerTy()))
+ Idx = DAG.getNode(ISD::TRUNCATE, TLI.getPointerTy(), Idx);
+ else
+ Idx = DAG.getNode(ISD::ZERO_EXTEND, TLI.getPointerTy(), Idx);
+
StackPtr = DAG.getNode(ISD::ADD, Idx.getValueType(), Idx, StackPtr);
Op = DAG.getLoad(Op.getValueType(), Ch, StackPtr, NULL, 0);
Tmp2 = TLI.SimplifySetCC(TLI.getSetCCResultTy(), LHSHi, RHSHi,
CCCode, false, DagCombineInfo);
if (!Tmp2.Val)
- Tmp2 = DAG.getNode(ISD::SETCC, TLI.getSetCCResultTy(), LHSHi, RHSHi, CC);
+ Tmp2 = DAG.getNode(ISD::SETCC, TLI.getSetCCResultTy(), LHSHi, RHSHi,CC);
ConstantSDNode *Tmp1C = dyn_cast<ConstantSDNode>(Tmp1.Val);
ConstantSDNode *Tmp2C = dyn_cast<ConstantSDNode>(Tmp2.Val);
SDOperand SelectionDAGLegalize::ExpandBIT_CONVERT(MVT::ValueType DestVT,
SDOperand SrcOp) {
// Create the stack frame object.
- SDOperand FIPtr = CreateStackTemporary(DestVT);
+ SDOperand FIPtr = DAG.CreateStackTemporary(DestVT);
// Emit a store to the stack slot.
SDOperand Store = DAG.getStore(DAG.getEntryNode(), SrcOp, FIPtr, NULL, 0);
SDOperand SelectionDAGLegalize::ExpandSCALAR_TO_VECTOR(SDNode *Node) {
// Create a vector sized/aligned stack slot, store the value to element #0,
// then load the whole vector back out.
- SDOperand StackPtr = CreateStackTemporary(Node->getValueType(0));
+ SDOperand StackPtr = DAG.CreateStackTemporary(Node->getValueType(0));
SDOperand Ch = DAG.getStore(DAG.getEntryNode(), Node->getOperand(0), StackPtr,
NULL, 0);
return DAG.getLoad(Node->getValueType(0), Ch, StackPtr, NULL, 0);
// the result as a vector.
MVT::ValueType VT = Node->getValueType(0);
// Create the stack frame object.
- SDOperand FIPtr = CreateStackTemporary(VT);
+ SDOperand FIPtr = DAG.CreateStackTemporary(VT);
// Emit a store of each element to the stack slot.
SmallVector<SDOperand, 8> Stores;
return DAG.getLoad(VT, StoreChain, FIPtr, NULL, 0);
}
-/// CreateStackTemporary - Create a stack temporary, suitable for holding the
-/// specified value type.
-SDOperand SelectionDAGLegalize::CreateStackTemporary(MVT::ValueType VT) {
- MachineFrameInfo *FrameInfo = DAG.getMachineFunction().getFrameInfo();
- unsigned ByteSize = MVT::getSizeInBits(VT)/8;
- const Type *Ty = MVT::getTypeForValueType(VT);
- unsigned StackAlign = (unsigned)TLI.getTargetData()->getPrefTypeAlignment(Ty);
- int FrameIdx = FrameInfo->CreateStackObject(ByteSize, StackAlign);
- return DAG.getFrameIndex(FrameIdx, TLI.getPointerTy());
-}
-
void SelectionDAGLegalize::ExpandShiftParts(unsigned NodeOp,
SDOperand Op, SDOperand Amt,
SDOperand &Lo, SDOperand &Hi) {
unsigned VTBits = MVT::getSizeInBits(Op.getValueType());
unsigned NVTBits = MVT::getSizeInBits(NVT);
- // Handle the case when Amt is an immediate. Other cases are currently broken
- // and are disabled.
+ // Handle the case when Amt is an immediate.
if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Amt.Val)) {
unsigned Cst = CN->getValue();
// Expand the incoming operand to be shifted, so that we have its parts
Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
getIntPtrConstant(IncrementSize));
SVOffset += IncrementSize;
- if (Alignment > IncrementSize)
- Alignment = IncrementSize;
+ Alignment = MinAlign(Alignment, IncrementSize);
Hi = DAG.getLoad(NVT, Ch, Ptr, LD->getSrcValue(), SVOffset,
isVolatile, Alignment);
} else {
MVT::ValueType EVT = LD->getLoadedVT();
- if (VT == MVT::f64 && EVT == MVT::f32) {
+ if ((VT == MVT::f64 && EVT == MVT::f32) ||
+ (VT == MVT::ppcf128 && (EVT==MVT::f64 || EVT==MVT::f32))) {
// f64 = EXTLOAD f32 should expand to LOAD, FP_EXTEND
SDOperand Load = DAG.getLoad(EVT, Ch, Ptr, LD->getSrcValue(),
SVOffset, isVolatile, Alignment);
Hi = DAG.getNode(ISD::MULHU, NVT, LL, RL);
break;
}
- break;
}
if (LHSSB > BitSize && RHSSB > BitSize) {
// The input values are both sign-extended.
Hi = DAG.getNode(ISD::ADD, NVT, Hi, LH);
break;
}
+ if (HasMULHU) {
+ Lo = DAG.getNode(ISD::MUL, NVT, LL, RL);
+ Hi = DAG.getNode(ISD::MULHU, NVT, LL, RL);
+ RH = DAG.getNode(ISD::MUL, NVT, LL, RH);
+ LH = DAG.getNode(ISD::MUL, NVT, LH, RL);
+ Hi = DAG.getNode(ISD::ADD, NVT, Hi, RH);
+ Hi = DAG.getNode(ISD::ADD, NVT, Hi, LH);
+ break;
+ }
}
// If nothing else, we can make a libcall.
break;
}
case ISD::FABS: {
+ if (VT == MVT::ppcf128) {
+ SDOperand Tmp;
+ ExpandOp(Node->getOperand(0), Lo, Tmp);
+ Hi = DAG.getNode(ISD::FABS, NVT, Tmp);
+ // lo = hi==fabs(hi) ? lo : -lo;
+ Lo = DAG.getNode(ISD::SELECT_CC, NVT, Hi, Tmp,
+ Lo, DAG.getNode(ISD::FNEG, NVT, Lo),
+ DAG.getCondCode(ISD::SETEQ));
+ break;
+ }
SDOperand Mask = (VT == MVT::f64)
? DAG.getConstantFP(BitsToDouble(~(1ULL << 63)), VT)
: DAG.getConstantFP(BitsToFloat(~(1U << 31)), VT);
break;
}
case ISD::FNEG: {
+ if (VT == MVT::ppcf128) {
+ ExpandOp(Node->getOperand(0), Lo, Hi);
+ Lo = DAG.getNode(ISD::FNEG, MVT::f64, Lo);
+ Hi = DAG.getNode(ISD::FNEG, MVT::f64, Hi);
+ break;
+ }
SDOperand Mask = (VT == MVT::f64)
? DAG.getConstantFP(BitsToDouble(1ULL << 63), VT)
: DAG.getConstantFP(BitsToFloat(1U << 31), VT);
case ISD::UINT_TO_FP: {
bool isSigned = Node->getOpcode() == ISD::SINT_TO_FP;
MVT::ValueType SrcVT = Node->getOperand(0).getValueType();
- if (VT == MVT::ppcf128) {
+ if (VT == MVT::ppcf128 && SrcVT != MVT::i64) {
static uint64_t zero = 0;
if (isSigned) {
Hi = LegalizeOp(DAG.getNode(ISD::SINT_TO_FP, MVT::f64,
Node->getOperand(0)));
Lo = DAG.getConstantFP(APFloat(APInt(64, 1, &zero)), MVT::f64);
Hi = DAG.getNode(ISD::BUILD_PAIR, VT, Lo, Hi);
+ // X>=0 ? {(f64)x, 0} : {(f64)x, 0} + 2^32
ExpandOp(DAG.getNode(ISD::SELECT_CC, MVT::ppcf128, Node->getOperand(0),
DAG.getConstant(0, MVT::i32),
DAG.getNode(ISD::FADD, MVT::ppcf128, Hi,
}
break;
}
+ if (VT == MVT::ppcf128 && SrcVT == MVT::i64 && !isSigned) {
+ // si64->ppcf128 done by libcall, below
+ static uint64_t TwoE64[] = { 0x43f0000000000000LL, 0 };
+ ExpandOp(DAG.getNode(ISD::SINT_TO_FP, MVT::ppcf128, Node->getOperand(0)),
+ Lo, Hi);
+ Hi = DAG.getNode(ISD::BUILD_PAIR, VT, Lo, Hi);
+ // x>=0 ? (ppcf128)(i64)x : (ppcf128)(i64)x + 2^64
+ ExpandOp(DAG.getNode(ISD::SELECT_CC, MVT::ppcf128, Node->getOperand(0),
+ DAG.getConstant(0, MVT::i64),
+ DAG.getNode(ISD::FADD, MVT::ppcf128, Hi,
+ DAG.getConstantFP(
+ APFloat(APInt(128, 2, TwoE64)),
+ MVT::ppcf128)),
+ Hi,
+ DAG.getCondCode(ISD::SETLT)),
+ Lo, Hi);
+ break;
+ }
RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
if (Node->getOperand(0).getValueType() == MVT::i64) {
if (VT == MVT::f32)
}
break;
}
+ case ISD::SELECT: {
+ SDOperand Cond = Node->getOperand(0);
+
+ SDOperand LL, LH, RL, RH;
+ SplitVectorOp(Node->getOperand(1), LL, LH);
+ SplitVectorOp(Node->getOperand(2), RL, RH);
+
+ if (MVT::isVector(Cond.getValueType())) {
+ // Handle a vector merge.
+ SDOperand CL, CH;
+ SplitVectorOp(Cond, CL, CH);
+ Lo = DAG.getNode(Node->getOpcode(), NewVT, CL, LL, RL);
+ Hi = DAG.getNode(Node->getOpcode(), NewVT, CH, LH, RH);
+ } else {
+ // Handle a simple select with vector operands.
+ Lo = DAG.getNode(Node->getOpcode(), NewVT, Cond, LL, RL);
+ Hi = DAG.getNode(Node->getOpcode(), NewVT, Cond, LH, RH);
+ }
+ break;
+ }
case ISD::ADD:
case ISD::SUB:
case ISD::MUL:
Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
getIntPtrConstant(IncrementSize));
SVOffset += IncrementSize;
- if (Alignment > IncrementSize)
- Alignment = IncrementSize;
+ Alignment = MinAlign(Alignment, IncrementSize);
Hi = DAG.getLoad(NewVT, Ch, Ptr, SV, SVOffset, isVolatile, Alignment);
// Build a factor node to remember that this load is independent of the
// The input is a scalar or single-element vector.
// Lower to a store/load so that it can be split.
// FIXME: this could be improved probably.
- SDOperand Ptr = CreateStackTemporary(InOp.getValueType());
+ SDOperand Ptr = DAG.CreateStackTemporary(InOp.getValueType());
SDOperand St = DAG.getStore(DAG.getEntryNode(),
InOp, Ptr, NULL, 0);
NewVT,
ScalarizeVectorOp(Node->getOperand(0)));
break;
+ case ISD::FPOWI:
+ Result = DAG.getNode(Node->getOpcode(),
+ NewVT,
+ ScalarizeVectorOp(Node->getOperand(0)),
+ Node->getOperand(1));
+ break;
case ISD::LOAD: {
LoadSDNode *LD = cast<LoadSDNode>(Node);
SDOperand Ch = LegalizeOp(LD->getChain()); // Legalize the chain.