forked from OSchip/llvm-project
[SystemZ/z/OS] Add va intrinsics for XPLINK
Add support for va intrinsics for the XPLINK ABI. Only the extended vararg variant, which uses a pointer to next argument, is supported. The standard variant will build on this. Reviewed By: uweigand Differential Revision: https://reviews.llvm.org/D120148
This commit is contained in:
parent
7fb02d2752
commit
30053c1445
|
@ -3505,6 +3505,32 @@ SDValue SystemZTargetLowering::lowerBITCAST(SDValue Op,
|
|||
|
||||
SDValue SystemZTargetLowering::lowerVASTART(SDValue Op,
|
||||
SelectionDAG &DAG) const {
|
||||
|
||||
if (Subtarget.isTargetXPLINK64())
|
||||
return lowerVASTART_XPLINK(Op, DAG);
|
||||
else
|
||||
return lowerVASTART_ELF(Op, DAG);
|
||||
}
|
||||
|
||||
SDValue SystemZTargetLowering::lowerVASTART_XPLINK(SDValue Op,
|
||||
SelectionDAG &DAG) const {
|
||||
MachineFunction &MF = DAG.getMachineFunction();
|
||||
SystemZMachineFunctionInfo *FuncInfo =
|
||||
MF.getInfo<SystemZMachineFunctionInfo>();
|
||||
|
||||
SDLoc DL(Op);
|
||||
|
||||
// vastart just stores the address of the VarArgsFrameIndex slot into the
|
||||
// memory location argument.
|
||||
EVT PtrVT = getPointerTy(DAG.getDataLayout());
|
||||
SDValue FR = DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(), PtrVT);
|
||||
const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
|
||||
return DAG.getStore(Op.getOperand(0), DL, FR, Op.getOperand(1),
|
||||
MachinePointerInfo(SV));
|
||||
}
|
||||
|
||||
SDValue SystemZTargetLowering::lowerVASTART_ELF(SDValue Op,
|
||||
SelectionDAG &DAG) const {
|
||||
MachineFunction &MF = DAG.getMachineFunction();
|
||||
SystemZMachineFunctionInfo *FuncInfo =
|
||||
MF.getInfo<SystemZMachineFunctionInfo>();
|
||||
|
@ -3548,7 +3574,9 @@ SDValue SystemZTargetLowering::lowerVACOPY(SDValue Op,
|
|||
const Value *SrcSV = cast<SrcValueSDNode>(Op.getOperand(4))->getValue();
|
||||
SDLoc DL(Op);
|
||||
|
||||
return DAG.getMemcpy(Chain, DL, DstPtr, SrcPtr, DAG.getIntPtrConstant(32, DL),
|
||||
uint32_t Sz =
|
||||
Subtarget.isTargetXPLINK64() ? getTargetMachine().getPointerSize(0) : 32;
|
||||
return DAG.getMemcpy(Chain, DL, DstPtr, SrcPtr, DAG.getIntPtrConstant(Sz, DL),
|
||||
Align(8), /*isVolatile*/ false, /*AlwaysInline*/ false,
|
||||
/*isTailCall*/ false, MachinePointerInfo(DstSV),
|
||||
MachinePointerInfo(SrcSV));
|
||||
|
|
|
@ -628,6 +628,8 @@ private:
|
|||
SDValue lowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue lowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue lowerVASTART(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue lowerVASTART_ELF(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue lowerVASTART_XPLINK(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue lowerVACOPY(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue lowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue lowerDYNAMIC_STACKALLOC_ELF(SDValue Op, SelectionDAG &DAG) const;
|
||||
|
|
|
@ -189,6 +189,40 @@ entry:
|
|||
ret i64 %retval
|
||||
}
|
||||
|
||||
; Derived from C source:
|
||||
; #define _VARARG_EXT_
|
||||
; #include <stdarg.h>
|
||||
;
|
||||
; long pass(long x, ...) {
|
||||
; va_list va;
|
||||
; va_start(va, x);
|
||||
; long ret = va_arg(va, long);
|
||||
; va_end(va);
|
||||
; return ret;
|
||||
; }
|
||||
;
|
||||
; CHECK-LABEL: pass_vararg:
|
||||
; CHECK: aghi 4, -160
|
||||
; CHECK: la 0, 2208(4)
|
||||
; CHECK: stg 0, 2200(4)
|
||||
define hidden i64 @pass_vararg(i64 %x, ...) {
|
||||
entry:
|
||||
%va = alloca i8*, align 8
|
||||
%va1 = bitcast i8** %va to i8*
|
||||
call void @llvm.va_start(i8* %va1)
|
||||
%argp.cur = load i8*, i8** %va, align 8
|
||||
%argp.next = getelementptr inbounds i8, i8* %argp.cur, i64 8
|
||||
store i8* %argp.next, i8** %va, align 8
|
||||
%0 = bitcast i8* %argp.cur to i64*
|
||||
%ret = load i64, i64* %0, align 8
|
||||
%va2 = bitcast i8** %va to i8*
|
||||
call void @llvm.va_end(i8* %va2)
|
||||
ret i64 %ret
|
||||
}
|
||||
|
||||
declare void @llvm.va_start(i8*)
|
||||
declare void @llvm.va_end(i8*)
|
||||
|
||||
declare i64 @pass_vararg0(i64 %arg0, i64 %arg1, ...)
|
||||
declare i64 @pass_vararg1(fp128 %arg0, ...)
|
||||
declare i64 @pass_vararg2(i64 %arg0, ...)
|
||||
|
|
Loading…
Reference in New Issue