mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-21 19:20:28 +00:00
Initial support for calling functions with byval arguments on x86-64
llvm-svn: 41643
This commit is contained in:
parent
aa7930b4f0
commit
4ddaad4de0
@ -1036,6 +1036,34 @@ X86TargetLowering::LowerFastCCArguments(SDOperand Op, SelectionDAG &DAG) {
|
||||
&ArgValues[0], ArgValues.size()).getValue(Op.ResNo);
|
||||
}
|
||||
|
||||
SDOperand
|
||||
X86TargetLowering::LowerMemOpCallTo(SDOperand Op, SelectionDAG &DAG,
|
||||
const SDOperand &StackPtr,
|
||||
const CCValAssign &VA,
|
||||
SDOperand Chain,
|
||||
SDOperand Arg) {
|
||||
SDOperand PtrOff = DAG.getConstant(VA.getLocMemOffset(), getPointerTy());
|
||||
PtrOff = DAG.getNode(ISD::ADD, getPointerTy(), StackPtr, PtrOff);
|
||||
SDOperand FlagsOp = Op.getOperand(6+2*VA.getValNo());
|
||||
unsigned Flags = cast<ConstantSDNode>(FlagsOp)->getValue();
|
||||
if (Flags & ISD::ParamFlags::ByVal) {
|
||||
unsigned Align = 1 << ((Flags & ISD::ParamFlags::ByValAlign) >>
|
||||
ISD::ParamFlags::ByValAlignOffs);
|
||||
|
||||
assert (Align >= 8);
|
||||
unsigned Size = (Flags & ISD::ParamFlags::ByValSize) >>
|
||||
ISD::ParamFlags::ByValSizeOffs;
|
||||
|
||||
SDOperand AlignNode = DAG.getConstant(Align, MVT::i32);
|
||||
SDOperand SizeNode = DAG.getConstant(Size, MVT::i32);
|
||||
|
||||
return DAG.getNode(ISD::MEMCPY, MVT::Other, Chain, PtrOff, Arg, SizeNode,
|
||||
AlignNode);
|
||||
} else {
|
||||
return DAG.getStore(Chain, Arg, PtrOff, NULL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
SDOperand X86TargetLowering::LowerFastCCCallTo(SDOperand Op, SelectionDAG &DAG,
|
||||
unsigned CC) {
|
||||
SDOperand Chain = Op.getOperand(0);
|
||||
@ -1375,29 +1403,9 @@ X86TargetLowering::LowerX86_64CCCCallTo(SDOperand Op, SelectionDAG &DAG,
|
||||
assert(VA.isMemLoc());
|
||||
if (StackPtr.Val == 0)
|
||||
StackPtr = DAG.getRegister(getStackPtrReg(), getPointerTy());
|
||||
SDOperand PtrOff = DAG.getConstant(VA.getLocMemOffset(), getPointerTy());
|
||||
PtrOff = DAG.getNode(ISD::ADD, getPointerTy(), StackPtr, PtrOff);
|
||||
|
||||
SDOperand FlagsOp = Op.getOperand(6+2*VA.getValNo());
|
||||
unsigned Flags = cast<ConstantSDNode>(FlagsOp)->getValue();
|
||||
if (Flags & ISD::ParamFlags::ByVal) {
|
||||
unsigned Align = 1 << ((Flags & ISD::ParamFlags::ByValAlign) >>
|
||||
ISD::ParamFlags::ByValAlignOffs);
|
||||
unsigned Size = (Flags & ISD::ParamFlags::ByValSize) >>
|
||||
ISD::ParamFlags::ByValSizeOffs;
|
||||
|
||||
SDOperand AlignNode = DAG.getConstant(Align, MVT::i32);
|
||||
SDOperand SizeNode = DAG.getConstant(Size, MVT::i32);
|
||||
|
||||
assert(0 && "Not Implemented");
|
||||
|
||||
SDOperand Copy = DAG.getNode(ISD::MEMCPY, MVT::Other, Chain, PtrOff,
|
||||
Arg, SizeNode, AlignNode);
|
||||
MemOpChains.push_back(Copy);
|
||||
}
|
||||
else {
|
||||
MemOpChains.push_back(DAG.getStore(Chain, Arg, PtrOff, NULL, 0));
|
||||
}
|
||||
MemOpChains.push_back(LowerMemOpCallTo(Op, DAG, StackPtr, VA, Chain,
|
||||
Arg));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "X86RegisterInfo.h"
|
||||
#include "llvm/Target/TargetLowering.h"
|
||||
#include "llvm/CodeGen/SelectionDAG.h"
|
||||
#include "llvm/CodeGen/CallingConvLower.h"
|
||||
|
||||
namespace llvm {
|
||||
namespace X86ISD {
|
||||
@ -378,6 +379,12 @@ namespace llvm {
|
||||
SDNode *LowerCallResult(SDOperand Chain, SDOperand InFlag, SDNode*TheCall,
|
||||
unsigned CallingConv, SelectionDAG &DAG);
|
||||
|
||||
|
||||
SDOperand LowerMemOpCallTo(SDOperand Op, SelectionDAG &DAG,
|
||||
const SDOperand &StackPtr,
|
||||
const CCValAssign &VA, SDOperand Chain,
|
||||
SDOperand Arg);
|
||||
|
||||
// C and StdCall Calling Convention implementation.
|
||||
SDOperand LowerCCCArguments(SDOperand Op, SelectionDAG &DAG,
|
||||
bool isStdCall = false);
|
||||
|
19
test/CodeGen/X86/byval2.ll
Normal file
19
test/CodeGen/X86/byval2.ll
Normal file
@ -0,0 +1,19 @@
|
||||
; RUN: llvm-as < %s | llc -march=x86-64 | grep rep.movsl | count 2
|
||||
|
||||
%struct.s = type { i64, i64, i64 }
|
||||
|
||||
define void @g(i64 %a, i64 %b, i64 %c) {
|
||||
entry:
|
||||
%d = alloca %struct.s, align 16
|
||||
%tmp = getelementptr %struct.s* %d, i32 0, i32 0
|
||||
store i64 %a, i64* %tmp, align 16
|
||||
%tmp2 = getelementptr %struct.s* %d, i32 0, i32 1
|
||||
store i64 %b, i64* %tmp2, align 16
|
||||
%tmp4 = getelementptr %struct.s* %d, i32 0, i32 2
|
||||
store i64 %c, i64* %tmp4, align 16
|
||||
call void @f( %struct.s* %d byval)
|
||||
call void @f( %struct.s* %d byval)
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @f(%struct.s* byval)
|
Loading…
Reference in New Issue
Block a user