Home | History | Annotate | Download | only in Mips
      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