1 ; RUN: llc -march=mips -mcpu=mips32 < %s \
2 ; RUN: | FileCheck %s -check-prefixes=ALL,32
3 ; RUN: llc -march=mips -mcpu=mips32r2 < %s \
4 ; RUN: | FileCheck %s -check-prefixes=ALL,32
5 ; RUN: llc -march=mips -mcpu=mips32r6 < %s \
6 ; RUN: | FileCheck %s -check-prefixes=ALL,32R6
7 ; RUN: llc -march=mips -mcpu=mips32r2 -mattr=dsp < %s \
8 ; RUN: | FileCheck %s -check-prefix=DSP
9 ; RUN: llc -march=mips -mcpu=mips64 -target-abi n64 < %s \
10 ; RUN: | FileCheck %s -check-prefixes=ALL,64
11 ; RUN: llc -march=mips -mcpu=mips64r2 -target-abi n64 < %s \
12 ; RUN: | FileCheck %s -check-prefixes=ALL,64
13 ; RUN: llc -march=mips -mcpu=mips64r6 -target-abi n64 < %s \
14 ; RUN: | FileCheck %s -check-prefixes=ALL,64R6
16 ; FIXME: The MIPS16 test should check its output
17 ; RUN: llc -march=mips -mattr=mips16 < %s
21 ; 32-DAG: sra $[[T0:[0-9]+]], $6, 31
23 ; 32-DAG: [[m:m]]add ${{[45]}}, ${{[45]}}
27 ; DSP-DAG: sra $[[T0:[0-9]+]], $6, 31
28 ; DSP-DAG: mtlo $6, $[[AC:ac[0-3]+]]
29 ; DSP-DAG: madd $[[AC]], ${{[45]}}, ${{[45]}}
30 ; DSP-DAG: mfhi $2, $[[AC]]
31 ; DSP-DAG: mflo $3, $[[AC]]
33 ; 32R6-DAG: mul $[[T0:[0-9]+]], ${{[45]}}, ${{[45]}}
34 ; 32R6-DAG: addu $[[T1:[0-9]+]], $[[T0]], $6
35 ; 32R6-DAG: sltu $[[T2:[0-9]+]], $[[T1]], $[[T0]]
36 ; 32R6-DAG: muh $[[T3:[0-9]+]], ${{[45]}}, ${{[45]}}
37 ; 32R6-DAG: sra $[[T4:[0-9]+]], $6, 31
38 ; 32R6-DAG: addu $[[T5:[0-9]+]], $[[T3]], $[[T4]]
39 ; 32R6-DAG: addu $2, $[[T5]], $[[T2]]
41 ; 64-DAG: sll $[[T0:[0-9]+]], $4, 0
42 ; 64-DAG: sll $[[T1:[0-9]+]], $5, 0
43 ; 64-DAG: d[[m:m]]ult $[[T1]], $[[T0]]
44 ; 64-DAG: [[m]]flo $[[T2:[0-9]+]]
45 ; 64-DAG: sll $[[T3:[0-9]+]], $6, 0
46 ; 64-DAG: daddu $2, $[[T2]], $[[T3]]
48 ; 64R6-DAG: sll $[[T0:[0-9]+]], $4, 0
49 ; 64R6-DAG: sll $[[T1:[0-9]+]], $5, 0
50 ; 64R6-DAG: dmul $[[T2:[0-9]+]], $[[T1]], $[[T0]]
51 ; 64R6-DAG: sll $[[T3:[0-9]+]], $6, 0
52 ; 64R6-DAG: daddu $2, $[[T2]], $[[T3]]
54 define i64 @madd1(i32 %a, i32 %b, i32 %c) nounwind readnone {
56 %conv = sext i32 %a to i64
57 %conv2 = sext i32 %b to i64
58 %mul = mul nsw i64 %conv2, %conv
59 %conv4 = sext i32 %c to i64
60 %add = add nsw i64 %mul, %conv4
66 ; FIXME: We don't really need this instruction
67 ; 32-DAG: addiu $[[T0:[0-9]+]], $zero, 0
69 ; 32-DAG: [[m:m]]addu ${{[45]}}, ${{[45]}}
73 ; DSP-DAG: addiu $[[T0:[0-9]+]], $zero, 0
74 ; DSP-DAG: mtlo $6, $[[AC:ac[0-3]+]]
75 ; DSP-DAG: maddu $[[AC]], ${{[45]}}, ${{[45]}}
76 ; DSP-DAG: mfhi $2, $[[AC]]
77 ; DSP-DAG: mflo $3, $[[AC]]
79 ; 32R6-DAG: mul $[[T0:[0-9]+]], ${{[45]}}, ${{[45]}}
80 ; 32R6-DAG: addu $[[T1:[0-9]+]], $[[T0]], $6
81 ; 32R6-DAG: sltu $[[T2:[0-9]+]], $[[T1]], $[[T0]]
82 ; FIXME: There's a redundant move here. We should remove it
83 ; 32R6-DAG: muhu $[[T3:[0-9]+]], ${{[45]}}, ${{[45]}}
84 ; 32R6-DAG: addu $2, $[[T3]], $[[T2]]
86 ; 64-DAG: d[[m:m]]ult $5, $4
87 ; 64-DAG: [[m]]flo $[[T0:[0-9]+]]
88 ; 64-DAG: daddu $2, $[[T0]], $6
90 ; 64R6-DAG: dmul $[[T0:[0-9]+]], $5, $4
91 ; 64R6-DAG: daddu $2, $[[T0]], $6
93 define i64 @madd2(i32 zeroext %a, i32 zeroext %b, i32 zeroext %c) nounwind readnone {
95 %conv = zext i32 %a to i64
96 %conv2 = zext i32 %b to i64
97 %mul = mul nsw i64 %conv2, %conv
98 %conv4 = zext i32 %c to i64
99 %add = add nsw i64 %mul, %conv4
107 ; 32-DAG: [[m:m]]add ${{[45]}}, ${{[45]}}
108 ; 32-DAG: [[m]]fhi $2
109 ; 32-DAG: [[m]]flo $3
111 ; DSP-DAG: mthi $6, $[[AC:ac[0-3]+]]
112 ; DSP-DAG: mtlo $7, $[[AC]]
113 ; DSP-DAG: madd $[[AC]], ${{[45]}}, ${{[45]}}
114 ; DSP-DAG: mfhi $2, $[[AC]]
115 ; DSP-DAG: mflo $3, $[[AC]]
117 ; 32R6-DAG: mul $[[T0:[0-9]+]], ${{[45]}}, ${{[45]}}
118 ; 32R6-DAG: addu $[[T1:[0-9]+]], $[[T0]], $7
119 ; 32R6-DAG: sltu $[[T2:[0-9]+]], $[[T1]], $1
120 ; 32R6-DAG: muh $[[T3:[0-9]+]], ${{[45]}}, ${{[45]}}
121 ; 32R6-DAG: addu $[[T4:[0-9]+]], $[[T3]], $6
122 ; 32R6-DAG: addu $2, $[[T4]], $[[T2]]
124 ; 64-DAG: sll $[[T0:[0-9]+]], $4, 0
125 ; 64-DAG: sll $[[T1:[0-9]+]], $5, 0
126 ; 64-DAG: d[[m:m]]ult $[[T1]], $[[T0]]
127 ; 64-DAG: [[m]]flo $[[T2:[0-9]+]]
128 ; 64-DAG: daddu $2, $[[T2]], $6
130 ; 64R6-DAG: sll $[[T0:[0-9]+]], $4, 0
131 ; 64R6-DAG: sll $[[T1:[0-9]+]], $5, 0
132 ; 64R6-DAG: dmul $[[T2:[0-9]+]], $[[T1]], $[[T0]]
133 ; 64R6-DAG: daddu $2, $[[T2]], $6
135 define i64 @madd3(i32 %a, i32 %b, i64 %c) nounwind readnone {
137 %conv = sext i32 %a to i64
138 %conv2 = sext i32 %b to i64
139 %mul = mul nsw i64 %conv2, %conv
140 %add = add nsw i64 %mul, %c
145 ; ALL-NOT: madd ${{[0-9]+}}, ${{[0-9]+}}
147 define i32 @madd4(i32 %a, i32 %b, i32 %c) {
149 %mul = mul nsw i32 %a, %b
150 %add = add nsw i32 %c, %mul
157 ; 32-DAG: sra $[[T0:[0-9]+]], $6, 31
159 ; 32-DAG: [[m:m]]sub ${{[45]}}, ${{[45]}}
160 ; 32-DAG: [[m]]fhi $2
161 ; 32-DAG: [[m]]flo $3
163 ; DSP-DAG: sra $[[T0:[0-9]+]], $6, 31
164 ; DSP-DAG: mtlo $6, $[[AC:ac[0-3]+]]
165 ; DSP-DAG: msub $[[AC]], ${{[45]}}, ${{[45]}}
166 ; DSP-DAG: mfhi $2, $[[AC]]
167 ; DSP-DAG: mflo $3, $[[AC]]
169 ; 32R6-DAG: mul $[[T0:[0-9]+]], ${{[45]}}, ${{[45]}}
170 ; 32R6-DAG: sltu $[[T1:[0-9]+]], $6, $[[T0]]
171 ; 32R6-DAG: muh $[[T2:[0-9]+]], ${{[45]}}, ${{[45]}}
172 ; 32R6-DAG: sra $[[T3:[0-9]+]], $6, 31
173 ; 32R6-DAG: subu $[[T4:[0-9]+]], $[[T3]], $[[T2]]
174 ; 32R6-DAG: subu $2, $[[T4]], $[[T1]]
175 ; 32R6-DAG: subu $3, $6, $[[T0]]
177 ; 64-DAG: sll $[[T0:[0-9]+]], $4, 0
178 ; 64-DAG: sll $[[T1:[0-9]+]], $5, 0
179 ; 64-DAG: d[[m:m]]ult $[[T1]], $[[T0]]
180 ; 64-DAG: [[m]]flo $[[T2:[0-9]+]]
181 ; 64-DAG: sll $[[T3:[0-9]+]], $6, 0
182 ; 64-DAG: dsubu $2, $[[T3]], $[[T2]]
184 ; 64R6-DAG: sll $[[T0:[0-9]+]], $4, 0
185 ; 64R6-DAG: sll $[[T1:[0-9]+]], $5, 0
186 ; 64R6-DAG: dmul $[[T2:[0-9]+]], $[[T1]], $[[T0]]
187 ; 64R6-DAG: sll $[[T3:[0-9]+]], $6, 0
188 ; 64R6-DAG: dsubu $2, $[[T3]], $[[T2]]
190 define i64 @msub1(i32 %a, i32 %b, i32 %c) nounwind readnone {
192 %conv = sext i32 %c to i64
193 %conv2 = sext i32 %a to i64
194 %conv4 = sext i32 %b to i64
195 %mul = mul nsw i64 %conv4, %conv2
196 %sub = sub nsw i64 %conv, %mul
202 ; FIXME: We don't really need this instruction
203 ; 32-DAG: addiu $[[T0:[0-9]+]], $zero, 0
205 ; 32-DAG: [[m:m]]subu ${{[45]}}, ${{[45]}}
206 ; 32-DAG: [[m]]fhi $2
207 ; 32-DAG: [[m]]flo $3
209 ; DSP-DAG: addiu $[[T0:[0-9]+]], $zero, 0
210 ; DSP-DAG: mtlo $6, $[[AC:ac[0-3]+]]
211 ; DSP-DAG: msubu $[[AC]], ${{[45]}}, ${{[45]}}
212 ; DSP-DAG: mfhi $2, $[[AC]]
213 ; DSP-DAG: mflo $3, $[[AC]]
215 ; 32R6-DAG: mul $[[T0:[0-9]+]], ${{[45]}}, ${{[45]}}
216 ; 32R6-DAG: sltu $[[T1:[0-9]+]], $6, $[[T0]]
217 ; 32R6-DAG: muhu $[[T2:[0-9]+]], ${{[45]}}, ${{[45]}}
218 ; 32R6-DAG: negu $[[T3:[0-9]+]], $[[T2]]
219 ; 32R6-DAG: subu $2, $[[T3]], $[[T1]]
220 ; 32R6-DAG: subu $3, $6, $[[T0]]
222 ; 64-DAG: d[[m:m]]ult $5, $4
223 ; 64-DAG: [[m]]flo $[[T0:[0-9]+]]
224 ; 64-DAG: dsubu $2, $6, $[[T0]]
226 ; 64R6-DAG: dmul $[[T0:[0-9]+]], $5, $4
227 ; 64R6-DAG: dsubu $2, $6, $[[T0]]
229 define i64 @msub2(i32 zeroext %a, i32 zeroext %b, i32 zeroext %c) nounwind readnone {
231 %conv = zext i32 %c to i64
232 %conv2 = zext i32 %a to i64
233 %conv4 = zext i32 %b to i64
234 %mul = mul nsw i64 %conv4, %conv2
235 %sub = sub nsw i64 %conv, %mul
241 ; FIXME: We don't really need this instruction
244 ; 32-DAG: [[m:m]]sub ${{[45]}}, ${{[45]}}
245 ; 32-DAG: [[m]]fhi $2
246 ; 32-DAG: [[m]]flo $3
248 ; DSP-DAG: mtlo $7, $[[AC:ac[0-3]+]]
249 ; DSP-DAG: mthi $6, $[[AC]]
250 ; DSP-DAG: msub $[[AC]], ${{[45]}}, ${{[45]}}
251 ; DSP-DAG: mfhi $2, $[[AC]]
252 ; DSP-DAG: mflo $3, $[[AC]]
254 ; 32R6-DAG: mul $[[T0:[0-9]+]], ${{[45]}}, ${{[45]}}
255 ; 32R6-DAG: sltu $[[T1:[0-9]+]], $7, $[[T0]]
256 ; 32R6-DAG: muh $[[T2:[0-9]+]], ${{[45]}}, ${{[45]}}
257 ; 32R6-DAG: subu $[[T3:[0-9]+]], $6, $[[T2]]
258 ; 32R6-DAG: subu $2, $[[T3]], $[[T1]]
259 ; 32R6-DAG: subu $3, $7, $[[T0]]
261 ; 64-DAG: sll $[[T0:[0-9]+]], $4, 0
262 ; 64-DAG: sll $[[T1:[0-9]+]], $5, 0
263 ; 64-DAG: d[[m:m]]ult $[[T1]], $[[T0]]
264 ; 64-DAG: [[m]]flo $[[T2:[0-9]+]]
265 ; 64-DAG: dsubu $2, $6, $[[T2]]
267 ; 64R6-DAG: sll $[[T0:[0-9]+]], $4, 0
268 ; 64R6-DAG: sll $[[T1:[0-9]+]], $5, 0
269 ; 64R6-DAG: dmul $[[T2:[0-9]+]], $[[T1]], $[[T0]]
270 ; 64R6-DAG: dsubu $2, $6, $[[T2]]
272 define i64 @msub3(i32 %a, i32 %b, i64 %c) nounwind readnone {
274 %conv = sext i32 %a to i64
275 %conv3 = sext i32 %b to i64
276 %mul = mul nsw i64 %conv3, %conv
277 %sub = sub nsw i64 %c, %mul
282 ; ALL-NOT: msub ${{[0-9]+}}, ${{[0-9]+}}
284 define i32 @msub4(i32 %a, i32 %b, i32 %c) {
286 %mul = mul nsw i32 %a, %b
287 %sub = sub nsw i32 %c, %mul