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