mirror of
https://github.com/fluencelabs/parity-wasm
synced 2025-06-27 05:32:07 +00:00
f32_bitwise && f64_bitwise
This commit is contained in:
@ -9,5 +9,7 @@ macro_rules! run_test {
|
|||||||
|
|
||||||
run_test!("i32", wasm_i32);
|
run_test!("i32", wasm_i32);
|
||||||
run_test!("f32", wasm_f32);
|
run_test!("f32", wasm_f32);
|
||||||
|
run_test!("f32_bitwise", wasm_f32_bitwise);
|
||||||
run_test!("f64", wasm_f64);
|
run_test!("f64", wasm_f64);
|
||||||
|
run_test!("f64_bitwise", wasm_f64_bitwise);
|
||||||
run_test!("endianness", wasm_endianness);
|
run_test!("endianness", wasm_endianness);
|
||||||
|
@ -108,7 +108,21 @@ pub fn spec(name: &str) {
|
|||||||
Ok(result) => {
|
Ok(result) => {
|
||||||
let spec_expected = runtime_values(expected);
|
let spec_expected = runtime_values(expected);
|
||||||
let actual_result = result.into_iter().collect::<Vec<parity_wasm::RuntimeValue>>();
|
let actual_result = result.into_iter().collect::<Vec<parity_wasm::RuntimeValue>>();
|
||||||
assert_eq!(actual_result, spec_expected);
|
for (actual_result, spec_expected) in actual_result.iter().zip(spec_expected.iter()) {
|
||||||
|
assert_eq!(actual_result.variable_type(), spec_expected.variable_type());
|
||||||
|
// f32::NAN != f32::NAN
|
||||||
|
match spec_expected {
|
||||||
|
&RuntimeValue::F32(val) if val.is_nan() => match actual_result {
|
||||||
|
&RuntimeValue::F32(val) => assert!(val.is_nan()),
|
||||||
|
_ => unreachable!(), // checked above that types are same
|
||||||
|
},
|
||||||
|
&RuntimeValue::F64(val) if val.is_nan() => match actual_result {
|
||||||
|
&RuntimeValue::F64(val) => assert!(val.is_nan()),
|
||||||
|
_ => unreachable!(), // checked above that types are same
|
||||||
|
},
|
||||||
|
spec_expected @ _ => assert_eq!(actual_result, spec_expected),
|
||||||
|
}
|
||||||
|
}
|
||||||
println!("assert_return at line {} - success", line);
|
println!("assert_return at line {} - success", line);
|
||||||
},
|
},
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
@ -599,7 +599,7 @@ impl_integer!(i64);
|
|||||||
impl_integer!(u64);
|
impl_integer!(u64);
|
||||||
|
|
||||||
macro_rules! impl_float {
|
macro_rules! impl_float {
|
||||||
($type: ident) => {
|
($type: ident, $int_type: ident) => {
|
||||||
impl Float<$type> for $type {
|
impl Float<$type> for $type {
|
||||||
fn abs(self) -> $type { self.abs() }
|
fn abs(self) -> $type { self.abs() }
|
||||||
fn floor(self) -> $type { self.floor() }
|
fn floor(self) -> $type { self.floor() }
|
||||||
@ -641,16 +641,28 @@ macro_rules! impl_float {
|
|||||||
self.max(other)
|
self.max(other)
|
||||||
}
|
}
|
||||||
fn copysign(self, other: $type) -> $type {
|
fn copysign(self, other: $type) -> $type {
|
||||||
// TODO: this may be buggy for edge cases
|
use std::mem::size_of;
|
||||||
if self.is_sign_positive() == other.is_sign_positive() {
|
|
||||||
|
if self.is_nan() {
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
let sign_mask: $int_type = 1 << ((size_of::<$int_type>() << 3) - 1);
|
||||||
|
let self_int: $int_type = self.transmute_into();
|
||||||
|
let other_int: $int_type = other.transmute_into();
|
||||||
|
let is_self_sign_set = (self_int & sign_mask) != 0;
|
||||||
|
let is_other_sign_set = (other_int & sign_mask) != 0;
|
||||||
|
if is_self_sign_set == is_other_sign_set {
|
||||||
self
|
self
|
||||||
|
} else if is_other_sign_set {
|
||||||
|
(self_int | sign_mask).transmute_into()
|
||||||
} else {
|
} else {
|
||||||
self * -1.0
|
(self_int & !sign_mask).transmute_into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_float!(f32);
|
impl_float!(f32, i32);
|
||||||
impl_float!(f64);
|
impl_float!(f64, i64);
|
||||||
|
Reference in New Issue
Block a user