[mips][mips16] MIPS16 is not a CPU/Architecture but is an ASE.
[oota-llvm.git] / test / CodeGen / Mips / madd-msub.ll
1 ; RUN: llc -march=mips -mcpu=mips32   < %s | FileCheck %s -check-prefix=ALL -check-prefix=32
2 ; RUN: llc -march=mips -mcpu=mips32r2 < %s | FileCheck %s -check-prefix=ALL -check-prefix=32
3 ; RUN: llc -march=mips -mcpu=mips32r6 < %s | FileCheck %s -check-prefix=ALL -check-prefix=32R6
4 ; RUN: llc -march=mips -mcpu=mips32 -mattr=dsp < %s | FileCheck %s -check-prefix=DSP
5 ; RUN: llc -march=mips -mcpu=mips64   < %s | FileCheck %s -check-prefix=ALL -check-prefix=64
6 ; RUN: llc -march=mips -mcpu=mips64r2 < %s | FileCheck %s -check-prefix=ALL -check-prefix=64
7 ; RUN: llc -march=mips -mcpu=mips64r6 < %s | FileCheck %s -check-prefix=ALL -check-prefix=64R6
8
9 ; FIXME: The MIPS16 test should check its output
10 ; RUN: llc -march=mips -mattr=mips16 < %s
11
12 ; ALL-LABEL: madd1:
13
14 ; 32-DAG:        sra $[[T0:[0-9]+]], $6, 31
15 ; 32-DAG:        mtlo $6
16 ; 32-DAG:        [[m:m]]add ${{[45]}}, ${{[45]}}
17 ; 32-DAG:        [[m]]fhi $2
18 ; 32-DAG:        [[m]]flo $3
19
20 ; DSP-DAG:       sra $[[T0:[0-9]+]], $6, 31
21 ; DSP-DAG:       mtlo $[[AC:ac[0-3]+]], $6
22 ; DSP-DAG:       madd $[[AC]], ${{[45]}}, ${{[45]}}
23 ; DSP-DAG:       mfhi $2, $[[AC]]
24 ; DSP-DAG:       mflo $3, $[[AC]]
25
26 ; 32R6-DAG:      mul  $[[T0:[0-9]+]], ${{[45]}}, ${{[45]}}
27 ; 32R6-DAG:      addu $[[T1:[0-9]+]], $[[T0]], $6
28 ; 32R6-DAG:      sltu $[[T2:[0-9]+]], $[[T1]], $6
29 ; 32R6-DAG:      sra  $[[T3:[0-9]+]], $6, 31
30 ; 32R6-DAG:      addu $[[T4:[0-9]+]], $[[T2]], $[[T3]]
31 ; 32R6-DAG:      muh  $[[T5:[0-9]+]], ${{[45]}}, ${{[45]}}
32 ; 32R6-DAG:      addu $2, $[[T5]], $[[T4]]
33
34 ; 64-DAG:        sll $[[T0:[0-9]+]], $4, 0
35 ; 64-DAG:        sll $[[T1:[0-9]+]], $5, 0
36 ; 64-DAG:        d[[m:m]]ult $[[T1]], $[[T0]]
37 ; 64-DAG:        [[m]]flo $[[T2:[0-9]+]]
38 ; 64-DAG:        sll $[[T3:[0-9]+]], $6, 0
39 ; 64-DAG:        daddu $2, $[[T2]], $[[T3]]
40
41 ; 64R6-DAG:      sll $[[T0:[0-9]+]], $4, 0
42 ; 64R6-DAG:      sll $[[T1:[0-9]+]], $5, 0
43 ; 64R6-DAG:      dmul $[[T2:[0-9]+]], $[[T1]], $[[T0]]
44 ; 64R6-DAG:      sll $[[T3:[0-9]+]], $6, 0
45 ; 64R6-DAG:      daddu $2, $[[T2]], $[[T3]]
46
47 define i64 @madd1(i32 %a, i32 %b, i32 %c) nounwind readnone {
48 entry:
49   %conv = sext i32 %a to i64
50   %conv2 = sext i32 %b to i64
51   %mul = mul nsw i64 %conv2, %conv
52   %conv4 = sext i32 %c to i64
53   %add = add nsw i64 %mul, %conv4
54   ret i64 %add
55 }
56
57 ; ALL-LABEL: madd2:
58
59 ; FIXME: We don't really need this instruction
60 ; 32-DAG:        addiu $[[T0:[0-9]+]], $zero, 0
61 ; 32-DAG:        mtlo $6
62 ; 32-DAG:        [[m:m]]addu ${{[45]}}, ${{[45]}}
63 ; 32-DAG:        [[m]]fhi $2
64 ; 32-DAG:        [[m]]flo $3
65
66 ; DSP-DAG:       addiu $[[T0:[0-9]+]], $zero, 0
67 ; DSP-DAG:       mtlo $[[AC:ac[0-3]+]], $6
68 ; DSP-DAG:       maddu $[[AC]], ${{[45]}}, ${{[45]}}
69 ; DSP-DAG:       mfhi $2, $[[AC]]
70 ; DSP-DAG:       mflo $3, $[[AC]]
71
72 ; 32R6-DAG:      mul  $[[T0:[0-9]+]], ${{[45]}}, ${{[45]}}
73 ; 32R6-DAG:      addu $[[T1:[0-9]+]], $[[T0]], $6
74 ; 32R6-DAG:      sltu $[[T2:[0-9]+]], $[[T1]], $6
75 ; FIXME: There's a redundant move here. We should remove it
76 ; 32R6-DAG:      muhu $[[T3:[0-9]+]], ${{[45]}}, ${{[45]}}
77 ; 32R6-DAG:      addu $2, $[[T3]], $[[T2]]
78
79 ; 64-DAG:        d[[m:m]]ult $5, $4
80 ; 64-DAG:        [[m]]flo $[[T0:[0-9]+]]
81 ; 64-DAG:        daddu $2, $[[T0]], $6
82
83 ; 64R6-DAG:      dmul $[[T0:[0-9]+]], $5, $4
84 ; 64R6-DAG:      daddu $2, $[[T0]], $6
85
86 define i64 @madd2(i32 zeroext %a, i32 zeroext %b, i32 zeroext %c) nounwind readnone {
87 entry:
88   %conv = zext i32 %a to i64
89   %conv2 = zext i32 %b to i64
90   %mul = mul nsw i64 %conv2, %conv
91   %conv4 = zext i32 %c to i64
92   %add = add nsw i64 %mul, %conv4
93   ret i64 %add
94 }
95
96 ; ALL-LABEL: madd3:
97
98 ; 32-DAG:        mthi $6
99 ; 32-DAG:        mtlo $7
100 ; 32-DAG:        [[m:m]]add ${{[45]}}, ${{[45]}}
101 ; 32-DAG:        [[m]]fhi $2
102 ; 32-DAG:        [[m]]flo $3
103
104 ; DSP-DAG:       mthi $[[AC:ac[0-3]+]], $6
105 ; DSP-DAG:       mtlo $[[AC]], $7
106 ; DSP-DAG:       madd $[[AC]], ${{[45]}}, ${{[45]}}
107 ; DSP-DAG:       mfhi $2, $[[AC]]
108 ; DSP-DAG:       mflo $3, $[[AC]]
109
110 ; 32R6-DAG:      mul  $[[T0:[0-9]+]], ${{[45]}}, ${{[45]}}
111 ; 32R6-DAG:      addu $[[T1:[0-9]+]], $[[T0]], $7
112 ; 32R6-DAG:      sltu $[[T2:[0-9]+]], $[[T1]], $7
113 ; 32R6-DAG:      addu $[[T4:[0-9]+]], $[[T2]], $6
114 ; 32R6-DAG:      muh  $[[T5:[0-9]+]], ${{[45]}}, ${{[45]}}
115 ; 32R6-DAG:      addu $2, $[[T5]], $[[T4]]
116
117 ; 64-DAG:        sll $[[T0:[0-9]+]], $4, 0
118 ; 64-DAG:        sll $[[T1:[0-9]+]], $5, 0
119 ; 64-DAG:        d[[m:m]]ult $[[T1]], $[[T0]]
120 ; 64-DAG:        [[m]]flo $[[T2:[0-9]+]]
121 ; 64-DAG:        daddu $2, $[[T2]], $6
122
123 ; 64R6-DAG:      sll $[[T0:[0-9]+]], $4, 0
124 ; 64R6-DAG:      sll $[[T1:[0-9]+]], $5, 0
125 ; 64R6-DAG:      dmul $[[T2:[0-9]+]], $[[T1]], $[[T0]]
126 ; 64R6-DAG:      daddu $2, $[[T2]], $6
127
128 define i64 @madd3(i32 %a, i32 %b, i64 %c) nounwind readnone {
129 entry:
130   %conv = sext i32 %a to i64
131   %conv2 = sext i32 %b to i64
132   %mul = mul nsw i64 %conv2, %conv
133   %add = add nsw i64 %mul, %c
134   ret i64 %add
135 }
136
137 ; ALL-LABEL: msub1:
138
139 ; 32-DAG:        sra $[[T0:[0-9]+]], $6, 31
140 ; 32-DAG:        mtlo $6
141 ; 32-DAG:        [[m:m]]sub ${{[45]}}, ${{[45]}}
142 ; 32-DAG:        [[m]]fhi $2
143 ; 32-DAG:        [[m]]flo $3
144
145 ; DSP-DAG:       sra $[[T0:[0-9]+]], $6, 31
146 ; DSP-DAG:       mtlo $[[AC:ac[0-3]+]], $6
147 ; DSP-DAG:       msub $[[AC]], ${{[45]}}, ${{[45]}}
148 ; DSP-DAG:       mfhi $2, $[[AC]]
149 ; DSP-DAG:       mflo $3, $[[AC]]
150
151 ; 32R6-DAG:      muh  $[[T0:[0-9]+]], ${{[45]}}, ${{[45]}}
152 ; 32R6-DAG:      mul  $[[T1:[0-9]+]], ${{[45]}}, ${{[45]}}
153 ; 32R6-DAG:      sltu $[[T3:[0-9]+]], $6, $[[T1]]
154 ; 32R6-DAG:      addu $[[T4:[0-9]+]], $[[T3]], $[[T0]]
155 ; 32R6-DAG:      sra  $[[T5:[0-9]+]], $6, 31
156 ; 32R6-DAG:      subu $2, $[[T5]], $[[T4]]
157 ; 32R6-DAG:      subu $3, $6, $[[T1]]
158
159 ; 64-DAG:        sll $[[T0:[0-9]+]], $4, 0
160 ; 64-DAG:        sll $[[T1:[0-9]+]], $5, 0
161 ; 64-DAG:        d[[m:m]]ult $[[T1]], $[[T0]]
162 ; 64-DAG:        [[m]]flo $[[T2:[0-9]+]]
163 ; 64-DAG:        sll $[[T3:[0-9]+]], $6, 0
164 ; 64-DAG:        dsubu $2, $[[T3]], $[[T2]]
165
166 ; 64R6-DAG:      sll $[[T0:[0-9]+]], $4, 0
167 ; 64R6-DAG:      sll $[[T1:[0-9]+]], $5, 0
168 ; 64R6-DAG:      dmul $[[T2:[0-9]+]], $[[T1]], $[[T0]]
169 ; 64R6-DAG:      sll $[[T3:[0-9]+]], $6, 0
170 ; 64R6-DAG:      dsubu $2, $[[T3]], $[[T2]]
171
172 define i64 @msub1(i32 %a, i32 %b, i32 %c) nounwind readnone {
173 entry:
174   %conv = sext i32 %c to i64
175   %conv2 = sext i32 %a to i64
176   %conv4 = sext i32 %b to i64
177   %mul = mul nsw i64 %conv4, %conv2
178   %sub = sub nsw i64 %conv, %mul
179   ret i64 %sub
180 }
181
182 ; ALL-LABEL: msub2:
183
184 ; FIXME: We don't really need this instruction
185 ; 32-DAG:        addiu $[[T0:[0-9]+]], $zero, 0
186 ; 32-DAG:        mtlo $6
187 ; 32-DAG:        [[m:m]]subu ${{[45]}}, ${{[45]}}
188 ; 32-DAG:        [[m]]fhi $2
189 ; 32-DAG:        [[m]]flo $3
190
191 ; DSP-DAG:       addiu $[[T0:[0-9]+]], $zero, 0
192 ; DSP-DAG:       mtlo $[[AC:ac[0-3]+]], $6
193 ; DSP-DAG:       msubu $[[AC]], ${{[45]}}, ${{[45]}}
194 ; DSP-DAG:       mfhi $2, $[[AC]]
195 ; DSP-DAG:       mflo $3, $[[AC]]
196
197 ; 32R6-DAG:      muhu $[[T0:[0-9]+]], ${{[45]}}, ${{[45]}}
198 ; 32R6-DAG:      mul $[[T1:[0-9]+]], ${{[45]}}, ${{[45]}}
199
200 ; 32R6-DAG:      sltu $[[T2:[0-9]+]], $6, $[[T1]]
201 ; 32R6-DAG:      addu $[[T3:[0-9]+]], $[[T2]], $[[T0]]
202 ; 32R6-DAG:      negu $2, $[[T3]]
203 ; 32R6-DAG:      subu $3, $6, $[[T1]]
204
205 ; 64-DAG:        d[[m:m]]ult $5, $4
206 ; 64-DAG:        [[m]]flo $[[T0:[0-9]+]]
207 ; 64-DAG:        dsubu $2, $6, $[[T0]]
208
209 ; 64R6-DAG:      dmul $[[T0:[0-9]+]], $5, $4
210 ; 64R6-DAG:      dsubu $2, $6, $[[T0]]
211
212 define i64 @msub2(i32 zeroext %a, i32 zeroext %b, i32 zeroext %c) nounwind readnone {
213 entry:
214   %conv = zext i32 %c to i64
215   %conv2 = zext i32 %a to i64
216   %conv4 = zext i32 %b to i64
217   %mul = mul nsw i64 %conv4, %conv2
218   %sub = sub nsw i64 %conv, %mul
219   ret i64 %sub
220 }
221
222 ; ALL-LABEL: msub3:
223
224 ; FIXME: We don't really need this instruction
225 ; 32-DAG:        mthi $6
226 ; 32-DAG:        mtlo $7
227 ; 32-DAG:        [[m:m]]sub ${{[45]}}, ${{[45]}}
228 ; 32-DAG:        [[m]]fhi $2
229 ; 32-DAG:        [[m]]flo $3
230
231 ; DSP-DAG:       addiu $[[T0:[0-9]+]], $zero, 0
232 ; DSP-DAG:       mtlo $[[AC:ac[0-3]+]], $6
233 ; DSP-DAG:       msub $[[AC]], ${{[45]}}, ${{[45]}}
234 ; DSP-DAG:       mfhi $2, $[[AC]]
235 ; DSP-DAG:       mflo $3, $[[AC]]
236
237 ; 32R6-DAG:      muh $[[T0:[0-9]+]], ${{[45]}}, ${{[45]}}
238 ; 32R6-DAG:      mul $[[T1:[0-9]+]], ${{[45]}}, ${{[45]}}
239 ; 32R6-DAG:      sltu $[[T2:[0-9]+]], $7, $[[T1]]
240 ; 32R6-DAG:      addu $[[T3:[0-9]+]], $[[T2]], $[[T0]]
241 ; 32R6-DAG:      subu $2, $6, $[[T3]]
242 ; 32R6-DAG:      subu $3, $7, $[[T1]]
243
244 ; 64-DAG:        sll $[[T0:[0-9]+]], $4, 0
245 ; 64-DAG:        sll $[[T1:[0-9]+]], $5, 0
246 ; 64-DAG:        d[[m:m]]ult $[[T1]], $[[T0]]
247 ; 64-DAG:        [[m]]flo $[[T2:[0-9]+]]
248 ; 64-DAG:        dsubu $2, $6, $[[T2]]
249
250 ; 64R6-DAG:      sll $[[T0:[0-9]+]], $4, 0
251 ; 64R6-DAG:      sll $[[T1:[0-9]+]], $5, 0
252 ; 64R6-DAG:      dmul $[[T2:[0-9]+]], $[[T1]], $[[T0]]
253 ; 64R6-DAG:      dsubu $2, $6, $[[T2]]
254
255 define i64 @msub3(i32 %a, i32 %b, i64 %c) nounwind readnone {
256 entry:
257   %conv = sext i32 %a to i64
258   %conv3 = sext i32 %b to i64
259   %mul = mul nsw i64 %conv3, %conv
260   %sub = sub nsw i64 %c, %mul
261   ret i64 %sub
262 }