Skip to content

Commit 83425b1

Browse files
committed
replace old soft division code with new functions
1 parent d242475 commit 83425b1

File tree

2 files changed

+33
-76
lines changed

2 files changed

+33
-76
lines changed

src/int/sdiv.rs

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -57,54 +57,59 @@ trait Divmod: Int {
5757
impl Divmod for i32 {}
5858
impl Divmod for i64 {}
5959

60+
6061
intrinsics! {
6162
#[maybe_use_optimized_c_shim]
6263
#[arm_aeabi_alias = __aeabi_idiv]
6364
/// Returns `n / d`
6465
pub extern "C" fn __divsi3(a: i32, b: i32) -> i32 {
65-
a.div(b)
66+
i32_div_rem(a, b).0
6667
}
6768

6869
#[maybe_use_optimized_c_shim]
6970
/// Returns `n % d`
7071
pub extern "C" fn __modsi3(a: i32, b: i32) -> i32 {
71-
a.mod_(b)
72+
i32_div_rem(a, b).1
7273
}
73-
74+
7475
#[maybe_use_optimized_c_shim]
7576
/// Returns `n / d` and sets `*rem = n % d`
7677
pub extern "C" fn __divmodsi4(a: i32, b: i32, rem: &mut i32) -> i32 {
77-
a.divmod(b, rem, |a, b| __divsi3(a, b))
78+
let quo_rem = i32_div_rem(a, b);
79+
*rem = quo_rem.1;
80+
quo_rem.0
7881
}
7982

8083
#[maybe_use_optimized_c_shim]
8184
/// Returns `n / d`
8285
pub extern "C" fn __divdi3(a: i64, b: i64) -> i64 {
83-
a.div(b)
86+
i64_div_rem(a, b).0
8487
}
8588

8689
#[maybe_use_optimized_c_shim]
8790
/// Returns `n % d`
8891
pub extern "C" fn __moddi3(a: i64, b: i64) -> i64 {
89-
a.mod_(b)
92+
i64_div_rem(a, b).1
9093
}
9194

9295
#[aapcs_on_arm]
9396
/// Returns `n / d` and sets `*rem = n % d`
9497
pub extern "C" fn __divmoddi4(a: i64, b: i64, rem: &mut i64) -> i64 {
95-
a.divmod(b, rem, |a, b| __divdi3(a, b))
98+
let quo_rem = i64_div_rem(a, b);
99+
*rem = quo_rem.1;
100+
quo_rem.0
96101
}
97102

98103
#[win64_128bit_abi_hack]
99104
/// Returns `n / d`
100105
pub extern "C" fn __divti3(a: i128, b: i128) -> i128 {
101-
a.div(b)
106+
i128_div_rem(a, b).0
102107
}
103108

104109
#[win64_128bit_abi_hack]
105110
/// Returns `n % d`
106111
pub extern "C" fn __modti3(a: i128, b: i128) -> i128 {
107-
a.mod_(b)
112+
i128_div_rem(a, b).1
108113
}
109114

110115
// LLVM does not currently have a `__divmodti4` function

src/int/udiv.rs

Lines changed: 19 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -156,113 +156,65 @@ intrinsics! {
156156
#[arm_aeabi_alias = __aeabi_uidiv]
157157
/// Returns `n / d`
158158
pub extern "C" fn __udivsi3(n: u32, d: u32) -> u32 {
159-
// Special cases
160-
if d == 0 {
161-
// NOTE This should be unreachable in safe Rust because the program will panic before
162-
// this intrinsic is called
163-
::abort();
164-
}
165-
166-
if n == 0 {
167-
return 0;
168-
}
169-
170-
let mut sr = d.leading_zeros().wrapping_sub(n.leading_zeros());
171-
172-
// d > n
173-
if sr > u32::BITS - 1 {
174-
return 0;
175-
}
176-
177-
// d == 1
178-
if sr == u32::BITS - 1 {
179-
return n;
180-
}
181-
182-
sr += 1;
183-
184-
// 1 <= sr <= u32::BITS - 1
185-
let mut q = n << (u32::BITS - sr);
186-
let mut r = n >> sr;
187-
188-
let mut carry = 0;
189-
190-
// Don't use a range because they may generate references to memcpy in unoptimized code
191-
let mut i = 0;
192-
while i < sr {
193-
i += 1;
194-
195-
// r:q = ((r:q) << 1) | carry
196-
r = (r << 1) | (q >> (u32::BITS - 1));
197-
q = (q << 1) | carry;
198-
199-
// carry = 0;
200-
// if r > d {
201-
// r -= d;
202-
// carry = 1;
203-
// }
204-
205-
let s = (d.wrapping_sub(r).wrapping_sub(1)) as i32 >> (u32::BITS - 1);
206-
carry = (s & 1) as u32;
207-
r -= d & s as u32;
208-
}
209-
210-
(q << 1) | carry
159+
u32_div_rem(n, d).0
211160
}
212161

213162
#[maybe_use_optimized_c_shim]
214163
/// Returns `n % d`
215164
pub extern "C" fn __umodsi3(n: u32, d: u32) -> u32 {
216-
let q = __udivsi3(n, d);
217-
n - q * d
165+
u32_div_rem(n, d).1
218166
}
219167

220168
#[maybe_use_optimized_c_shim]
221169
/// Returns `n / d` and sets `*rem = n % d`
222170
pub extern "C" fn __udivmodsi4(n: u32, d: u32, rem: Option<&mut u32>) -> u32 {
223-
let q = __udivsi3(n, d);
171+
let quo_rem = u32_div_rem(n, d);
224172
if let Some(rem) = rem {
225-
*rem = n - (q * d);
173+
*rem = quo_rem.1;
226174
}
227-
q
175+
quo_rem.0
228176
}
229177

230178
#[maybe_use_optimized_c_shim]
231179
/// Returns `n / d`
232180
pub extern "C" fn __udivdi3(n: u64, d: u64) -> u64 {
233-
__udivmoddi4(n, d, None)
181+
u64_div_rem(n, d).0
234182
}
235183

236184
#[maybe_use_optimized_c_shim]
237185
/// Returns `n % d`
238186
pub extern "C" fn __umoddi3(n: u64, d: u64) -> u64 {
239-
let mut rem = 0;
240-
__udivmoddi4(n, d, Some(&mut rem));
241-
rem
187+
u64_div_rem(n, d).1
242188
}
243189

244190
/// Returns `n / d` and sets `*rem = n % d`
245191
pub extern "C" fn __udivmoddi4(n: u64, d: u64, rem: Option<&mut u64>) -> u64 {
246-
udivmod_inner!(n, d, rem, u64)
192+
let quo_rem = u64_div_rem(n, d);
193+
if let Some(rem) = rem {
194+
*rem = quo_rem.1;
195+
}
196+
quo_rem.0
247197
}
248198

249199
#[win64_128bit_abi_hack]
250200
/// Returns `n / d`
251201
pub extern "C" fn __udivti3(n: u128, d: u128) -> u128 {
252-
__udivmodti4(n, d, None)
202+
u128_div_rem(n, d).0
253203
}
254204

255205
#[win64_128bit_abi_hack]
256206
/// Returns `n % d`
257207
pub extern "C" fn __umodti3(n: u128, d: u128) -> u128 {
258-
let mut rem = 0;
259-
__udivmodti4(n, d, Some(&mut rem));
260-
rem
208+
u128_div_rem(n, d).1
261209
}
262210

263211
#[win64_128bit_abi_hack]
264212
/// Returns `n / d` and sets `*rem = n % d`
265213
pub extern "C" fn __udivmodti4(n: u128, d: u128, rem: Option<&mut u128>) -> u128 {
266-
udivmod_inner!(n, d, rem, u128)
214+
let quo_rem = u128_div_rem(n, d);
215+
if let Some(rem) = rem {
216+
*rem = quo_rem.1;
217+
}
218+
quo_rem.0
267219
}
268220
}

0 commit comments

Comments
 (0)