1; RUN: llc -mattr=sram,addsubiw < %s -march=avr | FileCheck %s
2
3@char = common global i8 0
4@char.array = common global [3 x i8] zeroinitializer
5@char.static = internal global i8 0
6
7@int = common global i16 0
8@int.array = common global [3 x i16] zeroinitializer
9@int.static = internal global i16 0
10
11@long = common global i32 0
12@long.array = common global [3 x i32] zeroinitializer
13@long.static = internal global i32 0
14
15@longlong = common global i64 0
16@longlong.array = common global [3 x i64] zeroinitializer
17@longlong.static = internal global i64 0
18
19define void @global8_store() {
20; CHECK-LABEL: global8_store:
21; CHECK: ldi [[REG:r[0-9]+]], 6
22; CHECK: sts char, [[REG]]
23  store i8 6, i8* @char
24  ret void
25}
26
27define i8 @global8_load() {
28; CHECK-LABEL: global8_load:
29; CHECK: lds r24, char
30  %result = load i8, i8* @char
31  ret i8 %result
32}
33
34define void @array8_store() {
35; CHECK-LABEL: array8_store:
36; CHECK: ldi [[REG1:r[0-9]+]], 3
37; CHECK: sts char.array+2, [[REG1]]
38; CHECK: ldi [[REG3:r[0-9]+]], 1
39; CHECK: ldi [[REG2:r[0-9]+]], 2
40; CHECK: sts char.array+1, [[REG2]]
41; CHECK: sts char.array, [[REG3]]
42  store i8 1, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @char.array, i32 0, i64 0)
43  store i8 2, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @char.array, i32 0, i64 1)
44  store i8 3, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @char.array, i32 0, i64 2)
45  ret void
46}
47
48define i8 @array8_load() {
49; CHECK-LABEL: array8_load:
50; CHECK: lds r24, char.array+2
51  %result = load i8, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @char.array, i32 0, i64 2)
52  ret i8 %result
53}
54
55define i8 @static8_inc() {
56; CHECK-LABEL: static8_inc:
57; CHECK: lds r24, char.static
58; CHECK: inc r24
59; CHECK: sts char.static, r24
60  %1 = load i8, i8* @char.static
61  %inc = add nsw i8 %1, 1
62  store i8 %inc, i8* @char.static
63  ret i8 %inc
64}
65
66define void @global16_store() {
67; CHECK-LABEL: global16_store:
68; CHECK: ldi [[REG1:r[0-9]+]], 187
69; CHECK: ldi [[REG2:r[0-9]+]], 170
70; CHECK: sts int+1, [[REG2]]
71; CHECK: sts int, [[REG1]]
72  store i16 43707, i16* @int
73  ret void
74}
75
76define i16 @global16_load() {
77; CHECK-LABEL: global16_load:
78; CHECK: lds r24, int
79; CHECK: lds r25, int+1
80  %result = load i16, i16* @int
81  ret i16 %result
82}
83
84define void @array16_store() {
85; CHECK-LABEL: array16_store:
86
87; CHECK: ldi [[REG1:r[0-9]+]], 221
88; CHECK: ldi [[REG2:r[0-9]+]], 170
89; CHECK: sts int.array+5, [[REG2]]
90; CHECK: sts int.array+4, [[REG1]]
91
92; CHECK: ldi [[REG1:r[0-9]+]], 204
93; CHECK: ldi [[REG2:r[0-9]+]], 170
94; CHECK: sts int.array+3, [[REG2]]
95; CHECK: sts int.array+2, [[REG1]]
96
97; CHECK: ldi [[REG1:r[0-9]+]], 187
98; CHECK: ldi [[REG2:r[0-9]+]], 170
99; CHECK: sts int.array+1, [[REG2]]
100; CHECK: sts int.array, [[REG1]]
101  store i16 43707, i16* getelementptr inbounds ([3 x i16], [3 x i16]* @int.array, i32 0, i64 0)
102  store i16 43724, i16* getelementptr inbounds ([3 x i16], [3 x i16]* @int.array, i32 0, i64 1)
103  store i16 43741, i16* getelementptr inbounds ([3 x i16], [3 x i16]* @int.array, i32 0, i64 2)
104  ret void
105}
106
107define i16 @array16_load() {
108; CHECK-LABEL: array16_load:
109; CHECK: lds r24, int.array+4
110; CHECK: lds r25, int.array+5
111  %result = load i16, i16* getelementptr inbounds ([3 x i16], [3 x i16]* @int.array, i32 0, i64 2)
112  ret i16 %result
113}
114
115define i16 @static16_inc() {
116; CHECK-LABEL: static16_inc:
117; CHECK: lds r24, int.static
118; CHECK: lds r25, int.static+1
119; CHECK: adiw r24, 1
120; CHECK: sts int.static+1, r25
121; CHECK: sts int.static, r24
122  %1 = load i16, i16* @int.static
123  %inc = add nsw i16 %1, 1
124  store i16 %inc, i16* @int.static
125  ret i16 %inc
126}
127
128define void @global32_store() {
129; CHECK-LABEL: global32_store:
130; CHECK: ldi [[REG1:r[0-9]+]], 187
131; CHECK: ldi [[REG2:r[0-9]+]], 170
132; CHECK: sts long+3, [[REG2]]
133; CHECK: sts long+2, [[REG1]]
134; CHECK: ldi [[REG1:r[0-9]+]], 221
135; CHECK: ldi [[REG2:r[0-9]+]], 204
136; CHECK: sts long+1, [[REG2]]
137; CHECK: sts long, [[REG1]]
138  store i32 2864434397, i32* @long
139  ret void
140}
141
142define i32 @global32_load() {
143; CHECK-LABEL: global32_load:
144; CHECK: lds r22, long
145; CHECK: lds r23, long+1
146; CHECK: lds r24, long+2
147; CHECK: lds r25, long+3
148  %result = load i32, i32* @long
149  ret i32 %result
150}
151
152define void @array32_store() {
153; CHECK-LABEL: array32_store:
154
155; CHECK: ldi [[REG1:r[0-9]+]], 170
156; CHECK: ldi [[REG2:r[0-9]+]], 153
157; CHECK: sts long.array+11, [[REG2]]
158; CHECK: sts long.array+10, [[REG1]]
159
160; CHECK: ldi [[REG1:r[0-9]+]], 204
161; CHECK: ldi [[REG2:r[0-9]+]], 187
162; CHECK: sts long.array+9, [[REG2]]
163; CHECK: sts long.array+8, [[REG1]]
164
165; CHECK: ldi [[REG1:r[0-9]+]], 102
166; CHECK: ldi [[REG2:r[0-9]+]], 85
167; CHECK: sts long.array+7, [[REG2]]
168; CHECK: sts long.array+6, [[REG1]]
169
170; CHECK: ldi [[REG1:r[0-9]+]], 136
171; CHECK: ldi [[REG2:r[0-9]+]], 119
172; CHECK: sts long.array+5, [[REG2]]
173; CHECK: sts long.array+4, [[REG1]]
174
175; CHECK: ldi [[REG1:r[0-9]+]], 27
176; CHECK: ldi [[REG2:r[0-9]+]], 172
177; CHECK: sts long.array+3, [[REG2]]
178; CHECK: sts long.array+2, [[REG1]]
179
180; CHECK: ldi [[REG1:r[0-9]+]], 68
181; CHECK: ldi [[REG2:r[0-9]+]], 13
182; CHECK: sts long.array+1, [[REG2]]
183; CHECK: sts long.array, [[REG1]]
184  store i32 2887454020, i32* getelementptr inbounds ([3 x i32], [3 x i32]* @long.array, i32 0, i64 0)
185  store i32 1432778632, i32* getelementptr inbounds ([3 x i32], [3 x i32]* @long.array, i32 0, i64 1)
186  store i32 2578103244, i32* getelementptr inbounds ([3 x i32], [3 x i32]* @long.array, i32 0, i64 2)
187  ret void
188}
189
190define i32 @array32_load() {
191; CHECK-LABEL: array32_load:
192; CHECK: lds r22, long.array+8
193; CHECK: lds r23, long.array+9
194; CHECK: lds r24, long.array+10
195; CHECK: lds r25, long.array+11
196  %result = load i32, i32* getelementptr inbounds ([3 x i32], [3 x i32]* @long.array, i32 0, i64 2)
197  ret i32 %result
198}
199
200define i32 @static32_inc() {
201; CHECK-LABEL: static32_inc:
202; CHECK: lds r22, long.static
203; CHECK: lds r23, long.static+1
204; CHECK: lds r24, long.static+2
205; CHECK: lds r25, long.static+3
206; CHECK: subi r22, 255
207; CHECK: sbci r23, 255
208; CHECK: sbci r24, 255
209; CHECK: sbci r25, 255
210; CHECK-DAG: sts long.static+3, r25
211; CHECK-DAG: sts long.static+2, r24
212; CHECK-DAG: sts long.static+1, r23
213; CHECK-DAG: sts long.static, r22
214  %1 = load i32, i32* @long.static
215  %inc = add nsw i32 %1, 1
216  store i32 %inc, i32* @long.static
217  ret i32 %inc
218}
219
220define void @global64_store() {
221; CHECK-LABEL: global64_store:
222; CHECK: ldi [[REG1:r[0-9]+]], 34
223; CHECK: ldi [[REG2:r[0-9]+]], 17
224; CHECK: sts longlong+7, [[REG2]]
225; CHECK: sts longlong+6, [[REG1]]
226; CHECK: ldi [[REG1:r[0-9]+]], 68
227; CHECK: ldi [[REG2:r[0-9]+]], 51
228; CHECK: sts longlong+5, [[REG2]]
229; CHECK: sts longlong+4, [[REG1]]
230; CHECK: ldi [[REG1:r[0-9]+]], 102
231; CHECK: ldi [[REG2:r[0-9]+]], 85
232; CHECK: sts longlong+3, [[REG2]]
233; CHECK: sts longlong+2, [[REG1]]
234; CHECK: ldi [[REG1:r[0-9]+]], 136
235; CHECK: ldi [[REG2:r[0-9]+]], 119
236; CHECK: sts longlong+1, [[REG2]]
237; CHECK: sts longlong, [[REG1]]
238  store i64 1234605616436508552, i64* @longlong
239  ret void
240}
241
242define i64 @global64_load() {
243; CHECK-LABEL: global64_load:
244; CHECK: lds r18, longlong
245; CHECK: lds r19, longlong+1
246; CHECK: lds r20, longlong+2
247; CHECK: lds r21, longlong+3
248; CHECK: lds r22, longlong+4
249; CHECK: lds r23, longlong+5
250; CHECK: lds r24, longlong+6
251; CHECK: lds r25, longlong+7
252  %result = load i64, i64* @longlong
253  ret i64 %result
254}
255
256define void @array64_store() {
257; CHECK-LABEL: array64_store:
258; CHECK: ldi [[REG1:r[0-9]+]], 34
259; CHECK: ldi [[REG2:r[0-9]+]], 17
260; CHECK: sts longlong.array+7, [[REG2]]
261; CHECK: sts longlong.array+6, [[REG1]]
262; CHECK: ldi [[REG1:r[0-9]+]], 68
263; CHECK: ldi [[REG2:r[0-9]+]], 51
264; CHECK: sts longlong.array+5, [[REG2]]
265; CHECK: sts longlong.array+4, [[REG1]]
266; CHECK: ldi [[REG1:r[0-9]+]], 102
267; CHECK: ldi [[REG2:r[0-9]+]], 85
268; CHECK: sts longlong.array+3, [[REG2]]
269; CHECK: sts longlong.array+2, [[REG1]]
270; CHECK: ldi [[REG1:r[0-9]+]], 136
271; CHECK: ldi [[REG2:r[0-9]+]], 119
272; CHECK: sts longlong.array+1, [[REG2]]
273; CHECK: sts longlong.array, [[REG1]]
274  store i64 1234605616436508552, i64* getelementptr inbounds ([3 x i64], [3 x i64]* @longlong.array, i64 0, i64 0)
275  store i64 81985529216486895, i64* getelementptr inbounds ([3 x i64], [3 x i64]* @longlong.array, i64 0, i64 1)
276  store i64 1836475854449306472, i64* getelementptr inbounds ([3 x i64], [3 x i64]* @longlong.array, i64 0, i64 2)
277  ret void
278}
279
280define i64 @array64_load() {
281; CHECK-LABEL: array64_load:
282; CHECK: lds r18, longlong.array+16
283; CHECK: lds r19, longlong.array+17
284; CHECK: lds r20, longlong.array+18
285; CHECK: lds r21, longlong.array+19
286; CHECK: lds r22, longlong.array+20
287; CHECK: lds r23, longlong.array+21
288; CHECK: lds r24, longlong.array+22
289; CHECK: lds r25, longlong.array+23
290  %result = load i64, i64* getelementptr inbounds ([3 x i64], [3 x i64]* @longlong.array, i64 0, i64 2)
291  ret i64 %result
292}
293
294define i64 @static64_inc() {
295; CHECK-LABEL: static64_inc:
296; CHECK: lds r18, longlong.static
297; CHECK: lds r19, longlong.static+1
298; CHECK: lds r20, longlong.static+2
299; CHECK: lds r21, longlong.static+3
300; CHECK: lds r22, longlong.static+4
301; CHECK: lds r23, longlong.static+5
302; CHECK: lds r24, longlong.static+6
303; CHECK: lds r25, longlong.static+7
304; CHECK: subi r18, 255
305; CHECK: sbci r19, 255
306; CHECK: sbci r20, 255
307; CHECK: sbci r21, 255
308; CHECK: sbci r22, 255
309; CHECK: sbci r23, 255
310; CHECK: sbci r24, 255
311; CHECK: sbci r25, 255
312; CHECK-DAG: sts longlong.static+7, r25
313; CHECK-DAG: sts longlong.static+6, r24
314; CHECK-DAG: sts longlong.static+5, r23
315; CHECK-DAG: sts longlong.static+4, r22
316; CHECK-DAG: sts longlong.static+3, r21
317; CHECK-DAG: sts longlong.static+2, r20
318; CHECK-DAG: sts longlong.static+1, r19
319; CHECK-DAG: sts longlong.static, r18
320  %1 = load i64, i64* @longlong.static
321  %inc = add nsw i64 %1, 1
322  store i64 %inc, i64* @longlong.static
323  ret i64 %inc
324}
325
326define i8 @constantaddr_read8() {
327; CHECK-LABEL: constantaddr_read8:
328; CHECK: lds r24, 1234
329  %1 = load i8, i8* inttoptr (i16 1234 to i8*)
330  ret i8 %1
331}
332
333define i16 @constantaddr_read16() {
334; CHECK-LABEL: constantaddr_read16:
335; CHECK: lds r24, 1234
336; CHECK: lds r25, 1235
337  %1 = load i16, i16* inttoptr (i16 1234 to i16*)
338  ret i16 %1
339}
340
341define void @constantaddr_write8() {
342; CHECK-LABEL: constantaddr_write8:
343; CHECK: sts 1234
344  store i8 22, i8* inttoptr (i16 1234 to i8*)
345  ret void
346}
347
348define void @constantaddr_write16() {
349; CHECK-LABEL: constantaddr_write16:
350; CHECK: sts 1235
351; CHECK: sts 1234
352  store i16 2222, i16* inttoptr (i16 1234 to i16*)
353  ret void
354}
355