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 -0000 1.259 > +++ PPCISelLowering.cpp 6 Mar 2007 18:09:01 -0000 > @@ -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 = > cast<ConstantSDNode>(Op.getOperand(ArgNo+3))->getValue(); > + // See if next argument requires stack alignment in ELF > + unsigned Expand = (ObjectVT == MVT::f64) || ((ArgNo + 1 < e) && > + (cast<ConstantSDNode>(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 = cast<ConstantSDNode>(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::vector<std::pair<unsigned, SDOperand> > RegsToPass; > SmallVector<SDOperand, 8> MemOpChains; > for (unsigned i = 0; i != NumOps; ++i) { > bool inMem = false; > SDOperand Arg = Op.getOperand(5+2*i); > - > + unsigned Flags = > cast<ConstantSDNode>(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) && > + (cast<ConstantSDNode>(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 = DAG.getConstant(ArgOffset, StackPtr.getValueType()); > + > PtrOff = DAG.getNode(ISD::ADD, PtrVT, StackPtr, PtrOff); > > // On PPC64, promote integers to 64-bit values. > if (isPPC64 && Arg.getValueType() == MVT::i32) { > - unsigned Flags = > cast<ConstantSDNode>(Op.getOperand(5+2*i+1))->getValue(); > unsigned ExtOp = (Flags & 1) ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND; > > Arg = DAG.getNode(ExtOp, MVT::i64, Arg); > } > > switch (Arg.getValueType()) { > default: assert(0 && "Unexpected ValueType for argument!"); > case MVT::i32: > case MVT::i64: > + // Double word align in ELF > + if (isELF_ABI && Expand && !isPPC64) GPR_idx += (GPR_idx % 2); > if (GPR_idx != NumGPRs) { > RegsToPass.push_back(std::make_pair(GPR[GPR_idx++], Arg)); > } else { > MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0)); > inMem = true; > } > - if (inMem || isMachoABI) ArgOffset += PtrByteSize; > + if (inMem || isMachoABI) > + { > + // Stack align in ELF > + if (isELF_ABI && Expand && !isPPC64) > + ArgOffset += ((ArgOffset/4) % 2) * PtrByteSize; > + > + ArgOffset += PtrByteSize; > + } > break; > case MVT::f32: > case MVT::f64: > if (isVarArg) { > // Float varargs need to be promoted to double. > @@ -1467,10 +1505,13 @@ static SDOperand LowerCALL(SDOperand Op, > } else { > MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0)); > inMem = true; > } > if (inMem || isMachoABI) { > + // Stack align in ELF > + if (isELF_ABI && Expand && !isPPC64) > + ArgOffset += ((ArgOffset/4) % 2) * PtrByteSize; > if (isPPC64) > ArgOffset += 8; > else > ArgOffset += Arg.getValueType() == MVT::f32 ? 4 : 8; > } > @@ -1498,11 +1539,11 @@ static SDOperand LowerCALL(SDOperand Op, > InFlag); > InFlag = Chain.getValue(1); > } > > // With the ELF ABI, set CR6 to true if this is a vararg call. > - if (isVarArg && !isMachoABI) { > + if (isVarArg && isELF_ABI) { > SDOperand SetCR(DAG.getTargetNode(PPC::SETCR, MVT::i32), 0); > Chain = DAG.getCopyToReg(Chain, PPC::CR6, SetCR, InFlag); > InFlag = Chain.getValue(1); > } > > > ------------------------------------------------------------------------ > > _______________________________________________ > llvm-commits mailing list > llvm-commits@cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits