1; RUN: llc < %s -march=mips -mcpu=mips2 | FileCheck %s \
2; RUN:    -check-prefixes=ALL,NOT-R2-R6,GP32
3; RUN: llc < %s -march=mips -mcpu=mips32 | FileCheck %s \
4; RUN:    -check-prefixes=ALL,NOT-R2-R6,GP32
5; RUN: llc < %s -march=mips -mcpu=mips32r2 | FileCheck %s \
6; RUN:    -check-prefixes=ALL,R2-R6,GP32
7; RUN: llc < %s -march=mips -mcpu=mips32r3 | FileCheck %s \
8; RUN:    -check-prefixes=ALL,R2-R6,GP32
9; RUN: llc < %s -march=mips -mcpu=mips32r5 | FileCheck %s \
10; RUN:    -check-prefixes=ALL,R2-R6,GP32
11; RUN: llc < %s -march=mips -mcpu=mips32r6 | FileCheck %s \
12; RUN:    -check-prefixes=ALL,R2-R6,GP32
13; RUN: llc < %s -march=mips64 -mcpu=mips3 | FileCheck %s \
14; RUN:    -check-prefixes=ALL,NOT-R2-R6,GP64
15; RUN: llc < %s -march=mips64 -mcpu=mips4 | FileCheck %s \
16; RUN:    -check-prefixes=ALL,NOT-R2-R6,GP64
17; RUN: llc < %s -march=mips64 -mcpu=mips64 | FileCheck %s \
18; RUN:    -check-prefixes=ALL,NOT-R2-R6,GP64
19; RUN: llc < %s -march=mips64 -mcpu=mips64r2 | FileCheck %s \
20; RUN:    -check-prefixes=ALL,R2-R6,GP64
21; RUN: llc < %s -march=mips64 -mcpu=mips64r3 | FileCheck %s \
22; RUN:    -check-prefixes=ALL,R2-R6,GP64
23; RUN: llc < %s -march=mips64 -mcpu=mips64r5 | FileCheck %s \
24; RUN:    -check-prefixes=ALL,R2-R6,GP64
25; RUN: llc < %s -march=mips64 -mcpu=mips64r6 | FileCheck %s \
26; RUN:    -check-prefixes=ALL,R2-R6,GP64
27; RUN: llc < %s -march=mips -mcpu=mips32r3 -mattr=+micromips -O2 | FileCheck %s \
28; RUN:    -check-prefixes=ALL,MMR6,MM32
29; RUN: llc < %s -march=mips -mcpu=mips32r6 -mattr=+micromips -O2 | FileCheck %s \
30; RUN:    -check-prefixes=ALL,MMR6,MM32
31; RUN: llc < %s -march=mips -mcpu=mips64r6 -target-abi n64 -mattr=+micromips -O2 | FileCheck %s \
32; RUN:    -check-prefixes=ALL,MMR6,MM64
33
34
35; FIXME: This code sequence is inefficient as it should be 'subu $[[T0]], $zero, $[[T0]'.
36; This sequence is even better as it's a single instruction. See D25485 for the rest of
37; the cases where this sequence occurs.
38
39define signext i1 @add_i1(i1 signext %a, i1 signext %b) {
40entry:
41; ALL-LABEL: add_i1:
42
43  ; NOT-R2-R6:  addu   $[[T0:[0-9]+]], $4, $5
44  ; NOT-R2-R6:  andi   $[[T0]], $[[T0]], 1
45  ; NOT-R2-R6:  negu   $2, $[[T0]]
46
47  ; R2-R6:      addu   $[[T0:[0-9]+]], $4, $5
48  ; R2-R6:      andi   $[[T0]], $[[T0]], 1
49  ; R2-R6:      negu   $2, $[[T0]]
50
51  ; MMR6:       addu16  $[[T0:[0-9]+]], $4, $5
52  ; MMR6:       andi16  $[[T0]], $[[T0]], 1
53  ; MMR6:       li16    $[[T1:[0-9]+]], 0
54  ; MMR6:       subu16  $[[T0]], $[[T1]], $[[T0]]
55
56  %r = add i1 %a, %b
57  ret i1 %r
58}
59
60define signext i8 @add_i8(i8 signext %a, i8 signext %b) {
61entry:
62; ALL-LABEL: add_i8:
63
64  ; NOT-R2-R6:  addu    $[[T0:[0-9]+]], $4, $5
65  ; NOT-R2-R6:  sll     $[[T0]], $[[T0]], 24
66  ; NOT-R2-R6:  sra     $2, $[[T0]], 24
67
68  ; R2-R6:      addu    $[[T0:[0-9]+]], $4, $5
69  ; R2-R6:      seb     $2, $[[T0:[0-9]+]]
70
71  ; MMR6:       addu16  $[[T0:[0-9]+]], $4, $5
72  ; MMR6:       seb     $2, $[[T0]]
73
74  %r = add i8 %a, %b
75  ret i8 %r
76}
77
78define signext i16 @add_i16(i16 signext %a, i16 signext %b) {
79entry:
80; ALL-LABEL: add_i16:
81
82  ; NOT-R2-R6:  addu    $[[T0:[0-9]+]], $4, $5
83  ; NOT-R2-R6:  sll     $[[T0]], $[[T0]], 16
84  ; NOT-R2-R6:  sra     $2, $[[T0]], 16
85
86  ; R2-R6:      addu    $[[T0:[0-9]+]], $4, $5
87  ; R2-R6:      seh     $2, $[[T0]]
88
89  ; MMR6:       addu16  $[[T0:[0-9]+]], $4, $5
90  ; MMR6:       seh     $2, $[[T0]]
91
92  %r = add i16 %a, %b
93  ret i16 %r
94}
95
96define signext i32 @add_i32(i32 signext %a, i32 signext %b) {
97entry:
98; ALL-LABEL: add_i32:
99
100  ; NOT-R2-R6:  addu    $2, $4, $5
101  ; R2-R6:      addu    $2, $4, $5
102
103  ; MMR6:       addu16  $[[T0:[0-9]+]], $4, $5
104
105  %r = add i32 %a, %b
106  ret i32 %r
107}
108
109define signext i64 @add_i64(i64 signext %a, i64 signext %b) {
110entry:
111; ALL-LABEL: add_i64:
112
113  ; GP32:       addu    $3, $5, $7
114  ; GP32:       sltu    $[[T0:[0-9]+]], $3, $7
115  ; GP32:       addu    $[[T1:[0-9]+]], $[[T0]], $6
116  ; GP32:       addu    $2, $4, $[[T1]]
117
118  ; GP64:       daddu   $2, $4, $5
119
120  ; MM32:       addu    $3, $5, $7
121  ; MM32:       sltu    $[[T0:[0-9]+]], $3, $7
122  ; MM32:       addu    $[[T1:[0-9]+]], $[[T0]], $6
123  ; MM32:       addu    $2, $4, $[[T1]]
124
125  ; MM64:       daddu   $2, $4, $5
126
127  %r = add i64 %a, %b
128  ret i64 %r
129}
130
131define signext i128 @add_i128(i128 signext %a, i128 signext %b) {
132entry:
133; ALL-LABEL: add_i128:
134
135  ; GP32:       lw        $[[T0:[0-9]+]], 28($sp)
136  ; GP32:       addu      $[[T1:[0-9]+]], $7, $[[T0]]
137  ; GP32:       sltu      $[[T2:[0-9]+]], $[[T1]], $[[T0]]
138  ; GP32:       lw        $[[T3:[0-9]+]], 24($sp)
139  ; GP32:       addu      $[[T4:[0-9]+]], $[[T2]], $[[T3]]
140  ; GP32:       addu      $[[T5:[0-9]+]], $6, $[[T4]]
141  ; GP32:       sltu      $[[T6:[0-9]+]], $[[T5]], $[[T3]]
142  ; GP32:       lw        $[[T7:[0-9]+]], 20($sp)
143  ; GP32:       addu      $[[T8:[0-9]+]], $[[T6]], $[[T7]]
144  ; GP32:       lw        $[[T9:[0-9]+]], 16($sp)
145  ; GP32:       addu      $3, $5, $[[T8]]
146  ; GP32:       sltu      $[[T10:[0-9]+]], $3, $[[T7]]
147  ; GP32:       addu      $[[T11:[0-9]+]], $[[T10]], $[[T9]]
148  ; GP32:       addu      $2, $4, $[[T11]]
149  ; GP32:       move      $4, $[[T5]]
150  ; GP32:       move      $5, $[[T1]]
151
152  ; GP64:       daddu     $3, $5, $7
153  ; GP64:       sltu      $[[T0:[0-9]+]], $3, $7
154  ; GP64:       daddu     $[[T1:[0-9]+]], $[[T0]], $6
155  ; GP64:       daddu     $2, $4, $[[T1]]
156
157  ; MM32:       lw        $[[T0:[0-9]+]], 28($sp)
158  ; MM32:       addu      $[[T1:[0-9]+]], $7, $[[T0]]
159  ; MM32:       sltu      $[[T2:[0-9]+]], $[[T1]], $[[T0]]
160  ; MM32:       lw        $[[T3:[0-9]+]], 24($sp)
161  ; MM32:       addu      $[[T4:[0-9]+]], $[[T2]], $[[T3]]
162  ; MM32:       addu      $[[T5:[0-9]+]], $6, $[[T4]]
163  ; MM32:       sltu      $[[T6:[0-9]+]], $[[T5]], $[[T3]]
164  ; MM32:       lw        $[[T7:[0-9]+]], 20($sp)
165  ; MM32:       addu      $[[T8:[0-9]+]], $[[T6]], $[[T7]]
166  ; MM32:       lw        $[[T9:[0-9]+]], 16($sp)
167  ; MM32:       addu      $[[T10:[0-9]+]], $5, $[[T8]]
168  ; MM32:       sltu      $[[T11:[0-9]+]], $[[T10]], $[[T7]]
169  ; MM32:       addu      $[[T12:[0-9]+]], $[[T11]], $[[T9]]
170  ; MM32:       addu      $[[T13:[0-9]+]], $4, $[[T12]]
171  ; MM32:       move      $4, $[[T5]]
172  ; MM32:       move      $5, $[[T1]]
173
174  ; MM64:       daddu     $3, $5, $7
175  ; MM64:       sltu      $[[T0:[0-9]+]], $3, $7
176  ; MM64:       daddu     $[[T1:[0-9]+]], $[[T0]], $6
177  ; MM64:       daddu     $2, $4, $[[T1]]
178
179  %r = add i128 %a, %b
180  ret i128 %r
181}
182
183define signext i1 @add_i1_4(i1 signext %a) {
184; ALL-LABEL: add_i1_4:
185
186  ; ALL:        move      $2, $4
187
188  %r = add i1 4, %a
189  ret i1 %r
190}
191
192define signext i8 @add_i8_4(i8 signext %a) {
193; ALL-LABEL: add_i8_4:
194
195  ; NOT-R2-R6:  sll     $[[T0:[0-9]+]], $4, 24
196  ; NOT-R2-R6:  lui     $[[T1:[0-9]+]], 1024
197  ; NOT-R2-R6:  addu    $[[T0]], $[[T0]], $[[T1]]
198  ; NOT-R2-R6:  sra     $2, $[[T0]], 24
199
200  ; R2-R6:      addiu   $[[T0:[0-9]+]], $4, 4
201  ; R2-R6:      seb     $2, $[[T0]]
202
203  ; MM32:       addiur2 $[[T0:[0-9]+]], $4, 4
204  ; MM32:       seb     $2, $[[T0]]
205
206  ; MM64:       addiur2 $[[T0:[0-9]+]], $4, 4
207  ; MM64:       seb     $2, $[[T0]]
208
209  %r = add i8 4, %a
210  ret i8 %r
211}
212
213define signext i16 @add_i16_4(i16 signext %a) {
214; ALL-LABEL: add_i16_4:
215
216  ; NOT-R2-R6:  sll     $[[T0:[0-9]+]], $4, 16
217  ; NOT-R2-R6:  lui     $[[T1:[0-9]+]], 4
218  ; NOT-R2-R6:  addu    $[[T0]], $[[T0]], $[[T1]]
219  ; NOT-R2-R6:  sra     $2, $[[T0]], 16
220
221  ; R2-R6:      addiu   $[[T0:[0-9]+]], $4, 4
222  ; R2-R6:      seh     $2, $[[T0]]
223
224  ; MM32:       addiur2 $[[T0:[0-9]+]], $4, 4
225  ; MM32:       seh     $2, $[[T0]]
226
227  ; MM64:       addiur2 $[[T0:[0-9]+]], $4, 4
228  ; MM64:       seh     $2, $[[T0]]
229
230  %r = add i16 4, %a
231  ret i16 %r
232}
233
234define signext i32 @add_i32_4(i32 signext %a) {
235; ALL-LABEL: add_i32_4:
236
237  ; GP32:       addiu   $2, $4, 4
238
239  ; GP64:       addiu   $2, $4, 4
240
241  ; MM32:       addiur2 $2, $4, 4
242
243  ; MM64:       addiur2 $2, $4, 4
244
245  %r = add i32 4, %a
246  ret i32 %r
247}
248
249define signext i64 @add_i64_4(i64 signext %a) {
250; ALL-LABEL: add_i64_4:
251
252  ; GP32:       addiu   $[[T0:[0-9]+]], $5, 4
253  ; GP32:       addiu   $[[T1:[0-9]+]], $zero, 4
254  ; GP32:       sltu    $[[T1]], $[[T0]], $[[T1]]
255  ; GP32:       addu    $2, $4, $[[T1]]
256
257  ; GP64:       daddiu  $2, $4, 4
258
259  ; MM32:       addiu   $[[T0:[0-9]+]], $5, 4
260  ; MM32:       li16    $[[T1:[0-9]+]], 4
261  ; MM32:       sltu    $[[T2:[0-9]+]], $[[T0]], $[[T1]]
262  ; MM32:       addu    $2, $4, $[[T2]]
263
264  ; MM64:       daddiu  $2, $4, 4
265
266  %r = add i64 4, %a
267  ret i64 %r
268}
269
270define signext i128 @add_i128_4(i128 signext %a) {
271; ALL-LABEL: add_i128_4:
272
273  ; GP32:       addiu   $[[T0:[0-9]+]], $7, 4
274  ; GP32:       addiu   $[[T1:[0-9]+]], $zero, 4
275  ; GP32:       sltu    $[[T1]], $[[T0]], $[[T1]]
276  ; GP32:       addu    $[[T2:[0-9]+]], $6, $[[T1]]
277  ; GP32:       sltu    $[[T1]], $[[T2]], $zero
278  ; GP32:       addu    $[[T3:[0-9]+]], $5, $[[T1]]
279  ; GP32:       sltu    $[[T1]], $[[T3]], $zero
280  ; GP32:       addu    $[[T1]], $4, $[[T1]]
281  ; GP32:       move    $4, $[[T2]]
282  ; GP32:       move    $5, $[[T0]]
283
284  ; GP64:       daddiu  $[[T0:[0-9]+]], $5, 4
285  ; GP64:       daddiu  $[[T1:[0-9]+]], $zero, 4
286  ; GP64:       sltu    $[[T1]], $[[T0]], $[[T1]]
287  ; GP64:       daddu   $2, $4, $[[T1]]
288
289  ; MM32:       addiu   $[[T0:[0-9]+]], $7, 4
290  ; MM32:       li16    $[[T1:[0-9]+]], 4
291  ; MM32:       sltu    $[[T1]], $[[T0]], $[[T1]]
292  ; MM32:       addu    $[[T2:[0-9]+]], $6, $[[T1]]
293  ; MM32:       li16    $[[T1]], 0
294  ; MM32:       sltu    $[[T3:[0-9]+]], $[[T2]], $[[T1]]
295  ; MM32:       addu    $[[T3]], $5, $[[T3]]
296  ; MM32:       sltu    $[[T1]], $[[T3]], $[[T1]]
297  ; MM32:       addu    $[[T1]], $4, $[[T1]]
298  ; MM32:       move    $4, $[[T2]]
299  ; MM32:       move    $5, $[[T0]]
300
301  ; MM64:       daddiu  $[[T0:[0-9]+]], $5, 4
302  ; MM64:       daddiu  $[[T1:[0-9]+]], $zero, 4
303  ; MM64:       sltu    $[[T1]], $[[T0]], $[[T1]]
304  ; MM64:       daddu   $2, $4, $[[T1]]
305
306  %r = add i128 4, %a
307  ret i128 %r
308}
309
310define signext i1 @add_i1_3(i1 signext %a) {
311; ALL-LABEL: add_i1_3:
312  ; GP32:        addiu  $[[T0:[0-9]+]], $4, 1
313  ; GP32:        andi   $[[T0]], $[[T0]], 1
314  ; GP32:        negu   $2, $[[T0]]
315
316  ; GP64:        addiu  $[[T0:[0-9]+]], $4, 1
317  ; GP64:        andi   $[[T0]], $[[T0]], 1
318  ; GP64:        negu   $2, $[[T0]]
319
320  ; MMR6:        addiur2 $[[T0:[0-9]+]], $4, 1
321  ; MMR6:        andi16  $[[T0]], $[[T0]], 1
322  ; MMR6:        li16    $[[T1:[0-9]+]], 0
323  ; MMR6:        subu16  $2, $[[T1]], $[[T0]]
324
325  %r = add i1 3, %a
326  ret i1 %r
327}
328
329define signext i8 @add_i8_3(i8 signext %a) {
330; ALL-LABEL: add_i8_3:
331
332  ; NOT-R2-R6:  sll     $[[T0:[0-9]+]], $4, 24
333  ; NOT-R2-R6:  lui     $[[T1:[0-9]+]], 768
334  ; NOT-R2-R6:  addu    $[[T0]], $[[T0]], $[[T1]]
335  ; NOT-R2-R6:  sra     $2, $[[T0]], 24
336
337  ; R2-R6:      addiu   $[[T0:[0-9]+]], $4, 3
338  ; R2-R6:      seb     $2, $[[T0]]
339
340  ; MMR6:       addius5 $[[T0:[0-9]+]], 3
341  ; MMR6:       seb     $2, $[[T0]]
342
343  %r = add i8 3, %a
344  ret i8 %r
345}
346
347define signext i16 @add_i16_3(i16 signext %a) {
348; ALL-LABEL: add_i16_3:
349
350  ; NOT-R2-R6:  sll     $[[T0:[0-9]+]], $4, 16
351  ; NOT-R2-R6:  lui     $[[T1:[0-9]+]], 3
352  ; NOT-R2-R6:  addu    $[[T0]], $[[T0]], $[[T1]]
353  ; NOT-R2-R6:  sra     $2, $[[T0]], 16
354
355  ; R2-R6:      addiu   $[[T0:[0-9]+]], $4, 3
356  ; R2-R6:      seh     $2, $[[T0]]
357
358  ; MMR6:       addius5 $[[T0:[0-9]+]], 3
359  ; MMR6:       seh     $2, $[[T0]]
360
361  %r = add i16 3, %a
362  ret i16 %r
363}
364
365define signext i32 @add_i32_3(i32 signext %a) {
366; ALL-LABEL: add_i32_3:
367
368  ; NOT-R2-R6:  addiu   $2, $4, 3
369
370  ; R2-R6:      addiu   $2, $4, 3
371
372  ; MMR6:       addius5 $[[T0:[0-9]+]], 3
373  ; MMR6:       move    $2, $[[T0]]
374
375  %r = add i32 3, %a
376  ret i32 %r
377}
378
379define signext i64 @add_i64_3(i64 signext %a) {
380; ALL-LABEL: add_i64_3:
381
382  ; GP32:       addiu   $[[T0:[0-9]+]], $5, 3
383  ; GP32:       addiu   $[[T1:[0-9]+]], $zero, 3
384  ; GP32:       sltu    $[[T1]], $[[T0]], $[[T1]]
385  ; GP32:       addu    $2, $4, $[[T1]]
386
387  ; GP64:       daddiu  $2, $4, 3
388
389  ; MM32:       addiu   $[[T0:[0-9]+]], $5, 3
390  ; MM32:       li16    $[[T1:[0-9]+]], 3
391  ; MM32:       sltu    $[[T2:[0-9]+]], $[[T0]], $[[T1]]
392  ; MM32:       addu    $2, $4, $[[T2]]
393
394  ; MM64:       daddiu  $2, $4, 3
395
396  %r = add i64 3, %a
397  ret i64 %r
398}
399
400define signext i128 @add_i128_3(i128 signext %a) {
401; ALL-LABEL: add_i128_3:
402
403  ; GP32:       addiu   $[[T0:[0-9]+]], $7, 3
404  ; GP32:       addiu   $[[T1:[0-9]+]], $zero, 3
405  ; GP32:       sltu    $[[T1]], $[[T0]], $[[T1]]
406  ; GP32:       addu    $[[T2:[0-9]+]], $6, $[[T1]]
407  ; GP32:       sltu    $[[T3:[0-9]+]], $[[T2]], $zero
408  ; GP32:       addu    $[[T4:[0-9]+]], $5, $[[T3]]
409  ; GP32:       sltu    $[[T5:[0-9]+]], $[[T4]], $zero
410  ; GP32:       addu    $[[T5]], $4, $[[T5]]
411  ; GP32:       move    $4, $[[T2]]
412  ; GP32:       move    $5, $[[T0]]
413
414  ; GP64:       daddiu  $[[T0:[0-9]+]], $5, 3
415  ; GP64:       daddiu  $[[T1:[0-9]+]], $zero, 3
416  ; GP64:       sltu    $[[T1]], $[[T0]], $[[T1]]
417  ; GP64:       daddu   $2, $4, $[[T1]]
418
419  ; MM32:       addiu   $[[T0:[0-9]+]], $7, 3
420  ; MM32:       li16    $[[T1:[0-9]+]], 3
421  ; MM32:       sltu    $[[T1]], $[[T0]], $[[T1]]
422  ; MM32:       addu    $[[T2:[0-9]+]], $6, $[[T1]]
423  ; MM32:       li16    $[[T3:[0-9]+]], 0
424  ; MM32:       sltu    $[[T4:[0-9]+]], $[[T2]], $[[T3]]
425  ; MM32:       addu    $[[T4]], $5, $[[T4]]
426  ; MM32:       sltu    $[[T5:[0-9]+]], $[[T4]], $[[T3]]
427  ; MM32:       addu    $[[T5]], $4, $[[T5]]
428  ; MM32:       move    $4, $[[T2]]
429  ; MM32:       move    $5, $[[T0]]
430
431  ; MM64:       daddiu  $[[T0:[0-9]+]], $5, 3
432  ; MM64:       daddiu  $[[T1:[0-9]+]], $zero, 3
433  ; MM64:       sltu    $[[T1]], $[[T0]], $[[T1]]
434  ; MM64:       daddu   $2, $4, $[[T1]]
435
436  %r = add i128 3, %a
437  ret i128 %r
438}
439