1; RUN: llc -mtriple=aarch64-unknown-linux-gnu < %s | FileCheck %s
2
3; Check the GHC call convention works (aarch64)
4
5@base  = external global i64 ; assigned to register: r19
6@sp    = external global i64 ; assigned to register: r20
7@hp    = external global i64 ; assigned to register: r21
8@r1    = external global i64 ; assigned to register: r22
9@r2    = external global i64 ; assigned to register: r23
10@r3    = external global i64 ; assigned to register: r24
11@r4    = external global i64 ; assigned to register: r25
12@r5    = external global i64 ; assigned to register: r26
13@r6    = external global i64 ; assigned to register: r27
14@splim = external global i64 ; assigned to register: r28
15
16@f1 = external global float  ; assigned to register: s8
17@f2 = external global float  ; assigned to register: s9
18@f3 = external global float  ; assigned to register: s10
19@f4 = external global float  ; assigned to register: s11
20
21@d1 = external global double ; assigned to register: d12
22@d2 = external global double ; assigned to register: d13
23@d3 = external global double ; assigned to register: d14
24@d4 = external global double ; assigned to register: d15
25
26define ghccc i64 @addtwo(i64 %x, i64 %y) nounwind {
27entry:
28  ; CHECK-LABEL: addtwo
29  ; CHECK:       add      x0, x19, x20
30  ; CHECK-NEXT:  ret
31  %0 = add i64 %x, %y
32  ret i64 %0
33}
34
35define void @zap(i64 %a, i64 %b) nounwind {
36entry:
37  ; CHECK-LABEL: zap
38  ; CHECK-NOT:   mov   {{x[0-9]+}}, sp
39  ; CHECK:       bl    addtwo
40  ; CHECK-NEXT:  bl    foo
41  %0 = call ghccc i64 @addtwo(i64 %a, i64 %b)
42  call void @foo() nounwind
43  ret void
44}
45
46define ghccc void @foo_i64 () nounwind {
47entry:
48  ; CHECK-LABEL: foo_i64
49  ; CHECK:       adrp    {{x[0-9]+}}, base
50  ; CHECK-NEXT:  ldr     x19, [{{x[0-9]+}}, :lo12:base]
51  ; CHECK-NEXT:  bl      bar_i64
52  ; CHECK-NEXT:  ret
53
54  %0 = load i64* @base
55  tail call ghccc void @bar_i64( i64 %0 ) nounwind
56  ret void
57}
58
59define ghccc void @foo_float () nounwind {
60entry:
61  ; CHECK-LABEL: foo_float
62  ; CHECK:       adrp    {{x[0-9]+}}, f1
63  ; CHECK-NEXT:  ldr     s8, [{{x[0-9]+}}, :lo12:f1]
64  ; CHECK-NEXT:  bl      bar_float
65  ; CHECK-NEXT:  ret
66
67  %0 = load float* @f1
68  tail call ghccc void @bar_float( float %0 ) nounwind
69  ret void
70}
71
72define ghccc void @foo_double () nounwind {
73entry:
74  ; CHECK-LABEL: foo_double
75  ; CHECK:       adrp    {{x[0-9]+}}, d1
76  ; CHECK-NEXT:  ldr     d12, [{{x[0-9]+}}, :lo12:d1]
77  ; CHECK-NEXT:  bl      bar_double
78  ; CHECK-NEXT:  ret
79
80  %0 = load double* @d1
81  tail call ghccc void @bar_double( double %0 ) nounwind
82  ret void
83}
84
85declare ghccc void @foo ()
86
87declare ghccc void @bar_i64 (i64)
88declare ghccc void @bar_float (float)
89declare ghccc void @bar_double (double)
90