mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-06 06:33:24 +00:00
Add support for byval args. Patch by Job Noorman!
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@168439 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
6ee1e0867d
commit
6cbeb4d839
@ -24,6 +24,9 @@ def RetCC_MSP430 : CallingConv<[
|
|||||||
// MSP430 Argument Calling Conventions
|
// MSP430 Argument Calling Conventions
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
def CC_MSP430 : CallingConv<[
|
def CC_MSP430 : CallingConv<[
|
||||||
|
// Pass by value if the byval attribute is given
|
||||||
|
CCIfByVal<CCPassByVal<2, 2>>,
|
||||||
|
|
||||||
// Promote i8 arguments to i16.
|
// Promote i8 arguments to i16.
|
||||||
CCIfType<[i8], CCPromoteToType<i16>>,
|
CCIfType<[i8], CCPromoteToType<i16>>,
|
||||||
|
|
||||||
|
@ -357,6 +357,15 @@ MSP430TargetLowering::LowerCCCArguments(SDValue Chain,
|
|||||||
} else {
|
} else {
|
||||||
// Sanity check
|
// Sanity check
|
||||||
assert(VA.isMemLoc());
|
assert(VA.isMemLoc());
|
||||||
|
|
||||||
|
SDValue InVal;
|
||||||
|
ISD::ArgFlagsTy Flags = Ins[i].Flags;
|
||||||
|
|
||||||
|
if (Flags.isByVal()) {
|
||||||
|
int FI = MFI->CreateFixedObject(Flags.getByValSize(),
|
||||||
|
VA.getLocMemOffset(), true);
|
||||||
|
InVal = DAG.getFrameIndex(FI, getPointerTy());
|
||||||
|
} else {
|
||||||
// Load the argument to a virtual register
|
// Load the argument to a virtual register
|
||||||
unsigned ObjSize = VA.getLocVT().getSizeInBits()/8;
|
unsigned ObjSize = VA.getLocVT().getSizeInBits()/8;
|
||||||
if (ObjSize > 2) {
|
if (ObjSize > 2) {
|
||||||
@ -370,9 +379,12 @@ MSP430TargetLowering::LowerCCCArguments(SDValue Chain,
|
|||||||
// Create the SelectionDAG nodes corresponding to a load
|
// Create the SelectionDAG nodes corresponding to a load
|
||||||
//from this parameter
|
//from this parameter
|
||||||
SDValue FIN = DAG.getFrameIndex(FI, MVT::i16);
|
SDValue FIN = DAG.getFrameIndex(FI, MVT::i16);
|
||||||
InVals.push_back(DAG.getLoad(VA.getLocVT(), dl, Chain, FIN,
|
InVal = DAG.getLoad(VA.getLocVT(), dl, Chain, FIN,
|
||||||
MachinePointerInfo::getFixedStack(FI),
|
MachinePointerInfo::getFixedStack(FI),
|
||||||
false, false, false, 0));
|
false, false, false, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
InVals.push_back(InVal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -498,9 +510,23 @@ MSP430TargetLowering::LowerCCCCallTo(SDValue Chain, SDValue Callee,
|
|||||||
StackPtr,
|
StackPtr,
|
||||||
DAG.getIntPtrConstant(VA.getLocMemOffset()));
|
DAG.getIntPtrConstant(VA.getLocMemOffset()));
|
||||||
|
|
||||||
|
SDValue MemOp;
|
||||||
|
ISD::ArgFlagsTy Flags = Outs[i].Flags;
|
||||||
|
|
||||||
MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff,
|
if (Flags.isByVal()) {
|
||||||
MachinePointerInfo(),false, false, 0));
|
SDValue SizeNode = DAG.getConstant(Flags.getByValSize(), MVT::i16);
|
||||||
|
MemOp = DAG.getMemcpy(Chain, dl, PtrOff, Arg, SizeNode,
|
||||||
|
Flags.getByValAlign(),
|
||||||
|
/*isVolatile*/false,
|
||||||
|
/*AlwaysInline=*/true,
|
||||||
|
MachinePointerInfo(),
|
||||||
|
MachinePointerInfo());
|
||||||
|
} else {
|
||||||
|
MemOp = DAG.getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo(),
|
||||||
|
false, false, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
MemOpChains.push_back(MemOp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
26
test/CodeGen/MSP430/byval.ll
Normal file
26
test/CodeGen/MSP430/byval.ll
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
; RUN: llc < %s | FileCheck %s
|
||||||
|
|
||||||
|
target datalayout = "e-p:16:16:16-i8:8:8-i16:16:16-i32:16:32-n8:16"
|
||||||
|
target triple = "msp430---elf"
|
||||||
|
|
||||||
|
%struct.Foo = type { i16, i16, i16 }
|
||||||
|
@foo = global %struct.Foo { i16 1, i16 2, i16 3 }, align 2
|
||||||
|
|
||||||
|
define i16 @callee(%struct.Foo* byval %f) nounwind {
|
||||||
|
entry:
|
||||||
|
; CHECK: callee:
|
||||||
|
; CHECK: mov.w 2(r1), r15
|
||||||
|
%0 = getelementptr inbounds %struct.Foo* %f, i32 0, i32 0
|
||||||
|
%1 = load i16* %0, align 2
|
||||||
|
ret i16 %1
|
||||||
|
}
|
||||||
|
|
||||||
|
define void @caller() nounwind {
|
||||||
|
entry:
|
||||||
|
; CHECK: caller:
|
||||||
|
; CHECK: mov.w &foo+4, 4(r1)
|
||||||
|
; CHECK-NEXT: mov.w &foo+2, 2(r1)
|
||||||
|
; CHECK-NEXT: mov.w &foo, 0(r1)
|
||||||
|
%call = call i16 @callee(%struct.Foo* byval @foo)
|
||||||
|
ret void
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user