1 ; RUN: llc < %s -march=avr | FileCheck %s
4 @funcptr = global ptr addrspace(1) null
6 define avr_intrcc void @interrupt_handler() {
7 ; CHECK-LABEL: interrupt_handler:
10 ; CHECK-NEXT: in r0, 63
13 ; CHECK-NEXT: out 63, r0
19 define void @interrupt_handler_via_ir_attribute() #0 {
20 ; CHECK-LABEL: interrupt_handler_via_ir_attribute:
23 ; CHECK-NEXT: in r0, 63
26 ; CHECK-NEXT: out 63, r0
32 define avr_signalcc void @signal_handler() {
33 ; CHECK-LABEL: signal_handler:
36 ; CHECK-NEXT: in r0, 63
39 ; CHECK-NEXT: out 63, r0
45 define void @signal_handler_via_attribute() #1 {
46 ; CHECK-LABEL: signal_handler_via_attribute:
49 ; CHECK-NEXT: in r0, 63
52 ; CHECK-NEXT: out 63, r0
58 define avr_intrcc void @interrupt_alloca() {
59 ; CHECK-LABEL: interrupt_alloca:
62 ; CHECK-NEXT: in r0, 63
65 ; CHECK-NEXT: push r29
66 ; CHECK-NEXT: in r28, 61
67 ; CHECK-NEXT: in r29, 62
68 ; CHECK-NEXT: sbiw r28, 1
69 ; CHECK-NEXT: in r0, 63
71 ; CHECK-NEXT: out 62, r29
72 ; CHECK-NEXT: out 63, r0
73 ; CHECK-NEXT: out 61, r28
75 ; CHECK-NEXT: in r0, 63
77 ; CHECK-NEXT: out 62, r29
78 ; CHECK-NEXT: out 63, r0
79 ; CHECK-NEXT: out 61, r28
83 ; CHECK-NEXT: out 63, r0
90 define void @signal_handler_with_increment() #1 {
91 ; CHECK-LABEL: signal_handler_with_increment:
93 ; CHECK-NEXT: in r0, 63
95 ; CHECK-NEXT: push r24
96 ; CHECK-NEXT: lds r24, count
98 ; CHECK-NEXT: sts count, r24
101 ; CHECK-NEXT: out 63, r0
104 %old = load volatile i8, ptr @count
105 %new = add i8 %old, 1
106 store volatile i8 %new, ptr @count
110 ; Check that r1 is saved/restored and set to 0 when using inline assembly.
111 define void @signal_handler_with_asm() #1 {
112 ; CHECK-LABEL: signal_handler_with_asm:
114 ; CHECK-NEXT: in r0, 63
115 ; CHECK-NEXT: push r0
116 ; CHECK-NEXT: push r1
118 ; CHECK-NEXT: push r24
126 ; CHECK-NEXT: out 63, r0
129 call i8 asm sideeffect "mov $0, $1", "=r,r"(i8 3) nounwind
135 ; When a signal handler calls a function, it must push/pop all call clobbered
137 define void @signal_handler_with_call() #1 {
138 ; CHECK-LABEL: signal_handler_with_call:
140 ; CHECK-NEXT: in r0, 63
141 ; CHECK-NEXT: push r0
142 ; CHECK-NEXT: push r1
144 ; CHECK-NEXT: push r18
145 ; CHECK-NEXT: push r19
146 ; CHECK-NEXT: push r20
147 ; CHECK-NEXT: push r21
148 ; CHECK-NEXT: push r22
149 ; CHECK-NEXT: push r23
150 ; CHECK-NEXT: push r24
151 ; CHECK-NEXT: push r25
152 ; CHECK-NEXT: push r26
153 ; CHECK-NEXT: push r27
154 ; CHECK-NEXT: push r30
155 ; CHECK-NEXT: push r31
156 ; CHECK-NEXT: call foo
157 ; CHECK-NEXT: pop r31
158 ; CHECK-NEXT: pop r30
159 ; CHECK-NEXT: pop r27
160 ; CHECK-NEXT: pop r26
161 ; CHECK-NEXT: pop r25
162 ; CHECK-NEXT: pop r24
163 ; CHECK-NEXT: pop r23
164 ; CHECK-NEXT: pop r22
165 ; CHECK-NEXT: pop r21
166 ; CHECK-NEXT: pop r20
167 ; CHECK-NEXT: pop r19
168 ; CHECK-NEXT: pop r18
171 ; CHECK-NEXT: out 63, r0
178 define void @signal_handler_with_icall() #1 {
179 ; CHECK-LABEL: signal_handler_with_icall:
181 ; CHECK-NEXT: in r0, 63
182 ; CHECK-NEXT: push r0
183 ; CHECK-NEXT: push r1
185 ; CHECK-NEXT: push r18
186 ; CHECK-NEXT: push r19
187 ; CHECK-NEXT: push r20
188 ; CHECK-NEXT: push r21
189 ; CHECK-NEXT: push r22
190 ; CHECK-NEXT: push r23
191 ; CHECK-NEXT: push r24
192 ; CHECK-NEXT: push r25
193 ; CHECK-NEXT: push r26
194 ; CHECK-NEXT: push r27
195 ; CHECK-NEXT: push r30
196 ; CHECK-NEXT: push r31
197 ; CHECK-NEXT: lds r30, funcptr
198 ; CHECK-NEXT: lds r31, funcptr+1
200 ; CHECK-NEXT: pop r31
201 ; CHECK-NEXT: pop r30
202 ; CHECK-NEXT: pop r27
203 ; CHECK-NEXT: pop r26
204 ; CHECK-NEXT: pop r25
205 ; CHECK-NEXT: pop r24
206 ; CHECK-NEXT: pop r23
207 ; CHECK-NEXT: pop r22
208 ; CHECK-NEXT: pop r21
209 ; CHECK-NEXT: pop r20
210 ; CHECK-NEXT: pop r19
211 ; CHECK-NEXT: pop r18
214 ; CHECK-NEXT: out 63, r0
217 %ptr = load volatile ptr addrspace(1), ptr @funcptr
222 attributes #0 = { "interrupt" }
223 attributes #1 = { "signal" }