1; RUN: llc -march=mips   -mcpu=mips32   -verify-machineinstrs    -relocation-model=pic < %s | FileCheck %s -check-prefixes=ALL,ACC32,ACC32-TRAP
2; RUN: llc -march=mips   -mcpu=mips32r2 -verify-machineinstrs    -relocation-model=pic < %s | FileCheck %s -check-prefixes=ALL,ACC32,ACC32-TRAP
3; RUN: llc -march=mips   -mcpu=mips32r6 -verify-machineinstrs    -relocation-model=pic < %s | FileCheck %s -check-prefixes=ALL,GPR32,GPR32-TRAP
4; RUN: llc -march=mips64 -mcpu=mips64   -verify-machineinstrs    -relocation-model=pic < %s | FileCheck %s -check-prefixes=ALL,ACC64,ACC64-TRAP
5; RUN: llc -march=mips64 -mcpu=mips64r2 -verify-machineinstrs    -relocation-model=pic < %s | FileCheck %s -check-prefixes=ALL,ACC64,ACC64-TRAP
6; RUN: llc -march=mips64 -mcpu=mips64r6 -verify-machineinstrs    -relocation-model=pic < %s | FileCheck %s -check-prefixes=ALL,GPR64,GPR64-TRAP
7
8; RUN: llc -march=mips   -mcpu=mips32   -mno-check-zero-division -relocation-model=pic < %s | FileCheck %s -check-prefixes=ALL,ACC32,NOCHECK
9; RUN: llc -march=mips   -mcpu=mips32r2 -mno-check-zero-division -relocation-model=pic < %s | FileCheck %s -check-prefixes=ALL,ACC32,NOCHECK
10; RUN: llc -march=mips   -mcpu=mips32r6 -mno-check-zero-division -relocation-model=pic < %s | FileCheck %s -check-prefixes=ALL,GPR32,NOCHECK
11; RUN: llc -march=mips64 -mcpu=mips64   -mno-check-zero-division -relocation-model=pic < %s | FileCheck %s -check-prefixes=ALL,ACC64,NOCHECK
12; RUN: llc -march=mips64 -mcpu=mips64r2 -mno-check-zero-division -relocation-model=pic < %s | FileCheck %s -check-prefixes=ALL,ACC64,NOCHECK
13; RUN: llc -march=mips64 -mcpu=mips64r6 -mno-check-zero-division -relocation-model=pic < %s | FileCheck %s -check-prefixes=ALL,GPR64,NOCHECK
14
15; FileCheck Prefixes:
16;   ALL - All targets
17;   ACC32 - Accumulator based multiply/divide on 32-bit targets
18;   ACC64 - Same as ACC32 but only for 64-bit targets
19;   GPR32 - GPR based multiply/divide on 32-bit targets
20;   GPR64 - Same as GPR32 but only for 64-bit targets
21;   ACC32-TRAP - Same as TRAP and ACC32 combined
22;   ACC64-TRAP - Same as TRAP and ACC64 combined
23;   GPR32-TRAP - Same as TRAP and GPR32 combined
24;   GPR64-TRAP - Same as TRAP and GPR64 combined
25;   NOCHECK - Division by zero will not be detected
26
27@g0 = common global i32 0, align 4
28@g1 = common global i32 0, align 4
29
30define i32 @sdiv1(i32 signext %a0, i32 signext %a1) nounwind readnone {
31entry:
32; ALL-LABEL: sdiv1:
33
34; ACC32:         div $zero, $4, $5
35; ACC32-TRAP:    teq $5, $zero, 7
36
37; ACC64:         div $zero, $4, $5
38; ACC64-TRAP:    teq $5, $zero, 7
39
40; GPR32:         div $2, $4, $5
41; GPR32-TRAP:    teq $5, $zero, 7
42
43; GPR64:         div $2, $4, $5
44; GPR64-TRAP:    teq $5, $zero, 7
45
46; NOCHECK-NOT:   teq
47
48; ACC32:         mflo $2
49; ACC64:         mflo $2
50
51; ALL: .end sdiv1
52
53  %div = sdiv i32 %a0, %a1
54  ret i32 %div
55}
56
57define i32 @srem1(i32 signext %a0, i32 signext %a1) nounwind readnone {
58entry:
59; ALL-LABEL: srem1:
60
61; ACC32:         div $zero, $4, $5
62; ACC32-TRAP:    teq $5, $zero, 7
63
64; ACC64:         div $zero, $4, $5
65; ACC64-TRAP:    teq $5, $zero, 7
66
67; GPR32:         mod $2, $4, $5
68; GPR32-TRAP:    teq $5, $zero, 7
69
70; GPR64:         mod $2, $4, $5
71; GPR64-TRAP:    teq $5, $zero, 7
72
73; NOCHECK-NOT:   teq
74
75; ACC32:         mfhi $2
76; ACC64:         mfhi $2
77
78; ALL: .end srem1
79
80  %rem = srem i32 %a0, %a1
81  ret i32 %rem
82}
83
84define i32 @udiv1(i32 signext %a0, i32 signext %a1) nounwind readnone {
85entry:
86; ALL-LABEL: udiv1:
87
88; ACC32:         divu $zero, $4, $5
89; ACC32-TRAP:    teq $5, $zero, 7
90
91; ACC64:         divu $zero, $4, $5
92; ACC64-TRAP:    teq $5, $zero, 7
93
94; GPR32:         divu $2, $4, $5
95; GPR32-TRAP:    teq $5, $zero, 7
96
97; GPR64:         divu $2, $4, $5
98; GPR64-TRAP:    teq $5, $zero, 7
99
100; NOCHECK-NOT:   teq
101
102; ACC32:         mflo $2
103; ACC64:         mflo $2
104
105; ALL: .end udiv1
106  %div = udiv i32 %a0, %a1
107  ret i32 %div
108}
109
110define i32 @urem1(i32 signext %a0, i32 signext %a1) nounwind readnone {
111entry:
112; ALL-LABEL: urem1:
113
114; ACC32:         divu $zero, $4, $5
115; ACC32-TRAP:    teq $5, $zero, 7
116
117; ACC64:         divu $zero, $4, $5
118; ACC64-TRAP:    teq $5, $zero, 7
119
120; GPR32:         modu $2, $4, $5
121; GPR32-TRAP:    teq $5, $zero, 7
122
123; GPR64:         modu $2, $4, $5
124; GPR64-TRAP:    teq $5, $zero, 7
125
126; NOCHECK-NOT:   teq
127
128; ACC32:         mfhi $2
129; ACC64:         mfhi $2
130
131; ALL: .end urem1
132
133  %rem = urem i32 %a0, %a1
134  ret i32 %rem
135}
136
137define i32 @sdivrem1(i32 signext %a0, i32 signext %a1, i32* nocapture %r) nounwind {
138entry:
139; ALL-LABEL: sdivrem1:
140
141; ACC32:         div $zero, $4, $5
142; ACC32-TRAP:    teq $5, $zero, 7
143; NOCHECK-NOT:   teq
144; ACC32:         mflo $2
145; ACC32:         mfhi $[[R0:[0-9]+]]
146; ACC32:         sw $[[R0]], 0(${{[0-9]+}})
147
148; ACC64:         div $zero, $4, $5
149; ACC64-TRAP:    teq $5, $zero, 7
150; NOCHECK-NOT:   teq
151; ACC64:         mflo $2
152; ACC64:         mfhi $[[R0:[0-9]+]]
153; ACC64:         sw $[[R0]], 0(${{[0-9]+}})
154
155; GPR32-DAG:     mod $[[R0:[0-9]+]], $4, $5
156; GPR32-TRAP:    teq $5, $zero, 7
157; NOCHECK-NOT:   teq
158; GPR32:         sw $[[R0]], 0(${{[0-9]+}})
159; GPR32-DAG:     div $2, $4, $5
160; GPR32-TRAP:    teq $5, $zero, 7
161
162; GPR64-DAG:     mod $[[R0:[0-9]+]], $4, $5
163; GPR64-TRAP:    teq $5, $zero, 7
164; NOCHECK-NOT:   teq
165; GPR64:         sw $[[R0]], 0(${{[0-9]+}})
166; GPR64-DAG:     div $2, $4, $5
167; GPR64-TRAP:    teq $5, $zero, 7
168; NOCHECK-NOT:   teq
169
170; ALL: .end sdivrem1
171
172  %rem = srem i32 %a0, %a1
173  store i32 %rem, i32* %r, align 4
174  %div = sdiv i32 %a0, %a1
175  ret i32 %div
176}
177
178define i32 @udivrem1(i32 signext %a0, i32 signext %a1, i32* nocapture %r) nounwind {
179entry:
180; ALL-LABEL: udivrem1:
181
182; ACC32:         divu $zero, $4, $5
183; ACC32-TRAP:    teq $5, $zero, 7
184; NOCHECK-NOT:   teq
185; ACC32:         mflo $2
186; ACC32:         mfhi $[[R0:[0-9]+]]
187; ACC32:         sw $[[R0]], 0(${{[0-9]+}})
188
189; ACC64:         divu $zero, $4, $5
190; ACC64-TRAP:    teq $5, $zero, 7
191; NOCHECK-NOT:   teq
192; ACC64:         mflo $2
193; ACC64:         mfhi $[[R0:[0-9]+]]
194; ACC64:         sw $[[R0]], 0(${{[0-9]+}})
195
196; GPR32-DAG:     modu $[[R0:[0-9]+]], $4, $5
197; GPR32-TRAP:    teq $5, $zero, 7
198; GPR32:         sw $[[R0]], 0(${{[0-9]+}})
199; NOCHECK-NOT:   teq
200; GPR32-DAG:     divu $2, $4, $5
201; GPR32-TRAP:    teq $5, $zero, 7
202; NOCHECK-NOT:   teq
203
204; GPR64-DAG:     modu $[[R0:[0-9]+]], $4, $5
205; GPR64-TRAP:    teq $5, $zero, 7
206; NOCHECK-NOT:   teq
207; GPR64:         sw $[[R0]], 0(${{[0-9]+}})
208; GPR64-DAG:     divu $2, $4, $5
209; GPR64-TRAP:    teq $5, $zero, 7
210; NOCHECK-NOT:   teq
211
212; ALL: .end udivrem1
213
214  %rem = urem i32 %a0, %a1
215  store i32 %rem, i32* %r, align 4
216  %div = udiv i32 %a0, %a1
217  ret i32 %div
218}
219
220; FIXME: It's not clear what this is supposed to test.
221define i32 @killFlags() {
222entry:
223  %0 = load i32, i32* @g0, align 4
224  %1 = load i32, i32* @g1, align 4
225  %div = sdiv i32 %0, %1
226  ret i32 %div
227}
228
229define i64 @sdiv2(i64 %a0, i64 %a1) nounwind readnone {
230entry:
231; ALL-LABEL: sdiv2:
232
233; ACC32:         lw $25, %call16(__divdi3)(
234; ACC32:         jalr $25
235
236; ACC64:         ddiv $zero, $4, $5
237; ACC64-TRAP:    teq $5, $zero, 7
238
239; GPR64:         ddiv $2, $4, $5
240; GPR64-TRAP:    teq $5, $zero, 7
241
242; NOCHECK-NOT:   teq
243
244; ACC64:         mflo $2
245
246; ALL: .end sdiv2
247
248  %div = sdiv i64 %a0, %a1
249  ret i64 %div
250}
251
252define i64 @srem2(i64 %a0, i64 %a1) nounwind readnone {
253entry:
254; ALL-LABEL: srem2:
255
256; ACC32:         lw $25, %call16(__moddi3)(
257; ACC32:         jalr $25
258
259; ACC64:         div $zero, $4, $5
260; ACC64-TRAP:    teq $5, $zero, 7
261
262; GPR64:         dmod $2, $4, $5
263; GPR64-TRAP:    teq $5, $zero, 7
264
265; NOCHECK-NOT:   teq
266
267; ACC64:         mfhi $2
268
269; ALL: .end srem2
270
271  %rem = srem i64 %a0, %a1
272  ret i64 %rem
273}
274
275define i64 @udiv2(i64 %a0, i64 %a1) nounwind readnone {
276entry:
277; ALL-LABEL: udiv2:
278
279; ACC32:         lw $25, %call16(__udivdi3)(
280; ACC32:         jalr $25
281
282; ACC64:         divu $zero, $4, $5
283; ACC64-TRAP:    teq $5, $zero, 7
284
285; GPR64:         ddivu $2, $4, $5
286; GPR64-TRAP:    teq $5, $zero, 7
287
288; NOCHECK-NOT:   teq
289
290; ACC64:         mflo $2
291
292; ALL: .end udiv2
293  %div = udiv i64 %a0, %a1
294  ret i64 %div
295}
296
297define i64 @urem2(i64 %a0, i64 %a1) nounwind readnone {
298entry:
299; ALL-LABEL: urem2:
300
301; ACC32:         lw $25, %call16(__umoddi3)(
302; ACC32:         jalr $25
303
304; ACC64:         divu $zero, $4, $5
305; ACC64-TRAP:    teq $5, $zero, 7
306
307; GPR64:         dmodu $2, $4, $5
308; GPR64-TRAP:    teq $5, $zero, 7
309
310; NOCHECK-NOT:   teq
311
312; ACC64:         mfhi $2
313
314; ALL: .end urem2
315
316  %rem = urem i64 %a0, %a1
317  ret i64 %rem
318}
319
320define i64 @sdivrem2(i64 %a0, i64 %a1, i64* nocapture %r) nounwind {
321entry:
322; ALL-LABEL: sdivrem2:
323
324; sdivrem2 is too complex to effectively check. We can at least check for the
325; calls though.
326; ACC32:         lw $25, %call16(__moddi3)(
327; ACC32:         jalr $25
328; ACC32:         lw $25, %call16(__divdi3)(
329; ACC32:         jalr $25
330
331; ACC64:         ddiv $zero, $4, $5
332; ACC64-TRAP:    teq $5, $zero, 7
333; NOCHECK-NOT:   teq
334; ACC64:         mflo $2
335; ACC64:         mfhi $[[R0:[0-9]+]]
336; ACC64:         sd $[[R0]], 0(${{[0-9]+}})
337
338; GPR64-DAG:     dmod $[[R0:[0-9]+]], $4, $5
339; GPR64-TRAP:    teq $5, $zero, 7
340; NOCHECK-NOT:   teq
341; GPR64:         sd $[[R0]], 0(${{[0-9]+}})
342
343; GPR64-DAG:     ddiv $2, $4, $5
344; GPR64-TRAP:    teq $5, $zero, 7
345; NOCHECK-NOT:   teq
346
347; ALL: .end sdivrem2
348
349  %rem = srem i64 %a0, %a1
350  store i64 %rem, i64* %r, align 8
351  %div = sdiv i64 %a0, %a1
352  ret i64 %div
353}
354
355define i64 @udivrem2(i64 %a0, i64 %a1, i64* nocapture %r) nounwind {
356entry:
357; ALL-LABEL: udivrem2:
358
359; udivrem2 is too complex to effectively check. We can at least check for the
360; calls though.
361; ACC32:         lw $25, %call16(__umoddi3)(
362; ACC32:         jalr $25
363; ACC32:         lw $25, %call16(__udivdi3)(
364; ACC32:         jalr $25
365
366; ACC64:         ddivu $zero, $4, $5
367; ACC64-TRAP:    teq $5, $zero, 7
368; NOCHECK-NOT:   teq
369; ACC64:         mflo $2
370; ACC64:         mfhi $[[R0:[0-9]+]]
371; ACC64:         sd $[[R0]], 0(${{[0-9]+}})
372
373; GPR64:         dmodu $[[R0:[0-9]+]], $4, $5
374; GPR64-TRAP:    teq $5, $zero, 7
375; NOCHECK-NOT:   teq
376; GPR64:         sd $[[R0]], 0(${{[0-9]+}})
377
378; GPR64-DAG:     ddivu $2, $4, $5
379; GPR64-TRAP:    teq $5, $zero, 7
380; NOCHECK-NOT:   teq
381
382; ALL: .end udivrem2
383
384  %rem = urem i64 %a0, %a1
385  store i64 %rem, i64* %r, align 8
386  %div = udiv i64 %a0, %a1
387  ret i64 %div
388}
389