1 ; RUN: llc < %s -march=xcore | FileCheck %s
2 ; RUN: llc < %s -march=xcore -disable-fp-elim | FileCheck %s -check-prefix=CHECKFP
4 declare i8* @llvm.frameaddress(i32) nounwind readnone
5 declare i8* @llvm.returnaddress(i32) nounwind
6 declare i8* @llvm.eh.dwarf.cfa(i32) nounwind
7 declare void @llvm.eh.return.i32(i32, i8*) nounwind
8 declare void @llvm.eh.unwind.init() nounwind
10 define i8* @FA0() nounwind {
13 ; CHECK: ldaw r0, sp[0]
15 %0 = call i8* @llvm.frameaddress(i32 0)
19 define i8* @FA1() nounwind {
23 ; CHECK-NEXT: ldaw r0, sp[0]
24 ; CHECK-NEXT: retsp 100
25 %0 = alloca [100 x i32]
26 %1 = call i8* @llvm.frameaddress(i32 0)
30 define i8* @RA0() nounwind {
33 ; CHECK: stw lr, sp[0]
34 ; CHECK-NEXT: ldw r0, sp[0]
35 ; CHECK-NEXT: ldw lr, sp[0]
37 %0 = call i8* @llvm.returnaddress(i32 0)
41 define i8* @RA1() nounwind {
45 ; CHECK-NEXT: ldw r0, sp[100]
46 ; CHECK-NEXT: retsp 100
47 %0 = alloca [100 x i32]
48 %1 = call i8* @llvm.returnaddress(i32 0)
52 ; test FRAME_TO_ARGS_OFFSET lowering
53 define i8* @FTAO0() nounwind {
57 ; CHECK-NEXT: ldaw r1, sp[0]
58 ; CHECK-NEXT: add r0, r1, r0
60 %0 = call i8* @llvm.eh.dwarf.cfa(i32 0)
64 define i8* @FTAO1() nounwind {
68 ; CHECK-NEXT: ldc r0, 400
69 ; CHECK-NEXT: ldaw r1, sp[0]
70 ; CHECK-NEXT: add r0, r1, r0
71 ; CHECK-NEXT: retsp 100
72 %0 = alloca [100 x i32]
73 %1 = call i8* @llvm.eh.dwarf.cfa(i32 0)
77 define i8* @EH0(i32 %offset, i8* %handler) {
81 ; CHECK-NEXT: ldaw r3, sp[0]
82 ; CHECK-NEXT: add r2, r3, r2
83 ; CHECK-NEXT: add r2, r2, r0
84 ; CHECK-NEXT: mov r3, r1
85 ; CHECK-NEXT: set sp, r2
87 call void @llvm.eh.return.i32(i32 %offset, i8* %handler)
91 declare void @foo(...)
92 define i8* @EH1(i32 %offset, i8* %handler) {
96 ; CHECK: stw r4, sp[2]
97 ; CHECK: stw r5, sp[1]
99 ; CHECK-NEXT: mov r5, r0
101 ; CHECK-NEXT: ldc r0, 12
102 ; CHECK-NEXT: ldaw r1, sp[0]
103 ; CHECK-NEXT: add r0, r1, r0
104 ; CHECK-NEXT: add r2, r0, r5
105 ; CHECK-NEXT: mov r3, r4
106 ; CHECK-NEXT: ldw r5, sp[1]
107 ; CHECK-NEXT: ldw r4, sp[2]
108 ; CHECK-NEXT: set sp, r2
110 call void (...)* @foo()
111 call void @llvm.eh.return.i32(i32 %offset, i8* %handler)
115 @offset = external constant i32
116 @handler = external constant i8
117 define i8* @EH2(i32 %r0, i32 %r1, i32 %r2, i32 %r3) {
122 ; CHECK-NEXT: ldw r0, cp[offset]
123 ; CHECK-NEXT: ldc r1, 4
124 ; CHECK-NEXT: ldaw r2, sp[0]
125 ; CHECK-NEXT: add r1, r2, r1
126 ; CHECK-NEXT: add r2, r1, r0
127 ; CHECK-NEXT: ldaw r11, cp[handler]
128 ; CHECK-NEXT: mov r3, r11
129 ; CHECK-NEXT: set sp, r2
131 call void (...)* @foo()
132 %0 = load i32* @offset
133 call void @llvm.eh.return.i32(i32 %0, i8* @handler)
138 ; FP: spill FP+SR+R4:9 = entsp 2 + 6
139 ; CHECKFP-LABEL: Unwind0:
141 ; CHECKFP: stw r10, sp[1]
142 ; CHECKFP: ldaw r10, sp[0]
143 ; CHECKFP: stw r4, r10[7]
144 ; CHECKFP: stw r5, r10[6]
145 ; CHECKFP: stw r6, r10[5]
146 ; CHECKFP: stw r7, r10[4]
147 ; CHECKFP: stw r8, r10[3]
148 ; CHECKFP: stw r9, r10[2]
149 ; CHECKFP: ldw r9, r10[2]
150 ; CHECKFP: ldw r8, r10[3]
151 ; CHECKFP: ldw r7, r10[4]
152 ; CHECKFP: ldw r6, r10[5]
153 ; CHECKFP: ldw r5, r10[6]
154 ; CHECKFP: ldw r4, r10[7]
155 ; CHECKFP: set sp, r10
156 ; CHECKFP: ldw r10, sp[1]
159 ; !FP: spill R4:10 = entsp 7
160 ; CHECK-LABEL: Unwind0:
162 ; CHECK: stw r4, sp[6]
163 ; CHECK: stw r5, sp[5]
164 ; CHECK: stw r6, sp[4]
165 ; CHECK: stw r7, sp[3]
166 ; CHECK: stw r8, sp[2]
167 ; CHECK: stw r9, sp[1]
168 ; CHECK: stw r10, sp[0]
169 ; CHECK: ldw r10, sp[0]
170 ; CHECK: ldw r9, sp[1]
171 ; CHECK: ldw r8, sp[2]
172 ; CHECK: ldw r7, sp[3]
173 ; CHECK: ldw r6, sp[4]
174 ; CHECK: ldw r5, sp[5]
175 ; CHECK: ldw r4, sp[6]
177 define void @Unwind0() {
178 call void @llvm.eh.unwind.init()
183 ; FP: spill FP+SR+R4:9+LR = entsp 2 + 6 + extsp 1
184 ; CHECKFP-LABEL: Unwind1:
186 ; CHECKFP: stw r10, sp[1]
187 ; CHECKFP: ldaw r10, sp[0]
188 ; CHECKFP: stw r4, r10[7]
189 ; CHECKFP: stw r5, r10[6]
190 ; CHECKFP: stw r6, r10[5]
191 ; CHECKFP: stw r7, r10[4]
192 ; CHECKFP: stw r8, r10[3]
193 ; CHECKFP: stw r9, r10[2]
196 ; CHECKFP: ldaw sp, sp[1]
197 ; CHECKFP: ldw r9, r10[2]
198 ; CHECKFP: ldw r8, r10[3]
199 ; CHECKFP: ldw r7, r10[4]
200 ; CHECKFP: ldw r6, r10[5]
201 ; CHECKFP: ldw r5, r10[6]
202 ; CHECKFP: ldw r4, r10[7]
203 ; CHECKFP: set sp, r10
204 ; CHECKFP: ldw r10, sp[1]
207 ; !FP: spill R4:10+LR = entsp 7 + 1
208 ; CHECK-LABEL: Unwind1:
210 ; CHECK: stw r4, sp[7]
211 ; CHECK: stw r5, sp[6]
212 ; CHECK: stw r6, sp[5]
213 ; CHECK: stw r7, sp[4]
214 ; CHECK: stw r8, sp[3]
215 ; CHECK: stw r9, sp[2]
216 ; CHECK: stw r10, sp[1]
218 ; CHECK: ldw r10, sp[1]
219 ; CHECK: ldw r9, sp[2]
220 ; CHECK: ldw r8, sp[3]
221 ; CHECK: ldw r7, sp[4]
222 ; CHECK: ldw r6, sp[5]
223 ; CHECK: ldw r5, sp[6]
224 ; CHECK: ldw r4, sp[7]
226 define void @Unwind1() {
227 call void (...)* @foo()
228 call void @llvm.eh.unwind.init()