XCore target: Lower EH_RETURN
[oota-llvm.git] / test / CodeGen / XCore / llvm-intrinsics.ll
1 ; RUN: llc < %s -march=xcore | FileCheck %s
2
3 declare i8* @llvm.frameaddress(i32) nounwind readnone
4 define i8* @FA0() nounwind {
5 entry:
6 ; CHECK-LABEL: FA0
7 ; CHECK: ldaw r0, sp[0]
8 ; CHECK-NEXT: retsp 0
9   %0 = call i8* @llvm.frameaddress(i32 0)
10   ret i8* %0
11 }
12
13 define i8* @FA1() nounwind {
14 entry:
15 ; CHECK-LABEL: FA1
16 ; CHECK: entsp 100
17 ; CHECK-NEXT: ldaw r0, sp[0]
18 ; CHECK-NEXT: retsp 100
19   %0 = alloca [100 x i32]
20   %1 = call i8* @llvm.frameaddress(i32 0)
21   ret i8* %1
22 }
23
24 declare i8* @llvm.returnaddress(i32) nounwind readnone
25 define i8* @RA0() nounwind {
26 entry:
27 ; CHECK-LABEL: RA0
28 ; CHECK: stw lr, sp[0]
29 ; CHECK-NEXT: ldw r0, sp[0]
30 ; CHECK-NEXT: ldw lr, sp[0]
31 ; CHECK-NEXT: retsp 0
32   %0 = call i8* @llvm.returnaddress(i32 0)
33   ret i8* %0
34 }
35
36 define i8* @RA1() nounwind {
37 entry:
38 ; CHECK-LABEL: RA1
39 ; CHECK: entsp 100
40 ; CHECK-NEXT: ldw r0, sp[100]
41 ; CHECK-NEXT: retsp 100
42   %0 = alloca [100 x i32]
43   %1 = call i8* @llvm.returnaddress(i32 0)
44   ret i8* %1
45 }
46
47 ; test FRAME_TO_ARGS_OFFSET lowering
48 declare i8* @llvm.eh.dwarf.cfa(i32) nounwind
49 define i8* @FTAO0() nounwind {
50 entry:
51 ; CHECK-LABEL: FTAO0
52 ; CHECK: ldc r0, 0
53 ; CHECK-NEXT: ldaw r1, sp[0]
54 ; CHECK-NEXT: add r0, r1, r0
55 ; CHECK-NEXT: retsp 0
56   %0 = call i8* @llvm.eh.dwarf.cfa(i32 0)
57   ret i8* %0
58 }
59
60 define i8* @FTAO1() nounwind {
61 entry:
62 ; CHECK-LABEL: FTAO1
63 ; CHECK: entsp 100
64 ; CHECK-NEXT: ldc r0, 400
65 ; CHECK-NEXT: ldaw r1, sp[0]
66 ; CHECK-NEXT: add r0, r1, r0
67 ; CHECK-NEXT: retsp 100
68   %0 = alloca [100 x i32]
69   %1 = call i8* @llvm.eh.dwarf.cfa(i32 0)
70   ret i8* %1
71 }
72
73 declare void @llvm.eh.return.i32(i32, i8*)
74 define i8* @EH0(i32 %offset, i8* %handler) {
75 entry:
76 ; CHECK-LABEL: EH0
77 ; CHECK: ldc r2, 0
78 ; CHECK-NEXT: ldaw r3, sp[0]
79 ; CHECK-NEXT: add r2, r3, r2
80 ; CHECK-NEXT: add r2, r2, r0
81 ; CHECK-NEXT: mov r3, r1
82 ; CHECK-NEXT: set sp, r2
83 ; CHECK-NEXT: bau r3
84   call void @llvm.eh.return.i32(i32 %offset, i8* %handler)
85   unreachable
86 }
87
88 declare void @foo(...)
89 define i8* @EH1(i32 %offset, i8* %handler) {
90 entry:
91 ; CHECK-LABEL: EH1
92 ; CHECK: entsp 3
93 ; CHECK: stw r4, sp[2]
94 ; CHECK: stw r5, sp[1]
95 ; CHECK: mov r4, r1
96 ; CHECK-NEXT: mov r5, r0
97 ; CHECK-NEXT: bl foo
98 ; CHECK-NEXT: ldc r0, 12
99 ; CHECK-NEXT: ldaw r1, sp[0]
100 ; CHECK-NEXT: add r0, r1, r0
101 ; CHECK-NEXT: add r2, r0, r5
102 ; CHECK-NEXT: mov r3, r4
103 ; CHECK-NEXT: ldw r5, sp[1]
104 ; CHECK-NEXT: ldw r4, sp[2]
105 ; CHECK-NEXT: set sp, r2
106 ; CHECK-NEXT: bau r3
107   call void (...)* @foo()
108   call void @llvm.eh.return.i32(i32 %offset, i8* %handler)
109   unreachable
110 }
111
112 @offset = external constant i32
113 @handler = external constant i8
114 define i8* @EH2(i32 %r0, i32 %r1, i32 %r2, i32 %r3) {
115 entry:
116 ; CHECK-LABEL: EH2
117 ; CHECK: entsp 1
118 ; CHECK: bl foo
119 ; CHECK-NEXT: ldw r0, cp[offset]
120 ; CHECK-NEXT: ldc r1, 4
121 ; CHECK-NEXT: ldaw r2, sp[0]
122 ; CHECK-NEXT: add r1, r2, r1
123 ; CHECK-NEXT: add r2, r1, r0
124 ; CHECK-NEXT: ldaw r11, cp[handler]
125 ; CHECK-NEXT: mov r3, r11
126 ; CHECK-NEXT: set sp, r2
127 ; CHECK-NEXT: bau r3
128   call void (...)* @foo()
129   %0 = load i32* @offset
130   call void @llvm.eh.return.i32(i32 %0, i8* @handler)
131   unreachable
132 }