According to ARM EABI, 8-bytes function arguments must be 8-bytes aligned.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@34241 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Lauro Ramos Venancio 2007-02-13 14:07:13 +00:00
parent 7aa47b69ca
commit 876eaf1135
3 changed files with 63 additions and 30 deletions

View File

@ -338,29 +338,36 @@ static bool FPCCToARMCC(ISD::CondCode CC, ARMCC::CondCodes &CondCode,
}
static void
HowToPassArgument(MVT::ValueType ObjectVT,
unsigned NumGPRs, unsigned &ObjSize, unsigned &ObjGPRs) {
ObjSize = 0;
ObjGPRs = 0;
HowToPassArgument(MVT::ValueType ObjectVT, unsigned NumGPRs,
unsigned StackOffset, unsigned &NeededGPRs,
unsigned &NeededStackSize, unsigned &GPRPad,
unsigned &StackPad, unsigned Flags) {
NeededStackSize = 0;
NeededGPRs = 0;
StackPad = 0;
GPRPad = 0;
unsigned align = (Flags >> 27);
GPRPad = NumGPRs % ((align + 3)/4);
StackPad = StackOffset % align;
unsigned firstGPR = NumGPRs + GPRPad;
switch (ObjectVT) {
default: assert(0 && "Unhandled argument type!");
case MVT::i32:
case MVT::f32:
if (NumGPRs < 4)
ObjGPRs = 1;
if (firstGPR < 4)
NeededGPRs = 1;
else
ObjSize = 4;
NeededStackSize = 4;
break;
case MVT::i64:
case MVT::f64:
if (NumGPRs < 3)
ObjGPRs = 2;
else if (NumGPRs == 3) {
ObjGPRs = 1;
ObjSize = 4;
if (firstGPR < 3)
NeededGPRs = 2;
else if (firstGPR == 3) {
NeededGPRs = 1;
NeededStackSize = 4;
} else
ObjSize = 8;
NeededStackSize = 8;
}
}
@ -383,12 +390,16 @@ SDOperand ARMTargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG) {
// Add up all the space actually used.
for (unsigned i = 0; i < NumOps; ++i) {
unsigned ObjSize = 0;
unsigned ObjGPRs = 0;
unsigned ObjSize;
unsigned ObjGPRs;
unsigned StackPad;
unsigned GPRPad;
MVT::ValueType ObjectVT = Op.getOperand(5+2*i).getValueType();
HowToPassArgument(ObjectVT, NumGPRs, ObjSize, ObjGPRs);
NumBytes += ObjSize;
NumGPRs += ObjGPRs;
unsigned Flags = Op.getConstantOperandVal(5+2*i+1);
HowToPassArgument(ObjectVT, NumGPRs, NumBytes, ObjGPRs, ObjSize,
GPRPad, StackPad, Flags);
NumBytes += ObjSize + StackPad;
NumGPRs += ObjGPRs + GPRPad;
}
// Adjust the stack pointer for the new arguments...
@ -407,11 +418,17 @@ SDOperand ARMTargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG) {
std::vector<SDOperand> MemOpChains;
for (unsigned i = 0; i != NumOps; ++i) {
SDOperand Arg = Op.getOperand(5+2*i);
unsigned Flags = Op.getConstantOperandVal(5+2*i+1);
MVT::ValueType ArgVT = Arg.getValueType();
unsigned ObjSize = 0;
unsigned ObjGPRs = 0;
HowToPassArgument(ArgVT, NumGPRs, ObjSize, ObjGPRs);
unsigned ObjSize;
unsigned ObjGPRs;
unsigned GPRPad;
unsigned StackPad;
HowToPassArgument(ArgVT, NumGPRs, ArgOffset, ObjGPRs,
ObjSize, GPRPad, StackPad, Flags);
NumGPRs += GPRPad;
ArgOffset += StackPad;
if (ObjGPRs > 0) {
switch (ArgVT) {
default: assert(0 && "Unexpected ValueType for argument!");
@ -727,9 +744,15 @@ static SDOperand LowerFORMAL_ARGUMENT(SDOperand Op, SelectionDAG &DAG,
ARM::R0, ARM::R1, ARM::R2, ARM::R3
};
unsigned ObjSize = 0;
unsigned ObjGPRs = 0;
HowToPassArgument(ObjectVT, NumGPRs, ObjSize, ObjGPRs);
unsigned ObjSize;
unsigned ObjGPRs;
unsigned GPRPad;
unsigned StackPad;
unsigned Flags = Op.getConstantOperandVal(ArgNo + 3);
HowToPassArgument(ObjectVT, NumGPRs, ArgOffset, ObjGPRs,
ObjSize, GPRPad, StackPad, Flags);
NumGPRs += GPRPad;
ArgOffset += StackPad;
SDOperand ArgValue;
if (ObjGPRs == 1) {

View File

@ -39,8 +39,8 @@ ARMTargetMachine::ARMTargetMachine(const Module &M, const std::string &FS)
std::string("e-p:32:32-d:32:32-l:32:32-s:16:32-b:8:32-B:8:32-A:32") :
std::string("e-p:32:32-d:32:32-l:32:32")) :
(Subtarget.isThumb() ?
std::string("e-p:32:32-d:32:64-l:32:64-s:16:32-b:8:32-B:8:32-A:32") :
std::string("e-p:32:32-d:32:64-l:32:64"))),
std::string("e-p:32:32-d:32:64-l:64:64-s:16:32-b:8:32-B:8:32-A:32") :
std::string("e-p:32:32-d:32:64-l:64:64"))),
InstrInfo(Subtarget),
FrameInfo(Subtarget) {}

View File

@ -0,0 +1,10 @@
; RUN: llvm-as < %s | llc -march=arm &&
; RUN: llvm-as < %s | llc -mtriple=arm-linux | grep "mov r0, r2" | wc -l | grep 1 &&
; RUN: llvm-as < %s | llc -mtriple=arm-apple-darwin | grep "mov r0, r1" | wc -l | grep 1
define i32 @f(i32 %a, i64 %b) {
%tmp = call i32 @g(i64 %b)
ret i32 %tmp
}
declare i32 @g(i64)