From 876eaf1135b40869f59fb27c87a7d626459e9181 Mon Sep 17 00:00:00 2001 From: Lauro Ramos Venancio Date: Tue, 13 Feb 2007 14:07:13 +0000 Subject: [PATCH] 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 --- lib/Target/ARM/ARMISelLowering.cpp | 79 +++++++++++++++++++---------- lib/Target/ARM/ARMTargetMachine.cpp | 4 +- test/CodeGen/ARM/arguments.ll | 10 ++++ 3 files changed, 63 insertions(+), 30 deletions(-) create mode 100644 test/CodeGen/ARM/arguments.ll diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp index 00dc378ddfb..90d02b82cf6 100644 --- a/lib/Target/ARM/ARMISelLowering.cpp +++ b/lib/Target/ARM/ARMISelLowering.cpp @@ -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,18 +418,24 @@ SDOperand ARMTargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG) { std::vector 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!"); case MVT::i32: RegsToPass.push_back(std::make_pair(GPRArgRegs[NumGPRs], Arg)); break; - case MVT::f32: + case MVT::f32: RegsToPass.push_back(std::make_pair(GPRArgRegs[NumGPRs], DAG.getNode(ISD::BIT_CONVERT, MVT::i32, Arg))); break; @@ -436,7 +453,7 @@ SDOperand ARMTargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG) { MemOpChains.push_back(DAG.getStore(Chain, Hi, PtrOff, NULL, 0)); } break; - } + } case MVT::f64: { SDOperand Cvt = DAG.getNode(ARMISD::FMRRD, 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, - unsigned *vRegs, unsigned ArgNo, + unsigned *vRegs, unsigned ArgNo, unsigned &NumGPRs, unsigned &ArgOffset) { MachineFunction &MF = DAG.getMachineFunction(); 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 }; - 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) { diff --git a/lib/Target/ARM/ARMTargetMachine.cpp b/lib/Target/ARM/ARMTargetMachine.cpp index 0b743487213..442d25ecc25 100644 --- a/lib/Target/ARM/ARMTargetMachine.cpp +++ b/lib/Target/ARM/ARMTargetMachine.cpp @@ -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) {} diff --git a/test/CodeGen/ARM/arguments.ll b/test/CodeGen/ARM/arguments.ll new file mode 100644 index 00000000000..77cadd6fdfb --- /dev/null +++ b/test/CodeGen/ARM/arguments.ll @@ -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) \ No newline at end of file