aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen')
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp32
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeTypes.h1
2 files changed, 33 insertions, 0 deletions
diff --git a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
index cf98b3c9d1..1a97dcaf58 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
@@ -84,6 +84,8 @@ void DAGTypeLegalizer::PromoteIntegerResult(SDNode *N, unsigned ResNo) {
case ISD::EXTRACT_VECTOR_ELT:
Result = PromoteIntRes_EXTRACT_VECTOR_ELT(N);
break;
+
+ case ISD::VAARG : Result = PromoteIntRes_VAARG(N); break;
}
// If Result is null, the sub-method took care of registering the result.
@@ -411,6 +413,36 @@ SDOperand DAGTypeLegalizer::PromoteIntRes_EXTRACT_VECTOR_ELT(SDNode *N) {
return DAG.getNode(ISD::SELECT, NewVT, Odd, Hi, Lo);
}
+SDOperand DAGTypeLegalizer::PromoteIntRes_VAARG(SDNode *N) {
+ SDOperand Chain = N->getOperand(0); // Get the chain.
+ SDOperand Ptr = N->getOperand(1); // Get the pointer.
+ MVT VT = N->getValueType(0);
+
+ const Value *V = cast<SrcValueSDNode>(N->getOperand(2))->getValue();
+ SDOperand VAList = DAG.getLoad(TLI.getPointerTy(), Chain, Ptr, V, 0);
+
+ // Increment the arg pointer, VAList, to the next vaarg
+ // FIXME: should the ABI size be used for the increment? Think of
+ // x86 long double (10 bytes long, but aligned on 4 or 8 bytes) or
+ // integers of unusual size (such MVT::i1, which gives an increment
+ // of zero here!).
+ unsigned Increment = VT.getSizeInBits() / 8;
+ SDOperand Tmp = DAG.getNode(ISD::ADD, TLI.getPointerTy(), VAList,
+ DAG.getConstant(Increment, TLI.getPointerTy()));
+
+ // Store the incremented VAList to the pointer.
+ Tmp = DAG.getStore(VAList.getValue(1), Tmp, Ptr, V, 0);
+
+ // Load the actual argument out of the arg pointer VAList.
+ Tmp = DAG.getExtLoad(ISD::EXTLOAD, TLI.getTypeToTransformTo(VT), Tmp,
+ VAList, NULL, 0, VT);
+
+ // Legalized the chain result - switch anything that used the old chain to
+ // use the new one.
+ ReplaceValueWith(SDOperand(N, 1), Tmp.getValue(1));
+ return Tmp;
+}
+
//===----------------------------------------------------------------------===//
// Integer Operand Promotion
//===----------------------------------------------------------------------===//
diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypes.h b/lib/CodeGen/SelectionDAG/LegalizeTypes.h
index 6b9d1abed1..13a10f7365 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeTypes.h
+++ b/lib/CodeGen/SelectionDAG/LegalizeTypes.h
@@ -234,6 +234,7 @@ private:
SDOperand PromoteIntRes_TRUNCATE(SDNode *N);
SDOperand PromoteIntRes_UDIV(SDNode *N);
SDOperand PromoteIntRes_UNDEF(SDNode *N);
+ SDOperand PromoteIntRes_VAARG(SDNode *N);
// Integer Operand Promotion.
bool PromoteIntegerOperand(SDNode *N, unsigned OperandNo);