aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLauro Ramos Venancio <lauro.venancio@gmail.com>2007-02-13 14:07:13 +0000
committerLauro Ramos Venancio <lauro.venancio@gmail.com>2007-02-13 14:07:13 +0000
commit876eaf1135b40869f59fb27c87a7d626459e9181 (patch)
tree8798ba5674b8f98d1bbb5a62d630db7ca52db447
parent7aa47b69ca5f4feb6b106a50959e37822bd25b4f (diff)
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
-rw-r--r--lib/Target/ARM/ARMISelLowering.cpp79
-rw-r--r--lib/Target/ARM/ARMTargetMachine.cpp4
-rw-r--r--test/CodeGen/ARM/arguments.ll10
3 files changed, 63 insertions, 30 deletions
diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp
index 00dc378ddf..90d02b82cf 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<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!");
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 0b74348721..442d25ecc2 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 0000000000..77cadd6fdf
--- /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