| ; RUN: llc -mtriple=aarch64-unknown-linux-gnu < %s | FileCheck %s | |
| ; Check the GHC call convention works (aarch64) | |
| @base = external global i64 ; assigned to register: r19 | |
| @sp = external global i64 ; assigned to register: r20 | |
| @hp = external global i64 ; assigned to register: r21 | |
| @r1 = external global i64 ; assigned to register: r22 | |
| @r2 = external global i64 ; assigned to register: r23 | |
| @r3 = external global i64 ; assigned to register: r24 | |
| @r4 = external global i64 ; assigned to register: r25 | |
| @r5 = external global i64 ; assigned to register: r26 | |
| @r6 = external global i64 ; assigned to register: r27 | |
| @splim = external global i64 ; assigned to register: r28 | |
| @f1 = external global float ; assigned to register: s8 | |
| @f2 = external global float ; assigned to register: s9 | |
| @f3 = external global float ; assigned to register: s10 | |
| @f4 = external global float ; assigned to register: s11 | |
| @d1 = external global double ; assigned to register: d12 | |
| @d2 = external global double ; assigned to register: d13 | |
| @d3 = external global double ; assigned to register: d14 | |
| @d4 = external global double ; assigned to register: d15 | |
| define ghccc i64 @addtwo(i64 %x, i64 %y) nounwind { | |
| entry: | |
| ; CHECK-LABEL: addtwo | |
| ; CHECK: add x0, x19, x20 | |
| ; CHECK-NEXT: ret | |
| %0 = add i64 %x, %y | |
| ret i64 %0 | |
| } | |
| define void @zap(i64 %a, i64 %b) nounwind { | |
| entry: | |
| ; CHECK-LABEL: zap | |
| ; CHECK-NOT: mov {{x[0-9]+}}, sp | |
| ; CHECK: bl addtwo | |
| ; CHECK-NEXT: bl foo | |
| %0 = call ghccc i64 @addtwo(i64 %a, i64 %b) | |
| call void @foo() nounwind | |
| ret void | |
| } | |
| define ghccc void @foo_i64 () nounwind { | |
| entry: | |
| ; CHECK-LABEL: foo_i64 | |
| ; CHECK: adrp {{x[0-9]+}}, base | |
| ; CHECK-NEXT: ldr x19, [{{x[0-9]+}}, :lo12:base] | |
| ; CHECK-NEXT: bl bar_i64 | |
| ; CHECK-NEXT: ret | |
| %0 = load i64, i64* @base | |
| tail call ghccc void @bar_i64( i64 %0 ) nounwind | |
| ret void | |
| } | |
| define ghccc void @foo_float () nounwind { | |
| entry: | |
| ; CHECK-LABEL: foo_float | |
| ; CHECK: adrp {{x[0-9]+}}, f1 | |
| ; CHECK-NEXT: ldr s8, [{{x[0-9]+}}, :lo12:f1] | |
| ; CHECK-NEXT: bl bar_float | |
| ; CHECK-NEXT: ret | |
| %0 = load float, float* @f1 | |
| tail call ghccc void @bar_float( float %0 ) nounwind | |
| ret void | |
| } | |
| define ghccc void @foo_double () nounwind { | |
| entry: | |
| ; CHECK-LABEL: foo_double | |
| ; CHECK: adrp {{x[0-9]+}}, d1 | |
| ; CHECK-NEXT: ldr d12, [{{x[0-9]+}}, :lo12:d1] | |
| ; CHECK-NEXT: bl bar_double | |
| ; CHECK-NEXT: ret | |
| %0 = load double, double* @d1 | |
| tail call ghccc void @bar_double( double %0 ) nounwind | |
| ret void | |
| } | |
| declare ghccc void @foo () | |
| declare ghccc void @bar_i64 (i64) | |
| declare ghccc void @bar_float (float) | |
| declare ghccc void @bar_double (double) |