Home | History | Annotate | Download | only in ARM
      1 ; RUN: llc -mtriple=thumbv7m-none-macho %s -o - -relocation-model=pic -disable-fp-elim | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NON-FAST
      2 ; RUN: llc -mtriple=thumbv7m-none-macho -O0 %s -o - -relocation-model=pic -disable-fp-elim | FileCheck %s
      3 ; RUN: llc -mtriple=thumbv7m-none-macho -filetype=obj %s -o /dev/null
      4 
      5   ; Bare-metal should probably "declare" segments just like normal MachO
      6 ; CHECK: __picsymbolstub4
      7 ; CHECK: __StaticInit
      8 ; CHECK: __text
      9 
     10 @var = external global i32
     11 
     12 define i32 @test_litpool() minsize {
     13 ; CHECK-LABEL: test_litpool:
     14   %val = load i32* @var
     15   ret i32 %val
     16 
     17   ; Lit-pool entries need to produce a "$non_lazy_ptr" version of the symbol.
     18 ; CHECK: LCPI0_0:
     19 ; CHECK-NEXT: .long L_var$non_lazy_ptr-(LPC0_0+4)
     20 }
     21 
     22 define i32 @test_movw_movt() {
     23 ; CHECK-LABEL: test_movw_movt:
     24   %val = load i32* @var
     25   ret i32 %val
     26 
     27   ; movw/movt should also address their symbols MachO-style
     28 ; CHECK: movw [[RTMP:r[0-9]+]], :lower16:(L_var$non_lazy_ptr-(LPC1_0+4))
     29 ; CHECK: movt [[RTMP]], :upper16:(L_var$non_lazy_ptr-(LPC1_0+4))
     30 ; CHECK: LPC1_0:
     31 ; CHECK: add [[RTMP]], pc
     32 }
     33 
     34 declare void @llvm.trap()
     35 
     36 define void @test_trap() {
     37 ; CHECK-LABEL: test_trap:
     38 
     39   ; Bare-metal MachO gets compiled on top of normal MachO toolchain which
     40   ; understands trap natively.
     41   call void @llvm.trap()
     42 ; CHECK: trap
     43 
     44   ret void
     45 }
     46 
     47 define i32 @test_frame_ptr() {
     48 ; CHECK-LABEL: test_frame_ptr:
     49   call void @test_trap()
     50 
     51   ; Frame pointer is r11.
     52 ; CHECK: mov r11, sp
     53   ret i32 42
     54 }
     55 
     56 %big_arr = type [8 x i32]
     57 define void @test_two_areas(%big_arr* %addr) {
     58 ; CHECK-LABEL: test_two_areas:
     59   %val = load %big_arr* %addr
     60   call void @test_trap()
     61   store %big_arr %val, %big_arr* %addr
     62 
     63   ; This goes with the choice of r7 as FP (largely). FP and LR have to be stored
     64   ; consecutively on the stack for the frame record to be valid, which means we
     65   ; need the 2 register-save areas employed by iOS.
     66 ; CHECK-NON-FAST: push.w {r4, r5, r6, r7, r8, r9, r10, r11, lr}
     67 ; ...
     68 ; CHECK-NON-FAST: pop.w {r4, r5, r6, r7, r8, r9, r10, r11, pc}
     69   ret void
     70 }
     71 
     72 define void @test_tail_call() {
     73 ; CHECK-LABEL: test_tail_call:
     74   tail call void @test_trap()
     75 
     76   ; Tail calls should be available and use Thumb2 branch.
     77 ; CHECK: b.w _test_trap
     78   ret void
     79 }
     80 
     81 define float @test_softfloat_calls(float %in) {
     82 ; CHECK-LABEL: test_softfloat_calls:
     83   %sum = fadd float %in, %in
     84 
     85   ; Soft-float calls should be GNU-style rather than RTABI and should not be the
     86   ; *vfp variants used for ARMv6 iOS.
     87 ; CHECK: blx ___addsf3{{$}}
     88   ret float %sum
     89 }
     90 
     91   ; Even bare-metal PIC needs GOT-like behaviour, in principle. Depends a bit on
     92   ; the use-case of course, but LLVM doesn't know what that is.
     93 ; CHECK: non_lazy_symbol_pointers
     94 ; CHECK: L_var$non_lazy_ptr:
     95 ; CHECK-NEXT:   .indirect_symbol _var
     96 
     97   ; All MachO objects should have this to give the linker leeway in removing
     98   ; dead code.
     99 ; CHECK: .subsections_via_symbols
    100