xref: /llvm-project/llvm/test/CodeGen/Thumb/smul_fix.ll (revision e30a4fc3e20bf5d9cc2f5bfcb61b4eb0e686a193)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=thumbv6m-none-unknown-eabi -mcpu=cortex-m0 | FileCheck %s --check-prefix=ARM
3
4declare  i4  @llvm.smul.fix.i4   (i4,  i4, i32)
5declare  i32 @llvm.smul.fix.i32  (i32, i32, i32)
6declare  i64 @llvm.smul.fix.i64  (i64, i64, i32)
7
8define i32 @func(i32 %x, i32 %y) nounwind {
9; ARM-LABEL: func:
10; ARM:       @ %bb.0:
11; ARM-NEXT:    .save {r7, lr}
12; ARM-NEXT:    push {r7, lr}
13; ARM-NEXT:    mov r2, r1
14; ARM-NEXT:    asrs r1, r0, #31
15; ARM-NEXT:    asrs r3, r2, #31
16; ARM-NEXT:    bl __aeabi_lmul
17; ARM-NEXT:    lsrs r0, r0, #2
18; ARM-NEXT:    lsls r1, r1, #30
19; ARM-NEXT:    adds r0, r1, r0
20; ARM-NEXT:    pop {r7, pc}
21  %tmp = call i32 @llvm.smul.fix.i32(i32 %x, i32 %y, i32 2)
22  ret i32 %tmp
23}
24
25define i64 @func2(i64 %x, i64 %y) {
26; ARM-LABEL: func2:
27; ARM:       @ %bb.0:
28; ARM-NEXT:    .save {r4, r5, r6, r7, lr}
29; ARM-NEXT:    push {r4, r5, r6, r7, lr}
30; ARM-NEXT:    .pad #20
31; ARM-NEXT:    sub sp, #20
32; ARM-NEXT:    str r3, [sp, #16] @ 4-byte Spill
33; ARM-NEXT:    mov r7, r2
34; ARM-NEXT:    mov r2, r1
35; ARM-NEXT:    str r1, [sp, #12] @ 4-byte Spill
36; ARM-NEXT:    mov r5, r0
37; ARM-NEXT:    asrs r1, r1, #31
38; ARM-NEXT:    str r1, [sp, #8] @ 4-byte Spill
39; ARM-NEXT:    movs r4, #0
40; ARM-NEXT:    mov r0, r2
41; ARM-NEXT:    mov r2, r7
42; ARM-NEXT:    mov r3, r4
43; ARM-NEXT:    bl __aeabi_lmul
44; ARM-NEXT:    str r0, [sp] @ 4-byte Spill
45; ARM-NEXT:    mov r6, r1
46; ARM-NEXT:    mov r0, r5
47; ARM-NEXT:    mov r1, r4
48; ARM-NEXT:    mov r2, r7
49; ARM-NEXT:    mov r3, r4
50; ARM-NEXT:    bl __aeabi_lmul
51; ARM-NEXT:    str r0, [sp, #4] @ 4-byte Spill
52; ARM-NEXT:    ldr r0, [sp] @ 4-byte Reload
53; ARM-NEXT:    adds r0, r0, r1
54; ARM-NEXT:    str r0, [sp] @ 4-byte Spill
55; ARM-NEXT:    adcs r6, r4
56; ARM-NEXT:    ldr r2, [sp, #16] @ 4-byte Reload
57; ARM-NEXT:    asrs r7, r2, #31
58; ARM-NEXT:    mov r0, r5
59; ARM-NEXT:    mov r1, r4
60; ARM-NEXT:    mov r3, r7
61; ARM-NEXT:    bl __aeabi_lmul
62; ARM-NEXT:    mov r4, r1
63; ARM-NEXT:    ldr r1, [sp] @ 4-byte Reload
64; ARM-NEXT:    adds r5, r0, r1
65; ARM-NEXT:    adcs r4, r6
66; ARM-NEXT:    ldr r0, [sp, #12] @ 4-byte Reload
67; ARM-NEXT:    ldr r1, [sp, #8] @ 4-byte Reload
68; ARM-NEXT:    ldr r2, [sp, #16] @ 4-byte Reload
69; ARM-NEXT:    mov r3, r7
70; ARM-NEXT:    bl __aeabi_lmul
71; ARM-NEXT:    adds r0, r0, r4
72; ARM-NEXT:    lsls r0, r0, #30
73; ARM-NEXT:    lsrs r1, r5, #2
74; ARM-NEXT:    adds r1, r0, r1
75; ARM-NEXT:    lsls r0, r5, #30
76; ARM-NEXT:    ldr r2, [sp, #4] @ 4-byte Reload
77; ARM-NEXT:    lsrs r2, r2, #2
78; ARM-NEXT:    adds r0, r0, r2
79; ARM-NEXT:    add sp, #20
80; ARM-NEXT:    pop {r4, r5, r6, r7, pc}
81  %tmp = call i64 @llvm.smul.fix.i64(i64 %x, i64 %y, i32 2)
82  ret i64 %tmp
83}
84
85define i4 @func3(i4 %x, i4 %y) nounwind {
86; ARM-LABEL: func3:
87; ARM:       @ %bb.0:
88; ARM-NEXT:    .save {r4, lr}
89; ARM-NEXT:    push {r4, lr}
90; ARM-NEXT:    lsls r2, r0, #28
91; ARM-NEXT:    asrs r0, r2, #28
92; ARM-NEXT:    asrs r4, r2, #31
93; ARM-NEXT:    lsls r1, r1, #28
94; ARM-NEXT:    asrs r2, r1, #28
95; ARM-NEXT:    asrs r3, r1, #31
96; ARM-NEXT:    mov r1, r4
97; ARM-NEXT:    bl __aeabi_lmul
98; ARM-NEXT:    lsrs r0, r0, #2
99; ARM-NEXT:    lsls r1, r1, #30
100; ARM-NEXT:    adds r0, r1, r0
101; ARM-NEXT:    pop {r4, pc}
102  %tmp = call i4 @llvm.smul.fix.i4(i4 %x, i4 %y, i32 2)
103  ret i4 %tmp
104}
105
106;; These result in regular integer multiplication
107define i32 @func4(i32 %x, i32 %y) nounwind {
108; ARM-LABEL: func4:
109; ARM:       @ %bb.0:
110; ARM-NEXT:    muls r0, r1, r0
111; ARM-NEXT:    bx lr
112  %tmp = call i32 @llvm.smul.fix.i32(i32 %x, i32 %y, i32 0)
113  ret i32 %tmp
114}
115
116define i64 @func5(i64 %x, i64 %y) {
117; ARM-LABEL: func5:
118; ARM:       @ %bb.0:
119; ARM-NEXT:    .save {r7, lr}
120; ARM-NEXT:    push {r7, lr}
121; ARM-NEXT:    bl __aeabi_lmul
122; ARM-NEXT:    pop {r7, pc}
123  %tmp = call i64 @llvm.smul.fix.i64(i64 %x, i64 %y, i32 0)
124  ret i64 %tmp
125}
126
127define i4 @func6(i4 %x, i4 %y) nounwind {
128; ARM-LABEL: func6:
129; ARM:       @ %bb.0:
130; ARM-NEXT:    lsls r1, r1, #28
131; ARM-NEXT:    asrs r1, r1, #28
132; ARM-NEXT:    lsls r0, r0, #28
133; ARM-NEXT:    asrs r0, r0, #28
134; ARM-NEXT:    muls r0, r1, r0
135; ARM-NEXT:    bx lr
136  %tmp = call i4 @llvm.smul.fix.i4(i4 %x, i4 %y, i32 0)
137  ret i4 %tmp
138}
139
140define i64 @func7(i64 %x, i64 %y) nounwind {
141; ARM-LABEL: func7:
142; ARM:       @ %bb.0:
143; ARM-NEXT:    .save {r4, r5, r6, r7, lr}
144; ARM-NEXT:    push {r4, r5, r6, r7, lr}
145; ARM-NEXT:    .pad #20
146; ARM-NEXT:    sub sp, #20
147; ARM-NEXT:    str r3, [sp, #16] @ 4-byte Spill
148; ARM-NEXT:    mov r7, r2
149; ARM-NEXT:    mov r2, r1
150; ARM-NEXT:    str r1, [sp, #8] @ 4-byte Spill
151; ARM-NEXT:    mov r5, r0
152; ARM-NEXT:    asrs r1, r1, #31
153; ARM-NEXT:    str r1, [sp, #12] @ 4-byte Spill
154; ARM-NEXT:    movs r4, #0
155; ARM-NEXT:    mov r0, r2
156; ARM-NEXT:    mov r2, r7
157; ARM-NEXT:    mov r3, r4
158; ARM-NEXT:    bl __aeabi_lmul
159; ARM-NEXT:    str r0, [sp, #4] @ 4-byte Spill
160; ARM-NEXT:    mov r6, r1
161; ARM-NEXT:    mov r0, r5
162; ARM-NEXT:    mov r1, r4
163; ARM-NEXT:    mov r2, r7
164; ARM-NEXT:    mov r3, r4
165; ARM-NEXT:    bl __aeabi_lmul
166; ARM-NEXT:    ldr r0, [sp, #4] @ 4-byte Reload
167; ARM-NEXT:    adds r0, r0, r1
168; ARM-NEXT:    str r0, [sp, #4] @ 4-byte Spill
169; ARM-NEXT:    adcs r6, r4
170; ARM-NEXT:    ldr r2, [sp, #16] @ 4-byte Reload
171; ARM-NEXT:    asrs r7, r2, #31
172; ARM-NEXT:    mov r0, r5
173; ARM-NEXT:    mov r1, r4
174; ARM-NEXT:    mov r3, r7
175; ARM-NEXT:    bl __aeabi_lmul
176; ARM-NEXT:    mov r4, r1
177; ARM-NEXT:    ldr r1, [sp, #4] @ 4-byte Reload
178; ARM-NEXT:    adds r5, r0, r1
179; ARM-NEXT:    adcs r4, r6
180; ARM-NEXT:    add r2, sp, #8
181; ARM-NEXT:    ldm r2, {r0, r1, r2} @ 12-byte Folded Reload
182; ARM-NEXT:    mov r3, r7
183; ARM-NEXT:    bl __aeabi_lmul
184; ARM-NEXT:    adds r1, r0, r4
185; ARM-NEXT:    mov r0, r5
186; ARM-NEXT:    add sp, #20
187; ARM-NEXT:    pop {r4, r5, r6, r7, pc}
188  %tmp = call i64 @llvm.smul.fix.i64(i64 %x, i64 %y, i32 32)
189  ret i64 %tmp
190}
191
192define i64 @func8(i64 %x, i64 %y) nounwind {
193; ARM-LABEL: func8:
194; ARM:       @ %bb.0:
195; ARM-NEXT:    .save {r4, r5, r6, r7, lr}
196; ARM-NEXT:    push {r4, r5, r6, r7, lr}
197; ARM-NEXT:    .pad #20
198; ARM-NEXT:    sub sp, #20
199; ARM-NEXT:    str r3, [sp, #16] @ 4-byte Spill
200; ARM-NEXT:    mov r4, r2
201; ARM-NEXT:    mov r2, r1
202; ARM-NEXT:    str r1, [sp, #8] @ 4-byte Spill
203; ARM-NEXT:    mov r5, r0
204; ARM-NEXT:    asrs r1, r1, #31
205; ARM-NEXT:    str r1, [sp, #12] @ 4-byte Spill
206; ARM-NEXT:    movs r7, #0
207; ARM-NEXT:    mov r0, r2
208; ARM-NEXT:    mov r2, r4
209; ARM-NEXT:    mov r3, r7
210; ARM-NEXT:    bl __aeabi_lmul
211; ARM-NEXT:    str r0, [sp, #4] @ 4-byte Spill
212; ARM-NEXT:    mov r6, r1
213; ARM-NEXT:    mov r0, r5
214; ARM-NEXT:    mov r1, r7
215; ARM-NEXT:    mov r2, r4
216; ARM-NEXT:    mov r3, r7
217; ARM-NEXT:    bl __aeabi_lmul
218; ARM-NEXT:    ldr r0, [sp, #4] @ 4-byte Reload
219; ARM-NEXT:    adds r0, r0, r1
220; ARM-NEXT:    str r0, [sp] @ 4-byte Spill
221; ARM-NEXT:    adcs r6, r7
222; ARM-NEXT:    asrs r0, r6, #31
223; ARM-NEXT:    str r0, [sp, #4] @ 4-byte Spill
224; ARM-NEXT:    ldr r2, [sp, #16] @ 4-byte Reload
225; ARM-NEXT:    asrs r4, r2, #31
226; ARM-NEXT:    mov r0, r5
227; ARM-NEXT:    mov r1, r7
228; ARM-NEXT:    mov r3, r4
229; ARM-NEXT:    bl __aeabi_lmul
230; ARM-NEXT:    ldr r2, [sp] @ 4-byte Reload
231; ARM-NEXT:    adds r5, r0, r2
232; ARM-NEXT:    adcs r1, r7
233; ARM-NEXT:    asrs r7, r1, #31
234; ARM-NEXT:    adds r6, r6, r1
235; ARM-NEXT:    ldr r0, [sp, #4] @ 4-byte Reload
236; ARM-NEXT:    adcs r7, r0
237; ARM-NEXT:    add r2, sp, #8
238; ARM-NEXT:    ldm r2, {r0, r1, r2} @ 12-byte Folded Reload
239; ARM-NEXT:    mov r3, r4
240; ARM-NEXT:    bl __aeabi_lmul
241; ARM-NEXT:    adds r0, r0, r6
242; ARM-NEXT:    adcs r1, r7
243; ARM-NEXT:    lsls r1, r1, #1
244; ARM-NEXT:    lsrs r2, r0, #31
245; ARM-NEXT:    adds r1, r1, r2
246; ARM-NEXT:    lsls r0, r0, #1
247; ARM-NEXT:    lsrs r2, r5, #31
248; ARM-NEXT:    adds r0, r0, r2
249; ARM-NEXT:    add sp, #20
250; ARM-NEXT:    pop {r4, r5, r6, r7, pc}
251  %tmp = call i64 @llvm.smul.fix.i64(i64 %x, i64 %y, i32 63)
252  ret i64 %tmp
253}
254