[llvm-commits] Stack and register alignment in linux/ppc calls

Nicolas Geoffray nicolas.geoffray at lip6.fr
Fri Mar 9 01:51:53 PST 2007


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 at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>   




More information about the llvm-commits mailing list