Changes in directory llvm/lib/Target/PowerPC:
PPCISelLowering.cpp updated: 1.261 -> 1.262 --- Log message: Stack and register alignment of call arguments in the ELF ABI --- Diffs of the changes: (+52 -6) PPCISelLowering.cpp | 58 ++++++++++++++++++++++++++++++++++++++++++++++------ 1 files changed, 52 insertions(+), 6 deletions(-) Index: llvm/lib/Target/PowerPC/PPCISelLowering.cpp diff -u llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.261 llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.262 --- llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.261 Mon Mar 12 18:29:01 2007 +++ llvm/lib/Target/PowerPC/PPCISelLowering.cpp Tue Mar 13 10:02:46 2007 @@ -1132,6 +1132,7 @@ 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); @@ -1163,17 +1164,30 @@ // 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 = cast<ConstantSDNode>(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) && + (cast<ConstantSDNode>(Op.getOperand(ArgNo+4))->getValue() & AlignFlag) && + (!(Flags & AlignFlag))); 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); @@ -1183,6 +1197,9 @@ 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; @@ -1204,7 +1221,7 @@ 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; @@ -1222,6 +1239,9 @@ 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; @@ -1324,6 +1344,7 @@ 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; @@ -1399,15 +1420,29 @@ 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(); + unsigned AlignFlag = 1 << ISD::ParamFlags::OrigAlignmentOffs; + // See if next argument requires stack alignment in ELF + unsigned next = 5+2*(i+1)+1; + bool Expand = (Arg.getValueType() == MVT::f64) || ((i + 1 < NumOps) && + (cast<ConstantSDNode>(Op.getOperand(next))->getValue() & AlignFlag) && + (!(Flags & AlignFlag))); + // 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); @@ -1417,13 +1452,21 @@ 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: @@ -1472,6 +1515,9 @@ inMem = true; } if (inMem || isMachoABI) { + // Stack align in ELF + if (isELF_ABI && Expand && !isPPC64) + ArgOffset += ((ArgOffset/4) % 2) * PtrByteSize; if (isPPC64) ArgOffset += 8; else @@ -1503,7 +1549,7 @@ } // 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