cranelift: Add fadd/fsub/fmul/fdiv to interpreter (#4446)
Fuzzgen found these as soon as I added float support
This commit is contained in:
@@ -18,6 +18,7 @@ pub trait Value: Clone + From<DataValue> {
|
||||
fn into_int(self) -> ValueResult<i128>;
|
||||
fn float(n: u64, ty: Type) -> ValueResult<Self>;
|
||||
fn into_float(self) -> ValueResult<f64>;
|
||||
fn is_float(&self) -> bool;
|
||||
fn is_nan(&self) -> ValueResult<bool>;
|
||||
fn bool(b: bool, ty: Type) -> ValueResult<Self>;
|
||||
fn into_bool(self) -> ValueResult<bool>;
|
||||
@@ -250,6 +251,13 @@ impl Value for DataValue {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn is_float(&self) -> bool {
|
||||
match self {
|
||||
DataValue::F32(_) | DataValue::F64(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn is_nan(&self) -> ValueResult<bool> {
|
||||
match self {
|
||||
DataValue::F32(f) => Ok(f.is_nan()),
|
||||
@@ -457,19 +465,34 @@ impl Value for DataValue {
|
||||
}
|
||||
|
||||
fn add(self, other: Self) -> ValueResult<Self> {
|
||||
// TODO: floats must handle NaNs, +/-0
|
||||
binary_match!(wrapping_add(&self, &other); [I8, I16, I32, I64, I128, U8, U16, U32, U64, U128])
|
||||
if self.is_float() {
|
||||
binary_match!(+(self, other); [F32, F64])
|
||||
} else {
|
||||
binary_match!(wrapping_add(&self, &other); [I8, I16, I32, I64, I128, U8, U16, U32, U64, U128])
|
||||
}
|
||||
}
|
||||
|
||||
fn sub(self, other: Self) -> ValueResult<Self> {
|
||||
binary_match!(wrapping_sub(&self, &other); [I8, I16, I32, I64, I128]) // TODO: floats must handle NaNs, +/-0
|
||||
if self.is_float() {
|
||||
binary_match!(-(self, other); [F32, F64])
|
||||
} else {
|
||||
binary_match!(wrapping_sub(&self, &other); [I8, I16, I32, I64, I128])
|
||||
}
|
||||
}
|
||||
|
||||
fn mul(self, other: Self) -> ValueResult<Self> {
|
||||
binary_match!(wrapping_mul(&self, &other); [I8, I16, I32, I64, I128])
|
||||
if self.is_float() {
|
||||
binary_match!(*(self, other); [F32, F64])
|
||||
} else {
|
||||
binary_match!(wrapping_mul(&self, &other); [I8, I16, I32, I64, I128])
|
||||
}
|
||||
}
|
||||
|
||||
fn div(self, other: Self) -> ValueResult<Self> {
|
||||
if self.is_float() {
|
||||
return binary_match!(/(self, other); [F32, F64]);
|
||||
}
|
||||
|
||||
let denominator = other.clone().into_int()?;
|
||||
|
||||
// Check if we are dividing INT_MIN / -1. This causes an integer overflow trap.
|
||||
|
||||
Reference in New Issue
Block a user