Re: [llvm-commits] Stack and register alignment in linux/ppc calls
On Mar 12, 2007, at 8:36 AM, Nicolas Geoffray wrote: Here's the final patch with the modifications you suggested. Thx a lot for your reviewing Chris. If everything's OK I'm checking this in soon. Looks great, please do. Please also check the sabre-ppc32 tester the day after this goes in, just to verify that there are no obvious darwin regressions. Thanks! -Chris Cheers, Nicolas Chris Lattner wrote: On Mar 6, 2007, at 10:03 AM, Nicolas Geoffray wrote: This patch corrects arguments passing alignment for linux/ppc calls (ELF ABI). It affects LowerFORMAL_ARGUMENTS and LowerCALL of PPCISelLowering.cpp. Sure, sorry for the delay. Please add some high-level comments that explain what is going on here (what the ABI says). I would eventually like to switch PPC over to using autogenerated callingconv code, but I haven't had a chance to finish argument passing. @@ -1164,24 +1165,34 @@ static SDOperand LowerFORMAL_ARGUMENTS(S SDOperand ArgVal; bool needsLoad = false; MVT::ValueType ObjectVT = Op.getValue(ArgNo).getValueType(); unsigned ObjSize = MVT::getSizeInBits(ObjectVT)/8; unsigned ArgSize = ObjSize; +unsigned Flags = castConstantSDNode(Op.getOperand(ArgNo +3))-getValue(); +// See if next argument requires stack alignment in ELF +unsigned Expand = (ObjectVT == MVT::f64) || ((ArgNo + 1 e) + (castConstantSDNode(Op.getOperand(ArgNo+4))-getValue() (1 27)) + (!(Flags (1 27; Please update this to use the enums that anton recently added for decoding the flags values. unsigned CurArgOffset = ArgOffset; switch (ObjectVT) { default: assert(0 Unhandled argument type!); case MVT::i32: + // Double word align in ELF + if (Expand !isELF_ABI !isPPC64) GPR_idx += (GPR_idx % 2); This says !isELF_ABI, shouldn't it be isELF_ABI? If not, you're modifying the Darwin/PPC ABI. - +unsigned Flags = castConstantSDNode(Op.getOperand(5+2*i +1))-getValue(); +// See if next argument requires stack alignment in ELF +unsigned Expand = (Arg.getValueType() == MVT::f64) || + ((i + 1 NumOps) + (castConstantSDNode(Op.getOperand(5+2*(i+1)+1))-getValue() + (1 27)) + (!(Flags (1 27; Likewise, plz use enums here. Also, there is some funky indentation going on here. Perhaps making a ConstantSDNode *Tmp would make this more natural. // PtrOff will be used to store the current argument to the stack if a // register cannot be found for it. -SDOperand PtrOff = DAG.getConstant(ArgOffset, StackPtr.getValueType()); +SDOperand PtrOff; + +// Stack align in ELF +if (isELF_ABI Expand !isPPC64) +PtrOff = DAG.getConstant(ArgOffset + ((ArgOffset/4) % 2) * PtrByteSize, +StackPtr.getValueType()); +else +PtrOff = DAG.getConstant(ArgOffset, StackPtr.getValueType ()); + Funky indentation. Statements should be indented by 2. Subexpressions (StackPtr.getValueType() should be aligned to the (. Otherwise, looks great, thanks! -Chris Index: PPCISelLowering.cpp === RCS file: /var/cvs/llvm/llvm/lib/Target/PowerPC/PPCISelLowering.cpp,v retrieving revision 1.260 diff -t -d -u -p -5 -r1.260 PPCISelLowering.cpp --- PPCISelLowering.cpp 6 Mar 2007 00:59:59 - 1.260 +++ PPCISelLowering.cpp 12 Mar 2007 15:39:25 - @@ -1130,10 +1130,11 @@ static SDOperand LowerFORMAL_ARGUMENTS(S SDOperand Root = Op.getOperand(0); MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); bool isPPC64 = PtrVT == MVT::i64; bool isMachoABI = Subtarget.isMachoABI(); + bool isELF_ABI = Subtarget.isELF_ABI(); unsigned PtrByteSize = isPPC64 ? 8 : 4; unsigned ArgOffset = PPCFrameInfo::getLinkageSize(isPPC64, isMachoABI); static const unsigned GPR_32[] = { // 32-bit registers. @@ -1161,30 +1162,46 @@ static SDOperand LowerFORMAL_ARGUMENTS(S const unsigned *GPR = isPPC64 ? GPR_64 : GPR_32; // Add DAG nodes to load the arguments or copy them out of registers. On // entry to a function on PPC, the arguments start after the linkage area, // although the first ones are often in registers. + // + // In the ELF 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. + for (unsigned ArgNo = 0, e = Op.Val-getNumValues()-1; ArgNo != e; ++ArgNo) { SDOperand ArgVal; bool needsLoad = false; MVT::ValueType ObjectVT = Op.getValue(ArgNo).getValueType(); unsigned ObjSize = MVT::getSizeInBits(ObjectVT)/8; unsigned ArgSize = ObjSize; +unsigned Flags = castConstantSDNode(Op.getOperand(ArgNo+3))-
Re: [llvm-commits] Stack and register alignment in linux/ppc calls
Here's the final patch with the modifications you suggested. Thx a lot for your reviewing Chris. If everything's OK I'm checking this in soon. Cheers, Nicolas Chris Lattner wrote: On Mar 6, 2007, at 10:03 AM, Nicolas Geoffray wrote: This patch corrects arguments passing alignment for linux/ppc calls (ELF ABI). It affects LowerFORMAL_ARGUMENTS and LowerCALL of PPCISelLowering.cpp. Sure, sorry for the delay. Please add some high-level comments that explain what is going on here (what the ABI says). I would eventually like to switch PPC over to using autogenerated callingconv code, but I haven't had a chance to finish argument passing. @@ -1164,24 +1165,34 @@ static SDOperand LowerFORMAL_ARGUMENTS(S SDOperand ArgVal; bool needsLoad = false; MVT::ValueType ObjectVT = Op.getValue(ArgNo).getValueType(); unsigned ObjSize = MVT::getSizeInBits(ObjectVT)/8; unsigned ArgSize = ObjSize; +unsigned Flags = castConstantSDNode(Op.getOperand(ArgNo+3))-getValue(); +// See if next argument requires stack alignment in ELF +unsigned Expand = (ObjectVT == MVT::f64) || ((ArgNo + 1 e) + (castConstantSDNode(Op.getOperand(ArgNo+4))-getValue() (1 27)) + (!(Flags (1 27; Please update this to use the enums that anton recently added for decoding the flags values. unsigned CurArgOffset = ArgOffset; switch (ObjectVT) { default: assert(0 Unhandled argument type!); case MVT::i32: + // Double word align in ELF + if (Expand !isELF_ABI !isPPC64) GPR_idx += (GPR_idx % 2); This says !isELF_ABI, shouldn't it be isELF_ABI? If not, you're modifying the Darwin/PPC ABI. - +unsigned Flags = castConstantSDNode(Op.getOperand(5+2*i+1))-getValue(); +// See if next argument requires stack alignment in ELF +unsigned Expand = (Arg.getValueType() == MVT::f64) || + ((i + 1 NumOps) + (castConstantSDNode(Op.getOperand(5+2*(i+1)+1))-getValue() + (1 27)) + (!(Flags (1 27; Likewise, plz use enums here. Also, there is some funky indentation going on here. Perhaps making a ConstantSDNode *Tmp would make this more natural. // PtrOff will be used to store the current argument to the stack if a // register cannot be found for it. -SDOperand PtrOff = DAG.getConstant(ArgOffset, StackPtr.getValueType()); +SDOperand PtrOff; + +// Stack align in ELF +if (isELF_ABI Expand !isPPC64) +PtrOff = DAG.getConstant(ArgOffset + ((ArgOffset/4) % 2) * PtrByteSize, +StackPtr.getValueType()); +else +PtrOff = DAG.getConstant(ArgOffset, StackPtr.getValueType()); + Funky indentation. Statements should be indented by 2. Subexpressions (StackPtr.getValueType() should be aligned to the (. Otherwise, looks great, thanks! -Chris Index: PPCISelLowering.cpp === RCS file: /var/cvs/llvm/llvm/lib/Target/PowerPC/PPCISelLowering.cpp,v retrieving revision 1.260 diff -t -d -u -p -5 -r1.260 PPCISelLowering.cpp --- PPCISelLowering.cpp 6 Mar 2007 00:59:59 - 1.260 +++ PPCISelLowering.cpp 12 Mar 2007 15:39:25 - @@ -1130,10 +1130,11 @@ static SDOperand LowerFORMAL_ARGUMENTS(S SDOperand Root = Op.getOperand(0); MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); bool isPPC64 = PtrVT == MVT::i64; bool isMachoABI = Subtarget.isMachoABI(); + bool isELF_ABI = Subtarget.isELF_ABI(); unsigned PtrByteSize = isPPC64 ? 8 : 4; unsigned ArgOffset = PPCFrameInfo::getLinkageSize(isPPC64, isMachoABI); static const unsigned GPR_32[] = { // 32-bit registers. @@ -1161,30 +1162,46 @@ static SDOperand LowerFORMAL_ARGUMENTS(S const unsigned *GPR = isPPC64 ? GPR_64 : GPR_32; // Add DAG nodes to load the arguments or copy them out of registers. On // entry to a function on PPC, the arguments start after the linkage area, // although the first ones are often in registers. + // + // In the ELF 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. + for (unsigned ArgNo = 0, e = Op.Val-getNumValues()-1; ArgNo != e; ++ArgNo) { SDOperand ArgVal; bool needsLoad = false; MVT::ValueType ObjectVT = Op.getValue(ArgNo).getValueType(); unsigned ObjSize = MVT::getSizeInBits(ObjectVT)/8; unsigned ArgSize = ObjSize; +unsigned Flags = castConstantSDNode(Op.getOperand(ArgNo+3))-getValue(); +unsigned AlignFlag = 1 ISD::ParamFlags::OrigAlignmentOffs; +// See if next argument requires stack alignment in ELF +bool Expand = (ObjectVT == MVT::f64) || ((ArgNo + 1 e) + (castConstantSDNode(Op.getOperand(ArgNo+4))-getValue() AlignFlag) + (!(Flags AlignFlag))); unsigned CurArgOffset = ArgOffset; switch
Re: [llvm-commits] Stack and register alignment in linux/ppc calls
If there is no objection, I'm checking this in. Nicolas Nicolas Geoffray wrote: Small mistake, here's the correct patch. Nicolas Nicolas Geoffray wrote: This patch corrects arguments passing alignment for linux/ppc calls (ELF ABI). It affects LowerFORMAL_ARGUMENTS and LowerCALL of PPCISelLowering.cpp. OK to commit? Index: PPCISelLowering.cpp === RCS file: /var/cvs/llvm/llvm/lib/Target/PowerPC/PPCISelLowering.cpp,v retrieving revision 1.259 diff -t -d -u -p -5 -r1.259 PPCISelLowering.cpp --- PPCISelLowering.cpp 1 Mar 2007 13:11:38 - 1.259 +++ PPCISelLowering.cpp 6 Mar 2007 18:09:01 - @@ -1127,10 +1127,11 @@ static SDOperand LowerFORMAL_ARGUMENTS(S SDOperand Root = Op.getOperand(0); MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); bool isPPC64 = PtrVT == MVT::i64; bool isMachoABI = Subtarget.isMachoABI(); + bool isELF_ABI = Subtarget.isELF_ABI(); unsigned PtrByteSize = isPPC64 ? 8 : 4; unsigned ArgOffset = PPCFrameInfo::getLinkageSize(isPPC64, isMachoABI); static const unsigned GPR_32[] = { // 32-bit registers. @@ -1164,24 +1165,34 @@ static SDOperand LowerFORMAL_ARGUMENTS(S SDOperand ArgVal; bool needsLoad = false; MVT::ValueType ObjectVT = Op.getValue(ArgNo).getValueType(); unsigned ObjSize = MVT::getSizeInBits(ObjectVT)/8; unsigned ArgSize = ObjSize; +unsigned Flags = castConstantSDNode(Op.getOperand(ArgNo+3))-getValue(); +// See if next argument requires stack alignment in ELF +unsigned Expand = (ObjectVT == MVT::f64) || ((ArgNo + 1 e) + (castConstantSDNode(Op.getOperand(ArgNo+4))-getValue() (1 27)) + (!(Flags (1 27; unsigned CurArgOffset = ArgOffset; switch (ObjectVT) { default: assert(0 Unhandled argument type!); case MVT::i32: + // Double word align in ELF + if (Expand isELF_ABI !isPPC64) GPR_idx += (GPR_idx % 2); if (GPR_idx != Num_GPR_Regs) { unsigned VReg = RegMap-createVirtualRegister(PPC::GPRCRegClass); MF.addLiveIn(GPR[GPR_idx], VReg); ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::i32); ++GPR_idx; } else { needsLoad = true; ArgSize = PtrByteSize; } + // Stack align in ELF + if (needsLoad Expand isELF_ABI !isPPC64) +ArgOffset += ((ArgOffset/4) % 2) * PtrByteSize; // All int arguments reserve stack space in Macho ABI. if (isMachoABI || needsLoad) ArgOffset += PtrByteSize; break; case MVT::i64: // PPC64 @@ -1199,11 +1210,11 @@ static SDOperand LowerFORMAL_ARGUMENTS(S case MVT::f32: case MVT::f64: // Every 4 bytes of argument space consumes one of the GPRs available for // argument passing. - if (GPR_idx != Num_GPR_Regs) { + if (GPR_idx != Num_GPR_Regs isMachoABI) { ++GPR_idx; if (ObjSize == 8 GPR_idx != Num_GPR_Regs !isPPC64) ++GPR_idx; } if (FPR_idx != Num_FPR_Regs) { @@ -1217,10 +1228,13 @@ static SDOperand LowerFORMAL_ARGUMENTS(S ++FPR_idx; } else { needsLoad = true; } + // Stack align in ELF + if (needsLoad Expand isELF_ABI !isPPC64) +ArgOffset += ((ArgOffset/4) % 2) * PtrByteSize; // All FP arguments reserve stack space in Macho ABI. if (isMachoABI || needsLoad) ArgOffset += isPPC64 ? 8 : ObjSize; break; case MVT::v4f32: case MVT::v4i32: @@ -1319,10 +1333,11 @@ static SDOperand LowerCALL(SDOperand Op, bool isVarArg= castConstantSDNode(Op.getOperand(2))-getValue() != 0; SDOperand Callee = Op.getOperand(4); unsigned NumOps = (Op.getNumOperands() - 5) / 2; bool isMachoABI = Subtarget.isMachoABI(); + bool isELF_ABI = Subtarget.isELF_ABI(); MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); bool isPPC64 = PtrVT == MVT::i64; unsigned PtrByteSize = isPPC64 ? 8 : 4; @@ -1394,35 +1409,58 @@ static SDOperand LowerCALL(SDOperand Op, std::vectorstd::pairunsigned, SDOperand RegsToPass; SmallVectorSDOperand, 8 MemOpChains; for (unsigned i = 0; i != NumOps; ++i) { bool inMem = false; SDOperand Arg = Op.getOperand(5+2*i); - +unsigned Flags = castConstantSDNode(Op.getOperand(5+2*i+1))-getValue(); +// See if next argument requires stack alignment in ELF +unsigned Expand = (Arg.getValueType() == MVT::f64) || + ((i + 1 NumOps) + (castConstantSDNode(Op.getOperand(5+2*(i+1)+1))-getValue() + (1 27)) + (!(Flags (1 27; + // PtrOff will be used to store the current argument to the stack if a
Re: [llvm-commits] Stack and register alignment in linux/ppc calls
On Mar 6, 2007, at 10:03 AM, Nicolas Geoffray wrote: This patch corrects arguments passing alignment for linux/ppc calls (ELF ABI). It affects LowerFORMAL_ARGUMENTS and LowerCALL of PPCISelLowering.cpp. Sure, sorry for the delay. Please add some high-level comments that explain what is going on here (what the ABI says). I would eventually like to switch PPC over to using autogenerated callingconv code, but I haven't had a chance to finish argument passing. @@ -1164,24 +1165,34 @@ static SDOperand LowerFORMAL_ARGUMENTS(S SDOperand ArgVal; bool needsLoad = false; MVT::ValueType ObjectVT = Op.getValue(ArgNo).getValueType(); unsigned ObjSize = MVT::getSizeInBits(ObjectVT)/8; unsigned ArgSize = ObjSize; +unsigned Flags = castConstantSDNode(Op.getOperand(ArgNo+3))- getValue(); +// See if next argument requires stack alignment in ELF +unsigned Expand = (ObjectVT == MVT::f64) || ((ArgNo + 1 e) + (castConstantSDNode(Op.getOperand(ArgNo+4))-getValue() (1 27)) + (!(Flags (1 27; Please update this to use the enums that anton recently added for decoding the flags values. unsigned CurArgOffset = ArgOffset; switch (ObjectVT) { default: assert(0 Unhandled argument type!); case MVT::i32: + // Double word align in ELF + if (Expand !isELF_ABI !isPPC64) GPR_idx += (GPR_idx % 2); This says !isELF_ABI, shouldn't it be isELF_ABI? If not, you're modifying the Darwin/PPC ABI. - +unsigned Flags = castConstantSDNode(Op.getOperand(5+2*i+1))- getValue(); +// See if next argument requires stack alignment in ELF +unsigned Expand = (Arg.getValueType() == MVT::f64) || + ((i + 1 NumOps) + (castConstantSDNode(Op.getOperand(5+2*(i+1)+1))-getValue() + (1 27)) + (!(Flags (1 27; Likewise, plz use enums here. Also, there is some funky indentation going on here. Perhaps making a ConstantSDNode *Tmp would make this more natural. // PtrOff will be used to store the current argument to the stack if a // register cannot be found for it. -SDOperand PtrOff = DAG.getConstant(ArgOffset, StackPtr.getValueType()); +SDOperand PtrOff; + +// Stack align in ELF +if (isELF_ABI Expand !isPPC64) +PtrOff = DAG.getConstant(ArgOffset + ((ArgOffset/4) % 2) * PtrByteSize, +StackPtr.getValueType()); +else +PtrOff = DAG.getConstant(ArgOffset, StackPtr.getValueType()); + Funky indentation. Statements should be indented by 2. Subexpressions (StackPtr.getValueType() should be aligned to the (. Otherwise, looks great, thanks! -Chris ___ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
[llvm-commits] Stack and register alignment in linux/ppc calls
This patch corrects arguments passing alignment for linux/ppc calls (ELF ABI). It affects LowerFORMAL_ARGUMENTS and LowerCALL of PPCISelLowering.cpp. OK to commit? Index: PPCISelLowering.cpp === RCS file: /var/cvs/llvm/llvm/lib/Target/PowerPC/PPCISelLowering.cpp,v retrieving revision 1.259 diff -t -d -u -p -5 -r1.259 PPCISelLowering.cpp --- PPCISelLowering.cpp 1 Mar 2007 13:11:38 - 1.259 +++ PPCISelLowering.cpp 6 Mar 2007 17:57:47 - @@ -1127,10 +1127,11 @@ static SDOperand LowerFORMAL_ARGUMENTS(S SDOperand Root = Op.getOperand(0); MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); bool isPPC64 = PtrVT == MVT::i64; bool isMachoABI = Subtarget.isMachoABI(); + bool isELF_ABI = Subtarget.isELF_ABI(); unsigned PtrByteSize = isPPC64 ? 8 : 4; unsigned ArgOffset = PPCFrameInfo::getLinkageSize(isPPC64, isMachoABI); static const unsigned GPR_32[] = { // 32-bit registers. @@ -1164,24 +1165,34 @@ static SDOperand LowerFORMAL_ARGUMENTS(S SDOperand ArgVal; bool needsLoad = false; MVT::ValueType ObjectVT = Op.getValue(ArgNo).getValueType(); unsigned ObjSize = MVT::getSizeInBits(ObjectVT)/8; unsigned ArgSize = ObjSize; +unsigned Flags = castConstantSDNode(Op.getOperand(ArgNo+3))-getValue(); +// See if next argument requires stack alignment in ELF +unsigned Expand = (ObjectVT == MVT::f64) || ((ArgNo + 1 e) + (castConstantSDNode(Op.getOperand(ArgNo+4))-getValue() (1 27)) + (!(Flags (1 27; unsigned CurArgOffset = ArgOffset; switch (ObjectVT) { default: assert(0 Unhandled argument type!); case MVT::i32: + // Double word align in ELF + if (Expand !isELF_ABI !isPPC64) GPR_idx += (GPR_idx % 2); if (GPR_idx != Num_GPR_Regs) { unsigned VReg = RegMap-createVirtualRegister(PPC::GPRCRegClass); MF.addLiveIn(GPR[GPR_idx], VReg); ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::i32); ++GPR_idx; } else { needsLoad = true; ArgSize = PtrByteSize; } + // Stack align in ELF + if (needsLoad Expand isELF_ABI !isPPC64) +ArgOffset += ((ArgOffset/4) % 2) * PtrByteSize; // All int arguments reserve stack space in Macho ABI. if (isMachoABI || needsLoad) ArgOffset += PtrByteSize; break; case MVT::i64: // PPC64 @@ -1199,11 +1210,11 @@ static SDOperand LowerFORMAL_ARGUMENTS(S case MVT::f32: case MVT::f64: // Every 4 bytes of argument space consumes one of the GPRs available for // argument passing. - if (GPR_idx != Num_GPR_Regs) { + if (GPR_idx != Num_GPR_Regs isMachoABI) { ++GPR_idx; if (ObjSize == 8 GPR_idx != Num_GPR_Regs !isPPC64) ++GPR_idx; } if (FPR_idx != Num_FPR_Regs) { @@ -1217,10 +1228,13 @@ static SDOperand LowerFORMAL_ARGUMENTS(S ++FPR_idx; } else { needsLoad = true; } + // Stack align in ELF + if (needsLoad Expand isELF_ABI !isPPC64) +ArgOffset += ((ArgOffset/4) % 2) * PtrByteSize; // All FP arguments reserve stack space in Macho ABI. if (isMachoABI || needsLoad) ArgOffset += isPPC64 ? 8 : ObjSize; break; case MVT::v4f32: case MVT::v4i32: @@ -1319,10 +1333,11 @@ static SDOperand LowerCALL(SDOperand Op, bool isVarArg= castConstantSDNode(Op.getOperand(2))-getValue() != 0; SDOperand Callee = Op.getOperand(4); unsigned NumOps = (Op.getNumOperands() - 5) / 2; bool isMachoABI = Subtarget.isMachoABI(); + bool isELF_ABI = Subtarget.isELF_ABI(); MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); bool isPPC64 = PtrVT == MVT::i64; unsigned PtrByteSize = isPPC64 ? 8 : 4; @@ -1394,35 +1409,58 @@ static SDOperand LowerCALL(SDOperand Op, std::vectorstd::pairunsigned, SDOperand RegsToPass; SmallVectorSDOperand, 8 MemOpChains; for (unsigned i = 0; i != NumOps; ++i) { bool inMem = false; SDOperand Arg = Op.getOperand(5+2*i); - +unsigned Flags = castConstantSDNode(Op.getOperand(5+2*i+1))-getValue(); +// See if next argument requires stack alignment in ELF +unsigned Expand = (Arg.getValueType() == MVT::f64) || + ((i + 1 NumOps) + (castConstantSDNode(Op.getOperand(5+2*(i+1)+1))-getValue() + (1 27)) + (!(Flags (1 27; + // PtrOff will be used to store the current argument to the stack if a // register cannot be found for it. -SDOperand PtrOff = DAG.getConstant(ArgOffset, StackPtr.getValueType()); +SDOperand PtrOff; + +// Stack align in ELF +if (isELF_ABI Expand !isPPC64) +PtrOff = DAG.getConstant(ArgOffset + ((ArgOffset/4) % 2) * PtrByteSize, +StackPtr.getValueType()); +else +PtrOff =
Re: [llvm-commits] Stack and register alignment in linux/ppc calls
Small mistake, here's the correct patch. Nicolas Nicolas Geoffray wrote: This patch corrects arguments passing alignment for linux/ppc calls (ELF ABI). It affects LowerFORMAL_ARGUMENTS and LowerCALL of PPCISelLowering.cpp. OK to commit? Index: PPCISelLowering.cpp === RCS file: /var/cvs/llvm/llvm/lib/Target/PowerPC/PPCISelLowering.cpp,v retrieving revision 1.259 diff -t -d -u -p -5 -r1.259 PPCISelLowering.cpp --- PPCISelLowering.cpp 1 Mar 2007 13:11:38 - 1.259 +++ PPCISelLowering.cpp 6 Mar 2007 18:09:01 - @@ -1127,10 +1127,11 @@ static SDOperand LowerFORMAL_ARGUMENTS(S SDOperand Root = Op.getOperand(0); MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); bool isPPC64 = PtrVT == MVT::i64; bool isMachoABI = Subtarget.isMachoABI(); + bool isELF_ABI = Subtarget.isELF_ABI(); unsigned PtrByteSize = isPPC64 ? 8 : 4; unsigned ArgOffset = PPCFrameInfo::getLinkageSize(isPPC64, isMachoABI); static const unsigned GPR_32[] = { // 32-bit registers. @@ -1164,24 +1165,34 @@ static SDOperand LowerFORMAL_ARGUMENTS(S SDOperand ArgVal; bool needsLoad = false; MVT::ValueType ObjectVT = Op.getValue(ArgNo).getValueType(); unsigned ObjSize = MVT::getSizeInBits(ObjectVT)/8; unsigned ArgSize = ObjSize; +unsigned Flags = castConstantSDNode(Op.getOperand(ArgNo+3))-getValue(); +// See if next argument requires stack alignment in ELF +unsigned Expand = (ObjectVT == MVT::f64) || ((ArgNo + 1 e) + (castConstantSDNode(Op.getOperand(ArgNo+4))-getValue() (1 27)) + (!(Flags (1 27; unsigned CurArgOffset = ArgOffset; switch (ObjectVT) { default: assert(0 Unhandled argument type!); case MVT::i32: + // Double word align in ELF + if (Expand isELF_ABI !isPPC64) GPR_idx += (GPR_idx % 2); if (GPR_idx != Num_GPR_Regs) { unsigned VReg = RegMap-createVirtualRegister(PPC::GPRCRegClass); MF.addLiveIn(GPR[GPR_idx], VReg); ArgVal = DAG.getCopyFromReg(Root, VReg, MVT::i32); ++GPR_idx; } else { needsLoad = true; ArgSize = PtrByteSize; } + // Stack align in ELF + if (needsLoad Expand isELF_ABI !isPPC64) +ArgOffset += ((ArgOffset/4) % 2) * PtrByteSize; // All int arguments reserve stack space in Macho ABI. if (isMachoABI || needsLoad) ArgOffset += PtrByteSize; break; case MVT::i64: // PPC64 @@ -1199,11 +1210,11 @@ static SDOperand LowerFORMAL_ARGUMENTS(S case MVT::f32: case MVT::f64: // Every 4 bytes of argument space consumes one of the GPRs available for // argument passing. - if (GPR_idx != Num_GPR_Regs) { + if (GPR_idx != Num_GPR_Regs isMachoABI) { ++GPR_idx; if (ObjSize == 8 GPR_idx != Num_GPR_Regs !isPPC64) ++GPR_idx; } if (FPR_idx != Num_FPR_Regs) { @@ -1217,10 +1228,13 @@ static SDOperand LowerFORMAL_ARGUMENTS(S ++FPR_idx; } else { needsLoad = true; } + // Stack align in ELF + if (needsLoad Expand isELF_ABI !isPPC64) +ArgOffset += ((ArgOffset/4) % 2) * PtrByteSize; // All FP arguments reserve stack space in Macho ABI. if (isMachoABI || needsLoad) ArgOffset += isPPC64 ? 8 : ObjSize; break; case MVT::v4f32: case MVT::v4i32: @@ -1319,10 +1333,11 @@ static SDOperand LowerCALL(SDOperand Op, bool isVarArg= castConstantSDNode(Op.getOperand(2))-getValue() != 0; SDOperand Callee = Op.getOperand(4); unsigned NumOps = (Op.getNumOperands() - 5) / 2; bool isMachoABI = Subtarget.isMachoABI(); + bool isELF_ABI = Subtarget.isELF_ABI(); MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); bool isPPC64 = PtrVT == MVT::i64; unsigned PtrByteSize = isPPC64 ? 8 : 4; @@ -1394,35 +1409,58 @@ static SDOperand LowerCALL(SDOperand Op, std::vectorstd::pairunsigned, SDOperand RegsToPass; SmallVectorSDOperand, 8 MemOpChains; for (unsigned i = 0; i != NumOps; ++i) { bool inMem = false; SDOperand Arg = Op.getOperand(5+2*i); - +unsigned Flags = castConstantSDNode(Op.getOperand(5+2*i+1))-getValue(); +// See if next argument requires stack alignment in ELF +unsigned Expand = (Arg.getValueType() == MVT::f64) || + ((i + 1 NumOps) + (castConstantSDNode(Op.getOperand(5+2*(i+1)+1))-getValue() + (1 27)) + (!(Flags (1 27; + // PtrOff will be used to store the current argument to the stack if a // register cannot be found for it. -SDOperand PtrOff = DAG.getConstant(ArgOffset, StackPtr.getValueType()); +SDOperand PtrOff; + +// Stack align in ELF +if (isELF_ABI Expand !isPPC64) +PtrOff = DAG.getConstant(ArgOffset + ((ArgOffset/4) % 2) * PtrByteSize, +