Home | History | Annotate | Download | only in Mips
      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 
     11 declare void @llvm.va_start(i8*) nounwind
     12 declare void @llvm.va_end(i8*) nounwind
     13 
     14 ; return int
     15 define i32 @va1(i32 %a, ...) nounwind {
     16 entry:
     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* %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: lw      $2, 20($sp)
     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)
     41 define double @va2(i32 %a, ...) nounwind {
     42 entry:
     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* %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
     69 define i32 @va3(double %a, ...) nounwind {
     70 entry:
     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* %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: lw      $2, 24($sp)
     89 }
     90 
     91 ; double
     92 define double @va4(double %a, ...) nounwind {
     93 entry:
     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* %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
    116 define i32 @va5(i32 %a, i32 %b, i32 %c, ...) nounwind {
    117 entry:
    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* %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: lw      $2, 36($sp)
    139 }
    140 
    141 ; double
    142 define double @va6(i32 %a, i32 %b, i32 %c, ...) nounwind {
    143 entry:
    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* %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
    172 define i32 @va7(i32 %a, double %b, ...) nounwind {
    173 entry:
    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* %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
    195 define double @va8(i32 %a, double %b, ...) nounwind {
    196 entry:
    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* %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
    219 define i32 @va9(double %a, double %b, i32 %c, ...) nounwind {
    220 entry:
    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* %d, align 4
    236   ret i32 %tmp
    237 
    238 ; CHECK-LABEL: va9:
    239 ; CHECK: addiu   $sp, $sp, -32
    240 ; CHECK: lw      $2, 52($sp)
    241 }
    242 
    243 ; double
    244 define double @va10(double %a, double %b, i32 %c, ...) nounwind {
    245 entry:
    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* %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