From d6dbc0e83081e057db3140d27bc9afecb01b5218 Mon Sep 17 00:00:00 2001 From: Chris Fallin Date: Thu, 23 Feb 2023 19:31:51 -0800 Subject: [PATCH] Fill in some missing FP ops in interpreter --- src/interp.rs | 120 ++++++++++++++++++++++++++++++++++++++++++++++- src/op_traits.rs | 2 +- 2 files changed, 119 insertions(+), 3 deletions(-) diff --git a/src/interp.rs b/src/interp.rs index f117468..b5a9e33 100644 --- a/src/interp.rs +++ b/src/interp.rs @@ -141,7 +141,13 @@ impl InterpContext { multivalue[0] }) .collect::>(); - let result = const_eval(op, &args[..], Some(self))?; + let result = match const_eval(op, &args[..], Some(self)) { + Some(result) => result, + None => { + log::trace!("const_eval failed on {:?} args {:?}", op, args); + return None; + } + }; smallvec![result] } &ValueDef::None | &ValueDef::Placeholder(..) | &ValueDef::BlockParam(..) => { @@ -361,6 +367,92 @@ pub fn const_eval( Some(ConstVal::I32(if a >= b { 1 } else { 0 })) } + (Operator::F32Eq, [ConstVal::F32(a), ConstVal::F32(b)]) => { + Some(ConstVal::I32(if f32::from_bits(*a) == f32::from_bits(*b) { + 1 + } else { + 0 + })) + } + (Operator::F32Ne, [ConstVal::F32(a), ConstVal::F32(b)]) => { + Some(ConstVal::I32(if f32::from_bits(*a) != f32::from_bits(*b) { + 1 + } else { + 0 + })) + } + (Operator::F32Lt, [ConstVal::F32(a), ConstVal::F32(b)]) => { + Some(ConstVal::I32(if f32::from_bits(*a) < f32::from_bits(*b) { + 1 + } else { + 0 + })) + } + (Operator::F32Gt, [ConstVal::F32(a), ConstVal::F32(b)]) => { + Some(ConstVal::I32(if f32::from_bits(*a) > f32::from_bits(*b) { + 1 + } else { + 0 + })) + } + (Operator::F32Le, [ConstVal::F32(a), ConstVal::F32(b)]) => { + Some(ConstVal::I32(if f32::from_bits(*a) <= f32::from_bits(*b) { + 1 + } else { + 0 + })) + } + (Operator::F32Ge, [ConstVal::F32(a), ConstVal::F32(b)]) => { + Some(ConstVal::I32(if f32::from_bits(*a) >= f32::from_bits(*b) { + 1 + } else { + 0 + })) + } + + (Operator::F64Eq, [ConstVal::F64(a), ConstVal::F64(b)]) => { + Some(ConstVal::I32(if f64::from_bits(*a) == f64::from_bits(*b) { + 1 + } else { + 0 + })) + } + (Operator::F64Ne, [ConstVal::F64(a), ConstVal::F64(b)]) => { + Some(ConstVal::I32(if f64::from_bits(*a) != f64::from_bits(*b) { + 1 + } else { + 0 + })) + } + (Operator::F64Lt, [ConstVal::F64(a), ConstVal::F64(b)]) => { + Some(ConstVal::I32(if f64::from_bits(*a) < f64::from_bits(*b) { + 1 + } else { + 0 + })) + } + (Operator::F64Gt, [ConstVal::F64(a), ConstVal::F64(b)]) => { + Some(ConstVal::I32(if f64::from_bits(*a) > f64::from_bits(*b) { + 1 + } else { + 0 + })) + } + (Operator::F64Le, [ConstVal::F64(a), ConstVal::F64(b)]) => { + Some(ConstVal::I32(if f64::from_bits(*a) <= f64::from_bits(*b) { + 1 + } else { + 0 + })) + } + (Operator::F64Ge, [ConstVal::F64(a), ConstVal::F64(b)]) => { + Some(ConstVal::I32(if f64::from_bits(*a) >= f64::from_bits(*b) { + 1 + } else { + 0 + })) + } + (Operator::I32Clz, [ConstVal::I32(x)]) => Some(ConstVal::I32(x.leading_zeros())), (Operator::I32Ctz, [ConstVal::I32(x)]) => Some(ConstVal::I32(x.trailing_zeros())), (Operator::I32Popcnt, [ConstVal::I32(x)]) => Some(ConstVal::I32(x.count_ones())), @@ -461,6 +553,9 @@ pub fn const_eval( (Operator::F32Floor, [ConstVal::F32(a)]) => { Some(ConstVal::F32(f32::from_bits(*a).floor().to_bits())) } + (Operator::F32Trunc, [ConstVal::F32(a)]) => { + Some(ConstVal::F32(f32::from_bits(*a).trunc().to_bits())) + } (Operator::F32Nearest, [ConstVal::F32(a)]) => { Some(ConstVal::F32(f32::from_bits(*a).round().to_bits())) } @@ -501,6 +596,9 @@ pub fn const_eval( (Operator::F64Floor, [ConstVal::F64(a)]) => { Some(ConstVal::F64(f64::from_bits(*a).floor().to_bits())) } + (Operator::F64Trunc, [ConstVal::F64(a)]) => { + Some(ConstVal::F64(f64::from_bits(*a).trunc().to_bits())) + } (Operator::F64Nearest, [ConstVal::F64(a)]) => { Some(ConstVal::F64(f64::from_bits(*a).round().to_bits())) } @@ -837,7 +935,25 @@ pub fn const_eval( ConstVal::None }) } - _ => None, + (Operator::F32Store { memory }, [ConstVal::I32(addr), ConstVal::F32(data)]) => { + ctx.map(|global| { + let addr = *addr + memory.offset; + write_u32(&mut global.memories[memory.memory], addr, *data); + ConstVal::None + }) + } + (Operator::F64Store { memory }, [ConstVal::I32(addr), ConstVal::F64(data)]) => { + ctx.map(|global| { + let addr = *addr + memory.offset; + write_u64(&mut global.memories[memory.memory], addr, *data); + ConstVal::None + }) + } + (op, args) => unimplemented!( + "Undefined operator or arg combination: {:?}, {:?}", + op, + args + ), } } diff --git a/src/op_traits.rs b/src/op_traits.rs index 663e57f..bda859f 100644 --- a/src/op_traits.rs +++ b/src/op_traits.rs @@ -678,7 +678,7 @@ impl std::fmt::Display for Operator { Operator::I32Store { memory } => write!(f, "i32store<{}>", memory)?, Operator::I64Store { memory } => write!(f, "i64store<{}>", memory)?, Operator::F32Store { memory } => write!(f, "f32store<{}>", memory)?, - Operator::F64Store { memory } => write!(f, "f642store<{}>", memory)?, + Operator::F64Store { memory } => write!(f, "f64store<{}>", memory)?, Operator::I32Store8 { memory } => write!(f, "i32store8<{}>", memory)?, Operator::I32Store16 { memory } => write!(f, "i32store16<{}>", memory)?, Operator::I64Store8 { memory } => write!(f, "i64store8<{}>", memory)?,