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 static void
HowToPassArgument(MVT::ValueType ObjectVT, HowToPassArgument(MVT::ValueType ObjectVT, unsigned NumGPRs,
unsigned NumGPRs, unsigned &ObjSize, unsigned &ObjGPRs) { unsigned StackOffset, unsigned &NeededGPRs,
ObjSize = 0; unsigned &NeededStackSize, unsigned &GPRPad,
ObjGPRs = 0; 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) { switch (ObjectVT) {
default: assert(0 && "Unhandled argument type!"); default: assert(0 && "Unhandled argument type!");
case MVT::i32: case MVT::i32:
case MVT::f32: case MVT::f32:
if (NumGPRs < 4) if (firstGPR < 4)
ObjGPRs = 1; NeededGPRs = 1;
else else
ObjSize = 4; NeededStackSize = 4;
break; break;
case MVT::i64: case MVT::i64:
case MVT::f64: case MVT::f64:
if (NumGPRs < 3) if (firstGPR < 3)
ObjGPRs = 2; NeededGPRs = 2;
else if (NumGPRs == 3) { else if (firstGPR == 3) {
ObjGPRs = 1; NeededGPRs = 1;
ObjSize = 4; NeededStackSize = 4;
} else } else
ObjSize = 8; NeededStackSize = 8;
} }
} }
@@ -383,12 +390,16 @@ SDOperand ARMTargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG) {
// Add up all the space actually used. // Add up all the space actually used.
for (unsigned i = 0; i < NumOps; ++i) { for (unsigned i = 0; i < NumOps; ++i) {
unsigned ObjSize = 0; unsigned ObjSize;
unsigned ObjGPRs = 0; unsigned ObjGPRs;
unsigned StackPad;
unsigned GPRPad;
MVT::ValueType ObjectVT = Op.getOperand(5+2*i).getValueType(); MVT::ValueType ObjectVT = Op.getOperand(5+2*i).getValueType();
HowToPassArgument(ObjectVT, NumGPRs, ObjSize, ObjGPRs); unsigned Flags = Op.getConstantOperandVal(5+2*i+1);
NumBytes += ObjSize; HowToPassArgument(ObjectVT, NumGPRs, NumBytes, ObjGPRs, ObjSize,
NumGPRs += ObjGPRs; GPRPad, StackPad, Flags);
NumBytes += ObjSize + StackPad;
NumGPRs += ObjGPRs + GPRPad;
} }
// Adjust the stack pointer for the new arguments... // Adjust the stack pointer for the new arguments...
@@ -407,18 +418,24 @@ SDOperand ARMTargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG) {
std::vector<SDOperand> MemOpChains; std::vector<SDOperand> MemOpChains;
for (unsigned i = 0; i != NumOps; ++i) { for (unsigned i = 0; i != NumOps; ++i) {
SDOperand Arg = Op.getOperand(5+2*i); SDOperand Arg = Op.getOperand(5+2*i);
unsigned Flags = Op.getConstantOperandVal(5+2*i+1);
MVT::ValueType ArgVT = Arg.getValueType(); MVT::ValueType ArgVT = Arg.getValueType();
unsigned ObjSize = 0; unsigned ObjSize;
unsigned ObjGPRs = 0; unsigned ObjGPRs;
HowToPassArgument(ArgVT, NumGPRs, ObjSize, ObjGPRs); unsigned GPRPad;
unsigned StackPad;
HowToPassArgument(ArgVT, NumGPRs, ArgOffset, ObjGPRs,
ObjSize, GPRPad, StackPad, Flags);
NumGPRs += GPRPad;
ArgOffset += StackPad;
if (ObjGPRs > 0) { if (ObjGPRs > 0) {
switch (ArgVT) { switch (ArgVT) {
default: assert(0 && "Unexpected ValueType for argument!"); default: assert(0 && "Unexpected ValueType for argument!");
case MVT::i32: case MVT::i32:
RegsToPass.push_back(std::make_pair(GPRArgRegs[NumGPRs], Arg)); RegsToPass.push_back(std::make_pair(GPRArgRegs[NumGPRs], Arg));
break; break;
case MVT::f32: case MVT::f32:
RegsToPass.push_back(std::make_pair(GPRArgRegs[NumGPRs], RegsToPass.push_back(std::make_pair(GPRArgRegs[NumGPRs],
DAG.getNode(ISD::BIT_CONVERT, MVT::i32, Arg))); DAG.getNode(ISD::BIT_CONVERT, MVT::i32, Arg)));
break; break;
@@ -436,7 +453,7 @@ SDOperand ARMTargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG) {
MemOpChains.push_back(DAG.getStore(Chain, Hi, PtrOff, NULL, 0)); MemOpChains.push_back(DAG.getStore(Chain, Hi, PtrOff, NULL, 0));
} }
break; break;
} }
case MVT::f64: { case MVT::f64: {
SDOperand Cvt = DAG.getNode(ARMISD::FMRRD, SDOperand Cvt = DAG.getNode(ARMISD::FMRRD,
DAG.getVTList(MVT::i32, MVT::i32), DAG.getVTList(MVT::i32, MVT::i32),
@@ -715,7 +732,7 @@ static SDOperand LowerVASTART(SDOperand Op, SelectionDAG &DAG,
} }
static SDOperand LowerFORMAL_ARGUMENT(SDOperand Op, SelectionDAG &DAG, static SDOperand LowerFORMAL_ARGUMENT(SDOperand Op, SelectionDAG &DAG,
unsigned *vRegs, unsigned ArgNo, unsigned *vRegs, unsigned ArgNo,
unsigned &NumGPRs, unsigned &ArgOffset) { unsigned &NumGPRs, unsigned &ArgOffset) {
MachineFunction &MF = DAG.getMachineFunction(); MachineFunction &MF = DAG.getMachineFunction();
MVT::ValueType ObjectVT = Op.getValue(ArgNo).getValueType(); MVT::ValueType ObjectVT = Op.getValue(ArgNo).getValueType();
@@ -727,9 +744,15 @@ static SDOperand LowerFORMAL_ARGUMENT(SDOperand Op, SelectionDAG &DAG,
ARM::R0, ARM::R1, ARM::R2, ARM::R3 ARM::R0, ARM::R1, ARM::R2, ARM::R3
}; };
unsigned ObjSize = 0; unsigned ObjSize;
unsigned ObjGPRs = 0; unsigned ObjGPRs;
HowToPassArgument(ObjectVT, NumGPRs, ObjSize, 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; SDOperand ArgValue;
if (ObjGPRs == 1) { 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-s:16:32-b:8:32-B:8:32-A:32") :
std::string("e-p:32:32-d:32:32-l:32:32")) : std::string("e-p:32:32-d:32:32-l:32:32")) :
(Subtarget.isThumb() ? (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:64: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"))),
InstrInfo(Subtarget), InstrInfo(Subtarget),
FrameInfo(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)