1*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -mcpu=generic -mtriple=x86_64-pc-linux-gnu | FileCheck %s 2*9880d681SAndroid Build Coastguard Worker 3*9880d681SAndroid Build Coastguard Worker; Verify that the var arg parameters which are passed in registers are stored 4*9880d681SAndroid Build Coastguard Worker; in home stack slots allocated by the caller and that AP is correctly 5*9880d681SAndroid Build Coastguard Worker; calculated. 6*9880d681SAndroid Build Coastguard Workerdefine x86_64_win64cc void @average_va(i32 %count, ...) nounwind { 7*9880d681SAndroid Build Coastguard Workerentry: 8*9880d681SAndroid Build Coastguard Worker; CHECK: pushq 9*9880d681SAndroid Build Coastguard Worker; CHECK: movq %r9, 40(%rsp) 10*9880d681SAndroid Build Coastguard Worker; CHECK: movq %r8, 32(%rsp) 11*9880d681SAndroid Build Coastguard Worker; CHECK: movq %rdx, 24(%rsp) 12*9880d681SAndroid Build Coastguard Worker; CHECK: leaq 24(%rsp), %rax 13*9880d681SAndroid Build Coastguard Worker 14*9880d681SAndroid Build Coastguard Worker %ap = alloca i8*, align 8 ; <i8**> [#uses=1] 15*9880d681SAndroid Build Coastguard Worker %ap.0 = bitcast i8** %ap to i8* 16*9880d681SAndroid Build Coastguard Worker call void @llvm.va_start(i8* %ap.0) 17*9880d681SAndroid Build Coastguard Worker ret void 18*9880d681SAndroid Build Coastguard Worker} 19*9880d681SAndroid Build Coastguard Worker 20*9880d681SAndroid Build Coastguard Workerdeclare void @llvm.va_start(i8*) nounwind 21*9880d681SAndroid Build Coastguard Workerdeclare void @llvm.va_copy(i8*, i8*) nounwind 22*9880d681SAndroid Build Coastguard Workerdeclare void @llvm.va_end(i8*) nounwind 23*9880d681SAndroid Build Coastguard Worker 24*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f5: 25*9880d681SAndroid Build Coastguard Worker; CHECK: pushq 26*9880d681SAndroid Build Coastguard Worker; CHECK: leaq 56(%rsp), 27*9880d681SAndroid Build Coastguard Workerdefine x86_64_win64cc i8** @f5(i64 %a0, i64 %a1, i64 %a2, i64 %a3, i64 %a4, ...) nounwind { 28*9880d681SAndroid Build Coastguard Workerentry: 29*9880d681SAndroid Build Coastguard Worker %ap = alloca i8*, align 8 30*9880d681SAndroid Build Coastguard Worker %ap.0 = bitcast i8** %ap to i8* 31*9880d681SAndroid Build Coastguard Worker call void @llvm.va_start(i8* %ap.0) 32*9880d681SAndroid Build Coastguard Worker ret i8** %ap 33*9880d681SAndroid Build Coastguard Worker} 34*9880d681SAndroid Build Coastguard Worker 35*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f4: 36*9880d681SAndroid Build Coastguard Worker; CHECK: pushq 37*9880d681SAndroid Build Coastguard Worker; CHECK: leaq 48(%rsp), 38*9880d681SAndroid Build Coastguard Workerdefine x86_64_win64cc i8** @f4(i64 %a0, i64 %a1, i64 %a2, i64 %a3, ...) nounwind { 39*9880d681SAndroid Build Coastguard Workerentry: 40*9880d681SAndroid Build Coastguard Worker %ap = alloca i8*, align 8 41*9880d681SAndroid Build Coastguard Worker %ap.0 = bitcast i8** %ap to i8* 42*9880d681SAndroid Build Coastguard Worker call void @llvm.va_start(i8* %ap.0) 43*9880d681SAndroid Build Coastguard Worker ret i8** %ap 44*9880d681SAndroid Build Coastguard Worker} 45*9880d681SAndroid Build Coastguard Worker 46*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f3: 47*9880d681SAndroid Build Coastguard Worker; CHECK: pushq 48*9880d681SAndroid Build Coastguard Worker; CHECK: leaq 40(%rsp), 49*9880d681SAndroid Build Coastguard Workerdefine x86_64_win64cc i8** @f3(i64 %a0, i64 %a1, i64 %a2, ...) nounwind { 50*9880d681SAndroid Build Coastguard Workerentry: 51*9880d681SAndroid Build Coastguard Worker %ap = alloca i8*, align 8 52*9880d681SAndroid Build Coastguard Worker %ap.0 = bitcast i8** %ap to i8* 53*9880d681SAndroid Build Coastguard Worker call void @llvm.va_start(i8* %ap.0) 54*9880d681SAndroid Build Coastguard Worker ret i8** %ap 55*9880d681SAndroid Build Coastguard Worker} 56*9880d681SAndroid Build Coastguard Worker 57*9880d681SAndroid Build Coastguard Worker; WinX86_64 uses char* for va_list. Verify that the correct amount of bytes 58*9880d681SAndroid Build Coastguard Worker; are copied using va_copy. 59*9880d681SAndroid Build Coastguard Worker 60*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: copy1: 61*9880d681SAndroid Build Coastguard Worker; CHECK: leaq 32(%rsp), [[REG_copy1:%[a-z]+]] 62*9880d681SAndroid Build Coastguard Worker; CHECK: movq [[REG_copy1]], 8(%rsp) 63*9880d681SAndroid Build Coastguard Worker; CHECK: movq [[REG_copy1]], (%rsp) 64*9880d681SAndroid Build Coastguard Worker; CHECK: ret 65*9880d681SAndroid Build Coastguard Workerdefine x86_64_win64cc void @copy1(i64 %a0, ...) nounwind { 66*9880d681SAndroid Build Coastguard Workerentry: 67*9880d681SAndroid Build Coastguard Worker %ap = alloca i8*, align 8 68*9880d681SAndroid Build Coastguard Worker %cp = alloca i8*, align 8 69*9880d681SAndroid Build Coastguard Worker %ap.0 = bitcast i8** %ap to i8* 70*9880d681SAndroid Build Coastguard Worker %cp.0 = bitcast i8** %cp to i8* 71*9880d681SAndroid Build Coastguard Worker call void @llvm.va_start(i8* %ap.0) 72*9880d681SAndroid Build Coastguard Worker call void @llvm.va_copy(i8* %cp.0, i8* %ap.0) 73*9880d681SAndroid Build Coastguard Worker ret void 74*9880d681SAndroid Build Coastguard Worker} 75*9880d681SAndroid Build Coastguard Worker 76*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: copy4: 77*9880d681SAndroid Build Coastguard Worker; CHECK: leaq 56(%rsp), [[REG_copy4:%[a-z]+]] 78*9880d681SAndroid Build Coastguard Worker; CHECK: movq [[REG_copy4]], 8(%rsp) 79*9880d681SAndroid Build Coastguard Worker; CHECK: movq [[REG_copy4]], (%rsp) 80*9880d681SAndroid Build Coastguard Worker; CHECK: ret 81*9880d681SAndroid Build Coastguard Workerdefine x86_64_win64cc void @copy4(i64 %a0, i64 %a1, i64 %a2, i64 %a3, ...) nounwind { 82*9880d681SAndroid Build Coastguard Workerentry: 83*9880d681SAndroid Build Coastguard Worker %ap = alloca i8*, align 8 84*9880d681SAndroid Build Coastguard Worker %cp = alloca i8*, align 8 85*9880d681SAndroid Build Coastguard Worker %ap.0 = bitcast i8** %ap to i8* 86*9880d681SAndroid Build Coastguard Worker %cp.0 = bitcast i8** %cp to i8* 87*9880d681SAndroid Build Coastguard Worker call void @llvm.va_start(i8* %ap.0) 88*9880d681SAndroid Build Coastguard Worker call void @llvm.va_copy(i8* %cp.0, i8* %ap.0) 89*9880d681SAndroid Build Coastguard Worker ret void 90*9880d681SAndroid Build Coastguard Worker} 91*9880d681SAndroid Build Coastguard Worker 92*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: arg4: 93*9880d681SAndroid Build Coastguard Worker; va_start: 94*9880d681SAndroid Build Coastguard Worker; CHECK: leaq 48(%rsp), [[REG_arg4_1:%[a-z]+]] 95*9880d681SAndroid Build Coastguard Worker; CHECK: movq [[REG_arg4_1]], (%rsp) 96*9880d681SAndroid Build Coastguard Worker; va_arg: 97*9880d681SAndroid Build Coastguard Worker; CHECK: leaq 52(%rsp), [[REG_arg4_2:%[a-z]+]] 98*9880d681SAndroid Build Coastguard Worker; CHECK: movq [[REG_arg4_2]], (%rsp) 99*9880d681SAndroid Build Coastguard Worker; CHECK: movl 48(%rsp), %eax 100*9880d681SAndroid Build Coastguard Worker; CHECK: ret 101*9880d681SAndroid Build Coastguard Workerdefine x86_64_win64cc i32 @arg4(i64 %a0, i64 %a1, i64 %a2, i64 %a3, ...) nounwind { 102*9880d681SAndroid Build Coastguard Workerentry: 103*9880d681SAndroid Build Coastguard Worker %ap = alloca i8*, align 8 104*9880d681SAndroid Build Coastguard Worker %ap.0 = bitcast i8** %ap to i8* 105*9880d681SAndroid Build Coastguard Worker call void @llvm.va_start(i8* %ap.0) 106*9880d681SAndroid Build Coastguard Worker %tmp = va_arg i8** %ap, i32 107*9880d681SAndroid Build Coastguard Worker ret i32 %tmp 108*9880d681SAndroid Build Coastguard Worker} 109