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

2007-03-13 Thread Chris Lattner
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

2007-03-12 Thread Nicolas Geoffray
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

2007-03-09 Thread Nicolas Geoffray
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

2007-03-09 Thread Chris Lattner

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

2007-03-06 Thread Nicolas Geoffray
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

2007-03-06 Thread Nicolas Geoffray

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,
+