Implement fma/fabs/fneg/fcopysign on the interpreter (#4367)
* cranelift: Implement `fma` on interpreter * cranelift: Implement `fabs` on interpreter * cranelift: Fix `fneg` implementation on interpreter `fneg` was implemented as `0 - x` which is not correct according to the standard since that operation makes no guarantees on what the output is when the input is `NaN`. However for `fneg` the output for `NaN` inputs is fully defined. * cranelift: Implement `fcopysign` on interpreter
This commit is contained in:
@@ -51,6 +51,12 @@ pub trait Value: Clone + From<DataValue> {
|
||||
fn div(self, other: Self) -> ValueResult<Self>;
|
||||
fn rem(self, other: Self) -> ValueResult<Self>;
|
||||
fn sqrt(self) -> ValueResult<Self>;
|
||||
fn fma(self, a: Self, b: Self) -> ValueResult<Self>;
|
||||
fn abs(self) -> ValueResult<Self>;
|
||||
|
||||
// Float operations
|
||||
fn neg(self) -> ValueResult<Self>;
|
||||
fn copysign(self, sign: Self) -> ValueResult<Self>;
|
||||
|
||||
// Saturating arithmetic.
|
||||
fn add_sat(self, other: Self) -> ValueResult<Self>;
|
||||
@@ -468,6 +474,30 @@ impl Value for DataValue {
|
||||
unary_match!(sqrt(&self); [F32, F64]; [Ieee32, Ieee64])
|
||||
}
|
||||
|
||||
fn fma(self, b: Self, c: Self) -> ValueResult<Self> {
|
||||
match (self, b, c) {
|
||||
(DataValue::F32(a), DataValue::F32(b), DataValue::F32(c)) => {
|
||||
Ok(DataValue::F32(a.mul_add(b, c)))
|
||||
}
|
||||
(DataValue::F64(a), DataValue::F64(b), DataValue::F64(c)) => {
|
||||
Ok(DataValue::F64(a.mul_add(b, c)))
|
||||
}
|
||||
(a, _b, _c) => Err(ValueError::InvalidType(ValueTypeClass::Float, a.ty())),
|
||||
}
|
||||
}
|
||||
|
||||
fn abs(self) -> ValueResult<Self> {
|
||||
unary_match!(abs(&self); [F32, F64])
|
||||
}
|
||||
|
||||
fn neg(self) -> ValueResult<Self> {
|
||||
unary_match!(neg(&self); [F32, F64])
|
||||
}
|
||||
|
||||
fn copysign(self, sign: Self) -> ValueResult<Self> {
|
||||
binary_match!(copysign(&self, &sign); [F32, F64])
|
||||
}
|
||||
|
||||
fn add_sat(self, other: Self) -> ValueResult<Self> {
|
||||
binary_match!(saturating_add(self, &other); [I8, I16, I32, I64, I128, U8, U16, U32, U64, U128])
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user