aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorBill Schmidt <wschmidt@linux.vnet.ibm.com>2012-10-29 21:18:16 +0000
committerBill Schmidt <wschmidt@linux.vnet.ibm.com>2012-10-29 21:18:16 +0000
commite6c56433de56fb89f1d476332134b6b2e22cfa28 (patch)
tree76c7a3b8e0642cfe144506d32720862e6eca0da2 /lib
parent4830ccff925b8d57f589650a3ad6007ffa0536d5 (diff)
downloadexternal_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.cpp12
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);