From c0cb28fd3abee9a8b40856990e04f1af2f9bd7b8 Mon Sep 17 00:00:00 2001 From: Nicolas Geoffray Date: Sun, 13 Apr 2008 13:40:22 +0000 Subject: Add a divided flag for the first piece of an argument divided into mulitple parts. Fixes PR1643 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@49611 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 9 +++++++-- lib/Target/PowerPC/PPCISelLowering.cpp | 24 ++++++++++++------------ 2 files changed, 19 insertions(+), 14 deletions(-) (limited to 'lib') diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index ac5cfd2..04aa472 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -4162,8 +4162,11 @@ TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) { unsigned NumRegs = getNumRegisters(VT); for (unsigned i = 0; i != NumRegs; ++i) { RetVals.push_back(RegisterVT); + + if (NumRegs > 1 && i == 0) + Flags.setDivided(); // if it isn't first piece, alignment must be 1 - if (i > 0) + else if (i > 0) Flags.setOrigAlign(1); Ops.push_back(DAG.getArgFlags(Flags)); } @@ -4285,7 +4288,9 @@ TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy, for (unsigned i = 0; i != NumParts; ++i) { // if it isn't first piece, alignment must be 1 ISD::ArgFlagsTy MyFlags = Flags; - if (i != 0) + if (NumParts > 1 && i == 0) + MyFlags.setDivided(); + else if (i != 0) MyFlags.setOrigAlign(1); Ops.push_back(Parts[i]); diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp index e42e9dc..b164390 100644 --- a/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/lib/Target/PowerPC/PPCISelLowering.cpp @@ -1410,7 +1410,7 @@ PPCTargetLowering::LowerFORMAL_ARGUMENTS(SDOperand Op, // // In the ELF 32 ABI, GPRs and stack are double word align: an argument // represented with two words (long long or double) must be copied to an - // even GPR_idx value or to an even ArgOffset value. TODO: implement this. + // even GPR_idx value or to an even ArgOffset value. SmallVector MemOps; @@ -1423,7 +1423,7 @@ PPCTargetLowering::LowerFORMAL_ARGUMENTS(SDOperand Op, ISD::ArgFlagsTy Flags = cast(Op.getOperand(ArgNo+3))->getArgFlags(); // See if next argument requires stack alignment in ELF - bool Expand = false; // TODO: implement this. + bool Align = Flags.isDivided(); unsigned CurArgOffset = ArgOffset; @@ -1435,7 +1435,7 @@ PPCTargetLowering::LowerFORMAL_ARGUMENTS(SDOperand Op, ObjSize = Flags.getByValSize(); ArgSize = ((ObjSize + PtrByteSize - 1)/PtrByteSize) * PtrByteSize; // Double word align in ELF - if (Expand && isELF32_ABI) GPR_idx += (GPR_idx % 2); + if (Align && isELF32_ABI) GPR_idx += (GPR_idx % 2); // Objects of size 1 and 2 are right justified, everything else is // left justified. This means the memory address is adjusted forwards. if (ObjSize==1 || ObjSize==2) { @@ -1487,7 +1487,7 @@ PPCTargetLowering::LowerFORMAL_ARGUMENTS(SDOperand Op, case MVT::i32: if (!isPPC64) { // Double word align in ELF - if (Expand && isELF32_ABI) GPR_idx += (GPR_idx % 2); + if (Align && isELF32_ABI) GPR_idx += (GPR_idx % 2); if (GPR_idx != Num_GPR_Regs) { unsigned VReg = RegInfo.createVirtualRegister(&PPC::GPRCRegClass); @@ -1499,7 +1499,7 @@ PPCTargetLowering::LowerFORMAL_ARGUMENTS(SDOperand Op, ArgSize = PtrByteSize; } // Stack align in ELF - if (needsLoad && Expand && isELF32_ABI) + if (needsLoad && Align && isELF32_ABI) ArgOffset += ((ArgOffset/4) % 2) * PtrByteSize; // All int arguments reserve stack space in Macho ABI. if (isMachoABI || needsLoad) ArgOffset += PtrByteSize; @@ -1556,7 +1556,7 @@ PPCTargetLowering::LowerFORMAL_ARGUMENTS(SDOperand Op, } // Stack align in ELF - if (needsLoad && Expand && isELF32_ABI) + if (needsLoad && Align && isELF32_ABI) ArgOffset += ((ArgOffset/4) % 2) * PtrByteSize; // All FP arguments reserve stack space in Macho ABI. if (isMachoABI || needsLoad) ArgOffset += isPPC64 ? 8 : ObjSize; @@ -1855,14 +1855,14 @@ SDOperand PPCTargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG, ISD::ArgFlagsTy Flags = cast(Op.getOperand(5+2*i+1))->getArgFlags(); // See if next argument requires stack alignment in ELF - bool Expand = false; // TODO: implement this. + bool Align = Flags.isDivided(); // PtrOff will be used to store the current argument to the stack if a // register cannot be found for it. SDOperand PtrOff; // Stack align in ELF 32 - if (isELF32_ABI && Expand) + if (isELF32_ABI && Align) PtrOff = DAG.getConstant(ArgOffset + ((ArgOffset/4) % 2) * PtrByteSize, StackPtr.getValueType()); else @@ -1881,7 +1881,7 @@ SDOperand PPCTargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG, // FIXME memcpy is used way more than necessary. Correctness first. if (Flags.isByVal()) { unsigned Size = Flags.getByValSize(); - if (isELF32_ABI && Expand) GPR_idx += (GPR_idx % 2); + if (isELF32_ABI && Align) GPR_idx += (GPR_idx % 2); if (Size==1 || Size==2) { // Very small objects are passed right-justified. // Everything else is passed left-justified. @@ -1942,7 +1942,7 @@ SDOperand PPCTargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG, case MVT::i32: case MVT::i64: // Double word align in ELF - if (isELF32_ABI && Expand) GPR_idx += (GPR_idx % 2); + if (isELF32_ABI && Align) GPR_idx += (GPR_idx % 2); if (GPR_idx != NumGPRs) { RegsToPass.push_back(std::make_pair(GPR[GPR_idx++], Arg)); } else { @@ -1951,7 +1951,7 @@ SDOperand PPCTargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG, } if (inMem || isMachoABI) { // Stack align in ELF - if (isELF32_ABI && Expand) + if (isELF32_ABI && Align) ArgOffset += ((ArgOffset/4) % 2) * PtrByteSize; ArgOffset += PtrByteSize; @@ -1999,7 +1999,7 @@ SDOperand PPCTargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG, } if (inMem || isMachoABI) { // Stack align in ELF - if (isELF32_ABI && Expand) + if (isELF32_ABI && Align) ArgOffset += ((ArgOffset/4) % 2) * PtrByteSize; if (isPPC64) ArgOffset += 8; -- cgit v1.1