Skip to content

Commit

Permalink
Add support for byval args. Patch by Job Noorman!
Browse files Browse the repository at this point in the history
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@168439 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
asl committed Nov 21, 2012
1 parent 6ee1e08 commit 6cbeb4d
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 17 deletions.
3 changes: 3 additions & 0 deletions lib/Target/MSP430/MSP430CallingConv.td
Original file line number Diff line number Diff line change
Expand Up @@ -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>>,

Expand Down
60 changes: 43 additions & 17 deletions lib/Target/MSP430/MSP430ISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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";

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);
}
// 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));

InVals.push_back(InVal);
}
}

Expand Down Expand Up @@ -498,9 +510,23 @@ MSP430TargetLowering::LowerCCCCallTo(SDValue Chain, SDValue Callee,
StackPtr,
DAG.getIntPtrConstant(VA.getLocMemOffset()));

SDValue MemOp;
ISD::ArgFlagsTy Flags = Outs[i].Flags;

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(DAG.getStore(Chain, dl, Arg, PtrOff,
MachinePointerInfo(),false, false, 0));
MemOpChains.push_back(MemOp);
}
}

Expand Down
26 changes: 26 additions & 0 deletions test/CodeGen/MSP430/byval.ll
Original file line number Diff line number Diff line change
@@ -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
}

0 comments on commit 6cbeb4d

Please sign in to comment.