[mips] Add CCValAssign::[ASZ]ExtUpper and CCPromoteToUpperBitsInType and handle struc...
[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 -mcpu=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:        dsll $[[T0:[0-9]+]], $4, 32
80 ; 64-DAG:        dsrl $[[T1:[0-9]+]], $[[T0]], 32
81 ; 64-DAG:        dsll $[[T2:[0-9]+]], $5, 32
82 ; 64-DAG:        dsrl $[[T3:[0-9]+]], $[[T2]], 32
83 ; 64-DAG:        d[[m:m]]ult $[[T3]], $[[T1]]
84 ; 64-DAG:        [[m]]flo $[[T4:[0-9]+]]
85 ; 64-DAG:        dsll $[[T5:[0-9]+]], $6, 32
86 ; 64-DAG:        dsrl $[[T6:[0-9]+]], $[[T5]], 32
87 ; 64-DAG:        daddu $2, $[[T4]], $[[T6]]
88
89 ; 64R6-DAG:      dsll $[[T0:[0-9]+]], $4, 32
90 ; 64R6-DAG:      dsrl $[[T1:[0-9]+]], $[[T0]], 32
91 ; 64R6-DAG:      dsll $[[T2:[0-9]+]], $5, 32
92 ; 64R6-DAG:      dsrl $[[T3:[0-9]+]], $[[T2]], 32
93 ; 64R6-DAG:      dmul $[[T4:[0-9]+]], $[[T3]], $[[T1]]
94 ; 64R6-DAG:      dsll $[[T5:[0-9]+]], $6, 32
95 ; 64R6-DAG:      dsrl $[[T6:[0-9]+]], $[[T5]], 32
96 ; 64R6-DAG:      daddu $2, $[[T4]], $[[T6]]
97
98 define i64 @madd2(i32 %a, i32 %b, i32 %c) nounwind readnone {
99 entry:
100   %conv = zext i32 %a to i64
101   %conv2 = zext i32 %b to i64
102   %mul = mul nsw i64 %conv2, %conv
103   %conv4 = zext i32 %c to i64
104   %add = add nsw i64 %mul, %conv4
105   ret i64 %add
106 }
107
108 ; ALL-LABEL: madd3:
109
110 ; 32-DAG:        mthi $6
111 ; 32-DAG:        mtlo $7
112 ; 32-DAG:        [[m:m]]add ${{[45]}}, ${{[45]}}
113 ; 32-DAG:        [[m]]fhi $2
114 ; 32-DAG:        [[m]]flo $3
115
116 ; DSP-DAG:       mthi $[[AC:ac[0-3]+]], $6
117 ; DSP-DAG:       mtlo $[[AC]], $7
118 ; DSP-DAG:       madd $[[AC]], ${{[45]}}, ${{[45]}}
119 ; DSP-DAG:       mfhi $2, $[[AC]]
120 ; DSP-DAG:       mflo $3, $[[AC]]
121
122 ; 32R6-DAG:      mul  $[[T0:[0-9]+]], ${{[45]}}, ${{[45]}}
123 ; 32R6-DAG:      addu $[[T1:[0-9]+]], $[[T0]], $7
124 ; 32R6-DAG:      sltu $[[T2:[0-9]+]], $[[T1]], $7
125 ; 32R6-DAG:      addu $[[T4:[0-9]+]], $[[T2]], $6
126 ; 32R6-DAG:      muh  $[[T5:[0-9]+]], ${{[45]}}, ${{[45]}}
127 ; 32R6-DAG:      addu $2, $[[T5]], $[[T4]]
128
129 ; 64-DAG:        sll $[[T0:[0-9]+]], $4, 0
130 ; 64-DAG:        sll $[[T1:[0-9]+]], $5, 0
131 ; 64-DAG:        d[[m:m]]ult $[[T1]], $[[T0]]
132 ; 64-DAG:        [[m]]flo $[[T2:[0-9]+]]
133 ; 64-DAG:        daddu $2, $[[T2]], $6
134
135 ; 64R6-DAG:      sll $[[T0:[0-9]+]], $4, 0
136 ; 64R6-DAG:      sll $[[T1:[0-9]+]], $5, 0
137 ; 64R6-DAG:      dmul $[[T2:[0-9]+]], $[[T1]], $[[T0]]
138 ; 64R6-DAG:      daddu $2, $[[T2]], $6
139
140 define i64 @madd3(i32 %a, i32 %b, i64 %c) nounwind readnone {
141 entry:
142   %conv = sext i32 %a to i64
143   %conv2 = sext i32 %b to i64
144   %mul = mul nsw i64 %conv2, %conv
145   %add = add nsw i64 %mul, %c
146   ret i64 %add
147 }
148
149 ; ALL-LABEL: msub1:
150
151 ; 32-DAG:        sra $[[T0:[0-9]+]], $6, 31
152 ; 32-DAG:        mtlo $6
153 ; 32-DAG:        [[m:m]]sub ${{[45]}}, ${{[45]}}
154 ; 32-DAG:        [[m]]fhi $2
155 ; 32-DAG:        [[m]]flo $3
156
157 ; DSP-DAG:       sra $[[T0:[0-9]+]], $6, 31
158 ; DSP-DAG:       mtlo $[[AC:ac[0-3]+]], $6
159 ; DSP-DAG:       msub $[[AC]], ${{[45]}}, ${{[45]}}
160 ; DSP-DAG:       mfhi $2, $[[AC]]
161 ; DSP-DAG:       mflo $3, $[[AC]]
162
163 ; 32R6-DAG:      muh  $[[T0:[0-9]+]], ${{[45]}}, ${{[45]}}
164 ; 32R6-DAG:      mul  $[[T1:[0-9]+]], ${{[45]}}, ${{[45]}}
165 ; 32R6-DAG:      sltu $[[T3:[0-9]+]], $6, $[[T1]]
166 ; 32R6-DAG:      addu $[[T4:[0-9]+]], $[[T3]], $[[T0]]
167 ; 32R6-DAG:      sra  $[[T5:[0-9]+]], $6, 31
168 ; 32R6-DAG:      subu $2, $[[T5]], $[[T4]]
169 ; 32R6-DAG:      subu $3, $6, $[[T1]]
170
171 ; 64-DAG:        sll $[[T0:[0-9]+]], $4, 0
172 ; 64-DAG:        sll $[[T1:[0-9]+]], $5, 0
173 ; 64-DAG:        d[[m:m]]ult $[[T1]], $[[T0]]
174 ; 64-DAG:        [[m]]flo $[[T2:[0-9]+]]
175 ; 64-DAG:        sll $[[T3:[0-9]+]], $6, 0
176 ; 64-DAG:        dsubu $2, $[[T3]], $[[T2]]
177
178 ; 64R6-DAG:      sll $[[T0:[0-9]+]], $4, 0
179 ; 64R6-DAG:      sll $[[T1:[0-9]+]], $5, 0
180 ; 64R6-DAG:      dmul $[[T2:[0-9]+]], $[[T1]], $[[T0]]
181 ; 64R6-DAG:      sll $[[T3:[0-9]+]], $6, 0
182 ; 64R6-DAG:      dsubu $2, $[[T3]], $[[T2]]
183
184 define i64 @msub1(i32 %a, i32 %b, i32 %c) nounwind readnone {
185 entry:
186   %conv = sext i32 %c to i64
187   %conv2 = sext i32 %a to i64
188   %conv4 = sext i32 %b to i64
189   %mul = mul nsw i64 %conv4, %conv2
190   %sub = sub nsw i64 %conv, %mul
191   ret i64 %sub
192 }
193
194 ; ALL-LABEL: msub2:
195
196 ; FIXME: We don't really need this instruction
197 ; 32-DAG:        addiu $[[T0:[0-9]+]], $zero, 0
198 ; 32-DAG:        mtlo $6
199 ; 32-DAG:        [[m:m]]subu ${{[45]}}, ${{[45]}}
200 ; 32-DAG:        [[m]]fhi $2
201 ; 32-DAG:        [[m]]flo $3
202
203 ; DSP-DAG:       addiu $[[T0:[0-9]+]], $zero, 0
204 ; DSP-DAG:       mtlo $[[AC:ac[0-3]+]], $6
205 ; DSP-DAG:       msubu $[[AC]], ${{[45]}}, ${{[45]}}
206 ; DSP-DAG:       mfhi $2, $[[AC]]
207 ; DSP-DAG:       mflo $3, $[[AC]]
208
209 ; 32R6-DAG:      muhu $[[T0:[0-9]+]], ${{[45]}}, ${{[45]}}
210 ; 32R6-DAG:      mul $[[T1:[0-9]+]], ${{[45]}}, ${{[45]}}
211
212 ; 32R6-DAG:      sltu $[[T2:[0-9]+]], $6, $[[T1]]
213 ; 32R6-DAG:      addu $[[T3:[0-9]+]], $[[T2]], $[[T0]]
214 ; 32R6-DAG:      negu $2, $[[T3]]
215 ; 32R6-DAG:      subu $3, $6, $[[T1]]
216
217 ; 64-DAG:        dsll $[[T0:[0-9]+]], $4, 32
218 ; 64-DAG:        dsrl $[[T1:[0-9]+]], $[[T0]], 32
219 ; 64-DAG:        dsll $[[T2:[0-9]+]], $5, 32
220 ; 64-DAG:        dsrl $[[T3:[0-9]+]], $[[T2]], 32
221 ; 64-DAG:        d[[m:m]]ult $[[T3]], $[[T1]]
222 ; 64-DAG:        [[m]]flo $[[T4:[0-9]+]]
223 ; 64-DAG:        dsll $[[T5:[0-9]+]], $6, 32
224 ; 64-DAG:        dsrl $[[T6:[0-9]+]], $[[T5]], 32
225 ; 64-DAG:        dsubu $2, $[[T6]], $[[T4]]
226
227 ; 64R6-DAG:      dsll $[[T0:[0-9]+]], $4, 32
228 ; 64R6-DAG:      dsrl $[[T1:[0-9]+]], $[[T0]], 32
229 ; 64R6-DAG:      dsll $[[T2:[0-9]+]], $5, 32
230 ; 64R6-DAG:      dsrl $[[T3:[0-9]+]], $[[T2]], 32
231 ; 64R6-DAG:      dmul $[[T4:[0-9]+]], $[[T3]], $[[T1]]
232 ; 64R6-DAG:      dsll $[[T5:[0-9]+]], $6, 32
233 ; 64R6-DAG:      dsrl $[[T6:[0-9]+]], $[[T5]], 32
234 ; 64R6-DAG:      dsubu $2, $[[T6]], $[[T4]]
235
236 define i64 @msub2(i32 %a, i32 %b, i32 %c) nounwind readnone {
237 entry:
238   %conv = zext i32 %c to i64
239   %conv2 = zext i32 %a to i64
240   %conv4 = zext i32 %b to i64
241   %mul = mul nsw i64 %conv4, %conv2
242   %sub = sub nsw i64 %conv, %mul
243   ret i64 %sub
244 }
245
246 ; ALL-LABEL: msub3:
247
248 ; FIXME: We don't really need this instruction
249 ; 32-DAG:        mthi $6
250 ; 32-DAG:        mtlo $7
251 ; 32-DAG:        [[m:m]]sub ${{[45]}}, ${{[45]}}
252 ; 32-DAG:        [[m]]fhi $2
253 ; 32-DAG:        [[m]]flo $3
254
255 ; DSP-DAG:       addiu $[[T0:[0-9]+]], $zero, 0
256 ; DSP-DAG:       mtlo $[[AC:ac[0-3]+]], $6
257 ; DSP-DAG:       msub $[[AC]], ${{[45]}}, ${{[45]}}
258 ; DSP-DAG:       mfhi $2, $[[AC]]
259 ; DSP-DAG:       mflo $3, $[[AC]]
260
261 ; 32R6-DAG:      muh $[[T0:[0-9]+]], ${{[45]}}, ${{[45]}}
262 ; 32R6-DAG:      mul $[[T1:[0-9]+]], ${{[45]}}, ${{[45]}}
263 ; 32R6-DAG:      sltu $[[T2:[0-9]+]], $7, $[[T1]]
264 ; 32R6-DAG:      addu $[[T3:[0-9]+]], $[[T2]], $[[T0]]
265 ; 32R6-DAG:      subu $2, $6, $[[T3]]
266 ; 32R6-DAG:      subu $3, $7, $[[T1]]
267
268 ; 64-DAG:        sll $[[T0:[0-9]+]], $4, 0
269 ; 64-DAG:        sll $[[T1:[0-9]+]], $5, 0
270 ; 64-DAG:        d[[m:m]]ult $[[T1]], $[[T0]]
271 ; 64-DAG:        [[m]]flo $[[T2:[0-9]+]]
272 ; 64-DAG:        dsubu $2, $6, $[[T2]]
273
274 ; 64R6-DAG:      sll $[[T0:[0-9]+]], $4, 0
275 ; 64R6-DAG:      sll $[[T1:[0-9]+]], $5, 0
276 ; 64R6-DAG:      dmul $[[T2:[0-9]+]], $[[T1]], $[[T0]]
277 ; 64R6-DAG:      dsubu $2, $6, $[[T2]]
278
279 define i64 @msub3(i32 %a, i32 %b, i64 %c) nounwind readnone {
280 entry:
281   %conv = sext i32 %a to i64
282   %conv3 = sext i32 %b to i64
283   %mul = mul nsw i64 %conv3, %conv
284   %sub = sub nsw i64 %c, %mul
285   ret i64 %sub
286 }