@@ -40,9 +40,44 @@ pub fn f64_to_wrapping_u32(n: f64) -> u32 {
4040/// Converts an `f64` to an `i32` with ECMAScript `ToInt32` wrapping behavior.
4141/// The value will be wrapped in the range [-2^31, 2^31).
4242pub fn f64_to_wrapping_i32 ( n : f64 ) -> i32 {
43+ #[ cfg( feature = "aarch64_jsconv" ) ]
44+ {
45+ #[ cfg( all( target_arch = "aarch64" , target_feature = "jsconv" ) ) ]
46+ unsafe {
47+ f64_to_wrapping_int32_aarch64 ( n)
48+ }
49+ #[ cfg( not( all( target_arch = "aarch64" , target_feature = "jsconv" ) ) ) ]
50+ f64_to_wrapping_i32_generic ( n)
51+ }
52+ #[ cfg( not( feature = "aarch64_jsconv" ) ) ]
53+ f64_to_wrapping_i32_generic ( n)
54+ }
55+
56+ #[ allow( unused) ]
57+ fn f64_to_wrapping_i32_generic ( n : f64 ) -> i32 {
4358 f64_to_wrapping_u32 ( n) as i32
4459}
4560
61+ #[ allow( unused) ]
62+ #[ cfg( feature = "aarch64_jsconv" ) ]
63+ #[ cfg( target_arch = "aarch64" ) ]
64+ #[ target_feature( enable = "jsconv" ) ]
65+ /// Converts an `f64` to an `i32` with ECMAScript `ToInt32` wrapping behavior.
66+ /// The value will be wrapped in the range [-2^31, 2^31).
67+ /// Optimized for aarch64 cpu with the fjcvtzs instruction.
68+ unsafe fn f64_to_wrapping_int32_aarch64 ( number : f64 ) -> i32 {
69+ let ret: i32 ;
70+ // SAFETY: fjcvtzs instruction is available under jsconv feature.
71+ unsafe {
72+ std:: arch:: asm!(
73+ "fjcvtzs {dst:w}, {src:d}" ,
74+ src = in( vreg) number,
75+ dst = out( reg) ret,
76+ ) ;
77+ }
78+ ret
79+ }
80+
4681/// Implements the IEEE-754 "Round to nearest, ties to even" rounding rule.
4782/// (e.g., both 1.5 and 2.5 will round to 2).
4883/// This also clamps out-of-range values and NaN to `i32::MIN`.
0 commit comments