; RUN: llc < %s -march=arm -tailcallopt -mtriple=arm-linux-gnu | FileCheck %s

; Check the GHC call convention works (ARM)

@base  = external global i32 ; assigned to register: R4
@sp    = external global i32 ; assigned to register: R5
@hp    = external global i32 ; assigned to register: R6
@r1    = external global i32 ; assigned to register: R7
@r2    = external global i32 ; assigned to register: R8
@r3    = external global i32 ; assigned to register: R9
@r4    = external global i32 ; assigned to register: R10
@splim = external global i32 ; assigned to register: R11

@f1 = external global float  ; assigned to register: S16
@f2 = external global float  ; assigned to register: S17
@f3 = external global float  ; assigned to register: S18
@f4 = external global float  ; assigned to register: S19
@d1 = external global double ; assigned to register: D10
@d2 = external global double ; assigned to register: D11

define void @zap(i32 %a, i32 %b) nounwind {
entry:
  ; CHECK:      movq %rdi, %r13
  ; CHECK-NEXT: movq %rsi, %rbp
  ; CHECK-NEXT: callq addtwo
  %0 = call cc 10 i32 @addtwo(i32 %a, i32 %b)
  ; CHECK:      callq foo
  call void @foo() nounwind
  ret void
}

define cc 10 i32 @addtwo(i32 %x, i32 %y) nounwind {
entry:
  ; CHECK:      leaq (%r13,%rbp), %rax
  %0 = add i32 %x, %y
  ; CHECK-NEXT: ret
  ret i32 %0
}

define cc 10 void @foo() nounwind {
entry:
  ; CHECK: movq base(%rip), %r13
  ; CHECK-NEXT: movq sp(%rip), %rbp
  ; CHECK-NEXT: movq hp(%rip), %r12
  ; CHECK-NEXT: movq r1(%rip), %rbx
  ; CHECK-NEXT: movq r2(%rip), %r14
  ; CHECK-NEXT: movq r3(%rip), %rsi
  ; CHECK-NEXT: movq r4(%rip), %rdi
  ; CHECK-NEXT: movq splim(%rip), %r15
  ; CHECK-NEXT: movss f1(%rip), %xmm1
  ; CHECK-NEXT: movss f2(%rip), %xmm2
  ; CHECK-NEXT: movss f3(%rip), %xmm3
  ; CHECK-NEXT: movss f4(%rip), %xmm4
  ; CHECK-NEXT: movsd d1(%rip), %xmm5
  ; CHECK-NEXT: movsd d2(%rip), %xmm6
  %0 = load double* @d2
  %1 = load double* @d1
  %2 = load float* @f4
  %3 = load float* @f3
  %4 = load float* @f2
  %5 = load float* @f1
  %6 = load i32* @splim
;  %7 = load i32* @r4
;  %8 = load i32* @r3
;  %9 = load i32* @r2
;  %10 = load i32* @r1
;  %11 = load i32* @hp
;  %12 = load i32* @sp
;  %13 = load i32* @base
  ; CHECK: jmp bar
;  tail call cc 10 void @bar( i32 %13, i32 %12, i32 %11,
;                             i32 %10, i32 %9, i32 %8, i32 %7, i32 %6,
;                             float %5, float %4, float %3, float %2, double %1,
;                             double %0 ) nounwind
  tail call cc 10 void @bar2(i32 %6, float %5, float %4, float %3, float %2, double %1, double %0) nounwind
  ret void
}

declare cc 10 void @bar(i32, i32, i32, i32, i32, i32, i32, i32,
                        float, float, float, float, double, double)

declare cc 10 void @bar2(i32, float, float, float, float, double, double)