1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -march=mips -mcpu=mips32 < %s | FileCheck %s -check-prefixes=32
3; RUN: llc -march=mips -mcpu=mips32r2 < %s | FileCheck %s -check-prefixes=32
4; RUN: llc -march=mips -mcpu=mips32r6 < %s | FileCheck %s -check-prefixes=32R6
5; RUN: llc -march=mips -mcpu=mips32r2 -mattr=dsp < %s | FileCheck %s -check-prefix=DSP
6; RUN: llc -march=mips -mcpu=mips64   -target-abi n64 < %s | FileCheck %s -check-prefixes=64
7; RUN: llc -march=mips -mcpu=mips64r2 -target-abi n64 < %s | FileCheck %s -check-prefixes=64
8; RUN: llc -march=mips -mcpu=mips64r6 -target-abi n64 < %s | FileCheck %s -check-prefixes=64R6
9; RUN: llc -march=mips -mattr=mips16 < %s | FileCheck %s -check-prefixes=16
10
11define i64 @madd1(i32 %a, i32 %b, i32 %c) nounwind readnone {
12; 32-LABEL: madd1:
13; 32:       # %bb.0: # %entry
14; 32-NEXT:    sra $1, $6, 31
15; 32-NEXT:    mtlo $6
16; 32-NEXT:    mthi $1
17; 32-NEXT:    madd $5, $4
18; 32-NEXT:    mfhi $2
19; 32-NEXT:    jr $ra
20; 32-NEXT:    mflo $3
21;
22; 32R6-LABEL: madd1:
23; 32R6:       # %bb.0: # %entry
24; 32R6-NEXT:    mul $1, $5, $4
25; 32R6-NEXT:    addu $3, $1, $6
26; 32R6-NEXT:    sltu $1, $3, $1
27; 32R6-NEXT:    muh $2, $5, $4
28; 32R6-NEXT:    sra $4, $6, 31
29; 32R6-NEXT:    addu $2, $2, $4
30; 32R6-NEXT:    jr $ra
31; 32R6-NEXT:    addu $2, $2, $1
32;
33; DSP-LABEL: madd1:
34; DSP:       # %bb.0: # %entry
35; DSP-NEXT:    sra $1, $6, 31
36; DSP-NEXT:    mtlo $6, $ac0
37; DSP-NEXT:    mthi $1, $ac0
38; DSP-NEXT:    madd $ac0, $5, $4
39; DSP-NEXT:    mfhi $2, $ac0
40; DSP-NEXT:    jr $ra
41; DSP-NEXT:    mflo $3, $ac0
42;
43; 64-LABEL: madd1:
44; 64:       # %bb.0: # %entry
45; 64-NEXT:    sll $1, $4, 0
46; 64-NEXT:    sll $2, $5, 0
47; 64-NEXT:    dmult $2, $1
48; 64-NEXT:    mflo $1
49; 64-NEXT:    sll $2, $6, 0
50; 64-NEXT:    jr $ra
51; 64-NEXT:    daddu $2, $1, $2
52;
53; 64R6-LABEL: madd1:
54; 64R6:       # %bb.0: # %entry
55; 64R6-NEXT:    sll $1, $4, 0
56; 64R6-NEXT:    sll $2, $5, 0
57; 64R6-NEXT:    dmul $1, $2, $1
58; 64R6-NEXT:    sll $2, $6, 0
59; 64R6-NEXT:    jr $ra
60; 64R6-NEXT:    daddu $2, $1, $2
61;
62; 16-LABEL: madd1:
63; 16:       # %bb.0: # %entry
64; 16-NEXT:    mult $5, $4
65; 16-NEXT:    mflo $2
66; 16-NEXT:    mfhi $3
67; 16-NEXT:    sra $4, $6, 31
68; 16-NEXT:    addu $4, $3, $4
69; 16-NEXT:    addu $3, $2, $6
70; 16-NEXT:    sltu $3, $2
71; 16-NEXT:    move $2, $24
72; 16-NEXT:    addu $2, $4, $2
73; 16-NEXT:    jrc $ra
74entry:
75  %conv = sext i32 %a to i64
76  %conv2 = sext i32 %b to i64
77  %mul = mul nsw i64 %conv2, %conv
78  %conv4 = sext i32 %c to i64
79  %add = add nsw i64 %mul, %conv4
80  ret i64 %add
81}
82
83define i64 @madd2(i32 zeroext %a, i32 zeroext %b, i32 zeroext %c) nounwind readnone {
84; 32-LABEL: madd2:
85; 32:       # %bb.0: # %entry
86; 32-NEXT:    addiu $1, $zero, 0
87; 32-NEXT:    mtlo $6
88; 32-NEXT:    mthi $1
89; 32-NEXT:    maddu $5, $4
90; 32-NEXT:    mfhi $2
91; 32-NEXT:    jr $ra
92; 32-NEXT:    mflo $3
93;
94; 32R6-LABEL: madd2:
95; 32R6:       # %bb.0: # %entry
96; 32R6-NEXT:    mul $1, $5, $4
97; 32R6-NEXT:    addu $3, $1, $6
98; 32R6-NEXT:    sltu $1, $3, $1
99; 32R6-NEXT:    muhu $2, $5, $4
100; 32R6-NEXT:    jr $ra
101; 32R6-NEXT:    addu $2, $2, $1
102;
103; DSP-LABEL: madd2:
104; DSP:       # %bb.0: # %entry
105; DSP-NEXT:    addiu $1, $zero, 0
106; DSP-NEXT:    mtlo $6, $ac0
107; DSP-NEXT:    mthi $1, $ac0
108; DSP-NEXT:    maddu $ac0, $5, $4
109; DSP-NEXT:    mfhi $2, $ac0
110; DSP-NEXT:    jr $ra
111; DSP-NEXT:    mflo $3, $ac0
112;
113; 64-LABEL: madd2:
114; 64:       # %bb.0: # %entry
115; 64-NEXT:    dmult $5, $4
116; 64-NEXT:    mflo $1
117; 64-NEXT:    jr $ra
118; 64-NEXT:    daddu $2, $1, $6
119;
120; 64R6-LABEL: madd2:
121; 64R6:       # %bb.0: # %entry
122; 64R6-NEXT:    dmul $1, $5, $4
123; 64R6-NEXT:    jr $ra
124; 64R6-NEXT:    daddu $2, $1, $6
125;
126; 16-LABEL: madd2:
127; 16:       # %bb.0: # %entry
128; 16-NEXT:    multu $5, $4
129; 16-NEXT:    mflo $2
130; 16-NEXT:    mfhi $4
131; 16-NEXT:    addu $3, $2, $6
132; 16-NEXT:    sltu $3, $2
133; 16-NEXT:    move $2, $24
134; 16-NEXT:    addu $2, $4, $2
135; 16-NEXT:    jrc $ra
136entry:
137  %conv = zext i32 %a to i64
138  %conv2 = zext i32 %b to i64
139  %mul = mul nsw i64 %conv2, %conv
140  %conv4 = zext i32 %c to i64
141  %add = add nsw i64 %mul, %conv4
142  ret i64 %add
143}
144
145define i64 @madd3(i32 %a, i32 %b, i64 %c) nounwind readnone {
146; 32-LABEL: madd3:
147; 32:       # %bb.0: # %entry
148; 32-NEXT:    mtlo $7
149; 32-NEXT:    mthi $6
150; 32-NEXT:    madd $5, $4
151; 32-NEXT:    mfhi $2
152; 32-NEXT:    jr $ra
153; 32-NEXT:    mflo $3
154;
155; 32R6-LABEL: madd3:
156; 32R6:       # %bb.0: # %entry
157; 32R6-NEXT:    mul $1, $5, $4
158; 32R6-NEXT:    addu $3, $1, $7
159; 32R6-NEXT:    sltu $1, $3, $1
160; 32R6-NEXT:    muh $2, $5, $4
161; 32R6-NEXT:    addu $2, $2, $6
162; 32R6-NEXT:    jr $ra
163; 32R6-NEXT:    addu $2, $2, $1
164;
165; DSP-LABEL: madd3:
166; DSP:       # %bb.0: # %entry
167; DSP-NEXT:    mtlo $7, $ac0
168; DSP-NEXT:    mthi $6, $ac0
169; DSP-NEXT:    madd $ac0, $5, $4
170; DSP-NEXT:    mfhi $2, $ac0
171; DSP-NEXT:    jr $ra
172; DSP-NEXT:    mflo $3, $ac0
173;
174; 64-LABEL: madd3:
175; 64:       # %bb.0: # %entry
176; 64-NEXT:    sll $1, $4, 0
177; 64-NEXT:    sll $2, $5, 0
178; 64-NEXT:    dmult $2, $1
179; 64-NEXT:    mflo $1
180; 64-NEXT:    jr $ra
181; 64-NEXT:    daddu $2, $1, $6
182;
183; 64R6-LABEL: madd3:
184; 64R6:       # %bb.0: # %entry
185; 64R6-NEXT:    sll $1, $4, 0
186; 64R6-NEXT:    sll $2, $5, 0
187; 64R6-NEXT:    dmul $1, $2, $1
188; 64R6-NEXT:    jr $ra
189; 64R6-NEXT:    daddu $2, $1, $6
190;
191; 16-LABEL: madd3:
192; 16:       # %bb.0: # %entry
193; 16-NEXT:    mult $5, $4
194; 16-NEXT:    mflo $2
195; 16-NEXT:    mfhi $3
196; 16-NEXT:    addu $4, $3, $6
197; 16-NEXT:    addu $3, $2, $7
198; 16-NEXT:    sltu $3, $2
199; 16-NEXT:    move $2, $24
200; 16-NEXT:    addu $2, $4, $2
201; 16-NEXT:    jrc $ra
202entry:
203  %conv = sext i32 %a to i64
204  %conv2 = sext i32 %b to i64
205  %mul = mul nsw i64 %conv2, %conv
206  %add = add nsw i64 %mul, %c
207  ret i64 %add
208}
209
210define i32 @madd4(i32 %a, i32 %b, i32 %c) {
211; 32-LABEL: madd4:
212; 32:       # %bb.0: # %entry
213; 32-NEXT:    mul $1, $4, $5
214; 32-NEXT:    jr $ra
215; 32-NEXT:    addu $2, $6, $1
216;
217; 32R6-LABEL: madd4:
218; 32R6:       # %bb.0: # %entry
219; 32R6-NEXT:    mul $1, $4, $5
220; 32R6-NEXT:    jr $ra
221; 32R6-NEXT:    addu $2, $6, $1
222;
223; DSP-LABEL: madd4:
224; DSP:       # %bb.0: # %entry
225; DSP-NEXT:    mul $1, $4, $5
226; DSP-NEXT:    jr $ra
227; DSP-NEXT:    addu $2, $6, $1
228;
229; 64-LABEL: madd4:
230; 64:       # %bb.0: # %entry
231; 64-NEXT:    sll $1, $5, 0
232; 64-NEXT:    sll $2, $4, 0
233; 64-NEXT:    mul $1, $2, $1
234; 64-NEXT:    sll $2, $6, 0
235; 64-NEXT:    jr $ra
236; 64-NEXT:    addu $2, $2, $1
237;
238; 64R6-LABEL: madd4:
239; 64R6:       # %bb.0: # %entry
240; 64R6-NEXT:    sll $1, $5, 0
241; 64R6-NEXT:    sll $2, $4, 0
242; 64R6-NEXT:    mul $1, $2, $1
243; 64R6-NEXT:    sll $2, $6, 0
244; 64R6-NEXT:    jr $ra
245; 64R6-NEXT:    addu $2, $2, $1
246;
247; 16-LABEL: madd4:
248; 16:       # %bb.0: # %entry
249; 16-NEXT:    mult $4, $5
250; 16-NEXT:    mflo $2
251; 16-NEXT:    addu $2, $6, $2
252; 16-NEXT:    jrc $ra
253entry:
254  %mul = mul nsw i32 %a, %b
255  %add = add nsw i32 %c, %mul
256
257  ret i32 %add
258}
259
260define i64 @msub1(i32 %a, i32 %b, i32 %c) nounwind readnone {
261; 32-LABEL: msub1:
262; 32:       # %bb.0: # %entry
263; 32-NEXT:    sra $1, $6, 31
264; 32-NEXT:    mtlo $6
265; 32-NEXT:    mthi $1
266; 32-NEXT:    msub $5, $4
267; 32-NEXT:    mfhi $2
268; 32-NEXT:    jr $ra
269; 32-NEXT:    mflo $3
270;
271; 32R6-LABEL: msub1:
272; 32R6:       # %bb.0: # %entry
273; 32R6-NEXT:    mul $1, $5, $4
274; 32R6-NEXT:    sltu $2, $6, $1
275; 32R6-NEXT:    muh $3, $5, $4
276; 32R6-NEXT:    sra $4, $6, 31
277; 32R6-NEXT:    subu $3, $4, $3
278; 32R6-NEXT:    subu $2, $3, $2
279; 32R6-NEXT:    jr $ra
280; 32R6-NEXT:    subu $3, $6, $1
281;
282; DSP-LABEL: msub1:
283; DSP:       # %bb.0: # %entry
284; DSP-NEXT:    sra $1, $6, 31
285; DSP-NEXT:    mtlo $6, $ac0
286; DSP-NEXT:    mthi $1, $ac0
287; DSP-NEXT:    msub $ac0, $5, $4
288; DSP-NEXT:    mfhi $2, $ac0
289; DSP-NEXT:    jr $ra
290; DSP-NEXT:    mflo $3, $ac0
291;
292; 64-LABEL: msub1:
293; 64:       # %bb.0: # %entry
294; 64-NEXT:    sll $1, $4, 0
295; 64-NEXT:    sll $2, $5, 0
296; 64-NEXT:    dmult $2, $1
297; 64-NEXT:    mflo $1
298; 64-NEXT:    sll $2, $6, 0
299; 64-NEXT:    jr $ra
300; 64-NEXT:    dsubu $2, $2, $1
301;
302; 64R6-LABEL: msub1:
303; 64R6:       # %bb.0: # %entry
304; 64R6-NEXT:    sll $1, $4, 0
305; 64R6-NEXT:    sll $2, $5, 0
306; 64R6-NEXT:    dmul $1, $2, $1
307; 64R6-NEXT:    sll $2, $6, 0
308; 64R6-NEXT:    jr $ra
309; 64R6-NEXT:    dsubu $2, $2, $1
310;
311; 16-LABEL: msub1:
312; 16:       # %bb.0: # %entry
313; 16-NEXT:    mult $5, $4
314; 16-NEXT:    mflo $2
315; 16-NEXT:    mfhi $4
316; 16-NEXT:    subu $3, $6, $2
317; 16-NEXT:    sltu $6, $2
318; 16-NEXT:    move $2, $24
319; 16-NEXT:    sra $5, $6, 31
320; 16-NEXT:    subu $4, $5, $4
321; 16-NEXT:    subu $2, $4, $2
322; 16-NEXT:    jrc $ra
323entry:
324  %conv = sext i32 %c to i64
325  %conv2 = sext i32 %a to i64
326  %conv4 = sext i32 %b to i64
327  %mul = mul nsw i64 %conv4, %conv2
328  %sub = sub nsw i64 %conv, %mul
329  ret i64 %sub
330}
331
332define i64 @msub2(i32 zeroext %a, i32 zeroext %b, i32 zeroext %c) nounwind readnone {
333; 32-LABEL: msub2:
334; 32:       # %bb.0: # %entry
335; 32-NEXT:    addiu $1, $zero, 0
336; 32-NEXT:    mtlo $6
337; 32-NEXT:    mthi $1
338; 32-NEXT:    msubu $5, $4
339; 32-NEXT:    mfhi $2
340; 32-NEXT:    jr $ra
341; 32-NEXT:    mflo $3
342;
343; 32R6-LABEL: msub2:
344; 32R6:       # %bb.0: # %entry
345; 32R6-NEXT:    muhu $1, $5, $4
346; 32R6-NEXT:    mul $3, $5, $4
347; 32R6-NEXT:    sltu $2, $6, $3
348; 32R6-NEXT:    addu $1, $1, $2
349; 32R6-NEXT:    negu $2, $1
350; 32R6-NEXT:    jr $ra
351; 32R6-NEXT:    subu $3, $6, $3
352;
353; DSP-LABEL: msub2:
354; DSP:       # %bb.0: # %entry
355; DSP-NEXT:    addiu $1, $zero, 0
356; DSP-NEXT:    mtlo $6, $ac0
357; DSP-NEXT:    mthi $1, $ac0
358; DSP-NEXT:    msubu $ac0, $5, $4
359; DSP-NEXT:    mfhi $2, $ac0
360; DSP-NEXT:    jr $ra
361; DSP-NEXT:    mflo $3, $ac0
362;
363; 64-LABEL: msub2:
364; 64:       # %bb.0: # %entry
365; 64-NEXT:    dmult $5, $4
366; 64-NEXT:    mflo $1
367; 64-NEXT:    jr $ra
368; 64-NEXT:    dsubu $2, $6, $1
369;
370; 64R6-LABEL: msub2:
371; 64R6:       # %bb.0: # %entry
372; 64R6-NEXT:    dmul $1, $5, $4
373; 64R6-NEXT:    jr $ra
374; 64R6-NEXT:    dsubu $2, $6, $1
375;
376; 16-LABEL: msub2:
377; 16:       # %bb.0: # %entry
378; 16-NEXT:    multu $5, $4
379; 16-NEXT:    mflo $2
380; 16-NEXT:    mfhi $3
381; 16-NEXT:    sltu $6, $2
382; 16-NEXT:    move $4, $24
383; 16-NEXT:    addu $4, $3, $4
384; 16-NEXT:    subu $3, $6, $2
385; 16-NEXT:    neg $2, $4
386; 16-NEXT:    jrc $ra
387entry:
388  %conv = zext i32 %c to i64
389  %conv2 = zext i32 %a to i64
390  %conv4 = zext i32 %b to i64
391  %mul = mul nsw i64 %conv4, %conv2
392  %sub = sub nsw i64 %conv, %mul
393  ret i64 %sub
394}
395
396define i64 @msub3(i32 %a, i32 %b, i64 %c) nounwind readnone {
397; 32-LABEL: msub3:
398; 32:       # %bb.0: # %entry
399; 32-NEXT:    mtlo $7
400; 32-NEXT:    mthi $6
401; 32-NEXT:    msub $5, $4
402; 32-NEXT:    mfhi $2
403; 32-NEXT:    jr $ra
404; 32-NEXT:    mflo $3
405;
406; 32R6-LABEL: msub3:
407; 32R6:       # %bb.0: # %entry
408; 32R6-NEXT:    mul $1, $5, $4
409; 32R6-NEXT:    sltu $2, $7, $1
410; 32R6-NEXT:    muh $3, $5, $4
411; 32R6-NEXT:    subu $3, $6, $3
412; 32R6-NEXT:    subu $2, $3, $2
413; 32R6-NEXT:    jr $ra
414; 32R6-NEXT:    subu $3, $7, $1
415;
416; DSP-LABEL: msub3:
417; DSP:       # %bb.0: # %entry
418; DSP-NEXT:    mtlo $7, $ac0
419; DSP-NEXT:    mthi $6, $ac0
420; DSP-NEXT:    msub $ac0, $5, $4
421; DSP-NEXT:    mfhi $2, $ac0
422; DSP-NEXT:    jr $ra
423; DSP-NEXT:    mflo $3, $ac0
424;
425; 64-LABEL: msub3:
426; 64:       # %bb.0: # %entry
427; 64-NEXT:    sll $1, $4, 0
428; 64-NEXT:    sll $2, $5, 0
429; 64-NEXT:    dmult $2, $1
430; 64-NEXT:    mflo $1
431; 64-NEXT:    jr $ra
432; 64-NEXT:    dsubu $2, $6, $1
433;
434; 64R6-LABEL: msub3:
435; 64R6:       # %bb.0: # %entry
436; 64R6-NEXT:    sll $1, $4, 0
437; 64R6-NEXT:    sll $2, $5, 0
438; 64R6-NEXT:    dmul $1, $2, $1
439; 64R6-NEXT:    jr $ra
440; 64R6-NEXT:    dsubu $2, $6, $1
441;
442; 16-LABEL: msub3:
443; 16:       # %bb.0: # %entry
444; 16-NEXT:    mult $5, $4
445; 16-NEXT:    mflo $2
446; 16-NEXT:    mfhi $4
447; 16-NEXT:    subu $3, $7, $2
448; 16-NEXT:    sltu $7, $2
449; 16-NEXT:    move $2, $24
450; 16-NEXT:    subu $4, $6, $4
451; 16-NEXT:    subu $2, $4, $2
452; 16-NEXT:    jrc $ra
453entry:
454  %conv = sext i32 %a to i64
455  %conv3 = sext i32 %b to i64
456  %mul = mul nsw i64 %conv3, %conv
457  %sub = sub nsw i64 %c, %mul
458  ret i64 %sub
459}
460
461define i32 @msub4(i32 %a, i32 %b, i32 %c) {
462; 32-LABEL: msub4:
463; 32:       # %bb.0: # %entry
464; 32-NEXT:    mul $1, $4, $5
465; 32-NEXT:    jr $ra
466; 32-NEXT:    subu $2, $6, $1
467;
468; 32R6-LABEL: msub4:
469; 32R6:       # %bb.0: # %entry
470; 32R6-NEXT:    mul $1, $4, $5
471; 32R6-NEXT:    jr $ra
472; 32R6-NEXT:    subu $2, $6, $1
473;
474; DSP-LABEL: msub4:
475; DSP:       # %bb.0: # %entry
476; DSP-NEXT:    mul $1, $4, $5
477; DSP-NEXT:    jr $ra
478; DSP-NEXT:    subu $2, $6, $1
479;
480; 64-LABEL: msub4:
481; 64:       # %bb.0: # %entry
482; 64-NEXT:    sll $1, $5, 0
483; 64-NEXT:    sll $2, $4, 0
484; 64-NEXT:    mul $1, $2, $1
485; 64-NEXT:    sll $2, $6, 0
486; 64-NEXT:    jr $ra
487; 64-NEXT:    subu $2, $2, $1
488;
489; 64R6-LABEL: msub4:
490; 64R6:       # %bb.0: # %entry
491; 64R6-NEXT:    sll $1, $5, 0
492; 64R6-NEXT:    sll $2, $4, 0
493; 64R6-NEXT:    mul $1, $2, $1
494; 64R6-NEXT:    sll $2, $6, 0
495; 64R6-NEXT:    jr $ra
496; 64R6-NEXT:    subu $2, $2, $1
497;
498; 16-LABEL: msub4:
499; 16:       # %bb.0: # %entry
500; 16-NEXT:    mult $4, $5
501; 16-NEXT:    mflo $2
502; 16-NEXT:    subu $2, $6, $2
503; 16-NEXT:    jrc $ra
504entry:
505  %mul = mul nsw i32 %a, %b
506  %sub = sub nsw i32 %c, %mul
507
508  ret i32 %sub
509}
510