1; RUN: llc -march=mipsel -pre-RA-sched=source < %s | FileCheck %s 2 3 4; All test functions do the same thing - they return the first variable 5; argument. 6 7; All CHECK's do the same thing - they check whether variable arguments from 8; registers are placed on correct stack locations, and whether the first 9; variable argument is returned from the correct stack location. 10 11 12declare void @llvm.va_start(i8*) nounwind 13declare void @llvm.va_end(i8*) nounwind 14 15; return int 16define i32 @va1(i32 %a, ...) nounwind { 17entry: 18 %a.addr = alloca i32, align 4 19 %ap = alloca i8*, align 4 20 %b = alloca i32, align 4 21 store i32 %a, i32* %a.addr, align 4 22 %ap1 = bitcast i8** %ap to i8* 23 call void @llvm.va_start(i8* %ap1) 24 %0 = va_arg i8** %ap, i32 25 store i32 %0, i32* %b, align 4 26 %ap2 = bitcast i8** %ap to i8* 27 call void @llvm.va_end(i8* %ap2) 28 %tmp = load i32* %b, align 4 29 ret i32 %tmp 30 31; CHECK: va1: 32; CHECK: addiu $sp, $sp, -16 33; CHECK: sw $7, 28($sp) 34; CHECK: sw $6, 24($sp) 35; CHECK: sw $5, 20($sp) 36; CHECK: lw $2, 20($sp) 37} 38 39; check whether the variable double argument will be accessed from the 8-byte 40; aligned location (i.e. whether the address is computed by adding 7 and 41; clearing lower 3 bits) 42define double @va2(i32 %a, ...) nounwind { 43entry: 44 %a.addr = alloca i32, align 4 45 %ap = alloca i8*, align 4 46 %b = alloca double, align 8 47 store i32 %a, i32* %a.addr, align 4 48 %ap1 = bitcast i8** %ap to i8* 49 call void @llvm.va_start(i8* %ap1) 50 %0 = va_arg i8** %ap, double 51 store double %0, double* %b, align 8 52 %ap2 = bitcast i8** %ap to i8* 53 call void @llvm.va_end(i8* %ap2) 54 %tmp = load double* %b, align 8 55 ret double %tmp 56 57; CHECK: va2: 58; CHECK: addiu $sp, $sp, -16 59; CHECK: sw $7, 28($sp) 60; CHECK: sw $6, 24($sp) 61; CHECK: sw $5, 20($sp) 62; CHECK: addiu $[[R0:[0-9]+]], $sp, 20 63; CHECK: addiu $[[R1:[0-9]+]], $[[R0]], 7 64; CHECK: addiu $[[R2:[0-9]+]], $zero, -8 65; CHECK: and $[[R3:[0-9]+]], $[[R1]], $[[R2]] 66; CHECK: ldc1 $f0, 0($[[R3]]) 67} 68 69; int 70define i32 @va3(double %a, ...) nounwind { 71entry: 72 %a.addr = alloca double, align 8 73 %ap = alloca i8*, align 4 74 %b = alloca i32, align 4 75 store double %a, double* %a.addr, align 8 76 %ap1 = bitcast i8** %ap to i8* 77 call void @llvm.va_start(i8* %ap1) 78 %0 = va_arg i8** %ap, i32 79 store i32 %0, i32* %b, align 4 80 %ap2 = bitcast i8** %ap to i8* 81 call void @llvm.va_end(i8* %ap2) 82 %tmp = load i32* %b, align 4 83 ret i32 %tmp 84 85; CHECK: va3: 86; CHECK: addiu $sp, $sp, -16 87; CHECK: sw $7, 28($sp) 88; CHECK: sw $6, 24($sp) 89; CHECK: lw $2, 24($sp) 90} 91 92; double 93define double @va4(double %a, ...) nounwind { 94entry: 95 %a.addr = alloca double, align 8 96 %ap = alloca i8*, align 4 97 %b = alloca double, align 8 98 store double %a, double* %a.addr, align 8 99 %ap1 = bitcast i8** %ap to i8* 100 call void @llvm.va_start(i8* %ap1) 101 %0 = va_arg i8** %ap, double 102 store double %0, double* %b, align 8 103 %ap2 = bitcast i8** %ap to i8* 104 call void @llvm.va_end(i8* %ap2) 105 %tmp = load double* %b, align 8 106 ret double %tmp 107 108; CHECK: va4: 109; CHECK: addiu $sp, $sp, -24 110; CHECK: sw $7, 36($sp) 111; CHECK: sw $6, 32($sp) 112; CHECK: addiu ${{[0-9]+}}, $sp, 32 113; CHECK: ldc1 $f0, 32($sp) 114} 115 116; int 117define i32 @va5(i32 %a, i32 %b, i32 %c, ...) nounwind { 118entry: 119 %a.addr = alloca i32, align 4 120 %b.addr = alloca i32, align 4 121 %c.addr = alloca i32, align 4 122 %ap = alloca i8*, align 4 123 %d = alloca i32, align 4 124 store i32 %a, i32* %a.addr, align 4 125 store i32 %b, i32* %b.addr, align 4 126 store i32 %c, i32* %c.addr, align 4 127 %ap1 = bitcast i8** %ap to i8* 128 call void @llvm.va_start(i8* %ap1) 129 %0 = va_arg i8** %ap, i32 130 store i32 %0, i32* %d, align 4 131 %ap2 = bitcast i8** %ap to i8* 132 call void @llvm.va_end(i8* %ap2) 133 %tmp = load i32* %d, align 4 134 ret i32 %tmp 135 136; CHECK: va5: 137; CHECK: addiu $sp, $sp, -24 138; CHECK: sw $7, 36($sp) 139; CHECK: lw $2, 36($sp) 140} 141 142; double 143define double @va6(i32 %a, i32 %b, i32 %c, ...) nounwind { 144entry: 145 %a.addr = alloca i32, align 4 146 %b.addr = alloca i32, align 4 147 %c.addr = alloca i32, align 4 148 %ap = alloca i8*, align 4 149 %d = alloca double, align 8 150 store i32 %a, i32* %a.addr, align 4 151 store i32 %b, i32* %b.addr, align 4 152 store i32 %c, i32* %c.addr, align 4 153 %ap1 = bitcast i8** %ap to i8* 154 call void @llvm.va_start(i8* %ap1) 155 %0 = va_arg i8** %ap, double 156 store double %0, double* %d, align 8 157 %ap2 = bitcast i8** %ap to i8* 158 call void @llvm.va_end(i8* %ap2) 159 %tmp = load double* %d, align 8 160 ret double %tmp 161 162; CHECK: va6: 163; CHECK: addiu $sp, $sp, -24 164; CHECK: sw $7, 36($sp) 165; CHECK: addiu $[[R0:[0-9]+]], $sp, 36 166; CHECK: addiu $[[R1:[0-9]+]], $[[R0]], 7 167; CHECK: addiu $[[R2:[0-9]+]], $zero, -8 168; CHECK: and $[[R3:[0-9]+]], $[[R1]], $[[R2]] 169; CHECK: ldc1 $f0, 0($[[R3]]) 170} 171 172; int 173define i32 @va7(i32 %a, double %b, ...) nounwind { 174entry: 175 %a.addr = alloca i32, align 4 176 %b.addr = alloca double, align 8 177 %ap = alloca i8*, align 4 178 %c = alloca i32, align 4 179 store i32 %a, i32* %a.addr, align 4 180 store double %b, double* %b.addr, align 8 181 %ap1 = bitcast i8** %ap to i8* 182 call void @llvm.va_start(i8* %ap1) 183 %0 = va_arg i8** %ap, i32 184 store i32 %0, i32* %c, align 4 185 %ap2 = bitcast i8** %ap to i8* 186 call void @llvm.va_end(i8* %ap2) 187 %tmp = load i32* %c, align 4 188 ret i32 %tmp 189 190; CHECK: va7: 191; CHECK: addiu $sp, $sp, -24 192; CHECK: lw $2, 40($sp) 193} 194 195; double 196define double @va8(i32 %a, double %b, ...) nounwind { 197entry: 198 %a.addr = alloca i32, align 4 199 %b.addr = alloca double, align 8 200 %ap = alloca i8*, align 4 201 %c = alloca double, align 8 202 store i32 %a, i32* %a.addr, align 4 203 store double %b, double* %b.addr, align 8 204 %ap1 = bitcast i8** %ap to i8* 205 call void @llvm.va_start(i8* %ap1) 206 %0 = va_arg i8** %ap, double 207 store double %0, double* %c, align 8 208 %ap2 = bitcast i8** %ap to i8* 209 call void @llvm.va_end(i8* %ap2) 210 %tmp = load double* %c, align 8 211 ret double %tmp 212 213; CHECK: va8: 214; CHECK: addiu $sp, $sp, -32 215; CHECK: addiu ${{[0-9]+}}, $sp, 48 216; CHECK: ldc1 $f0, 48($sp) 217} 218 219; int 220define i32 @va9(double %a, double %b, i32 %c, ...) nounwind { 221entry: 222 %a.addr = alloca double, align 8 223 %b.addr = alloca double, align 8 224 %c.addr = alloca i32, align 4 225 %ap = alloca i8*, align 4 226 %d = alloca i32, align 4 227 store double %a, double* %a.addr, align 8 228 store double %b, double* %b.addr, align 8 229 store i32 %c, i32* %c.addr, align 4 230 %ap1 = bitcast i8** %ap to i8* 231 call void @llvm.va_start(i8* %ap1) 232 %0 = va_arg i8** %ap, i32 233 store i32 %0, i32* %d, align 4 234 %ap2 = bitcast i8** %ap to i8* 235 call void @llvm.va_end(i8* %ap2) 236 %tmp = load i32* %d, align 4 237 ret i32 %tmp 238 239; CHECK: va9: 240; CHECK: addiu $sp, $sp, -32 241; CHECK: lw $2, 52($sp) 242} 243 244; double 245define double @va10(double %a, double %b, i32 %c, ...) nounwind { 246entry: 247 %a.addr = alloca double, align 8 248 %b.addr = alloca double, align 8 249 %c.addr = alloca i32, align 4 250 %ap = alloca i8*, align 4 251 %d = alloca double, align 8 252 store double %a, double* %a.addr, align 8 253 store double %b, double* %b.addr, align 8 254 store i32 %c, i32* %c.addr, align 4 255 %ap1 = bitcast i8** %ap to i8* 256 call void @llvm.va_start(i8* %ap1) 257 %0 = va_arg i8** %ap, double 258 store double %0, double* %d, align 8 259 %ap2 = bitcast i8** %ap to i8* 260 call void @llvm.va_end(i8* %ap2) 261 %tmp = load double* %d, align 8 262 ret double %tmp 263 264; CHECK: va10: 265; CHECK: addiu $sp, $sp, -32 266; CHECK: addiu $[[R0:[0-9]+]], $sp, 52 267; CHECK: addiu $[[R1:[0-9]+]], $[[R0]], 7 268; CHECK: addiu $[[R2:[0-9]+]], $zero, -8 269; CHECK: and $[[R3:[0-9]+]], $[[R1]], $[[R2]] 270; CHECK: ldc1 $f0, 0($[[R3]]) 271} 272