1; RUN: llc < %s -march=avr -verify-machineinstrs | FileCheck %s
2
3; Optimize for speed.
4; CHECK-LABEL: shift_i8_i8_speed
5define i8 @shift_i8_i8_speed(i8 %a, i8 %b) {
6  ; CHECK:        dec r22
7  ; CHECK-NEXT:   brmi .LBB0_2
8  ; CHECK-NEXT: .LBB0_1:
9  ; CHECK-NEXT:   lsl r24
10  ; CHECK-NEXT:   dec r22
11  ; CHECK-NEXT:   brpl .LBB0_1
12  ; CHECK-NEXT: .LBB0_2:
13  ; CHECK-NEXT:   ret
14  %result = shl i8 %a, %b
15  ret i8 %result
16}
17
18; Optimize for size (producing slightly smaller code).
19; CHECK-LABEL: shift_i8_i8_size
20define i8 @shift_i8_i8_size(i8 %a, i8 %b) optsize {
21  ; CHECK:      .LBB1_1:
22  ; CHECK-NEXT:   dec r22
23  ; CHECK-NEXT:   brmi .LBB1_3
24  ; CHECK:        lsl r24
25  ; CHECK-NEXT:   rjmp .LBB1_1
26  ; CHECK-NEXT: .LBB1_3:
27  ; CHECK-NEXT:   ret
28  %result = shl i8 %a, %b
29  ret i8 %result
30}
31
32; CHECK-LABEL: shift_i16_i16
33define i16 @shift_i16_i16(i16 %a, i16 %b) {
34  ; CHECK:        dec r22
35  ; CHECK-NEXT:   brmi .LBB2_2
36  ; CHECK-NEXT: .LBB2_1:
37  ; CHECK-NEXT:   lsl r24
38  ; CHECK-NEXT:   rol r25
39  ; CHECK-NEXT:   dec r22
40  ; CHECK-NEXT:   brpl .LBB2_1
41  ; CHECK-NEXT: .LBB2_2:
42  ; CHECK-NEXT:   ret
43  %result = shl i16 %a, %b
44  ret i16 %result
45}
46
47; CHECK-LABEL: shift_i64_i64
48define i64 @shift_i64_i64(i64 %a, i64 %b) {
49  ; CHECK: call    __ashldi3
50  %result = shl i64 %a, %b
51  ret i64 %result
52}
53
54define i8 @lsl_i8_1(i8 %a) {
55; CHECK-LABEL: lsl_i8_1:
56; CHECK:       lsl r24
57  %res = shl i8 %a, 1
58  ret i8 %res
59}
60
61define i8 @lsl_i8_2(i8 %a) {
62; CHECK-LABEL: lsl_i8_2:
63; CHECK:       lsl r24
64; CHECK-NEXT:  lsl r24
65  %res = shl i8 %a, 2
66  ret i8 %res
67}
68
69define i8 @lsl_i8_3(i8 %a) {
70; CHECK-LABEL: lsl_i8_3:
71; CHECK:       lsl r24
72; CHECK-NEXT:  lsl r24
73; CHECK-NEXT:  lsl r24
74  %res = shl i8 %a, 3
75  ret i8 %res
76}
77
78define i8 @lsl_i8_4(i8 %a) {
79; CHECK-LABEL: lsl_i8_4:
80; CHECK:       swap r24
81; CHECK-NEXT:  andi r24, -16
82  %res = shl i8 %a, 4
83  ret i8 %res
84}
85
86define i8 @lsl_i8_5(i8 %a) {
87; CHECK-LABEL: lsl_i8_5:
88; CHECK:       swap r24
89; CHECK-NEXT:  andi r24, -16
90; CHECK-NEXT:  lsl r24
91  %res = shl i8 %a, 5
92  ret i8 %res
93}
94
95define i8 @lsl_i8_6(i8 %a) {
96; CHECK-LABEL: lsl_i8_6:
97; CHECK:       swap r24
98; CHECK-NEXT:  andi r24, -16
99; CHECK-NEXT:  lsl r24
100; CHECK-NEXT:  lsl r24
101  %res = shl i8 %a, 6
102  ret i8 %res
103}
104
105define i8 @lsr_i8_1(i8 %a) {
106; CHECK-LABEL: lsr_i8_1:
107; CHECK:       lsr r24
108  %res = lshr i8 %a, 1
109  ret i8 %res
110}
111
112define i8 @lsr_i8_2(i8 %a) {
113; CHECK-LABEL: lsr_i8_2:
114; CHECK:       lsr r24
115; CHECK-NEXT:  lsr r24
116  %res = lshr i8 %a, 2
117  ret i8 %res
118}
119
120define i8 @lsr_i8_3(i8 %a) {
121; CHECK-LABEL: lsr_i8_3:
122; CHECK:       lsr r24
123; CHECK-NEXT:  lsr r24
124; CHECK-NEXT:  lsr r24
125  %res = lshr i8 %a, 3
126  ret i8 %res
127}
128
129define i8 @lsr_i8_4(i8 %a) {
130; CHECK-LABEL: lsr_i8_4:
131; CHECK:       swap r24
132; CHECK-NEXT:  andi r24, 15
133  %res = lshr i8 %a, 4
134  ret i8 %res
135}
136
137define i8 @lsr_i8_5(i8 %a) {
138; CHECK-LABEL: lsr_i8_5:
139; CHECK:       swap r24
140; CHECK-NEXT:  andi r24, 15
141; CHECK-NEXT:  lsr r24
142  %res = lshr i8 %a, 5
143  ret i8 %res
144}
145
146define i8 @lsr_i8_6(i8 %a) {
147; CHECK-LABEL: lsr_i8_6:
148; CHECK:       swap r24
149; CHECK-NEXT:  andi r24, 15
150; CHECK-NEXT:  lsr r24
151; CHECK-NEXT:  lsr r24
152  %res = lshr i8 %a, 6
153  ret i8 %res
154}
155
156define i8 @lsl_i8_7(i8 %a) {
157; CHECK-LABEL: lsl_i8_7
158; CHECK:      ror r24
159; CHECK-NEXT: clr r24
160; CHECK-NEXT: ror r24
161  %result = shl i8 %a, 7
162  ret i8 %result
163}
164
165define i8 @lsr_i8_7(i8 %a) {
166; CHECK-LABEL: lsr_i8_7
167; CHECK:      rol r24
168; CHECK-NEXT: clr r24
169; CHECK-NEXT: rol r24
170  %result = lshr i8 %a, 7
171  ret i8 %result
172}
173
174define i8 @asr_i8_6(i8 %a) {
175; CHECK-LABEL: asr_i8_6
176; CHECK:      bst r24, 6
177; CHECK-NEXT: lsl r24
178; CHECK-NEXT: sbc r24, r24
179; CHECK-NEXT: bld r24, 0
180  %result = ashr i8 %a, 6
181  ret i8 %result
182}
183
184define i8 @asr_i8_7(i8 %a) {
185; CHECK-LABEL: asr_i8_7
186; CHECK:      lsl r24
187; CHECK-NEXT: sbc r24, r24
188  %result = ashr i8 %a, 7
189  ret i8 %result
190}
191
192define i16 @lsl_i16_5(i16 %a) {
193; CHECK-LABEL: lsl_i16_5
194; CHECK:       swap r25
195; CHECK-NEXT:  swap r24
196; CHECK-NEXT:  andi r25, 240
197; CHECK-NEXT:  eor r25, r24
198; CHECK-NEXT:  andi r24, 240
199; CHECK-NEXT:  eor r25, r24
200; CHECK-NEXT:  lsl r24
201; CHECK-NEXT:  rol r25
202; CHECK-NEXT:  ret
203  %result = shl i16 %a, 5
204  ret i16 %result
205}
206
207define i16 @lsl_i16_6(i16 %a, i16 %b, i16 %c, i16 %d, i16 %e, i16 %f) {
208; CHECK-LABEL: lsl_i16_6
209; CHECK:       mov r24, r14
210; CHECK-NEXT:  mov r25, r15
211; CHECK-NEXT:  swap r25
212; CHECK-NEXT:  swap r24
213; CHECK-NEXT:  andi r25, 240
214; CHECK-NEXT:  eor r25, r24
215; CHECK-NEXT:  andi r24, 240
216; CHECK-NEXT:  eor r25, r24
217; CHECK-NEXT:  lsl r24
218; CHECK-NEXT:  rol r25
219; CHECK-NEXT:  lsl r24
220; CHECK-NEXT:  rol r25
221; CHECK-NEXT:  ret
222  %result = shl i16 %f, 6
223  ret i16 %result
224}
225
226define i16 @lsl_i16_9(i16 %a) {
227; CHECK-LABEL: lsl_i16_9
228; CHECK:       mov r25, r24
229; CHECK-NEXT:  clr r24
230; CHECK-NEXT:  lsl r25
231; CHECK-NEXT:  ret
232  %result = shl i16 %a, 9
233  ret i16 %result
234}
235
236define i16 @lsl_i16_13(i16 %a) {
237; CHECK-LABEL: lsl_i16_13
238; CHECK:       mov r25, r24
239; CHECK-NEXT:  swap r25
240; CHECK-NEXT:  andi r25, 240
241; CHECK-NEXT:  clr r24
242; CHECK-NEXT:  lsl r25
243; CHECK-NEXT:  ret
244  %result = shl i16 %a, 13
245  ret i16 %result
246}
247
248define i16 @lsr_i16_5(i16 %a) {
249; CHECK-LABEL: lsr_i16_5
250; CHECK:       swap r25
251; CHECK-NEXT:  swap r24
252; CHECK-NEXT:  andi r24, 15
253; CHECK-NEXT:  eor r24, r25
254; CHECK-NEXT:  andi r25, 15
255; CHECK-NEXT:  eor r24, r25
256; CHECK-NEXT:  lsr r25
257; CHECK-NEXT:  ror r24
258; CHECK-NEXT:  ret
259  %result = lshr i16 %a, 5
260  ret i16 %result
261}
262
263define i16 @lsr_i16_6(i16 %a, i16 %b, i16 %c, i16 %d, i16 %e, i16 %f) {
264; CHECK-LABEL: lsr_i16_6
265; CHECK:       mov r24, r14
266; CHECK-NEXT:  mov r25, r15
267; CHECK-NEXT:  swap r25
268; CHECK-NEXT:  swap r24
269; CHECK-NEXT:  andi r24, 15
270; CHECK-NEXT:  eor r24, r25
271; CHECK-NEXT:  andi r25, 15
272; CHECK-NEXT:  eor r24, r25
273; CHECK-NEXT:  lsr r25
274; CHECK-NEXT:  ror r24
275; CHECK-NEXT:  lsr r25
276; CHECK-NEXT:  ror r24
277; CHECK-NEXT: ret
278  %result = lshr i16 %f, 6
279  ret i16 %result
280}
281
282define i16 @lsr_i16_9(i16 %a) {
283; CHECK-LABEL: lsr_i16_9
284; CHECK:       mov r24, r25
285; CHECK-NEXT:  clr r25
286; CHECK-NEXT:  lsr r24
287; CHECK-NEXT:  ret
288  %result = lshr i16 %a, 9
289  ret i16 %result
290}
291
292define i16 @lsr_i16_13(i16 %a) {
293; CHECK-LABEL: lsr_i16_13
294; CHECK:       mov r24, r25
295; CHECK-NEXT:  swap r24
296; CHECK-NEXT:  andi r24, 15
297; CHECK-NEXT:  clr r25
298; CHECK-NEXT:  lsr r24
299; CHECK-NEXT:  ret
300  %result = lshr i16 %a, 13
301  ret i16 %result
302}
303
304define i16 @asr_i16_7(i16 %a) {
305; CHECK-LABEL: asr_i16_7
306; CHECK:       lsl r24
307; CHECK-NEXT:  mov r24, r25
308; CHECK-NEXT:  rol r24
309; CHECK-NEXT:  sbc r25, r25
310; CHECK-NEXT:  ret
311  %result = ashr i16 %a, 7
312  ret i16 %result
313}
314
315define i16 @asr_i16_9(i16 %a) {
316; CHECK-LABEL: asr_i16_9
317; CHECK:       mov r24, r25
318; CHECK-NEXT:  lsl r25
319; CHECK-NEXT:  sbc r25, r25
320; CHECK-NEXT:  asr r24
321; CHECK-NEXT:  ret
322  %result = ashr i16 %a, 9
323  ret i16 %result
324}
325
326define i16 @asr_i16_12(i16 %a) {
327; CHECK-LABEL: asr_i16_12
328; CHECK:       mov r24, r25
329; CHECK-NEXT:  lsl r25
330; CHECK-NEXT:  sbc r25, r25
331; CHECK-NEXT:  asr r24
332; CHECK-NEXT:  asr r24
333; CHECK-NEXT:  asr r24
334; CHECK-NEXT:  asr r24
335; CHECK-NEXT:  ret
336  %result = ashr i16 %a, 12
337  ret i16 %result
338}
339
340define i16 @asr_i16_14(i16 %a) {
341; CHECK-LABEL: asr_i16_14
342; CHECK:      lsl r25
343; CHECK-NEXT: sbc r24, r24
344; CHECK-NEXT: lsl r25
345; CHECK-NEXT: mov r25, r24
346; CHECK-NEXT: rol r24
347; CHECK-NEXT: ret
348  %result = ashr i16 %a, 14
349  ret i16 %result
350}
351
352define i16 @asr_i16_15(i16 %a) {
353; CHECK-LABEL: asr_i16_15
354; CHECK:      lsl r25
355; CHECK-NEXT: sbc r25, r25
356; CHECK-NEXT: mov r24, r25
357; CHECK-NEXT: ret
358  %result = ashr i16 %a, 15
359  ret i16 %result
360}
361