Skip to main content

libdivide/
lib.rs

1// See LICENSE.txt for license.
2
3// Port from libdivide.h 4.0.0
4
5#![no_std]
6
7use core::convert::TryInto;
8use core::fmt::Debug;
9use num_integer::Integer;
10use num_traits::{PrimInt, Unsigned, WrappingShr};
11
12#[derive(Copy, Clone, Eq, PartialEq, Debug)]
13pub struct DividerInner<T> {
14    magic: T,
15    more: u8,
16}
17
18#[derive(Copy, Clone, Eq, PartialEq, Debug)]
19#[repr(transparent)]
20pub struct Divider<T: PrimInt>(DividerInner<T>);
21
22#[derive(Copy, Clone, Eq, PartialEq, Debug)]
23#[repr(transparent)]
24pub struct BranchFreeDivider<T: PrimInt>(DividerInner<T>);
25
26// Explanation of the "more" field:
27//
28// * _BITS 0-5 is the shift value (for shift path or mult path).
29// * Bit 6 is the add indicator for mult path.
30// * Bit 7 is set if the divisor is negative. We use bit 7 as the negative
31//   divisor indicator so that we can efficiently use sign extension to
32//   create a bitmask with all _BITS set to 1 (if the divisor is negative)
33//   or 0 (if the divisor is positive).
34//
35// u32: [0-4] shift value
36//      [5] ignored
37//      [6] add indicator
38//      magic number of 0 indicates shift path
39//
40// s32: [0-4] shift value
41//      [5] ignored
42//      [6] add indicator
43//      [7] indicates negative divisor
44//      magic number of 0 indicates shift path
45//
46// u64: [0-5] shift value
47//      [6] add indicator
48//      magic number of 0 indicates shift path
49//
50// s64: [0-5] shift value
51//      [6] add indicator
52//      [7] indicates negative divisor
53//      magic number of 0 indicates shift path
54//
55// In s32 and s64 branchfree modes, the magic number is negated according to
56// whether the divisor is negated. In branchfree strategy, it is not negated.
57
58impl<T> DividerInner<T> {
59    #[inline]
60    fn new(magic: T, more: u8) -> Self {
61        Self { magic, more }
62    }
63}
64
65const SHIFT_MASK_32: u8 = 0x1F;
66const SHIFT_MASK_64: u8 = 0x3F;
67const ADD_MARKER: u8 = 0x40;
68const NEGATIVE_DIVISOR: u8 = 0x80;
69
70#[derive(thiserror::Error, Debug)]
71pub enum DividerError {
72    #[error("divider must be != 0")]
73    Zero,
74    #[error("branchfree divider must be != 1")]
75    BranchFreeOne,
76}
77
78pub trait DividerInt: PrimInt
79where
80    <Self::Double as TryInto<Self>>::Error: Debug,
81{
82    const SHIFT_MASK: u8;
83    const BITS: u32;
84    const SIGNED: bool;
85    type Double: PrimInt + From<Self> + TryInto<Self>;
86    type Unsigned: PrimInt + Unsigned;
87    type UnsignedDouble: PrimInt + Unsigned;
88
89    #[inline]
90    // this funciton can be simplified with an unstable Self::widening_mul without using Self::Double.
91    // https://github.com/rust-lang/rust/issues/85532
92    fn mullhi(x: Self, y: Self) -> Self {
93        let x = Self::Double::from(x);
94        let y = Self::Double::from(y);
95        let r = x * y;
96        // unwrap is optimized away if the shift is right.
97        (r >> Self::BITS as usize).try_into().unwrap()
98    }
99    fn internal_gen(self, branchfree: bool) -> Result<DividerInner<Self>, DividerError>;
100    fn gen(self) -> Result<DividerInner<Self>, DividerError> {
101        self.internal_gen(false)
102    }
103    fn branchfree_gen(self) -> Result<DividerInner<Self>, DividerError> {
104        if Self::SIGNED {
105            self.internal_gen(true)
106        } else {
107            if self == Self::one() {
108                return Err(DividerError::BranchFreeOne);
109            }
110            let mut inner = self.internal_gen(true)?;
111            inner.more &= Self::SHIFT_MASK;
112            Ok(inner)
113        }
114    }
115    fn recover(denom: &DividerInner<Self>) -> Self;
116    fn branchfree_recover(denom: &DividerInner<Self>) -> Self;
117
118    fn unsigned_div_by(self, denom: &Divider<Self>) -> Self {
119        let numer = self;
120        let magic = denom.0.magic;
121        let more = denom.0.more;
122        if magic.is_zero() {
123            numer.shr(more as usize)
124        } else {
125            let q = Self::mullhi(magic, numer);
126            if (more & ADD_MARKER) != 0 {
127                let t = ((numer - q) >> 1) + q;
128                t.shr((more & Self::SHIFT_MASK) as usize)
129            } else {
130                // All upper _BITS are 0,
131                // don't need to mask them off.
132                q.shr(more as usize)
133            }
134        }
135    }
136
137    fn unsigned_branchfree_div_by(self, denom: &BranchFreeDivider<Self>) -> Self
138    where
139        Self: WrappingShr,
140    {
141        let numer = self;
142        let q = Self::mullhi(denom.0.magic, numer);
143        let t = ((numer - q) >> 1) + q;
144        t.wrapping_shr(denom.0.more as u32)
145    }
146}
147
148impl DividerInt for u32 {
149    const SHIFT_MASK: u8 = SHIFT_MASK_32;
150    const BITS: u32 = 32;
151    const SIGNED: bool = false;
152    type Double = u64;
153    type Unsigned = Self;
154    type UnsignedDouble = Self::Double;
155
156    fn internal_gen(self, branchfree: bool) -> Result<DividerInner<Self>, DividerError> {
157        let d = self;
158        if d == 0 {
159            return Err(DividerError::Zero);
160        }
161
162        let floor_log_2_d = (Self::BITS - 1) - d.leading_zeros();
163
164        // Power of 2
165        Ok(if (d & (d - 1)) == 0 {
166            // We need to subtract 1 from the shift value in case of an unsigned
167            // branchfree divider because there is a hardcoded right shift by 1
168            // in its division algorithm. Because of this we also need to add back
169            // 1 in its recovery algorithm.
170            DividerInner::new(0, (floor_log_2_d - u32::from(branchfree)) as u8)
171        } else {
172            let (proposed_m, rem) = (1u64 << (floor_log_2_d + 32)).div_rem(&(d as u64));
173            let mut proposed_m = proposed_m as u32;
174            let rem = rem as u32;
175            assert!(rem > 0 && rem < d);
176
177            let e = d - rem;
178
179            // This power works if e < 2**floor_log_2_d.
180            let more = if !branchfree && (e < (1 << floor_log_2_d)) {
181                // This power works
182                floor_log_2_d as u8
183            } else {
184                // We have to use the general 33-bit algorithm.  We need to compute
185                // (2**power) / d. However, we already have (2**(power-1))/d and
186                // its remainder.  By doubling both, and then correcting the
187                // remainder, we can compute the larger division.
188                // don't care about overflow here - in fact, we expect it
189                proposed_m = proposed_m.wrapping_add(proposed_m);
190                let twice_rem = rem.wrapping_add(rem);
191                if twice_rem >= d || twice_rem < rem {
192                    proposed_m += 1;
193                }
194                (floor_log_2_d as u8) | ADD_MARKER
195            };
196            DividerInner::new(1 + proposed_m, more)
197            // result.more's shift should in general be ceil_log_2_d. But if we
198            // used the smaller power, we subtract one from the shift because we're
199            // using the smaller power. If we're using the larger power, we
200            // subtract one from the shift because it's taken care of by the add
201            // indicator. So floor_log_2_d happens to be correct in both cases.
202        })
203    }
204
205    fn recover(denom: &DividerInner<Self>) -> Self {
206        let more = denom.more;
207        let shift = more & Self::SHIFT_MASK;
208
209        if 0 == denom.magic {
210            1 << shift
211        } else if 0 == (more & ADD_MARKER) {
212            // We compute q = n/d = n*m / 2^(32 + shift)
213            // Therefore we have d = 2^(32 + shift) / m
214            // We need to ceil it.
215            // We know d is not a power of 2, so m is not a power of 2,
216            // so we can just add 1 to the floor
217            let dividend: Self::Double = 1 << (shift as u32 + Self::BITS);
218            1 + (dividend / denom.magic as Self::Double) as Self
219        } else {
220            // Here we wish to compute d = 2^(32+shift+1)/(m+2^32).
221            // Notice (m + 2^32) is a 33 bit number. Use 64 bit division for now
222            // Also note that shift may be as high as 31, so shift + 1 will
223            // overflow. So we have to compute it as 2^(32+shift)/(m+2^32), and
224            // then double the quotient and remainder.
225            let half_n: Self::Double = 1 << (32 + shift);
226            let d = (1 << 32) | denom.magic as Self::Double;
227            // Note that the quotient is guaranteed <= 32 _BITS, but the remainder
228            // may need 33!
229            let (half_q, rem) = half_n.div_rem(&d);
230            let half_q = half_q as Self;
231            // We computed 2^(32+shift)/(m+2^32)
232            // Need to double it, and then add 1 to the quotient if doubling th
233            // remainder would increase the quotient.
234            // Note that rem<<1 cannot overflow, since rem < d and d is 33 _BITS
235            let full_q = half_q + half_q + Self::from((rem << 1) >= d);
236
237            // We rounded down in gen (hence +1)
238            full_q + 1
239        }
240    }
241
242    fn branchfree_recover(denom: &DividerInner<Self>) -> Self {
243        let more = denom.more;
244        let shift = more & Self::SHIFT_MASK;
245
246        if 0 == denom.magic {
247            1 << (shift + 1)
248        } else {
249            // Here we wish to compute d = 2^(32+shift+1)/(m+2^32).
250            // Notice (m + 2^32) is a 33 bit number. Use 64 bit division for now
251            // Also note that shift may be as high as 31, so shift + 1 will
252            // overflow. So we have to compute it as 2^(32+shift)/(m+2^32), and
253            // then double the quotient and remainder.
254            let half_n: Self::Double = 1 << (Self::BITS + shift as u32);
255            let d = (1 << Self::BITS) | denom.magic as Self::Double;
256            // Note that the quotient is guaranteed <= 32 bits, but the remainder
257            // may need 33!
258            let (half_q, rem) = half_n.div_rem(&d);
259            let half_q = half_q as Self;
260            // We computed 2^(32+shift)/(m+2^32)
261            // Need to double it, and then add 1 to the quotient if doubling th
262            // remainder would increase the quotient.
263            // Note that rem<<1 cannot overflow, since rem < d and d is 33 bits
264            let full_q = half_q + half_q + Self::from((rem << 1) >= d);
265
266            // We rounded down in gen (hence +1)
267            full_q + 1
268        }
269    }
270}
271
272impl DividerInt for i32 {
273    const SHIFT_MASK: u8 = SHIFT_MASK_32;
274    const BITS: u32 = 32;
275    const SIGNED: bool = true;
276    type Double = i64;
277    type Unsigned = u32;
278    type UnsignedDouble = u64;
279
280    fn internal_gen(self, branchfree: bool) -> Result<DividerInner<Self>, DividerError> {
281        let d = self;
282
283        if d == 0 {
284            return Err(DividerError::Zero);
285        }
286
287        // If d is a power of 2, or negative a power of 2, we have to use a shift.
288        // This is especially important because the magic algorithm fails for -1.
289        // To check if d is a power of 2 or its inverse, it suffices to check
290        // whether its absolute value has exactly one bit set. This works even for
291        // INT_MIN, because abs(INT_MIN) == INT_MIN, and INT_MIN has one bit set
292        // and is a power of 2.
293        let abs_d = (if d < 0 { d.wrapping_neg() } else { d }) as Self::Unsigned;
294        let floor_log_2_d = (Self::BITS - 1) - abs_d.leading_zeros();
295        // check if exactly one bit is set,
296        // don't care if abs_d is 0 since that's divide by zero
297        Ok(if (abs_d & (abs_d - 1)) == 0 {
298            // Branchfree and normal paths are exactly the same
299            DividerInner::new(
300                0,
301                floor_log_2_d as u8 | if d < 0 { NEGATIVE_DIVISOR } else { 0 },
302            )
303        } else {
304            assert!(floor_log_2_d >= 1);
305
306            // the dividend here is 2**(floor_log_2_d + 31), so the low 32 bit word
307            // is 0 and the high word is floor_log_2_d - 1
308            let (proposed_m, rem) =
309                (1u64 << (floor_log_2_d - 1 + Self::BITS)).div_rem(&(abs_d as u64));
310            let mut proposed_m = proposed_m as Self::Unsigned;
311            let rem = rem as Self::Unsigned;
312            let e = abs_d - rem;
313
314            // We are going to start with a power of floor_log_2_d - 1.
315            // This works if works if e < 2**floor_log_2_d.
316            let mut more = if !branchfree && e < (1 << floor_log_2_d) {
317                // This power works
318                (floor_log_2_d - 1) as u8
319            } else {
320                // We need to go one higher. This should not make proposed_m
321                // overflow, but it will make it negative when interpreted as an
322                // int32_t.
323                proposed_m = proposed_m.wrapping_add(proposed_m);
324                let twice_rem = rem.wrapping_add(rem);
325                if twice_rem >= abs_d || twice_rem < rem {
326                    proposed_m += 1;
327                }
328                floor_log_2_d as u8 | ADD_MARKER
329            };
330
331            proposed_m += 1;
332            let mut magic = proposed_m as Self;
333
334            // Mark if we are negative. Note we only negate the magic number in the
335            // branchfull case.
336            if d < 0 {
337                more |= NEGATIVE_DIVISOR;
338                if !branchfree {
339                    magic = -magic;
340                }
341            }
342            DividerInner::new(magic, more)
343        })
344    }
345
346    fn recover(denom: &DividerInner<Self>) -> Self {
347        let more = denom.more;
348        let shift = more & Self::SHIFT_MASK;
349        if 0 == denom.magic {
350            let mut abs_d: Self = 1 << shift;
351            if 0 != (more & NEGATIVE_DIVISOR) {
352                abs_d = abs_d.wrapping_neg();
353            }
354            abs_d
355        } else {
356            // Unsigned math is much easier
357            // We negate the magic number only in the branchfull case, and we don't
358            // know which case we're in. However we have enough information to
359            // determine the correct sign of the magic number. The divisor was
360            // negative if LIBDIVIDE_NEGATIVE_DIVISOR is set. If ADD_MARKER is set,
361            // the magic number's sign is opposite that of the divisor.
362            // We want to compute the positive magic number.
363            let negative_divisor = 0 != (more & NEGATIVE_DIVISOR);
364            let magic_was_negated = if 0 != (more & ADD_MARKER) {
365                denom.magic > 0
366            } else {
367                denom.magic < 0
368            };
369
370            // Handle the power of 2 case (including branchfree)
371            let result = if denom.magic == 0 {
372                1 << shift
373            } else {
374                let d = (if magic_was_negated {
375                    -denom.magic
376                } else {
377                    denom.magic
378                }) as Self::Unsigned;
379                let n = 1u64 << (32 + shift); // this shift cannot exceed 30
380                let q = (n / d as u64) as Self::Unsigned;
381                q as Self + 1
382            };
383            if negative_divisor {
384                -result
385            } else {
386                result
387            }
388        }
389    }
390
391    #[inline]
392    fn branchfree_recover(denom: &DividerInner<Self>) -> Self {
393        Self::recover(denom)
394    }
395}
396
397impl DividerInt for u64 {
398    const SHIFT_MASK: u8 = SHIFT_MASK_64;
399    const BITS: u32 = 64;
400    const SIGNED: bool = false;
401    type Double = u128;
402    type Unsigned = Self;
403    type UnsignedDouble = Self::Double;
404
405    fn internal_gen(self, branchfree: bool) -> Result<DividerInner<Self>, DividerError> {
406        let d = self;
407
408        if d == 0 {
409            return Err(DividerError::Zero);
410        }
411        let floor_log_2_d: u32 = 63 - d.leading_zeros();
412
413        // Power of 2
414        Ok(if (d & (d - 1)) == 0 {
415            // We need to subtract 1 from the shift value in case of an unsigned
416            // branchfree divider because there is a hardcoded right shift by 1
417            // in its division algorithm. Because of this we also need to add back
418            // 1 in its recovery algorithm.
419            DividerInner::new(0, (floor_log_2_d - u32::from(branchfree)) as u8)
420        } else {
421            // (1 << (64 + floor_log_2_d)) / d
422            let (proposed_m, rem) = (1u128 << (floor_log_2_d + 64)).div_rem(&(d as u128));
423            let mut proposed_m = proposed_m as u64;
424            let rem = rem as u64;
425            assert!(rem > 0 && rem < d);
426
427            let e = d - rem;
428
429            // This power works if e < 2**floor_log_2_d.
430            let more = if !branchfree && e < (1 << floor_log_2_d) {
431                // This power works
432                floor_log_2_d as u8
433            } else {
434                // We have to use the general 65-bit algorithm.  We need to compute
435                // (2**power) / d. However, we already have (2**(power-1))/d and
436                // its remainder. By doubling both, and then correcting the
437                // remainder, we can compute the larger division.
438                // don't care about overflow here - in fact, we expect it
439                proposed_m = proposed_m.wrapping_add(proposed_m);
440                let twice_rem = rem.wrapping_add(rem);
441                if twice_rem >= d || twice_rem < rem {
442                    proposed_m += 1;
443                }
444                (floor_log_2_d as u8) | ADD_MARKER
445            };
446
447            DividerInner::new(1 + proposed_m, more)
448            // result.more's shift should in general be ceil_log_2_d. But if we
449            // used the smaller power, we subtract one from the shift because we're
450            // using the smaller power. If we're using the larger power, we
451            // subtract one from the shift because it's taken care of by the add
452            // indicator. So floor_log_2_d happens to be correct in both cases,
453            // which is why we do it outside of the if statement.
454        })
455    }
456
457    fn recover(denom: &DividerInner<Self>) -> Self {
458        let more = denom.more;
459        let shift = more & Self::SHIFT_MASK;
460
461        if 0 == denom.magic {
462            1 << shift
463        } else if 0 == (more & ADD_MARKER) {
464            // We compute q = n/d = n*m / 2^(64 + shift)
465            // Therefore we have d = 2^(64 + shift) / m
466            // We need to ceil it.
467            // We know d is not a power of 2, so m is not a power of 2,
468            // so we can just add 1 to the floor
469            let dividend = 1u128 << (shift + 64);
470            1 + (dividend / denom.magic as u128) as u64
471        } else {
472            // Here we wish to compute d = 2^(64+shift+1)/(m+2^64).
473            // Notice (m + 2^64) is a 65 bit number. This gets hairy. See
474            // libdivide_u32_recover for more on what we do here.
475            // TODO: do something better than 128 bit math
476
477            // Full n is a (potentially) 129 bit value
478            // half_n is a 128 bit value
479            // Compute the hi half of half_n. Low half is 0.
480            let half_n = 1u128 << (shift + 64);
481            // d is a 65 bit value. The high bit is always set to 1.
482            let d = (1 << 64) | denom.magic as u128;
483            // Note that the quotient is guaranteed <= 64 _BITS,
484            // but the remainder may need 65!
485            let (half_q, r) = half_n.div_rem(&d);
486            let half_q = half_q as u64;
487            // We computed 2^(64+shift)/(m+2^64)
488            // Double the remainder ('dr') and check if that is larger than d
489            // Note that d is a 65 bit value, so r1 is small and so r1 + r1
490            // cannot overflow
491            let dr = r.wrapping_add(r);
492            let dr_exceeds_d = dr > d;
493            let full_q = half_q + half_q + u64::from(dr_exceeds_d);
494            full_q + 1
495        }
496    }
497
498    fn branchfree_recover(denom: &DividerInner<Self>) -> Self {
499        let more = denom.more;
500        let shift = more & Self::SHIFT_MASK;
501        if denom.magic == 0 {
502            1 << (shift + 1)
503        } else {
504            // Here we wish to compute d = 2^(64+shift+1)/(m+2^64).
505            // Notice (m + 2^64) is a 65 bit number. This gets hairy. See
506            // libdivide_u32_recover for more on what we do here.
507            // TODO: do something better than 128 bit math
508
509            // Full n is a (potentially) 129 bit value
510            // half_n is a 128 bit value
511            // Compute the hi half of half_n. Low half is 0.
512            let half_n = 1u128 << (shift + 64);
513            // d is a 65 bit value. The high bit is always set to 1.
514            let d = (1 << 64) + denom.magic as u128;
515            // Note that the quotient is guaranteed <= 64 _BITS,
516            // but the remainder may need 65!
517            let (half_q, r) = half_n.div_rem(&d);
518            let half_q = half_q as u64;
519            // We computed 2^(64+shift)/(m+2^64)
520            // Double the remainder ('dr') and check if that is larger than d
521            // Note that d is a 65 bit value, so r1 is small and so r1 + r1
522            // cannot overflow
523            let dr = r.wrapping_add(r);
524            let dr_exceeds_d = dr > d;
525            let full_q = half_q + half_q + u64::from(dr_exceeds_d);
526            full_q + 1
527        }
528    }
529}
530
531impl DividerInt for i64 {
532    const SHIFT_MASK: u8 = SHIFT_MASK_64;
533    const BITS: u32 = 64;
534    const SIGNED: bool = true;
535    type Double = i128;
536    type Unsigned = u64;
537    type UnsignedDouble = u128;
538
539    fn internal_gen(self, branchfree: bool) -> Result<DividerInner<Self>, DividerError> {
540        let d = self;
541
542        if d == 0 {
543            return Err(DividerError::Zero);
544        }
545
546        // If d is a power of 2, or negative a power of 2, we have to use a shift.
547        // This is especially important because the magic algorithm fails for -1.
548        // To check if d is a power of 2 or its inverse, it suffices to check
549        // whether its absolute value has exactly one bit set. This works even for
550        // INT_MIN, because abs(INT_MIN) == INT_MIN, and INT_MIN has one bit set
551        // and is a power of 2.
552        let abs_d = (if d < 0 { d.wrapping_neg() } else { d }) as Self::Unsigned;
553        let floor_log_2_d = (Self::BITS - 1) - abs_d.leading_zeros();
554        // check if exactly one bit is set,
555        // don't care if abs_d is 0 since that's divide by zero
556        Ok(if (abs_d & (abs_d - 1)) == 0 {
557            // Branchfree and normal paths are exactly the same
558            DividerInner::new(
559                0,
560                floor_log_2_d as u8 | if d < 0 { NEGATIVE_DIVISOR } else { 0 },
561            )
562        } else {
563            assert!(floor_log_2_d >= 1);
564
565            // the dividend here is 2**(floor_log_2_d + 31), so the low 32 bit word
566            // is 0 and the high word is floor_log_2_d - 1
567            let (proposed_m, rem) =
568                (1u128 << (floor_log_2_d - 1 + Self::BITS)).div_rem(&(abs_d as u128));
569            let mut proposed_m = proposed_m as Self::Unsigned;
570            let rem = rem as Self::Unsigned;
571            let e = abs_d - rem;
572
573            // We are going to start with a power of floor_log_2_d - 1.
574            // This works if works if e < 2**floor_log_2_d.
575            let mut more = if !branchfree && e < (1 << floor_log_2_d) {
576                // This power works
577                (floor_log_2_d - 1) as u8
578            } else {
579                // We need to go one higher. This should not make proposed_m
580                // overflow, but it will make it negative when interpreted as an
581                // int32_t.
582                proposed_m = proposed_m.wrapping_add(proposed_m);
583                let twice_rem = rem.wrapping_add(rem);
584                if twice_rem >= abs_d || twice_rem < rem {
585                    proposed_m += 1;
586                }
587                floor_log_2_d as u8 | ADD_MARKER
588            };
589
590            proposed_m += 1;
591            let mut magic = proposed_m as Self;
592
593            // Mark if we are negative. Note we only negate the magic number in the
594            // branchfull case.
595            if d < 0 {
596                more |= NEGATIVE_DIVISOR;
597                if !branchfree {
598                    magic = -magic;
599                }
600            }
601            DividerInner::new(magic, more)
602        })
603    }
604
605    fn recover(denom: &DividerInner<Self>) -> Self {
606        let more = denom.more;
607        let shift = more & Self::SHIFT_MASK;
608        if 0 == denom.magic {
609            let mut abs_d = 1i64 << shift;
610            if 0 != (more & NEGATIVE_DIVISOR) {
611                abs_d = abs_d.wrapping_neg();
612            }
613            abs_d
614        } else {
615            // Unsigned math is much easier
616            let negative_divisor = 0 != (more & NEGATIVE_DIVISOR);
617            let magic_was_negated = if 0 != (more & ADD_MARKER) {
618                denom.magic > 0
619            } else {
620                denom.magic < 0
621            };
622
623            let d = if magic_was_negated {
624                -denom.magic
625            } else {
626                denom.magic
627            } as Self::Unsigned;
628            let n = 1u128 << (shift as u32 + Self::BITS);
629            let q = (n / d as u128) as u64;
630            let mut result = (q + 1) as Self;
631            if negative_divisor {
632                result = -result;
633            }
634            result
635        }
636    }
637
638    #[inline]
639    fn branchfree_recover(denom: &DividerInner<Self>) -> Self {
640        Self::recover(denom)
641    }
642}
643
644impl<T: DividerInt> From<T> for Divider<T> {
645    fn from(d: T) -> Self {
646        Self::new(d).unwrap()
647    }
648}
649
650impl<T: DividerInt> Divider<T> {
651    pub fn new(d: T) -> Result<Self, DividerError> {
652        d.gen().map(Self)
653    }
654
655    pub fn recover(&self) -> T {
656        T::recover(&self.0)
657    }
658}
659
660impl<T: DividerInt> From<T> for BranchFreeDivider<T> {
661    fn from(d: T) -> Self {
662        Self::new(d).unwrap()
663    }
664}
665
666impl<T: DividerInt> BranchFreeDivider<T> {
667    pub fn new(d: T) -> Result<Self, DividerError> {
668        d.branchfree_gen().map(Self)
669    }
670
671    pub fn recover(&self) -> T {
672        T::branchfree_recover(&self.0)
673    }
674}
675
676impl core::ops::Div<&Divider<Self>> for u32 {
677    type Output = Self;
678
679    #[inline]
680    fn div(self, denom: &Divider<Self>) -> Self::Output {
681        self.unsigned_div_by(denom)
682    }
683}
684
685impl core::ops::Div<&BranchFreeDivider<Self>> for u32 {
686    type Output = Self;
687
688    #[inline]
689    fn div(self, denom: &BranchFreeDivider<Self>) -> Self::Output {
690        self.unsigned_branchfree_div_by(denom)
691    }
692}
693
694impl core::ops::Div<&Divider<Self>> for i32 {
695    type Output = Self;
696
697    #[inline]
698    fn div(self, denom: &Divider<Self>) -> Self::Output {
699        let numer = self;
700        let more = denom.0.more;
701        let shift = more & Self::SHIFT_MASK;
702
703        if 0 == denom.0.magic {
704            let sign = (more as i8 >> 7) as u32;
705            let mask = (1u32 << shift) - 1;
706            let uq = (numer as u32).wrapping_add((numer >> 31) as u32 & mask);
707            let mut q = uq as Self;
708            q >>= shift;
709            q = (q as u32 ^ sign).wrapping_sub(sign) as Self;
710            q
711        } else {
712            let mut uq = Self::mullhi(denom.0.magic, numer) as u32;
713            if 0 != (more & ADD_MARKER) {
714                // must be arithmetic shift and then sign extend
715                let sign = (more as i8 >> 7) as Self;
716                // q += (more < 0 ? -numer : numer)
717                // cast required to avoid UB
718                uq = uq.wrapping_add(((numer as u32) ^ (sign as u32)).wrapping_sub(sign as u32));
719            }
720            let mut q = uq as Self;
721            q >>= shift;
722            q += Self::from(q < 0);
723            q
724        }
725    }
726}
727
728impl core::ops::Div<&BranchFreeDivider<Self>> for i32 {
729    type Output = Self;
730
731    #[inline]
732    fn div(self, denom: &BranchFreeDivider<Self>) -> Self::Output {
733        let numer = self;
734        let more = denom.0.more;
735        let shift = more & Self::SHIFT_MASK;
736        // must be arithmetic shift and then sign extend
737        let sign = (more as i8 >> 7) as Self;
738        let magic = denom.0.magic;
739        let mut q = Self::mullhi(magic, numer);
740        q += numer;
741
742        // If q is non-negative, we have nothing to do
743        // If q is negative, we want to add either (2**shift)-1 if d is a power of
744        // 2, or (2**shift) if it is not a power of 2
745        let is_power_of_2 = u32::from(magic == 0);
746        let q_sign = (q >> 31) as u32;
747        q += (q_sign & ((1 << shift) - is_power_of_2)) as Self;
748
749        // Now arithmetic right shift
750        q >>= shift;
751        // Negate if needed
752        q = (q ^ sign).wrapping_sub(sign);
753
754        q
755    }
756}
757
758impl core::ops::Div<&Divider<Self>> for u64 {
759    type Output = Self;
760
761    #[inline]
762    fn div(self, denom: &Divider<Self>) -> Self::Output {
763        self.unsigned_div_by(denom)
764    }
765}
766
767impl core::ops::Div<&BranchFreeDivider<Self>> for u64 {
768    type Output = Self;
769
770    #[inline]
771    fn div(self, denom: &BranchFreeDivider<Self>) -> Self::Output {
772        self.unsigned_branchfree_div_by(denom)
773    }
774}
775
776impl core::ops::Div<&Divider<Self>> for i64 {
777    type Output = Self;
778
779    #[inline]
780    fn div(self, denom: &Divider<Self>) -> Self::Output {
781        let numer = self;
782        let more = denom.0.more;
783        let shift = more & Self::SHIFT_MASK;
784
785        if 0 == denom.0.magic {
786            let sign = (more as i8 >> 7) as u64;
787            let mask = (1u64 << shift) - 1;
788            let uq = (numer as u64).wrapping_add((numer >> 63) as u64 & mask);
789            let mut q = uq as Self;
790            q >>= shift;
791            q = (q as u64 ^ sign).wrapping_sub(sign) as Self;
792            q
793        } else {
794            let mut uq = Self::mullhi(denom.0.magic, numer) as u64;
795            if 0 != (more & ADD_MARKER) {
796                // must be arithmetic shift and then sign extend
797                let sign = (more as i8 >> 7) as Self;
798                // q += (more < 0 ? -numer : numer)
799                // cast required to avoid UB
800                uq = uq.wrapping_add(((numer as u64) ^ (sign as u64)).wrapping_sub(sign as u64));
801            }
802            let mut q = uq as Self;
803            q >>= shift;
804            q += Self::from(q < 0);
805            q
806        }
807    }
808}
809
810impl core::ops::Div<&BranchFreeDivider<Self>> for i64 {
811    type Output = Self;
812
813    #[inline]
814    fn div(self, denom: &BranchFreeDivider<Self>) -> Self::Output {
815        let numer = self;
816        let more = denom.0.more;
817        let shift = more & Self::SHIFT_MASK;
818        // must be arithmetic shift and then sign extend
819        let sign = (more as i8 >> 7) as Self;
820        let magic = denom.0.magic;
821        let mut q = Self::mullhi(magic, numer);
822        q += numer;
823
824        // If q is non-negative, we have nothing to do
825        // If q is negative, we want to add either (2**shift)-1 if d is a power of
826        // 2, or (2**shift) if it is not a power of 2
827        let is_power_of_2 = u64::from(magic == 0);
828        let q_sign = (q >> 63) as u64;
829        q += (q_sign & ((1 << shift) - is_power_of_2)) as Self;
830
831        // Now arithmetic right shift
832        q >>= shift;
833        // Negate if needed
834        q = (q ^ sign).wrapping_sub(sign);
835
836        q
837    }
838}