mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-11-02 07:11:49 +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
|
||||
//===----------------------------------------------------------------------===//
|
||||
def CC_MSP430 : CallingConv<[
|
||||
// Pass by value if the byval attribute is given
|
||||
CCIfByVal<CCPassByVal<2, 2>>,
|
||||
|
||||
// Promote i8 arguments to i16.
|
||||
CCIfType<[i8], CCPromoteToType<i16>>,
|
||||
|
||||
|
@ -357,22 +357,34 @@ MSP430TargetLowering::LowerCCCArguments(SDValue Chain,
|
||||
} else {
|
||||
// Sanity check
|
||||
assert(VA.isMemLoc());
|
||||
// Load the argument to a virtual register
|
||||
unsigned ObjSize = VA.getLocVT().getSizeInBits()/8;
|
||||
if (ObjSize > 2) {
|
||||
errs() << "LowerFormalArguments Unhandled argument type: "
|
||||
<< EVT(VA.getLocVT()).getEVTString()
|
||||
<< "\n";
|
||||
}
|
||||
// Create the frame index object for this incoming parameter...
|
||||
int FI = MFI->CreateFixedObject(ObjSize, VA.getLocMemOffset(), true);
|
||||
|
||||
// Create the SelectionDAG nodes corresponding to a load
|
||||
//from this parameter
|
||||
SDValue FIN = DAG.getFrameIndex(FI, MVT::i16);
|
||||
InVals.push_back(DAG.getLoad(VA.getLocVT(), dl, Chain, FIN,
|
||||
MachinePointerInfo::getFixedStack(FI),
|
||||
false, false, false, 0));
|
||||
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
|
||||
unsigned ObjSize = VA.getLocVT().getSizeInBits()/8;
|
||||
if (ObjSize > 2) {
|
||||
errs() << "LowerFormalArguments Unhandled argument type: "
|
||||
<< EVT(VA.getLocVT()).getEVTString()
|
||||
<< "\n";
|
||||
}
|
||||
// Create the frame index object for this incoming parameter...
|
||||
int FI = MFI->CreateFixedObject(ObjSize, VA.getLocMemOffset(), true);
|
||||
|
||||
// Create the SelectionDAG nodes corresponding to a load
|
||||
//from this parameter
|
||||
SDValue FIN = DAG.getFrameIndex(FI, MVT::i16);
|
||||
InVal = DAG.getLoad(VA.getLocVT(), dl, Chain, FIN,
|
||||
MachinePointerInfo::getFixedStack(FI),
|
||||
false, false, false, 0);
|
||||
}
|
||||
|
||||
InVals.push_back(InVal);
|
||||
}
|
||||
}
|
||||
|
||||
@ -498,9 +510,23 @@ MSP430TargetLowering::LowerCCCCallTo(SDValue Chain, SDValue Callee,
|
||||
StackPtr,
|
||||
DAG.getIntPtrConstant(VA.getLocMemOffset()));
|
||||
|
||||
SDValue MemOp;
|
||||
ISD::ArgFlagsTy Flags = Outs[i].Flags;
|
||||
|
||||
MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff,
|
||||
MachinePointerInfo(),false, false, 0));
|
||||
if (Flags.isByVal()) {
|
||||
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…
Reference in New Issue
Block a user