///|
/// Ports `softfloat_countLeadingZeros8` from `s_countLeadingZeros8.c`.
fn count_leading_zeros8(a : UInt32) -> Int32 {
let a = a & 0xFFU
if a >= 0x80U {
0
} else if a >= 0x40U {
1
} else if a >= 0x20U {
2
} else if a >= 0x10U {
3
} else if a >= 0x08U {
4
} else if a >= 0x04U {
5
} else if a >= 0x02U {
6
} else if a >= 0x01U {
7
} else {
8
}
}
///|
/// Ports `softfloat_countLeadingZeros16` from `s_countLeadingZeros16.c`.
fn count_leading_zeros16(a : UInt16) -> Int32 {
if a >= 0x0100 {
count_leading_zeros8((a >> 8).to_uint())
} else {
8 + count_leading_zeros8(a.to_uint())
}
}
///|
/// Ports `softfloat_countLeadingZeros32` from `s_countLeadingZeros32.c`.
fn count_leading_zeros32(a : UInt32) -> Int32 {
if a >= 0x01000000U {
count_leading_zeros8(a >> 24)
} else if a >= 0x00010000U {
8 + count_leading_zeros8(a >> 16)
} else if a >= 0x00000100U {
16 + count_leading_zeros8(a >> 8)
} else {
24 + count_leading_zeros8(a)
}
}
///|
/// Ports `softfloat_countLeadingZeros64` from `s_countLeadingZeros64.c`.
fn count_leading_zeros64(a : UInt64) -> Int32 {
let hi = (a >> 32).to_uint()
if hi != 0U {
count_leading_zeros32(hi)
} else {
32 + count_leading_zeros32(a.to_uint())
}
}
///|
fn jam_bit64(nonzero : Bool) -> UInt64 {
if nonzero {
1UL
} else {
0UL
}
}
///|
fn jam_bit32(nonzero : Bool) -> UInt32 {
if nonzero {
1U
} else {
0U
}
}
///|
/// Ports `softfloat_shiftRightJam32` from `s_shiftRightJam32.c`.
fn shift_right_jam32(a : UInt32, dist : Int32) -> UInt32 {
if dist <= 0 {
a
} else if dist < 32 {
let mask = (1U << dist) - 1U
(a >> dist) | jam_bit32((a & mask) != 0U)
} else {
jam_bit32(a != 0U)
}
}
///|
/// Ports `softfloat_shortShiftRightJam64` from `s_shortShiftRightJam64.c`.
fn short_shift_right_jam64(a : UInt64, dist : Int32) -> UInt64 {
shift_right_jam64(a, dist)
}
///|
/// Ports `softfloat_shiftRightJam64` from `s_shiftRightJam64.c`.
fn shift_right_jam64(a : UInt64, dist : Int32) -> UInt64 {
if dist <= 0 {
a
} else if dist < 64 {
let mask = (1UL << dist) - 1UL
(a >> dist) | jam_bit64((a & mask) != 0UL)
} else {
jam_bit64(a != 0UL)
}
}
///|
/// Ports `softfloat_shiftRightJam64Extra` from `s_shiftRightJam64Extra.c`.
fn shift_right_jam64_extra(
a : UInt64,
extra : UInt64,
dist : Int32,
) -> UInt64Extra {
if dist <= 0 {
{ value: a, extra, }
} else {
let shifted = if dist < 64 {
{ value: a >> dist, extra: a << (64 - dist), }
} else {
{ value: 0UL, extra: if dist == 64 { a } else { jam_bit64(a != 0UL) }, }
}
{ ..shifted, extra: shifted.extra | jam_bit64(extra != 0UL), }
}
}
///|
/// Ports `softfloat_shortShiftRightJam128` from `s_shortShiftRightJam128.c`.
fn short_shift_right_jam128(a : UInt128, dist : Int32) -> UInt128 {
if dist <= 0 {
a
} else if dist < 64 {
let mask = (1UL << dist) - 1UL
{
hi: a.hi >> dist,
lo: (a.hi << (64 - dist)) |
(a.lo >> dist) |
jam_bit64((a.lo & mask) != 0UL),
}
} else {
shift_right_jam128(a, dist)
}
}
///|
/// Ports `softfloat_shiftRightJam128` from `s_shiftRightJam128.c`.
fn shift_right_jam128(a : UInt128, dist : Int32) -> UInt128 {
if dist <= 0 {
a
} else if dist < 64 {
short_shift_right_jam128(a, dist)
} else if dist < 128 {
let word_dist = dist - 64
let shifted = if word_dist == 0 { a.hi } else { a.hi >> word_dist }
let jammed = if word_dist == 0 {
a.lo != 0UL
} else {
((a.hi & ((1UL << word_dist) - 1UL)) | a.lo) != 0UL
}
{ hi: 0UL, lo: shifted | jam_bit64(jammed), }
} else {
{ hi: 0UL, lo: jam_bit64(!uint128_is_zero(a)), }
}
}