@@ -151,119 +151,75 @@ macro_rules! udivmod_inner {
151
151
( q << 1 ) | carry as $ty
152
152
} }
153
153
}
154
+ // NOTE: there are aborts inside the specialized_div_rem functions if division by 0
155
+ // is encountered, however these should be unreachable and optimized away unless
156
+ // uses of `std/core::intrinsics::unchecked_div/rem` do not have a 0 check in front
157
+ // of them.
154
158
155
159
intrinsics ! {
156
160
#[ maybe_use_optimized_c_shim]
157
161
#[ arm_aeabi_alias = __aeabi_uidiv]
158
162
/// Returns `n / d`
159
163
pub extern "C" fn __udivsi3( n: u32 , d: u32 ) -> u32 {
160
- // Special cases
161
- if d == 0 {
162
- // NOTE This should be unreachable in safe Rust because the program will panic before
163
- // this intrinsic is called
164
- :: abort( ) ;
165
- }
166
-
167
- if n == 0 {
168
- return 0 ;
169
- }
170
-
171
- let mut sr = d. leading_zeros( ) . wrapping_sub( n. leading_zeros( ) ) ;
172
-
173
- // d > n
174
- if sr > u32 :: BITS - 1 {
175
- return 0 ;
176
- }
177
-
178
- // d == 1
179
- if sr == u32 :: BITS - 1 {
180
- return n;
181
- }
182
-
183
- sr += 1 ;
184
-
185
- // 1 <= sr <= u32::BITS - 1
186
- let mut q = n << ( u32 :: BITS - sr) ;
187
- let mut r = n >> sr;
188
-
189
- let mut carry = 0 ;
190
-
191
- // Don't use a range because they may generate references to memcpy in unoptimized code
192
- let mut i = 0 ;
193
- while i < sr {
194
- i += 1 ;
195
-
196
- // r:q = ((r:q) << 1) | carry
197
- r = ( r << 1 ) | ( q >> ( u32 :: BITS - 1 ) ) ;
198
- q = ( q << 1 ) | carry;
199
-
200
- // carry = 0;
201
- // if r > d {
202
- // r -= d;
203
- // carry = 1;
204
- // }
205
-
206
- let s = ( d. wrapping_sub( r) . wrapping_sub( 1 ) ) as i32 >> ( u32 :: BITS - 1 ) ;
207
- carry = ( s & 1 ) as u32 ;
208
- r -= d & s as u32 ;
209
- }
210
-
211
- ( q << 1 ) | carry
164
+ u32_div_rem( n, d) . 0
212
165
}
213
166
214
167
#[ maybe_use_optimized_c_shim]
215
168
/// Returns `n % d`
216
169
pub extern "C" fn __umodsi3( n: u32 , d: u32 ) -> u32 {
217
- let q = __udivsi3( n, d) ;
218
- n - q * d
170
+ u32_div_rem( n, d) . 1
219
171
}
220
172
221
173
#[ maybe_use_optimized_c_shim]
222
174
/// Returns `n / d` and sets `*rem = n % d`
223
175
pub extern "C" fn __udivmodsi4( n: u32 , d: u32 , rem: Option <& mut u32 >) -> u32 {
224
- let q = __udivsi3 ( n, d) ;
176
+ let quo_rem = u32_div_rem ( n, d) ;
225
177
if let Some ( rem) = rem {
226
- * rem = n - ( q * d ) ;
178
+ * rem = quo_rem . 1 ;
227
179
}
228
- q
180
+ quo_rem . 0
229
181
}
230
182
231
183
#[ maybe_use_optimized_c_shim]
232
184
/// Returns `n / d`
233
185
pub extern "C" fn __udivdi3( n: u64 , d: u64 ) -> u64 {
234
- __udivmoddi4 ( n, d, None )
186
+ u64_div_rem ( n, d) . 0
235
187
}
236
188
237
189
#[ maybe_use_optimized_c_shim]
238
190
/// Returns `n % d`
239
191
pub extern "C" fn __umoddi3( n: u64 , d: u64 ) -> u64 {
240
- let mut rem = 0 ;
241
- __udivmoddi4( n, d, Some ( & mut rem) ) ;
242
- rem
192
+ u64_div_rem( n, d) . 1
243
193
}
244
194
245
195
/// Returns `n / d` and sets `*rem = n % d`
246
196
pub extern "C" fn __udivmoddi4( n: u64 , d: u64 , rem: Option <& mut u64 >) -> u64 {
247
- udivmod_inner!( n, d, rem, u64 )
197
+ let quo_rem = u64_div_rem( n, d) ;
198
+ if let Some ( rem) = rem {
199
+ * rem = quo_rem. 1 ;
200
+ }
201
+ quo_rem. 0
248
202
}
249
203
250
204
#[ win64_128bit_abi_hack]
251
205
/// Returns `n / d`
252
206
pub extern "C" fn __udivti3( n: u128 , d: u128 ) -> u128 {
253
- __udivmodti4 ( n, d, None )
207
+ u128_div_rem ( n, d) . 0
254
208
}
255
209
256
210
#[ win64_128bit_abi_hack]
257
211
/// Returns `n % d`
258
212
pub extern "C" fn __umodti3( n: u128 , d: u128 ) -> u128 {
259
- let mut rem = 0 ;
260
- __udivmodti4( n, d, Some ( & mut rem) ) ;
261
- rem
213
+ u128_div_rem( n, d) . 1
262
214
}
263
215
264
216
#[ win64_128bit_abi_hack]
265
217
/// Returns `n / d` and sets `*rem = n % d`
266
218
pub extern "C" fn __udivmodti4( n: u128 , d: u128 , rem: Option <& mut u128 >) -> u128 {
267
- udivmod_inner!( n, d, rem, u128 )
219
+ let quo_rem = u128_div_rem( n, d) ;
220
+ if let Some ( rem) = rem {
221
+ * rem = quo_rem. 1 ;
222
+ }
223
+ quo_rem. 0
268
224
}
269
225
}
0 commit comments