Home | History | Annotate | Download | only in ARM
      1 ; RUN: llc < %s -O0 -fast-isel-abort -relocation-model=dynamic-no-pic -mtriple=armv7-apple-ios | FileCheck %s --check-prefix=ARM
      2 ; RUN: llc < %s -O0 -fast-isel-abort -relocation-model=dynamic-no-pic -mtriple=thumbv7-apple-ios | FileCheck %s --check-prefix=THUMB
      3 ; RUN: llc < %s -O0 -fast-isel-abort -relocation-model=dynamic-no-pic -mtriple=armv7-apple-ios -arm-long-calls | FileCheck %s --check-prefix=ARM-LONG
      4 ; RUN: llc < %s -O0 -fast-isel-abort -relocation-model=dynamic-no-pic -mtriple=thumbv7-apple-ios -arm-long-calls | FileCheck %s --check-prefix=THUMB-LONG
      5 ; RUN: llc < %s -O0 -relocation-model=dynamic-no-pic -mtriple=armv7-apple-ios -mattr=-vfp2 | FileCheck %s --check-prefix=ARM-NOVFP
      6 ; RUN: llc < %s -O0 -relocation-model=dynamic-no-pic -mtriple=thumbv7-apple-ios -mattr=-vfp2 | FileCheck %s --check-prefix=THUMB-NOVFP
      7 
      8 define i32 @t0(i1 zeroext %a) nounwind {
      9   %1 = zext i1 %a to i32
     10   ret i32 %1
     11 }
     12 
     13 define i32 @t1(i8 signext %a) nounwind {
     14   %1 = sext i8 %a to i32
     15   ret i32 %1
     16 }
     17 
     18 define i32 @t2(i8 zeroext %a) nounwind {
     19   %1 = zext i8 %a to i32
     20   ret i32 %1
     21 }
     22 
     23 define i32 @t3(i16 signext %a) nounwind {
     24   %1 = sext i16 %a to i32
     25   ret i32 %1
     26 }
     27 
     28 define i32 @t4(i16 zeroext %a) nounwind {
     29   %1 = zext i16 %a to i32
     30   ret i32 %1
     31 }
     32 
     33 define void @foo(i8 %a, i16 %b) nounwind {
     34 ; ARM: foo
     35 ; THUMB: foo
     36 ;; Materialize i1 1
     37 ; ARM: movw r2, #1
     38 ;; zero-ext
     39 ; ARM: and r2, r2, #1
     40 ; THUMB: and r2, r2, #1
     41   %1 = call i32 @t0(i1 zeroext 1)
     42 ; ARM: sxtb	r2, r1
     43 ; ARM: mov r0, r2
     44 ; THUMB: sxtb	r2, r1
     45 ; THUMB: mov r0, r2
     46   %2 = call i32 @t1(i8 signext %a)
     47 ; ARM: uxtb	r2, r1
     48 ; ARM: mov r0, r2
     49 ; THUMB: uxtb	r2, r1
     50 ; THUMB: mov r0, r2
     51   %3 = call i32 @t2(i8 zeroext %a)
     52 ; ARM: sxth	r2, r1
     53 ; ARM: mov r0, r2
     54 ; THUMB: sxth	r2, r1
     55 ; THUMB: mov r0, r2
     56   %4 = call i32 @t3(i16 signext %b)
     57 ; ARM: uxth	r2, r1
     58 ; ARM: mov r0, r2
     59 ; THUMB: uxth	r2, r1
     60 ; THUMB: mov r0, r2
     61   %5 = call i32 @t4(i16 zeroext %b)
     62 
     63 ;; A few test to check materialization
     64 ;; Note: i1 1 was materialized with t1 call
     65 ; ARM: movw r1, #255
     66 %6 = call i32 @t2(i8 zeroext 255)
     67 ; ARM: movw r1, #65535
     68 ; THUMB: movw r1, #65535
     69 %7 = call i32 @t4(i16 zeroext 65535)
     70   ret void
     71 }
     72 
     73 define void @foo2() nounwind {
     74   %1 = call signext i16 @t5()
     75   %2 = call zeroext i16 @t6()
     76   %3 = call signext i8 @t7()
     77   %4 = call zeroext i8 @t8()
     78   %5 = call zeroext i1 @t9()
     79   ret void
     80 }
     81 
     82 declare signext i16 @t5();
     83 declare zeroext i16 @t6();
     84 declare signext i8 @t7();
     85 declare zeroext i8 @t8();
     86 declare zeroext i1 @t9();
     87 
     88 define i32 @t10(i32 %argc, i8** nocapture %argv) {
     89 entry:
     90 ; ARM: @t10
     91 ; ARM: movw r0, #0
     92 ; ARM: movw r1, #248
     93 ; ARM: movw r2, #187
     94 ; ARM: movw r3, #28
     95 ; ARM: movw r9, #40
     96 ; ARM: movw r12, #186
     97 ; ARM: uxtb r0, r0
     98 ; ARM: uxtb r1, r1
     99 ; ARM: uxtb r2, r2
    100 ; ARM: uxtb r3, r3
    101 ; ARM: uxtb r9, r9
    102 ; ARM: str r9, [sp]
    103 ; ARM: uxtb r9, r12
    104 ; ARM: str r9, [sp, #4]
    105 ; ARM: bl _bar
    106 ; ARM-LONG: @t10
    107 ; ARM-LONG: movw lr, :lower16:L_bar$non_lazy_ptr
    108 ; ARM-LONG: movt lr, :upper16:L_bar$non_lazy_ptr
    109 ; ARM-LONG: ldr lr, [lr]
    110 ; ARM-LONG: blx lr
    111 ; THUMB: @t10
    112 ; THUMB: movs r0, #0
    113 ; THUMB: movt r0, #0
    114 ; THUMB: movs r1, #248
    115 ; THUMB: movt r1, #0
    116 ; THUMB: movs r2, #187
    117 ; THUMB: movt r2, #0
    118 ; THUMB: movs r3, #28
    119 ; THUMB: movt r3, #0
    120 ; THUMB: movw r9, #40
    121 ; THUMB: movt r9, #0
    122 ; THUMB: movw r12, #186
    123 ; THUMB: movt r12, #0
    124 ; THUMB: uxtb r0, r0
    125 ; THUMB: uxtb r1, r1
    126 ; THUMB: uxtb r2, r2
    127 ; THUMB: uxtb r3, r3
    128 ; THUMB: uxtb.w r9, r9
    129 ; THUMB: str.w r9, [sp]
    130 ; THUMB: uxtb.w r9, r12
    131 ; THUMB: str.w r9, [sp, #4]
    132 ; THUMB: bl _bar
    133 ; THUMB-LONG: @t10
    134 ; THUMB-LONG: movw lr, :lower16:L_bar$non_lazy_ptr
    135 ; THUMB-LONG: movt lr, :upper16:L_bar$non_lazy_ptr
    136 ; THUMB-LONG: ldr.w lr, [lr]
    137 ; THUMB-LONG: blx lr
    138   %call = call i32 @bar(i8 zeroext 0, i8 zeroext -8, i8 zeroext -69, i8 zeroext 28, i8 zeroext 40, i8 zeroext -70)
    139   ret i32 0
    140 }
    141 
    142 declare i32 @bar(i8 zeroext, i8 zeroext, i8 zeroext, i8 zeroext, i8 zeroext, i8 zeroext)
    143 
    144 define i32 @bar0(i32 %i) nounwind {
    145   ret i32 0
    146 }
    147 
    148 define void @foo3() uwtable {
    149 ; ARM: movw    r0, #0
    150 ; ARM: movw    r1, :lower16:_bar0
    151 ; ARM: movt    r1, :upper16:_bar0
    152 ; ARM: blx     r1
    153 ; THUMB: movs    r0, #0
    154 ; THUMB: movw    r1, :lower16:_bar0
    155 ; THUMB: movt    r1, :upper16:_bar0
    156 ; THUMB: blx     r1
    157   %fptr = alloca i32 (i32)*, align 8
    158   store i32 (i32)* @bar0, i32 (i32)** %fptr, align 8
    159   %1 = load i32 (i32)** %fptr, align 8
    160   %call = call i32 %1(i32 0)
    161   ret void
    162 }
    163 
    164 define i32 @LibCall(i32 %a, i32 %b) {
    165 entry:
    166 ; ARM: LibCall
    167 ; ARM: bl ___udivsi3
    168 ; ARM-LONG: LibCall
    169 ; ARM-LONG: movw r2, :lower16:L___udivsi3$non_lazy_ptr
    170 ; ARM-LONG: movt r2, :upper16:L___udivsi3$non_lazy_ptr
    171 ; ARM-LONG: ldr r2, [r2]
    172 ; ARM-LONG: blx r2
    173 ; THUMB: LibCall
    174 ; THUMB: bl ___udivsi3
    175 ; THUMB-LONG: LibCall
    176 ; THUMB-LONG: movw r2, :lower16:L___udivsi3$non_lazy_ptr
    177 ; THUMB-LONG: movt r2, :upper16:L___udivsi3$non_lazy_ptr
    178 ; THUMB-LONG: ldr r2, [r2]
    179 ; THUMB-LONG: blx r2
    180         %tmp1 = udiv i32 %a, %b         ; <i32> [#uses=1]
    181         ret i32 %tmp1
    182 }
    183 
    184 define i32 @VarArg() nounwind {
    185 entry:
    186   %i = alloca i32, align 4
    187   %j = alloca i32, align 4
    188   %k = alloca i32, align 4
    189   %m = alloca i32, align 4
    190   %n = alloca i32, align 4
    191   %tmp = alloca i32, align 4
    192   %0 = load i32* %i, align 4
    193   %1 = load i32* %j, align 4
    194   %2 = load i32* %k, align 4
    195   %3 = load i32* %m, align 4
    196   %4 = load i32* %n, align 4
    197 ; ARM: VarArg
    198 ; ARM: mov r7, sp
    199 ; ARM: movw r0, #5
    200 ; ARM: ldr r1, [r7, #-4]
    201 ; ARM: ldr r2, [r7, #-8]
    202 ; ARM: ldr r3, [r7, #-12]
    203 ; ARM: ldr r9, [sp, #16]
    204 ; ARM: ldr r12, [sp, #12]
    205 ; ARM: str r9, [sp]
    206 ; ARM: str r12, [sp, #4]
    207 ; ARM: bl _CallVariadic
    208 ; THUMB: mov r7, sp
    209 ; THUMB: movs r0, #5
    210 ; THUMB: movt r0, #0
    211 ; THUMB: ldr r1, [sp, #28]
    212 ; THUMB: ldr r2, [sp, #24]
    213 ; THUMB: ldr r3, [sp, #20]
    214 ; THUMB: ldr.w r9, [sp, #16]
    215 ; THUMB: ldr.w r12, [sp, #12]
    216 ; THUMB: str.w r9, [sp]
    217 ; THUMB: str.w r12, [sp, #4]
    218 ; THUMB: bl _CallVariadic
    219   %call = call i32 (i32, ...)* @CallVariadic(i32 5, i32 %0, i32 %1, i32 %2, i32 %3, i32 %4)
    220   store i32 %call, i32* %tmp, align 4
    221   %5 = load i32* %tmp, align 4
    222   ret i32 %5
    223 }
    224 
    225 declare i32 @CallVariadic(i32, ...)
    226 
    227 ; Test fastcc
    228 
    229 define fastcc void @fast_callee(float %i) ssp {
    230 entry:
    231 ; ARM: fast_callee
    232 ; ARM: vmov r0, s0
    233 ; THUMB: fast_callee
    234 ; THUMB: vmov r0, s0
    235 ; ARM-NOVFP: fast_callee
    236 ; ARM-NOVFP-NOT: s0
    237 ; THUMB-NOVFP: fast_callee
    238 ; THUMB-NOVFP-NOT: s0
    239   call void @print(float %i)
    240   ret void
    241 }
    242 
    243 define void @fast_caller() ssp {
    244 entry:
    245 ; ARM: fast_caller
    246 ; ARM: vldr s0,
    247 ; THUMB: fast_caller
    248 ; THUMB: vldr s0,
    249 ; ARM-NOVFP: fast_caller
    250 ; ARM-NOVFP: movw r0, #13107
    251 ; ARM-NOVFP: movt r0, #16611
    252 ; THUMB-NOVFP: fast_caller
    253 ; THUMB-NOVFP: movw r0, #13107
    254 ; THUMB-NOVFP: movt r0, #16611
    255   call fastcc void @fast_callee(float 0x401C666660000000)
    256   ret void
    257 }
    258 
    259 define void @no_fast_callee(float %i) ssp {
    260 entry:
    261 ; ARM: no_fast_callee
    262 ; ARM: vmov s0, r0
    263 ; THUMB: no_fast_callee
    264 ; THUMB: vmov s0, r0
    265 ; ARM-NOVFP: no_fast_callee
    266 ; ARM-NOVFP-NOT: s0
    267 ; THUMB-NOVFP: no_fast_callee
    268 ; THUMB-NOVFP-NOT: s0
    269   call void @print(float %i)
    270   ret void
    271 }
    272 
    273 define void @no_fast_caller() ssp {
    274 entry:
    275 ; ARM: no_fast_caller
    276 ; ARM: vmov r0, s0
    277 ; THUMB: no_fast_caller
    278 ; THUMB: vmov r0, s0
    279 ; ARM-NOVFP: no_fast_caller
    280 ; ARM-NOVFP: movw r0, #13107
    281 ; ARM-NOVFP: movt r0, #16611
    282 ; THUMB-NOVFP: no_fast_caller
    283 ; THUMB-NOVFP: movw r0, #13107
    284 ; THUMB-NOVFP: movt r0, #16611
    285   call void @no_fast_callee(float 0x401C666660000000)
    286   ret void
    287 }
    288 
    289 declare void @print(float)
    290