diff options
author | Duncan Sands <baldrick@free.fr> | 2008-06-30 13:55:15 +0000 |
---|---|---|
committer | Duncan Sands <baldrick@free.fr> | 2008-06-30 13:55:15 +0000 |
commit | d3ca9fc9984d036146886a40ad3f73aaf7a424eb (patch) | |
tree | b8ba49284efee4feffa51d30d1a2e2343b469093 /lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp | |
parent | 7fc8ab81f5f46dcba0f76b1c546a1d11ccbebe26 (diff) |
Support for VAARG. As noted in a comment, this is
wrong for types like x86 long double and i1, but
no worse than what is done in LegalizeDAG.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@52898 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp')
-rw-r--r-- | lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp | 32 |
1 files changed, 32 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 //===----------------------------------------------------------------------===// |