xref: /llvm-project/llvm/test/CodeGen/M68k/Arith/imul.ll (revision ebbc5de7db45b2fc81564a6c870a57f4b95d0477)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=m68k-linux | FileCheck %s
3
4define i32 @mul4_32(i32 %A) {
5; CHECK-LABEL: mul4_32:
6; CHECK:         .cfi_startproc
7; CHECK-NEXT:  ; %bb.0:
8; CHECK-NEXT:    move.l (4,%sp), %d0
9; CHECK-NEXT:    lsl.l #2, %d0
10; CHECK-NEXT:    rts
11    %mul = mul i32 %A, 4
12    ret i32 %mul
13}
14
15define i64 @mul4_64(i64 %A) {
16; CHECK-LABEL: mul4_64:
17; CHECK:         .cfi_startproc
18; CHECK-NEXT:  ; %bb.0:
19; CHECK-NEXT:    suba.l #4, %sp
20; CHECK-NEXT:    .cfi_def_cfa_offset -8
21; CHECK-NEXT:    movem.l %d2, (0,%sp) ; 8-byte Folded Spill
22; CHECK-NEXT:    moveq #30, %d0
23; CHECK-NEXT:    move.l (12,%sp), %d1
24; CHECK-NEXT:    move.l %d1, %d2
25; CHECK-NEXT:    lsr.l %d0, %d2
26; CHECK-NEXT:    move.l (8,%sp), %d0
27; CHECK-NEXT:    lsl.l #2, %d0
28; CHECK-NEXT:    or.l %d2, %d0
29; CHECK-NEXT:    lsl.l #2, %d1
30; CHECK-NEXT:    movem.l (0,%sp), %d2 ; 8-byte Folded Reload
31; CHECK-NEXT:    adda.l #4, %sp
32; CHECK-NEXT:    rts
33    %mul = mul i64 %A, 4
34    ret i64 %mul
35}
36
37define i32 @mul4096_32(i32 %A) {
38; CHECK-LABEL: mul4096_32:
39; CHECK:         .cfi_startproc
40; CHECK-NEXT:  ; %bb.0:
41; CHECK-NEXT:    moveq #12, %d1
42; CHECK-NEXT:    move.l (4,%sp), %d0
43; CHECK-NEXT:    lsl.l %d1, %d0
44; CHECK-NEXT:    rts
45    %mul = mul i32 %A, 4096
46    ret i32 %mul
47}
48
49define i64 @mul4096_64(i64 %A) {
50; CHECK-LABEL: mul4096_64:
51; CHECK:         .cfi_startproc
52; CHECK-NEXT:  ; %bb.0:
53; CHECK-NEXT:    suba.l #8, %sp
54; CHECK-NEXT:    .cfi_def_cfa_offset -12
55; CHECK-NEXT:    movem.l %d2-%d3, (0,%sp) ; 12-byte Folded Spill
56; CHECK-NEXT:    moveq #20, %d0
57; CHECK-NEXT:    move.l (16,%sp), %d1
58; CHECK-NEXT:    move.l %d1, %d2
59; CHECK-NEXT:    lsr.l %d0, %d2
60; CHECK-NEXT:    moveq #12, %d3
61; CHECK-NEXT:    move.l (12,%sp), %d0
62; CHECK-NEXT:    lsl.l %d3, %d0
63; CHECK-NEXT:    or.l %d2, %d0
64; CHECK-NEXT:    lsl.l %d3, %d1
65; CHECK-NEXT:    movem.l (0,%sp), %d2-%d3 ; 12-byte Folded Reload
66; CHECK-NEXT:    adda.l #8, %sp
67; CHECK-NEXT:    rts
68    %mul = mul i64 %A, 4096
69    ret i64 %mul
70}
71
72define i32 @mulmin4096_32(i32 %A) {
73; CHECK-LABEL: mulmin4096_32:
74; CHECK:         .cfi_startproc
75; CHECK-NEXT:  ; %bb.0:
76; CHECK-NEXT:    moveq #12, %d1
77; CHECK-NEXT:    move.l (4,%sp), %d0
78; CHECK-NEXT:    lsl.l %d1, %d0
79; CHECK-NEXT:    neg.l %d0
80; CHECK-NEXT:    rts
81    %mul = mul i32 %A, -4096
82    ret i32 %mul
83}
84
85define i64 @mulmin4096_64(i64 %A) {
86; CHECK-LABEL: mulmin4096_64:
87; CHECK:         .cfi_startproc
88; CHECK-NEXT:  ; %bb.0:
89; CHECK-NEXT:    suba.l #8, %sp
90; CHECK-NEXT:    .cfi_def_cfa_offset -12
91; CHECK-NEXT:    movem.l %d2-%d3, (0,%sp) ; 12-byte Folded Spill
92; CHECK-NEXT:    moveq #20, %d0
93; CHECK-NEXT:    move.l (16,%sp), %d1
94; CHECK-NEXT:    move.l %d1, %d2
95; CHECK-NEXT:    lsr.l %d0, %d2
96; CHECK-NEXT:    moveq #12, %d3
97; CHECK-NEXT:    move.l (12,%sp), %d0
98; CHECK-NEXT:    lsl.l %d3, %d0
99; CHECK-NEXT:    or.l %d2, %d0
100; CHECK-NEXT:    lsl.l %d3, %d1
101; CHECK-NEXT:    neg.l %d1
102; CHECK-NEXT:    negx.l %d0
103; CHECK-NEXT:    movem.l (0,%sp), %d2-%d3 ; 12-byte Folded Reload
104; CHECK-NEXT:    adda.l #8, %sp
105; CHECK-NEXT:    rts
106    %mul = mul i64 %A, -4096
107    ret i64 %mul
108}
109
110; No i32 multiply for M68000
111define i32 @mul_32(i32 %a, i32 %b) {
112; CHECK-LABEL: mul_32:
113; CHECK:         .cfi_startproc
114; CHECK-NEXT:  ; %bb.0:
115; CHECK-NEXT:    suba.l #12, %sp
116; CHECK-NEXT:    .cfi_def_cfa_offset -16
117; CHECK-NEXT:    move.l (20,%sp), (4,%sp)
118; CHECK-NEXT:    move.l (16,%sp), (%sp)
119; CHECK-NEXT:    jsr __mulsi3
120; CHECK-NEXT:    adda.l #12, %sp
121; CHECK-NEXT:    rts
122    %mul = mul i32 %a, %b
123    ret i32 %mul
124}
125
126; Lower to shift and add if we can
127define i32 @mul3_32(i32 %A) {
128; CHECK-LABEL: mul3_32:
129; CHECK:         .cfi_startproc
130; CHECK-NEXT:  ; %bb.0:
131; CHECK-NEXT:    move.l (4,%sp), %d1
132; CHECK-NEXT:    move.l %d1, %d0
133; CHECK-NEXT:    lsl.l #1, %d0
134; CHECK-NEXT:    add.l %d1, %d0
135; CHECK-NEXT:    rts
136    %mul = mul i32 %A, 3
137    ret i32 %mul
138}
139
140define i32 @mul40_32(i32 %A) {
141; CHECK-LABEL: mul40_32:
142; CHECK:         .cfi_startproc
143; CHECK-NEXT:  ; %bb.0:
144; CHECK-NEXT:    move.l (4,%sp), %d0
145; CHECK-NEXT:    move.l %d0, %d1
146; CHECK-NEXT:    lsl.l #3, %d1
147; CHECK-NEXT:    lsl.l #5, %d0
148; CHECK-NEXT:    add.l %d1, %d0
149; CHECK-NEXT:    rts
150    %mul = mul i32 %A, 40
151    ret i32 %mul
152}
153
154; No i64 multiply for M68000
155define i64 @mul_64(i64 %a, i64 %b) {
156; CHECK-LABEL: mul_64:
157; CHECK:         .cfi_startproc
158; CHECK-NEXT:  ; %bb.0:
159; CHECK-NEXT:    suba.l #20, %sp
160; CHECK-NEXT:    .cfi_def_cfa_offset -24
161; CHECK-NEXT:    move.l (36,%sp), (12,%sp)
162; CHECK-NEXT:    move.l (32,%sp), (8,%sp)
163; CHECK-NEXT:    move.l (28,%sp), (4,%sp)
164; CHECK-NEXT:    move.l (24,%sp), (%sp)
165; CHECK-NEXT:    jsr __muldi3
166; CHECK-NEXT:    adda.l #20, %sp
167; CHECK-NEXT:    rts
168    %mul = mul i64 %a, %b
169    ret i64 %mul
170}
171
172define i64 @mul3_64(i64 %A) {
173; CHECK-LABEL: mul3_64:
174; CHECK:         .cfi_startproc
175; CHECK-NEXT:  ; %bb.0:
176; CHECK-NEXT:    suba.l #20, %sp
177; CHECK-NEXT:    .cfi_def_cfa_offset -24
178; CHECK-NEXT:    move.l #3, (12,%sp)
179; CHECK-NEXT:    move.l #0, (8,%sp)
180; CHECK-NEXT:    move.l (28,%sp), (4,%sp)
181; CHECK-NEXT:    move.l (24,%sp), (%sp)
182; CHECK-NEXT:    jsr __muldi3
183; CHECK-NEXT:    adda.l #20, %sp
184; CHECK-NEXT:    rts
185    %mul = mul i64 %A, 3
186    ret i64 %mul
187}
188
189define i64 @mul40_64(i64 %A) {
190; CHECK-LABEL: mul40_64:
191; CHECK:         .cfi_startproc
192; CHECK-NEXT:  ; %bb.0:
193; CHECK-NEXT:    suba.l #20, %sp
194; CHECK-NEXT:    .cfi_def_cfa_offset -24
195; CHECK-NEXT:    move.l #40, (12,%sp)
196; CHECK-NEXT:    move.l #0, (8,%sp)
197; CHECK-NEXT:    move.l (28,%sp), (4,%sp)
198; CHECK-NEXT:    move.l (24,%sp), (%sp)
199; CHECK-NEXT:    jsr __muldi3
200; CHECK-NEXT:    adda.l #20, %sp
201; CHECK-NEXT:    rts
202    %mul = mul i64 %A, 40
203    ret i64 %mul
204}
205
206define i32 @mul4_32_minsize(i32 %A) minsize {
207; CHECK-LABEL: mul4_32_minsize:
208; CHECK:         .cfi_startproc
209; CHECK-NEXT:  ; %bb.0:
210; CHECK-NEXT:    move.l (4,%sp), %d0
211; CHECK-NEXT:    lsl.l #2, %d0
212; CHECK-NEXT:    rts
213    %mul = mul i32 %A, 4
214    ret i32 %mul
215}
216
217define i32 @mul40_32_minsize(i32 %A) minsize {
218; CHECK-LABEL: mul40_32_minsize:
219; CHECK:         .cfi_startproc
220; CHECK-NEXT:  ; %bb.0:
221; CHECK-NEXT:    move.l (4,%sp), %d0
222; CHECK-NEXT:    move.l %d0, %d1
223; CHECK-NEXT:    lsl.l #3, %d1
224; CHECK-NEXT:    lsl.l #5, %d0
225; CHECK-NEXT:    add.l %d1, %d0
226; CHECK-NEXT:    rts
227    %mul = mul i32 %A, 40
228    ret i32 %mul
229}
230
231define i32 @mul33_32(i32 %A) {
232; CHECK-LABEL: mul33_32:
233; CHECK:         .cfi_startproc
234; CHECK-NEXT:  ; %bb.0:
235; CHECK-NEXT:    move.l (4,%sp), %d1
236; CHECK-NEXT:    move.l %d1, %d0
237; CHECK-NEXT:    lsl.l #5, %d0
238; CHECK-NEXT:    add.l %d1, %d0
239; CHECK-NEXT:    rts
240    %mul = mul i32 %A, 33
241    ret i32 %mul
242}
243
244define i32 @mul31_32(i32 %A) {
245; CHECK-LABEL: mul31_32:
246; CHECK:         .cfi_startproc
247; CHECK-NEXT:  ; %bb.0:
248; CHECK-NEXT:    move.l (4,%sp), %d1
249; CHECK-NEXT:    move.l %d1, %d0
250; CHECK-NEXT:    lsl.l #5, %d0
251; CHECK-NEXT:    sub.l %d1, %d0
252; CHECK-NEXT:    rts
253    %mul = mul i32 %A, 31
254    ret i32 %mul
255}
256
257define i32 @mul0_32(i32 %A) {
258; CHECK-LABEL: mul0_32:
259; CHECK:         .cfi_startproc
260; CHECK-NEXT:  ; %bb.0:
261; CHECK-NEXT:    moveq #0, %d0
262; CHECK-NEXT:    rts
263    %mul = mul i32 %A, 0
264    ret i32 %mul
265}
266