ARM EABI divmod support
[oota-llvm.git] / test / CodeGen / ARM / divmod-eabi.ll
1 ; RUN: llc -mtriple armv7-none-eabi %s -o - | FileCheck %s --check-prefix=EABI
2 ; RUN: llc -mtriple armv7-linux-gnueabi %s -o - | FileCheck %s --check-prefix=GNU
3 ; RUN: llc -mtriple armv7-apple-darwin %s -o - | FileCheck %s --check-prefix=DARWIN
4
5 define signext i16 @f16(i16 signext %a, i16 signext %b) {
6 ; EABI: f16:
7 ; GNU: f16:
8 ; DARWIN: f16:
9 entry:
10   %conv = sext i16 %a to i32
11   %conv1 = sext i16 %b to i32
12   %div = sdiv i32 %conv, %conv1
13   %rem = srem i32 %conv, %conv1
14 ; EABI: __aeabi_idivmod
15 ; EABI: mov [[div:r[0-9]+]], r0
16 ; EABI: mov [[rem:r[0-9]+]], r1
17 ; GNU: __aeabi_idiv
18 ; GNU: mov [[sum:r[0-9]+]], r0
19 ; GNU: __modsi3
20 ; GNU: add [[sum]]{{.*}}r0
21 ; DARWIN: ___divsi3
22 ; DARWIN: mov [[sum:r[0-9]+]], r0
23 ; DARWIN: __modsi3
24 ; DARWIN: add [[sum]]{{.*}}r0
25   %rem8 = srem i32 %conv1, %conv
26 ; EABI: __aeabi_idivmod
27 ; GNU: __modsi3
28 ; DARWIN: __modsi3
29   %add = add nsw i32 %rem, %div
30   %add13 = add nsw i32 %add, %rem8
31   %conv14 = trunc i32 %add13 to i16
32 ; EABI: add r0{{.*}}r1
33 ; EABI: sxth r0, r0
34 ; GNU: add r0{{.*}}[[sum]]
35 ; GNU: sxth r0, r0
36 ; DARWIN: add r0{{.*}}[[sum]]
37 ; DARWIN: sxth r0, r0
38   ret i16 %conv14
39 }
40
41 define i32 @f32(i32 %a, i32 %b) {
42 ; EABI: f32:
43 ; GNU: f32:
44 ; DARWIN: f32:
45 entry:
46   %div = sdiv i32 %a, %b
47   %rem = srem i32 %a, %b
48 ; EABI: __aeabi_idivmod
49 ; EABI: mov [[div:r[0-9]+]], r0
50 ; EABI: mov [[rem:r[0-9]+]], r1
51 ; GNU: __aeabi_idiv
52 ; GNU: mov [[sum:r[0-9]+]], r0
53 ; GNU: __modsi3
54 ; GNU: add [[sum]]{{.*}}r0
55 ; DARWIN: ___divsi3
56 ; DARWIN: mov [[sum:r[0-9]+]], r0
57 ; DARWIN: __modsi3
58 ; DARWIN: add [[sum]]{{.*}}r0
59   %rem1 = srem i32 %b, %a
60 ; EABI: __aeabi_idivmod
61 ; GNU: __modsi3
62 ; DARWIN: __modsi3
63   %add = add nsw i32 %rem, %div
64   %add2 = add nsw i32 %add, %rem1
65 ; EABI: add r0{{.*}}r1
66 ; GNU: add r0{{.*}}[[sum]]
67 ; DARWIN: add r0{{.*}}[[sum]]
68   ret i32 %add2
69 }
70
71 define i32 @uf(i32 %a, i32 %b) {
72 ; EABI: uf:
73 ; GNU: uf:
74 ; DARWIN: uf:
75 entry:
76   %div = udiv i32 %a, %b
77   %rem = urem i32 %a, %b
78 ; EABI: __aeabi_uidivmod
79 ; GNU: __aeabi_uidiv
80 ; GNU: mov [[sum:r[0-9]+]], r0
81 ; GNU: __umodsi3
82 ; GNU: add [[sum]]{{.*}}r0
83 ; DARWIN: ___udivsi3
84 ; DARWIN: mov [[sum:r[0-9]+]], r0
85 ; DARWIN: __umodsi3
86 ; DARWIN: add [[sum]]{{.*}}r0
87   %rem1 = urem i32 %b, %a
88 ; EABI: __aeabi_uidivmod
89 ; GNU: __umodsi3
90 ; DARWIN: __umodsi3
91   %add = add nuw i32 %rem, %div
92   %add2 = add nuw i32 %add, %rem1
93 ; EABI: add r0{{.*}}r1
94 ; GNU: add r0{{.*}}[[sum]]
95 ; DARWIN: add r0{{.*}}[[sum]]
96   ret i32 %add2
97 }
98
99 ; FIXME: AEABI is not lowering long u/srem into u/ldivmod
100 define i64 @longf(i64 %a, i64 %b) {
101 ; EABI: longf:
102 ; GNU: longf:
103 ; DARWIN: longf:
104 entry:
105   %div = sdiv i64 %a, %b
106   %rem = srem i64 %a, %b
107 ; EABI: __aeabi_ldivmod
108 ; GNU: __aeabi_ldivmod
109 ; GNU: mov [[div1:r[0-9]+]], r0
110 ; GNU: mov [[div2:r[0-9]+]], r1
111 ; DARWIN: ___divdi3
112 ; DARWIN: mov [[div1:r[0-9]+]], r0
113 ; DARWIN: mov [[div2:r[0-9]+]], r1
114 ; DARWIN: __moddi3
115   %add = add nsw i64 %rem, %div
116 ; GNU: adds r0{{.*}}[[div1]]
117 ; GNU: adc r1{{.*}}[[div2]]
118 ; DARWIN: adds r0{{.*}}[[div1]]
119 ; DARWIN: adc r1{{.*}}[[div2]]
120   ret i64 %add
121 }
122
123 define i32 @g1(i32 %a, i32 %b) {
124 ; EABI: g1:
125 ; GNU: g1:
126 ; DARWIN: g1:
127 entry:
128   %div = sdiv i32 %a, %b
129   %rem = srem i32 %a, %b
130 ; EABI: __aeabi_idivmod
131 ; GNU: __aeabi_idiv
132 ; GNU: mov [[sum:r[0-9]+]], r0
133 ; GNU: __modsi3
134 ; DARWIN: ___divsi3
135 ; DARWIN: mov [[sum:r[0-9]+]], r0
136 ; DARWIN: __modsi3
137   %add = add nsw i32 %rem, %div
138 ; EABI: add     r0{{.*}}r1
139 ; GNU: add r0{{.*}}[[sum]]
140 ; DARWIN: add r0{{.*}}[[sum]]
141   ret i32 %add
142 }
143
144 ; On both Darwin and Gnu, this is just a call to __modsi3
145 define i32 @g2(i32 %a, i32 %b) {
146 ; EABI: g2:
147 ; GNU: g2:
148 ; DARWIN: g2:
149 entry:
150   %rem = srem i32 %a, %b
151 ; EABI: __aeabi_idivmod
152 ; GNU: __modsi3
153 ; DARWIN: __modsi3
154   ret i32 %rem
155 ; EABI: mov     r0, r1
156 }
157
158 define i32 @g3(i32 %a, i32 %b) {
159 ; EABI: g3:
160 ; GNU: g3:
161 ; DARWIN: g3:
162 entry:
163   %rem = srem i32 %a, %b
164 ; EABI: __aeabi_idivmod
165 ; EABI: mov [[mod:r[0-9]+]], r1
166 ; GNU: __modsi3
167 ; GNU: mov [[sum:r[0-9]+]], r0
168 ; DARWIN: __modsi3
169 ; DARWIN: mov [[sum:r[0-9]+]], r0
170   %rem1 = srem i32 %b, %rem
171 ; EABI: __aeabi_idivmod
172 ; GNU: __modsi3
173 ; DARWIN: __modsi3
174   %add = add nsw i32 %rem1, %rem
175 ; EABI: add r0, r1, [[mod]]
176 ; GNU: add r0{{.*}}[[sum]]
177 ; DARWIN: add r0{{.*}}[[sum]]
178   ret i32 %add
179 }
180
181 define i32 @g4(i32 %a, i32 %b) {
182 ; EABI: g4:
183 ; GNU: g4:
184 ; DARWIN: g4:
185 entry:
186   %div = sdiv i32 %a, %b
187 ; EABI: __aeabi_idivmod
188 ; EABI: mov [[div:r[0-9]+]], r0
189 ; GNU __aeabi_idiv
190 ; GNU: mov [[sum:r[0-9]+]], r0
191 ; DARWIN: ___divsi3
192 ; DARWIN: mov [[sum:r[0-9]+]], r0
193   %rem = srem i32 %b, %div
194 ; EABI: __aeabi_idivmod
195 ; GNU: __modsi3
196 ; DARWIN: __modsi3
197   %add = add nsw i32 %rem, %div
198 ; EABI: add r0, r1, [[div]]
199 ; GNU: add r0{{.*}}[[sum]]
200 ; DARWIN: add r0{{.*}}[[sum]]
201   ret i32 %add
202 }