373: Rj/dsp tweaks r=jordens a=jordens

* saturating_scale fixes and docs

Co-authored-by: Robert Jördens <rj@quartiq.de>
This commit is contained in:
bors[bot] 2021-06-01 15:01:13 +00:00 committed by GitHub
commit 5be7d175c1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 23 additions and 17 deletions

View File

@ -77,6 +77,8 @@ pub fn atan2(y: i32, x: i32) -> i32 {
if sign.1 { if sign.1 {
angle = angle.wrapping_neg(); angle = angle.wrapping_neg();
// Negation ends up in slightly faster assembly
// angle = !angle;
} }
angle angle

View File

@ -87,20 +87,3 @@ pub fn macc_i32(y0: i32, x: &[i32], a: &[i32], shift: u32) -> i32 {
.fold(y0, |y, xa| y + xa); .fold(y0, |y, xa| y + xa);
(y >> shift) as i32 (y >> shift) as i32
} }
/// Combine high and low i32 into a single downscaled i32, saturating the type.
pub fn saturating_scale(lo: i32, hi: i32, shift: u32) -> i32 {
debug_assert!(shift & 31 == shift);
let shift_hi = 31 - shift;
debug_assert!(shift_hi & 31 == shift_hi);
let over = hi >> shift;
if over < -1 {
i32::MIN
} else if over > 0 {
i32::MAX
} else {
(lo >> shift) + (hi << shift_hi)
}
}

View File

@ -16,6 +16,27 @@ pub fn overflowing_sub(y: i32, x: i32) -> (i32, i8) {
(delta, wrap) (delta, wrap)
} }
/// Combine high and low i32 into a single downscaled i32, saturating monotonically.
///
/// Args:
/// `lo`: LSB i32 to scale down by `shift` and range-extend with `hi`
/// `hi`: MSB i32 to scale up and extend `lo` with. Output will be clipped if
/// `hi` exceeds the output i32 range.
/// `shift`: Downscale `lo` by that many bits. Values from 1 to 32 inclusive
/// are valid.
pub fn saturating_scale(lo: i32, hi: i32, shift: u32) -> i32 {
debug_assert!(shift > 0);
debug_assert!(shift <= 32);
let hi_range = -1 << (shift - 1);
if hi <= hi_range {
i32::MIN - hi_range
} else if -hi <= hi_range {
hi_range - i32::MIN
} else {
(lo >> shift) + (hi << (32 - shift))
}
}
/// Overflow unwrapper. /// Overflow unwrapper.
/// ///
/// This is unwrapping as in the phase and overflow unwrapping context, not /// This is unwrapping as in the phase and overflow unwrapping context, not