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 12 declare void @llvm.va_start(i8*) nounwind 13 declare void @llvm.va_end(i8*) nounwind 14 15 ; return int 16 define i32 @va1(i32 %a, ...) nounwind { 17 entry: 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) 42 define double @va2(i32 %a, ...) nounwind { 43 entry: 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 70 define i32 @va3(double %a, ...) nounwind { 71 entry: 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 93 define double @va4(double %a, ...) nounwind { 94 entry: 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 117 define i32 @va5(i32 %a, i32 %b, i32 %c, ...) nounwind { 118 entry: 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 143 define double @va6(i32 %a, i32 %b, i32 %c, ...) nounwind { 144 entry: 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 173 define i32 @va7(i32 %a, double %b, ...) nounwind { 174 entry: 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 196 define double @va8(i32 %a, double %b, ...) nounwind { 197 entry: 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 220 define i32 @va9(double %a, double %b, i32 %c, ...) nounwind { 221 entry: 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 245 define double @va10(double %a, double %b, i32 %c, ...) nounwind { 246 entry: 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