aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNate Begeman <natebegeman@mac.com>2006-01-25 18:21:52 +0000
committerNate Begeman <natebegeman@mac.com>2006-01-25 18:21:52 +0000
commitacc398c195a697795bff3245943d104eb19192b9 (patch)
treed5efdfaaaf3a9c0d6b467c769dee5ea884aced3c
parent05ebc8d795f039f1b7647bb33e995aa2f5c40b73 (diff)
First part of bug 680:
Remove TLI.LowerVA* and replace it with SDNodes that are lowered the same way as everything else. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@25606 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/CodeGen/SelectionDAG.h5
-rw-r--r--include/llvm/CodeGen/SelectionDAGNodes.h13
-rw-r--r--include/llvm/Target/TargetLowering.h25
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeDAG.cpp157
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAG.cpp33
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp69
-rw-r--r--lib/Target/Alpha/AlphaISelLowering.cpp144
-rw-r--r--lib/Target/Alpha/AlphaISelLowering.h9
-rw-r--r--lib/Target/IA64/IA64ISelLowering.cpp63
-rw-r--r--lib/Target/IA64/IA64ISelLowering.h7
-rw-r--r--lib/Target/PowerPC/PPCISelLowering.cpp48
-rw-r--r--lib/Target/PowerPC/PPCISelLowering.h7
-rw-r--r--lib/Target/Sparc/SparcISelDAGToDAG.cpp55
-rw-r--r--lib/Target/SparcV8/SparcV8ISelDAGToDAG.cpp55
-rw-r--r--lib/Target/X86/X86ISelLowering.cpp50
-rw-r--r--lib/Target/X86/X86ISelLowering.h6
16 files changed, 373 insertions, 373 deletions
diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h
index f9d7172672..70aafcca9e 100644
--- a/include/llvm/CodeGen/SelectionDAG.h
+++ b/include/llvm/CodeGen/SelectionDAG.h
@@ -278,6 +278,11 @@ public:
Ops.push_back(False);
return getNode(ISD::BRTWOWAY_CC, MVT::Other, Ops);
}
+
+ /// getVAArg - VAArg produces a result and token chain, and takes a pointer
+ /// and a source value as input.
+ SDOperand getVAArg(MVT::ValueType VT, SDOperand Chain, SDOperand Ptr,
+ SDOperand SV);
/// getLoad - Loads are not normal binary operators: their result type is not
/// determined by their operands, and they produce a value AND a token chain.
diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h
index f0907f5499..431364e072 100644
--- a/include/llvm/CodeGen/SelectionDAGNodes.h
+++ b/include/llvm/CodeGen/SelectionDAGNodes.h
@@ -335,6 +335,19 @@ namespace ISD {
// target and not touched by the DAG optimizers.
CALLSEQ_START, // Beginning of a call sequence
CALLSEQ_END, // End of a call sequence
+
+ // VAARG - VAARG has three operands: an input chain, a pointer, and a
+ // SRCVALUE. It returns a pair of values: the vaarg value and a new chain.
+ VAARG,
+
+ // VACOPY - VACOPY has five operands: an input chain, a destination pointer,
+ // a source pointer, a SRCVALUE for the destination, and a SRCVALUE for the
+ // source.
+ VACOPY,
+
+ // VAEND, VASTART - VAEND and VASTART have three operands: an input chain, a
+ // pointer, and a SRCVALUE.
+ VAEND, VASTART,
// SRCVALUE - This corresponds to a Value*, and is used to associate memory
// locations with their value. This allows one use alias analysis
diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h
index 2a99962a2f..e93bc2331d 100644
--- a/include/llvm/Target/TargetLowering.h
+++ b/include/llvm/Target/TargetLowering.h
@@ -366,31 +366,6 @@ public:
virtual SDOperand LowerReturnTo(SDOperand Chain, SDOperand Op,
SelectionDAG &DAG);
- /// LowerVAStart - This lowers the llvm.va_start intrinsic. If not
- /// implemented, this method prints a message and aborts. This method should
- /// return the modified chain value. Note that VAListPtr* correspond to the
- /// llvm.va_start operand.
- virtual SDOperand LowerVAStart(SDOperand Chain, SDOperand VAListP,
- Value *VAListV, SelectionDAG &DAG);
-
- /// LowerVAEnd - This lowers llvm.va_end and returns the resultant chain. If
- /// not implemented, this defaults to a noop.
- virtual SDOperand LowerVAEnd(SDOperand Chain, SDOperand LP, Value *LV,
- SelectionDAG &DAG);
-
- /// LowerVACopy - This lowers llvm.va_copy and returns the resultant chain.
- /// If not implemented, this defaults to loading a pointer from the input and
- /// storing it to the output.
- virtual SDOperand LowerVACopy(SDOperand Chain, SDOperand SrcP, Value *SrcV,
- SDOperand DestP, Value *DestV,
- SelectionDAG &DAG);
-
- /// LowerVAArg - This lowers the vaarg instruction. If not implemented, this
- /// prints a message and aborts.
- virtual std::pair<SDOperand,SDOperand>
- LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV,
- const Type *ArgTy, SelectionDAG &DAG);
-
/// LowerFrameReturnAddress - This hook lowers a call to llvm.returnaddress or
/// llvm.frameaddress (depending on the value of the first argument). The
/// return values are the result pointer and the resultant token chain. If
diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index e5dd538eb4..933aa70e88 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -1115,13 +1115,12 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
switch (TLI.getOperationAction(Node->getOpcode(), VT)) {
default: assert(0 && "This action is not supported yet!");
case TargetLowering::Custom: {
- SDOperand Op = DAG.getLoad(Node->getValueType(0),
- Tmp1, Tmp2, Node->getOperand(2));
+ SDOperand Op = DAG.getLoad(VT, Tmp1, Tmp2, Node->getOperand(2));
SDOperand Tmp = TLI.LowerOperation(Op, DAG);
if (Tmp.Val) {
Result = LegalizeOp(Tmp);
- // Since loads produce two values, make sure to remember that we legalized
- // both of them.
+ // Since loads produce two values, make sure to remember that we
+ // legalized both of them.
AddLegalizedOperand(SDOperand(Node, 0), Result);
AddLegalizedOperand(SDOperand(Node, 1), Result.getValue(1));
return Result.getValue(Op.ResNo);
@@ -1131,8 +1130,7 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
case TargetLowering::Legal:
if (Tmp1 != Node->getOperand(0) ||
Tmp2 != Node->getOperand(1))
- Result = DAG.getLoad(Node->getValueType(0), Tmp1, Tmp2,
- Node->getOperand(2));
+ Result = DAG.getLoad(VT, Tmp1, Tmp2, Node->getOperand(2));
else
Result = SDOperand(Node, 0);
@@ -2222,6 +2220,140 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
}
break;
+ case ISD::VAARG: {
+ Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain.
+ Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the pointer.
+
+ MVT::ValueType VT = Node->getValueType(0);
+ switch (TLI.getOperationAction(Node->getOpcode(), MVT::Other)) {
+ default: assert(0 && "This action is not supported yet!");
+ case TargetLowering::Custom: {
+ SDOperand Op = DAG.getVAArg(VT, Tmp1, Tmp2, Node->getOperand(2));
+ SDOperand Tmp = TLI.LowerOperation(Op, DAG);
+ if (Tmp.Val) {
+ Result = LegalizeOp(Tmp);
+ break;
+ }
+ // FALLTHROUGH if the target thinks it is legal.
+ }
+ case TargetLowering::Legal:
+ if (Tmp1 != Node->getOperand(0) ||
+ Tmp2 != Node->getOperand(1))
+ Result = DAG.getVAArg(VT, Tmp1, Tmp2, Node->getOperand(2));
+ else
+ Result = SDOperand(Node, 0);
+ break;
+ case TargetLowering::Expand: {
+ SDOperand VAList = DAG.getLoad(TLI.getPointerTy(), Tmp1, Tmp2,
+ Node->getOperand(2));
+ // Increment the pointer, VAList, to the next vaarg
+ Tmp3 = DAG.getNode(ISD::ADD, TLI.getPointerTy(), VAList,
+ DAG.getConstant(MVT::getSizeInBits(VT)/8,
+ TLI.getPointerTy()));
+ // Store the incremented VAList to the legalized pointer
+ Tmp3 = DAG.getNode(ISD::STORE, MVT::Other, VAList.getValue(1), Tmp3, Tmp2,
+ Node->getOperand(2));
+ // Load the actual argument out of the pointer VAList
+ Result = DAG.getLoad(VT, Tmp3, VAList, DAG.getSrcValue(0));
+ Result = LegalizeOp(Result);
+ break;
+ }
+ }
+ // Since VAARG produces two values, make sure to remember that we
+ // legalized both of them.
+ AddLegalizedOperand(SDOperand(Node, 0), Result);
+ AddLegalizedOperand(SDOperand(Node, 1), Result.getValue(1));
+ return Result.getValue(Op.ResNo);
+ }
+
+ case ISD::VACOPY:
+ Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain.
+ Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the dest pointer.
+ Tmp3 = LegalizeOp(Node->getOperand(2)); // Legalize the source pointer.
+
+ switch (TLI.getOperationAction(ISD::VACOPY, MVT::Other)) {
+ default: assert(0 && "This action is not supported yet!");
+ case TargetLowering::Custom: {
+ SDOperand Op = DAG.getNode(ISD::VACOPY, MVT::Other, Tmp1, Tmp2, Tmp3,
+ Node->getOperand(3), Node->getOperand(4));
+ SDOperand Tmp = TLI.LowerOperation(Op, DAG);
+ if (Tmp.Val) {
+ Result = LegalizeOp(Tmp);
+ break;
+ }
+ // FALLTHROUGH if the target thinks it is legal.
+ }
+ case TargetLowering::Legal:
+ if (Tmp1 != Node->getOperand(0) ||
+ Tmp2 != Node->getOperand(1) ||
+ Tmp3 != Node->getOperand(2))
+ Result = DAG.getNode(ISD::VACOPY, MVT::Other, Tmp1, Tmp2, Tmp3,
+ Node->getOperand(3), Node->getOperand(4));
+ break;
+ case TargetLowering::Expand:
+ // This defaults to loading a pointer from the input and storing it to the
+ // output, returning the chain.
+ Tmp4 = DAG.getLoad(TLI.getPointerTy(), Tmp1, Tmp3, Node->getOperand(3));
+ Result = DAG.getNode(ISD::STORE, MVT::Other, Tmp4.getValue(1), Tmp4, Tmp2,
+ Node->getOperand(4));
+ Result = LegalizeOp(Result);
+ break;
+ }
+ break;
+
+ case ISD::VAEND:
+ Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain.
+ Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the pointer.
+
+ switch (TLI.getOperationAction(ISD::VAEND, MVT::Other)) {
+ default: assert(0 && "This action is not supported yet!");
+ case TargetLowering::Custom: {
+ SDOperand Op = DAG.getNode(ISD::VAEND, MVT::Other, Tmp1, Tmp2,
+ Node->getOperand(2));
+ SDOperand Tmp = TLI.LowerOperation(Op, DAG);
+ if (Tmp.Val) {
+ Result = LegalizeOp(Tmp);
+ break;
+ }
+ // FALLTHROUGH if the target thinks it is legal.
+ }
+ case TargetLowering::Legal:
+ if (Tmp1 != Node->getOperand(0) ||
+ Tmp2 != Node->getOperand(1))
+ Result = DAG.getNode(ISD::VAEND, MVT::Other, Tmp1, Tmp2,
+ Node->getOperand(2));
+ break;
+ case TargetLowering::Expand:
+ Result = Tmp1; // Default to a no-op, return the chain
+ break;
+ }
+ break;
+
+ case ISD::VASTART:
+ Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain.
+ Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the pointer.
+
+ switch (TLI.getOperationAction(ISD::VASTART, MVT::Other)) {
+ default: assert(0 && "This action is not supported yet!");
+ case TargetLowering::Custom: {
+ SDOperand Op = DAG.getNode(ISD::VASTART, MVT::Other, Tmp1, Tmp2,
+ Node->getOperand(2));
+ SDOperand Tmp = TLI.LowerOperation(Op, DAG);
+ if (Tmp.Val) {
+ Result = LegalizeOp(Tmp);
+ break;
+ }
+ // FALLTHROUGH if the target thinks it is legal.
+ }
+ case TargetLowering::Legal:
+ if (Tmp1 != Node->getOperand(0) ||
+ Tmp2 != Node->getOperand(1))
+ Result = DAG.getNode(ISD::VASTART, MVT::Other, Tmp1, Tmp2,
+ Node->getOperand(2));
+ break;
+ }
+ break;
+
case ISD::ROTL:
case ISD::ROTR:
Tmp1 = LegalizeOp(Node->getOperand(0)); // LHS
@@ -3823,6 +3955,19 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){
break;
}
+ case ISD::VAARG: {
+ SDOperand Ch = LegalizeOp(Node->getOperand(0)); // Legalize the chain.
+ SDOperand Ptr = LegalizeOp(Node->getOperand(1)); // Legalize the pointer.
+ Lo = DAG.getVAArg(NVT, Ch, Ptr, Node->getOperand(2));
+ Hi = DAG.getVAArg(NVT, Lo.getValue(1), Ptr, Node->getOperand(2));
+
+ // Remember that we legalized the chain.
+ AddLegalizedOperand(Op.getValue(1), Hi.getValue(1));
+ if (!TLI.isLittleEndian())
+ std::swap(Lo, Hi);
+ break;
+ }
+
case ISD::LOAD: {
SDOperand Ch = LegalizeOp(Node->getOperand(0)); // Legalize the chain.
SDOperand Ptr = LegalizeOp(Node->getOperand(1)); // Legalize the pointer.
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index ed96bd61ae..d864042537 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -1348,6 +1348,20 @@ SDOperand SelectionDAG::getSrcValue(const Value *V, int Offset) {
return SDOperand(N, 0);
}
+SDOperand SelectionDAG::getVAArg(MVT::ValueType VT,
+ SDOperand Chain, SDOperand Ptr,
+ SDOperand SV) {
+ std::vector<SDOperand> Ops;
+ Ops.reserve(3);
+ Ops.push_back(Chain);
+ Ops.push_back(Ptr);
+ Ops.push_back(SV);
+ std::vector<MVT::ValueType> VTs;
+ VTs.reserve(2);
+ VTs.push_back(VT); VTs.push_back(MVT::Other); // Add token chain.
+ return getNode(ISD::VAARG, VTs, Ops);
+}
+
SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
std::vector<SDOperand> &Ops) {
switch (Ops.size()) {
@@ -2087,14 +2101,17 @@ const char *SDNode::getOperationName(const SelectionDAG *G) const {
case ISD::CALLSEQ_END: return "callseq_end";
// Other operators
- case ISD::LOAD: return "load";
- case ISD::STORE: return "store";
- case ISD::VLOAD: return "vload";
- case ISD::EXTLOAD: return "extload";
- case ISD::SEXTLOAD: return "sextload";
- case ISD::ZEXTLOAD: return "zextload";
- case ISD::TRUNCSTORE: return "truncstore";
-
+ case ISD::LOAD: return "load";
+ case ISD::STORE: return "store";
+ case ISD::VLOAD: return "vload";
+ case ISD::EXTLOAD: return "extload";
+ case ISD::SEXTLOAD: return "sextload";
+ case ISD::ZEXTLOAD: return "zextload";
+ case ISD::TRUNCSTORE: return "truncstore";
+ case ISD::VAARG: return "vaarg";
+ case ISD::VACOPY: return "vacopy";
+ case ISD::VAEND: return "vaend";
+ case ISD::VASTART: return "vastart";
case ISD::DYNAMIC_STACKALLOC: return "dynamic_stackalloc";
case ISD::EXTRACT_ELEMENT: return "extract_element";
case ISD::BUILD_PAIR: return "build_pair";
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index 06a3b016de..f75bdbeba7 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -1204,71 +1204,34 @@ SDOperand TargetLowering::LowerReturnTo(SDOperand Chain, SDOperand Op,
return DAG.getNode(ISD::RET, MVT::Other, Chain, Op);
}
-SDOperand TargetLowering::LowerVAStart(SDOperand Chain,
- SDOperand VAListP, Value *VAListV,
- SelectionDAG &DAG) {
- // We have no sane default behavior, just emit a useful error message and bail
- // out.
- std::cerr << "Variable arguments handling not implemented on this target!\n";
- abort();
- return SDOperand();
-}
-
-SDOperand TargetLowering::LowerVAEnd(SDOperand Chain, SDOperand LP, Value *LV,
- SelectionDAG &DAG) {
- // Default to a noop.
- return Chain;
-}
-
-SDOperand TargetLowering::LowerVACopy(SDOperand Chain,
- SDOperand SrcP, Value *SrcV,
- SDOperand DestP, Value *DestV,
- SelectionDAG &DAG) {
- // Default to copying the input list.
- SDOperand Val = DAG.getLoad(getPointerTy(), Chain,
- SrcP, DAG.getSrcValue(SrcV));
- SDOperand Result = DAG.getNode(ISD::STORE, MVT::Other, Val.getValue(1),
- Val, DestP, DAG.getSrcValue(DestV));
- return Result;
-}
-
-std::pair<SDOperand,SDOperand>
-TargetLowering::LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV,
- const Type *ArgTy, SelectionDAG &DAG) {
- // We have no sane default behavior, just emit a useful error message and bail
- // out.
- std::cerr << "Variable arguments handling not implemented on this target!\n";
- abort();
- return std::make_pair(SDOperand(), SDOperand());
-}
-
-
void SelectionDAGLowering::visitVAStart(CallInst &I) {
- DAG.setRoot(TLI.LowerVAStart(getRoot(), getValue(I.getOperand(1)),
- I.getOperand(1), DAG));
+ DAG.setRoot(DAG.getNode(ISD::VASTART, MVT::Other, getRoot(),
+ getValue(I.getOperand(1)),
+ DAG.getSrcValue(I.getOperand(1))));
}
void SelectionDAGLowering::visitVAArg(VAArgInst &I) {
- std::pair<SDOperand,SDOperand> Result =
- TLI.LowerVAArg(getRoot(), getValue(I.getOperand(0)), I.getOperand(0),
- I.getType(), DAG);
- setValue(&I, Result.first);
- DAG.setRoot(Result.second);
+ SDOperand V = DAG.getVAArg(TLI.getValueType(I.getType()), getRoot(),
+ getValue(I.getOperand(0)),
+ DAG.getSrcValue(I.getOperand(0)));
+ setValue(&I, V);
+ DAG.setRoot(V.getValue(1));
}
void SelectionDAGLowering::visitVAEnd(CallInst &I) {
- DAG.setRoot(TLI.LowerVAEnd(getRoot(), getValue(I.getOperand(1)),
- I.getOperand(1), DAG));
+ DAG.setRoot(DAG.getNode(ISD::VAEND, MVT::Other, getRoot(),
+ getValue(I.getOperand(1)),
+ DAG.getSrcValue(I.getOperand(1))));
}
void SelectionDAGLowering::visitVACopy(CallInst &I) {
- SDOperand Result =
- TLI.LowerVACopy(getRoot(), getValue(I.getOperand(2)), I.getOperand(2),
- getValue(I.getOperand(1)), I.getOperand(1), DAG);
- DAG.setRoot(Result);
+ DAG.setRoot(DAG.getNode(ISD::VACOPY, MVT::Other, getRoot(),
+ getValue(I.getOperand(1)),
+ getValue(I.getOperand(2)),
+ DAG.getSrcValue(I.getOperand(1)),
+ DAG.getSrcValue(I.getOperand(2))));
}
-
// It is always conservatively correct for llvm.returnaddress and
// llvm.frameaddress to return 0.
std::pair<SDOperand, SDOperand>
diff --git a/lib/Target/Alpha/AlphaISelLowering.cpp b/lib/Target/Alpha/AlphaISelLowering.cpp
index 6f8226113c..44b37c75fd 100644
--- a/lib/Target/Alpha/AlphaISelLowering.cpp
+++ b/lib/Target/Alpha/AlphaISelLowering.cpp
@@ -368,79 +368,6 @@ AlphaTargetLowering::LowerCallTo(SDOperand Chain,
return std::make_pair(RetVal, Chain);
}
-SDOperand AlphaTargetLowering::LowerVAStart(SDOperand Chain, SDOperand VAListP,
- Value *VAListV, SelectionDAG &DAG) {
- // vastart stores the address of the VarArgsBase and VarArgsOffset
- SDOperand FR = DAG.getFrameIndex(VarArgsBase, MVT::i64);
- SDOperand S1 = DAG.getNode(ISD::STORE, MVT::Other, Chain, FR, VAListP,
- DAG.getSrcValue(VAListV));
- SDOperand SA2 = DAG.getNode(ISD::ADD, MVT::i64, VAListP,
- DAG.getConstant(8, MVT::i64));
- return DAG.getNode(ISD::TRUNCSTORE, MVT::Other, S1,
- DAG.getConstant(VarArgsOffset, MVT::i64), SA2,
- DAG.getSrcValue(VAListV, 8), DAG.getValueType(MVT::i32));
-}
-
-std::pair<SDOperand,SDOperand> AlphaTargetLowering::
-LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV,
- const Type *ArgTy, SelectionDAG &DAG) {
- SDOperand Base = DAG.getLoad(MVT::i64, Chain, VAListP,
- DAG.getSrcValue(VAListV));
- SDOperand Tmp = DAG.getNode(ISD::ADD, MVT::i64, VAListP,
- DAG.getConstant(8, MVT::i64));
- SDOperand Offset = DAG.getExtLoad(ISD::SEXTLOAD, MVT::i64, Base.getValue(1),
- Tmp, DAG.getSrcValue(VAListV, 8), MVT::i32);
- SDOperand DataPtr = DAG.getNode(ISD::ADD, MVT::i64, Base, Offset);
- if (ArgTy->isFloatingPoint())
- {
- //if fp && Offset < 6*8, then subtract 6*8 from DataPtr
- SDOperand FPDataPtr = DAG.getNode(ISD::SUB, MVT::i64, DataPtr,
- DAG.getConstant(8*6, MVT::i64));
- SDOperand CC = DAG.getSetCC(MVT::i64, Offset,
- DAG.getConstant(8*6, MVT::i64), ISD::SETLT);
- DataPtr = DAG.getNode(ISD::SELECT, MVT::i64, CC, FPDataPtr, DataPtr);
- }
-
- SDOperand Result;
- if (ArgTy == Type::IntTy)
- Result = DAG.getExtLoad(ISD::SEXTLOAD, MVT::i64, Offset.getValue(1),
- DataPtr, DAG.getSrcValue(NULL), MVT::i32);
- else if (ArgTy == Type::UIntTy)
- Result = DAG.getExtLoad(ISD::ZEXTLOAD, MVT::i64, Offset.getValue(1),
- DataPtr, DAG.getSrcValue(NULL), MVT::i32);
- else
- Result = DAG.getLoad(getValueType(ArgTy), Offset.getValue(1), DataPtr,
- DAG.getSrcValue(NULL));
-
- SDOperand NewOffset = DAG.getNode(ISD::ADD, MVT::i64, Offset,
- DAG.getConstant(8, MVT::i64));
- SDOperand Update = DAG.getNode(ISD::TRUNCSTORE, MVT::Other,
- Result.getValue(1), NewOffset,
- Tmp, DAG.getSrcValue(VAListV, 8),
- DAG.getValueType(MVT::i32));
- Result = DAG.getNode(ISD::TRUNCATE, getValueType(ArgTy), Result);
-
- return std::make_pair(Result, Update);
-}
-
-SDOperand AlphaTargetLowering::
-LowerVACopy(SDOperand Chain, SDOperand SrcP, Value *SrcV, SDOperand DestP,
- Value *DestV, SelectionDAG &DAG) {
- SDOperand Val = DAG.getLoad(getPointerTy(), Chain, SrcP,
- DAG.getSrcValue(SrcV));
- SDOperand Result = DAG.getNode(ISD::STORE, MVT::Other, Val.getValue(1),
- Val, DestP, DAG.getSrcValue(DestV));
- SDOperand NP = DAG.getNode(ISD::ADD, MVT::i64, SrcP,
- DAG.getConstant(8, MVT::i64));
- Val = DAG.getExtLoad(ISD::SEXTLOAD, MVT::i64, Result, NP,
- DAG.getSrcValue(SrcV, 8), MVT::i32);
- SDOperand NPD = DAG.getNode(ISD::ADD, MVT::i64, DestP,
- DAG.getConstant(8, MVT::i64));
- return DAG.getNode(ISD::TRUNCSTORE, MVT::Other, Val.getValue(1),
- Val, NPD, DAG.getSrcValue(DestV, 8),
- DAG.getValueType(MVT::i32));
-}
-
void AlphaTargetLowering::restoreGP(MachineBasicBlock* BB)
{
BuildMI(BB, Alpha::BIS, 2, Alpha::R29).addReg(GP).addReg(GP);
@@ -680,8 +607,77 @@ SDOperand AlphaTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
ARGS.push_back(DAG.getConstant(getUID(), MVT::i64));
return DAG.getNode(Opc, VTS, ARGS);
}
+ case ISD::VAARG: {
+ SDOperand Chain = Op.getOperand(0);
+ SDOperand VAListP = Op.getOperand(1);
+ SDOperand VAListS = Op.getOperand(2);
+
+ SDOperand Base = DAG.getLoad(MVT::i64, Chain, VAListP, VAListS);
+ SDOperand Tmp = DAG.getNode(ISD::ADD, MVT::i64, VAListP,
+ DAG.getConstant(8, MVT::i64));
+ SDOperand Offset = DAG.getExtLoad(ISD::SEXTLOAD, MVT::i64, Base.getValue(1),
+ Tmp, DAG.getSrcValue(0), MVT::i32);
+ SDOperand DataPtr = DAG.getNode(ISD::ADD, MVT::i64, Base, Offset);
+ if (MVT::isFloatingPoint(Op.getValueType()))
+ {
+ //if fp && Offset < 6*8, then subtract 6*8 from DataPtr
+ SDOperand FPDataPtr = DAG.getNode(ISD::SUB, MVT::i64, DataPtr,
+ DAG.getConstant(8*6, MVT::i64));
+ SDOperand CC = DAG.getSetCC(MVT::i64, Offset,
+ DAG.getConstant(8*6, MVT::i64), ISD::SETLT);
+ DataPtr = DAG.getNode(ISD::SELECT, MVT::i64, CC, FPDataPtr, DataPtr);
+ }
-
+ SDOperand NewOffset = DAG.getNode(ISD::ADD, MVT::i64, Offset,
+ DAG.getConstant(8, MVT::i64));
+ SDOperand Update = DAG.getNode(ISD::TRUNCSTORE, MVT::Other,
+ Offset.getValue(1), NewOffset,
+ Tmp, DAG.getSrcValue(0),
+ DAG.getValueType(MVT::i32));
+
+ SDOperand Result;
+ if (Op.getValueType() == MVT::i32)
+ Result = DAG.getExtLoad(ISD::SEXTLOAD, MVT::i64, Update, DataPtr,
+ DAG.getSrcValue(0), MVT::i32);
+ else
+ Result = DAG.getLoad(Op.getValueType(), Update, DataPtr,
+ DAG.getSrcValue(0));
+ return Result;
+ }
+ case ISD::VACOPY: {
+ SDOperand Chain = Op.getOperand(0);
+ SDOperand DestP = Op.getOperand(1);
+ SDOperand SrcP = Op.getOperand(2);
+ SDOperand DestS = Op.getOperand(3);
+ SDOperand SrcS = Op.getOperand(4);
+
+ SDOperand Val = DAG.getLoad(getPointerTy(), Chain, SrcP, SrcS);
+ SDOperand Result = DAG.getNode(ISD::STORE, MVT::Other, Val.getValue(1), Val,
+ DestP, DestS);
+ SDOperand NP = DAG.getNode(ISD::ADD, MVT::i64, SrcP,
+ DAG.getConstant(8, MVT::i64));
+ Val = DAG.getExtLoad(ISD::SEXTLOAD, MVT::i64, Result, NP,
+ DAG.getSrcValue(0), MVT::i32);
+ SDOperand NPD = DAG.getNode(ISD::ADD, MVT::i64, DestP,
+ DAG.getConstant(8, MVT::i64));
+ return DAG.getNode(ISD::TRUNCSTORE, MVT::Other, Val.getValue(1),
+ Val, NPD, DAG.getSrcValue(0),DAG.getValueType(MVT::i32));
+ }
+ case ISD::VASTART: {
+ SDOperand Chain = Op.getOperand(0);
+ SDOperand VAListP = Op.getOperand(1);
+ SDOperand VAListS = Op.getOperand(2);
+
+ // vastart stores the address of the VarArgsBase and VarArgsOffset
+ SDOperand FR = DAG.getFrameIndex(VarArgsBase, MVT::i64);
+ SDOperand S1 = DAG.getNode(ISD::STORE, MVT::Other, Chain, FR, VAListP,
+ VAListS);
+ SDOperand SA2 = DAG.getNode(ISD::ADD, MVT::i64, VAListP,
+ DAG.getConstant(8, MVT::i64));
+ return DAG.getNode(ISD::TRUNCSTORE, MVT::Other, S1,
+ DAG.getConstant(VarArgsOffset, MVT::i64), SA2,
+ DAG.getSrcValue(0), DAG.getValueType(MVT::i32));
+ }
}
return SDOperand();
diff --git a/lib/Target/Alpha/AlphaISelLowering.h b/lib/Target/Alpha/AlphaISelLowering.h
index 6b6db79a04..aedaf395c6 100644
--- a/lib/Target/Alpha/AlphaISelLowering.h
+++ b/lib/Target/Alpha/AlphaISelLowering.h
@@ -75,15 +75,6 @@ namespace llvm {
bool isTailCall, SDOperand Callee, ArgListTy &Args,
SelectionDAG &DAG);
- virtual SDOperand LowerVAStart(SDOperand Chain, SDOperand VAListP,
- Value *VAListV, SelectionDAG &DAG);
- virtual SDOperand LowerVACopy(SDOperand Chain, SDOperand SrcP, Value *SrcV,
- SDOperand DestP, Value *DestV,
- SelectionDAG &DAG);
- virtual std::pair<SDOperand,SDOperand>
- LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV,
- const Type *ArgTy, SelectionDAG &DAG);
-
void restoreGP(MachineBasicBlock* BB);
void restoreRA(MachineBasicBlock* BB);
unsigned getVRegGP() { return GP; }
diff --git a/lib/Target/IA64/IA64ISelLowering.cpp b/lib/Target/IA64/IA64ISelLowering.cpp
index 91bd4e6f21..c963bfc5a6 100644
--- a/lib/Target/IA64/IA64ISelLowering.cpp
+++ b/lib/Target/IA64/IA64ISelLowering.cpp
@@ -89,6 +89,13 @@ IA64TargetLowering::IA64TargetLowering(TargetMachine &TM)
setOperationAction(ISD::ROTR , MVT::i64 , Expand);
setOperationAction(ISD::BSWAP, MVT::i64 , Expand); // mux @rev
+ // VASTART needs to be custom lowered to use the VarArgsFrameIndex
+ setOperationAction(ISD::VAARG , MVT::Other, Custom);
+ setOperationAction(ISD::VASTART , MVT::Other, Custom);
+
+ // Use the default implementation.
+ setOperationAction(ISD::VACOPY , MVT::Other, Expand);
+ setOperationAction(ISD::VAEND , MVT::Other, Expand);
setOperationAction(ISD::STACKSAVE, MVT::Other, Expand);
setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand);
setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i64, Expand);
@@ -569,41 +576,6 @@ SDOperand IA64TargetLowering::LowerReturnTo(SDOperand Chain, SDOperand Op,
// return DAG.getNode(IA64ISD::RET_FLAG, MVT::Other, MVT::Other, Copy, Chain, InFlag);
}
-SDOperand
-IA64TargetLowering::LowerVAStart(SDOperand Chain, SDOperand VAListP,
- Value *VAListV, SelectionDAG &DAG) {
- // vastart just stores the address of the VarArgsFrameIndex slot.
- SDOperand FR = DAG.getFrameIndex(VarArgsFrameIndex, MVT::i64);
- return DAG.getNode(ISD::STORE, MVT::Other, Chain, FR,
- VAListP, DAG.getSrcValue(VAListV));
-}
-
-std::pair<SDOperand,SDOperand> IA64TargetLowering::
-LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV,
- const Type *ArgTy, SelectionDAG &DAG) {
-
- MVT::ValueType ArgVT = getValueType(ArgTy);
- SDOperand Val = DAG.getLoad(MVT::i64, Chain,
- VAListP, DAG.getSrcValue(VAListV));
- SDOperand Result = DAG.getLoad(ArgVT, DAG.getEntryNode(), Val,
- DAG.getSrcValue(NULL));
- unsigned Amt;
- if (ArgVT == MVT::i32 || ArgVT == MVT::f32)
- Amt = 8;
- else {
- assert((ArgVT == MVT::i64 || ArgVT == MVT::f64) &&
- "Other types should have been promoted for varargs!");
- Amt = 8;
- }
- Val = DAG.getNode(ISD::ADD, Val.getValueType(), Val,
- DAG.getConstant(Amt, Val.getValueType()));
- Chain = DAG.getNode(ISD::STORE, MVT::Other, Chain,
- Val, VAListP, DAG.getSrcValue(VAListV));
- return std::make_pair(Result, Chain);
-}
-
-
-
std::pair<SDOperand, SDOperand> IA64TargetLowering::
LowerFrameReturnAddress(bool isFrameAddress, SDOperand Chain, unsigned Depth,
SelectionDAG &DAG) {
@@ -631,5 +603,26 @@ LowerOperation(SDOperand Op, SelectionDAG &DAG) {
// and then just emit a 'ret' instruction
return DAG.getNode(IA64ISD::RET_FLAG, MVT::Other, Chain);
}
+ case ISD::VAARG: {
+ MVT::ValueType VT = getPointerTy();
+ SDOperand VAList = DAG.getLoad(VT, Op.getOperand(0), Op.getOperand(1),
+ Op.getOperand(2));
+ // Increment the pointer, VAList, to the next vaarg
+ SDOperand VAIncr = DAG.getNode(ISD::ADD, VT, VAList,
+ DAG.getConstant(MVT::getSizeInBits(VT)/8,
+ VT));
+ // Store the incremented VAList to the legalized pointer
+ VAIncr = DAG.getNode(ISD::STORE, MVT::Other, VAList.getValue(1), VAIncr,
+ Op.getOperand(1), Op.getOperand(2));
+ // Load the actual argument out of the pointer VAList
+ return DAG.getLoad(VT, VAIncr, VAList, DAG.getSrcValue(0));
+ }
+ case ISD::VASTART: {
+ // vastart just stores the address of the VarArgsFrameIndex slot into the
+ // memory location argument.
+ SDOperand FR = DAG.getFrameIndex(VarArgsFrameIndex, MVT::i64);
+ return DAG.getNode(ISD::STORE, MVT::Other, Op.getOperand(0), FR,
+ Op.getOperand(1), Op.getOperand(2));
+ }
}
}
diff --git a/lib/Target/IA64/IA64ISelLowering.h b/lib/Target/IA64/IA64ISelLowering.h
index a73bbaa7f1..bd63be1572 100644
--- a/lib/Target/IA64/IA64ISelLowering.h
+++ b/lib/Target/IA64/IA64ISelLowering.h
@@ -76,13 +76,6 @@ namespace llvm {
/// (currently, only "ret void")
virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG);
- virtual SDOperand LowerVAStart(SDOperand Chain, SDOperand VAListP,
- Value *VAListV, SelectionDAG &DAG);
-
- virtual std::pair<SDOperand,SDOperand>
- LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV,
- const Type *ArgTy, SelectionDAG &DAG);
-
virtual std::pair<SDOperand, SDOperand>
LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth,
SelectionDAG &DAG);
diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp
index 629b7cabf8..df69a84acb 100644
--- a/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -110,7 +110,13 @@ PPCTargetLowering::PPCTargetLowering(TargetMachine &TM)
setOperationAction(ISD::GlobalAddress, MVT::i32, Custom);
setOperationAction(ISD::ConstantPool, MVT::i32, Custom);
+ // VASTART needs to be custom lowered to use the VarArgsFrameIndex
+ setOperationAction(ISD::VASTART , MVT::Other, Custom);
+
// Use the default implementation.
+ setOperationAction(ISD::VAARG , MVT::Other, Expand);
+ setOperationAction(ISD::VACOPY , MVT::Other, Expand);
+ setOperationAction(ISD::VAEND , MVT::Other, Expand);
setOperationAction(ISD::STACKSAVE , MVT::Other, Expand);
setOperationAction(ISD::STACKRESTORE , MVT::Other, Expand);
setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32 , Expand);
@@ -427,6 +433,14 @@ SDOperand PPCTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
// resolution stub.
return DAG.getLoad(MVT::i32, DAG.getEntryNode(), Lo, DAG.getSrcValue(0));
}
+ case ISD::VASTART: {
+ // vastart just stores the address of the VarArgsFrameIndex slot into the
+ // memory location argument.
+ // FIXME: Replace MVT::i32 with PointerTy
+ SDOperand FR = DAG.getFrameIndex(VarArgsFrameIndex, MVT::i32);
+ return DAG.getNode(ISD::STORE, MVT::Other, Op.getOperand(0), FR,
+