1use core::arch::asm;
11
12const ABOVE_I32F: f32 = 2147483648.0;
14const ABOVE_I32: f64 = 2147483648.0;
15const ROUNDS_ABOVE_I32: f64 = 2147483647.5;
16const ABOVE_I64: f64 = 9223372036854775808.0;
17
18#[inline]
20pub fn cvtt(x: f32) -> i32 {
21 if x < ABOVE_I32F { x as i32 } else { i32::MIN }
22}
23
24#[inline]
26pub fn cvt(x: f32) -> i32 {
27 let r: i32;
28 unsafe { asm!("fcvtns {0:w}, {1:s}", out(reg) r, in(vreg) x, options(pure, nomem, nostack)) };
30 if x < ABOVE_I32F { r } else { i32::MIN }
31}
32
33#[inline]
35pub fn sqrt(x: f32) -> f32 {
36 let r: f32;
37 unsafe { asm!("fsqrt {0:s}, {1:s}", out(vreg) r, in(vreg) x, options(pure, nomem, nostack)) };
39 if r.is_nan() { crate::portable::fx::arithmetic32(x, x, r) } else { r }
40}
41
42#[inline]
44pub fn minss(a: f32, b: f32) -> f32 {
45 if a < b { a } else { b }
46}
47
48#[inline]
50pub fn maxss(a: f32, b: f32) -> f32 {
51 if a > b { a } else { b }
52}
53
54#[inline]
56pub fn floor_i(x: f32) -> i32 {
57 let t = cvtt(x);
58 if (t as f32) > x { t.wrapping_sub(1) } else { t }
59}
60
61#[inline]
62pub fn ceil_i(x: f32) -> i32 {
63 let t = cvtt(x);
64 if (t as f32) < x { t.wrapping_add(1) } else { t }
65}
66
67#[inline]
70pub fn div255(x: u32) -> u32 {
71 debug_assert!(x < 1 << 24, "div255 is for x <= 65025");
72 ((x + 128) * 257) >> 16
73}
74
75#[inline]
79pub fn sqrtd(x: f64) -> f64 {
80 let r: f64;
81 unsafe { asm!("fsqrt {0:d}, {1:d}", out(vreg) r, in(vreg) x, options(pure, nomem, nostack)) };
83 if r.is_nan() { crate::portable::fx::arithmetic64(x, x, r) } else { r }
84}
85
86#[inline]
88pub fn maxsd(a: f64, b: f64) -> f64 {
89 if a > b { a } else { b }
90}
91
92#[inline]
94pub fn minsd(a: f64, b: f64) -> f64 {
95 if a < b { a } else { b }
96}
97
98#[inline]
100pub fn cvttd(x: f64) -> i32 {
101 if x < ABOVE_I32 { x as i32 } else { i32::MIN }
102}
103
104#[inline]
106pub fn cvtd(x: f64) -> i32 {
107 let r: i32;
108 unsafe { asm!("fcvtns {0:w}, {1:d}", out(reg) r, in(vreg) x, options(pure, nomem, nostack)) };
110 if x < ROUNDS_ABOVE_I32 { r } else { i32::MIN }
111}
112
113#[inline]
115pub fn cvtd64(x: f64) -> i64 {
116 let r: i64;
117 unsafe { asm!("fcvtns {0:x}, {1:d}", out(reg) r, in(vreg) x, options(pure, nomem, nostack)) };
119 if x < ABOVE_I64 { r } else { i64::MIN }
120}
121
122#[inline]
124pub fn cvttd64(x: f64) -> i64 {
125 if x < ABOVE_I64 { x as i64 } else { i64::MIN }
126}