mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-08-08 19:25:47 +00:00
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:
@@ -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) {
|
||||||
|
@@ -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) {}
|
||||||
|
|
||||||
|
10
test/CodeGen/ARM/arguments.ll
Normal file
10
test/CodeGen/ARM/arguments.ll
Normal 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)
|
Reference in New Issue
Block a user