Maybe fixed questionable code
This commit is contained in:
parent
975ce8a9fe
commit
fe9a0667b8
|
@ -9,13 +9,28 @@ macro_rules! fnsdef {
|
||||||
$vis fn $name(val: $from, mode: RoundingMode) -> $to {
|
$vis fn $name(val: $from, mode: RoundingMode) -> $to {
|
||||||
let result: $to;
|
let result: $to;
|
||||||
unsafe {
|
unsafe {
|
||||||
set_rounding_mode(mode);
|
if mode == RoundingMode::NearestEven {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let fpcr: u64;
|
||||||
|
unsafe { asm!("mrs {}, fpcr", out(reg) fpcr) };
|
||||||
|
|
||||||
|
let fpcr_new = fpcr & !(0b11 << 22)
|
||||||
|
| (match mode {
|
||||||
|
RoundingMode::NearestEven => 0b00,
|
||||||
|
RoundingMode::Truncate => 0b11,
|
||||||
|
RoundingMode::Up => 0b01,
|
||||||
|
RoundingMode::Down => 0b10,
|
||||||
|
}) << 22;
|
||||||
|
|
||||||
|
unsafe { asm!("msr fpcr, {}", in(reg) fpcr_new) };
|
||||||
asm!(
|
asm!(
|
||||||
$ins,
|
$ins,
|
||||||
out($outreg) result,
|
out($outreg) result,
|
||||||
in($inreg) val,
|
in($inreg) val,
|
||||||
);
|
);
|
||||||
default_rounding_mode();
|
unsafe { asm!("msr fpcr, {}", in(reg) fpcr) };
|
||||||
}
|
}
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
@ -32,35 +47,3 @@ fnsdef! {
|
||||||
/// Convert [`f64`] to [`i64`] with chosen rounding mode
|
/// Convert [`f64`] to [`i64`] with chosen rounding mode
|
||||||
pub fn f64toint[vreg -> reg](f64 -> i64): "fcvtzs {}, {:d}";
|
pub fn f64toint[vreg -> reg](f64 -> i64): "fcvtzs {}, {:d}";
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set rounding mode
|
|
||||||
///
|
|
||||||
/// # Safety
|
|
||||||
/// - Do not call if rounding mode isn't [`RoundingMode::NearestEven`]
|
|
||||||
/// - Do not perform any Rust FP operations until reset using
|
|
||||||
/// [`default_rounding_mode`], you have to rely on inline assembly
|
|
||||||
#[inline(always)]
|
|
||||||
unsafe fn set_rounding_mode(mode: RoundingMode) {
|
|
||||||
if mode == RoundingMode::NearestEven {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let fpcr: u64;
|
|
||||||
unsafe { asm!("mrs {}, fpcr", out(reg) fpcr) };
|
|
||||||
|
|
||||||
let fpcr = fpcr & !(0b11 << 22)
|
|
||||||
| (match mode {
|
|
||||||
RoundingMode::NearestEven => 0b00,
|
|
||||||
RoundingMode::Truncate => 0b11,
|
|
||||||
RoundingMode::Up => 0b01,
|
|
||||||
RoundingMode::Down => 0b10,
|
|
||||||
}) << 22;
|
|
||||||
|
|
||||||
unsafe { asm!("msr fpcr, {}", in(reg) fpcr) };
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
unsafe fn default_rounding_mode() {
|
|
||||||
// I hope so much it gets optimised
|
|
||||||
set_rounding_mode(RoundingMode::NearestEven);
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue