#include "llvm/CallingConv.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
-#include "llvm/Support/Alignment.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/MathExtras.h"
// The only option for this is to custom lower it.
Tmp3 = TLI.LowerOperation(Result.getValue(0), DAG);
assert(Tmp3.Val && "Target didn't custom lower this node!");
- assert(Tmp3.Val->getNumValues() == Result.Val->getNumValues() &&
+
+ // The number of incoming and outgoing values should match; unless the final
+ // outgoing value is a flag.
+ assert((Tmp3.Val->getNumValues() == Result.Val->getNumValues() ||
+ (Tmp3.Val->getNumValues() == Result.Val->getNumValues() + 1 &&
+ Tmp3.Val->getValueType(Tmp3.Val->getNumValues() - 1) ==
+ MVT::Flag)) &&
"Lowering call/formal_arguments produced unexpected # results!");
// Since CALL/FORMAL_ARGUMENTS nodes produce multiple values, make sure to
// remember that we legalized all of them, so it doesn't get relegalized.
for (unsigned i = 0, e = Tmp3.Val->getNumValues(); i != e; ++i) {
+ if (Tmp3.Val->getValueType(i) == MVT::Flag)
+ continue;
Tmp1 = LegalizeOp(Tmp3.getValue(i));
if (Op.ResNo == i)
Tmp2 = Tmp1;
assert(SPReg && "Target cannot require DYNAMIC_STACKALLOC expansion and"
" not tell us which reg is the stack pointer!");
SDOperand Chain = Tmp1.getOperand(0);
+
+ // Chain the dynamic stack allocation so that it doesn't modify the stack
+ // pointer when other instructions are using the stack.
+ Chain = DAG.getCALLSEQ_START(Chain,
+ DAG.getConstant(0, TLI.getPointerTy()));
+
SDOperand Size = Tmp2.getOperand(1);
SDOperand SP = DAG.getCopyFromReg(Chain, SPReg, VT);
Chain = SP.getValue(1);
SP = DAG.getNode(ISD::AND, VT, SP,
DAG.getConstant(-(uint64_t)Align, VT));
Tmp1 = DAG.getNode(ISD::SUB, VT, SP, Size); // Value
- Tmp2 = DAG.getCopyToReg(Chain, SPReg, Tmp1); // Output chain
+ Chain = DAG.getCopyToReg(Chain, SPReg, Tmp1); // Output chain
+
+ Tmp2 =
+ DAG.getCALLSEQ_END(Chain,
+ DAG.getConstant(0, TLI.getPointerTy()),
+ DAG.getConstant(0, TLI.getPointerTy()),
+ SDOperand());
+
Tmp1 = LegalizeOp(Tmp1);
Tmp2 = LegalizeOp(Tmp2);
break;
case 8: LD = DAG.getLoad(MVT::i64, Chain, Addr, NULL, 0); break;
}
+ Addr = LD;
if (TLI.getTargetMachine().getRelocationModel() == Reloc::PIC_) {
// For PIC, the sequence is:
// BRIND(load(Jumptable + index) + RelocBase)
- // RelocBase is the JumpTable on PPC and X86, GOT on Alpha
- SDOperand Reloc;
- if (TLI.usesGlobalOffsetTable())
- Reloc = DAG.getNode(ISD::GLOBAL_OFFSET_TABLE, PTy);
- else
- Reloc = Table;
- Addr = (PTy != MVT::i32) ? DAG.getNode(ISD::SIGN_EXTEND, PTy, LD) : LD;
- Addr = DAG.getNode(ISD::ADD, PTy, Addr, Reloc);
- Result = DAG.getNode(ISD::BRIND, MVT::Other, LD.getValue(1), Addr);
- } else {
- Result = DAG.getNode(ISD::BRIND, MVT::Other, LD.getValue(1), LD);
+ // RelocBase can be JumpTable, GOT or some sort of global base.
+ if (PTy != MVT::i32)
+ Addr = DAG.getNode(ISD::SIGN_EXTEND, PTy, Addr);
+ Addr = DAG.getNode(ISD::ADD, PTy, Addr,
+ TLI.getPICJumpTableRelocBase(Table, DAG));
}
+ Result = DAG.getNode(ISD::BRIND, MVT::Other, LD.getValue(1), Addr);
}
}
break;
break;
} else {
SplitVectorOp(Node->getOperand(1), Lo, Hi);
- IncrementSize = NumElems/2 * MVT::getSizeInBits(EVT)/8;
+ IncrementSize = MVT::getVectorNumElements(Lo.Val->getValueType(0)) *
+ MVT::getSizeInBits(EVT)/8;
}
} else {
ExpandOp(Node->getOperand(1), Lo, Hi);
SDNode *Node = Op.Val;
unsigned NumElements = MVT::getVectorNumElements(Op.getValueType());
assert(NumElements > 1 && "Cannot split a single element vector!");
- unsigned NewNumElts = NumElements/2;
+
MVT::ValueType NewEltVT = MVT::getVectorElementType(Op.getValueType());
- MVT::ValueType NewVT = MVT::getVectorType(NewEltVT, NewNumElts);
-
+
+ unsigned NewNumElts_Lo = 1 << Log2_32(NumElements-1);
+ unsigned NewNumElts_Hi = NumElements - NewNumElts_Lo;
+
+ MVT::ValueType NewVT_Lo = MVT::getVectorType(NewEltVT, NewNumElts_Lo);
+ MVT::ValueType NewVT_Hi = MVT::getVectorType(NewEltVT, NewNumElts_Hi);
+
// See if we already split it.
std::map<SDOperand, std::pair<SDOperand, SDOperand> >::iterator I
= SplitNodes.find(Op);
SplitVectorOp(Node->getOperand(0), Lo, Hi);
unsigned Index = cast<ConstantSDNode>(Node->getOperand(2))->getValue();
SDOperand ScalarOp = Node->getOperand(1);
- if (Index < NewNumElts)
- Lo = DAG.getNode(ISD::INSERT_VECTOR_ELT, NewVT, Lo, ScalarOp,
+ if (Index < NewNumElts_Lo)
+ Lo = DAG.getNode(ISD::INSERT_VECTOR_ELT, NewVT_Lo, Lo, ScalarOp,
DAG.getConstant(Index, TLI.getPointerTy()));
else
- Hi = DAG.getNode(ISD::INSERT_VECTOR_ELT, NewVT, Hi, ScalarOp,
- DAG.getConstant(Index - NewNumElts, TLI.getPointerTy()));
+ Hi = DAG.getNode(ISD::INSERT_VECTOR_ELT, NewVT_Hi, Hi, ScalarOp,
+ DAG.getConstant(Index - NewNumElts_Lo,
+ TLI.getPointerTy()));
break;
}
case ISD::BUILD_VECTOR: {
SmallVector<SDOperand, 8> LoOps(Node->op_begin(),
- Node->op_begin()+NewNumElts);
- Lo = DAG.getNode(ISD::BUILD_VECTOR, NewVT, &LoOps[0], LoOps.size());
+ Node->op_begin()+NewNumElts_Lo);
+ Lo = DAG.getNode(ISD::BUILD_VECTOR, NewVT_Lo, &LoOps[0], LoOps.size());
- SmallVector<SDOperand, 8> HiOps(Node->op_begin()+NewNumElts,
+ SmallVector<SDOperand, 8> HiOps(Node->op_begin()+NewNumElts_Lo,
Node->op_end());
- Hi = DAG.getNode(ISD::BUILD_VECTOR, NewVT, &HiOps[0], HiOps.size());
+ Hi = DAG.getNode(ISD::BUILD_VECTOR, NewVT_Hi, &HiOps[0], HiOps.size());
break;
}
case ISD::CONCAT_VECTORS: {
+ // FIXME: Handle non-power-of-two vectors?
unsigned NewNumSubvectors = Node->getNumOperands() / 2;
if (NewNumSubvectors == 1) {
Lo = Node->getOperand(0);
} else {
SmallVector<SDOperand, 8> LoOps(Node->op_begin(),
Node->op_begin()+NewNumSubvectors);
- Lo = DAG.getNode(ISD::CONCAT_VECTORS, NewVT, &LoOps[0], LoOps.size());
+ Lo = DAG.getNode(ISD::CONCAT_VECTORS, NewVT_Lo, &LoOps[0], LoOps.size());
SmallVector<SDOperand, 8> HiOps(Node->op_begin()+NewNumSubvectors,
Node->op_end());
- Hi = DAG.getNode(ISD::CONCAT_VECTORS, NewVT, &HiOps[0], HiOps.size());
+ Hi = DAG.getNode(ISD::CONCAT_VECTORS, NewVT_Hi, &HiOps[0], HiOps.size());
}
break;
}
// 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);
+ Lo = DAG.getNode(Node->getOpcode(), NewVT_Lo, CL, LL, RL);
+ Hi = DAG.getNode(Node->getOpcode(), NewVT_Hi, 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);
+ Lo = DAG.getNode(Node->getOpcode(), NewVT_Lo, Cond, LL, RL);
+ Hi = DAG.getNode(Node->getOpcode(), NewVT_Hi, Cond, LH, RH);
}
break;
}
SplitVectorOp(Node->getOperand(0), LL, LH);
SplitVectorOp(Node->getOperand(1), RL, RH);
- Lo = DAG.getNode(Node->getOpcode(), NewVT, LL, RL);
- Hi = DAG.getNode(Node->getOpcode(), NewVT, LH, RH);
+ Lo = DAG.getNode(Node->getOpcode(), NewVT_Lo, LL, RL);
+ Hi = DAG.getNode(Node->getOpcode(), NewVT_Hi, LH, RH);
break;
}
case ISD::FPOWI: {
SDOperand L, H;
SplitVectorOp(Node->getOperand(0), L, H);
- Lo = DAG.getNode(Node->getOpcode(), NewVT, L, Node->getOperand(1));
- Hi = DAG.getNode(Node->getOpcode(), NewVT, H, Node->getOperand(1));
+ Lo = DAG.getNode(Node->getOpcode(), NewVT_Lo, L, Node->getOperand(1));
+ Hi = DAG.getNode(Node->getOpcode(), NewVT_Hi, H, Node->getOperand(1));
break;
}
case ISD::CTTZ:
SDOperand L, H;
SplitVectorOp(Node->getOperand(0), L, H);
- Lo = DAG.getNode(Node->getOpcode(), NewVT, L);
- Hi = DAG.getNode(Node->getOpcode(), NewVT, H);
+ Lo = DAG.getNode(Node->getOpcode(), NewVT_Lo, L);
+ Hi = DAG.getNode(Node->getOpcode(), NewVT_Hi, H);
break;
}
case ISD::LOAD: {
unsigned Alignment = LD->getAlignment();
bool isVolatile = LD->isVolatile();
- Lo = DAG.getLoad(NewVT, Ch, Ptr, SV, SVOffset, isVolatile, Alignment);
- unsigned IncrementSize = NewNumElts * MVT::getSizeInBits(NewEltVT)/8;
+ 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));
SVOffset += IncrementSize;
Alignment = MinAlign(Alignment, IncrementSize);
- Hi = DAG.getLoad(NewVT, Ch, Ptr, SV, SVOffset, isVolatile, Alignment);
+ Hi = DAG.getLoad(NewVT_Hi, Ch, Ptr, SV, SVOffset, isVolatile, Alignment);
// Build a factor node to remember that this load is independent of the
// other one.
}
// Split the vector and convert each of the pieces now.
SplitVectorOp(InOp, Lo, Hi);
- Lo = DAG.getNode(ISD::BIT_CONVERT, NewVT, Lo);
- Hi = DAG.getNode(ISD::BIT_CONVERT, NewVT, Hi);
+ Lo = DAG.getNode(ISD::BIT_CONVERT, NewVT_Lo, Lo);
+ Hi = DAG.getNode(ISD::BIT_CONVERT, NewVT_Hi, Hi);
break;
}
}