Repository: bytecodealliance/wasmtime
Pull request #5885 (2023-02-26 15:09:34)

fuzzgen: Initial SIMD support
👋 Hey,

This PR Introduces support for SIMD vectors on fuzzgen. This is mostly to test ABI since it doesn't enable a lot of instructions.

I'm also not planning on introducing pretty much any other SIMD opcodes with the current opcode list system. I think the next step really is to move away from the opcode list.

---

This also does some changes to the clif file format. The current format represents consts as:
```
const0 = [0x00 0x01 0x02]
```

However, when printing a function we print in the following format:
```
const0 = 0x000102
```

And the file does not parse anymore. I.e. we are printing invalid CLIF when constants are involved.

It was easier for me to change the parser, than the printer. However if people prefer the old format, it should also be a fairly easy change.

Another option would be to start accepting both formats, which should also be fairly easy.

If anyone has opinions about this, let me know!


Patch:
diff --git a/cranelift/codegen/meta/src/shared/instructions.rs b/cranelift/codegen/meta/src/shared/instructions.rs
index 56a135072..a54a9818c 100755
--- a/cranelift/codegen/meta/src/shared/instructions.rs
+++ b/cranelift/codegen/meta/src/shared/instructions.rs
@@ -3134,41 +3134,6 @@ pub(crate) fn define(
         .operands_out(vec![a]),
     );
 
-    let I16x8 = &TypeVar::new(
-        "I16x8",
-        "A SIMD vector type containing 8 integer lanes each 16 bits wide.",
-        TypeSetBuilder::new()
-            .ints(16..16)
-            .simd_lanes(8..8)
-            .includes_scalars(false)
-            .build(),
-    );
-
-    let x = &Operand::new("x", I16x8);
-    let y = &Operand::new("y", I16x8);
-    let a = &Operand::new("a", &I16x8.merge_lanes());
-
-    ig.push(
-        Inst::new(
-            "widening_pairwise_dot_product_s",
-            r#"
-        Takes corresponding elements in `x` and `y`, performs a sign-extending length-doubling
-        multiplication on them, then adds adjacent pairs of elements to form the result.  For
-        example, if the input vectors are `[x3, x2, x1, x0]` and `[y3, y2, y1, y0]`, it produces
-        the vector `[r1, r0]`, where `r1 = sx(x3) * sx(y3) + sx(x2) * sx(y2)` and
-        `r0 = sx(x1) * sx(y1) + sx(x0) * sx(y0)`, and `sx(n)` sign-extends `n` to twice its width.
-
-        This will double the lane width and halve the number of lanes.  So the resulting
-        vector has the same number of bits as `x` and `y` do (individually).
-
-        See <https://github.com/WebAssembly/simd/pull/127> for background info.
-            "#,
-            &formats.binary,
-        )
-        .operands_in(vec![x, y])
-        .operands_out(vec![a]),
-    );
-
     let IntTo = &TypeVar::new(
         "IntTo",
         "A larger integer type with the same number of lanes",
diff --git a/cranelift/codegen/src/isa/aarch64/lower.isle b/cranelift/codegen/src/isa/aarch64/lower.isle
index fca811ea8..3eec28c11 100644
--- a/cranelift/codegen/src/isa/aarch64/lower.isle
+++ b/cranelift/codegen/src/isa/aarch64/lower.isle
@@ -204,15 +204,19 @@
 
 ;;;; Rules for `iadd_pairwise` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
+;; special case for the `i16x8.extadd_pairwise_i8x16_s` wasm instruction
 (rule (lower (has_type $I16X8 (iadd_pairwise (swiden_low x) (swiden_high x))))
       (saddlp8 x))
 
+;; special case for the `i32x4.extadd_pairwise_i16x8_s` wasm instruction
 (rule (lower (has_type $I32X4 (iadd_pairwise (swiden_low x) (swiden_high x))))
       (saddlp16 x))
 
+;; special case for the `i16x8.extadd_pairwise_i8x16_u` wasm instruction
 (rule (lower (has_type $I16X8 (iadd_pairwise (uwiden_low x) (uwiden_high x))))
       (uaddlp8 x))
 
+;; special case for the `i32x4.extadd_pairwise_i16x8_u` wasm instruction
 (rule (lower (has_type $I32X4 (iadd_pairwise (uwiden_low x) (uwiden_high x))))
       (uaddlp16 x))
 
@@ -2030,18 +2034,6 @@
       (let ((tmp Reg (fpu_move_from_vec x 1 (VectorSize.Size32x2))))
        (vec_extend (VecExtendOp.Uxtl) tmp $false (lane_size ty))))
 
-;;;; Rules for `widening_pairwise_dot_product_s` ;;;;;;;;;;;;;;;;;;;;;;
-
-;; The args have type I16X8.
-;; "dst = i32x4.dot_i16x8_s(x, y)"
-;; => smull  tmp, x, y
-;;    smull2 dst, x, y
-;;    addp   dst, tmp, dst
-(rule (lower (has_type $I32X4 (widening_pairwise_dot_product_s x y)))
-      (let ((tmp Reg (vec_rrr_long (VecRRRLongOp.Smull16) x y $false))
-            (dst Reg (vec_rrr_long (VecRRRLongOp.Smull16) x y $true)))
-       (vec_rrr (VecALUOp.Addp) tmp dst (VectorSize.Size32x4))))
-
 ;;;; Rules for `Fence` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 (rule (lower (fence))
diff --git a/cranelift/codegen/src/isa/riscv64/inst/emit.rs b/cranelift/codegen/src/isa/riscv64/inst/emit.rs
index d359ff237..007a2c38f 100644
--- a/cranelift/codegen/src/isa/riscv64/inst/emit.rs
+++ b/cranelift/codegen/src/isa/riscv64/inst/emit.rs
@@ -1751,23 +1751,23 @@ impl MachInstEmit for Inst {
                 if out_type.bits() < 32 && is_signed {
                     // load value part mask.
                     Inst::load_constant_u32(
-                        tmp,
+                        writable_spilltmp_reg(),
                         if 16 == out_type.bits() {
                             (u16::MAX >> 1) as u64
                         } else {
                             // I8
                             (u8::MAX >> 1) as u64
                         },
-                        &mut |_| writable_spilltmp_reg(),
+                        &mut |_| writable_spilltmp_reg2(),
                     )
                     .into_iter()
                     .for_each(|x| x.emit(&[], sink, emit_info, state));
                     // keep value part.
                     Inst::AluRRR {
                         alu_op: AluOPRRR::And,
-                        rd: tmp,
+                        rd: writable_spilltmp_reg(),
                         rs1: rd.to_reg(),
-                        rs2: tmp.to_reg(),
+                        rs2: spilltmp_reg(),
                     }
                     .emit(&[], sink, emit_info, state);
                     // extact sign bit.
@@ -1795,7 +1795,7 @@ impl MachInstEmit for Inst {
                         alu_op: AluOPRRR::Or,
                         rd: rd,
                         rs1: rd.to_reg(),
-                        rs2: tmp.to_reg(),
+                        rs2: spilltmp_reg(),
                     }
                     .emit(&[], sink, emit_info, state);
                 }
diff --git a/cranelift/codegen/src/isa/riscv64/inst/mod.rs b/cranelift/codegen/src/isa/riscv64/inst/mod.rs
index 482f309bd..d7fbb6ca9 100644
--- a/cranelift/codegen/src/isa/riscv64/inst/mod.rs
+++ b/cranelift/codegen/src/isa/riscv64/inst/mod.rs
@@ -524,7 +524,7 @@ fn riscv64_get_operands<F: Fn(VReg) -> VReg>(inst: &Inst, collector: &mut Operan
         &Inst::FcvtToInt { rd, rs, tmp, .. } => {
             collector.reg_use(rs);
             collector.reg_early_def(tmp);
-            collector.reg_def(rd);
+            collector.reg_early_def(rd);
         }
         &Inst::SelectIf {
             ref rd,
diff --git a/cranelift/codegen/src/isa/s390x/lower.isle b/cranelift/codegen/src/isa/s390x/lower.isle
index ed725d1dc..84e10b4fd 100644
--- a/cranelift/codegen/src/isa/s390x/lower.isle
+++ b/cranelift/codegen/src/isa/s390x/lower.isle
@@ -138,6 +138,14 @@
                              (vec_add ty x (vec_lshr_by_byte x size))
                              (vec_add ty y (vec_lshr_by_byte y size)))))
 
+;; special case for the `i32x4.dot_i16x8_s` wasm instruction
+(rule 1 (lower
+        (has_type dst_ty (iadd_pairwise
+                           (imul (swiden_low x @ (value_type src_ty)) (swiden_low y))
+                           (imul (swiden_high x) (swiden_high y)))))
+      (vec_add dst_ty (vec_smul_even src_ty x y)
+                      (vec_smul_odd src_ty x y)))
+
 
 ;;;; Rules for `isub` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
@@ -484,15 +492,6 @@
         (mov_to_vec128 $I64X2 res_0 res_1)))
 
 
-;;;; Rules for `widening_pairwise_dot_product_s` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-;; Widening pairwise dot product of two vector registers.
-(rule (lower (has_type dst_ty (widening_pairwise_dot_product_s
-                                 x @ (value_type src_ty) y)))
-      (vec_add dst_ty (vec_smul_even src_ty x y)
-                      (vec_smul_odd src_ty x y)))
-
-
 ;;;; Rules for `sqmul_round_sat` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 ;; Fixed-point multiplication of two vector registers.
diff --git a/cranelift/codegen/src/isa/x64/inst.isle b/cranelift/codegen/src/isa/x64/inst.isle
index 34e3145c5..d25cc7efc 100644
--- a/cranelift/codegen/src/isa/x64/inst.isle
+++ b/cranelift/codegen/src/isa/x64/inst.isle
@@ -4489,6 +4489,8 @@
 (convert SyntheticAmode XmmMem synthetic_amode_to_xmm_mem)
 (convert Amode XmmMemAligned amode_to_xmm_mem_aligned)
 (convert SyntheticAmode XmmMemAligned synthetic_amode_to_xmm_mem_aligned)
+(convert VCodeConstant SyntheticAmode const_to_synthetic_amode)
+(convert VCodeConstant XmmMem const_to_xmm_mem)
 
 (convert IntCC CC intcc_to_cc)
 (convert AtomicRmwOp MachAtomicRmwOp atomic_rmw_op_to_mach_atomic_rmw_op)
@@ -4537,6 +4539,8 @@
       (synthetic_amode_to_reg_mem amode))
 (decl const_to_synthetic_amode (VCodeConstant) SyntheticAmode)
 (extern constructor const_to_synthetic_amode const_to_synthetic_amode)
+(decl const_to_xmm_mem (VCodeConstant) XmmMem)
+(rule (const_to_xmm_mem c) (const_to_synthetic_amode c))
 
 (decl xmm_to_xmm_mem_aligned (Xmm) XmmMemAligned)
 (rule (xmm_to_xmm_mem_aligned reg) (xmm_mem_to_xmm_mem_aligned reg))
