diff options
| author | Bill Schmidt <wschmidt@linux.vnet.ibm.com> | 2012-10-29 21:18:16 +0000 |
|---|---|---|
| committer | Bill Schmidt <wschmidt@linux.vnet.ibm.com> | 2012-10-29 21:18:16 +0000 |
| commit | e6c56433de56fb89f1d476332134b6b2e22cfa28 (patch) | |
| tree | 76c7a3b8e0642cfe144506d32720862e6eca0da2 /lib | |
| parent | 4830ccff925b8d57f589650a3ad6007ffa0536d5 (diff) | |
| download | external_llvm-e6c56433de56fb89f1d476332134b6b2e22cfa28.zip external_llvm-e6c56433de56fb89f1d476332134b6b2e22cfa28.tar.gz external_llvm-e6c56433de56fb89f1d476332134b6b2e22cfa28.tar.bz2 | |
This patch solves a problem with passing varargs parameters under the PPC64
ELF ABI.
A varargs parameter consisting of a single-precision floating-point value,
or of a single-element aggregate containing a single-precision floating-point
value, must be passed in the low-order (rightmost) four bytes of the
doubleword stack slot reserved for that parameter. If there are GPR protocol
registers remaining, the parameter must also be mirrored in the low-order
four bytes of the reserved GPR.
Prior to this patch, such parameters were being passed in the high-order
four bytes of the stack slot and the mirrored GPR.
The patch adds a new test case to verify the correct code generation.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@166968 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/Target/PowerPC/PPCISelLowering.cpp | 12 |
1 files changed, 11 insertions, 1 deletions
diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp index cbb043c..f277910 100644 --- a/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/lib/Target/PowerPC/PPCISelLowering.cpp @@ -3751,7 +3751,17 @@ PPCTargetLowering::LowerCall_64SVR4(SDValue Chain, SDValue Callee, RegsToPass.push_back(std::make_pair(FPR[FPR_idx++], Arg)); if (isVarArg) { - SDValue Store = DAG.getStore(Chain, dl, Arg, PtrOff, + // A single float or an aggregate containing only a single float + // must be passed right-justified in the stack doubleword, and + // in the GPR, if one is available. + SDValue StoreOff; + if (Arg.getValueType().getSimpleVT().SimpleTy == MVT::f32) { + SDValue ConstFour = DAG.getConstant(4, PtrOff.getValueType()); + StoreOff = DAG.getNode(ISD::ADD, dl, PtrVT, PtrOff, ConstFour); + } else + StoreOff = PtrOff; + + SDValue Store = DAG.getStore(Chain, dl, Arg, StoreOff, MachinePointerInfo(), false, false, 0); MemOpChains.push_back(Store); |
