• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \
3; RUN:   | FileCheck %s -check-prefix=RV32I
4; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
5; RUN:   | FileCheck %s -check-prefix=RV64I
6
7; Basic shift support is tested as part of ALU.ll. This file ensures that
8; shifts which may not be supported natively are lowered properly.
9
10define i64 @lshr64(i64 %a, i64 %b) nounwind {
11; RV32I-LABEL: lshr64:
12; RV32I:       # %bb.0:
13; RV32I-NEXT:    addi a3, a2, -32
14; RV32I-NEXT:    bltz a3, .LBB0_2
15; RV32I-NEXT:  # %bb.1:
16; RV32I-NEXT:    srl a0, a1, a3
17; RV32I-NEXT:    mv a1, zero
18; RV32I-NEXT:    ret
19; RV32I-NEXT:  .LBB0_2:
20; RV32I-NEXT:    srl a0, a0, a2
21; RV32I-NEXT:    addi a3, zero, 31
22; RV32I-NEXT:    sub a3, a3, a2
23; RV32I-NEXT:    slli a4, a1, 1
24; RV32I-NEXT:    sll a3, a4, a3
25; RV32I-NEXT:    or a0, a0, a3
26; RV32I-NEXT:    srl a1, a1, a2
27; RV32I-NEXT:    ret
28;
29; RV64I-LABEL: lshr64:
30; RV64I:       # %bb.0:
31; RV64I-NEXT:    srl a0, a0, a1
32; RV64I-NEXT:    ret
33  %1 = lshr i64 %a, %b
34  ret i64 %1
35}
36
37define i64 @lshr64_minsize(i64 %a, i64 %b) minsize nounwind {
38; RV32I-LABEL: lshr64_minsize:
39; RV32I:       # %bb.0:
40; RV32I-NEXT:    addi sp, sp, -16
41; RV32I-NEXT:    sw ra, 12(sp)
42; RV32I-NEXT:    call __lshrdi3
43; RV32I-NEXT:    lw ra, 12(sp)
44; RV32I-NEXT:    addi sp, sp, 16
45; RV32I-NEXT:    ret
46;
47; RV64I-LABEL: lshr64_minsize:
48; RV64I:       # %bb.0:
49; RV64I-NEXT:    srl a0, a0, a1
50; RV64I-NEXT:    ret
51  %1 = lshr i64 %a, %b
52  ret i64 %1
53}
54
55define i64 @ashr64(i64 %a, i64 %b) nounwind {
56; RV32I-LABEL: ashr64:
57; RV32I:       # %bb.0:
58; RV32I-NEXT:    addi a3, a2, -32
59; RV32I-NEXT:    bltz a3, .LBB2_2
60; RV32I-NEXT:  # %bb.1:
61; RV32I-NEXT:    sra a0, a1, a3
62; RV32I-NEXT:    srai a1, a1, 31
63; RV32I-NEXT:    ret
64; RV32I-NEXT:  .LBB2_2:
65; RV32I-NEXT:    srl a0, a0, a2
66; RV32I-NEXT:    addi a3, zero, 31
67; RV32I-NEXT:    sub a3, a3, a2
68; RV32I-NEXT:    slli a4, a1, 1
69; RV32I-NEXT:    sll a3, a4, a3
70; RV32I-NEXT:    or a0, a0, a3
71; RV32I-NEXT:    sra a1, a1, a2
72; RV32I-NEXT:    ret
73;
74; RV64I-LABEL: ashr64:
75; RV64I:       # %bb.0:
76; RV64I-NEXT:    sra a0, a0, a1
77; RV64I-NEXT:    ret
78  %1 = ashr i64 %a, %b
79  ret i64 %1
80}
81
82define i64 @ashr64_minsize(i64 %a, i64 %b) minsize nounwind {
83; RV32I-LABEL: ashr64_minsize:
84; RV32I:       # %bb.0:
85; RV32I-NEXT:    addi sp, sp, -16
86; RV32I-NEXT:    sw ra, 12(sp)
87; RV32I-NEXT:    call __ashrdi3
88; RV32I-NEXT:    lw ra, 12(sp)
89; RV32I-NEXT:    addi sp, sp, 16
90; RV32I-NEXT:    ret
91;
92; RV64I-LABEL: ashr64_minsize:
93; RV64I:       # %bb.0:
94; RV64I-NEXT:    sra a0, a0, a1
95; RV64I-NEXT:    ret
96  %1 = ashr i64 %a, %b
97  ret i64 %1
98}
99
100define i64 @shl64(i64 %a, i64 %b) nounwind {
101; RV32I-LABEL: shl64:
102; RV32I:       # %bb.0:
103; RV32I-NEXT:    addi a3, a2, -32
104; RV32I-NEXT:    bltz a3, .LBB4_2
105; RV32I-NEXT:  # %bb.1:
106; RV32I-NEXT:    sll a1, a0, a3
107; RV32I-NEXT:    mv a0, zero
108; RV32I-NEXT:    ret
109; RV32I-NEXT:  .LBB4_2:
110; RV32I-NEXT:    sll a1, a1, a2
111; RV32I-NEXT:    addi a3, zero, 31
112; RV32I-NEXT:    sub a3, a3, a2
113; RV32I-NEXT:    srli a4, a0, 1
114; RV32I-NEXT:    srl a3, a4, a3
115; RV32I-NEXT:    or a1, a1, a3
116; RV32I-NEXT:    sll a0, a0, a2
117; RV32I-NEXT:    ret
118;
119; RV64I-LABEL: shl64:
120; RV64I:       # %bb.0:
121; RV64I-NEXT:    sll a0, a0, a1
122; RV64I-NEXT:    ret
123  %1 = shl i64 %a, %b
124  ret i64 %1
125}
126
127define i64 @shl64_minsize(i64 %a, i64 %b) minsize nounwind {
128; RV32I-LABEL: shl64_minsize:
129; RV32I:       # %bb.0:
130; RV32I-NEXT:    addi sp, sp, -16
131; RV32I-NEXT:    sw ra, 12(sp)
132; RV32I-NEXT:    call __ashldi3
133; RV32I-NEXT:    lw ra, 12(sp)
134; RV32I-NEXT:    addi sp, sp, 16
135; RV32I-NEXT:    ret
136;
137; RV64I-LABEL: shl64_minsize:
138; RV64I:       # %bb.0:
139; RV64I-NEXT:    sll a0, a0, a1
140; RV64I-NEXT:    ret
141  %1 = shl i64 %a, %b
142  ret i64 %1
143}
144
145define i128 @lshr128(i128 %a, i128 %b) nounwind {
146; RV32I-LABEL: lshr128:
147; RV32I:       # %bb.0:
148; RV32I-NEXT:    addi sp, sp, -48
149; RV32I-NEXT:    sw ra, 44(sp)
150; RV32I-NEXT:    sw s0, 40(sp)
151; RV32I-NEXT:    lw a2, 0(a2)
152; RV32I-NEXT:    lw a3, 0(a1)
153; RV32I-NEXT:    lw a4, 4(a1)
154; RV32I-NEXT:    lw a5, 8(a1)
155; RV32I-NEXT:    lw a1, 12(a1)
156; RV32I-NEXT:    mv s0, a0
157; RV32I-NEXT:    sw a1, 20(sp)
158; RV32I-NEXT:    sw a5, 16(sp)
159; RV32I-NEXT:    sw a4, 12(sp)
160; RV32I-NEXT:    addi a0, sp, 24
161; RV32I-NEXT:    addi a1, sp, 8
162; RV32I-NEXT:    sw a3, 8(sp)
163; RV32I-NEXT:    call __lshrti3
164; RV32I-NEXT:    lw a0, 36(sp)
165; RV32I-NEXT:    lw a1, 32(sp)
166; RV32I-NEXT:    lw a2, 28(sp)
167; RV32I-NEXT:    lw a3, 24(sp)
168; RV32I-NEXT:    sw a0, 12(s0)
169; RV32I-NEXT:    sw a1, 8(s0)
170; RV32I-NEXT:    sw a2, 4(s0)
171; RV32I-NEXT:    sw a3, 0(s0)
172; RV32I-NEXT:    lw s0, 40(sp)
173; RV32I-NEXT:    lw ra, 44(sp)
174; RV32I-NEXT:    addi sp, sp, 48
175; RV32I-NEXT:    ret
176;
177; RV64I-LABEL: lshr128:
178; RV64I:       # %bb.0:
179; RV64I-NEXT:    addi a3, a2, -64
180; RV64I-NEXT:    bltz a3, .LBB6_2
181; RV64I-NEXT:  # %bb.1:
182; RV64I-NEXT:    srl a0, a1, a3
183; RV64I-NEXT:    mv a1, zero
184; RV64I-NEXT:    ret
185; RV64I-NEXT:  .LBB6_2:
186; RV64I-NEXT:    srl a0, a0, a2
187; RV64I-NEXT:    addi a3, zero, 63
188; RV64I-NEXT:    sub a3, a3, a2
189; RV64I-NEXT:    slli a4, a1, 1
190; RV64I-NEXT:    sll a3, a4, a3
191; RV64I-NEXT:    or a0, a0, a3
192; RV64I-NEXT:    srl a1, a1, a2
193; RV64I-NEXT:    ret
194  %1 = lshr i128 %a, %b
195  ret i128 %1
196}
197
198define i128 @ashr128(i128 %a, i128 %b) nounwind {
199; RV32I-LABEL: ashr128:
200; RV32I:       # %bb.0:
201; RV32I-NEXT:    addi sp, sp, -48
202; RV32I-NEXT:    sw ra, 44(sp)
203; RV32I-NEXT:    sw s0, 40(sp)
204; RV32I-NEXT:    lw a2, 0(a2)
205; RV32I-NEXT:    lw a3, 0(a1)
206; RV32I-NEXT:    lw a4, 4(a1)
207; RV32I-NEXT:    lw a5, 8(a1)
208; RV32I-NEXT:    lw a1, 12(a1)
209; RV32I-NEXT:    mv s0, a0
210; RV32I-NEXT:    sw a1, 20(sp)
211; RV32I-NEXT:    sw a5, 16(sp)
212; RV32I-NEXT:    sw a4, 12(sp)
213; RV32I-NEXT:    addi a0, sp, 24
214; RV32I-NEXT:    addi a1, sp, 8
215; RV32I-NEXT:    sw a3, 8(sp)
216; RV32I-NEXT:    call __ashrti3
217; RV32I-NEXT:    lw a0, 36(sp)
218; RV32I-NEXT:    lw a1, 32(sp)
219; RV32I-NEXT:    lw a2, 28(sp)
220; RV32I-NEXT:    lw a3, 24(sp)
221; RV32I-NEXT:    sw a0, 12(s0)
222; RV32I-NEXT:    sw a1, 8(s0)
223; RV32I-NEXT:    sw a2, 4(s0)
224; RV32I-NEXT:    sw a3, 0(s0)
225; RV32I-NEXT:    lw s0, 40(sp)
226; RV32I-NEXT:    lw ra, 44(sp)
227; RV32I-NEXT:    addi sp, sp, 48
228; RV32I-NEXT:    ret
229;
230; RV64I-LABEL: ashr128:
231; RV64I:       # %bb.0:
232; RV64I-NEXT:    addi a3, a2, -64
233; RV64I-NEXT:    bltz a3, .LBB7_2
234; RV64I-NEXT:  # %bb.1:
235; RV64I-NEXT:    sra a0, a1, a3
236; RV64I-NEXT:    srai a1, a1, 63
237; RV64I-NEXT:    ret
238; RV64I-NEXT:  .LBB7_2:
239; RV64I-NEXT:    srl a0, a0, a2
240; RV64I-NEXT:    addi a3, zero, 63
241; RV64I-NEXT:    sub a3, a3, a2
242; RV64I-NEXT:    slli a4, a1, 1
243; RV64I-NEXT:    sll a3, a4, a3
244; RV64I-NEXT:    or a0, a0, a3
245; RV64I-NEXT:    sra a1, a1, a2
246; RV64I-NEXT:    ret
247  %1 = ashr i128 %a, %b
248  ret i128 %1
249}
250
251define i128 @shl128(i128 %a, i128 %b) nounwind {
252; RV32I-LABEL: shl128:
253; RV32I:       # %bb.0:
254; RV32I-NEXT:    addi sp, sp, -48
255; RV32I-NEXT:    sw ra, 44(sp)
256; RV32I-NEXT:    sw s0, 40(sp)
257; RV32I-NEXT:    lw a2, 0(a2)
258; RV32I-NEXT:    lw a3, 0(a1)
259; RV32I-NEXT:    lw a4, 4(a1)
260; RV32I-NEXT:    lw a5, 8(a1)
261; RV32I-NEXT:    lw a1, 12(a1)
262; RV32I-NEXT:    mv s0, a0
263; RV32I-NEXT:    sw a1, 20(sp)
264; RV32I-NEXT:    sw a5, 16(sp)
265; RV32I-NEXT:    sw a4, 12(sp)
266; RV32I-NEXT:    addi a0, sp, 24
267; RV32I-NEXT:    addi a1, sp, 8
268; RV32I-NEXT:    sw a3, 8(sp)
269; RV32I-NEXT:    call __ashlti3
270; RV32I-NEXT:    lw a0, 36(sp)
271; RV32I-NEXT:    lw a1, 32(sp)
272; RV32I-NEXT:    lw a2, 28(sp)
273; RV32I-NEXT:    lw a3, 24(sp)
274; RV32I-NEXT:    sw a0, 12(s0)
275; RV32I-NEXT:    sw a1, 8(s0)
276; RV32I-NEXT:    sw a2, 4(s0)
277; RV32I-NEXT:    sw a3, 0(s0)
278; RV32I-NEXT:    lw s0, 40(sp)
279; RV32I-NEXT:    lw ra, 44(sp)
280; RV32I-NEXT:    addi sp, sp, 48
281; RV32I-NEXT:    ret
282;
283; RV64I-LABEL: shl128:
284; RV64I:       # %bb.0:
285; RV64I-NEXT:    addi a3, a2, -64
286; RV64I-NEXT:    bltz a3, .LBB8_2
287; RV64I-NEXT:  # %bb.1:
288; RV64I-NEXT:    sll a1, a0, a3
289; RV64I-NEXT:    mv a0, zero
290; RV64I-NEXT:    ret
291; RV64I-NEXT:  .LBB8_2:
292; RV64I-NEXT:    sll a1, a1, a2
293; RV64I-NEXT:    addi a3, zero, 63
294; RV64I-NEXT:    sub a3, a3, a2
295; RV64I-NEXT:    srli a4, a0, 1
296; RV64I-NEXT:    srl a3, a4, a3
297; RV64I-NEXT:    or a1, a1, a3
298; RV64I-NEXT:    sll a0, a0, a2
299; RV64I-NEXT:    ret
300  %1 = shl i128 %a, %b
301  ret i128 %1
302}
303