1; RUN: llc < %s -march=avr | 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_7(i8 %a) {
175; CHECK-LABEL: asr_i8_7
176; CHECK:      lsl r24
177; CHECK-NEXT: sbc r24, r24
178  %result = ashr i8 %a, 7
179  ret i8 %result
180}
181
182define i16 @lsl_i16_5(i16 %a) {
183; CHECK-LABEL: lsl_i16_5
184; CHECK:       swap r25
185; CHECK-NEXT:  swap r24
186; CHECK-NEXT:  andi r25, 240
187; CHECK-NEXT:  eor r25, r24
188; CHECK-NEXT:  andi r24, 240
189; CHECK-NEXT:  eor r25, r24
190; CHECK-NEXT:  lsl r24
191; CHECK-NEXT:  rol r25
192; CHECK-NEXT:  ret
193  %result = shl i16 %a, 5
194  ret i16 %result
195}
196
197define i16 @lsl_i16_6(i16 %a, i16 %b, i16 %c, i16 %d, i16 %e, i16 %f) {
198; CHECK-LABEL: lsl_i16_6
199; CHECK:       mov r24, r14
200; CHECK-NEXT:  mov r25, r15
201; CHECK-NEXT:  swap r25
202; CHECK-NEXT:  swap r24
203; CHECK-NEXT:  andi r25, 240
204; CHECK-NEXT:  eor r25, r24
205; CHECK-NEXT:  andi r24, 240
206; CHECK-NEXT:  eor r25, r24
207; CHECK-NEXT:  lsl r24
208; CHECK-NEXT:  rol r25
209; CHECK-NEXT:  lsl r24
210; CHECK-NEXT:  rol r25
211; CHECK-NEXT:  ret
212  %result = shl i16 %f, 6
213  ret i16 %result
214}
215
216define i16 @lsl_i16_9(i16 %a) {
217; CHECK-LABEL: lsl_i16_9
218; CHECK:       mov r25, r24
219; CHECK-NEXT:  clr r24
220; CHECK-NEXT:  lsl r24
221; CHECK-NEXT:  rol r25
222; CHECK-NEXT:  ret
223  %result = shl i16 %a, 9
224  ret i16 %result
225}
226
227define i16 @lsl_i16_13(i16 %a) {
228; CHECK-LABEL: lsl_i16_13
229; CHECK:       mov r25, r24
230; CHECK-NEXT:  swap r25
231; CHECK-NEXT:  andi r25, 240
232; CHECK-NEXT:  clr r24
233; CHECK-NEXT:  lsl r24
234; CHECK-NEXT:  rol r25
235; CHECK-NEXT:  ret
236  %result = shl i16 %a, 13
237  ret i16 %result
238}
239
240define i16 @lsr_i16_5(i16 %a) {
241; CHECK-LABEL: lsr_i16_5
242; CHECK:       swap r25
243; CHECK-NEXT:  swap r24
244; CHECK-NEXT:  andi r24, 15
245; CHECK-NEXT:  eor r24, r25
246; CHECK-NEXT:  andi r25, 15
247; CHECK-NEXT:  eor r24, r25
248; CHECK-NEXT:  lsr r25
249; CHECK-NEXT:  ror r24
250; CHECK-NEXT:  ret
251  %result = lshr i16 %a, 5
252  ret i16 %result
253}
254
255define i16 @lsr_i16_6(i16 %a, i16 %b, i16 %c, i16 %d, i16 %e, i16 %f) {
256; CHECK-LABEL: lsr_i16_6
257; CHECK:       mov r24, r14
258; CHECK-NEXT:  mov r25, r15
259; CHECK-NEXT:  swap r25
260; CHECK-NEXT:  swap r24
261; CHECK-NEXT:  andi r24, 15
262; CHECK-NEXT:  eor r24, r25
263; CHECK-NEXT:  andi r25, 15
264; CHECK-NEXT:  eor r24, r25
265; CHECK-NEXT:  lsr r25
266; CHECK-NEXT:  ror r24
267; CHECK-NEXT:  lsr r25
268; CHECK-NEXT:  ror r24
269; CHECK-NEXT: ret
270  %result = lshr i16 %f, 6
271  ret i16 %result
272}
273
274define i16 @lsr_i16_9(i16 %a) {
275; CHECK-LABEL: lsr_i16_9
276; CHECK:       mov r24, r25
277; CHECK-NEXT:  clr r25
278; CHECK-NEXT:  lsr r25
279; CHECK-NEXT:  ror r24
280; CHECK-NEXT:  ret
281  %result = lshr i16 %a, 9
282  ret i16 %result
283}
284
285define i16 @lsr_i16_13(i16 %a) {
286; CHECK-LABEL: lsr_i16_13
287; CHECK:       mov r24, r25
288; CHECK-NEXT:  swap r24
289; CHECK-NEXT:  andi r24, 15
290; CHECK-NEXT:  clr r25
291; CHECK-NEXT:  lsr r25
292; CHECK-NEXT:  ror r24
293; CHECK-NEXT:  ret
294  %result = lshr i16 %a, 13
295  ret i16 %result
296}
297
298define i16 @asr_i16_9(i16 %a) {
299; CHECK-LABEL: asr_i16_9
300; CHECK:       mov r24, r25
301; CHECK-NEXT:  lsl r25
302; CHECK-NEXT:  sbc r25, r25
303; CHECK-NEXT:  asr r25
304; CHECK-NEXT:  ror r24
305; CHECK-NEXT:  ret
306  %result = ashr i16 %a, 9
307  ret i16 %result
308}
309