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