diff --git a/cranelift/codegen/src/isa/x64/lower.isle b/cranelift/codegen/src/isa/x64/lower.isle
index dcc8bd1f0..40b40f9b9 100644
--- a/cranelift/codegen/src/isa/x64/lower.isle
+++ b/cranelift/codegen/src/isa/x64/lower.isle
@@ -1908,7 +1908,7 @@
 (rule (lower (has_type $I8X16
                        (popcnt src)))
       (let ((nibble_table_const VCodeConstant (popcount_4bit_table))
-            (low_mask Xmm (x64_xmm_load_const $I8X16 (popcount_low_mask)))
+            (low_mask XmmMem (popcount_low_mask))
             (low_nibbles Xmm (sse_and $I8X16 src low_mask))
             ;; Note that this is a 16x8 shift, but that's OK; we mask
             ;; off anything that traverses from one byte to the next
@@ -2147,12 +2147,6 @@
 (rule (lower (debugtrap))
       (side_effect (x64_hlt)))
 
-;; Rules for `widening_pairwise_dot_product_s` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-(rule (lower (has_type $I32X4
-                       (widening_pairwise_dot_product_s x y)))
-      (x64_pmaddwd x y))
-
 ;; Rules for `fadd` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 (rule (lower (has_type $F32 (fadd x y)))
@@ -2990,9 +2984,9 @@
 ;; every value of the mantissa represents a corresponding uint32 number.
 ;; When we subtract 0x1.0p52 we are left with double(src).
 (rule 1 (lower (has_type $F64X2 (fcvt_from_uint (uwiden_low val @ (value_type $I32X4)))))
-      (let ((uint_mask Xmm (x64_xmm_load_const $I32X4 (fcvt_uint_mask_const)))
+      (let ((uint_mask XmmMem (fcvt_uint_mask_const))
             (res Xmm (x64_unpcklps val uint_mask))
-            (uint_mask_high Xmm (x64_xmm_load_const $I32X4 (fcvt_uint_mask_high_const))))
+            (uint_mask_high XmmMem (fcvt_uint_mask_high_const)))
         (x64_subpd res uint_mask_high)))
 
 ;; When AVX512VL and AVX512F are available,
@@ -3179,6 +3173,7 @@
 
 ;; Rules for `iadd_pairwise` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
+;; special case for the `i16x8.extadd_pairwise_i8x16_s` wasm instruction
 (rule (lower
         (has_type $I16X8 (iadd_pairwise
                            (swiden_low val @ (value_type $I8X16))
@@ -3186,33 +3181,43 @@
       (let ((mul_const Xmm (x64_xmm_load_const $I8X16 (iadd_pairwise_mul_const_16))))
         (x64_pmaddubsw mul_const val)))
 
+;; special case for the `i32x4.extadd_pairwise_i16x8_s` wasm instruction
 (rule (lower
         (has_type $I32X4 (iadd_pairwise
                            (swiden_low val @ (value_type $I16X8))
                            (swiden_high val))))
-      (let ((mul_const Xmm (x64_xmm_load_const $I16X8 (iadd_pairwise_mul_const_32))))
+      (let ((mul_const XmmMem (iadd_pairwise_mul_const_32)))
         (x64_pmaddwd val mul_const)))
 
+;; special case for the `i16x8.extadd_pairwise_i8x16_u` wasm instruction
 (rule (lower
         (has_type $I16X8 (iadd_pairwise
                            (uwiden_low val @ (value_type $I8X16))
                            (uwiden_high val))))
-      (let ((mul_const Xmm (x64_xmm_load_const $I8X16 (iadd_pairwise_mul_const_16))))
+      (let ((mul_const XmmMem (iadd_pairwise_mul_const_16)))
         (x64_pmaddubsw val mul_const)))
 
+;; special case for the `i32x4.extadd_pairwise_i16x8_u` wasm instruction
 (rule (lower
         (has_type $I32X4 (iadd_pairwise
                            (uwiden_low val @ (value_type $I16X8))
                            (uwiden_high val))))
-      (let ((xor_const Xmm (x64_xmm_load_const $I16X8 (iadd_pairwise_xor_const_32)))
+      (let ((xor_const XmmMem (iadd_pairwise_xor_const_32))
             (dst Xmm (x64_pxor val xor_const))
 
-            (madd_const Xmm (x64_xmm_load_const $I16X8 (iadd_pairwise_mul_const_32)))
+            (madd_const XmmMem (iadd_pairwise_mul_const_32))
             (dst Xmm (x64_pmaddwd dst madd_const))
 
-            (addd_const Xmm (x64_xmm_load_const $I16X8 (iadd_pairwise_addd_const_32))))
+            (addd_const XmmMem (iadd_pairwise_addd_const_32)))
         (x64_paddd dst addd_const)))
 
+;; special case for the `i32x4.dot_i16x8_s` wasm instruction
+(rule (lower
+        (has_type $I32X4 (iadd_pairwise
+                           (imul (swiden_low x) (swiden_low y))
+                           (imul (swiden_high x) (swiden_high y)))))
+      (x64_pmaddwd x y))
+
 ;; Rules for `swiden_low` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 (rule (lower (has_type $I16X8 (swiden_low val @ (value_type $I8X16))))
@@ -3288,7 +3293,7 @@
             ;; CVTTPD2DQ xmm_y, xmm_y
 
             (tmp1 Xmm (x64_cmppd a a (FcmpImm.Equal)))
-            (umax_mask Xmm (x64_xmm_load_const $F64X2 (snarrow_umax_mask)))
+            (umax_mask XmmMem (snarrow_umax_mask))
 
             ;; ANDPD xmm_y, [wasm_f64x2_splat(2147483647.0)]
             (tmp1 Xmm (x64_andps tmp1 umax_mask))
@@ -3504,7 +3509,7 @@
 ;; indices (may not be completely necessary: verification could fail incorrect
 ;; mask values) and fix the indexes to all point to the `dst` vector.
 (rule 3 (lower (shuffle a a (vec_mask_from_immediate mask)))
-      (x64_pshufb a (x64_xmm_load_const $I8X16 (shuffle_0_31_mask mask))))
+      (x64_pshufb a (shuffle_0_31_mask mask)))
 
 ;; For the case where the shuffle mask contains out-of-bounds values (values
 ;; greater than 31) we must mask off those resulting values in the result of
@@ -3512,9 +3517,7 @@
 (rule 2 (lower (has_type (and (avx512vl_enabled $true) (avx512vbmi_enabled $true))
                          (shuffle a b (vec_mask_from_immediate
                                         (perm_from_mask_with_zeros mask zeros)))))
-      (x64_andps
-        (x64_xmm_load_const $I8X16 zeros)
-        (x64_vpermi2b b a (x64_xmm_load_const $I8X16 mask))))
+      (x64_andps (x64_vpermi2b b a (x64_xmm_load_const $I8X16 mask)) zeros))
 
 ;; However, if the shuffle mask contains no out-of-bounds values, we can use
 ;; `vpermi2b` without any masking.
@@ -3527,8 +3530,8 @@
 ;; above, we build the `constructed_mask` for each case statically.
 (rule (lower (shuffle a b (vec_mask_from_immediate mask)))
       (x64_por
-        (x64_pshufb a (x64_xmm_load_const $I8X16 (shuffle_0_15_mask mask)))
-        (x64_pshufb b (x64_xmm_load_const $I8X16 (shuffle_16_31_mask mask)))))
+        (x64_pshufb a (shuffle_0_15_mask mask))
+        (x64_pshufb b (shuffle_16_31_mask mask))))
 
 ;; Rules for `swizzle` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
@@ -3539,9 +3542,7 @@
 ;; Wasm SIMD semantics for this instruction. The instruction format maps to
 ;; variables like: %dst = swizzle %src, %mask
 (rule (lower (swizzle src mask))
-      (let ((mask Xmm (x64_paddusb
-                        mask
-                        (x64_xmm_load_const $I8X16 (swizzle_zero_mask)))))
+      (let ((mask Xmm (x64_paddusb mask (swizzle_zero_mask))))
         (x64_pshufb src mask)))
 
 ;; Rules for `extractlane` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -3716,9 +3717,9 @@
       (let ((src1 Xmm qx)
             (src2 Xmm qy)
 
-            (mask Xmm (x64_xmm_load_const $I16X8 (sqmul_round_sat_mask)))
+            (mask XmmMem (sqmul_round_sat_mask))
             (dst Xmm (x64_pmulhrsw src1 src2))
-            (cmp Xmm (x64_pcmpeqw mask dst)))
+            (cmp Xmm (x64_pcmpeqw dst mask)))
         (x64_pxor dst cmp)))
 
 ;; Rules for `sqmul_round_sat` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -3744,7 +3745,7 @@
             (zeros Xmm (xmm_zero $F64X2))
             (dst Xmm (x64_maxpd src zeros))
 
-            (umax_mask Xmm (x64_xmm_load_const $F64X2 (uunarrow_umax_mask)))
+            (umax_mask XmmMem (uunarrow_umax_mask))
 
             ;; MINPD xmm_y, [wasm_f64x2_splat(4294967295.0)]
             (dst Xmm (x64_minpd dst umax_mask))
@@ -3753,7 +3754,7 @@
             (dst Xmm (x64_roundpd dst (RoundImm.RoundZero)))
 
             ;; ADDPD xmm_y, [wasm_f64x2_splat(0x1.0p+52)]
-            (uint_mask Xmm (x64_xmm_load_const $F64X2 (uunarrow_uint_mask)))
+            (uint_mask XmmMem (uunarrow_uint_mask))
             (dst Xmm (x64_addpd dst uint_mask)))
 
         ;; SHUFPS xmm_y, xmm_xmp, 0x88
diff --git a/cranelift/codegen/src/isle_prelude.rs b/cranelift/codegen/src/isle_prelude.rs
index 0e3e293c1..435955fa2 100644
--- a/cranelift/codegen/src/isle_prelude.rs
+++ b/cranelift/codegen/src/isle_prelude.rs
@@ -129,6 +129,16 @@ macro_rules! isle_common_prelude_methods {
             x == y
         }
 
+        #[inline]
+        fn u64_le(&mut self, x: u64, y: u64) -> bool {
+            x <= y
+        }
+
+        #[inline]
+        fn u64_lt(&mut self, x: u64, y: u64) -> bool {
+            x < y
+        }
+
         #[inline]
         fn u64_is_zero(&mut self, value: u64) -> bool {
             0 == value
diff --git a/cranelift/codegen/src/opts/algebraic.isle b/cranelift/codegen/src/opts/algebraic.isle
index da177603e..ecd71988c 100644
--- a/cranelift/codegen/src/opts/algebraic.isle
+++ b/cranelift/codegen/src/opts/algebraic.isle
@@ -187,16 +187,10 @@
 (rule (simplify (imul ty (iconst _ (imm64_power_of_two c)) x))
       (ishl ty x (iconst ty (imm64 c))))
 
-;; x<<32>>32: uextend/sextend 32->64.
-(rule (simplify (ushr $I64 (ishl $I64 (uextend $I64 x @ (value_type $I32)) (iconst _ (simm32 32))) (iconst _ (simm32 32))))
-      (uextend $I64 x))
-
-(rule (simplify (sshr $I64 (ishl $I64 (uextend $I64 x @ (value_type $I32)) (iconst _ (simm32 32))) (iconst _ (simm32 32))))
-      (sextend $I64 x))
-
 ;; TODO: strength reduction: div to shifts
 ;; TODO: div/rem by constants -> magic multiplications
 
+
 ;; `(x >> k) << k` is the same as masking off the bottom `k` bits (regardless if
 ;; this is a signed or unsigned shift right).
 (rule (simplify (ishl (fits_in_64 ty)
@@ -210,6 +204,66 @@
       (let ((mask Imm64 (imm64_shl ty (imm64 0xFFFF_FFFF_FFFF_FFFF) k)))
         (band ty x (iconst ty mask))))
 
+
+;; For unsigned shifts, `(x << k) >> k` is the same as masking out the top
+;; `k` bits. A similar rule is valid for vectors but this `iconst` mask only
+;; works for scalar integers.
+(rule (simplify (ushr (fits_in_64 (ty_int ty))
+                      (ishl ty x (iconst _ k))
+                      (iconst _ k)))
+      (band ty x (iconst ty (imm64_ushr ty (imm64 (ty_mask ty)) k))))
+
+
+;; For signed shifts, `(x << k) >> k` does sign-extension from `n` bits to
+;; `n+k` bits. In the special case where `x` is the result of either `sextend`
+;; or `uextend` from `n` bits to `n+k` bits, we can implement this using
+;; `sextend`.
+(rule (simplify (sshr wide
+                 (ishl wide
+                  (uextend wide x @ (value_type narrow))
+                  (iconst _ shift))
+                 (iconst _ shift)))
+      (if-let (u64_from_imm64 shift_u64) shift)
+      (if-let $true (u64_eq shift_u64 (u64_sub (ty_bits_u64 wide) (ty_bits_u64 narrow))))
+      (sextend wide x))
+
+;; If `k` is smaller than the difference in bit widths of the two types, then
+;; the intermediate sign bit comes from the extend op, so the final result is
+;; the same as the original extend op.
+(rule (simplify (sshr wide
+                 (ishl wide
+                  x @ (uextend wide (value_type narrow))
+                  (iconst _ shift))
+                 (iconst _ shift)))
+      (if-let (u64_from_imm64 shift_u64) shift)
+      (if-let $true (u64_lt shift_u64 (u64_sub (ty_bits_u64 wide) (ty_bits_u64 narrow))))
+      x)
+
+;; If the original extend op was `sextend`, then both of the above cases say
+;; the result should also be `sextend`.
+(rule (simplify (sshr wide
+                 (ishl wide
+                  x @ (sextend wide (value_type narrow))
+                  (iconst _ shift))
+                 (iconst _ shift)))
+      (if-let (u64_from_imm64 shift_u64) shift)
+      (if-let $true (u64_le shift_u64 (u64_sub (ty_bits_u64 wide) (ty_bits_u64 narrow))))
+      x)
+
+
+;; Masking out any of the top bits of the result of `uextend` is a no-op. (This
+;; is like a cheap version of known-bits analysis.)
+(rule (simplify (band wide x @ (uextend _ (value_type narrow)) (iconst _ (u64_from_imm64 mask))))
+      ; Check that `narrow_mask` has a subset of the bits that `mask` does.
+      (if-let $true (let ((narrow_mask u64 (ty_mask narrow))) (u64_eq narrow_mask (u64_and mask narrow_mask))))
+      x)
+
+;; Masking out the sign-extended bits of an `sextend` turns it into a `uextend`.
+(rule (simplify (band wide (sextend _ x @ (value_type narrow)) (iconst _ (u64_from_imm64 mask))))
+      (if-let $true (u64_eq mask (ty_mask narrow)))
+      (uextend wide x))
+
+
 ;; Rematerialize ALU-op-with-imm and iconsts in each block where they're
 ;; used. This is neutral (add-with-imm) or positive (iconst) for
 ;; register pressure, and these ops are very cheap.
diff --git a/cranelift/codegen/src/prelude.isle b/cranelift/codegen/src/prelude.isle
index 701f414a9..89fc8e981 100644
--- a/cranelift/codegen/src/prelude.isle
+++ b/cranelift/codegen/src/prelude.isle
@@ -144,6 +144,12 @@
 (decl pure u64_eq (u64 u64) bool)
 (extern constructor u64_eq u64_eq)
 
+(decl pure u64_le (u64 u64) bool)
+(extern constructor u64_le u64_le)
+
+(decl pure u64_lt (u64 u64) bool)
+(extern constructor u64_lt u64_lt)
+
 (decl pure i64_sextend_imm64 (Type Imm64) i64)
 (extern constructor i64_sextend_imm64 i64_sextend_imm64)
 
diff --git a/cranelift/fuzzgen/src/cranelift_arbitrary.rs b/cranelift/fuzzgen/src/cranelift_arbitrary.rs
index ca59135ae..ebafb55d8 100644
--- a/cranelift/fuzzgen/src/cranelift_arbitrary.rs
+++ b/cranelift/fuzzgen/src/cranelift_arbitrary.rs
@@ -7,27 +7,39 @@ use cranelift::codegen::isa::CallConv;
 
 use arbitrary::Unstructured;
 use cranelift::prelude::{Ieee32, Ieee64};
+use target_lexicon::Architecture;
 
 /// A trait for generating random Cranelift datastructures.
 pub trait CraneliftArbitrary {
-    fn _type(&mut self) -> Result<Type>;
+    fn _type(&mut self, architecture: Architecture) -> Result<Type>;
     fn callconv(&mut self) -> Result<CallConv>;
-    fn abi_param(&mut self) -> Result<AbiParam>;
-    fn signature(&mut self, max_params: usize, max_rets: usize) -> Result<Signature>;
+    fn abi_param(&mut self, architecture: Architecture) -> Result<AbiParam>;
+    fn signature(
+        &mut self,
+        architecture: Architecture,
+        max_params: usize,
+        max_rets: usize,
+    ) -> Result<Signature>;
     fn datavalue(&mut self, ty: Type) -> Result<DataValue>;
 }
 
 impl<'a> CraneliftArbitrary for &mut Unstructured<'a> {
-    fn _type(&mut self) -> Result<Type> {
+    fn _type(&mut self, architecture: Architecture) -> Result<Type> {
         // TODO: It would be nice if we could get these directly from cranelift
-        let scalars = [
-            I8, I16, I32, I64, I128, F32, F64,
-            // R32, R64,
-        ];
-        // TODO: vector types
+        // TODO: RISCV does not support SIMD yet
+        let supports_simd = !matches!(architecture, Architecture::Riscv64(_));
+        let choices = if supports_simd {
+            &[
+                I8, I16, I32, I64, I128, // Scalar Integers
+                F32, F64, // Scalar Floats
+                I8X16, I16X8, I32X4, I64X2, // SIMD Integers
+                F32X4, F64X2, // SIMD Floats
+            ][..]
+        } else {
+            &[I8, I16, I32, I64, I128, F32, F64][..]
+        };
 
-        let ty = self.choose(&scalars[..])?;
-        Ok(*ty)
+        Ok(*self.choose(choices)?)
     }
 
     fn callconv(&mut self) -> Result<CallConv> {
@@ -35,8 +47,8 @@ impl<'a> CraneliftArbitrary for &mut Unstructured<'a> {
         Ok(CallConv::SystemV)
     }
 
-    fn abi_param(&mut self) -> Result<AbiParam> {
-        let value_type = self._type()?;
+    fn abi_param(&mut self, architecture: Architecture) -> Result<AbiParam> {
+        let value_type = self._type(architecture)?;
         // TODO: There are more argument purposes to be explored...
         let purpose = ArgumentPurpose::Normal;
         let extension = if value_type.is_int() {
@@ -56,16 +68,21 @@ impl<'a> CraneliftArbitrary for &mut Unstructured<'a> {
         })
     }
 
-    fn signature(&mut self, max_params: usize, max_rets: usize) -> Result<Signature> {
+    fn signature(
+        &mut self,
+        architecture: Architecture,
+        max_params: usize,
+        max_rets: usize,
+    ) -> Result<Signature> {
         let callconv = self.callconv()?;
         let mut sig = Signature::new(callconv);
 
         for _ in 0..max_params {
-            sig.params.push(self.abi_param()?);
+            sig.params.push(self.abi_param(architecture)?);
         }
 
         for _ in 0..max_rets {
-            sig.returns.push(self.abi_param()?);
+            sig.returns.push(self.abi_param(architecture)?);
         }
 
         Ok(sig)
@@ -88,6 +105,9 @@ impl<'a> CraneliftArbitrary for &mut Unstructured<'a> {
             // such as Signaling NaN's / NaN's with payload, so generate floats from integers.
             F32 => DataValue::F32(Ieee32::with_bits(self.arbitrary::<u32>()?)),
             F64 => DataValue::F64(Ieee64::with_bits(self.arbitrary::<u64>()?)),
+            ty if ty.is_vector() && ty.bits() == 128 => {
+                DataValue::V128(self.arbitrary::<[u8; 16]>()?)
+            }
             _ => unimplemented!(),
         })
     }
diff --git a/cranelift/fuzzgen/src/function_generator.rs b/cranelift/fuzzgen/src/function_generator.rs
index 8272a5455..00c4a9212 100644
--- a/cranelift/fuzzgen/src/function_generator.rs
+++ b/cranelift/fuzzgen/src/function_generator.rs
@@ -290,6 +290,36 @@ fn insert_atomic_rmw(
     Ok(())
 }
 
+fn insert_atomic_cas(
+    fgen: &mut FunctionGenerator,
+    builder: &mut FunctionBuilder,
+    _: Opcode,
+    _: &'static [Type],
+    rets: &'static [Type],
+) -> Result<()> {
+    let ctrl_type = *rets.first().unwrap();
+    let type_size = ctrl_type.bytes();
+
+    let (address, flags, offset) = fgen.generate_address_and_memflags(builder, type_size, true)?;
+
+    // AtomicCas does not directly support offsets, so add the offset to the address separately.
+    let address = builder.ins().iadd_imm(address, i64::from(offset));
+
+    // Source and Target variables
+    let expected_var = fgen.get_variable_of_type(ctrl_type)?;
+    let store_var = fgen.get_variable_of_type(ctrl_type)?;
+    let loaded_var = fgen.get_variable_of_type(ctrl_type)?;
+
+    let expected_val = builder.use_var(expected_var);
+    let store_val = builder.use_var(store_var);
+    let new_val = builder
+        .ins()
+        .atomic_cas(flags, address, expected_val, store_val);
+
+    builder.def_var(loaded_var, new_val);
+    Ok(())
+}
+
 type OpcodeInserter = fn(
     fgen: &mut FunctionGenerator,
     builder: &mut FunctionBuilder,
@@ -535,6 +565,12 @@ fn valid_for_target(triple: &Triple, op: Opcode, args: &[Type], rets: &[Type]) -
         }
 
         Architecture::Riscv64(_) => {
+            // RISC-V Does not support SIMD at all
+            let is_simd = args.iter().chain(rets).any(|t| t.is_vector());
+            if is_simd {
+                return false;
+            }
+
             exceptions!(
                 // TODO
                 (Opcode::IaddCout),
@@ -617,6 +653,8 @@ fn valid_for_target(triple: &Triple, op: Opcode, args: &[Type], rets: &[Type]) -
                 // TODO
                 (Opcode::BxorNot, &[F32, F32]),
                 (Opcode::BxorNot, &[F64, F64]),
+                // https://github.com/bytecodealliance/wasmtime/issues/5884
+                (Opcode::AtomicRmw),
             )
         }
 
@@ -705,6 +743,10 @@ const OPCODE_SIGNATURES: &[OpcodeSignature] = &[
     (Opcode::Iabs, &[I32], &[I32], insert_opcode),
     (Opcode::Iabs, &[I64], &[I64], insert_opcode),
     (Opcode::Iabs, &[I128], &[I128], insert_opcode),
+    (Opcode::Iabs, &[I8X16, I8X16], &[I8X16], insert_opcode),
+    (Opcode::Iabs, &[I16X8, I16X8], &[I16X8], insert_opcode),
+    (Opcode::Iabs, &[I32X4, I32X4], &[I32X4], insert_opcode),
+    (Opcode::Iabs, &[I64X2, I64X2], &[I64X2], insert_opcode),
     // Smin
     (Opcode::Smin, &[I8, I8], &[I8], insert_opcode),
     (Opcode::Smin, &[I16, I16], &[I16], insert_opcode),
@@ -1272,6 +1314,11 @@ const OPCODE_SIGNATURES: &[OpcodeSignature] = &[
     (Opcode::AtomicRmw, &[I16, I16], &[I16], insert_atomic_rmw),
     (Opcode::AtomicRmw, &[I32, I32], &[I32], insert_atomic_rmw),
     (Opcode::AtomicRmw, &[I64, I64], &[I64], insert_atomic_rmw),
+    // AtomicCas
+    (Opcode::AtomicCas, &[I8, I8], &[I8], insert_atomic_cas),
+    (Opcode::AtomicCas, &[I16, I16], &[I16], insert_atomic_cas),
+    (Opcode::AtomicCas, &[I32, I32], &[I32], insert_atomic_cas),
+    (Opcode::AtomicCas, &[I64, I64], &[I64], insert_atomic_cas),
     // Bitcast
     (Opcode::Bitcast, &[F32], &[I32], insert_bitcast),
     (Opcode::Bitcast, &[I32], &[F32], insert_bitcast),
@@ -1458,10 +1505,14 @@ where
         is_atomic: bool,
     ) -> Result<(Value, MemFlags, Offset32)> {
         // Should we generate an aligned address
-        let is_aarch64 = matches!(self.target_triple.architecture, Architecture::Aarch64(_));
-        let aligned = if is_atomic && is_aarch64 {
-            // AArch64 has issues with unaligned atomics.
-            // https://github.com/bytecodealliance/wasmtime/issues/5483
+        // Some backends have issues with unaligned atomics.
+        // AArch64: https://github.com/bytecodealliance/wasmtime/issues/5483
+        // RISCV: https://github.com/bytecodealliance/wasmtime/issues/5882
+        let requires_aligned_atomics = matches!(
+            self.target_triple.architecture,
+            Architecture::Aarch64(_) | Architecture::Riscv64(_)
+        );
+        let aligned = if is_atomic && requires_aligned_atomics {
             true
         } else {
             bool::arbitrary(self.u)?
@@ -1511,6 +1562,11 @@ where
             }
             DataValue::F32(f) => builder.ins().f32const(f),
             DataValue::F64(f) => builder.ins().f64const(f),
+            DataValue::V128(bytes) => {
+                let data = bytes.to_vec().into();
+                let handle = builder.func.dfg.constants.insert(data);
+                builder.ins().vconst(ty, handle)
+            }
             _ => unimplemented!(),
         })
     }
@@ -1881,7 +1937,7 @@ where
 
         let mut params = Vec::with_capacity(param_count);
         for _ in 0..param_count {
-            params.push(self.u._type()?);
+            params.push(self.u._type(self.target_triple.architecture)?);
         }
         Ok(params)
     }
@@ -1901,7 +1957,7 @@ where
 
         // Create a pool of vars that are going to be used in this function
         for _ in 0..self.param(&self.config.vars_per_function)? {
-            let ty = self.u._type()?;
+            let ty = self.u._type(self.target_triple.architecture)?;
             let value = self.generate_const(builder, ty)?;
             vars.push((ty, value));
         }
diff --git a/cranelift/fuzzgen/src/lib.rs b/cranelift/fuzzgen/src/lib.rs
index ee0c36423..d03665004 100644
--- a/cranelift/fuzzgen/src/lib.rs
+++ b/cranelift/fuzzgen/src/lib.rs
@@ -256,7 +256,9 @@ where
     fn generate_func(&mut self, target_triple: Triple) -> Result<Function> {
         let max_params = self.u.int_in_range(self.config.signature_params.clone())?;
         let max_rets = self.u.int_in_range(self.config.signature_rets.clone())?;
-        let sig = self.u.signature(max_params, max_rets)?;
+        let sig = self
+            .u
+            .signature(target_triple.architecture, max_params, max_rets)?;
 
         // Function name must be in a different namespace than TESTFILE_NAMESPACE (0)
         let fname = UserFuncName::user(1, 0);
@@ -266,7 +268,9 @@ where
             .map(|i| {
                 let max_params = self.u.int_in_range(self.config.signature_params.clone())?;
                 let max_rets = self.u.int_in_range(self.config.signature_rets.clone())?;
-                let sig = self.u.signature(max_params, max_rets)?;
+                let sig = self
+                    .u
+                    .signature(target_triple.architecture, max_params, max_rets)?;
                 let name = UserExternalName {
                     namespace: 2,
                     index: i as u32,
diff --git a/cranelift/interpreter/src/step.rs b/cranelift/interpreter/src/step.rs
index e64d90838..d4da0a2d2 100644
--- a/cranelift/interpreter/src/step.rs
+++ b/cranelift/interpreter/src/step.rs
@@ -1308,26 +1308,6 @@ where
             // actually need to emit a fence here.
             ControlFlow::Continue
         }
-        Opcode::WideningPairwiseDotProductS => {
-            let ctrl_ty = types::I16X8;
-            let new_type = ctrl_ty.merge_lanes().unwrap();
-            let arg0 = extractlanes(&arg(0)?, ctrl_ty)?;
-            let arg1 = extractlanes(&arg(1)?, ctrl_ty)?;
-            let new_vec = arg0
-                .chunks(2)
-                .into_iter()
-                .zip(arg1.chunks(2))
-                .into_iter()
-                .map(|(x, y)| {
-                    let mut z = 0i128;
-                    for (lhs, rhs) in x.into_iter().zip(y.into_iter()) {
-                        z += lhs.clone().into_int()? * rhs.clone().into_int()?;
-                    }
-                    Value::int(z, new_type.lane_type())
-                })
-                .collect::<ValueResult<Vec<_>>>()?;
-            assign(vectorizelanes(&new_vec, new_type)?)
-        }
         Opcode::SqmulRoundSat => {
             let lane_type = ctrl_ty.lane_type();
             let double_width = ctrl_ty.double_width().unwrap().lane_type();
diff --git a/cranelift/jit/src/compiled_blob.rs b/cranelift/jit/src/compiled_blob.rs
index 1d1d5cc4d..7c60454e7 100644
--- a/cranelift/jit/src/compiled_blob.rs
+++ b/cranelift/jit/src/compiled_blob.rs
@@ -3,6 +3,14 @@ use cranelift_module::ModuleExtName;
 use cranelift_module::ModuleReloc;
 use std::convert::TryFrom;
 
+/// Reads a 32bit instruction at `iptr`, and writes it again after
+/// being altered by `modifier`
+unsafe fn modify_inst32(iptr: *mut u32, modifier: impl FnOnce(u32) -> u32) {
+    let inst = iptr.read_unaligned();
+    let new_inst = modifier(inst);
+    iptr.write_unaligned(new_inst);
+}
+
 #[derive(Clone)]
 pub(crate) struct CompiledBlob {
     pub(crate) ptr: *mut u8,
@@ -97,9 +105,34 @@ impl CompiledBlob {
                     // immediate offset argument.
                     let chop = 32 - 26;
                     let imm26 = (diff as u32) << chop >> chop;
-                    let ins = unsafe { iptr.read_unaligned() } | imm26;
+                    unsafe { modify_inst32(iptr, |inst| inst | imm26) };
+                }
+                Reloc::RiscvCall => {
+                    // A R_RISCV_CALL relocation expects auipc+jalr instruction pair.
+                    // It is the equivalent of two relocations:
+                    // 1. R_RISCV_PCREL_HI20 on the `auipc`
+                    // 2. R_RISCV_PCREL_LO12_I on the `jalr`
+
+                    let base = get_address(name);
+                    let what = unsafe { base.offset(isize::try_from(addend).unwrap()) };
+                    let pcrel = i32::try_from((what as isize) - (at as isize)).unwrap() as u32;
+
+                    // See https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-elf.adoc#pc-relative-symbol-addresses
+                    // for a better explanation of the following code.
+                    //
+                    // Unlike the regular symbol relocations, here both "sub-relocations" point
+                    // to the same address.
+                    let hi20 = pcrel.wrapping_add(0x800) & 0xFFFFF000;
+                    let lo12 = (pcrel - hi20) & 0xFFF;
+
                     unsafe {
-                        iptr.write_unaligned(ins);
+                        // Do a R_RISCV_PCREL_HI20 on the `auipc`
+                        let auipc_addr = at as *mut u32;
+                        modify_inst32(auipc_addr, |auipc| (auipc & 0xFFF) | hi20);
+
+                        // Do a R_RISCV_PCREL_LO12_I on the `jalr`
+                        let jalr_addr = at.offset(4) as *mut u32;
+                        modify_inst32(jalr_addr, |jalr| (jalr & 0xFFFFF) | (lo12 << 20));
                     }
                 }
                 _ => unimplemented!(),
diff --git a/cranelift/reader/src/parser.rs b/cranelift/reader/src/parser.rs
index fca5fa499..1e2be4824 100644
--- a/cranelift/reader/src/parser.rs
+++ b/cranelift/reader/src/parser.rs
@@ -729,16 +729,6 @@ impl<'a> Parser<'a> {
         }
     }
 
-    // Match and consume a sequence of immediate bytes (uimm8); e.g. [0x42 0x99 0x32]
-    fn match_constant_data(&mut self) -> ParseResult<ConstantData> {
-        self.match_token(Token::LBracket, "expected an opening left bracket")?;
-        let mut data = ConstantData::default();
-        while !self.optional(Token::RBracket) {
-            data = data.append(self.match_uimm8("expected a sequence of bytes (uimm8)")?);
-        }
-        Ok(data)
-    }
-
     // Match and consume either a hexadecimal Uimm128 immediate (e.g. 0x000102...) or its literal
     // list form (e.g. [0 1 2...]). For convenience, since uimm128 values are stored in the
     // `ConstantPool`, this returns `ConstantData`.
@@ -1840,7 +1830,7 @@ impl<'a> Parser<'a> {
             let ty = self.match_type("expected type of constant")?;
             self.match_uimm128(ty)
         } else {
-            self.match_constant_data()
+            self.match_hexadecimal_constant("expected an immediate hexadecimal operand")
         }?;
 
         // Collect any trailing comments.
@@ -3440,14 +3430,18 @@ mod tests {
 
     #[test]
     fn parse_unbounded_constants() {
-        // Unlike match_uimm128, match_constant_data can parse byte sequences of any size:
+        // Unlike match_uimm128, match_hexadecimal_constant can parse byte sequences of any size:
         assert_eq!(
-            Parser::new("[0 1]").match_constant_data().unwrap(),
+            Parser::new("0x0100")
+                .match_hexadecimal_constant("err message")
+                .unwrap(),
             vec![0, 1].into()
         );
 
-        // Only parse byte literals:
-        assert!(Parser::new("[256]").match_constant_data().is_err());
+        // Only parse hexadecimal constants:
+        assert!(Parser::new("228")
+            .match_hexadecimal_constant("err message")
+            .is_err());
     }
 
     #[test]
diff --git a/cranelift/wasm/src/code_translator.rs b/cranelift/wasm/src/code_translator.rs
index fc5c05c66..94301f932 100644
--- a/cranelift/wasm/src/code_translator.rs
+++ b/cranelift/wasm/src/code_translator.rs
@@ -2059,7 +2059,13 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
         }
         Operator::I32x4DotI16x8S => {
             let (a, b) = pop2_with_bitcast(state, I16X8, builder);
-            state.push1(builder.ins().widening_pairwise_dot_product_s(a, b));
+            let alow = builder.ins().swiden_low(a);
+            let blow = builder.ins().swiden_low(b);
+            let low = builder.ins().imul(alow, blow);
+            let ahigh = builder.ins().swiden_high(a);
+            let bhigh = builder.ins().swiden_high(b);
+            let high = builder.ins().imul(ahigh, bhigh);
+            state.push1(builder.ins().iadd_pairwise(low, high));
         }
         Operator::I8x16Popcnt => {
             let arg = pop1_with_bitcast(state, type_of(op), builder);
diff --git a/crates/wasmtime/src/component/mod.rs b/crates/wasmtime/src/component/mod.rs
index 15212fb92..e5cc6d496 100644
--- a/crates/wasmtime/src/component/mod.rs
+++ b/crates/wasmtime/src/component/mod.rs
@@ -135,7 +135,7 @@ pub(crate) use self::store::ComponentStoreData;
 ///
 ///     // Here our `greet` function doesn't take any parameters for the component,
 ///     // but in the Wasmtime embedding API the first argument is always a `Store`.
-///     bindings.greet(&mut store)?;
+///     bindings.call_greet(&mut store)?;
 ///     Ok(())
 /// }
 /// ```
diff --git a/crates/wit-bindgen/src/lib.rs b/crates/wit-bindgen/src/lib.rs
index 21f029613..eb4753f0f 100644
--- a/crates/wit-bindgen/src/lib.rs
+++ b/crates/wit-bindgen/src/lib.rs
@@ -1,4 +1,4 @@
-use crate::rust::{to_rust_ident, RustGenerator, TypeMode};
+use crate::rust::{to_rust_ident, to_rust_upper_camel_case, RustGenerator, TypeMode};
 use crate::types::{TypeInfo, Types};
 use heck::*;
 use std::collections::BTreeMap;
@@ -162,7 +162,7 @@ impl Wasmtime {
                 gen.generate_trappable_error_types(TypeOwner::Interface(*id));
                 let iface = &resolve.interfaces[*id];
 
-                let camel = name.to_upper_camel_case();
+                let camel = to_rust_upper_camel_case(name);
                 uwriteln!(gen.src, "pub struct {camel} {{");
                 for (_, func) in iface.functions.iter() {
                     uwriteln!(
@@ -237,7 +237,7 @@ impl Wasmtime {
     }
 
     fn finish(&mut self, resolve: &Resolve, world: WorldId) -> String {
-        let camel = resolve.worlds[world].name.to_upper_camel_case();
+        let camel = to_rust_upper_camel_case(&resolve.worlds[world].name);
         uwriteln!(self.src, "pub struct {camel} {{");
         for (name, (ty, _)) in self.exports.fields.iter() {
             uwriteln!(self.src, "{name}: {ty},");
@@ -363,7 +363,7 @@ impl Wasmtime {
             return;
         }
 
-        let world_camel = resolve.worlds[world].name.to_upper_camel_case();
+        let world_camel = to_rust_upper_camel_case(&resolve.worlds[world].name);
         if self.opts.async_ {
             uwriteln!(self.src, "#[wasmtime::component::__internal::async_trait]")
         }
@@ -401,11 +401,11 @@ impl Wasmtime {
                     where U: \
             "
         );
-        let world_camel = resolve.worlds[world].name.to_upper_camel_case();
+        let world_camel = to_rust_upper_camel_case(&resolve.worlds[world].name);
         let world_trait = format!("{world_camel}Imports");
         for (i, name) in interfaces
             .iter()
-            .map(|n| format!("{n}::{}", n.to_upper_camel_case()))
+            .map(|n| format!("{n}::Host"))
             .chain(if functions.is_empty() {
                 None
             } else {
@@ -591,7 +591,7 @@ impl<'a> InterfaceGenerator<'a> {
         self.rustdoc(docs);
         self.src.push_str("wasmtime::component::flags!(\n");
         self.src
-            .push_str(&format!("{} {{\n", name.to_upper_camel_case()));
+            .push_str(&format!("{} {{\n", to_rust_upper_camel_case(name)));
         for flag in flags.flags.iter() {
             // TODO wasmtime-component-macro doesnt support docs for flags rn
             uwrite!(
@@ -657,7 +657,7 @@ impl<'a> InterfaceGenerator<'a> {
         let info = self.info(id);
 
         for (name, mode) in self.modes_of(id) {
-            let name = name.to_upper_camel_case();
+            let name = to_rust_upper_camel_case(&name);
 
             self.rustdoc(docs);
             let lt = self.lifetime_for(&info, mode);
@@ -783,14 +783,14 @@ impl<'a> InterfaceGenerator<'a> {
     fn type_enum(&mut self, id: TypeId, name: &str, enum_: &Enum, docs: &Docs) {
         let info = self.info(id);
 
-        let name = name.to_upper_camel_case();
+        let name = to_rust_upper_camel_case(name);
         self.rustdoc(docs);
         self.push_str("#[derive(wasmtime::component::ComponentType)]\n");
         self.push_str("#[derive(wasmtime::component::Lift)]\n");
         self.push_str("#[derive(wasmtime::component::Lower)]\n");
         self.push_str("#[component(enum)]\n");
         self.push_str("#[derive(Clone, Copy, PartialEq, Eq)]\n");
-        self.push_str(&format!("pub enum {} {{\n", name.to_upper_camel_case()));
+        self.push_str(&format!("pub enum {} {{\n", name));
         for case in enum_.cases.iter() {
             self.rustdoc(&case.docs);
             self.push_str(&format!("#[component(name = \"{}\")]", case.name));
@@ -953,7 +953,6 @@ impl<'a> InterfaceGenerator<'a> {
 
     fn generate_add_to_linker(&mut self, id: InterfaceId, name: &str) {
         let iface = &self.resolve.interfaces[id];
-        let camel = name.to_upper_camel_case();
         let owner = TypeOwner::Interface(id);
 
         if self.gen.opts.async_ {
@@ -961,16 +960,16 @@ impl<'a> InterfaceGenerator<'a> {
         }
         // Generate the `pub trait` which represents the host functionality for
         // this import.
-        uwriteln!(self.src, "pub trait {camel}: Sized {{");
+        uwriteln!(self.src, "pub trait Host: Sized {{");
         for (_, func) in iface.functions.iter() {
             self.generate_function_trait_sig(owner, func);
         }
         uwriteln!(self.src, "}}");
 
         let where_clause = if self.gen.opts.async_ {
-            format!("T: Send, U: {camel} + Send")
+            format!("T: Send, U: Host + Send")
         } else {
-            format!("U: {camel}")
+            format!("U: Host")
         };
         uwriteln!(
             self.src,
diff --git a/crates/wit-bindgen/src/rust.rs b/crates/wit-bindgen/src/rust.rs
index 7253106b3..6a8c4a9b1 100644
--- a/crates/wit-bindgen/src/rust.rs
+++ b/crates/wit-bindgen/src/rust.rs
@@ -368,6 +368,7 @@ pub trait RustGenerator<'a> {
     }
 }
 
+/// Translate `name` to a Rust `snake_case` identifier.
 pub fn to_rust_ident(name: &str) -> String {
     match name {
         // Escape Rust keywords.
@@ -425,3 +426,13 @@ pub fn to_rust_ident(name: &str) -> String {
         s => s.to_snake_case(),
     }
 }
+
+/// Translate `name` to a Rust `UpperCamelCase` identifier.
+pub fn to_rust_upper_camel_case(name: &str) -> String {
+    match name {
+        // We use `Host` as the name of the trait for host implementations
+        // to fill in, so rename it if "Host" is used as a regular identifier.
+        "host" => "Host_".into(),
+        s => s.to_upper_camel_case(),
+    }
+}


Test patch:
diff --git a/cranelift/filetests/filetests/egraph/algebraic.clif b/cranelift/filetests/filetests/egraph/algebraic.clif
index 3e8577cdb..24460845a 100644
--- a/cranelift/filetests/filetests/egraph/algebraic.clif
+++ b/cranelift/filetests/filetests/egraph/algebraic.clif
@@ -29,7 +29,7 @@ block0(v0: i8):
     return v3
     ; check: v4 = iconst.i8 224
     ; check: v5 = band v0, v4
-    ; return v5
+    ; check: return v5
 }
 
 function %unsigned_shift_right_shift_left_i32(i32) -> i32 {
@@ -51,7 +51,7 @@ block0(v0: i64):
     return v3
     ; check: v4 = iconst.i64 -32
     ; check: v5 = band v0, v4
-    ; return v5
+    ; check: return v5
 }
 
 function %signed_shift_right_shift_left_i8(i8) -> i8 {
@@ -62,7 +62,7 @@ block0(v0: i8):
     return v3
     ; check: v4 = iconst.i8 224
     ; check: v5 = band v0, v4
-    ; return v5
+    ; check: return v5
 }
 
 function %signed_shift_right_shift_left_i32(i32) -> i32 {
@@ -73,7 +73,7 @@ block0(v0: i32):
     return v3
     ; check: v4 = iconst.i32 0xffff_ffe0
     ; check: v5 = band v0, v4
-    ; return v5
+    ; check: return v5
 }
 
 function %signed_shift_right_shift_left_i64(i64) -> i64 {
@@ -84,7 +84,7 @@ block0(v0: i64):
     return v3
     ; check: v4 = iconst.i64 -32
     ; check: v5 = band v0, v4
-    ; return v5
+    ; check: return v5
 }
 
 function %signed_shift_right_shift_left_i8_mask_rhs(i8) -> i8 {
@@ -95,7 +95,133 @@ block0(v0: i8):
     return v3
     ; check: v4 = iconst.i8 224
     ; check: v5 = band v0, v4
-    ; return v5
+    ; check: return v5
+}
+
+function %sextend_shift_32_64_unsigned(i32) -> i64 {
+block0(v0: i32):
+    v1 = iconst.i8 32
+    v2 = sextend.i64 v0
+    v3 = ishl v2, v1
+    v4 = ushr v3, v1
+    return v4
+    ; check: v7 = uextend.i64 v0
+    ; check: return v7
+}
+
+function %sextend_shift_32_64_signed(i32) -> i64 {
+block0(v0: i32):
+    v1 = iconst.i8 32
+    v2 = sextend.i64 v0
+    v3 = ishl v2, v1
+    v4 = sshr v3, v1
+    return v4
+    ; check: return v2
+}
+
+function %sextend_undershift_32_64_unsigned(i32) -> i64 {
+block0(v0: i32):
+    v1 = iconst.i8 31
+    v2 = sextend.i64 v0
+    v3 = ishl v2, v1
+    v4 = ushr v3, v1
+    return v4
+    ; check: v5 = iconst.i64 0x0001_ffff_ffff
+    ; check: v6 = band v2, v5
+    ; check: return v6
+}
+
+function %sextend_undershift_32_64_signed(i32) -> i64 {
+block0(v0: i32):
+    v1 = iconst.i8 31
+    v2 = sextend.i64 v0
+    v3 = ishl v2, v1
+    v4 = sshr v3, v1
+    return v4
+    ; check: return v2
+}
+
+function %sextend_shift_8_64_unsigned(i8) -> i64 {
+block0(v0: i8):
+    v1 = iconst.i8 56
+    v2 = sextend.i64 v0
+    v3 = ishl v2, v1
+    v4 = ushr v3, v1
+    return v4
+    ; check: v7 = uextend.i64 v0
+    ; check: return v7
+}
+
+function %sextend_shift_8_64_signed(i8) -> i64 {
+block0(v0: i8):
+    v1 = iconst.i8 56
+    v2 = sextend.i64 v0
+    v3 = ishl v2, v1
+    v4 = sshr v3, v1
+    return v4
+    ; check: return v2
+}
+
+function %uextend_shift_32_64_unsigned(i32) -> i64 {
+block0(v0: i32):
+    v1 = iconst.i8 32
+    v2 = uextend.i64 v0
+    v3 = ishl v2, v1
+    v4 = ushr v3, v1
+    return v4
+    ; check: return v2
+}
+
+function %uextend_shift_32_64_signed(i32) -> i64 {
+block0(v0: i32):
+    v1 = iconst.i8 32
+    v2 = uextend.i64 v0
+    v3 = ishl v2, v1
+    v4 = sshr v3, v1
+    return v4
+    ; check: v5 = sextend.i64 v0
+    ; check: return v5
+}
+
+function %uextend_undershift_32_64_unsigned(i32) -> i64 {
+block0(v0: i32):
+    v1 = iconst.i8 31
+    v2 = uextend.i64 v0
+    v3 = ishl v2, v1
+    v4 = ushr v3, v1
+    return v4
+    ; check: return v2
+}
+
+function %uextend_undershift_32_64_signed(i32) -> i64 {
+block0(v0: i32):
+    v1 = iconst.i8 31
+    v2 = uextend.i64 v0
+    v3 = ishl v2, v1
+    v4 = sshr v3, v1
+    return v4
+    ; check: return v2
+}
+
+function %uextend_shift_8_64_unsigned(i8) -> i64 {
+block0(v0: i8):
+    v1 = iconst.i8 56
+    v2 = uextend.i64 v0
+    v3 = ishl v2, v1
+    v4 = ushr v3, v1
+    return v4
+    ; check: return v2
+}
+
+function %uextend_shift_8_64_signed(i8) -> i64 {
+block0(v0: i8):
+    v1 = iconst.i8 56
+    v2 = uextend.i64 v0
+    v3 = ishl v2, v1
+    v4 = sshr v3, v1
+    return v4
+    ; check: v5 = sextend.i64 v0
+    ; check: return v5
 }
 
 function %or_and_y_with_not_y_i8(i8, i8) -> i8 {
diff --git a/cranelift/filetests/filetests/isa/riscv64/call.clif b/cranelift/filetests/filetests/isa/riscv64/call.clif
index 37a4fe4aa..aaf113343 100644
--- a/cranelift/filetests/filetests/isa/riscv64/call.clif
+++ b/cranelift/filetests/filetests/isa/riscv64/call.clif
@@ -810,3 +810,52 @@ block0:
 ;   addi a1, zero, 1
 ;   ret
 
+
+
+function %call_colocated(i16) -> i16 {
+    sig0 = () system_v
+    fn0 = colocated u0:0 sig0
+
+block0(v0: i16):
+    call fn0()
+    return v0
+}
+
+; VCode:
+;   add sp,-16
+;   sd ra,8(sp)
+;   sd fp,0(sp)
+;   mv fp,sp
+;   sd s3,-8(sp)
+;   add sp,-16
+; block0:
+;   mv s3,a0
+;   call userextname0
+;   mv a0,s3
+;   add sp,+16
+;   ld s3,-8(sp)
+;   ld ra,8(sp)
+;   ld fp,0(sp)
+;   add sp,+16
+;   ret
+; 
+; Disassembled:
+; block0: ; offset 0x0
+;   addi sp, sp, -0x10
+;   sd ra, 8(sp)
+;   sd s0, 0(sp)
+;   ori s0, sp, 0
+;   sd s3, -8(sp)
+;   addi sp, sp, -0x10
+; block1: ; offset 0x18
+;   ori s3, a0, 0
+;   auipc ra, 0 ; reloc_external RiscvCall u0:0 0
+;   jalr ra
+;   ori a0, s3, 0
+;   addi sp, sp, 0x10
+;   ld s3, -8(sp)
+;   ld ra, 8(sp)
+;   ld s0, 0(sp)
+;   addi sp, sp, 0x10
+;   ret
+
diff --git a/cranelift/filetests/filetests/isa/s390x/vec-arithmetic.clif b/cranelift/filetests/filetests/isa/s390x/vec-arithmetic.clif
index bb8da42fe..960477cbb 100644
--- a/cranelift/filetests/filetests/isa/s390x/vec-arithmetic.clif
+++ b/cranelift/filetests/filetests/isa/s390x/vec-arithmetic.clif
@@ -1295,8 +1295,14 @@ block0(v0: i8x16, v1: i8x16):
 
 function %widening_pairwise_dot_product_s_i16x8(i16x8, i16x8) -> i32x4 {
 block0(v0: i16x8, v1: i16x8):
-  v2 = widening_pairwise_dot_product_s v0, v1
-  return v2
+    v2 = swiden_low v0
+    v3 = swiden_low v1
+    v4 = imul v2, v3
+    v5 = swiden_high v0
+    v6 = swiden_high v1
+    v7 = imul v5, v6
+    v8 = iadd_pairwise v4, v7
+    return v8
 }
 
 ; VCode:
diff --git a/cranelift/filetests/filetests/isa/x64/fcvt.clif b/cranelift/filetests/filetests/isa/x64/fcvt.clif
index f5d366095..aee96700a 100644
--- a/cranelift/filetests/filetests/isa/x64/fcvt.clif
+++ b/cranelift/filetests/filetests/isa/x64/fcvt.clif
@@ -304,10 +304,8 @@ block0(v0: i32x4):
 ;   pushq   %rbp
 ;   movq    %rsp, %rbp
 ; block0:
-;   movdqu  const(0), %xmm2
-;   unpcklps %xmm0, %xmm2, %xmm0
-;   movdqu  const(1), %xmm6
-;   subpd   %xmm0, %xmm6, %xmm0
+;   unpcklps %xmm0, const(0), %xmm0
+;   subpd   %xmm0, const(1), %xmm0
 ;   movq    %rbp, %rsp
 ;   popq    %rbp
 ;   ret
@@ -317,14 +315,16 @@ block0(v0: i32x4):
 ;   pushq %rbp
 ;   movq %rsp, %rbp
 ; block1: ; offset 0x4
-;   movdqu 0x14(%rip), %xmm2
-;   unpcklps %xmm2, %xmm0
-;   movdqu 0x19(%rip), %xmm6
-;   subpd %xmm6, %xmm0
+;   unpcklps 0x15(%rip), %xmm0
+;   subpd 0x1d(%rip), %xmm0
 ;   movq %rbp, %rsp
 ;   popq %rbp
 ;   retq
 ;   addb %al, (%rax)
+;   addb %al, (%rax)
+;   addb %al, (%rax)
+;   addb %al, (%rax)
+;   addb %al, (%rax)
 ;   xorb %al, (%rbx)
 ;   addb %dh, (%rax)
 ;   addb %al, (%r8)
diff --git a/cranelift/filetests/filetests/isa/x64/float-avx.clif b/cranelift/filetests/filetests/isa/x64/float-avx.clif
index 8626b3475..6776bb529 100644
--- a/cranelift/filetests/filetests/isa/x64/float-avx.clif
+++ b/cranelift/filetests/filetests/isa/x64/float-avx.clif
@@ -566,10 +566,9 @@ block0(v0: f64x2):
 ;   movq    %rsp, %rbp
 ; block0:
 ;   vcmppd  $0 %xmm0, %xmm0, %xmm2
-;   movupd  const(0), %xmm4
-;   vandps  %xmm2, %xmm4, %xmm6
-;   vminpd  %xmm0, %xmm6, %xmm8
-;   vcvttpd2dq %xmm8, %xmm0
+;   vandps  %xmm2, const(0), %xmm4
+;   vminpd  %xmm0, %xmm4, %xmm6
+;   vcvttpd2dq %xmm6, %xmm0
 ;   movq    %rbp, %rsp
 ;   popq    %rbp
 ;   ret
@@ -580,19 +579,13 @@ block0(v0: f64x2):
 ;   movq %rsp, %rbp
 ; block1: ; offset 0x4
 ;   vcmpeqpd %xmm0, %xmm0, %xmm2
-;   movupd 0x1f(%rip), %xmm4
-;   vandps %xmm4, %xmm2, %xmm6
-;   vminpd %xmm6, %xmm0, %xmm8
-;   vcvttpd2dq %xmm8, %xmm0
+;   vandps 0xf(%rip), %xmm2, %xmm4
+;   vminpd %xmm4, %xmm0, %xmm6
+;   vcvttpd2dq %xmm6, %xmm0
 ;   movq %rbp, %rsp
 ;   popq %rbp
 ;   retq
 ;   addb %al, (%rax)
 ;   addb %al, (%rax)
-;   addb %al, (%rax)
-;   addb %al, (%rax)
-;   addb %al, (%rax)
-;   addb %al, (%rax)
-;   addb %al, (%rax)
-;   addb %al, %al
+;   sarb $0xff, %bh
 
diff --git a/cranelift/filetests/filetests/isa/x64/narrowing.clif b/cranelift/filetests/filetests/isa/x64/narrowing.clif
index 2e9025d5e..5eba16326 100644
--- a/cranelift/filetests/filetests/isa/x64/narrowing.clif
+++ b/cranelift/filetests/filetests/isa/x64/narrowing.clif
@@ -63,13 +63,12 @@ block0(v0: f64x2):
 ;   pushq   %rbp
 ;   movq    %rsp, %rbp
 ; block0:
-;   movdqa  %xmm0, %xmm4
-;   cmppd   $0, %xmm4, %xmm0, %xmm4
-;   movupd  const(0), %xmm5
-;   andps   %xmm4, %xmm5, %xmm4
-;   movdqa  %xmm0, %xmm8
-;   minpd   %xmm8, %xmm4, %xmm8
-;   cvttpd2dq %xmm8, %xmm0
+;   movdqa  %xmm0, %xmm3
+;   cmppd   $0, %xmm3, %xmm0, %xmm3
+;   andps   %xmm3, const(0), %xmm3
+;   movdqa  %xmm0, %xmm6
+;   minpd   %xmm6, %xmm3, %xmm6
+;   cvttpd2dq %xmm6, %xmm0
 ;   movq    %rbp, %rsp
 ;   popq    %rbp
 ;   ret
@@ -79,20 +78,22 @@ block0(v0: f64x2):
 ;   pushq %rbp
 ;   movq %rsp, %rbp
 ; block1: ; offset 0x4
-;   movdqa %xmm0, %xmm4
-;   cmpeqpd %xmm0, %xmm4
-;   movupd 0x1b(%rip), %xmm5
-;   andps %xmm5, %xmm4
-;   movdqa %xmm0, %xmm8
-;   minpd %xmm4, %xmm8
-;   cvttpd2dq %xmm8, %xmm0
+;   movdqa %xmm0, %xmm3
+;   cmpeqpd %xmm0, %xmm3
+;   andps 0x1c(%rip), %xmm3
+;   movdqa %xmm0, %xmm6
+;   minpd %xmm3, %xmm6
+;   cvttpd2dq %xmm6, %xmm0
 ;   movq %rbp, %rsp
 ;   popq %rbp
 ;   retq
 ;   addb %al, (%rax)
 ;   addb %al, (%rax)
 ;   addb %al, (%rax)
-;   sarb $0xff, %bh
+;   addb %al, (%rax)
+;   addb %al, (%rax)
+;   addb %al, (%rax)
+;   addb %al, %al
 
 function %f4(i16x8, i16x8) -> i8x16 {
 block0(v0: i16x8, v1: i16x8):
diff --git a/cranelift/filetests/filetests/isa/x64/shuffle-avx512.clif b/cranelift/filetests/filetests/isa/x64/shuffle-avx512.clif
index c7bbf96e4..6f6301049 100644
--- a/cranelift/filetests/filetests/isa/x64/shuffle-avx512.clif
+++ b/cranelift/filetests/filetests/isa/x64/shuffle-avx512.clif
@@ -55,12 +55,11 @@ block0(v0: i8x16, v1: i8x16):
 ;   pushq   %rbp
 ;   movq    %rsp, %rbp
 ; block0:
-;   movdqa  %xmm0, %xmm7
-;   movdqu  const(1), %xmm0
-;   movdqu  const(0), %xmm6
-;   movdqa  %xmm7, %xmm9
-;   vpermi2b %xmm1, %xmm9, %xmm6, %xmm6
-;   andps   %xmm0, %xmm6, %xmm0
+;   movdqa  %xmm0, %xmm6
+;   movdqu  const(0), %xmm0
+;   movdqa  %xmm6, %xmm7
+;   vpermi2b %xmm1, %xmm7, %xmm0, %xmm0
+;   andps   %xmm0, const(1), %xmm0
 ;   movq    %rbp, %rsp
 ;   popq    %rbp
 ;   ret
@@ -70,12 +69,11 @@ block0(v0: i8x16, v1: i8x16):
 ;   pushq %rbp
 ;   movq %rsp, %rbp
 ; block1: ; offset 0x4
-;   movdqa %xmm0, %xmm7
-;   movdqu 0x30(%rip), %xmm0
-;   movdqu 0x18(%rip), %xmm6
-;   movdqa %xmm7, %xmm9
-;   vpermi2b %xmm1, %xmm9, %xmm6
-;   andps %xmm6, %xmm0
+;   movdqa %xmm0, %xmm6
+;   movdqu 0x20(%rip), %xmm0
+;   movdqa %xmm6, %xmm7
+;   vpermi2b %xmm1, %xmm7, %xmm0
+;   andps 0x1f(%rip), %xmm0
 ;   movq %rbp, %rsp
 ;   popq %rbp
 ;   retq
@@ -89,7 +87,9 @@ block0(v0: i8x16, v1: i8x16):
 ;   addb %al, (%rax)
 ;   addb %al, (%rax)
 ;   addb %al, (%rax)
-;   cmpb $0xff, %bh
+;   addb %al, (%rax)
+;   addb %al, (%rax)
+;   addb %al, -1(%rax)
 
 function %f3(i8x16, i8x16) -> i8x16 {
 block0(v0: i8x16, v1: i8x16):
diff --git a/cranelift/filetests/filetests/isa/x64/simd-arith-avx.clif b/cranelift/filetests/filetests/isa/x64/simd-arith-avx.clif
index 323280260..3e622bd5f 100644
--- a/cranelift/filetests/filetests/isa/x64/simd-arith-avx.clif
+++ b/cranelift/filetests/filetests/isa/x64/simd-arith-avx.clif
@@ -574,10 +574,9 @@ block0(v0: i16x8, v1: i16x8):
 ;   pushq   %rbp
 ;   movq    %rsp, %rbp
 ; block0:
-;   movdqu  const(0), %xmm3
-;   vpmulhrsw %xmm0, %xmm1, %xmm5
-;   vpcmpeqw %xmm3, %xmm5, %xmm7
-;   vpxor   %xmm5, %xmm7, %xmm0
+;   vpmulhrsw %xmm0, %xmm1, %xmm3
+;   vpcmpeqw %xmm3, const(0), %xmm5
+;   vpxor   %xmm3, %xmm5, %xmm0
 ;   movq    %rbp, %rsp
 ;   popq    %rbp
 ;   ret
@@ -587,14 +586,15 @@ block0(v0: i16x8, v1: i16x8):
 ;   pushq %rbp
 ;   movq %rsp, %rbp
 ; block1: ; offset 0x4
-;   movdqu 0x14(%rip), %xmm3
-;   vpmulhrsw %xmm1, %xmm0, %xmm5
-;   vpcmpeqw %xmm5, %xmm3, %xmm7
-;   vpxor %xmm7, %xmm5, %xmm0
+;   vpmulhrsw %xmm1, %xmm0, %xmm3
+;   vpcmpeqw 0xf(%rip), %xmm3, %xmm5
+;   vpxor %xmm5, %xmm3, %xmm0
 ;   movq %rbp, %rsp
 ;   popq %rbp
 ;   retq
 ;   addb %al, (%rax)
+;   addb %al, (%rax)
+;   addb %al, (%rax)
 ;   addb %al, -0x7fff8000(%rax)
 ;   addb %al, -0x7fff8000(%rax)
 
@@ -671,10 +671,8 @@ block0(v0: i32x4):
 ;   pushq   %rbp
 ;   movq    %rsp, %rbp
 ; block0:
-;   movdqu  const(0), %xmm2
-;   vunpcklps %xmm0, %xmm2, %xmm4
-;   movdqu  const(1), %xmm6
-;   vsubpd  %xmm4, %xmm6, %xmm0
+;   vunpcklps %xmm0, const(0), %xmm2
+;   vsubpd  %xmm2, const(1), %xmm0
 ;   movq    %rbp, %rsp
 ;   popq    %rbp
 ;   ret
@@ -684,10 +682,8 @@ block0(v0: i32x4):
 ;   pushq %rbp
 ;   movq %rsp, %rbp
 ; block1: ; offset 0x4
-;   movdqu 0x24(%rip), %xmm2
-;   vunpcklps %xmm2, %xmm0, %xmm4
-;   movdqu 0x28(%rip), %xmm6
-;   vsubpd %xmm6, %xmm4, %xmm0
+;   vunpcklps 0x14(%rip), %xmm0, %xmm2
+;   vsubpd 0x1c(%rip), %xmm2, %xmm0
 ;   movq %rbp, %rsp
 ;   popq %rbp
 ;   retq
@@ -695,10 +691,6 @@ block0(v0: i32x4):
 ;   addb %al, (%rax)
 ;   addb %al, (%rax)
 ;   addb %al, (%rax)
-;   addb %al, (%rax)
-;   addb %al, (%rax)
-;   addb %al, (%rax)
-;   addb %al, (%rax)
 ;   addb %dh, (%rax)
 ;   addb %al, (%r8)
 ;   xorb %al, (%rbx)
@@ -1283,8 +1275,7 @@ block0(v0: i16x8):
 ;   pushq   %rbp
 ;   movq    %rsp, %rbp
 ; block0:
-;   movdqu  const(0), %xmm2
-;   vpmaddwd %xmm0, %xmm2, %xmm0
+;   vpmaddwd %xmm0, const(0), %xmm0
 ;   movq    %rbp, %rsp
 ;   popq    %rbp
 ;   ret
@@ -1294,8 +1285,7 @@ block0(v0: i16x8):
 ;   pushq %rbp
 ;   movq %rsp, %rbp
 ; block1: ; offset 0x4
-;   movdqu 0x14(%rip), %xmm2
-;   vpmaddwd %xmm2, %xmm0, %xmm0
+;   vpmaddwd 0x14(%rip), %xmm0, %xmm0
 ;   movq %rbp, %rsp
 ;   popq %rbp
 ;   retq
@@ -1304,6 +1294,8 @@ block0(v0: i16x8):
 ;   addb %al, (%rax)
 ;   addb %al, (%rax)
 ;   addb %al, (%rax)
+;   addb %al, (%rax)
+;   addb %al, (%rax)
 ;   addb %al, (%rcx)
 ;   addb %al, (%rcx)
 ;   addb %al, (%rcx)
@@ -1357,12 +1349,10 @@ block0(v0: f64x2):
 ; block0:
 ;   xorpd   %xmm2, %xmm2, %xmm2
 ;   vmaxpd  %xmm0, %xmm2, %xmm4
-;   movupd  const(0), %xmm6
-;   vminpd  %xmm4, %xmm6, %xmm8
-;   vroundpd $3, %xmm8, %xmm10
-;   movupd  const(1), %xmm12
-;   vaddpd  %xmm10, %xmm12, %xmm14
-;   vshufps $136 %xmm14, %xmm2, %xmm0
+;   vminpd  %xmm4, const(0), %xmm6
+;   vroundpd $3, %xmm6, %xmm8
+;   vaddpd  %xmm8, const(1), %xmm10
+;   vshufps $136 %xmm10, %xmm2, %xmm0
 ;   movq    %rbp, %rsp
 ;   popq    %rbp
 ;   ret
@@ -1374,22 +1364,17 @@ block0(v0: f64x2):
 ; block1: ; offset 0x4
 ;   xorpd %xmm2, %xmm2
 ;   vmaxpd %xmm2, %xmm0, %xmm4
-;   movupd 0x2c(%rip), %xmm6
-;   vminpd %xmm6, %xmm4, %xmm8
-;   vroundpd $3, %xmm8, %xmm10
-;   movupd 0x29(%rip), %xmm12
-;   vaddpd %xmm12, %xmm10, %xmm14
-;   vshufps $0x88, %xmm2, %xmm14, %xmm0
+;   vminpd 0x1c(%rip), %xmm4, %xmm6
+;   vroundpd $3, %xmm6, %xmm8
+;   vaddpd 0x1e(%rip), %xmm8, %xmm10
+;   vshufps $0x88, %xmm2, %xmm10, %xmm0
 ;   movq %rbp, %rsp
 ;   popq %rbp
 ;   retq
 ;   addb %al, (%rax)
 ;   addb %al, (%rax)
 ;   addb %al, (%rax)
-;   addb %al, (%rax)
-;   addb %al, (%rax)
-;   addb %al, (%rax)
-;   loopne 0x43
+;   loopne 0x33
 
 function %i8x16_shl(i8x16, i32) -> i8x16 {
 block0(v0: i8x16, v1: i32):
diff --git a/cranelift/filetests/filetests/isa/x64/simd-lane-access-compile.clif b/cranelift/filetests/filetests/isa/x64/simd-lane-access-compile.clif
index 790fde063..b6f75d779 100644
--- a/cranelift/filetests/filetests/isa/x64/simd-lane-access-compile.clif
+++ b/cranelift/filetests/filetests/isa/x64/simd-lane-access-compile.clif
@@ -17,12 +17,10 @@ block0:
 ;   movq    %rsp, %rbp
 ; block0:
 ;   movdqu  const(3), %xmm0
-;   movdqu  const(2), %xmm4
-;   movdqu  const(0), %xmm2
-;   pshufb  %xmm0, %xmm2, %xmm0
-;   movdqu  const(1), %xmm6
-;   pshufb  %xmm4, %xmm6, %xmm4
-;   por     %xmm0, %xmm4, %xmm0
+;   movdqu  const(2), %xmm2
+;   pshufb  %xmm0, const(0), %xmm0
+;   pshufb  %xmm2, const(1), %xmm2
+;   por     %xmm0, %xmm2, %xmm0
 ;   movq    %rbp, %rsp
 ;   popq    %rbp
 ;   ret
@@ -32,13 +30,11 @@ block0:
 ;   pushq %rbp
 ;   movq %rsp, %rbp
 ; block1: ; offset 0x4
-;   movdqu 0x64(%rip), %xmm0
-;   movdqu 0x4c(%rip), %xmm4
-;   movdqu 0x24(%rip), %xmm2
-;   pshufb %xmm2, %xmm0
-;   movdqu 0x27(%rip), %xmm6
-;   pshufb %xmm6, %xmm4
-;   por %xmm4, %xmm0
+;   movdqu 0x54(%rip), %xmm0
+;   movdqu 0x3c(%rip), %xmm2
+;   pshufb 0x13(%rip), %xmm0
+;   pshufb 0x1a(%rip), %xmm2
+;   por %xmm2, %xmm0
 ;   movq %rbp, %rsp
 ;   popq %rbp
 ;   retq
@@ -50,10 +46,6 @@ block0:
 ;   addb %al, (%rax)
 ;   addb %al, (%rax)
 ;   addb %al, (%rax)
-;   addb %al, (%rax)
-;   addb %al, (%rax)
-;   addb %al, (%rax)
-;   addb %al, (%rax)
 ;   addb $0x80, -0x7f7f7f80(%rax)
 ;   addb $0x80, -0x7f7f7f80(%rax)
 ;   addb $0, 0x101(%rax)
@@ -84,8 +76,7 @@ block0:
 ;   movq    %rsp, %rbp
 ; block0:
 ;   movdqu  const(1), %xmm0
-;   movdqu  const(0), %xmm1
-;   pshufb  %xmm0, %xmm1, %xmm0
+;   pshufb  %xmm0, const(0), %xmm0
 ;   movq    %rbp, %rsp
 ;   popq    %rbp
 ;   ret
@@ -96,8 +87,7 @@ block0:
 ;   movq %rsp, %rbp
 ; block1: ; offset 0x4
 ;   movdqu 0x24(%rip), %xmm0
-;   movdqu 0xc(%rip), %xmm1
-;   pshufb %xmm1, %xmm0
+;   pshufb 0xb(%rip), %xmm0
 ;   movq %rbp, %rsp
 ;   popq %rbp
 ;   retq
@@ -109,6 +99,8 @@ block0:
 ;   addb %al, (%rax)
 ;   addb %al, (%rax)
 ;   addb %al, (%rax)
+;   addb %al, (%rax)
+;   addb %al, (%rax)
 ;   addb %al, (%rcx, %rax)
 ;   addb %al, (%rax)
 ;   addb %al, (%rax)
@@ -131,10 +123,9 @@ block0:
 ;   movq    %rsp, %rbp
 ; block0:
 ;   movdqu  const(1), %xmm0
-;   movdqu  const(1), %xmm2
-;   movdqu  const(0), %xmm3
-;   paddusb %xmm2, %xmm3, %xmm2
-;   pshufb  %xmm0, %xmm2, %xmm0
+;   movdqu  const(1), %xmm1
+;   paddusb %xmm1, const(0), %xmm1
+;   pshufb  %xmm0, %xmm1, %xmm0
 ;   movq    %rbp, %rsp
 ;   popq    %rbp
 ;   ret
@@ -145,16 +136,17 @@ block0:
 ;   movq %rsp, %rbp
 ; block1: ; offset 0x4
 ;   movdqu 0x34(%rip), %xmm0
-;   movdqu 0x2c(%rip), %xmm2
-;   movdqu 0x14(%rip), %xmm3
-;   paddusb %xmm3, %xmm2
-;   pshufb %xmm2, %xmm0
+;   movdqu 0x2c(%rip), %xmm1
+;   paddusb 0x14(%rip), %xmm1
+;   pshufb %xmm1, %xmm0
 ;   movq %rbp, %rsp
 ;   popq %rbp
 ;   retq
 ;   addb %al, (%rax)
 ;   addb %al, (%rax)
 ;   addb %al, (%rax)
+;   addb %al, (%rax)
+;   addb %al, (%rax)
 ;   jo 0xa2
 ;   jo 0xa4
 ;   jo 0xa6
diff --git a/cranelift/filetests/filetests/isa/x64/simd-pairwise-add.clif b/cranelift/filetests/filetests/isa/x64/simd-pairwise-add.clif
index 6f3698c61..1838ddacd 100644
--- a/cranelift/filetests/filetests/isa/x64/simd-pairwise-add.clif
+++ b/cranelift/filetests/filetests/isa/x64/simd-pairwise-add.clif
@@ -55,8 +55,7 @@ block0(v0: i16x8):
 ;   pushq   %rbp
 ;   movq    %rsp, %rbp
 ; block0:
-;   movdqu  const(0), %xmm2
-;   pmaddwd %xmm0, %xmm2, %xmm0
+;   pmaddwd %xmm0, const(0), %xmm0
 ;   movq    %rbp, %rsp
 ;   popq    %rbp
 ;   ret
@@ -66,8 +65,7 @@ block0(v0: i16x8):
 ;   pushq %rbp
 ;   movq %rsp, %rbp
 ; block1: ; offset 0x4
-;   movdqu 0x14(%rip), %xmm2
-;   pmaddwd %xmm2, %xmm0
+;   pmaddwd 0x14(%rip), %xmm0
 ;   movq %rbp, %rsp
 ;   popq %rbp
 ;   retq
@@ -76,6 +74,8 @@ block0(v0: i16x8):
 ;   addb %al, (%rax)
 ;   addb %al, (%rax)
 ;   addb %al, (%rax)
+;   addb %al, (%rax)
+;   addb %al, (%rax)
 ;   addb %al, (%rcx)
 ;   addb %al, (%rcx)
 ;   addb %al, (%rcx)
@@ -97,8 +97,7 @@ block0(v0: i8x16):
 ;   pushq   %rbp
 ;   movq    %rsp, %rbp
 ; block0:
-;   movdqu  const(0), %xmm2
-;   pmaddubsw %xmm0, %xmm2, %xmm0
+;   pmaddubsw %xmm0, const(0), %xmm0
 ;   movq    %rbp, %rsp
 ;   popq    %rbp
 ;   ret
@@ -108,8 +107,7 @@ block0(v0: i8x16):
 ;   pushq %rbp
 ;   movq %rsp, %rbp
 ; block1: ; offset 0x4
-;   movdqu 0x14(%rip), %xmm2
-;   pmaddubsw %xmm2, %xmm0
+;   pmaddubsw 0x13(%rip), %xmm0
 ;   movq %rbp, %rsp
 ;   popq %rbp
 ;   retq
@@ -118,6 +116,8 @@ block0(v0: i8x16):
 ;   addb %al, (%rax)
 ;   addb %al, (%rax)
 ;   addb %al, (%rax)
+;   addb %al, (%rax)
+;   addb %al, (%rax)
 ;   addl %eax, (%rcx)
 ;   addl %eax, (%rcx)
 ;   addl %eax, (%rcx)
@@ -139,12 +139,9 @@ block0(v0: i16x8):
 ;   pushq   %rbp
 ;   movq    %rsp, %rbp
 ; block0:
-;   movdqu  const(0), %xmm2
-;   pxor    %xmm0, %xmm2, %xmm0
-;   movdqu  const(1), %xmm6
-;   pmaddwd %xmm0, %xmm6, %xmm0
-;   movdqu  const(2), %xmm10
-;   paddd   %xmm0, %xmm10, %xmm0
+;   pxor    %xmm0, const(0), %xmm0
+;   pmaddwd %xmm0, const(1), %xmm0
+;   paddd   %xmm0, const(2), %xmm0
 ;   movq    %rbp, %rsp
 ;   popq    %rbp
 ;   ret
@@ -154,16 +151,20 @@ block0(v0: i16x8):
 ;   pushq %rbp
 ;   movq %rsp, %rbp
 ; block1: ; offset 0x4
-;   movdqu 0x24(%rip), %xmm2
-;   pxor %xmm2, %xmm0
-;   movdqu 0x28(%rip), %xmm6
-;   pmaddwd %xmm6, %xmm0
-;   movdqu 0x2b(%rip), %xmm10
-;   paddd %xmm10, %xmm0
+;   pxor 0x24(%rip), %xmm0
+;   pmaddwd 0x2c(%rip), %xmm0
+;   paddd 0x34(%rip), %xmm0
 ;   movq %rbp, %rsp
 ;   popq %rbp
 ;   retq
 ;   addb %al, (%rax)
+;   addb %al, (%rax)
+;   addb %al, (%rax)
+;   addb %al, (%rax)
+;   addb %al, (%rax)
+;   addb %al, (%rax)
+;   addb %al, (%rax)
+;   addb %al, (%rax)
 ;   addb $0x80, (%rax)
 ;   addb %al, -0x7fff8000(%rax)
 ;   addb %al, -0x7fff8000(%rax)
diff --git a/cranelift/filetests/filetests/isa/x64/sqmul_round_sat.clif b/cranelift/filetests/filetests/isa/x64/sqmul_round_sat.clif
index d9241b604..fdf7cee8f 100644
--- a/cranelift/filetests/filetests/isa/x64/sqmul_round_sat.clif
+++ b/cranelift/filetests/filetests/isa/x64/sqmul_round_sat.clif
@@ -11,9 +11,9 @@ block0(v0: i16x8, v1: i16x8):
 ;   pushq   %rbp
 ;   movq    %rsp, %rbp
 ; block0:
-;   movdqu  const(0), %xmm5
 ;   pmulhrsw %xmm0, %xmm1, %xmm0
-;   pcmpeqw %xmm5, %xmm0, %xmm5
+;   movdqa  %xmm0, %xmm5
+;   pcmpeqw %xmm5, const(0), %xmm5
 ;   pxor    %xmm0, %xmm5, %xmm0
 ;   movq    %rbp, %rsp
 ;   popq    %rbp
@@ -24,9 +24,9 @@ block0(v0: i16x8, v1: i16x8):
 ;   pushq %rbp
 ;   movq %rsp, %rbp
 ; block1: ; offset 0x4
-;   movdqu 0x14(%rip), %xmm5
 ;   pmulhrsw %xmm1, %xmm0
-;   pcmpeqw %xmm0, %xmm5
+;   movdqa %xmm0, %xmm5
+;   pcmpeqw 0xb(%rip), %xmm5
 ;   pxor %xmm5, %xmm0
 ;   movq %rbp, %rsp
 ;   popq %rbp
diff --git a/cranelift/filetests/filetests/isa/x64/uunarrow.clif b/cranelift/filetests/filetests/isa/x64/uunarrow.clif
index b65eb2643..643b32f8e 100644
--- a/cranelift/filetests/filetests/isa/x64/uunarrow.clif
+++ b/cranelift/filetests/filetests/isa/x64/uunarrow.clif
@@ -14,13 +14,11 @@ block0(v0: f64x2):
 ;   movq    %rsp, %rbp
 ; block0:
 ;   xorpd   %xmm2, %xmm2, %xmm2
-;   movdqa  %xmm0, %xmm6
-;   maxpd   %xmm6, %xmm2, %xmm6
-;   movupd  const(0), %xmm7
-;   minpd   %xmm6, %xmm7, %xmm6
-;   roundpd $3, %xmm6, %xmm0
-;   movupd  const(1), %xmm12
-;   addpd   %xmm0, %xmm12, %xmm0
+;   movdqa  %xmm0, %xmm5
+;   maxpd   %xmm5, %xmm2, %xmm5
+;   minpd   %xmm5, const(0), %xmm5
+;   roundpd $3, %xmm5, %xmm0
+;   addpd   %xmm0, const(1), %xmm0
 ;   shufps  $136, %xmm0, %xmm2, %xmm0
 ;   movq    %rbp, %rsp
 ;   popq    %rbp
@@ -32,20 +30,15 @@ block0(v0: f64x2):
 ;   movq %rsp, %rbp
 ; block1: ; offset 0x4
 ;   xorpd %xmm2, %xmm2
-;   movdqa %xmm0, %xmm6
-;   maxpd %xmm2, %xmm6
-;   movupd 0x28(%rip), %xmm7
-;   minpd %xmm7, %xmm6
-;   roundpd $3, %xmm6, %xmm0
-;   movupd 0x25(%rip), %xmm12
-;   addpd %xmm12, %xmm0
+;   movdqa %xmm0, %xmm5
+;   maxpd %xmm2, %xmm5
+;   minpd 0x18(%rip), %xmm5
+;   roundpd $3, %xmm5, %xmm0
+;   addpd 0x1a(%rip), %xmm0
 ;   shufps $0x88, %xmm2, %xmm0
 ;   movq %rbp, %rsp
 ;   popq %rbp
 ;   retq
 ;   addb %al, (%rax)
-;   addb %al, (%rax)
-;   addb %al, (%rax)
-;   addb %al, (%rax)
 ;   addb %ah, %al
 
diff --git a/cranelift/filetests/filetests/runtests/call.clif b/cranelift/filetests/filetests/runtests/call.clif
index 7df6586e3..78fa62ad0 100644
--- a/cranelift/filetests/filetests/runtests/call.clif
+++ b/cranelift/filetests/filetests/runtests/call.clif
@@ -5,6 +5,7 @@ target aarch64
 target aarch64 sign_return_address
 target aarch64 has_pauth sign_return_address
 target s390x
+target riscv64
 
 
 function %callee_i64(i64) -> i64 {
diff --git a/cranelift/filetests/filetests/runtests/call_libcall.clif b/cranelift/filetests/filetests/runtests/call_libcall.clif
index 3e9cafd37..8800fe25f 100644
--- a/cranelift/filetests/filetests/runtests/call_libcall.clif
+++ b/cranelift/filetests/filetests/runtests/call_libcall.clif
@@ -2,6 +2,7 @@ test run
 target x86_64
 ; AArch64 Does not have these libcalls
 target s390x
+target riscv64
 
 
 function %libcall_ceilf32(f32) -> f32 {
diff --git a/cranelift/filetests/filetests/runtests/issue5714.clif b/cranelift/filetests/filetests/runtests/issue5714.clif
new file mode 100644
index 000000000..35cbab7d2
--- /dev/null
+++ b/cranelift/filetests/filetests/runtests/issue5714.clif
@@ -0,0 +1,25 @@
+test interpret
+test run
+target aarch64
+target s390x
+target riscv64
+
+function %a(i32 sext, f64, f32, i64 uext) -> f32, i8, i8 system_v {
+block0(v0: i32, v1: f64, v2: f32, v3: i64):
+    v12 -> v1
+    v14 -> v2
+    v16 -> v2
+    v4 = iconst.i16 0x4242
+    v5 = iconst.i64 0x0042_4242_4242_4242
+    jump block1
+
+block1:
+    v13 = fcvt_to_sint_sat.i8 v12
+    v15 -> v13
+    brif v13, block2, block1
+
+block2:
+    return v14, v15, v15
+}
+
+; run: %a(1111441986, -0x1.ffa8b425b4242p128, 0x0.00859ep-126, 0) == [0x0.00859ep-126, -128, -128]
\ No newline at end of file
diff --git a/cranelift/filetests/filetests/runtests/simd-wideningpairwisedotproducts.clif b/cranelift/filetests/filetests/runtests/simd-wideningpairwisedotproducts.clif
index c38099c42..205f43181 100644
--- a/cranelift/filetests/filetests/runtests/simd-wideningpairwisedotproducts.clif
+++ b/cranelift/filetests/filetests/runtests/simd-wideningpairwisedotproducts.clif
@@ -1,4 +1,3 @@
-test interpret
 test run
 target aarch64
 target s390x
@@ -7,8 +6,14 @@ target x86_64 has_sse3 has_ssse3 has_sse41
 
 function %wpdps(i16x8, i16x8) -> i32x4 {
 block0(v0: i16x8, v1: i16x8):
-    v2 = widening_pairwise_dot_product_s v0, v1
-    return v2
+    v2 = swiden_low v0
+    v3 = swiden_low v1
+    v4 = imul v2, v3
+    v5 = swiden_high v0
+    v6 = swiden_high v1
+    v7 = imul v5, v6
+    v8 = iadd_pairwise v4, v7
+    return v8
 }
 ; run: %wpdps([1 2 3 4 5 6 7 8], [8000 7000 6000 5000 4000 3000 2000 1000]) == [22000 38000 38000 22000]
 ; run: %wpdps([1 -2 3 -4 5 -6 7 -8], [32767 32767 32767 32767 -32768 -32768 -32768 -32768]) == [-32767 -32767 32768 32768]
diff --git a/cranelift/filetests/filetests/verifier/constant.clif b/cranelift/filetests/filetests/verifier/constant.clif
index a93abb82d..ac6aff204 100644
--- a/cranelift/filetests/filetests/verifier/constant.clif
+++ b/cranelift/filetests/filetests/verifier/constant.clif
@@ -2,7 +2,7 @@ test verifier
 set enable_simd
 
 function %incorrect_constant_size() {
-const13 = [1 2 3 4 5]  ; this constant has 5 bytes
+const13 = 0x0102030405  ; this constant has 5 bytes
 block0:
     v0 = vconst.i32x4 const13 ; error: The instruction expects const13 to have a size of 16 bytes but it has 5
     return
diff --git a/crates/component-macro/tests/codegen/simple-wasi.wit b/crates/component-macro/tests/codegen/simple-wasi.wit
index e2c2cee35..02c47dc9b 100644
--- a/crates/component-macro/tests/codegen/simple-wasi.wit
+++ b/crates/component-macro/tests/codegen/simple-wasi.wit
@@ -10,6 +10,12 @@ interface wasi-filesystem {
   stat: func() -> result<descriptor-stat, errno>
 }
 
+interface wall-clock {
+  record wall-clock {
+  }
+}
+
 default world wasi {
   import wasi-filesystem: self.wasi-filesystem
+  import wall-clock: self.wall-clock
 }
diff --git a/tests/all/component_model/bindgen.rs b/tests/all/component_model/bindgen.rs
index ddadec891..70681b6bf 100644
--- a/tests/all/component_model/bindgen.rs
+++ b/tests/all/component_model/bindgen.rs
@@ -97,7 +97,7 @@ mod one_import {
             hit: bool,
         }
 
-        impl foo::Foo for MyImports {
+        impl foo::Host for MyImports {
             fn foo(&mut self) -> Result<()> {
                 self.hit = true;
                 Ok(())
diff --git a/tests/all/component_model/bindgen/results.rs b/tests/all/component_model/bindgen/results.rs
index 321eed9fd..0626af86f 100644
--- a/tests/all/component_model/bindgen/results.rs
+++ b/tests/all/component_model/bindgen/results.rs
@@ -60,7 +60,7 @@ mod empty_error {
         #[derive(Default)]
         struct MyImports {}
 
-        impl imports::Imports for MyImports {
+        impl imports::Host for MyImports {
             fn empty_error(&mut self, a: f64) -> Result<Result<f64, ()>, Error> {
                 if a == 0.0 {
                     Ok(Ok(a))
@@ -171,7 +171,7 @@ mod string_error {
         #[derive(Default)]
         struct MyImports {}
 
-        impl imports::Imports for MyImports {
+        impl imports::Host for MyImports {
             fn string_error(&mut self, a: f64) -> Result<Result<f64, String>, Error> {
                 if a == 0.0 {
                     Ok(Ok(a))
@@ -313,7 +313,7 @@ mod enum_error {
         #[derive(Default)]
         struct MyImports {}
 
-        impl imports::Imports for MyImports {
+        impl imports::Host for MyImports {
             fn enum_error(&mut self, a: f64) -> Result<f64, imports::TrappableE1> {
                 if a == 0.0 {
                     Ok(a)
@@ -440,7 +440,7 @@ mod record_error {
         #[derive(Default)]
         struct MyImports {}
 
-        impl imports::Imports for MyImports {
+        impl imports::Host for MyImports {
             fn record_error(&mut self, a: f64) -> Result<f64, imports::TrappableE2> {
                 if a == 0.0 {
                     Ok(a)
@@ -576,7 +576,7 @@ mod variant_error {
         #[derive(Default)]
         struct MyImports {}
 
-        impl imports::Imports for MyImports {
+        impl imports::Host for MyImports {
             fn variant_error(&mut self, a: f64) -> Result<f64, imports::TrappableE3> {
                 if a == 0.0 {
                     Ok(a)