Repository: bytecodealliance/wasm-tools
Pull request #1818 (2024-09-24 05:30:34)

wasm-smith: Add config option to disallow floats
- Add finer-grained categories `InstructionKinds::NumericNonFloat`, `InstructionKinds::VectorNonFloat` and `InstructionKinds::MemoryNonFloat`
    - https://github.com/bytecodealliance/wasm-tools/pull/400#issuecomment-983114142
- Add a `wasm_smith::Config` option `allow_floats` toggling whether floating point types and instructions are generated.



Patch:
diff --git a/crates/wasm-smith/src/config.rs b/crates/wasm-smith/src/config.rs
index 97c707a0..8011dc13 100644
--- a/crates/wasm-smith/src/config.rs
+++ b/crates/wasm-smith/src/config.rs
@@ -253,6 +253,11 @@ define_config! {
         /// specification](https://webassembly.github.io/spec/core/syntax/instructions.html);
         /// e.g., numeric, vector, control, memory, etc.
         ///
+        /// Additionally, we include finer-grained categories which exclude floating point
+        /// instructions, e.g. [`InstructionKind::NumericInt`] is a subset of
+        /// [`InstructionKind::Numeric`] consisting of all numeric instructions which
+        /// don't involve floats.
+        ///
         /// Note that modifying this setting is separate from the proposal
         /// flags; that is, if `simd_enabled() == true` but
         /// `allowed_instruction()` does not include vector instructions, the
@@ -260,6 +265,11 @@ define_config! {
         /// contain vector types.
         pub allowed_instructions: InstructionKinds = InstructionKinds::all(),
 
+        /// Determines whether we generate floating point instructions and types.
+        ///
+        /// Defaults to `true`.
+        pub allow_floats: bool = true,
+
         /// Determines whether the bulk memory proposal is enabled for
         /// generating instructions.
         ///
@@ -698,6 +708,7 @@ impl<'a> Arbitrary<'a> for Config {
             table_max_size_required: u.arbitrary()?,
             max_table_elements: u.int_in_range(0..=1_000_000)?,
             disallow_traps: u.arbitrary()?,
+            allow_floats: u.arbitrary()?,
 
             // These fields, unlike the ones above, are less useful to set.
             // They either make weird inputs or are for features not widely
diff --git a/crates/wasm-smith/src/core.rs b/crates/wasm-smith/src/core.rs
index 2b0fc10b..0c18795b 100644
--- a/crates/wasm-smith/src/core.rs
+++ b/crates/wasm-smith/src/core.rs
@@ -1465,7 +1465,7 @@ impl Module {
     }
 
     fn arbitrary_valtype(&self, u: &mut Unstructured) -> Result<ValType> {
-        #[derive(Arbitrary)]
+        #[derive(PartialEq, Eq, PartialOrd, Ord)]
         enum ValTypeClass {
             I32,
             I64,
@@ -1475,25 +1475,28 @@ impl Module {
             Ref,
         }
 
-        match u.arbitrary::<ValTypeClass>()? {
+        let mut val_classes: Vec<_> = self
+            .valtypes
+            .iter()
+            .map(|vt| match vt {
+                ValType::I32 => ValTypeClass::I32,
+                ValType::I64 => ValTypeClass::I64,
+                ValType::F32 => ValTypeClass::F32,
+                ValType::F64 => ValTypeClass::F64,
+                ValType::V128 => ValTypeClass::V128,
+                ValType::Ref(_) => ValTypeClass::Ref,
+            })
+            .collect();
+        val_classes.sort_unstable();
+        val_classes.dedup();
+
+        match u.choose(&val_classes)? {
             ValTypeClass::I32 => Ok(ValType::I32),
             ValTypeClass::I64 => Ok(ValType::I64),
             ValTypeClass::F32 => Ok(ValType::F32),
             ValTypeClass::F64 => Ok(ValType::F64),
-            ValTypeClass::V128 => {
-                if self.config.simd_enabled {
-                    Ok(ValType::V128)
-                } else {
-                    Ok(ValType::I32)
-                }
-            }
-            ValTypeClass::Ref => {
-                if self.config.reference_types_enabled {
-                    Ok(ValType::Ref(self.arbitrary_ref_type(u)?))
-                } else {
-                    Ok(ValType::I32)
-                }
-            }
+            ValTypeClass::V128 => Ok(ValType::V128),
+            ValTypeClass::Ref => Ok(ValType::Ref(self.arbitrary_ref_type(u)?)),
         }
     }
 
@@ -2482,12 +2485,14 @@ pub(crate) fn configured_valtypes(config: &Config) -> Vec<ValType> {
     let mut valtypes = Vec::with_capacity(25);
     valtypes.push(ValType::I32);
     valtypes.push(ValType::I64);
-    valtypes.push(ValType::F32);
-    valtypes.push(ValType::F64);
+    if config.allow_floats {
+        valtypes.push(ValType::F32);
+        valtypes.push(ValType::F64);
+    }
     if config.simd_enabled {
         valtypes.push(ValType::V128);
     }
-    if config.gc_enabled {
+    if config.gc_enabled && config.reference_types_enabled {
         for nullable in [
             // TODO: For now, only create allow nullable reference
             // types. Eventually we should support non-nullable reference types,
@@ -2808,6 +2813,24 @@ impl InstructionKinds {
     pub fn contains(&self, kind: InstructionKind) -> bool {
         self.0.contains(kind)
     }
+
+    /// Restrict each [InstructionKind] to its subset not involving floats
+    pub fn without_floats(&self) -> Self {
+        let mut floatless = self.0;
+        if floatless.contains(InstructionKind::Numeric) {
+            floatless -= InstructionKind::Numeric;
+            floatless |= InstructionKind::NumericInt;
+        }
+        if floatless.contains(InstructionKind::Vector) {
+            floatless -= InstructionKind::Vector;
+            floatless |= InstructionKind::VectorInt;
+        }
+        if floatless.contains(InstructionKind::Memory) {
+            floatless -= InstructionKind::Memory;
+            floatless |= InstructionKind::MemoryInt;
+        }
+        Self(floatless)
+    }
 }
 
 flags! {
@@ -2816,15 +2839,18 @@ flags! {
     #[allow(missing_docs)]
     #[cfg_attr(feature = "_internal_cli", derive(serde_derive::Deserialize))]
     pub enum InstructionKind: u16 {
-        Numeric,
-        Vector,
-        Reference,
-        Parametric,
-        Variable,
-        Table,
-        Memory,
-        Control,
-        Aggregate,
+        NumericInt = 1 << 0,
+        Numeric = (1 << 1) | (1 << 0),
+        VectorInt = 1 << 2,
+        Vector = (1 << 3) | (1 << 2),
+        Reference = 1 << 4,
+        Parametric = 1 << 5,
+        Variable = 1 << 6,
+        Table = 1 << 7,
+        MemoryInt = 1 << 8,
+        Memory = (1 << 9) | (1 << 8),
+        Control = 1 << 10,
+        Aggregate = 1 << 11,
     }
 }
 
@@ -2844,12 +2870,15 @@ impl FromStr for InstructionKind {
     type Err = String;
     fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
         match s.to_lowercase().as_str() {
+            "numeric_non_float" => Ok(InstructionKind::NumericInt),
             "numeric" => Ok(InstructionKind::Numeric),
+            "vector_non_float" => Ok(InstructionKind::VectorInt),
             "vector" => Ok(InstructionKind::Vector),
             "reference" => Ok(InstructionKind::Reference),
             "parametric" => Ok(InstructionKind::Parametric),
             "variable" => Ok(InstructionKind::Variable),
             "table" => Ok(InstructionKind::Table),
+            "memory_non_float" => Ok(InstructionKind::MemoryInt),
             "memory" => Ok(InstructionKind::Memory),
             "control" => Ok(InstructionKind::Control),
             _ => Err(format!("unknown instruction kind: {}", s)),
diff --git a/crates/wasm-smith/src/core/code_builder.rs b/crates/wasm-smith/src/core/code_builder.rs
index f06340ae..8f63a196 100644
--- a/crates/wasm-smith/src/core/code_builder.rs
+++ b/crates/wasm-smith/src/core/code_builder.rs
@@ -126,62 +126,62 @@ instructions! {
     (Some(global_get_valid), global_get, Variable),
     (Some(global_set_valid), global_set, Variable),
     // Memory instructions.
-    (Some(have_memory_and_offset), i32_load, Memory),
-    (Some(have_memory_and_offset), i64_load, Memory),
+    (Some(have_memory_and_offset), i32_load, MemoryInt),
+    (Some(have_memory_and_offset), i64_load, MemoryInt),
     (Some(have_memory_and_offset), f32_load, Memory),
     (Some(have_memory_and_offset), f64_load, Memory),
-    (Some(have_memory_and_offset), i32_load_8_s, Memory),
-    (Some(have_memory_and_offset), i32_load_8_u, Memory),
-    (Some(have_memory_and_offset), i32_load_16_s, Memory),
-    (Some(have_memory_and_offset), i32_load_16_u, Memory),
-    (Some(have_memory_and_offset), i64_load_8_s, Memory),
-    (Some(have_memory_and_offset), i64_load_16_s, Memory),
-    (Some(have_memory_and_offset), i64_load_32_s, Memory),
-    (Some(have_memory_and_offset), i64_load_8_u, Memory),
-    (Some(have_memory_and_offset), i64_load_16_u, Memory),
-    (Some(have_memory_and_offset), i64_load_32_u, Memory),
-    (Some(i32_store_valid), i32_store, Memory),
-    (Some(i64_store_valid), i64_store, Memory),
+    (Some(have_memory_and_offset), i32_load_8_s, MemoryInt),
+    (Some(have_memory_and_offset), i32_load_8_u, MemoryInt),
+    (Some(have_memory_and_offset), i32_load_16_s, MemoryInt),
+    (Some(have_memory_and_offset), i32_load_16_u, MemoryInt),
+    (Some(have_memory_and_offset), i64_load_8_s, MemoryInt),
+    (Some(have_memory_and_offset), i64_load_16_s, MemoryInt),
+    (Some(have_memory_and_offset), i64_load_32_s, MemoryInt),
+    (Some(have_memory_and_offset), i64_load_8_u, MemoryInt),
+    (Some(have_memory_and_offset), i64_load_16_u, MemoryInt),
+    (Some(have_memory_and_offset), i64_load_32_u, MemoryInt),
+    (Some(i32_store_valid), i32_store, MemoryInt),
+    (Some(i64_store_valid), i64_store, MemoryInt),
     (Some(f32_store_valid), f32_store, Memory),
     (Some(f64_store_valid), f64_store, Memory),
-    (Some(i32_store_valid), i32_store_8, Memory),
-    (Some(i32_store_valid), i32_store_16, Memory),
-    (Some(i64_store_valid), i64_store_8, Memory),
-    (Some(i64_store_valid), i64_store_16, Memory),
-    (Some(i64_store_valid), i64_store_32, Memory),
-    (Some(have_memory), memory_size, Memory),
-    (Some(memory_grow_valid), memory_grow, Memory),
-    (Some(memory_init_valid), memory_init, Memory),
-    (Some(data_drop_valid), data_drop, Memory),
-    (Some(memory_copy_valid), memory_copy, Memory),
-    (Some(memory_fill_valid), memory_fill, Memory),
+    (Some(i32_store_valid), i32_store_8, MemoryInt),
+    (Some(i32_store_valid), i32_store_16, MemoryInt),
+    (Some(i64_store_valid), i64_store_8, MemoryInt),
+    (Some(i64_store_valid), i64_store_16, MemoryInt),
+    (Some(i64_store_valid), i64_store_32, MemoryInt),
+    (Some(have_memory), memory_size, MemoryInt),
+    (Some(memory_grow_valid), memory_grow, MemoryInt),
+    (Some(memory_init_valid), memory_init, MemoryInt),
+    (Some(data_drop_valid), data_drop, MemoryInt),
+    (Some(memory_copy_valid), memory_copy, MemoryInt),
+    (Some(memory_fill_valid), memory_fill, MemoryInt),
     // Numeric instructions.
-    (None, i32_const, Numeric),
-    (None, i64_const, Numeric),
+    (None, i32_const, NumericInt),
+    (None, i64_const, NumericInt),
     (None, f32_const, Numeric),
     (None, f64_const, Numeric),
-    (Some(i32_on_stack), i32_eqz, Numeric),
-    (Some(i32_i32_on_stack), i32_eq, Numeric),
-    (Some(i32_i32_on_stack), i32_ne, Numeric),
-    (Some(i32_i32_on_stack), i32_lt_s, Numeric),
-    (Some(i32_i32_on_stack), i32_lt_u, Numeric),
-    (Some(i32_i32_on_stack), i32_gt_s, Numeric),
-    (Some(i32_i32_on_stack), i32_gt_u, Numeric),
-    (Some(i32_i32_on_stack), i32_le_s, Numeric),
-    (Some(i32_i32_on_stack), i32_le_u, Numeric),
-    (Some(i32_i32_on_stack), i32_ge_s, Numeric),
-    (Some(i32_i32_on_stack), i32_ge_u, Numeric),
-    (Some(i64_on_stack), i64_eqz, Numeric),
-    (Some(i64_i64_on_stack), i64_eq, Numeric),
-    (Some(i64_i64_on_stack), i64_ne, Numeric),
-    (Some(i64_i64_on_stack), i64_lt_s, Numeric),
-    (Some(i64_i64_on_stack), i64_lt_u, Numeric),
-    (Some(i64_i64_on_stack), i64_gt_s, Numeric),
-    (Some(i64_i64_on_stack), i64_gt_u, Numeric),
-    (Some(i64_i64_on_stack), i64_le_s, Numeric),
-    (Some(i64_i64_on_stack), i64_le_u, Numeric),
-    (Some(i64_i64_on_stack), i64_ge_s, Numeric),
-    (Some(i64_i64_on_stack), i64_ge_u, Numeric),
+    (Some(i32_on_stack), i32_eqz, NumericInt),
+    (Some(i32_i32_on_stack), i32_eq, NumericInt),
+    (Some(i32_i32_on_stack), i32_ne, NumericInt),
+    (Some(i32_i32_on_stack), i32_lt_s, NumericInt),
+    (Some(i32_i32_on_stack), i32_lt_u, NumericInt),
+    (Some(i32_i32_on_stack), i32_gt_s, NumericInt),
+    (Some(i32_i32_on_stack), i32_gt_u, NumericInt),
+    (Some(i32_i32_on_stack), i32_le_s, NumericInt),
+    (Some(i32_i32_on_stack), i32_le_u, NumericInt),
+    (Some(i32_i32_on_stack), i32_ge_s, NumericInt),
+    (Some(i32_i32_on_stack), i32_ge_u, NumericInt),
+    (Some(i64_on_stack), i64_eqz, NumericInt),
+    (Some(i64_i64_on_stack), i64_eq, NumericInt),
+    (Some(i64_i64_on_stack), i64_ne, NumericInt),
+    (Some(i64_i64_on_stack), i64_lt_s, NumericInt),
+    (Some(i64_i64_on_stack), i64_lt_u, NumericInt),
+    (Some(i64_i64_on_stack), i64_gt_s, NumericInt),
+    (Some(i64_i64_on_stack), i64_gt_u, NumericInt),
+    (Some(i64_i64_on_stack), i64_le_s, NumericInt),
+    (Some(i64_i64_on_stack), i64_le_u, NumericInt),
+    (Some(i64_i64_on_stack), i64_ge_s, NumericInt),
+    (Some(i64_i64_on_stack), i64_ge_u, NumericInt),
     (Some(f32_f32_on_stack), f32_eq, Numeric),
     (Some(f32_f32_on_stack), f32_ne, Numeric),
     (Some(f32_f32_on_stack), f32_lt, Numeric),
@@ -194,42 +194,42 @@ instructions! {
     (Some(f64_f64_on_stack), f64_gt, Numeric),
     (Some(f64_f64_on_stack), f64_le, Numeric),
     (Some(f64_f64_on_stack), f64_ge, Numeric),
-    (Some(i32_on_stack), i32_clz, Numeric),
-    (Some(i32_on_stack), i32_ctz, Numeric),
-    (Some(i32_on_stack), i32_popcnt, Numeric),
-    (Some(i32_i32_on_stack), i32_add, Numeric),
-    (Some(i32_i32_on_stack), i32_sub, Numeric),
-    (Some(i32_i32_on_stack), i32_mul, Numeric),
-    (Some(i32_i32_on_stack), i32_div_s, Numeric),
-    (Some(i32_i32_on_stack), i32_div_u, Numeric),
-    (Some(i32_i32_on_stack), i32_rem_s, Numeric),
-    (Some(i32_i32_on_stack), i32_rem_u, Numeric),
-    (Some(i32_i32_on_stack), i32_and, Numeric),
-    (Some(i32_i32_on_stack), i32_or, Numeric),
-    (Some(i32_i32_on_stack), i32_xor, Numeric),
-    (Some(i32_i32_on_stack), i32_shl, Numeric),
-    (Some(i32_i32_on_stack), i32_shr_s, Numeric),
-    (Some(i32_i32_on_stack), i32_shr_u, Numeric),
-    (Some(i32_i32_on_stack), i32_rotl, Numeric),
-    (Some(i32_i32_on_stack), i32_rotr, Numeric),
-    (Some(i64_on_stack), i64_clz, Numeric),
-    (Some(i64_on_stack), i64_ctz, Numeric),
-    (Some(i64_on_stack), i64_popcnt, Numeric),
-    (Some(i64_i64_on_stack), i64_add, Numeric),
-    (Some(i64_i64_on_stack), i64_sub, Numeric),
-    (Some(i64_i64_on_stack), i64_mul, Numeric),
-    (Some(i64_i64_on_stack), i64_div_s, Numeric),
-    (Some(i64_i64_on_stack), i64_div_u, Numeric),
-    (Some(i64_i64_on_stack), i64_rem_s, Numeric),
-    (Some(i64_i64_on_stack), i64_rem_u, Numeric),
-    (Some(i64_i64_on_stack), i64_and, Numeric),
-    (Some(i64_i64_on_stack), i64_or, Numeric),
-    (Some(i64_i64_on_stack), i64_xor, Numeric),
-    (Some(i64_i64_on_stack), i64_shl, Numeric),
-    (Some(i64_i64_on_stack), i64_shr_s, Numeric),
-    (Some(i64_i64_on_stack), i64_shr_u, Numeric),
-    (Some(i64_i64_on_stack), i64_rotl, Numeric),
-    (Some(i64_i64_on_stack), i64_rotr, Numeric),
+    (Some(i32_on_stack), i32_clz, NumericInt),
+    (Some(i32_on_stack), i32_ctz, NumericInt),
+    (Some(i32_on_stack), i32_popcnt, NumericInt),
+    (Some(i32_i32_on_stack), i32_add, NumericInt),
+    (Some(i32_i32_on_stack), i32_sub, NumericInt),
+    (Some(i32_i32_on_stack), i32_mul, NumericInt),
+    (Some(i32_i32_on_stack), i32_div_s, NumericInt),
+    (Some(i32_i32_on_stack), i32_div_u, NumericInt),
+    (Some(i32_i32_on_stack), i32_rem_s, NumericInt),
+    (Some(i32_i32_on_stack), i32_rem_u, NumericInt),
+    (Some(i32_i32_on_stack), i32_and, NumericInt),
+    (Some(i32_i32_on_stack), i32_or, NumericInt),
+    (Some(i32_i32_on_stack), i32_xor, NumericInt),
+    (Some(i32_i32_on_stack), i32_shl, NumericInt),
+    (Some(i32_i32_on_stack), i32_shr_s, NumericInt),
+    (Some(i32_i32_on_stack), i32_shr_u, NumericInt),
+    (Some(i32_i32_on_stack), i32_rotl, NumericInt),
+    (Some(i32_i32_on_stack), i32_rotr, NumericInt),
+    (Some(i64_on_stack), i64_clz, NumericInt),
+    (Some(i64_on_stack), i64_ctz, NumericInt),
+    (Some(i64_on_stack), i64_popcnt, NumericInt),
+    (Some(i64_i64_on_stack), i64_add, NumericInt),
+    (Some(i64_i64_on_stack), i64_sub, NumericInt),
+    (Some(i64_i64_on_stack), i64_mul, NumericInt),
+    (Some(i64_i64_on_stack), i64_div_s, NumericInt),
+    (Some(i64_i64_on_stack), i64_div_u, NumericInt),
+    (Some(i64_i64_on_stack), i64_rem_s, NumericInt),
+    (Some(i64_i64_on_stack), i64_rem_u, NumericInt),
+    (Some(i64_i64_on_stack), i64_and, NumericInt),
+    (Some(i64_i64_on_stack), i64_or, NumericInt),
+    (Some(i64_i64_on_stack), i64_xor, NumericInt),
+    (Some(i64_i64_on_stack), i64_shl, NumericInt),
+    (Some(i64_i64_on_stack), i64_shr_s, NumericInt),
+    (Some(i64_i64_on_stack), i64_shr_u, NumericInt),
+    (Some(i64_i64_on_stack), i64_rotl, NumericInt),
+    (Some(i64_i64_on_stack), i64_rotr, NumericInt),
     (Some(f32_on_stack), f32_abs, Numeric),
     (Some(f32_on_stack), f32_neg, Numeric),
     (Some(f32_on_stack), f32_ceil, Numeric),
@@ -258,13 +258,13 @@ instructions! {
     (Some(f64_f64_on_stack), f64_min, Numeric),
     (Some(f64_f64_on_stack), f64_max, Numeric),
     (Some(f64_f64_on_stack), f64_copysign, Numeric),
-    (Some(i64_on_stack), i32_wrap_i64, Numeric),
+    (Some(i64_on_stack), i32_wrap_i64, NumericInt),
     (Some(f32_on_stack), i32_trunc_f32_s, Numeric),
     (Some(f32_on_stack), i32_trunc_f32_u, Numeric),
     (Some(f64_on_stack), i32_trunc_f64_s, Numeric),
     (Some(f64_on_stack), i32_trunc_f64_u, Numeric),
-    (Some(i32_on_stack), i64_extend_i32_s, Numeric),
-    (Some(i32_on_stack), i64_extend_i32_u, Numeric),
+    (Some(i32_on_stack), i64_extend_i32_s, NumericInt),
+    (Some(i32_on_stack), i64_extend_i32_u, NumericInt),
     (Some(f32_on_stack), i64_trunc_f32_s, Numeric),
     (Some(f32_on_stack), i64_trunc_f32_u, Numeric),
     (Some(f64_on_stack), i64_trunc_f64_s, Numeric),
@@ -283,11 +283,11 @@ instructions! {
     (Some(f64_on_stack), i64_reinterpret_f64, Numeric),
     (Some(i32_on_stack), f32_reinterpret_i32, Numeric),
     (Some(i64_on_stack), f64_reinterpret_i64, Numeric),
-    (Some(extendable_i32_on_stack), i32_extend_8_s, Numeric),
-    (Some(extendable_i32_on_stack), i32_extend_16_s, Numeric),
-    (Some(extendable_i64_on_stack), i64_extend_8_s, Numeric),
-    (Some(extendable_i64_on_stack), i64_extend_16_s, Numeric),
-    (Some(extendable_i64_on_stack), i64_extend_32_s, Numeric),
+    (Some(extendable_i32_on_stack), i32_extend_8_s, NumericInt),
+    (Some(extendable_i32_on_stack), i32_extend_16_s, NumericInt),
+    (Some(extendable_i64_on_stack), i64_extend_8_s, NumericInt),
+    (Some(extendable_i64_on_stack), i64_extend_16_s, NumericInt),
+    (Some(extendable_i64_on_stack), i64_extend_32_s, NumericInt),
     (Some(nontrapping_f32_on_stack), i32_trunc_sat_f32_s, Numeric),
     (Some(nontrapping_f32_on_stack), i32_trunc_sat_f32_u, Numeric),
     (Some(nontrapping_f64_on_stack), i32_trunc_sat_f64_s, Numeric),
@@ -334,93 +334,93 @@ instructions! {
     (Some(any_convert_extern_valid), any_convert_extern, Aggregate),
     (Some(extern_convert_any_valid), extern_convert_any, Aggregate),
     // SIMD instructions.
-    (Some(simd_have_memory_and_offset), v128_load, Vector),
-    (Some(simd_have_memory_and_offset), v128_load8x8s, Vector),
-    (Some(simd_have_memory_and_offset), v128_load8x8u, Vector),
-    (Some(simd_have_memory_and_offset), v128_load16x4s, Vector),
-    (Some(simd_have_memory_and_offset), v128_load16x4u, Vector),
-    (Some(simd_have_memory_and_offset), v128_load32x2s, Vector),
-    (Some(simd_have_memory_and_offset), v128_load32x2u, Vector),
-    (Some(simd_have_memory_and_offset), v128_load8_splat, Vector),
-    (Some(simd_have_memory_and_offset), v128_load16_splat, Vector),
-    (Some(simd_have_memory_and_offset), v128_load32_splat, Vector),
-    (Some(simd_have_memory_and_offset), v128_load64_splat, Vector),
-    (Some(simd_have_memory_and_offset), v128_load32_zero, Vector),
-    (Some(simd_have_memory_and_offset), v128_load64_zero, Vector),
-    (Some(simd_v128_store_valid), v128_store, Vector),
-    (Some(simd_load_lane_valid), v128_load8_lane, Vector),
-    (Some(simd_load_lane_valid), v128_load16_lane, Vector),
-    (Some(simd_load_lane_valid), v128_load32_lane, Vector),
-    (Some(simd_load_lane_valid), v128_load64_lane, Vector),
-    (Some(simd_store_lane_valid), v128_store8_lane, Vector),
-    (Some(simd_store_lane_valid), v128_store16_lane, Vector),
-    (Some(simd_store_lane_valid), v128_store32_lane, Vector),
-    (Some(simd_store_lane_valid), v128_store64_lane, Vector),
-    (Some(simd_enabled), v128_const, Vector),
-    (Some(simd_v128_v128_on_stack), i8x16_shuffle, Vector),
-    (Some(simd_v128_on_stack), i8x16_extract_lane_s, Vector),
-    (Some(simd_v128_on_stack), i8x16_extract_lane_u, Vector),
-    (Some(simd_v128_i32_on_stack), i8x16_replace_lane, Vector),
-    (Some(simd_v128_on_stack), i16x8_extract_lane_s, Vector),
-    (Some(simd_v128_on_stack), i16x8_extract_lane_u, Vector),
-    (Some(simd_v128_i32_on_stack), i16x8_replace_lane, Vector),
-    (Some(simd_v128_on_stack), i32x4_extract_lane, Vector),
-    (Some(simd_v128_i32_on_stack), i32x4_replace_lane, Vector),
-    (Some(simd_v128_on_stack), i64x2_extract_lane, Vector),
-    (Some(simd_v128_i64_on_stack), i64x2_replace_lane, Vector),
+    (Some(simd_have_memory_and_offset), v128_load, VectorInt),
+    (Some(simd_have_memory_and_offset), v128_load8x8s, VectorInt),
+    (Some(simd_have_memory_and_offset), v128_load8x8u, VectorInt),
+    (Some(simd_have_memory_and_offset), v128_load16x4s, VectorInt),
+    (Some(simd_have_memory_and_offset), v128_load16x4u, VectorInt),
+    (Some(simd_have_memory_and_offset), v128_load32x2s, VectorInt),
+    (Some(simd_have_memory_and_offset), v128_load32x2u, VectorInt),
+    (Some(simd_have_memory_and_offset), v128_load8_splat, VectorInt),
+    (Some(simd_have_memory_and_offset), v128_load16_splat, VectorInt),
+    (Some(simd_have_memory_and_offset), v128_load32_splat, VectorInt),
+    (Some(simd_have_memory_and_offset), v128_load64_splat, VectorInt),
+    (Some(simd_have_memory_and_offset), v128_load32_zero, VectorInt),
+    (Some(simd_have_memory_and_offset), v128_load64_zero, VectorInt),
+    (Some(simd_v128_store_valid), v128_store, VectorInt),
+    (Some(simd_load_lane_valid), v128_load8_lane, VectorInt),
+    (Some(simd_load_lane_valid), v128_load16_lane, VectorInt),
+    (Some(simd_load_lane_valid), v128_load32_lane, VectorInt),
+    (Some(simd_load_lane_valid), v128_load64_lane, VectorInt),
+    (Some(simd_store_lane_valid), v128_store8_lane, VectorInt),
+    (Some(simd_store_lane_valid), v128_store16_lane, VectorInt),
+    (Some(simd_store_lane_valid), v128_store32_lane, VectorInt),
+    (Some(simd_store_lane_valid), v128_store64_lane, VectorInt),
+    (Some(simd_enabled), v128_const, VectorInt),
+    (Some(simd_v128_v128_on_stack), i8x16_shuffle, VectorInt),
+    (Some(simd_v128_on_stack), i8x16_extract_lane_s, VectorInt),
+    (Some(simd_v128_on_stack), i8x16_extract_lane_u, VectorInt),
+    (Some(simd_v128_i32_on_stack), i8x16_replace_lane, VectorInt),
+    (Some(simd_v128_on_stack), i16x8_extract_lane_s, VectorInt),
+    (Some(simd_v128_on_stack), i16x8_extract_lane_u, VectorInt),
+    (Some(simd_v128_i32_on_stack), i16x8_replace_lane, VectorInt),
+    (Some(simd_v128_on_stack), i32x4_extract_lane, VectorInt),
+    (Some(simd_v128_i32_on_stack), i32x4_replace_lane, VectorInt),
+    (Some(simd_v128_on_stack), i64x2_extract_lane, VectorInt),
+    (Some(simd_v128_i64_on_stack), i64x2_replace_lane, VectorInt),
     (Some(simd_v128_on_stack), f32x4_extract_lane, Vector),
     (Some(simd_v128_f32_on_stack), f32x4_replace_lane, Vector),
     (Some(simd_v128_on_stack), f64x2_extract_lane, Vector),
     (Some(simd_v128_f64_on_stack), f64x2_replace_lane, Vector),
-    (Some(simd_i32_on_stack), i8x16_splat, Vector),
-    (Some(simd_i32_on_stack), i16x8_splat, Vector),
-    (Some(simd_i32_on_stack), i32x4_splat, Vector),
-    (Some(simd_i64_on_stack), i64x2_splat, Vector),
+    (Some(simd_i32_on_stack), i8x16_splat, VectorInt),
+    (Some(simd_i32_on_stack), i16x8_splat, VectorInt),
+    (Some(simd_i32_on_stack), i32x4_splat, VectorInt),
+    (Some(simd_i64_on_stack), i64x2_splat, VectorInt),
     (Some(simd_f32_on_stack), f32x4_splat, Vector),
     (Some(simd_f64_on_stack), f64x2_splat, Vector),
-    (Some(simd_v128_v128_on_stack), i8x16_swizzle, Vector),
-    (Some(simd_v128_v128_on_stack_relaxed), i8x16_relaxed_swizzle, Vector),
-    (Some(simd_v128_v128_v128_on_stack), v128_bitselect, Vector),
-    (Some(simd_v128_v128_v128_on_stack_relaxed), i8x16_relaxed_laneselect, Vector),
-    (Some(simd_v128_v128_v128_on_stack_relaxed), i16x8_relaxed_laneselect, Vector),
-    (Some(simd_v128_v128_v128_on_stack_relaxed), i32x4_relaxed_laneselect, Vector),
-    (Some(simd_v128_v128_v128_on_stack_relaxed), i64x2_relaxed_laneselect, Vector),
-    (Some(simd_v128_v128_on_stack), i8x16_eq, Vector),
-    (Some(simd_v128_v128_on_stack), i8x16_ne, Vector),
-    (Some(simd_v128_v128_on_stack), i8x16_lt_s, Vector),
-    (Some(simd_v128_v128_on_stack), i8x16_lt_u, Vector),
-    (Some(simd_v128_v128_on_stack), i8x16_gt_s, Vector),
-    (Some(simd_v128_v128_on_stack), i8x16_gt_u, Vector),
-    (Some(simd_v128_v128_on_stack), i8x16_le_s, Vector),
-    (Some(simd_v128_v128_on_stack), i8x16_le_u, Vector),
-    (Some(simd_v128_v128_on_stack), i8x16_ge_s, Vector),
-    (Some(simd_v128_v128_on_stack), i8x16_ge_u, Vector),
-    (Some(simd_v128_v128_on_stack), i16x8_eq, Vector),
-    (Some(simd_v128_v128_on_stack), i16x8_ne, Vector),
-    (Some(simd_v128_v128_on_stack), i16x8_lt_s, Vector),
-    (Some(simd_v128_v128_on_stack), i16x8_lt_u, Vector),
-    (Some(simd_v128_v128_on_stack), i16x8_gt_s, Vector),
-    (Some(simd_v128_v128_on_stack), i16x8_gt_u, Vector),
-    (Some(simd_v128_v128_on_stack), i16x8_le_s, Vector),
-    (Some(simd_v128_v128_on_stack), i16x8_le_u, Vector),
-    (Some(simd_v128_v128_on_stack), i16x8_ge_s, Vector),
-    (Some(simd_v128_v128_on_stack), i16x8_ge_u, Vector),
-    (Some(simd_v128_v128_on_stack), i32x4_eq, Vector),
-    (Some(simd_v128_v128_on_stack), i32x4_ne, Vector),
-    (Some(simd_v128_v128_on_stack), i32x4_lt_s, Vector),
-    (Some(simd_v128_v128_on_stack), i32x4_lt_u, Vector),
-    (Some(simd_v128_v128_on_stack), i32x4_gt_s, Vector),
-    (Some(simd_v128_v128_on_stack), i32x4_gt_u, Vector),
-    (Some(simd_v128_v128_on_stack), i32x4_le_s, Vector),
-    (Some(simd_v128_v128_on_stack), i32x4_le_u, Vector),
-    (Some(simd_v128_v128_on_stack), i32x4_ge_s, Vector),
-    (Some(simd_v128_v128_on_stack), i32x4_ge_u, Vector),
-    (Some(simd_v128_v128_on_stack), i64x2_eq, Vector),
-    (Some(simd_v128_v128_on_stack), i64x2_ne, Vector),
-    (Some(simd_v128_v128_on_stack), i64x2_lt_s, Vector),
-    (Some(simd_v128_v128_on_stack), i64x2_gt_s, Vector),
-    (Some(simd_v128_v128_on_stack), i64x2_le_s, Vector),
-    (Some(simd_v128_v128_on_stack), i64x2_ge_s, Vector),
+    (Some(simd_v128_v128_on_stack), i8x16_swizzle, VectorInt),
+    (Some(simd_v128_v128_on_stack_relaxed), i8x16_relaxed_swizzle, VectorInt),
+    (Some(simd_v128_v128_v128_on_stack), v128_bitselect, VectorInt),
+    (Some(simd_v128_v128_v128_on_stack_relaxed), i8x16_relaxed_laneselect, VectorInt),
+    (Some(simd_v128_v128_v128_on_stack_relaxed), i16x8_relaxed_laneselect, VectorInt),
+    (Some(simd_v128_v128_v128_on_stack_relaxed), i32x4_relaxed_laneselect, VectorInt),
+    (Some(simd_v128_v128_v128_on_stack_relaxed), i64x2_relaxed_laneselect, VectorInt),
+    (Some(simd_v128_v128_on_stack), i8x16_eq, VectorInt),
+    (Some(simd_v128_v128_on_stack), i8x16_ne, VectorInt),
+    (Some(simd_v128_v128_on_stack), i8x16_lt_s, VectorInt),
+    (Some(simd_v128_v128_on_stack), i8x16_lt_u, VectorInt),
+    (Some(simd_v128_v128_on_stack), i8x16_gt_s, VectorInt),
+    (Some(simd_v128_v128_on_stack), i8x16_gt_u, VectorInt),
+    (Some(simd_v128_v128_on_stack), i8x16_le_s, VectorInt),
+    (Some(simd_v128_v128_on_stack), i8x16_le_u, VectorInt),
+    (Some(simd_v128_v128_on_stack), i8x16_ge_s, VectorInt),
+    (Some(simd_v128_v128_on_stack), i8x16_ge_u, VectorInt),
+    (Some(simd_v128_v128_on_stack), i16x8_eq, VectorInt),
+    (Some(simd_v128_v128_on_stack), i16x8_ne, VectorInt),
+    (Some(simd_v128_v128_on_stack), i16x8_lt_s, VectorInt),
+    (Some(simd_v128_v128_on_stack), i16x8_lt_u, VectorInt),
+    (Some(simd_v128_v128_on_stack), i16x8_gt_s, VectorInt),
+    (Some(simd_v128_v128_on_stack), i16x8_gt_u, VectorInt),
+    (Some(simd_v128_v128_on_stack), i16x8_le_s, VectorInt),
+    (Some(simd_v128_v128_on_stack), i16x8_le_u, VectorInt),
+    (Some(simd_v128_v128_on_stack), i16x8_ge_s, VectorInt),
+    (Some(simd_v128_v128_on_stack), i16x8_ge_u, VectorInt),
+    (Some(simd_v128_v128_on_stack), i32x4_eq, VectorInt),
+    (Some(simd_v128_v128_on_stack), i32x4_ne, VectorInt),
+    (Some(simd_v128_v128_on_stack), i32x4_lt_s, VectorInt),
+    (Some(simd_v128_v128_on_stack), i32x4_lt_u, VectorInt),
+    (Some(simd_v128_v128_on_stack), i32x4_gt_s, VectorInt),
+    (Some(simd_v128_v128_on_stack), i32x4_gt_u, VectorInt),
+    (Some(simd_v128_v128_on_stack), i32x4_le_s, VectorInt),
+    (Some(simd_v128_v128_on_stack), i32x4_le_u, VectorInt),
+    (Some(simd_v128_v128_on_stack), i32x4_ge_s, VectorInt),
+    (Some(simd_v128_v128_on_stack), i32x4_ge_u, VectorInt),
+    (Some(simd_v128_v128_on_stack), i64x2_eq, VectorInt),
+    (Some(simd_v128_v128_on_stack), i64x2_ne, VectorInt),
+    (Some(simd_v128_v128_on_stack), i64x2_lt_s, VectorInt),
+    (Some(simd_v128_v128_on_stack), i64x2_gt_s, VectorInt),
+    (Some(simd_v128_v128_on_stack), i64x2_le_s, VectorInt),
+    (Some(simd_v128_v128_on_stack), i64x2_ge_s, VectorInt),
     (Some(simd_v128_v128_on_stack), f32x4_eq, Vector),
     (Some(simd_v128_v128_on_stack), f32x4_ne, Vector),
     (Some(simd_v128_v128_on_stack), f32x4_lt, Vector),
@@ -433,108 +433,108 @@ instructions! {
     (Some(simd_v128_v128_on_stack), f64x2_gt, Vector),
     (Some(simd_v128_v128_on_stack), f64x2_le, Vector),
     (Some(simd_v128_v128_on_stack), f64x2_ge, Vector),
-    (Some(simd_v128_on_stack), v128_not, Vector),
-    (Some(simd_v128_v128_on_stack), v128_and, Vector),
-    (Some(simd_v128_v128_on_stack), v128_and_not, Vector),
-    (Some(simd_v128_v128_on_stack), v128_or, Vector),
-    (Some(simd_v128_v128_on_stack), v128_xor, Vector),
-    (Some(simd_v128_v128_on_stack), v128_any_true, Vector),
-    (Some(simd_v128_on_stack), i8x16_abs, Vector),
-    (Some(simd_v128_on_stack), i8x16_neg, Vector),
-    (Some(simd_v128_on_stack), i8x16_popcnt, Vector),
-    (Some(simd_v128_on_stack), i8x16_all_true, Vector),
-    (Some(simd_v128_on_stack), i8x16_bitmask, Vector),
-    (Some(simd_v128_v128_on_stack), i8x16_narrow_i16x8s, Vector),
-    (Some(simd_v128_v128_on_stack), i8x16_narrow_i16x8u, Vector),
-    (Some(simd_v128_i32_on_stack), i8x16_shl, Vector),
-    (Some(simd_v128_i32_on_stack), i8x16_shr_s, Vector),
-    (Some(simd_v128_i32_on_stack), i8x16_shr_u, Vector),
-    (Some(simd_v128_v128_on_stack), i8x16_add, Vector),
-    (Some(simd_v128_v128_on_stack), i8x16_add_sat_s, Vector),
-    (Some(simd_v128_v128_on_stack), i8x16_add_sat_u, Vector),
-    (Some(simd_v128_v128_on_stack), i8x16_sub, Vector),
-    (Some(simd_v128_v128_on_stack), i8x16_sub_sat_s, Vector),
-    (Some(simd_v128_v128_on_stack), i8x16_sub_sat_u, Vector),
-    (Some(simd_v128_v128_on_stack), i8x16_min_s, Vector),
-    (Some(simd_v128_v128_on_stack), i8x16_min_u, Vector),
-    (Some(simd_v128_v128_on_stack), i8x16_max_s, Vector),
-    (Some(simd_v128_v128_on_stack), i8x16_max_u, Vector),
-    (Some(simd_v128_v128_on_stack), i8x16_avgr_u, Vector),
-    (Some(simd_v128_on_stack), i16x8_extadd_pairwise_i8x16s, Vector),
-    (Some(simd_v128_on_stack), i16x8_extadd_pairwise_i8x16u, Vector),
-    (Some(simd_v128_on_stack), i16x8_abs, Vector),
-    (Some(simd_v128_on_stack), i16x8_neg, Vector),
-    (Some(simd_v128_v128_on_stack), i16x8q15_mulr_sat_s, Vector),
-    (Some(simd_v128_on_stack), i16x8_all_true, Vector),
-    (Some(simd_v128_on_stack), i16x8_bitmask, Vector),
-    (Some(simd_v128_v128_on_stack), i16x8_narrow_i32x4s, Vector),
-    (Some(simd_v128_v128_on_stack), i16x8_narrow_i32x4u, Vector),
-    (Some(simd_v128_on_stack), i16x8_extend_low_i8x16s, Vector),
-    (Some(simd_v128_on_stack), i16x8_extend_high_i8x16s, Vector),
-    (Some(simd_v128_on_stack), i16x8_extend_low_i8x16u, Vector),
-    (Some(simd_v128_on_stack), i16x8_extend_high_i8x16u, Vector),
-    (Some(simd_v128_i32_on_stack), i16x8_shl, Vector),
-    (Some(simd_v128_i32_on_stack), i16x8_shr_s, Vector),
-    (Some(simd_v128_i32_on_stack), i16x8_shr_u, Vector),
-    (Some(simd_v128_v128_on_stack), i16x8_add, Vector),
-    (Some(simd_v128_v128_on_stack), i16x8_add_sat_s, Vector),
-    (Some(simd_v128_v128_on_stack), i16x8_add_sat_u, Vector),
-    (Some(simd_v128_v128_on_stack), i16x8_sub, Vector),
-    (Some(simd_v128_v128_on_stack), i16x8_sub_sat_s, Vector),
-    (Some(simd_v128_v128_on_stack), i16x8_sub_sat_u, Vector),
-    (Some(simd_v128_v128_on_stack), i16x8_mul, Vector),
-    (Some(simd_v128_v128_on_stack), i16x8_min_s, Vector),
-    (Some(simd_v128_v128_on_stack), i16x8_min_u, Vector),
-    (Some(simd_v128_v128_on_stack), i16x8_max_s, Vector),
-    (Some(simd_v128_v128_on_stack), i16x8_max_u, Vector),
-    (Some(simd_v128_v128_on_stack), i16x8_avgr_u, Vector),
-    (Some(simd_v128_v128_on_stack), i16x8_extmul_low_i8x16s, Vector),
-    (Some(simd_v128_v128_on_stack), i16x8_extmul_high_i8x16s, Vector),
-    (Some(simd_v128_v128_on_stack), i16x8_extmul_low_i8x16u, Vector),
-    (Some(simd_v128_v128_on_stack), i16x8_extmul_high_i8x16u, Vector),
-    (Some(simd_v128_on_stack), i32x4_extadd_pairwise_i16x8s, Vector),
-    (Some(simd_v128_on_stack), i32x4_extadd_pairwise_i16x8u, Vector),
-    (Some(simd_v128_on_stack), i32x4_abs, Vector),
-    (Some(simd_v128_on_stack), i32x4_neg, Vector),
-    (Some(simd_v128_on_stack), i32x4_all_true, Vector),
-    (Some(simd_v128_on_stack), i32x4_bitmask, Vector),
-    (Some(simd_v128_on_stack), i32x4_extend_low_i16x8s, Vector),
-    (Some(simd_v128_on_stack), i32x4_extend_high_i16x8s, Vector),
-    (Some(simd_v128_on_stack), i32x4_extend_low_i16x8u, Vector),
-    (Some(simd_v128_on_stack), i32x4_extend_high_i16x8u, Vector),
-    (Some(simd_v128_i32_on_stack), i32x4_shl, Vector),
-    (Some(simd_v128_i32_on_stack), i32x4_shr_s, Vector),
-    (Some(simd_v128_i32_on_stack), i32x4_shr_u, Vector),
-    (Some(simd_v128_v128_on_stack), i32x4_add, Vector),
-    (Some(simd_v128_v128_on_stack), i32x4_sub, Vector),
-    (Some(simd_v128_v128_on_stack), i32x4_mul, Vector),
-    (Some(simd_v128_v128_on_stack), i32x4_min_s, Vector),
-    (Some(simd_v128_v128_on_stack), i32x4_min_u, Vector),
-    (Some(simd_v128_v128_on_stack), i32x4_max_s, Vector),
-    (Some(simd_v128_v128_on_stack), i32x4_max_u, Vector),
-    (Some(simd_v128_v128_on_stack), i32x4_dot_i16x8s, Vector),
-    (Some(simd_v128_v128_on_stack), i32x4_extmul_low_i16x8s, Vector),
-    (Some(simd_v128_v128_on_stack), i32x4_extmul_high_i16x8s, Vector),
-    (Some(simd_v128_v128_on_stack), i32x4_extmul_low_i16x8u, Vector),
-    (Some(simd_v128_v128_on_stack), i32x4_extmul_high_i16x8u, Vector),
-    (Some(simd_v128_on_stack), i64x2_abs, Vector),
-    (Some(simd_v128_on_stack), i64x2_neg, Vector),
-    (Some(simd_v128_on_stack), i64x2_all_true, Vector),
-    (Some(simd_v128_on_stack), i64x2_bitmask, Vector),
-    (Some(simd_v128_on_stack), i64x2_extend_low_i32x4s, Vector),
-    (Some(simd_v128_on_stack), i64x2_extend_high_i32x4s, Vector),
-    (Some(simd_v128_on_stack), i64x2_extend_low_i32x4u, Vector),
-    (Some(simd_v128_on_stack), i64x2_extend_high_i32x4u, Vector),
-    (Some(simd_v128_i32_on_stack), i64x2_shl, Vector),
-    (Some(simd_v128_i32_on_stack), i64x2_shr_s, Vector),
-    (Some(simd_v128_i32_on_stack), i64x2_shr_u, Vector),
-    (Some(simd_v128_v128_on_stack), i64x2_add, Vector),
-    (Some(simd_v128_v128_on_stack), i64x2_sub, Vector),
-    (Some(simd_v128_v128_on_stack), i64x2_mul, Vector),
-    (Some(simd_v128_v128_on_stack), i64x2_extmul_low_i32x4s, Vector),
-    (Some(simd_v128_v128_on_stack), i64x2_extmul_high_i32x4s, Vector),
-    (Some(simd_v128_v128_on_stack), i64x2_extmul_low_i32x4u, Vector),
-    (Some(simd_v128_v128_on_stack), i64x2_extmul_high_i32x4u, Vector),
+    (Some(simd_v128_on_stack), v128_not, VectorInt),
+    (Some(simd_v128_v128_on_stack), v128_and, VectorInt),
+    (Some(simd_v128_v128_on_stack), v128_and_not, VectorInt),
+    (Some(simd_v128_v128_on_stack), v128_or, VectorInt),
+    (Some(simd_v128_v128_on_stack), v128_xor, VectorInt),
+    (Some(simd_v128_v128_on_stack), v128_any_true, VectorInt),
+    (Some(simd_v128_on_stack), i8x16_abs, VectorInt),
+    (Some(simd_v128_on_stack), i8x16_neg, VectorInt),
+    (Some(simd_v128_on_stack), i8x16_popcnt, VectorInt),
+    (Some(simd_v128_on_stack), i8x16_all_true, VectorInt),
+    (Some(simd_v128_on_stack), i8x16_bitmask, VectorInt),
+    (Some(simd_v128_v128_on_stack), i8x16_narrow_i16x8s, VectorInt),
+    (Some(simd_v128_v128_on_stack), i8x16_narrow_i16x8u, VectorInt),
+    (Some(simd_v128_i32_on_stack), i8x16_shl, VectorInt),
+    (Some(simd_v128_i32_on_stack), i8x16_shr_s, VectorInt),
+    (Some(simd_v128_i32_on_stack), i8x16_shr_u, VectorInt),
+    (Some(simd_v128_v128_on_stack), i8x16_add, VectorInt),
+    (Some(simd_v128_v128_on_stack), i8x16_add_sat_s, VectorInt),
+    (Some(simd_v128_v128_on_stack), i8x16_add_sat_u, VectorInt),
+    (Some(simd_v128_v128_on_stack), i8x16_sub, VectorInt),
+    (Some(simd_v128_v128_on_stack), i8x16_sub_sat_s, VectorInt),
+    (Some(simd_v128_v128_on_stack), i8x16_sub_sat_u, VectorInt),
+    (Some(simd_v128_v128_on_stack), i8x16_min_s, VectorInt),
+    (Some(simd_v128_v128_on_stack), i8x16_min_u, VectorInt),
+    (Some(simd_v128_v128_on_stack), i8x16_max_s, VectorInt),
+    (Some(simd_v128_v128_on_stack), i8x16_max_u, VectorInt),
+    (Some(simd_v128_v128_on_stack), i8x16_avgr_u, VectorInt),
+    (Some(simd_v128_on_stack), i16x8_extadd_pairwise_i8x16s, VectorInt),
+    (Some(simd_v128_on_stack), i16x8_extadd_pairwise_i8x16u, VectorInt),
+    (Some(simd_v128_on_stack), i16x8_abs, VectorInt),
+    (Some(simd_v128_on_stack), i16x8_neg, VectorInt),
+    (Some(simd_v128_v128_on_stack), i16x8q15_mulr_sat_s, VectorInt),
+    (Some(simd_v128_on_stack), i16x8_all_true, VectorInt),
+    (Some(simd_v128_on_stack), i16x8_bitmask, VectorInt),
+    (Some(simd_v128_v128_on_stack), i16x8_narrow_i32x4s, VectorInt),
+    (Some(simd_v128_v128_on_stack), i16x8_narrow_i32x4u, VectorInt),
+    (Some(simd_v128_on_stack), i16x8_extend_low_i8x16s, VectorInt),
+    (Some(simd_v128_on_stack), i16x8_extend_high_i8x16s, VectorInt),
+    (Some(simd_v128_on_stack), i16x8_extend_low_i8x16u, VectorInt),
+    (Some(simd_v128_on_stack), i16x8_extend_high_i8x16u, VectorInt),
+    (Some(simd_v128_i32_on_stack), i16x8_shl, VectorInt),
+    (Some(simd_v128_i32_on_stack), i16x8_shr_s, VectorInt),
+    (Some(simd_v128_i32_on_stack), i16x8_shr_u, VectorInt),
+    (Some(simd_v128_v128_on_stack), i16x8_add, VectorInt),
+    (Some(simd_v128_v128_on_stack), i16x8_add_sat_s, VectorInt),
+    (Some(simd_v128_v128_on_stack), i16x8_add_sat_u, VectorInt),
+    (Some(simd_v128_v128_on_stack), i16x8_sub, VectorInt),
+    (Some(simd_v128_v128_on_stack), i16x8_sub_sat_s, VectorInt),
+    (Some(simd_v128_v128_on_stack), i16x8_sub_sat_u, VectorInt),
+    (Some(simd_v128_v128_on_stack), i16x8_mul, VectorInt),
+    (Some(simd_v128_v128_on_stack), i16x8_min_s, VectorInt),
+    (Some(simd_v128_v128_on_stack), i16x8_min_u, VectorInt),
+    (Some(simd_v128_v128_on_stack), i16x8_max_s, VectorInt),
+    (Some(simd_v128_v128_on_stack), i16x8_max_u, VectorInt),
+    (Some(simd_v128_v128_on_stack), i16x8_avgr_u, VectorInt),
+    (Some(simd_v128_v128_on_stack), i16x8_extmul_low_i8x16s, VectorInt),
+    (Some(simd_v128_v128_on_stack), i16x8_extmul_high_i8x16s, VectorInt),
+    (Some(simd_v128_v128_on_stack), i16x8_extmul_low_i8x16u, VectorInt),
+    (Some(simd_v128_v128_on_stack), i16x8_extmul_high_i8x16u, VectorInt),
+    (Some(simd_v128_on_stack), i32x4_extadd_pairwise_i16x8s, VectorInt),
+    (Some(simd_v128_on_stack), i32x4_extadd_pairwise_i16x8u, VectorInt),
+    (Some(simd_v128_on_stack), i32x4_abs, VectorInt),
+    (Some(simd_v128_on_stack), i32x4_neg, VectorInt),
+    (Some(simd_v128_on_stack), i32x4_all_true, VectorInt),
+    (Some(simd_v128_on_stack), i32x4_bitmask, VectorInt),
+    (Some(simd_v128_on_stack), i32x4_extend_low_i16x8s, VectorInt),
+    (Some(simd_v128_on_stack), i32x4_extend_high_i16x8s, VectorInt),
+    (Some(simd_v128_on_stack), i32x4_extend_low_i16x8u, VectorInt),
+    (Some(simd_v128_on_stack), i32x4_extend_high_i16x8u, VectorInt),
+    (Some(simd_v128_i32_on_stack), i32x4_shl, VectorInt),
+    (Some(simd_v128_i32_on_stack), i32x4_shr_s, VectorInt),
+    (Some(simd_v128_i32_on_stack), i32x4_shr_u, VectorInt),
+    (Some(simd_v128_v128_on_stack), i32x4_add, VectorInt),
+    (Some(simd_v128_v128_on_stack), i32x4_sub, VectorInt),
+    (Some(simd_v128_v128_on_stack), i32x4_mul, VectorInt),
+    (Some(simd_v128_v128_on_stack), i32x4_min_s, VectorInt),
+    (Some(simd_v128_v128_on_stack), i32x4_min_u, VectorInt),
+    (Some(simd_v128_v128_on_stack), i32x4_max_s, VectorInt),
+    (Some(simd_v128_v128_on_stack), i32x4_max_u, VectorInt),
+    (Some(simd_v128_v128_on_stack), i32x4_dot_i16x8s, VectorInt),
+    (Some(simd_v128_v128_on_stack), i32x4_extmul_low_i16x8s, VectorInt),
+    (Some(simd_v128_v128_on_stack), i32x4_extmul_high_i16x8s, VectorInt),
+    (Some(simd_v128_v128_on_stack), i32x4_extmul_low_i16x8u, VectorInt),
+    (Some(simd_v128_v128_on_stack), i32x4_extmul_high_i16x8u, VectorInt),
+    (Some(simd_v128_on_stack), i64x2_abs, VectorInt),
+    (Some(simd_v128_on_stack), i64x2_neg, VectorInt),
+    (Some(simd_v128_on_stack), i64x2_all_true, VectorInt),
+    (Some(simd_v128_on_stack), i64x2_bitmask, VectorInt),
+    (Some(simd_v128_on_stack), i64x2_extend_low_i32x4s, VectorInt),
+    (Some(simd_v128_on_stack), i64x2_extend_high_i32x4s, VectorInt),
+    (Some(simd_v128_on_stack), i64x2_extend_low_i32x4u, VectorInt),
+    (Some(simd_v128_on_stack), i64x2_extend_high_i32x4u, VectorInt),
+    (Some(simd_v128_i32_on_stack), i64x2_shl, VectorInt),
+    (Some(simd_v128_i32_on_stack), i64x2_shr_s, VectorInt),
+    (Some(simd_v128_i32_on_stack), i64x2_shr_u, VectorInt),
+    (Some(simd_v128_v128_on_stack), i64x2_add, VectorInt),
+    (Some(simd_v128_v128_on_stack), i64x2_sub, VectorInt),
+    (Some(simd_v128_v128_on_stack), i64x2_mul, VectorInt),
+    (Some(simd_v128_v128_on_stack), i64x2_extmul_low_i32x4s, VectorInt),
+    (Some(simd_v128_v128_on_stack), i64x2_extmul_high_i32x4s, VectorInt),
+    (Some(simd_v128_v128_on_stack), i64x2_extmul_low_i32x4u, VectorInt),
+    (Some(simd_v128_v128_on_stack), i64x2_extmul_high_i32x4u, VectorInt),
     (Some(simd_v128_on_stack), f32x4_ceil, Vector),
     (Some(simd_v128_on_stack), f32x4_floor, Vector),
     (Some(simd_v128_on_stack), f32x4_trunc, Vector),
@@ -587,9 +587,9 @@ instructions! {
     (Some(simd_v128_v128_on_stack_relaxed), f32x4_relaxed_max, Vector),
     (Some(simd_v128_v128_on_stack_relaxed), f64x2_relaxed_min, Vector),
     (Some(simd_v128_v128_on_stack_relaxed), f64x2_relaxed_max, Vector),
-    (Some(simd_v128_v128_on_stack_relaxed), i16x8_relaxed_q15mulr_s, Vector),
-    (Some(simd_v128_v128_on_stack_relaxed), i16x8_relaxed_dot_i8x16_i7x16_s, Vector),
-    (Some(simd_v128_v128_v128_on_stack_relaxed), i32x4_relaxed_dot_i8x16_i7x16_add_s, Vector),
+    (Some(simd_v128_v128_on_stack_relaxed), i16x8_relaxed_q15mulr_s, VectorInt),
+    (Some(simd_v128_v128_on_stack_relaxed), i16x8_relaxed_dot_i8x16_i7x16_s, VectorInt),
+    (Some(simd_v128_v128_v128_on_stack_relaxed), i32x4_relaxed_dot_i8x16_i7x16_add_s, VectorInt),
 }
 
 pub(crate) struct CodeBuilderAllocations {
@@ -1239,7 +1239,11 @@ impl CodeBuilder<'_> {
         module: &Module,
     ) -> Result<Vec<Instruction>> {
         let max_instructions = module.config.max_instructions;
-        let allowed_instructions = module.config.allowed_instructions;
+        let allowed_instructions = if module.config.allow_floats {
+            module.config.allowed_instructions
+        } else {
+            module.config.allowed_instructions.without_floats()
+        };
         let mut instructions = vec![];
 
         while !self.allocs.controls.is_empty() {
diff --git a/crates/wast/src/core/binary.rs b/crates/wast/src/core/binary.rs
index 18724a7c..69314d37 100644
--- a/crates/wast/src/core/binary.rs
+++ b/crates/wast/src/core/binary.rs
@@ -256,9 +256,8 @@ impl Encoder<'_> {
 
         if !list.is_empty() {
             let mut branch_hints = wasm_encoder::BranchHints::new();
-            let mut code_section = Vec::new();
+            let mut code_section = wasm_encoder::CodeSection::new();
 
-            list.len().encode(&mut code_section);
             for func in list.iter() {
                 let hints = func.encode(&mut code_section, dwarf.as_deref_mut());
                 if !hints.is_empty() {
@@ -274,13 +273,10 @@ impl Encoder<'_> {
             }
 
             // Finally, insert the Code section from the tmp buffer
-            self.wasm.section(&wasm_encoder::RawSection {
-                id: wasm_encoder::SectionId::Code as u8,
-                data: &code_section,
-            });
+            self.wasm.section(&code_section);
 
             if let Some(dwarf) = &mut dwarf {
-                dwarf.set_code_section_size(code_section.len());
+                dwarf.set_code_section_size(code_section.byte_len());
             }
         }
         self.custom_sections(CustomPlace::After(CustomPlaceAnchor::Code));
@@ -449,90 +445,13 @@ impl Encode for Option<Id<'_>> {
 
 impl<'a> Encode for ValType<'a> {
     fn encode(&self, e: &mut Vec<u8>) {
-        match self {
-            ValType::I32 => e.push(0x7f),
-            ValType::I64 => e.push(0x7e),
-            ValType::F32 => e.push(0x7d),
-            ValType::F64 => e.push(0x7c),
-            ValType::V128 => e.push(0x7b),
-            ValType::Ref(ty) => {
-                ty.encode(e);
-            }
-        }
+        wasm_encoder::Encode::encode(&wasm_encoder::ValType::from(*self), e)
     }
 }
 
 impl<'a> Encode for HeapType<'a> {
     fn encode(&self, e: &mut Vec<u8>) {
-        match self {
-            HeapType::Abstract { shared, ty } => {
-                if *shared {
-                    e.push(0x65);
-                }
-                ty.encode(e)
-            }
-            // Note that this is encoded as a signed leb128 so be sure to cast
-            // to an i64 first
-            HeapType::Concrete(Index::Num(n, _)) => i64::from(*n).encode(e),
-            HeapType::Concrete(Index::Id(n)) => {
-                panic!("unresolved index in emission: {:?}", n)
-            }
-        }
-    }
-}
-
-impl<'a> Encode for AbstractHeapType {
-    fn encode(&self, e: &mut Vec<u8>) {
-        use AbstractHeapType::*;
-        match self {
-            Func => e.push(0x70),
-            Extern => e.push(0x6f),
-            Cont => e.push(0x68),
-            Exn => e.push(0x69),
-            Any => e.push(0x6e),
-            Eq => e.push(0x6d),
-            Struct => e.push(0x6b),
-            Array => e.push(0x6a),
-            I31 => e.push(0x6c),
-            NoFunc => e.push(0x73),
-            NoExtern => e.push(0x72),
-            NoExn => e.push(0x74),
-            NoCont => e.push(0x75),
-            None => e.push(0x71),
-        }
-    }
-}
-
-impl<'a> Encode for RefType<'a> {
-    fn encode(&self, e: &mut Vec<u8>) {
-        match self {
-            // Binary abbreviations (i.e., short form), for when the ref is
-            // nullable.
-            RefType {
-                nullable: true,
-                heap: heap @ HeapType::Abstract { .. },
-            } => {
-                heap.encode(e);
-            }
-
-            // Generic 'ref null <heaptype>' encoding (i.e., long form).
-            RefType {
-                nullable: true,
-                heap,
-            } => {
-                e.push(0x63);
-                heap.encode(e);
-            }
-
-            // Generic 'ref <heaptype>' encoding.
-            RefType {
-                nullable: false,
-                heap,
-            } => {
-                e.push(0x64);
-                heap.encode(e);
-            }
-        }
+        wasm_encoder::Encode::encode(&wasm_encoder::HeapType::from(*self), e)
     }
 }
 
@@ -672,7 +591,7 @@ impl SectionItem for Table<'_> {
                 ty,
                 init_expr: Some(init_expr),
             } => {
-                section.table_with_init(ty.to_table_type(), &init_expr.to_const_expr(None));
+                section.table_with_init(ty.to_table_type(), &init_expr.to_const_expr());
             }
             _ => panic!("TableKind should be normal during encoding"),
         }
@@ -701,7 +620,7 @@ impl SectionItem for Global<'_> {
     fn encode(&self, section: &mut wasm_encoder::GlobalSection) {
         assert!(self.exports.names.is_empty());
         let init = match &self.kind {
-            GlobalKind::Inline(expr) => expr.to_const_expr(None),
+            GlobalKind::Inline(expr) => expr.to_const_expr(),
             _ => panic!("GlobalKind should be inline during encoding"),
         };
         section.global(self.ty.to_global_type(), &init);
@@ -730,14 +649,14 @@ impl SectionItem for Elem<'_> {
             }
             ElemPayload::Exprs { exprs, ty } => Elements::Expressions(
                 (*ty).into(),
-                Cow::Owned(exprs.iter().map(|e| e.to_const_expr(None)).collect()),
+                Cow::Owned(exprs.iter().map(|e| e.to_const_expr()).collect()),
             ),
         };
         match &self.kind {
             ElemKind::Active { table, offset } => {
                 section.active(
                     table.map(|t| t.unwrap_u32()),
-                    &offset.to_const_expr(None),
+                    &offset.to_const_expr(),
                     elements,
                 );
             }
@@ -765,7 +684,7 @@ impl SectionItem for Data<'_> {
                 section.passive(data);
             }
             DataKind::Active { memory, offset } => {
-                section.active(memory.unwrap_u32(), &offset.to_const_expr(None), data);
+                section.active(memory.unwrap_u32(), &offset.to_const_expr(), data);
             }
         }
     }
@@ -779,7 +698,7 @@ impl Func<'_> {
     /// for each instruction.
     fn encode(
         &self,
-        e: &mut Vec<u8>,
+        section: &mut wasm_encoder::CodeSection,
         mut dwarf: Option<&mut dwarf::Dwarf>,
     ) -> Vec<wasm_encoder::BranchHint> {
         assert!(self.exports.names.is_empty());
@@ -799,35 +718,20 @@ impl Func<'_> {
         // Encode the function into a temporary vector because functions are
         // prefixed with their length. The temporary vector, when encoded,
         // encodes its length first then the body.
-        let mut tmp = Vec::new();
-        locals.encode(&mut tmp);
-        let branch_hints = expr.encode(&mut tmp, dwarf.as_deref_mut());
-        tmp.encode(e);
+        let mut func =
+            wasm_encoder::Function::new_with_locals_types(locals.iter().map(|t| t.ty.into()));
+        let branch_hints = expr.encode(&mut func, dwarf.as_deref_mut());
+        let func_size = func.byte_len();
+        section.function(&func);
 
         if let Some(dwarf) = &mut dwarf {
-            dwarf.end_func(tmp.len(), e.len());
+            dwarf.end_func(func_size, section.byte_len());
         }
 
         branch_hints
     }
 }
 
-impl Encode for Box<[Local<'_>]> {
-    fn encode(&self, e: &mut Vec<u8>) {
-        let mut locals_compressed = Vec::<(u32, ValType)>::new();
-        for local in self.iter() {
-            if let Some((cnt, prev)) = locals_compressed.last_mut() {
-                if *prev == local.ty {
-                    *cnt += 1;
-                    continue;
-                }
-            }
-            locals_compressed.push((1, local.ty));
-        }
-        locals_compressed.encode(e);
-    }
-}
-
 impl Expression<'_> {
     /// Encodes this expression into `e` and optionally tracks debugging
     /// information for each instruction in `dwarf`.
@@ -835,11 +739,12 @@ impl Expression<'_> {
     /// Returns all branch hints, if any, found while parsing this function.
     fn encode(
         &self,
-        e: &mut Vec<u8>,
+        func: &mut wasm_encoder::Function,
         mut dwarf: Option<&mut dwarf::Dwarf>,
     ) -> Vec<wasm_encoder::BranchHint> {
         let mut hints = Vec::with_capacity(self.branch_hints.len());
         let mut next_hint = self.branch_hints.iter().peekable();
+        let mut tmp = Vec::new();
 
         for (i, instr) in self.instrs.iter().enumerate() {
             // Branch hints are stored in order of increasing `instr_index` so
@@ -847,7 +752,7 @@ impl Expression<'_> {
             // index.
             if let Some(hint) = next_hint.next_if(|h| h.instr_index == i) {
                 hints.push(wasm_encoder::BranchHint {
-                    branch_func_offset: u32::try_from(e.len()).unwrap(),
+                    branch_func_offset: u32::try_from(func.byte_len() + tmp.len()).unwrap(),
                     branch_hint_value: hint.value,
                 });
             }
@@ -856,22 +761,24 @@ impl Expression<'_> {
             // and source location.
             if let Some(dwarf) = &mut dwarf {
                 if let Some(span) = self.instr_spans.as_ref().map(|s| s[i]) {
-                    dwarf.instr(e.len(), span);
+                    dwarf.instr(func.byte_len() + tmp.len(), span);
                 }
             }
 
             // Finally emit the instruction and move to the next.
-            instr.encode(e);
+            instr.encode(&mut tmp);
         }
-        e.push(0x0b);
+        func.raw(tmp.iter().copied());
+        func.instruction(&wasm_encoder::Instruction::End);
 
         hints
     }
 
-    fn to_const_expr(&self, dwarf: Option<&mut dwarf::Dwarf>) -> wasm_encoder::ConstExpr {
+    fn to_const_expr(&self) -> wasm_encoder::ConstExpr {
         let mut tmp = Vec::new();
-        self.encode(&mut tmp, dwarf);
-        tmp.pop(); // remove trailing 0x0b byte which wasm-encoder doesn't want
+        for instr in self.instrs.iter() {
+            instr.encode(&mut tmp);
+        }
         wasm_encoder::ConstExpr::raw(tmp)
     }
 }


Test patch:
diff --git a/crates/wasm-smith/tests/core.rs b/crates/wasm-smith/tests/core.rs
index 279dca2f..7d949f0b 100644
--- a/crates/wasm-smith/tests/core.rs
+++ b/crates/wasm-smith/tests/core.rs
@@ -124,6 +124,45 @@ fn smoke_test_no_trapping_mode() {
     }
 }
 
+#[test]
+fn smoke_test_disallow_floats() {
+    let mut rng = SmallRng::seed_from_u64(0);
+    let mut buf = vec![0; 2048];
+    for _ in 0..1024 {
+        rng.fill_bytes(&mut buf);
+        let mut u = Unstructured::new(&buf);
+        let mut cfg = Config::arbitrary(&mut u).unwrap();
+        cfg.allow_floats = false;
+        if let Ok(module) = Module::new(cfg, &mut u) {
+            let wasm_bytes = module.to_bytes();
+            let mut features = wasm_features();
+            features.remove(WasmFeatures::FLOATS);
+            let mut validator = Validator::new_with_features(features);
+            validate(&mut validator, &wasm_bytes);
+        }
+    }
+}
+
+#[test]
+fn smoke_test_reference_types() {
+    let mut rng = SmallRng::seed_from_u64(0);
+    let mut buf = vec![0; 2048];
+    for _ in 0..1024 {
+        rng.fill_bytes(&mut buf);
+        let mut u = Unstructured::new(&buf);
+        let mut cfg = Config::arbitrary(&mut u).unwrap();
+        cfg.reference_types_enabled = false;
+        cfg.max_tables = 0;
+        if let Ok(module) = Module::new(cfg, &mut u) {
+            let wasm_bytes = module.to_bytes();
+            let mut features = wasm_features();
+            features.remove(WasmFeatures::REFERENCE_TYPES);
+            let mut validator = Validator::new_with_features(features);
+            validate(&mut validator, &wasm_bytes);
+        }
+    }
+}
+
 #[test]
 fn smoke_test_wasm_gc() {
     let mut rng = SmallRng::seed_from_u64(0);